aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
Diffstat (limited to 'backends')
-rw-r--r--backends/platform/sdl/graphics.cpp152
-rw-r--r--backends/platform/sdl/sdl.cpp3
-rw-r--r--backends/platform/sdl/sdl.h7
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;