From 77a60673ef970ec32fc2e4db09aa5ac534481c8d Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Wed, 2 Jul 2008 01:41:08 +0000 Subject: - Changed labels to be GfxObj's, thus removing the Label object altogether. - Changed Item's to be almost GfxObj's, since ownership and destruction of underlying resource is an issue here (got to think some more about it). svn-id: r32873 --- engines/parallaction/exec_br.cpp | 4 +- engines/parallaction/gfxbase.cpp | 38 ++++-- engines/parallaction/graphics.cpp | 199 +++++++++++++++---------------- engines/parallaction/graphics.h | 41 +++---- engines/parallaction/input.h | 2 +- engines/parallaction/objects.cpp | 1 - engines/parallaction/objects.h | 2 +- engines/parallaction/parallaction.cpp | 6 +- engines/parallaction/parallaction_ns.cpp | 4 +- 9 files changed, 146 insertions(+), 151 deletions(-) (limited to 'engines') diff --git a/engines/parallaction/exec_br.cpp b/engines/parallaction/exec_br.cpp index 3b67b4c370..348af2b731 100644 --- a/engines/parallaction/exec_br.cpp +++ b/engines/parallaction/exec_br.cpp @@ -100,8 +100,8 @@ void Parallaction_br::setupSubtitles(char *s, char *s2, int y) { } void Parallaction_br::clearSubtitles() { - _gfx->freeLabels(); - _subtitle[0] = _subtitle[1] = -1; + _gfx->hideLabel(_subtitle[0]); + _gfx->hideLabel(_subtitle[1]); } diff --git a/engines/parallaction/gfxbase.cpp b/engines/parallaction/gfxbase.cpp index cdf4c9cdf6..383f5d549c 100644 --- a/engines/parallaction/gfxbase.cpp +++ b/engines/parallaction/gfxbase.cpp @@ -92,6 +92,7 @@ GfxObj* Gfx::loadAnim(const char *name) { // animation Z is not set here, but controlled by game scripts and user interaction. // it is always >=0 and type = kGfxObjTypeAnim; + obj->transparentKey = 0; _gfxobjList.push_back(obj); return obj; } @@ -103,6 +104,7 @@ GfxObj* Gfx::loadGet(const char *name) { obj->z = kGfxObjGetZ; // this preset Z value ensures that get zones are drawn after doors but before animations obj->type = kGfxObjTypeGet; + obj->transparentKey = 0; _gfxobjList.push_back(obj); return obj; } @@ -113,6 +115,7 @@ GfxObj* Gfx::loadDoor(const char *name) { obj->z = kGfxObjDoorZ; // this preset Z value ensures that doors are drawn first obj->type = kGfxObjTypeDoor; + obj->transparentKey = 0; _gfxobjList.push_back(obj); return obj; } @@ -150,11 +153,32 @@ void Gfx::sortAnimations() { Common::sort(first, last, compareZ); } -void Gfx::drawGfxObjects(Graphics::Surface &surf) { + +void Gfx::drawGfxObject(GfxObj *obj, Graphics::Surface &surf, bool scene) { + if (!obj->isVisible()) { + return; + } Common::Rect rect; byte *data; + uint scrollX = (scene) ? -_varScrollX : 0; + + obj->getRect(obj->frame, rect); + rect.translate(obj->x + scrollX, obj->y); + data = obj->getData(obj->frame); + + if (obj->getSize(obj->frame) == obj->getRawSize(obj->frame)) { + blt(rect, data, &surf, obj->layer, obj->transparentKey); + } else { + unpackBlt(rect, data, obj->getRawSize(obj->frame), &surf, obj->layer, obj->transparentKey); + } + +} + + +void Gfx::drawGfxObjects(Graphics::Surface &surf) { + sortAnimations(); // TODO: some zones don't appear because of wrong masking (3 or 0?) // TODO: Dr.Ki is not visible inside the club @@ -164,17 +188,7 @@ void Gfx::drawGfxObjects(Graphics::Surface &surf) { GfxObjList::iterator e = _gfxobjList.end(); for (; b != e; b++) { - GfxObj *obj = *b; - if (obj->isVisible()) { - obj->getRect(obj->frame, rect); - rect.translate(obj->x - _varScrollX, obj->y); - data = obj->getData(obj->frame); - if (obj->getSize(obj->frame) == obj->getRawSize(obj->frame)) { - blt(rect, data, &surf, obj->layer, 0); - } else { - unpackBlt(rect, data, obj->getRawSize(obj->frame), &surf, obj->layer, 0); - } - } + drawGfxObject(*b, surf, true); } } diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp index 5d8d81253b..838827b19f 100644 --- a/engines/parallaction/graphics.cpp +++ b/engines/parallaction/graphics.cpp @@ -356,17 +356,7 @@ void Gfx::drawItems() { Graphics::Surface *surf = g_system->lockScreen(); for (uint i = 0; i < _numItems; i++) { - GfxObj *obj = _items[i].data; - - Common::Rect rect; - obj->getRect(obj->frame, rect); - rect.translate(obj->x, obj->y); - - if (obj->getSize(obj->frame) == obj->getRawSize(obj->frame)) { - blt(rect, obj->getData(obj->frame), surf, LAYER_FOREGROUND, _items[i].transparentColor); - } else { - unpackBlt(rect, obj->getData(obj->frame), obj->getRawSize(obj->frame), surf, LAYER_FOREGROUND, _items[i].transparentColor); - } + drawGfxObject(_items[i].data, *surf, false); } g_system->unlockScreen(); } @@ -540,10 +530,9 @@ void setupLabelSurface(Graphics::Surface &surf, uint w, uint h) { surf.fillRect(Common::Rect(w,h), LABEL_TRANSPARENT_COLOR); } -Label *Gfx::renderFloatingLabel(Font *font, char *text) { +uint Gfx::renderFloatingLabel(Font *font, char *text) { - Label *label = new Label; - Graphics::Surface *cnv = &label->_cnv; + Graphics::Surface *cnv = new Graphics::Surface; uint w, h; @@ -569,14 +558,74 @@ Label *Gfx::renderFloatingLabel(Font *font, char *text) { drawText(font, cnv, 0, 0, text, 0); } - return label; + GfxObj *obj = new GfxObj(kGfxObjTypeLabel, new SurfaceToFrames(cnv), "floatingLabel"); + obj->transparentKey = LABEL_TRANSPARENT_COLOR; + obj->layer = LAYER_FOREGROUND; + + uint id = _labels.size(); + _labels.insert_at(id, obj); + + return id; +} + +void Gfx::showFloatingLabel(uint label) { + assert(label < _labels.size()); + + hideFloatingLabel(); + + _labels[label]->x = -1000; + _labels[label]->y = -1000; + _labels[label]->setFlags(kGfxObjVisible); + + _floatingLabel = label; +} + +void Gfx::hideFloatingLabel() { + if (_floatingLabel != NO_FLOATING_LABEL) { + _labels[_floatingLabel]->clearFlags(kGfxObjVisible); + } + _floatingLabel = NO_FLOATING_LABEL; +} + + +void Gfx::updateFloatingLabel() { + if (_floatingLabel == NO_FLOATING_LABEL) { + return; + } + + int16 _si, _di; + + Common::Point cursor; + _vm->_input->getCursorPos(cursor); + + Common::Rect r; + _labels[_floatingLabel]->getRect(0, r); + + if (_vm->_input->_activeItem._id != 0) { + _si = cursor.x + 16 - r.width()/2; + _di = cursor.y + 34; + } else { + _si = cursor.x + 8 - r.width()/2; + _di = cursor.y + 21; + } + + if (_si < 0) _si = 0; + if (_di > 190) _di = 190; + + if (r.width() + _si > _vm->_screenWidth) + _si = _vm->_screenWidth - r.width(); + + _labels[_floatingLabel]->x = _si; + _labels[_floatingLabel]->y = _di; } + + + uint Gfx::createLabel(Font *font, const char *text, byte color) { - assert(_numLabels < MAX_NUM_LABELS); + assert(_labels.size() < MAX_NUM_LABELS); - Label *label = new Label; - Graphics::Surface *cnv = &label->_cnv; + Graphics::Surface *cnv = new Graphics::Surface; uint w, h; @@ -597,122 +646,64 @@ uint Gfx::createLabel(Font *font, const char *text, byte color) { drawText(font, cnv, 0, 0, text, color); } - uint id = _numLabels; - _labels[id] = label; - _numLabels++; + GfxObj *obj = new GfxObj(kGfxObjTypeLabel, new SurfaceToFrames(cnv), "label"); + obj->transparentKey = LABEL_TRANSPARENT_COLOR; + obj->layer = LAYER_FOREGROUND; + + int id = _labels.size(); + + _labels.insert_at(id, obj); return id; } void Gfx::showLabel(uint id, int16 x, int16 y) { - assert(id < _numLabels); - _labels[id]->_visible = true; + assert(id < _labels.size()); + _labels[id]->setFlags(kGfxObjVisible); + + Common::Rect r; + _labels[id]->getRect(0, r); if (x == CENTER_LABEL_HORIZONTAL) { - x = CLIP((_vm->_screenWidth - _labels[id]->_cnv.w) / 2, 0, _vm->_screenWidth/2); + x = CLIP((_vm->_screenWidth - r.width()) / 2, 0, _vm->_screenWidth/2); } if (y == CENTER_LABEL_VERTICAL) { - y = CLIP((_vm->_screenHeight - _labels[id]->_cnv.h) / 2, 0, _vm->_screenHeight/2); + y = CLIP((_vm->_screenHeight - r.height()) / 2, 0, _vm->_screenHeight/2); } - _labels[id]->_pos.x = x; - _labels[id]->_pos.y = y; + _labels[id]->x = x; + _labels[id]->y = y; } void Gfx::hideLabel(uint id) { - assert(id < _numLabels); - _labels[id]->_visible = false; + assert(id < _labels.size()); + _labels[id]->clearFlags(kGfxObjVisible); } void Gfx::freeLabels() { - for (uint i = 0; i < _numLabels; i++) { + for (uint i = 0; i < _labels.size(); i++) { delete _labels[i]; } - _numLabels = 0; -} - - -void Gfx::setFloatingLabel(Label *label) { - _floatingLabel = label; - - if (_floatingLabel) { - _floatingLabel->resetPosition(); - } -} - -void Gfx::updateFloatingLabel() { - if (!_floatingLabel) { - return; - } - - int16 _si, _di; - - Common::Point cursor; - _vm->_input->getCursorPos(cursor); - - if (_vm->_input->_activeItem._id != 0) { - _si = cursor.x + 16 - _floatingLabel->_cnv.w/2; - _di = cursor.y + 34; - } else { - _si = cursor.x + 8 - _floatingLabel->_cnv.w/2; - _di = cursor.y + 21; - } - - if (_si < 0) _si = 0; - if (_di > 190) _di = 190; - - if (_floatingLabel->_cnv.w + _si > _vm->_screenWidth) - _si = _vm->_screenWidth - _floatingLabel->_cnv.w; - - _floatingLabel->_pos.x = _si; - _floatingLabel->_pos.y = _di; + _labels.clear(); } void Gfx::drawLabels() { - if ((!_floatingLabel) && (_numLabels == 0)) { + if (_labels.size() == 0) { return; } + updateFloatingLabel(); Graphics::Surface* surf = g_system->lockScreen(); - for (uint i = 0; i < _numLabels; i++) { - if (_labels[i]->_visible) { - Common::Rect r(_labels[i]->_cnv.w, _labels[i]->_cnv.h); - r.moveTo(_labels[i]->_pos); - blt(r, (byte*)_labels[i]->_cnv.getBasePtr(0, 0), surf, LAYER_FOREGROUND, LABEL_TRANSPARENT_COLOR); - } - } - - if (_floatingLabel) { - Common::Rect r(_floatingLabel->_cnv.w, _floatingLabel->_cnv.h); - r.moveTo(_floatingLabel->_pos); - blt(r, (byte*)_floatingLabel->_cnv.getBasePtr(0, 0), surf, LAYER_FOREGROUND, LABEL_TRANSPARENT_COLOR); + for (uint i = 0; i < _labels.size(); i++) { + drawGfxObject(_labels[i], *surf, false); } g_system->unlockScreen(); } -Label::Label() { - resetPosition(); - _visible = false; -} - -Label::~Label() { - free(); -} - -void Label::free() { - _cnv.free(); - resetPosition(); -} - -void Label::resetPosition() { - _pos.x = -1000; - _pos.y = -1000; -} - void Gfx::getStringExtent(Font *font, char *text, uint16 maxwidth, int16* width, int16* height) { @@ -790,8 +781,7 @@ Gfx::Gfx(Parallaction* vm) : _numBalloons = 0; _numItems = 0; - _numLabels = 0; - _floatingLabel = 0; + _floatingLabel = NO_FLOATING_LABEL; _screenX = 0; _screenY = 0; @@ -826,8 +816,8 @@ int Gfx::setItem(GfxObj* frames, uint16 x, uint16 y, byte transparentColor) { _items[id].data = frames; _items[id].data->x = x; _items[id].data->y = y; - - _items[id].transparentColor = transparentColor; + _items[id].data->layer = LAYER_FOREGROUND; + _items[id].data->transparentKey = transparentColor; _numItems++; @@ -837,6 +827,7 @@ int Gfx::setItem(GfxObj* frames, uint16 x, uint16 y, byte transparentColor) { void Gfx::setItemFrame(uint item, uint16 f) { assert(item < _numItems); _items[item].data->frame = f; + _items[item].data->setFlags(kGfxObjVisible); } Gfx::Balloon* Gfx::getBalloon(uint id) { diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h index 17869de432..df4cab4caf 100644 --- a/engines/parallaction/graphics.h +++ b/engines/parallaction/graphics.h @@ -326,20 +326,6 @@ public: #define CENTER_LABEL_HORIZONTAL -1 #define CENTER_LABEL_VERTICAL -1 -struct Label { - Graphics::Surface _cnv; - - Common::Point _pos; - bool _visible; - - Label(); - ~Label(); - - void free(); - void resetPosition(); -}; - - #define MAX_BALLOON_WIDTH 130 @@ -357,7 +343,8 @@ enum { kGfxObjTypeDoor = 0, kGfxObjTypeGet = 1, - kGfxObjTypeAnim = 2 + kGfxObjTypeAnim = 2, + kGfxObjTypeLabel = 3 }; enum { @@ -381,6 +368,7 @@ public: uint type; uint frame; uint layer; + uint transparentKey; GfxObj(uint type, Frames *frames, const char *name = NULL); virtual ~GfxObj(); @@ -478,9 +466,12 @@ public: void clearGfxObjects(); void sortAnimations(); + // labels - void setFloatingLabel(Label *label); - Label *renderFloatingLabel(Font *font, char *text); + void showFloatingLabel(uint label); + void hideFloatingLabel(); + + uint renderFloatingLabel(Font *font, char *text); uint createLabel(Font *font, const char *text, byte color); void showLabel(uint id, int16 x, int16 y); void hideLabel(uint id); @@ -572,19 +563,18 @@ public: uint _numBalloons; struct Item { - uint16 frame; GfxObj *data; - - byte transparentColor; - Common::Rect rect; } _items[14]; uint _numItems; - #define MAX_NUM_LABELS 5 - Label* _labels[MAX_NUM_LABELS]; - uint _numLabels; - Label *_floatingLabel; + #define MAX_NUM_LABELS 20 + #define NO_FLOATING_LABEL 1000 + + typedef Common::Array GfxObjArray; + GfxObjArray _labels; + + uint _floatingLabel; void drawInventory(); void updateFloatingLabel(); @@ -601,6 +591,7 @@ public: void drawText(Font *font, Graphics::Surface* surf, uint16 x, uint16 y, const char *text, byte color); void drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapwidth); + void drawGfxObject(GfxObj *obj, Graphics::Surface &surf, bool scene); void blt(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, byte transparentColor); void unpackBlt(const Common::Rect& r, byte *data, uint size, Graphics::Surface *surf, uint16 z, byte transparentColor); }; diff --git a/engines/parallaction/input.h b/engines/parallaction/input.h index 46dbb08c4e..e06fe96705 100644 --- a/engines/parallaction/input.h +++ b/engines/parallaction/input.h @@ -44,7 +44,7 @@ struct InputData { Common::Point _mousePos; int16 _inventoryIndex; ZonePtr _zone; - Label* _label; + uint _label; }; class Input { diff --git a/engines/parallaction/objects.cpp b/engines/parallaction/objects.cpp index 5b5aa85584..54afabc318 100644 --- a/engines/parallaction/objects.cpp +++ b/engines/parallaction/objects.cpp @@ -182,7 +182,6 @@ Zone::~Zone() { break; } - delete _label; } void Zone::getRect(Common::Rect& r) const { diff --git a/engines/parallaction/objects.h b/engines/parallaction/objects.h index 44ad35e0ab..19835da9d0 100644 --- a/engines/parallaction/objects.h +++ b/engines/parallaction/objects.h @@ -287,7 +287,7 @@ struct Zone { int16 _bottom; uint32 _type; uint32 _flags; - Label *_label; + uint _label; uint16 field_2C; // unused uint16 field_2E; // unused TypeData u; diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index 4f586961a6..5f5cfdb820 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -290,12 +290,12 @@ void Parallaction::processInput(InputData *data) { switch (data->_event) { case kEvEnterZone: debugC(2, kDebugInput, "processInput: kEvEnterZone"); - _gfx->setFloatingLabel(data->_label); + _gfx->showFloatingLabel(data->_label); break; case kEvExitZone: debugC(2, kDebugInput, "processInput: kEvExitZone"); - _gfx->setFloatingLabel(0); + _gfx->hideFloatingLabel(); break; case kEvAction: @@ -308,7 +308,7 @@ void Parallaction::processInput(InputData *data) { case kEvOpenInventory: _input->stopHovering(); - _gfx->setFloatingLabel(0); + _gfx->hideFloatingLabel(); if (hitZone(kZoneYou, data->_mousePos.x, data->_mousePos.y) == 0) { setArrowCursor(); } diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp index 59b9465d0a..af848aa6af 100644 --- a/engines/parallaction/parallaction_ns.cpp +++ b/engines/parallaction/parallaction_ns.cpp @@ -187,7 +187,7 @@ void Parallaction_ns::setArrowCursor() { debugC(1, kDebugInput, "setting mouse cursor to arrow"); // this stuff is needed to avoid artifacts with labels and selected items when switching cursors - _gfx->setFloatingLabel(0); + _gfx->hideFloatingLabel(); _input->_activeItem._id = 0; _system->setMouseCursor(_mouseArrow, MOUSEARROW_WIDTH, MOUSEARROW_HEIGHT, 0, 0, 0); @@ -298,7 +298,7 @@ void Parallaction_ns::changeLocation(char *location) { _soundMan->playLocationMusic(location); - _gfx->setFloatingLabel(0); + _gfx->hideFloatingLabel(); _gfx->freeLabels(); _input->stopHovering(); -- cgit v1.2.3