diff --git a/engines/grim/color.h b/engines/grim/color.h index 720c382ae83..80850487735 100644 --- a/engines/grim/color.h +++ b/engines/grim/color.h @@ -67,12 +67,14 @@ public: state->writeByte(_vals[2]); } - bool restoreState(SaveGame *state) { - _vals[0] = state->readByte(); - _vals[1] = state->readByte(); - _vals[2] = state->readByte(); + static ObjectPtr restoreObject(SaveGame *state) { + Color *c = new Color(); + ObjectPtr ptr(c); + c->_vals[0] = state->readByte(); + c->_vals[1] = state->readByte(); + c->_vals[2] = state->readByte(); - return true; + return ptr; } }; diff --git a/engines/grim/font.cpp b/engines/grim/font.cpp index c63a334d281..703ba489088 100644 --- a/engines/grim/font.cpp +++ b/engines/grim/font.cpp @@ -36,180 +36,75 @@ using namespace std; namespace Grim { Font::Font(const char *filename, const char *data, int len) : Object() { - load(filename, data, len); + _fname = filename; + + _filename = filename; + _numChars = READ_LE_UINT32(data); + _dataSize = READ_LE_UINT32(data + 4); + _height = READ_LE_UINT32(data + 8); + _baseOffsetY = READ_LE_UINT32(data + 12); + _firstChar = READ_LE_UINT32(data + 24); + _lastChar = READ_LE_UINT32(data + 28); + + data += 32; + + // Read character indexes - are the key/value reversed? + _charIndex = new uint16[_numChars]; + if (!_charIndex) + error("Could not load font %s. Out of memory", filename); + for (uint i = 0; i < _numChars; ++i) { + _charIndex[i] = READ_LE_UINT16(data + 2 * i); + } + + data += _numChars * 2; + + // Read character headers + _charHeaders = new CharHeader[_numChars]; + if (!_charHeaders) + error("Could not load font %s. Out of memory", filename); + for (uint i = 0; i < _numChars; ++i) { + _charHeaders[i].offset = READ_LE_UINT32(data); + _charHeaders[i].width = *(int8 *)(data + 4); + _charHeaders[i].startingCol = *(int8 *)(data + 5); + _charHeaders[i].startingLine = *(int8 *)(data + 6); + _charHeaders[i].dataWidth = READ_LE_UINT32(data + 8); + _charHeaders[i].dataHeight = READ_LE_UINT32(data + 12); + data += 16; + } + // Read font data + _fontData = new byte[_dataSize]; + if (!_fontData) + error("Could not load font %s. Out of memory", filename); + + memcpy(_fontData, data, _dataSize); +} + +Font::Font() : + Object() { + _charIndex = NULL; } Font::~Font() { - if (_charIndex) { - delete[] _charIndex; - delete[] _charHeaders; - delete[] _fontData; + if (_charIndex) { + delete[] _charIndex; + delete[] _charHeaders; + delete[] _fontData; g_resourceloader->uncacheFont(this); - } -} - -void Font::load(const char *filename, const char *data, int len) { - _fname = filename; - - _filename = filename; - _numChars = READ_LE_UINT32(data); - _dataSize = READ_LE_UINT32(data + 4); - _height = READ_LE_UINT32(data + 8); - _baseOffsetY = READ_LE_UINT32(data + 12); - _firstChar = READ_LE_UINT32(data + 24); - _lastChar = READ_LE_UINT32(data + 28); - - data += 32; - - // Read character indexes - are the key/value reversed? - _charIndex = new uint16[_numChars]; - if (!_charIndex) - error("Could not load font %s. Out of memory", filename); - for (uint i = 0; i < _numChars; ++i) { - _charIndex[i] = READ_LE_UINT16(data + 2 * i); - } - - data += _numChars * 2; - - // Read character headers - _charHeaders = new CharHeader[_numChars]; - if (!_charHeaders) - error("Could not load font %s. Out of memory", filename); - for (uint i = 0; i < _numChars; ++i) { - _charHeaders[i].offset = READ_LE_UINT32(data); - _charHeaders[i].width = *(int8 *)(data + 4); - _charHeaders[i].startingCol = *(int8 *)(data + 5); - _charHeaders[i].startingLine = *(int8 *)(data + 6); - _charHeaders[i].dataWidth = READ_LE_UINT32(data + 8); - _charHeaders[i].dataHeight = READ_LE_UINT32(data + 12); - data += 16; - } - // Read font data - _fontData = new byte[_dataSize]; - if (!_fontData) - error("Could not load font %s. Out of memory", filename); - - memcpy(_fontData, data, _dataSize); + } } void Font::saveState(SaveGame *savedState) const { - int32 size; - const char *str; - - str = _fname.c_str(); - size = strlen(str); - savedState->writeLESint32(size); - savedState->write(str, size); - -// savedState->writeLESint32(_fname.size()); -// savedState->write(_fname.c_str(), _fname.size()); -// savedState->writeLESint32(_filename.size()); -// savedState->write(_filename.c_str(), _filename.size()); -// -// //_fontData -// savedState->writeLEUint32(_dataSize); -// PointerId ptr = makeIdFromPointer(_fontData); -// // cout<writeLEUint32(ptr.low); -// savedState->writeLEUint32(ptr.hi); -// for (uint32 i = 0; i < _dataSize; ++i) { -// savedState->writeByte(_fontData[i]); -// } -// -// //_charHeaders -// savedState->writeLEUint32(_numChars); -// ptr = makeIdFromPointer(_charHeaders); -// savedState->writeLEUint32(ptr.low); -// savedState->writeLEUint32(ptr.hi); -// // cout<<_numChars<writeLESint32(_charHeaders[i].offset); -// savedState->writeLESint32(_charHeaders[i].width); -// savedState->writeLESint32(_charHeaders[i].startingCol); -// savedState->writeLESint32(_charHeaders[i].startingLine); -// savedState->writeLESint32(_charHeaders[i].dataWidth); -// savedState->writeLESint32(_charHeaders[i].dataHeight); -// } -// -// //_charIndex -// ptr = makeIdFromPointer(_charIndex); -// savedState->writeLEUint32(ptr.low); -// savedState->writeLEUint32(ptr.hi); -// for (uint32 i = 0; i < _numChars; ++i) { -// savedState->writeLEUint32(_charIndex[i]); -// } -// -// savedState->writeLEUint32(_firstChar); -// savedState->writeLEUint32(_lastChar); -// savedState->writeLEUint32(_height); -// savedState->writeLEUint32(_baseOffsetY); + savedState->writeCharString(_fname.c_str()); } -bool Font::restoreState(SaveGame *savedState) { - int32 size; - char *str = 0; +ObjectPtr Font::restoreObject(SaveGame *state) { + const char *fname = state->readCharString(); + FontPtr font = g_resourceloader->getFont(fname); + delete[] fname; + ObjectPtr ptr = font.object(); - // load actor name - size = savedState->readLESint32(); - str = new char[size + 1]; - savedState->read(str, size); - str[size] = '\0'; - - Block *b = g_resourceloader->getBlock(str); - if (b) { - load(str, b->data(), b->len()); - } - - - delete[] str; - return true; - -// int32 size = savedState->readLESint32(); -// char *str = new char[size]; -// savedState->read(str, size); -// _fname.load(str, size); -// delete str; -// size = savedState->readLESint32(); -// str = new char[size]; -// savedState->read(str, size); -// _filename.load(str, size); -// delete str; -// -// _dataSize = savedState->readLEUint32(); -// PointerId ptr; -// ptr.low = savedState->readLEUint32(); -// ptr.hi = savedState->readLEUint32(); -// _fontData = static_cast(makePointerFromId(ptr)); -// for (uint32 i = 0; i < _dataSize; ++i) { -// _fontData[i] = savedState->readByte(); -// } -// -// _numChars = savedState->readLEUint32(); -// ptr.low = savedState->readLEUint32(); -// ptr.hi = savedState->readLEUint32(); -// _charHeaders = static_cast(makePointerFromId(ptr)); -// for (uint32 i = 0; i < _numChars; ++i) { -// _charHeaders[i].offset = savedState->readLESint32(); -// _charHeaders[i].width = savedState->readLESint32(); -// _charHeaders[i].startingCol = savedState->readLESint32(); -// _charHeaders[i].startingLine = savedState->readLESint32(); -// _charHeaders[i].dataWidth = savedState->readLESint32(); -// _charHeaders[i].dataHeight = savedState->readLESint32(); -// } -// -// //_charIndex -// ptr.low = savedState->readLEUint32(); -// ptr.hi = savedState->readLEUint32(); -// _charIndex = static_cast(makePointerFromId(ptr)); -// for (uint32 i = 0; i < _numChars; ++i) { -// _charIndex[i] = savedState->readLEUint32(); -// } -// -// _firstChar = savedState->readLEUint32(); -// _lastChar = savedState->readLEUint32(); -// _height = savedState->readLEUint32(); -// _baseOffsetY = savedState->readLEUint32(); + return ptr; } uint16 Font::getCharIndex(unsigned char c) { diff --git a/engines/grim/font.h b/engines/grim/font.h index 11f3a84337f..81e8a4c547e 100644 --- a/engines/grim/font.h +++ b/engines/grim/font.h @@ -37,11 +37,9 @@ class Font : public Object { GRIM_OBJECT(Font) public: Font(const char *filename, const char *data, int len); - Font() : Object() { _charIndex = 0; } + Font(); ~Font(); - void load(const char *filename, const char *data, int len); - Common::String getFilename() { return _filename; } int32 getHeight() { return _height; } int32 getBaseOffsetY() { return _baseOffsetY; } @@ -53,7 +51,7 @@ public: const byte *getCharData(unsigned char c) { return _fontData + (_charHeaders[getCharIndex(c)].offset); } void saveState(SaveGame *savedState) const; - bool restoreState(SaveGame *savedState); + static ObjectPtr restoreObject(SaveGame *savedState); static const uint8 emerFont[][13]; private: diff --git a/engines/grim/grim.cpp b/engines/grim/grim.cpp index 06b18e3f782..8b9b0f0f319 100644 --- a/engines/grim/grim.cpp +++ b/engines/grim/grim.cpp @@ -61,10 +61,10 @@ namespace Grim { static const bool color = ObjectManager::registerType(); static const bool luafile = ObjectManager::registerType(); -static const bool bitmap = ObjectManager::registerType(); -static const bool costume = ObjectManager::registerType(); +// static const bool bitmap = ObjectManager::registerType(); +// static const bool costume = ObjectManager::registerType(); static const bool font = ObjectManager::registerType(); -static const bool material = ObjectManager::registerType(); +// static const bool material = ObjectManager::registerType(); static bool g_lua_initialized = false; diff --git a/engines/grim/lua/liolib.cpp b/engines/grim/lua/liolib.cpp index 781cf50e729..add2bbbd684 100644 --- a/engines/grim/lua/liolib.cpp +++ b/engines/grim/lua/liolib.cpp @@ -120,24 +120,26 @@ void LuaFile::saveState(SaveGame *state) const { state->writeLESint32(_stderr); } -bool LuaFile::restoreState(SaveGame *state) { - _name = state->readString();; - _filename = state->readString(); +ObjectPtr LuaFile::restoreObject(SaveGame *state) { + LuaFile *l = new LuaFile(); + + l->_name = state->readString(); + l->_filename = state->readString(); if (state->readLESint32()) { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); - _in = saveFileMan->openForLoading(_filename.c_str()); + l->_in = saveFileMan->openForLoading(l->_filename.c_str()); } if (state->readLESint32()) { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); - _out = saveFileMan->openForSaving(_filename.c_str()); + l->_out = saveFileMan->openForSaving(l->_filename.c_str()); } - _stdin = state->readLESint32(); - _stdout = state->readLESint32(); - _stderr = state->readLESint32(); + l->_stdin = state->readLESint32(); + l->_stdout = state->readLESint32(); + l->_stderr = state->readLESint32(); - return true; + return ObjectPtr(l); } static int32 gettag(int32 i) { diff --git a/engines/grim/lua/lrestore.cpp b/engines/grim/lua/lrestore.cpp index 4a52ac23632..82b0020827c 100644 --- a/engines/grim/lua/lrestore.cpp +++ b/engines/grim/lua/lrestore.cpp @@ -286,7 +286,10 @@ void lua_Restore(RestoreStream restoreStream, RestoreSint32 restoreSint32, Resto int id = restoreUint32(); pointer = g_grim->objectState(id); } else { - pointer = ObjectManager::restoreObject(g_grim->_savedState); + ObjectPtr p = ObjectManager::restoreObject(g_grim->_savedState); + Object *o = p.object(); + o->reference(); + pointer = o; } if (!pointer) { pointer = makePointerFromId(ptr); diff --git a/engines/grim/lua/lua.h b/engines/grim/lua/lua.h index fb45019c985..287cf595be4 100644 --- a/engines/grim/lua/lua.h +++ b/engines/grim/lua/lua.h @@ -56,7 +56,7 @@ public: ~LuaFile(); void saveState(SaveGame *state) const; - bool restoreState(SaveGame *state); + static ObjectPtr restoreObject(SaveGame *state); void close(); bool isOpen() const; diff --git a/engines/grim/lua_v1.cpp b/engines/grim/lua_v1.cpp index 5c11c8bde2e..5893cb7d9e4 100644 --- a/engines/grim/lua_v1.cpp +++ b/engines/grim/lua_v1.cpp @@ -2738,7 +2738,7 @@ static void GetImage() { const char *bitmapName = lua_getstring(nameObj); BitmapPtr ptr = g_resourceloader->getBitmap(bitmapName).object(); Bitmap *image = ptr.object(); - image->ref(); + image->reference(); lua_pushusertag(image, MKID_BE('VBUF')); } @@ -2747,7 +2747,7 @@ static void FreeImage() { if (!lua_isuserdata(param) || lua_tag(param) != MKID_BE('VBUF')) return; Bitmap *bitmap = static_cast(lua_getuserdata(param)); - bitmap->deref(); + bitmap->dereference(); killBitmapPrimitives(bitmap); } @@ -3648,7 +3648,7 @@ static void LockFont() { const char *fontName = lua_getstring(param1); FontPtr ptr = g_resourceloader->getFont(fontName); Font *result = ptr.object(); - result->ref(); + result->reference(); if (result) { lua_pushusertag(result, MKID_BE('FONT')); return; diff --git a/engines/grim/object.cpp b/engines/grim/object.cpp index ea1486e8adb..9992a76835e 100644 --- a/engines/grim/object.cpp +++ b/engines/grim/object.cpp @@ -4,9 +4,11 @@ #include "engines/grim/lua/lobject.h" +#include "engines/grim/font.h" + namespace Grim { -typedef Object *(*CreatorFunc)(); +typedef ObjectPtr (*CreatorFunc)(SaveGame *); Common::HashMap ObjectManager::_creators; Object::Object() : _refCount(0) { @@ -22,18 +24,6 @@ Object::~Object() { } } -void Object::save(SaveGame *state) const { - state->writeLEUint32(_refCount); - - saveState(state); -} - -bool Object::restore(SaveGame *state) { - _refCount = state->readLEUint32(); - - return restoreState(state); -} - void Object::saveState(SaveGame */*state*/) const { } @@ -42,11 +32,11 @@ bool Object::restoreState(SaveGame */*state*/) { return false; } -void Object::ref() { +void Object::reference() { ++_refCount; } -void Object::deref() { +void Object::dereference() { if (_refCount > 0) { --_refCount; } @@ -65,32 +55,23 @@ void ObjectManager::saveObject(SaveGame *state, Object *object) { state->writeLEUint32(len); state->write(str, len); - object->save(state); + object->saveState(state); } -Object *ObjectManager::restoreObject(SaveGame *state) { - int32 len = state->readLEUint32(); - char *str = new char[len + 1]; - state->read(str, len); - str[len] = '\0'; +ObjectPtr ObjectManager::restoreObject(SaveGame *state) { + const char *str = state->readCharString(); - Object *o = newObject(str); + ObjectPtr ptr; + Common::String type = str; delete[] str; - o->restore(state); - return o; -} - -Object *ObjectManager::newObject(const char *typeName) { - Common::String type = typeName; if (_creators.contains(type)) { CreatorFunc func = _creators.getVal(type); - Object *o = (func)(); - return o; + ptr = (func)(state); } else { - warning("Type name \"%s\" not registered", typeName); + error("Type name \"%s\" not registered", type.c_str()); } - return 0; + return ptr; } } diff --git a/engines/grim/object.h b/engines/grim/object.h index 1de57c244f9..181084258ae 100644 --- a/engines/grim/object.h +++ b/engines/grim/object.h @@ -31,8 +31,8 @@ #include "common/hash-str.h" #include "common/func.h" #include "common/list.h" -#include -using namespace std; +#include "common/debug.h" + namespace Grim { class SaveGame; @@ -45,16 +45,12 @@ public: virtual const char *typeName() const { return ""; } - void save(SaveGame *state) const; - bool restore(SaveGame *state); - - void ref(); - void deref(); - -protected: virtual void saveState(SaveGame *state) const; virtual bool restoreState(SaveGame *state); + void reference(); + void dereference(); + private: int _refCount; Common::List _pointers; @@ -87,7 +83,7 @@ public: ObjectPtr(T *obj) : _obj(obj) { if (obj) { - _obj->ref(); + _obj->reference(); addPointer(obj); } } @@ -98,7 +94,7 @@ public: ~ObjectPtr() { if (_obj) { rmPointer(_obj); - _obj->deref(); + _obj->dereference(); } } @@ -106,14 +102,14 @@ public: if (obj != _obj) { if (_obj) { rmPointer(_obj); - _obj->deref(); + _obj->dereference(); _obj = NULL; } if (obj) { _obj = obj; - _obj->ref(); + _obj->reference(); addPointer(obj); } } @@ -124,14 +120,14 @@ public: if (_obj != ptr._obj) { if (_obj) { rmPointer(_obj); - _obj->deref(); + _obj->dereference(); _obj = NULL; } if (ptr._obj) { _obj = ptr._obj; - _obj->ref(); + _obj->reference(); addPointer(_obj); } } @@ -176,8 +172,7 @@ private: class ObjectManager { public: static void saveObject(SaveGame *state, Object *object); - static Object *restoreObject(SaveGame *state); - static Object *newObject(const char *typeName); + static ObjectPtr restoreObject(SaveGame *state); template static bool registerType() { T obj; @@ -186,7 +181,7 @@ public: warning("Type name %s already registered", type.c_str()); return false; } - _creators.setVal(type, &createObj); + _creators.setVal(type, T::restoreObject); return true; } @@ -196,7 +191,7 @@ private: return new T(); } - typedef Object *(*CreatorFunc)(); + typedef ObjectPtr (*CreatorFunc)(SaveGame *); static Common::HashMap _creators; };