From bb195d033fe390421d2be998b1784b390e7e9d77 Mon Sep 17 00:00:00 2001 From: knakos Date: Tue, 24 Jan 2006 22:57:55 +0000 Subject: [PATCH] add support for raw framebuffer access method. QVGA smartphone support in. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@980 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- stella/src/wince/FrameBufferWinCE.cpp | 125 ++++++++++++++++++++------ stella/src/wince/FrameBufferWinCE.hxx | 31 ++++++- stella/src/wince/OSystemWinCE.cxx | 6 +- stella/src/wince/OSystemWinCE.hxx | 1 + 4 files changed, 128 insertions(+), 35 deletions(-) diff --git a/stella/src/wince/FrameBufferWinCE.cpp b/stella/src/wince/FrameBufferWinCE.cpp index 8e6f6138c..5088f724e 100644 --- a/stella/src/wince/FrameBufferWinCE.cpp +++ b/stella/src/wince/FrameBufferWinCE.cpp @@ -26,18 +26,70 @@ FrameBufferWinCE::FrameBufferWinCE(OSystem *osystem) : FrameBuffer(osystem), myDstScreen(NULL), SubsystemInited(false), displacement(0), - issmartphone(true), islandscape(false), displaymode(0) +issmartphone(true), islandscape(false), displaymode(0), legacygapi(true), devres(SM_LOW) { + gxdp.cxWidth = gxdp.cyHeight = gxdp.cbxPitch = gxdp.cbyPitch = gxdp.cBPP = gxdp.ffFormat = 0; } FrameBufferWinCE::~FrameBufferWinCE() { } +void FrameBufferWinCE::GetDeviceProperties(void) +{ + if (gxdp.cxWidth) return; + + // screen access mode + gxdp = GXGetDisplayProperties(); + legacygapi = true; + if (((unsigned int) GetSystemMetrics(SM_CXSCREEN) != gxdp.cxWidth) || ((unsigned int) GetSystemMetrics(SM_CYSCREEN) != gxdp.cyHeight)) + { + // 2003SE+ and lying about the resolution. good luck. + legacygapi = false; + + RawFrameBufferInfo rfbi; + HDC hdc = GetDC(NULL); + ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi); + ReleaseDC(NULL, hdc); + + if (rfbi.wFormat == FORMAT_565) + gxdp.ffFormat = kfDirect565; + else if (rfbi.wFormat == FORMAT_555) + gxdp.ffFormat = kfDirect555; + else + gxdp.ffFormat = 0; + gxdp.cBPP = rfbi.wBPP; + gxdp.cbxPitch = rfbi.cxStride; + gxdp.cbyPitch = rfbi.cyStride; + gxdp.cxWidth = rfbi.cxPixels; + gxdp.cyHeight = rfbi.cyPixels; + } + + // device detection (some redundancy here, but nevermind :) + TCHAR platform[100]; + issmartphone = false; + if (gxdp.cxWidth == 176 && gxdp.cyHeight == 220) + issmartphone = true; + if (SystemParametersInfo(SPI_GETPLATFORMTYPE, 100, platform, 0)) + { + if (wcsstr(platform, _T("mart"))) + issmartphone = true; + } + else + issmartphone = true; // most likely + + if (gxdp.cxWidth == 176 && gxdp.cyHeight == 220) + devres = SM_LOW; + /*else if (gxdp.cxWidth == 480 && gxdp.cyHeight == 640) + devres = VGA;*/ + else + devres = QVGA; +} + void FrameBufferWinCE::setPalette(const uInt32* palette) { //setup palette - gxdp = GXGetDisplayProperties(); + GetDeviceProperties(); for (uInt16 i=0; i<256; i++) { uInt8 r = (uInt8) ((palette[i] & 0xFF0000) >> 16); @@ -55,7 +107,7 @@ void FrameBufferWinCE::setPalette(const uInt32* palette) bool FrameBufferWinCE::initSubsystem() { - gxdp = GXGetDisplayProperties(); + GetDeviceProperties(); for (int i=0; iconsole().mediaSource().height(); myWidthdiv4 = myWidth >> 2; - if (issmartphone) + if (devres == SM_LOW) if (!islandscape) w = myWidth; else w = (int) ((float) myWidth * 11.0f / 8.0f + 0.5f); - else + else //if (devres == QVGA) if (!islandscape) w = (int) ((float) myWidth * 3.0f / 2.0f + 0.5f); else w = myWidth * 2; - - if (issmartphone && islandscape) + /*else + { + // VGA + } + */ + if (devres == SM_LOW && islandscape) h = (int) ((float) myHeight * 4.0f / 5.0f + 0.5f); else h = myHeight; @@ -208,7 +264,18 @@ void FrameBufferWinCE::lateinit(void) void FrameBufferWinCE::preFrameUpdate() { - myDstScreen = (uInt8 *) GXBeginDraw(); + static HDC hdc; + static RawFrameBufferInfo rfbi; + + if (legacygapi) + myDstScreen = (uInt8 *) GXBeginDraw(); + else + { + hdc = GetDC(NULL); + ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi); + ReleaseDC(NULL, hdc); + myDstScreen = (uInt8 *) rfbi.pFramePointer; + } } void FrameBufferWinCE::drawMediaSource() @@ -236,7 +303,7 @@ void FrameBufferWinCE::drawMediaSource() theRedrawTIAIndicator = false; } - if (issmartphone && islandscape == 0) + if (devres == SM_LOW && !islandscape) { // straight for (y=0; yconsole().mediaSource().previousFrameBuffer(); memset(s, 0, myWidth*myHeight-1); - if ( (d = (uInt8 *) GXBeginDraw()) == NULL ) - return; - for (int i=0; i < scrwidth*scrheight; i++, *((uInt16 *)d) = 0, d += scrpixelstep); - GXEndDraw(); + preFrameUpdate(); + //uInt8 *d; + //d=myDstScreen; + //for (int i=0; i < scrwidth*scrheight; i++, *((uInt16 *)d) = 0, d += scrpixelstep); + memset(myDstScreen, 0, scrwidth*scrheight*2); + postFrameUpdate(); } void FrameBufferWinCE::postFrameUpdate() { - GXEndDraw(); + if (legacygapi) GXEndDraw(); } void FrameBufferWinCE::drawChar(const GUI::Font* font, uInt8 c, uInt32 x, uInt32 y, OverlayColor color) @@ -488,7 +555,7 @@ void FrameBufferWinCE::drawChar(const GUI::Font* font, uInt8 c, uInt32 x, uInt32 uInt8 *d; uInt32 stride; - if (issmartphone) + if (devres == SM_LOW) { d = myDstScreen + y * scrlinestep + ((x+1) >> 1) * scrpixelstep; stride = (scrwidth - w) * scrpixelstep; @@ -506,7 +573,7 @@ void FrameBufferWinCE::drawChar(const GUI::Font* font, uInt8 c, uInt32 x, uInt32 for(int y2 = 0; y2 < h; y2++) { const uInt16 buffer = *tmp++; - if (issmartphone) + if (devres == SM_LOW) { uInt16 mask = 0xC000; for(int x2 = 0; x2 < w; x2++, mask >>= 2) @@ -565,7 +632,7 @@ uInt32 FrameBufferWinCE::mapRGB(Uint8 r, Uint8 g, Uint8 b) void FrameBufferWinCE::hLine(uInt32 x, uInt32 y, uInt32 x2, OverlayColor color) { - if (issmartphone) + if (devres == SM_LOW) { int kx = x >> 1; int ky = y; int kx2 = x2>> 1; if (kx<0) kx=0; if (ky<0) ky=0; if (ky>scrheight-1) return; if (kx2>scrwidth-1) kx2=scrwidth-1; @@ -589,10 +656,10 @@ void FrameBufferWinCE::PlothLine(uInt32 x, uInt32 y, uInt32 x2, OverlayColor col void FrameBufferWinCE::vLine(uInt32 x, uInt32 y, uInt32 y2, OverlayColor color) { - if (issmartphone) + if (devres == SM_LOW) { int kx = x >> 1; int ky = y; int ky2 = y2; - if (kx<0) kx=0; if (ky<0) ky=0; if (kx>scrwidth-1) return; if (ky2>scrheight-1) ky2=scrheight-1; + if (kx<0) kx=0; if (ky<0) ky=0; if (kx>scrwidth-1) return; if (ky>scrheight-1) ky=scrheight-1; if (ky2>scrheight-1) ky2=scrheight-1; PlotvLine(kx, ky, ky2, color); } else @@ -614,7 +681,7 @@ void FrameBufferWinCE::PlotvLine(uInt32 x, uInt32 y, uInt32 y2, OverlayColor col void FrameBufferWinCE::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, OverlayColor color) { - if (issmartphone) + if (devres == SM_LOW) { int kx = x >> 1; int ky = y; int kw = (w >> 1); int kh = h; if (ky>scrheight-1) return; if (kx>scrwidth-1) return; diff --git a/stella/src/wince/FrameBufferWinCE.hxx b/stella/src/wince/FrameBufferWinCE.hxx index 4acab96d9..e36f1e156 100644 --- a/stella/src/wince/FrameBufferWinCE.hxx +++ b/stella/src/wince/FrameBufferWinCE.hxx @@ -24,6 +24,26 @@ #include "FrameBuffer.hxx" #include "OSystem.hxx" + +// The necessary nonsense for extended resolutions +#define GETRAWFRAMEBUFFER 0x00020001 + +#define FORMAT_565 1 +#define FORMAT_555 2 +#define FORMAT_OTHER 3 + +typedef struct _RawFrameBufferInfo +{ + WORD wFormat; + WORD wBPP; + VOID *pFramePointer; + int cxStride; + int cyStride; + int cxPixels; + int cyPixels; +} RawFrameBufferInfo; + + class FrameBufferWinCE : public FrameBuffer { public: @@ -32,8 +52,8 @@ class FrameBufferWinCE : public FrameBuffer ~FrameBufferWinCE(); virtual void setPalette(const uInt32* palette); virtual bool initSubsystem(); - virtual BufferType type() { return kSoftBuffer; } - virtual void setAspectRatio() ; + virtual BufferType type() { return kSoftBuffer; } + virtual void setAspectRatio() ; virtual bool createScreen(); virtual void toggleFilter(); virtual void drawMediaSource(); @@ -48,8 +68,10 @@ class FrameBufferWinCE : public FrameBuffer virtual void drawBitmap(uInt32* bitmap, Int32 x, Int32 y, OverlayColor color, Int32 h = 8); virtual void translateCoords(Int32* x, Int32* y); virtual void addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h); + virtual void enablePhosphor(bool enable) { return; }; virtual uInt32 lineDim(); void wipescreen(void); + virtual void cls() { return; }; void setmode(uInt8 mode); uInt8 rotatedisplay(void); @@ -59,6 +81,7 @@ class FrameBufferWinCE : public FrameBuffer void PlothLine(uInt32 x, uInt32 y, uInt32 x2, OverlayColor color); void PlotvLine(uInt32 x, uInt32 y, uInt32 y2, OverlayColor color); void PlotfillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, OverlayColor color); + void GetDeviceProperties(void); uInt16 pal[256], myWidth, myWidthdiv4, myHeight, guipal[kNumColors-256], scrwidth, scrheight; Int32 pixelstep, linestep, scrpixelstep, scrlinestep; @@ -66,7 +89,8 @@ class FrameBufferWinCE : public FrameBuffer bool SubsystemInited; uInt8 *myDstScreen; - bool issmartphone, islandscape; + bool issmartphone, islandscape, legacygapi; + enum {SM_LOW, QVGA, VGA} devres; uInt16 minydim, optgreenmaskN, optgreenmask; Int32 pixelsteptimes5, pixelsteptimes6; GXDisplayProperties gxdp; @@ -74,6 +98,7 @@ class FrameBufferWinCE : public FrameBuffer public: bool IsSmartphone(void) { return issmartphone; } + bool IsSmartphoneLowRes(void) { return (issmartphone && devres==SM_LOW); } uInt8 getmode(void) { return displaymode; } }; diff --git a/stella/src/wince/OSystemWinCE.cxx b/stella/src/wince/OSystemWinCE.cxx index d4ca0d363..b6f059040 100644 --- a/stella/src/wince/OSystemWinCE.cxx +++ b/stella/src/wince/OSystemWinCE.cxx @@ -74,7 +74,7 @@ void OSystemWinCE::mainLoop() // Main game loop MSG msg; int laststate = -1; - if (!((FrameBufferWinCE *)myFrameBuffer)->IsSmartphone()) + if (!((FrameBufferWinCE *)myFrameBuffer)->IsSmartphoneLowRes()) { lastkeyset = 0; KeySetMode(1); @@ -113,7 +113,7 @@ void OSystemWinCE::mainLoop() } else { - if ( ((FrameBufferWinCE *)myFrameBuffer)->IsSmartphone() ) + if ( ((FrameBufferWinCE *)myFrameBuffer)->IsSmartphoneLowRes() ) { KeySetMode(0); ((FrameBufferWinCE *)myFrameBuffer)->setmode(0); @@ -165,7 +165,7 @@ uInt32 OSystemWinCE::getTicks(void) inline const GUI::Font& OSystemWinCE::font() const { - if ( ((FrameBufferWinCE *)myFrameBuffer)->IsSmartphone() ) + if ( ((FrameBufferWinCE *)myFrameBuffer)->IsSmartphoneLowRes() ) return consoleFont(); else return OSystem::font(); diff --git a/stella/src/wince/OSystemWinCE.hxx b/stella/src/wince/OSystemWinCE.hxx index ea783b405..47695c737 100644 --- a/stella/src/wince/OSystemWinCE.hxx +++ b/stella/src/wince/OSystemWinCE.hxx @@ -32,6 +32,7 @@ class OSystemWinCE : public OSystem virtual void mainLoop(); virtual uInt32 getTicks(void); virtual void setFramerate(uInt32 framerate); + virtual void getScreenDimensions(int& width, int& height) { width = GetSystemMetrics(SM_CXSCREEN); height = GetSystemMetrics(SM_CYSCREEN); }; inline const GUI::Font& font() const; };