mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-14 13:21:34 +00:00
Add support to recover tilemaps/tilesets from backup data
This commit is contained in:
parent
3e0a3d6f61
commit
ffcd4983c1
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -61,8 +61,8 @@ void AddTileset::onUndo()
|
||||
|
||||
void AddTileset::onRedo()
|
||||
{
|
||||
SubObjectsFromSprite io(sprite());
|
||||
doc::Tileset* tileset = read_tileset(m_stream, &io);
|
||||
auto sprite = this->sprite();
|
||||
doc::Tileset* tileset = read_tileset(m_stream, sprite);
|
||||
|
||||
addTileset(tileset);
|
||||
|
||||
|
@ -92,6 +92,7 @@ void CopyTileRegion::rehash()
|
||||
auto tileset = get<Tileset>(m_tilesetId);
|
||||
ASSERT(tileset);
|
||||
if (tileset) {
|
||||
tileset->incrementVersion();
|
||||
tileset->notifyTileContentChange(m_tileIndex);
|
||||
|
||||
// Notify thath the tileset changed
|
||||
|
@ -189,6 +189,7 @@ bool BackupObserver::saveDocData(Doc* doc)
|
||||
diff.frameDuration ? "frameDuration": "",
|
||||
diff.tags ? "tags": "",
|
||||
diff.palettes ? "palettes": "",
|
||||
diff.tilesets ? "tilesets": "",
|
||||
diff.layers ? "layers": "",
|
||||
diff.cels ? "cels": "",
|
||||
diff.images ? "images": "",
|
||||
|
15
src/app/crash/doc_format.h
Normal file
15
src/app/crash/doc_format.h
Normal file
@ -0,0 +1,15 @@
|
||||
// Aseprite
|
||||
// Copyright (c) 2020 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifndef APP_CRASH_DOC_FORMAT_H_INCLUDED
|
||||
#define APP_CRASH_DOC_FORMAT_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#define DOC_FORMAT_VERSION_0 0 // Old version
|
||||
#define DOC_FORMAT_VERSION_1 1 // New version with tilesets
|
||||
#define DOC_FORMAT_VERSION_LAST 1
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -12,6 +12,7 @@
|
||||
#include "app/crash/read_document.h"
|
||||
|
||||
#include "app/console.h"
|
||||
#include "app/crash/doc_format.h"
|
||||
#include "app/crash/internals.h"
|
||||
#include "app/doc.h"
|
||||
#include "base/convert_to.h"
|
||||
@ -27,6 +28,7 @@
|
||||
#include "doc/frame.h"
|
||||
#include "doc/image_io.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/layer_tilemap.h"
|
||||
#include "doc/palette.h"
|
||||
#include "doc/palette_io.h"
|
||||
#include "doc/slice.h"
|
||||
@ -36,6 +38,9 @@
|
||||
#include "doc/subobjects_io.h"
|
||||
#include "doc/tag.h"
|
||||
#include "doc/tag_io.h"
|
||||
#include "doc/tileset.h"
|
||||
#include "doc/tileset_io.h"
|
||||
#include "doc/tilesets.h"
|
||||
#include "fixmath/fixmath.h"
|
||||
|
||||
#include <fstream>
|
||||
@ -54,7 +59,8 @@ class Reader : public SubObjectsIO {
|
||||
public:
|
||||
Reader(const std::string& dir,
|
||||
base::task_token* t)
|
||||
: m_sprite(nullptr)
|
||||
: m_docFormatVer(DOC_FORMAT_VERSION_0)
|
||||
, m_sprite(nullptr)
|
||||
, m_dir(dir)
|
||||
, m_docId(0)
|
||||
, m_docVersions(nullptr)
|
||||
@ -176,6 +182,10 @@ private:
|
||||
Doc* readDocument(std::ifstream& s) {
|
||||
ObjectId sprId = read32(s);
|
||||
std::string filename = read_string(s);
|
||||
m_docFormatVer = read16(s);
|
||||
if (s.eof()) m_docFormatVer = DOC_FORMAT_VERSION_0;
|
||||
|
||||
TRACE("RECO: internal format version=%d\n", m_docFormatVer);
|
||||
|
||||
// Load DocumentInfo only
|
||||
if (m_loadInfo) {
|
||||
@ -197,6 +207,7 @@ private:
|
||||
}
|
||||
|
||||
Sprite* readSprite(std::ifstream& s) {
|
||||
// Header
|
||||
ColorMode mode = (ColorMode)read8(s);
|
||||
int w = read16(s);
|
||||
int h = read16(s);
|
||||
@ -240,6 +251,19 @@ private:
|
||||
Console().printf("Invalid number of frames #%d\n", nframes);
|
||||
}
|
||||
|
||||
// IDs of all tilesets
|
||||
if (m_docFormatVer >= DOC_FORMAT_VERSION_1) {
|
||||
int ntilesets = read32(s);
|
||||
if (ntilesets > 0 && ntilesets < 0xffffff) {
|
||||
for (int i=0; i<ntilesets; ++i) {
|
||||
ObjectId tilesetId = read32(s);
|
||||
Tileset* tileset = loadObject<Tileset*>("tset", tilesetId, &Reader::readTileset);
|
||||
if (tileset)
|
||||
spr->tilesets()->add(tileset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read layers
|
||||
int nlayers = read32(s);
|
||||
if (nlayers >= 1 && nlayers < 0xfffff) {
|
||||
@ -383,12 +407,26 @@ private:
|
||||
LayerFlags flags = (LayerFlags)read32(s);
|
||||
ObjectType type = (ObjectType)read16(s);
|
||||
ASSERT(type == ObjectType::LayerImage ||
|
||||
type == ObjectType::LayerGroup);
|
||||
type == ObjectType::LayerGroup ||
|
||||
type == ObjectType::LayerTilemap);
|
||||
|
||||
std::string name = read_string(s);
|
||||
|
||||
if (type == ObjectType::LayerImage) {
|
||||
std::unique_ptr<LayerImage> lay(new LayerImage(m_sprite));
|
||||
if (type == ObjectType::LayerImage ||
|
||||
type == ObjectType::LayerTilemap) {
|
||||
std::unique_ptr<LayerImage> lay;
|
||||
|
||||
switch (type) {
|
||||
case ObjectType::LayerImage:
|
||||
lay.reset(new LayerImage(m_sprite));
|
||||
break;
|
||||
case ObjectType::LayerTilemap: {
|
||||
tileset_index tilesetIndex = read32(s);
|
||||
lay.reset(new LayerTilemap(m_sprite, tilesetIndex));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lay->setName(name);
|
||||
lay->setFlags(flags);
|
||||
|
||||
@ -437,6 +475,10 @@ private:
|
||||
return read_palette(s);
|
||||
}
|
||||
|
||||
Tileset* readTileset(std::ifstream& s) {
|
||||
return read_tileset(s, m_sprite, false);
|
||||
}
|
||||
|
||||
Tag* readTag(std::ifstream& s) {
|
||||
return read_tag(s, false);
|
||||
}
|
||||
@ -475,6 +517,7 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
int m_docFormatVer;
|
||||
Sprite* m_sprite; // Used to pass the sprite in LayerImage() ctor
|
||||
std::string m_dir;
|
||||
ObjectVersion m_docId;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -11,6 +11,7 @@
|
||||
|
||||
#include "app/crash/write_document.h"
|
||||
|
||||
#include "app/crash/doc_format.h"
|
||||
#include "app/crash/internals.h"
|
||||
#include "app/doc.h"
|
||||
#include "base/convert_to.h"
|
||||
@ -26,6 +27,7 @@
|
||||
#include "doc/frame.h"
|
||||
#include "doc/image_io.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/layer_tilemap.h"
|
||||
#include "doc/palette.h"
|
||||
#include "doc/palette_io.h"
|
||||
#include "doc/slice.h"
|
||||
@ -34,6 +36,9 @@
|
||||
#include "doc/string_io.h"
|
||||
#include "doc/tag.h"
|
||||
#include "doc/tag_io.h"
|
||||
#include "doc/tileset.h"
|
||||
#include "doc/tileset_io.h"
|
||||
#include "doc/tilesets.h"
|
||||
#include "fixmath/fixmath.h"
|
||||
|
||||
#include <fstream>
|
||||
@ -71,6 +76,12 @@ public:
|
||||
if (!saveObject("pal", pal, &Writer::writePalette))
|
||||
return false;
|
||||
|
||||
if (spr->hasTilesets()) {
|
||||
for (Tileset* tset : *spr->tilesets())
|
||||
if (!saveObject("tset", tset, &Writer::writeTileset))
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Tag* frtag : spr->tags())
|
||||
if (!saveObject("frtag", frtag, &Writer::writeFrameTag))
|
||||
return false;
|
||||
@ -134,20 +145,29 @@ private:
|
||||
bool writeDocumentFile(std::ofstream& s, Doc* doc) {
|
||||
write32(s, doc->sprite()->id());
|
||||
write_string(s, doc->filename());
|
||||
write16(s, DOC_FORMAT_VERSION_LAST);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool writeSprite(std::ofstream& s, Sprite* spr) {
|
||||
// Header
|
||||
write8(s, int(spr->colorMode()));
|
||||
write16(s, spr->width());
|
||||
write16(s, spr->height());
|
||||
write32(s, spr->transparentColor());
|
||||
write32(s, spr->totalFrames());
|
||||
|
||||
// Frame durations
|
||||
write32(s, spr->totalFrames());
|
||||
for (frame_t fr = 0; fr < spr->totalFrames(); ++fr)
|
||||
write32(s, spr->frameDuration(fr));
|
||||
|
||||
// IDs of all tilesets
|
||||
write32(s, spr->hasTilesets() ? spr->tilesets()->size(): 0);
|
||||
if (spr->hasTilesets()) {
|
||||
for (Tileset* tileset : *spr->tilesets())
|
||||
write32(s, tileset->id());
|
||||
}
|
||||
|
||||
// IDs of all main layers
|
||||
write32(s, spr->allLayersCount());
|
||||
writeAllLayersID(s, 0, spr->root());
|
||||
@ -215,7 +235,12 @@ private:
|
||||
|
||||
switch (lay->type()) {
|
||||
|
||||
case ObjectType::LayerImage: {
|
||||
case ObjectType::LayerImage:
|
||||
case ObjectType::LayerTilemap: {
|
||||
// Tileset index
|
||||
if (lay->type() == ObjectType::LayerTilemap)
|
||||
write32(s, static_cast<const LayerTilemap*>(lay)->tilesetIndex());
|
||||
|
||||
CelConstIterator it, begin = static_cast<const LayerImage*>(lay)->getCelBegin();
|
||||
CelConstIterator end = static_cast<const LayerImage*>(lay)->getCelEnd();
|
||||
|
||||
@ -259,6 +284,11 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool writeTileset(std::ofstream& s, Tileset* tileset) {
|
||||
write_tileset(s, tileset);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool writeFrameTag(std::ofstream& s, Tag* frameTag) {
|
||||
write_tag(s, frameTag);
|
||||
return true;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||
// Copyright (C) 2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -15,10 +15,13 @@
|
||||
#include "doc/cel.h"
|
||||
#include "doc/image.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/layer_tilemap.h"
|
||||
#include "doc/palette.h"
|
||||
#include "doc/primitives.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "doc/tag.h"
|
||||
#include "doc/tileset.h"
|
||||
#include "doc/tilesets.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
@ -70,7 +73,7 @@ DocDiff compare_docs(const Doc* a,
|
||||
}
|
||||
}
|
||||
|
||||
// Palettes layers
|
||||
// Palettes
|
||||
if (a->sprite()->getPalettes().size() != b->sprite()->getPalettes().size()) {
|
||||
const PalettesList& aPals = a->sprite()->getPalettes();
|
||||
const PalettesList& bPals = b->sprite()->getPalettes();
|
||||
@ -88,6 +91,35 @@ DocDiff compare_docs(const Doc* a,
|
||||
}
|
||||
}
|
||||
|
||||
// Compare tilesets
|
||||
const tile_index aTilesetSize = (a->sprite()->hasTilesets() ? a->sprite()->tilesets()->size(): 0);
|
||||
const tile_index bTilesetSize = (b->sprite()->hasTilesets() ? b->sprite()->tilesets()->size(): 0);
|
||||
if (aTilesetSize != bTilesetSize) {
|
||||
diff.anything = diff.tilesets = true;
|
||||
}
|
||||
else {
|
||||
for (int i=0; i<aTilesetSize; ++i) {
|
||||
Tileset* aTileset = a->sprite()->tilesets()->get(i);
|
||||
Tileset* bTileset = b->sprite()->tilesets()->get(i);
|
||||
|
||||
if (aTileset->grid().tileSize() != bTileset->grid().tileSize() ||
|
||||
aTileset->size() != bTileset->size()) {
|
||||
diff.anything = diff.tilesets = true;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
for (tile_index ti=0; ti<aTileset->size(); ++ti) {
|
||||
if (!is_same_image(aTileset->get(ti).get(),
|
||||
bTileset->get(ti).get())) {
|
||||
diff.anything = diff.tilesets = true;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
done:;
|
||||
}
|
||||
|
||||
// Compare layers
|
||||
if (a->sprite()->allLayersCount() != b->sprite()->allLayersCount()) {
|
||||
diff.anything = diff.layers = true;
|
||||
@ -106,7 +138,9 @@ DocDiff compare_docs(const Doc* a,
|
||||
aLay->name() != bLay->name() ||
|
||||
aLay->flags() != bLay->flags() ||
|
||||
(aLay->isImage() && bLay->isImage() &&
|
||||
(((const LayerImage*)aLay)->opacity() != ((const LayerImage*)bLay)->opacity()))) {
|
||||
(((const LayerImage*)aLay)->opacity() != ((const LayerImage*)bLay)->opacity())) ||
|
||||
(aLay->isTilemap() && bLay->isTilemap() &&
|
||||
(((const LayerTilemap*)aLay)->tilesetIndex() != ((const LayerTilemap*)bLay)->tilesetIndex()))) {
|
||||
diff.anything = diff.layers = true;
|
||||
break;
|
||||
}
|
||||
@ -128,7 +162,7 @@ DocDiff compare_docs(const Doc* a,
|
||||
}
|
||||
if (aCel->image() && bCel->image()) {
|
||||
if (aCel->image()->bounds() != bCel->image()->bounds() ||
|
||||
count_diff_between_images(aCel->image(), bCel->image()))
|
||||
!is_same_image(aCel->image(), bCel->image()))
|
||||
diff.anything = diff.images = true;
|
||||
}
|
||||
else if (aCel->image() != bCel->image())
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||
// Copyright (C) 2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -19,6 +19,7 @@ namespace app {
|
||||
bool frameDuration : 1;
|
||||
bool tags : 1;
|
||||
bool palettes : 1;
|
||||
bool tilesets : 1;
|
||||
bool layers : 1;
|
||||
bool cels : 1;
|
||||
bool images : 1;
|
||||
@ -32,6 +33,7 @@ namespace app {
|
||||
frameDuration(false),
|
||||
tags(false),
|
||||
palettes(false),
|
||||
tilesets(false),
|
||||
layers(false),
|
||||
cels(false),
|
||||
images(false),
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -1575,88 +1575,93 @@ void Timeline::onPaint(ui::PaintEvent& ev)
|
||||
|
||||
// Draw each visible layer.
|
||||
DrawCelData data;
|
||||
for (layer=lastLayer; layer>=firstLayer; --layer) {
|
||||
{
|
||||
IntersectClip clip(g, getLayerHeadersBounds());
|
||||
if (clip)
|
||||
drawLayer(g, layer);
|
||||
}
|
||||
if (layer >= lastLayer &&
|
||||
layer >= firstLayer) {
|
||||
for (layer=lastLayer; layer>=firstLayer; --layer) {
|
||||
ASSERT(layer >= 0 && layer < int(m_rows.size()));
|
||||
|
||||
IntersectClip clip(g, getCelsBounds());
|
||||
if (!clip)
|
||||
continue;
|
||||
|
||||
Layer* layerPtr = m_rows[layer].layer();
|
||||
if (!layerPtr->isImage()) {
|
||||
// Draw empty cels
|
||||
for (frame=firstFrame; frame<=lastFrame; ++frame) {
|
||||
drawCel(g, layer, frame, nullptr, nullptr);
|
||||
{
|
||||
IntersectClip clip(g, getLayerHeadersBounds());
|
||||
if (clip)
|
||||
drawLayer(g, layer);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the first CelIterator to be drawn (it is the first cel with cel->frame >= first_frame)
|
||||
LayerImage* layerImagePtr = static_cast<LayerImage*>(layerPtr);
|
||||
data.begin = layerImagePtr->getCelBegin();
|
||||
data.end = layerImagePtr->getCelEnd();
|
||||
data.it = layerImagePtr->findFirstCelIteratorAfter(firstFrame-1);
|
||||
if (firstFrame > 0 && data.it != data.begin)
|
||||
data.prevIt = data.it-1;
|
||||
else
|
||||
data.prevIt = data.end;
|
||||
data.nextIt = (data.it != data.end ? data.it+1: data.end);
|
||||
IntersectClip clip(g, getCelsBounds());
|
||||
if (!clip)
|
||||
continue;
|
||||
|
||||
// Calculate link range for the active cel
|
||||
data.firstLink = data.end;
|
||||
data.lastLink = data.end;
|
||||
Layer* layerPtr = m_rows[layer].layer();
|
||||
if (!layerPtr->isImage()) {
|
||||
// Draw empty cels
|
||||
for (frame=firstFrame; frame<=lastFrame; ++frame) {
|
||||
drawCel(g, layer, frame, nullptr, nullptr);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (layerPtr == m_layer) {
|
||||
data.activeIt = layerImagePtr->findCelIterator(m_frame);
|
||||
if (data.activeIt != data.end) {
|
||||
data.firstLink = data.activeIt;
|
||||
data.lastLink = data.activeIt;
|
||||
// Get the first CelIterator to be drawn (it is the first cel with cel->frame >= first_frame)
|
||||
LayerImage* layerImagePtr = static_cast<LayerImage*>(layerPtr);
|
||||
data.begin = layerImagePtr->getCelBegin();
|
||||
data.end = layerImagePtr->getCelEnd();
|
||||
data.it = layerImagePtr->findFirstCelIteratorAfter(firstFrame-1);
|
||||
if (firstFrame > 0 && data.it != data.begin)
|
||||
data.prevIt = data.it-1;
|
||||
else
|
||||
data.prevIt = data.end;
|
||||
data.nextIt = (data.it != data.end ? data.it+1: data.end);
|
||||
|
||||
ObjectId imageId = (*data.activeIt)->image()->id();
|
||||
// Calculate link range for the active cel
|
||||
data.firstLink = data.end;
|
||||
data.lastLink = data.end;
|
||||
|
||||
auto it2 = data.activeIt;
|
||||
if (it2 != data.begin) {
|
||||
do {
|
||||
--it2;
|
||||
if (layerPtr == m_layer) {
|
||||
data.activeIt = layerImagePtr->findCelIterator(m_frame);
|
||||
if (data.activeIt != data.end) {
|
||||
data.firstLink = data.activeIt;
|
||||
data.lastLink = data.activeIt;
|
||||
|
||||
ObjectId imageId = (*data.activeIt)->image()->id();
|
||||
|
||||
auto it2 = data.activeIt;
|
||||
if (it2 != data.begin) {
|
||||
do {
|
||||
--it2;
|
||||
if ((*it2)->image()->id() == imageId) {
|
||||
data.firstLink = it2;
|
||||
if ((*data.firstLink)->frame() < firstFrame)
|
||||
break;
|
||||
}
|
||||
} while (it2 != data.begin);
|
||||
}
|
||||
|
||||
it2 = data.activeIt;
|
||||
while (it2 != data.end) {
|
||||
if ((*it2)->image()->id() == imageId) {
|
||||
data.firstLink = it2;
|
||||
if ((*data.firstLink)->frame() < firstFrame)
|
||||
data.lastLink = it2;
|
||||
if ((*data.lastLink)->frame() > lastFrame)
|
||||
break;
|
||||
}
|
||||
} while (it2 != data.begin);
|
||||
}
|
||||
|
||||
it2 = data.activeIt;
|
||||
while (it2 != data.end) {
|
||||
if ((*it2)->image()->id() == imageId) {
|
||||
data.lastLink = it2;
|
||||
if ((*data.lastLink)->frame() > lastFrame)
|
||||
break;
|
||||
++it2;
|
||||
}
|
||||
++it2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
data.activeIt = data.end;
|
||||
else
|
||||
data.activeIt = data.end;
|
||||
|
||||
// Draw every visible cel for each layer.
|
||||
for (frame=firstFrame; frame<=lastFrame; ++frame) {
|
||||
Cel* cel =
|
||||
(data.it != data.end &&
|
||||
(*data.it)->frame() == frame ? *data.it: nullptr);
|
||||
// Draw every visible cel for each layer.
|
||||
for (frame=firstFrame; frame<=lastFrame; ++frame) {
|
||||
Cel* cel =
|
||||
(data.it != data.end &&
|
||||
(*data.it)->frame() == frame ? *data.it: nullptr);
|
||||
|
||||
drawCel(g, layer, frame, cel, &data);
|
||||
drawCel(g, layer, frame, cel, &data);
|
||||
|
||||
if (cel) {
|
||||
data.prevIt = data.it;
|
||||
data.it = data.nextIt; // Point to next cel
|
||||
if (data.nextIt != data.end)
|
||||
++data.nextIt;
|
||||
if (cel) {
|
||||
data.prevIt = data.it;
|
||||
data.it = data.nextIt; // Point to next cel
|
||||
if (data.nextIt != data.end)
|
||||
++data.nextIt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2035,6 +2040,10 @@ void Timeline::drawHeaderFrame(ui::Graphics* g, frame_t frame)
|
||||
|
||||
void Timeline::drawLayer(ui::Graphics* g, int layerIdx)
|
||||
{
|
||||
ASSERT(layerIdx >= 0 && layerIdx < int(m_rows.size()));
|
||||
if (layerIdx < 0 || layerIdx >= m_rows.size())
|
||||
return;
|
||||
|
||||
auto& styles = skinTheme()->styles;
|
||||
Layer* layer = m_rows[layerIdx].layer();
|
||||
bool is_active = isLayerActive(layerIdx);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Document Library
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -11,7 +11,9 @@
|
||||
#include "doc/tileset_io.h"
|
||||
|
||||
#include "base/serialization.h"
|
||||
#include "doc/cancel_io.h"
|
||||
#include "doc/grid_io.h"
|
||||
#include "doc/image_io.h"
|
||||
#include "doc/subobjects_io.h"
|
||||
#include "doc/tileset.h"
|
||||
|
||||
@ -28,21 +30,34 @@ bool write_tileset(std::ostream& os,
|
||||
{
|
||||
write32(os, tileset->id());
|
||||
write32(os, tileset->size());
|
||||
return write_grid(os, tileset->grid());
|
||||
write_grid(os, tileset->grid());
|
||||
|
||||
// TODO save images
|
||||
for (tile_index ti=0; ti<tileset->size(); ++ti) {
|
||||
if (cancel && cancel->isCanceled())
|
||||
return false;
|
||||
|
||||
write_image(os, tileset->get(ti).get(), cancel);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Tileset* read_tileset(std::istream& is,
|
||||
SubObjectsFromSprite* subObjects,
|
||||
Sprite* sprite,
|
||||
bool setId)
|
||||
{
|
||||
ObjectId id = read32(is);
|
||||
tileset_index ntiles = read32(is);
|
||||
Grid grid = read_grid(is, setId);
|
||||
auto tileset = new Tileset(subObjects->sprite(), grid, ntiles);
|
||||
auto tileset = new Tileset(sprite, grid, ntiles);
|
||||
if (setId)
|
||||
tileset->setId(id);
|
||||
|
||||
for (tileset_index ti=0; ti<ntiles; ++ti) {
|
||||
ImageRef image(read_image(is, setId));
|
||||
tileset->set(ti, image);
|
||||
}
|
||||
|
||||
return tileset;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Document Library
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -13,7 +13,7 @@
|
||||
namespace doc {
|
||||
|
||||
class CancelIO;
|
||||
class SubObjectsFromSprite;
|
||||
class Sprite;
|
||||
class Tileset;
|
||||
|
||||
bool write_tileset(std::ostream& os,
|
||||
@ -21,7 +21,7 @@ namespace doc {
|
||||
CancelIO* cancel = nullptr);
|
||||
|
||||
Tileset* read_tileset(std::istream& is,
|
||||
SubObjectsFromSprite* subObjects,
|
||||
Sprite* sprite,
|
||||
bool setId = true);
|
||||
|
||||
} // namespace doc
|
||||
|
Loading…
x
Reference in New Issue
Block a user