improved the alpha blending code, now works properly for nesting/redraw (changed meaning of WIDGET_CLEARBG a little bit for this)
svn-id: r4509
This commit is contained in:
parent
5cc6e3f6a0
commit
d32e3ad11f
5 changed files with 137 additions and 19 deletions
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
@ -59,6 +61,9 @@ public:
|
|||
|
||||
NewGui *getGui() { return _gui; }
|
||||
|
||||
void setupScreenBuf();
|
||||
void teardownScreenBuf();
|
||||
|
||||
protected:
|
||||
Widget* findWidget(int x, int y); // Find the widget at pos x,y if any
|
||||
void close();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
83
newgui.cpp
83
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
12
newgui.h
12
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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue