Ticket #9198: scummvm-dingux-04082010-port.diff

File scummvm-dingux-04082010-port.diff, 24.7 KB (added by hkzlab, 14 years ago)

Patch against svn trunk rev.51723

  • configure

     
    930930        _host_os=riscos
    931931        _host_cpu=arm
    932932        ;;
     933dingux)
     934        _host_os=linux
     935        _host_cpu=mipsel
     936        _host_alias=mipsel-linux
     937        ;;
    933938dreamcast)
    934939        _host_os=dreamcast
    935940        _host_cpu=sh
     
    15241529                        _ranlib=$_host-ranlib
    15251530                        _strip=$_host-strip
    15261531                        ;;
     1532                dingux)
     1533                        DEFINES="$DEFINES -DUNIX -DDINGUX -DDISABLE_DOSBOX_OPL"
     1534                        ASFLAGS="$ASFLAGS"
     1535                        CXXFLAGS="$CXXFLAGS -msoft-float -mips32"
     1536                        _need_memalign=yes
     1537                        _backend="dingux"
     1538                        _mt32emu=no
     1539                        _vkeybd=yes
     1540                        _build_hq_scalers=no
     1541                        _keymapper=no
     1542                        ;;
    15271543                dreamcast)
    15281544                        DEFINES="$DEFINES -DDISABLE_DEFAULT_SAVEFILEMANAGER -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE"
    15291545                        CXXFLAGS="$CXXFLAGS -O3 -funroll-loops -fschedule-insns2 -fomit-frame-pointer -fdelete-null-pointer-checks"
     
    18381854# Enable 16bit support only for backends which support it
    18391855#
    18401856case $_backend in
    1841         dreamcast | samsungtv | sdl | wii | psp)
     1857        dreamcast | dingux | samsungtv | sdl | wii | psp)
    18421858                if test "$_16bit" = auto ; then
    18431859                        _16bit=yes
    18441860                else
     
    25122528                LDFLAGS="$LDFLAGS -Wl,-Ttext,0x8c010000 -nostartfiles "'$(ronindir)/lib/crt0.o -L$(ronindir)/lib'
    25132529                LIBS="$LIBS -lronin -lm"
    25142530                ;;
     2531        dingux)
     2532                find_sdlconfig
     2533                INCLUDES="$INCLUDES `$_sdlconfig --prefix="$_sdlpath" --cflags`"
     2534                LIBS="$LIBS `$_sdlconfig --prefix="$_sdlpath" --libs`"
     2535                DEFINES="$DEFINES -DSDL_BACKEND -DDINGUX"
     2536                LDFLAGS="$LDFLAGS "
     2537                MODULES="$MODULES backends/platform/sdl"
     2538                ;;
    25152539        ds)
    25162540                # TODO ds
    25172541                INCLUDES="$INCLUDES "'-I$(srcdir)/backends/platform/ds/arm9/source'
  • common/scummsys.h

     
    243243        #define SCUMM_NEED_ALIGNMENT
    244244        #endif
    245245
     246        // Very BAD hack following, used to avoid triggering an assert in uClibc dingux library
     247        // "toupper" when pressing keyboard function keys.
     248        #if defined(DINGUX)
     249        #undef toupper
     250        #define toupper(c) (((c & 0xFF) >= 97) && ((c & 0xFF) <= 122) ? ((c & 0xFF) - 32) : (c & 0xFF))
     251        #endif
     252
    246253#elif defined(__DC__)
    247254
    248255        #define scumm_stricmp strcasecmp
  • backends/platform/sdl/graphics.cpp

     
    537537        assert(_inited);
    538538        _forceFull = true;
    539539
    540 #if !defined(__MAEMO__) && !defined(GP2XWIZ) && !defined(LINUXMOTO)
     540#if !defined(__MAEMO__) && !defined(GP2XWIZ) && !defined(LINUXMOTO) && !defined(DINGUX)
    541541        _videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
    542542        _videoMode.overlayHeight = _videoMode.screenHeight * _videoMode.scaleFactor;
    543543
  • backends/platform/sdl/sdl.cpp

     
    150150        memset(&_videoMode, 0, sizeof(_videoMode));
    151151        memset(&_transactionDetails, 0, sizeof(_transactionDetails));
    152152
    153 #if !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) && defined(USE_SCALERS)
     153#if !defined(_WIN32_WCE) && !defined(DINGUX) && !defined(__SYMBIAN32__) && defined(USE_SCALERS)
    154154        _videoMode.mode = GFX_DOUBLESIZE;
    155155        _videoMode.scaleFactor = 2;
    156156        _videoMode.aspectRatioCorrection = ConfMan.getBool("aspect_ratio");
  • backends/platform/sdl/main.cpp

     
    3838
    3939// Several SDL based ports use a custom main, and hence do not want to compile
    4040// of this file. The following "#if" ensures that.
    41 #if !defined(__MAEMO__) && !defined(_WIN32_WCE) && !defined(GP2XWIZ)&& !defined(LINUXMOTO) && !defined(__SYMBIAN32__)
     41#if !defined(__MAEMO__) && !defined(_WIN32_WCE) && !defined(GP2XWIZ)&& !defined(LINUXMOTO) && !defined(__SYMBIAN32__) && !defined(DINGUX)
    4242
    4343
    4444#include "backends/platform/sdl/sdl.h"
  • backends/platform/dingux/dingux.cpp

     
     1
     2#include "backends/platform/dingux/dingux.h"
     3
     4#if defined(DINGUX)
     5
     6bool OSystem_SDL_Dingux::hasFeature(Feature f) {
     7        return
     8            (f == kFeatureAspectRatioCorrection) ||
     9            (f == kFeatureCursorHasPalette);
     10}
     11
     12void OSystem_SDL_Dingux::setFeatureState(Feature f, bool enable) {
     13        switch (f) {
     14        case kFeatureAspectRatioCorrection:
     15                setAspectRatioCorrection(enable);
     16                break;
     17        default:
     18                break;
     19        }
     20}
     21
     22bool OSystem_SDL_Dingux::getFeatureState(Feature f) {
     23        assert(_transactionMode == kTransactionNone);
     24
     25        switch (f) {
     26        case kFeatureAspectRatioCorrection:
     27                return _videoMode.aspectRatioCorrection;
     28        default:
     29                return false;
     30        }
     31}
     32
     33#endif
     34
  • backends/platform/dingux/dingux-events.cpp

     
     1
     2#include "backends/platform/dingux/dingux.h"
     3
     4#include "graphics/scaler/aspect.h"     // for aspect2Real
     5
     6#if defined (DINGUX)
     7
     8#define PAD_UP    SDLK_UP
     9#define PAD_DOWN  SDLK_DOWN
     10#define PAD_LEFT  SDLK_LEFT
     11#define PAD_RIGHT SDLK_RIGHT
     12#define BUT_A     SDLK_LCTRL
     13#define BUT_B     SDLK_LALT
     14#define BUT_X     SDLK_SPACE
     15#define BUT_Y     SDLK_LSHIFT
     16#define BUT_SELECT   SDLK_ESCAPE
     17#define BUT_START    SDLK_RETURN
     18#define TRIG_L    SDLK_TAB
     19#define TRIG_R    SDLK_BACKSPACE
     20
     21static int mapKey(SDLKey key, SDLMod mod, Uint16 unicode) {
     22        if (key >= SDLK_F1 && key <= SDLK_F9) {
     23                return key - SDLK_F1 + Common::ASCII_F1;
     24        } else if (key >= SDLK_KP0 && key <= SDLK_KP9) {
     25                return key - SDLK_KP0 + '0';
     26        } else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) {
     27                return key;
     28        } else if (unicode) {
     29                return unicode;
     30        } else if (key >= 'a' && key <= 'z' && (mod & KMOD_SHIFT)) {
     31                return key & ~0x20;
     32        } else if (key >= SDLK_NUMLOCK && key <= SDLK_EURO) {
     33                return 0;
     34        }
     35        return key;
     36}
     37
     38bool OSystem_SDL_Dingux::remapKey(SDL_Event &ev, Common::Event &event) {
     39        if (ev.key.keysym.sym == PAD_UP) {
     40                if (ev.type == SDL_KEYDOWN) {
     41                        _km.y_vel = -1;
     42                        _km.y_down_count = 1;
     43                } else {
     44                        _km.y_vel = 0;
     45                        _km.y_down_count = 0;
     46                }
     47
     48                event.type = Common::EVENT_MOUSEMOVE;
     49                fillMouseEvent(event, _km.x, _km.y);
     50
     51                return true;
     52        } else if (ev.key.keysym.sym == PAD_DOWN) {
     53                if (ev.type == SDL_KEYDOWN) {
     54                        _km.y_vel = 1;
     55                        _km.y_down_count = 1;
     56                } else {
     57                        _km.y_vel = 0;
     58                        _km.y_down_count = 0;
     59                }
     60
     61                event.type = Common::EVENT_MOUSEMOVE;
     62                fillMouseEvent(event, _km.x, _km.y);
     63
     64                return true;
     65        } else if (ev.key.keysym.sym == PAD_LEFT) {
     66                if (ev.type == SDL_KEYDOWN) {
     67                        _km.x_vel = -1;
     68                        _km.x_down_count = 1;
     69                } else {
     70                        _km.x_vel = 0;
     71                        _km.x_down_count = 0;
     72                }
     73
     74                event.type = Common::EVENT_MOUSEMOVE;
     75                fillMouseEvent(event, _km.x, _km.y);
     76
     77                return true;
     78        } else if (ev.key.keysym.sym == PAD_RIGHT) {
     79                if (ev.type == SDL_KEYDOWN) {
     80                        _km.x_vel = 1;
     81                        _km.x_down_count = 1;
     82                } else {
     83                        _km.x_vel = 0;
     84                        _km.x_down_count = 0;
     85                }
     86
     87                event.type = Common::EVENT_MOUSEMOVE;
     88                fillMouseEvent(event, _km.x, _km.y);
     89
     90                return true;
     91        } else if (ev.key.keysym.sym == BUT_Y) { // left mouse button
     92                if (ev.type == SDL_KEYDOWN) {
     93                        event.type = Common::EVENT_LBUTTONDOWN;
     94                } else {
     95                        event.type = Common::EVENT_LBUTTONUP;
     96                }
     97
     98                fillMouseEvent(event, _km.x, _km.y);
     99
     100                return true;
     101        } else if (ev.key.keysym.sym == BUT_B) { // right mouse button
     102                if (ev.type == SDL_KEYDOWN) {
     103                        event.type = Common::EVENT_RBUTTONDOWN;
     104                } else {
     105                        event.type = Common::EVENT_RBUTTONUP;
     106                }
     107
     108                fillMouseEvent(event, _km.x, _km.y);
     109
     110                return true;
     111        } else if (ev.key.keysym.sym == BUT_X) { // '.' skip dialogue
     112                ev.key.keysym.sym = SDLK_PERIOD;
     113                ev.key.keysym.mod = (SDLMod)0;
     114                ev.key.keysym.unicode = '.';
     115        } else if (ev.key.keysym.sym == TRIG_L) { // global menu
     116                ev.key.keysym.sym = SDLK_F5;
     117                event.kbd.keycode = Common::KEYCODE_F5;
     118                event.kbd.ascii = Common::ASCII_F5;
     119                event.kbd.flags = Common::KBD_CTRL;
     120
     121                if (ev.type == SDL_KEYDOWN) {
     122                        event.type = Common::EVENT_KEYDOWN;
     123                } else {
     124                        event.type = Common::EVENT_KEYUP;
     125                }
     126
     127                return true;
     128        } else if (ev.key.keysym.sym == BUT_A) { // virtual keyboard
     129                ev.key.keysym.sym = SDLK_0;
     130
     131                event.kbd.keycode = Common::KEYCODE_0;
     132                event.kbd.ascii = '0';
     133                event.kbd.flags = 0;
     134
     135                if (ev.type == SDL_KEYDOWN) {
     136                        event.type = Common::EVENT_KEYDOWN;
     137                } else {
     138                        event.type = Common::EVENT_KEYUP;
     139                }
     140
     141                return true;
     142        } else if (ev.key.keysym.sym == BUT_SELECT) { // virtual keyboard
     143                ev.key.keysym.sym = SDLK_F7;
     144
     145        } else if (ev.key.keysym.sym == BUT_START) { // F5, menu in some games
     146                ev.key.keysym.sym = SDLK_F5;
     147
     148        }  else if (ev.key.keysym.sym == TRIG_R) { // ESC
     149                ev.key.keysym.sym = SDLK_ESCAPE;
     150        } else {
     151                event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym;
     152                event.kbd.ascii = mapKey(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode);
     153        }
     154
     155        return false;
     156}
     157
     158void OSystem_SDL_Dingux::fillMouseEvent(Common::Event &event, int x, int y) {
     159        if (_videoMode.mode == GFX_HALF && !_overlayVisible) {
     160                event.mouse.x = x * 2;
     161                event.mouse.y = y * 2;
     162        } else {
     163                event.mouse.x = x;
     164                event.mouse.y = y;
     165        }
     166
     167        // Update the "keyboard mouse" coords
     168        _km.x = x;
     169        _km.y = y;
     170
     171        // Adjust for the screen scaling
     172        if (!_overlayVisible) {
     173                event.mouse.x /= _videoMode.scaleFactor;
     174                event.mouse.y /= _videoMode.scaleFactor;
     175                if (_videoMode.aspectRatioCorrection)
     176                        event.mouse.y = aspect2Real(event.mouse.y);
     177        }
     178}
     179
     180void OSystem_SDL_Dingux::warpMouse(int x, int y) {
     181        if (_mouseCurState.x != x || _mouseCurState.y != y) {
     182                if (_videoMode.mode == GFX_HALF && !_overlayVisible) {
     183                        x = x / 2;
     184                        y = y / 2;
     185                }
     186        }
     187        OSystem_SDL::warpMouse(x, y);
     188}
     189
     190#endif
     191
  • backends/platform/dingux/dingux.h

     
     1
     2#ifndef SDL_DINGUX_COMMON_H
     3#define SDL_DINGUX_COMMON_H
     4
     5#include <SDL.h>
     6
     7#include "backends/base-backend.h"
     8#include "backends/platform/sdl/sdl.h"
     9
     10#if defined(DINGUX)
     11
     12enum {
     13        GFX_HALF = 12
     14};
     15
     16class OSystem_SDL_Dingux : public OSystem_SDL {
     17public:
     18        virtual bool hasFeature(Feature f);
     19        virtual void setFeatureState(Feature f, bool enable);
     20        virtual bool getFeatureState(Feature f);
     21        virtual int getDefaultGraphicsMode() const;
     22        void initSize(uint w, uint h);
     23        const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
     24        bool setGraphicsMode(const char *name);
     25        bool setGraphicsMode(int mode);
     26        void setGraphicsModeIntern();
     27        void internUpdateScreen();
     28        void showOverlay();
     29        void hideOverlay();
     30        bool loadGFXMode();
     31        void drawMouse();
     32        void undrawMouse();     
     33        void warpMouse(int, int);
     34        void fillMouseEvent(Common::Event&, int, int);
     35
     36protected:
     37        virtual bool remapKey(SDL_Event &ev, Common::Event &event);
     38};
     39
     40
     41#endif
     42
     43#endif
     44
  • backends/platform/dingux/main.cpp

     
     1
     2#include "backends/platform/dingux/dingux.h"
     3#include "backends/plugins/sdl/sdl-provider.h"
     4//#include "backends/plugins/posix/posix-provider.h"
     5#include "base/main.h"
     6
     7#if defined(DINGUX)
     8
     9#include <unistd.h>
     10
     11int main(int argc, char* argv[]) {
     12
     13        g_system = new OSystem_SDL_Dingux();
     14        assert(g_system);
     15
     16#ifdef DYNAMIC_MODULES
     17        PluginManager::instance().addPluginProvider(new SDLPluginProvider());
     18//      PluginManager::instance().addPluginProvider(new POSIXPluginProvider());
     19#endif
     20
     21        // Invoke the actual ScummVM main entry point:
     22        int res = scummvm_main(argc, argv);
     23        ((OSystem_SDL *)g_system)->deinit();
     24        return res;
     25
     26}
     27
     28#endif
     29
  • backends/platform/dingux/module.mk

     
     1MODULE := backends/platform/dingux
     2
     3MODULE_OBJS := \
     4        main.o \
     5        dingux.o \
     6        dingux-events.o \
     7        dingux-graphics.o \
     8
     9MODULE_DIRS += \
     10        backends/platform/dingux/
     11
     12# We don't use the rules.mk here on purpose
     13OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS)
  • backends/platform/dingux/dingux-graphics.cpp

     
     1
     2#include "backends/platform/dingux/dingux.h"
     3
     4#include "common/mutex.h"
     5#include "graphics/scaler.h"
     6#include "graphics/scaler/aspect.h"
     7#include "graphics/scaler/downscaler.h"
     8#include "graphics/surface.h"
     9
     10#if defined (DINGUX)
     11
     12static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
     13        {"1x", "Standard", GFX_NORMAL},
     14        {0, 0, 0}
     15};
     16
     17int OSystem_SDL_Dingux::getDefaultGraphicsMode() const {
     18        return GFX_NORMAL;
     19}
     20
     21const OSystem::GraphicsMode *OSystem_SDL_Dingux::getSupportedGraphicsModes() const {
     22        return s_supportedGraphicsModes;
     23}
     24
     25bool OSystem_SDL_Dingux::setGraphicsMode(int mode) {
     26        Common::StackLock lock(_graphicsMutex);
     27
     28        assert(_transactionMode == kTransactionActive);
     29
     30        if (_oldVideoMode.setup && _oldVideoMode.mode == mode)
     31                return true;
     32
     33        int newScaleFactor = 1;
     34
     35        switch (mode) {
     36        case GFX_NORMAL:
     37                newScaleFactor = 1;
     38                break;
     39        case GFX_HALF:
     40                newScaleFactor = 1;
     41                break;
     42        default:
     43                warning("unknown gfx mode %d", mode);
     44                return false;
     45        }
     46
     47        _transactionDetails.normal1xScaler = (mode == GFX_NORMAL);
     48        if (_oldVideoMode.setup && _oldVideoMode.scaleFactor != newScaleFactor)
     49                _transactionDetails.needHotswap = true;
     50
     51        _transactionDetails.needUpdatescreen = true;
     52
     53        _videoMode.mode = mode;
     54        _videoMode.scaleFactor = newScaleFactor;
     55
     56        return true;
     57}
     58
     59void OSystem_SDL_Dingux::setGraphicsModeIntern() {
     60        Common::StackLock lock(_graphicsMutex);
     61        ScalerProc *newScalerProc = 0;
     62
     63        switch (_videoMode.mode) {
     64        case GFX_NORMAL:
     65                newScalerProc = Normal1x;
     66                break;
     67        case GFX_HALF:
     68                newScalerProc = DownscaleAllByHalf;
     69                break;
     70
     71        default:
     72                error("Unknown gfx mode %d", _videoMode.mode);
     73        }
     74
     75        _scalerProc = newScalerProc;
     76
     77        if (!_screen || !_hwscreen)
     78                return;
     79
     80        // Blit everything to the screen
     81        _forceFull = true;
     82
     83        // Even if the old and new scale factors are the same, we may have a
     84        // different scaler for the cursor now.
     85        blitCursor();
     86}
     87
     88void OSystem_SDL_Dingux::initSize(uint w, uint h) {
     89        assert(_transactionMode == kTransactionActive);
     90
     91        // Avoid redundant res changes
     92        if ((int)w == _videoMode.screenWidth && (int)h == _videoMode.screenHeight)
     93                return;
     94
     95        _videoMode.screenWidth = w;
     96        _videoMode.screenHeight = h;
     97        if (w > 320 || h > 240) {
     98                setGraphicsMode(GFX_HALF);
     99                setGraphicsModeIntern();
     100                toggleMouseGrab();
     101        }
     102
     103        _transactionDetails.sizeChanged = true;
     104}
     105
     106void OSystem_SDL_Dingux::drawMouse() {
     107        if (!_mouseVisible || !_mouseSurface) {
     108                _mouseBackup.x = _mouseBackup.y = _mouseBackup.w = _mouseBackup.h = 0;
     109                return;
     110        }
     111
     112        SDL_Rect dst;
     113        int scale;
     114        int hotX, hotY;
     115
     116        if (_videoMode.mode == GFX_HALF && !_overlayVisible) {
     117                dst.x = _mouseCurState.x / 2;
     118                dst.y = _mouseCurState.y / 2;
     119        } else {
     120                dst.x = _mouseCurState.x;
     121                dst.y = _mouseCurState.y;
     122        }
     123
     124        if (!_overlayVisible) {
     125                scale = _videoMode.scaleFactor;
     126                dst.w = _mouseCurState.vW;
     127                dst.h = _mouseCurState.vH;
     128                hotX = _mouseCurState.vHotX;
     129                hotY = _mouseCurState.vHotY;
     130        } else {
     131                scale = 1;
     132                dst.w = _mouseCurState.rW;
     133                dst.h = _mouseCurState.rH;
     134                hotX = _mouseCurState.rHotX;
     135                hotY = _mouseCurState.rHotY;
     136        }
     137
     138        // The mouse is undrawn using virtual coordinates, i.e. they may be
     139        // scaled and aspect-ratio corrected.
     140
     141        _mouseBackup.x = dst.x - hotX;
     142        _mouseBackup.y = dst.y - hotY;
     143        _mouseBackup.w = dst.w;
     144        _mouseBackup.h = dst.h;
     145
     146        // We draw the pre-scaled cursor image, so now we need to adjust for
     147        // scaling, shake position and aspect ratio correction manually.
     148
     149        if (!_overlayVisible) {
     150                dst.y += _currentShakePos;
     151        }
     152
     153        if (_videoMode.aspectRatioCorrection && !_overlayVisible)
     154                dst.y = real2Aspect(dst.y);
     155
     156        dst.x = scale * dst.x - _mouseCurState.rHotX;
     157        dst.y = scale * dst.y - _mouseCurState.rHotY;
     158        dst.w = _mouseCurState.rW;
     159        dst.h = _mouseCurState.rH;
     160
     161        // Note that SDL_BlitSurface() and addDirtyRect() will both perform any
     162        // clipping necessary
     163
     164        if (SDL_BlitSurface(_mouseSurface, NULL, _hwscreen, &dst) != 0)
     165                error("SDL_BlitSurface failed: %s", SDL_GetError());
     166
     167        // The screen will be updated using real surface coordinates, i.e.
     168        // they will not be scaled or aspect-ratio corrected.
     169        addDirtyRect(dst.x, dst.y, dst.w, dst.h, true);
     170}
     171
     172void OSystem_SDL_Dingux::undrawMouse() {
     173        const int x = _mouseBackup.x;
     174        const int y = _mouseBackup.y;
     175
     176        // When we switch bigger overlay off mouse jumps. Argh!
     177        // This is intended to prevent undrawing offscreen mouse
     178        if (!_overlayVisible && (x >= _videoMode.screenWidth || y >= _videoMode.screenHeight))
     179                return;
     180
     181        if (_mouseBackup.w != 0 && _mouseBackup.h != 0) {
     182                if (_videoMode.mode == GFX_HALF && !_overlayVisible) {
     183                        addDirtyRect(x*2, y*2, _mouseBackup.w*2, _mouseBackup.h*2);
     184                } else {
     185                        addDirtyRect(x, y, _mouseBackup.w, _mouseBackup.h);
     186                }
     187        }
     188}
     189
     190void OSystem_SDL_Dingux::internUpdateScreen() {
     191        SDL_Surface *srcSurf, *origSurf;
     192        int height, width;
     193        ScalerProc *scalerProc;
     194        int scale1;
     195
     196#if defined (DEBUG) && ! defined(_WIN32_WCE) // definitions not available for non-DEBUG here. (needed this to compile in SYMBIAN32 & linux?)
     197        assert(_hwscreen != NULL);
     198        assert(_hwscreen->map->sw_data != NULL);
     199#endif
     200
     201        // If the shake position changed, fill the dirty area with blackness
     202        if (_currentShakePos != _newShakePos) {
     203                SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _videoMode.scaleFactor, _newShakePos * _videoMode.scaleFactor};
     204
     205                if (_videoMode.aspectRatioCorrection && !_overlayVisible)
     206                        blackrect.h = real2Aspect(blackrect.h - 1) + 1;
     207
     208                SDL_FillRect(_hwscreen, &blackrect, 0);
     209
     210                _currentShakePos = _newShakePos;
     211
     212                _forceFull = true;
     213        }
     214
     215        // Check whether the palette was changed in the meantime and update the
     216        // screen surface accordingly.
     217        if (_screen && _paletteDirtyEnd != 0) {
     218                SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart,
     219                              _paletteDirtyStart,
     220                              _paletteDirtyEnd - _paletteDirtyStart);
     221
     222                _paletteDirtyEnd = 0;
     223
     224                _forceFull = true;
     225        }
     226
     227#ifdef USE_OSD
     228        // OSD visible (i.e. non-transparent)?
     229        if (_osdAlpha != SDL_ALPHA_TRANSPARENT) {
     230                // Updated alpha value
     231                const int diff = SDL_GetTicks() - _osdFadeStartTime;
     232                if (diff > 0) {
     233                        if (diff >= kOSDFadeOutDuration) {
     234                                // Back to full transparency
     235                                _osdAlpha = SDL_ALPHA_TRANSPARENT;
     236                        } else {
     237                                // Do a linear fade out...
     238                                const int startAlpha = SDL_ALPHA_TRANSPARENT + kOSDInitialAlpha * (SDL_ALPHA_OPAQUE - SDL_ALPHA_TRANSPARENT) / 100;
     239                                _osdAlpha = startAlpha + diff * (SDL_ALPHA_TRANSPARENT - startAlpha) / kOSDFadeOutDuration;
     240                        }
     241                        SDL_SetAlpha(_osdSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, _osdAlpha);
     242                        _forceFull = true;
     243                }
     244        }
     245#endif
     246
     247        if (!_overlayVisible) {
     248                origSurf = _screen;
     249                srcSurf = _tmpscreen;
     250                width = _videoMode.screenWidth;
     251                height = _videoMode.screenHeight;
     252                scalerProc = _scalerProc;
     253                scale1 = _videoMode.scaleFactor;
     254        } else {
     255                origSurf = _overlayscreen;
     256                srcSurf = _tmpscreen2;
     257                width = _videoMode.overlayWidth;
     258                height = _videoMode.overlayHeight;
     259                scalerProc = Normal1x;
     260                scale1 = 1;
     261        }
     262
     263        // Add the area covered by the mouse cursor to the list of dirty rects if
     264        // we have to redraw the mouse.
     265        if (_mouseNeedsRedraw)
     266                undrawMouse();
     267
     268        // Force a full redraw if requested
     269        if (_forceFull) {
     270                _numDirtyRects = 1;
     271                _dirtyRectList[0].x = 0;
     272                _dirtyRectList[0].y = 0;
     273                _dirtyRectList[0].w = width;
     274                _dirtyRectList[0].h = height;
     275        }
     276
     277        // Only draw anything if necessary
     278        if (_numDirtyRects > 0 || _mouseNeedsRedraw) {
     279                SDL_Rect *r;
     280                SDL_Rect dst;
     281                uint32 srcPitch, dstPitch;
     282                SDL_Rect *lastRect = _dirtyRectList + _numDirtyRects;
     283
     284                for (r = _dirtyRectList; r != lastRect; ++r) {
     285                        dst = *r;
     286                        dst.x++;        // Shift rect by one since 2xSai needs to access the data around
     287                        dst.y++;        // any pixel to scale it, and we want to avoid mem access crashes.
     288
     289                        if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0)
     290                                error("SDL_BlitSurface failed: %s", SDL_GetError());
     291                }
     292
     293                SDL_LockSurface(srcSurf);
     294                SDL_LockSurface(_hwscreen);
     295
     296                srcPitch = srcSurf->pitch;
     297                dstPitch = _hwscreen->pitch;
     298
     299                for (r = _dirtyRectList; r != lastRect; ++r) {
     300                        register int dst_y = r->y + _currentShakePos;
     301                        register int dst_h = 0;
     302                        register int dst_w = r->w;
     303                        register int orig_dst_y = 0;
     304                        register int dst_x = r->x;
     305                        register int src_y;
     306                        register int src_x;
     307
     308                        if (dst_y < height) {
     309                                dst_h = r->h;
     310                                if (dst_h > height - dst_y)
     311                                        dst_h = height - dst_y;
     312
     313                                orig_dst_y = dst_y;
     314                                src_x = dst_x;
     315                                src_y = dst_y;
     316
     317                                if (_videoMode.aspectRatioCorrection && !_overlayVisible)
     318                                        dst_y = real2Aspect(dst_y);
     319
     320                                assert(scalerProc != NULL);
     321
     322                                if ((_videoMode.mode == GFX_HALF) && (scalerProc == DownscaleAllByHalf)) {
     323                                        if (dst_x % 2 == 1) {
     324                                                dst_x--;
     325                                                dst_w++;
     326                                        }
     327                                        if (dst_y % 2 == 1) {
     328                                                dst_y--;
     329                                                dst_h++;
     330                                        }
     331                                        src_x = dst_x;
     332                                        src_y = dst_y;
     333                                        dst_x = dst_x / 2;
     334                                        dst_y = dst_y / 2;
     335
     336                                        scalerProc((byte *)srcSurf->pixels + (src_x * 2 + 2) + (src_y + 1) * srcPitch, srcPitch,
     337                                                   (byte *)_hwscreen->pixels + dst_x * 2 + dst_y * dstPitch, dstPitch, dst_w, dst_h);
     338
     339                                } else {
     340                                        scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch,
     341                                                   (byte *)_hwscreen->pixels + r->x * 2 + dst_y * dstPitch, dstPitch, r->w, dst_h);
     342                                }
     343                        }
     344
     345                        if (_videoMode.mode == GFX_HALF && scalerProc == DownscaleAllByHalf) {
     346                                r->w = r->w / 2;
     347                                r->h = dst_h / 2;
     348                        } else {
     349                                r->w = r->w;
     350                                r->h = dst_h;
     351                        }
     352
     353                        r->x = dst_x;
     354                        r->y = dst_y;
     355
     356
     357#ifdef USE_SCALERS
     358                        if (_videoMode.aspectRatioCorrection && orig_dst_y < height && !_overlayVisible)
     359                                r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1);
     360#endif
     361                }
     362                SDL_UnlockSurface(srcSurf);
     363                SDL_UnlockSurface(_hwscreen);
     364
     365                // Readjust the dirty rect list in case we are doing a full update.
     366                // This is necessary if shaking is active.
     367                if (_forceFull) {
     368                        _dirtyRectList[0].y = 0;
     369                        _dirtyRectList[0].h = (_videoMode.mode == GFX_HALF) ? effectiveScreenHeight() / 2 : effectiveScreenHeight();
     370                }
     371
     372                drawMouse();
     373
     374#ifdef USE_OSD
     375                if (_osdAlpha != SDL_ALPHA_TRANSPARENT) {
     376                        SDL_BlitSurface(_osdSurface, 0, _hwscreen, 0);
     377                }
     378#endif
     379                // Finally, blit all our changes to the screen
     380                SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList);
     381        }
     382
     383        _numDirtyRects = 0;
     384        _forceFull = false;
     385        _mouseNeedsRedraw = false;
     386}
     387
     388void OSystem_SDL_Dingux::showOverlay() {
     389        if (_videoMode.mode == GFX_HALF) {
     390                _mouseCurState.x = _mouseCurState.x / 2;
     391                _mouseCurState.y = _mouseCurState.y / 2;
     392        }
     393        OSystem_SDL::showOverlay();
     394}
     395
     396void OSystem_SDL_Dingux::hideOverlay() {
     397        if (_videoMode.mode == GFX_HALF) {
     398                _mouseCurState.x = _mouseCurState.x * 2;
     399                _mouseCurState.y = _mouseCurState.y * 2;
     400        }
     401        OSystem_SDL::hideOverlay();
     402}
     403
     404bool OSystem_SDL_Dingux::loadGFXMode() {
     405        fprintf(stdout, "Game ScreenMode = %d*%d\n", _videoMode.screenWidth, _videoMode.screenHeight);
     406        if (_videoMode.screenWidth > 320 || _videoMode.screenHeight > 240) {
     407                _videoMode.aspectRatioCorrection = false;
     408                setGraphicsMode(GFX_HALF);
     409                fprintf(stdout, "GraphicsMode set to HALF\n");
     410        } else {
     411                setGraphicsMode(GFX_NORMAL);
     412                fprintf(stdout, "GraphicsMode set to NORMAL\n");
     413        }
     414
     415        if ((_videoMode.mode == GFX_HALF) && !_overlayVisible) {
     416                _videoMode.overlayWidth = _videoMode.screenWidth / 2;
     417                _videoMode.overlayHeight = _videoMode.screenHeight / 2;
     418                _videoMode.fullscreen = true;
     419        } else {
     420
     421                _videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
     422                _videoMode.overlayHeight = _videoMode.screenHeight * _videoMode.scaleFactor;
     423
     424                if (_videoMode.aspectRatioCorrection)
     425                        _videoMode.overlayHeight = real2Aspect(_videoMode.overlayHeight);
     426
     427                _videoMode.hardwareWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
     428                _videoMode.hardwareHeight = effectiveScreenHeight();
     429        }
     430
     431
     432        return OSystem_SDL::loadGFXMode();
     433}
     434
     435#endif
     436