672b92b3 [nostalgia/gfx/studio] Remove accidental version tag in default Palette 762a6517 [nostalgia] Rename core to gfx d141154a Merge commit '38777cfac8868b3628332090260710d5ac26aba0' 6170647c [nostalgia,studio] Proper fix for input filtering 48e45c7d [studio] Cleanup 5d3d9229 [nostalgia/core/studio/paletteeditor] Ignore keyboard input when popup is open d54e93d8 [studio] Cleanup 7b638538 Merge commit '8e0b6ffbabb10f8a6e9ad7e9f07e0ba1d039a02e' 240effd3 Merge commit '7e20f7200963cd0b22f84cc46e10db12b6c13806' f6f2acd6 [nostalgia/core/studio/tilesheeteditor] Add back file type check for palette drop git-subtree-dir: deps/nostalgia git-subtree-split: 672b92b363a2047c4c8ce93fb3d88001a76da35f
537 lines
14 KiB
C++
537 lines
14 KiB
C++
/*
|
|
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <ox/fs/fs.hpp>
|
|
#include <ox/std/array.hpp>
|
|
#include <ox/std/point.hpp>
|
|
#include <ox/std/size.hpp>
|
|
#include <ox/std/span.hpp>
|
|
#include <ox/std/types.hpp>
|
|
#include <ox/model/def.hpp>
|
|
|
|
#include <nostalgia/gfx/ptidxconv.hpp>
|
|
|
|
#include "palette.hpp"
|
|
|
|
namespace nostalgia::gfx {
|
|
|
|
struct SubSheetTemplate {
|
|
static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.SubSheetTemplate";
|
|
static constexpr auto TypeVersion = 1;
|
|
ox::String name;
|
|
int32_t width{};
|
|
int32_t height{};
|
|
ox::Vector<SubSheetTemplate> subsheets;
|
|
};
|
|
|
|
OX_MODEL_BEGIN(SubSheetTemplate)
|
|
OX_MODEL_FIELD(name)
|
|
OX_MODEL_FIELD(width)
|
|
OX_MODEL_FIELD(height)
|
|
OX_MODEL_FIELD(subsheets)
|
|
OX_MODEL_END()
|
|
|
|
|
|
// Predecessor to TileSheet, kept for backward compatibility
|
|
struct TileSheetV1 {
|
|
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.NostalgiaGraphic";
|
|
static constexpr auto TypeVersion = 1;
|
|
int8_t bpp = 0;
|
|
// rows and columns are really only used by TileSheetEditor
|
|
int rows = 1;
|
|
int columns = 1;
|
|
ox::FileAddress defaultPalette;
|
|
PaletteV1 pal;
|
|
ox::Vector<uint8_t> pixels = {};
|
|
};
|
|
|
|
[[nodiscard]]
|
|
constexpr bool valid(TileSheetV1 const&ts) noexcept {
|
|
auto const bytes = static_cast<size_t>(ts.columns * ts.rows * PixelsPerTile) / (ts.bpp == 4 ? 2 : 1);
|
|
return (ts.bpp == 4 || ts.bpp == 8) && ts.pixels.size() == bytes;
|
|
}
|
|
|
|
constexpr ox::Error repair(TileSheetV1 &ts, int bpp) noexcept {
|
|
auto const bytes = static_cast<size_t>(ts.columns * ts.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
|
ts.pixels.resize(bytes);
|
|
return {};
|
|
}
|
|
|
|
|
|
struct TileSheetV2 {
|
|
using SubSheetIdx = ox::Vector<std::size_t, 4>;
|
|
|
|
struct SubSheet {
|
|
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheet.SubSheet";
|
|
static constexpr auto TypeVersion = 1;
|
|
ox::String name;
|
|
int columns = 0;
|
|
int rows = 0;
|
|
ox::Vector<SubSheet> subsheets;
|
|
ox::Vector<uint8_t> pixels;
|
|
constexpr SubSheet() noexcept = default;
|
|
constexpr SubSheet(ox::StringParam pName, int pColumns, int pRows, int bpp) noexcept:
|
|
name(std::move(pName)),
|
|
columns(pColumns),
|
|
rows(pRows),
|
|
pixels(static_cast<size_t>(columns * rows * PixelsPerTile) / (bpp == 4 ? 2u : 1u)) {
|
|
}
|
|
};
|
|
|
|
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheet";
|
|
static constexpr auto TypeVersion = 2;
|
|
int8_t bpp = 4;
|
|
ox::FileAddress defaultPalette;
|
|
SubSheet subsheet{"Root", 1, 1, bpp};
|
|
|
|
};
|
|
|
|
[[nodiscard]]
|
|
constexpr bool valid(TileSheetV2::SubSheet const&ss, int bpp) noexcept {
|
|
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
|
return ox::all_of(ss.subsheets.begin(), ss.subsheets.end(),
|
|
[bpp, bytes](TileSheetV2::SubSheet const&s) {
|
|
return bytes == s.pixels.size() && valid(s, bpp);
|
|
});
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr bool valid(TileSheetV2 const&ts) noexcept {
|
|
return (ts.bpp == 4 || ts.bpp == 8) && valid(ts.subsheet, ts.bpp);
|
|
}
|
|
|
|
constexpr void repair(TileSheetV2::SubSheet &ss, int bpp) noexcept {
|
|
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
|
ss.pixels.resize(bytes);
|
|
for (auto &s : ss.subsheets) {
|
|
repair(s, bpp);
|
|
}
|
|
}
|
|
|
|
constexpr ox::Error repair(TileSheetV2 &ts) noexcept {
|
|
if (ts.bpp != 4 && ts.bpp != 8) {
|
|
return ox::Error(1, "Unable to repair TileSheet");
|
|
}
|
|
repair(ts.subsheet, ts.bpp);
|
|
return {};
|
|
}
|
|
|
|
|
|
using SubSheetId = int32_t;
|
|
|
|
struct TileSheetV3 {
|
|
using SubSheetIdx = ox::Vector<std::size_t, 4>;
|
|
|
|
struct SubSheet {
|
|
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheet.SubSheet";
|
|
static constexpr auto TypeVersion = 3;
|
|
SubSheetId id = 0;
|
|
ox::String name;
|
|
int columns = 0;
|
|
int rows = 0;
|
|
ox::Vector<SubSheet> subsheets;
|
|
ox::Vector<uint8_t> pixels;
|
|
constexpr SubSheet() noexcept = default;
|
|
SubSheet(
|
|
SubSheetId pId,
|
|
ox::StringParam pName,
|
|
int pColumns,
|
|
int pRows,
|
|
int bpp) noexcept:
|
|
id(pId),
|
|
name(std::move(pName)),
|
|
columns(pColumns),
|
|
rows(pRows),
|
|
pixels(static_cast<std::size_t>(columns * rows * PixelsPerTile) / (bpp == 4 ? 2u : 1u)) {
|
|
}
|
|
|
|
};
|
|
|
|
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheet";
|
|
static constexpr auto TypeVersion = 3;
|
|
int8_t bpp = 4;
|
|
SubSheetId idIt = 0;
|
|
ox::FileAddress defaultPalette;
|
|
SubSheet subsheet{0, "Root", 1, 1, bpp};
|
|
|
|
};
|
|
|
|
[[nodiscard]]
|
|
constexpr bool valid(TileSheetV3::SubSheet const&ss, int bpp) noexcept {
|
|
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
|
return ox::all_of(ss.subsheets.begin(), ss.subsheets.end(),
|
|
[bpp, bytes](TileSheetV3::SubSheet const&s) {
|
|
return bytes == s.pixels.size() && valid(s, bpp);
|
|
});
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr bool valid(TileSheetV3 const&ts) noexcept {
|
|
return (ts.bpp == 4 || ts.bpp == 8) && valid(ts.subsheet, ts.bpp);
|
|
}
|
|
|
|
constexpr void repair(TileSheetV3::SubSheet &ss, int bpp) noexcept {
|
|
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
|
ss.pixels.resize(bytes);
|
|
for (auto &s : ss.subsheets) {
|
|
repair(s, bpp);
|
|
}
|
|
}
|
|
|
|
constexpr ox::Error repair(TileSheetV3 &ts) noexcept {
|
|
if (ts.bpp != 4 && ts.bpp != 8) {
|
|
return ox::Error(1, "Unable to repair TileSheet");
|
|
}
|
|
repair(ts.subsheet, ts.bpp);
|
|
return {};
|
|
}
|
|
|
|
|
|
struct TileSheetV4 {
|
|
using SubSheetIdx = ox::Vector<std::size_t, 4>;
|
|
|
|
struct SubSheet {
|
|
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheet.SubSheet";
|
|
static constexpr auto TypeVersion = 4;
|
|
SubSheetId id = 0;
|
|
ox::String name;
|
|
int columns = 0;
|
|
int rows = 0;
|
|
ox::Vector<SubSheet> subsheets;
|
|
ox::Vector<uint8_t> pixels;
|
|
|
|
constexpr SubSheet() noexcept = default;
|
|
SubSheet(
|
|
SubSheetId pId,
|
|
ox::StringParam pName,
|
|
int pColumns,
|
|
int pRows,
|
|
int bpp) noexcept:
|
|
id(pId),
|
|
name(std::move(pName)),
|
|
columns(pColumns),
|
|
rows(pRows),
|
|
pixels(static_cast<std::size_t>(columns * rows * PixelsPerTile) / (bpp == 4 ? 2u : 1u)) {
|
|
}
|
|
SubSheet(
|
|
SubSheetId pId,
|
|
ox::StringParam pName,
|
|
int pColumns,
|
|
int pRows,
|
|
ox::Vector<uint8_t> pPixels) noexcept:
|
|
id(pId),
|
|
name(std::move(pName)),
|
|
columns(pColumns),
|
|
rows(pRows),
|
|
pixels(std::move(pPixels)) {
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @return the dimensional size of the SubSheet (e.g. width * height)
|
|
*/
|
|
[[nodiscard]]
|
|
constexpr std::size_t size() const noexcept {
|
|
return static_cast<std::size_t>(columns) * static_cast<std::size_t>(rows);
|
|
}
|
|
|
|
};
|
|
|
|
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheet";
|
|
static constexpr auto TypeVersion = 4;
|
|
int8_t bpp = 4;
|
|
SubSheetId idIt = 0;
|
|
ox::FileAddress defaultPalette;
|
|
SubSheet subsheet{0, "Root", 1, 1, bpp};
|
|
|
|
constexpr TileSheetV4() noexcept = default;
|
|
|
|
};
|
|
|
|
[[nodiscard]]
|
|
constexpr bool valid(TileSheetV4::SubSheet const&ss, int bpp) noexcept {
|
|
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
|
return
|
|
(ss.pixels.empty() || ss.subsheets.empty()) &&
|
|
ox::all_of(ss.subsheets.begin(), ss.subsheets.end(),
|
|
[bpp, bytes](TileSheetV4::SubSheet const&s) {
|
|
return bytes == s.pixels.size() && valid(s, bpp);
|
|
});
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr bool valid(TileSheetV4 const&ts) noexcept {
|
|
return (ts.bpp == 4 || ts.bpp == 8) && valid(ts.subsheet, ts.bpp);
|
|
}
|
|
|
|
constexpr void repair(TileSheetV4::SubSheet &ss, int bpp) noexcept {
|
|
if (ss.subsheets.empty()) {
|
|
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
|
ss.pixels.resize(bytes);
|
|
} else {
|
|
ss.pixels.clear();
|
|
ss.columns = -1;
|
|
ss.rows = -1;
|
|
}
|
|
for (auto &s : ss.subsheets) {
|
|
repair(s, bpp);
|
|
}
|
|
}
|
|
|
|
constexpr ox::Error repair(TileSheetV4 &ts) noexcept {
|
|
if (ts.bpp != 4 && ts.bpp != 8) {
|
|
return ox::Error(1, "Unable to repair TileSheet");
|
|
}
|
|
repair(ts.subsheet, ts.bpp);
|
|
return {};
|
|
}
|
|
|
|
|
|
using TileSheet = TileSheetV4;
|
|
|
|
[[nodiscard]]
|
|
std::size_t idx(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept;
|
|
|
|
[[nodiscard]]
|
|
size_t getTileCnt(TileSheet const&ts) noexcept;
|
|
|
|
[[nodiscard]]
|
|
TileSheet::SubSheet const*getSubsheet(TileSheet const&ts, SubSheetId id) noexcept;
|
|
|
|
[[nodiscard]]
|
|
ox::Optional<size_t> getTileIdx(TileSheet const&ts, SubSheetId id) noexcept;
|
|
|
|
[[nodiscard]]
|
|
uint8_t getPixel4Bpp(TileSheet::SubSheet const&ss, std::size_t idx) noexcept;
|
|
|
|
[[nodiscard]]
|
|
uint8_t getPixel8Bpp(TileSheet::SubSheet const&ss, std::size_t idx) noexcept;
|
|
|
|
[[nodiscard]]
|
|
uint8_t getPixel(TileSheet::SubSheet const&ss, int8_t pBpp, std::size_t idx) noexcept;
|
|
|
|
[[nodiscard]]
|
|
uint8_t getPixel4Bpp(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept;
|
|
|
|
[[nodiscard]]
|
|
uint8_t getPixel8Bpp(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept;
|
|
|
|
[[nodiscard]]
|
|
uint8_t getPixel(TileSheet::SubSheet const&ss, int8_t pBpp, ox::Point const&pt) noexcept;
|
|
|
|
constexpr void walkPixels(TileSheet::SubSheet const&ss, int8_t pBpp, auto callback) noexcept {
|
|
if (pBpp == 4) {
|
|
const auto pixelCnt = ox::min<std::size_t>(
|
|
static_cast<std::size_t>(ss.columns * ss.rows * PixelsPerTile) / 2,
|
|
ss.pixels.size());
|
|
//oxAssert(pixels.size() == pixelCnt, "Pixel count does not match rows and columns");
|
|
for (std::size_t i = 0; i < pixelCnt; ++i) {
|
|
const auto colorIdx1 = static_cast<uint8_t>(ss.pixels[i] & 0xF);
|
|
const auto colorIdx2 = static_cast<uint8_t>(ss.pixels[i] >> 4);
|
|
callback(i * 2 + 0, colorIdx1);
|
|
callback(i * 2 + 1, colorIdx2);
|
|
}
|
|
} else {
|
|
const auto pixelCnt = ox::min<std::size_t>(
|
|
static_cast<std::size_t>(ss.columns * ss.rows * PixelsPerTile),
|
|
ss.pixels.size());
|
|
for (std::size_t i = 0; i < pixelCnt; ++i) {
|
|
const auto p = ss.pixels[i];
|
|
callback(i, p);
|
|
}
|
|
}
|
|
}
|
|
|
|
void setPixel(TileSheet::SubSheet &ss, int8_t pBpp, uint64_t idx, uint8_t palIdx) noexcept;
|
|
|
|
void setPixel(TileSheet::SubSheet &ss, int8_t pBpp, ox::Point const&pt, uint8_t palIdx) noexcept;
|
|
|
|
ox::Error setPixelCount(TileSheet::SubSheet &ss, int8_t pBpp, std::size_t cnt) noexcept;
|
|
|
|
/**
|
|
* Gets a count of the pixels in this sheet, and not that of its children.
|
|
* @param pBpp bits per pixel, need for knowing how to count the pixels
|
|
* @return a count of the pixels in this sheet
|
|
*/
|
|
[[nodiscard]]
|
|
unsigned pixelCnt(TileSheet::SubSheet const&ss, int8_t pBpp) noexcept;
|
|
|
|
/**
|
|
*
|
|
* @param ss
|
|
* @param pBpp
|
|
* @param sz size of Subsheet in tiles (not pixels)
|
|
*/
|
|
ox::Error resizeSubsheet(TileSheet::SubSheet &ss, int8_t pBpp, ox::Size const&sz) noexcept;
|
|
|
|
/**
|
|
* validateSubSheetIdx takes a SubSheetIdx and moves the index to the
|
|
* preceding or parent sheet if the current corresponding sheet does
|
|
* not exist.
|
|
* @param idx SubSheetIdx to validate and correct
|
|
* @return a valid version of idx
|
|
*/
|
|
[[nodiscard]]
|
|
TileSheet::SubSheetIdx validateSubSheetIdx(TileSheet const&ts, TileSheet::SubSheetIdx idx) noexcept;
|
|
|
|
[[nodiscard]]
|
|
TileSheet::SubSheet const&getSubSheet(
|
|
TileSheet::SubSheetIdx const&idx,
|
|
std::size_t idxIt,
|
|
TileSheet::SubSheet const&pSubsheet) noexcept;
|
|
|
|
[[nodiscard]]
|
|
TileSheet::SubSheet &getSubSheet(
|
|
TileSheet::SubSheetIdx const&idx,
|
|
std::size_t idxIt,
|
|
TileSheet::SubSheet &pSubsheet) noexcept;
|
|
|
|
[[nodiscard]]
|
|
TileSheet::SubSheet const&getSubSheet(TileSheet const&ts, TileSheet::SubSheetIdx const&idx) noexcept;
|
|
|
|
[[nodiscard]]
|
|
TileSheet::SubSheet &getSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept;
|
|
|
|
ox::Error addSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept;
|
|
|
|
ox::Error rmSubSheet(
|
|
TileSheet &ts,
|
|
TileSheet::SubSheetIdx const&idx,
|
|
std::size_t idxIt,
|
|
TileSheet::SubSheet &pSubsheet) noexcept;
|
|
|
|
ox::Error rmSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept;
|
|
|
|
[[nodiscard]]
|
|
uint8_t getPixel4Bpp(
|
|
TileSheet const&ts,
|
|
ox::Point const&pt,
|
|
TileSheet::SubSheetIdx const&subsheetIdx) noexcept;
|
|
|
|
[[nodiscard]]
|
|
uint8_t getPixel8Bpp(
|
|
TileSheet const&ts,
|
|
ox::Point const&pt,
|
|
TileSheet::SubSheetIdx const&subsheetIdx) noexcept;
|
|
|
|
ox::Result<SubSheetId> getIdFor(TileSheet const&ts, ox::StringViewCR path) noexcept;
|
|
|
|
ox::Result<unsigned> getTileOffset(TileSheet const&ts, ox::StringViewCR pNamePath) noexcept;
|
|
|
|
ox::Result<uint32_t> getTileOffset(TileSheet const&ts, SubSheetId pId) noexcept;
|
|
|
|
ox::Result<ox::StringView> getNameFor(TileSheet::SubSheet const&ss, SubSheetId pId) noexcept;
|
|
|
|
ox::Result<ox::StringView> getNameFor(TileSheet const&ts, SubSheetId pId) noexcept;
|
|
|
|
[[nodiscard]]
|
|
ox::Vector<uint8_t> pixels(TileSheet &ts) noexcept;
|
|
|
|
|
|
struct CompactTileSheetV1 {
|
|
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.CompactTileSheet";
|
|
static constexpr auto TypeVersion = 1;
|
|
static constexpr auto Preloadable = true;
|
|
int8_t bpp = 0;
|
|
ox::FileAddress defaultPalette;
|
|
ox::Vector<uint8_t> pixels;
|
|
};
|
|
|
|
[[nodiscard]]
|
|
constexpr bool valid(CompactTileSheetV1 const&ts) noexcept {
|
|
return ts.bpp == 4 || ts.bpp == 8;
|
|
}
|
|
|
|
|
|
using CompactTileSheet = CompactTileSheetV1;
|
|
|
|
[[nodiscard]]
|
|
uint8_t getPixel4Bpp(
|
|
CompactTileSheet const&ts,
|
|
size_t idx) noexcept;
|
|
|
|
[[nodiscard]]
|
|
uint8_t getPixel8Bpp(
|
|
CompactTileSheet const&ts,
|
|
size_t idx) noexcept;
|
|
|
|
[[nodiscard]]
|
|
ox::Pair<uint8_t> get2Pixels4Bpp(
|
|
CompactTileSheet const&ts,
|
|
size_t idx) noexcept;
|
|
|
|
[[nodiscard]]
|
|
ox::Pair<uint8_t> get2Pixels8Bpp(
|
|
CompactTileSheet const&ts,
|
|
size_t idx) noexcept;
|
|
|
|
OX_MODEL_BEGIN(TileSheetV1)
|
|
OX_MODEL_FIELD(bpp)
|
|
OX_MODEL_FIELD(rows)
|
|
OX_MODEL_FIELD(columns)
|
|
OX_MODEL_FIELD(defaultPalette)
|
|
OX_MODEL_FIELD(pal)
|
|
OX_MODEL_FIELD(pixels)
|
|
OX_MODEL_END()
|
|
|
|
OX_MODEL_BEGIN(TileSheetV2::SubSheet)
|
|
OX_MODEL_FIELD(name)
|
|
OX_MODEL_FIELD(rows)
|
|
OX_MODEL_FIELD(columns)
|
|
OX_MODEL_FIELD(subsheets)
|
|
OX_MODEL_FIELD(pixels)
|
|
OX_MODEL_END()
|
|
|
|
OX_MODEL_BEGIN(TileSheetV2)
|
|
OX_MODEL_FIELD(bpp)
|
|
OX_MODEL_FIELD(defaultPalette)
|
|
OX_MODEL_FIELD(subsheet)
|
|
OX_MODEL_END()
|
|
|
|
OX_MODEL_BEGIN(TileSheetV3::SubSheet)
|
|
OX_MODEL_FIELD(name)
|
|
OX_MODEL_FIELD(rows)
|
|
OX_MODEL_FIELD(columns)
|
|
OX_MODEL_FIELD(subsheets)
|
|
OX_MODEL_FIELD(pixels)
|
|
OX_MODEL_END()
|
|
|
|
OX_MODEL_BEGIN(TileSheetV3)
|
|
OX_MODEL_FIELD(bpp)
|
|
OX_MODEL_FIELD(idIt)
|
|
OX_MODEL_FIELD(defaultPalette)
|
|
OX_MODEL_FIELD(subsheet)
|
|
OX_MODEL_END()
|
|
|
|
OX_MODEL_BEGIN(TileSheetV4::SubSheet)
|
|
OX_MODEL_FIELD(id)
|
|
OX_MODEL_FIELD(name)
|
|
OX_MODEL_FIELD(rows)
|
|
OX_MODEL_FIELD(columns)
|
|
OX_MODEL_FIELD(subsheets)
|
|
OX_MODEL_FIELD(pixels)
|
|
OX_MODEL_END()
|
|
|
|
OX_MODEL_BEGIN(TileSheetV4)
|
|
OX_MODEL_FIELD(bpp)
|
|
OX_MODEL_FIELD(idIt)
|
|
OX_MODEL_FIELD(defaultPalette)
|
|
OX_MODEL_FIELD(subsheet)
|
|
OX_MODEL_END()
|
|
|
|
OX_MODEL_BEGIN(CompactTileSheetV1)
|
|
OX_MODEL_FIELD(bpp)
|
|
OX_MODEL_FIELD(defaultPalette)
|
|
OX_MODEL_FIELD(pixels)
|
|
OX_MODEL_END()
|
|
|
|
ox::Vector<uint32_t> resizeTileSheetData(
|
|
ox::Vector<uint32_t> const&srcPixels,
|
|
ox::Size const&srcSize,
|
|
int scale = 2) noexcept;
|
|
|
|
}
|