aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm
diff options
context:
space:
mode:
authorTobias Gunkel2012-01-21 23:05:16 +0100
committerTobias Gunkel2012-02-11 08:29:05 +0100
commitf22bbc47b460bf7901844649e1e7929f512b9670 (patch)
tree1cdd8078d001eee1a2dd02ce5f7f601b664ea1eb /engines/scumm
parent2f1336cdf07b59c560d082a1ce3bb7986a3913df (diff)
downloadscummvm-rg350-f22bbc47b460bf7901844649e1e7929f512b9670.tar.gz
scummvm-rg350-f22bbc47b460bf7901844649e1e7929f512b9670.tar.bz2
scummvm-rg350-f22bbc47b460bf7901844649e1e7929f512b9670.zip
SCUMM: fix v0 mode handling and actor switching
- handle mode switching correctly - do not freeze scripts in cutscene mode (mode 0), as some scripts are freezed in mode 0 that should not be freezed - kModeNoNewKid (mode 2) needs the same userState as mode 3 - rename o_cursorCommand to o_setMode as it is not really cursor specific - handle actorHiding correctly (do not set costume to 0 as the previous costume cannot be reverted after hiding) - add drawSentence - document meanings for actor misc flags - fix actor names for "new kid" if the radiation suit is used (all kids are set to 0 then with actor 0 name " ") - cleanup actor switching routine - _userPut is not used anymore in v0
Diffstat (limited to 'engines/scumm')
-rw-r--r--engines/scumm/actor.cpp9
-rw-r--r--engines/scumm/actor.h16
-rw-r--r--engines/scumm/script_v0.cpp55
-rw-r--r--engines/scumm/scumm_v0.h4
-rw-r--r--engines/scumm/verbs.cpp20
5 files changed, 52 insertions, 52 deletions
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index 090ad25c9a..86daaeff2f 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -1512,12 +1512,17 @@ void ScummEngine::processActors() {
for (Actor** ac = _sortedActors; ac != end; ++ac) {
Actor* a = *ac;
- // V0 MM: 0x057B
if (_game.version == 0) {
+ // 0x057B
ActorC64 *A = (ActorC64*) a;
- if ((A->_speaking & 1))
+ if (A->_speaking & 1)
A->_speaking ^= 0xFE;
+
+ // 0x22B5
+ if (A->_miscflags & kActorMiscFlagHide)
+ continue;
}
+
// Draw and animate the actors, except those w/o a costume.
// Note: We could 'optimize' this a little bit by only putting
// actors with a costume into the _sortedActors array in the
diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h
index 0b3fcd7143..7e8faa54cc 100644
--- a/engines/scumm/actor.h
+++ b/engines/scumm/actor.h
@@ -336,14 +336,14 @@ protected:
};
enum ActorC64MiscFlags {
- kActorMiscFlagStrong = 0x01, // Kid is strong (Hunk-O-Matic used)
- kActorMiscFlag_02 = 0x02, // ???
- kActorMiscFlag_04 = 0x04, // ???
- kActorMiscFlagEdsEnemy = 0x08, // Kid is not Weird Ed's friend
- kActorMiscFlag_10 = 0x10, // ???
- kActorMiscFlag_20 = 0x20, // ???
- kActorMiscFlagFreeze = 0x40, // Stop moving
- kActorMiscFlagHide = 0x80, // Hide actor (e.g. dead or wearing radiation suit)
+ kActorMiscFlagStrong = 0x01, // Kid is strong (Hunk-O-Matic used)
+ kActorMiscFlagGTFriend = 0x02, // Kid is green tentacle's friend (recording contract)
+ kActorMiscFlagWatchedTV = 0x04, // Kid knows publisher's address (watched TV)
+ kActorMiscFlagEdsEnemy = 0x08, // Kid is not Weird Ed's friend
+ kActorMiscFlag_10 = 0x10, // ???
+ kActorMiscFlag_20 = 0x20, // ???
+ kActorMiscFlagFreeze = 0x40, // Stop moving
+ kActorMiscFlagHide = 0x80, // Kid is invisible (dead or in radiation suit)
};
class ActorC64 : public Actor_v2 {
diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index 7fce4011e4..b0e3a958e4 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -154,7 +154,7 @@ void ScummEngine_v0::setupOpcodes() {
OPCODE(0x5e, o2_walkActorTo);
OPCODE(0x5f, o2_ifState04);
/* 60 */
- OPCODE(0x60, o_cursorCommand);
+ OPCODE(0x60, o_setMode);
OPCODE(0x61, o2_putActor);
OPCODE(0x62, o2_stopScript);
OPCODE(0x63, o_stopCurrentScript);
@@ -314,7 +314,7 @@ void ScummEngine_v0::setupOpcodes() {
OPCODE(0xde, o2_walkActorTo);
OPCODE(0xdf, o2_ifNotState04);
/* E0 */
- OPCODE(0xe0, o_cursorCommand);
+ OPCODE(0xe0, o_setMode);
OPCODE(0xe1, o2_putActor);
OPCODE(0xe2, o2_stopScript);
OPCODE(0xe3, o_stopCurrentScript);
@@ -463,8 +463,16 @@ void ScummEngine_v0::drawSentenceLine() {
if (_activeVerb == kVerbNewKid) {
_sentenceBuf = "";
for (int i = 0; i < 3; ++i) {
- Actor *a = derefActor(VAR(97 + i), "drawSentenceLine");
- _sentenceBuf += Common::String::format("%-13s", a->getActorName());
+ char *actorName;
+ int actorId = VAR(97 + i);
+ if (actorId == 0) {
+ // after usage of the radiation suit, kid vars are set to 0
+ actorName = " ";
+ } else {
+ Actor *a = derefActor(actorId, "drawSentenceLine");
+ actorName = (char *)a->getActorName();
+ }
+ _sentenceBuf += Common::String::format("%-13s", actorName);
}
flushSentenceLine();
return;
@@ -620,28 +628,30 @@ void ScummEngine_v0::o_unlockRoom() {
_res->unlock(rtRoom, resid);
}
-void ScummEngine_v0::o_cursorCommand() {
- // TODO
+void ScummEngine_v0::setMode(byte mode) {
int state = 0;
- _currentMode = fetchScriptByte();
+ _currentMode = mode;
+
switch (_currentMode) {
case kModeCutscene:
_redrawSentenceLine = false;
- state = 15;
+ state = 7;
break;
case kModeKeypad:
- state = 31;
- break;
- case kModeNoNewKid:
+ state = 23;
break;
case kModeNormal:
+ case kModeNoNewKid:
state = 247;
break;
}
setUserState(state);
- debug(0, "o_cursorCommand(%d)", _currentMode);
+}
+
+void ScummEngine_v0::o_setMode() {
+ setMode(fetchScriptByte());
}
void ScummEngine_v0::o_lights() {
@@ -777,8 +787,6 @@ void ScummEngine_v0::o_setActorBitVar() {
// This flag causes the actor to stop moving (used by script #158, Green Tentacle 'Oomph!')
if (a->_miscflags & kActorMiscFlagFreeze)
a->stopActorMoving();
- if (a->_miscflags & kActorMiscFlagHide)
- a->setActorCostume(0);
debug(0, "o_setActorBitVar(%d, %d, %d)", act, mask, mod);
}
@@ -904,12 +912,10 @@ void ScummEngine_v0::o_getClosestObjActor() {
}
void ScummEngine_v0::o_cutscene() {
- vm.cutSceneData[0] = _userState | (_userPut ? 16 : 0);
+ vm.cutSceneData[0] = _currentMode;
vm.cutSceneData[2] = _currentRoom;
- vm.cutSceneData[3] = camera._mode;
- // Hide inventory, freeze scripts, hide cursor
- setUserState(15);
+ setMode(kModeCutscene);
_sentenceNum = 0;
resetSentence();
@@ -924,17 +930,14 @@ void ScummEngine_v0::o_endCutscene() {
vm.cutSceneScript[0] = 0;
vm.cutScenePtr[0] = 0;
- // Reset user state to values before cutscene
- setUserState(vm.cutSceneData[0] | 7);
+ setMode(vm.cutSceneData[0]);
- camera._mode = (byte) vm.cutSceneData[3];
- if (camera._mode == kFollowActorCameraMode) {
- actorFollowCamera(VAR(VAR_EGO));
- } else if (vm.cutSceneData[2] != _currentRoom) {
+ if (_currentMode == kModeKeypad) {
startScene(vm.cutSceneData[2], 0, 0);
+ } else {
+ actorFollowCamera(VAR(VAR_EGO));
+ _redrawSentenceLine = true;
}
-
- _redrawSentenceLine = true;
}
void ScummEngine_v0::o_beginOverride() {
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index ae97b57a3e..c5c0c0950c 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -92,6 +92,8 @@ protected:
void drawSentenceObject(int object);
void drawSentenceLine();
+ void setMode(byte mode);
+
void switchActor(int slot);
virtual int getVarOrDirectWord(byte mask);
@@ -122,7 +124,7 @@ protected:
void o_lockScript();
void o_loadScript();
void o_lockRoom();
- void o_cursorCommand();
+ void o_setMode();
void o_lights();
void o_unlockCostume();
void o_unlockScript();
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 8888935ea7..bb0d8f4ae2 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -134,21 +134,12 @@ void ScummEngine_v0::resetVerbs() {
void ScummEngine_v0::switchActor(int slot) {
resetSentence();
- if (_currentRoom == 45)
- return;
-
- // radiation suit? don't let the player switch
- if (VAR(VAR_EGO) == 8)
- return;
-
- // verbs disabled? or just new kid button?
- if (_currentMode == kModeCutscene || _currentMode == kModeKeypad || _currentMode == kModeNoNewKid)
+ // actor switching only allowed during normal gamplay (not cutscene, ...)
+ if (_currentMode != kModeNormal)
return;
VAR(VAR_EGO) = VAR(97 + slot);
- resetVerbs();
actorFollowCamera(VAR(VAR_EGO));
- setUserState(247);
}
void ScummEngine_v2::initV2MouseOver() {
@@ -743,9 +734,6 @@ void ScummEngine_v0::checkExecVerbs() {
bool execute = false;
- //if (_userPut <= 0)
- // return;
-
if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) {
int over = findVerbAtPos(_mouse.x, _mouse.y);
// click region: verbs
@@ -777,7 +765,7 @@ void ScummEngine_v0::checkExecVerbs() {
}
if (_mouseAndKeyboardStat > 0 && _mouseAndKeyboardStat < MBS_MAX_KEY) {
- // TODO: check keypresses
+ // keys already checked by input handler
} else if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK) || _activeVerb == kVerbWhatIs) {
// click region: sentence line
if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) {
@@ -793,9 +781,11 @@ void ScummEngine_v0::checkExecVerbs() {
kid = 2;
_activeVerb = kVerbWalkTo;
_redrawSentenceLine = true;
+ drawSentenceLine();
switchActor(kid);
}
_activeVerb = kVerbWalkTo;
+ _redrawSentenceLine = true;
return;
} else {
// execute sentence if complete