aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction
diff options
context:
space:
mode:
authorNicola Mettifogo2007-09-02 18:34:11 +0000
committerNicola Mettifogo2007-09-02 18:34:11 +0000
commit21e4f4f1760e204de6e8d0a413f8e8f8987dd083 (patch)
tree1902fcb1756b1226e05dc12a4bfabead8ba9215d /engines/parallaction
parentf1f324cee424cb97da1a14789db2806002ba3f6e (diff)
downloadscummvm-rg350-21e4f4f1760e204de6e8d0a413f8e8f8987dd083.tar.gz
scummvm-rg350-21e4f4f1760e204de6e8d0a413f8e8f8987dd083.tar.bz2
scummvm-rg350-21e4f4f1760e204de6e8d0a413f8e8f8987dd083.zip
Simplified global label management and added subtitles for BRA.
svn-id: r28828
Diffstat (limited to 'engines/parallaction')
-rw-r--r--engines/parallaction/exec_br.cpp72
-rw-r--r--engines/parallaction/exec_ns.cpp14
-rw-r--r--engines/parallaction/graphics.cpp10
-rw-r--r--engines/parallaction/graphics.h6
-rw-r--r--engines/parallaction/objects.cpp31
-rw-r--r--engines/parallaction/objects.h7
-rw-r--r--engines/parallaction/parallaction.cpp51
-rw-r--r--engines/parallaction/parallaction.h28
-rw-r--r--engines/parallaction/parallaction_ns.cpp10
-rw-r--r--engines/parallaction/parser_br.cpp3
10 files changed, 175 insertions, 57 deletions
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<Parallaction_br> 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;