diff options
| author | octorock <79596758+octorock@users.noreply.github.com> | 2022-12-11 12:07:48 +0100 |
|---|---|---|
| committer | octorock <79596758+octorock@users.noreply.github.com> | 2022-12-11 12:07:48 +0100 |
| commit | 1d741c182dec03c6c7a6ea337f351eedf7d6eb65 (patch) | |
| tree | 7a1fc484cc98a123a562ed5bb2e03e85b6f28e95 /tools/src/asset_processor | |
| parent | 017eb5a65efe06ab338f7d6a3bdd1188fcca6c3e (diff) | |
Extract dungeon maps
Diffstat (limited to 'tools/src/asset_processor')
| -rw-r--r-- | tools/src/asset_processor/assets/asset.h | 2 | ||||
| -rw-r--r-- | tools/src/asset_processor/assets/dungeonmap.cpp | 108 | ||||
| -rw-r--r-- | tools/src/asset_processor/assets/dungeonmap.h | 17 | ||||
| -rw-r--r-- | tools/src/asset_processor/assets/gfx.cpp | 1 | ||||
| -rw-r--r-- | tools/src/asset_processor/assets/tileset.cpp | 1 | ||||
| -rw-r--r-- | tools/src/asset_processor/main.cpp | 5 |
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(); |
