diff --git a/src/app/crash/doc_format.h b/src/app/crash/doc_format.h index 52346056a..be47ce1f1 100644 --- a/src/app/crash/doc_format.h +++ b/src/app/crash/doc_format.h @@ -10,6 +10,7 @@ #define DOC_FORMAT_VERSION_0 0 // Old version #define DOC_FORMAT_VERSION_1 1 // New version with tilesets -#define DOC_FORMAT_VERSION_LAST 1 +#define DOC_FORMAT_VERSION_2 2 // Version 2 adds custom properties to user data +#define DOC_FORMAT_VERSION_LAST 2 #endif diff --git a/src/app/crash/read_document.cpp b/src/app/crash/read_document.cpp index 5799bb66d..45646d547 100644 --- a/src/app/crash/read_document.cpp +++ b/src/app/crash/read_document.cpp @@ -385,7 +385,7 @@ private: // Read Sprite User Data if (!s.eof()) { - UserData userData = read_user_data(s); + UserData userData = read_user_data(s, m_docFormatVer); if (!userData.isEmpty()) spr->setUserData(userData); } @@ -483,7 +483,7 @@ private: } if (lay) { - UserData userData = read_user_data(s); + UserData userData = read_user_data(s, m_docFormatVer); lay->setUserData(userData); return lay.release(); } @@ -496,7 +496,7 @@ private: } CelData* readCelData(std::ifstream& s) { - return read_celdata(s, this, false); + return read_celdata(s, this, false, m_docFormatVer); } Image* readImage(std::ifstream& s) { @@ -508,16 +508,15 @@ private: } Tileset* readTileset(std::ifstream& s) { - bool isOldVersion = false; - Tileset* tileset = read_tileset(s, m_sprite, false, &isOldVersion); - if (tileset && isOldVersion) + uint32_t tilesetVer; + Tileset* tileset = read_tileset(s, m_sprite, false, &tilesetVer, m_docFormatVer); + if (tileset && tilesetVer < TILESET_VER1) m_updateOldTilemapWithTileset.insert(tileset->id()); return tileset; } Tag* readTag(std::ifstream& s) { - const bool oldVersion = (m_docFormatVer < DOC_FORMAT_VERSION_1); - return read_tag(s, false, oldVersion); + return read_tag(s, false, m_docFormatVer); } Slice* readSlice(std::ifstream& s) { diff --git a/src/doc/cel_data_io.cpp b/src/doc/cel_data_io.cpp index ca5f5124b..13551035e 100644 --- a/src/doc/cel_data_io.cpp +++ b/src/doc/cel_data_io.cpp @@ -50,7 +50,7 @@ void write_celdata(std::ostream& os, const CelData* celdata) } } -CelData* read_celdata(std::istream& is, SubObjectsIO* subObjects, bool setId) +CelData* read_celdata(std::istream& is, SubObjectsIO* subObjects, const bool setId, const int docFormatVer) { ObjectId id = read32(is); int x = read32(is); @@ -59,7 +59,7 @@ CelData* read_celdata(std::istream& is, SubObjectsIO* subObjects, bool setId) int h = read32(is); int opacity = read8(is); ObjectId imageId = read32(is); - UserData userData = read_user_data(is); + UserData userData = read_user_data(is, docFormatVer); gfx::RectF boundsF; // Extra fields diff --git a/src/doc/cel_data_io.h b/src/doc/cel_data_io.h index a41e9ebe8..102f38819 100644 --- a/src/doc/cel_data_io.h +++ b/src/doc/cel_data_io.h @@ -8,6 +8,8 @@ #define DOC_CEL_DATA_IO_H_INCLUDED #pragma once +#include "app/crash/doc_format.h" + #include namespace doc { @@ -16,7 +18,7 @@ namespace doc { class SubObjectsIO; void write_celdata(std::ostream& os, const CelData* cel); - CelData* read_celdata(std::istream& is, SubObjectsIO* subObjects, bool setId = true); + CelData* read_celdata(std::istream& is, SubObjectsIO* subObjects, const bool setId = true, const int read_celdata = DOC_FORMAT_VERSION_LAST); } // namespace doc diff --git a/src/doc/layer_io.cpp b/src/doc/layer_io.cpp index 3c7d76979..4a18e4a80 100644 --- a/src/doc/layer_io.cpp +++ b/src/doc/layer_io.cpp @@ -110,7 +110,7 @@ void write_layer(std::ostream& os, const Layer* layer) write_user_data(os, layer->userData()); } -Layer* read_layer(std::istream& is, SubObjectsFromSprite* subObjects) +Layer* read_layer(std::istream& is, SubObjectsFromSprite* subObjects, const int docFormatVer) { ObjectId id = read32(is); std::string name = read_string(is); @@ -147,7 +147,7 @@ Layer* read_layer(std::istream& is, SubObjectsFromSprite* subObjects) // Read celdatas int celdatas = read16(is); for (int c=0; caddCelDataRef(celdata); } @@ -190,7 +190,7 @@ Layer* read_layer(std::istream& is, SubObjectsFromSprite* subObjects) } - UserData userData = read_user_data(is); + UserData userData = read_user_data(is, docFormatVer); if (layer) { layer->setName(name); diff --git a/src/doc/layer_io.h b/src/doc/layer_io.h index 69740a696..64a0699bf 100644 --- a/src/doc/layer_io.h +++ b/src/doc/layer_io.h @@ -8,6 +8,7 @@ #define DOC_LAYER_IO_H_INCLUDED #pragma once +#include "app/crash/doc_format.h" #include "base/exception.h" #include @@ -23,7 +24,7 @@ namespace doc { }; void write_layer(std::ostream& os, const Layer* layer); - Layer* read_layer(std::istream& is, SubObjectsFromSprite* subObjects); + Layer* read_layer(std::istream& is, SubObjectsFromSprite* subObjects, const int docFormatVer = DOC_FORMAT_VERSION_LAST); } // namespace doc diff --git a/src/doc/slice_io.cpp b/src/doc/slice_io.cpp index af2d2e6e7..c86ac8bce 100644 --- a/src/doc/slice_io.cpp +++ b/src/doc/slice_io.cpp @@ -37,11 +37,11 @@ void write_slice(std::ostream& os, const Slice* slice) } } -Slice* read_slice(std::istream& is, bool setId) +Slice* read_slice(std::istream& is, const bool setId, const int docFormatVer) { ObjectId id = read32(is); std::string name = read_string(is); - UserData userData = read_user_data(is); + UserData userData = read_user_data(is, docFormatVer); size_t nkeys = read32(is); std::unique_ptr slice(new Slice); diff --git a/src/doc/slice_io.h b/src/doc/slice_io.h index f550e25d6..14487e96a 100644 --- a/src/doc/slice_io.h +++ b/src/doc/slice_io.h @@ -8,6 +8,8 @@ #define DOC_SLICE_IO_H_INCLUDED #pragma once +#include "app/crash/doc_format.h" + #include namespace doc { @@ -16,7 +18,7 @@ namespace doc { class SliceKey; void write_slice(std::ostream& os, const Slice* slice); - Slice* read_slice(std::istream& is, bool setId = true); + Slice* read_slice(std::istream& is, const bool setId = true, const int docFormatVer = DOC_FORMAT_VERSION_LAST); void write_slicekey(std::ostream& os, const SliceKey& sliceKey); SliceKey read_slicekey(std::istream& is); diff --git a/src/doc/tag_io.cpp b/src/doc/tag_io.cpp index 2818be344..56fadb7b6 100644 --- a/src/doc/tag_io.cpp +++ b/src/doc/tag_io.cpp @@ -39,7 +39,7 @@ void write_tag(std::ostream& os, const Tag* tag) Tag* read_tag(std::istream& is, const bool setId, - const bool oldVersion) + const int docFormatVer) { ObjectId id = read32(is); frame_t from = read32(is); @@ -47,7 +47,7 @@ Tag* read_tag(std::istream& is, // If we are reading a session from v1.2.x, there is a color field color_t color; - if (oldVersion) + if (docFormatVer < DOC_FORMAT_VERSION_1) color = read32(is); AniDir aniDir = (AniDir)read8(is); @@ -56,15 +56,15 @@ Tag* read_tag(std::istream& is, // If we are reading the new v1.3.x version, there is a user data with the color + text int repeat = 0; - if (!oldVersion) { - userData = read_user_data(is); + if (docFormatVer >= DOC_FORMAT_VERSION_1) { + userData = read_user_data(is, docFormatVer); repeat = read32(is); } auto tag = std::make_unique(from, to); tag->setAniDir(aniDir); tag->setName(name); - if (oldVersion) + if (docFormatVer < DOC_FORMAT_VERSION_1) tag->setColor(color); else { tag->setUserData(userData); diff --git a/src/doc/tag_io.h b/src/doc/tag_io.h index 0e14317a1..887fb847b 100644 --- a/src/doc/tag_io.h +++ b/src/doc/tag_io.h @@ -9,6 +9,8 @@ #define DOC_TAG_IO_H_INCLUDED #pragma once +#include "app/crash/doc_format.h" + #include namespace doc { @@ -18,7 +20,7 @@ namespace doc { void write_tag(std::ostream& os, const Tag* tag); Tag* read_tag(std::istream& is, const bool setId = true, - const bool oldVersion = false); + const int docFormatVer = DOC_FORMAT_VERSION_LAST); } // namespace doc diff --git a/src/doc/tileset_io.cpp b/src/doc/tileset_io.cpp index f3bb8f02b..0f5987267 100644 --- a/src/doc/tileset_io.cpp +++ b/src/doc/tileset_io.cpp @@ -22,17 +22,6 @@ #include -// Extra BYTE with special flags to check the tileset version. This -// field didn't exist in Aseprite v1.3-alpha3 (so read8() fails = 0) -#define TILESET_VER1 1 - -// Tileset has UserData now -#define TILESET_VER2 2 - -// Tileset name (was missing originally) + each tileset's tile has -// UserData now -#define TILESET_VER3 3 - namespace doc { using namespace base::serialization; @@ -69,7 +58,8 @@ bool write_tileset(std::ostream& os, Tileset* read_tileset(std::istream& is, Sprite* sprite, bool setId, - bool* isOldVersion) + uint32_t* tilesetVer, + const int docFormatVer) { ObjectId id = read32(is); tileset_index ntiles = read32(is); @@ -85,21 +75,20 @@ Tileset* read_tileset(std::istream& is, // Read extra version byte after tiles uint32_t ver = read8(is); + if (tilesetVer) + *tilesetVer = ver; if (ver >= TILESET_VER1) { - if (isOldVersion) - *isOldVersion = false; - tileset->setBaseIndex(1); if (ver >= TILESET_VER2) { - UserData userData = read_user_data(is); + UserData userData = read_user_data(is, docFormatVer); tileset->setUserData(userData); if (ver >= TILESET_VER3) { tileset->setName(read_string(is)); for (tileset_index ti=0; tisetTileData(ti, read_user_data(is)); + tileset->setTileData(ti, read_user_data(is, docFormatVer)); } } } @@ -107,9 +96,6 @@ Tileset* read_tileset(std::istream& is, // Old tileset used in internal versions (this was added to recover // old files, maybe in a future we could remove this code) else { - if (isOldVersion) - *isOldVersion = true; - fix_old_tileset(tileset); } diff --git a/src/doc/tileset_io.h b/src/doc/tileset_io.h index eee64ee31..63177be53 100644 --- a/src/doc/tileset_io.h +++ b/src/doc/tileset_io.h @@ -8,8 +8,21 @@ #define DOC_TILESET_IO_H_INCLUDED #pragma once +#include "app/crash/doc_format.h" + #include +// Extra BYTE with special flags to check the tileset version. This +// field didn't exist in Aseprite v1.3-alpha3 (so read8() fails = 0) +#define TILESET_VER1 1 + +// Tileset has UserData now +#define TILESET_VER2 2 + +// Tileset name (was missing originally) + each tileset's tile has +// UserData now +#define TILESET_VER3 3 + namespace doc { class CancelIO; @@ -23,7 +36,8 @@ namespace doc { Tileset* read_tileset(std::istream& is, Sprite* sprite, bool setId = true, - bool* isOldVersion = nullptr); + uint32_t* tilesetVer = nullptr, + const int docFormatVer = DOC_FORMAT_VERSION_LAST); } // namespace doc diff --git a/src/doc/user_data_io.cpp b/src/doc/user_data_io.cpp index 3b9d416e6..94573d256 100644 --- a/src/doc/user_data_io.cpp +++ b/src/doc/user_data_io.cpp @@ -244,7 +244,7 @@ static UserData::PropertiesMaps read_properties_maps(std::istream& is) return propertiesMaps; } -UserData read_user_data(std::istream& is) +UserData read_user_data(std::istream& is, const int docFormatVer) { UserData userData; userData.setText(read_string(is)); @@ -255,7 +255,12 @@ UserData read_user_data(std::istream& is) // 0xffffffff in 32-bit). if (!is.eof()) { userData.setColor(read32(is)); - userData.propertiesMaps() = read_properties_maps(is); + // When recovering a session from an old Aseprite version, we need + // to skip reading the parts that it doesn't contains. Otherwise + // it is very likely to fail. + if (docFormatVer >= DOC_FORMAT_VERSION_2) { + userData.propertiesMaps() = read_properties_maps(is); + } } return userData; } diff --git a/src/doc/user_data_io.h b/src/doc/user_data_io.h index de0b06cd8..f5abcfd3f 100644 --- a/src/doc/user_data_io.h +++ b/src/doc/user_data_io.h @@ -8,6 +8,8 @@ #define DOC_USER_DATA_IO_H_INCLUDED #pragma once +#include "app/crash/doc_format.h" + #include namespace doc { @@ -15,7 +17,7 @@ namespace doc { class UserData; void write_user_data(std::ostream& os, const UserData& userData); - UserData read_user_data(std::istream& is); + UserData read_user_data(std::istream& is, const int docFormatVer = DOC_FORMAT_VERSION_LAST); } // namespace doc