summaryrefslogtreecommitdiff
path: root/tools/asset_processor/main.cpp
diff options
context:
space:
mode:
authorHenny022p <info@henny022.de>2021-11-23 05:40:41 +0100
committerHenny022p <info@henny022.de>2021-11-23 05:40:41 +0100
commitbc4a8577f3f139a8d0b420e2decbbb9701d25c4c (patch)
tree180a00ab6fb3a51ec6776747610e56e231f4140e /tools/asset_processor/main.cpp
parent47a3e614a01598cf28f9f484c5405b522fd789fe (diff)
moved asset_processor to new location
Diffstat (limited to 'tools/asset_processor/main.cpp')
-rw-r--r--tools/asset_processor/main.cpp313
1 files changed, 0 insertions, 313 deletions
diff --git a/tools/asset_processor/main.cpp b/tools/asset_processor/main.cpp
deleted file mode 100644
index f642d64f..00000000
--- a/tools/asset_processor/main.cpp
+++ /dev/null
@@ -1,313 +0,0 @@
-#include "main.h"
-#include "assets/aif.h"
-#include "assets/animation.h"
-#include "assets/exitlist.h"
-#include "assets/frameobjlists.h"
-#include "assets/gfx.h"
-#include "assets/midi.h"
-#include "assets/palette.h"
-#include "assets/spriteframe.h"
-#include "assets/tileset.h"
-#include "offsets.h"
-#include <filesystem>
-#include <fstream>
-#include <iostream>
-#include <json.hpp>
-
-using nlohmann::json;
-
-// Does json array contain element? https://github.com/nlohmann/json/issues/399#issuecomment-844212174
-#define CONTAINS(list, value) (std::find(list.begin(), list.end(), value) != list.end())
-
-void usage() {
- std::cout << "Usage: asset_processor [options] MODE VARIANT BUILD_PATH\n"
- << "\n"
- << "MODE Mode to execute\n"
- << "VARIANT Variant to build. One of USA, JP, EU, DEMO_USA, DEMO_JP\n"
- << "BUILD_PATH Path to the build folder\n"
- << "\n"
- << "Modes:\n"
- << "extract Extract binary data from baserom\n"
- << "convert Convert data to human readable format\n"
- << "build Build binary data from assets\n"
- << "\n"
- << "Options:\n"
- << "-v Print verbose output\n"
- << "-h Show this help\n"
- << "-f Force extraction of all assets (even if unmodified)\n";
- std::exit(1);
-}
-
-bool gVerbose = false;
-bool gForceExtraction = false;
-Mode gMode;
-std::string gVariant;
-std::string gAssetsFolder;
-std::string gBaseromPath;
-
-static std::map<std::string, std::string> baseroms = { { "USA", "baserom.gba" },
- { "EU", "baserom_eu.gba" },
- { "JP", "baserom_jp.gba" },
- { "DEMO_USA", "baserom_demo.gba" },
- { "DEMO_JP", "baserom_demo_jp.gba" } };
-
-int main(int argc, char** argv) {
-
- // Parse options.
- int argCount = argc - 1; // Skip program name
- char** args = &argv[1];
-
- while (argCount > 0 && args[0][0] == '-') {
- if (strcmp(args[0], "-v") == 0) {
- gVerbose = true;
- argCount--;
- args++;
- } else if (strcmp(args[0], "-h") == 0) {
- argCount--;
- args++;
- usage();
- } else if (strcmp(args[0], "-f") == 0) {
- gForceExtraction = true;
- argCount--;
- args++;
- } else {
- std::cerr << "Error: Unrecognized argument `" << args[0] << "`" << std::endl;
- std::exit(1);
- }
- }
-
- if (argCount != 3) {
- std::cerr << "Error: Not enough arguments. expected: 3, actual: " << argCount << std::endl;
- usage();
- }
-
- if (strcmp(args[0], "extract") == 0) {
- gMode = EXTRACT;
- } else if (strcmp(args[0], "convert") == 0) {
- gMode = CONVERT;
- } else if (strcmp(args[0], "build") == 0) {
- gMode = BUILD;
- } else {
- std::cerr << "Error: Unsupported mode `" << args[0] << "`" << std::endl;
- std::exit(1);
- }
- gVariant = args[1];
- if (gVariant != "USA" && gVariant != "EU" && gVariant != "JP" && gVariant != "DEMO_USA" && gVariant != "DEMO_JP") {
- std::cerr << "Error: Unsupported variant `" << gVariant << "`" << std::endl;
- std::exit(1);
- }
-
- gAssetsFolder = args[2];
- gBaseromPath = baseroms[gVariant];
-
- if (!std::filesystem::exists(gBaseromPath)) {
- std::cerr << "Error: You need to provide a " << gVariant << " ROM as " << gBaseromPath << std::endl;
- std::exit(1);
- }
-
- // Read baserom.
- std::ifstream file(gBaseromPath, std::ios::binary | std::ios::ate);
- std::streamsize size = file.tellg();
- file.seekg(0, std::ios::beg);
-
- std::vector<char> baserom(size);
- if (!file.read(baserom.data(), size)) {
- std::cerr << "Could not read baserom " << gBaseromPath << std::endl;
- std::exit(1);
- }
- file.close();
-
- // Gather all json configs from assets folder.
- std::vector<std::filesystem::path> configs;
- std::string configFolder = "assets";
- for (const auto& entry : std::filesystem::directory_iterator(configFolder)) {
- const auto& path = entry.path();
- if (path.extension() == ".json") {
- configs.push_back(path);
- }
- }
- std::sort(configs.begin(), configs.end());
-
- for (const auto& config : configs) {
- if (gVerbose) {
- std::cout << "Parsing " << config << "..." << std::endl;
- }
-
- std::ifstream input(config);
- json assets;
- input >> assets;
-
- std::filesystem::file_time_type configModified = std::filesystem::last_write_time(config);
-
- std::unique_ptr<OffsetCalculator> offsetCalculator;
-
- uint currentOffset = 0;
- for (const auto& asset : assets) {
- if (asset.contains("offsets")) { // Offset definition
- if (asset["offsets"].contains(gVariant)) {
- currentOffset = asset["offsets"][gVariant];
- }
- } else if (asset.contains("calculateOffsets")) { // Start offset calculation
- std::filesystem::path path = gAssetsFolder;
- path = path / asset["calculateOffsets"];
- int baseOffset = asset["start"].get<int>() + currentOffset;
- offsetCalculator = std::make_unique<OffsetCalculator>(path, baseOffset);
- } else if (asset.contains("path")) { // Asset definition
-
- if (asset.contains("variants")) {
- if (!CONTAINS(asset["variants"], gVariant)) {
- // This asset is not used in the current variant
- continue;
- }
- }
-
- std::filesystem::path path = gAssetsFolder;
- path = path / asset["path"];
-
- switch (gMode) {
- case EXTRACT: {
- std::unique_ptr<BaseAsset> assetHandler = getAssetHandlerByType(path, asset, currentOffset);
- if (shouldExtractAsset(path, configModified)) {
- if (gVerbose) {
- std::cout << "Extracting " << path << "..." << std::endl;
- }
-
- extractAsset(assetHandler, baserom);
- }
- if (offsetCalculator != nullptr) {
- offsetCalculator->addAsset(assetHandler->getStart(), assetHandler->getSymbol());
- }
- break;
- }
- case CONVERT: {
- std::unique_ptr<BaseAsset> assetHandler = getAssetHandlerByType(path, asset, currentOffset);
- if (shouldConvertAsset(assetHandler)) {
- if (gVerbose) {
- std::cout << "Converting " << assetHandler->getAssetPath() << "..." << std::endl;
- }
- convertAsset(assetHandler, baserom);
- }
- break;
- }
- case BUILD: {
- std::unique_ptr<BaseAsset> assetHandler = getAssetHandlerByType(path, asset, currentOffset);
- if (shouldBuildAsset(assetHandler)) {
- if (gVerbose) {
- std::cout << "Building " << assetHandler->getAssetPath() << "..." << std::endl;
- }
- buildAsset(assetHandler);
- }
- break;
- }
- }
- }
- }
- }
-
- if (gVerbose) {
- std::cout << "done" << std::endl;
- }
-}
-
-std::unique_ptr<BaseAsset> getAssetHandlerByType(const std::filesystem::path& path, const json& asset,
- const int& currentOffset) {
-
- int start = 0;
- if (asset.contains("start")) {
- // Apply offset to the start of the USA variant
- start = asset["start"].get<int>() + currentOffset;
- } else if (asset.contains("starts")) {
- // Use start for the current variant
- start = asset["starts"][gVariant];
- }
-
- std::string type = "";
- if (asset.contains("type")) {
- type = asset["type"];
- }
-
- int size = 0;
- if (asset.contains("size")) { // The asset has a size and want to be extracted first.
- size = asset["size"]; // TODO can different sizes for the different variants ever occur?
- }
-
- std::unique_ptr<BaseAsset> assetHandler;
- if (type == "tileset") {
- assetHandler = std::make_unique<TilesetAsset>(path, start, size, asset);
- } else if (type == "animation") {
- assetHandler = std::make_unique<AnimationAsset>(path, start, size, asset);
- } else if (type == "sprite_frame") {
- assetHandler = std::make_unique<SpriteFrameAsset>(path, start, size, asset);
- } else if (type == "exit_list") {
- assetHandler = std::make_unique<ExitListAsset>(path, start, size, asset);
- } else if (type == "frame_obj_lists") {
- assetHandler = std::make_unique<FrameObjListsAsset>(path, start, size, asset);
- } else if (type == "midi") {
- assetHandler = std::make_unique<MidiAsset>(path, start, size, asset);
- } else if (type == "aif") {
- assetHandler = std::make_unique<AifAsset>(path, start, size, asset);
- } else if (type == "gfx") {
- assetHandler = std::make_unique<GfxAsset>(path, start, size, asset);
- } else if (type == "palette") {
- assetHandler = std::make_unique<PaletteAsset>(path, start, size, asset);
- } else if (type == "map_gfx" || type == "map_layer1" || type == "map_layer2" || type == "metatiles_tile_types1" ||
- type == "metatiles_tile_types2" || type == "metatiles_tileset1" || type == "metatiles_tileset2" ||
- type == "map_mapping1" || type == "map_mapping2" || type == "tileset_mapping3" ||
- type == "map_collision" || type == "unknown") {
- // TODO implement conversions
- assetHandler = std::make_unique<BaseAsset>(path, start, size, asset);
- } else if (type == "") {
- // Unknown binary asset
- assetHandler = std::make_unique<BaseAsset>(path, start, size, asset);
- } else {
- std::cerr << "Error: Unimplemented asset type `" << type << "`" << std::endl;
- std::exit(1);
- }
- assetHandler->setup();
- return assetHandler;
-}
-
-bool shouldExtractAsset(const std::filesystem::path& path, const std::filesystem::file_time_type& configModified) {
- if (gForceExtraction) {
- return true;
- }
- if (std::filesystem::is_regular_file(path)) {
- std::filesystem::file_time_type fileModified = std::filesystem::last_write_time(path);
- if (fileModified < configModified) {
- // File was created before the config was modified, so it needs to be renewed.
- return true;
- } else {
- return false;
- }
- } else {
- // Target file does not yet exist -> extract
- return true;
- }
-}
-
-void extractAsset(std::unique_ptr<BaseAsset>& assetHandler, const std::vector<char>& baserom) {
- // Create the parent directory
- std::filesystem::path parentDir = std::filesystem::path(assetHandler->getPath());
- parentDir.remove_filename();
- std::filesystem::create_directories(parentDir);
-
- assetHandler->extractBinary(baserom);
-}
-
-bool shouldConvertAsset(const std::unique_ptr<BaseAsset>& assetHandler) {
- (void)assetHandler;
- return true; // TODO
-}
-
-void convertAsset(std::unique_ptr<BaseAsset>& assetHandler, const std::vector<char>& baserom) {
- assetHandler->convertToHumanReadable(baserom);
-}
-
-bool shouldBuildAsset(const std::unique_ptr<BaseAsset>& assetHandler) {
- (void)assetHandler;
- return true; // TODO
-}
-
-void buildAsset(std::unique_ptr<BaseAsset>& assetHandler) {
- assetHandler->buildToBinary();
-} \ No newline at end of file