From a15458317af273608410708d14fbeac03314f31c Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Sun, 26 Mar 2006 16:02:33 +0000 Subject: [PATCH] Portability --- Makefile | 3 +- box.cc | 12 +- box.h | 9 +- colour.h | 5 + defines.h | 28 ++-- main.cc | 1 - osdmvp.cc | 4 +- osdmvp.h | 2 +- player.cc | 18 +-- surface.cc | 420 +----------------------------------------------- surface.h | 206 +++--------------------- surfacemvp.cc | 437 ++++++++++++++++++++++++++++++++++++++++++++++++++ surfacemvp.h | 214 ++++++++++++++++++++++++ surfacewin.cc | 75 +++++++++ surfacewin.h | 51 ++++++ vepg.cc | 30 ++-- view.cc | 2 +- viewman.cc | 7 - viewman.h | 1 - 19 files changed, 862 insertions(+), 663 deletions(-) create mode 100644 surfacemvp.cc create mode 100644 surfacemvp.h create mode 100644 surfacewin.cc create mode 100644 surfacewin.h diff --git a/Makefile b/Makefile index 3b5bc3b..c4e1414 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,8 @@ OBJECTS1 = main.o command.o log.o tcp.o dsock.o thread.o timers.o i18n.o OBJECTS2 = remote.o led.o mtd.o video.o audio.o osd.o surface.o \ audiomvp.o audiowin.o \ videomvp.o videowin.o \ - osdmvp.o osdwin.o + osdmvp.o osdwin.o \ + surfacemvp.o surfacewin.o OBJECTS = $(OBJECTS1) $(OBJECTS2) diff --git a/box.cc b/box.cc index 9c8120b..f4e590a 100644 --- a/box.cc +++ b/box.cc @@ -187,29 +187,29 @@ void Box::drawPara(char* text, int x, int y, Colour& colour) // Level 0 drawing functions -void Box::rectangle(int x1, int y1, int w, int h, Colour& colour) +void Box::rectangle(int x1, int y1, int w, int h, Colour colour) { - surface->fillblt(offsetX + x1, offsetY + y1, w, h, surface->rgba(colour.red, colour.green, colour.blue, colour.alpha)); + surface->fillblt(offsetX + x1, offsetY + y1, w, h, colour.rgba()); } void Box::rectangle(Region& region, Colour& colour) { - surface->fillblt(offsetX + region.x, offsetY + region.y, region.w, region.h, surface->rgba(colour.red, colour.green, colour.blue, colour.alpha)); + surface->fillblt(offsetX + region.x, offsetY + region.y, region.w, region.h, colour.rgba()); } void Box::drawText(char* text, int x, int y, Colour& colour) { - surface->drawText(text, offsetX + x, offsetY + y, colour.red, colour.green, colour.blue); + surface->drawText(text, offsetX + x, offsetY + y, colour.rgba()); } void Box::drawTextRJ(char* text, int x, int y, Colour& colour) { - surface->drawTextRJ(text, offsetX + x, offsetY + y, colour.red, colour.green, colour.blue); + surface->drawTextRJ(text, offsetX + x, offsetY + y, colour.rgba()); } void Box::drawTextCentre(char* text, int x, int y, Colour& colour) { - surface->drawTextCentre(text, offsetX + x, offsetY + y, colour.red, colour.green, colour.blue); + surface->drawTextCentre(text, offsetX + x, offsetY + y, colour.rgba()); } void Box::drawPixel(UINT x, UINT y, Colour& colour) diff --git a/box.h b/box.h index 06de500..839e352 100644 --- a/box.h +++ b/box.h @@ -25,9 +25,14 @@ #include "log.h" #include "colour.h" -#include "surface.h" #include "region.h" +#ifdef WIN32 +#include "surfacewin.h" +#else +#include "surfacemvp.h" +#endif + // Abstract ??????? class Box { @@ -48,7 +53,7 @@ class Box void drawPara(char* text, int x, int y, Colour& colour); // Drawing functions level 0 - void rectangle(int x1, int y1, int w, int h, Colour& colour); + void rectangle(int x, int y, int w, int h, Colour colour); // FIXME make this ref again void rectangle(Region& region, Colour& colour); void drawText(char* text, int x, int y, Colour& colour); diff --git a/colour.h b/colour.h index 9067e2a..34b860f 100644 --- a/colour.h +++ b/colour.h @@ -39,6 +39,11 @@ class Colour void set(int Tred, int Tgreen, int Tblue, int Talpha) { red = Tred; green = Tgreen; blue = Tblue; alpha = Talpha; } + unsigned long rgba() + { + return (alpha << 24) | (red << 16) | (green << 8) | blue; + } + int red; int green; int blue; diff --git a/defines.h b/defines.h index 8ab58db..8c3b1ee 100644 --- a/defines.h +++ b/defines.h @@ -35,17 +35,25 @@ ULLONG ntohll(ULLONG a); void MILLISLEEP(ULONG a); #ifdef WIN32 -#define SNPRINTF _snprintf -#define VSNPRINTF _vsnprintf -#define STRCASECMP stricmp -#define STRCASESTR StrStrI -#define STRTOULL _strtoui64 + + #define Surface_TYPE SurfaceWin + + #define SNPRINTF _snprintf + #define VSNPRINTF _vsnprintf + #define STRCASECMP stricmp + #define STRCASESTR StrStrI + #define STRTOULL _strtoui64 + #else -#define SNPRINTF snprintf -#define VSNPRINTF vsnprintf -#define STRCASECMP strcasecmp -#define STRCASESTR strcasestr -#define STRTOULL strtoull + + #define Surface_TYPE SurfaceMVP + + #define SNPRINTF snprintf + #define VSNPRINTF vsnprintf + #define STRCASECMP strcasecmp + #define STRCASESTR strcasestr + #define STRTOULL strtoull + #endif #endif diff --git a/main.cc b/main.cc index 5ff34bc..70259b3 100644 --- a/main.cc +++ b/main.cc @@ -467,7 +467,6 @@ void MILLISLEEP(ULONG a) struct timespec delayTime; delayTime.tv_sec = a / 1000; delayTime.tv_nsec = (a % 1000) * 1000000; - printf("%lu %lu\n", delayTime.tv_sec, delayTime.tv_nsec); nanosleep(&delayTime, NULL); #else Sleep(a); diff --git a/osdmvp.cc b/osdmvp.cc index b4fda69..a86f9a0 100644 --- a/osdmvp.cc +++ b/osdmvp.cc @@ -49,11 +49,11 @@ int OsdMVP::init(char* device) initted = 1; // must set this here or create surface won't work - Surface::initConversionTables(); + SurfaceMVP::initConversionTables(); Video* video = Video::getInstance(); - screen = new Surface(Surface::SCREEN); + screen = new SurfaceMVP(Surface::SCREEN); screen->create(video->getScreenWidth(), video->getScreenHeight()); screen->display(); diff --git a/osdmvp.h b/osdmvp.h index dbea737..5b6dfc4 100644 --- a/osdmvp.h +++ b/osdmvp.h @@ -28,7 +28,7 @@ #include "osd.h" #include "defines.h" #include "log.h" -#include "surface.h" +#include "surfacemvp.h" #include "video.h" class OsdMVP : public Osd diff --git a/player.cc b/player.cc index c0893af..faf1436 100644 --- a/player.cc +++ b/player.cc @@ -112,7 +112,7 @@ void Player::resyncAudio() // Temp hopefully if (!initted) return; audio->pause(); - usleep(500000); + MILLISLEEP(500); audio->unPause(); } @@ -121,7 +121,7 @@ void Player::resyncVideo() // Temp hopefully if (!initted) return; video->pause(); - usleep(500000); + MILLISLEEP(500); video->unPause(); } @@ -179,25 +179,15 @@ int Player::play() /* threadStart(); -// sleep(1); - -// struct timespec delay; -// delay.tv_sec = 1; -// delay.tv_nsec = 500000000; -// nanosleep(&delay, NULL); +// MILLISLEEP(1000); vfeed.start(); afeed.start(); video->play(); audio->play(); - video->sync(); audio->sync(); - - video->pause(); - usleep(500000); // SYNC - video->sync(); - video->unPause(); video->sync(); + resyncVideo(); */ // ------------------------------------------------------------------------------------------------ diff --git a/surface.cc b/surface.cc index 3ba19cb..5339171 100644 --- a/surface.cc +++ b/surface.cc @@ -28,28 +28,10 @@ osd_font_t* Surface::font = &font_helvB18; Surface::Surface(int id) { if (id == SCREEN) screen = this; - - fdOsd = Osd::getInstance()->getFD(); - memset(&surface, 0, sizeof(osd_surface_t)); - memset(&surface.sfc, 0, sizeof(stbgfx_sfc_t)); - memset(&surface.map, 0, sizeof(stbgfx_map_t)); } Surface::~Surface() { - for (int i = 0; i < 3; i++) - { - if (surface.base[i]) munmap(surface.base[i], surface.map.map[i].size); - } - - int a; - - a = ioctl(fdOsd, GFX_FB_SFC_UNMAP, surface.sfc.handle); - if (a) Log::getInstance()->log("Surface", Log::ERR, "Surface unmap failed"); - - a = ioctl(fdOsd, GFX_FB_SFC_FREE, surface.sfc.handle); - if (a) Log::getInstance()->log("Surface", Log::ERR, "Surface destroy failed"); - } Surface* Surface::getScreen() @@ -57,264 +39,10 @@ Surface* Surface::getScreen() return screen; } -int Surface::create(UINT width, UINT height) -{ - int r = 0; - int displayNumber = 0; // mvpmc iterates 0->15 till it gets one that works? - - surface.sfc.width = width; - surface.sfc.height = height; - surface.sfc.flags = 0x3f1533; - - surface.sfc.unknown = -1; - -// r = ioctl(fdOsd, GFX_FB_SET_OSD, &displayNumber); -// if (r) return 0; - - r = ioctl(fdOsd, GFX_FB_OSD_SURFACE, &displayNumber); - if (r) return 0; - - r = ioctl(fdOsd, GFX_FB_SFC_ALLOC, &surface.sfc); - if (r) return 0; - - surface.map.map[0].unknown = surface.sfc.handle; - r = ioctl(fdOsd, GFX_FB_MAP, &surface.map); - if (r) return 0; - - surface.base[0] = (unsigned char *)mmap(NULL, surface.map.map[0].size, PROT_READ|PROT_WRITE, MAP_SHARED, fdOsd, surface.map.map[0].addr); - if (surface.base[0] == MAP_FAILED) return 0; - - surface.base[1] = (unsigned char *)mmap(NULL, surface.map.map[1].size, PROT_READ|PROT_WRITE, MAP_SHARED, fdOsd, surface.map.map[1].addr); - if (surface.base[1] == MAP_FAILED) return 0; - - surface.base[2] = (unsigned char *)mmap(NULL, surface.map.map[2].size, PROT_READ|PROT_WRITE, MAP_SHARED, fdOsd, surface.map.map[2].addr); - if (surface.base[2] == MAP_FAILED) return 0; - -// surface.display.num = displayNumber; -// r = ioctl(fdOsd, GFX_FB_MOVE_DISPLAY, &surface.display); -// if (r) return 0; - -// r = ioctl(fdOsd, GFX_FB_SET_DISPLAY, &surface.display); -// if (r) return 0; - - return 1; -} - -void Surface::display() -{ - unsigned long fb_descriptor[2]; - - fb_descriptor[0] = surface.sfc.handle; - fb_descriptor[1] = 1; - - ioctl(fdOsd, GFX_FB_ATTACH, fb_descriptor); -} - -unsigned long Surface::getSurfaceHandle() -{ - return surface.sfc.handle; -} - -// ---------------------------------------------------------------------------- - -// Now for the drawing functions - -/* - * RGB to YUV conversion tables - */ -int Surface::conv_YB[256]; -int Surface::conv_YG[256]; -int Surface::conv_YR[256]; -int Surface::conv_UB[256]; -int Surface::conv_UG[256]; -int Surface::conv_UR[256]; -int Surface::conv_VB[256]; -int Surface::conv_VG[256]; -int Surface::conv_VR[256]; - -int Surface::conv_BY[256]; -int Surface::conv_GY[256]; -int Surface::conv_RY[256]; -int Surface::conv_BU[256]; -int Surface::conv_GU[256]; -int Surface::conv_RU[256]; -int Surface::conv_BV[256]; -int Surface::conv_GV[256]; -int Surface::conv_RV[256]; - -/* - * gfx_init() - initialize the RGB to YUV conversion tables - */ -void Surface::initConversionTables(void) -{ - int i; - - for (i=0; i<256; i++) { - conv_YB[i] = (int)(0.299 * (double)i); - conv_BY[i] = i; - } - for (i=0; i<256; i++) { - conv_YG[i] = (int)(0.587 * (double)i); - conv_GY[i] = i; - } - for (i=0; i<256; i++) { - conv_YR[i] = (int)(0.114 * (double)i); - conv_RY[i] = i; - } - - for (i=0; i<256; i++) { - conv_UB[i] = (int)(0.5 * (double)i); - conv_BU[i] = (int)(1.732 * (i - 128)); - } - for (i=0; i<256; i++) { - conv_UG[i] = (int)(-0.33126 * (double)i); - conv_GU[i] = (int)(-0.338 * (i - 128)); - } - for (i=0; i<256; i++) { - conv_UR[i] = (int)(-0.16874 * (double)i); - conv_RU[i] = 0; - } - - for (i=0; i<256; i++) { - conv_VB[i] = (int)(-0.08131 * (double)i); - conv_BV[i] = 0; - } - for (i=0; i<256; i++) { - conv_VG[i] = (int)(-0.41869 * (double)i); - conv_GV[i] = (int)(-0.698 * (i - 128)); - } - for (i=0; i<256; i++) { - conv_VR[i] = (int)(0.5 * (double)i); - conv_RV[i] = (int)(1.370 * ((double)i - 128)); - } -} - -/* - * rgb2yuv() - convert an RGB pixel to YUV - */ - //inline me? -void Surface::rgb2yuv(unsigned char r, unsigned char g, unsigned char b, unsigned char *y, unsigned char *u, unsigned char *v) -{ - int Y, U, V; - - Y = conv_YB[b] + conv_YG[g] + conv_YR[r]; - U = conv_UB[b] + conv_UG[g] + conv_UR[r] + 128; - V = conv_VB[b] + conv_VG[g] + conv_VR[r] + 128; - - if (Y > 255) - Y = 255; - else if (Y < 0) - Y = 0; - if (U > 255) - U = 255; - else if (U < 0) - U = 0; - if (V > 255) - V = 255; - else if (V < 0) - V = 0; - - *y = Y; - *u = U; - *v = V; -} - -int Surface::fillblt(int x, int y, int width, int height, unsigned int c) -{ - osd_fillblt_t fblt; - - fblt.handle = surface.sfc.handle; - fblt.x = x; - fblt.y = y; - fblt.width = width; - fblt.height = height; - fblt.colour = c; - - return ioctl(fdOsd, GFX_FB_OSD_FILLBLT, &fblt); -} - -void Surface::drawPixel(int x, int y, unsigned int c) -{ - int offset; - unsigned char r, g, b, a, Y, U, V; - unsigned int line, remainder; - - if ((x >= (int)surface.sfc.width) || (y >= (int)surface.sfc.height)) - return; - - c2rgba(c, &r, &g, &b, &a); - - rgb2yuv(r, g, b, &Y, &U, &V); - - remainder = (surface.sfc.width % 4); - if (remainder == 0) - line = surface.sfc.width; - else - line = surface.sfc.width + (4 - remainder); - - offset = (y * line) + x; - - *(surface.base[0] + offset) = Y; - *(surface.base[1] + (offset & 0xfffffffe)) = U; - *(surface.base[1] + (offset & 0xfffffffe) + 1) = V; - *(surface.base[2] + offset) = a; - -} - -void Surface::drawHorzLine(int x1, int x2, int y, unsigned int c) -{ - fillblt(x1, y, x2-x1, 1, c); -} - -void Surface::drawVertLine(int x, int y1, int y2, unsigned int c) -{ - fillblt(x, y1, 1, y2-y1, c); -} - - - /* surface update to screen needs: - source x distance into this surface - source y distance into this surface - width of update - height of update - destination x on screen - destination y on screen - */ -int Surface::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME -{ - return blt(fdOsd, surface.sfc.handle, sx, sy, w, h, screen->getSurfaceHandle(), dx, dy); -} - -int Surface::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy) -{ - osd_bitblt_t fblt; - memset(&fblt, 0, sizeof(fblt)); - - fblt.dst_handle = dhandle; - fblt.dst_x = dx; - fblt.dst_y = dy; - - fblt.src_handle = shandle; - fblt.src_x = sx; - fblt.src_y = sy; - - fblt.width = width; - fblt.height = height; - - fblt.u1 = 1; - fblt.u2 = 0; - fblt.u3 = 0x0f; - - return ioctl(fd, GFX_FB_OSD_BITBLT, &fblt); -} - -int Surface::drawText(char* text, int x, int y, int r, int g, int b) +int Surface::drawText(char* text, int x, int y, ULONG rgba) { int h, n, i; int Y, X, cx; - unsigned long fg; - - fg = rgba(r, g, b, 255); n = strlen(text); h = font->height; @@ -334,7 +62,7 @@ int Surface::drawText(char* text, int x, int y, int r, int g, int b) { if ((character[Y] >> (32 - X)) & 0x1) { - drawPixel(x+X+cx, y+Y, fg); + drawPixel(x+X+cx, y+Y, rgba); pixels++; } } @@ -344,7 +72,7 @@ int Surface::drawText(char* text, int x, int y, int r, int g, int b) return 1; } -int Surface::drawTextRJ(char* text, int x, int y, int r, int g, int b) +int Surface::drawTextRJ(char* text, int x, int y, ULONG rgba) { int i, n, w; w = 0; @@ -359,10 +87,10 @@ int Surface::drawTextRJ(char* text, int x, int y, int r, int g, int b) x -= w; if (x < 0) return 0; - else return drawText(text, x, y, r, g, b); + else return drawText(text, x, y, rgba); } -int Surface::drawTextCentre(char* text, int x, int y, int r, int g, int b) +int Surface::drawTextCentre(char* text, int x, int y, ULONG rgba) { int i, n, w; w = 0; @@ -377,7 +105,7 @@ int Surface::drawTextCentre(char* text, int x, int y, int r, int g, int b) x -= w / 2; if (x < 0) return 0; - else return drawText(text, x, y, r, g, b); + else return drawText(text, x, y, rgba); } int Surface::getCharWidth(char c) @@ -389,139 +117,3 @@ int Surface::getFontHeight() { return font->spacing; } - -void Surface::screenShot(char* fileName) -{ - Log* logger = Log::getInstance(); - - FILE* outfile = fopen(fileName, "w"); - if (outfile == NULL) - { - logger->log("Surface", Log::ERR, "Can't open JPEG"); - return; - } - logger->log("Surface", Log::DEBUG, "File opened %u %u", surface.sfc.height, surface.sfc.width); - - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_compress(&cinfo); - jpeg_stdio_dest(&cinfo, outfile); - cinfo.image_width = surface.sfc.width; - cinfo.image_height = surface.sfc.height; - cinfo.input_components = 3; - cinfo.in_color_space = JCS_RGB; - jpeg_set_defaults(&cinfo); - jpeg_start_compress(&cinfo, TRUE); - - - unsigned char row[surface.sfc.width * 3]; - unsigned char* prow = (unsigned char*)&row; - unsigned char r, g, b; - - while (cinfo.next_scanline < cinfo.image_height) - { - for(unsigned int i = 0; i < surface.sfc.width; i++) - { - readPixel(i, cinfo.next_scanline, &r, &g, &b); - row[i * 3] = r; - row[(i * 3) + 1] = g; - row[(i * 3) + 2] = b; - } - jpeg_write_scanlines(&cinfo, (JSAMPLE **)&prow, 1); - } - - jpeg_finish_compress(&cinfo); - jpeg_destroy_compress(&cinfo); - fclose(outfile); - logger->log("Surface", Log::DEBUG, "Jpeg saved"); -} - -void Surface::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b) -{ - int offset; - unsigned char a, Y, U, V; - unsigned int line, remainder; - - if (((unsigned int)x >= surface.sfc.width) || ((unsigned int)y >= surface.sfc.height)) return; - - remainder = (surface.sfc.width % 4); - if (remainder == 0) - line = surface.sfc.width; - else - line = surface.sfc.width + (4 - remainder); - - offset = (y * line) + x; - - Y = *(surface.base[0] + offset); - U = *(surface.base[1] + (offset & 0xfffffffe)); - V = *(surface.base[1] + (offset & 0xfffffffe) + 1); - a = *(surface.base[2] + offset); - - yuv2rgb(Y, U, V, r, g, b); -} - -void Surface::yuv2rgb(int y, int u, int v, unsigned char* pr, unsigned char* pg, unsigned char* pb) -{ - // from http://www.fourcc.org/index.php?http%3A//www.fourcc.org/fccyvrgb.php - -// unsigned int pixel32; -// unsigned char *pixel = (unsigned char *)&pixel32; - int r, g, b; - - - /* - One formula I found: (not the right one) - - R = 1.164(Y - 16) + 1.596(Cr - 128) - G = 1.164(Y - 16) - 0.813(Cr - 128) - 0.391(Cb - 128) - B = 1.164(Y - 16) + 2.018(Cb - 128) - - - r = (1.164 * (y - 16)) - + (2.018 * (v - 128)); - g = (1.164 * (y - 16)) - - (0.813 * (u - 128)) - - (0.391 * (v - 128)); - b = (1.164 * (y - 16)) - + (1.596 * (u - 128)); - - - Another formula I found: (seems to work) - - R = Y + 1.370705 (V-128) - G = Y - 0.698001 (V-128) - 0.337633 (U-128) - B = Y + 1.732446 (U-128) - */ - - r = (int)( y + (1.370705 * (v-128)) ); - g = (int)( y - (0.698001 * (v-128)) - (0.337633 * (u-128)) ); - b = (int)( y + (1.732446 * (u-128)) ); - - // Even with proper conversion, some values still need clipping. - if (r > 255) r = 255; - if (g > 255) g = 255; - if (b > 255) b = 255; - if (r < 0) r = 0; - if (g < 0) g = 0; - if (b < 0) b = 0; - - // Values only go from 0-220.. Why? -// pixel[0] = r * 220 / 256; -// pixel[1] = g * 220 / 256; -// pixel[2] = b * 220 / 256; -// pixel[3] = 0; - - *pr = (unsigned char) (r * 220 / 256); - *pg = (unsigned char) (g * 220 / 256); - *pb = (unsigned char) (b * 220 / 256); - - /* Debug - //printf("yuv2rgb(%i, %i, %i) -> %i, %i, %i (0x%x)\n", - y, u, v, - pixel[0], pixel[1], pixel[2], - pixel32); - */ - -// return pixel32; -} diff --git a/surface.h b/surface.h index c44656d..66fb5fe 100644 --- a/surface.h +++ b/surface.h @@ -23,87 +23,8 @@ #define SURFACE_H #include -#include -#include -#include -#include - -// Structures for surface management - -typedef struct -{ - unsigned long num; - unsigned long unknown[4]; - unsigned long width; - unsigned long height; - char unknown2; -} stbgfx_display_t; - -typedef struct -{ - unsigned long unknown; - unsigned long win_unknown; - unsigned long addr; - unsigned long size; - unsigned long unknown2; - unsigned long width; - unsigned long height; - unsigned long unknown3; - unsigned long unknown4; - unsigned long width2; - unsigned long unknown5; - unsigned long unknown6; -} stbgfx_map_item_t; - -typedef struct { - stbgfx_map_item_t map[3]; - unsigned long other[2]; -} stbgfx_map_t; - -typedef struct -{ - unsigned long handle; /* surface handle */ - unsigned long width; - unsigned long height; - unsigned long flags; - long unknown; //unsigned long - unsigned long depth; /* number of subplanes */ -} stbgfx_sfc_t; - -typedef struct -{ - stbgfx_display_t display; - stbgfx_map_t map; - stbgfx_sfc_t sfc; - unsigned char *base[3]; -} osd_surface_t; - - -// Structures for surface drawing - -typedef struct -{ - unsigned long handle; - unsigned long x; - unsigned long y; - unsigned long width; - unsigned long height; - unsigned long colour; -} osd_fillblt_t; - -typedef struct { - unsigned long dst_handle; - unsigned long dst_x; - unsigned long dst_y; - unsigned long width; - unsigned long height; - unsigned long src_handle; - unsigned long src_x; - unsigned long src_y; - unsigned long u1; - unsigned long u2; - unsigned char u3; -} osd_bitblt_t; +#include "defines.h" +#include "log.h" // Font stuff @@ -120,130 +41,39 @@ extern osd_font_t font_CaslonRoman_1_25; extern osd_font_t font_helvB24; extern osd_font_t font_helvB18; -// Surface ioctls - -#define GFX_FB_SFC_ALLOC _IOWR(0xfb,1,int*) -#define GFX_FB_SFC_FREE _IOW(0xfb,2,int) -#define GFX_FB_MAP _IOWR(0xfb,3,int*) -#define GFX_FB_SFC_UNMAP _IOW(0xfb,4,int) -#define GFX_FB_SET_PAL_1 _IOWR(0xfb,5,int*) -#define GFX_FB_SET_PAL_2 _IOW(0xfb,6,int*) -#define GFX_FB_OSD_SURFACE _IO(0xfb,7) -#define GFX_FB_SFC_SET_SHARE _IOW(0xfb,8,int) -#define GFX_FB_OSD_CUR_SETATTR _IOW(0xfb,9,int*) -#define GFX_FB_ATTACH _IOW(0xfb,11,int) -#define GFX_FB_SFC_DETACH _IOW(0xfb,12,int*) -#define GFX_FB_MOVE_DISPLAY _IOWR(0xfb,13,int) -#define GFX_FB_SET_DISPLAY _IOW(0xfb,14,int) -#define GFX_FB_OSD_CUR_MOVE_1 _IOW(0xfb,15,int*) -#define GFX_FB_OSD_CUR_MOVE_2 _IOW(0xfb,16,int) -#define GFX_FB_SET_OSD _IOW(0xfb,18,int) -#define GFX_FB_SET_DISP_CTRL _IOW(0xfb,21,int*) -#define GFX_FB_GET_DISP_CTRL _IOWR(0xfb,22,int*) -#define GFX_FB_SET_VIS_DEV_CTL _IOWR(0xfb,23,int*) -#define GFX_FB_GET_VIS_DEV_CTL _IOWR(0xfb,24,int*) -#define GFX_FB_OSD_BITBLT _IOW(0xfb,51,osd_bitblt_t*) -#define GFX_FB_OSD_FILLBLT _IOW(0xfb,53,osd_fillblt_t*) -#define GFX_FB_OSD_ADVFILLBLT _IOW(0xfb,54,osd_afillblt_t*) -#define GFX_FB_OSD_BLEND _IOW(0xfb,55,int*) -#define GFX_FB_OSD_ADVBLEND _IOW(0xfb,56,int*) -#define GFX_FB_OSD_RESIZE _IOW(0xfb,58,int*) -#define GFX_FB_ENGINE_WAIT _IOW(0xfb,60,int) -#define GFX_FB_RESET_ENGINE _IO(0xfb,61) -#define GFX_FB_SET_ENGINE_MODE _IOW(0xfb,62,int) -#define GFX_FB_GET_ENGINE_MODE _IO(0xfb,63) -#define GFX_FB_GET_SFC_INFO _IO(0xfb,64,int*) -#define GFX_FB_OSD_SFC_CLIP _IOW(0xfb,65,osd_clip_rec_t*) -#define GFX_FB_OSD_COLOURKEY _IOW(0xfb,67,int*) -#define GFX_FB_GET_SFC_PSEUDO _IOWR(0xfb,68,int*) - -extern "C" -{ - #include -} - -#include "defines.h" -#include "log.h" - class Surface { public: Surface(int id = 0); - ~Surface(); + virtual ~Surface(); static Surface* getScreen(); static int getFontHeight(); + int getCharWidth(char c); - int create(UINT width, UINT height); - void display(); - unsigned long getSurfaceHandle(); + int drawText(char* text, int x, int y, ULONG rgba); + int drawTextRJ(char* text, int x, int y, ULONG rgba); + int drawTextCentre(char* text, int x, int y, ULONG rgba); - int fillblt(int x, int y, int width, int height, unsigned int c); - void drawPixel(int x, int y, unsigned int c); - void drawHorzLine(int x1, int x2, int y, unsigned int c); - void drawVertLine(int x, int y1, int y2, unsigned int c); - int updateToScreen(int sx, int sy, int w, int h, int dx, int dy); + virtual int create(UINT width, UINT height)=0; + virtual void display()=0; - int drawText(char* text, int x, int y, int r, int g, int b); - int drawTextRJ(char* text, int x, int y, int r, int g, int b); - int drawTextCentre(char* text, int x, int y, int r, int g, int b); - int getCharWidth(char c); - void readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b); - void yuv2rgb(int y, int u, int v, unsigned char* pr, unsigned char* pg, unsigned char* pb); - void screenShot(char* fileName); + virtual int fillblt(int x, int y, int width, int height, unsigned int c)=0; + virtual void drawPixel(int x, int y, unsigned int c)=0; + virtual void drawHorzLine(int x1, int x2, int y, unsigned int c)=0; + virtual void drawVertLine(int x, int y1, int y2, unsigned int c)=0; + virtual int updateToScreen(int sx, int sy, int w, int h, int dx, int dy)=0; + virtual void readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)=0; + virtual void screenShot(char* fileName)=0; - static void initConversionTables(); - - static int blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy); + virtual int blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)=0; const static int SCREEN = 1; const static int BUFFER = 2; - // Implicit inlines - void c2rgba(unsigned long c, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) - { - *a = (c & 0xff000000) >> 24; - *r = (c & 0x00ff0000) >> 16; - *g = (c & 0x0000ff00) >> 8; - *b = (c & 0x000000ff); - } - - unsigned long rgba(unsigned char r, unsigned char g, unsigned char b, unsigned char a) - { - return (a<<24) | (r<<16) | (g<<8) | b; - - } - - private: + protected: static Surface* screen; static osd_font_t* font; - - int fdOsd; - - osd_surface_t surface; - - void rgb2yuv(unsigned char r, unsigned char g, unsigned char b, unsigned char *y, unsigned char *u, unsigned char *v); - - static int conv_YB[256]; - static int conv_YG[256]; - static int conv_YR[256]; - static int conv_UB[256]; - static int conv_UG[256]; - static int conv_UR[256]; - static int conv_VB[256]; - static int conv_VG[256]; - static int conv_VR[256]; - - static int conv_BY[256]; - static int conv_GY[256]; - static int conv_RY[256]; - static int conv_BU[256]; - static int conv_GU[256]; - static int conv_RU[256]; - static int conv_BV[256]; - static int conv_GV[256]; - static int conv_RV[256]; - }; #endif diff --git a/surfacemvp.cc b/surfacemvp.cc new file mode 100644 index 0000000..66626c0 --- /dev/null +++ b/surfacemvp.cc @@ -0,0 +1,437 @@ +/* + Copyright 2004-2005 Chris Tallon + Portions copyright 2004 Jon Gettler + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "surfacemvp.h" +#include "osd.h" + +SurfaceMVP::SurfaceMVP(int id) +{ + if (id == SCREEN) screen = this; + + fdOsd = Osd::getInstance()->getFD(); + memset(&surface, 0, sizeof(osd_surface_t)); + memset(&surface.sfc, 0, sizeof(stbgfx_sfc_t)); + memset(&surface.map, 0, sizeof(stbgfx_map_t)); +} + +SurfaceMVP::~SurfaceMVP() +{ + for (int i = 0; i < 3; i++) + { + if (surface.base[i]) munmap(surface.base[i], surface.map.map[i].size); + } + + int a; + + a = ioctl(fdOsd, GFX_FB_SFC_UNMAP, surface.sfc.handle); + if (a) Log::getInstance()->log("Surface", Log::ERR, "Surface unmap failed"); + + a = ioctl(fdOsd, GFX_FB_SFC_FREE, surface.sfc.handle); + if (a) Log::getInstance()->log("Surface", Log::ERR, "Surface destroy failed"); + +} + +int SurfaceMVP::create(UINT width, UINT height) +{ + int r = 0; + int displayNumber = 0; // mvpmc iterates 0->15 till it gets one that works? + + surface.sfc.width = width; + surface.sfc.height = height; + surface.sfc.flags = 0x3f1533; + + surface.sfc.unknown = -1; + +// r = ioctl(fdOsd, GFX_FB_SET_OSD, &displayNumber); +// if (r) return 0; + + r = ioctl(fdOsd, GFX_FB_OSD_SURFACE, &displayNumber); + if (r) return 0; + + r = ioctl(fdOsd, GFX_FB_SFC_ALLOC, &surface.sfc); + if (r) return 0; + + surface.map.map[0].unknown = surface.sfc.handle; + r = ioctl(fdOsd, GFX_FB_MAP, &surface.map); + if (r) return 0; + + surface.base[0] = (unsigned char *)mmap(NULL, surface.map.map[0].size, PROT_READ|PROT_WRITE, MAP_SHARED, fdOsd, surface.map.map[0].addr); + if (surface.base[0] == MAP_FAILED) return 0; + + surface.base[1] = (unsigned char *)mmap(NULL, surface.map.map[1].size, PROT_READ|PROT_WRITE, MAP_SHARED, fdOsd, surface.map.map[1].addr); + if (surface.base[1] == MAP_FAILED) return 0; + + surface.base[2] = (unsigned char *)mmap(NULL, surface.map.map[2].size, PROT_READ|PROT_WRITE, MAP_SHARED, fdOsd, surface.map.map[2].addr); + if (surface.base[2] == MAP_FAILED) return 0; + +// surface.display.num = displayNumber; +// r = ioctl(fdOsd, GFX_FB_MOVE_DISPLAY, &surface.display); +// if (r) return 0; + +// r = ioctl(fdOsd, GFX_FB_SET_DISPLAY, &surface.display); +// if (r) return 0; + + return 1; +} + +void SurfaceMVP::display() +{ + unsigned long fb_descriptor[2]; + + fb_descriptor[0] = surface.sfc.handle; + fb_descriptor[1] = 1; + + ioctl(fdOsd, GFX_FB_ATTACH, fb_descriptor); +} + +unsigned long SurfaceMVP::getSurfaceHandle() +{ + return surface.sfc.handle; +} + +// ---------------------------------------------------------------------------- + +// Now for the drawing functions + +/* + * RGB to YUV conversion tables + */ +int SurfaceMVP::conv_YB[256]; +int SurfaceMVP::conv_YG[256]; +int SurfaceMVP::conv_YR[256]; +int SurfaceMVP::conv_UB[256]; +int SurfaceMVP::conv_UG[256]; +int SurfaceMVP::conv_UR[256]; +int SurfaceMVP::conv_VB[256]; +int SurfaceMVP::conv_VG[256]; +int SurfaceMVP::conv_VR[256]; + +int SurfaceMVP::conv_BY[256]; +int SurfaceMVP::conv_GY[256]; +int SurfaceMVP::conv_RY[256]; +int SurfaceMVP::conv_BU[256]; +int SurfaceMVP::conv_GU[256]; +int SurfaceMVP::conv_RU[256]; +int SurfaceMVP::conv_BV[256]; +int SurfaceMVP::conv_GV[256]; +int SurfaceMVP::conv_RV[256]; + +/* + * gfx_init() - initialize the RGB to YUV conversion tables + */ +void SurfaceMVP::initConversionTables(void) +{ + int i; + + for (i=0; i<256; i++) { + conv_YB[i] = (int)(0.299 * (double)i); + conv_BY[i] = i; + } + for (i=0; i<256; i++) { + conv_YG[i] = (int)(0.587 * (double)i); + conv_GY[i] = i; + } + for (i=0; i<256; i++) { + conv_YR[i] = (int)(0.114 * (double)i); + conv_RY[i] = i; + } + + for (i=0; i<256; i++) { + conv_UB[i] = (int)(0.5 * (double)i); + conv_BU[i] = (int)(1.732 * (i - 128)); + } + for (i=0; i<256; i++) { + conv_UG[i] = (int)(-0.33126 * (double)i); + conv_GU[i] = (int)(-0.338 * (i - 128)); + } + for (i=0; i<256; i++) { + conv_UR[i] = (int)(-0.16874 * (double)i); + conv_RU[i] = 0; + } + + for (i=0; i<256; i++) { + conv_VB[i] = (int)(-0.08131 * (double)i); + conv_BV[i] = 0; + } + for (i=0; i<256; i++) { + conv_VG[i] = (int)(-0.41869 * (double)i); + conv_GV[i] = (int)(-0.698 * (i - 128)); + } + for (i=0; i<256; i++) { + conv_VR[i] = (int)(0.5 * (double)i); + conv_RV[i] = (int)(1.370 * ((double)i - 128)); + } +} + +/* + * rgb2yuv() - convert an RGB pixel to YUV + */ + //inline me? +void SurfaceMVP::rgb2yuv(unsigned char r, unsigned char g, unsigned char b, unsigned char *y, unsigned char *u, unsigned char *v) +{ + int Y, U, V; + + Y = conv_YB[b] + conv_YG[g] + conv_YR[r]; + U = conv_UB[b] + conv_UG[g] + conv_UR[r] + 128; + V = conv_VB[b] + conv_VG[g] + conv_VR[r] + 128; + + if (Y > 255) + Y = 255; + else if (Y < 0) + Y = 0; + if (U > 255) + U = 255; + else if (U < 0) + U = 0; + if (V > 255) + V = 255; + else if (V < 0) + V = 0; + + *y = Y; + *u = U; + *v = V; +} + +int SurfaceMVP::fillblt(int x, int y, int width, int height, unsigned int c) +{ + osd_fillblt_t fblt; + + fblt.handle = surface.sfc.handle; + fblt.x = x; + fblt.y = y; + fblt.width = width; + fblt.height = height; + fblt.colour = c; + + return ioctl(fdOsd, GFX_FB_OSD_FILLBLT, &fblt); +} + +void SurfaceMVP::drawPixel(int x, int y, unsigned int c) +{ + int offset; + unsigned char r, g, b, a, Y, U, V; + unsigned int line, remainder; + + if ((x >= (int)surface.sfc.width) || (y >= (int)surface.sfc.height)) + return; + + c2rgba(c, &r, &g, &b, &a); + + rgb2yuv(r, g, b, &Y, &U, &V); + + remainder = (surface.sfc.width % 4); + if (remainder == 0) + line = surface.sfc.width; + else + line = surface.sfc.width + (4 - remainder); + + offset = (y * line) + x; + + *(surface.base[0] + offset) = Y; + *(surface.base[1] + (offset & 0xfffffffe)) = U; + *(surface.base[1] + (offset & 0xfffffffe) + 1) = V; + *(surface.base[2] + offset) = a; + +} + +void SurfaceMVP::drawHorzLine(int x1, int x2, int y, unsigned int c) +{ + fillblt(x1, y, x2-x1, 1, c); +} + +void SurfaceMVP::drawVertLine(int x, int y1, int y2, unsigned int c) +{ + fillblt(x, y1, 1, y2-y1, c); +} + + + /* surface update to screen needs: + source x distance into this surface + source y distance into this surface + width of update + height of update + destination x on screen + destination y on screen + */ +int SurfaceMVP::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME +{ + return blt(fdOsd, surface.sfc.handle, sx, sy, w, h, ((SurfaceMVP*)screen)->getSurfaceHandle(), dx, dy); +} + +int SurfaceMVP::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy) +{ + osd_bitblt_t fblt; + memset(&fblt, 0, sizeof(fblt)); + + fblt.dst_handle = dhandle; + fblt.dst_x = dx; + fblt.dst_y = dy; + + fblt.src_handle = shandle; + fblt.src_x = sx; + fblt.src_y = sy; + + fblt.width = width; + fblt.height = height; + + fblt.u1 = 1; + fblt.u2 = 0; + fblt.u3 = 0x0f; + + return ioctl(fd, GFX_FB_OSD_BITBLT, &fblt); +} + +void SurfaceMVP::screenShot(char* fileName) +{ + Log* logger = Log::getInstance(); + + FILE* outfile = fopen(fileName, "w"); + if (outfile == NULL) + { + logger->log("Surface", Log::ERR, "Can't open JPEG"); + return; + } + logger->log("Surface", Log::DEBUG, "File opened %u %u", surface.sfc.height, surface.sfc.width); + + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + jpeg_stdio_dest(&cinfo, outfile); + cinfo.image_width = surface.sfc.width; + cinfo.image_height = surface.sfc.height; + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + jpeg_set_defaults(&cinfo); + jpeg_start_compress(&cinfo, TRUE); + + + unsigned char row[surface.sfc.width * 3]; + unsigned char* prow = (unsigned char*)&row; + unsigned char r, g, b; + + while (cinfo.next_scanline < cinfo.image_height) + { + for(unsigned int i = 0; i < surface.sfc.width; i++) + { + readPixel(i, cinfo.next_scanline, &r, &g, &b); + row[i * 3] = r; + row[(i * 3) + 1] = g; + row[(i * 3) + 2] = b; + } + jpeg_write_scanlines(&cinfo, (JSAMPLE **)&prow, 1); + } + + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + fclose(outfile); + logger->log("Surface", Log::DEBUG, "Jpeg saved"); +} + +void SurfaceMVP::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b) +{ + int offset; + unsigned char a, Y, U, V; + unsigned int line, remainder; + + if (((unsigned int)x >= surface.sfc.width) || ((unsigned int)y >= surface.sfc.height)) return; + + remainder = (surface.sfc.width % 4); + if (remainder == 0) + line = surface.sfc.width; + else + line = surface.sfc.width + (4 - remainder); + + offset = (y * line) + x; + + Y = *(surface.base[0] + offset); + U = *(surface.base[1] + (offset & 0xfffffffe)); + V = *(surface.base[1] + (offset & 0xfffffffe) + 1); + a = *(surface.base[2] + offset); + + yuv2rgb(Y, U, V, r, g, b); +} + +void SurfaceMVP::yuv2rgb(int y, int u, int v, unsigned char* pr, unsigned char* pg, unsigned char* pb) +{ + // from http://www.fourcc.org/index.php?http%3A//www.fourcc.org/fccyvrgb.php + +// unsigned int pixel32; +// unsigned char *pixel = (unsigned char *)&pixel32; + int r, g, b; + + + /* + One formula I found: (not the right one) + + R = 1.164(Y - 16) + 1.596(Cr - 128) + G = 1.164(Y - 16) - 0.813(Cr - 128) - 0.391(Cb - 128) + B = 1.164(Y - 16) + 2.018(Cb - 128) + + + r = (1.164 * (y - 16)) + + (2.018 * (v - 128)); + g = (1.164 * (y - 16)) + - (0.813 * (u - 128)) + - (0.391 * (v - 128)); + b = (1.164 * (y - 16)) + + (1.596 * (u - 128)); + + + Another formula I found: (seems to work) + + R = Y + 1.370705 (V-128) + G = Y - 0.698001 (V-128) - 0.337633 (U-128) + B = Y + 1.732446 (U-128) + */ + + r = (int)( y + (1.370705 * (v-128)) ); + g = (int)( y - (0.698001 * (v-128)) - (0.337633 * (u-128)) ); + b = (int)( y + (1.732446 * (u-128)) ); + + // Even with proper conversion, some values still need clipping. + if (r > 255) r = 255; + if (g > 255) g = 255; + if (b > 255) b = 255; + if (r < 0) r = 0; + if (g < 0) g = 0; + if (b < 0) b = 0; + + // Values only go from 0-220.. Why? +// pixel[0] = r * 220 / 256; +// pixel[1] = g * 220 / 256; +// pixel[2] = b * 220 / 256; +// pixel[3] = 0; + + *pr = (unsigned char) (r * 220 / 256); + *pg = (unsigned char) (g * 220 / 256); + *pb = (unsigned char) (b * 220 / 256); + + /* Debug + //printf("yuv2rgb(%i, %i, %i) -> %i, %i, %i (0x%x)\n", + y, u, v, + pixel[0], pixel[1], pixel[2], + pixel32); + */ + +// return pixel32; +} diff --git a/surfacemvp.h b/surfacemvp.h new file mode 100644 index 0000000..79c4083 --- /dev/null +++ b/surfacemvp.h @@ -0,0 +1,214 @@ +/* + Copyright 2004-2005 Chris Tallon + Portions copyright 2004 Jon Gettler + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef SURFACEMVP_H +#define SURFACEMVP_H + +#include +#include +#include +#include +#include + +extern "C" +{ + #include +} + +#include "defines.h" +#include "log.h" +#include "surface.h" + +// Structures for surface management + +typedef struct +{ + unsigned long num; + unsigned long unknown[4]; + unsigned long width; + unsigned long height; + char unknown2; +} stbgfx_display_t; + +typedef struct +{ + unsigned long unknown; + unsigned long win_unknown; + unsigned long addr; + unsigned long size; + unsigned long unknown2; + unsigned long width; + unsigned long height; + unsigned long unknown3; + unsigned long unknown4; + unsigned long width2; + unsigned long unknown5; + unsigned long unknown6; +} stbgfx_map_item_t; + +typedef struct { + stbgfx_map_item_t map[3]; + unsigned long other[2]; +} stbgfx_map_t; + +typedef struct +{ + unsigned long handle; /* surface handle */ + unsigned long width; + unsigned long height; + unsigned long flags; + long unknown; //unsigned long + unsigned long depth; /* number of subplanes */ +} stbgfx_sfc_t; + +typedef struct +{ + stbgfx_display_t display; + stbgfx_map_t map; + stbgfx_sfc_t sfc; + unsigned char *base[3]; +} osd_surface_t; + + +// Structures for surface drawing + +typedef struct +{ + unsigned long handle; + unsigned long x; + unsigned long y; + unsigned long width; + unsigned long height; + unsigned long colour; +} osd_fillblt_t; + +typedef struct { + unsigned long dst_handle; + unsigned long dst_x; + unsigned long dst_y; + unsigned long width; + unsigned long height; + unsigned long src_handle; + unsigned long src_x; + unsigned long src_y; + unsigned long u1; + unsigned long u2; + unsigned char u3; +} osd_bitblt_t; + +// Surface ioctls + +#define GFX_FB_SFC_ALLOC _IOWR(0xfb,1,int*) +#define GFX_FB_SFC_FREE _IOW(0xfb,2,int) +#define GFX_FB_MAP _IOWR(0xfb,3,int*) +#define GFX_FB_SFC_UNMAP _IOW(0xfb,4,int) +#define GFX_FB_SET_PAL_1 _IOWR(0xfb,5,int*) +#define GFX_FB_SET_PAL_2 _IOW(0xfb,6,int*) +#define GFX_FB_OSD_SURFACE _IO(0xfb,7) +#define GFX_FB_SFC_SET_SHARE _IOW(0xfb,8,int) +#define GFX_FB_OSD_CUR_SETATTR _IOW(0xfb,9,int*) +#define GFX_FB_ATTACH _IOW(0xfb,11,int) +#define GFX_FB_SFC_DETACH _IOW(0xfb,12,int*) +#define GFX_FB_MOVE_DISPLAY _IOWR(0xfb,13,int) +#define GFX_FB_SET_DISPLAY _IOW(0xfb,14,int) +#define GFX_FB_OSD_CUR_MOVE_1 _IOW(0xfb,15,int*) +#define GFX_FB_OSD_CUR_MOVE_2 _IOW(0xfb,16,int) +#define GFX_FB_SET_OSD _IOW(0xfb,18,int) +#define GFX_FB_SET_DISP_CTRL _IOW(0xfb,21,int*) +#define GFX_FB_GET_DISP_CTRL _IOWR(0xfb,22,int*) +#define GFX_FB_SET_VIS_DEV_CTL _IOWR(0xfb,23,int*) +#define GFX_FB_GET_VIS_DEV_CTL _IOWR(0xfb,24,int*) +#define GFX_FB_OSD_BITBLT _IOW(0xfb,51,osd_bitblt_t*) +#define GFX_FB_OSD_FILLBLT _IOW(0xfb,53,osd_fillblt_t*) +#define GFX_FB_OSD_ADVFILLBLT _IOW(0xfb,54,osd_afillblt_t*) +#define GFX_FB_OSD_BLEND _IOW(0xfb,55,int*) +#define GFX_FB_OSD_ADVBLEND _IOW(0xfb,56,int*) +#define GFX_FB_OSD_RESIZE _IOW(0xfb,58,int*) +#define GFX_FB_ENGINE_WAIT _IOW(0xfb,60,int) +#define GFX_FB_RESET_ENGINE _IO(0xfb,61) +#define GFX_FB_SET_ENGINE_MODE _IOW(0xfb,62,int) +#define GFX_FB_GET_ENGINE_MODE _IO(0xfb,63) +#define GFX_FB_GET_SFC_INFO _IO(0xfb,64,int*) +#define GFX_FB_OSD_SFC_CLIP _IOW(0xfb,65,osd_clip_rec_t*) +#define GFX_FB_OSD_COLOURKEY _IOW(0xfb,67,int*) +#define GFX_FB_GET_SFC_PSEUDO _IOWR(0xfb,68,int*) + +class SurfaceMVP : public Surface +{ + public: + SurfaceMVP(int id = 0); + ~SurfaceMVP(); + + int create(UINT width, UINT height); + void display(); + unsigned long getSurfaceHandle(); + + int fillblt(int x, int y, int width, int height, unsigned int rgba); + void drawPixel(int x, int y, unsigned int c); + void drawHorzLine(int x1, int x2, int y, unsigned int c); + void drawVertLine(int x, int y1, int y2, unsigned int c); + int updateToScreen(int sx, int sy, int w, int h, int dx, int dy); + void readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b); + void screenShot(char* fileName); + + static void initConversionTables(); + + int blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy); + + private: + int fdOsd; + osd_surface_t surface; + + void yuv2rgb(int y, int u, int v, unsigned char* pr, unsigned char* pg, unsigned char* pb); + void rgb2yuv(unsigned char r, unsigned char g, unsigned char b, unsigned char *y, unsigned char *u, unsigned char *v); + + // Implicit inlines + void c2rgba(unsigned long c, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) + { + *a = (c & 0xff000000) >> 24; + *r = (c & 0x00ff0000) >> 16; + *g = (c & 0x0000ff00) >> 8; + *b = (c & 0x000000ff); + } + + static int conv_YB[256]; + static int conv_YG[256]; + static int conv_YR[256]; + static int conv_UB[256]; + static int conv_UG[256]; + static int conv_UR[256]; + static int conv_VB[256]; + static int conv_VG[256]; + static int conv_VR[256]; + + static int conv_BY[256]; + static int conv_GY[256]; + static int conv_RY[256]; + static int conv_BU[256]; + static int conv_GU[256]; + static int conv_RU[256]; + static int conv_BV[256]; + static int conv_GV[256]; + static int conv_RV[256]; + +}; + +#endif diff --git a/surfacewin.cc b/surfacewin.cc new file mode 100644 index 0000000..d17eb24 --- /dev/null +++ b/surfacewin.cc @@ -0,0 +1,75 @@ +/* + Copyright 2004-2005 Chris Tallon + Portions copyright 2004 Jon Gettler + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "surfacewin.h" +#include "osd.h" + +SurfaceWin::SurfaceWin(int id) +{ +} + +SurfaceWin::~SurfaceWin() +{ +} + +int SurfaceWin::create(UINT width, UINT height) +{ + return 0; +} + +void SurfaceWin::display() +{ +} + +int SurfaceWin::fillblt(int x, int y, int width, int height, unsigned int c) +{ + return 0; +} + +void SurfaceWin::drawPixel(int x, int y, unsigned int c) +{ +} + +void SurfaceWin::drawHorzLine(int x1, int x2, int y, unsigned int c) +{ +} + +void SurfaceWin::drawVertLine(int x, int y1, int y2, unsigned int c) +{ +} + +int SurfaceWin::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME +{ + return 0; +} + +int SurfaceWin::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy) +{ + return 0; +} + +void SurfaceWin::screenShot(char* fileName) +{ +} + +void SurfaceWin::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b) +{ +} diff --git a/surfacewin.h b/surfacewin.h new file mode 100644 index 0000000..6b7eb70 --- /dev/null +++ b/surfacewin.h @@ -0,0 +1,51 @@ +/* + Copyright 2004-2005 Chris Tallon + Portions copyright 2004 Jon Gettler + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef SURFACEWIN_H +#define SURFACEWIN_H + +#include "defines.h" +#include "log.h" +#include "surface.h" + +class SurfaceWin : public Surface +{ + public: + SurfaceWin(int id = 0); + ~SurfaceWin(); + + int create(UINT width, UINT height); + void display(); + + int fillblt(int x, int y, int width, int height, unsigned int c); + void drawPixel(int x, int y, unsigned int c); + void drawHorzLine(int x1, int x2, int y, unsigned int c); + void drawVertLine(int x, int y1, int y2, unsigned int c); + int updateToScreen(int sx, int sy, int w, int h, int dx, int dy); + void readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b); + void screenShot(char* fileName); + + int blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy); + + private: +}; + +#endif diff --git a/vepg.cc b/vepg.cc index 9aaca60..a27a05f 100644 --- a/vepg.cc +++ b/vepg.cc @@ -197,7 +197,7 @@ void VEpg::draw() // Display the status and key stuff at the bottom int keyx = chanListbox.getOffsetX(); int keyy = chanListbox.getOffsetY() + chanListbox.getHeight() + 2; - surface->fillblt(keyx, keyy, 605, Surface::getFontHeight() * 2 + 14, surface->rgba(100, 100, 100, 255)); + rectangle(keyx, keyy, 605, Surface::getFontHeight() * 2 + 14, Colour(100, 100, 100, 255)); WSymbol w; w.setSurface(surface); @@ -220,32 +220,32 @@ void VEpg::draw() drawText(tr("OK"), keyx + 18, keyy + 20, Colour::LIGHTTEXT); - surface->fillblt(keyx + 72, keyy + 4, 104, Surface::getFontHeight() + 2, surface->rgba(200, 0, 0, 255)); + rectangle(keyx + 72, keyy + 4, 104, Surface::getFontHeight() + 2, Colour(200, 0, 0, 255)); drawText(tr("Page up"), keyx + 74, keyy + 5, Colour::LIGHTTEXT); - surface->fillblt(keyx + 72, keyy + Surface::getFontHeight() + 8, 104, Surface::getFontHeight() + 2, surface->rgba(0, 200, 0, 255)); + rectangle(keyx + 72, keyy + Surface::getFontHeight() + 8, 104, Surface::getFontHeight() + 2, Colour(0, 200, 0, 255)); drawText(tr("Page down"), keyx + 74, keyy + Surface::getFontHeight() + 9, Colour::LIGHTTEXT); - surface->fillblt(keyx + 180, keyy + 4, 104, Surface::getFontHeight() + 2, surface->rgba(200, 200, 0, 255)); + rectangle(keyx + 180, keyy + 4, 104, Surface::getFontHeight() + 2, Colour(200, 200, 0, 255)); drawText(tr("-24 hours"), keyx + 182, keyy + 5, Colour::LIGHTTEXT); - surface->fillblt(keyx + 180, keyy + Surface::getFontHeight() + 8, 104, Surface::getFontHeight() + 2, surface->rgba( 0, 0, 200, 255)); + rectangle(keyx + 180, keyy + Surface::getFontHeight() + 8, 104, Surface::getFontHeight() + 2, Colour(0, 0, 200, 255)); drawText(tr("+24 hours"), keyx + 182, keyy + Surface::getFontHeight() + 9, Colour::LIGHTTEXT); - surface->fillblt(keyx + 290, keyy + 4, 180, Surface::getFontHeight() + 2, surface->rgba( 180, 180, 180, 255)); + rectangle(keyx + 290, keyy + 4, 180, Surface::getFontHeight() + 2, Colour(180, 180, 180, 255)); drawText(tr("Guide / Back: Close"), keyx + 292 , keyy + 5, Colour::LIGHTTEXT); - surface->fillblt(keyx + 290, keyy + Surface::getFontHeight() + 8, 180, Surface::getFontHeight() + 2, surface->rgba( 180, 180, 180, 255)); + rectangle(keyx + 290, keyy + Surface::getFontHeight() + 8, 180, Surface::getFontHeight() + 2, Colour(180, 180, 180, 255)); Colour red = Colour(130, 0, 0); drawText(tr("Rec: Set timer"), keyx + 292, keyy + Surface::getFontHeight() + 9, red); - surface->fillblt(keyx + 474, keyy + 4, 128, Surface::getFontHeight() + 2, surface->rgba( 180, 180, 180, 255)); + rectangle(keyx + 474, keyy + 4, 128, Surface::getFontHeight() + 2, Colour(180, 180, 180, 255)); w.nextSymbol = WSymbol::PLAY; w.setSurfaceOffset(keyx + 476, keyy + 5); w.draw(); drawText(tr("Sel channel"), keyx + 496, keyy + 5, Colour::LIGHTTEXT); - surface->fillblt(keyx + 474, keyy + Surface::getFontHeight() + 8, 128, Surface::getFontHeight() + 2, surface->rgba( 180, 180, 180, 255)); + rectangle(keyx + 474, keyy + Surface::getFontHeight() + 8, 128, Surface::getFontHeight() + 2, Colour(180, 180, 180, 255)); drawText(tr("Go: Preview"), keyx + 476, keyy + Surface::getFontHeight() + 9, Colour::LIGHTTEXT); // Draw all the dynamic data @@ -425,19 +425,19 @@ void VEpg::drawgrid() // redraws grid and select programme drawTextRJ(timeString, timex - 10, timey, Colour::LIGHTTEXT); // print date strftime(timeString, 19, "%H:%M", tms); drawText(timeString, timex, timey, Colour::LIGHTTEXT); // print left time - surface->fillblt(155, timey + Surface::getFontHeight(), 2, 7, surface->rgba(255, 255, 255, 255)); + rectangle(155, timey + Surface::getFontHeight(), 2, 7, Colour(255, 255, 255, 255)); t = t + 3600; tms = localtime(&t); strftime(timeString, 19, "%H:%M", tms); drawText(timeString, timex + 180, timey, Colour::LIGHTTEXT); // print middle time - surface->fillblt(335, timey + Surface::getFontHeight(), 2, 7, surface->rgba(255, 255, 255, 255)); + rectangle(335, timey + Surface::getFontHeight(), 2, 7, Colour(255, 255, 255, 255)); t = t + 3600; tms = localtime(&t); strftime(timeString, 19, "%H:%M", tms); drawText(timeString, timex + 360, timey, Colour::LIGHTTEXT); // print right time - surface->fillblt(515, timey + Surface::getFontHeight(), 2, 7, surface->rgba(255, 255, 255, 255)); + rectangle(515, timey + Surface::getFontHeight(), 2, 7, Colour(255, 255, 255, 255)); // pointer to selTime - surface->fillblt(155 + (selTime - ltime) / 20, timey + Surface::getFontHeight(), 2, 7, surface->rgba(255, 50, 50, 255)); + rectangle(155 + (selTime - ltime) / 20, timey + Surface::getFontHeight(), 2, 7, Colour(255, 50, 50, 255)); // TODO should the above two comditional statements be combined to avoid calling updateEventList() twice? Event* event; @@ -587,7 +587,7 @@ void VEpg::paintCell(Event* event, int yOffset, Colour bg, Colour fg) } if (w > 155 + WINDOW_WIDTH * MINUTE_SCALE - x) w = 155 + WINDOW_WIDTH * MINUTE_SCALE -x; // limit cells to RHS of window - surface->fillblt(x, y, w, h, surface->rgba(bg.red, bg.green, bg.blue, bg.alpha)); + rectangle(x, y, w, h, bg); char* tt = new char[strlen(event->title) + 1]; strcpy (tt, event->title); int textWidth = 0; @@ -606,7 +606,7 @@ void VEpg::paintCell(Event* event, int yOffset, Colour bg, Colour fg) { strncpy(tT, tt, textWidth - 1); tT[textWidth - 1] = '\0'; - surface->drawText(tT, x+2, y, fg.red, fg.green, fg.blue); + surface->drawText(tT, x+2, y, fg.rgba()); } delete tT; diff --git a/view.cc b/view.cc index efeb07b..962069f 100644 --- a/view.cc +++ b/view.cc @@ -50,7 +50,7 @@ bool View::create(UINT w, UINT h) area.w = w; area.h = h; - surface = new Surface(); + surface = new Surface_TYPE(); return surface->create(area.w, area.h); } diff --git a/viewman.cc b/viewman.cc index 0ddc920..99e88c6 100644 --- a/viewman.cc +++ b/viewman.cc @@ -330,13 +330,6 @@ void ViewMan::boxSplit(Region r, int start, int end, int direction, RegionList& } } -// TEMP -void ViewMan::drawBlack(Region& r) -{ - Surface* surface = Surface::getScreen(); - surface->fillblt(r.x, r.y, r.w, r.h, surface->rgba(0, 0, 0, 255)); -} - ///////////////////////////////////////////////////////////////////////////// // END NEW STUFF ///////////////////////////////////////////////////////////////////////////// diff --git a/viewman.h b/viewman.h index 6fc3d2b..5b4643a 100644 --- a/viewman.h +++ b/viewman.h @@ -72,7 +72,6 @@ class ViewMan : public MessageQueue void deleteView(int z); void repaintRevealed(int x, Region r); void boxSplit(Region r, int start, int end, int direction, RegionList& rl); - void drawBlack(Region& r); }; #endif -- 2.39.2