aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Horn2002-07-10 16:49:45 +0000
committerMax Horn2002-07-10 16:49:45 +0000
commitd32e3ad11f8f5e73b9a72cdaa003d8b66211172c (patch)
tree1e1c2c8dda75fe6a08e23acc620bf08c5dc2cdc3
parent5cc6e3f6a037453193aac1ee6a18771f962ad653 (diff)
downloadscummvm-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.cpp44
-rw-r--r--gui/dialog.h7
-rw-r--r--gui/widget.cpp10
-rw-r--r--newgui.cpp83
-rw-r--r--newgui.h12
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;
+ }
+}
+
diff --git a/newgui.h b/newgui.h
index da405c9639..a7707abb00 100644
--- a/newgui.h
+++ b/newgui.h
@@ -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);