[Scummvm-git-logs] scummvm master -> ce551c1f1c5c8dae51b4d64181ee9717df03c7d8
elasota
noreply at scummvm.org
Wed Mar 8 02:40:56 UTC 2023
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
ce551c1f1c VCRUISE: Add initial save game support and enough script ops to enter second area.
Commit: ce551c1f1c5c8dae51b4d64181ee9717df03c7d8
https://github.com/scummvm/scummvm/commit/ce551c1f1c5c8dae51b4d64181ee9717df03c7d8
Author: elasota (ejlasota at gmail.com)
Date: 2023-03-07T21:38:56-05:00
Commit Message:
VCRUISE: Add initial save game support and enough script ops to enter second area.
Changed paths:
engines/vcruise/POTFILES
engines/vcruise/metaengine.cpp
engines/vcruise/runtime.cpp
engines/vcruise/runtime.h
engines/vcruise/script.cpp
engines/vcruise/script.h
engines/vcruise/vcruise.cpp
engines/vcruise/vcruise.h
diff --git a/engines/vcruise/POTFILES b/engines/vcruise/POTFILES
index e62f9068bc3..a64c348f1b5 100644
--- a/engines/vcruise/POTFILES
+++ b/engines/vcruise/POTFILES
@@ -1,2 +1,3 @@
engines/vcruise/metaengine.cpp
+engines/vcruise/runtime.cpp
engines/vcruise/vcruise.cpp
diff --git a/engines/vcruise/metaengine.cpp b/engines/vcruise/metaengine.cpp
index 56c5535e8fb..f19018985b0 100644
--- a/engines/vcruise/metaengine.cpp
+++ b/engines/vcruise/metaengine.cpp
@@ -64,6 +64,13 @@ public:
};
bool VCruiseMetaEngine::hasFeature(MetaEngineFeature f) const {
+ switch (f) {
+ case kSupportsLoadingDuringStartup:
+ return true;
+ default:
+ break;
+ }
+
return checkExtendedSaves(f);
}
diff --git a/engines/vcruise/runtime.cpp b/engines/vcruise/runtime.cpp
index e955d426bfb..5f7101dbbba 100644
--- a/engines/vcruise/runtime.cpp
+++ b/engines/vcruise/runtime.cpp
@@ -25,6 +25,7 @@
#include "common/random.h"
#include "common/system.h"
#include "common/stream.h"
+#include "common/translation.h"
#include "graphics/cursorman.h"
#include "graphics/font.h"
@@ -37,6 +38,8 @@
#include "video/avi_decoder.h"
+#include "gui/message.h"
+
#include "vcruise/audio_player.h"
#include "vcruise/runtime.h"
#include "vcruise/script.h"
@@ -185,7 +188,7 @@ void Runtime::loadCursors(const char *exeName) {
_namedCursors["CUR_TYL"] = 22; // Tyl = back
//_namedCursors["CUR_NIC"] = ? // Nic = nothing
- //_namedCursors["CUR_WEZ"] = 50 // Wez = call? FIXME
+ _namedCursors["CUR_WEZ"] = 90; // Wez = call? This is the pick-up hand.
_namedCursors["CUR_LUPA"] = 21; // Lupa = magnifier, could be 36 too?
_namedCursors["CUR_NAC"] = 13; // Nac = top? Not sure. But this is the finger pointer.
_namedCursors["CUR_PRZOD"] = 1; // Przod = forward
@@ -219,7 +222,7 @@ bool Runtime::runFrame() {
moreActions = false;
switch (_gameState) {
case kGameStateBoot:
- moreActions = bootGame();
+ moreActions = bootGame(true);
break;
case kGameStateQuit:
return false;
@@ -262,18 +265,22 @@ bool Runtime::runFrame() {
return true;
}
-bool Runtime::bootGame() {
+bool Runtime::bootGame(bool newGame) {
+ assert(_gameState == kGameStateBoot);
+
debug(1, "Booting V-Cruise game...");
loadIndex();
debug(1, "Index loaded OK");
_gameState = kGameStateIdle;
- if (_gameID == GID_REAH) {
- // TODO: Change to the logo instead (0xb1) instead when menus are implemented
- changeToScreen(1, 0xb0);
- } else
- error("Couldn't figure out what screen to start on");
+ if (newGame) {
+ if (_gameID == GID_REAH) {
+ // TODO: Change to the logo instead (0xb1) instead when menus are implemented
+ changeToScreen(1, 0xb0);
+ } else
+ error("Couldn't figure out what screen to start on");
+ }
return true;
}
@@ -708,20 +715,37 @@ bool Runtime::runScript() {
DISPATCH_OP(Static);
DISPATCH_OP(VarLoad);
DISPATCH_OP(VarStore);
+ DISPATCH_OP(ItemCheck);
+ DISPATCH_OP(ItemCRSet);
+ DISPATCH_OP(ItemSRSet);
+ DISPATCH_OP(ItemRSet);
DISPATCH_OP(SetCursor);
DISPATCH_OP(SetRoom);
DISPATCH_OP(LMB);
DISPATCH_OP(LMB1);
DISPATCH_OP(SoundS1);
+ DISPATCH_OP(SoundS2);
+ DISPATCH_OP(SoundS3);
+ DISPATCH_OP(SoundL1);
DISPATCH_OP(SoundL2);
+ DISPATCH_OP(SoundL3);
+ DISPATCH_OP(3DSoundL2);
+ DISPATCH_OP(Range);
+ DISPATCH_OP(AddXSound);
+ DISPATCH_OP(ClrXSound);
+ DISPATCH_OP(StopSndLA);
+ DISPATCH_OP(StopSndLO);
DISPATCH_OP(Music);
DISPATCH_OP(MusicUp);
DISPATCH_OP(MusicDn);
+ DISPATCH_OP(Parm0);
DISPATCH_OP(Parm1);
DISPATCH_OP(Parm2);
DISPATCH_OP(Parm3);
DISPATCH_OP(ParmG);
+ DISPATCH_OP(SParmX);
+ DISPATCH_OP(SAnimX);
DISPATCH_OP(VolumeDn4);
DISPATCH_OP(VolumeUp3);
@@ -729,8 +753,10 @@ bool Runtime::runScript() {
DISPATCH_OP(Drop);
DISPATCH_OP(Dup);
DISPATCH_OP(Say3);
+ DISPATCH_OP(Say3Get);
DISPATCH_OP(SetTimer);
DISPATCH_OP(GetTimer);
+ DISPATCH_OP(Delay);
DISPATCH_OP(LoSet);
DISPATCH_OP(LoGet);
DISPATCH_OP(HiSet);
@@ -739,7 +765,11 @@ bool Runtime::runScript() {
DISPATCH_OP(Not);
DISPATCH_OP(And);
DISPATCH_OP(Or);
+ DISPATCH_OP(Add);
+ DISPATCH_OP(Sub);
DISPATCH_OP(CmpEq);
+ DISPATCH_OP(CmpGt);
+ DISPATCH_OP(CmpLt);
DISPATCH_OP(BitLoad);
DISPATCH_OP(BitSet0);
@@ -975,6 +1005,8 @@ void Runtime::changeToScreen(uint roomNumber, uint screenNumber) {
}
void Runtime::returnToIdleState() {
+ debug(1, "Returned to idle state in room %u screen 0%x facing direction %u", _roomNumber, _screenNumber, _direction);
+
_animPlayWhileIdle = false;
if (_haveIdleAnimations[_direction]) {
@@ -1518,6 +1550,108 @@ void Runtime::onKeyDown(Common::KeyCode keyCode) {
queueOSEvent(evt);
}
+bool Runtime::canSave() const {
+ return _gameState == kGameStateIdle;
+}
+
+bool Runtime::canLoad() const {
+ return _gameState == kGameStateIdle;
+}
+
+void Runtime::saveGame(Common::WriteStream *stream) const {
+ stream->writeUint32BE(kSaveGameIdentifier);
+ stream->writeUint32BE(kSaveGameCurrentVersion);
+
+ stream->writeUint32BE(_roomNumber);
+ stream->writeUint32BE(_screenNumber);
+ stream->writeUint32BE(_direction);
+
+ Common::Array<uint32> variableIDs;
+
+ for (const Common::HashMap<uint32, int32>::Node &varNode : _variables)
+ variableIDs.push_back(varNode._key);
+
+ Common::sort(variableIDs.begin(), variableIDs.end());
+
+ stream->writeUint32BE(variableIDs.size());
+
+ for (uint32 variableKey : variableIDs) {
+ Common::HashMap<uint32, int32>::const_iterator it = _variables.find(variableKey);
+ assert(it != _variables.end());
+
+ stream->writeUint32BE(variableKey);
+ stream->writeSint32BE(it->_value);
+ }
+}
+
+bool Runtime::loadGame(Common::ReadStream *stream) {
+ assert(canLoad());
+
+ uint32 saveGameID = stream->readUint32BE();
+ uint32 saveVersion = stream->readUint32BE();
+
+ if (stream->err() || stream->eos()) {
+ GUI::MessageDialog dialog(_("Failed to read version information from save file"));
+ dialog.runModal();
+
+ return false;
+ }
+
+ if (saveGameID != kSaveGameIdentifier) {
+ GUI::MessageDialog dialog(_("Failed to load save, the save file doesn't contain valid version information."));
+ dialog.runModal();
+
+ return false;
+ }
+
+ if (saveVersion > kSaveGameCurrentVersion) {
+ GUI::MessageDialog dialog(_("Saved game was created with a newer version of ScummVM. Unable to load."));
+ dialog.runModal();
+
+ return false;
+ }
+
+ if (saveVersion < kSaveGameEarliestSupportedVersion) {
+ GUI::MessageDialog dialog(_("Saved game was created with an earlier, incompatible version of ScummVM. Unable to load."));
+ dialog.runModal();
+
+ return false;
+ }
+
+ uint32 roomNumber = stream->readUint32BE();
+ uint32 screenNumber = stream->readUint32BE();
+ uint32 direction = stream->readUint32BE();
+
+ uint32 numVars = stream->readUint32BE();
+
+ if (stream->err() || stream->eos())
+ return false;
+
+ Common::HashMap<uint32, int32> vars;
+
+ for (uint32 i = 0; i < numVars; i++) {
+ uint32 varID = stream->readUint32BE();
+ int32 varValue = stream->readSint32BE();
+
+ vars[varID] = varValue;
+ }
+
+ if (stream->err() || stream->eos())
+ return false;
+
+ if (direction >= kNumDirections)
+ return false;
+
+ // Load succeeded
+ _variables = Common::move(vars);
+
+ _direction = direction;
+ changeToScreen(roomNumber, screenNumber);
+ _havePendingReturnToIdleState = true;
+
+ return true;
+}
+
#ifdef PEEK_STACK
#error "PEEK_STACK is already defined"
#endif
@@ -1782,6 +1916,11 @@ void Runtime::scriptOpVarStore(ScriptArg_t arg) {
_variables[varID] = stackArgs[0];
}
+OPCODE_STUB(ItemCheck)
+OPCODE_STUB(ItemCRSet)
+OPCODE_STUB(ItemSRSet)
+OPCODE_STUB(ItemRSet)
+
void Runtime::scriptOpSetCursor(ScriptArg_t arg) {
TAKE_STACK(1);
@@ -1820,14 +1959,78 @@ void Runtime::scriptOpLMB1(ScriptArg_t arg) {
void Runtime::scriptOpSoundS1(ScriptArg_t arg) {
TAKE_STACK(1);
- warning("Sound play not implemented yet");
+ warning("Sound play 1 not implemented yet");
+ (void)stackArgs;
+}
+
+void Runtime::scriptOpSoundS2(ScriptArg_t arg) {
+ TAKE_STACK(2);
+
+ warning("Sound play 2 not implemented yet");
+ (void)stackArgs;
+}
+
+void Runtime::scriptOpSoundS3(ScriptArg_t arg) {
+ TAKE_STACK(3);
+
+ warning("Sound play 3 not implemented yet");
+ (void)stackArgs;
+}
+
+void Runtime::scriptOpSoundL1(ScriptArg_t arg) {
+ TAKE_STACK(1);
+
+ warning("Sound loop 1 not implemented yet");
(void)stackArgs;
}
void Runtime::scriptOpSoundL2(ScriptArg_t arg) {
TAKE_STACK(2);
- warning("Sound loop not implemented yet");
+ warning("Sound loop 2 not implemented yet");
+ (void)stackArgs;
+}
+
+void Runtime::scriptOpSoundL3(ScriptArg_t arg) {
+ TAKE_STACK(3);
+
+ warning("Sound loop 3 not implemented yet");
+ (void)stackArgs;
+}
+
+void Runtime::scriptOp3DSoundL2(ScriptArg_t arg) {
+ TAKE_STACK(4);
+
+ warning("3D sound loop not implemented yet");
+ (void)stackArgs;
+}
+
+void Runtime::scriptOpAddXSound(ScriptArg_t arg) {
+ TAKE_STACK(4);
+
+ warning("AddXSound not implemented yet");
+ (void)stackArgs;
+}
+
+void Runtime::scriptOpClrXSound(ScriptArg_t arg) {
+ warning("ClrXSound not implemented yet");
+}
+
+void Runtime::scriptOpStopSndLA(ScriptArg_t arg) {
+ warning("StopSndLA not implemented yet");
+}
+
+void Runtime::scriptOpStopSndLO(ScriptArg_t arg) {
+ TAKE_STACK(1);
+
+ warning("StopSndLO not implemented yet");
+ (void)stackArgs;
+}
+
+void Runtime::scriptOpRange(ScriptArg_t arg) {
+ TAKE_STACK(3);
+
+ warning("Range not implemented yet");
(void)stackArgs;
}
@@ -1851,6 +2054,13 @@ void Runtime::scriptOpMusicDn(ScriptArg_t arg) {
(void)stackArgs;
}
+void Runtime::scriptOpParm0(ScriptArg_t arg) {
+ TAKE_STACK(4);
+
+ warning("Parm0 is not implemented");
+ (void)stackArgs;
+}
+
void Runtime::scriptOpParm1(ScriptArg_t arg) {
TAKE_STACK(3);
@@ -1892,6 +2102,9 @@ void Runtime::scriptOpParmG(ScriptArg_t arg) {
_gyros.maxValue = maxValue;
}
+OPCODE_STUB(SParmX)
+OPCODE_STUB(SAnimX)
+
void Runtime::scriptOpVolumeUp3(ScriptArg_t arg) {
TAKE_STACK(3);
@@ -1943,6 +2156,8 @@ void Runtime::scriptOpSay3(ScriptArg_t arg) {
(void)stackArgs;
}
+OPCODE_STUB(Say3Get)
+
void Runtime::scriptOpSetTimer(ScriptArg_t arg) {
TAKE_STACK(2);
@@ -1952,7 +2167,7 @@ void Runtime::scriptOpSetTimer(ScriptArg_t arg) {
void Runtime::scriptOpGetTimer(ScriptArg_t arg) {
TAKE_STACK(1);
- bool isCompleted = false;
+ bool isCompleted = true;
Common::HashMap<uint, uint32>::const_iterator timerIt = _timers.find(stackArgs[0]);
if (timerIt != _timers.end())
@@ -1961,6 +2176,13 @@ void Runtime::scriptOpGetTimer(ScriptArg_t arg) {
_scriptStack.push_back(isCompleted ? 1 : 0);
}
+void Runtime::scriptOpDelay(ScriptArg_t arg) {
+ TAKE_STACK(1);
+
+ warning("Delay opcode is not implemented yet");
+ (void)stackArgs;
+}
+
void Runtime::scriptOpLoSet(ScriptArg_t arg) {
scriptOpVerticalPanSet(_havePanDownFromDirection);
}
@@ -2035,12 +2257,36 @@ void Runtime::scriptOpOr(ScriptArg_t arg) {
_scriptStack.push_back((stackArgs[0] != 0 || stackArgs[1] != 0) ? 1 : 0);
}
+void Runtime::scriptOpAdd(ScriptArg_t arg) {
+ TAKE_STACK(2);
+
+ _scriptStack.push_back(stackArgs[0] + stackArgs[1]);
+}
+
+void Runtime::scriptOpSub(ScriptArg_t arg) {
+ TAKE_STACK(2);
+
+ _scriptStack.push_back(stackArgs[0] - stackArgs[1]);
+}
+
void Runtime::scriptOpCmpEq(ScriptArg_t arg) {
TAKE_STACK(2);
_scriptStack.push_back((stackArgs[0] == stackArgs[1]) ? 1 : 0);
}
+void Runtime::scriptOpCmpLt(ScriptArg_t arg) {
+ TAKE_STACK(2);
+
+ _scriptStack.push_back((stackArgs[0] < stackArgs[1]) ? 1 : 0);
+}
+
+void Runtime::scriptOpCmpGt(ScriptArg_t arg) {
+ TAKE_STACK(2);
+
+ _scriptStack.push_back((stackArgs[0] > stackArgs[1]) ? 1 : 0);
+}
+
void Runtime::scriptOpBitLoad(ScriptArg_t arg) {
TAKE_STACK(2);
diff --git a/engines/vcruise/runtime.h b/engines/vcruise/runtime.h
index 8cdc64d9a47..fe01947f0c9 100644
--- a/engines/vcruise/runtime.h
+++ b/engines/vcruise/runtime.h
@@ -32,6 +32,8 @@ class OSystem;
namespace Common {
class RandomSource;
+class ReadStream;
+class WriteStream;
} // End of namespace Commom
@@ -142,6 +144,14 @@ public:
void onMouseMove(int16 x, int16 y);
void onKeyDown(Common::KeyCode keyCode);
+ bool canSave() const;
+ bool canLoad() const;
+
+ void saveGame(Common::WriteStream *stream) const;
+ bool loadGame(Common::ReadStream *stream);
+
+ bool bootGame(bool newGame);
+
private:
enum IndexParseType {
kIndexParseTypeNone,
@@ -254,7 +264,6 @@ private:
typedef int32 ScriptArg_t;
typedef int32 StackValue_t;
- bool bootGame();
bool runIdle();
bool runHorizontalPan(bool isRight);
bool runScript();
@@ -323,20 +332,39 @@ private:
void scriptOpStatic(ScriptArg_t arg);
void scriptOpVarLoad(ScriptArg_t arg);
void scriptOpVarStore(ScriptArg_t arg);
+
+ void scriptOpItemCheck(ScriptArg_t arg);
+ void scriptOpItemCRSet(ScriptArg_t arg);
+ void scriptOpItemSRSet(ScriptArg_t arg);
+ void scriptOpItemRSet(ScriptArg_t arg);
+
void scriptOpSetCursor(ScriptArg_t arg);
void scriptOpSetRoom(ScriptArg_t arg);
void scriptOpLMB(ScriptArg_t arg);
void scriptOpLMB1(ScriptArg_t arg);
void scriptOpSoundS1(ScriptArg_t arg);
+ void scriptOpSoundS2(ScriptArg_t arg);
+ void scriptOpSoundS3(ScriptArg_t arg);
+ void scriptOpSoundL1(ScriptArg_t arg);
void scriptOpSoundL2(ScriptArg_t arg);
+ void scriptOpSoundL3(ScriptArg_t arg);
+ void scriptOp3DSoundL2(ScriptArg_t arg);
+ void scriptOpRange(ScriptArg_t arg);
+ void scriptOpAddXSound(ScriptArg_t arg);
+ void scriptOpClrXSound(ScriptArg_t arg);
+ void scriptOpStopSndLA(ScriptArg_t arg);
+ void scriptOpStopSndLO(ScriptArg_t arg);
void scriptOpMusic(ScriptArg_t arg);
void scriptOpMusicUp(ScriptArg_t arg);
void scriptOpMusicDn(ScriptArg_t arg);
+ void scriptOpParm0(ScriptArg_t arg);
void scriptOpParm1(ScriptArg_t arg);
void scriptOpParm2(ScriptArg_t arg);
void scriptOpParm3(ScriptArg_t arg);
void scriptOpParmG(ScriptArg_t arg);
+ void scriptOpSParmX(ScriptArg_t arg);
+ void scriptOpSAnimX(ScriptArg_t arg);
void scriptOpVolumeDn4(ScriptArg_t arg);
void scriptOpVolumeUp3(ScriptArg_t arg);
@@ -344,8 +372,10 @@ private:
void scriptOpDrop(ScriptArg_t arg);
void scriptOpDup(ScriptArg_t arg);
void scriptOpSay3(ScriptArg_t arg);
+ void scriptOpSay3Get(ScriptArg_t arg);
void scriptOpSetTimer(ScriptArg_t arg);
void scriptOpGetTimer(ScriptArg_t arg);
+ void scriptOpDelay(ScriptArg_t arg);
void scriptOpLoSet(ScriptArg_t arg);
void scriptOpLoGet(ScriptArg_t arg);
void scriptOpHiSet(ScriptArg_t arg);
@@ -354,7 +384,11 @@ private:
void scriptOpNot(ScriptArg_t arg);
void scriptOpAnd(ScriptArg_t arg);
void scriptOpOr(ScriptArg_t arg);
+ void scriptOpAdd(ScriptArg_t arg);
+ void scriptOpSub(ScriptArg_t arg);
void scriptOpCmpEq(ScriptArg_t arg);
+ void scriptOpCmpLt(ScriptArg_t arg);
+ void scriptOpCmpGt(ScriptArg_t arg);
void scriptOpBitLoad(ScriptArg_t arg);
void scriptOpBitSet0(ScriptArg_t arg);
@@ -496,6 +530,10 @@ private:
static const int kPanoramaPanningMarginX = 11;
static const int kPanoramaPanningMarginY = 11;
+
+ static const uint kSaveGameIdentifier = 0x53566372;
+ static const uint kSaveGameCurrentVersion = 1;
+ static const uint kSaveGameEarliestSupportedVersion = 1;
};
} // End of namespace VCruise
diff --git a/engines/vcruise/script.cpp b/engines/vcruise/script.cpp
index c32a56b8936..f3432f3de67 100644
--- a/engines/vcruise/script.cpp
+++ b/engines/vcruise/script.cpp
@@ -305,6 +305,10 @@ void ScriptCompiler::compileScreenScriptSet(ScreenScriptSet *sss) {
protoScript.reset();
sss->interactionScripts[interactionNumber] = currentScript;
+ } else if (token == "DEC") {
+ _numberParsingMode = kNumberParsingDec;
+ } else if (token == "HEX") {
+ _numberParsingMode = kNumberParsingHex;
} else if (compileInstructionToken(protoScript, token)) {
// Nothing
} else {
@@ -320,6 +324,7 @@ static ScriptNamedInstruction g_namedInstructions[] = {
{"speed", ProtoOp::kProtoOpScript, ScriptOps::kSpeed},
{"sanimL", ProtoOp::kProtoOpScript, ScriptOps::kSAnimL},
{"changeL", ProtoOp::kProtoOpScript, ScriptOps::kChangeL},
+ {"changeL1", ProtoOp::kProtoOpScript, ScriptOps::kChangeL}, // This seems wrong, but not sure what changeL1 does differently from changeL yet
{"animR", ProtoOp::kProtoOpScript, ScriptOps::kAnimR},
{"animF", ProtoOp::kProtoOpScript, ScriptOps::kAnimF},
{"animN", ProtoOp::kProtoOpScript, ScriptOps::kAnimN},
@@ -329,6 +334,10 @@ static ScriptNamedInstruction g_namedInstructions[] = {
{"static", ProtoOp::kProtoOpScript, ScriptOps::kStatic},
{"yes@", ProtoOp::kProtoOpScript, ScriptOps::kVarLoad},
{"yes!", ProtoOp::kProtoOpScript, ScriptOps::kVarStore},
+ {"cr?", ProtoOp::kProtoOpScript, ScriptOps::kItemCheck},
+ {"cr!", ProtoOp::kProtoOpScript, ScriptOps::kItemCRSet},
+ {"sr!", ProtoOp::kProtoOpScript, ScriptOps::kItemSRSet},
+ {"r!", ProtoOp::kProtoOpScript, ScriptOps::kItemRSet},
{"cursor!", ProtoOp::kProtoOpScript, ScriptOps::kSetCursor},
{"room!", ProtoOp::kProtoOpScript, ScriptOps::kSetRoom},
{"lmb", ProtoOp::kProtoOpScript, ScriptOps::kLMB},
@@ -339,8 +348,10 @@ static ScriptNamedInstruction g_namedInstructions[] = {
{"drop", ProtoOp::kProtoOpScript, ScriptOps::kDrop},
{"dup", ProtoOp::kProtoOpScript, ScriptOps::kDup},
{"say3", ProtoOp::kProtoOpScript, ScriptOps::kSay3},
+ {"say3@", ProtoOp::kProtoOpScript, ScriptOps::kSay3Get},
{"setTimer", ProtoOp::kProtoOpScript, ScriptOps::kSetTimer},
{"getTimer", ProtoOp::kProtoOpScript, ScriptOps::kGetTimer},
+ {"delay", ProtoOp::kProtoOpScript, ScriptOps::kDelay},
{"lo!", ProtoOp::kProtoOpScript, ScriptOps::kLoSet},
{"lo@", ProtoOp::kProtoOpScript, ScriptOps::kLoGet},
{"hi!", ProtoOp::kProtoOpScript, ScriptOps::kHiSet},
@@ -348,23 +359,41 @@ static ScriptNamedInstruction g_namedInstructions[] = {
{"and", ProtoOp::kProtoOpScript, ScriptOps::kAnd},
{"or", ProtoOp::kProtoOpScript, ScriptOps::kOr},
+ {"+", ProtoOp::kProtoOpScript, ScriptOps::kAdd},
+ {"-", ProtoOp::kProtoOpScript, ScriptOps::kSub},
{"not", ProtoOp::kProtoOpScript, ScriptOps::kNot},
{"=", ProtoOp::kProtoOpScript, ScriptOps::kCmpEq},
+ {">", ProtoOp::kProtoOpScript, ScriptOps::kCmpGt},
+ {"<", ProtoOp::kProtoOpScript, ScriptOps::kCmpLt},
{"bit@", ProtoOp::kProtoOpScript, ScriptOps::kBitLoad},
{"bit0!", ProtoOp::kProtoOpScript, ScriptOps::kBitSet0},
{"bit1!", ProtoOp::kProtoOpScript, ScriptOps::kBitSet1},
{"soundS1", ProtoOp::kProtoOpScript, ScriptOps::kSoundS1},
+ {"soundS2", ProtoOp::kProtoOpScript, ScriptOps::kSoundS2},
+ {"soundS3", ProtoOp::kProtoOpScript, ScriptOps::kSoundS3},
+ {"soundL1", ProtoOp::kProtoOpScript, ScriptOps::kSoundL1},
{"soundL2", ProtoOp::kProtoOpScript, ScriptOps::kSoundL2},
+ {"soundL3", ProtoOp::kProtoOpScript, ScriptOps::kSoundL3},
+ {"3DsoundL2", ProtoOp::kProtoOpScript, ScriptOps::k3DSoundL2},
+ {"range", ProtoOp::kProtoOpScript, ScriptOps::kRange},
+ {"addXsound", ProtoOp::kProtoOpScript, ScriptOps::kAddXSound},
+ {"clrXsound", ProtoOp::kProtoOpScript, ScriptOps::kClrXSound},
+ {"stopSndLA", ProtoOp::kProtoOpScript, ScriptOps::kStopSndLA},
+ {"stopSndLO", ProtoOp::kProtoOpScript, ScriptOps::kStopSndLO},
+
{"music", ProtoOp::kProtoOpScript, ScriptOps::kMusic},
{"musicUp", ProtoOp::kProtoOpScript, ScriptOps::kMusicUp},
{"musicDn", ProtoOp::kProtoOpScript, ScriptOps::kMusicDn},
+ {"parm0", ProtoOp::kProtoOpScript, ScriptOps::kParm0},
{"parm1", ProtoOp::kProtoOpScript, ScriptOps::kParm1},
{"parm2", ProtoOp::kProtoOpScript, ScriptOps::kParm2},
{"parm3", ProtoOp::kProtoOpScript, ScriptOps::kParm3},
{"parmG", ProtoOp::kProtoOpScript, ScriptOps::kParmG},
+ {"sparmX", ProtoOp::kProtoOpScript, ScriptOps::kSParmX},
+ {"sanimX", ProtoOp::kProtoOpScript, ScriptOps::kSAnimX},
{"disc1", ProtoOp::kProtoOpScript, ScriptOps::kDisc1},
{"disc2", ProtoOp::kProtoOpScript, ScriptOps::kDisc2},
diff --git a/engines/vcruise/script.h b/engines/vcruise/script.h
index 1976606a3ce..ccf8f2f1bd1 100644
--- a/engines/vcruise/script.h
+++ b/engines/vcruise/script.h
@@ -61,27 +61,46 @@ enum ScriptOp {
kStatic,
kVarLoad,
kVarStore,
+ kItemCheck,
+ kItemCRSet,
+ kItemSRSet,
+ kItemRSet,
kSetCursor,
kSetRoom,
kLMB,
kLMB1,
kSoundS1,
+ kSoundS2,
+ kSoundS3,
+ kSoundL1,
kSoundL2,
+ kSoundL3,
+ k3DSoundL2,
+ kRange,
+ kAddXSound,
+ kClrXSound,
+ kStopSndLA,
+ kStopSndLO,
kMusic,
kMusicUp,
kMusicDn,
+ kParm0,
kParm1,
kParm2,
kParm3,
kParmG,
+ kSParmX,
+ kSAnimX,
kVolumeDn4,
kVolumeUp3,
kRandom,
kDrop,
kDup,
kSay3,
+ kSay3Get,
kSetTimer,
kGetTimer,
+ kDelay,
kLoSet,
kLoGet,
kHiSet,
@@ -90,7 +109,11 @@ enum ScriptOp {
kNot,
kAnd,
kOr,
+ kSub,
+ kAdd,
kCmpEq,
+ kCmpLt,
+ kCmpGt,
kBitLoad,
kBitSet0,
diff --git a/engines/vcruise/vcruise.cpp b/engines/vcruise/vcruise.cpp
index c8bf0603390..b2bfb51d325 100644
--- a/engines/vcruise/vcruise.cpp
+++ b/engines/vcruise/vcruise.cpp
@@ -23,6 +23,7 @@
#include "common/config-manager.h"
#include "common/events.h"
+#include "common/stream.h"
#include "common/system.h"
#include "common/algorithm.h"
#include "common/translation.h"
@@ -168,6 +169,17 @@ Common::Error VCruiseEngine::run() {
_runtime->setDebugMode(true);
}
+ if (ConfMan.hasKey("save_slot")) {
+ int saveSlot = ConfMan.getInt("save_slot");
+ if (saveSlot >= 0) {
+ (void)_runtime->bootGame(false);
+
+ Common::Error err = loadGameState(saveSlot);
+ if (err.getCode() != Common::kNoError)
+ return err;
+ }
+ }
+
// Run the game
while (!shouldQuit()) {
handleEvents();
@@ -191,7 +203,8 @@ void VCruiseEngine::pauseEngineIntern(bool pause) {
bool VCruiseEngine::hasFeature(EngineFeature f) const {
switch (f) {
case kSupportsReturnToLauncher:
- //case kSupportsSavingDuringRuntime:
+ case kSupportsSavingDuringRuntime:
+ case kSupportsLoadingDuringRuntime:
return true;
default:
return false;
@@ -199,15 +212,31 @@ bool VCruiseEngine::hasFeature(EngineFeature f) const {
}
Common::Error VCruiseEngine::saveGameStream(Common::WriteStream *stream, bool isAutosave) {
- return Common::Error(Common::kUnknownError);
+ _runtime->saveGame(stream);
+
+ if (stream->err())
+ return Common::Error(Common::kWritingFailed);
+
+ return Common::Error(Common::kNoError);
+}
+
+Common::Error VCruiseEngine::loadGameStream(Common::SeekableReadStream *stream) {
+ if (!_runtime->loadGame(stream))
+ return Common::Error(Common::kReadingFailed);
+
+ return Common::Error(Common::kNoError);
}
bool VCruiseEngine::canSaveAutosaveCurrently() {
- return false;
+ return _runtime->canSave();
}
bool VCruiseEngine::canSaveGameStateCurrently() {
- return false;
+ return _runtime->canSave();
+}
+
+bool VCruiseEngine::canLoadGameStateCurrently() {
+ return _runtime->canLoad();
}
void VCruiseEngine::initializePath(const Common::FSNode &gamePath) {
diff --git a/engines/vcruise/vcruise.h b/engines/vcruise/vcruise.h
index eb16bc7adcf..44ccb05b9ad 100644
--- a/engines/vcruise/vcruise.h
+++ b/engines/vcruise/vcruise.h
@@ -54,8 +54,11 @@ public:
const VCruiseGameDescription *_gameDescription;
Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave) override;
+ Common::Error loadGameStream(Common::SeekableReadStream *stream) override;
+
bool canSaveAutosaveCurrently() override;
bool canSaveGameStateCurrently() override;
+ bool canLoadGameStateCurrently() override;
void initializePath(const Common::FSNode &gamePath) override;
More information about the Scummvm-git-logs
mailing list