Implement nost-pack tool

This commit is contained in:
Gary Talent 2017-04-13 04:38:59 -05:00
parent c5712f26e2
commit ab2e6e5ea2
12 changed files with 165 additions and 30 deletions

View File

@ -7,7 +7,7 @@
*/ */
#include "bounds.hpp" #include "bounds.hpp"
namespace wombat { namespace nostalgia {
namespace common { namespace common {
Bounds::Bounds() { Bounds::Bounds() {

View File

@ -5,12 +5,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#ifndef NOSTALGIA_COMMON_BOUNDS_HPP #pragma once
#define NOSTALGIA_COMMON_BOUNDS_HPP
#include "point.hpp" #include "point.hpp"
namespace wombat { namespace nostalgia {
namespace common { namespace common {
class Bounds { class Bounds {
@ -40,5 +39,3 @@ class Bounds {
} }
} }
#endif

View File

@ -7,7 +7,7 @@
*/ */
#include "point.hpp" #include "point.hpp"
namespace wombat { namespace nostalgia {
namespace common { namespace common {
Point::Point() { Point::Point() {

View File

@ -5,10 +5,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#ifndef NOSTALGIA_COMMON_POINT_HPP #pragma once
#define NOSTALGIA_COMMON_POINT_HPP
namespace wombat { namespace nostalgia {
namespace common { namespace common {
class Point { class Point {
@ -58,5 +57,3 @@ class Point {
} }
} }
#endif

View File

@ -11,7 +11,7 @@
namespace nostalgia { namespace nostalgia {
namespace core { namespace core {
ox::std::Error init() { ox::Error init() {
auto err = initGfx(); auto err = initGfx();
return err; return err;
} }

View File

@ -12,7 +12,7 @@
namespace nostalgia { namespace nostalgia {
namespace core { namespace core {
ox::std::Error init(); ox::Error init();
} }
} }

28
src/core/gba/gba.hpp Normal file
View File

@ -0,0 +1,28 @@
/*
* Copyright 2016-2017 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once
namespace nostalgia {
namespace core {
typedef struct { uint32_t data[8]; } Tile, Tile4;
// d-tile: double-sized tile (8bpp)
typedef struct { uint32_t data[16]; } Tile8;
// tile block: 32x16 tiles, 16x16 d-tiles
typedef unsigned short Pallete[256];
typedef Tile CharBlock[512];
typedef Tile8 CharBlock8[256];
struct GbaImageData {
Pallete pal;
uint8_t tiles[1];
};
}
}

View File

@ -10,26 +10,18 @@
#include <ox/std/std.hpp> #include <ox/std/std.hpp>
#include "addresses.hpp" #include "addresses.hpp"
#include "media.hpp" #include "media.hpp"
#include "gba.hpp"
#include "dirt.h" #include "dirt.h"
namespace nostalgia { namespace nostalgia {
namespace core { namespace core {
using namespace ox::fs; using namespace ox::fs;
using namespace ox::std;
typedef struct { uint32_t data[8]; } Tile, Tile4;
// d-tile: double-sized tile (8bpp)
typedef struct { uint32_t data[16]; } Tile8;
// tile block: 32x16 tiles, 16x16 d-tiles
typedef struct { unsigned short data[256]; } Pallete;
typedef Tile CharBlock[512];
typedef Tile8 CharBlock8[256];
#define TILE_ADDR ((CharBlock*) 0x06000000) #define TILE_ADDR ((CharBlock*) 0x06000000)
#define TILE8_ADDR ((CharBlock8*) 0x06000000) #define TILE8_ADDR ((CharBlock8*) 0x06000000)
ox::std::Error initGfx() { ox::Error initGfx() {
/* Sprite Mode ----\ */ /* Sprite Mode ----\ */
/* ---\| */ /* ---\| */
/* Background 0 -\|| */ /* Background 0 -\|| */

View File

@ -12,7 +12,7 @@
namespace nostalgia { namespace nostalgia {
namespace core { namespace core {
ox::std::Error initGfx(); ox::Error initGfx();
} }
} }

View File

@ -11,7 +11,7 @@
namespace nostalgia { namespace nostalgia {
namespace core { namespace core {
ox::std::Error initGfx() { ox::Error initGfx() {
return 0; return 0;
} }

View File

@ -10,10 +10,11 @@ add_executable(nost-pack pack.cpp)
target_link_libraries( target_link_libraries(
nost-pack nost-pack
Qt5::Widgets Qt5::Widgets
NostalgiaCore
${OxStd_LIBRARY}
${OxClArgs_LIBRARY} ${OxClArgs_LIBRARY}
${OxFS_LIBRARY} ${OxFS_LIBRARY}
${OxStd_LIBRARY}
NostalgiaCommon
NostalgiaCore
) )
set(CMAKE_INCLUDE_CURRENT_DIR OFF) set(CMAKE_INCLUDE_CURRENT_DIR OFF)

View File

@ -6,10 +6,130 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#include <iostream>
#include <QColor>
#include <QImage> #include <QImage>
#include <QMap>
#include <core/gba/gba.hpp>
#include <common/point.hpp>
#include <ox/clargs/clargs.hpp> #include <ox/clargs/clargs.hpp>
#include <ox/fs/filesystem.hpp>
using namespace std;
using namespace ox;
using namespace ox::clargs;
using namespace ox::fs;
using namespace nostalgia::core;
using namespace nostalgia::common;
uint8_t *loadFileBuff(QString path, ::size_t *sizeOut = nullptr) {
auto file = fopen(path.toUtf8(), "rb");
if (file) {
fseek(file, 0, SEEK_END);
const auto size = ftell(file);
rewind(file);
auto buff = new uint8_t[size];
auto itemsRead = fread(buff, size, 1, file);
fclose(file);
if (sizeOut) {
*sizeOut = itemsRead ? size : 0;
}
return buff;
} else {
return nullptr;
}
}
uint16_t toGbaColor(QColor c) {
auto r = ((uint32_t) c.red()) >> 3;
auto g = ((uint32_t) c.green()) >> 3;
auto b = ((uint32_t) c.blue()) >> 3;
return (r << 10) | (g << 5) | (b << 0);
}
int pointToIdx(int w, int x, int y) {
const auto colLength = 64;
const auto rowLength = (w / 8) * colLength;
const auto colStart = colLength * (x / 8);
const auto rowStart = rowLength * (y / 8);
const auto colOffset = x % 8;
const auto rowOffset = (y % 8) * 8;
return colStart + colOffset + rowStart + rowOffset;
}
int run(ClArgs args) {
Error err = 0;
QString inPath = args.getString("img").c_str();
QString fsPath = args.getString("fs").c_str();
auto compact = args.getBool("c");
QMap<QRgb, int> colors;
QImage src(inPath);
const auto imgDataBuffSize = sizeof(Pallete) + src.width() * src.height();
uint8_t imgDataBuff[imgDataBuffSize];
GbaImageData *id = (GbaImageData*) imgDataBuff;
int colorId = 0;
if (!src.isNull()) {
// copy pixels as color ids
for (int x = 0; x < src.colorCount(); x++) {
for (int y = 0; y < src.colorCount(); y++) {
auto destI = pointToIdx(src.width(), x, y);
auto c = src.pixel(x, y);
if (!colors.contains(c)) {
colors[c] = colorId;
colorId++;
}
((uint8_t*) &id->tiles)[destI] = colors[c];
}
}
// store colors in palette with the corresponding color id
for (auto key : colors.keys()) {
auto colorId = colors[key];
id->pal[colorId] = toGbaColor(key);
}
size_t fsBuffSize;
auto fsBuff = loadFileBuff(fsPath, &fsBuffSize);
if (fsBuff && !err) {
auto fs = createFileSystem(fsBuff, fsBuffSize);
if (fs) {
fs = expandCopyCleanup(fs, fs->size() + fs->spaceNeeded(imgDataBuffSize));
fsBuff = fs->buff(); // update fsBuff pointer in case there is a new buff
err |= fs->write(1, imgDataBuff, imgDataBuffSize);
if (compact) {
fs->resize();
}
auto fsFile = fopen(fsPath.toUtf8(), "wb");
if (fsFile) {
err = fwrite(fsBuff, fs->size(), 1, fsFile) != 1;
err |= fclose(fsFile);
if (err) {
cerr << "Could not write to file system file.\n";
}
} else {
err = 2;
}
delete fs;
} else {
err = 3;
}
}
delete[] fsBuff;
} else {
err = 4;
}
return err;
}
int main(int argc, const char **args) { int main(int argc, const char **args) {
QImage src("charset.png"); return run(ClArgs(argc, args));
return 0;
} }