Simplified global label management and added subtitles for BRA.

svn-id: r28828
This commit is contained in:
Nicola Mettifogo 2007-09-02 18:34:11 +00:00
parent f1f324cee4
commit 21e4f4f176
10 changed files with 177 additions and 59 deletions

View file

@ -44,6 +44,50 @@ typedef OpcodeImpl<Parallaction_br> OpcodeV2;
#define INSTRUCTION_OPCODE(op) OpcodeV2(this, &Parallaction_br::instOp_##op) #define INSTRUCTION_OPCODE(op) OpcodeV2(this, &Parallaction_br::instOp_##op)
#define DECLARE_INSTRUCTION_OPCODE(op) void 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) { DECLARE_COMMAND_OPCODE(location) {
warning("Parallaction_br::cmdOp_location command not yet implemented"); warning("Parallaction_br::cmdOp_location command not yet implemented");
@ -201,7 +245,8 @@ DECLARE_COMMAND_OPCODE(give) {
DECLARE_COMMAND_OPCODE(text) { 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) { DECLARE_INSTRUCTION_OPCODE(text) {
warning("Parallaction_br::instOp_text not yet implemented"); Instruction *inst = (*_instRunCtxt.inst);
setupSubtitles(inst->_text, inst->_text2, inst->_y);
} }

View file

@ -858,9 +858,7 @@ void Parallaction_ns::jobDisplayLabel(void *parm, Job *j) {
Label *label = (Label*)parm; Label *label = (Label*)parm;
debugC(9, kDebugJobs, "jobDisplayLabel (%p)", (const void*) label); debugC(9, kDebugJobs, "jobDisplayLabel (%p)", (const void*) label);
if (label->_cnv.w == 0) _gfx->drawLabel(*label);
return;
_gfx->flatBlitCnv(&label->_cnv, _gfx->_labelPosition[0].x, _gfx->_labelPosition[0].y, Gfx::kBitBack);
return; return;
} }
@ -886,13 +884,13 @@ void Parallaction_ns::jobEraseLabel(void *parm, Job *j) {
if (label->_cnv.w + _si > _screenWidth) if (label->_cnv.w + _si > _screenWidth)
_si = _screenWidth - label->_cnv.w; _si = _screenWidth - label->_cnv.w;
Common::Rect r(label->_cnv.w, label->_cnv.h); Common::Rect r;
r.moveTo(_gfx->_labelPosition[1]); label->getRect(r, true);
_gfx->restoreBackground(r); _gfx->restoreBackground(r);
_gfx->_labelPosition[1] = _gfx->_labelPosition[0]; label->_old = label->_pos;
_gfx->_labelPosition[0].x = _si; label->_pos.x = _si;
_gfx->_labelPosition[0].y = _di; label->_pos.y = _di;
return; return;
} }

View file

@ -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);
}
// //

View file

@ -135,7 +135,7 @@ class Parallaction;
struct DoorData; struct DoorData;
struct GetData; struct GetData;
struct Label;
struct MaskBuffer { struct MaskBuffer {
// handles a 2-bit depth buffer used for z-buffering // handles a 2-bit depth buffer used for z-buffering
@ -219,6 +219,8 @@ public:
uint16 getStringWidth(const char *text); uint16 getStringWidth(const char *text);
void getStringExtent(char *text, uint16 maxwidth, int16* width, int16* height); void getStringExtent(char *text, uint16 maxwidth, int16* width, int16* height);
void drawLabel(Label &label);
// cut/paste // cut/paste
void flatBlitCnv(Graphics::Surface *cnv, int16 x, int16 y, Gfx::Buffers buffer); 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); void flatBlitCnv(Frames *cnv, uint16 frame, int16 x, int16 y, Gfx::Buffers buffer);
@ -259,7 +261,6 @@ public:
public: public:
Common::Point _labelPosition[2];
uint16 _bgLayers[4]; uint16 _bgLayers[4];
PaletteFxRange _palettefx[6]; PaletteFxRange _palettefx[6];
Palette _palette; Palette _palette;
@ -296,3 +297,4 @@ protected:

View file

@ -131,8 +131,6 @@ Zone::Zone() {
Zone::~Zone() { Zone::~Zone() {
// printf("~Zone(%s)\n", _label._text); // printf("~Zone(%s)\n", _label._text);
_label._cnv.free();
switch (_type & 0xFFFF) { switch (_type & 0xFFFF) {
case kZoneExamine: case kZoneExamine:
free(u.examine->_filename); free(u.examine->_filename);
@ -198,15 +196,40 @@ uint16 Zone::height() const {
} }
Label::Label() { Label::Label() {
_text = NULL; resetPosition();
_text = 0;
} }
Label::~Label() { Label::~Label() {
_cnv.free(); free();
if (_text)
free(_text);
} }
void Label::free() {
_cnv.free();
if (_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() { Answer::Answer() {
_text = NULL; _text = NULL;

View file

@ -263,8 +263,15 @@ struct Label {
char* _text; char* _text;
Graphics::Surface _cnv; Graphics::Surface _cnv;
Common::Point _pos;
Common::Point _old;
Label(); Label();
~Label(); ~Label();
void free();
void resetPosition();
void getRect(Common::Rect &r, bool old = false);
}; };
struct Zone { struct Zone {

View file

@ -353,6 +353,31 @@ void Parallaction::runGame() {
return; 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) { void Parallaction::processInput(InputData *data) {
Zone *z; Zone *z;
@ -360,19 +385,12 @@ void Parallaction::processInput(InputData *data) {
switch (data->_event) { switch (data->_event) {
case kEvEnterZone: case kEvEnterZone:
debugC(2, kDebugInput, "processInput: kEvEnterZone"); debugC(2, kDebugInput, "processInput: kEvEnterZone");
_gfx->_labelPosition[1].x = -1000; showLabel(*data->_label);
_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);
break; break;
case kEvExitZone: case kEvExitZone:
debugC(2, kDebugInput, "processInput: kEvExitZone"); debugC(2, kDebugInput, "processInput: kEvExitZone");
removeJob(_jDrawLabel); hideLabel(kPriority15);
addJob(kJobWaitRemoveJob, _jEraseLabel, kPriority15);
_jDrawLabel = NULL;
break; break;
case kEvAction: case kEvAction:
@ -390,13 +408,10 @@ void Parallaction::processInput(InputData *data) {
case kEvOpenInventory: case kEvOpenInventory:
_procCurrentHoverItem = -1; _procCurrentHoverItem = -1;
_hoverZone = NULL; _hoverZone = NULL;
if (_jDrawLabel != 0) { hideLabel(kPriority2);
removeJob(_jDrawLabel); if (hitZone(kZoneYou, _mousePos.x, _mousePos.y) == 0) {
_jDrawLabel = NULL;
addJob(kJobWaitRemoveJob, _jEraseLabel, kPriority2);
}
if (hitZone(kZoneYou, _mousePos.x, _mousePos.y) == 0)
changeCursor(kCursorArrow); changeCursor(kCursorArrow);
}
removeJob(_jRunScripts); removeJob(_jRunScripts);
_jDrawInventory = addJob(kJobShowInventory, 0, kPriority2); _jDrawInventory = addJob(kJobShowInventory, 0, kPriority2);
openInventory(); openInventory();
@ -619,11 +634,7 @@ void Parallaction::changeCursor(int32 index) {
debugC(1, kDebugInput, "changeCursor(%i), label: %p", index, (const void*)_jDrawLabel); debugC(1, kDebugInput, "changeCursor(%i), label: %p", index, (const void*)_jDrawLabel);
if (_jDrawLabel != NULL) { hideLabel(kPriority15);
removeJob(_jDrawLabel);
addJob(kJobWaitRemoveJob, _jEraseLabel, kPriority15 );
_jDrawLabel = NULL;
}
_activeItem._id = 0; _activeItem._id = 0;

View file

@ -90,7 +90,8 @@ enum {
kPriority18 = 18, kPriority18 = 18,
kPriority19 = 19, kPriority19 = 19,
kPriority20 = 20, kPriority20 = 20,
kPriority21 = 21 kPriority21 = 21,
kPriority99 = 99 // fictitious priority value used as a flag to handle quick label deletion
}; };
enum { enum {
@ -372,8 +373,8 @@ enum Jobs {
kJobHideInventory, kJobHideInventory,
// BRA specific // BRA specific
kJobClearSubtitle = 10, kJobEraseSubtitle = 10,
kJobDrawSubtitle, kJobDisplaySubtitle,
kJobWaitRemoveSubtitleJob, kJobWaitRemoveSubtitleJob,
kJobPauseSfx, kJobPauseSfx,
kJobStopFollower, kJobStopFollower,
@ -475,6 +476,9 @@ public:
Table *_localFlagNames; Table *_localFlagNames;
void showLabel(Label &label);
void hideLabel(uint priority);
public: public:
int getGameType() const; int getGameType() const;
uint32 getFeatures() const; uint32 getFeatures() const;
@ -745,6 +749,9 @@ protected:
CommandList *list; CommandList *list;
bool endcommands; bool endcommands;
Command *cmd; Command *cmd;
// BRA specific
int numZones;
} _locParseCtxt; } _locParseCtxt;
DECLARE_UNQUALIFIED_LOCATION_PARSER(invalid); DECLARE_UNQUALIFIED_LOCATION_PARSER(invalid);
@ -914,6 +921,10 @@ public:
int _zeta2; int _zeta2;
int16 _lipSyncVal; int16 _lipSyncVal;
uint _subtitleLipSync;
Label _subtitle0;
Label _subtitle1;
Zone *_activeZone2; Zone *_activeZone2;
@ -921,10 +932,6 @@ public:
uint32 _zoneFlags[NUM_LOCATIONS][NUM_ZONES]; uint32 _zoneFlags[NUM_LOCATIONS][NUM_ZONES];
struct LocationParserContext_br : public LocationParserContext {
int numZones;
} _locParseCtxt;
private: private:
void initResources(); void initResources();
void initFonts(); void initFonts();
@ -1082,6 +1089,13 @@ private:
DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(stop); DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(stop);
DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(endscript); 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 // FIXME: remove global

View file

@ -232,16 +232,10 @@ void Parallaction_ns::changeLocation(char *location) {
_soundMan->playLocationMusic(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 // execution of label jobs after a location switch. The other workaround in
// Parallaction::runGame should have been rendered useless by this one. // Parallaction::runGame should have been rendered useless by this one.
if (_jDrawLabel != NULL) { hideLabel(kPriority99);
removeJob(_jDrawLabel);
removeJob(_jEraseLabel);
_jDrawLabel = NULL;
_jEraseLabel = NULL;
}
_hoverZone = NULL; _hoverZone = NULL;
if (_engineFlags & kEngineBlockInput) { if (_engineFlags & kEngineBlockInput) {

View file

@ -705,7 +705,8 @@ void Parallaction_br::initParsers() {
INSTRUCTION_PARSER(inc), // div INSTRUCTION_PARSER(inc), // div
INSTRUCTION_PARSER(if_op), INSTRUCTION_PARSER(if_op),
INSTRUCTION_PARSER(endif), INSTRUCTION_PARSER(endif),
INSTRUCTION_PARSER(zone) // stop INSTRUCTION_PARSER(zone), // stop
INSTRUCTION_PARSER(endscript)
}; };
uint i; uint i;