diff options
author | Tony Puccinelli | 2010-08-11 01:11:16 +0000 |
---|---|---|
committer | Tony Puccinelli | 2010-08-11 01:11:16 +0000 |
commit | 3a7a0ba720f219c4780cf19d196cda9c0456a20b (patch) | |
tree | fe7f45242447dc7d14447babbdea9fbbb771c506 /engines/parallaction | |
parent | 6543062e5701e8011a4b12abffa8afca56f30b3f (diff) | |
parent | fffec23a02cc88ed8daba0a3b50007b7e220c075 (diff) | |
download | scummvm-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.cpp | 27 | ||||
-rw-r--r-- | engines/parallaction/debug.h | 1 | ||||
-rw-r--r-- | engines/parallaction/dialogue.cpp | 4 | ||||
-rw-r--r-- | engines/parallaction/exec_br.cpp | 2 | ||||
-rw-r--r-- | engines/parallaction/graphics.cpp | 6 | ||||
-rw-r--r-- | engines/parallaction/input.cpp | 15 | ||||
-rw-r--r-- | engines/parallaction/objects.h | 4 | ||||
-rw-r--r-- | engines/parallaction/parallaction.cpp | 112 | ||||
-rw-r--r-- | engines/parallaction/parallaction.h | 2 | ||||
-rw-r--r-- | engines/parallaction/parallaction_br.cpp | 4 | ||||
-rw-r--r-- | engines/parallaction/parser.cpp | 9 | ||||
-rw-r--r-- | engines/parallaction/parser_ns.cpp | 2 | ||||
-rw-r--r-- | engines/parallaction/sound_br.cpp | 4 |
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); |