From dd5567613f4e733b62760c981cb547fe9656fced Mon Sep 17 00:00:00 2001 From: Benjamin Haisch Date: Mon, 11 Aug 2008 12:43:00 +0000 Subject: TOLTECS: - Renamed stuff and cleanups - Beginnings of the saveload system (incomplete) --- engines/toltecs/animation.cpp | 22 +++++++- engines/toltecs/animation.h | 4 +- engines/toltecs/input.cpp | 14 ++++++ engines/toltecs/module.mk | 1 + engines/toltecs/palette.cpp | 40 +++++++++++++++ engines/toltecs/palette.h | 8 +++ engines/toltecs/saveload.cpp | 114 ++++++++++++++++++++++++++++++++++++++++++ engines/toltecs/screen.cpp | 11 ++++ engines/toltecs/screen.h | 4 ++ engines/toltecs/script.cpp | 48 +++++++++++++++--- engines/toltecs/script.h | 22 ++++---- engines/toltecs/toltecs.cpp | 12 ++--- engines/toltecs/toltecs.h | 7 ++- 13 files changed, 280 insertions(+), 27 deletions(-) create mode 100644 engines/toltecs/saveload.cpp (limited to 'engines/toltecs') diff --git a/engines/toltecs/animation.cpp b/engines/toltecs/animation.cpp index 2ecc12bafd..bd8fd7f46f 100644 --- a/engines/toltecs/animation.cpp +++ b/engines/toltecs/animation.cpp @@ -34,6 +34,7 @@ #include "toltecs/toltecs.h" #include "toltecs/animation.h" +#include "toltecs/palette.h" #include "toltecs/screen.h" namespace Toltecs { @@ -55,7 +56,7 @@ void AnimationPlayer::start(uint resIndex) { _height = _vm->_arc->readUint16LE(); _width = _vm->_arc->readUint16LE(); _frameCount = _vm->_arc->readUint16LE(); - _vm->_arc->read(_palette, 768); + _vm->_arc->read(_vm->_palette->getAnimPalette(), 768); _curFrameSize = _vm->_arc->readUint32LE(); _nextFrameOffset = _curFrameSize + 782; _vm->_arc->read(_animBuffer, _curFrameSize); @@ -136,4 +137,23 @@ void AnimationPlayer::unpackFrame() { _vm->_screen->unpackRle(_animBuffer, _vm->_screen->_backScreen, _width, _height); } +void AnimationPlayer::saveState(Common::WriteStream *out) { + out->writeUint16LE(_resIndex); + // NOTE: The original engine doesn't save width/height, but we do + out->writeUint16LE(_width); + out->writeUint16LE(_height); + out->writeUint16LE(_frameCount); + out->writeUint16LE(_frameNumber); + out->writeUint32LE(_keepFrameCounter); + out->writeUint32LE(_curFrameSize); + out->writeUint32LE(_nextFrameSize); + out->writeUint32LE(_nextFrameOffset); + out->writeUint32LE(_firstCurFrameSize); + out->writeUint32LE(_firstNextFrameSize); + out->writeUint32LE(_firstNextFrameOffset); +} + +void AnimationPlayer::loadState(Common::ReadStream *in) { +} + } // End of namespace Toltecs diff --git a/engines/toltecs/animation.h b/engines/toltecs/animation.h index a8bef1fdbf..03aa18cf66 100644 --- a/engines/toltecs/animation.h +++ b/engines/toltecs/animation.h @@ -57,6 +57,9 @@ public: int16 getStatus(); uint16 getFrameNumber() const { return _frameNumber; } + void saveState(Common::WriteStream *out); + void loadState(Common::ReadStream *in); + //protected: public: ToltecsEngine *_vm; @@ -65,7 +68,6 @@ public: byte *_animBuffer; uint _resIndex; - byte _palette[768]; uint16 _width, _height; uint16 _frameNumber, _frameCount; diff --git a/engines/toltecs/input.cpp b/engines/toltecs/input.cpp index ca09a9bb2b..b658c6278b 100644 --- a/engines/toltecs/input.cpp +++ b/engines/toltecs/input.cpp @@ -64,6 +64,20 @@ void Input::update() { while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_KEYDOWN: + + // FIXME: This is just for debugging + switch (event.kbd.keycode) { + case Common::KEYCODE_F6: + _vm->savegame("toltecs.001"); + break; + case Common::KEYCODE_F9: + _vm->loadgame("toltecs.001"); + break; + default: + break; + } + + break; case Common::EVENT_QUIT: break; case Common::EVENT_MOUSEMOVE: diff --git a/engines/toltecs/module.mk b/engines/toltecs/module.mk index 63a804307d..1f249a8220 100644 --- a/engines/toltecs/module.mk +++ b/engines/toltecs/module.mk @@ -7,6 +7,7 @@ MODULE_OBJS = \ palette.o \ toltecs.o \ resource.o \ + saveload.o \ screen.o \ script.o \ segmap.o diff --git a/engines/toltecs/palette.cpp b/engines/toltecs/palette.cpp index 7c882f1c8a..0f08694db0 100644 --- a/engines/toltecs/palette.cpp +++ b/engines/toltecs/palette.cpp @@ -42,6 +42,8 @@ Palette::Palette(ToltecsEngine *vm) : _vm(vm) { clearFragments(); + memset(_colorTransTable, 0, sizeof(_colorTransTable)); + } Palette::~Palette() { @@ -59,6 +61,16 @@ void Palette::setFullPalette(byte *palette) { _vm->_system->updateScreen(); } +void Palette::getFullPalette(byte *palette) { + byte colors[1024]; + _vm->_system->grabPalette(colors, 0, 256); + for (int i = 0; i < 256; i++) { + palette[i * 3 + 0] = colors[i * 4 + 0] >> 2; + palette[i * 3 + 1] = colors[i * 4 + 1] >> 2; + palette[i * 3 + 2] = colors[i * 4 + 2] >> 2; + } +} + void Palette::setDeltaPalette(byte *palette, byte mask, char deltaValue, int16 count, int16 startIndex) { byte colors[1024]; @@ -154,4 +166,32 @@ void Palette::clearFragments() { _fragments.clear(); } +void Palette::saveState(Common::WriteStream *out) { + + // Save currently active palette + byte palette[768]; + getFullPalette(palette); + out->write(palette, 768); + + out->write(_mainPalette, 768); + out->write(_animPalette, 768); + out->write(_colorTransTable, 256); + + uint16 fragmentCount = _fragments.size(); + out->writeUint16LE(fragmentCount); + for (PaletteFragmentArray::iterator iter = _fragments.begin(); iter != _fragments.end(); iter++) { + PaletteFragment fragment = *iter; + out->writeUint16LE(fragment.id); + out->writeByte(fragment.index); + out->writeByte(fragment.count); + } + out->writeByte(_fragmentIndex); + + +} + +void Palette::loadState(Common::ReadStream *in) { +} + + } // End of namespace Toltecs diff --git a/engines/toltecs/palette.h b/engines/toltecs/palette.h index 339ff8db7d..acc340723d 100644 --- a/engines/toltecs/palette.h +++ b/engines/toltecs/palette.h @@ -29,6 +29,7 @@ #include "common/util.h" #include "common/file.h" #include "common/savefile.h" +#include "common/stream.h" #include "common/system.h" #include "common/hash-str.h" #include "common/events.h" @@ -53,6 +54,7 @@ public: ~Palette(); void setFullPalette(byte *palette); + void getFullPalette(byte *palette); void setDeltaPalette(byte *palette, byte mask, char deltaValue, int16 count, int16 startIndex); void loadAddPalette(uint resIndex, byte startIndex); @@ -63,6 +65,10 @@ public: void clearFragments(); byte *getMainPalette() { return _mainPalette; } + byte *getAnimPalette() { return _animPalette; } + + void saveState(Common::WriteStream *out); + void loadState(Common::ReadStream *in); protected: @@ -76,6 +82,8 @@ protected: ToltecsEngine *_vm; byte _mainPalette[768]; + byte _animPalette[768]; + byte _colorTransTable[256]; PaletteFragmentArray _fragments; byte _fragmentIndex; diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp new file mode 100644 index 0000000000..52325b9ab3 --- /dev/null +++ b/engines/toltecs/saveload.cpp @@ -0,0 +1,114 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * + */ + +#include "common/events.h" +#include "common/keyboard.h" +#include "common/file.h" +#include "common/savefile.h" +#include "common/config-manager.h" + +#include "base/plugins.h" +#include "base/version.h" + +#include "sound/mixer.h" + +#include "toltecs/toltecs.h" +#include "toltecs/animation.h" +#include "toltecs/input.h" +#include "toltecs/palette.h" +#include "toltecs/resource.h" +#include "toltecs/script.h" +#include "toltecs/screen.h" +#include "toltecs/segmap.h" + +namespace Toltecs { + +// TODO: Saveload is not working yet + +void ToltecsEngine::savegame(const char *filename) { + + Common::OutSaveFile *out; + if (!(out = g_system->getSavefileManager()->openForSaving(filename))) { + warning("Can't create file '%s', game not saved", filename); + } + + // Save game variables + for (uint variable = 0; variable < 22; variable++) { + int16 value = _script->getGameVar(variable); + out->writeUint16LE(value); + } + + _palette->saveState(out); + _script->saveState(out); + _anim->saveState(out); + + // Save GUI + { + + } + +/* +case 0: return "mouseDisabled"; +case 1: return "mouseY"; +case 2: return "mouseX"; +case 3: return "mouseButton"; +case 4: return "verbLineY"; +case 5: return "verbLineX"; +case 6: return "verbLineWidth"; +case 7: return "verbLineCount"; +case 8: return "verbLineNum"; +case 9: return "talkTextItemNum"; +case 10: return "talkTextY"; +case 11: return "talkTextX"; +case 12: return "talkTextFontColor"; +case 13: return "cameraY"; +case 14: return "cameraX"; +case 15: return "walkSpeedY"; +case 16: return "walkSpeedX"; +case 17: return "flag01"; +case 18: return "sceneResIndex"; +case 19: return "cameraTop"; +case 20: return "sceneHeight"; +case 21: return "sceneWidth"; +*/ + +/* +PersistentGameVarRef +PersistentGameVarRef +PersistentGameVarRef +PersistentGameVarRef +PersistentGameVarRef +PersistentGameVarRef +PersistentGameVarRef +PersistentGameVarRef +*/ + + delete out; + +} + +void ToltecsEngine::loadgame(const char *filename) { +} + + +} // End of namespace Toltecs diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp index 779513a420..a11022cb13 100644 --- a/engines/toltecs/screen.cpp +++ b/engines/toltecs/screen.cpp @@ -963,6 +963,17 @@ void Screen::drawChar2(const Font &font, byte *dest, int16 x, int16 y, byte ch, } +void Screen::saveState(Common::WriteStream *out) { + for (int i = 0; i < 8; i++) { + out->writeUint16LE(_verbLineItems[i].slotIndex); + out->writeUint16LE(_verbLineItems[i].slotOffset); + } +} + +void Screen::loadState(Common::ReadStream *in) { +} + + /* void Screen::update() { } diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h index 156e4e18b6..c34f44dfa8 100644 --- a/engines/toltecs/screen.h +++ b/engines/toltecs/screen.h @@ -327,6 +327,9 @@ public: void drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color); void drawChar2(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color); + void saveState(Common::WriteStream *out); + void loadState(Common::ReadStream *in); + //protected: public: @@ -348,6 +351,7 @@ public: uint _fontResIndexArray[10]; byte _fontColor1, _fontColor2; + // TODO: Remove this _tempXXX stuff byte _tempString[100]; byte _tempStringLen1, _tempStringLen2; diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp index 0b27e8af3b..fa382194f8 100644 --- a/engines/toltecs/script.cpp +++ b/engines/toltecs/script.cpp @@ -21,6 +21,8 @@ * */ +// TODO: Clean up game variable handling and move it to ToltecsEngine + #include "common/events.h" #include "common/keyboard.h" #include "common/file.h" @@ -45,7 +47,7 @@ namespace Toltecs { ScriptInterpreter::ScriptInterpreter(ToltecsEngine *vm) : _vm(vm) { - _stack = new byte[4096 + 4]; + _stack = new byte[kScriptStackSize]; memset(_slots, 0, sizeof(_slots)); @@ -550,7 +552,7 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) { case 14:// ok { debug(0, "o2_setDeltaPalette(animPalette, %d, %d, %d, %d)", arg8(6), arg8(5), arg8(4), arg8(3)); - _vm->_palette->setDeltaPalette(_vm->_anim->_palette, arg8(6), (char)arg8(5), arg8(4), arg8(3)); + _vm->_palette->setDeltaPalette(_vm->_palette->getAnimPalette(), arg8(6), (char)arg8(5), arg8(4), arg8(3)); break; } @@ -604,8 +606,8 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) { case 22:// ok { - debug(0, "o2_setCameraTop(%d)", arg8(3)); - _vm->setCameraTop(arg8(3)); + debug(0, "o2_setGuiHeight(%d)", arg8(3)); + _vm->setGuiHeight(arg8(3)); break; } @@ -926,7 +928,7 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) { } -ScriptInterpreter::VarType ScriptInterpreter::getGameVarType(uint variable) { +VarType ScriptInterpreter::getGameVarType(uint variable) { switch (variable) { case 0: return vtByte; case 1: return vtWord; @@ -976,7 +978,7 @@ const char *getVarName(uint variable) { case 16: return "walkSpeedX"; case 17: return "flag01"; case 18: return "sceneResIndex"; - case 19: return "cameraTop"; + case 19: return "guiHeight"; case 20: return "sceneHeight"; case 21: return "sceneWidth"; } @@ -1047,7 +1049,7 @@ int16 ScriptInterpreter::getGameVar(uint variable) { value = _vm->_sceneResIndex; break; case 19: - value = _vm->_cameraTop; + value = _vm->_guiHeight; break; case 20: value = _vm->_sceneHeight; @@ -1122,7 +1124,7 @@ void ScriptInterpreter::setGameVar(uint variable, int16 value) { _vm->_sceneResIndex = value; break; case 19: - _vm->_cameraTop = value; + _vm->_guiHeight = value; break; case 20: _vm->_sceneHeight = value; @@ -1217,4 +1219,34 @@ byte *ScriptInterpreter::localPtr(int16 offset) { return &_localData[offset]; } +void ScriptInterpreter::saveState(Common::WriteStream *out) { + + // Save registers + out->writeUint16LE(_regs.reg0); + out->writeUint16LE(_regs.reg1); + out->writeUint16LE(_regs.reg2); + out->writeUint16LE(_regs.reg3); + out->writeUint16LE(_regs.reg4); + out->writeUint16LE(_regs.reg5); + out->writeUint16LE(_regs.reg6); + out->writeUint16LE(_regs.sp); + out->writeUint16LE(_regs.reg8); + + // Save slots + for (int slot = 0; slot < kMaxScriptSlots; slot++) { + out->writeUint32LE(_slots[slot].size); + out->writeUint16LE(_slots[slot].resIndex); + if (_slots[slot].size > 0) + out->write(_slots[slot].data, _slots[slot].size); + } + + // Save stack + out->write(_stack, kScriptStackSize); + out->writeUint16LE(_savedSp); + +} + +void ScriptInterpreter::loadState(Common::ReadStream *in) { +} + } // End of namespace Toltecs diff --git a/engines/toltecs/script.h b/engines/toltecs/script.h index d7712a8932..eacd116d82 100644 --- a/engines/toltecs/script.h +++ b/engines/toltecs/script.h @@ -45,6 +45,12 @@ namespace Toltecs { const int kMaxScriptSlots = 50; +const int kScriptStackSize = 4096 + 4; + +enum VarType { + vtByte, + vtWord +}; class ScriptInterpreter { public: @@ -56,12 +62,14 @@ public: byte *getSlotData(int slotIndex) const { return _slots[slotIndex].data; } -protected: + VarType getGameVarType(uint variable); + int16 getGameVar(uint variable); + void setGameVar(uint variable, int16 value); - enum VarType { - vtByte, - vtWord - }; + void saveState(Common::WriteStream *out); + void loadState(Common::ReadStream *in); + +protected: struct ScriptRegs { int16 reg0; @@ -101,10 +109,6 @@ protected: void execOpcode(byte opcode); void execKernelOpcode(uint16 kernelOpcode); - VarType getGameVarType(uint variable); - int16 getGameVar(uint variable); - void setGameVar(uint variable, int16 value); - byte arg8(int16 offset); int16 arg16(int16 offset); int32 arg32(int16 offset); diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp index 73de88f6f3..f1b531f878 100644 --- a/engines/toltecs/toltecs.cpp +++ b/engines/toltecs/toltecs.cpp @@ -98,7 +98,7 @@ int ToltecsEngine::go() { _cameraY = 0; _newCameraX = 0; _newCameraY = 0; - _cameraTop = 26; + _guiHeight = 26; _cameraHeight = 0; _yetAnotherX = 0; @@ -227,11 +227,11 @@ void ToltecsEngine::setCamera(int16 x, int16 y) { } -void ToltecsEngine::setCameraTop(int16 top) { - if (top != _cameraTop) { - _cameraTop = top; - _cameraHeight = 400 - _cameraTop; - debug(0, "ToltecsEngine::setCameraTop() _cameraTop = %d; _cameraHeight = %d", _cameraTop, _cameraHeight); +void ToltecsEngine::setGuiHeight(int16 guiHeight) { + if (guiHeight != _guiHeight) { + _guiHeight = guiHeight; + _cameraHeight = 400 - _guiHeight; + debug(0, "ToltecsEngine::setGuiHeight() _guiHeight = %d; _cameraHeight = %d", _guiHeight, _cameraHeight); // TODO: clearScreen(); } } diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h index 1d5a394f62..11ce76715c 100644 --- a/engines/toltecs/toltecs.h +++ b/engines/toltecs/toltecs.h @@ -80,7 +80,7 @@ public: void updateScreen(); void setCamera(int16 x, int16 y); - void setCameraTop(int16 top); + void setGuiHeight(int16 guiHeight); void scrollCameraUp(int16 delta); void scrollCameraDown(int16 delta); void scrollCameraLeft(int16 delta); @@ -94,6 +94,9 @@ public: int16 findRectAtPoint(byte *rectData, int16 x, int16 y, int16 index, int16 itemSize); + void savegame(const char *filename); + void loadgame(const char *filename); + public: AnimationPlayer *_anim; ArchiveReader *_arc; @@ -116,7 +119,7 @@ public: // TODO: Move camera stuff into own Scene class int16 _cameraX, _cameraY; int16 _newCameraX, _newCameraY; - int16 _cameraTop, _cameraHeight; + int16 _guiHeight, _cameraHeight; int16 _yetAnotherX; bool _doSpeech, _doText; -- cgit v1.2.3