[lua] Add test about saving/loading/modifying tilemap w/flags

Something interesting is that Image:drawPixel() must ask for a rehash
to the tileset when the tile is modified, maybe we can find a better
way to handle this in the future.
This commit is contained in:
David Capello 2023-07-17 19:45:39 -03:00
parent b43fbe2249
commit d3a8a10517
7 changed files with 137 additions and 18 deletions

View File

@ -178,7 +178,7 @@ namespace app {
void push_tile(lua_State* L, const doc::Tileset* tileset, doc::tile_index ti);
void push_tile_properties(lua_State* L, const doc::Tileset* tileset, doc::tile_index ti, const std::string& extID);
void push_tileset(lua_State* L, const doc::Tileset* tileset);
void push_tileset_image(lua_State* L, doc::Tileset* tileset, doc::Image* image);
void push_tileset_image(lua_State* L, doc::Tileset* tileset, doc::tile_index ti);
void push_tilesets(lua_State* L, doc::Tilesets* tilesets);
void push_tool(lua_State* L, app::tools::Tool* tool);
void push_version(lua_State* L, const base::Version& ver);

View File

@ -51,6 +51,7 @@ struct ImageObj {
doc::ObjectId imageId = 0;
doc::ObjectId celId = 0;
doc::ObjectId tilesetId = 0;
doc::tile_index ti = 0;
ImageObj(doc::Image* image)
: imageId(image->id()) {
}
@ -58,9 +59,12 @@ struct ImageObj {
: imageId(cel->image()->id())
, celId(cel->id()) {
}
ImageObj(doc::Tileset* tileset, doc::Image* image)
ImageObj(doc::Tileset* tileset,
doc::tile_index ti,
doc::Image* image)
: imageId(image->id())
, tilesetId(tileset->id()) {
, tilesetId(tileset->id())
, ti(ti) {
}
ImageObj(const ImageObj&) = delete;
ImageObj& operator=(const ImageObj&) = delete;
@ -264,6 +268,14 @@ int Image_drawPixel(lua_State* L)
else
color = convert_args_into_pixel_color(L, 4, img->pixelFormat());
doc::put_pixel(img, x, y, color);
// Rehash tileset
if (obj->tilesetId) {
if (doc::Tileset* ts = obj->tileset(L)) {
ts->incrementVersion();
ts->notifyTileContentChange(obj->ti);
}
}
return 0;
}
@ -779,9 +791,13 @@ void push_image(lua_State* L, doc::Image* image)
push_new<ImageObj>(L, image);
}
void push_tileset_image(lua_State* L, doc::Tileset* tileset, doc::Image* image)
void push_tileset_image(lua_State* L, doc::Tileset* tileset, doc::tile_index ti)
{
push_new<ImageObj>(L, tileset, image);
doc::ImageRef image = tileset->get(ti);
if (image)
push_new<ImageObj>(L, tileset, ti, image.get());
else
lua_pushnil(L);
}
doc::Image* may_get_image_from_arg(lua_State* L, int index)

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2018-2019 Igara Studio S.A.
// Copyright (C) 2018-2023 Igara Studio S.A.
// Copyright (C) 2018 David Capello
//
// This program is distributed under the terms of
@ -102,6 +102,12 @@ inline void setfield_integer(lua_State* L, const char* key, const T& value) {
lua_setfield(L, -2, key);
}
template<typename T>
inline void setfield_uinteger(lua_State* L, const char* key, const T& value) {
lua_pushinteger(L, value);
lua_setfield(L, -2, key);
}
#define REG_CLASS(L, T) { \
luaL_newmetatable(L, get_mtname<T>()); \
lua_getglobal(L, "__generic_mt_index"); \

View File

@ -116,6 +116,12 @@ void register_app_pixel_color_object(lua_State* L)
lua_pushvalue(L, -2); // Copy table
lua_rawset(L, -4);
luaL_setfuncs(L, PixelColor_methods, 0);
// Masks for tile flags
setfield_uinteger(L, "TILE_XFLIP", doc::tile_f_xflip);
setfield_uinteger(L, "TILE_YFLIP", doc::tile_f_yflip);
setfield_uinteger(L, "TILE_DFLIP", doc::tile_f_dflip);
lua_pop(L, 2); // Pop table & app global
}

View File

@ -48,11 +48,7 @@ int Tile_get_image(lua_State* L)
if (!ts)
return 0;
ImageRef image = ts->get(tile->ti);
if (image)
push_tileset_image(L, ts, image.get());
else
lua_pushnil(L);
push_tileset_image(L, ts, tile->ti);
return 1;
}

View File

@ -41,12 +41,8 @@ int Tileset_len(lua_State* L)
int Tileset_getTile(lua_State* L)
{
auto tileset = get_docobj<Tileset>(L, 1);
tile_index i = lua_tointeger(L, 2);
ImageRef image = tileset->get(i);
if (image)
push_tileset_image(L, tileset, image.get());
else
lua_pushnil(L);
tile_index ti = lua_tointeger(L, 2);
push_tileset_image(L, tileset, ti);
return 1;
}

View File

@ -1226,4 +1226,103 @@ do
assert(spr.tilesets[1] == tilemapLay1.tileset)
assert(spr.tilesets[2] == tilemapLay2.tileset)
assert(spr.tilesets[3] == tilemapLay3.tileset)
end
end
-----------------------------------------------------------------------
-- Test tilemaps with flags (flips)
-----------------------------------------------------------------------
do
local spr = Sprite(8, 8, ColorMode.INDEXED)
-- Create a new tilemap (delete the default regular layer)
app.command.NewLayer{ tilemap=true, gridBounds=Rectangle{ 0, 0, 2, 2 } }
local mapLay = app.layer
spr:deleteLayer(spr.layers[1])
assert(#mapLay.cels == 0)
-- Set a palette just for testing/preview the result
spr:setPalette(Palette{ fromResource="Teletext" })
-- Create one tile with these pixels (indexes):
-- 12
-- 34
local tile = spr:newTile(mapLay.tileset, 1)
array_to_pixels({ 1, 2,
3, 4 }, tile.image)
-- Fill the tilemap with this only tile
app.useTool{ tool='paint_bucket', color=1, layer=mapLay,
tilemapMode=TilemapMode.TILES,
points={ Point(0, 0) }}
assert(#mapLay.cels == 1)
local map = mapLay.cels[1].image
assert(map.width == 4)
assert(map.height == 4)
-- Constants
local x = app.pixelColor.TILE_XFLIP
local y = app.pixelColor.TILE_YFLIP
local d = app.pixelColor.TILE_DFLIP
-- Normal (tile without flags)
-- 12
-- 34
map:drawPixel(0, 0, 1)
-- Flip X
-- 21
-- 43
map:drawPixel(1, 0, 1|x)
-- Flip Y
-- 34
-- 12
map:drawPixel(0, 1, 1|y)
-- Flip X+Y
-- 43
-- 21
map:drawPixel(1, 1, 1|x|y)
-- Flip D
-- 31
-- 42
map:drawPixel(2, 2, 1|d)
-- Flip X+D
-- 42
-- 31
map:drawPixel(3, 2, 1|x|d)
-- Flip Y+D
-- 13
-- 24
map:drawPixel(2, 3, 1|y|d)
-- Flip X+Y+D
-- 24
-- 13
map:drawPixel(3, 3, 1|x|y|d)
-- Clear areas
app.useTool{ tool='filled_rectangle', color=0, layer=mapLay,
tilemapMode=TilemapMode.TILES,
points={ Point(0, 4), Point(3, 7) }}
app.useTool{ tool='filled_rectangle', color=0, layer=mapLay,
tilemapMode=TilemapMode.TILES,
points={ Point(4, 0), Point(7, 3) }}
-- Save, load, and test if the tilemap were saved correctly with the
-- given flags
spr:saveAs('_test_tile_flags.aseprite')
spr:close()
local spr2 = app.open('_test_tile_flags.aseprite')
local map2 = spr2.layers[1].cels[1].image
expect_img(map2, { 1, (1|x), 0, 0,
1|y, (1|x|y), 0, 0,
0, 0, 1|d, (1|x|d),
0, 0, 1|y|d, (1|x|y|d) })
end