mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-17 05:59:58 +00:00
Simplified global label management and added subtitles for BRA.
svn-id: r28828
This commit is contained in:
parent
f1f324cee4
commit
21e4f4f176
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
@ -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:
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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() {
|
||||
_cnv.free();
|
||||
if (_text)
|
||||
free(_text);
|
||||
free();
|
||||
}
|
||||
|
||||
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() {
|
||||
_text = NULL;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user