Ticket #8388: scaleableGui-v1.patch

File scaleableGui-v1.patch, 16.7 KB (added by lordhoto, 16 years ago)

initial patch

  • graphics/font.cpp

    diff -u --rec -N --exclude=CVS --exclude=.deps --exclude=*.o scummvm.old/graphics/font.cpp scummvm/graphics/font.cpp
    old new  
    2020
    2121#include "common/stdafx.h"
    2222#include "graphics/font.h"
     23#include "gui/newgui.h"
    2324
    2425namespace Graphics {
    2526
     
    3839
    3940void NewFont::drawChar(const Surface *dst, byte chr, int tx, int ty, uint32 color) const {
    4041        assert(dst != 0);
     42        const int scaleFactorWidth = g_gui.getScaleFactorWidth(), scaleFactorHeight = g_gui.getScaleFactorHeight();
     43        tx *= scaleFactorWidth; ty *= scaleFactorHeight;
     44
    4145        byte *ptr = (byte *)dst->getBasePtr(tx, ty);
    4246
    4347        assert(desc.bits != 0 && desc.maxwidth <= 16);
     
    5458        chr -= desc.firstchar;
    5559        const bitmap_t *tmp = desc.bits + (desc.offset ? desc.offset[chr] : (chr * desc.height));
    5660
    57         for (int y = 0; y < desc.height; y++, ptr += dst->pitch) {
    58                 const bitmap_t buffer = *tmp++;
     61        for (int y = 0; y < desc.height * scaleFactorHeight; y++, ptr += dst->pitch) {
     62                const bitmap_t *buffer = 0;
     63                if(scaleFactorHeight != 1) {
     64                        if(!(y % 2))
     65                                buffer = tmp++;
     66                        else
     67                                buffer = tmp;
     68                } else
     69                        buffer = tmp++;
    5970                bitmap_t mask = 0x8000;
    6071                if (ty + y < 0 || ty + y >= dst->h)
    6172                        continue;
    62                
    63                 for (int x = 0; x < w; x++, mask >>= 1) {
     73
     74                for (int x = 0; x < w * scaleFactorWidth; x++) {
     75                        if(scaleFactorWidth != 1) {
     76                                if(!(x % 2) && x != 0)
     77                                        mask >>= 1;
     78                        } else if(x != 0)
     79                                mask >>= 1;
     80
    6481                        if (tx + x < 0 || tx + x >= dst->w)
    6582                                continue;
    66                         if ((buffer & mask) != 0) {
     83                        if ((*buffer & mask) != 0) {
    6784                                if (dst->bytesPerPixel == 1)
    6885                                        ptr[x] = color;
    6986                                else if (dst->bytesPerPixel == 2)
     
    91108        uint i;
    92109        int width = getStringWidth(s);
    93110        Common::String str;
    94        
     111
    95112        if (useEllipsis && width > w) {
    96113                // String is too wide. So we shorten it "intellegently", by replacing
    97114                // parts of it by an ellipsis ("..."). There are three possibilities
     
    100117                // make this configurable, replacing the middle probably is a good
    101118                // compromise.
    102119                const int ellipsisWidth = getStringWidth("...");
    103                
     120
    104121                // SLOW algorithm to remove enough of the middle. But it is good enough
    105122                // for now.
    106123                const int halfWidth = (w - ellipsisWidth) / 2;
    107124                int w2 = 0;
    108                
     125
    109126                for (i = 0; i < s.size(); ++i) {
    110127                        int charWidth = getCharWidth(s[i]);
    111128                        if (w2 + charWidth > halfWidth)
     
    116133                // At this point we know that the first 'i' chars are together 'w2'
    117134                // pixels wide. We took the first i-1, and add "..." to them.
    118135                str += "...";
    119                
     136
    120137                // The original string is width wide. Of those we already skipped past
    121138                // w2 pixels, which means (width - w2) remain.
    122139                // The new str is (w2+ellipsisWidth) wide, so we can accomodate about
  • graphics/scummfont.cpp

    diff -u --rec -N --exclude=CVS --exclude=.deps --exclude=*.o scummvm.old/graphics/scummfont.cpp scummvm/graphics/scummfont.cpp
    old new  
    2020
    2121#include "stdafx.h"
    2222#include "graphics/font.h"
     23#include "gui/newgui.h"
    2324
    2425namespace Graphics {
    2526
     
    6465//void ScummFont::drawChar(byte chr, int xx, int yy, OverlayColor color) {
    6566void ScummFont::drawChar(const Surface *dst, byte chr, int tx, int ty, uint32 color) const {
    6667        assert(dst != 0);
     68        const int scaleFactorWidth = g_gui.getScaleFactorWidth(), scaleFactorHeight = g_gui.getScaleFactorHeight();
     69        tx *= scaleFactorWidth; ty *= scaleFactorHeight;
     70
    6771        byte *ptr = (byte *)dst->getBasePtr(tx, ty);
    6872
    6973        const byte *tmp = guifont + 6 + guifont[4] + chr * 8;
    7074        uint buffer = 0;
    7175        uint mask = 0;
    7276
    73         for (int y = 0; y < 8; y++) {
     77        for (int y = 0; y < 8 * scaleFactorHeight; y++) {
    7478                if (ty + y < 0 || ty + y >= dst->h)
    7579                        continue;
    76                 for (int x = 0; x < 8; x++) {
     80                for (int x = 0; x < 8 * scaleFactorWidth; x++) {
    7781                        if (tx + x < 0 || tx + x >= dst->w)
    7882                                continue;
    7983                        unsigned char c;
    80                         mask >>= 1;
     84                        if(scaleFactorWidth != 1 && !(x % 2))
     85                                mask >>= 1;
     86                        else if(scaleFactorWidth == 1)
     87                                mask >>= 1;
     88
    8189                        if (mask == 0) {
    82                                 buffer = *tmp++;
     90                                if(scaleFactorHeight != 1 && !(y % 2))
     91                                        buffer = *tmp++;
     92                                else if(scaleFactorHeight == 1)
     93                                        buffer = *tmp++;
     94
    8395                                mask = 0x80;
    8496                        }
    8597                        c = ((buffer & mask) != 0);
  • gui/dialog.cpp

    diff -u --rec -N --exclude=CVS --exclude=.deps --exclude=*.o scummvm.old/gui/dialog.cpp scummvm/gui/dialog.cpp
    old new  
    2929
    3030/*
    3131 * TODO list
    32  * - add some sense of the window being "active" (i.e. in front) or not. If it 
     32 * - add some sense of the window being "active" (i.e. in front) or not. If it
    3333 *   was inactive and just became active, reset certain vars (like who is focused).
    3434 *   Maybe we should just add lostFocus and receivedFocus methods to Dialog, just
    3535 *   like we have for class Widget?
     
    9898}
    9999
    100100void Dialog::drawDialog() {
    101        
     101
    102102        if (!isVisible())
    103103                return;
    104104
     
    117117}
    118118
    119119void Dialog::handleMouseDown(int x, int y, int button, int clickCount) {
     120        x /= g_gui.getScaleFactorWidth(); y /= g_gui.getScaleFactorHeight();
     121
    120122        Widget *w;
     123
    121124        w = findWidget(x, y);
    122        
     125
    123126        _dragWidget = w;
    124127
    125128        // If the click occured inside a widget which is not the currently
     
    141144}
    142145
    143146void Dialog::handleMouseUp(int x, int y, int button, int clickCount) {
     147        x /= g_gui.getScaleFactorWidth(); y /= g_gui.getScaleFactorHeight();
     148
    144149        Widget *w;
    145150
    146151        if (_focusedWidget) {
    147152                //w = _focusedWidget;
    148                
     153
    149154                // Lose focus on mouseup unless the widget requested to retain the focus
    150155                if (! (_focusedWidget->getFlags() & WIDGET_RETAIN_FOCUS )) {
    151156                        releaseFocus();
     
    161166}
    162167
    163168void Dialog::handleMouseWheel(int x, int y, int direction) {
     169        x /= g_gui.getScaleFactorWidth(); y /= g_gui.getScaleFactorHeight();
     170
    164171        Widget *w;
    165172
    166173        // This may look a bit backwards, but I think it makes more sense for
     
    212219}
    213220
    214221void Dialog::handleMouseMoved(int x, int y, int button) {
     222        x /= g_gui.getScaleFactorWidth(); y /= g_gui.getScaleFactorHeight();
     223
    215224        Widget *w;
    216        
     225
    217226        //if (!button)
    218227        //      _dragWidget = 0;
    219        
     228
    220229        if (_focusedWidget && !_dragWidget) {
    221230                w = _focusedWidget;
    222231                int wx = w->getAbsX() - _x;
    223232                int wy = w->getAbsY() - _y;
    224                
     233
    225234                // We still send mouseEntered/Left messages to the focused item
    226235                // (but to no other items).
    227236                bool mouseInFocusedWidget = (x >= wx && x < wx + w->_w && y >= wy && y < wy + w->_h);
     
    237246
    238247                w->handleMouseMoved(x - wx, y - wy, button);
    239248        }
    240        
     249
    241250        // While a "drag" is in process (i.e. mouse is moved while a button is pressed),
    242251        // only deal with the widget in which the click originated.
    243252        if (_dragWidget)
     
    251260                if (w)
    252261                        w->handleMouseEntered(button);
    253262                _mouseWidget = w;
    254         } 
     263        }
    255264
    256265        if (w && (w->getFlags() & WIDGET_TRACK_MOUSE)) {
    257266                w->handleMouseMoved(x - (w->getAbsX() - _x), y - (w->getAbsY() - _y), button);
  • gui/newgui.cpp

    diff -u --rec -N --exclude=CVS --exclude=.deps --exclude=*.o scummvm.old/gui/newgui.cpp scummvm/gui/newgui.cpp
    old new  
    4141 * - allow multi line (l/c/r aligned) text via StaticTextWidget ?
    4242 * - add "close" widget to all dialogs (with a flag to turn it off) ?
    4343 * - make dialogs "moveable" ?
    44  * - come up with a new look & feel / theme for the GUI 
     44 * - come up with a new look & feel / theme for the GUI
    4545 * - ...
    4646 */
    4747
     
    5656// Constructor
    5757NewGui::NewGui() : _needRedraw(false),
    5858        _stateIsSaved(false), _cursorAnimateCounter(0), _cursorAnimateTimer(0) {
    59        
     59
    6060        _system = OSystem::instance();
    6161
    6262        // Clear the cursor
     
    6464
    6565        // Reset key repeat
    6666        _currentKeyDown.keycode = 0;
     67
     68        // updates the scaling factor
     69        updateScaleFactor();
    6770}
    6871
    6972void NewGui::updateColors() {
     
    7578        _textcolorhi = _system->RGBToColor(0, 255, 0);
    7679}
    7780
     81void NewGui::updateScaleFactor() {
     82        const int16 stdGuiWidth = 320;
     83        const int16 stdGuiHeight = 200;
     84
     85        _scaleFactorWidth = _system->getWidth() / stdGuiWidth;
     86        _scaleFactorHeight = _system->getHeight() / stdGuiHeight;
     87}
     88
    7889void NewGui::runLoop() {
    7990        Dialog *activeDialog = _dialogStack.top();
    8091        bool didSaveState = false;
    8192
    8293        if (activeDialog == 0)
    8394                return;
    84        
     95
    8596        // Setup some default GUI colors. Normally this will be done whenever an
    8697        // EVENT_SCREEN_CHANGED is received. However, not yet all backends support
    8798        // that event, so we also do it "manually" whenever a run loop is entered.
    8899        updateColors();
     100        updateScaleFactor();
    89101
    90102        if (!_stateIsSaved) {
    91103                saveState();
     
    106118                }
    107119
    108120                animateCursor();
    109                 _system->updateScreen();               
     121                _system->updateScreen();
    110122
    111123                OSystem::Event event;
    112124                uint32 time = _system->getMillis();
     
    131143                                        _currentKeyDown.keycode = 0;
    132144                                break;
    133145                        case OSystem::EVENT_MOUSEMOVE:
    134                                 activeDialog->handleMouseMoved(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, 0);
     146                                activeDialog->handleMouseMoved(event.mouse.x - (activeDialog->_x * _scaleFactorWidth), event.mouse.y - (activeDialog->_y * _scaleFactorHeight), 0);
    135147                                break;
    136148                        // We don't distinguish between mousebuttons (for now at least)
    137149                        case OSystem::EVENT_LBUTTONDOWN:
     
    146158                                        _lastClick.count = 1;
    147159                                }
    148160                                _lastClick.time = time;
    149                                 activeDialog->handleMouseDown(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, 1, _lastClick.count);
     161                                activeDialog->handleMouseDown(event.mouse.x - (activeDialog->_x * _scaleFactorWidth), event.mouse.y - (activeDialog->_y * _scaleFactorHeight), 1, _lastClick.count);
    150162                                break;
    151163                        case OSystem::EVENT_LBUTTONUP:
    152164                        case OSystem::EVENT_RBUTTONUP:
    153                                 activeDialog->handleMouseUp(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, 1, _lastClick.count);
     165                                activeDialog->handleMouseUp(event.mouse.x - (activeDialog->_x * _scaleFactorWidth), event.mouse.y - (activeDialog->_y * _scaleFactorHeight), 1, _lastClick.count);
    154166                                break;
    155167                        case OSystem::EVENT_WHEELUP:
    156                                 activeDialog->handleMouseWheel(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, -1);
     168                                activeDialog->handleMouseWheel(event.mouse.x - (activeDialog->_x * _scaleFactorWidth), event.mouse.y - (activeDialog->_y * _scaleFactorHeight), -1);
    157169                                break;
    158170                        case OSystem::EVENT_WHEELDOWN:
    159                                 activeDialog->handleMouseWheel(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, 1);
     171                                activeDialog->handleMouseWheel(event.mouse.x - (activeDialog->_x * _scaleFactorWidth), event.mouse.y - (activeDialog->_y * _scaleFactorHeight), 1);
    160172                                break;
    161173                        case OSystem::EVENT_QUIT:
    162174                                _system->quit();
    163175                                return;
    164176                        case OSystem::EVENT_SCREEN_CHANGED:
    165177                                updateColors();
     178                                updateScaleFactor();
    166179                                activeDialog->handleScreenChanged();
    167180                                break;
    168181                        }
     
    180193                // Delay for a moment
    181194                _system->delayMillis(10);
    182195        }
    183        
     196
    184197        if (didSaveState)
    185198                restoreState();
    186199}
     
    224237        }
    225238
    226239        _system->updateScreen();
    227        
     240
    228241        _stateIsSaved = false;
    229242}
    230243
     
    270283}
    271284
    272285void NewGui::hLine(int x, int y, int x2, OverlayColor color) {
    273         _screen.hLine(x, y, x2, color);
     286        _screen.hLine(x * _scaleFactorWidth, y * _scaleFactorHeight, x2 * _scaleFactorWidth, color);
    274287}
    275288
    276289void NewGui::vLine(int x, int y, int y2, OverlayColor color) {
    277         _screen.vLine(x, y, y2, color);
     290        _screen.vLine(x * _scaleFactorWidth, y * _scaleFactorHeight, y2 * _scaleFactorHeight, color);
    278291}
    279292
    280293void NewGui::blendRect(int x, int y, int w, int h, OverlayColor color, int level) {
    281294#ifdef NEWGUI_256
    282295        fillRect(x, y, w, h, color);
    283296#else
    284         Common::Rect rect(x, y, x + w, y + h);
     297        Common::Rect rect(x * _scaleFactorWidth, y * _scaleFactorHeight, (x + w) * _scaleFactorWidth, (y + h) * _scaleFactorHeight);
    285298        rect.clip(_screen.w, _screen.h);
    286        
     299
    287300        if (!rect.isValidRect())
    288301                return;
    289302
     
    311324}
    312325
    313326void NewGui::fillRect(int x, int y, int w, int h, OverlayColor color) {
    314         _screen.fillRect(Common::Rect(x, y, x+w, y+h), color);
     327        _screen.fillRect(Common::Rect(x * _scaleFactorWidth, y * _scaleFactorHeight, (x+w) * _scaleFactorWidth, (y+h) * _scaleFactorHeight), color);
    315328}
    316329
    317330void NewGui::frameRect(int x, int y, int w, int h, OverlayColor color) {
    318         _screen.frameRect(Common::Rect(x, y, x+w, y+h), color);
     331        _screen.frameRect(Common::Rect(x * _scaleFactorWidth, y * _scaleFactorHeight, (x+w) * _scaleFactorWidth, (y+h) * _scaleFactorHeight), color);
    319332}
    320333
    321334void NewGui::addDirtyRect(int x, int y, int w, int h) {
    322         Common::Rect rect(x, y, x + w, y + h);
     335        Common::Rect rect(x * _scaleFactorWidth, y * _scaleFactorHeight, (x + w) * _scaleFactorWidth, (y + h) * _scaleFactorHeight);
    323336        rect.clip(_screen.w, _screen.h);
    324        
     337
    325338        if (!rect.isValidRect())
    326339                return;
    327340
     
    339352}
    340353
    341354int NewGui::getStringWidth(const String &str) {
    342         return getFont().getStringWidth(str);
     355        return getFont().getStringWidth(str) * _scaleFactorWidth;
    343356}
    344357
    345358int NewGui::getCharWidth(byte c) {
    346         return getFont().getCharWidth(c);
     359        return getFont().getCharWidth(c) * _scaleFactorWidth;
    347360}
    348361
    349362void NewGui::drawString(const String &s, int x, int y, int w, OverlayColor color, TextAlignment align, int deltax, bool useEllipsis) {
     
    354367// Draw an 8x8 bitmap at location (x,y)
    355368//
    356369void NewGui::drawBitmap(uint32 *bitmap, int tx, int ty, OverlayColor color, int h) {
     370        tx *= _scaleFactorWidth; ty *= _scaleFactorHeight;
     371        h *= _scaleFactorHeight;
    357372        OverlayColor *ptr = getBasePtr(tx, ty);
    358373
    359374        for (int y = 0; y < h; y++, ptr += _screenPitch) {
    360375                uint32 mask = 0xF0000000;
    361376                if (ty + y < 0 || ty + y >= _screen.h)
    362377                        continue;
    363                 for (int x = 0; x < 8; x++, mask >>= 4) {
     378                for (int x = 0; x < 8 * _scaleFactorWidth; x++) {
     379                        if(!(x % 2) && _scaleFactorWidth != 1 && x != 0)
     380                                mask >>= 4;
     381                        else if(_scaleFactorWidth == 1 && x != 0)
     382                                mask >>= 4;
     383
    364384                        if (tx + x < 0 || tx + x >= _screen.w)
    365385                                continue;
    366                         if (bitmap[y] & mask)
    367                                 ptr[x] = color;
     386                        if (bitmap[y / _scaleFactorHeight] & mask)
     387                                        ptr[x] = color;
    368388                }
    369389        }
    370390}
     
    374394// We could plug in a different cursor here if we like to.
    375395//
    376396void NewGui::animateCursor() {
    377         int time = _system->getMillis(); 
     397        int time = _system->getMillis();
    378398        if (time > _cursorAnimateTimer + kCursorAnimateDelay) {
    379399                const byte colors[4] = { 15, 15, 7, 8 };
    380400                const byte color = colors[_cursorAnimateCounter];
    381401                int i;
    382                
     402
    383403                for (i = 0; i < 15; i++) {
    384404                        if ((i < 6) || (i > 8)) {
    385405                                _cursor[16 * 7 + i] = color;
    386406                                _cursor[16 * i + 7] = color;
    387407                        }
    388408                }
    389        
     409
    390410                _system->setMouseCursor(_cursor, 16, 16, 7, 7);
    391411
    392412                _cursorAnimateTimer = time;
  • gui/newgui.h

    diff -u --rec -N --exclude=CVS --exclude=.deps --exclude=*.o scummvm.old/gui/newgui.h scummvm/gui/newgui.h
    old new  
    5252
    5353/**
    5454 * GUI manager singleton.
    55  */ 
     55 */
    5656class NewGui : public Common::Singleton<NewGui> {
    5757        typedef Common::String String;
    5858        friend class Dialog;
     
    6666
    6767        bool isActive() { return ! _dialogStack.empty(); }
    6868
     69        int getScaleFactorWidth() { return _scaleFactorWidth; }
     70        int getScaleFactorHeight() { return _scaleFactorHeight; }
     71
    6972protected:
    70         OSystem         *_system;
    71         Graphics::Surface               _screen;
     73        OSystem                 *_system;
     74        Graphics::Surface       _screen;
    7275        int                     _screenPitch;
    73        
     76
     77        int                     _scaleFactorWidth;
     78        int                     _scaleFactorHeight;
     79
    7480        bool            _needRedraw;
    7581        DialogStack     _dialogStack;
    76        
     82
    7783        bool            _stateIsSaved;
    78        
     84
    7985        // for continuous events (keyDown)
    8086        struct {
    8187                uint16 ascii;
     
    8389                int keycode;
    8490        } _currentKeyDown;
    8591        uint32          _keyRepeatTime;
    86        
     92
    8793        // position and time of last mouse click (used to detect double clicks)
    8894        struct {
    8995                int16 x, y;     // Position of mouse when the click occured
    9096                uint32 time;    // Time
    9197                int count;      // How often was it already pressed?
    9298        } _lastClick;
    93        
     99
    94100        // mouse cursor state
    95101        bool            _oldCursorMode;
    96         int                     _cursorAnimateCounter;
    97         int                     _cursorAnimateTimer;
     102        int             _cursorAnimateCounter;
     103        int             _cursorAnimateTimer;
    98104        byte            _cursor[2048];
    99105
    100106        void saveState();
    101107        void restoreState();
    102        
     108
    103109        void openDialog(Dialog *dialog);
    104110        void closeTopDialog();
    105        
     111
    106112        void loop();
    107113
    108114        void animateCursor();
    109115        void updateColors();
     116        void updateScaleFactor();
    110117
    111118        OverlayColor *getBasePtr(int x, int y);
    112119
     
    116123        OverlayColor _bgcolor;
    117124        OverlayColor _textcolor;
    118125        OverlayColor _textcolorhi;
    119        
     126
    120127        // Font
    121128        const Graphics::Font &getFont() const;
    122129