aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--saga/actor.cpp6
-rw-r--r--saga/actor.h7
-rw-r--r--saga/input.cpp6
-rw-r--r--saga/interface.cpp15
-rw-r--r--saga/interface.h3
-rw-r--r--saga/isomap.h1
-rw-r--r--saga/module.mk1
-rw-r--r--saga/saga.h3
-rw-r--r--saga/saveload.cpp192
-rw-r--r--saga/scene.cpp19
-rw-r--r--saga/scene.h2
-rw-r--r--saga/script.h10
-rw-r--r--saga/sfuncs.cpp9
13 files changed, 257 insertions, 17 deletions
diff --git a/saga/actor.cpp b/saga/actor.cpp
index 0926fdb2f4..77cb38fe59 100644
--- a/saga/actor.cpp
+++ b/saga/actor.cpp
@@ -180,6 +180,7 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) {
_pathDirectionListAlloced = 0;
_centerActor = _protagonist = NULL;
+ _protagState = 0;
_lastTickMsec = 0;
_yCellCount = _vm->getSceneHeight();
@@ -548,6 +549,11 @@ bool Actor::validFollowerLocation(const Location &location) {
return (_vm->_scene->canWalk(point));
}
+void Actor::setProtagState(int state) {
+ debug(0, "STUB: setProtagState(%d)", state);
+ _protagState = state;
+}
+
void Actor::updateActorsScene(int actorsEntrance) {
int i, j;
int followerDirection;
diff --git a/saga/actor.h b/saga/actor.h
index 93e3f2a803..c734f4c1ad 100644
--- a/saga/actor.h
+++ b/saga/actor.h
@@ -382,6 +382,9 @@ public:
bool isSpeaking() {
return _activeSpeech.stringsCount > 0;
}
+
+ void setProtagState(int state);
+ int getProtagState() { return _protagState; }
private:
bool loadActorResources(ActorData *actor);
@@ -428,14 +431,16 @@ private:
protected:
friend class IsoMap;
+ friend class SagaEngine;
int _actorsCount;
ActorData **_actors;
-private:
int _objsCount;
ObjectData **_objs;
+private:
SpeechData _activeSpeech;
+ int _protagState;
//path stuff
struct PathNode {
diff --git a/saga/input.cpp b/saga/input.cpp
index 56139ae932..c93a5782be 100644
--- a/saga/input.cpp
+++ b/saga/input.cpp
@@ -84,6 +84,12 @@ int SagaEngine::processInput() {
case 287: // F6
_render->toggleFlag(RF_ACTOR_PATH_TEST);
break;
+ case 288: // F7
+ save();
+ break;
+ case 289: // F8
+ load();
+ break;
case 9: // Tab
_script->SThreadDebugStep();
break;
diff --git a/saga/interface.cpp b/saga/interface.cpp
index 361254b81b..2e27612de2 100644
--- a/saga/interface.cpp
+++ b/saga/interface.cpp
@@ -506,7 +506,13 @@ PanelButton *Interface::verbHitTest(const Point& mousePoint) {
return NULL;
}
-void Interface::addToInventory(int sprite) {
+void Interface::addToInventory(int sprite, int pos) {
+ if (pos != -1) {
+ _inventory[pos] = sprite;
+ _inventoryCount++;
+ return;
+ }
+
if (_inventoryCount < _inventorySize) {
for (int i = _inventoryCount; i > 0; i--) {
_inventory[i] = _inventory[i - 1];
@@ -535,6 +541,13 @@ void Interface::removeFromInventory(int sprite) {
}
}
+void Interface::clearInventory() {
+ for (int i = 0; i < _inventoryCount; i++)
+ _inventory[i] = 0;
+
+ _inventoryCount = 0;
+}
+
int Interface::inventoryItemPosition(int sprite) {
for (int i = 0; i < _inventoryCount; i++)
if (_inventory[i] == sprite)
diff --git a/saga/interface.h b/saga/interface.h
index 84c8322004..654e7dea7d 100644
--- a/saga/interface.h
+++ b/saga/interface.h
@@ -137,8 +137,9 @@ public:
bool processKeyCode(int keyCode);
- void addToInventory(int sprite);
+ void addToInventory(int sprite, int pos = -1);
void removeFromInventory(int sprite);
+ void clearInventory();
int inventoryItemPosition(int sprite);
void drawInventory();
diff --git a/saga/isomap.h b/saga/isomap.h
index 971d53ba52..a59f559dcd 100644
--- a/saga/isomap.h
+++ b/saga/isomap.h
@@ -167,6 +167,7 @@ public:
void findTilePath(ActorData* actor, const Location &start, const Location &end);
bool nextTileTarget(ActorData* actor);
void setTileDoorState(int doorNumber, int doorState);
+ Point getMapPosition() { return _mapPosition; }
private:
void drawTiles(SURFACE *ds, const Location *location);
diff --git a/saga/module.mk b/saga/module.mk
index d28f57c823..adbb632b66 100644
--- a/saga/module.mk
+++ b/saga/module.mk
@@ -20,6 +20,7 @@ MODULE_OBJS := \
saga/render.o \
saga/rscfile.o \
saga/saga.o \
+ saga/saveload.o \
saga/scene.o \
saga/script.o \
saga/sdebug.o \
diff --git a/saga/saga.h b/saga/saga.h
index a789bc9cc7..2c6dd0e614 100644
--- a/saga/saga.h
+++ b/saga/saga.h
@@ -425,6 +425,9 @@ public:
virtual ~SagaEngine();
void shutDown() { _quit = true; }
+ void save();
+ void load();
+
int _soundEnabled;
int _musicEnabled;
diff --git a/saga/saveload.cpp b/saga/saveload.cpp
new file mode 100644
index 0000000000..fd7f096104
--- /dev/null
+++ b/saga/saveload.cpp
@@ -0,0 +1,192 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2004-2005 The ScummVM project
+ *
+ * The ReInherit Engine is (C)2000-2003 by Daniel Balsom.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "stdafx.h"
+
+#include "common/config-manager.h"
+#include "common/savefile.h"
+#include "common/system.h"
+#include "common/file.h"
+
+#include "saga/saga.h"
+#include "saga/actor.h"
+#include "saga/isomap.h"
+#include "saga/resnames.h"
+#include "saga/script.h"
+#include "saga/interface.h"
+#include "saga/scene.h"
+
+namespace Saga {
+
+void SagaEngine::save() {
+ File out;
+
+ out.open("ite.sav", File::kFileWriteMode);
+
+ out.writeSint16LE(_actor->_actorsCount);
+ out.writeSint16LE(_actor->_objsCount);
+ out.writeSint16LE(_script->_commonBufferSize);
+ out.writeSint16LE(_actor->getProtagState());
+
+ // Surrounding scene
+ out.writeSint32LE(_scene->getOutsetSceneNumber());
+ out.writeSint32LE(0);
+
+ // Inset scene
+ out.writeSint32LE(_scene->currentSceneNumber());
+ out.writeSint32LE(0);
+
+ uint16 i;
+
+ for (i = 0; i < _actor->_actorsCount; i++) {
+ ActorData *a = _actor->_actors[i];
+
+ out.writeSint32LE(a->sceneNumber);
+ out.writeSint16LE(a->location.x);
+ out.writeSint16LE(a->location.y);
+ out.writeSint16LE(a->location.z);
+ out.writeSint16LE(a->finalTarget.x);
+ out.writeSint16LE(a->finalTarget.y);
+ out.writeSint16LE(a->finalTarget.z);
+ out.writeByte(a->currentAction);
+ out.writeByte(a->facingDirection);
+ out.writeSint16LE(a->targetObject);
+ out.writeByte(a->flags & (kProtagonist | kFollower));
+ out.writeByte(a->frameNumber);
+ out.writeSint16LE(0);
+ }
+
+ for (i = 0; i < _actor->_objsCount; i++) {
+ ObjectData *o = _actor->_objs[i];
+
+ out.writeSint32LE(o->sceneNumber);
+ out.writeSint32LE(o->id);
+ out.writeSint16LE(o->location.x);
+ out.writeSint16LE(o->location.y);
+ out.writeSint16LE(o->location.z);
+ out.writeSint16LE(o->nameIndex);
+ if (o->sceneNumber == ITE_SCENE_INV) {
+ out.writeSint16LE(_interface->inventoryItemPosition(_actor->objIndexToId(i)));
+ } else {
+ out.writeSint16LE(0);
+ }
+ out.writeByte(0);
+ }
+
+ for (i = 0; i < _script->_commonBufferSize; i++)
+ out.writeByte(_script->_commonBuffer[i]);
+
+ out.writeSint16LE(_isoMap->getMapPosition().x);
+ out.writeSint16LE(_isoMap->getMapPosition().y);
+
+ out.close();
+}
+
+void SagaEngine::load() {
+ File out;
+ int actorsCount, objsCount, commonBufferSize;
+ int scenenum, inset;
+
+ out.open("ite.sav");
+
+ if (!out.isOpen())
+ return;
+
+ actorsCount = out.readSint16LE();
+ objsCount = out.readSint16LE();
+ commonBufferSize = out.readSint16LE();
+ _actor->setProtagState(out.readSint16LE());
+
+ // Surrounding scene
+ scenenum = out.readSint32LE();
+ out.readSint32LE();
+
+ // Inset scene
+ inset = out.readSint32LE();
+ out.readSint32LE();
+
+ uint16 i;
+
+ for (i = 0; i < actorsCount; i++) {
+ ActorData *a = _actor->_actors[i];
+
+ a->sceneNumber = out.readSint32LE();
+ a->location.x = out.readSint16LE();
+ a->location.y = out.readSint16LE();
+ a->location.z = out.readSint16LE();
+ a->finalTarget.x = out.readSint16LE();
+ a->finalTarget.y = out.readSint16LE();
+ a->finalTarget.z = out.readSint16LE();
+ a->currentAction = out.readByte();
+ a->facingDirection = out.readByte();
+ a->targetObject = out.readSint16LE();
+ a->flags = (a->flags & ~(kProtagonist | kFollower) | out.readByte());
+ a->frameNumber = out.readByte();
+ out.readSint16LE();
+ }
+
+ _interface->clearInventory();
+
+ for (i = 0; i < objsCount; i++) {
+ ObjectData *o = _actor->_objs[i];
+ int pos;
+
+ o->sceneNumber = out.readSint32LE();
+ o->id = out.readSint32LE();
+ o->location.x = out.readSint16LE();
+ o->location.y = out.readSint16LE();
+ o->location.z = out.readSint16LE();
+ o->nameIndex = out.readSint16LE();
+
+ pos = out.readSint16LE();
+ if (o->sceneNumber == ITE_SCENE_INV) {
+ _interface->addToInventory(_actor->objIndexToId(i), pos);
+ }
+ out.readByte();
+ }
+
+ for (i = 0; i < commonBufferSize; i++)
+ _script->_commonBuffer[i] = out.readByte();
+
+ _isoMap->getMapPosition().x = out.readSint16LE();
+ _isoMap->getMapPosition().y = out.readSint16LE();
+
+ out.close();
+
+
+ // FIXME: When save/load screen will be implemented we should
+ // call these after that screen left by user
+ _interface->draw();
+
+ // FIXME: hmmm... now we always require actorsEntrance to be defined
+ // so no way to restore at arbitrary position
+ _scene->clearSceneQueue();
+ _scene->changeScene(scenenum, 0);
+
+ if (inset != scenenum) {
+ _scene->clearSceneQueue();
+ _scene->changeScene(inset, 0);
+ }
+}
+
+} // End of namespace Saga
diff --git a/saga/scene.cpp b/saga/scene.cpp
index c03263fb37..2c0b0b5b0a 100644
--- a/saga/scene.cpp
+++ b/saga/scene.cpp
@@ -581,6 +581,13 @@ int Scene::loadScene(int scene_num, int load_flag, SCENE_PROC scene_proc, SceneD
return FAILURE;
}
+ if (_desc.flags & kSceneFlagISO) {
+ _outsetSceneNumber = _sceneNumber;
+ } else {
+ if (!(_bg.w < _vm->getDisplayWidth() || _bg.h < _vm->getSceneHeight()))
+ _outsetSceneNumber = _sceneNumber;
+ }
+
_sceneLoaded = true;
q_event = NULL;
@@ -875,7 +882,7 @@ int Scene::processSceneResources() {
_actionMap->load(res_data, res_data_len);
break;
case SAGA_ISO_IMAGES:
- if (!(_vm->_scene->getFlags() & kSceneFlagISO)) {
+ if (!(_desc.flags & kSceneFlagISO)) {
error("Scene::ProcessSceneResources(): not Iso mode");
}
@@ -884,7 +891,7 @@ int Scene::processSceneResources() {
_vm->_isoMap->loadImages(res_data, res_data_len);
break;
case SAGA_ISO_MAP:
- if (!(_vm->_scene->getFlags() & kSceneFlagISO)) {
+ if (!(_desc.flags & kSceneFlagISO)) {
error("Scene::ProcessSceneResources(): not Iso mode");
}
@@ -893,7 +900,7 @@ int Scene::processSceneResources() {
_vm->_isoMap->loadMap(res_data, res_data_len);
break;
case SAGA_ISO_PLATFORMS:
- if (!(_vm->_scene->getFlags() & kSceneFlagISO)) {
+ if (!(_desc.flags & kSceneFlagISO)) {
error("Scene::ProcessSceneResources(): not Iso mode");
}
@@ -902,7 +909,7 @@ int Scene::processSceneResources() {
_vm->_isoMap->loadPlatforms(res_data, res_data_len);
break;
case SAGA_ISO_METATILES:
- if (!(_vm->_scene->getFlags() & kSceneFlagISO)) {
+ if (!(_desc.flags & kSceneFlagISO)) {
error("Scene::ProcessSceneResources(): not Iso mode");
}
@@ -938,7 +945,7 @@ int Scene::processSceneResources() {
}
break;
case SAGA_ISO_MULTI:
- if (!(_vm->_scene->getFlags() & kSceneFlagISO)) {
+ if (!(_desc.flags & kSceneFlagISO)) {
error("Scene::ProcessSceneResources(): not Iso mode");
}
@@ -973,7 +980,7 @@ int Scene::draw(SURFACE *dst_s) {
_vm->_render->getBufferInfo(&buf_info);
- if (_vm->_scene->getFlags() & kSceneFlagISO) {
+ if (_desc.flags & kSceneFlagISO) {
_vm->_isoMap->adjustScroll(false);
_vm->_isoMap->draw(dst_s);
} else {
diff --git a/saga/scene.h b/saga/scene.h
index df0c1344e1..7405bcea77 100644
--- a/saga/scene.h
+++ b/saga/scene.h
@@ -261,6 +261,7 @@ class Scene {
int getSceneLUT(int num);
int currentSceneNumber() const { return _sceneNumber; }
+ int getOutsetSceneNumber() const { return _outsetSceneNumber; }
int currentSceneResourceId() const { return _sceneResourceId; }
private:
@@ -282,6 +283,7 @@ class Scene {
int _firstScene;
bool _sceneLoaded;
int _sceneNumber;
+ int _outsetSceneNumber;
int _sceneResourceId;
bool _inGame;
bool _loadDesc;
diff --git a/saga/script.h b/saga/script.h
index 4fa8feb3d1..d115116f1f 100644
--- a/saga/script.h
+++ b/saga/script.h
@@ -389,9 +389,13 @@ private:
uint16 _modulesLUTEntryLen;
ModuleData *_modules;
int _modulesCount;
-
- byte* _commonBuffer;
+
+protected:
+ friend class SagaEngine;
+ byte *_commonBuffer;
uint _commonBufferSize;
+
+private:
uint _staticSize;
ScriptThreadList _threadList;
@@ -508,7 +512,7 @@ private:
void SF_simulSpeech2(SCRIPTFUNC_PARAMS);
void sfPlacard(SCRIPTFUNC_PARAMS);
void sfPlacardOff(SCRIPTFUNC_PARAMS);
- void SF_setProtagState(SCRIPTFUNC_PARAMS);
+ void sfSetProtagState(SCRIPTFUNC_PARAMS);
void sfResumeBgdAnim(SCRIPTFUNC_PARAMS);
void SF_throwActor(SCRIPTFUNC_PARAMS);
void sfWaitWalk(SCRIPTFUNC_PARAMS);
diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp
index 4a2eaf81e8..07c5dd947c 100644
--- a/saga/sfuncs.cpp
+++ b/saga/sfuncs.cpp
@@ -100,7 +100,7 @@ void Script::setupScriptFuncList(void) {
OPCODE(SF_simulSpeech2),
OPCODE(sfPlacard),
OPCODE(sfPlacardOff),
- OPCODE(SF_setProtagState),
+ OPCODE(sfSetProtagState),
OPCODE(sfResumeBgdAnim),
OPCODE(SF_throwActor),
OPCODE(sfWaitWalk),
@@ -1305,11 +1305,10 @@ void Script::sfPlacardOff(SCRIPTFUNC_PARAMS) {
}
// Script function #50 (0x32)
-void Script::SF_setProtagState(SCRIPTFUNC_PARAMS) {
- for (int i = 0; i < nArgs; i++)
- thread->pop();
+void Script::sfSetProtagState(SCRIPTFUNC_PARAMS) {
+ int protagState = thread->pop();
- debug(0, "STUB: SF_setProtagState(), %d args", nArgs);
+ _vm->_actor->setProtagState(protagState);
}
// Script function #51 (0x33)