diff options
Diffstat (limited to 'backends/platform/sdl')
-rw-r--r-- | backends/platform/sdl/events.cpp | 2 | ||||
-rw-r--r-- | backends/platform/sdl/graphics.cpp | 304 | ||||
-rw-r--r-- | backends/platform/sdl/main.cpp | 2 | ||||
-rw-r--r-- | backends/platform/sdl/sdl.cpp | 62 | ||||
-rw-r--r-- | backends/platform/sdl/sdl.h | 43 |
5 files changed, 347 insertions, 66 deletions
diff --git a/backends/platform/sdl/events.cpp b/backends/platform/sdl/events.cpp index feb2c9a9c5..e6c8d716e3 100644 --- a/backends/platform/sdl/events.cpp +++ b/backends/platform/sdl/events.cpp @@ -186,6 +186,8 @@ bool OSystem_SDL::pollEvent(Common::Event &event) { } while (SDL_PollEvent(&ev)) { + preprocessEvents(&ev); + switch (ev.type) { case SDL_KEYDOWN:{ b = event.kbd.flags = SDLModToOSystemKeyFlags(SDL_GetModState()); diff --git a/backends/platform/sdl/graphics.cpp b/backends/platform/sdl/graphics.cpp index 78b8bd8c63..89e3a38bcb 100644 --- a/backends/platform/sdl/graphics.cpp +++ b/backends/platform/sdl/graphics.cpp @@ -26,6 +26,9 @@ #include "backends/platform/sdl/sdl.h" #include "common/mutex.h" #include "common/util.h" +#ifdef USE_RGB_COLOR +#include "common/list.h" +#endif #include "graphics/font.h" #include "graphics/fontman.h" #include "graphics/scaler.h" @@ -97,6 +100,9 @@ void OSystem_SDL::beginGFXTransaction(void) { _transactionDetails.needUpdatescreen = false; _transactionDetails.normal1xScaler = false; +#ifdef USE_RGB_COLOR + _transactionDetails.formatChanged = false; +#endif _oldVideoMode = _videoMode; } @@ -120,6 +126,13 @@ OSystem::TransactionError OSystem_SDL::endGFXTransaction(void) { _videoMode.mode = _oldVideoMode.mode; _videoMode.scaleFactor = _oldVideoMode.scaleFactor; +#ifdef USE_RGB_COLOR + } else if (_videoMode.format != _oldVideoMode.format) { + errors |= kTransactionFormatNotSupported; + + _videoMode.format = _oldVideoMode.format; + _screenFormat = _videoMode.format; +#endif } else if (_videoMode.screenWidth != _oldVideoMode.screenWidth || _videoMode.screenHeight != _oldVideoMode.screenHeight) { errors |= kTransactionSizeChangeFailed; @@ -143,7 +156,11 @@ OSystem::TransactionError OSystem_SDL::endGFXTransaction(void) { } } +#ifdef USE_RGB_COLOR + if (_transactionDetails.sizeChanged || _transactionDetails.formatChanged) { +#else if (_transactionDetails.sizeChanged) { +#endif unloadGFXMode(); if (!loadGFXMode()) { if (_oldVideoMode.setup) { @@ -186,12 +203,94 @@ OSystem::TransactionError OSystem_SDL::endGFXTransaction(void) { } else if (_transactionDetails.needUpdatescreen) { setGraphicsModeIntern(); internUpdateScreen(); - } + } _transactionMode = kTransactionNone; return (TransactionError)errors; } +#ifdef USE_RGB_COLOR +const Graphics::PixelFormat RGBList[] = { +#ifdef ENABLE_32BIT + // RGBA8888, ARGB8888, RGB888 + Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0), + Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24), + Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0), +#endif + // RGB565, XRGB1555, RGB555, RGBA4444, ARGB4444 + Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), + Graphics::PixelFormat(2, 5, 5, 5, 1, 10, 5, 0, 15), + Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0), + Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0), + Graphics::PixelFormat(2, 4, 4, 4, 4, 8, 4, 0, 12) +}; +const Graphics::PixelFormat BGRList[] = { +#ifdef ENABLE_32BIT + // ABGR8888, BGRA8888, BGR888 + Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24), + Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0), + Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0), +#endif + // BGR565, XBGR1555, BGR555, ABGR4444, BGRA4444 + Graphics::PixelFormat(2, 5, 6, 5, 0, 0, 5, 11, 0), + Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15), + Graphics::PixelFormat(2, 5, 5, 5, 0, 0, 5, 10, 0), + Graphics::PixelFormat(2, 4, 4, 4, 4, 0, 4, 8, 12), + Graphics::PixelFormat(2, 4, 4, 4, 4, 4, 8, 12, 0) +}; + +// TODO: prioritize matching alpha masks +Common::List<Graphics::PixelFormat> OSystem_SDL::getSupportedFormats() { + static Common::List<Graphics::PixelFormat> list; + static bool inited = false; + + if (inited) + return list; + + bool BGR = false; + int listLength = ARRAYSIZE(RGBList); + + Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8(); + if (_hwscreen) { + // Get our currently set hardware format + format = Graphics::PixelFormat(_hwscreen->format->BytesPerPixel, + 8 - _hwscreen->format->Rloss, 8 - _hwscreen->format->Gloss, + 8 - _hwscreen->format->Bloss, 8 - _hwscreen->format->Aloss, + _hwscreen->format->Rshift, _hwscreen->format->Gshift, + _hwscreen->format->Bshift, _hwscreen->format->Ashift); + + // Workaround to MacOSX SDL not providing an accurate Aloss value. + if (_hwscreen->format->Amask == 0) + format.aLoss = 8; + + // Push it first, as the prefered format. + list.push_back(format); + + if (format.bShift > format.rShift) + BGR = true; + + // Mark that we don't need to do this any more. + inited = true; + } + + for (int i = 0; i < listLength; i++) { + if (inited && (RGBList[i].bytesPerPixel > format.bytesPerPixel)) + continue; + if (BGR) { + if (BGRList[i] != format) + list.push_back(BGRList[i]); + list.push_back(RGBList[i]); + } else { + if (RGBList[i] != format) + list.push_back(RGBList[i]); + list.push_back(BGRList[i]); + } + } + list.push_back(Graphics::PixelFormat::createFormatCLUT8()); + return list; +} +#endif + bool OSystem_SDL::setGraphicsMode(int mode) { Common::StackLock lock(_graphicsMutex); @@ -340,9 +439,27 @@ int OSystem_SDL::getGraphicsMode() const { return _videoMode.mode; } -void OSystem_SDL::initSize(uint w, uint h) { +void OSystem_SDL::initSize(uint w, uint h, const Graphics::PixelFormat *format) { assert(_transactionMode == kTransactionActive); +#ifdef USE_RGB_COLOR + //avoid redundant format changes + Graphics::PixelFormat newFormat; + if (!format) + newFormat = Graphics::PixelFormat::createFormatCLUT8(); + else + newFormat = *format; + + assert(newFormat.bytesPerPixel > 0); + + if (newFormat != _videoMode.format) + { + _videoMode.format = newFormat; + _transactionDetails.formatChanged = true; + _screenFormat = newFormat; + } +#endif + // Avoid redundant res changes if ((int)w == _videoMode.screenWidth && (int)h == _videoMode.screenHeight) return; @@ -358,13 +475,55 @@ void OSystem_SDL::initSize(uint w, uint h) { _dirtyChecksums = (uint32 *)calloc(_cksumNum * 2, sizeof(uint32)); } + +static void fixupResolutionForAspectRatio(AspectRatio desiredAspectRatio, int &width, int &height) { + assert(&width != &height); + + if (desiredAspectRatio.isAuto()) + return; + + int kw = desiredAspectRatio.kw(); + int kh = desiredAspectRatio.kh(); + + const int w = width; + const int h = height; + + SDL_Rect const* const*availableModes = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_SWSURFACE); //TODO : Maybe specify a pixel format + assert(availableModes); + + const SDL_Rect *bestMode = NULL; + uint bestMetric = (uint)-1; // Metric is wasted space + while (const SDL_Rect *mode = *availableModes++) { + if (mode->w < w) + continue; + if (mode->h < h) + continue; + if (mode->h * kw != mode->w * kh) + continue; + //printf("%d %d\n", mode->w, mode->h); + + uint metric = mode->w * mode->h - w * h; + if (metric > bestMetric) + continue; + + bestMetric = metric; + bestMode = mode; + } + + if (!bestMode) { + warning("Unable to enforce the desired aspect ratio!"); + return; + } + //printf("%d %d\n", bestMode->w, bestMode->h); + width = bestMode->w; + height = bestMode->h; +} + bool OSystem_SDL::loadGFXMode() { assert(_inited); _forceFull = true; - int hwW, hwH; - -#ifndef __MAEMO__ +#if !defined(__MAEMO__) && !defined(GP2XWIZ) _videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor; _videoMode.overlayHeight = _videoMode.screenHeight * _videoMode.scaleFactor; @@ -374,25 +533,41 @@ bool OSystem_SDL::loadGFXMode() { if (_videoMode.aspectRatioCorrection) _videoMode.overlayHeight = real2Aspect(_videoMode.overlayHeight); - hwW = _videoMode.screenWidth * _videoMode.scaleFactor; - hwH = effectiveScreenHeight(); + _videoMode.hardwareWidth = _videoMode.screenWidth * _videoMode.scaleFactor; + _videoMode.hardwareHeight = effectiveScreenHeight(); #else - hwW = _videoMode.overlayWidth; - hwH = _videoMode.overlayHeight; + _videoMode.hardwareWidth = _videoMode.overlayWidth; + _videoMode.hardwareHeight = _videoMode.overlayHeight; #endif // // Create the surface that contains the 8 bit game data // +#ifdef USE_RGB_COLOR + _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, + _screenFormat.bytesPerPixel << 3, + ((1 << _screenFormat.rBits()) - 1) << _screenFormat.rShift , + ((1 << _screenFormat.gBits()) - 1) << _screenFormat.gShift , + ((1 << _screenFormat.bBits()) - 1) << _screenFormat.bShift , + ((1 << _screenFormat.aBits()) - 1) << _screenFormat.aShift ); + if (_screen == NULL) + error("allocating _screen failed"); + +#else _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0); if (_screen == NULL) error("allocating _screen failed"); +#endif // // Create the surface that contains the scaled graphics in 16 bit mode // - _hwscreen = SDL_SetVideoMode(hwW, hwH, 16, + if (_videoMode.fullscreen) { + fixupResolutionForAspectRatio(_videoMode.desiredAspectRatio, _videoMode.hardwareWidth, _videoMode.hardwareHeight); + } + + _hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 16, _videoMode.fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE ); if (_hwscreen == NULL) { @@ -525,8 +700,8 @@ bool OSystem_SDL::hotswapGFXMode() { // 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_overlayscreen = _overlayscreen; _screen = NULL; + SDL_Surface *old_overlayscreen = _overlayscreen; _overlayscreen = NULL; // Release the HW screen surface @@ -675,7 +850,7 @@ void OSystem_SDL::internUpdateScreen() { for (r = _dirtyRectList; r != lastRect; ++r) { dst = *r; - dst.x++; // Shift rect by one since 2xSai needs to acces the data around + dst.x++; // Shift rect by one since 2xSai needs to access 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) @@ -800,30 +975,6 @@ void OSystem_SDL::copyRectToScreen(const byte *src, int pitch, int x, int y, int * and just updates those, on the actual display. */ addDirtyRgnAuto(src); } else { - /* Clip the coordinates */ - if (x < 0) { - w += x; - src -= x; - x = 0; - } - - if (y < 0) { - h += y; - src -= y * pitch; - y = 0; - } - - if (w > _videoMode.screenWidth - x) { - w = _videoMode.screenWidth - x; - } - - if (h > _videoMode.screenHeight - y) { - h = _videoMode.screenHeight - y; - } - - if (w <= 0 || h <= 0) - return; - _cksumValid = false; addDirtyRect(x, y, w, h); } @@ -832,8 +983,19 @@ void OSystem_SDL::copyRectToScreen(const byte *src, int pitch, int x, int y, int if (SDL_LockSurface(_screen) == -1) error("SDL_LockSurface failed: %s", SDL_GetError()); +#ifdef USE_RGB_COLOR + byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth * _screenFormat.bytesPerPixel + x * _screenFormat.bytesPerPixel; + if (_videoMode.screenWidth == w && pitch == w * _screenFormat.bytesPerPixel) { + memcpy(dst, src, h*w*_screenFormat.bytesPerPixel); + } else { + do { + memcpy(dst, src, w * _screenFormat.bytesPerPixel); + src += pitch; + dst += _videoMode.screenWidth * _screenFormat.bytesPerPixel; + } while (--h); + } +#else byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x; - if (_videoMode.screenWidth == pitch && pitch == w) { memcpy(dst, src, h*w); } else { @@ -843,6 +1005,7 @@ void OSystem_SDL::copyRectToScreen(const byte *src, int pitch, int x, int y, int dst += _videoMode.screenWidth; } while (--h); } +#endif // Unlock the screen surface SDL_UnlockSurface(_screen); @@ -866,7 +1029,11 @@ Graphics::Surface *OSystem_SDL::lockScreen() { _framebuffer.w = _screen->w; _framebuffer.h = _screen->h; _framebuffer.pitch = _screen->pitch; +#ifdef USE_RGB_COLOR + _framebuffer.bytesPerPixel = _screenFormat.bytesPerPixel; +#else _framebuffer.bytesPerPixel = 1; +#endif return &_framebuffer; } @@ -1050,6 +1217,11 @@ int16 OSystem_SDL::getWidth() { void OSystem_SDL::setPalette(const byte *colors, uint start, uint num) { assert(colors); +#ifdef USE_RGB_COLOR + if (_screenFormat.bytesPerPixel > 1) + return; //not using a paletted pixel format +#endif + // Setting the palette before _screen is created is allowed - for now - // 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. @@ -1103,10 +1275,10 @@ void OSystem_SDL::setCursorPalette(const byte *colors, uint start, uint num) { } _cursorPaletteDisabled = false; - blitCursor(); } + void OSystem_SDL::setShakePos(int shake_pos) { assert (_transactionMode == kTransactionNone); @@ -1311,7 +1483,17 @@ void OSystem_SDL::warpMouse(int x, int y) { } } -void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale) { +void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { +#ifdef USE_RGB_COLOR + if (!format) + _cursorFormat = Graphics::PixelFormat::createFormatCLUT8(); + else if (format->bytesPerPixel <= _screenFormat.bytesPerPixel) + _cursorFormat = *format; + keycolor &= (1 << (_cursorFormat.bytesPerPixel << 3)) - 1; +#else + keycolor &= 0xFF; +#endif + if (w == 0 || h == 0) return; @@ -1345,16 +1527,26 @@ void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, } free(_mouseData); - +#ifdef USE_RGB_COLOR + _mouseData = (byte *)malloc(w * h * _cursorFormat.bytesPerPixel); + memcpy(_mouseData, buf, w * h * _cursorFormat.bytesPerPixel); +#else _mouseData = (byte *)malloc(w * h); memcpy(_mouseData, buf, w * h); +#endif + blitCursor(); } void OSystem_SDL::blitCursor() { byte *dstPtr; const byte *srcPtr = _mouseData; +#ifdef USE_RGB_COLOR + uint32 color; + uint32 colormask = (1 << (_cursorFormat.bytesPerPixel << 3)) - 1; +#else byte color; +#endif int w, h, i, j; if (!_mouseOrigSurface || !_mouseData) @@ -1388,13 +1580,29 @@ void OSystem_SDL::blitCursor() { for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { - color = *srcPtr; - if (color != _mouseKeyColor) { // transparent, don't draw - *(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format, - palette[color].r, palette[color].g, palette[color].b); +#ifdef USE_RGB_COLOR + if (_cursorFormat.bytesPerPixel > 1) { + color = (*(uint32 *) srcPtr) & colormask; + if (color != _mouseKeyColor) { // transparent, don't draw + uint8 r,g,b; + _cursorFormat.colorToRGB(color,r,g,b); + *(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format, + r, g, b); + } + dstPtr += 2; + srcPtr += _cursorFormat.bytesPerPixel; + } else { +#endif + color = *srcPtr; + 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++; +#ifdef USE_RGB_COLOR } - dstPtr += 2; - srcPtr++; +#endif } dstPtr += _mouseOrigSurface->pitch - w * 2; } @@ -1719,7 +1927,7 @@ void OSystem_SDL::handleScalerHotkeys(const SDL_KeyboardEvent &key) { ); displayMessageOnOSD(buffer); #endif - + internUpdateScreen(); return; } @@ -1775,7 +1983,7 @@ void OSystem_SDL::handleScalerHotkeys(const SDL_KeyboardEvent &key) { } } #endif - + internUpdateScreen(); } } diff --git a/backends/platform/sdl/main.cpp b/backends/platform/sdl/main.cpp index 021bda155c..fa8f6ededb 100644 --- a/backends/platform/sdl/main.cpp +++ b/backends/platform/sdl/main.cpp @@ -37,7 +37,7 @@ #include "SymbianOs.h" #endif -#if !defined(__MAEMO__) && !defined(_WIN32_WCE) && !defined(GP2XWIZ) +#if !defined(__MAEMO__) && !defined(_WIN32_WCE) && !defined(GP2XWIZ)&& !defined(LINUXMOTO) #if defined (WIN32) int __stdcall WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/, LPSTR /*lpCmdLine*/, int /*iShowCmd*/) { diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index c11c97c041..547720d435 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -33,7 +33,7 @@ #include "common/archive.h" #include "common/config-manager.h" #include "common/debug.h" -#include "common/events.h" +#include "common/EventRecorder.h" #include "common/util.h" #ifdef UNIX @@ -85,6 +85,31 @@ static Uint32 timer_handler(Uint32 interval, void *param) { return interval; } +AspectRatio::AspectRatio(int w, int h) { + // TODO : Validation and so on... + // Currently, we just ensure the program don't instantiate non-supported aspect ratios + _kw = w; + _kh = h; +} + +static const size_t AR_COUNT = 4; +static const char* desiredAspectRatioAsStrings[AR_COUNT] = { "auto", "4/3", "16/9", "16/10" }; +static const AspectRatio desiredAspectRatios[AR_COUNT] = { AspectRatio(0, 0), AspectRatio(4,3), AspectRatio(16,9), AspectRatio(16,10) }; +static AspectRatio getDesiredAspectRatio() { + //TODO : We could parse an arbitrary string, if we code enough proper validation + Common::String desiredAspectRatio = ConfMan.get("desired_screen_aspect_ratio"); + + for (size_t i = 0; i < AR_COUNT; i++) { + assert(desiredAspectRatioAsStrings[i] != NULL); + + if (!scumm_stricmp(desiredAspectRatio.c_str(), desiredAspectRatioAsStrings[i])) { + return desiredAspectRatios[i]; + } + } + // TODO : Report a warning + return AspectRatio(0, 0); +} + void OSystem_SDL::initBackend() { assert(!_inited); @@ -124,6 +149,7 @@ void OSystem_SDL::initBackend() { _videoMode.mode = GFX_DOUBLESIZE; _videoMode.scaleFactor = 2; _videoMode.aspectRatioCorrection = ConfMan.getBool("aspect_ratio"); + _videoMode.desiredAspectRatio = getDesiredAspectRatio(); _scalerProc = Normal2x; #else // for small screen platforms _videoMode.mode = GFX_NORMAL; @@ -196,6 +222,10 @@ OSystem_SDL::OSystem_SDL() _osdSurface(0), _osdAlpha(SDL_ALPHA_TRANSPARENT), _osdFadeStartTime(0), #endif _hwscreen(0), _screen(0), _tmpscreen(0), +#ifdef USE_RGB_COLOR + _screenFormat(Graphics::PixelFormat::createFormatCLUT8()), + _cursorFormat(Graphics::PixelFormat::createFormatCLUT8()), +#endif _overlayVisible(false), _overlayscreen(0), _tmpscreen2(0), _samplesPerSec(0), @@ -257,7 +287,7 @@ OSystem_SDL::~OSystem_SDL() { uint32 OSystem_SDL::getMillis() { uint32 millis = SDL_GetTicks(); - getEventManager()->processMillis(millis); + g_eventRec.processMillis(millis); return millis; } @@ -391,13 +421,20 @@ Common::WriteStream *OSystem_SDL::createConfigWriteStream() { } void OSystem_SDL::setWindowCaption(const char *caption) { - Common::String cap(caption); + Common::String cap; + byte c; + + // The string caption is supposed to be in LATIN-1 encoding. + // SDL expects UTF-8. So we perform the conversion here. + while ((c = *(const byte *)caption++)) { + if (c < 0x80) + cap += c; + else { + cap += 0xC0 | (c >> 6); + cap += 0x80 | (c & 0x3F); + } + } - // Filter out any non-ASCII characters, replacing them by question marks. - // At some point, we may wish to allow LATIN 1 or UTF-8. - for (uint i = 0; i < cap.size(); ++i) - if ((byte)cap[i] > 0x7F) - cap.setChar('?', i); SDL_WM_SetCaption(cap.c_str(), cap.c_str()); } @@ -483,7 +520,7 @@ void OSystem_SDL::quit() { void OSystem_SDL::setupIcon() { int x, y, w, h, ncols, nbytes, i; unsigned int rgba[256]; - unsigned int *icon; + unsigned int *icon; sscanf(scummvm_icon[0], "%d %d %d %d", &w, &h, &ncols, &nbytes); if ((w > 512) || (h > 512) || (ncols > 255) || (nbytes > 1)) { @@ -658,7 +695,6 @@ void OSystem_SDL::mixCallback(void *sys, byte *samples, int len) { void OSystem_SDL::setupMixer() { SDL_AudioSpec desired; - SDL_AudioSpec obtained; // Determine the desired output sampling frequency. _samplesPerSec = 0; @@ -688,7 +724,7 @@ void OSystem_SDL::setupMixer() { _mixer = new Audio::MixerImpl(this); assert(_mixer); - if (SDL_OpenAudio(&desired, &obtained) != 0) { + if (SDL_OpenAudio(&desired, &_obtainedRate) != 0) { warning("Could not open audio device: %s", SDL_GetError()); _samplesPerSec = 0; _mixer->setReady(false); @@ -696,7 +732,7 @@ void OSystem_SDL::setupMixer() { // Note: This should be the obtained output rate, but it seems that at // least on some platforms SDL will lie and claim it did get the rate // even if it didn't. Probably only happens for "weird" rates, though. - _samplesPerSec = obtained.freq; + _samplesPerSec = _obtainedRate.freq; debug(1, "Output sample rate: %d Hz", _samplesPerSec); // Tell the mixer that we are ready and start the sound processing @@ -704,7 +740,7 @@ void OSystem_SDL::setupMixer() { _mixer->setReady(true); #ifdef MIXER_DOUBLE_BUFFERING - initThreadedMixer(_mixer, obtained.samples * 4); + initThreadedMixer(_mixer, _obtainedRate.samples * 4); #endif // start the sound system diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index 7498f48b08..82c1e7bf1b 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -70,6 +70,18 @@ enum { GFX_DOTMATRIX = 11 }; +class AspectRatio { + int _kw, _kh; +public: + AspectRatio() { _kw = _kh = 0; } + AspectRatio(int w, int h); + + bool isAuto() const { return (_kw | _kh) == 0; } + + int kw() const { return _kw; } + int kh() const { return _kh; } +}; + class OSystem_SDL : public BaseBackend { public: @@ -81,9 +93,17 @@ public: void beginGFXTransaction(void); TransactionError endGFXTransaction(void); - // Set the size of the video bitmap. - // Typically, 320x200 - virtual void initSize(uint w, uint h); // overloaded by CE backend +#ifdef USE_RGB_COLOR + // Game screen + virtual Graphics::PixelFormat getScreenFormat() const { return _screenFormat; } + + // Highest supported + virtual Common::List<Graphics::PixelFormat> getSupportedFormats(); +#endif + + // Set the size and format of the video bitmap. + // Typically, 320x200 CLUT8 + virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format); // overloaded by CE backend virtual int getScreenChangeID() const { return _screenChangeCount; } @@ -112,7 +132,7 @@ public: virtual void warpMouse(int x, int y); // overloaded by CE backend (FIXME) // Set the bitmap that's used when drawing the cursor. - 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) + virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); // overloaded by CE backend (FIXME) // Set colors of cursor palette void setCursorPalette(const byte *colors, uint start, uint num); @@ -174,6 +194,7 @@ public: // Overlay virtual Graphics::PixelFormat getOverlayFormat() const { return _overlayFormat; } + virtual void showOverlay(); virtual void hideOverlay(); virtual void clearOverlay(); @@ -195,6 +216,7 @@ public: virtual bool hasFeature(Feature f); virtual void setFeatureState(Feature f, bool enable); virtual bool getFeatureState(Feature f); + virtual void preprocessEvents(SDL_Event *event) {}; #ifdef USE_OSD void displayMessageOnOSD(const char *msg); @@ -209,6 +231,7 @@ public: protected: bool _inited; + SDL_AudioSpec _obtainedRate; #ifdef USE_OSD SDL_Surface *_osdSurface; @@ -227,6 +250,10 @@ protected: // unseen game screen SDL_Surface *_screen; +#ifdef USE_RGB_COLOR + Graphics::PixelFormat _screenFormat; + Graphics::PixelFormat _cursorFormat; +#endif // temporary screen (for scalers) SDL_Surface *_tmpscreen; @@ -260,6 +287,9 @@ protected: bool needHotswap; bool needUpdatescreen; bool normal1xScaler; +#ifdef USE_RGB_COLOR + bool formatChanged; +#endif }; TransactionDetails _transactionDetails; @@ -268,12 +298,17 @@ protected: bool fullscreen; bool aspectRatioCorrection; + AspectRatio desiredAspectRatio; int mode; int scaleFactor; int screenWidth, screenHeight; int overlayWidth, overlayHeight; + int hardwareWidth, hardwareHeight; +#ifdef USE_RGB_COLOR + Graphics::PixelFormat format; +#endif }; VideoState _videoMode, _oldVideoMode; |