mirror of
https://github.com/izzy2lost/Diddy-Kong-Racing.git
synced 2026-06-19 01:16:26 -07:00
300 lines
12 KiB
C++
300 lines
12 KiB
C++
/**
|
|
* This tool handles everything assets-related including extracting and building.
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "dkr_assets_tool_classes/common/util.h"
|
|
#include "dkr_assets_tool_classes/extractor/extractor.h"
|
|
#include "dkr_assets_tool_classes/builder/builder.h"
|
|
#include "dkr_assets_tool_classes/make_asset_files/asset_enums_header.h"
|
|
#include "dkr_assets_tool_classes/make_asset_files/asset_asm_data.h"
|
|
#include "dkr_assets_tool_classes/compiler/compiler.h"
|
|
|
|
/**************************************************************************/
|
|
|
|
void print_usage() {
|
|
std::cout << "---- Usages -------------------------------------------------------------" << std::endl;
|
|
std::cout << "Extracting assets: ./dkr_assets_tool -e <version> <configs path> <baseroms path> <output path>" << std::endl;
|
|
std::cout << "Building an asset: ./dkr_assets_tool -b <version> <assets path> <source path> <output path>" << std::endl;
|
|
std::cout << "Creating includes: ./dkr_assets_tool -i <version> <assets path> <include directory> <build directory> <asm output directory>" << std::endl;
|
|
std::cout << "Compiling assets: ./dkr_assets_tool -c <version> <assets path>" << std::endl;
|
|
std::cout << "Compress file: ./dkr_assets_tool -fc <input_filename> <output_filename>" << std::endl;
|
|
std::cout << "Decompress file: ./dkr_assets_tool -fd <input_filename> <output_filename>" << std::endl;
|
|
std::cout << "-------------------------------------------------------------------------" << std::endl;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
typedef enum _ToolType {
|
|
TT_DO_NOTHING,
|
|
TT_EXTRACT,
|
|
TT_BUILD,
|
|
TT_ASSET_INCLUDES,
|
|
TT_ASSET_COMPILE,
|
|
TT_ASSET_COMPRESS_FILE,
|
|
TT_ASSET_DECOMPRESS_FILE,
|
|
} ToolType;
|
|
|
|
typedef struct _CmdArgOptions {
|
|
ToolType type;
|
|
std::vector<std::string> paths;
|
|
} CmdArgOptions;
|
|
|
|
CmdArgOptions options;
|
|
|
|
/**************************************************************************/
|
|
|
|
typedef enum _CurrentParseOption {
|
|
PO_NONE,
|
|
PO_TYPE
|
|
} CurrentParseOption;
|
|
|
|
std::string get_cmd_from_parse_option(ToolType type) {
|
|
switch(type) {
|
|
case TT_EXTRACT: return "-e";
|
|
case TT_BUILD: return "-b";
|
|
case TT_ASSET_INCLUDES: return "-i";
|
|
case TT_ASSET_COMPILE: return "-c";
|
|
case TT_ASSET_COMPRESS_FILE: return "-fc";
|
|
case TT_ASSET_DECOMPRESS_FILE: return "-fd";
|
|
}
|
|
return "(Invalid option)";
|
|
}
|
|
|
|
bool parse_options(int argc, char *argv[]) {
|
|
std::vector<std::string> args(argv, argv+argc);
|
|
|
|
if(argc == 1) {
|
|
return false; // Display usage
|
|
}
|
|
|
|
// Parse options from command line.
|
|
bool parsingCmd = false;
|
|
int curOptionState = 0;
|
|
int curOptionArgs = 0;
|
|
CurrentParseOption curOption = PO_NONE;
|
|
for (size_t i = 1; i < args.size(); ++i) {
|
|
if(args[i][0] == '-') {
|
|
if(parsingCmd) {
|
|
display_error("Not enough args for the current command \"", get_cmd_from_parse_option(options.type), "\"");
|
|
return false;
|
|
}
|
|
if(args[i] == "-e") {
|
|
curOption = PO_TYPE;
|
|
curOptionState = 1;
|
|
options.type = TT_EXTRACT;
|
|
parsingCmd = true;
|
|
} else if(args[i] == "-b") {
|
|
curOption = PO_TYPE;
|
|
curOptionState = 2;
|
|
options.type = TT_BUILD;
|
|
parsingCmd = true;
|
|
} else if(args[i] == "-i") {
|
|
curOption = PO_TYPE;
|
|
curOptionState = 3;
|
|
options.type = TT_ASSET_INCLUDES;
|
|
parsingCmd = true;
|
|
} else if(args[i] == "-c") {
|
|
curOption = PO_TYPE;
|
|
curOptionState = 4;
|
|
options.type = TT_ASSET_COMPILE;
|
|
parsingCmd = true;
|
|
} else if(args[i] == "-fc") {
|
|
curOption = PO_TYPE;
|
|
curOptionState = 5;
|
|
options.type = TT_ASSET_COMPRESS_FILE;
|
|
parsingCmd = true;
|
|
} else if(args[i] == "-fd") {
|
|
curOption = PO_TYPE;
|
|
curOptionState = 6;
|
|
options.type = TT_ASSET_DECOMPRESS_FILE;
|
|
parsingCmd = true;
|
|
} else if(args[i] == "-h") {
|
|
return false;
|
|
} else {
|
|
display_error("Invalid option \"", args[i], "\"");
|
|
return false;
|
|
}
|
|
curOptionArgs = 0;
|
|
} else {
|
|
if(!parsingCmd) {
|
|
display_error("Too many args for the current command \"", get_cmd_from_parse_option(options.type), "\"");
|
|
return false;
|
|
}
|
|
switch(curOption) {
|
|
case PO_TYPE:
|
|
switch(curOptionState) {
|
|
case 1: // Extractor
|
|
switch(curOptionArgs) {
|
|
case 0: // version
|
|
case 1: // assets directory
|
|
case 2: // configs directory
|
|
case 3: // baseroms directory
|
|
options.paths.push_back(args[i]);
|
|
break;
|
|
case 4: // output
|
|
options.paths.push_back(args[i]);
|
|
// End of arguments.
|
|
parsingCmd = false;
|
|
curOption = PO_NONE;
|
|
break;
|
|
}
|
|
break;
|
|
case 2: // Builder
|
|
switch(curOptionArgs) {
|
|
case 0: // version
|
|
case 1: // assets directory
|
|
case 2: // source path
|
|
options.paths.push_back(args[i]);
|
|
break;
|
|
case 3: // output
|
|
options.paths.push_back(args[i]);
|
|
// End of arguments.
|
|
parsingCmd = false;
|
|
curOption = PO_NONE;
|
|
break;
|
|
}
|
|
break;
|
|
case 3: // Asset header
|
|
switch(curOptionArgs) {
|
|
case 0: // Assets directory
|
|
case 1: // Enum file output path
|
|
case 2: // Build directory
|
|
case 3: // Asm output directory
|
|
options.paths.push_back(args[i]);
|
|
break;
|
|
case 4: // DKR version
|
|
options.paths.push_back(args[i]);
|
|
// End of arguments.
|
|
parsingCmd = false;
|
|
curOption = PO_NONE;
|
|
break;
|
|
}
|
|
break;
|
|
case 4: // Compile assets
|
|
case 5: // Compress file
|
|
case 6: // Decompress file
|
|
switch(curOptionArgs) {
|
|
case 0: // Assets directory / Input filename
|
|
options.paths.push_back(args[i]);
|
|
break;
|
|
case 1: // version / Output filename
|
|
options.paths.push_back(args[i]);
|
|
// End of arguments.
|
|
parsingCmd = false;
|
|
curOption = PO_NONE;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
default: // This should hopefully never get called
|
|
display_error_and_abort("Invalid dkr_assets_tool option. You should not be seeing this message!");
|
|
}
|
|
curOptionArgs++;
|
|
}
|
|
}
|
|
|
|
if(parsingCmd) {
|
|
display_error("Not enough args for the current command \"", get_cmd_from_parse_option(options.type), "\"");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
int main(int argc, char *argv[]) {
|
|
if(!parse_options(argc, argv)) {
|
|
print_usage();
|
|
return 1;
|
|
}
|
|
|
|
switch(options.type) {
|
|
case TT_EXTRACT:
|
|
{
|
|
std::string version = options.paths[0]; // us_1.0
|
|
std::string assetsDir = options.paths[1]; // <root>/assets
|
|
std::string configsPath = options.paths[2]; // <root>/extract-ver
|
|
std::string baseromsPath = options.paths[3]; // <root>/baseroms
|
|
std::string outputPath = options.paths[4]; // <root>
|
|
|
|
set_assets_folder_path(assetsDir + "/vanilla");
|
|
set_version(version);
|
|
|
|
Extractor extractor(version, configsPath, baseromsPath, outputPath);
|
|
}
|
|
break;
|
|
case TT_BUILD:
|
|
{
|
|
std::string version = options.paths[0]; // us_1.0
|
|
std::string assetsDir = options.paths[1]; // <root>/assets
|
|
std::string sourcePath = options.paths[2]; // Input .json filepath
|
|
std::string outputPath = options.paths[3]; // Output .bin filepath
|
|
|
|
set_assets_folder_path(assetsDir);
|
|
set_version(version);
|
|
|
|
Builder builder(sourcePath, outputPath);
|
|
}
|
|
break;
|
|
case TT_ASSET_INCLUDES:
|
|
{
|
|
std::string version = options.paths[0]; // us_1.0
|
|
std::string assetsDir = options.paths[1]; // <root>/assets
|
|
std::string includeDir = options.paths[2]; // <root>/include
|
|
std::string buildDir = options.paths[3]; // <root>/build
|
|
std::string assetsAsmDir = options.paths[4]; // <root>/asm/assets
|
|
|
|
set_assets_folder_path(assetsDir);
|
|
set_version(version);
|
|
|
|
AssetEnumsHeader assetEnumsHeader(includeDir);
|
|
AssetAsmIncludes assetAsmIncludes(assetsDir + "/" + version, buildDir + "/" + version, assetsAsmDir);
|
|
}
|
|
break;
|
|
case TT_ASSET_COMPILE:
|
|
{
|
|
std::string version = options.paths[0]; // us_1.0
|
|
std::string assetsDir = options.paths[1]; // <root>/assets
|
|
|
|
set_assets_folder_path(assetsDir);
|
|
set_version(version);
|
|
|
|
AssetCompiler compiler;
|
|
}
|
|
break;
|
|
case TT_ASSET_COMPRESS_FILE:
|
|
case TT_ASSET_DECOMPRESS_FILE:
|
|
{
|
|
DKRCompression compression;
|
|
std::string inputFilename = options.paths[0];
|
|
std::string outputFilename = options.paths[1];
|
|
std::vector<uint8_t> inputBinary, outputBinary;
|
|
|
|
if(compression.readBinaryFile(inputBinary, inputFilename)) {
|
|
if(inputBinary.size() == 0) {
|
|
compression.writeBinaryFile(inputBinary, outputFilename);
|
|
} else {
|
|
if (options.type == TT_ASSET_COMPRESS_FILE) {
|
|
outputBinary = compression.compressBuffer(inputBinary);
|
|
} else if (options.type == TT_ASSET_DECOMPRESS_FILE) {
|
|
outputBinary = compression.decompressBuffer(inputBinary);
|
|
}
|
|
compression.writeBinaryFile(outputBinary, outputFilename);
|
|
}
|
|
} else {
|
|
display_error_and_abort("Could not read file: ", inputFilename);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|