diff.committed_by
Łukasz Magiera
11 changed files with 712 additions and 6 deletions
@ -1,4 +1,5 @@ |
|||
#ifndef RES_H |
|||
#define RES_H |
|||
extern char res_eepromDefault[]; |
|||
extern char res_unifont[]; |
|||
#endif |
|||
|
diff.bin_not_shown
@ -0,0 +1,503 @@ |
|||
#define _XOPEN_SOURCE 500 |
|||
|
|||
#include "res.h" |
|||
#include "lupi.h" |
|||
#include <lua.h> |
|||
#include <lualib.h> |
|||
#include <lauxlib.h> |
|||
#include <sys/ioctl.h> |
|||
#include <sys/types.h> |
|||
#include <sys/mman.h> |
|||
#include <sys/stat.h> |
|||
#include <fcntl.h> |
|||
#include <string.h> |
|||
#include <stdlib.h> |
|||
#include <math.h> |
|||
#include <unistd.h> |
|||
#include <limits.h> |
|||
#include <linux/fb.h> |
|||
|
|||
int fb_ready = 0; |
|||
int fb_file; |
|||
struct fb_var_screeninfo fb_vinfo; |
|||
struct fb_fix_screeninfo fb_finfo; |
|||
char *fb_ptr = 0; |
|||
char *colbuf = 0; |
|||
ushort *chrbuf = 0; |
|||
int fb_cw, fb_ch, fb_bpp, fb_bypp, fb_xo, fb_yo, fb_pitch; |
|||
int fb_rot = 0; |
|||
int palette[256]; |
|||
float pal_yuv[768]; |
|||
|
|||
#define XY_TO_FB(x, y) (((fb_yo + (y)) * fb_pitch) + ((fb_xo + (x)) * fb_bypp)) |
|||
#define XY_TO_COLBUF(x, y, z) (((((y) * fb_cw) + (x)) * 2) + (z)) |
|||
#define XY_TO_CHRBUF(x, y) (((y) * fb_cw) + (x)) |
|||
|
|||
static inline int fb_xrot(int x, int y) { |
|||
switch (fb_rot) { |
|||
default: |
|||
return x; |
|||
case 1: |
|||
return fb_vinfo.xres - y - 1; |
|||
case 2: |
|||
return fb_vinfo.xres - x - 1; |
|||
case 3: |
|||
return y; |
|||
} |
|||
} |
|||
|
|||
static inline int fb_yrot(int x, int y) { |
|||
switch (fb_rot) { |
|||
default: |
|||
return y; |
|||
case 1: |
|||
return x; |
|||
case 2: |
|||
return fb_vinfo.yres - y - 1; |
|||
case 3: |
|||
return fb_vinfo.yres - x - 1; |
|||
} |
|||
} |
|||
|
|||
static inline int fb_cxrot(int x, int y) { |
|||
switch (fb_rot) { |
|||
default: |
|||
return x; |
|||
case 1: |
|||
return (fb_vinfo.xres >> 4) - y - 1; |
|||
case 2: |
|||
return (fb_vinfo.xres >> 3) - x - 1; |
|||
case 3: |
|||
return y; |
|||
} |
|||
} |
|||
|
|||
static inline int fb_cyrot(int x, int y) { |
|||
switch (fb_rot) { |
|||
default: |
|||
return y; |
|||
case 1: |
|||
return x; |
|||
case 2: |
|||
return (fb_vinfo.yres >> 4) - y - 1; |
|||
case 3: |
|||
return (fb_vinfo.yres >> 3) - x - 1; |
|||
} |
|||
} |
|||
|
|||
static inline float yuv_y(int r, int g, int b) { |
|||
float rf = r/255.0f; |
|||
float gf = g/255.0f; |
|||
float bf = b/255.0f; |
|||
return 0.299f * r + 0.587f * g + 0.114f * b; |
|||
} |
|||
static inline float yuv_u(int r, int g, int b) { |
|||
float rf = r/255.0f; |
|||
float gf = g/255.0f; |
|||
float bf = b/255.0f; |
|||
return -0.147f * r - 0.289f * g + 0.436f * b; |
|||
} |
|||
static inline float yuv_v(int r, int g, int b) { |
|||
float rf = r/255.0f; |
|||
float gf = g/255.0f; |
|||
float bf = b/255.0f; |
|||
return 0.615f * r - 0.515f * g - 0.100f * b; |
|||
} |
|||
|
|||
static int l_set_palette (lua_State *L) { |
|||
int i = lua_tonumber(L, 1); |
|||
int pal = lua_tonumber(L, 2); |
|||
if(i >= 0 && i < 256) { |
|||
// calculate yuv
|
|||
int r = (pal >> 16) & 0xFF; |
|||
int g = (pal >> 8) & 0xFF; |
|||
int b = pal & 0xFF; |
|||
pal_yuv[i*3] = yuv_y(r, g, b); |
|||
pal_yuv[i*3+1] = yuv_u(r, g, b); |
|||
pal_yuv[i*3+2] = yuv_v(r, g, b); |
|||
// set palette color
|
|||
if (fb_bpp == 16) { |
|||
palette[i] = |
|||
((r & 0xF8) << 8) | |
|||
((g & 0xFC) << 3) | |
|||
((b & 0xF8) >> 3); |
|||
} else { |
|||
palette[i] = pal; |
|||
} |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
static int l_get_nearest (lua_State *L) { |
|||
int nck = 0; |
|||
float ncv = 1000000; |
|||
int i; |
|||
int col = lua_tonumber(L, 1); |
|||
int r = (col >> 16) & 0xFF; |
|||
int g = (col >> 8) & 0xFF; |
|||
int b = (col) & 0xFF; |
|||
float coly = yuv_y(r, g, b); |
|||
float colu = yuv_u(r, g, b); |
|||
float colv = yuv_v(r, g, b); |
|||
float dist,dy,du,dv; |
|||
for (i = 0; i < 256; i++) { |
|||
if (palette[i] == col) { |
|||
lua_pushnumber(L, i); |
|||
return 1; |
|||
} |
|||
dy = coly - pal_yuv[i*3]; |
|||
du = colu - pal_yuv[i*3+1]; |
|||
dv = colv - pal_yuv[i*3+2]; |
|||
dist = dy*dy + du*du + dv*dv; |
|||
if (dist < ncv) { |
|||
nck = i; |
|||
ncv = dist; |
|||
} |
|||
} |
|||
lua_pushnumber(L, nck); |
|||
return 1; |
|||
} |
|||
|
|||
static int fb_copy(int x, int y, int w, int h, int x2, int y2) { |
|||
int i, j; |
|||
char* tmp = (char*) malloc(w*h*fb_bypp); |
|||
|
|||
for (j = 0; j < h; j++) { |
|||
char* ptr = &fb_ptr[XY_TO_FB((x), ((y) + (j)))]; |
|||
memcpy(&tmp[w*j*fb_bypp], ptr, w*fb_bypp); |
|||
} |
|||
for (j = 0; j < h; j++) { |
|||
char* ptr = &fb_ptr[XY_TO_FB((x2), (y2 + (j)))]; |
|||
memcpy(ptr, &tmp[w*j*fb_bypp], w*fb_bypp); |
|||
} |
|||
|
|||
free(tmp); |
|||
} |
|||
|
|||
static inline int fb_draw_16(int x, int y, ushort bg, ushort fg, int chr, int cwd) { |
|||
int table[4]; |
|||
int px, py; |
|||
int c = 0; |
|||
|
|||
if (fb_rot > 0) { |
|||
short* ptr = (short*) &fb_ptr; |
|||
for (py = 0; py < 16; py++) { |
|||
if (cwd == 2) { |
|||
c = (res_unifont[chr * 33 + 2 + (py * 2)] << 8) | res_unifont[chr * 33 + 1 + (py * 2)]; |
|||
} else if (cwd == 1) { |
|||
c = res_unifont[chr * 33 + 1 + py]; |
|||
} |
|||
for (px = (cwd == 2 ? 15 : 7); px >= 0; px--) { |
|||
*((short*) &fb_ptr[XY_TO_FB( |
|||
fb_xrot((x * 8) + px, (y * 16) + py), |
|||
fb_yrot((x * 8) + px, (y * 16) + py) |
|||
)]) = (c & 1) ? fg : bg; |
|||
c >>= 1; |
|||
} |
|||
} |
|||
} else { |
|||
table[0] = bg << 16 | bg; |
|||
table[1] = fg << 16 | bg; |
|||
table[2] = bg << 16 | fg; |
|||
table[3] = fg << 16 | fg; |
|||
/* for (py = 0; py < 16; py++) {
|
|||
if (cwd == 2) { |
|||
c = (res_unifont[chr * 33 + 2 + (py * 2)] << 8) | res_unifont[chr * 33 + 1 + (py * 2)]; |
|||
} else if (cwd == 1) { |
|||
c = res_unifont[chr * 33 + 1 + py]; |
|||
} |
|||
ptr = (short*) (&fb_ptr[XY_TO_FB((x * 8), ((y * 16) + py))]); |
|||
for (px = (cwd == 2 ? 15 : 7); px >= 0; px--) { |
|||
ptr[px] = (c & 1) ? fg : bg; |
|||
c >>= 1; |
|||
} |
|||
} */ |
|||
int* ptr = (int*) (&fb_ptr[XY_TO_FB((x * 8), ((y * 16)))]); |
|||
for (py = 0; py < 16; py++) { |
|||
if (cwd == 2) { |
|||
c = (res_unifont[chr * 33 + 2 + (py * 2)] << 8) | res_unifont[chr * 33 + 1 + (py * 2)]; |
|||
ptr[7] = table[(c & 3)]; |
|||
c >>= 2; |
|||
ptr[6] = table[(c & 3)]; |
|||
c >>= 2; |
|||
ptr[5] = table[(c & 3)]; |
|||
c >>= 2; |
|||
ptr[4] = table[(c & 3)]; |
|||
c >>= 2; |
|||
ptr[3] = table[(c & 3)]; |
|||
c >>= 2; |
|||
ptr[2] = table[(c & 3)]; |
|||
c >>= 2; |
|||
ptr[1] = table[(c & 3)]; |
|||
c >>= 2; |
|||
ptr[0] = table[(c & 3)]; |
|||
c >>= 2; |
|||
} else if (cwd == 1) { |
|||
c = res_unifont[chr * 33 + 1 + py]; |
|||
ptr[3] = table[(c & 3)]; |
|||
c >>= 2; |
|||
ptr[2] = table[(c & 3)]; |
|||
c >>= 2; |
|||
ptr[1] = table[(c & 3)]; |
|||
c >>= 2; |
|||
ptr[0] = table[(c & 3)]; |
|||
c >>= 2; |
|||
} |
|||
ptr += fb_pitch >> 2; |
|||
} |
|||
} |
|||
} |
|||
|
|||
static inline int fb_draw_32(int x, int y, int bg, int fg, int chr, int cwd) { |
|||
int px, py; |
|||
int c = 0; |
|||
int* ptr; |
|||
if (fb_rot > 0) { |
|||
for (py = 0; py < 16; py++) { |
|||
if (cwd == 2) { |
|||
c = (res_unifont[chr * 33 + 2 + (py * 2)] << 8) | res_unifont[chr * 33 + 1 + (py * 2)]; |
|||
} else if (cwd == 1) { |
|||
c = res_unifont[chr * 33 + 1 + py]; |
|||
} |
|||
for (px = (cwd == 2 ? 15 : 7); px >= 0; px--) { |
|||
*((int*) &fb_ptr[XY_TO_FB( |
|||
fb_xrot((x * 8) + px, (y * 16) + py), |
|||
fb_yrot((x * 8) + px, (y * 16) + py) |
|||
)]) = (c & 1) ? fg : bg; |
|||
c >>= 1; |
|||
} |
|||
} |
|||
} else { |
|||
ptr = (int*) (&fb_ptr[XY_TO_FB((x * 8), ((y * 16) + py))]); |
|||
for (py = 0; py < 16; py++) { |
|||
if (cwd == 2) { |
|||
c = (res_unifont[chr * 33 + 2 + (py * 2)] << 8) | res_unifont[chr * 33 + 1 + (py * 2)]; |
|||
} else if (cwd == 1) { |
|||
c = res_unifont[chr * 33 + 1 + py]; |
|||
} |
|||
for (px = (cwd == 2 ? 15 : 7); px >= 0; px--) { |
|||
ptr[px] = (c & 1) ? fg : bg; |
|||
c >>= 1; |
|||
} |
|||
ptr += fb_pitch >> 2; |
|||
} |
|||
} |
|||
} |
|||
|
|||
static int fb_draw(int x, int y, int bg, int fg, int chr) { |
|||
if (x < 0 || x >= fb_cw || y < 0 || y >= fb_ch || bg < 0 || bg >= 256 || fg < 0 || fg >= 256 |
|||
|| chr < 0 || chr >= 65536) { |
|||
return 0; |
|||
} |
|||
|
|||
colbuf[XY_TO_COLBUF(x, y, 0)] = (char) bg; |
|||
colbuf[XY_TO_COLBUF(x, y, 1)] = (char) fg; |
|||
chrbuf[XY_TO_CHRBUF(x, y)] = (ushort) chr; |
|||
|
|||
int cwd = res_unifont[chr * 33]; |
|||
if (cwd == 2 && x < (fb_cw - 1)) { |
|||
chrbuf[XY_TO_CHRBUF(x + 1, y)] = (ushort) 0; |
|||
} |
|||
if (fb_bpp == 32) { |
|||
fb_draw_32(x,y,palette[bg],palette[fg],chr,cwd); |
|||
} else if (fb_bpp == 16) { |
|||
fb_draw_16(x,y,(ushort) palette[bg],(ushort) palette[fg],chr,cwd); |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
static int l_fbput (lua_State *L) { |
|||
int x = lua_tonumber(L, 1); |
|||
int y = lua_tonumber(L, 2); |
|||
int bg = lua_tonumber(L, 3); |
|||
int fg = lua_tonumber(L, 4); |
|||
int chr = lua_tonumber(L, 5); |
|||
return fb_draw(x, y, bg, fg, chr); |
|||
} |
|||
|
|||
static int l_fbcopy (lua_State *L) { |
|||
int x = lua_tonumber(L, 1); |
|||
int y = lua_tonumber(L, 2); |
|||
int w = lua_tonumber(L, 3); |
|||
int h = lua_tonumber(L, 4); |
|||
int tx = x+lua_tonumber(L, 5); |
|||
int ty = y+lua_tonumber(L, 6); |
|||
int j, px = x<<3, py = y<<4, pw = w<<3, ph = h<<4, ptx = tx<<3, pty = ty<<4; |
|||
|
|||
char* tmpcol = (char*) malloc(w*h*2); |
|||
char* tmpchr = (char*) malloc(w*h*2); |
|||
|
|||
if (fb_rot == 1 || fb_rot == 3) { |
|||
j = pw; |
|||
pw = ph; |
|||
ph = j; |
|||
} |
|||
j = fb_xrot(px, py); |
|||
py = fb_yrot(px, py); |
|||
px = j; |
|||
j = fb_xrot(ptx, pty); |
|||
pty = fb_yrot(ptx, pty); |
|||
ptx = j; |
|||
|
|||
if (fb_rot == 1 || fb_rot == 2) { |
|||
px -= pw-1; |
|||
ptx -= pw-1; |
|||
} |
|||
if (fb_rot == 3 || fb_rot == 2) { |
|||
py -= ph-1; |
|||
pty -= ph-1; |
|||
} |
|||
|
|||
for (j = 0; j < h; j++) { |
|||
memcpy(&tmpcol[j*w*2], &colbuf[XY_TO_COLBUF(x, y+j, 0)], w * 2); |
|||
memcpy(&tmpchr[j*w*2], &chrbuf[XY_TO_CHRBUF(x, y+j)], w * 2); |
|||
} |
|||
|
|||
fb_copy(px, py, pw, ph, ptx, pty); |
|||
|
|||
for (j = 0; j < h; j++) { |
|||
memcpy(&colbuf[XY_TO_COLBUF(tx, ty+j, 0)], &tmpcol[j*w*2], w * 2); |
|||
memcpy(&chrbuf[XY_TO_CHRBUF(tx, ty+j)], &tmpchr[j*w*2], w * 2); |
|||
} |
|||
|
|||
free(tmpcol); |
|||
free(tmpchr); |
|||
} |
|||
|
|||
static int l_fbfill (lua_State *L) { |
|||
int x1 = lua_tonumber(L, 1); |
|||
int y1 = lua_tonumber(L, 2); |
|||
int x2 = lua_tonumber(L, 3); |
|||
int y2 = lua_tonumber(L, 4); |
|||
int bg = lua_tonumber(L, 5); |
|||
int fg = lua_tonumber(L, 6); |
|||
int chr = lua_tonumber(L, 7); |
|||
int i, j; |
|||
for (i = y1; i <= y2; i++) { |
|||
for (j = x1; j <= x2; j++) { |
|||
fb_draw(j, i, bg, fg, chr); |
|||
} |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
static int l_get_width (lua_State *L) { |
|||
lua_pushnumber(L, fb_cw); |
|||
return 1; |
|||
} |
|||
|
|||
static int l_get_height (lua_State *L) { |
|||
lua_pushnumber(L, fb_ch); |
|||
return 1; |
|||
} |
|||
|
|||
static int l_fb_ready (lua_State *L) { |
|||
lua_pushboolean(L, fb_ready); |
|||
return 1; |
|||
} |
|||
|
|||
static int l_fb_getbg (lua_State *L) { |
|||
int x = lua_tonumber(L, 1); |
|||
int y = lua_tonumber(L, 2); |
|||
if (x >= 0 && y >= 0 && x < fb_cw && y < fb_ch) { |
|||
lua_pushnumber(L, colbuf[XY_TO_COLBUF(x, y, 0)]); |
|||
} else { |
|||
lua_pushnumber(L, 0); |
|||
} |
|||
return 1; |
|||
} |
|||
|
|||
static int l_fb_getfg (lua_State *L) { |
|||
int x = lua_tonumber(L, 1); |
|||
int y = lua_tonumber(L, 2); |
|||
if (x >= 0 && y >= 0 && x < fb_cw && y < fb_ch) { |
|||
lua_pushnumber(L, colbuf[XY_TO_COLBUF(x, y, 1)]); |
|||
} else { |
|||
lua_pushnumber(L, 0); |
|||
} |
|||
return 1; |
|||
} |
|||
|
|||
static int l_fb_get (lua_State *L) { |
|||
int x = lua_tonumber(L, 1); |
|||
int y = lua_tonumber(L, 2); |
|||
if (x >= 0 && y >= 0 && x < fb_cw && y < fb_ch) { |
|||
lua_pushnumber(L, chrbuf[XY_TO_CHRBUF(x, y)]); |
|||
} else { |
|||
lua_pushnumber(L, 0); |
|||
} |
|||
return 1; |
|||
} |
|||
|
|||
void fb_start(lua_State *L) { |
|||
fb_file = open("/dev/fb0", O_RDWR); |
|||
if (fb_file == -1) { |
|||
printf("Error: cannot open framebuffer device"); |
|||
exit(1); |
|||
return; |
|||
} |
|||
|
|||
if (ioctl(fb_file, FBIOGET_FSCREENINFO, &fb_finfo) == -1) { |
|||
printf("Error reading fixed information"); |
|||
exit(1); |
|||
return; |
|||
} |
|||
|
|||
if (ioctl(fb_file, FBIOGET_VSCREENINFO, &fb_vinfo) == -1) { |
|||
printf("Error reading variable information"); |
|||
exit(1); |
|||
return; |
|||
} |
|||
|
|||
fb_vinfo.bits_per_pixel = 16; |
|||
if (fb_rot == 1 || fb_rot == 3) { |
|||
fb_cw = fb_vinfo.yres / 8; |
|||
fb_ch = fb_vinfo.xres / 16; |
|||
} else { |
|||
fb_cw = fb_vinfo.xres / 8; |
|||
fb_ch = fb_vinfo.yres / 16; |
|||
} |
|||
if (ioctl(fb_file, FBIOPUT_VSCREENINFO, &fb_vinfo) == -1) { |
|||
fb_vinfo.bits_per_pixel = 32; |
|||
if (ioctl(fb_file, FBIOPUT_VSCREENINFO, &fb_vinfo) == -1) { |
|||
printf("Error setting 32 or 16BPP mode"); |
|||
exit(1); |
|||
return; |
|||
} |
|||
} |
|||
|
|||
fb_bpp = fb_vinfo.bits_per_pixel; |
|||
fb_bypp = fb_bpp >> 3; |
|||
fb_pitch = fb_vinfo.xres_virtual * fb_bypp; |
|||
fb_xo = fb_vinfo.xoffset; |
|||
fb_yo = fb_vinfo.yoffset; |
|||
|
|||
fb_ptr = (char *)mmap(0, fb_vinfo.xres * fb_vinfo.yres * fb_bypp, PROT_READ | PROT_WRITE, MAP_SHARED, fb_file, 0); |
|||
if ((intptr_t)fb_ptr == -1) { |
|||
printf("Failed to map framebuffer device to memory"); |
|||
exit(1); |
|||
return; |
|||
} |
|||
|
|||
colbuf = (char *)malloc(2 * fb_cw * fb_ch); |
|||
chrbuf = (ushort *)malloc(2 * fb_cw * fb_ch); |
|||
|
|||
fb_ready = 1; |
|||
|
|||
struct luaL_Reg fblib[] = { |
|||
{"setPalette", l_set_palette}, |
|||
{"getWidth", l_get_width}, |
|||
{"getHeight", l_get_height}, |
|||
{"put", l_fbput}, |
|||
{"copy", l_fbcopy}, |
|||
{"fill", l_fbfill}, |
|||
{"isReady", l_fb_ready}, |
|||
{"getBackground", l_fb_getbg}, |
|||
{"getForeground", l_fb_getfg}, |
|||
{"get", l_fb_get}, |
|||
{"getNearest", l_get_nearest}, |
|||
{NULL, NULL} |
|||
}; |
|||
|
|||
luaL_openlib(L, "framebuffer", fblib, 0); |
|||
} |
@ -0,0 +1,171 @@ |
|||
local fbgpu = {} |
|||
|
|||
local mapping = {} |
|||
|
|||
for i=0,15 do |
|||
mapping[i] = (i * 15) << 16 | (i * 15) << 8 | (i * 15) |
|||
end |
|||
|
|||
for i=0,239 do |
|||
local b = math.floor((i % 5) * 255 / 4.0) |
|||
local g = math.floor((math.floor(i / 5.0) % 8) * 255 / 7.0) |
|||
local r = math.floor((math.floor(i / 40.0) % 6) * 255 / 5.0) |
|||
mapping[16+i] = r << 16 | g << 8 | b |
|||
end |
|||
|
|||
--[[local nw = io.write |
|||
io.write = function(...) |
|||
nw(...) |
|||
io.flush() |
|||
native.sleep(20000) |
|||
end]]-- |
|||
|
|||
local fb = framebuffer |
|||
local write = io.write |
|||
local flush = io.flush |
|||
|
|||
for k,v in pairs(mapping) do |
|||
fb.setPalette(k, v) |
|||
end |
|||
|
|||
local background = 0 |
|||
local foreground = 0 |
|||
|
|||
local usub |
|||
|
|||
function fbgpu.start() |
|||
usub = modules.sandbox.unicode.sub |
|||
local gpu = {} |
|||
function gpu.bind() return false, "This is static bound gpu" end |
|||
function gpu.getScreen() return "n/a" end |
|||
function gpu.setBackground(color, isPaletteIndex) |
|||
checkArg(1, color, "number") |
|||
checkArg(2, isPaletteIndex, "boolean", "nil") |
|||
if isPaletteIndex and color >= 0 and color < 256 then |
|||
background = color |
|||
return mapping[color] |
|||
end |
|||
local old = background |
|||
background = fb.getNearest(color) |
|||
return mapping[old] |
|||
end |
|||
function gpu.setForeground(color, isPaletteIndex) |
|||
checkArg(1, color, "number") |
|||
checkArg(2, isPaletteIndex, "boolean", "nil") |
|||
if isPaletteIndex and color >= 0 and color < 256 then |
|||
foreground = color |
|||
return mapping[color] |
|||
end |
|||
local old = foreground |
|||
foreground = fb.getNearest(color) |
|||
return mapping[old] |
|||
end |
|||
function gpu.getBackground() |
|||
return mapping[background], false |
|||
end |
|||
function gpu.getForeground() |
|||
return mapping[foreground], false |
|||
end |
|||
function gpu.getPaletteColor() |
|||
return nil |
|||
end |
|||
function gpu.setPaletteColor(index, value) |
|||
checkArg(1, index, "number") |
|||
checkArg(2, value, "number") |
|||
fb.setPalette(index, value) |
|||
return value |
|||
end |
|||
function gpu.maxDepth() |
|||
return 8 |
|||
end |
|||
function gpu.setDepth() |
|||
return false |
|||
end |
|||
function gpu.getDepth() |
|||
return 8 |
|||
end |
|||
function gpu.maxResolution() |
|||
return fb.getWidth(), fb.getHeight() |
|||
end |
|||
function gpu.getResolution() |
|||
return fb.getWidth(), fb.getHeight() |
|||
end |
|||
function gpu.getViewport() |
|||
return termutils.getSize() |
|||
end |
|||
function gpu.setViewport(w, h) |
|||
checkArg(1, w, "number") |
|||
checkArg(2, h, "number") |
|||
return false, "Viewport not supported for this gpu" |
|||
end |
|||
function gpu.setResolution(w, h) |
|||
checkArg(1, w, "number") |
|||
checkArg(2, h, "number") |
|||
return false, "Non resizeable gpu" |
|||
end |
|||
function gpu.get(x, y) |
|||
checkArg(1, x, "number") |
|||
checkArg(2, y, "number") |
|||
return utf8.char(fb.get(x-1, y-1)) |
|||
end |
|||
function gpu.set(x, y, value, vertical) |
|||
checkArg(1, x, "number") |
|||
checkArg(2, y, "number") |
|||
checkArg(3, value, "string") |
|||
checkArg(4, vertical, "boolean", "nil") |
|||
x = math.floor(x) |
|||
y = math.floor(y) |
|||
if not vertical then |
|||
local i = 0 |
|||
value:gsub(".", function(c) |
|||
fb.put(x+i-1, y-1, background, foreground, utf8.codepoint(c)) |
|||
i = i+1 |
|||
end) |
|||
else |
|||
local i = 0 |
|||
value:gsub(".", function(c) |
|||
fb.put(x-1, y+i-1, background, foreground, utf8.codepoint(c)) |
|||
i = i+1 |
|||
end) |
|||
end |
|||
flush() |
|||
return true |
|||
end |
|||
function gpu.copy(x, y, w, h, tx, ty) --TODO: Check(check X multiple times) |
|||
checkArg(1, x, "number") |
|||
checkArg(2, y, "number") |
|||
checkArg(3, w, "number") |
|||
checkArg(4, h, "number") |
|||
checkArg(5, tx, "number") |
|||
checkArg(6, ty, "number") |
|||
fb.copy(x-1, y-1, w, h, tx, ty); |
|||
return true |
|||
end |
|||
function gpu.fill(x, y, w, h, ch) |
|||
checkArg(1, x, "number") |
|||
checkArg(2, y, "number") |
|||
checkArg(3, w, "number") |
|||
checkArg(4, h, "number") |
|||
checkArg(5, ch, "string") |
|||
ch = ch:sub(1, 1) |
|||
fb.fill(x-1, y-1, x+w-2, y+h-2, background, foreground, utf8.codepoint(ch)) |
|||
return true |
|||
end |
|||
|
|||
local w, h = gpu.getResolution() |
|||
gpu.setForeground(0xFFFFFF) |
|||
gpu.setBackground(0x000000) |
|||
|
|||
termutils.init() |
|||
write("\x1b[?25l") --Disable cursor |
|||
|
|||
modules.component.api.register(nil, "gpu", gpu) |
|||
modules.component.api.register(nil, "screen", {getKeyboards = function() return {"TODO:SetThisUuid"} end}) --verry dummy screen, TODO: make it better, kbd uuid also in epoll.c |
|||
modules.component.api.register("TODO:SetThisUuid", "keyboard", {}) |
|||
|
|||
deadhooks[#deadhooks + 1] = function() |
|||
write("\x1b[?25h") --Enable cursor on quit |
|||
end |
|||
end |
|||
|
|||
return fbgpu |
Loading…
issues.context.reference_issue