summaryrefslogtreecommitdiff
path: root/tools/src
diff options
context:
space:
mode:
authoroctorock <79596758+octorock@users.noreply.github.com>2022-12-11 12:07:48 +0100
committeroctorock <79596758+octorock@users.noreply.github.com>2022-12-11 12:07:48 +0100
commit1d741c182dec03c6c7a6ea337f351eedf7d6eb65 (patch)
tree7a1fc484cc98a123a562ed5bb2e03e85b6f28e95 /tools/src
parent017eb5a65efe06ab338f7d6a3bdd1188fcca6c3e (diff)
Extract dungeon maps
Diffstat (limited to 'tools/src')
-rw-r--r--tools/src/asset_processor/assets/asset.h2
-rw-r--r--tools/src/asset_processor/assets/dungeonmap.cpp108
-rw-r--r--tools/src/asset_processor/assets/dungeonmap.h17
-rw-r--r--tools/src/asset_processor/assets/gfx.cpp1
-rw-r--r--tools/src/asset_processor/assets/tileset.cpp1
-rw-r--r--tools/src/asset_processor/main.cpp5
6 files changed, 132 insertions, 2 deletions
diff --git a/tools/src/asset_processor/assets/asset.h b/tools/src/asset_processor/assets/asset.h
index f34485a2..1b29c03c 100644
--- a/tools/src/asset_processor/assets/asset.h
+++ b/tools/src/asset_processor/assets/asset.h
@@ -49,7 +49,7 @@ class BaseAsset {
}
// Returns the base of the filename of the asset.
- [[nodiscard]] std::string getSymbol() const {
+ [[nodiscard]] virtual std::string getSymbol() const {
// Need to get the stem twice to remove both of the .4bpp.lz extensions.
return (path.stem()).stem();
}
diff --git a/tools/src/asset_processor/assets/dungeonmap.cpp b/tools/src/asset_processor/assets/dungeonmap.cpp
new file mode 100644
index 00000000..c01db47e
--- /dev/null
+++ b/tools/src/asset_processor/assets/dungeonmap.cpp
@@ -0,0 +1,108 @@
+#include "dungeonmap.h"
+#include "util.h"
+#include <fmt/format.h>
+#include <fstream>
+#include <nlohmann/json.hpp>
+#include <util/file.h>
+
+std::filesystem::path DungeonMapAsset::generateAssetPath() {
+ std::filesystem::path txtPath = path;
+ txtPath.replace_extension(".txt");
+ return txtPath;
+}
+
+void DungeonMapAsset::convertToHumanReadable(const std::vector<char>& baserom) {
+ (void)baserom;
+ const char characters[] = {' ', '#', '.', '-'};
+
+ std::ifstream file(path.string(), std::ios::binary | std::ios::ate);
+ auto fileSize = file.tellg();
+ file.seekg(0, std::ios::beg);
+
+ std::vector<char> data(static_cast<size_t>(fileSize));
+ if (!file.read(data.data(), fileSize)) {
+ fmt::print(stderr, "Can not read dungeon map {}\n", path.string());
+ std::exit(1);
+ }
+ file.close();
+
+ auto output_file = util::open_file(assetPath, "w");
+
+ size_t width = asset["options"]["width"];
+ width *= 4;
+ size_t height = asset["options"]["height"];
+ size_t bytesPerRow = (width + 3) / 4;
+
+ for (size_t y = 0; y < height; y++) {
+ for (size_t x = 0; x < width; x +=4) {
+ size_t offset = y * bytesPerRow + x / 4;
+ char byte = data[offset];
+ for (size_t i = 0; i < 4; i++) {
+ int color = (byte >> (6 - i*2)) & 3;
+ std::fputc(characters[color], output_file.get());
+ }
+ }
+ std::fputc('\n', output_file.get());
+ }
+}
+
+void DungeonMapAsset::buildToBinary() {
+ std::ifstream file(assetPath.string(), std::ios::binary | std::ios::ate);
+ auto fileSize = file.tellg();
+ file.seekg(0, std::ios::beg);
+
+ std::vector<char> data(static_cast<size_t>(fileSize));
+ if (!file.read(data.data(), fileSize)) {
+ fmt::print(stderr, "Can not read dungeon map {}\n", assetPath.string());
+ std::exit(1);
+ }
+ file.close();
+
+ auto output_file = util::open_file(buildPath, "w");
+ char byte = 0;
+ size_t pixels = 0;
+ for (size_t i = 0; i < static_cast<size_t>(fileSize); i++) {
+ switch (data[i]) {
+ case '\n':
+ continue;
+ case ' ':
+ byte <<= 2;
+ pixels++;
+ break;
+ case '#':
+ byte <<= 2;
+ byte |= 1;
+ pixels++;
+ break;
+ case '.':
+ byte <<= 2;
+ byte |= 2;
+ pixels++;
+ break;
+ case '-':
+ byte <<= 2;
+ byte |= 3;
+ pixels++;
+ break;
+ default:
+ fmt::print(stderr, "Unexpected character {}\n", data[i]);
+ std::exit(1);
+ break;
+ }
+
+ if (pixels % 4 == 0) {
+ std::fputc(byte, output_file.get());
+ byte = 0;
+ }
+ }
+
+ // Pad to two bytes.
+ while ((pixels / 4) % 4 != 0) {
+ std::fputc(0, output_file.get());
+ pixels += 4;
+ }
+}
+
+std::string DungeonMapAsset::getSymbol() const {
+ return asset["name"];
+} \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/dungeonmap.h b/tools/src/asset_processor/assets/dungeonmap.h
new file mode 100644
index 00000000..1c669636
--- /dev/null
+++ b/tools/src/asset_processor/assets/dungeonmap.h
@@ -0,0 +1,17 @@
+#ifndef DUNGEONMAP_H
+#define DUNGEONMAP_H
+
+#include "asset.h"
+
+class DungeonMapAsset : public BaseAsset {
+ public:
+ using BaseAsset::BaseAsset;
+ virtual void convertToHumanReadable(const std::vector<char>& baserom);
+ virtual void buildToBinary();
+ virtual std::string getSymbol() const;
+
+ private:
+ virtual std::filesystem::path generateAssetPath();
+};
+
+#endif // DUNGEONMAP_H
diff --git a/tools/src/asset_processor/assets/gfx.cpp b/tools/src/asset_processor/assets/gfx.cpp
index ef656e25..ffceefc0 100644
--- a/tools/src/asset_processor/assets/gfx.cpp
+++ b/tools/src/asset_processor/assets/gfx.cpp
@@ -56,6 +56,7 @@ void GfxAsset::buildToBinary() {
check_call(cmd);
if (isCompressed()) {
+ cmd.clear();
// Compress.
cmd.push_back(toolsPath / "bin" / "gbagfx");
cmd.push_back(decompressedPath);
diff --git a/tools/src/asset_processor/assets/tileset.cpp b/tools/src/asset_processor/assets/tileset.cpp
index 56a9bb72..84321b80 100644
--- a/tools/src/asset_processor/assets/tileset.cpp
+++ b/tools/src/asset_processor/assets/tileset.cpp
@@ -53,6 +53,7 @@ void TilesetAsset::buildToBinary() {
if (isCompressed()) {
// Compress.
+ cmd.clear();
cmd.push_back(toolsPath / "bin" / "gbagfx");
cmd.push_back(decompressedPath);
cmd.push_back(path);
diff --git a/tools/src/asset_processor/main.cpp b/tools/src/asset_processor/main.cpp
index 195c6939..67e1158d 100644
--- a/tools/src/asset_processor/main.cpp
+++ b/tools/src/asset_processor/main.cpp
@@ -1,6 +1,7 @@
#include "main.h"
#include "assets/aif.h"
#include "assets/animation.h"
+#include "assets/dungeonmap.h"
#include "assets/frameobjlists.h"
#include "assets/gfx.h"
#include "assets/map.h"
@@ -284,6 +285,8 @@ std::unique_ptr<BaseAsset> getAssetHandlerByType(const std::filesystem::path& pa
type == "map_mapping1" || type == "map_mapping2" || type == "tileset_mapping3" ||
type == "map_collision") {
assetHandler = std::make_unique<MapAsset>(path, start, size, asset);
+ } else if (type == "dungeon_map") {
+ assetHandler = std::make_unique<DungeonMapAsset>(path, start, size, asset);
} else if (type == "unknown") {
// TODO implement conversions
assetHandler = std::make_unique<BaseAsset>(path, start, size, asset);
@@ -291,7 +294,7 @@ std::unique_ptr<BaseAsset> getAssetHandlerByType(const std::filesystem::path& pa
// Unknown binary asset
assetHandler = std::make_unique<BaseAsset>(path, start, size, asset);
} else {
- fmt::print(stderr, "Error: Unimplemented asset type \"{}\"", type);
+ fmt::print(stderr, "Error: Unimplemented asset type \"{}\"\n", type);
std::exit(1);
}
assetHandler->setup();