From f51278b094bdd1c27e922a593833cae088507c3f Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Wed, 15 Feb 2017 00:31:26 +0100 Subject: [PATCH] tuxtxt: convert to int-pointer arithmetic, work with all framebuffers This converts the drawing code from byte-pointer to fb_pixel_t-pointer arithmetic, making the calculations more obvious and probably more efficient. Additionally, the color tables are now generated in a way that it should work regardless of the frame buffer color format. Allows to remove a few hardware specific #ifdefs. --- lib/libtuxtxt/tuxtxt.cpp | 199 +++++++++++++++++---------------------- lib/libtuxtxt/tuxtxt.h | 34 +------ 2 files changed, 93 insertions(+), 140 deletions(-) diff --git a/lib/libtuxtxt/tuxtxt.cpp b/lib/libtuxtxt/tuxtxt.cpp index c6f5f4ce9..dc7d5a7c5 100644 --- a/lib/libtuxtxt/tuxtxt.cpp +++ b/lib/libtuxtxt/tuxtxt.cpp @@ -49,7 +49,7 @@ static int screen_x, screen_y, screen_w, screen_h; //#define USE_FBPAN // FBIOPAN_DISPLAY seems to be working in current driver -unsigned char *getFBp(int *y) +fb_pixel_t *getFBp(int *y) { if (*y < (int)var_screeninfo.yres) return lfb; @@ -60,20 +60,15 @@ unsigned char *getFBp(int *y) void FillRect(int x, int y, int w, int h, int color) { - unsigned char *p = getFBp(&y); + fb_pixel_t *p = getFBp(&y); MARK_FB(x, y, w, h); - p += x*4 + y * fix_screeninfo.line_length; -#if !HAVE_TRIPLEDRAGON - unsigned int col = bgra[color][3] << 24 | bgra[color][2] << 16 | bgra[color][1] << 8 | bgra[color][0]; -#else - unsigned int col = *((unsigned int*)bgra[color]); -#endif + p += x + y * stride; if (w > 0) for (int count = 0; count < h; count++) { - unsigned int * dest0 = (unsigned int *)p; + fb_pixel_t *dest0 = p; for (int i = 0; i < w; i++) - *(dest0++) = col; - p += fix_screeninfo.line_length; + *(dest0++) = bgra[color]; + p += stride; } } @@ -319,25 +314,14 @@ void setfontwidth(int newwidth) } } -#if HAVE_TRIPLEDRAGON -#define _A 0 -#define _R 1 -#define _G 2 -#define _B 3 -#else -#define _A 3 -#define _R 2 -#define _G 1 -#define _B 0 -#endif void setcolors(unsigned short *pcolormap, int offset, int number) { - int i,trans_tmp; + int i,trans_tmp,tr; int j = offset; /* index in global color table */ - - trans_tmp=25-trans_mode; - - bgra[transp2][_A]=((trans_tmp+7)<<11 | 0x7FF)>>8; + int R = var_screeninfo.red.offset; + int G = var_screeninfo.green.offset; + int B = var_screeninfo.blue.offset; + int A = var_screeninfo.transp.offset; for (i = 0; i < number; i++) { @@ -348,13 +332,17 @@ void setcolors(unsigned short *pcolormap, int offset, int number) r = (r * (0x3f+(color_mode<<3))) >> 8; g = (g * (0x3f+(color_mode<<3))) >> 8; b = (b * (0x3f+(color_mode<<3))) >> 8; - - bgra[j][_R]=r; - bgra[j][_G]=g; - bgra[j][_B]=b; - + bgra[j] = (r << R) | (g << G) | (b << B) | (0xff << A); j++; } + trans_tmp=25-trans_mode; + tr = ((trans_tmp+7)<<11 | 0x7FF)>>8; + bgra[transp2] &= ~(0xff << A); /* clear alpha */ + bgra[transp2] |= tr << A; + bgra[menu3] &= ~(0xff << A); + bgra[menu3] |= 0xc0 << A; + bgra[transp] &= ~(0xff << A); + bgra[transp] |= 0; } /* hexdump of page contents to stdout for debugging */ @@ -1666,8 +1654,8 @@ int tuxtx_main(int /*_rc*/, int pid, int page, int source) #endif CFrameBuffer *fbp = CFrameBuffer::getInstance(); - lfb = (unsigned char *)fbp->getFrameBufferPointer(); - lbb = (unsigned char *)fbp->getBackBufferPointer(); + lfb = fbp->getFrameBufferPointer(); + lbb = fbp->getBackBufferPointer(); tuxtxt_cache.vtxtpid = pid; @@ -1693,6 +1681,8 @@ int tuxtx_main(int /*_rc*/, int pid, int page, int source) #else struct fb_var_screeninfo *var; var = fbp->getScreenInfo(); + /* this is actually the length of the screen in pixels */ + stride = fbp->getStride() / sizeof(fb_pixel_t); memcpy(&var_screeninfo, var, sizeof(struct fb_var_screeninfo)); fix_screeninfo.line_length = var_screeninfo.xres * sizeof(fb_pixel_t); #endif @@ -4117,7 +4107,7 @@ void SwitchHintMode() void RenderDRCS( //FIX ME unsigned char *s, /* pointer to char data, parity undecoded */ - unsigned char *d, /* pointer to frame buffer of top left pixel */ + fb_pixel_t *d, /* pointer to frame buffer of top left pixel */ unsigned char *ax, /* array[0..12] of x-offsets, array[0..10] of y-offsets for each pixel */ unsigned char fgcolor, unsigned char bgcolor) { @@ -4149,52 +4139,45 @@ void RenderDRCS( //FIX ME { // memset(d + ax[x], f1, ax[x+1] - ax[x]); for (ltmp=0 ; ltmp <= (ax[x+1]-ax[x]); ltmp++) - { - memmove(d + ax[x]*4 +ltmp*4,bgra[f1],4); - } + *(d + ax[x] + ltmp) = bgra[f1]; } if (ax[x+7] > ax[x+6]) { // memset(d + ax[x+6], f2, ax[x+7] - ax[x+6]); /* 2nd byte 6 pixels to the right */ for (ltmp=0 ; ltmp <= (ax[x+7]-ax[x+6]); ltmp++) - { - memmove(d + ax[x+6]*4 +ltmp*4,bgra[f2],4); - } - + *(d + ax[x+6] + ltmp) = bgra[f2]; } - d += fix_screeninfo.line_length; + d += stride; } - d -= h * fix_screeninfo.line_length; + d -= h * stride; } - d += h * fix_screeninfo.line_length; + d += h * stride; } } void DrawVLine(int x, int y, int l, int color) { - unsigned char *p = getFBp(&y); + fb_pixel_t *p = getFBp(&y); MARK_FB(x, y, 0, l); - p += x*4 + y * fix_screeninfo.line_length; + p += x + y * stride; for ( ; l > 0 ; l--) { - memmove(p,bgra[color],4); - p += fix_screeninfo.line_length; + *p = bgra[color]; + p += stride; } } void DrawHLine(int x, int y, int l, int color) { int ltmp; - unsigned char *p = getFBp(&y); + fb_pixel_t *p = getFBp(&y); MARK_FB(x, y, l, 0); if (l > 0) { for (ltmp=0; ltmp <= l; ltmp++) - { - memmove(p + x*4 + ltmp*4 + y * fix_screeninfo.line_length, bgra[color], 4); - } + *(p + x + ltmp + y * stride) = bgra[color]; } } @@ -4209,9 +4192,9 @@ void FillRectMosaicSeparated(int x, int y, int w, int h, int fgcolor, int bgcolo void FillTrapez(int x0, int y0, int l0, int xoffset1, int h, int l1, int color) { - unsigned char *p = getFBp(&y0); + fb_pixel_t *p = getFBp(&y0); MARK_FB(x0, y0, l0, h); - p += x0 * 4 + y0 * fix_screeninfo.line_length; + p += x0 + y0 * stride; int xoffset, l; int yoffset; @@ -4224,19 +4207,17 @@ void FillTrapez(int x0, int y0, int l0, int xoffset1, int h, int l1, int color) if (l > 0) { for (ltmp=0; ltmp <= l; ltmp++) - { - memmove(p + xoffset*4 +ltmp*4, bgra[color], 4); - } + *(p + xoffset + ltmp) = bgra[color]; } - p += fix_screeninfo.line_length; + p += stride; } } void FlipHorz(int x, int y, int w, int h) { unsigned char *buf= new unsigned char[w*4]; - unsigned char *p = getFBp(&y); + fb_pixel_t *p = getFBp(&y); MARK_FB(x, y, w, h); - p += x * 4 + y * fix_screeninfo.line_length; + p += x + y * stride; int w1,h1; if(buf != NULL){ @@ -4245,9 +4226,9 @@ void FlipHorz(int x, int y, int w, int h) memmove(buf,p,w*4); for (w1 = 0 ; w1 < w ; w1++) { - memmove(p+w1*4,buf+((w-w1)*4)-4,4); + memmove(p + w1,buf+((w-w1)*4)-4,4); } - p += fix_screeninfo.line_length; + p += stride; } delete [] buf; } @@ -4255,17 +4236,17 @@ void FlipHorz(int x, int y, int w, int h) void FlipVert(int x, int y, int w, int h) { unsigned char *buf= new unsigned char[w*4]; - unsigned char *p1, *p2; - unsigned char *p = getFBp(&y); + fb_pixel_t *p1, *p2; + fb_pixel_t *p = getFBp(&y); MARK_FB(x, y, w, h); - p += x*4 + y * fix_screeninfo.line_length; + p += x + y * stride; int h1; if(buf != NULL){ for (h1 = 0 ; h1 < h/2 ; h1++) { - p1 = (p+(h1*fix_screeninfo.line_length)); - p2 = (p+(h-(h1+1))*fix_screeninfo.line_length); + p1 = (p + (h1 * stride)); + p2 = (p + (h - (h1 + 1)) * stride); memmove(buf,p1,w*4); memmove(p1,p2,w*4); memmove(p2,buf,w*4); @@ -4521,9 +4502,9 @@ void RenderChar(int Char, tstPageAttr *Attribute, int zoom, int yoffset) { int x,y,f,c; y = yoffset; - unsigned char *p = getFBp(&y); + fb_pixel_t *p = getFBp(&y); MARK_FB(PosX, PosY, curfontwidth, fontheight); - p += PosX * 4 + PosY * fix_screeninfo.line_length; + p += PosX + PosY * stride; for (y=0; ytop + TTFShiftY); @@ -4848,18 +4829,18 @@ void RenderChar(int Char, tstPageAttr *Attribute, int zoom, int yoffset) int y = yoffset; p = getFBp(&y); - p += PosX * 4 + (PosY + Row) * fix_screeninfo.line_length; /* running pointer into framebuffer */ + p += PosX + (PosY + Row) * stride; /* running pointer into framebuffer */ for (Row = sbit->height; Row; Row--) /* row counts up, but down may be a little faster :) */ { int pixtodo = (usettf ? sbit->width : curfontwidth); - char *pstart = (char*) p; + fb_pixel_t *pstart = p; for (Bit = xfactor * (sbit->left + TTFShiftX); Bit > 0; Bit--) /* fill left margin */ { for (f = factor-1; f >= 0; f--) - memmove((p + f*fix_screeninfo.line_length),bgra[bgcolor],4);/*bgcolor*/ - p+=4; + *(p + f * stride) = bgra[bgcolor]; + p++; if (!usettf) pixtodo--; } @@ -4879,14 +4860,14 @@ void RenderChar(int Char, tstPageAttr *Attribute, int zoom, int yoffset) color = bgcolor; for (f = factor-1; f >= 0; f--) - memmove((p + f*fix_screeninfo.line_length),bgra[color],4); - p+=4; + *(p + f * stride) = bgra[color]; + p++; if (xfactor > 1) /* double width */ { for (f = factor-1; f >= 0; f--) - memmove((p + f*fix_screeninfo.line_length),bgra[color],4); - p+=4; + *(p + f * stride) = bgra[color]; + p++; if (!usettf) pixtodo--; @@ -4898,11 +4879,11 @@ void RenderChar(int Char, tstPageAttr *Attribute, int zoom, int yoffset) Bit > 0; Bit--) /* fill rest of char width */ { for (f = factor-1; f >= 0; f--) - memmove((p + f*fix_screeninfo.line_length),bgra[bgcolor],4); - p+=4; + *(p + f * stride) = bgra[bgcolor]; + p++; } - p = (unsigned char*) pstart + factor*fix_screeninfo.line_length; + p = pstart + factor * stride; } Row = ascender - sbit->top + sbit->height + TTFShiftY; @@ -5612,7 +5593,7 @@ void CreateLine25() void CopyBB2FB() { - unsigned char *src, *dst, *topsrc; + fb_pixel_t *src, *dst, *topsrc; int fillcolor, i, screenwidth, swtmp; #ifdef HAVE_SPARK_HARDWARE CFrameBuffer *f = CFrameBuffer::getInstance(); @@ -5658,8 +5639,8 @@ void CopyBB2FB() return; } - src = topsrc = lbb + StartY * fix_screeninfo.line_length; - dst = lfb + StartY * fix_screeninfo.line_length; + src = topsrc = lbb + StartY * stride; + dst = lfb + StartY * stride; #ifdef USE_FBPAN #error USE_FBPAN code is not working right now. @@ -5673,7 +5654,7 @@ void CopyBB2FB() #endif /* copy line25 in normal height */ if (!pagecatching ) - memmove(dst+(24*fontheight)*fix_screeninfo.line_length, src + (24*fontheight)*fix_screeninfo.line_length, fix_screeninfo.line_length*fontheight); + memmove(dst + (24 * fontheight) * stride, src + (24 * fontheight) * stride, stride * fontheight); if (transpmode) fillcolor = transp; @@ -5681,12 +5662,12 @@ void CopyBB2FB() fillcolor = FullScrColor; if (zoommode == 2) - src += 12*fontheight*fix_screeninfo.line_length; + src += 12 * fontheight * stride; /* copy topmenu in normal height (since PIG also keeps dimensions) */ if (screenmode == 1) { - screenwidth = ( TV43STARTX ) * 4; + screenwidth = ( TV43STARTX ); #ifdef HAVE_SPARK_HARDWARE int cx = var_screeninfo.xres - TV43STARTX; /* x start */ int cw = TV43STARTX; /* width */ @@ -5694,47 +5675,43 @@ void CopyBB2FB() int ch = 24*fontheight; f->blit2FB(lbb, cw, ch, cx, cy, cx, cy, true); #else - unsigned char *topdst = dst; - size_t width = ex * sizeof(fb_pixel_t) - screenwidth; + fb_pixel_t *topdst = dst; + size_t width = (ex - screenwidth) * sizeof(fb_pixel_t); topsrc += screenwidth; topdst += screenwidth; for (i=0; i < 24*fontheight; i++) { memmove(topdst, topsrc, width); - topdst += fix_screeninfo.line_length; - topsrc += fix_screeninfo.line_length; + topdst += stride; + topsrc += stride; } #endif } else if (screenmode == 2) - screenwidth = ( TV169FULLSTARTX ) * 4; + screenwidth = ( TV169FULLSTARTX ); else - screenwidth = fix_screeninfo.line_length;//var_screeninfo.xres; + screenwidth = stride; for (i = StartY; i>0;i--) { for (swtmp=0; swtmp<=screenwidth; swtmp++) - { - memmove(dst - i*fix_screeninfo.line_length+swtmp*4, bgra[fillcolor], 4); - } + *(dst - i * stride + swtmp) = bgra[fillcolor]; } for (i = 12*fontheight; i; i--) { - memmove(dst, src, screenwidth); - dst += fix_screeninfo.line_length; - memmove(dst, src, screenwidth); - dst += fix_screeninfo.line_length; - src += fix_screeninfo.line_length; + memmove(dst, src, screenwidth * sizeof(fb_pixel_t)); + dst += stride; + memmove(dst, src, screenwidth * sizeof(fb_pixel_t)); + dst += stride; + src += stride; } for (i = var_screeninfo.yres - StartY - 25*fontheight; i >= 0;i--) { for (swtmp=0; swtmp<= screenwidth;swtmp++) - { - memmove(dst + fix_screeninfo.line_length*(fontheight+i)+swtmp*4, bgra[fillcolor], 4); - } + *(dst + stride * (fontheight + i) + swtmp) = bgra[fillcolor]; } #ifdef HAVE_SPARK_HARDWARE f->mark(0, 0, var_screeninfo.xres, var_screeninfo.yres); @@ -6056,8 +6033,8 @@ void DecodePage() RenderDRCS( page_char + 20 * (DRCSCOLS * row + col + 2), lfb - + (StartY + fontheight + DRCSYSPC * row + var_screeninfo.yres - var_screeninfo.yoffset) * fix_screeninfo.line_length - + (StartX + DRCSXSPC * col)*4, + + (StartY + fontheight + DRCSYSPC * row + var_screeninfo.yres - var_screeninfo.yoffset) * stride + + (StartX + DRCSXSPC * col), ax, white, black); memset(page_char + 40, 0xff, 24*40); /* don't render any char below row 0 */ diff --git a/lib/libtuxtxt/tuxtxt.h b/lib/libtuxtxt/tuxtxt.h index 1a6974c86..b347d6420 100644 --- a/lib/libtuxtxt/tuxtxt.h +++ b/lib/libtuxtxt/tuxtxt.h @@ -247,10 +247,11 @@ const char *ObjectType[] = #define NoServicesFound 3 /* framebuffer stuff */ -static unsigned char *lfb = 0; -static unsigned char *lbb = 0; +static fb_pixel_t *lfb = 0; +static fb_pixel_t *lbb = 0; struct fb_var_screeninfo var_screeninfo; struct fb_fix_screeninfo fix_screeninfo; +int stride; /* freetype stuff */ FT_Library library; @@ -1248,33 +1249,8 @@ const unsigned short defaultcolors[] = /* 0x0bgr */ 0x420, 0x210, 0x420, 0x000, 0x000 }; -#if !HAVE_TRIPLEDRAGON -/* 32bit colortable */ -unsigned char bgra[][5] = { -"\0\0\0\xFF", "\0\0\0\xFF", "\0\0\0\xFF", "\0\0\0\xFF", -"\0\0\0\xFF", "\0\0\0\xFF", "\0\0\0\xFF", "\0\0\0\xFF", -"\0\0\0\xFF", "\0\0\0\xFF", "\0\0\0\xFF", "\0\0\0\xFF", -"\0\0\0\xFF", "\0\0\0\xFF", "\0\0\0\xFF", "\0\0\0\xFF", -"\0\0\0\xFF", "\0\0\0\xFF", "\0\0\0\xFF", "\0\0\0\xFF", -"\0\0\0\xFF", "\0\0\0\xFF", "\0\0\0\xFF", "\0\0\0\xFF", -"\0\0\0\xFF", "\0\0\0\xFF", "\0\0\0\xFF", "\0\0\0\xFF", -"\0\0\0\xFF", "\0\0\0\xFF", "\0\0\0\xFF", "\0\0\0\xFF", -"\0\0\0\xFF", "\0\0\0\xFF", "\0\0\0\xC0", "\0\0\0\x00", -"\0\0\0\x33" }; -#else -/* actually "ARGB" */ -unsigned char bgra[][5] = { -"\xFF\0\0\0", "\xFF\0\0\0", "\xFF\0\0\0", "\xFF\0\0\0", -"\xFF\0\0\0", "\xFF\0\0\0", "\xFF\0\0\0", "\xFF\0\0\0", -"\xFF\0\0\0", "\xFF\0\0\0", "\xFF\0\0\0", "\xFF\0\0\0", -"\xFF\0\0\0", "\xFF\0\0\0", "\xFF\0\0\0", "\xFF\0\0\0", -"\xFF\0\0\0", "\xFF\0\0\0", "\xFF\0\0\0", "\xFF\0\0\0", -"\xFF\0\0\0", "\xFF\0\0\0", "\xFF\0\0\0", "\xFF\0\0\0", -"\xFF\0\0\0", "\xFF\0\0\0", "\xFF\0\0\0", "\xFF\0\0\0", -"\xFF\0\0\0", "\xFF\0\0\0", "\xFF\0\0\0", "\xFF\0\0\0", -"\xFF\0\0\0", "\xFF\0\0\0", "\xC0\0\0\0", "\x00\0\0\0", -"\x33\0\0\0" }; -#endif +/* filled in setcolors() */ +fb_pixel_t bgra[SIZECOLTABLE]; /* old 8bit color table */ unsigned short rd0[] = {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0x00<<8, 0x00<<8, 0x00<<8, 0, 0 };