aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction
diff options
context:
space:
mode:
Diffstat (limited to 'engines/parallaction')
-rw-r--r--engines/parallaction/balloons.cpp107
-rw-r--r--engines/parallaction/callables_ns.cpp11
-rw-r--r--engines/parallaction/detection.cpp2
-rw-r--r--engines/parallaction/dialogue.cpp16
-rw-r--r--engines/parallaction/disk.h4
-rw-r--r--engines/parallaction/exec_br.cpp23
-rw-r--r--engines/parallaction/exec_ns.cpp323
-rw-r--r--engines/parallaction/gfxbase.cpp190
-rw-r--r--engines/parallaction/graphics.cpp88
-rw-r--r--engines/parallaction/graphics.h28
-rw-r--r--engines/parallaction/gui_br.cpp61
-rw-r--r--engines/parallaction/gui_ns.cpp94
-rw-r--r--engines/parallaction/input.cpp186
-rw-r--r--engines/parallaction/input.h45
-rw-r--r--engines/parallaction/objects.cpp2
-rw-r--r--engines/parallaction/objects.h17
-rw-r--r--engines/parallaction/parallaction.cpp448
-rw-r--r--engines/parallaction/parallaction.h495
-rw-r--r--engines/parallaction/parallaction_br.cpp219
-rw-r--r--engines/parallaction/parallaction_ns.cpp132
-rw-r--r--engines/parallaction/parser.cpp29
-rw-r--r--engines/parallaction/parser.h1
-rw-r--r--engines/parallaction/parser_br.cpp2
-rw-r--r--engines/parallaction/saveload.cpp140
-rw-r--r--engines/parallaction/saveload.h96
-rw-r--r--engines/parallaction/sound.cpp3
-rw-r--r--engines/parallaction/staticres.cpp15
27 files changed, 1462 insertions, 1315 deletions
diff --git a/engines/parallaction/balloons.cpp b/engines/parallaction/balloons.cpp
index 222954ec3a..290aa5e625 100644
--- a/engines/parallaction/balloons.cpp
+++ b/engines/parallaction/balloons.cpp
@@ -246,6 +246,8 @@ class BalloonManager_ns : public BalloonManager {
static int16 _dialogueBalloonX[5];
+ byte _textColors[2];
+
struct Balloon {
Common::Rect outerBox;
Common::Rect innerBox;
@@ -266,16 +268,18 @@ public:
void freeBalloons();
int setLocationBalloon(char *text, bool endGame);
- int setDialogueBalloon(char *text, uint16 winding, byte textColor);
- int setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor);
- void setBalloonText(uint id, char *text, byte textColor);
+ int setDialogueBalloon(char *text, uint16 winding, TextColor textColor);
+ int setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, TextColor textColor);
+ void setBalloonText(uint id, char *text, TextColor textColor);
int hitTestDialogueBalloon(int x, int y);
};
int16 BalloonManager_ns::_dialogueBalloonX[5] = { 80, 120, 150, 150, 150 };
BalloonManager_ns::BalloonManager_ns(Gfx *gfx) : _numBalloons(0), _gfx(gfx) {
-
+ _textColors[kSelectedColor] = 0;
+ _textColors[kUnselectedColor] = 3;
+ _textColors[kNormalColor] = 0;
}
BalloonManager_ns::~BalloonManager_ns() {
@@ -314,7 +318,7 @@ int BalloonManager_ns::createBalloon(int16 w, int16 h, int16 winding, uint16 bor
winding = (winding == 0 ? 1 : 0);
Common::Rect s(BALLOON_TAIL_WIDTH, BALLOON_TAIL_HEIGHT);
s.moveTo(r.width()/2 - 5, r.bottom - 1);
- _gfx->blt(s, _resBalloonTail[winding], balloon->surface, LAYER_FOREGROUND, BALLOON_TRANSPARENT_COLOR_NS);
+ _gfx->blt(s, _resBalloonTail[winding], balloon->surface, LAYER_FOREGROUND, 100, BALLOON_TRANSPARENT_COLOR_NS);
}
_numBalloons++;
@@ -323,7 +327,7 @@ int BalloonManager_ns::createBalloon(int16 w, int16 h, int16 winding, uint16 bor
}
-int BalloonManager_ns::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor) {
+int BalloonManager_ns::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, TextColor textColor) {
int16 w, h;
@@ -336,7 +340,7 @@ int BalloonManager_ns::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 w
Balloon *balloon = &_intBalloons[id];
StringWriter_NS sw(_vm->_dialogueFont);
- sw.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface);
+ sw.write(text, MAX_BALLOON_WIDTH, _textColors[textColor], balloon->surface);
// TODO: extract some text to make a name for obj
balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
@@ -347,7 +351,7 @@ int BalloonManager_ns::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 w
return id;
}
-int BalloonManager_ns::setDialogueBalloon(char *text, uint16 winding, byte textColor) {
+int BalloonManager_ns::setDialogueBalloon(char *text, uint16 winding, TextColor textColor) {
int16 w, h;
@@ -361,7 +365,7 @@ int BalloonManager_ns::setDialogueBalloon(char *text, uint16 winding, byte textC
Balloon *balloon = &_intBalloons[id];
StringWriter_NS sw(_vm->_dialogueFont);
- sw.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface);
+ sw.write(text, MAX_BALLOON_WIDTH, _textColors[textColor], balloon->surface);
// TODO: extract some text to make a name for obj
balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
@@ -377,12 +381,12 @@ int BalloonManager_ns::setDialogueBalloon(char *text, uint16 winding, byte textC
return id;
}
-void BalloonManager_ns::setBalloonText(uint id, char *text, byte textColor) {
+void BalloonManager_ns::setBalloonText(uint id, char *text, TextColor textColor) {
Balloon *balloon = getBalloon(id);
balloon->surface->fillRect(balloon->innerBox, 1);
StringWriter_NS sw(_vm->_dialogueFont);
- sw.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface);
+ sw.write(text, MAX_BALLOON_WIDTH, _textColors[textColor], balloon->surface);
}
@@ -398,7 +402,7 @@ int BalloonManager_ns::setLocationBalloon(char *text, bool endGame) {
int id = createBalloon(w+(endGame ? 5 : 10), h+5, -1, BALLOON_TRANSPARENT_COLOR_NS);
Balloon *balloon = &_intBalloons[id];
StringWriter_NS sw(_vm->_dialogueFont);
- sw.write(text, MAX_BALLOON_WIDTH, 0, balloon->surface);
+ sw.write(text, MAX_BALLOON_WIDTH, _textColors[kNormalColor], balloon->surface);
// TODO: extract some text to make a name for obj
balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
@@ -513,8 +517,6 @@ public:
StringWriter_BR(Font *font) : WrappedLineFormatter(font) { }
void write(const char *text, uint maxWidth, byte color, Graphics::Surface *surf) {
- maxWidth = 216;
-
StringExtent_BR se(_font);
se.calc(text, maxWidth);
_width = se.width() + 10;
@@ -534,6 +536,8 @@ public:
class BalloonManager_br : public BalloonManager {
+ byte _textColors[2];
+
struct Balloon {
Common::Rect box;
Graphics::Surface *surface;
@@ -550,7 +554,7 @@ class BalloonManager_br : public BalloonManager {
void cacheAnims();
void drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapwidth);
- int createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness);
+ int createBalloon(int16 w, int16 h, uint16 borderThickness);
Balloon *getBalloon(uint id);
Graphics::Surface *expandBalloon(Frames *data, int frameNum);
@@ -562,9 +566,9 @@ public:
void freeBalloons();
int setLocationBalloon(char *text, bool endGame);
- int setDialogueBalloon(char *text, uint16 winding, byte textColor);
- int setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor);
- void setBalloonText(uint id, char *text, byte textColor);
+ int setDialogueBalloon(char *text, uint16 winding, TextColor textColor);
+ int setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, TextColor textColor);
+ void setBalloonText(uint id, char *text, TextColor textColor);
int hitTestDialogueBalloon(int x, int y);
};
@@ -585,12 +589,12 @@ Graphics::Surface *BalloonManager_br::expandBalloon(Frames *data, int frameNum)
Graphics::Surface *surf = new Graphics::Surface;
surf->create(rect.width(), rect.height(), 1);
- _gfx->unpackBlt(rect, data->getData(frameNum), data->getRawSize(frameNum), surf, 0, BALLOON_TRANSPARENT_COLOR_BR);
+ _gfx->unpackBlt(rect, data->getData(frameNum), data->getRawSize(frameNum), surf, LAYER_FOREGROUND, 100, BALLOON_TRANSPARENT_COLOR_BR);
return surf;
}
-int BalloonManager_br::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor) {
+int BalloonManager_br::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, TextColor textColor) {
cacheAnims();
int id = _numBalloons;
@@ -613,7 +617,7 @@ int BalloonManager_br::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 w
balloon->surface = expandBalloon(src, srcFrame);
src->getRect(srcFrame, balloon->box);
- _writer.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface);
+ _writer.write(text, 216, _textColors[textColor], balloon->surface);
// TODO: extract some text to make a name for obj
balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
@@ -626,7 +630,7 @@ int BalloonManager_br::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 w
return id;
}
-int BalloonManager_br::setDialogueBalloon(char *text, uint16 winding, byte textColor) {
+int BalloonManager_br::setDialogueBalloon(char *text, uint16 winding, TextColor textColor) {
cacheAnims();
int id = _numBalloons;
@@ -637,11 +641,11 @@ int BalloonManager_br::setDialogueBalloon(char *text, uint16 winding, byte textC
if (winding == 0) {
src = _rightBalloon;
- srcFrame = id;
+ srcFrame = 0;
} else
if (winding == 1) {
src = _leftBalloon;
- srcFrame = 0;
+ srcFrame = id;
}
assert(src);
@@ -649,7 +653,7 @@ int BalloonManager_br::setDialogueBalloon(char *text, uint16 winding, byte textC
balloon->surface = expandBalloon(src, srcFrame);
src->getRect(srcFrame, balloon->box);
- _writer.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface);
+ _writer.write(text, 216, _textColors[textColor], balloon->surface);
// TODO: extract some text to make a name for obj
balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
@@ -657,32 +661,51 @@ int BalloonManager_br::setDialogueBalloon(char *text, uint16 winding, byte textC
balloon->obj->y = balloon->box.top;
balloon->obj->transparentKey = BALLOON_TRANSPARENT_COLOR_BR;
- if (id > 0) {
- balloon->obj->y += _intBalloons[id - 1].obj->y + _intBalloons[id - 1].box.height();
- }
-
_numBalloons++;
return id;
}
-void BalloonManager_br::setBalloonText(uint id, char *text, byte textColor) { }
+void BalloonManager_br::setBalloonText(uint id, char *text, TextColor textColor) {
+ Balloon *balloon = getBalloon(id);
+
+ StringWriter_BR sw(_vm->_dialogueFont);
+ sw.write(text, 216, _textColors[textColor], balloon->surface);
+}
+
+int BalloonManager_br::createBalloon(int16 w, int16 h, uint16 borderThickness) {
+ assert(_numBalloons < 5);
+
+ int id = _numBalloons;
+ Balloon *balloon = &_intBalloons[id];
+
+ balloon->surface = new Graphics::Surface;
+ balloon->surface->create(w, h, 1);
+
+ Common::Rect rect(w, h);
+ balloon->surface->fillRect(rect, 1);
+ rect.grow(-borderThickness);
+ balloon->surface->fillRect(rect, 15);
+
+ _numBalloons++;
+
+ return id;
+}
int BalloonManager_br::setLocationBalloon(char *text, bool endGame) {
-/*
- int16 w, h;
+ StringExtent_BR se(_vm->_dialogueFont);
- getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h);
+ se.calc(text, 240);
- int id = createBalloon(w+(endGame ? 5 : 10), h+5, -1, BALLOON_TRANSPARENT_COLOR);
+ int id = createBalloon(se.width() + 20, se.height() + 30, 2);
Balloon *balloon = &_intBalloons[id];
- drawWrappedText(_vm->_dialogueFont, balloon->surface, text, 0, MAX_BALLOON_WIDTH);
- // TODO: extract some text to make a name for obj
+ _writer.write(text, 240, kNormalColor, balloon->surface);
+
balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
balloon->obj->x = 5;
balloon->obj->y = 5;
-*/
+
return 0;
}
@@ -691,11 +714,9 @@ int BalloonManager_br::hitTestDialogueBalloon(int x, int y) {
Common::Point p;
for (uint i = 0; i < _numBalloons; i++) {
- p.x = x - _intBalloons[i].obj->x;
- p.y = y - _intBalloons[i].obj->y;
-
- if (_intBalloons[i].box.contains(p))
+ if (_intBalloons[i].box.contains(x, y)) {
return i;
+ }
}
return -1;
@@ -723,6 +744,10 @@ void BalloonManager_br::cacheAnims() {
BalloonManager_br::BalloonManager_br(Disk *disk, Gfx *gfx) : _numBalloons(0), _disk(disk), _gfx(gfx),
_leftBalloon(0), _rightBalloon(0), _writer(_vm->_dialogueFont) {
+
+ _textColors[kSelectedColor] = 12;
+ _textColors[kUnselectedColor] = 0;
+ _textColors[kNormalColor] = 0;
}
BalloonManager_br::~BalloonManager_br() {
diff --git a/engines/parallaction/callables_ns.cpp b/engines/parallaction/callables_ns.cpp
index 0f89ca22d1..7915daa0b8 100644
--- a/engines/parallaction/callables_ns.cpp
+++ b/engines/parallaction/callables_ns.cpp
@@ -32,6 +32,7 @@
#include "parallaction/input.h"
#include "parallaction/parallaction.h"
+#include "parallaction/saveload.h"
#include "parallaction/sound.h"
@@ -170,7 +171,7 @@ void Parallaction_ns::_c_fade(void *parm) {
_gfx->setPalette(pal);
_gfx->updateScreen();
- g_system->delayMillis(20);
+ _vm->_system->delayMillis(20);
}
return;
@@ -305,7 +306,7 @@ void Parallaction_ns::_c_endComment(void *param) {
_gfx->setPalette(_gfx->_palette);
_gfx->updateScreen();
- g_system->delayMillis(20);
+ _vm->_system->delayMillis(20);
}
_input->waitForButtonEvent(kMouseLeftUp);
@@ -324,10 +325,10 @@ void Parallaction_ns::_c_frankenstein(void *parm) {
}
for (uint16 _di = 0; _di < 30; _di++) {
- g_system->delayMillis(20);
+ _vm->_system->delayMillis(20);
_gfx->setPalette(pal0);
_gfx->updateScreen();
- g_system->delayMillis(20);
+ _vm->_system->delayMillis(20);
_gfx->setPalette(pal1);
_gfx->updateScreen();
}
@@ -341,7 +342,7 @@ void Parallaction_ns::_c_frankenstein(void *parm) {
void Parallaction_ns::_c_finito(void *parm) {
- setPartComplete(_char);
+ _saveLoad->setPartComplete(_char.getBaseName());
cleanInventory();
cleanupGame();
diff --git a/engines/parallaction/detection.cpp b/engines/parallaction/detection.cpp
index 472fe1fd75..bde4f7f6d6 100644
--- a/engines/parallaction/detection.cpp
+++ b/engines/parallaction/detection.cpp
@@ -289,7 +289,7 @@ SaveStateList ParallactionMetaEngine::listSaves(const char *target) const {
for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
// Obtain the last 2 digits of the filename, since they correspond to the save slot
int slotNum = atoi(file->c_str() + file->size() - 2);
-
+
if (slotNum >= 0 && slotNum <= 99) {
Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
if (in) {
diff --git a/engines/parallaction/dialogue.cpp b/engines/parallaction/dialogue.cpp
index c94db751e7..a2de3cbbf3 100644
--- a/engines/parallaction/dialogue.cpp
+++ b/engines/parallaction/dialogue.cpp
@@ -173,7 +173,7 @@ bool DialogueManager::displayAnswer(uint16 i) {
// display suitable answers
if (((a->_yesFlags & flags) == a->_yesFlags) && ((a->_noFlags & ~flags) == a->_noFlags)) {
- int id = _vm->_balloonMan->setDialogueBalloon(a->_text, 1, 3);
+ int id = _vm->_balloonMan->setDialogueBalloon(a->_text, 1, BalloonManager::kUnselectedColor);
assert(id >= 0);
_visAnswers[id] = i;
@@ -203,7 +203,7 @@ bool DialogueManager::displayAnswers() {
if (_numVisAnswers == 1) {
int id = _vm->_gfx->setItem(_answerer, _ballonPos._answerChar.x, _ballonPos._answerChar.y);
_vm->_gfx->setItemFrame(id, _q->_answers[0]->_mood & 0xF);
- _vm->_balloonMan->setBalloonText(0, _q->_answers[_visAnswers[0]]->_text, 0);
+ _vm->_balloonMan->setBalloonText(0, _q->_answers[_visAnswers[0]]->_text, BalloonManager::kNormalColor);
} else
if (_numVisAnswers > 1) {
int id = _vm->_gfx->setItem(_answerer, _ballonPos._answerChar.x, _ballonPos._answerChar.y);
@@ -218,7 +218,7 @@ bool DialogueManager::displayAnswers() {
bool DialogueManager::displayQuestion() {
if (!scumm_stricmp(_q->_text, "NULL")) return false;
- _vm->_balloonMan->setSingleBalloon(_q->_text, _ballonPos._questionBalloon.x, _ballonPos._questionBalloon.y, _q->_mood & 0x10, 0);
+ _vm->_balloonMan->setSingleBalloon(_q->_text, _ballonPos._questionBalloon.x, _ballonPos._questionBalloon.y, _q->_mood & 0x10, BalloonManager::kNormalColor);
int id = _vm->_gfx->setItem(_questioner, _ballonPos._questionChar.x, _ballonPos._questionChar.y);
_vm->_gfx->setItemFrame(id, _q->_mood & 0xF);
@@ -256,7 +256,7 @@ int16 DialogueManager::askPassword() {
}
if (_passwordChanged) {
- _vm->_balloonMan->setBalloonText(0, _q->_answers[0]->_text, 3);
+ _vm->_balloonMan->setBalloonText(0, _q->_answers[0]->_text, BalloonManager::kNormalColor);
_passwordChanged = false;
}
@@ -286,14 +286,11 @@ int16 DialogueManager::selectAnswerN() {
if (_selection != _oldSelection) {
if (_oldSelection != -1) {
- _vm->_balloonMan->setBalloonText(_oldSelection, _q->_answers[_visAnswers[_oldSelection]]->_text, 3);
+ _vm->_balloonMan->setBalloonText(_oldSelection, _q->_answers[_visAnswers[_oldSelection]]->_text, BalloonManager::kUnselectedColor);
}
- if (_vm->quit())
- return -1;
-
if (_selection != -1) {
- _vm->_balloonMan->setBalloonText(_selection, _q->_answers[_visAnswers[_selection]]->_text, 0);
+ _vm->_balloonMan->setBalloonText(_selection, _q->_answers[_visAnswers[_selection]]->_text, BalloonManager::kSelectedColor);
_vm->_gfx->setItemFrame(0, _q->_answers[_visAnswers[_selection]]->_mood & 0xF);
}
}
@@ -365,6 +362,7 @@ void DialogueManager::nextQuestion() {
}
}
+
void DialogueManager::run() {
// cache event data
diff --git a/engines/parallaction/disk.h b/engines/parallaction/disk.h
index 2923f239d4..45a2b9d2ef 100644
--- a/engines/parallaction/disk.h
+++ b/engines/parallaction/disk.h
@@ -29,10 +29,12 @@
#define PATH_LEN 200
#include "common/fs.h"
-
#include "common/file.h"
+
#include "graphics/surface.h"
+#include "parallaction/graphics.h"
+
namespace Parallaction {
class Table;
diff --git a/engines/parallaction/exec_br.cpp b/engines/parallaction/exec_br.cpp
index fe7b1b2903..bcc4a5b532 100644
--- a/engines/parallaction/exec_br.cpp
+++ b/engines/parallaction/exec_br.cpp
@@ -546,27 +546,4 @@ ProgramExec_br::ProgramExec_br(Parallaction_br *vm) : ProgramExec_ns(vm), _vm(vm
ProgramExec_br::~ProgramExec_br() {
}
-#if 0
-void Parallaction_br::jobWaitRemoveLabelJob(void *parm, Job *job) {
-
-}
-
-void Parallaction_br::jobPauseSfx(void *parm, Job *job) {
-
-}
-
-
-void Parallaction_br::jobStopFollower(void *parm, Job *job) {
-
-}
-
-
-void Parallaction_br::jobScroll(void *parm, Job *job) {
-
-}
-#endif
-
-
-
-
} // namespace Parallaction
diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp
index 30790a346f..2ce50f498e 100644
--- a/engines/parallaction/exec_ns.cpp
+++ b/engines/parallaction/exec_ns.cpp
@@ -247,32 +247,6 @@ DECLARE_COMMAND_OPCODE(close) {
_vm->updateDoor(_ctxt.cmd->u._zone, true);
}
-void Parallaction::showZone(ZonePtr z, bool visible) {
- if (!z) {
- return;
- }
-
- if (visible) {
- z->_flags &= ~kFlagsRemove;
- z->_flags |= kFlagsActive;
- } else {
- z->_flags |= kFlagsRemove;
- }
-
- if ((z->_type & 0xFFFF) == kZoneGet) {
- _gfx->showGfxObj(z->u.get->gfxobj, visible);
-
- GetData *data = z->u.get;
- if (data->hasMask && _gfx->_backgroundInfo->hasMask) {
- if (visible) {
- _gfx->_backgroundInfo->mask.bltOr(data->gfxobj->x, data->gfxobj->y, data->_mask[0], 0, 0, data->_mask->w, data->_mask->h);
- } else {
- _gfx->_backgroundInfo->mask.bltCopy(data->gfxobj->x, data->gfxobj->y, data->_mask[1], 0, 0, data->_mask->w, data->_mask->h);
- }
- }
- }
-}
-
DECLARE_COMMAND_OPCODE(on) {
_vm->showZone(_ctxt.cmd->u._zone, true);
}
@@ -319,66 +293,6 @@ DECLARE_COMMAND_OPCODE(stop) {
}
-void Parallaction_ns::drawAnimations() {
- debugC(9, kDebugExec, "Parallaction_ns::drawAnimations()\n");
-
- uint16 layer = 0;
-
- for (AnimationList::iterator it = _location._animations.begin(); it != _location._animations.end(); it++) {
-
- AnimationPtr anim = *it;
- GfxObj *obj = anim->gfxobj;
-
- // Validation is performed here, so that every animation is affected, instead that only the ones
- // who *own* a script. In fact, some scripts can change values in other animations.
- // The right way to do this would be to enforce validation when any variable is modified from
- // a script.
- anim->validateScriptVars();
-
- if ((anim->_flags & kFlagsActive) && ((anim->_flags & kFlagsRemove) == 0)) {
-
- if (anim->_flags & kFlagsNoMasked)
- layer = LAYER_FOREGROUND;
- else {
- if (getGameType() == GType_Nippon) {
- // Layer in NS depends on where the animation is on the screen, for each animation.
- layer = _gfx->_backgroundInfo->getLayer(anim->getFrameY() + anim->height());
- } else {
- // Layer in BRA is calculated from Z value. For characters it is the same as NS,
- // but other animations can have Z set from scripts independently from their
- // position on the screen.
- layer = _gfx->_backgroundInfo->getLayer(anim->getZ());
- }
- }
-
- if (obj) {
- _gfx->showGfxObj(obj, true);
- obj->frame = anim->getF();
- obj->x = anim->getX();
- obj->y = anim->getY();
- obj->z = anim->getZ();
- obj->layer = layer;
- }
- }
-
- if (((anim->_flags & kFlagsActive) == 0) && (anim->_flags & kFlagsRemove)) {
- anim->_flags &= ~kFlagsRemove;
- }
-
- if ((anim->_flags & kFlagsActive) && (anim->_flags & kFlagsRemove)) {
- anim->_flags &= ~kFlagsActive;
- anim->_flags |= kFlagsRemove;
- if (obj) {
- _gfx->showGfxObj(obj, false);
- }
- }
- }
-
- debugC(9, kDebugExec, "Parallaction_ns::drawAnimations done()\n");
-
- return;
-}
-
void ProgramExec::runScript(ProgramPtr script, AnimationPtr a) {
debugC(9, kDebugExec, "runScript(Animation = %s)", a->_name);
@@ -443,15 +357,11 @@ void CommandExec::runList(CommandList::iterator first, CommandList::iterator las
_ctxt.suspend = false;
for ( ; first != last; first++) {
-
if (_vm->quit())
break;
CommandPtr cmd = *first;
- if (_vm->quit())
- break;
-
if (cmd->_flagsOn & kFlagsGlobal) {
useFlags = _globalFlags | kFlagsGlobal;
useLocalFlags = false;
@@ -537,239 +447,6 @@ CommandExec_ns::~CommandExec_ns() {
}
-//
-// ZONE TYPE: EXAMINE
-//
-
-void Parallaction::enterCommentMode(ZonePtr z) {
- if (!z) {
- return;
- }
-
- _commentZone = z;
-
- ExamineData *data = _commentZone->u.examine;
-
- if (!data->_description) {
- return;
- }
-
- // TODO: move this balloons stuff into DialogueManager and BalloonManager
- if (getGameType() == GType_Nippon) {
- int id;
- if (data->_filename) {
- if (data->_cnv == 0) {
- data->_cnv = _disk->loadStatic(data->_filename);
- }
-
- _gfx->setHalfbriteMode(true);
- _balloonMan->setSingleBalloon(data->_description, 0, 90, 0, 0);
- Common::Rect r;
- data->_cnv->getRect(0, r);
- id = _gfx->setItem(data->_cnv, 140, (_screenHeight - r.height())/2);
- _gfx->setItemFrame(id, 0);
- id = _gfx->setItem(_char._head, 100, 152);
- _gfx->setItemFrame(id, 0);
- } else {
- _balloonMan->setSingleBalloon(data->_description, 140, 10, 0, 0);
- id = _gfx->setItem(_char._talk, 190, 80);
- _gfx->setItemFrame(id, 0);
- }
- } else
- if (getGameType() == GType_BRA) {
- _balloonMan->setSingleBalloon(data->_description, 0, 0, 1, 0);
- int id = _gfx->setItem(_char._talk, 10, 80);
- _gfx->setItemFrame(id, 0);
- }
-
- _input->_inputMode = Input::kInputModeComment;
-}
-
-void Parallaction::exitCommentMode() {
- _input->_inputMode = Input::kInputModeGame;
-
- hideDialogueStuff();
- _gfx->setHalfbriteMode(false);
-
- _cmdExec->run(_commentZone->_commands, _commentZone);
- _commentZone = nullZonePtr;
-}
-
-void Parallaction::runCommentFrame() {
- if (_input->_inputMode != Input::kInputModeComment) {
- return;
- }
-
- if (_input->getLastButtonEvent() == kMouseLeftUp) {
- exitCommentMode();
- }
-}
-
-
-void Parallaction::runZone(ZonePtr z) {
- debugC(3, kDebugExec, "runZone (%s)", z->_name);
-
- uint16 subtype = z->_type & 0xFFFF;
-
- debugC(3, kDebugExec, "type = %x, object = %x", subtype, (z->_type & 0xFFFF0000) >> 16);
- switch(subtype) {
-
- case kZoneExamine:
- enterCommentMode(z);
- return;
-
- case kZoneGet:
- pickupItem(z);
- break;
-
- case kZoneDoor:
- if (z->_flags & kFlagsLocked) break;
- updateDoor(z, !(z->_flags & kFlagsClosed));
- break;
-
- case kZoneHear:
- _soundMan->playSfx(z->u.hear->_name, z->u.hear->_channel, (z->_flags & kFlagsLooping) == kFlagsLooping);
- break;
-
- case kZoneSpeak:
- enterDialogueMode(z);
- return;
- }
-
- debugC(3, kDebugExec, "runZone completed");
-
- _cmdExec->run(z->_commands, z);
-
- return;
-}
-
-//
-// ZONE TYPE: DOOR
-//
-void Parallaction::updateDoor(ZonePtr z, bool close) {
- z->_flags = close ? (z->_flags |= kFlagsClosed) : (z->_flags &= ~kFlagsClosed);
-
- if (z->u.door->gfxobj) {
- uint frame = (close ? 0 : 1);
-// z->u.door->gfxobj->setFrame(frame);
- z->u.door->gfxobj->frame = frame;
- }
-
- return;
-}
-
-
-
-//
-// ZONE TYPE: GET
-//
-
-bool Parallaction::pickupItem(ZonePtr z) {
- if (z->_flags & kFlagsFixed) {
- return false;
- }
-
- int slot = addInventoryItem(z->u.get->_icon);
- if (slot != -1) {
- showZone(z, false);
- }
-
- return (slot != -1);
-}
-
-
-
-ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) {
-// printf("hitZone(%i, %i, %i)", type, x, y);
-
- uint16 _di = y;
- uint16 _si = x;
-
- for (ZoneList::iterator it = _location._zones.begin(); it != _location._zones.end(); it++) {
-// printf("Zone name: %s", z->_name);
-
- ZonePtr z = *it;
-
- if (z->_flags & kFlagsRemove) continue;
-
- Common::Rect r;
- z->getBox(r);
- r.right++; // adjust border because Common::Rect doesn't include bottom-right edge
- r.bottom++;
-
- r.grow(-1); // allows some tolerance for mouse click
-
- if (!r.contains(_si, _di)) {
-
- // out of Zone, so look for special values
- if ((z->getX() == -2) || (z->getX() == -3)) {
-
- // WORKAROUND: this huge condition is needed because we made TypeData a collection of structs
- // instead of an union. So, merge->_obj1 and get->_icon were just aliases in the original engine,
- // but we need to check it separately here. The same workaround is applied in freeZones.
- if ((((z->_type & 0xFFFF) == kZoneMerge) && (((_si == z->u.merge->_obj1) && (_di == z->u.merge->_obj2)) || ((_si == z->u.merge->_obj2) && (_di == z->u.merge->_obj1)))) ||
- (((z->_type & 0xFFFF) == kZoneGet) && ((_si == z->u.get->_icon) || (_di == z->u.get->_icon)))) {
-
- // special Zone
- if ((type == 0) && ((z->_type & 0xFFFF0000) == 0))
- return z;
- if (z->_type == type)
- return z;
- if ((z->_type & 0xFFFF0000) == type)
- return z;
-
- }
- }
-
- if (z->getX() != -1)
- continue;
- if (_si < _char._ani->getFrameX())
- continue;
- if (_si > (_char._ani->getFrameX() + _char._ani->width()))
- continue;
- if (_di < _char._ani->getFrameY())
- continue;
- if (_di > (_char._ani->getFrameY() + _char._ani->height()))
- continue;
-
- }
-
- // normal Zone
- if ((type == 0) && ((z->_type & 0xFFFF0000) == 0))
- return z;
- if (z->_type == type)
- return z;
- if ((z->_type & 0xFFFF0000) == type)
- return z;
-
- }
-
-
- int16 _a, _b, _c, _d, _e, _f;
- for (AnimationList::iterator ait = _location._animations.begin(); ait != _location._animations.end(); ait++) {
-
- AnimationPtr a = *ait;
-
- _a = (a->_flags & kFlagsActive) ? 1 : 0; // _a: active Animation
- _e = ((_si >= a->getFrameX() + a->width()) || (_si <= a->getFrameX())) ? 0 : 1; // _e: horizontal range
- _f = ((_di >= a->getFrameY() + a->height()) || (_di <= a->getFrameY())) ? 0 : 1; // _f: vertical range
-
- _b = ((type != 0) || (a->_type == kZoneYou)) ? 0 : 1; // _b: (no type specified) AND (Animation is not the character)
- _c = (a->_type & 0xFFFF0000) ? 0 : 1; // _c: Animation is not an object
- _d = ((a->_type & 0xFFFF0000) != type) ? 0 : 1; // _d: Animation is an object of the same type
-
- if ((_a != 0 && _e != 0 && _f != 0) && ((_b != 0 && _c != 0) || (a->_type == type) || (_d != 0))) {
-
- return a;
-
- }
-
- }
-
- return nullZonePtr;
-}
-
-
void CommandExec_ns::init() {
Common::Array<const Opcode*> *table = 0;
diff --git a/engines/parallaction/gfxbase.cpp b/engines/parallaction/gfxbase.cpp
index 1c373dda44..8eb9753edd 100644
--- a/engines/parallaction/gfxbase.cpp
+++ b/engines/parallaction/gfxbase.cpp
@@ -32,7 +32,7 @@
namespace Parallaction {
-GfxObj::GfxObj(uint objType, Frames *frames, const char* name) : _frames(frames), _keep(true), x(0), y(0), z(0), _flags(kGfxObjNormal), type(objType), frame(0), layer(3) {
+GfxObj::GfxObj(uint objType, Frames *frames, const char* name) : _frames(frames), _keep(true), x(0), y(0), z(0), _flags(kGfxObjNormal), type(objType), frame(0), layer(3), scale(100) {
if (name) {
_name = strdup(name);
} else {
@@ -180,9 +180,9 @@ void Gfx::drawGfxObject(GfxObj *obj, Graphics::Surface &surf, bool scene) {
data = obj->getData(obj->frame);
if (obj->getSize(obj->frame) == obj->getRawSize(obj->frame)) {
- blt(rect, data, &surf, obj->layer, obj->transparentKey);
+ blt(rect, data, &surf, obj->layer, obj->scale, obj->transparentKey);
} else {
- unpackBlt(rect, data, obj->getRawSize(obj->frame), &surf, obj->layer, obj->transparentKey);
+ unpackBlt(rect, data, obj->getRawSize(obj->frame), &surf, obj->layer, obj->scale, obj->transparentKey);
}
}
@@ -233,7 +233,7 @@ void Gfx::unpackBlt(const Common::Rect& r, byte *data, uint size, Graphics::Surf
blt(r, _unpackedBitmap, surf, z, transparentColor);
}
#endif
-void Gfx::unpackBlt(const Common::Rect& r, byte *data, uint size, Graphics::Surface *surf, uint16 z, byte transparentColor) {
+void Gfx::unpackBlt(const Common::Rect& r, byte *data, uint size, Graphics::Surface *surf, uint16 z, uint scale, byte transparentColor) {
byte *d = _unpackedBitmap;
uint pixelsLeftInLine = r.width();
@@ -259,11 +259,154 @@ void Gfx::unpackBlt(const Common::Rect& r, byte *data, uint size, Graphics::Surf
d += repeat;
}
- blt(r, _unpackedBitmap, surf, z, transparentColor);
+ blt(r, _unpackedBitmap, surf, z, scale, transparentColor);
}
-void Gfx::blt(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, byte transparentColor) {
+void Gfx::bltMaskScale(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, uint scale, byte transparentColor) {
+ if (scale == 100) {
+ // use optimized path
+ bltMaskNoScale(r, data, surf, z, transparentColor);
+ return;
+ }
+
+ Common::Rect q(r);
+ Common::Rect clipper(surf->w, surf->h);
+ q.clip(clipper);
+ if (!q.isValidRect()) return;
+
+ uint inc = r.width() * (100 - scale);
+ uint thr = r.width() * 100;
+ uint xAccum = 0, yAccum = 0;
+
+ Common::Point dp;
+ dp.x = q.left + (r.width() * (100 - scale)) / 200;
+ dp.y = q.top + (r.height() * (100 - scale)) / 100;
+ q.translate(-r.left, -r.top);
+ byte *s = data + q.left + q.top * r.width();
+ byte *d = (byte*)surf->getBasePtr(dp.x, dp.y);
+
+ uint line = 0, col = 0;
+
+ for (uint16 i = 0; i < q.height(); i++) {
+ yAccum += inc;
+
+ if (yAccum >= thr) {
+ yAccum -= thr;
+ s += r.width();
+ continue;
+ }
+
+ xAccum = 0;
+ byte *d2 = d;
+ col = 0;
+
+ for (uint16 j = 0; j < q.width(); j++) {
+ xAccum += inc;
+
+ if (xAccum >= thr) {
+ xAccum -= thr;
+ s++;
+ continue;
+ }
+
+ if (*s != transparentColor) {
+ byte v = _backgroundInfo->mask.getValue(dp.x + col, dp.y + line);
+ if (z >= v) *d2 = *s;
+ }
+
+ s++;
+ d2++;
+ col++;
+ }
+
+ s += r.width() - q.width();
+ d += surf->w;
+ line++;
+ }
+
+}
+
+void Gfx::bltMaskNoScale(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, byte transparentColor) {
+ if (!_backgroundInfo->mask.data || (z == LAYER_FOREGROUND)) {
+ // use optimized path
+ bltNoMaskNoScale(r, data, surf, transparentColor);
+ return;
+ }
+
+ Common::Point dp;
+ Common::Rect q(r);
+
+ Common::Rect clipper(surf->w, surf->h);
+
+ q.clip(clipper);
+ if (!q.isValidRect()) return;
+
+ dp.x = q.left;
+ dp.y = q.top;
+
+ q.translate(-r.left, -r.top);
+
+ byte *s = data + q.left + q.top * r.width();
+ byte *d = (byte*)surf->getBasePtr(dp.x, dp.y);
+
+ uint sPitch = r.width() - q.width();
+ uint dPitch = surf->w - q.width();
+
+ for (uint16 i = 0; i < q.height(); i++) {
+
+ for (uint16 j = 0; j < q.width(); j++) {
+ if (*s != transparentColor) {
+ byte v = _backgroundInfo->mask.getValue(dp.x + j, dp.y + i);
+ if (z >= v) *d = *s;
+ }
+
+ s++;
+ d++;
+ }
+
+ s += sPitch;
+ d += dPitch;
+ }
+
+}
+
+void Gfx::bltNoMaskNoScale(const Common::Rect& r, byte *data, Graphics::Surface *surf, byte transparentColor) {
+ Common::Point dp;
+ Common::Rect q(r);
+
+ Common::Rect clipper(surf->w, surf->h);
+
+ q.clip(clipper);
+ if (!q.isValidRect()) return;
+
+ dp.x = q.left;
+ dp.y = q.top;
+
+ q.translate(-r.left, -r.top);
+
+ byte *s = data + q.left + q.top * r.width();
+ byte *d = (byte*)surf->getBasePtr(dp.x, dp.y);
+
+ uint sPitch = r.width() - q.width();
+ uint dPitch = surf->w - q.width();
+
+ for (uint16 i = q.top; i < q.bottom; i++) {
+ for (uint16 j = q.left; j < q.right; j++) {
+ if (*s != transparentColor)
+ *d = *s;
+
+ s++;
+ d++;
+ }
+
+ s += sPitch;
+ d += dPitch;
+ }
+}
+
+
+void Gfx::blt(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, uint scale, byte transparentColor) {
Common::Point dp;
Common::Rect q(r);
@@ -308,40 +451,7 @@ void Gfx::blt(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16
}
} else {
- if (_backgroundInfo->mask.data && (z < LAYER_FOREGROUND)) {
-
- for (uint16 i = 0; i < q.height(); i++) {
-
- for (uint16 j = 0; j < q.width(); j++) {
- if (*s != transparentColor) {
- byte v = _backgroundInfo->mask.getValue(dp.x + j, dp.y + i);
- if (z >= v) *d = *s;
- }
-
- s++;
- d++;
- }
-
- s += sPitch;
- d += dPitch;
- }
-
- } else {
-
- for (uint16 i = q.top; i < q.bottom; i++) {
- for (uint16 j = q.left; j < q.right; j++) {
- if (*s != transparentColor)
- *d = *s;
-
- s++;
- d++;
- }
-
- s += sPitch;
- d += dPitch;
- }
-
- }
+ bltMaskScale(r, data, surf, z, scale, transparentColor);
}
}
diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp
index 1c2cb58b5b..2bd3935f01 100644
--- a/engines/parallaction/graphics.cpp
+++ b/engines/parallaction/graphics.cpp
@@ -34,8 +34,9 @@
namespace Parallaction {
// this is the size of the receiving buffer for unpacked frames,
-// since BRA uses some insanely big animations.
-#define MAXIMUM_UNPACKED_BITMAP_SIZE 640*401
+// since BRA uses some insanely big animations (the largest is
+// part0/ani/dino.ani).
+#define MAXIMUM_UNPACKED_BITMAP_SIZE 641*401
void Gfx::registerVar(const Common::String &name, int32 initialValue) {
@@ -251,7 +252,7 @@ void Gfx::setPalette(Palette pal) {
byte sysPal[256*4];
uint n = pal.fillRGBA(sysPal);
- g_system->setPalette(sysPal, 0, n);
+ _vm->_system->setPalette(sysPal, 0, n);
}
void Gfx::setBlackPalette() {
@@ -327,7 +328,7 @@ void Gfx::drawInventory() {
_vm->_inventoryRenderer->getRect(r);
byte *data = _vm->_inventoryRenderer->getData();
- g_system->copyRectToScreen(data, r.width(), r.left, r.top, r.width(), r.height());
+ _vm->_system->copyRectToScreen(data, r.width(), r.left, r.top, r.width(), r.height());
}
void Gfx::drawItems() {
@@ -335,11 +336,11 @@ void Gfx::drawItems() {
return;
}
- Graphics::Surface *surf = g_system->lockScreen();
+ Graphics::Surface *surf = _vm->_system->lockScreen();
for (uint i = 0; i < _numItems; i++) {
drawGfxObject(_items[i].data, *surf, false);
}
- g_system->unlockScreen();
+ _vm->_system->unlockScreen();
}
void Gfx::drawBalloons() {
@@ -347,15 +348,15 @@ void Gfx::drawBalloons() {
return;
}
- Graphics::Surface *surf = g_system->lockScreen();
+ Graphics::Surface *surf = _vm->_system->lockScreen();
for (uint i = 0; i < _balloons.size(); i++) {
drawGfxObject(_balloons[i], *surf, false);
}
- g_system->unlockScreen();
+ _vm->_system->unlockScreen();
}
void Gfx::clearScreen() {
- g_system->clearScreen();
+ _vm->_system->clearScreen();
}
void Gfx::beginFrame() {
@@ -377,7 +378,7 @@ void Gfx::beginFrame() {
*data++ = _backgroundInfo->mask.getValue(x, y);
}
}
-#if 1
+#if 0
Common::DumpFile dump;
dump.open("maskdump.bin");
dump.write(_bitmapMask.pixels, _bitmapMask.w * _bitmapMask.h);
@@ -437,11 +438,11 @@ void Gfx::updateScreen() {
backgroundPitch = _bitmapMask.pitch;
break;
}
- g_system->copyRectToScreen(backgroundData, backgroundPitch, _backgroundInfo->x, _backgroundInfo->y, w, h);
+ _vm->_system->copyRectToScreen(backgroundData, backgroundPitch, _backgroundInfo->x, _backgroundInfo->y, w, h);
}
if (_varDrawPathZones == 1) {
- Graphics::Surface *surf = g_system->lockScreen();
+ Graphics::Surface *surf = _vm->_system->lockScreen();
ZoneList::iterator b = _vm->_location._zones.begin();
ZoneList::iterator e = _vm->_location._zones.end();
for (; b != e; b++) {
@@ -450,13 +451,13 @@ void Gfx::updateScreen() {
surf->frameRect(Common::Rect(z->getX(), z->getY(), z->getX() + z->width(), z->getY() + z->height()), 2);
}
}
- g_system->unlockScreen();
+ _vm->_system->unlockScreen();
}
_varRenderMode = _varAnimRenderMode;
// TODO: transform objects coordinates to be drawn with scrolling
- Graphics::Surface *surf = g_system->lockScreen();
+ Graphics::Surface *surf = _vm->_system->lockScreen();
drawGfxObjects(*surf);
if (_halfbrite) {
@@ -480,7 +481,7 @@ void Gfx::updateScreen() {
}
}
- g_system->unlockScreen();
+ _vm->_system->unlockScreen();
_varRenderMode = _varMiscRenderMode;
@@ -489,7 +490,7 @@ void Gfx::updateScreen() {
drawBalloons();
drawLabels();
- g_system->updateScreen();
+ _vm->_system->updateScreen();
return;
}
@@ -506,7 +507,7 @@ void Gfx::patchBackground(Graphics::Surface &surf, int16 x, int16 y, bool mask)
r.moveTo(x, y);
uint16 z = (mask) ? _backgroundInfo->getLayer(y) : LAYER_FOREGROUND;
- blt(r, (byte*)surf.pixels, &_backgroundInfo->bg, z, 0);
+ blt(r, (byte*)surf.pixels, &_backgroundInfo->bg, z, 100, 0);
}
void Gfx::fillBackground(const Common::Rect& r, byte color) {
@@ -600,30 +601,41 @@ void Gfx::updateFloatingLabel() {
return;
}
- int16 _si, _di;
-
- Common::Point cursor;
- _vm->_input->getCursorPos(cursor);
+ struct FloatingLabelTraits {
+ Common::Point _offsetWithItem;
+ Common::Point _offsetWithoutItem;
+ int _minX;
+ int _minY;
+ int _maxX;
+ int _maxY;
+ } *traits;
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;
+ if (_vm->getGameType() == GType_Nippon) {
+ FloatingLabelTraits traits_NS = {
+ Common::Point(16 - r.width()/2, 34),
+ Common::Point(8 - r.width()/2, 21),
+ 0, 0, _vm->_screenWidth - r.width(), 190
+ };
+ traits = &traits_NS;
} else {
- _si = cursor.x + 8 - r.width()/2;
- _di = cursor.y + 21;
+ // FIXME: _maxY for BRA is not constant (390), but depends on _vm->_subtitleY
+ FloatingLabelTraits traits_BR = {
+ Common::Point(34 - r.width()/2, 70),
+ Common::Point(16 - r.width()/2, 37),
+ 0, 0, _vm->_screenWidth - r.width(), 390
+ };
+ traits = &traits_BR;
}
- if (_si < 0) _si = 0;
- if (_di > 190) _di = 190;
-
- if (r.width() + _si > _vm->_screenWidth)
- _si = _vm->_screenWidth - r.width();
+ Common::Point cursor;
+ _vm->_input->getCursorPos(cursor);
+ Common::Point offset = (_vm->_input->_activeItem._id) ? traits->_offsetWithItem : traits->_offsetWithoutItem;
- _labels[_floatingLabel]->x = _si;
- _labels[_floatingLabel]->y = _di;
+ _labels[_floatingLabel]->x = CLIP(cursor.x + offset.x, traits->_minX, traits->_maxX);
+ _labels[_floatingLabel]->y = CLIP(cursor.y + offset.y, traits->_minY, traits->_maxY);
}
@@ -703,13 +715,13 @@ void Gfx::drawLabels() {
updateFloatingLabel();
- Graphics::Surface* surf = g_system->lockScreen();
+ Graphics::Surface* surf = _vm->_system->lockScreen();
for (uint i = 0; i < _labels.size(); i++) {
drawGfxObject(_labels[i], *surf, false);
}
- g_system->unlockScreen();
+ _vm->_system->unlockScreen();
}
@@ -737,10 +749,10 @@ void Gfx::grabBackground(const Common::Rect& r, Graphics::Surface &dst) {
Gfx::Gfx(Parallaction* vm) :
_vm(vm), _disk(vm->_disk) {
- g_system->beginGFXTransaction();
- g_system->initSize(_vm->_screenWidth, _vm->_screenHeight);
+ _vm->_system->beginGFXTransaction();
+ _vm->_system->initSize(_vm->_screenWidth, _vm->_screenHeight);
_vm->initCommonGFX(_vm->getGameType() == GType_BRA);
- g_system->endGFXTransaction();
+ _vm->_system->endGFXTransaction();
setPalette(_palette);
diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h
index 471f71dfa8..ac9f096d7e 100644
--- a/engines/parallaction/graphics.h
+++ b/engines/parallaction/graphics.h
@@ -313,6 +313,7 @@ struct Cnv : public Frames {
uint16 _height; //
byte** field_8; // unused
byte* _data;
+ bool _freeData;
public:
Cnv() {
@@ -320,12 +321,14 @@ public:
_data = NULL;
}
- Cnv(uint16 numFrames, uint16 width, uint16 height, byte* data) : _count(numFrames), _width(width), _height(height), _data(data) {
+ Cnv(uint16 numFrames, uint16 width, uint16 height, byte* data, bool freeData = false)
+ : _count(numFrames), _width(width), _height(height), _data(data), _freeData(freeData) {
}
~Cnv() {
- free(_data);
+ if (_freeData)
+ free(_data);
}
byte* getFramePtr(uint16 index) {
@@ -410,6 +413,7 @@ public:
uint frame;
uint layer;
uint transparentKey;
+ uint scale;
GfxObj(uint type, Frames *frames, const char *name = NULL);
virtual ~GfxObj();
@@ -495,13 +499,19 @@ enum {
class BalloonManager {
public:
+ enum TextColor {
+ kSelectedColor = 0,
+ kUnselectedColor = 1,
+ kNormalColor = 2
+ };
+
virtual ~BalloonManager() { }
virtual void freeBalloons() = 0;
virtual int setLocationBalloon(char *text, bool endGame) = 0;
- virtual int setDialogueBalloon(char *text, uint16 winding, byte textColor) = 0;
- virtual int setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor) = 0;
- virtual void setBalloonText(uint id, char *text, byte textColor) = 0;
+ virtual int setDialogueBalloon(char *text, uint16 winding, TextColor textColor) = 0;
+ virtual int setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, TextColor textColor) = 0;
+ virtual void setBalloonText(uint id, char *text, TextColor textColor) = 0;
virtual int hitTestDialogueBalloon(int x, int y) = 0;
};
@@ -640,8 +650,12 @@ public:
void drawText(Font *font, Graphics::Surface* surf, uint16 x, uint16 y, const char *text, byte color);
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);
+ void blt(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, uint scale, byte transparentColor);
+ void unpackBlt(const Common::Rect& r, byte *data, uint size, Graphics::Surface *surf, uint16 z, uint scale, byte transparentColor);
+
+ void bltMaskScale(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, uint scale, byte transparentColor);
+ void bltMaskNoScale(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, byte transparentColor);
+ void bltNoMaskNoScale(const Common::Rect& r, byte *data, Graphics::Surface *surf, byte transparentColor);
};
diff --git a/engines/parallaction/gui_br.cpp b/engines/parallaction/gui_br.cpp
index 4343a982bf..b0beb5f953 100644
--- a/engines/parallaction/gui_br.cpp
+++ b/engines/parallaction/gui_br.cpp
@@ -28,6 +28,7 @@
#include "parallaction/gui.h"
#include "parallaction/input.h"
#include "parallaction/parallaction.h"
+#include "parallaction/saveload.h"
namespace Parallaction {
@@ -40,11 +41,11 @@ protected:
Palette blackPal;
Palette pal;
- Parallaction_br *_vm;
+ Parallaction *_vm;
int _fadeSteps;
public:
- SplashInputState_BR(Parallaction_br *vm, const Common::String &name, MenuInputHelper *helper) : MenuInputState(name, helper), _vm(vm) {
+ SplashInputState_BR(Parallaction *vm, const Common::String &name, MenuInputHelper *helper) : MenuInputState(name, helper), _vm(vm) {
}
virtual MenuInputState* run() {
@@ -52,8 +53,6 @@ public:
pal.fadeTo(blackPal, 1);
_vm->_gfx->setPalette(pal);
_fadeSteps--;
- // TODO: properly implement timers to avoid delay calls
- _vm->_system->delayMillis(20);
return this;
}
@@ -75,7 +74,7 @@ public:
_vm->showSlide(_slideName.c_str(), CENTER_LABEL_HORIZONTAL, CENTER_LABEL_VERTICAL);
_vm->_input->setMouseState(MOUSE_DISABLED);
- _startTime = g_system->getMillis();
+ _startTime = _vm->_system->getMillis();
_fadeSteps = -1;
}
};
@@ -152,6 +151,8 @@ class MainMenuInputState_BR : public MenuInputState {
static const char *_menuStrings[NUM_MENULINES];
static const MenuOptions _options[NUM_MENULINES];
+ static const char *_firstLocation[];
+
int _availItems;
int _selection;
@@ -167,16 +168,17 @@ class MainMenuInputState_BR : public MenuInputState {
void performChoice(int selectedItem) {
switch (selectedItem) {
case kMenuQuit: {
+ _vm->_quit = true;
_vm->quitGame();
- }
break;
+ }
case kMenuLoadGame:
warning("loadgame not yet implemented");
break;
default:
- _vm->startPart(selectedItem);
+ _vm->scheduleLocationSwitch(_firstLocation[selectedItem]);
}
}
@@ -221,9 +223,11 @@ public:
}
_vm->showSlide("tbra", x, y);
- // TODO: load progress from savefile
- int progress = 3;
- _availItems = 4 + progress;
+ _availItems = 4;
+
+ bool complete[3];
+ _vm->_saveLoad->getGamePartProgress(complete, 3);
+ for (int i = 0; i < 3 && complete[i]; i++, _availItems++) ;
// TODO: keep track of and destroy menu item frames/surfaces
int i;
@@ -233,12 +237,20 @@ public:
_vm->_gfx->setItemFrame(id, 0);
}
_selection = -1;
- _vm->setArrowCursor();
+ _vm->_input->setArrowCursor();
_vm->_input->setMouseState(MOUSE_ENABLED_SHOW);
}
};
+const char *MainMenuInputState_BR::_firstLocation[] = {
+ "intro.0",
+ "museo.1",
+ "start.2",
+ "bolscoi.3",
+ "treno.4"
+};
+
const char *MainMenuInputState_BR::_menuStrings[NUM_MENULINES] = {
"SEE INTRO",
"NEW GAME",
@@ -265,29 +277,24 @@ const MainMenuInputState_BR::MenuOptions MainMenuInputState_BR::_options[NUM_MEN
-void Parallaction_br::startGui() {
+void Parallaction_br::startGui(bool showSplash) {
_menuHelper = new MenuInputHelper;
- new SplashInputState0_BR(this, _menuHelper);
- new SplashInputState1_BR(this, _menuHelper);
- new MainMenuInputState_BR(this, _menuHelper);
-
- _menuHelper->setState("intro0");
- _input->_inputMode = Input::kInputModeMenu;
- do {
- _input->readInput();
- if (!_menuHelper->run()) break;
- _gfx->beginFrame();
- _gfx->updateScreen();
- } while (true);
+ new MainMenuInputState_BR(this, _menuHelper);
- delete _menuHelper;
- _menuHelper = 0;
+ if (showSplash) {
+ new SplashInputState0_BR(this, _menuHelper);
+ new SplashInputState1_BR(this, _menuHelper);
+ _menuHelper->setState("intro0");
+ } else {
+ _menuHelper->setState("mainmenu");
+ }
- _input->_inputMode = Input::kInputModeGame;
+ _input->_inputMode = Input::kInputModeMenu;
}
+
} // namespace Parallaction
diff --git a/engines/parallaction/gui_ns.cpp b/engines/parallaction/gui_ns.cpp
index e6f86a1a0a..73cc1be12e 100644
--- a/engines/parallaction/gui_ns.cpp
+++ b/engines/parallaction/gui_ns.cpp
@@ -23,13 +23,13 @@
*
*/
-#include "common/config-manager.h"
#include "common/system.h"
#include "common/hashmap.h"
#include "parallaction/gui.h"
#include "parallaction/input.h"
#include "parallaction/parallaction.h"
+#include "parallaction/saveload.h"
#include "parallaction/sound.h"
@@ -42,14 +42,14 @@ protected:
Common::String _nextState;
uint32 _startTime;
- Parallaction_ns *_vm;
+ Parallaction *_vm;
public:
- SplashInputState_NS(Parallaction_ns *vm, const Common::String &name, MenuInputHelper *helper) : MenuInputState(name, helper), _vm(vm) {
+ SplashInputState_NS(Parallaction *vm, const Common::String &name, MenuInputHelper *helper) : MenuInputState(name, helper), _vm(vm) {
}
virtual MenuInputState* run() {
- uint32 curTime = g_system->getMillis();
+ uint32 curTime = _vm->_system->getMillis();
if (curTime - _startTime > _timeOut) {
_vm->freeBackground();
return _helper->getState(_nextState);
@@ -60,14 +60,14 @@ public:
virtual void enter() {
_vm->_input->setMouseState(MOUSE_DISABLED);
_vm->showSlide(_slideName.c_str());
- _startTime = g_system->getMillis();
+ _startTime = _vm->_system->getMillis();
}
};
class SplashInputState0_NS : public SplashInputState_NS {
public:
- SplashInputState0_NS(Parallaction_ns *vm, MenuInputHelper *helper) : SplashInputState_NS(vm, "intro0", helper) {
+ SplashInputState0_NS(Parallaction *vm, MenuInputHelper *helper) : SplashInputState_NS(vm, "intro0", helper) {
_slideName = "intro";
_timeOut = 2000;
_nextState = "intro1";
@@ -77,7 +77,7 @@ public:
class SplashInputState1_NS : public SplashInputState_NS {
public:
- SplashInputState1_NS(Parallaction_ns *vm, MenuInputHelper *helper) : SplashInputState_NS(vm, "intro1", helper) {
+ SplashInputState1_NS(Parallaction *vm, MenuInputHelper *helper) : SplashInputState_NS(vm, "intro1", helper) {
_slideName = "minintro";
_timeOut = 2000;
_nextState = "chooselanguage";
@@ -112,14 +112,12 @@ class ChooseLanguageInputState_NS : public MenuInputState {
static const Common::Rect _amigaLanguageSelectBlocks[4];
const Common::Rect *_blocks;
- Parallaction_ns *_vm;
+ Parallaction *_vm;
public:
- ChooseLanguageInputState_NS(Parallaction_ns *vm, MenuInputHelper *helper) : MenuInputState("chooselanguage", helper), _vm(vm) {
+ ChooseLanguageInputState_NS(Parallaction *vm, MenuInputHelper *helper) : MenuInputState("chooselanguage", helper), _vm(vm) {
_allowChoice = false;
-
- if (ConfMan.getInt("save_slot") < 0 || ConfMan.getInt("save_slot") > 99)
- _nextState = "selectgame";
+ _nextState = "selectgame";
if (_vm->getPlatform() == Common::kPlatformAmiga) {
if (!(_vm->getFeatures() & GF_LANG_MULT)) {
@@ -181,7 +179,7 @@ public:
uint id = _vm->_gfx->createLabel(_vm->_introFont, "SELECT LANGUAGE", 1);
_vm->_gfx->showLabel(id, 60, 30);
- _vm->setArrowCursor();
+ _vm->_input->setArrowCursor();
}
};
@@ -206,13 +204,13 @@ class SelectGameInputState_NS : public MenuInputState {
uint _labels[2];
- Parallaction_ns *_vm;
+ Parallaction *_vm;
static const char *newGameMsg[4];
static const char *loadGameMsg[4];
public:
- SelectGameInputState_NS(Parallaction_ns *vm, MenuInputHelper *helper) : MenuInputState("selectgame", helper), _vm(vm) {
+ SelectGameInputState_NS(Parallaction *vm, MenuInputHelper *helper) : MenuInputState("selectgame", helper), _vm(vm) {
_choice = 0;
_oldChoice = -1;
@@ -274,10 +272,10 @@ const char *SelectGameInputState_NS::loadGameMsg[4] = {
class LoadGameInputState_NS : public MenuInputState {
bool _result;
- Parallaction_ns *_vm;
+ Parallaction *_vm;
public:
- LoadGameInputState_NS(Parallaction_ns *vm, MenuInputHelper *helper) : MenuInputState("loadgame", helper), _vm(vm) { }
+ LoadGameInputState_NS(Parallaction *vm, MenuInputHelper *helper) : MenuInputState("loadgame", helper), _vm(vm) { }
virtual MenuInputState* run() {
if (!_result) {
@@ -287,19 +285,19 @@ public:
}
virtual void enter() {
- _result = _vm->loadGame();
+ _result = _vm->_saveLoad->loadGame();
}
};
class NewGameInputState_NS : public MenuInputState {
- Parallaction_ns *_vm;
+ Parallaction *_vm;
static const char *introMsg3[4];
public:
- NewGameInputState_NS(Parallaction_ns *vm, MenuInputHelper *helper) : MenuInputState("newgame", helper), _vm(vm) {
+ NewGameInputState_NS(Parallaction *vm, MenuInputHelper *helper) : MenuInputState("newgame", helper), _vm(vm) {
}
virtual MenuInputState* run() {
@@ -347,14 +345,15 @@ const char *NewGameInputState_NS::introMsg3[4] = {
class StartDemoInputState_NS : public MenuInputState {
- Parallaction_ns *_vm;
+ Parallaction *_vm;
public:
- StartDemoInputState_NS(Parallaction_ns *vm, MenuInputHelper *helper) : MenuInputState("startdemo", helper), _vm(vm) {
+ StartDemoInputState_NS(Parallaction *vm, MenuInputHelper *helper) : MenuInputState("startdemo", helper), _vm(vm) {
}
virtual MenuInputState* run() {
_vm->scheduleLocationSwitch("fognedemo.dough");
+ _vm->_input->setMouseState(MOUSE_ENABLED_SHOW);
return 0;
}
@@ -374,7 +373,7 @@ class SelectCharacterInputState_NS : public MenuInputState {
static const Common::Rect codeSelectBlocks[9];
static const Common::Rect codeTrueBlocks[9];
- Parallaction_ns *_vm;
+ Parallaction *_vm;
int guiGetSelectedBlock(const Common::Point &p) {
@@ -391,7 +390,7 @@ class SelectCharacterInputState_NS : public MenuInputState {
_vm->_gfx->invertBackground(codeTrueBlocks[selection]);
_vm->_gfx->updateScreen();
_vm->beep();
- g_system->delayMillis(100);
+ _vm->_system->delayMillis(100);
_vm->_gfx->invertBackground(codeTrueBlocks[selection]);
_vm->_gfx->updateScreen();
}
@@ -427,7 +426,7 @@ class SelectCharacterInputState_NS : public MenuInputState {
public:
- SelectCharacterInputState_NS(Parallaction_ns *vm, MenuInputHelper *helper) : MenuInputState("selectcharacter", helper), _vm(vm) {
+ SelectCharacterInputState_NS(Parallaction *vm, MenuInputHelper *helper) : MenuInputState("selectcharacter", helper), _vm(vm) {
_keys = (_vm->getPlatform() == Common::kPlatformAmiga && (_vm->getFeatures() & GF_LANG_MULT)) ? _amigaKeys : _pcKeys;
_block.create(BLOCK_WIDTH, BLOCK_HEIGHT, 1);
}
@@ -446,7 +445,7 @@ public:
}
void delay() {
- if (g_system->getMillis() - _startTime < 2000) {
+ if (_vm->_system->getMillis() - _startTime < 2000) {
return;
}
cleanup();
@@ -488,7 +487,7 @@ public:
_vm->_gfx->patchBackground(_emptySlots, SLOT_X, SLOT_Y, false);
_vm->_gfx->hideLabel(_labels[0]);
_vm->_gfx->showLabel(_labels[1], 60, 30);
- _startTime = g_system->getMillis();
+ _startTime = _vm->_system->getMillis();
_state = DELAY;
}
@@ -511,7 +510,6 @@ public:
error("If you read this, either your CPU or transivity is broken (we believe the former).");
}
- _vm->_inTestResult = false;
_vm->cleanupGame();
_vm->scheduleLocationSwitch(_charStartLocation[character]);
}
@@ -558,7 +556,7 @@ public:
cleanup();
- _vm->setArrowCursor();
+ _vm->_input->setArrowCursor();
_vm->_input->setMouseState(MOUSE_ENABLED_SHOW);
_state = CHOICE;
}
@@ -623,7 +621,7 @@ const Common::Rect SelectCharacterInputState_NS::codeTrueBlocks[9] = {
class ShowCreditsInputState_NS : public MenuInputState {
- Parallaction_ns *_vm;
+ Parallaction *_vm;
int _current;
uint32 _startTime;
@@ -635,7 +633,7 @@ class ShowCreditsInputState_NS : public MenuInputState {
static const Credit _credits[6];
public:
- ShowCreditsInputState_NS(Parallaction_ns *vm, MenuInputHelper *helper) : MenuInputState("showcredits", helper), _vm(vm) {
+ ShowCreditsInputState_NS(Parallaction *vm, MenuInputHelper *helper) : MenuInputState("showcredits", helper), _vm(vm) {
}
void drawCurrentLabel() {
@@ -649,14 +647,14 @@ public:
virtual MenuInputState* run() {
if (_current == -1) {
- _startTime = g_system->getMillis();
+ _startTime = _vm->_system->getMillis();
_current = 0;
drawCurrentLabel();
return this;
}
int event = _vm->_input->getLastButtonEvent();
- uint32 curTime = g_system->getMillis();
+ uint32 curTime = _vm->_system->getMillis();
if ((event == kMouseLeftUp) || (curTime - _startTime > 5500)) {
_current++;
_startTime = curTime;
@@ -688,11 +686,11 @@ const ShowCreditsInputState_NS::Credit ShowCreditsInputState_NS::_credits[6] = {
};
class EndIntroInputState_NS : public MenuInputState {
- Parallaction_ns *_vm;
+ Parallaction *_vm;
bool _isDemo;
public:
- EndIntroInputState_NS(Parallaction_ns *vm, MenuInputHelper *helper) : MenuInputState("endintro", helper), _vm(vm) {
+ EndIntroInputState_NS(Parallaction *vm, MenuInputHelper *helper) : MenuInputState("endintro", helper), _vm(vm) {
_isDemo = (_vm->getFeatures() & GF_DEMO) != 0;
}
@@ -704,6 +702,7 @@ public:
}
if (_isDemo) {
+ _vm->_quit = true;
_vm->quitGame();
return 0;
}
@@ -725,7 +724,7 @@ public:
class EndPartInputState_NS : public MenuInputState {
- Parallaction_ns *_vm;
+ Parallaction *_vm;
bool _allPartsComplete;
// part completion messages
@@ -741,7 +740,7 @@ class EndPartInputState_NS : public MenuInputState {
public:
- EndPartInputState_NS(Parallaction_ns *vm, MenuInputHelper *helper) : MenuInputState("endpart", helper), _vm(vm) {
+ EndPartInputState_NS(Parallaction *vm, MenuInputHelper *helper) : MenuInputState("endpart", helper), _vm(vm) {
}
virtual MenuInputState* run() {
@@ -761,20 +760,23 @@ public:
}
virtual void enter() {
- _allPartsComplete = _vm->allPartsComplete();
+ bool completed[3];
+ _vm->_saveLoad->getGamePartProgress(completed, 3);
+ _allPartsComplete = (completed[0] && completed[1] && completed[2]);
_vm->_input->setMouseState(MOUSE_DISABLED);
+ uint16 language = _vm->getInternLanguage();
uint id[4];
if (_allPartsComplete) {
- id[0] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg4[_language], 1);
- id[1] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg5[_language], 1);
- id[2] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg6[_language], 1);
- id[3] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg7[_language], 1);
+ id[0] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg4[language], 1);
+ id[1] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg5[language], 1);
+ id[2] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg6[language], 1);
+ id[3] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg7[language], 1);
} else {
- id[0] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg0[_language], 1);
- id[1] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg1[_language], 1);
- id[2] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg2[_language], 1);
- id[3] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg3[_language], 1);
+ id[0] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg0[language], 1);
+ id[1] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg1[language], 1);
+ id[2] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg2[language], 1);
+ id[3] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg3[language], 1);
}
_vm->_gfx->showLabel(id[0], CENTER_LABEL_HORIZONTAL, 70);
diff --git a/engines/parallaction/input.cpp b/engines/parallaction/input.cpp
index 19747c007e..c91421e15e 100644
--- a/engines/parallaction/input.cpp
+++ b/engines/parallaction/input.cpp
@@ -31,6 +31,58 @@
namespace Parallaction {
+#define MOUSEARROW_WIDTH_NS 16
+#define MOUSEARROW_HEIGHT_NS 16
+
+#define MOUSECOMBO_WIDTH_NS 32 // sizes for cursor + selected inventory item
+#define MOUSECOMBO_HEIGHT_NS 32
+
+struct MouseComboProperties {
+ int _xOffset;
+ int _yOffset;
+ int _width;
+ int _height;
+};
+/*
+// TODO: improve NS's handling of normal cursor before merging cursor code.
+MouseComboProperties _mouseComboProps_NS = {
+ 7, // combo x offset (the icon from the inventory will be rendered from here)
+ 7, // combo y offset (ditto)
+ 32, // combo (arrow + icon) width
+ 32 // combo (arrow + icon) height
+};
+*/
+MouseComboProperties _mouseComboProps_BR = {
+ 8, // combo x offset (the icon from the inventory will be rendered from here)
+ 8, // combo y offset (ditto)
+ 68, // combo (arrow + icon) width
+ 68 // combo (arrow + icon) height
+};
+
+Input::Input(Parallaction *vm) : _vm(vm) {
+ _gameType = _vm->getGameType();
+ _transCurrentHoverItem = 0;
+ _hasDelayedAction = false; // actived when the character needs to move before taking an action
+ _mouseState = MOUSE_DISABLED;
+ _activeItem._index = 0;
+ _activeItem._id = 0;
+ _mouseButtons = 0;
+ _delayedActionZone = nullZonePtr;
+
+ initCursors();
+}
+
+Input::~Input() {
+ if (_gameType == GType_Nippon) {
+ delete _mouseArrow;
+ }
+
+ delete _comboArrow;
+ delete _dinoCursor;
+ delete _dougCursor;
+ delete _donnaCursor;
+}
+
// FIXME: the engine has 3 event loops. The following routine hosts the main one,
// and it's called from 8 different places in the code. There exist 2 more specialised
// loops which could possibly be merged into this one with some effort in changing
@@ -78,6 +130,7 @@ void Input::readInput() {
case Common::EVENT_MOUSEMOVE:
_mousePos = e.mouse;
break;
+
case Common::EVENT_RTL:
case Common::EVENT_QUIT:
_vm->_quit = true;
@@ -127,9 +180,9 @@ void Input::waitForButtonEvent(uint32 buttonEventMask, int32 timeout) {
}
-void Input::updateGameInput() {
+int Input::updateGameInput() {
- readInput();
+ int event = kEvNone;
if (!isMouseEnabled() ||
(_engineFlags & kEngineWalking) ||
@@ -141,44 +194,38 @@ void Input::updateGameInput() {
(_engineFlags & kEngineChangeLocation) == 0
);
- return;
+ return event;
}
if (_hasKeyPressEvent && (_vm->getFeatures() & GF_DEMO) == 0) {
- if (_keyPressed.keycode == Common::KEYCODE_l) _inputData._event = kEvLoadGame;
- if (_keyPressed.keycode == Common::KEYCODE_s) _inputData._event = kEvSaveGame;
+ if (_keyPressed.keycode == Common::KEYCODE_l) event = kEvLoadGame;
+ if (_keyPressed.keycode == Common::KEYCODE_s) event = kEvSaveGame;
}
- if (_inputData._event == kEvNone) {
- _inputData._mousePos = _mousePos;
+ if (event == kEvNone) {
translateGameInput();
}
+ return event;
}
-InputData* Input::updateInput() {
+int Input::updateInput() {
- _inputData._event = kEvNone;
+ int event = kEvNone;
+ readInput();
switch (_inputMode) {
- case kInputModeComment:
- case kInputModeDialogue:
- case kInputModeMenu:
- readInput();
- break;
-
case kInputModeGame:
- updateGameInput();
+ event = updateGameInput();
break;
case kInputModeInventory:
- readInput();
updateInventoryInput();
break;
}
- return &_inputData;
+ return event;
}
void Input::trackMouse(ZonePtr z) {
@@ -212,7 +259,7 @@ void Input::takeAction(ZonePtr z) {
void Input::walkTo(const Common::Point &dest) {
stopHovering();
- _vm->setArrowCursor();
+ setArrowCursor();
_vm->_char.scheduleWalk(dest.x, dest.y);
}
@@ -252,7 +299,6 @@ bool Input::translateGameInput() {
if ((_mouseButtons == kMouseLeftUp) && ((_activeItem._id != 0) || ((z->_type & 0xFFFF) == kZoneCommand))) {
- _inputData._zone = z;
if (z->_flags & kFlagsNoWalk) {
// character doesn't need to walk to take specified action
takeAction(z);
@@ -269,7 +315,7 @@ bool Input::translateGameInput() {
}
_vm->beep();
- _vm->setArrowCursor();
+ setArrowCursor();
return true;
}
@@ -285,7 +331,7 @@ void Input::enterInventoryMode() {
_activeItem._index = (_activeItem._id >> 16) & 0xFFFF;
_engineFlags |= kEngineDragging;
} else {
- _vm->setArrowCursor();
+ setArrowCursor();
}
}
@@ -320,12 +366,12 @@ void Input::exitInventoryMode() {
_vm->closeInventory();
if (pos == -1) {
- _vm->setArrowCursor();
+ setArrowCursor();
} else {
const InventoryItem *item = _vm->getInventoryItem(pos);
if (item->_index != 0) {
_activeItem._id = item->_id;
- _vm->setInventoryCursor(item->_index);
+ setInventoryCursor(item->_index);
}
}
_vm->resumeJobs();
@@ -373,4 +419,96 @@ bool Input::isMouseEnabled() {
return (_mouseState == MOUSE_ENABLED_SHOW) || (_mouseState == MOUSE_ENABLED_HIDE);
}
+
+void Input::initCursors() {
+
+ _dinoCursor = _donnaCursor = _dougCursor = 0;
+
+ switch (_gameType) {
+ case GType_Nippon:
+ _comboArrow = _vm->_disk->loadPointer("pointer");
+ _mouseArrow = new Cnv(1, MOUSEARROW_WIDTH_NS, MOUSEARROW_HEIGHT_NS, _resMouseArrow_NS, false);
+ break;
+
+ case GType_BRA:
+ if (_vm->getPlatform() == Common::kPlatformPC) {
+ _dinoCursor = _vm->_disk->loadPointer("pointer1");
+ _dougCursor = _vm->_disk->loadPointer("pointer2");
+ _donnaCursor = _vm->_disk->loadPointer("pointer3");
+
+ Graphics::Surface *surf = new Graphics::Surface;
+ surf->create(_mouseComboProps_BR._width, _mouseComboProps_BR._height, 1);
+ _comboArrow = new SurfaceToFrames(surf);
+
+ // TODO: choose the pointer depending on the active character
+ // For now, we pick Donna's
+ _mouseArrow = _donnaCursor;
+ } else {
+ // TODO: Where are the Amiga cursors?
+ _mouseArrow = 0;
+ }
+ break;
+
+ default:
+ warning("Input::initCursors: unknown gametype");
+ }
+
+}
+
+void Input::setArrowCursor() {
+
+ switch (_gameType) {
+ case GType_Nippon:
+ debugC(1, kDebugInput, "setting mouse cursor to arrow");
+ // this stuff is needed to avoid artifacts with labels and selected items when switching cursors
+ stopHovering();
+ _activeItem._id = 0;
+ _vm->_system->setMouseCursor(_mouseArrow->getData(0), MOUSEARROW_WIDTH_NS, MOUSEARROW_HEIGHT_NS, 0, 0, 0);
+ break;
+
+ case GType_BRA: {
+ if (_vm->getPlatform() == Common::kPlatformAmiga)
+ return;
+
+ Common::Rect r;
+ _mouseArrow->getRect(0, r);
+ _vm->_system->setMouseCursor(_mouseArrow->getData(0), r.width(), r.height(), 0, 0, 0);
+ _vm->_system->showMouse(true);
+ _activeItem._id = 0;
+ break;
+ }
+
+ default:
+ warning("Input::setArrowCursor: unknown gametype");
+ }
+
+}
+
+void Input::setInventoryCursor(ItemName name) {
+ assert(name > 0);
+
+ switch (_gameType) {
+ case GType_Nippon: {
+ byte *v8 = _comboArrow->getData(0);
+ // FIXME: destination offseting is not clear
+ _vm->_inventoryRenderer->drawItem(name, v8 + 7 * MOUSECOMBO_WIDTH_NS + 7, MOUSECOMBO_WIDTH_NS);
+ _vm->_system->setMouseCursor(v8, MOUSECOMBO_WIDTH_NS, MOUSECOMBO_HEIGHT_NS, 0, 0, 0);
+ break;
+ }
+
+ case GType_BRA: {
+ byte *src = _mouseArrow->getData(0);
+ byte *dst = _comboArrow->getData(0);
+ memcpy(dst, src, _comboArrow->getSize(0));
+ // FIXME: destination offseting is not clear
+ _vm->_inventoryRenderer->drawItem(name, dst + _mouseComboProps_BR._yOffset * _mouseComboProps_BR._width + _mouseComboProps_BR._xOffset, _mouseComboProps_BR._width);
+ _vm->_system->setMouseCursor(dst, _mouseComboProps_BR._width, _mouseComboProps_BR._height, 0, 0, 0);
+ }
+
+ default:
+ warning("Input::setInventoryCursor: unknown gametype");
+ }
+
+}
+
} // namespace Parallaction
diff --git a/engines/parallaction/input.h b/engines/parallaction/input.h
index c1e912db74..e7d20c0d2e 100644
--- a/engines/parallaction/input.h
+++ b/engines/parallaction/input.h
@@ -41,14 +41,6 @@ enum {
kMouseRightDown = 8
};
-struct InputData {
- uint16 _event;
- Common::Point _mousePos;
- int16 _inventoryIndex;
- ZonePtr _zone;
- uint _label;
-};
-
enum MouseTriState {
MOUSE_ENABLED_SHOW,
MOUSE_ENABLED_HIDE,
@@ -56,10 +48,7 @@ enum MouseTriState {
};
class Input {
- void updateGameInput();
-
- // input-only
- InputData _inputData;
+ int updateGameInput();
bool _hasKeyPressEvent;
Common::KeyState _keyPressed;
@@ -69,7 +58,7 @@ class Input {
int16 _transCurrentHoverItem;
- InputData *translateInput();
+ void translateInput();
bool translateGameInput();
bool updateInventoryInput();
void takeAction(ZonePtr z);
@@ -85,6 +74,17 @@ class Input {
void enterInventoryMode();
void exitInventoryMode();
+ int _gameType;
+
+ static byte _resMouseArrow_NS[256];
+ Frames *_mouseArrow;
+ Frames *_comboArrow;
+ Frames *_dinoCursor;
+ Frames *_dougCursor;
+ Frames *_donnaCursor;
+
+ void initCursors();
+
public:
enum {
kInputModeGame = 0,
@@ -95,18 +95,8 @@ public:
};
- Input(Parallaction *vm) : _vm(vm) {
- _transCurrentHoverItem = 0;
- _hasDelayedAction = false; // actived when the character needs to move before taking an action
- _mouseState = MOUSE_DISABLED;
- _activeItem._index = 0;
- _activeItem._id = 0;
- _mouseButtons = 0;
- _delayedActionZone = nullZonePtr;
- }
-
- virtual ~Input() { }
-
+ Input(Parallaction *vm);
+ virtual ~Input();
void getCursorPos(Common::Point& p) {
p = _mousePos;
@@ -116,7 +106,7 @@ public:
InventoryItem _activeItem;
void readInput();
- InputData* updateInput();
+ int updateInput();
void trackMouse(ZonePtr z);
void waitForButtonEvent(uint32 buttonEventMask, int32 timeout = -1);
uint32 getLastButtonEvent() { return _mouseButtons; }
@@ -129,6 +119,9 @@ public:
void setMouseState(MouseTriState state);
MouseTriState getMouseState();
bool isMouseEnabled();
+
+ void setArrowCursor();
+ void setInventoryCursor(ItemName name);
};
} // namespace Parallaction
diff --git a/engines/parallaction/objects.cpp b/engines/parallaction/objects.cpp
index d2332643ed..b4776250c6 100644
--- a/engines/parallaction/objects.cpp
+++ b/engines/parallaction/objects.cpp
@@ -180,7 +180,6 @@ Zone::~Zone() {
case kZoneDoor:
free(u.door->_location);
- free(u.door->_background);
u.door->gfxobj->release();
delete u.door;
break;
@@ -191,7 +190,6 @@ Zone::~Zone() {
break;
case kZoneGet:
- free(u.get->_backup);
u.get->gfxobj->release();
delete u.get;
break;
diff --git a/engines/parallaction/objects.h b/engines/parallaction/objects.h
index f66e602f68..eee69383b6 100644
--- a/engines/parallaction/objects.h
+++ b/engines/parallaction/objects.h
@@ -192,23 +192,19 @@ struct Dialogue {
~Dialogue();
};
-struct GetData { // size = 24
+struct GetData {
uint32 _icon;
GfxObj *gfxobj;
- byte *_backup;
- uint16 field_14; // unused
- uint16 field_16; // unused
MaskBuffer _mask[2];
bool hasMask;
GetData() {
_icon = 0;
- _backup = NULL;
gfxobj = NULL;
hasMask = false;
}
};
-struct SpeakData { // size = 36
+struct SpeakData {
char _name[32];
Dialogue *_dialogue;
@@ -217,30 +213,25 @@ struct SpeakData { // size = 36
_dialogue = NULL;
}
};
-struct ExamineData { // size = 28
+struct ExamineData {
GfxObj *_cnv;
- uint16 _opBase; // unused
- uint16 field_12; // unused
char* _description;
char* _filename;
ExamineData() {
- _opBase = 0;
_description = NULL;
_filename = NULL;
_cnv = NULL;
}
};
-struct DoorData { // size = 28
+struct DoorData {
char* _location;
GfxObj *gfxobj;
- byte* _background;
Common::Point _startPos;
uint16 _startFrame;
DoorData() {
_location = NULL;
- _background = NULL;
_startFrame = 0;
gfxobj = NULL;
}
diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
index afa246a9f8..03464d8a7e 100644
--- a/engines/parallaction/parallaction.cpp
+++ b/engines/parallaction/parallaction.cpp
@@ -35,6 +35,7 @@
#include "parallaction/input.h"
#include "parallaction/parallaction.h"
#include "parallaction/debug.h"
+#include "parallaction/saveload.h"
#include "parallaction/sound.h"
@@ -47,7 +48,6 @@ Parallaction *_vm = NULL;
// public stuff
char _saveData1[30] = { '\0' };
-uint16 _language = 0;
uint32 _engineFlags = 0;
uint16 _score = 1;
@@ -100,8 +100,6 @@ Parallaction::~Parallaction() {
cleanupGui();
- delete _comboArrow;
-
delete _localFlagNames;
delete _gfx;
delete _soundMan;
@@ -116,9 +114,7 @@ int Parallaction::init() {
_objectsNames = NULL;
_globalFlagsNames = NULL;
_location._hasSound = false;
- _baseTime = 0;
_numLocations = 0;
- _gameToLoad = -1;
_location._startPosition.x = -1000;
_location._startPosition.y = -1000;
_location._startFrame = 0;
@@ -126,7 +122,7 @@ int Parallaction::init() {
_location._endComment = NULL;
_quit = false;
-
+
_pathBuffer = 0;
_screenSize = _screenWidth * _screenHeight;
@@ -137,6 +133,7 @@ int Parallaction::init() {
initInventory(); // needs to be pushed into subclass
+ // this needs _disk to be already setup
_input = new Input(this);
_gfx = new Gfx(this);
@@ -146,19 +143,10 @@ int Parallaction::init() {
_menuHelper = 0;
setupBalloonManager();
- syncSoundSettings();
return 0;
}
-
-void Parallaction::clearSet(OpcodeSet &opcodes) {
- for (Common::Array<const Opcode*>::iterator i = opcodes.begin(); i != opcodes.end(); ++i)
- delete *i;
- opcodes.clear();
-}
-
-
void Parallaction::updateView() {
if ((_engineFlags & kEnginePauseJobs) && (_input->_inputMode != Input::kInputModeInventory)) {
@@ -167,7 +155,7 @@ void Parallaction::updateView() {
_gfx->animatePalette();
_gfx->updateScreen();
- g_system->delayMillis(30);
+ _vm->_system->delayMillis(30);
}
@@ -282,7 +270,15 @@ void Parallaction::freeLocation() {
return;
}
+void Parallaction::showSlide(const char *name, int x, int y) {
+ BackgroundInfo *info = new BackgroundInfo;
+ _disk->loadSlide(*info, name);
+
+ info->x = (x == CENTER_LABEL_HORIZONTAL) ? ((_vm->_screenWidth - info->width) >> 1) : x;
+ info->y = (y == CENTER_LABEL_VERTICAL) ? ((_vm->_screenHeight - info->height) >> 1) : y;
+ _gfx->setBackground(kBackgroundSlide, info);
+}
void Parallaction::freeBackground() {
@@ -307,23 +303,19 @@ void Parallaction::showLocationComment(const char *text, bool end) {
}
-void Parallaction::processInput(InputData *data) {
- if (!data) {
- return;
- }
-
- switch (data->_event) {
+void Parallaction::processInput(int event) {
+ switch (event) {
case kEvSaveGame:
_input->stopHovering();
- saveGame();
- setArrowCursor();
+ _saveLoad->saveGame();
+ _input->setArrowCursor();
break;
case kEvLoadGame:
_input->stopHovering();
- loadGame();
- setArrowCursor();
+ _saveLoad->loadGame();
+ _input->setArrowCursor();
break;
}
@@ -333,22 +325,19 @@ void Parallaction::processInput(InputData *data) {
void Parallaction::runGame() {
- InputData *data = _input->updateInput();
- if (_vm->quit())
+ int event = _input->updateInput();
+ if (quit())
return;
runGuiFrame();
runDialogueFrame();
runCommentFrame();
- if (_vm->quit())
- return;
-
if (_input->_inputMode == Input::kInputModeGame) {
- processInput(data);
+ processInput(event);
runPendingZones();
- if (_vm->quit())
+ if (quit())
return;
if (_engineFlags & kEngineChangeLocation) {
@@ -411,7 +400,7 @@ void Parallaction::doLocationEnterTransition() {
pal.fadeTo(_gfx->_palette, 4);
_gfx->setPalette(pal);
_gfx->updateScreen();
- g_system->delayMillis(20);
+ _vm->_system->delayMillis(20);
}
_gfx->setPalette(_gfx->_palette);
@@ -439,6 +428,387 @@ uint32 Parallaction::getLocationFlags() {
+void Parallaction::drawAnimations() {
+ debugC(9, kDebugExec, "Parallaction_ns::drawAnimations()\n");
+
+ uint16 layer = 0, scale = 100;
+
+ for (AnimationList::iterator it = _location._animations.begin(); it != _location._animations.end(); it++) {
+
+ AnimationPtr anim = *it;
+ GfxObj *obj = anim->gfxobj;
+
+ // Validation is performed here, so that every animation is affected, instead that only the ones
+ // who *own* a script. In fact, some scripts can change values in other animations.
+ // The right way to do this would be to enforce validation when any variable is modified from
+ // a script.
+ anim->validateScriptVars();
+
+ if ((anim->_flags & kFlagsActive) && ((anim->_flags & kFlagsRemove) == 0)) {
+
+ if (anim->_flags & kFlagsNoMasked)
+ layer = LAYER_FOREGROUND;
+ else {
+ if (getGameType() == GType_Nippon) {
+ // Layer in NS depends on where the animation is on the screen, for each animation.
+ layer = _gfx->_backgroundInfo->getLayer(anim->getFrameY() + anim->height());
+ } else {
+ // Layer in BRA is calculated from Z value. For characters it is the same as NS,
+ // but other animations can have Z set from scripts independently from their
+ // position on the screen.
+ layer = _gfx->_backgroundInfo->getLayer(anim->getZ());
+ }
+ }
+
+ if (getGameType() == GType_BRA) {
+ if (anim->_flags & (kFlagsScaled | kFlagsCharacter)) {
+ if (anim->getZ() <= _location._zeta0) {
+ if (anim->getZ() >= _location._zeta1) {
+ scale = ((anim->getZ() - _location._zeta1) * (100 - _location._zeta2)) / (_location._zeta0 - _location._zeta1) + _location._zeta2;
+ } else {
+ scale = _location._zeta2;
+ }
+ }
+ }
+ }
+
+ if (obj) {
+ _gfx->showGfxObj(obj, true);
+ obj->frame = anim->getF();
+ obj->x = anim->getX();
+ obj->y = anim->getY();
+ obj->z = anim->getZ();
+ obj->layer = layer;
+ obj->scale = scale;
+ }
+ }
+
+ if (((anim->_flags & kFlagsActive) == 0) && (anim->_flags & kFlagsRemove)) {
+ anim->_flags &= ~kFlagsRemove;
+ }
+
+ if ((anim->_flags & kFlagsActive) && (anim->_flags & kFlagsRemove)) {
+ anim->_flags &= ~kFlagsActive;
+ anim->_flags |= kFlagsRemove;
+ if (obj) {
+ _gfx->showGfxObj(obj, false);
+ }
+ }
+ }
+
+ debugC(9, kDebugExec, "Parallaction_ns::drawAnimations done()\n");
+
+ return;
+}
+
+
+void Parallaction::showZone(ZonePtr z, bool visible) {
+ if (!z) {
+ return;
+ }
+
+ if (visible) {
+ z->_flags &= ~kFlagsRemove;
+ z->_flags |= kFlagsActive;
+ } else {
+ z->_flags |= kFlagsRemove;
+ }
+
+ if ((z->_type & 0xFFFF) == kZoneGet) {
+ _gfx->showGfxObj(z->u.get->gfxobj, visible);
+
+ GetData *data = z->u.get;
+ if (data->hasMask && _gfx->_backgroundInfo->hasMask) {
+ if (visible) {
+ _gfx->_backgroundInfo->mask.bltOr(data->gfxobj->x, data->gfxobj->y, data->_mask[0], 0, 0, data->_mask->w, data->_mask->h);
+ } else {
+ _gfx->_backgroundInfo->mask.bltCopy(data->gfxobj->x, data->gfxobj->y, data->_mask[1], 0, 0, data->_mask->w, data->_mask->h);
+ }
+ }
+ }
+}
+
+
+//
+// ZONE TYPE: EXAMINE
+//
+
+void Parallaction::enterCommentMode(ZonePtr z) {
+ if (!z) {
+ return;
+ }
+
+ _commentZone = z;
+
+ ExamineData *data = _commentZone->u.examine;
+
+ if (!data->_description) {
+ return;
+ }
+
+ // TODO: move this balloons stuff into DialogueManager and BalloonManager
+ if (getGameType() == GType_Nippon) {
+ int id;
+ if (data->_filename) {
+ if (data->_cnv == 0) {
+ data->_cnv = _disk->loadStatic(data->_filename);
+ }
+
+ _gfx->setHalfbriteMode(true);
+ _balloonMan->setSingleBalloon(data->_description, 0, 90, 0, BalloonManager::kNormalColor);
+ Common::Rect r;
+ data->_cnv->getRect(0, r);
+ id = _gfx->setItem(data->_cnv, 140, (_screenHeight - r.height())/2);
+ _gfx->setItemFrame(id, 0);
+ id = _gfx->setItem(_char._head, 100, 152);
+ _gfx->setItemFrame(id, 0);
+ } else {
+ _balloonMan->setSingleBalloon(data->_description, 140, 10, 0, BalloonManager::kNormalColor);
+ id = _gfx->setItem(_char._talk, 190, 80);
+ _gfx->setItemFrame(id, 0);
+ }
+ } else
+ if (getGameType() == GType_BRA) {
+ _balloonMan->setSingleBalloon(data->_description, 0, 0, 1, BalloonManager::kNormalColor);
+ int id = _gfx->setItem(_char._talk, 10, 80);
+ _gfx->setItemFrame(id, 0);
+ }
+
+ _input->_inputMode = Input::kInputModeComment;
+}
+
+void Parallaction::exitCommentMode() {
+ _input->_inputMode = Input::kInputModeGame;
+
+ hideDialogueStuff();
+ _gfx->setHalfbriteMode(false);
+
+ _cmdExec->run(_commentZone->_commands, _commentZone);
+ _commentZone = nullZonePtr;
+}
+
+void Parallaction::runCommentFrame() {
+ if (_input->_inputMode != Input::kInputModeComment) {
+ return;
+ }
+
+ if (_input->getLastButtonEvent() == kMouseLeftUp) {
+ exitCommentMode();
+ }
+}
+
+
+void Parallaction::runZone(ZonePtr z) {
+ debugC(3, kDebugExec, "runZone (%s)", z->_name);
+
+ uint16 subtype = z->_type & 0xFFFF;
+
+ debugC(3, kDebugExec, "type = %x, object = %x", subtype, (z->_type & 0xFFFF0000) >> 16);
+ switch(subtype) {
+
+ case kZoneExamine:
+ enterCommentMode(z);
+ return;
+
+ case kZoneGet:
+ pickupItem(z);
+ break;
+
+ case kZoneDoor:
+ if (z->_flags & kFlagsLocked) break;
+ updateDoor(z, !(z->_flags & kFlagsClosed));
+ break;
+
+ case kZoneHear:
+ _soundMan->playSfx(z->u.hear->_name, z->u.hear->_channel, (z->_flags & kFlagsLooping) == kFlagsLooping, 60);
+ break;
+
+ case kZoneSpeak:
+ enterDialogueMode(z);
+ return;
+ }
+
+ debugC(3, kDebugExec, "runZone completed");
+
+ _cmdExec->run(z->_commands, z);
+
+ return;
+}
+
+//
+// ZONE TYPE: DOOR
+//
+void Parallaction::updateDoor(ZonePtr z, bool close) {
+ z->_flags = close ? (z->_flags |= kFlagsClosed) : (z->_flags &= ~kFlagsClosed);
+
+ if (z->u.door->gfxobj) {
+ uint frame = (close ? 0 : 1);
+// z->u.door->gfxobj->setFrame(frame);
+ z->u.door->gfxobj->frame = frame;
+ }
+
+ return;
+}
+
+
+
+//
+// ZONE TYPE: GET
+//
+
+bool Parallaction::pickupItem(ZonePtr z) {
+ if (z->_flags & kFlagsFixed) {
+ return false;
+ }
+
+ int slot = addInventoryItem(z->u.get->_icon);
+ if (slot != -1) {
+ showZone(z, false);
+ }
+
+ return (slot != -1);
+}
+
+// FIXME: input coordinates must be offseted to handle scrolling!
+bool Parallaction::checkSpecialZoneBox(ZonePtr z, uint32 type, uint x, uint y) {
+ // not a special zone
+ if ((z->getX() != -2) && (z->getX() != -3)) {
+ return false;
+ }
+
+ // WORKAROUND: this huge condition is needed because we made TypeData a collection of structs
+ // instead of an union. So, merge->_obj1 and get->_icon were just aliases in the original engine,
+ // but we need to check it separately here. The same workaround is applied in freeZones.
+ if ((((z->_type & 0xFFFF) == kZoneMerge) && (((x == z->u.merge->_obj1) && (y == z->u.merge->_obj2)) || ((x == z->u.merge->_obj2) && (y == z->u.merge->_obj1)))) ||
+ (((z->_type & 0xFFFF) == kZoneGet) && ((x == z->u.get->_icon) || (y == z->u.get->_icon)))) {
+
+ // WORKAROUND for bug 2070751: special zones are only used in NS, to allow the
+ // the EXAMINE/USE action to be applied on some particular item in the inventory.
+ // The usage a verb requires at least an item match, so type can't be 0, as it
+ // was in the original code. This bug has been here since the beginning, and was
+ // hidden by label code, which filtered the bogus matches produced here.
+
+ // look for action + item match
+ if (z->_type == type)
+ return true;
+ // look for item match, but don't accept 0 types
+ if (((z->_type & 0xFFFF0000) == type) && (type))
+ return true;
+ }
+
+ return false;
+}
+
+// FIXME: input coordinates must be offseted to handle scrolling!
+bool Parallaction::checkZoneBox(ZonePtr z, uint32 type, uint x, uint y) {
+ if (z->_flags & kFlagsRemove)
+ return false;
+
+ debugC(5, kDebugExec, "checkZoneBox for %s (type = %x, x = %i, y = %i)", z->_name, type, x, y);
+
+ Common::Rect r;
+ z->getBox(r);
+ r.right++; // adjust border because Common::Rect doesn't include bottom-right edge
+ r.bottom++;
+
+ r.grow(-1); // allows some tolerance for mouse click
+
+ if (!r.contains(x, y)) {
+
+ // check for special zones (items defined in common.loc)
+ if (checkSpecialZoneBox(z, type, x, y))
+ return true;
+
+ if (z->getX() != -1)
+ return false;
+ if ((int)x < _char._ani->getFrameX())
+ return false;
+ if ((int)x > (_char._ani->getFrameX() + _char._ani->width()))
+ return false;
+ if ((int)y < _char._ani->getFrameY())
+ return false;
+ if ((int)y > (_char._ani->getFrameY() + _char._ani->height()))
+ return false;
+ }
+
+ // normal Zone
+ if ((type == 0) && ((z->_type & 0xFFFF0000) == 0))
+ return true;
+ if (z->_type == type)
+ return true;
+ if ((z->_type & 0xFFFF0000) == type)
+ return true;
+
+ return false;
+}
+
+// FIXME: input coordinates must be offseted to handle scrolling!
+bool Parallaction::checkLinkedAnimBox(ZonePtr z, uint32 type, uint x, uint y) {
+ if (z->_flags & kFlagsRemove)
+ return false;
+
+ if ((z->_flags & kFlagsAnimLinked) == 0)
+ return false;
+
+ debugC(5, kDebugExec, "checkLinkedAnimBox for %s (type = %x, x = %i, y = %i)", z->_name, type, x, y);
+
+ AnimationPtr anim = z->_linkedAnim;
+ Common::Rect r(anim->getFrameX(), anim->getFrameY(), anim->getFrameX() + anim->width() + 1, anim->getFrameY() + anim->height() + 1);
+
+ if (!r.contains(x, y)) {
+ return false;
+ }
+
+ // NOTE: the implementation of the following lines is a different in the
+ // original... it is working so far, though
+ if ((type == 0) && ((z->_type & 0xFFFF0000) == 0))
+ return true;
+ if (z->_type == type)
+ return true;
+ if ((z->_type & 0xFFFF0000) == type)
+ return true;
+
+ return false;
+}
+
+ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) {
+ uint16 _di = y;
+ uint16 _si = x;
+
+ for (ZoneList::iterator it = _location._zones.begin(); it != _location._zones.end(); it++) {
+ if (checkLinkedAnimBox(*it, type, x, y)) {
+ return *it;
+ }
+ if (checkZoneBox(*it, type, x, y)) {
+ return *it;
+ }
+ }
+
+
+ int16 _a, _b, _c, _d, _e, _f;
+ for (AnimationList::iterator ait = _location._animations.begin(); ait != _location._animations.end(); ait++) {
+
+ AnimationPtr a = *ait;
+
+ _a = (a->_flags & kFlagsActive) ? 1 : 0; // _a: active Animation
+ _e = ((_si >= a->getFrameX() + a->width()) || (_si <= a->getFrameX())) ? 0 : 1; // _e: horizontal range
+ _f = ((_di >= a->getFrameY() + a->height()) || (_di <= a->getFrameY())) ? 0 : 1; // _f: vertical range
+
+ _b = ((type != 0) || (a->_type == kZoneYou)) ? 0 : 1; // _b: (no type specified) AND (Animation is not the character)
+ _c = (a->_type & 0xFFFF0000) ? 0 : 1; // _c: Animation is not an object
+ _d = ((a->_type & 0xFFFF0000) != type) ? 0 : 1; // _d: Animation is an object of the same type
+
+ if ((_a != 0 && _e != 0 && _f != 0) && ((_b != 0 && _c != 0) || (a->_type == type) || (_d != 0))) {
+
+ return a;
+
+ }
+
+ }
+
+ return nullZonePtr;
+}
+
ZonePtr Parallaction::findZone(const char *name) {
@@ -460,8 +830,7 @@ void Parallaction::freeZones() {
// NOTE : this condition has been relaxed compared to the original, to allow the engine
// to retain special - needed - zones that were lost across location switches.
ZonePtr z = *it;
-
- if (((z->getY() == -1) || (z->getX() == -2)) && ((_vm->quit()) == 0)) {
+ if (((z->getY() == -1) || (z->getX() == -2)) && (_quit == 0)) {
debugC(2, kDebugExec, "freeZones preserving zone '%s'", z->_name);
it++;
} else {
@@ -475,11 +844,6 @@ void Parallaction::freeZones() {
return;
}
-void Parallaction::syncSoundSettings() {
- _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
- _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume") / 6);
- _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
-}
enum {
WALK_LEFT = 0,
@@ -528,7 +892,7 @@ Character::Character(Parallaction *vm) : _vm(vm), _ani(new Animation) {
_ani->setY(100);
_ani->setZ(10);
_ani->setF(0);
- _ani->_flags = kFlagsActive | kFlagsNoName;
+ _ani->_flags = kFlagsActive | kFlagsNoName | kFlagsCharacter;
_ani->_type = kZoneYou;
strncpy(_ani->_name, "yourself", ZONENAME_LENGTH);
diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h
index eb7ab2e54b..d7add635cd 100644
--- a/engines/parallaction/parallaction.h
+++ b/engines/parallaction/parallaction.h
@@ -29,6 +29,7 @@
#include "common/str.h"
#include "common/stack.h"
#include "common/array.h"
+#include "common/func.h"
#include "common/savefile.h"
#include "engines/engine.h"
@@ -44,8 +45,6 @@
#define PATH_LEN 200
-extern OSystem *g_system;
-
namespace Parallaction {
enum {
@@ -71,33 +70,6 @@ enum {
};
-// high values mean high priority
-
-enum {
- kPriority0 = 0,
- kPriority1 = 1,
- kPriority2 = 2,
- kPriority3 = 3,
- kPriority4 = 4,
- kPriority5 = 5,
- kPriority6 = 6,
- kPriority7 = 7,
- kPriority8 = 8,
- kPriority9 = 9,
- kPriority10 = 10,
- kPriority11 = 11,
- kPriority12 = 12,
- kPriority13 = 13,
- kPriority14 = 14,
- kPriority15 = 15,
- kPriority16 = 16,
- kPriority17 = 17,
- kPriority18 = 18,
- kPriority19 = 19,
- kPriority20 = 20,
- kPriority21 = 21
-};
-
enum EngineFlags {
kEnginePauseJobs = (1 << 1),
kEngineWalking = (1 << 3),
@@ -115,10 +87,6 @@ enum {
kEvLoadGame = 4000
};
-enum {
- kCursorArrow = -1
-};
-
enum ParallactionGameType {
GType_Nippon = 1,
GType_BRA
@@ -129,10 +97,8 @@ struct PARALLACTIONGameDescription;
-extern uint16 _mouseButtons;
extern char _password[8];
extern uint16 _score;
-extern uint16 _language;
extern uint32 _engineFlags;
extern char _saveData1[];
extern uint32 _globalFlags;
@@ -237,6 +203,7 @@ public:
};
+class SaveLoad;
#define NUM_LOCATIONS 120
@@ -244,239 +211,148 @@ class Parallaction : public Engine {
friend class Debugger;
public:
-
- Parallaction(OSystem *syst, const PARALLACTIONGameDescription *gameDesc);
- ~Parallaction();
-
- int init();
-
- virtual bool loadGame() = 0;
- virtual bool saveGame() = 0;
-
- bool _quit; /* The only reason this flag exists is for freeZones() to properly
- * delete all zones when necessary. THIS FLAG IS NOT THE ENGINE QUIT FLAG,
- * use _eventMan->shouldQuit() for that.
- */
-
- Input *_input;
-
- void processInput(InputData* data);
-
- void pauseJobs();
- void resumeJobs();
-
- virtual void syncSoundSettings();
-
- ZonePtr findZone(const char *name);
- ZonePtr hitZone(uint32 type, uint16 x, uint16 y);
- void runZone(ZonePtr z);
- void freeZones();
-
- AnimationPtr findAnimation(const char *name);
- void freeAnimations();
-
- void setBackground(const char *background, const char *mask, const char *path);
- void freeBackground();
-
- Table *_globalFlagsNames;
- Table *_objectsNames;
- Table *_callableNames;
- Table *_localFlagNames;
-
-public:
int getGameType() const;
uint32 getFeatures() const;
Common::Language getLanguage() const;
Common::Platform getPlatform() const;
+protected: // members
+ bool detectGame(void);
+
private:
const PARALLACTIONGameDescription *_gameDescription;
+ uint16 _language;
public:
+ Parallaction(OSystem *syst, const PARALLACTIONGameDescription *gameDesc);
+ ~Parallaction();
+
+ int init();
+
// info
int32 _screenWidth;
int32 _screenHeight;
int32 _screenSize;
- PathBuffer *_pathBuffer;
-
+ // subsystems
+ Gfx *_gfx;
+ Disk *_disk;
+ Input *_input;
SoundMan *_soundMan;
+ Debugger *_debugger;
+ SaveLoad *_saveLoad;
+ MenuInputHelper *_menuHelper;
+ Common::RandomSource _rnd;
- Gfx* _gfx;
- Disk* _disk;
+ // fonts
+ Font *_labelFont;
+ Font *_menuFont;
+ Font *_introFont;
+ Font *_dialogueFont;
- CommandExec* _cmdExec;
- ProgramExec* _programExec;
+ // game utilities
+ Table *_globalFlagsNames;
+ Table *_objectsNames;
+ Table *_callableNames;
+ Table *_localFlagNames;
+ CommandExec *_cmdExec;
+ ProgramExec *_programExec;
+ PathBuffer *_pathBuffer;
+ Inventory *_inventory;
+ BalloonManager *_balloonMan;
+ DialogueManager *_dialogueMan;
+ InventoryRenderer *_inventoryRenderer;
+
+ // game data
Character _char;
-
- void setLocationFlags(uint32 flags);
- void clearLocationFlags(uint32 flags);
- void toggleLocationFlags(uint32 flags);
- uint32 getLocationFlags();
-
uint32 _localFlags[NUM_LOCATIONS];
char _locationNames[NUM_LOCATIONS][32];
int16 _currentLocationIndex;
uint16 _numLocations;
Location _location;
-
ZonePtr _activeZone;
+ char _characterName1[50]; // only used in changeCharacter
+ ZonePtr _zoneTrap;
+ ZonePtr _commentZone;
+ bool _quit; /* The only reason this flag exists is for freeZones() to properly
+ * delete all zones when necessary. THIS FLAG IS NOT THE ENGINE QUIT FLAG,
+ * use _eventMan->shouldQuit() for that.
+ */
- Font *_labelFont;
- Font *_menuFont;
- Font *_introFont;
- Font *_dialogueFont;
-
- Common::RandomSource _rnd;
-
- Debugger *_debugger;
- Frames *_comboArrow;
-
-
-protected: // data
- uint32 _baseTime;
- char _characterName1[50]; // only used in changeCharacter
-
- int _gameToLoad;
- Common::String _saveFileName;
-
-
-protected: // members
- bool detectGame(void);
-
- void initGlobals();
- void runGame();
- void updateView();
-
- void doLocationEnterTransition();
- virtual void changeLocation(char *location) = 0;
- virtual void runPendingZones() = 0;
- void allocateLocationSlot(const char *name);
- void finalizeLocationParsing();
- void freeLocation();
- void showLocationComment(const char *text, bool end);
-
- void displayComment(ExamineData *data);
-
- void freeCharacter();
-
- bool pickupItem(ZonePtr z);
-
- void clearSet(OpcodeSet &opcodes);
-
+protected:
+ void runGame();
+ void runGuiFrame();
+ void cleanupGui();
+ void runDialogueFrame();
+ void exitDialogueMode();
+ void runCommentFrame();
+ void enterCommentMode(ZonePtr z);
+ void exitCommentMode();
+ void processInput(int event);
+ void updateView();
+ void drawAnimations();
+ void freeCharacter();
+ void freeLocation();
+ void doLocationEnterTransition();
+ void allocateLocationSlot(const char *name);
+ void finalizeLocationParsing();
+ void showLocationComment(const char *text, bool end);
+ void setupBalloonManager();
public:
- void scheduleLocationSwitch(const char *location);
- virtual void changeCharacter(const char *name) = 0;
-
- virtual void callFunction(uint index, void* parm) { }
-
- virtual void setArrowCursor() = 0;
- virtual void setInventoryCursor(ItemName name) = 0;
-
- virtual void parseLocation(const char* name) = 0;
-
- void updateDoor(ZonePtr z, bool close);
-
- virtual void drawAnimations() = 0;
-
- void beep();
-
- ZonePtr _zoneTrap;
- PathBuilder* getPathBuilder(Character *ch);
+ void beep();
+ void pauseJobs();
+ void resumeJobs();
+ void hideDialogueStuff();
+ uint getInternLanguage();
+ void setInternLanguage(uint id);
+ void enterDialogueMode(ZonePtr z);
+ void scheduleLocationSwitch(const char *location);
+ void showSlide(const char *name, int x = 0, int y = 0);
public:
-// const char **_zoneFlagNamesRes;
-// const char **_zoneTypeNamesRes;
-// const char **_commandsNamesRes;
- const char **_callableNamesRes;
- const char **_instructionNamesRes;
-
- void highlightInventoryItem(ItemPosition pos);
- int16 getHoverInventoryItem(int16 x, int16 y);
- int addInventoryItem(ItemName item);
- int addInventoryItem(ItemName item, uint32 value);
- void dropItem(uint16 v);
- bool isItemInInventory(int32 v);
- const InventoryItem* getInventoryItem(int16 pos);
- int16 getInventoryItemIndex(int16 pos);
- void initInventory();
- void destroyInventory();
- void cleanInventory(bool keepVerbs = true);
- void openInventory();
- void closeInventory();
-
- Inventory *_inventory;
- InventoryRenderer *_inventoryRenderer;
-
- BalloonManager *_balloonMan;
-
- void setupBalloonManager();
-
- void hideDialogueStuff();
- DialogueManager *_dialogueMan;
- void enterDialogueMode(ZonePtr z);
- void exitDialogueMode();
- void runDialogueFrame();
-
- MenuInputHelper *_menuHelper;
- void runGuiFrame();
- void cleanupGui();
-
- ZonePtr _commentZone;
- void enterCommentMode(ZonePtr z);
- void exitCommentMode();
- void runCommentFrame();
-
- void setInternLanguage(uint id);
- uint getInternLanguage();
+ void setLocationFlags(uint32 flags);
+ void clearLocationFlags(uint32 flags);
+ void toggleLocationFlags(uint32 flags);
+ uint32 getLocationFlags();
+ bool checkSpecialZoneBox(ZonePtr z, uint32 type, uint x, uint y);
+ bool checkZoneBox(ZonePtr z, uint32 type, uint x, uint y);
+ bool checkLinkedAnimBox(ZonePtr z, uint32 type, uint x, uint y);
+ ZonePtr findZone(const char *name);
+ ZonePtr hitZone(uint32 type, uint16 x, uint16 y);
+ void runZone(ZonePtr z);
+ void freeZones();
+ bool pickupItem(ZonePtr z);
+ void updateDoor(ZonePtr z, bool close);
+ void showZone(ZonePtr z, bool visible);
+ AnimationPtr findAnimation(const char *name);
+ void freeAnimations();
+ void setBackground(const char *background, const char *mask, const char *path);
+ void freeBackground();
+ void highlightInventoryItem(ItemPosition pos);
+ int16 getHoverInventoryItem(int16 x, int16 y);
+ int addInventoryItem(ItemName item);
+ int addInventoryItem(ItemName item, uint32 value);
+ void dropItem(uint16 v);
+ bool isItemInInventory(int32 v);
+ const InventoryItem* getInventoryItem(int16 pos);
+ int16 getInventoryItemIndex(int16 pos);
+ void initInventory();
+ void destroyInventory();
+ void cleanInventory(bool keepVerbs = true);
+ void openInventory();
+ void closeInventory();
- void showZone(ZonePtr z, bool visible);
+ virtual void parseLocation(const char* name) = 0;
+ virtual void changeLocation(char *location) = 0;
+ virtual void changeCharacter(const char *name) = 0;
+ virtual void callFunction(uint index, void* parm) = 0;
+ virtual void runPendingZones() = 0;
+ virtual void cleanupGame() = 0;
};
-class LocationName {
-
- Common::String _slide;
- Common::String _character;
- Common::String _location;
-
- bool _hasCharacter;
- bool _hasSlide;
- char *_buf;
-
-public:
- LocationName();
- ~LocationName();
-
- void bind(const char*);
-
- const char *location() const {
- return _location.c_str();
- }
-
- bool hasCharacter() const {
- return _hasCharacter;
- }
-
- const char *character() const {
- return _character.c_str();
- }
-
- bool hasSlide() const {
- return _hasSlide;
- }
-
- const char *slide() const {
- return _slide.c_str();
- }
-
- const char *c_str() const {
- return _buf;
- }
-};
-
class Parallaction_ns : public Parallaction {
@@ -488,70 +364,45 @@ public:
int go();
public:
- typedef void (Parallaction_ns::*Callable)(void*);
+ virtual void parseLocation(const char *filename);
+ virtual void changeLocation(char *location);
+ virtual void changeCharacter(const char *name);
+ virtual void callFunction(uint index, void* parm);
+ virtual void runPendingZones();
+ virtual void cleanupGame();
- virtual void callFunction(uint index, void* parm);
-
- bool loadGame();
- bool saveGame();
-
- void switchBackground(const char* background, const char* mask);
- void showSlide(const char *name, int x = 0, int y = 0);
- void setArrowCursor();
- // TODO: this should be private!!!!!!!
- bool _inTestResult;
- void cleanupGame();
- bool allPartsComplete();
+ void switchBackground(const char* background, const char* mask);
private:
- LocationParser_ns *_locationParser;
- ProgramParser_ns *_programParser;
-
- void initFonts();
- void freeFonts();
- void renameOldSavefiles();
- Common::String genSaveFileName(uint slot, bool oldStyle = false);
- Common::InSaveFile *getInSaveFile(uint slot);
- Common::OutSaveFile *getOutSaveFile(uint slot);
- void setPartComplete(const Character& character);
+ bool _inTestResult;
+ LocationParser_ns *_locationParser;
+ ProgramParser_ns *_programParser;
private:
- void changeLocation(char *location);
- void changeCharacter(const char *name);
- void runPendingZones();
-
- void setInventoryCursor(ItemName name);
-
+ void initFonts();
+ void freeFonts();
+ void initResources();
+ void startGui();
+ void startCreditSequence();
+ void startEndPartSequence();
+ void loadProgram(AnimationPtr a, const char *filename);
- void doLoadGame(uint16 slot);
- void doSaveGame(uint16 slot, const char* name);
- int buildSaveFileList(Common::StringList& l);
- int selectSaveFile(uint16 arg_0, const char* caption, const char* button);
-
- void initResources();
- void initCursors();
-
- static byte _resMouseArrow[256];
- byte *_mouseArrow;
-
- static const Callable _dosCallables[25];
- static const Callable _amigaCallables[25];
-
- /*
- game callables data members
- */
+ // callables data
+ typedef void (Parallaction_ns::*Callable)(void*);
+ const Callable *_callables;
ZonePtr _moveSarcZone0;
ZonePtr _moveSarcZone1;
uint16 num_foglie;
int16 _introSarcData1;
uint16 _introSarcData2; // sarcophagus stuff to be saved
uint16 _introSarcData3; // sarcophagus stuff to be saved
-
ZonePtr _moveSarcZones[5];
ZonePtr _moveSarcExaZones[5];
AnimationPtr _rightHandAnim;
+ static const Callable _dosCallables[25];
+ static const Callable _amigaCallables[25];
// common callables
void _c_play_boogie(void*);
@@ -585,20 +436,6 @@ private:
void _c_startMusic(void*);
void _c_closeMusic(void*);
void _c_HBOn(void*);
-
- const Callable *_callables;
-
-protected:
- void drawAnimations();
-
- void parseLocation(const char *filename);
- void loadProgram(AnimationPtr a, const char *filename);
-
- void selectStartLocation();
-
- void startGui();
- void startCreditSequence();
- void startEndPartSequence();
};
@@ -607,8 +444,6 @@ protected:
class Parallaction_br : public Parallaction_ns {
- typedef Parallaction_ns Super;
-
public:
Parallaction_br(OSystem* syst, const PARALLACTIONGameDescription *gameDesc) : Parallaction_ns(syst, gameDesc) { }
~Parallaction_br();
@@ -617,83 +452,55 @@ public:
int go();
public:
- typedef void (Parallaction_br::*Callable)(void*);
+ virtual void parseLocation(const char* name);
+ virtual void changeLocation(char *location);
+ virtual void changeCharacter(const char *name);
virtual void callFunction(uint index, void* parm);
- void changeCharacter(const char *name);
+ virtual void runPendingZones();
+ virtual void cleanupGame();
+
+
void setupSubtitles(char *s, char *s2, int y);
void clearSubtitles();
-
public:
Table *_countersNames;
-
const char **_audioCommandsNamesRes;
-
+ static const char *_partNames[];
int _part;
- int _progress;
-
#if 0 // disabled since I couldn't find any references to lip sync in the scripts
int16 _lipSyncVal;
uint _subtitleLipSync;
#endif
int _subtitleY;
int _subtitle[2];
-
ZonePtr _activeZone2;
-
int32 _counters[32];
-
uint32 _zoneFlags[NUM_LOCATIONS][NUM_ZONES];
- void startPart(uint part);
- void setArrowCursor();
+
private:
LocationParser_br *_locationParser;
ProgramParser_br *_programParser;
- void initResources();
- void initFonts();
- void freeFonts();
-
- void setInventoryCursor(ItemName name);
-
- void changeLocation(char *location);
- void runPendingZones();
-
- void initPart();
- void freePart();
-
- void initCursors();
-
- Frames *_dinoCursor;
- Frames *_dougCursor;
- Frames *_donnaCursor;
- Frames *_mouseArrow;
-
-
- static const char *_partNames[];
-
- void startGui();
+private:
+ void initResources();
+ void initFonts();
+ void freeFonts();
+ void freeLocation();
+ void loadProgram(AnimationPtr a, const char *filename);
+ void startGui(bool showSplash);
+ typedef void (Parallaction_br::*Callable)(void*);
+ const Callable *_callables;
static const Callable _dosCallables[6];
+ // dos callables
void _c_blufade(void*);
void _c_resetpalette(void*);
void _c_ferrcycle(void*);
void _c_lipsinc(void*);
void _c_albcycle(void*);
void _c_password(void*);
-
- const Callable *_callables;
-
- void parseLocation(const char* name);
- void loadProgram(AnimationPtr a, const char *filename);
-
-#if 0
- void jobWaitRemoveLabelJob(void *parm, Job *job);
- void jobPauseSfx(void *parm, Job *job);
- void jobStopFollower(void *parm, Job *job);
- void jobScroll(void *parm, Job *job);
-#endif
};
// FIXME: remove global
diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp
index e65faaeda2..c2111777fe 100644
--- a/engines/parallaction/parallaction_br.cpp
+++ b/engines/parallaction/parallaction_br.cpp
@@ -28,31 +28,11 @@
#include "parallaction/parallaction.h"
#include "parallaction/input.h"
+#include "parallaction/saveload.h"
#include "parallaction/sound.h"
namespace Parallaction {
-struct MouseComboProperties {
- int _xOffset;
- int _yOffset;
- int _width;
- int _height;
-};
-/*
-// TODO: improve NS's handling of normal cursor before merging cursor code.
-MouseComboProperties _mouseComboProps_NS = {
- 7, // combo x offset (the icon from the inventory will be rendered from here)
- 7, // combo y offset (ditto)
- 32, // combo (arrow + icon) width
- 32 // combo (arrow + icon) height
-};
-*/
-MouseComboProperties _mouseComboProps_BR = {
- 8, // combo x offset (the icon from the inventory will be rendered from here)
- 8, // combo y offset (ditto)
- 68, // combo (arrow + icon) width
- 68 // combo (arrow + icon) height
-};
const char *Parallaction_br::_partNames[] = {
"PART0",
@@ -62,14 +42,6 @@ const char *Parallaction_br::_partNames[] = {
"PART4"
};
-const char *partFirstLocation[] = {
- "intro",
- "museo",
- "start",
- "bolscoi",
- "treno"
-};
-
int Parallaction_br::init() {
_screenWidth = 640;
@@ -96,7 +68,6 @@ int Parallaction_br::init() {
initResources();
initFonts();
- initCursors();
_locationParser = new LocationParser_br(this);
_locationParser->init();
_programParser = new ProgramParser_br(this);
@@ -112,6 +83,8 @@ int Parallaction_br::init() {
_subtitle[0] = -1;
_subtitle[1] = -1;
+ _saveLoad = new SaveLoad_br(this, _saveFileMan);
+
Parallaction::init();
return 0;
@@ -119,12 +92,6 @@ int Parallaction_br::init() {
Parallaction_br::~Parallaction_br() {
freeFonts();
-
- delete _dinoCursor;
- delete _dougCursor;
- delete _donnaCursor;
-
- delete _mouseArrow;
}
void Parallaction_br::callFunction(uint index, void* parm) {
@@ -135,25 +102,27 @@ void Parallaction_br::callFunction(uint index, void* parm) {
int Parallaction_br::go() {
- if (getFeatures() & GF_DEMO) {
- startPart(1);
- } else {
- startGui();
- }
+ bool splash = true;
- while (quit() == 0) {
+ while (!quit()) {
+
+ if (getFeatures() & GF_DEMO) {
+ scheduleLocationSwitch("camalb.1");
+ _input->_inputMode = Input::kInputModeGame;
+ } else {
+ startGui(splash);
+ // don't show splash after first time
+ splash = false;
+ }
// initCharacter();
- _input->_inputMode = Input::kInputModeGame;
while (((_engineFlags & kEngineReturn) == 0) && (!quit())) {
runGame();
}
_engineFlags &= ~kEngineReturn;
- freePart();
-// freeCharacter();
-
+ cleanupGame();
}
return _eventMan->shouldRTL();
@@ -169,70 +138,6 @@ void Parallaction_br::freeFonts() {
return;
}
-void Parallaction_br::initCursors() {
-
- if (getPlatform() == Common::kPlatformPC) {
- _dinoCursor = _disk->loadPointer("pointer1");
- _dougCursor = _disk->loadPointer("pointer2");
- _donnaCursor = _disk->loadPointer("pointer3");
-
- Graphics::Surface *surf = new Graphics::Surface;
- surf->create(_mouseComboProps_BR._width, _mouseComboProps_BR._height, 1);
- _comboArrow = new SurfaceToFrames(surf);
-
- // TODO: choose the pointer depending on the active character
- // For now, we pick Donna's
- _mouseArrow = _donnaCursor;
- } else {
- // TODO: Where are the Amiga cursors?
- }
-
-}
-
-void Parallaction_br::initPart() {
-
- memset(_counters, 0, ARRAYSIZE(_counters));
-
- _globalFlagsNames = _disk->loadTable("global");
- _objectsNames = _disk->loadTable("objects");
- _countersNames = _disk->loadTable("counters");
-
- // TODO: maybe handle this into Disk
- if (getPlatform() == Common::kPlatformPC) {
- _char._objs = _disk->loadObjects("icone.ico");
- } else {
- _char._objs = _disk->loadObjects("icons.ico");
- }
-
-}
-
-void Parallaction_br::freePart() {
-
- delete _globalFlagsNames;
- delete _objectsNames;
- delete _countersNames;
-
- _globalFlagsNames = 0;
- _objectsNames = 0;
- _countersNames = 0;
-}
-
-void Parallaction_br::startPart(uint part) {
- _part = part;
- _disk->selectArchive(_partNames[_part]);
-
- initPart();
-
- if (getFeatures() & GF_DEMO) {
- strcpy(_location._name, "camalb");
- } else {
- strcpy(_location._name, partFirstLocation[_part]);
- }
-
- parseLocation("common");
- changeLocation(_location._name);
-
-}
void Parallaction_br::runPendingZones() {
ZonePtr z;
@@ -260,8 +165,7 @@ void Parallaction_br::runPendingZones() {
}
}
-
-void Parallaction_br::changeLocation(char *location) {
+void Parallaction_br::freeLocation() {
// free open location stuff
clearSubtitles();
@@ -279,27 +183,75 @@ void Parallaction_br::changeLocation(char *location) {
_location._animations.push_front(_char._ani);
-// free(_location._comment);
-// _location._comment = 0;
+ free(_location._comment);
+ _location._comment = 0;
_location._commands.clear();
_location._aCommands.clear();
+}
+
+void Parallaction_br::cleanupGame() {
+ freeLocation();
+
+// freeCharacter();
+
+ delete _globalFlagsNames;
+ delete _objectsNames;
+ delete _countersNames;
+
+ _globalFlagsNames = 0;
+ _objectsNames = 0;
+ _countersNames = 0;
+}
+
+
+void Parallaction_br::changeLocation(char *location) {
+ char *partStr = strrchr(location, '.');
+ if (partStr) {
+ int n = partStr - location;
+ strncpy(_location._name, location, n);
+ _location._name[n] = '\0';
+
+ _part = atoi(++partStr);
+ if (getFeatures() & GF_DEMO) {
+ assert(_part == 1);
+ } else {
+ assert(_part >= 0 && _part <= 4);
+ }
+
+ _disk->selectArchive(_partNames[_part]);
+
+ memset(_counters, 0, ARRAYSIZE(_counters));
+
+ _globalFlagsNames = _disk->loadTable("global");
+ _objectsNames = _disk->loadTable("objects");
+ _countersNames = _disk->loadTable("counters");
+
+ // TODO: maybe handle this into Disk
+ if (getPlatform() == Common::kPlatformPC) {
+ _char._objs = _disk->loadObjects("icone.ico");
+ } else {
+ _char._objs = _disk->loadObjects("icons.ico");
+ }
+
+ parseLocation("common");
+ }
+
+ freeLocation();
// load new location
parseLocation(location);
-
- // kFlagsRemove is cleared because the character defaults to visible on new locations
- // script command can hide the character, anyway, so that's why the flag is cleared
- // before _location._commands are executed
+ // kFlagsRemove is cleared because the character is visible by default.
+ // Commands can hide the character, anyway.
_char._ani->_flags &= ~kFlagsRemove;
-
_cmdExec->run(_location._commands);
-// doLocationEnterTransition();
+
+ doLocationEnterTransition();
+
_cmdExec->run(_location._aCommands);
_engineFlags &= ~kEngineChangeLocation;
}
-
// FIXME: Parallaction_br::parseLocation() is now a verbatim copy of the same routine from Parallaction_ns.
void Parallaction_br::parseLocation(const char *filename) {
debugC(1, kDebugParser, "parseLocation('%s')", filename);
@@ -359,30 +311,5 @@ void Parallaction_br::changeCharacter(const char *name) {
}
-void Parallaction_br::setArrowCursor() {
- // FIXME: Where are the Amiga cursors?
- if (getPlatform() == Common::kPlatformAmiga)
- return;
-
- Common::Rect r;
- _mouseArrow->getRect(0, r);
-
- _system->setMouseCursor(_mouseArrow->getData(0), r.width(), r.height(), 0, 0, 0);
- _system->showMouse(true);
-
- _input->_activeItem._id = 0;
-}
-
-void Parallaction_br::setInventoryCursor(ItemName name) {
- assert(name > 0);
-
- byte *src = _mouseArrow->getData(0);
- byte *dst = _comboArrow->getData(0);
- memcpy(dst, src, _comboArrow->getSize(0));
-
- // FIXME: destination offseting is not clear
- _inventoryRenderer->drawItem(name, dst + _mouseComboProps_BR._yOffset * _mouseComboProps_BR._width + _mouseComboProps_BR._xOffset, _mouseComboProps_BR._width);
- _system->setMouseCursor(dst, _mouseComboProps_BR._width, _mouseComboProps_BR._height, 0, 0, 0);
-}
} // namespace Parallaction
diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp
index eab08142d4..e0c86a4e37 100644
--- a/engines/parallaction/parallaction_ns.cpp
+++ b/engines/parallaction/parallaction_ns.cpp
@@ -28,30 +28,62 @@
#include "common/config-manager.h"
#include "parallaction/parallaction.h"
-#include "parallaction/gui.h"
-#include "parallaction/gui_ns.cpp"
#include "parallaction/input.h"
+#include "parallaction/saveload.h"
#include "parallaction/sound.h"
namespace Parallaction {
-#define MOUSEARROW_WIDTH 16
-#define MOUSEARROW_HEIGHT 16
+class LocationName {
-#define MOUSECOMBO_WIDTH 32 // sizes for cursor + selected inventory item
-#define MOUSECOMBO_HEIGHT 32
+ Common::String _slide;
+ Common::String _character;
+ Common::String _location;
-LocationName::LocationName() {
- _buf = 0;
- _hasSlide = false;
- _hasCharacter = false;
-}
+ bool _hasCharacter;
+ bool _hasSlide;
+ char *_buf;
+
+public:
+ LocationName() {
+ _buf = 0;
+ _hasSlide = false;
+ _hasCharacter = false;
+ }
+
+ ~LocationName() {
+ free(_buf);
+ }
+
+ void bind(const char*);
+
+ const char *location() const {
+ return _location.c_str();
+ }
+
+ bool hasCharacter() const {
+ return _hasCharacter;
+ }
+
+ const char *character() const {
+ return _character.c_str();
+ }
+
+ bool hasSlide() const {
+ return _hasSlide;
+ }
+
+ const char *slide() const {
+ return _slide.c_str();
+ }
+
+ const char *c_str() const {
+ return _buf;
+ }
+};
-LocationName::~LocationName() {
- free(_buf);
-}
/*
@@ -137,7 +169,6 @@ int Parallaction_ns::init() {
initResources();
initFonts();
- initCursors();
_locationParser = new LocationParser_ns(this);
_locationParser->init();
_programParser = new ProgramParser_ns(this);
@@ -158,6 +189,8 @@ int Parallaction_ns::init() {
_location._animations.push_front(_char._ani);
+ _saveLoad = new SaveLoad_ns(this, _saveFileMan);
+
Parallaction::init();
return 0;
@@ -183,32 +216,6 @@ void Parallaction_ns::freeFonts() {
}
-void Parallaction_ns::initCursors() {
- _comboArrow = _disk->loadPointer("pointer");
- _mouseArrow = _resMouseArrow;
-}
-
-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
- _input->stopHovering();
- _input->_activeItem._id = 0;
-
- _system->setMouseCursor(_mouseArrow, MOUSEARROW_WIDTH, MOUSEARROW_HEIGHT, 0, 0, 0);
-}
-
-void Parallaction_ns::setInventoryCursor(ItemName name) {
- assert(name > 0);
-
- byte *v8 = _comboArrow->getData(0);
-
- // FIXME: destination offseting is not clear
- _inventoryRenderer->drawItem(name, v8 + 7 * MOUSECOMBO_WIDTH + 7, MOUSECOMBO_WIDTH);
- _system->setMouseCursor(v8, MOUSECOMBO_WIDTH, MOUSECOMBO_HEIGHT, 0, 0, 0);
-}
-
void Parallaction_ns::callFunction(uint index, void* parm) {
assert(index < 25); // magic value 25 is maximum # of callables for Nippon Safes
@@ -218,30 +225,12 @@ void Parallaction_ns::callFunction(uint index, void* parm) {
int Parallaction_ns::go() {
- renameOldSavefiles();
+ _saveLoad->renameOldSavefiles();
_globalFlagsNames = _disk->loadTable("global");
- // If requested, load a savegame instead of showing the intro
- if (ConfMan.hasKey("save_slot")) {
- _gameToLoad = ConfMan.getInt("save_slot");
- if (_gameToLoad < 0 || _gameToLoad > 99)
- _gameToLoad = -1;
- }
- if (_gameToLoad == -1) {
- startGui();
- } else {
- _disk->selectArchive((getFeatures() & GF_DEMO) ? "disk0" : "disk1");
-
- _menuHelper = new MenuInputHelper;
- assert(_menuHelper);
- new ChooseLanguageInputState_NS(this, _menuHelper);
- _menuHelper->setState("chooselanguage");
-
- _input->_inputMode = Input::kInputModeMenu;
- doLoadGame(_gameToLoad);
- }
-
+ startGui();
+
while (!quit()) {
runGame();
}
@@ -262,7 +251,7 @@ void Parallaction_ns::switchBackground(const char* background, const char* mask)
v2 += 4;
}
- g_system->delayMillis(20);
+ _vm->_system->delayMillis(20);
_gfx->setPalette(pal);
_gfx->updateScreen();
}
@@ -273,16 +262,6 @@ void Parallaction_ns::switchBackground(const char* background, const char* mask)
}
-void Parallaction_ns::showSlide(const char *name, int x, int y) {
- BackgroundInfo *info = new BackgroundInfo;
- _disk->loadSlide(*info, name);
-
- info->x = (x == CENTER_LABEL_HORIZONTAL) ? ((_vm->_screenWidth - info->width) >> 1) : x;
- info->y = (y == CENTER_LABEL_VERTICAL) ? ((_vm->_screenHeight - info->height) >> 1) : y;
-
- _gfx->setBackground(kBackgroundSlide, info);
-}
-
void Parallaction_ns::runPendingZones() {
if (_activeZone) {
ZonePtr z = _activeZone; // speak Zone or sound
@@ -307,7 +286,7 @@ void Parallaction_ns::changeLocation(char *location) {
_zoneTrap = nullZonePtr;
- setArrowCursor();
+ _input->setArrowCursor();
_gfx->showGfxObj(_char._ani->gfxobj, false);
_location._animations.remove(_char._ani);
@@ -448,6 +427,7 @@ void Parallaction_ns::changeCharacter(const char *name) {
}
void Parallaction_ns::cleanupGame() {
+ _inTestResult = false;
_engineFlags &= ~kEngineTransformedDonna;
@@ -472,6 +452,10 @@ void Parallaction_ns::cleanupGame() {
_location._animations.push_front(_char._ani);
_score = 0;
+ _soundMan->stopMusic();
+ _introSarcData3 = 200;
+ _introSarcData2 = 1;
+
return;
}
diff --git a/engines/parallaction/parser.cpp b/engines/parallaction/parser.cpp
index 8e30a631e4..a475f5701a 100644
--- a/engines/parallaction/parser.cpp
+++ b/engines/parallaction/parser.cpp
@@ -183,13 +183,12 @@ uint16 Script::readLineToken(bool errorOnEOF) {
clearTokens();
- bool inBlockComment = false, inLineComment;
+ bool inBlockComment = false;
char buf[200];
char *line = NULL;
+ char *start;
do {
- inLineComment = false;
-
line = readLine(buf, 200);
if (line == NULL) {
@@ -198,21 +197,27 @@ uint16 Script::readLineToken(bool errorOnEOF) {
else
return 0;
}
- line = Common::ltrim(line);
+ start = Common::ltrim(line);
- if (isCommentLine(line)) {
- inLineComment = true;
+ if (isCommentLine(start)) {
+ // ignore this line
+ start[0] = '\0';
} else
- if (isStartOfCommentBlock(line)) {
+ if (isStartOfCommentBlock(start)) {
+ // mark this and the following lines as comment
inBlockComment = true;
} else
- if (isEndOfCommentBlock(line)) {
+ if (isEndOfCommentBlock(start)) {
+ // comment is finished, so stop ignoring
inBlockComment = false;
+ // the current line must be skipped, though,
+ // as it contains the end-of-comment marker
+ start[0] = '\0';
}
- } while (inLineComment || inBlockComment || strlen(line) == 0);
+ } while (inBlockComment || strlen(start) == 0);
- return fillTokens(line);
+ return fillTokens(start);
}
@@ -403,7 +408,9 @@ void PreProcessor::preprocessScript(Script &script, StatementList &list) {
break;
StatementDef *def = findDef(_tokens[0]);
- assert(def);
+ if (!def) {
+ error("PreProcessor::preprocessScript: unknown statement '%s' found\n", _tokens[0]);
+ }
text = def->makeLine(script);
int score = getDefScore(def);
diff --git a/engines/parallaction/parser.h b/engines/parallaction/parser.h
index e622bfd81f..7bf41b2bea 100644
--- a/engines/parallaction/parser.h
+++ b/engines/parallaction/parser.h
@@ -27,6 +27,7 @@
#define PARALLACTION_PARSER_H
#include "common/stream.h"
+#include "common/stack.h"
#include "parallaction/objects.h"
#include "parallaction/walk.h"
diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp
index 20800abc33..4b11c5caa4 100644
--- a/engines/parallaction/parser_br.cpp
+++ b/engines/parallaction/parser_br.cpp
@@ -497,7 +497,7 @@ DECLARE_LOCATION_PARSER(zeta) {
_vm->_location._zeta1 = atoi(_tokens[2]);
if (_tokens[3][0] != '\0') {
- _vm->_location._zeta2 = atoi(_tokens[1]);
+ _vm->_location._zeta2 = atoi(_tokens[3]);
} else {
_vm->_location._zeta2 = 50;
}
diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp
index ed3812e5be..b59863947e 100644
--- a/engines/parallaction/saveload.cpp
+++ b/engines/parallaction/saveload.cpp
@@ -31,6 +31,7 @@
#include "gui/message.h"
#include "parallaction/parallaction.h"
+#include "parallaction/saveload.h"
#include "parallaction/sound.h"
@@ -57,12 +58,11 @@ protected:
GUI::StaticTextWidget *_time;
GUI::StaticTextWidget *_playtime;
GUI::ContainerWidget *_container;
- Parallaction_ns *_vm;
uint8 _fillR, _fillG, _fillB;
public:
- SaveLoadChooser(const String &title, const String &buttonLabel, Parallaction_ns *engine);
+ SaveLoadChooser(const String &title, const String &buttonLabel);
~SaveLoadChooser();
virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
@@ -73,34 +73,39 @@ public:
virtual void reflowLayout();
};
-Common::String Parallaction_ns::genSaveFileName(uint slot, bool oldStyle) {
+Common::String SaveLoad_ns::genOldSaveFileName(uint slot) {
assert(slot < NUM_SAVESLOTS || slot == SPECIAL_SAVESLOT);
char s[20];
- sprintf(s, (oldStyle ? "game.%i" : "nippon.%.3d"), slot );
+ sprintf(s, "game.%i", slot);
return Common::String(s);
}
-Common::InSaveFile *Parallaction_ns::getInSaveFile(uint slot) {
+
+Common::String SaveLoad::genSaveFileName(uint slot) {
+ assert(slot < NUM_SAVESLOTS || slot == SPECIAL_SAVESLOT);
+
+ char s[20];
+ sprintf(s, "%s.%.3d", _saveFilePrefix.c_str(), slot);
+
+ return Common::String(s);
+}
+
+Common::InSaveFile *SaveLoad::getInSaveFile(uint slot) {
Common::String name = genSaveFileName(slot);
return _saveFileMan->openForLoading(name.c_str());
}
-Common::OutSaveFile *Parallaction_ns::getOutSaveFile(uint slot) {
+Common::OutSaveFile *SaveLoad::getOutSaveFile(uint slot) {
Common::String name = genSaveFileName(slot);
return _saveFileMan->openForSaving(name.c_str());
}
-void Parallaction_ns::doLoadGame(uint16 slot) {
-
- _soundMan->stopMusic();
+void SaveLoad_ns::doLoadGame(uint16 slot) {
- cleanupGame();
-
- _introSarcData3 = 200;
- _introSarcData2 = 1;
+ _vm->cleanupGame();
Common::InSaveFile *f = getInSaveFile(slot);
if (!f) return;
@@ -116,10 +121,10 @@ void Parallaction_ns::doLoadGame(uint16 slot) {
f->readLine(l, 15);
f->readLine(s, 15);
- _location._startPosition.x = atoi(s);
+ _vm->_location._startPosition.x = atoi(s);
f->readLine(s, 15);
- _location._startPosition.y = atoi(s);
+ _vm->_location._startPosition.y = atoi(s);
f->readLine(s, 15);
_score = atoi(s);
@@ -134,26 +139,24 @@ void Parallaction_ns::doLoadGame(uint16 slot) {
// kChangeLocation will trigger a complete deletion. Anyway, we still
// need to invoke freeZones here with _quit set, because the
// call in changeLocation preserve certain zones.
- _quit = true;
-
- freeZones();
-
- _quit = false;
+ _vm->_quit = true;
+ _vm->freeZones();
+ _vm->_quit = false;
- _numLocations = atoi(s);
+ _vm->_numLocations = atoi(s);
uint16 _si;
- for (_si = 0; _si < _numLocations; _si++) {
+ for (_si = 0; _si < _vm->_numLocations; _si++) {
f->readLine(s, 20);
s[strlen(s)] = '\0';
- strcpy(_locationNames[_si], s);
+ strcpy(_vm->_locationNames[_si], s);
f->readLine(s, 15);
- _localFlags[_si] = atoi(s);
+ _vm->_localFlags[_si] = atoi(s);
}
- cleanInventory(false);
+ _vm->cleanInventory(false);
ItemName name;
uint32 value;
@@ -164,24 +167,24 @@ void Parallaction_ns::doLoadGame(uint16 slot) {
f->readLine(s, 15);
name = atoi(s);
- addInventoryItem(name, value);
+ _vm->addInventoryItem(name, value);
}
delete f;
// force reload of character to solve inventory
// bugs, but it's a good maneuver anyway
- strcpy(_characterName1, "null");
+ strcpy(_vm->_characterName1, "null");
char tmp[PATH_LEN];
sprintf(tmp, "%s.%s" , l, n);
- scheduleLocationSwitch(tmp);
+ _vm->scheduleLocationSwitch(tmp);
return;
}
-void Parallaction_ns::doSaveGame(uint16 slot, const char* name) {
+void SaveLoad_ns::doSaveGame(uint16 slot, const char* name) {
Common::OutSaveFile *f = getOutSaveFile(slot);
if (f == 0) {
@@ -204,30 +207,30 @@ void Parallaction_ns::doSaveGame(uint16 slot, const char* name) {
f->writeString(s);
f->writeString("\n");
- sprintf(s, "%s\n", _char.getFullName());
+ sprintf(s, "%s\n", _vm->_char.getFullName());
f->writeString(s);
sprintf(s, "%s\n", _saveData1);
f->writeString(s);
- sprintf(s, "%d\n", _char._ani->getX());
+ sprintf(s, "%d\n", _vm->_char._ani->getX());
f->writeString(s);
- sprintf(s, "%d\n", _char._ani->getY());
+ sprintf(s, "%d\n", _vm->_char._ani->getY());
f->writeString(s);
sprintf(s, "%d\n", _score);
f->writeString(s);
sprintf(s, "%u\n", _globalFlags);
f->writeString(s);
- sprintf(s, "%d\n", _numLocations);
+ sprintf(s, "%d\n", _vm->_numLocations);
f->writeString(s);
- for (uint16 _si = 0; _si < _numLocations; _si++) {
- sprintf(s, "%s\n%u\n", _locationNames[_si], _localFlags[_si]);
+ for (uint16 _si = 0; _si < _vm->_numLocations; _si++) {
+ sprintf(s, "%s\n%u\n", _vm->_locationNames[_si], _vm->_localFlags[_si]);
f->writeString(s);
}
const InventoryItem *item;
for (uint16 _si = 0; _si < 30; _si++) {
- item = getInventoryItem(_si);
+ item = _vm->getInventoryItem(_si);
sprintf(s, "%u\n%d\n", item->_id, item->_index);
f->writeString(s);
}
@@ -249,8 +252,8 @@ enum {
};
-SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel, Parallaction_ns *engine)
- : Dialog("scummsaveload"), _list(0), _chooseButton(0), _gfxWidget(0), _vm(engine) {
+SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel)
+ : Dialog("scummsaveload"), _list(0), _chooseButton(0), _gfxWidget(0) {
// _drawingHints |= GUI::THEME_HINT_SPECIAL_COLOR;
@@ -337,7 +340,7 @@ void SaveLoadChooser::reflowLayout() {
Dialog::reflowLayout();
}
-int Parallaction_ns::buildSaveFileList(Common::StringList& l) {
+int SaveLoad_ns::buildSaveFileList(Common::StringList& l) {
char buf[200];
@@ -361,9 +364,9 @@ int Parallaction_ns::buildSaveFileList(Common::StringList& l) {
}
-int Parallaction_ns::selectSaveFile(uint16 arg_0, const char* caption, const char* button) {
+int SaveLoad_ns::selectSaveFile(uint16 arg_0, const char* caption, const char* button) {
- SaveLoadChooser* slc = new SaveLoadChooser(caption, button, this);
+ SaveLoadChooser* slc = new SaveLoadChooser(caption, button);
Common::StringList l;
@@ -382,7 +385,7 @@ int Parallaction_ns::selectSaveFile(uint16 arg_0, const char* caption, const cha
-bool Parallaction_ns::loadGame() {
+bool SaveLoad_ns::loadGame() {
int _di = selectSaveFile( 0, "Load file", "Load" );
if (_di == -1) {
@@ -394,15 +397,15 @@ bool Parallaction_ns::loadGame() {
GUI::TimedMessageDialog dialog("Loading game...", 1500);
dialog.runModal();
- setArrowCursor();
+ _vm->_input->setArrowCursor();
return true;
}
-bool Parallaction_ns::saveGame() {
+bool SaveLoad_ns::saveGame() {
- if (!scumm_stricmp(_location._name, "caveau")) {
+ if (!scumm_stricmp(_vm->_location._name, "caveau")) {
return false;
}
@@ -420,7 +423,7 @@ bool Parallaction_ns::saveGame() {
}
-void Parallaction_ns::setPartComplete(const Character& character) {
+void SaveLoad_ns::setPartComplete(const char *part) {
char buf[30];
bool alreadyPresent = false;
@@ -431,7 +434,7 @@ void Parallaction_ns::setPartComplete(const Character& character) {
inFile->readLine(buf, 29);
delete inFile;
- if (strstr(buf, character.getBaseName())) {
+ if (strstr(buf, part)) {
alreadyPresent = true;
}
}
@@ -439,7 +442,7 @@ void Parallaction_ns::setPartComplete(const Character& character) {
if (!alreadyPresent) {
Common::OutSaveFile *outFile = getOutSaveFile(SPECIAL_SAVESLOT);
outFile->writeString(buf);
- outFile->writeString(character.getBaseName());
+ outFile->writeString(part);
outFile->finalize();
delete outFile;
}
@@ -447,17 +450,20 @@ void Parallaction_ns::setPartComplete(const Character& character) {
return;
}
-bool Parallaction_ns::allPartsComplete() {
- char buf[30];
+void SaveLoad_ns::getGamePartProgress(bool *complete, int size) {
+ assert(complete && size >= 3);
+ char buf[30];
Common::InSaveFile *inFile = getInSaveFile(SPECIAL_SAVESLOT);
inFile->readLine(buf, 29);
delete inFile;
- return strstr(buf, "dino") && strstr(buf, "donna") && strstr(buf, "dough");
+ complete[0] = strstr(buf, "dino");
+ complete[1] = strstr(buf, "donna");
+ complete[2] = strstr(buf, "dough");
}
-void Parallaction_ns::renameOldSavefiles() {
+void SaveLoad_ns::renameOldSavefiles() {
bool exists[NUM_SAVESLOTS];
uint num = 0;
@@ -465,7 +471,7 @@ void Parallaction_ns::renameOldSavefiles() {
for (i = 0; i < NUM_SAVESLOTS; i++) {
exists[i] = false;
- Common::String name = genSaveFileName(i, true);
+ Common::String name = genOldSaveFileName(i);
Common::InSaveFile *f = _saveFileMan->openForLoading(name.c_str());
if (f) {
exists[i] = true;
@@ -493,8 +499,8 @@ void Parallaction_ns::renameOldSavefiles() {
uint success = 0;
for (i = 0; i < NUM_SAVESLOTS; i++) {
if (exists[i]) {
- Common::String oldName = genSaveFileName(i, true);
- Common::String newName = genSaveFileName(i, false);
+ Common::String oldName = genOldSaveFileName(i);
+ Common::String newName = genSaveFileName(i);
if (_saveFileMan->renameSavefile(oldName.c_str(), newName.c_str())) {
success++;
} else {
@@ -520,4 +526,28 @@ void Parallaction_ns::renameOldSavefiles() {
}
+bool SaveLoad_br::loadGame() {
+ // TODO: implement loadgame
+ return false;
+}
+
+bool SaveLoad_br::saveGame() {
+ // TODO: implement savegame
+ return false;
+}
+
+void SaveLoad_br::getGamePartProgress(bool *complete, int size) {
+ assert(complete && size >= 3);
+
+ // TODO: implement progress loading
+
+ complete[0] = true;
+ complete[1] = true;
+ complete[2] = true;
+}
+
+void SaveLoad_br::setPartComplete(const char *part) {
+ // TODO: implement progress saving
+}
+
} // namespace Parallaction
diff --git a/engines/parallaction/saveload.h b/engines/parallaction/saveload.h
new file mode 100644
index 0000000000..10bb8aafc2
--- /dev/null
+++ b/engines/parallaction/saveload.h
@@ -0,0 +1,96 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+
+#ifndef PARALLACTION_SAVELOAD_H
+#define PARALLACTION_SAVELOAD_H
+
+namespace Parallaction {
+
+struct Character;
+
+
+class SaveLoad {
+
+protected:
+ Common::SaveFileManager *_saveFileMan;
+ Common::String _saveFilePrefix;
+
+ Common::String genSaveFileName(uint slot);
+ Common::InSaveFile *getInSaveFile(uint slot);
+ Common::OutSaveFile *getOutSaveFile(uint slot);
+
+public:
+ SaveLoad(Common::SaveFileManager* saveFileMan, const char *prefix) : _saveFileMan(saveFileMan), _saveFilePrefix(prefix) { }
+ virtual ~SaveLoad() { }
+
+ virtual bool loadGame() = 0;
+ virtual bool saveGame() = 0;
+ virtual void getGamePartProgress(bool *complete, int size) = 0;
+ virtual void setPartComplete(const char *part) = 0;
+
+ virtual void renameOldSavefiles() { }
+};
+
+class SaveLoad_ns : public SaveLoad {
+
+ Parallaction_ns *_vm;
+
+ Common::String _saveFileName;
+ Common::String genOldSaveFileName(uint slot);
+
+protected:
+ void renameOldSavefiles();
+ void doLoadGame(uint16 slot);
+ void doSaveGame(uint16 slot, const char* name);
+ int buildSaveFileList(Common::StringList& l);
+ int selectSaveFile(uint16 arg_0, const char* caption, const char* button);
+
+public:
+ SaveLoad_ns(Parallaction_ns *vm, Common::SaveFileManager *saveFileMan) : SaveLoad(saveFileMan, "nippon"), _vm(vm) { }
+
+ virtual bool loadGame();
+ virtual bool saveGame();
+ virtual void getGamePartProgress(bool *complete, int size);
+ virtual void setPartComplete(const char *part);
+};
+
+class SaveLoad_br : public SaveLoad {
+
+ Parallaction_br *_vm;
+
+public:
+ SaveLoad_br(Parallaction_br *vm, Common::SaveFileManager *saveFileMan) : SaveLoad(saveFileMan, "bra"), _vm(vm) { }
+
+ virtual bool loadGame();
+ virtual bool saveGame();
+ virtual void getGamePartProgress(bool *complete, int size);
+ virtual void setPartComplete(const char *part);
+};
+
+
+} // namespace Parallaction
+
+#endif
diff --git a/engines/parallaction/sound.cpp b/engines/parallaction/sound.cpp
index 4ac1399c3a..df6867a90c 100644
--- a/engines/parallaction/sound.cpp
+++ b/engines/parallaction/sound.cpp
@@ -387,8 +387,7 @@ void AmigaSoundMan::playSfx(const char *filename, uint channel, bool looping, in
rate = ch->header.samplesPerSec;
}
- _mixer->playRaw(Audio::Mixer::kSFXSoundType, &ch->handle, ch->data, ch->dataSize, rate, flags, -1,
- Audio::Mixer::kMaxChannelVolume, 0, loopStart, loopEnd);
+ _mixer->playRaw(Audio::Mixer::kSFXSoundType, &ch->handle, ch->data, ch->dataSize, rate, flags, -1, volume, 0, loopStart, loopEnd);
}
void AmigaSoundMan::stopSfx(uint channel) {
diff --git a/engines/parallaction/staticres.cpp b/engines/parallaction/staticres.cpp
index 2c5cf281dd..071495e8f1 100644
--- a/engines/parallaction/staticres.cpp
+++ b/engines/parallaction/staticres.cpp
@@ -29,7 +29,7 @@
namespace Parallaction {
-byte Parallaction_ns::_resMouseArrow[256] = {
+byte Input::_resMouseArrow_NS[256] = {
0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x00, 0x00,
0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x00, 0x00, 0x00,
0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x00, 0x00, 0x00, 0x00,
@@ -335,12 +335,6 @@ const Parallaction_br::Callable Parallaction_br::_dosCallables[] = {
void Parallaction_ns::initResources() {
-// _zoneFlagNamesRes = _zoneFlagNamesRes_ns;
-// _zoneTypeNamesRes = _zoneTypeNamesRes_ns;
-// _commandsNamesRes = _commandsNamesRes_ns;
- _callableNamesRes = _callableNamesRes_ns;
-// _instructionNamesRes = _instructionNamesRes_ns;
-
_callableNames = new Table(ARRAYSIZE(_callableNamesRes_ns), _callableNamesRes_ns);
_localFlagNames = new FixedTable(NUM_LOCATIONS, 1);
@@ -356,13 +350,6 @@ void Parallaction_ns::initResources() {
void Parallaction_br::initResources() {
-// _zoneFlagNamesRes = _zoneFlagNamesRes_br;
-// _zoneTypeNamesRes = _zoneTypeNamesRes_br;
-// _commandsNamesRes = _commandsNamesRes_br;
- _callableNamesRes = _callableNamesRes_br;
-// _instructionNamesRes = _instructionNamesRes_br;
-// _audioCommandsNamesRes = _audioCommandsNamesRes_br;
-
_callableNames = new Table(ARRAYSIZE(_callableNamesRes_br), _callableNamesRes_br);
_localFlagNames = new FixedTable(NUM_LOCATIONS, 2);