From 21e4f4f1760e204de6e8d0a413f8e8f8987dd083 Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Sun, 2 Sep 2007 18:34:11 +0000 Subject: Simplified global label management and added subtitles for BRA. svn-id: r28828 --- engines/parallaction/exec_br.cpp | 72 +++++++++++++++++++++++++++++++- engines/parallaction/exec_ns.cpp | 14 +++---- engines/parallaction/graphics.cpp | 10 ++--- engines/parallaction/graphics.h | 6 ++- engines/parallaction/objects.cpp | 31 ++++++++++++-- engines/parallaction/objects.h | 7 ++++ engines/parallaction/parallaction.cpp | 51 +++++++++++++--------- engines/parallaction/parallaction.h | 28 +++++++++---- engines/parallaction/parallaction_ns.cpp | 10 +---- engines/parallaction/parser_br.cpp | 3 +- 10 files changed, 175 insertions(+), 57 deletions(-) (limited to 'engines/parallaction') diff --git a/engines/parallaction/exec_br.cpp b/engines/parallaction/exec_br.cpp index 9c174dd036..a5dada219c 100644 --- a/engines/parallaction/exec_br.cpp +++ b/engines/parallaction/exec_br.cpp @@ -44,6 +44,50 @@ typedef OpcodeImpl OpcodeV2; #define INSTRUCTION_OPCODE(op) OpcodeV2(this, &Parallaction_br::instOp_##op) #define DECLARE_INSTRUCTION_OPCODE(op) void Parallaction_br::instOp_##op() +void Parallaction_br::setupSubtitles(char *s, char *s2, int y) { + + if (!scumm_stricmp("clear", s)) { + + removeJob(_jDisplaySubtitle); + addJob(kJobWaitRemoveSubtitleJob, _jEraseSubtitle, 15); + _jDisplaySubtitle = 0; + + _subtitle0.free(); + _subtitle1.free(); + return; + } + + _subtitle0.free(); + _subtitle1.free(); + + renderLabel(&_subtitle0._cnv, s); + _subtitle0._text = strdup(s); + + if (s2) { + renderLabel(&_subtitle1._cnv, s2); + _subtitle1._text = strdup(s2); + } + + _subtitleLipSync = 0; + + if (y != -1) { + _subtitle0._pos.y = y; + _subtitle1._pos.y = y + 5 + _labelFont->height(); + } + + _subtitle0._pos.x = (_gfx->_screenX << 2) + ((640 - _subtitle0._cnv.w) >> 1); + if (_subtitle1._text) + _subtitle1._pos.x = (_gfx->_screenX << 2) + ((640 - _subtitle1._cnv.w) >> 1); + + if (_jDisplaySubtitle == 0) { + _subtitle0._old.x = -1000; + _subtitle0._old.y = -1000; + _jDisplaySubtitle = addJob(kJobDisplaySubtitle, 0, 1); + _jEraseSubtitle = addJob(kJobEraseSubtitle, 0, 20); + } +} + + DECLARE_COMMAND_OPCODE(location) { warning("Parallaction_br::cmdOp_location command not yet implemented"); @@ -201,7 +245,8 @@ DECLARE_COMMAND_OPCODE(give) { DECLARE_COMMAND_OPCODE(text) { - warning("Parallaction_br::cmdOp_text not yet implemented"); + CommandData *data = &_cmdRunCtxt.cmd->u; + setupSubtitles(data->_string, data->_string2, data->_zeta0); } @@ -354,8 +399,31 @@ DECLARE_INSTRUCTION_OPCODE(print) { } + +void Parallaction_br::jobDisplaySubtitle(void *parm, Job *job) { + _gfx->drawLabel(_subtitle0); + _gfx->drawLabel(_subtitle1); +} + +void Parallaction_br::jobEraseSubtitle(void *parm, Job *job) { + Common::Rect r; + + if (_subtitle0._old.x != -1000) { + _subtitle0.getRect(r); + _gfx->restoreBackground(r); + } + _subtitle0._old = _subtitle0._pos; + + if (_subtitle1._old.x != -1000) { + _subtitle0.getRect(r); + _gfx->restoreBackground(r); + } + _subtitle1._old = _subtitle1._pos; +} + DECLARE_INSTRUCTION_OPCODE(text) { - warning("Parallaction_br::instOp_text not yet implemented"); + Instruction *inst = (*_instRunCtxt.inst); + setupSubtitles(inst->_text, inst->_text2, inst->_y); } diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp index 48817c10ab..d7500be7f1 100644 --- a/engines/parallaction/exec_ns.cpp +++ b/engines/parallaction/exec_ns.cpp @@ -858,9 +858,7 @@ void Parallaction_ns::jobDisplayLabel(void *parm, Job *j) { Label *label = (Label*)parm; debugC(9, kDebugJobs, "jobDisplayLabel (%p)", (const void*) label); - if (label->_cnv.w == 0) - return; - _gfx->flatBlitCnv(&label->_cnv, _gfx->_labelPosition[0].x, _gfx->_labelPosition[0].y, Gfx::kBitBack); + _gfx->drawLabel(*label); return; } @@ -886,13 +884,13 @@ void Parallaction_ns::jobEraseLabel(void *parm, Job *j) { if (label->_cnv.w + _si > _screenWidth) _si = _screenWidth - label->_cnv.w; - Common::Rect r(label->_cnv.w, label->_cnv.h); - r.moveTo(_gfx->_labelPosition[1]); + Common::Rect r; + label->getRect(r, true); _gfx->restoreBackground(r); - _gfx->_labelPosition[1] = _gfx->_labelPosition[0]; - _gfx->_labelPosition[0].x = _si; - _gfx->_labelPosition[0].y = _di; + label->_old = label->_pos; + label->_pos.x = _si; + label->_pos.y = _di; return; } diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp index 2508633c87..6a8ef0718b 100644 --- a/engines/parallaction/graphics.cpp +++ b/engines/parallaction/graphics.cpp @@ -409,12 +409,12 @@ void Gfx::blit(const Common::Rect& r, uint16 z, byte *data, Gfx::Buffers buffer) } +void Gfx::drawLabel(Label &label) { + if (label._text == 0) + return; - - - - - + flatBlitCnv(&label._cnv, label._pos.x, label._pos.y, Gfx::kBitBack); +} // diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h index 3913eebbdf..9f1101efa2 100644 --- a/engines/parallaction/graphics.h +++ b/engines/parallaction/graphics.h @@ -135,7 +135,7 @@ class Parallaction; struct DoorData; struct GetData; - +struct Label; struct MaskBuffer { // handles a 2-bit depth buffer used for z-buffering @@ -219,6 +219,8 @@ public: uint16 getStringWidth(const char *text); void getStringExtent(char *text, uint16 maxwidth, int16* width, int16* height); + void drawLabel(Label &label); + // cut/paste void flatBlitCnv(Graphics::Surface *cnv, int16 x, int16 y, Gfx::Buffers buffer); void flatBlitCnv(Frames *cnv, uint16 frame, int16 x, int16 y, Gfx::Buffers buffer); @@ -259,7 +261,6 @@ public: public: - Common::Point _labelPosition[2]; uint16 _bgLayers[4]; PaletteFxRange _palettefx[6]; Palette _palette; @@ -296,3 +297,4 @@ protected: + diff --git a/engines/parallaction/objects.cpp b/engines/parallaction/objects.cpp index 195d814265..c856d419e3 100644 --- a/engines/parallaction/objects.cpp +++ b/engines/parallaction/objects.cpp @@ -131,8 +131,6 @@ Zone::Zone() { Zone::~Zone() { // printf("~Zone(%s)\n", _label._text); - _label._cnv.free(); - switch (_type & 0xFFFF) { case kZoneExamine: free(u.examine->_filename); @@ -198,15 +196,40 @@ uint16 Zone::height() const { } Label::Label() { - _text = NULL; + resetPosition(); + _text = 0; } Label::~Label() { + free(); +} + +void Label::free() { _cnv.free(); if (_text) - free(_text); + ::free(_text); + _text = 0; + + resetPosition(); } +void Label::resetPosition() { + _pos.x = -1000; + _pos.y = -1000; + _old.x = -1000; + _old.y = -1000; +} + +void Label::getRect(Common::Rect &r, bool old) { + r.setWidth(_cnv.w); + r.setHeight(_cnv.h); + + if (old) { + r.moveTo(_old); + } else { + r.moveTo(_pos); + } +} Answer::Answer() { _text = NULL; diff --git a/engines/parallaction/objects.h b/engines/parallaction/objects.h index cc6e8e0fc6..b456a1960a 100644 --- a/engines/parallaction/objects.h +++ b/engines/parallaction/objects.h @@ -263,8 +263,15 @@ struct Label { char* _text; Graphics::Surface _cnv; + Common::Point _pos; + Common::Point _old; + Label(); ~Label(); + + void free(); + void resetPosition(); + void getRect(Common::Rect &r, bool old = false); }; struct Zone { diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index cab1658b29..7e5221d6ae 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -353,6 +353,31 @@ void Parallaction::runGame() { return; } +void Parallaction::showLabel(Label &label) { + label.resetPosition(); + _jDrawLabel = addJob(kJobDisplayLabel, (void*)&label, kPriority0); + _jEraseLabel = addJob(kJobEraseLabel, (void*)&label, kPriority20); +} + +void Parallaction::hideLabel(uint priority) { + + if (!_jDrawLabel) + return; + + removeJob(_jDrawLabel); + _jDrawLabel = 0; + + if (priority == kPriority99) { + // remove job immediately + removeJob(_jEraseLabel); + _jEraseLabel = 0; + } else { + // schedule job for deletion + addJob(kJobWaitRemoveJob, _jEraseLabel, priority); + } + +} + void Parallaction::processInput(InputData *data) { Zone *z; @@ -360,19 +385,12 @@ void Parallaction::processInput(InputData *data) { switch (data->_event) { case kEvEnterZone: debugC(2, kDebugInput, "processInput: kEvEnterZone"); - _gfx->_labelPosition[1].x = -1000; - _gfx->_labelPosition[1].y = -1000; - _gfx->_labelPosition[0].x = -1000; - _gfx->_labelPosition[0].y = -1000; - _jDrawLabel = addJob(kJobDisplayLabel, (void*)data->_label, kPriority0); - _jEraseLabel = addJob(kJobEraseLabel, (void*)data->_label, kPriority20); + showLabel(*data->_label); break; case kEvExitZone: debugC(2, kDebugInput, "processInput: kEvExitZone"); - removeJob(_jDrawLabel); - addJob(kJobWaitRemoveJob, _jEraseLabel, kPriority15); - _jDrawLabel = NULL; + hideLabel(kPriority15); break; case kEvAction: @@ -390,13 +408,10 @@ void Parallaction::processInput(InputData *data) { case kEvOpenInventory: _procCurrentHoverItem = -1; _hoverZone = NULL; - if (_jDrawLabel != 0) { - removeJob(_jDrawLabel); - _jDrawLabel = NULL; - addJob(kJobWaitRemoveJob, _jEraseLabel, kPriority2); + hideLabel(kPriority2); + if (hitZone(kZoneYou, _mousePos.x, _mousePos.y) == 0) { + changeCursor(kCursorArrow); } - if (hitZone(kZoneYou, _mousePos.x, _mousePos.y) == 0) - changeCursor(kCursorArrow); removeJob(_jRunScripts); _jDrawInventory = addJob(kJobShowInventory, 0, kPriority2); openInventory(); @@ -619,11 +634,7 @@ void Parallaction::changeCursor(int32 index) { debugC(1, kDebugInput, "changeCursor(%i), label: %p", index, (const void*)_jDrawLabel); - if (_jDrawLabel != NULL) { - removeJob(_jDrawLabel); - addJob(kJobWaitRemoveJob, _jEraseLabel, kPriority15 ); - _jDrawLabel = NULL; - } + hideLabel(kPriority15); _activeItem._id = 0; diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index 433587780e..f13ac3ab95 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -90,7 +90,8 @@ enum { kPriority18 = 18, kPriority19 = 19, kPriority20 = 20, - kPriority21 = 21 + kPriority21 = 21, + kPriority99 = 99 // fictitious priority value used as a flag to handle quick label deletion }; enum { @@ -372,8 +373,8 @@ enum Jobs { kJobHideInventory, // BRA specific - kJobClearSubtitle = 10, - kJobDrawSubtitle, + kJobEraseSubtitle = 10, + kJobDisplaySubtitle, kJobWaitRemoveSubtitleJob, kJobPauseSfx, kJobStopFollower, @@ -475,6 +476,9 @@ public: Table *_localFlagNames; + void showLabel(Label &label); + void hideLabel(uint priority); + public: int getGameType() const; uint32 getFeatures() const; @@ -745,6 +749,9 @@ protected: CommandList *list; bool endcommands; Command *cmd; + + // BRA specific + int numZones; } _locParseCtxt; DECLARE_UNQUALIFIED_LOCATION_PARSER(invalid); @@ -914,6 +921,10 @@ public: int _zeta2; int16 _lipSyncVal; + uint _subtitleLipSync; + + Label _subtitle0; + Label _subtitle1; Zone *_activeZone2; @@ -921,10 +932,6 @@ public: uint32 _zoneFlags[NUM_LOCATIONS][NUM_ZONES]; - struct LocationParserContext_br : public LocationParserContext { - int numZones; - } _locParseCtxt; - private: void initResources(); void initFonts(); @@ -1082,6 +1089,13 @@ private: DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(stop); DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(endscript); + Job *_jDisplaySubtitle; + Job *_jEraseSubtitle; + + void jobDisplaySubtitle(void *parm, Job *job); + void jobEraseSubtitle(void *parm, Job *job); + void setupSubtitles(char *s, char *s2, int y); + }; // FIXME: remove global diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp index 8bac86b121..6775553887 100644 --- a/engines/parallaction/parallaction_ns.cpp +++ b/engines/parallaction/parallaction_ns.cpp @@ -232,16 +232,10 @@ void Parallaction_ns::changeLocation(char *location) { _soundMan->playLocationMusic(location); - // WORKAROUND: this if-statement has been added to avoid crashes caused by + // WORKAROUND: this hideLabel has been added to avoid crashes caused by // execution of label jobs after a location switch. The other workaround in // Parallaction::runGame should have been rendered useless by this one. - if (_jDrawLabel != NULL) { - removeJob(_jDrawLabel); - removeJob(_jEraseLabel); - _jDrawLabel = NULL; - _jEraseLabel = NULL; - } - + hideLabel(kPriority99); _hoverZone = NULL; if (_engineFlags & kEngineBlockInput) { diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp index bf33471e1f..2390e80dd2 100644 --- a/engines/parallaction/parser_br.cpp +++ b/engines/parallaction/parser_br.cpp @@ -705,7 +705,8 @@ void Parallaction_br::initParsers() { INSTRUCTION_PARSER(inc), // div INSTRUCTION_PARSER(if_op), INSTRUCTION_PARSER(endif), - INSTRUCTION_PARSER(zone) // stop + INSTRUCTION_PARSER(zone), // stop + INSTRUCTION_PARSER(endscript) }; uint i; -- cgit v1.2.3