aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction
diff options
context:
space:
mode:
authorTony Puccinelli2010-08-11 01:11:16 +0000
committerTony Puccinelli2010-08-11 01:11:16 +0000
commit3a7a0ba720f219c4780cf19d196cda9c0456a20b (patch)
treefe7f45242447dc7d14447babbdea9fbbb771c506 /engines/parallaction
parent6543062e5701e8011a4b12abffa8afca56f30b3f (diff)
parentfffec23a02cc88ed8daba0a3b50007b7e220c075 (diff)
downloadscummvm-rg350-3a7a0ba720f219c4780cf19d196cda9c0456a20b.tar.gz
scummvm-rg350-3a7a0ba720f219c4780cf19d196cda9c0456a20b.tar.bz2
scummvm-rg350-3a7a0ba720f219c4780cf19d196cda9c0456a20b.zip
manually merged engines from trunk into branch
svn-id: r51964
Diffstat (limited to 'engines/parallaction')
-rw-r--r--engines/parallaction/debug.cpp27
-rw-r--r--engines/parallaction/debug.h1
-rw-r--r--engines/parallaction/dialogue.cpp4
-rw-r--r--engines/parallaction/exec_br.cpp2
-rw-r--r--engines/parallaction/graphics.cpp6
-rw-r--r--engines/parallaction/input.cpp15
-rw-r--r--engines/parallaction/objects.h4
-rw-r--r--engines/parallaction/parallaction.cpp112
-rw-r--r--engines/parallaction/parallaction.h2
-rw-r--r--engines/parallaction/parallaction_br.cpp4
-rw-r--r--engines/parallaction/parser.cpp9
-rw-r--r--engines/parallaction/parser_ns.cpp2
-rw-r--r--engines/parallaction/sound_br.cpp4
13 files changed, 137 insertions, 55 deletions
diff --git a/engines/parallaction/debug.cpp b/engines/parallaction/debug.cpp
index 8864c84e2f..b5eb82b456 100644
--- a/engines/parallaction/debug.cpp
+++ b/engines/parallaction/debug.cpp
@@ -42,6 +42,7 @@ Debugger::Debugger(Parallaction *vm)
DCmd_Register("zones", WRAP_METHOD(Debugger, Cmd_Zones));
DCmd_Register("animations", WRAP_METHOD(Debugger, Cmd_Animations));
DCmd_Register("globalflags",WRAP_METHOD(Debugger, Cmd_GlobalFlags));
+ DCmd_Register("toggleglobalflag",WRAP_METHOD(Debugger, Cmd_ToggleGlobalFlag));
DCmd_Register("localflags", WRAP_METHOD(Debugger, Cmd_LocalFlags));
DCmd_Register("locations", WRAP_METHOD(Debugger, Cmd_Locations));
DCmd_Register("gfxobjects", WRAP_METHOD(Debugger, Cmd_GfxObjects));
@@ -117,6 +118,32 @@ bool Debugger::Cmd_GlobalFlags(int argc, const char **argv) {
return true;
}
+bool Debugger::Cmd_ToggleGlobalFlag(int argc, const char **argv) {
+
+ int i;
+
+ switch (argc) {
+ case 2:
+ i = _vm->_globalFlagsNames->lookup(argv[1]);
+ if (i == Table::notFound) {
+ DebugPrintf("invalid flag '%s'\n", argv[1]);
+ } else {
+ i--;
+ if ((_globalFlags & (1 << i)) == 0)
+ _globalFlags |= (1 << i);
+ else
+ _globalFlags &= ~(1 << i);
+ }
+ break;
+
+ default:
+ DebugPrintf("toggleglobalflag <flag name>\n");
+
+ }
+
+ return true;
+}
+
bool Debugger::Cmd_LocalFlags(int argc, const char **argv) {
uint32 flags = _vm->getLocationFlags();
diff --git a/engines/parallaction/debug.h b/engines/parallaction/debug.h
index 54b578e95f..5267206d04 100644
--- a/engines/parallaction/debug.h
+++ b/engines/parallaction/debug.h
@@ -28,6 +28,7 @@ protected:
bool Cmd_Animations(int argc, const char **argv);
bool Cmd_LocalFlags(int argc, const char **argv);
bool Cmd_GlobalFlags(int argc, const char **argv);
+ bool Cmd_ToggleGlobalFlag(int argc, const char **argv);
bool Cmd_Locations(int argc, const char **argv);
bool Cmd_GfxObjects(int argc, const char **argv);
bool Cmd_Programs(int argc, const char** argv);
diff --git a/engines/parallaction/dialogue.cpp b/engines/parallaction/dialogue.cpp
index 6332600226..7a28d18f17 100644
--- a/engines/parallaction/dialogue.cpp
+++ b/engines/parallaction/dialogue.cpp
@@ -461,6 +461,10 @@ public:
void Parallaction::enterDialogueMode(ZonePtr z) {
+ if (!z->u._speakDialogue) {
+ return;
+ }
+
debugC(1, kDebugDialogue, "Parallaction::enterDialogueMode(%s)", z->u._filename.c_str());
_dialogueMan = createDialogueManager(z);
assert(_dialogueMan);
diff --git a/engines/parallaction/exec_br.cpp b/engines/parallaction/exec_br.cpp
index 13c1318123..1d8724e2d8 100644
--- a/engines/parallaction/exec_br.cpp
+++ b/engines/parallaction/exec_br.cpp
@@ -337,7 +337,7 @@ DECLARE_COMMAND_OPCODE(speak) {
return;
}
- if (ACTIONTYPE(ctxt._cmd->_zone) == kZoneSpeak) {
+ if (ACTIONTYPE(ctxt._cmd->_zone) == kZoneSpeak && ctxt._cmd->_zone->u._speakDialogue) {
_vm->enterDialogueMode(ctxt._cmd->_zone);
} else {
_vm->_activeZone = ctxt._cmd->_zone;
diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp
index 326ae2c519..2990d024d2 100644
--- a/engines/parallaction/graphics.cpp
+++ b/engines/parallaction/graphics.cpp
@@ -538,12 +538,12 @@ GfxObj *Gfx::renderFloatingLabel(Font *font, char *text) {
setupLabelSurface(*cnv, w, h);
- font->setColor((_vm->getGameType() == GType_BRA) ? 0 : 7);
+ font->setColor((_gameType == GType_BRA) ? 0 : 7);
font->drawString((byte*)cnv->pixels + 1, cnv->w, text);
font->drawString((byte*)cnv->pixels + 1 + cnv->w * 2, cnv->w, text);
font->drawString((byte*)cnv->pixels + cnv->w, cnv->w, text);
font->drawString((byte*)cnv->pixels + 2 + cnv->w, cnv->w, text);
- font->setColor((_vm->getGameType() == GType_BRA) ? 11 : 1);
+ font->setColor((_gameType == GType_BRA) ? 11 : 1);
font->drawString((byte*)cnv->pixels + 1 + cnv->w, cnv->w, text);
} else {
w = font->getStringWidth(text);
@@ -835,7 +835,7 @@ void Gfx::setBackground(uint type, BackgroundInfo *info) {
// The PC version of BRA needs the entries 20-31 of the palette to be constant, but
// the background resource files are screwed up. The right colors come from an unused
// bitmap (pointer.bmp). Nothing is known about the Amiga version so far.
- if ((_vm->getGameType() == GType_BRA) && (_vm->getPlatform() == Common::kPlatformPC)) {
+ if ((_gameType == GType_BRA) && (_vm->getPlatform() == Common::kPlatformPC)) {
int r, g, b;
for (uint i = 16; i < 32; i++) {
_backupPal.getEntry(i, r, g, b);
diff --git a/engines/parallaction/input.cpp b/engines/parallaction/input.cpp
index 7ad1be8681..ca8f358158 100644
--- a/engines/parallaction/input.cpp
+++ b/engines/parallaction/input.cpp
@@ -203,13 +203,13 @@ int Input::updateGameInput() {
return event;
}
- if (_vm->getGameType() == GType_Nippon) {
+ if (_gameType == GType_Nippon) {
if (_hasKeyPressEvent && (_vm->getFeatures() & GF_DEMO) == 0) {
if (_keyPressed.keycode == Common::KEYCODE_l) event = kEvLoadGame;
if (_keyPressed.keycode == Common::KEYCODE_s) event = kEvSaveGame;
}
} else
- if (_vm->getGameType() == GType_BRA) {
+ if (_gameType == GType_BRA) {
if (_hasKeyPressEvent && (_vm->getFeatures() & GF_DEMO) == 0) {
if (_keyPressed.keycode == Common::KEYCODE_F5) event = kEvIngameMenu;
}
@@ -325,8 +325,13 @@ bool Input::translateGameInput() {
if ((_mouseButtons == kMouseLeftUp) && ((_activeItem._id != 0) || (ACTIONTYPE(z) == kZoneCommand))) {
- if (z->_flags & kFlagsNoWalk) {
- // character doesn't need to walk to take specified action
+ bool noWalk = z->_flags & kFlagsNoWalk; // check the explicit no-walk flag
+ if (_gameType == GType_BRA) {
+ // action performed on object marked for self-use do not need walk in BRA
+ noWalk |= ((z->_flags & kFlagsYourself) != 0);
+ }
+
+ if (noWalk) {
takeAction(z);
} else {
// action delayed: if Zone defined a moveto position the character is programmed to move there,
@@ -351,7 +356,7 @@ bool Input::translateGameInput() {
void Input::enterInventoryMode() {
Common::Point mousePos;
- getCursorPos(mousePos);
+ getAbsoluteCursorPos(mousePos);
bool hitCharacter = _vm->hitZone(kZoneYou, mousePos.x, mousePos.y);
if (hitCharacter) {
diff --git a/engines/parallaction/objects.h b/engines/parallaction/objects.h
index 50a789247f..36231cfcc5 100644
--- a/engines/parallaction/objects.h
+++ b/engines/parallaction/objects.h
@@ -88,9 +88,9 @@ enum ZoneFlags {
kFlagsNoWalk = 0x800, // Zone: character doesn't need to walk towards object to interact
// BRA specific
- kFlagsYourself = 0x1000,
+ kFlagsYourself = 0x1000, // BRA: marks zones used by the character on him/herself
kFlagsScaled = 0x2000,
- kFlagsSelfuse = 0x4000,
+ kFlagsSelfuse = 0x4000, // BRA: marks zones to be preserved across location changes (see Parallaction::freeZones)
kFlagsIsAnimation = 0x1000000, // BRA: used in walk code (trap check), to tell is a Zone is an Animation
kFlagsAnimLinked = 0x2000000
};
diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
index cb208a17ff..ce7525345a 100644
--- a/engines/parallaction/parallaction.cpp
+++ b/engines/parallaction/parallaction.cpp
@@ -102,7 +102,8 @@ Parallaction::~Parallaction() {
Common::Error Parallaction::init() {
-
+
+ _gameType = getGameType();
_engineFlags = 0;
_objectsNames = NULL;
_globalFlagsNames = NULL;
@@ -408,7 +409,7 @@ void Parallaction::drawAnimation(AnimationPtr anim) {
uint16 layer = LAYER_FOREGROUND;
uint16 scale = 100;
- switch (getGameType()) {
+ switch (_gameType) {
case GType_Nippon:
if ((anim->_flags & kFlagsNoMasked) == 0) {
// Layer in NS depends on where the animation is on the screen, for each animation.
@@ -523,7 +524,7 @@ void Parallaction::enterCommentMode(ZonePtr z) {
}
// TODO: move this balloons stuff into DialogueManager and BalloonManager
- if (getGameType() == GType_Nippon) {
+ if (_gameType == GType_Nippon) {
if (!data->_filename.empty()) {
if (data->_gfxobj == 0) {
data->_gfxobj = _disk->loadStatic(data->_filename.c_str());
@@ -540,7 +541,7 @@ void Parallaction::enterCommentMode(ZonePtr z) {
_gfx->setItem(_char._talk, 190, 80);
}
} else
- if (getGameType() == GType_BRA) {
+ if (_gameType == GType_BRA) {
_balloonMan->setSingleBalloon(data->_examineText.c_str(), 0, 0, 1, BalloonManager::kNormalColor);
_gfx->setItem(_char._talk, 10, 80);
}
@@ -651,13 +652,21 @@ bool Parallaction::pickupItem(ZonePtr z) {
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;
+ // check if really a special zone
+ if (_gameType == GType_Nippon) {
+ // so-called special zones in NS have special x coordinates
+ if ((z->getX() != -2) && (z->getX() != -3)) {
+ return false;
+ }
}
-
+ if (_gameType == GType_BRA) {
+ // so far, special zones in BRA are only merge zones
+ if (ACTIONTYPE(z) != kZoneMerge) {
+ 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.
@@ -681,7 +690,33 @@ bool Parallaction::checkSpecialZoneBox(ZonePtr z, uint32 type, uint x, uint y) {
return false;
}
-// FIXME: input coordinates must be offseted to handle scrolling!
+bool Parallaction::checkZoneType(ZonePtr z, uint32 type) {
+ if (_gameType == GType_Nippon) {
+ if ((type == 0) && (ITEMTYPE(z) == 0))
+ return true;
+ }
+
+ if (_gameType == GType_BRA) {
+ if (type == 0) {
+ if (ITEMTYPE(z) == 0) {
+ if (ACTIONTYPE(z) != kZonePath) {
+ return true;
+ }
+ }
+ if (ACTIONTYPE(z) == kZoneDoor) {
+ return true;
+ }
+ }
+ }
+
+ if (z->_type == type)
+ return true;
+ if (ITEMTYPE(z) == type)
+ return true;
+
+ return false;
+}
+
bool Parallaction::checkZoneBox(ZonePtr z, uint32 type, uint x, uint y) {
if (z->_flags & kFlagsRemove)
return false;
@@ -689,29 +724,30 @@ bool Parallaction::checkZoneBox(ZonePtr z, uint32 type, uint x, uint y) {
debugC(5, kDebugExec, "checkZoneBox for %s (type = %x, x = %i, y = %i)", z->_name, type, x, y);
if (!z->hitRect(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 (!_char._ani->hitFrameRect(x, y))
+ // check if self-use zone (nothing to do with kFlagsSelfuse)
+ if (_gameType == GType_Nippon) {
+ if (z->getX() != -1) { // no explicit self-use flag in NS
+ return false;
+ }
+ }
+ if (_gameType == GType_BRA) {
+ if (!(z->_flags & kFlagsYourself)) {
+ return false;
+ }
+ }
+ if (!_char._ani->hitFrameRect(x, y)) {
return false;
+ }
+ // we get here only if (x,y) hits the character and the zone is marked as self-use
}
- // normal Zone
- if ((type == 0) && (ITEMTYPE(z) == 0))
- return true;
- if (z->_type == type)
- return true;
- if (ITEMTYPE(z) == type)
- return true;
-
- return false;
+ return checkZoneType(z, type);
}
-// 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;
@@ -727,18 +763,14 @@ bool Parallaction::checkLinkedAnimBox(ZonePtr z, uint32 type, uint x, uint 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) && (ITEMTYPE(z) == 0))
- return true;
- if (z->_type == type)
- return true;
- if (ITEMTYPE(z) == type)
- return true;
-
- return false;
+ return checkZoneType(z, type);
}
+/* NOTE: hitZone needs to be passed absolute game coordinates to work.
+
+ When type is kZoneMerge, then x and y are the identifiers of the objects to merge,
+ and the above requirement does not apply.
+*/
ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) {
uint16 _di = y;
uint16 _si = x;
@@ -752,14 +784,20 @@ ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) {
}
}
-
int16 _a, _b, _c, _d;
bool _ef;
for (AnimationList::iterator ait = _location._animations.begin(); ait != _location._animations.end(); ++ait) {
AnimationPtr a = *ait;
- _a = (a->_flags & kFlagsActive) ? 1 : 0; // _a: active Animation
+ _a = (a->_flags & kFlagsActive) ? 1 : 0; // _a: active Animation
+
+ if (!_a) {
+ if (_gameType == GType_BRA && ACTIONTYPE(a) != kZoneTrap) {
+ continue;
+ }
+ }
+
_ef = a->hitFrameRect(_si, _di);
_b = ((type != 0) || (a->_type == kZoneYou)) ? 0 : 1; // _b: (no type specified) AND (Animation is not the character)
@@ -951,7 +989,7 @@ bool CharacterName::dummy() const {
}
void Parallaction::beep() {
- if (getGameType() == GType_Nippon) {
+ if (_gameType == GType_Nippon) {
_soundMan->execute(SC_SETSFXCHANNEL, 3);
_soundMan->execute(SC_SETSFXVOLUME, 127);
_soundMan->execute(SC_SETSFXLOOPING, (int32)0);
diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h
index 3a84aa215e..7bbdf79f1c 100644
--- a/engines/parallaction/parallaction.h
+++ b/engines/parallaction/parallaction.h
@@ -280,6 +280,7 @@ public:
int32 _screenWidth;
int32 _screenHeight;
int32 _screenSize;
+ int _gameType;
// subsystems
Gfx *_gfx;
@@ -360,6 +361,7 @@ public:
uint32 getLocationFlags();
bool checkSpecialZoneBox(ZonePtr z, uint32 type, uint x, uint y);
bool checkZoneBox(ZonePtr z, uint32 type, uint x, uint y);
+ bool checkZoneType(ZonePtr z, uint32 type);
bool checkLinkedAnimBox(ZonePtr z, uint32 type, uint x, uint y);
ZonePtr hitZone(uint32 type, uint16 x, uint16 y);
void runZone(ZonePtr z);
diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp
index ee718189b5..470c698a21 100644
--- a/engines/parallaction/parallaction_br.cpp
+++ b/engines/parallaction/parallaction_br.cpp
@@ -196,7 +196,7 @@ void Parallaction_br::runPendingZones() {
if (_activeZone) {
z = _activeZone; // speak Zone or sound
_activeZone.reset();
- if (ACTIONTYPE(z) == kZoneSpeak) {
+ if (ACTIONTYPE(z) == kZoneSpeak && z->u._speakDialogue) {
enterDialogueMode(z);
} else {
runZone(z); // FIXME: BRA doesn't handle sound yet
@@ -206,7 +206,7 @@ void Parallaction_br::runPendingZones() {
if (_activeZone2) {
z = _activeZone2; // speak Zone or sound
_activeZone2.reset();
- if (ACTIONTYPE(z) == kZoneSpeak) {
+ if (ACTIONTYPE(z) == kZoneSpeak && z->u._speakDialogue) {
enterDialogueMode(z);
} else {
runZone(z); // FIXME: BRA doesn't handle sound yet
diff --git a/engines/parallaction/parser.cpp b/engines/parallaction/parser.cpp
index 928f3f5b74..df1e91e8b4 100644
--- a/engines/parallaction/parser.cpp
+++ b/engines/parallaction/parser.cpp
@@ -44,8 +44,10 @@ Script::~Script() {
/*
* readLineIntern read a text line and prepares it for
* parsing, by stripping the leading whitespace and
- * changing tabs to spaces. It will stop on a CR or LF,
- * and return an empty string (length = 0) when a line
+ * changing tabs to spaces. It will stop on a CR, LF, or
+ * SUB (0x1A), which may all occur at the end of a script
+ * line.
+ * Returns an empty string (length = 0) when a line
* has no printable text in it.
*/
char *Script::readLineIntern(char *buf, size_t bufSize) {
@@ -54,7 +56,8 @@ char *Script::readLineIntern(char *buf, size_t bufSize) {
char c = _input->readSByte();
if (_input->eos())
break;
- if (c == '\n' || c == '\r')
+ // break if EOL
+ if (c == '\n' || c == '\r' || c == (char)0x1A)
break;
if (c == '\t')
c = ' ';
diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp
index be72cf73a1..ff24a06ceb 100644
--- a/engines/parallaction/parser_ns.cpp
+++ b/engines/parallaction/parser_ns.cpp
@@ -286,6 +286,7 @@ void LocationParser_ns::parseAnimation(AnimationList &list, char *name) {
debugC(5, kDebugParser, "parseAnimation(name: %s)", name);
if (_vm->_location.findAnimation(name)) {
+ _zoneProg++;
_script->skip("endanimation");
return;
}
@@ -1305,6 +1306,7 @@ void LocationParser_ns::parseZone(ZoneList &list, char *name) {
debugC(5, kDebugParser, "parseZone(name: %s)", name);
if (_vm->_location.findZone(name)) {
+ _zoneProg++;
_script->skip("endzone");
return;
}
diff --git a/engines/parallaction/sound_br.cpp b/engines/parallaction/sound_br.cpp
index 1c724ddc1c..407dd86ec3 100644
--- a/engines/parallaction/sound_br.cpp
+++ b/engines/parallaction/sound_br.cpp
@@ -172,11 +172,11 @@ bool MidiParser_MSC::loadMusic(byte *data, uint32 size) {
byte *pos = data;
- uint32 signature = read4high(pos);
- if (memcmp("tCSM", &signature, 4)) {
+ if (memcmp("MSCt", pos, 4)) {
warning("Expected header not found in music file.");
return false;
}
+ pos += 4;
_beats = read1(pos);
_ppqn = read2low(pos);