[nostalgia] Add external palettes to tilesheet system

This commit is contained in:
2019-10-22 19:23:14 -05:00
parent fbdb48a1ee
commit 92103bfc41
31 changed files with 802 additions and 105 deletions

View File

@@ -56,28 +56,34 @@ namespace {
return colors.size();
}
[[nodiscard]] std::vector<char> pngToGba(QString argInPath, int argTiles, int argBpp) {
QImage src(argInPath);
[[nodiscard]] std::unique_ptr<core::NostalgiaGraphic> imgToNg(QString argSrc, int argTiles, int argBpp) {
constexpr auto TilePixels = 64;
QImage src(argSrc);
if (src.isNull()) {
return {};
}
const auto Pixels = argTiles ? argTiles * TilePixels : src.width() * src.height();
if (argTiles == 0) {
argTiles = (src.width() * src.height()) / 64;
argTiles = Pixels / 64;
}
const auto Colors = countColors(src, argTiles);
if (argBpp != 4 && argBpp != 8) {
argBpp = countColors(src, argTiles) > 16 ? 8 : 4;
argBpp = Colors > 16 ? 8 : 4;
}
QMap<QRgb, int> colors;
const auto imgDataBuffSize = sizeof(core::GbaImageData) + 1 + argTiles * 64;
std::vector<char> imgDataBuff(imgDataBuffSize);
auto id = new (imgDataBuff.data()) core::GbaImageData;
id->header.bpp = argBpp;
id->header.tileCount = argTiles;
int colorId = 0;
auto ng = std::make_unique<core::NostalgiaGraphic>();
ng->pal.resize(countColors(src, argTiles));
if (argBpp == 4) {
ng->tiles.resize(Pixels / 2);
} else {
ng->tiles.resize(Pixels);
}
ng->bpp = argBpp;
int colorIdx = 0;
// copy pixels as color ids
for (int x = 0; x < src.width(); x++) {
for (int y = 0; y < src.height(); y++) {
@@ -86,18 +92,18 @@ namespace {
const auto c = src.pixel(x, y);
// assign color a color id for the palette
if (!colors.contains(c)) {
colors[c] = colorId;
colorId++;
colors[c] = colorIdx;
colorIdx++;
}
// set pixel color
if (argBpp == 4) {
if (destI % 2) { // is odd number pixel
id->tiles[destI / 2] |= colors[c] << 4;
ng->tiles[destI / 2] |= colors[c] << 4;
} else {
id->tiles[destI / 2] |= colors[c];
ng->tiles[destI / 2] |= colors[c];
}
} else {
id->tiles[destI] = colors[c];
ng->tiles[destI] = colors[c];
}
}
}
@@ -106,10 +112,10 @@ namespace {
// store colors in palette with the corresponding color id
for (auto key : colors.keys()) {
auto colorId = colors[key];
id->pal[colorId] = toGbaColor(key);
ng->pal[colorId] = toGbaColor(key);
}
return imgDataBuff;
return ng;
}
}

View File

@@ -11,8 +11,24 @@
#include <ox/std/error.hpp>
#include <ox/std/types.hpp>
#include <ox/mc/mc.hpp>
#include <nostalgia/core/gfx.hpp>
namespace nostalgia {
[[nodiscard]] std::vector<char> pngToGba(QString argInPath, int argTiles, int argBpp = -1);
template<typename T>
[[nodiscard]] ox::ValErr<std::vector<uint8_t>> toBuffer(T *data, std::size_t buffSize = ox::units::MB) {
std::vector<uint8_t> buff(buffSize);
std::size_t sz = 0;
oxReturnError(ox::writeMC(buff.data(), buff.size(), data, &sz));
if (sz > buffSize) {
return OxError(1);
}
buff.resize(sz);
return buff;
}
[[nodiscard]] std::unique_ptr<core::NostalgiaGraphic> imgToNg(QString argInPath, int argTiles, int argBpp = -1);
}

View File

@@ -27,12 +27,12 @@ namespace {
* @return error
* stub for now
*/
[[nodiscard]] ox::Error pathToInode(std::vector<char>*) {
[[nodiscard]] ox::Error pathToInode(std::vector<uint8_t>*) {
return OxError(0);
}
// stub for now
[[nodiscard]] ox::Error toMetalClaw(std::vector<char>*) {
[[nodiscard]] ox::Error toMetalClaw(std::vector<uint8_t>*) {
return OxError(0);
}
@@ -50,7 +50,7 @@ namespace {
// do transforms
if (endsWith(path, ".claw")) {
// load file
std::vector<char> buff(stat.size);
std::vector<uint8_t> buff(stat.size);
oxReturnError(dest->read(path.c_str(), buff.data(), buff.size()));
// do transformations
oxReturnError(pathToInode(&buff));
@@ -63,8 +63,8 @@ namespace {
});
}
[[nodiscard]] ox::Error verifyFile(ox::FileSystem32 *fs, const std::string &path, const std::vector<char> &expected) noexcept {
std::vector<char> buff(expected.size());
[[nodiscard]] ox::Error verifyFile(ox::FileSystem32 *fs, const std::string &path, const std::vector<uint8_t> &expected) noexcept {
std::vector<uint8_t> buff(expected.size());
oxReturnError(fs->read(path.c_str(), buff.data(), buff.size()));
return OxError(buff == expected ? 0 : 1);
}
@@ -81,15 +81,15 @@ namespace {
oxReturnError(dest->mkdir(currentFile.c_str(), true));
oxReturnError(copy(src, dest, currentFile + '/'));
} else {
std::vector<char> buff;
std::vector<uint8_t> buff;
// do transforms
constexpr std::string_view PngExt = ".png";
constexpr std::string_view GbagExt = ".ng";
if (endsWith(currentFile, PngExt)) {
const std::string OldExt = path.substr(path.find_last_of('.'));
constexpr std::string_view NgExt = ".ng";
if (OldExt != NgExt) {
// load file from full path and transform
const auto fullPath = src->basePath() + currentFile;
buff = pngToGba(fullPath.c_str(), 0, 0);
currentFile = currentFile.substr(0, currentFile.size() - PngExt.size()) + GbagExt.data();
oxReturnError(toBuffer(imgToNg(fullPath.c_str(), 0, 0).get()).get(&buff));
currentFile = currentFile.substr(0, currentFile.size() - OldExt.size()) + NgExt.data();
if (!buff.size()) {
return OxError(1);
}