From 940298151777bf63bbb32d4f6ed07b8d6a86d962 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sat, 11 Aug 2007 08:44:43 +0000 Subject: SDL backend cleanup (minor) svn-id: r28520 --- backends/platform/sdl/events.cpp | 2 +- backends/platform/sdl/graphics.cpp | 87 ++++---- backends/platform/sdl/main.cpp | 112 ++++++++++ backends/platform/sdl/module.mk | 1 + backends/platform/sdl/sdl-common.h | 416 ------------------------------------- backends/platform/sdl/sdl.cpp | 134 ++---------- backends/platform/sdl/sdl.h | 415 ++++++++++++++++++++++++++++++++++++ 7 files changed, 588 insertions(+), 579 deletions(-) create mode 100644 backends/platform/sdl/main.cpp delete mode 100644 backends/platform/sdl/sdl-common.h create mode 100644 backends/platform/sdl/sdl.h diff --git a/backends/platform/sdl/events.cpp b/backends/platform/sdl/events.cpp index 19fb2372df..f69d46b4c6 100644 --- a/backends/platform/sdl/events.cpp +++ b/backends/platform/sdl/events.cpp @@ -23,7 +23,7 @@ * */ -#include "backends/platform/sdl/sdl-common.h" +#include "backends/platform/sdl/sdl.h" #include "common/util.h" #include "common/events.h" diff --git a/backends/platform/sdl/graphics.cpp b/backends/platform/sdl/graphics.cpp index f93c806aa8..721a5883a1 100644 --- a/backends/platform/sdl/graphics.cpp +++ b/backends/platform/sdl/graphics.cpp @@ -23,7 +23,7 @@ * */ -#include "backends/platform/sdl/sdl-common.h" +#include "backends/platform/sdl/sdl.h" #include "common/util.h" #include "graphics/font.h" #include "graphics/fontman.h" @@ -310,7 +310,6 @@ void OSystem_SDL::initSize(uint w, uint h) { void OSystem_SDL::loadGFXMode() { assert(_inited); _forceFull = true; - _modeFlags |= DF_UPDATE_EXPAND_1_PIXEL; int hwW, hwH; @@ -606,65 +605,55 @@ void OSystem_SDL::internUpdateScreen() { uint32 srcPitch, dstPitch; SDL_Rect *lastRect = _dirtyRectList + _numDirtyRects; - if (scalerProc == Normal1x && !_adjustAspectRatio && 0) { - for (r = _dirtyRectList; r != lastRect; ++r) { - dst = *r; + 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. - dst.y += _currentShakePos; - if (SDL_BlitSurface(origSurf, r, _hwscreen, &dst) != 0) - error("SDL_BlitSurface failed: %s", SDL_GetError()); - } - } else { - 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()); - } + if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0) + error("SDL_BlitSurface failed: %s", SDL_GetError()); + } - SDL_LockSurface(srcSurf); - SDL_LockSurface(_hwscreen); + SDL_LockSurface(srcSurf); + SDL_LockSurface(_hwscreen); - srcPitch = srcSurf->pitch; - dstPitch = _hwscreen->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; + 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; - if (dst_y < height) { - dst_h = r->h; - if (dst_h > height - dst_y) - dst_h = height - dst_y; + if (dst_y < height) { + dst_h = r->h; + if (dst_h > height - dst_y) + dst_h = height - dst_y; - orig_dst_y = dst_y; - dst_y = dst_y * scale1; + orig_dst_y = dst_y; + dst_y = dst_y * scale1; - if (_adjustAspectRatio && !_overlayVisible) - dst_y = real2Aspect(dst_y); + if (_adjustAspectRatio && !_overlayVisible) + dst_y = real2Aspect(dst_y); - assert(scalerProc != NULL); - 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); - } + assert(scalerProc != NULL); + 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 = rx1; - r->y = dst_y; - r->w = r->w * scale1; - r->h = dst_h * scale1; + r->x = rx1; + r->y = dst_y; + r->w = r->w * scale1; + r->h = dst_h * scale1; #ifndef DISABLE_SCALERS - if (_adjustAspectRatio && orig_dst_y < height && !_overlayVisible) - r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1); + if (_adjustAspectRatio && orig_dst_y < height && !_overlayVisible) + r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1); #endif - } - SDL_UnlockSurface(srcSurf); - SDL_UnlockSurface(_hwscreen); } + SDL_UnlockSurface(srcSurf); + SDL_UnlockSurface(_hwscreen); // Readjust the dirty rect list in case we are doing a full update. // This is necessary if shaking is active. @@ -893,7 +882,7 @@ void OSystem_SDL::addDirtyRect(int x, int y, int w, int h, bool realCoordinates) // Extend the dirty region by 1 pixel for scalers // that "smear" the screen, e.g. 2xSAI - if ((_modeFlags & DF_UPDATE_EXPAND_1_PIXEL) && !realCoordinates) { + if (!realCoordinates) { x--; y--; w+=2; diff --git a/backends/platform/sdl/main.cpp b/backends/platform/sdl/main.cpp new file mode 100644 index 0000000000..4ef41d99f2 --- /dev/null +++ b/backends/platform/sdl/main.cpp @@ -0,0 +1,112 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "backends/platform/sdl/sdl.h" +#include "base/main.h" + +#if defined(WIN32) +#include +// winnt.h defines ARRAYSIZE, but we want our own one... +#undef ARRAYSIZE +#endif + +#if defined(__SYMBIAN32__) +#include "SymbianOs.h" +#endif + +#if !defined(__MAEMO__) && !defined(_WIN32_WCE) + +#if defined (WIN32) +int __stdcall WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/, LPSTR /*lpCmdLine*/, int /*iShowCmd*/) { + SDL_SetModuleHandle(GetModuleHandle(NULL)); + return main(__argc, __argv); +} +#endif + +int main(int argc, char *argv[]) { + +#if defined(__SYMBIAN32__) + // + // Set up redirects for stdout/stderr under Windows and Symbian. + // Code copied from SDL_main. + // + + // Symbian does not like any output to the console through any *print* function + char STDOUT_FILE[256], STDERR_FILE[256]; // shhh, don't tell anybody :) + strcpy(STDOUT_FILE, Symbian::GetExecutablePath()); + strcpy(STDERR_FILE, Symbian::GetExecutablePath()); + strcat(STDOUT_FILE, "scummvm.stdout.txt"); + strcat(STDERR_FILE, "scummvm.stderr.txt"); + + /* Flush the output in case anything is queued */ + fclose(stdout); + fclose(stderr); + + /* Redirect standard input and standard output */ + FILE *newfp = freopen(STDOUT_FILE, "w", stdout); + if (newfp == NULL) { /* This happens on NT */ +#if !defined(stdout) + stdout = fopen(STDOUT_FILE, "w"); +#else + newfp = fopen(STDOUT_FILE, "w"); + if (newfp) { + *stdout = *newfp; + } +#endif + } + newfp = freopen(STDERR_FILE, "w", stderr); + if (newfp == NULL) { /* This happens on NT */ +#if !defined(stderr) + stderr = fopen(STDERR_FILE, "w"); +#else + newfp = fopen(STDERR_FILE, "w"); + if (newfp) { + *stderr = *newfp; + } +#endif + } + setbuf(stderr, NULL); /* No buffering */ + +#endif // defined(__SYMBIAN32__) + + // Create our OSystem instance +#if defined(__SYMBIAN32__) + g_system = new OSystem_SDL_Symbian(); +#else + g_system = new OSystem_SDL(); +#endif + assert(g_system); + +#ifdef DYNAMIC_MODULES + PluginManager::instance().addPluginProvider(new SDLPluginProvider()); +#endif + + // Invoke the actual ScummVM main entry point: + int res = scummvm_main(argc, argv); + g_system->quit(); // TODO: Consider removing / replacing this! + return res; +} + +#endif diff --git a/backends/platform/sdl/module.mk b/backends/platform/sdl/module.mk index 18e56bc4fe..def01345db 100644 --- a/backends/platform/sdl/module.mk +++ b/backends/platform/sdl/module.mk @@ -3,6 +3,7 @@ MODULE := backends/platform/sdl MODULE_OBJS := \ events.o \ graphics.o \ + main.o \ sdl.o MODULE_DIRS += \ diff --git a/backends/platform/sdl/sdl-common.h b/backends/platform/sdl/sdl-common.h deleted file mode 100644 index 4795b22a53..0000000000 --- a/backends/platform/sdl/sdl-common.h +++ /dev/null @@ -1,416 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef SDL_COMMON_H -#define SDL_COMMON_H - -#include - -#include "common/stdafx.h" -#include "common/scummsys.h" -#include "common/system.h" -#include "graphics/scaler.h" -#include "backends/intern.h" - - -namespace Audio { - class Mixer; -} - -namespace Common { - class SaveFileManager; - class TimerManager; -} - -#if !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) -// Uncomment this to enable the 'on screen display' code. -#define USE_OSD 1 -#endif - - -enum { - GFX_NORMAL = 0, - GFX_DOUBLESIZE = 1, - GFX_TRIPLESIZE = 2, - GFX_2XSAI = 3, - GFX_SUPER2XSAI = 4, - GFX_SUPEREAGLE = 5, - GFX_ADVMAME2X = 6, - GFX_ADVMAME3X = 7, - GFX_HQ2X = 8, - GFX_HQ3X = 9, - GFX_TV2X = 10, - GFX_DOTMATRIX = 11 -}; - - -class OSystem_SDL : public OSystem { -public: - OSystem_SDL(); - virtual ~OSystem_SDL(); - - virtual void initBackend(); - - void beginGFXTransaction(void); - void endGFXTransaction(void); - - // Set the size of the video bitmap. - // Typically, 320x200 - virtual void initSize(uint w, uint h); // overloaded by CE backend - - virtual int getScreenChangeID() const { return _screenChangeCount; } - - // Set colors of the palette - void setPalette(const byte *colors, uint start, uint num); - - // Get colors of the palette - void grabPalette(byte *colors, uint start, uint num); - - // Draw a bitmap to screen. - // The screen will not be updated to reflect the new bitmap - virtual void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h); // overloaded by CE backend (FIXME) - - virtual Graphics::Surface *lockScreen(); - virtual void unlockScreen(); - - // Update the dirty areas of the screen - void updateScreen(); - - // Either show or hide the mouse cursor - bool showMouse(bool visible); - - // Warp the mouse cursor. Where set_mouse_pos() only informs the - // backend of the mouse cursor's current position, this function - // actually moves the cursor to the specified position. - 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) - - // Set colors of cursor palette - void setCursorPalette(const byte *colors, uint start, uint num); - - // Disables or enables cursor palette - void disableCursorPalette(bool disable) { - _cursorPaletteDisabled = disable; - blitCursor(); - } - - // Shaking is used in SCUMM. Set current shake position. - void setShakePos(int shake_pos); - - // Get the number of milliseconds since the program was started. - uint32 getMillis(); - - // Delay for a specified amount of milliseconds - void delayMillis(uint msecs); - - // Get the next event. - // Returns true if an event was retrieved. - virtual bool pollEvent(Common::Event &event); // overloaded by CE backend - - // Set function that generates samples - typedef void (*SoundProc)(void *param, byte *buf, int len); - virtual bool setSoundCallback(SoundProc proc, void *param); // overloaded by CE backend - virtual Audio::Mixer *getMixer(); - - // Poll CD status - // Returns true if cd audio is playing - bool pollCD(); - - // Play CD audio track - void playCD(int track, int num_loops, int start_frame, int duration); - - // Stop CD audio track - void stopCD(); - - // Update CD audio status - void updateCD(); - - // Quit - virtual void quit(); // overloaded by CE backend - - virtual Common::TimerManager *getTimerManager(); - - // Mutex handling - MutexRef createMutex(); - void lockMutex(MutexRef mutex); - void unlockMutex(MutexRef mutex); - void deleteMutex(MutexRef mutex); - - // Overlay - virtual void showOverlay(); // WinCE FIXME - virtual void hideOverlay(); // WinCE FIXME - virtual void clearOverlay(); - virtual void grabOverlay(OverlayColor *buf, int pitch); - virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); // WinCE FIXME - virtual int16 getHeight(); - virtual int16 getWidth(); - virtual int16 getOverlayHeight() { return _overlayHeight; } - virtual int16 getOverlayWidth() { return _overlayWidth; } - - // Methods that convert RGB to/from colors suitable for the overlay. - virtual OverlayColor RGBToColor(uint8 r, uint8 g, uint8 b); - virtual void colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b); - - - virtual const GraphicsMode *getSupportedGraphicsModes() const; - virtual int getDefaultGraphicsMode() const; - virtual bool setGraphicsMode(int mode); - virtual int getGraphicsMode() const; - - virtual void setWindowCaption(const char *caption); - virtual bool openCD(int drive); - virtual int getOutputSampleRate() const; - - virtual bool hasFeature(Feature f); - virtual void setFeatureState(Feature f, bool enable); - virtual bool getFeatureState(Feature f); - -#ifdef USE_OSD - void displayMessageOnOSD(const char *msg); -#endif - - virtual Common::SaveFileManager *getSavefileManager(); - -protected: - bool _inited; - -#ifdef USE_OSD - SDL_Surface *_osdSurface; - Uint8 _osdAlpha; // Transparency level of the OSD - uint32 _osdFadeStartTime; // When to start the fade out - enum { - kOSDFadeOutDelay = 2 * 1000, // Delay before the OSD is faded out (in milliseconds) - kOSDFadeOutDuration = 500, // Duration of the OSD fade out (in milliseconds) - kOSDColorKey = 1, - kOSDInitialAlpha = 80 // Initial alpha level, in percent - }; -#endif - - // hardware screen - SDL_Surface *_hwscreen; - - // unseen game screen - SDL_Surface *_screen; - - // TODO: We could get rid of the following two vars and just use _screen instead - int _screenWidth, _screenHeight; - - // temporary screen (for scalers) - SDL_Surface *_tmpscreen; - SDL_Surface *_tmpscreen2; - - // overlay - SDL_Surface *_overlayscreen; - int _overlayWidth, _overlayHeight; - bool _overlayVisible; - - // Audio - int _samplesPerSec; - - // CD Audio - SDL_CD *_cdrom; - int _cdTrack, _cdNumLoops, _cdStartFrame, _cdDuration; - uint32 _cdEndTime, _cdStopTime; - - enum { - DF_WANT_RECT_OPTIM = 1 << 0, - DF_UPDATE_EXPAND_1_PIXEL = 1 << 1 - }; - - enum { - kTransactionNone = 0, - kTransactionCommit = 1, - kTransactionActive = 2 - }; - - struct TransactionDetails { - int mode; - bool modeChanged; - int w; - int h; - bool sizeChanged; - bool fs; - bool fsChanged; - bool ar; - bool arChanged; - bool needHotswap; - bool needUpdatescreen; - bool needUnload; - bool needToggle; - bool normal1xScaler; - }; - TransactionDetails _transactionDetails; - - /** Force full redraw on next updateScreen */ - bool _forceFull; - ScalerProc *_scalerProc; - int _scalerType; - int _scaleFactor; - int _mode; - int _transactionMode; - bool _fullscreen; - - bool _screenIsLocked; - Graphics::Surface _framebuffer; - - /** Current video mode flags (see DF_* constants) */ - uint32 _modeFlags; - bool _modeChanged; - int _screenChangeCount; - - /** True if aspect ratio correction is enabled. */ - bool _adjustAspectRatio; - - enum { - NUM_DIRTY_RECT = 100, - MAX_SCALING = 3 - }; - - // Dirty rect management - SDL_Rect _dirtyRectList[NUM_DIRTY_RECT]; - int _numDirtyRects; - uint32 *_dirtyChecksums; - bool _cksumValid; - int _cksumNum; - - // Keyboard mouse emulation. Disabled by fingolfin 2004-12-18. - // I am keeping the rest of the code in for now, since the joystick - // code (or rather, "hack") uses it, too. - struct KbdMouse { - int16 x, y, x_vel, y_vel, x_max, y_max, x_down_count, y_down_count; - uint32 last_time, delay_time, x_down_time, y_down_time; - }; - - struct MousePos { - // The mouse position, using either virtual (game) or real - // (overlay) coordinates. - int16 x, y; - - // The size and hotspot of the original cursor image. - int16 w, h; - int16 hotX, hotY; - - // The size and hotspot of the pre-scaled cursor image, in real - // coordinates. - int16 rW, rH; - int16 rHotX, rHotY; - - // The size and hotspot of the pre-scaled cursor image, in game - // coordinates. - int16 vW, vH; - int16 vHotX, vHotY; - - MousePos() : x(0), y(0), w(0), h(0), hotX(0), hotY(0), - rW(0), rH(0), rHotX(0), rHotY(0), vW(0), vH(0), - vHotX(0), vHotY(0) - { } - }; - - // mouse - KbdMouse _km; - bool _mouseVisible; - bool _mouseDrawn; - byte *_mouseData; - SDL_Rect _mouseBackup; - MousePos _mouseCurState; - byte _mouseKeyColor; - int _cursorTargetScale; - bool _cursorPaletteDisabled; - SDL_Surface *_mouseOrigSurface; - SDL_Surface *_mouseSurface; - enum { - kMouseColorKey = 1 - }; - - // joystick - SDL_Joystick *_joystick; - - // Shake mode - int _currentShakePos; - int _newShakePos; - - // Palette data - SDL_Color *_currentPalette; - uint _paletteDirtyStart, _paletteDirtyEnd; - - // Cursor palette data - SDL_Color *_cursorPalette; - - /** - * Mutex which prevents multiple threads from interfering with each other - * when accessing the screen. - */ - MutexRef _graphicsMutex; - - - Common::SaveFileManager *_savefile; - Audio::Mixer *_mixer; - - SDL_TimerID _timerID; - Common::TimerManager *_timer; - - - - void addDirtyRgnAuto(const byte *buf); - void makeChecksums(const byte *buf); - - virtual void addDirtyRect(int x, int y, int w, int h, bool realCoordinates = false); // overloaded by CE backend - - virtual void drawMouse(); // overloaded by CE backend - virtual void undrawMouse(); // overloaded by CE backend (FIXME) - virtual void blitCursor(); // overloaded by CE backend (FIXME) - - /** Set the position of the virtual mouse cursor. */ - void setMousePos(int x, int y); - virtual void fillMouseEvent(Common::Event &event, int x, int y); // overloaded by CE backend - void toggleMouseGrab(); - - virtual void internUpdateScreen(); // overloaded by CE backend - - virtual void loadGFXMode(); // overloaded by CE backend - virtual void unloadGFXMode(); // overloaded by CE backend - virtual void hotswapGFXMode(); // overloaded by CE backend - - void setFullscreenMode(bool enable); - void setAspectRatioCorrection(bool enable); - - virtual bool saveScreenshot(const char *filename); // overloaded by CE backend - - int effectiveScreenHeight() const { - return (_adjustAspectRatio ? real2Aspect(_screenHeight) : _screenHeight) - * _scaleFactor; - } - - void setupIcon(); - void handleKbdMouse(); - - virtual bool remapKey(SDL_Event &ev, Common::Event &event); - - void handleScalerHotkeys(const SDL_KeyboardEvent &key); -}; - -#endif diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index fe78bd4236..748948a850 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -23,17 +23,10 @@ * */ -#if defined(WIN32) -#include -// winnt.h defines ARRAYSIZE, but we want our own one... -#undef ARRAYSIZE -#endif - -#include "backends/platform/sdl/sdl-common.h" +#include "backends/platform/sdl/sdl.h" #include "backends/plugins/sdl/sdl-provider.h" #include "common/config-manager.h" #include "common/util.h" -#include "base/main.h" #include "backends/saves/default/default-saves.h" #include "backends/timer/default/default-timer.h" @@ -41,92 +34,11 @@ #include "icons/scummvm.xpm" -#if defined(__SYMBIAN32__) -#include "SymbianOs.h" -#endif - -#ifndef __MAEMO__ - static Uint32 timer_handler(Uint32 interval, void *param) { ((DefaultTimerManager *)param)->handler(); return interval; } -#ifndef _WIN32_WCE - -#if defined (WIN32) -int __stdcall WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/, LPSTR /*lpCmdLine*/, int /*iShowCmd*/) { - SDL_SetModuleHandle(GetModuleHandle(NULL)); - return main(__argc, __argv); -} -#endif - -int main(int argc, char *argv[]) { - -#if defined(__SYMBIAN32__) - // - // Set up redirects for stdout/stderr under Windows and Symbian. - // Code copied from SDL_main. - // - - // Symbian does not like any output to the console through any *print* function - char STDOUT_FILE[256], STDERR_FILE[256]; // shhh, don't tell anybody :) - strcpy(STDOUT_FILE, Symbian::GetExecutablePath()); - strcpy(STDERR_FILE, Symbian::GetExecutablePath()); - strcat(STDOUT_FILE, "scummvm.stdout.txt"); - strcat(STDERR_FILE, "scummvm.stderr.txt"); - - /* Flush the output in case anything is queued */ - fclose(stdout); - fclose(stderr); - - /* Redirect standard input and standard output */ - FILE *newfp = freopen(STDOUT_FILE, "w", stdout); - if (newfp == NULL) { /* This happens on NT */ -#if !defined(stdout) - stdout = fopen(STDOUT_FILE, "w"); -#else - newfp = fopen(STDOUT_FILE, "w"); - if (newfp) { - *stdout = *newfp; - } -#endif - } - newfp = freopen(STDERR_FILE, "w", stderr); - if (newfp == NULL) { /* This happens on NT */ -#if !defined(stderr) - stderr = fopen(STDERR_FILE, "w"); -#else - newfp = fopen(STDERR_FILE, "w"); - if (newfp) { - *stderr = *newfp; - } -#endif - } - setbuf(stderr, NULL); /* No buffering */ - -#endif // defined(__SYMBIAN32__) - - // Create our OSystem instance -#if defined(__SYMBIAN32__) - g_system = new OSystem_SDL_Symbian(); -#else - g_system = new OSystem_SDL(); -#endif - assert(g_system); - -#ifdef DYNAMIC_MODULES - PluginManager::instance().addPluginProvider(new SDLPluginProvider()); -#endif - - // Invoke the actual ScummVM main entry point: - int res = scummvm_main(argc, argv); - g_system->quit(); // TODO: Consider removing / replacing this! - return res; -} -#endif // defined(_WIN32_WCE) -#endif // defined(__MAEMO__) - void OSystem_SDL::initBackend() { assert(!_inited); @@ -162,12 +74,15 @@ void OSystem_SDL::initBackend() { _mode = GFX_DOUBLESIZE; _scaleFactor = 2; _scalerProc = Normal2x; - _fullscreen = ConfMan.getBool("fullscreen"); _adjustAspectRatio = ConfMan.getBool("aspect_ratio"); #else // for small screen platforms _mode = GFX_NORMAL; _scaleFactor = 1; _scalerProc = Normal1x; + _adjustAspectRatio = false; +#endif + _scalerType = 0; + _modeFlags = 0; #if !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) _fullscreen = ConfMan.getBool("fullscreen"); @@ -175,13 +90,11 @@ void OSystem_SDL::initBackend() { _fullscreen = true; #endif - _adjustAspectRatio = false; -#endif - _scalerType = 0; - _modeFlags = 0; - -#if !defined(MACOSX) && !defined(__SYMBIAN32__) // Don't set icon on OS X, as we use a nicer external icon there - setupIcon(); // Don't for Symbian: it uses the EScummVM.aif file for the icon +#if !defined(MACOSX) && !defined(__SYMBIAN32__) + // Setup a custom program icon. + // Don't set icon on OS X, as we use a nicer external icon there. + // Don't for Symbian: it uses the EScummVM.aif file for the icon. + setupIcon(); #endif // enable joystick @@ -208,17 +121,18 @@ void OSystem_SDL::initBackend() { // Create and hook up the timer manager, if none exists yet (we check for // this to allow subclasses to provide their own). if (_timer == 0) { - // TODO: We could implement a custom SDLTimerManager by using + // Note: We could implement a custom SDLTimerManager by using // SDL_AddTimer. That might yield better timer resolution, but it would // also change the semantics of a timer: Right now, ScummVM timers // *never* run in parallel, due to the way they are implemented. If we // switched to SDL_AddTimer, each timer might run in a separate thread. - // Unfortunately, not all our code is prepared for that, so we can't just - // switch. But it's a long term goal to do just that! + // However, not all our code is prepared for that, so we can't just + // switch. Still, it's a potential future change to keep in mind. _timer = new DefaultTimerManager(); _timerID = SDL_AddTimer(10, &timer_handler, _timer); } + // Invoke parent implementation of this method OSystem::initBackend(); _inited = true; @@ -427,28 +341,22 @@ bool OSystem_SDL::setSoundCallback(SoundProc proc, void *param) { SDL_AudioSpec desired; SDL_AudioSpec obtained; - memset(&desired, 0, sizeof(desired)); - + // Determine the desired output sampling frequency. _samplesPerSec = 0; - if (ConfMan.hasKey("output_rate")) _samplesPerSec = ConfMan.getInt("output_rate"); - if (_samplesPerSec <= 0) _samplesPerSec = SAMPLES_PER_SEC; - // Originally, we always used 2048 samples. This loop will produce the - // same result at 22050 Hz, and should hopefully produce something - // sensible for other frequencies. Note that it must be a power of two. - - uint32 samples = 0x8000; - - for (;;) { - if ((1000 * samples) / _samplesPerSec < 100) - break; + // Determine the sample buffer size. We want it to store enough data for + // about 1/10th of a second. Note that it must be a power of two. + // So e.g. at 22050 Hz, we request a sample buffer size of 2048. + int samples = 0x8000; + while (10 * samples >= _samplesPerSec) { samples >>= 1; } + memset(&desired, 0, sizeof(desired)); desired.freq = _samplesPerSec; desired.format = AUDIO_S16SYS; desired.channels = 2; diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h new file mode 100644 index 0000000000..38658ae76c --- /dev/null +++ b/backends/platform/sdl/sdl.h @@ -0,0 +1,415 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef SDL_COMMON_H +#define SDL_COMMON_H + +#include + +#include "common/stdafx.h" +#include "common/scummsys.h" +#include "common/system.h" +#include "graphics/scaler.h" +#include "backends/intern.h" + + +namespace Audio { + class Mixer; +} + +namespace Common { + class SaveFileManager; + class TimerManager; +} + +#if !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) +// Uncomment this to enable the 'on screen display' code. +#define USE_OSD 1 +#endif + + +enum { + GFX_NORMAL = 0, + GFX_DOUBLESIZE = 1, + GFX_TRIPLESIZE = 2, + GFX_2XSAI = 3, + GFX_SUPER2XSAI = 4, + GFX_SUPEREAGLE = 5, + GFX_ADVMAME2X = 6, + GFX_ADVMAME3X = 7, + GFX_HQ2X = 8, + GFX_HQ3X = 9, + GFX_TV2X = 10, + GFX_DOTMATRIX = 11 +}; + + +class OSystem_SDL : public OSystem { +public: + OSystem_SDL(); + virtual ~OSystem_SDL(); + + virtual void initBackend(); + + void beginGFXTransaction(void); + void endGFXTransaction(void); + + // Set the size of the video bitmap. + // Typically, 320x200 + virtual void initSize(uint w, uint h); // overloaded by CE backend + + virtual int getScreenChangeID() const { return _screenChangeCount; } + + // Set colors of the palette + void setPalette(const byte *colors, uint start, uint num); + + // Get colors of the palette + void grabPalette(byte *colors, uint start, uint num); + + // Draw a bitmap to screen. + // The screen will not be updated to reflect the new bitmap + virtual void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h); // overloaded by CE backend (FIXME) + + virtual Graphics::Surface *lockScreen(); + virtual void unlockScreen(); + + // Update the dirty areas of the screen + void updateScreen(); + + // Either show or hide the mouse cursor + bool showMouse(bool visible); + + // Warp the mouse cursor. Where set_mouse_pos() only informs the + // backend of the mouse cursor's current position, this function + // actually moves the cursor to the specified position. + 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) + + // Set colors of cursor palette + void setCursorPalette(const byte *colors, uint start, uint num); + + // Disables or enables cursor palette + void disableCursorPalette(bool disable) { + _cursorPaletteDisabled = disable; + blitCursor(); + } + + // Shaking is used in SCUMM. Set current shake position. + void setShakePos(int shake_pos); + + // Get the number of milliseconds since the program was started. + uint32 getMillis(); + + // Delay for a specified amount of milliseconds + void delayMillis(uint msecs); + + // Get the next event. + // Returns true if an event was retrieved. + virtual bool pollEvent(Common::Event &event); // overloaded by CE backend + + // Set function that generates samples + typedef void (*SoundProc)(void *param, byte *buf, int len); + virtual bool setSoundCallback(SoundProc proc, void *param); // overloaded by CE backend + virtual Audio::Mixer *getMixer(); + + // Poll CD status + // Returns true if cd audio is playing + bool pollCD(); + + // Play CD audio track + void playCD(int track, int num_loops, int start_frame, int duration); + + // Stop CD audio track + void stopCD(); + + // Update CD audio status + void updateCD(); + + // Quit + virtual void quit(); // overloaded by CE backend + + virtual Common::TimerManager *getTimerManager(); + + // Mutex handling + MutexRef createMutex(); + void lockMutex(MutexRef mutex); + void unlockMutex(MutexRef mutex); + void deleteMutex(MutexRef mutex); + + // Overlay + virtual void showOverlay(); // WinCE FIXME + virtual void hideOverlay(); // WinCE FIXME + virtual void clearOverlay(); + virtual void grabOverlay(OverlayColor *buf, int pitch); + virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); // WinCE FIXME + virtual int16 getHeight(); + virtual int16 getWidth(); + virtual int16 getOverlayHeight() { return _overlayHeight; } + virtual int16 getOverlayWidth() { return _overlayWidth; } + + // Methods that convert RGB to/from colors suitable for the overlay. + virtual OverlayColor RGBToColor(uint8 r, uint8 g, uint8 b); + virtual void colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b); + + + virtual const GraphicsMode *getSupportedGraphicsModes() const; + virtual int getDefaultGraphicsMode() const; + virtual bool setGraphicsMode(int mode); + virtual int getGraphicsMode() const; + + virtual void setWindowCaption(const char *caption); + virtual bool openCD(int drive); + virtual int getOutputSampleRate() const; + + virtual bool hasFeature(Feature f); + virtual void setFeatureState(Feature f, bool enable); + virtual bool getFeatureState(Feature f); + +#ifdef USE_OSD + void displayMessageOnOSD(const char *msg); +#endif + + virtual Common::SaveFileManager *getSavefileManager(); + +protected: + bool _inited; + +#ifdef USE_OSD + SDL_Surface *_osdSurface; + Uint8 _osdAlpha; // Transparency level of the OSD + uint32 _osdFadeStartTime; // When to start the fade out + enum { + kOSDFadeOutDelay = 2 * 1000, // Delay before the OSD is faded out (in milliseconds) + kOSDFadeOutDuration = 500, // Duration of the OSD fade out (in milliseconds) + kOSDColorKey = 1, + kOSDInitialAlpha = 80 // Initial alpha level, in percent + }; +#endif + + // hardware screen + SDL_Surface *_hwscreen; + + // unseen game screen + SDL_Surface *_screen; + + // TODO: We could get rid of the following two vars and just use _screen instead + int _screenWidth, _screenHeight; + + // temporary screen (for scalers) + SDL_Surface *_tmpscreen; + SDL_Surface *_tmpscreen2; + + // overlay + SDL_Surface *_overlayscreen; + int _overlayWidth, _overlayHeight; + bool _overlayVisible; + + // Audio + int _samplesPerSec; + + // CD Audio + SDL_CD *_cdrom; + int _cdTrack, _cdNumLoops, _cdStartFrame, _cdDuration; + uint32 _cdEndTime, _cdStopTime; + + enum { + DF_WANT_RECT_OPTIM = 1 << 0 + }; + + enum { + kTransactionNone = 0, + kTransactionCommit = 1, + kTransactionActive = 2 + }; + + struct TransactionDetails { + int mode; + bool modeChanged; + int w; + int h; + bool sizeChanged; + bool fs; + bool fsChanged; + bool ar; + bool arChanged; + bool needHotswap; + bool needUpdatescreen; + bool needUnload; + bool needToggle; + bool normal1xScaler; + }; + TransactionDetails _transactionDetails; + + /** Force full redraw on next updateScreen */ + bool _forceFull; + ScalerProc *_scalerProc; + int _scalerType; + int _scaleFactor; + int _mode; + int _transactionMode; + bool _fullscreen; + + bool _screenIsLocked; + Graphics::Surface _framebuffer; + + /** Current video mode flags (see DF_* constants) */ + uint32 _modeFlags; + bool _modeChanged; + int _screenChangeCount; + + /** True if aspect ratio correction is enabled. */ + bool _adjustAspectRatio; + + enum { + NUM_DIRTY_RECT = 100, + MAX_SCALING = 3 + }; + + // Dirty rect management + SDL_Rect _dirtyRectList[NUM_DIRTY_RECT]; + int _numDirtyRects; + uint32 *_dirtyChecksums; + bool _cksumValid; + int _cksumNum; + + // Keyboard mouse emulation. Disabled by fingolfin 2004-12-18. + // I am keeping the rest of the code in for now, since the joystick + // code (or rather, "hack") uses it, too. + struct KbdMouse { + int16 x, y, x_vel, y_vel, x_max, y_max, x_down_count, y_down_count; + uint32 last_time, delay_time, x_down_time, y_down_time; + }; + + struct MousePos { + // The mouse position, using either virtual (game) or real + // (overlay) coordinates. + int16 x, y; + + // The size and hotspot of the original cursor image. + int16 w, h; + int16 hotX, hotY; + + // The size and hotspot of the pre-scaled cursor image, in real + // coordinates. + int16 rW, rH; + int16 rHotX, rHotY; + + // The size and hotspot of the pre-scaled cursor image, in game + // coordinates. + int16 vW, vH; + int16 vHotX, vHotY; + + MousePos() : x(0), y(0), w(0), h(0), hotX(0), hotY(0), + rW(0), rH(0), rHotX(0), rHotY(0), vW(0), vH(0), + vHotX(0), vHotY(0) + { } + }; + + // mouse + KbdMouse _km; + bool _mouseVisible; + bool _mouseDrawn; + byte *_mouseData; + SDL_Rect _mouseBackup; + MousePos _mouseCurState; + byte _mouseKeyColor; + int _cursorTargetScale; + bool _cursorPaletteDisabled; + SDL_Surface *_mouseOrigSurface; + SDL_Surface *_mouseSurface; + enum { + kMouseColorKey = 1 + }; + + // joystick + SDL_Joystick *_joystick; + + // Shake mode + int _currentShakePos; + int _newShakePos; + + // Palette data + SDL_Color *_currentPalette; + uint _paletteDirtyStart, _paletteDirtyEnd; + + // Cursor palette data + SDL_Color *_cursorPalette; + + /** + * Mutex which prevents multiple threads from interfering with each other + * when accessing the screen. + */ + MutexRef _graphicsMutex; + + + Common::SaveFileManager *_savefile; + Audio::Mixer *_mixer; + + SDL_TimerID _timerID; + Common::TimerManager *_timer; + + + + void addDirtyRgnAuto(const byte *buf); + void makeChecksums(const byte *buf); + + virtual void addDirtyRect(int x, int y, int w, int h, bool realCoordinates = false); // overloaded by CE backend + + virtual void drawMouse(); // overloaded by CE backend + virtual void undrawMouse(); // overloaded by CE backend (FIXME) + virtual void blitCursor(); // overloaded by CE backend (FIXME) + + /** Set the position of the virtual mouse cursor. */ + void setMousePos(int x, int y); + virtual void fillMouseEvent(Common::Event &event, int x, int y); // overloaded by CE backend + void toggleMouseGrab(); + + virtual void internUpdateScreen(); // overloaded by CE backend + + virtual void loadGFXMode(); // overloaded by CE backend + virtual void unloadGFXMode(); // overloaded by CE backend + virtual void hotswapGFXMode(); // overloaded by CE backend + + void setFullscreenMode(bool enable); + void setAspectRatioCorrection(bool enable); + + virtual bool saveScreenshot(const char *filename); // overloaded by CE backend + + int effectiveScreenHeight() const { + return (_adjustAspectRatio ? real2Aspect(_screenHeight) : _screenHeight) + * _scaleFactor; + } + + void setupIcon(); + void handleKbdMouse(); + + virtual bool remapKey(SDL_Event &ev, Common::Event &event); + + void handleScalerHotkeys(const SDL_KeyboardEvent &key); +}; + +#endif -- cgit v1.2.3