diff options
author | Max Horn | 2002-07-10 16:49:45 +0000 |
---|---|---|
committer | Max Horn | 2002-07-10 16:49:45 +0000 |
commit | d32e3ad11f8f5e73b9a72cdaa003d8b66211172c (patch) | |
tree | 1e1c2c8dda75fe6a08e23acc620bf08c5dc2cdc3 | |
parent | 5cc6e3f6a037453193aac1ee6a18771f962ad653 (diff) | |
download | scummvm-rg350-d32e3ad11f8f5e73b9a72cdaa003d8b66211172c.tar.gz scummvm-rg350-d32e3ad11f8f5e73b9a72cdaa003d8b66211172c.tar.bz2 scummvm-rg350-d32e3ad11f8f5e73b9a72cdaa003d8b66211172c.zip |
improved the alpha blending code, now works properly for nesting/redraw (changed meaning of WIDGET_CLEARBG a little bit for this)
svn-id: r4509
-rw-r--r-- | gui/dialog.cpp | 44 | ||||
-rw-r--r-- | gui/dialog.h | 7 | ||||
-rw-r--r-- | gui/widget.cpp | 10 | ||||
-rw-r--r-- | newgui.cpp | 83 | ||||
-rw-r--r-- | newgui.h | 12 |
5 files changed, 137 insertions, 19 deletions
diff --git a/gui/dialog.cpp b/gui/dialog.cpp index 9031e0e210..9942bcfa39 100644 --- a/gui/dialog.cpp +++ b/gui/dialog.cpp @@ -25,12 +25,52 @@ #include "widget.h" #include "newgui.h" +Dialog::~Dialog() +{ + teardownScreenBuf(); +} + +void Dialog::setupScreenBuf() +{ + // Create _screenBuf if it doesn't already exist + if (!_screenBuf) + _screenBuf = new byte[320*200]; + + // Draw the fixed parts of the dialog: background and border. + _gui->blendArea(_x, _y, _w, _h, _gui->_bgcolor); + _gui->box(_x, _y, _w, _h); + + // Draw a bgcolor rectangle for all widgets which have WIDGET_CLEARBG set. + Widget *w = _firstWidget; + while (w) { + if (w->_flags & WIDGET_CLEARBG) + _gui->fillArea(_x + w->_x, _y + w->_y, w->_w, w->_h, _gui->_bgcolor); + // FIXME - should we also draw borders here if WIDGET_BORDER is set? + w = w->_next; + } + + // Finally blit this to _screenBuf + _gui->blitTo(_screenBuf, _x, _y, _w, _h); +} + +void Dialog::teardownScreenBuf() +{ + if (_screenBuf) { + delete [] _screenBuf; + _screenBuf = 0; + } +} + void Dialog::draw() { Widget *w = _firstWidget; - _gui->fillArea(_x, _y, _w, _h, _gui->_bgcolor); - _gui->box(_x, _y, _w, _h); + if (_screenBuf) { + _gui->blitFrom(_screenBuf, _x, _y, _w, _h); + } else { + _gui->fillArea(_x, _y, _w, _h, _gui->_bgcolor); + _gui->box(_x, _y, _w, _h); + } _gui->setAreaDirty(_x, _y, _w, _h); while (w) { diff --git a/gui/dialog.h b/gui/dialog.h index f91bc681a6..77eaf57738 100644 --- a/gui/dialog.h +++ b/gui/dialog.h @@ -43,11 +43,13 @@ protected: int16 _x, _y; uint16 _w, _h; Widget *_mouseWidget; + byte *_screenBuf; public: Dialog(NewGui *gui, int x, int y, int w, int h) - : _gui(gui), _firstWidget(0), _x(x), _y(y), _w(w), _h(h), _mouseWidget(0) + : _gui(gui), _firstWidget(0), _x(x), _y(y), _w(w), _h(h), _mouseWidget(0), _screenBuf(0) {} + virtual ~Dialog(); virtual void draw(); @@ -58,6 +60,9 @@ public: virtual void handleCommand(uint32 cmd); NewGui *getGui() { return _gui; } + + void setupScreenBuf(); + void teardownScreenBuf(); protected: Widget* findWidget(int x, int y); // Find the widget at pos x,y if any diff --git a/gui/widget.cpp b/gui/widget.cpp index 510eb8428b..bf45fb522f 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -43,8 +43,8 @@ void Widget::draw() _x += _boss->_x; _y += _boss->_y; - // Clear background - if (_flags & WIDGET_CLEARBG) + // Clear background (unless alpha blending is enabled) + if (_flags & WIDGET_CLEARBG && !_boss->_screenBuf) gui->fillArea(_x, _y, _w, _h, gui->_bgcolor); // Draw border @@ -94,7 +94,7 @@ void StaticTextWidget::drawWidget(bool hilite) ButtonWidget::ButtonWidget(Dialog *boss, int x, int y, int w, int h, const char *label, uint32 cmd, uint8 hotkey) : StaticTextWidget(boss, x, y, w, h, label), _cmd(cmd), _hotkey(hotkey) { - _flags = WIDGET_ENABLED | WIDGET_BORDER /* | WIDGET_CLEARBG */ ; + _flags = WIDGET_ENABLED | WIDGET_BORDER | WIDGET_CLEARBG ; _type = kButtonWidget; } @@ -148,7 +148,7 @@ void CheckboxWidget::drawWidget(bool hilite) if (_state) gui->drawBitmap(checked_img, _x + 3, _y + 3, gui->_textcolor); else - gui->fillArea(_x + 3, _y + 3, 8, 8, gui->_bgcolor); + gui->fillArea(_x + 2, _y + 2, 10, 10, gui->_bgcolor); // Finally draw the label gui->drawString(_text, _x + 20, _y + 3, _w, gui->_textcolor); @@ -159,7 +159,7 @@ void CheckboxWidget::drawWidget(bool hilite) SliderWidget::SliderWidget(Dialog *boss, int x, int y, int w, int h, const char *label, uint32 cmd, uint8 hotkey) : ButtonWidget(boss, x, y, w, h, label, cmd, hotkey), _value(0), _old_value(1) { - _flags = WIDGET_ENABLED | WIDGET_TRACK_MOUSE; + _flags = WIDGET_ENABLED | WIDGET_TRACK_MOUSE | WIDGET_CLEARBG; _type = kSliderWidget; } diff --git a/newgui.cpp b/newgui.cpp index 6f5d6153ea..b16f3fbc83 100644 --- a/newgui.cpp +++ b/newgui.cpp @@ -95,8 +95,9 @@ void ClearBlendCache(byte *palette, int weight) { * - ... */ -NewGui::NewGui(Scumm *s) : _s(s), _need_redraw(false), _pauseDialog(0), - _saveLoadDialog(0), _aboutDialog(0), _optionsDialog(0) +NewGui::NewGui(Scumm *s) : _s(s), _use_alpha_blending(true), + _need_redraw(false),_prepare_for_gui(true), + _pauseDialog(0), _saveLoadDialog(0), _aboutDialog(0), _optionsDialog(0) { } @@ -109,7 +110,6 @@ void NewGui::pauseDialog() void NewGui::saveloadDialog() { - ClearBlendCache(_s->_currentPalette, 128); if (!_saveLoadDialog) _saveLoadDialog = new SaveLoadDialog(this); openDialog(_saveLoadDialog); @@ -133,11 +133,19 @@ void NewGui::loop() { Dialog *activeDialog = _dialogStack.top(); + if (_prepare_for_gui) { + ClearBlendCache(_s->_currentPalette, 128); + saveState(); + if (_use_alpha_blending) + activeDialog->setupScreenBuf(); + _prepare_for_gui = false; + } + if (_need_redraw) { activeDialog->draw(); - saveState(); _need_redraw = false; } + _s->animateCursor(); _s->getKeyInput(0); if (_s->_mouseButStat & MBS_LEFT_CLICK) { @@ -194,17 +202,31 @@ void NewGui::restoreState() void NewGui::openDialog(Dialog *dialog) { + if (_dialogStack.empty()) + _prepare_for_gui = true; + else if (_use_alpha_blending) + dialog->setupScreenBuf(); + _dialogStack.push(dialog); _need_redraw = true; } void NewGui::closeTopDialog() { + // Don't do anything if no dialog is open + if (_dialogStack.empty()) + return; + + // Tear down its screenBuf + if (_use_alpha_blending) + _dialogStack.top()->teardownScreenBuf(); + + // Remove the dialog from the stack _dialogStack.pop(); if (_dialogStack.empty()) restoreState(); else - _dialogStack.top()->draw(); + _need_redraw = true; } #pragma mark - @@ -298,6 +320,20 @@ void NewGui::line(int x, int y, int x2, int y2, byte color) } } +void NewGui::blendArea(int x, int y, int w, int h, byte color) +{ + byte *ptr = getBasePtr(x, y); + if (ptr == NULL) + return; + + while (h--) { + for (int i = 0; i < w; i++) { + ptr[i] = Blend(ptr[i], color, _s->_currentPalette); + } + ptr += 320; + } +} + void NewGui::fillArea(int x, int y, int w, int h, byte color) { byte *ptr = getBasePtr(x, y); @@ -306,10 +342,8 @@ void NewGui::fillArea(int x, int y, int w, int h, byte color) while (h--) { for (int i = 0; i < w; i++) { - int srcc = ptr[i]; - ptr[i] = Blend(srcc, color, _s->_currentPalette); + ptr[i] = color; } - //ptr[i] = color; ptr += 320; } } @@ -392,3 +426,36 @@ void NewGui::drawBitmap(uint32 bitmap[8], int x, int y, byte color) ptr += 320; } } + +void NewGui::blitTo(byte buffer[320*200], int x, int y, int w, int h) +{ + byte *dstPtr = buffer + x + y*320; + byte *srcPtr = getBasePtr(x, y); + if (srcPtr == NULL) + return; + + while (h--) { + for (int i = 0; i < w; i++) { + *dstPtr++ = *srcPtr++; + } + dstPtr += 320 - w; + srcPtr += 320 - w; + } +} + +void NewGui::blitFrom(byte buffer[320*200], int x, int y, int w, int h) +{ + byte *srcPtr = buffer + x + y*320; + byte *dstPtr = getBasePtr(x, y); + if (dstPtr == NULL) + return; + + while (h--) { + for (int i = 0; i < w; i++) { + *dstPtr++ = *srcPtr++; + } + dstPtr += 320 - w; + srcPtr += 320 - w; + } +} + @@ -63,7 +63,9 @@ public: protected: Scumm *_s; + bool _use_alpha_blending; bool _need_redraw; + bool _prepare_for_gui; DialogStack _dialogStack; Dialog *_pauseDialog; @@ -94,12 +96,16 @@ public: // Drawing byte *getBasePtr(int x, int y); void box(int x, int y, int width, int height); - void line(int x, int y, int x2, int y2, byte color); - void fillArea(int x, int y, int w, int h, byte color); - void setAreaDirty(int x, int y, int w, int h); + void line(int x, int y, int x2, int y2, byte color); + void blendArea(int x, int y, int w, int h, byte color); + void fillArea(int x, int y, int w, int h, byte color); + void setAreaDirty(int x, int y, int w, int h); void drawChar(const char c, int x, int y); void drawString(const char *str, int x, int y, int w, byte color); + void drawBitmap(uint32 bitmap[8], int x, int y, byte color); + void blitTo(byte buffer[320*200], int x, int y, int w, int h); + void blitFrom(byte buffer[320*200], int x, int y, int w, int h); // Query a string from the resources const char *queryResString(int stringno); |