diff options
Diffstat (limited to 'backends')
-rw-r--r-- | backends/platform/sdl/graphics.cpp | 152 | ||||
-rw-r--r-- | backends/platform/sdl/sdl.cpp | 3 | ||||
-rw-r--r-- | backends/platform/sdl/sdl.h | 7 |
3 files changed, 160 insertions, 2 deletions
diff --git a/backends/platform/sdl/graphics.cpp b/backends/platform/sdl/graphics.cpp index 78b8bd8c63..fadd7a376c 100644 --- a/backends/platform/sdl/graphics.cpp +++ b/backends/platform/sdl/graphics.cpp @@ -407,6 +407,20 @@ bool OSystem_SDL::loadGFXMode() { } } +#ifdef ENABLE_16BIT + // + // Create the surface that contains the 16 bit game data + // + _screen16 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, + 16, + 0x7C00, + 0x3E0, + 0x1F, + 0); //555, not 565 + if (_screen16 == NULL) + error("allocating _screen16 failed"); +#endif + // // Create the surface used for the graphics in 16 bit before scaling, and also the overlay // @@ -484,10 +498,17 @@ bool OSystem_SDL::loadGFXMode() { } void OSystem_SDL::unloadGFXMode() { +#ifdef ENABLE_16BIT + if (_screen16) { + SDL_FreeSurface(_screen16); + _screen16 = NULL; + } +#else if (_screen) { SDL_FreeSurface(_screen); _screen = NULL; } +#endif if (_hwscreen) { SDL_FreeSurface(_hwscreen); @@ -519,14 +540,23 @@ void OSystem_SDL::unloadGFXMode() { } bool OSystem_SDL::hotswapGFXMode() { +#ifdef ENABLE_16BIT + if (!_screen16) +#else if (!_screen) +#endif return false; // Keep around the old _screen & _overlayscreen so we can restore the screen data // after the mode switch. +#ifdef ENABLE_16BIT + SDL_Surface *old_screen = _screen16; + _screen16 = NULL; +#else SDL_Surface *old_screen = _screen; - SDL_Surface *old_overlayscreen = _overlayscreen; _screen = NULL; +#endif + SDL_Surface *old_overlayscreen = _overlayscreen; _overlayscreen = NULL; // Release the HW screen surface @@ -544,7 +574,11 @@ bool OSystem_SDL::hotswapGFXMode() { if (!loadGFXMode()) { unloadGFXMode(); +#ifdef ENABLE_16BIT + _screen16 = old_screen; +#else _screen = old_screen; +#endif _overlayscreen = old_overlayscreen; return false; @@ -554,7 +588,11 @@ bool OSystem_SDL::hotswapGFXMode() { SDL_SetColors(_screen, _currentPalette, 0, 256); // Restore old screen content +#ifdef ENABLE_16BIT + SDL_BlitSurface(old_screen, NULL, _screen16, NULL); +#else SDL_BlitSurface(old_screen, NULL, _screen, NULL); +#endif SDL_BlitSurface(old_overlayscreen, NULL, _overlayscreen, NULL); // Free the old surfaces @@ -636,7 +674,11 @@ void OSystem_SDL::internUpdateScreen() { #endif if (!_overlayVisible) { +#ifdef ENABLE_16BIT + origSurf = _screen16; +#else origSurf = _screen; +#endif srcSurf = _tmpscreen; width = _videoMode.screenWidth; height = _videoMode.screenHeight; @@ -781,6 +823,12 @@ void OSystem_SDL::copyRectToScreen(const byte *src, int pitch, int x, int y, int assert (_transactionMode == kTransactionNone); assert(src); +#ifdef ENABLE_16BIT + if (_screen16 == NULL) { + warning("OSystem_SDL::copyRectToScreen: _screen16 == NULL"); + return; + } +#endif if (_screen == NULL) { warning("OSystem_SDL::copyRectToScreen: _screen == NULL"); return; @@ -829,11 +877,29 @@ void OSystem_SDL::copyRectToScreen(const byte *src, int pitch, int x, int y, int } // Try to lock the screen surface +#ifdef ENABLE_16BIT + if (SDL_LockSurface(_screen16) == -1) +#else if (SDL_LockSurface(_screen) == -1) +#endif error("SDL_LockSurface failed: %s", SDL_GetError()); - byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x; +#ifdef ENABLE_16BIT + byte *dst = (byte *)_screen16->pixels + y * _videoMode.screenWidth * 2 + x * 2; + if (_videoMode.screenWidth == w && pitch == w * 2) { + memcpy(dst, src, h*w*2); + } else { + do { + memcpy(dst, src, w * 2); + src += pitch; + dst += _videoMode.screenWidth * 2; + } while (--h); + } + // Unlock the screen surface + SDL_UnlockSurface(_screen16); +#else + byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x; if (_videoMode.screenWidth == pitch && pitch == w) { memcpy(dst, src, h*w); } else { @@ -846,6 +912,7 @@ void OSystem_SDL::copyRectToScreen(const byte *src, int pitch, int x, int y, int // Unlock the screen surface SDL_UnlockSurface(_screen); +#endif } Graphics::Surface *OSystem_SDL::lockScreen() { @@ -859,14 +926,26 @@ Graphics::Surface *OSystem_SDL::lockScreen() { _screenIsLocked = true; // Try to lock the screen surface +#ifdef ENABLE_16BIT + if (SDL_LockSurface(_screen16) == -1) +#else if (SDL_LockSurface(_screen) == -1) +#endif error("SDL_LockSurface failed: %s", SDL_GetError()); +#ifdef ENABLE_16BIT + _framebuffer.pixels = _screen16->pixels; + _framebuffer.w = _screen16->w; + _framebuffer.h = _screen16->h; + _framebuffer.pitch = _screen16->pitch; + _framebuffer.bytesPerPixel = 2; +#else _framebuffer.pixels = _screen->pixels; _framebuffer.w = _screen->w; _framebuffer.h = _screen->h; _framebuffer.pitch = _screen->pitch; _framebuffer.bytesPerPixel = 1; +#endif return &_framebuffer; } @@ -879,7 +958,11 @@ void OSystem_SDL::unlockScreen() { _screenIsLocked = false; // Unlock the screen surface +#ifdef ENABLE_16BIT + SDL_UnlockSurface(_screen16); +#else SDL_UnlockSurface(_screen); +#endif // Trigger a full screen update _forceFull = true; @@ -1054,8 +1137,13 @@ void OSystem_SDL::setPalette(const byte *colors, uint start, uint num) { // since we don't actually set the palette until the screen is updated. // But it could indicate a programming error, so let's warn about it. +#ifdef ENABLE_16BIT + if (!_screen16) + warning("OSystem_SDL::setPalette: _screen16 == NULL"); +#else if (!_screen) warning("OSystem_SDL::setPalette: _screen == NULL"); +#endif const byte *b = colors; uint i; @@ -1179,7 +1267,11 @@ void OSystem_SDL::clearOverlay() { dst.x = dst.y = 1; src.w = dst.w = _videoMode.screenWidth; src.h = dst.h = _videoMode.screenHeight; +#ifdef ENABLE_16BIT + if (SDL_BlitSurface(_screen16, &src, _tmpscreen, &dst) != 0) +#else if (SDL_BlitSurface(_screen, &src, _tmpscreen, &dst) != 0) +#endif error("SDL_BlitSurface failed: %s", SDL_GetError()); SDL_LockSurface(_tmpscreen); @@ -1311,6 +1403,49 @@ void OSystem_SDL::warpMouse(int x, int y) { } } +#ifdef ENABLE_16BIT +void OSystem_SDL::setMouseCursor16(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint16 keycolor, int cursorTargetScale) { + if (w == 0 || h == 0) + return; + + _mouseCurState.hotX = hotspot_x; + _mouseCurState.hotY = hotspot_y; + + _mouseKeyColor = keycolor; + + _cursorTargetScale = cursorTargetScale; + + if (_mouseCurState.w != (int)w || _mouseCurState.h != (int)h) { + _mouseCurState.w = w; + _mouseCurState.h = h; + + if (_mouseOrigSurface) + SDL_FreeSurface(_mouseOrigSurface); + + // Allocate bigger surface because AdvMame2x adds black pixel at [0,0] + _mouseOrigSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, + _mouseCurState.w + 2, + _mouseCurState.h + 2, + 16, + _hwscreen->format->Rmask, + _hwscreen->format->Gmask, + _hwscreen->format->Bmask, + _hwscreen->format->Amask); + + if (_mouseOrigSurface == NULL) + error("allocating _mouseOrigSurface failed"); + SDL_SetColorKey(_mouseOrigSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, kMouseColorKey); + } + + free(_mouseData); + + _mouseData = (byte *)malloc(w * h * 2); + memcpy(_mouseData, buf, w * h * 2); + + blitCursor(); +} +#endif + void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale) { if (w == 0 || h == 0) return; @@ -1348,6 +1483,7 @@ void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, _mouseData = (byte *)malloc(w * h); memcpy(_mouseData, buf, w * h); + blitCursor(); } @@ -1389,12 +1525,24 @@ void OSystem_SDL::blitCursor() { for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { color = *srcPtr; +#ifdef ENABLE_16BIT + if (color != _mouseKeyColor) { // transparent, don't draw + int8 r = ((*(uint16 *)srcPtr >> 10) & 0x1F) << 3; + int8 g = ((*(uint16 *)srcPtr >> 5) & 0x1F) << 3; + int8 b = (*(uint16 *)srcPtr & 0x1F) << 3; + *(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format, + r, g, b); + } + dstPtr += 2; + srcPtr += 2; +#else if (color != _mouseKeyColor) { // transparent, don't draw *(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format, palette[color].r, palette[color].g, palette[color].b); } dstPtr += 2; srcPtr++; +#endif } dstPtr += _mouseOrigSurface->pitch - w * 2; } diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index c11c97c041..b91d6938a2 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -196,6 +196,9 @@ OSystem_SDL::OSystem_SDL() _osdSurface(0), _osdAlpha(SDL_ALPHA_TRANSPARENT), _osdFadeStartTime(0), #endif _hwscreen(0), _screen(0), _tmpscreen(0), +#ifdef ENABLE_16BIT + _screen16(0), +#endif _overlayVisible(false), _overlayscreen(0), _tmpscreen2(0), _samplesPerSec(0), diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index 7498f48b08..3e0bf19f8f 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -112,6 +112,10 @@ public: virtual void warpMouse(int x, int y); // overloaded by CE backend (FIXME) // Set the bitmap that's used when drawing the cursor. +#ifdef ENABLE_16BIT + //HACK Made a second method as a quick and dirty workaround to avoid linker errors with engine libs + virtual void setMouseCursor16(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint16 keycolor, int cursorTargetScale); // overloaded by CE backend (FIXME) +#endif virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale); // overloaded by CE backend (FIXME) // Set colors of cursor palette @@ -227,6 +231,9 @@ protected: // unseen game screen SDL_Surface *_screen; +#ifdef ENABLE_16BIT + SDL_Surface *_screen16; +#endif // temporary screen (for scalers) SDL_Surface *_tmpscreen; |