mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-14 04:19:12 +00:00
Allow recovering of sessions generated in previous Aseprite versions (fix #3727)
This commit is contained in:
parent
e79907dae3
commit
e6cd13d7e1
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -8,6 +8,8 @@
|
||||
#define DOC_CEL_DATA_IO_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/crash/doc_format.h"
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
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
|
||||
|
||||
|
@ -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; c<celdatas; ++c) {
|
||||
CelDataRef celdata(read_celdata(is, subObjects));
|
||||
CelDataRef celdata(read_celdata(is, subObjects, true, docFormatVer));
|
||||
subObjects->addCelDataRef(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);
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define DOC_LAYER_IO_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/crash/doc_format.h"
|
||||
#include "base/exception.h"
|
||||
|
||||
#include <iosfwd>
|
||||
@ -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
|
||||
|
||||
|
@ -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> slice(new Slice);
|
||||
|
@ -8,6 +8,8 @@
|
||||
#define DOC_SLICE_IO_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/crash/doc_format.h"
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
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);
|
||||
|
@ -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<Tag>(from, to);
|
||||
tag->setAniDir(aniDir);
|
||||
tag->setName(name);
|
||||
if (oldVersion)
|
||||
if (docFormatVer < DOC_FORMAT_VERSION_1)
|
||||
tag->setColor(color);
|
||||
else {
|
||||
tag->setUserData(userData);
|
||||
|
@ -9,6 +9,8 @@
|
||||
#define DOC_TAG_IO_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/crash/doc_format.h"
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
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
|
||||
|
||||
|
@ -22,17 +22,6 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// 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; ti<ntiles; ++ti) {
|
||||
tileset->setTileData(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);
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,21 @@
|
||||
#define DOC_TILESET_IO_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/crash/doc_format.h"
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
// 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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -8,6 +8,8 @@
|
||||
#define DOC_USER_DATA_IO_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/crash/doc_format.h"
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user