aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
authorEugene Sandulenko2005-03-09 23:07:32 +0000
committerEugene Sandulenko2005-03-09 23:07:32 +0000
commit7bb53f3bf10acf3b97d635b75e50b3c51b2ff862 (patch)
treeab25d421bbffb9d1e43079b3b40b2bab0e0fd820 /backends
parentb72df416a64642d180e9b746484ce292d845fae4 (diff)
downloadscummvm-rg350-7bb53f3bf10acf3b97d635b75e50b3c51b2ff862.tar.gz
scummvm-rg350-7bb53f3bf10acf3b97d635b75e50b3c51b2ff862.tar.bz2
scummvm-rg350-7bb53f3bf10acf3b97d635b75e50b3c51b2ff862.zip
Patch #1013937 "OSystem layer with bigger resolution". Now you will always
get at least 640x400 window. And finally we have means of implementing nice looking GUI. Also updated all backends. If your backend has ability to run with 640x400 or 640x480 resolution then read patch tracker item to find out details. Other port maintainers shouldn't worry, as this patch doesn't affect them, they still get their 320x200. svn-id: r17055
Diffstat (limited to 'backends')
-rw-r--r--backends/PalmOS/Src/palm.h2
-rw-r--r--backends/PalmOS/Src/palmgfx.cpp2
-rw-r--r--backends/dc/dc.h2
-rw-r--r--backends/dc/display.cpp2
-rw-r--r--backends/gp32/gp32.cpp2
-rw-r--r--backends/gp32/gp32.h2
-rw-r--r--backends/morphos/morphos.cpp2
-rw-r--r--backends/morphos/morphos.h2
-rw-r--r--backends/null/null.cpp4
-rw-r--r--backends/sdl/events.cpp9
-rw-r--r--backends/sdl/graphics.cpp351
-rw-r--r--backends/sdl/sdl-common.h20
-rw-r--r--backends/sdl/sdl.cpp3
-rw-r--r--backends/wince/wince-sdl.cpp4
-rw-r--r--backends/wince/wince-sdl.h2
-rw-r--r--backends/x11/x11.cpp4
16 files changed, 274 insertions, 139 deletions
diff --git a/backends/PalmOS/Src/palm.h b/backends/PalmOS/Src/palm.h
index 996c49a912..a46ea7e318 100644
--- a/backends/PalmOS/Src/palm.h
+++ b/backends/PalmOS/Src/palm.h
@@ -82,7 +82,7 @@ public:
// Set the size of the video bitmap.
// Typically, 320x200
- void initSize(uint w, uint h);
+ void initSize(uint w, uint h, int overlayScale);
// Draw a bitmap to screen.
// The screen will not be updated to reflect the new bitmap
diff --git a/backends/PalmOS/Src/palmgfx.cpp b/backends/PalmOS/Src/palmgfx.cpp
index 4abf13e061..594d6645a7 100644
--- a/backends/PalmOS/Src/palmgfx.cpp
+++ b/backends/PalmOS/Src/palmgfx.cpp
@@ -78,7 +78,7 @@ bool OSystem_PALMOS::setGraphicsMode(int mode) {
return true;
}
-void OSystem_PALMOS::initSize(uint w, uint h) {
+void OSystem_PALMOS::initSize(uint w, uint h, int overlayScale) {
_screenWidth = w;
_screenHeight = h;
_offScreenPitch = gVars->screenPitch; // direct screen / flipping use this, reset later if buffered
diff --git a/backends/dc/dc.h b/backends/dc/dc.h
index 76d4f612af..cf6fd59726 100644
--- a/backends/dc/dc.h
+++ b/backends/dc/dc.h
@@ -67,7 +67,7 @@ class OSystem_Dreamcast : public OSystem {
// Set the size of the video bitmap.
// Typically, 320x200
- void initSize(uint w, uint h);
+ void initSize(uint w, uint h, int overlayScale);
int16 getHeight() { return _screen_h; }
int16 getWidth() { return _screen_w; }
diff --git a/backends/dc/display.cpp b/backends/dc/display.cpp
index c6a5bee176..040eb0dec5 100644
--- a/backends/dc/display.cpp
+++ b/backends/dc/display.cpp
@@ -157,7 +157,7 @@ void OSystem_Dreamcast::setScaling()
}
}
-void OSystem_Dreamcast::initSize(uint w, uint h)
+void OSystem_Dreamcast::initSize(uint w, uint h, int overlayScale)
{
assert(w <= SCREEN_W && h <= SCREEN_H);
diff --git a/backends/gp32/gp32.cpp b/backends/gp32/gp32.cpp
index c8912ed166..0ff9827a0a 100644
--- a/backends/gp32/gp32.cpp
+++ b/backends/gp32/gp32.cpp
@@ -229,7 +229,7 @@ const char shortkey3[] = "wlptuo"; // samnmax
const char *shortkey;
int skindex = 0;
-void OSystem_GP32::initSize(uint w, uint h) {
+void OSystem_GP32::initSize(uint w, uint h, int overlayScale) {
/*switch (menu[MENU_SCREENPOS].index) {
* case 0 : scrofsy = 239 - (240 - h)/2; break;
* case 1 : scrofsy = 239; break;
diff --git a/backends/gp32/gp32.h b/backends/gp32/gp32.h
index b5a9db6ee3..9b32f64255 100644
--- a/backends/gp32/gp32.h
+++ b/backends/gp32/gp32.h
@@ -88,7 +88,7 @@ public:
// Set the size of the video bitmap.
// Typically, 320x200
- void initSize(uint w, uint h);
+ void initSize(uint w, uint h, int overlayScale);
int16 getHeight() { return _screenHeight; }
int16 getWidth() { return _screenWidth; }
diff --git a/backends/morphos/morphos.cpp b/backends/morphos/morphos.cpp
index 5092ead8a7..987e43178e 100644
--- a/backends/morphos/morphos.cpp
+++ b/backends/morphos/morphos.cpp
@@ -1455,7 +1455,7 @@ void OSystem_MorphOS::clearSoundCallback()
}
}
-void OSystem_MorphOS::initSize(uint w, uint h)
+void OSystem_MorphOS::initSize(uint w, uint h, int overlayScale)
{
if (ScummBuffer)
{
diff --git a/backends/morphos/morphos.h b/backends/morphos/morphos.h
index 30c7c04edf..f1a99f3803 100644
--- a/backends/morphos/morphos.h
+++ b/backends/morphos/morphos.h
@@ -47,7 +47,7 @@ class OSystem_MorphOS : public OSystem
// Set the size of the video bitmap.
// Typically, 320x200
- virtual void initSize(uint w, uint h);
+ virtual void initSize(uint w, uint h, int overlayScale);
// Draw a bitmap to screen.
// The screen will not be updated to reflect the new bitmap
diff --git a/backends/null/null.cpp b/backends/null/null.cpp
index 3c5b0bd5b0..a85c83d8be 100644
--- a/backends/null/null.cpp
+++ b/backends/null/null.cpp
@@ -45,7 +45,7 @@ public:
virtual bool setGraphicsMode(int mode);
bool setGraphicsMode(const char *name);
virtual int getGraphicsMode() const;
- virtual void initSize(uint width, uint height);
+ virtual void initSize(uint width, uint height, int overlayScale);
virtual int16 getHeight();
virtual int16 getWidth();
virtual void setPalette(const byte *colors, uint start, uint num);
@@ -153,7 +153,7 @@ int OSystem_NULL::getGraphicsMode() const
return -1;
}
-void OSystem_NULL::initSize(uint width, uint height)
+void OSystem_NULL::initSize(uint width, uint height, int overlayScale)
{
}
diff --git a/backends/sdl/events.cpp b/backends/sdl/events.cpp
index e29616fbea..4185fcef37 100644
--- a/backends/sdl/events.cpp
+++ b/backends/sdl/events.cpp
@@ -68,8 +68,13 @@ void OSystem_SDL::fillMouseEvent(Event &event, int x, int y) {
_km.y = y;
// Adjust for the screen scaling
- event.mouse.x /= _scaleFactor;
- event.mouse.y /= _scaleFactor;
+ if (!_overlayVisible) {
+ event.mouse.x /= _scaleFactor;
+ event.mouse.y /= _scaleFactor;
+ } else {
+ event.mouse.x = event.mouse.x / _scaleFactor * _overlayScale;
+ event.mouse.y = event.mouse.y / _scaleFactor * _overlayScale;
+ }
// Optionally perform aspect ratio adjusting
if (_adjustAspectRatio)
diff --git a/backends/sdl/graphics.cpp b/backends/sdl/graphics.cpp
index 45a142de62..44335410eb 100644
--- a/backends/sdl/graphics.cpp
+++ b/backends/sdl/graphics.cpp
@@ -66,8 +66,7 @@ void OSystem_SDL::beginGFXTransaction(void) {
_transactionMode = kTransactionActive;
_transactionDetails.modeChanged = false;
- _transactionDetails.wChanged = false;
- _transactionDetails.hChanged = false;
+ _transactionDetails.sizeChanged = false;
_transactionDetails.arChanged = false;
_transactionDetails.fsChanged = false;
@@ -83,8 +82,9 @@ void OSystem_SDL::endGFXTransaction(void) {
if (_transactionDetails.modeChanged)
setGraphicsMode(_transactionDetails.mode);
- if (_transactionDetails.wChanged || _transactionDetails.hChanged)
- initSize(_transactionDetails.w, _transactionDetails.h);
+ if (_transactionDetails.sizeChanged)
+ initSize(_transactionDetails.w, _transactionDetails.h,
+ _transactionDetails.overlayScale);
if (_transactionDetails.arChanged)
setAspectRatioCorrection(_transactionDetails.ar);
@@ -92,6 +92,7 @@ void OSystem_SDL::endGFXTransaction(void) {
if (_transactionDetails.needUnload) {
unloadGFXMode();
loadGFXMode();
+ clearOverlay();
} else {
if (!_transactionDetails.fsChanged)
if (_transactionDetails.needHotswap)
@@ -168,6 +169,16 @@ bool OSystem_SDL::setGraphicsMode(int mode) {
return false;
}
+ // Do not let switch to lesser than overlay size resolutions
+ if (_screenWidth * newScaleFactor < _overlayWidth) {
+ if (_scaleFactor == 1) { // Force 2x mode
+ mode = GFX_DOUBLESIZE;
+ newScaleFactor = 2;
+ newScalerProc = Normal2x;
+ } else
+ return false;
+ }
+
_mode = mode;
_scalerProc = newScalerProc;
@@ -226,9 +237,10 @@ int OSystem_SDL::getGraphicsMode() const {
return _mode;
}
-void OSystem_SDL::initSize(uint w, uint h) {
+void OSystem_SDL::initSize(uint w, uint h, int overlayScale) {
// Avoid redundant res changes
if ((int)w == _screenWidth && (int)h == _screenHeight &&
+ (int)overlayScale == _overlayScale &&
_transactionMode != kTransactionCommit)
return;
@@ -238,13 +250,22 @@ void OSystem_SDL::initSize(uint w, uint h) {
if (h != 200)
_adjustAspectRatio = false;
+ if (overlayScale != -1) {
+ _overlayScale = overlayScale;
+ if (w != 320)
+ _overlayScale = 1;
+
+ _overlayWidth = w * _overlayScale;
+ _overlayHeight = h * _overlayScale;
+ }
+
_cksumNum = (_screenWidth * _screenHeight / (8 * 8));
if (_transactionMode == kTransactionActive) {
_transactionDetails.w = w;
- _transactionDetails.wChanged = true;
_transactionDetails.h = h;
- _transactionDetails.hChanged = true;
+ _transactionDetails.overlayScale = _overlayScale;
+ _transactionDetails.sizeChanged = true;
_transactionDetails.needUnload = true;
@@ -257,6 +278,9 @@ void OSystem_SDL::initSize(uint w, uint h) {
if (_transactionMode != kTransactionCommit) {
unloadGFXMode();
loadGFXMode();
+
+ // if initSize() gets called in the middle, overlay is not transparent
+ clearOverlay();
}
}
@@ -264,8 +288,6 @@ void OSystem_SDL::loadGFXMode() {
_forceFull = true;
_modeFlags |= DF_UPDATE_EXPAND_1_PIXEL;
- _tmpscreen = NULL;
-
//
// Create the surface that contains the 8 bit game data
//
@@ -312,18 +334,21 @@ void OSystem_SDL::loadGFXMode() {
InitScalers(565);
// Need some extra bytes around when using 2xSaI
- _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE,
- _screenWidth + 3,
- _screenHeight + 3,
- 16,
- _hwscreen->format->Rmask,
- _hwscreen->format->Gmask,
- _hwscreen->format->Bmask,
- _hwscreen->format->Amask);
+ _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _screenWidth + 3, _screenHeight + 3, 16, 0, 0, 0, 0);
if (_tmpscreen == NULL)
error("allocating _tmpscreen failed");
-
+
+ _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth, _overlayHeight, 16, 0, 0, 0, 0);
+
+ if (_overlayscreen == NULL)
+ error("allocating _overlayscreen failed");
+
+ _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth + 3, _overlayHeight + 3, 16, 0, 0, 0, 0);
+
+ if (_tmpscreen2 == NULL)
+ error("allocating _tmpscreen2 failed");
+
#ifdef USE_OSD
_osdSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA,
_hwscreen->w,
@@ -361,6 +386,16 @@ void OSystem_SDL::unloadGFXMode() {
_tmpscreen = NULL;
}
+ if (_tmpscreen2) {
+ SDL_FreeSurface(_tmpscreen2);
+ _tmpscreen2 = NULL;
+ }
+
+ if (_overlayscreen) {
+ SDL_FreeSurface(_overlayscreen);
+ _overlayscreen = NULL;
+ }
+
#ifdef USE_OSD
if (_osdSurface) {
SDL_FreeSurface(_osdSurface);
@@ -373,14 +408,17 @@ void OSystem_SDL::hotswapGFXMode() {
if (!_screen)
return;
- // Keep around the old _screen & _tmpscreen so we can restore the screen data
+ // Keep around the old _screen & _overlayscreen so we can restore the screen data
// after the mode switch.
SDL_Surface *old_screen = _screen;
- SDL_Surface *old_tmpscreen = _tmpscreen;
+ SDL_Surface *old_overlayscreen = _overlayscreen;
// Release the HW screen surface
SDL_FreeSurface(_hwscreen);
+ SDL_FreeSurface(_tmpscreen);
+ SDL_FreeSurface(_tmpscreen2);
+
#ifdef USE_OSD
// Release the OSD surface
SDL_FreeSurface(_osdSurface);
@@ -394,11 +432,11 @@ void OSystem_SDL::hotswapGFXMode() {
// Restore old screen content
SDL_BlitSurface(old_screen, NULL, _screen, NULL);
- SDL_BlitSurface(old_tmpscreen, NULL, _tmpscreen, NULL);
-
+ SDL_BlitSurface(old_overlayscreen, NULL, _overlayscreen, NULL);
+
// Free the old surfaces
SDL_FreeSurface(old_screen);
- SDL_FreeSurface(old_tmpscreen);
+ SDL_FreeSurface(old_overlayscreen);
// Update cursor to new scale
blitCursor();
@@ -419,6 +457,11 @@ void OSystem_SDL::updateScreen() {
}
void OSystem_SDL::internUpdateScreen() {
+ SDL_Surface *srcSurf, *origSurf;
+ int height, width;
+ ScalerProc *scalerProc;
+ int scale1, scale2;
+
assert(_hwscreen != NULL);
// If the shake position changed, fill the dirty area with blackness
@@ -467,16 +510,34 @@ void OSystem_SDL::internUpdateScreen() {
}
#endif
- undrawMouse();
+ if (!_overlayVisible) {
+ origSurf = _screen;
+ srcSurf = _tmpscreen;
+ width = _screenWidth;
+ height = _screenHeight;
+ scalerProc = _scalerProc;
+ scale1 = _scaleFactor;
+ scale2 = 1;
+ } else {
+ origSurf = _overlayscreen;
+ srcSurf = _tmpscreen2;
+ width = _overlayWidth;
+ height = _overlayHeight;
+ scalerProc = scalersMagn[_overlayScale-1][_scaleFactor-1];
+
+ scale1 = _scaleFactor;
+ scale2 = _overlayScale;
+ }
// Force a full redraw if requested
if (_forceFull) {
_numDirtyRects = 1;
_dirtyRectList[0].x = 0;
_dirtyRectList[0].y = 0;
- _dirtyRectList[0].w = _screenWidth;
- _dirtyRectList[0].h = _screenHeight;
- }
+ _dirtyRectList[0].w = width;
+ _dirtyRectList[0].h = height;
+ } else
+ undrawMouse();
// Only draw anything if necessary
if (_numDirtyRects > 0) {
@@ -486,67 +547,66 @@ void OSystem_SDL::internUpdateScreen() {
uint32 srcPitch, dstPitch;
SDL_Rect *lastRect = _dirtyRectList + _numDirtyRects;
- if (_scalerProc == Normal1x && !_adjustAspectRatio) {
- SDL_Surface *target = _overlayVisible ? _tmpscreen : _screen;
+ if (scalerProc == Normal1x && !_adjustAspectRatio && 0) {
for (r = _dirtyRectList; r != lastRect; ++r) {
dst = *r;
- if (_overlayVisible) {
- // FIXME: I don't understand why this is necessary...
- dst.x--;
- dst.y--;
- }
dst.y += _currentShakePos;
- if (SDL_BlitSurface(target, r, _hwscreen, &dst) != 0)
+ if (SDL_BlitSurface(origSurf, r, _hwscreen, &dst) != 0)
error("SDL_BlitSurface failed: %s", SDL_GetError());
}
} else {
- if (!_overlayVisible) {
- for (r = _dirtyRectList; r != lastRect; ++r) {
- dst = *r;
- dst.x++; // Shift rect by one since 2xSai needs to acces the data around
- dst.y++; // any pixel to scale it, and we want to avoid mem access crashes.
- if (SDL_BlitSurface(_screen, r, _tmpscreen, &dst) != 0)
- error("SDL_BlitSurface failed: %s", SDL_GetError());
- }
+ for (r = _dirtyRectList; r != lastRect; ++r) {
+ dst = *r;
+ dst.x++; // Shift rect by one since 2xSai needs to acces the data around
+ dst.y++; // any pixel to scale it, and we want to avoid mem access crashes.
+
+ if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0)
+ error("SDL_BlitSurface failed: %s", SDL_GetError());
}
- SDL_LockSurface(_tmpscreen);
+ SDL_LockSurface(srcSurf);
SDL_LockSurface(_hwscreen);
- srcPitch = _tmpscreen->pitch;
+ srcPitch = srcSurf->pitch;
dstPitch = _hwscreen->pitch;
for (r = _dirtyRectList; r != lastRect; ++r) {
register int dst_y = r->y + _currentShakePos;
register int dst_h = 0;
register int orig_dst_y = 0;
+ register int rx1 = r->x * scale1 / scale2;
- if (dst_y < _screenHeight) {
+ if (dst_y < height) {
dst_h = r->h;
- if (dst_h > _screenHeight - dst_y)
- dst_h = _screenHeight - dst_y;
+ if (dst_h > height - dst_y)
+ dst_h = height - dst_y;
- dst_y *= _scaleFactor;
+ orig_dst_y = dst_y;
+ dst_y = dst_y * scale1 / scale2;
- if (_adjustAspectRatio) {
- orig_dst_y = dst_y;
+ if (_adjustAspectRatio)
dst_y = real2Aspect(dst_y);
+
+ if (scale1 == 3 && scale2 == 2 && _overlayVisible) {
+ if (r->y % 2)
+ r->y--;
+ dst_y -= dst_y % 3;
}
- _scalerProc((byte *)_tmpscreen->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch,
- (byte *)_hwscreen->pixels + r->x * 2 * _scaleFactor + dst_y * dstPitch, dstPitch, r->w, dst_h);
+ scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch,
+ (byte *)_hwscreen->pixels + rx1 * 2 + dst_y * dstPitch, dstPitch, r->w, dst_h);
}
-
- r->x *= _scaleFactor;
+
+ r->x = rx1;
r->y = dst_y;
- r->w *= _scaleFactor;
- r->h = dst_h * _scaleFactor;
+ r->w = r->w * scale1 / scale2;
+ r->h = dst_h * scale1 / scale2;
- if (_adjustAspectRatio && orig_dst_y / _scaleFactor < _screenHeight)
- r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y);
+ if (_adjustAspectRatio && orig_dst_y < height)
+ r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1 / scale2);
}
- SDL_UnlockSurface(_tmpscreen);
+ SDL_UnlockSurface(srcSurf);
SDL_UnlockSurface(_hwscreen);
}
@@ -564,7 +624,6 @@ void OSystem_SDL::internUpdateScreen() {
SDL_BlitSurface(_osdSurface, 0, _hwscreen, 0);
}
#endif
-
// Finally, blit all our changes to the screen
SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList);
} else {
@@ -730,14 +789,24 @@ void OSystem_SDL::addDirtyRect(int x, int y, int w, int h, bool mouseRect) {
if (_forceFull)
return;
- if (mouseRect) {
- SDL_Rect *r = &_dirtyRectList[_numDirtyRects++];
- r->x = x;
- r->y = y;
- r->w = w;
- r->h = h;
- return;
- }
+ if (mouseRect) {
+ SDL_Rect *r = &_dirtyRectList[_numDirtyRects++];
+ r->x = x;
+ r->y = y;
+ r->w = w;
+ r->h = h;
+ return;
+ }
+
+ int height, width;
+
+ if (!_overlayVisible) {
+ width = _screenWidth;
+ height = _screenHeight;
+ } else {
+ width = _overlayWidth;
+ height = _overlayHeight;
+ }
if (_numDirtyRects == NUM_DIRTY_RECT)
_forceFull = true;
@@ -762,16 +831,21 @@ void OSystem_SDL::addDirtyRect(int x, int y, int w, int h, bool mouseRect) {
y=0;
}
- if (w > _screenWidth - x) {
- w = _screenWidth - x;
+ if (w > width - x) {
+ w = width - x;
}
- if (h > _screenHeight - y) {
- h = _screenHeight - y;
+ if (h > height - y) {
+ h = height - y;
}
- if (_adjustAspectRatio)
+ if (_adjustAspectRatio) {
makeRectStretchable(x, y, w, h);
+ if (_scaleFactor == 3 && _overlayScale == 2 && _overlayVisible) {
+ if (y % 2)
+ y++;
+ }
+ }
r->x = x;
r->y = y;
@@ -931,17 +1005,18 @@ void OSystem_SDL::hideOverlay() {
assert (_transactionMode == kTransactionNone);
_overlayVisible = false;
+ clearOverlay();
_forceFull = true;
}
void OSystem_SDL::clearOverlay() {
- assert (_transactionMode == kTransactionNone);
+ //assert (_transactionMode == kTransactionNone);
- if (!_overlayVisible)
- return;
-
Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends
+ if (!_overlayVisible)
+ return;
+
// Clear the overlay by making the game screen "look through" everywhere.
SDL_Rect src, dst;
src.x = src.y = 0;
@@ -951,39 +1026,47 @@ void OSystem_SDL::clearOverlay() {
if (SDL_BlitSurface(_screen, &src, _tmpscreen, &dst) != 0)
error("SDL_BlitSurface failed: %s", SDL_GetError());
+ SDL_LockSurface(_tmpscreen);
+ SDL_LockSurface(_overlayscreen);
+ if (_overlayScale == _scaleFactor) {
+ _scalerProc((byte *)(_tmpscreen->pixels) + _tmpscreen->pitch + 2,
+ _tmpscreen->pitch, (byte *)_overlayscreen->pixels, _overlayscreen->pitch, _screenWidth, _screenHeight);
+ } else {
+ // Quality is degraded here. It is possible to run one-less scaler here, but is it
+ // really needed? Quality will anyway be degraded because of 1.5x scaler.
+ (scalersMagn[0][_overlayScale-1])((byte *)(_tmpscreen->pixels) + _tmpscreen->pitch + 2,
+ _tmpscreen->pitch, (byte *)_overlayscreen->pixels, _overlayscreen->pitch, _screenWidth, _screenHeight);
+ }
+ SDL_UnlockSurface(_tmpscreen);
+ SDL_UnlockSurface(_overlayscreen);
+
_forceFull = true;
}
void OSystem_SDL::grabOverlay(OverlayColor *buf, int pitch) {
assert (_transactionMode == kTransactionNone);
- if (!_overlayVisible)
- return;
-
- if (_tmpscreen == NULL)
+ if (_overlayscreen == NULL)
return;
- if (SDL_LockSurface(_tmpscreen) == -1)
+ if (SDL_LockSurface(_overlayscreen) == -1)
error("SDL_LockSurface failed: %s", SDL_GetError());
- byte *src = (byte *)_tmpscreen->pixels + _tmpscreen->pitch + 2; // Offset by one row, one column
- int h = _screenHeight;
+ byte *src = (byte *)_overlayscreen->pixels;
+ int h = _overlayHeight;
do {
- memcpy(buf, src, _screenWidth*2);
- src += _tmpscreen->pitch;
+ memcpy(buf, src, _overlayWidth*2);
+ src += _overlayscreen->pitch;
buf += pitch;
} while (--h);
- SDL_UnlockSurface(_tmpscreen);
+ SDL_UnlockSurface(_overlayscreen);
}
void OSystem_SDL::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
assert (_transactionMode == kTransactionNone);
- if (!_overlayVisible)
- return;
-
- if (_tmpscreen == NULL)
+ if (_overlayscreen == NULL)
return;
// Clip the coordinates
@@ -998,12 +1081,12 @@ void OSystem_SDL::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, i
y = 0;
}
- if (w > _screenWidth - x) {
- w = _screenWidth - x;
+ if (w > _overlayWidth - x) {
+ w = _overlayWidth - x;
}
- if (h > _screenHeight-y) {
- h = _screenHeight - y;
+ if (h > _overlayHeight - y) {
+ h = _overlayHeight - y;
}
if (w <= 0 || h <= 0)
@@ -1013,25 +1096,25 @@ void OSystem_SDL::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, i
_cksumValid = false;
addDirtyRect(x, y, w, h);
- if (SDL_LockSurface(_tmpscreen) == -1)
+ if (SDL_LockSurface(_overlayscreen) == -1)
error("SDL_LockSurface failed: %s", SDL_GetError());
- byte *dst = (byte *)_tmpscreen->pixels + (y + 1) * _tmpscreen->pitch + (x + 1) * 2;
+ byte *dst = (byte *)_overlayscreen->pixels + y * _overlayscreen->pitch + x * 2;
do {
memcpy(dst, buf, w * 2);
- dst += _tmpscreen->pitch;
+ dst += _overlayscreen->pitch;
buf += pitch;
} while (--h);
- SDL_UnlockSurface(_tmpscreen);
+ SDL_UnlockSurface(_overlayscreen);
}
OverlayColor OSystem_SDL::RGBToColor(uint8 r, uint8 g, uint8 b) {
- return SDL_MapRGB(_tmpscreen->format, r, g, b);
+ return SDL_MapRGB(_overlayscreen->format, r, g, b);
}
void OSystem_SDL::colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b) {
- SDL_GetRGB(color, _tmpscreen->format, &r, &g, &b);
+ SDL_GetRGB(color, _overlayscreen->format, &r, &g, &b);
}
@@ -1061,7 +1144,10 @@ void OSystem_SDL::setMousePos(int x, int y) {
void OSystem_SDL::warpMouse(int x, int y) {
if (_mouseCurState.x != x || _mouseCurState.y != y) {
- SDL_WarpMouse(x * _scaleFactor, y * _scaleFactor);
+ if (_overlayVisible)
+ SDL_WarpMouse(x * _scaleFactor / _overlayScale, y * _scaleFactor / _overlayScale);
+ else
+ SDL_WarpMouse(x * _scaleFactor, y * _scaleFactor);
// SDL_WarpMouse() generates a mouse movement event, so
// setMousePos() would be called eventually. However, the
@@ -1235,13 +1321,24 @@ void OSystem_SDL::toggleMouseGrab() {
}
void OSystem_SDL::undrawMouse() {
+ // When we switch bigger overlay off mouse jumps. Argh!
+ // this intended to prevent undrawing offscreen mouse
+ if (!_overlayVisible)
+ if (_adjustAspectRatio) {
+ if (_mouseBackup.x > _screenWidth || aspect2Real(_mouseBackup.y) > _screenHeight)
+ return;
+ } else {
+ if (_mouseBackup.x > _screenWidth || _mouseBackup.y > _screenHeight)
+ return;
+ }
+
if (_mouseBackup.w) {
if (_adjustAspectRatio)
addDirtyRect(_mouseBackup.x, aspect2Real(_mouseBackup.y), _mouseBackup.w,
- _mouseBackup.h);
+ _mouseBackup.h);
else
addDirtyRect(_mouseBackup.x, _mouseBackup.y, _mouseBackup.w,
- _mouseBackup.h);
+ _mouseBackup.h);
}
}
@@ -1250,9 +1347,23 @@ void OSystem_SDL::drawMouse() {
_mouseBackup.x = _mouseBackup.y = _mouseBackup.w = _mouseBackup.h = 0;
return;
}
-
+
SDL_Rect src, dst;
bool scale;
+ int scale1, scale2;
+ int width, height;
+
+ if (!_overlayVisible) {
+ scale1 = _scaleFactor;
+ scale2 = 1;
+ width = _screenWidth;
+ height = _screenHeight;
+ } else {
+ scale1 = _scaleFactor;
+ scale2 = _overlayScale;
+ width = _overlayWidth;
+ height = _overlayHeight;
+ }
scale = (_scaleFactor > _cursorTargetScale);
@@ -1267,10 +1378,8 @@ void OSystem_SDL::drawMouse() {
int dx, dy;
dx = dst.x; dy = dst.y;
- dx = scale ? dst.x * _scaleFactor / _cursorTargetScale : dst.x;
- dy = scale ? dst.y * _scaleFactor / _cursorTargetScale : dst.y;
- if (_adjustAspectRatio)
- dy = real2Aspect(dy);
+ dx = scale ? dst.x * scale1 / scale2 / _cursorTargetScale : dst.x;
+ dy = scale ? dst.y * scale1 / scale2 / _cursorTargetScale : dst.y;
if (dst.x < 0) {
dst.w += dx;
@@ -1284,7 +1393,7 @@ void OSystem_SDL::drawMouse() {
}
// Quick check to see if anything has to be drawn at all
- if (dst.w <= 0 || dst.h <= 0)
+ if (dst.w <= 0 || dst.h <= 0 || dst.x >= width || dst.y >= height)
return;
src.w = dst.w;
@@ -1292,18 +1401,26 @@ void OSystem_SDL::drawMouse() {
if (_adjustAspectRatio)
dst.y = real2Aspect(dst.y);
-
+
+ // special case for 1o5x scaler to prevent backgound shaking
+ if (scale1 == 3 && scale2 == 2) {
+ if (dst.x % 2)
+ dst.x--;
+ if (dst.y % 2)
+ dst.y--;
+ }
+
_mouseBackup.x = dst.x;
_mouseBackup.y = dst.y;
_mouseBackup.w = dst.w;
_mouseBackup.h = dst.h;
-
- dst.x *= _scaleFactor;
- dst.y *= _scaleFactor;
-
+
+ dst.x = dst.x * scale1 / scale2;
+ dst.y = dst.y * scale1 / scale2;
+
if (SDL_BlitSurface(_mouseSurface, &src, _hwscreen, &dst) != 0)
error("SDL_BlitSurface failed: %s", SDL_GetError());
-
+
addDirtyRect(dst.x, dst.y, dst.w, dst.h, true);
}
diff --git a/backends/sdl/sdl-common.h b/backends/sdl/sdl-common.h
index b99b6e9eb2..5a92840040 100644
--- a/backends/sdl/sdl-common.h
+++ b/backends/sdl/sdl-common.h
@@ -58,7 +58,7 @@ public:
// Set the size of the video bitmap.
// Typically, 320x200
- virtual void initSize(uint w, uint h); // overloaded by CE backend
+ virtual void initSize(uint w, uint h, int overlayScale); // overloaded by CE backend
// Set colors of the palette
void setPalette(const byte *colors, uint start, uint num);
@@ -142,6 +142,12 @@ public:
virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
virtual int16 getHeight();
virtual int16 getWidth();
+ virtual int16 getOverlayHeight() { return _overlayHeight; }
+ virtual int16 getOverlayWidth() { return _overlayWidth; }
+ virtual int ScreenToOverlayX(int x) { return x * _overlayScale; }
+ virtual int ScreenToOverlayY(int y) { return y * _overlayScale; }
+ virtual int OverlayToScreenX(int x) { return x / _overlayScale; }
+ virtual int OverlayToScreenY(int y) { return y / _overlayScale; }
// Methods that convert RGB to/from colors suitable for the overlay.
virtual OverlayColor RGBToColor(uint8 r, uint8 g, uint8 b);
@@ -187,8 +193,14 @@ protected:
SDL_Surface *_screen;
int _screenWidth, _screenHeight;
- // temporary screen (for scalers/overlay)
+ // temporary screen (for scalers)
SDL_Surface *_tmpscreen;
+ SDL_Surface *_tmpscreen2;
+
+ // overlay
+ SDL_Surface *_overlayscreen;
+ int _overlayWidth, _overlayHeight;
+ int _overlayScale;
bool _overlayVisible;
// Audio
@@ -214,9 +226,9 @@ protected:
int mode;
bool modeChanged;
int w;
- bool wChanged;
int h;
- bool hChanged;
+ int overlayScale;
+ bool sizeChanged;
bool fs;
bool fsChanged;
bool ar;
diff --git a/backends/sdl/sdl.cpp b/backends/sdl/sdl.cpp
index 717523b9fb..7d558b8ece 100644
--- a/backends/sdl/sdl.cpp
+++ b/backends/sdl/sdl.cpp
@@ -97,7 +97,8 @@ OSystem_SDL::OSystem_SDL()
_osdSurface(0), _osdAlpha(SDL_ALPHA_TRANSPARENT), _osdFadeStartTime(0),
#endif
_hwscreen(0), _screen(0), _screenWidth(0), _screenHeight(0),
- _tmpscreen(0), _overlayVisible(false),
+ _tmpscreen(0), _overlayVisible(false), _overlayScale(1),
+ _overlayscreen(0), _tmpscreen2(0),
_samplesPerSec(0),
_cdrom(0), _scalerProc(0), _modeChanged(false), _dirtyChecksums(0),
_mouseVisible(false), _mouseDrawn(false), _mouseData(0), _mouseSurface(0),
diff --git a/backends/wince/wince-sdl.cpp b/backends/wince/wince-sdl.cpp
index 977232a649..1affda9df6 100644
--- a/backends/wince/wince-sdl.cpp
+++ b/backends/wince/wince-sdl.cpp
@@ -733,7 +733,7 @@ void OSystem_WINCE3::update_game_settings() {
get_sample_rate();
}
-void OSystem_WINCE3::initSize(uint w, uint h) {
+void OSystem_WINCE3::initSize(uint w, uint h, int overlaySize) {
if (_isSmartphone && h == 240)
h = 200; // mainly for the launcher
@@ -765,7 +765,7 @@ void OSystem_WINCE3::initSize(uint w, uint h) {
if (w != _screenWidth || h != _screenHeight)
_scalersChanged = false;
- OSystem_SDL::initSize(w, h);
+ OSystem_SDL::initSize(w, h, overlayScale);
if (_scalersChanged) {
unloadGFXMode();
diff --git a/backends/wince/wince-sdl.h b/backends/wince/wince-sdl.h
index 79bdff1cd5..6338b839a8 100644
--- a/backends/wince/wince-sdl.h
+++ b/backends/wince/wince-sdl.h
@@ -45,7 +45,7 @@ public:
// Update the dirty areas of the screen
void internUpdateScreen();
- void initSize(uint w, uint h);
+ void initSize(uint w, uint h, int overlaySize);
// Overloaded from SDL_Common (toolbar handling)
bool pollEvent(Event &event);
diff --git a/backends/x11/x11.cpp b/backends/x11/x11.cpp
index c528b09484..1e4ef11eac 100644
--- a/backends/x11/x11.cpp
+++ b/backends/x11/x11.cpp
@@ -84,7 +84,7 @@ public:
// Set the size of the video bitmap.
// Typically, 320x200
- void initSize(uint w, uint h);
+ void initSize(uint w, uint h, int overlaySize);
// Draw a bitmap to screen.
// The screen will not be updated to reflect the new bitmap
@@ -469,7 +469,7 @@ uint32 OSystem_X11::getMillis() {
((current_time.tv_usec - start_time.tv_usec) / 1000));
}
-void OSystem_X11::initSize(uint w, uint h) {
+void OSystem_X11::initSize(uint w, uint h, int overlaySize) {
static XShmSegmentInfo shminfo;
fb_width = w;