diff options
author | AECX <aecx@aecx.cc> | 2019-11-17 03:16:51 +0100 |
---|---|---|
committer | AECX <aecx@aecx.cc> | 2019-11-17 03:16:51 +0100 |
commit | bf3ac2c2c5d31bf06fde6ee8698300c1211c13e2 (patch) | |
tree | 8269d6a268d98e541162dc5ab753302a4038a6c6 | |
parent | 07b4cfc5e28e49db609975329b49147462d90392 (diff) |
3.2
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | include/Twilight Editor.h | 16 | ||||
-rw-r--r-- | include/converter.h | 14 | ||||
-rw-r--r-- | include/settings.h | 3 | ||||
-rw-r--r-- | source/Twilight Editor.cpp | 344 | ||||
-rw-r--r-- | source/converter.cpp | 172 | ||||
-rw-r--r-- | source/settings.cpp | 2 |
8 files changed, 374 insertions, 180 deletions
@@ -1,5 +1,6 @@ .git/ .vs/ +out/ bin/ CMakeSettings.json diff --git a/CMakeLists.txt b/CMakeLists.txt index a4c7ebf..53f97ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ set (CMAKE_CXX_STANDARD 17) project (TwilightEditor) set (TE_VERSION_MAIN 3) -set (TE_VERSION_SUB 1) +set (TE_VERSION_SUB 2) configure_file ( "${projectDir}include/config.h.in" diff --git a/include/Twilight Editor.h b/include/Twilight Editor.h index aacc808..53be193 100644 --- a/include/Twilight Editor.h +++ b/include/Twilight Editor.h @@ -8,9 +8,6 @@ #include <iostream> #include <fstream> -#include <filesystem> - -namespace fs = std::filesystem; int main(int argc, char* argv[]); void fastPrint(const std::string& message, bool newline = true); @@ -24,12 +21,19 @@ namespace TwilightEditor extern FILE* currentFilePtr; extern FILE* outputFile; - extern std::size_t fileSize; - extern uint16_t questLogSize; + extern uint8_t* questLogData; + + extern uint8_t* inputFileBuf; + extern uint8_t* outputFileBuf; + + extern uintmax_t fileSize; + extern uint16_t questLogLength; extern uint32_t questLogReadOffset; void initFile(); + void saveFile(); void set(); - void getChecksums(); + void readChecksums(); + void setChecksums(); std::string get(); }
\ No newline at end of file diff --git a/include/converter.h b/include/converter.h index a380b5b..15f07d0 100644 --- a/include/converter.h +++ b/include/converter.h @@ -5,6 +5,7 @@ #include <iostream> #include <cstdint> #include <sstream> +#include <iomanip> namespace TwilightEditor { @@ -14,11 +15,20 @@ namespace TwilightEditor uint16_t u16(std::string& value); uint8_t u8(std::string& value); + int32_t s32(std::string& value); + int16_t s16(std::string& value); + int8_t s8(std::string& value); + uint32_t bigEndian(uint32_t value); uint16_t bigEndian(uint16_t value); - void flag(uint8_t* value, std::string& flag, bool set = true); + int32_t bigEndian(int32_t value); + int16_t bigEndian(int16_t value); + + // Sets or unsets a flag in value + void flag(uint8_t* value, std::string& flag_value, bool set = true); - std::string toStr(uint8_t* data, offsetType type, std::size_t length, uint8_t flag = 0); + // Reads big endian data and returns its string equivalent depending on type and length + std::string toStr(uint8_t* data, offsetType type, std::size_t length, bool hex = false, uint8_t flag = 0); } }
\ No newline at end of file diff --git a/include/settings.h b/include/settings.h index 5ce0e2e..2c15ba5 100644 --- a/include/settings.h +++ b/include/settings.h @@ -13,7 +13,8 @@ namespace TwilightEditor enum offsetType { - TPINT, + TPUINT, + TPSINT, TPFLAG, TPUFLAG, TPSTRING diff --git a/source/Twilight Editor.cpp b/source/Twilight Editor.cpp index 68dc3a1..4baccb5 100644 --- a/source/Twilight Editor.cpp +++ b/source/Twilight Editor.cpp @@ -13,7 +13,6 @@ int main(int argc, char* argv[]) std::cout << "Output File: " << TwilightEditor::Settings.OUTPUT_FILE << std::endl; std::cout << "Mode: " << TwilightEditor::Settings.MODE << std::endl; std::cout << "QuestLog: " << TwilightEditor::Settings.QUESTLOG << std::endl; - std::cout << "Fix checksum: " << TwilightEditor::Settings.FIX << std::endl; std::cout << "Offset: " << TwilightEditor::Settings.OFFSET << std::endl; @@ -25,31 +24,36 @@ int main(int argc, char* argv[]) std::cout << "Force: " << TwilightEditor::Settings.FORCE << std::endl; } + /* + TwilightEditor::Settings.INPUT_FILE = "ql.tp"; + TwilightEditor::Settings.OUTPUT_FILE = "new.tp"; + TwilightEditor::Settings.FORCE = true; + TwilightEditor::Settings.LENGTH = 4; + TwilightEditor::Settings.OFFSET = 0x0A; + TwilightEditor::Settings.TYPE = TwilightEditor::offsetType::TPUINT;*/ + fastPrint("initializing file..."); TwilightEditor::initFile(); - TwilightEditor::getChecksums(); - return 0; - + TwilightEditor::readChecksums(); + switch (TwilightEditor::Settings.MODE) { case TwilightEditor::mode::GET: fastPrint("> GET"); - std::cout << TwilightEditor::get() << std::endl; + std::cout << "== BEGIN RESULT ==" << std::endl << TwilightEditor::get() << std::endl << "== END RESULT == "<< std::endl; break; case TwilightEditor::mode::SET: fastPrint("> SET"); - TwilightEditor::set(); + TwilightEditor::setChecksums(); + TwilightEditor::saveFile(); break; } - fastPrint("Closing file(s)..."); - fclose(TwilightEditor::currentFilePtr); - fclose(TwilightEditor::outputFile); return 0; } @@ -74,13 +78,12 @@ cxxopts::ParseResult parse(int argc, char* argv[]) ("m,mode", " (string) <GET> or <SET>", cxxopts::value<std::string>()->default_value("GET"), "<GET|SET>") ("o,output", " (string) If empty: Override input file", cxxopts::value<std::string>(), "<path/to/file>") ("q,questlog", " (int) QuestLog Index (0 based)", cxxopts::value<std::uint16_t>()->default_value("0"), "<n>") - ("fix", " (bool) Correct checksum?", cxxopts::value<bool>()->default_value("false")) ("hex", " (bool) Output in Hexadecimal format?", cxxopts::value<bool>()->default_value("false")); options.add_options("Offset") ("offset", "*(hex/dec) QuestLog offset", cxxopts::value<uint16_t>(), "<0x000>") ("length", "*(hex/dec) Length", cxxopts::value<uint16_t>(), "<0x00>") - ("type", "*(string) Value type/interpretation", cxxopts::value<std::string>(), "<int|flg|uflg|str>") + ("type", "*(string) Value type/interpretation", cxxopts::value<std::string>(), "<uint|sint|flg|uflg|str>") ("value", "(string) The value you want to apply", cxxopts::value<std::string>()->default_value("0"), "<\"Link\">"); options.add_options("Additional") @@ -90,12 +93,14 @@ cxxopts::ParseResult parse(int argc, char* argv[]) auto result = options.parse(argc, argv); + // -h, --help if (result.count("help")) { std::cout << options.help({ "General", "Offset", "Additional" }) << std::endl; exit(0); } - + + // -v, --version if (result.count("version")) { std::cout << "Twilight Editor (" << OS_STRING << ") v" << TE_VERSION_MAIN << "." << TE_VERSION_SUB << " (C) AECX 2019" << std::endl; @@ -136,8 +141,6 @@ cxxopts::ParseResult parse(int argc, char* argv[]) TwilightEditor::Settings.HEX = result["hex"].as<bool>(); } - TwilightEditor::Settings.FIX = result["fix"].as<bool>(); - if (result.count("offset")) { TwilightEditor::Settings.OFFSET = result["offset"].as<uint16_t>(); @@ -159,10 +162,10 @@ cxxopts::ParseResult parse(int argc, char* argv[]) // --type if (result.count("type")) { - TwilightEditor::Settings.TYPE = (result["type"].as<std::string>() == "int" ? TwilightEditor::offsetType::TPINT : result["type"].as<std::string>() == "flg" ? TwilightEditor::offsetType::TPFLAG : result["type"].as<std::string>() == "uflg" ? TwilightEditor::offsetType::TPUFLAG : TwilightEditor::offsetType::TPSTRING); + TwilightEditor::Settings.TYPE = (result["type"].as<std::string>() == "uint" ? TwilightEditor::offsetType::TPUINT : result["type"].as<std::string>() == "sint" ? TwilightEditor::offsetType::TPSINT : result["type"].as<std::string>() == "flg" ? TwilightEditor::offsetType::TPFLAG : result["type"].as<std::string>() == "uflg" ? TwilightEditor::offsetType::TPUFLAG : TwilightEditor::offsetType::TPSTRING); if (TwilightEditor::Settings.TYPE == TwilightEditor::offsetType::TPFLAG || TwilightEditor::Settings.TYPE == TwilightEditor::offsetType::TPUFLAG) { - fastPrint("Changed size to 1 since you're supplying a flag!"); + fastPrint("Forced size to 1 since you're supplying a flag!"); TwilightEditor::Settings.LENGTH = 1; } } @@ -173,7 +176,7 @@ cxxopts::ParseResult parse(int argc, char* argv[]) TwilightEditor::Settings.STR_VALUE = result["value"].as<std::string>(); } - // -v, --verbose + // --verbose TwilightEditor::Settings.VERBOSE = result["verbose"].as<bool>(); // -f, --force @@ -183,42 +186,35 @@ cxxopts::ParseResult parse(int argc, char* argv[]) } catch (const cxxopts::OptionException& e) { - std::cout << "error parsing options: " << e.what() << std::endl << "Maybe try --help" << std::endl; + std::cerr << "error parsing options: " << e.what() << std::endl << "Maybe try --help" << std::endl; exit(1); } } namespace TwilightEditor { - uint32_t checksum = 0; - uint32_t nchecksum = 0; - FILE* currentFilePtr = nullptr; - FILE* outputFile = nullptr; - std::size_t fileSize = 0; - uint16_t questLogSize = 0; + // QL Data including checksums + uint8_t* questLogData = nullptr; + + uint8_t* inputFileBuf = nullptr; + uint8_t* outputFileBuf = nullptr; + + uintmax_t fileSize = 0; + uint16_t questLogLength = 0; uint32_t questLogReadOffset = 0; std::string get() { try { - if ((Settings.OFFSET + questLogReadOffset) + Settings.LENGTH > fileSize) - { - throw std::runtime_error("offset + length exceeds the filesize"); - } - - if (Settings.OFFSET + Settings.LENGTH > questLogSize) + if ((Settings.OFFSET + Settings.LENGTH) > questLogLength) { - throw std::runtime_error("offset + length exceeds the QuestLog size"); + throw std::runtime_error("Read offset + length exceed the QuestLog"); } - uint8_t* buffer = new uint8_t[Settings.LENGTH]; - fseek(currentFilePtr, questLogReadOffset + Settings.OFFSET, SEEK_SET); - fread(buffer, sizeof(uint8_t), Settings.LENGTH, currentFilePtr); - - return TwilightEditor::Converter::toStr(buffer, Settings.TYPE, Settings.LENGTH, Converter::u8(Settings.STR_VALUE)); + return Converter::toStr(&questLogData[Settings.OFFSET], Settings.TYPE, Settings.LENGTH, Settings.HEX, Converter::u8(Settings.STR_VALUE)); } catch (const std::runtime_error& ex) { @@ -236,93 +232,75 @@ namespace TwilightEditor { try { - // write --value to --offset[--length] - // Save into --output - - // Templates - uint16_t t16 = 0; - uint32_t t32 = 0; + if ((Settings.OFFSET + Settings.LENGTH) > questLogLength) + { + throw std::runtime_error("Read offset + length exceed the QuestLog"); + } - // buffer for str - char* data = new char[Settings.LENGTH]; - memset(data, 0, Settings.LENGTH); + // Pointer to where we want to write the Settings.VALUE + void* target = &questLogData[Settings.OFFSET]; - // buffer for single char - unsigned* buffer = new unsigned[1]; + // Written data counter + int i = Settings.LENGTH; - std::size_t i = 0; - for (i; i < fileSize; i++) + switch (Settings.TYPE) { - // Loop through entire file - if (i == Settings.OFFSET) - { - // Modify this part - - // TODO convert --value to big endian and write it - if (Settings.TYPE == offsetType::TPINT) - { - switch (Settings.LENGTH) - { - case 1: - // Big endian == little endian, no conversion - buffer[0] = Converter::u8(Settings.STR_VALUE); - - fwrite(buffer, sizeof(uint8_t), 1, outputFile); - break; - - case 2: - t16 = Converter::bigEndian(Converter::u16(Settings.STR_VALUE)); - - fwrite(&t16, sizeof(uint16_t), 1, outputFile); - break; - - case 4: - t32 = Converter::bigEndian(Converter::u32(Settings.STR_VALUE)); - - fwrite(&t32, sizeof(uint32_t), 1, outputFile); - break; - - default: - throw std::runtime_error("invalid length supplied for type int"); - break; - } - } // Integer - - else if (Settings.TYPE == offsetType::TPFLAG || Settings.TYPE == offsetType::TPUFLAG) + case offsetType::TPUINT: + switch (Settings.LENGTH) { - unsigned flag = Converter::u8(Settings.STR_VALUE); - if (Settings.TYPE == offsetType::TPFLAG) - { - // Set the flag - buffer[0] = fgetc(currentFilePtr) | flag; - } - else - { - // Unset the flag - buffer[0] = (fgetc(currentFilePtr) & ~flag); - } - - fwrite(buffer, sizeof(char), 1, outputFile); - } // Flag + case 4: + *reinterpret_cast<uint32_t*>(target) = Converter::bigEndian(Converter::u32(Settings.STR_VALUE)); + break; - else + case 2: + *reinterpret_cast<uint16_t*>(target) = Converter::bigEndian(Converter::u16(Settings.STR_VALUE)); + break; + + default: + *reinterpret_cast<uint8_t*>(target) = Converter::u8(Settings.STR_VALUE); + break; + } + // Set uInt + break; + + case offsetType::TPSINT: + switch (Settings.LENGTH) { - std::strncpy(data, Settings.STR_VALUE.c_str(), Settings.LENGTH); - - fwrite(data, sizeof(char), Settings.LENGTH, outputFile); - } // String/Data - - // Continue after the offset + length - i += (Settings.LENGTH - 1); // - 1 because at the end of the loop it's ++ agian - fseek(currentFilePtr, Settings.LENGTH, SEEK_CUR); - } - else - { - // Write next byte to input file - buffer[0] = fgetc(currentFilePtr); - fwrite(reinterpret_cast<void*>(buffer), sizeof(char), 1, outputFile); - } + case 4: + *reinterpret_cast<int32_t*>(target) = Converter::bigEndian(Converter::s32(Settings.STR_VALUE)); + break; + + case 2: + *reinterpret_cast<int16_t*>(target) = Converter::bigEndian(Converter::s16(Settings.STR_VALUE)); + break; + + default: + *reinterpret_cast<int8_t*>(target) = Converter::s8(Settings.STR_VALUE); + break; + } + // Set sInt + break; + + case offsetType::TPFLAG: + Converter::flag(reinterpret_cast<uint8_t*>(target), Settings.STR_VALUE, true); + // Set flag + break; + + case offsetType::TPUFLAG: + Converter::flag(reinterpret_cast<uint8_t*>(target), Settings.STR_VALUE, false); + // Unset flag + break; + + case offsetType::TPSTRING: + // Fill 0 + memset(target, 0x0, Settings.LENGTH); + strncpy(reinterpret_cast<char*>(target), Settings.STR_VALUE.c_str(), Settings.LENGTH); + + // Write string + break; } + + std::cout << "Total bytes written: " << i << std::endl; } catch (const std::runtime_error& ex) { @@ -340,39 +318,25 @@ namespace TwilightEditor { try { - if (!fs::exists(Settings.INPUT_FILE)) - { - throw std::runtime_error("input file does not exist"); - } - - if (Settings.INPUT_FILE == Settings.OUTPUT_FILE) - { - throw std::runtime_error("currently unsupported. Please enter an output file"); - } - - fs::path filePath{ Settings.INPUT_FILE }; - currentFilePtr = fopen(Settings.INPUT_FILE.c_str(), "rb"); - outputFile = fopen(Settings.OUTPUT_FILE.c_str(), "wb"); if (currentFilePtr == NULL) { throw std::runtime_error("couldn't open input file for read"); } - if (outputFile == NULL) - { - throw std::runtime_error("couldn't open output file for write"); - } + fseek(currentFilePtr, 0, SEEK_END); + fileSize = ftell(currentFilePtr); + + // Back to 0 now that we know the length + fseek(currentFilePtr, 0, SEEK_SET); - fileSize = static_cast<std::size_t>(fs::file_size(filePath)); - switch (fileSize) { case 0x8040: // GCI/Container - fastPrint("Operating in GCI mode"); - questLogSize = 0xA94; + fastPrint("Operating in GCI mode (0xA94)"); + questLogLength = 0xA94; switch (Settings.QUESTLOG) { case 2: @@ -383,34 +347,49 @@ namespace TwilightEditor questLogReadOffset = 0x4ADC; break; - default: + case 0: questLogReadOffset = 0x4048; break; + + default: + throw std::runtime_error("invalid Quest Log index"); + break; } break; case 0xE00: // WiiU/QuestLog - fastPrint("Operating in Wii U mode"); - questLogSize = 0xE00; + fastPrint("Operating in Wii U mode (0xE00)"); + questLogLength = 0xE00; questLogReadOffset = 0; break; default: if (!Settings.FORCE) { - std::cout << "File could not be identified, do you want to treat it as a single QuestLog? (y/n)" << std::endl << "Is this a Questlog? "; - int result = getchar(); - if (result != 'Y' && result != 'y') - { - std::cout << "Exiting application..." << std::endl; - exit(1); - } - questLogSize = static_cast<uint16_t>(fileSize); + throw std::runtime_error("File could not be identified as a valid TP save. Use -f,--force to treat it as a QuestLog"); + } + else + { + fastPrint("Operating in QuestLog mode (QL = FileSize)"); + questLogLength = fileSize; questLogReadOffset = 0; } break; } + + // Set filebuffers + inputFileBuf = new uint8_t[fileSize]; + outputFileBuf = new uint8_t[fileSize]; + + + fread(inputFileBuf, sizeof(uint8_t), fileSize, currentFilePtr); + fclose(currentFilePtr); + + memcpy(outputFileBuf, inputFileBuf, fileSize); + + // Directly edit the output file + questLogData = &outputFileBuf[questLogReadOffset]; } catch (const std::runtime_error& ex) { @@ -424,26 +403,75 @@ namespace TwilightEditor } } - void getChecksums() + void saveFile() { try { - uint16_t questLogDataLength = questLogSize - 8; + currentFilePtr = fopen(Settings.OUTPUT_FILE.c_str(), "wb"); - uint8_t* questLogData = new uint8_t[questLogDataLength]; + if (currentFilePtr == NULL) + { + throw std::runtime_error("couldn't open input file for write"); + } - printf("read: %x\n", questLogReadOffset); - printf("len: %x\n", questLogDataLength); + fseek(currentFilePtr, 0, SEEK_SET); + + // Questlogdata is a pointer to outputfilebuf so it should already be contained in here + fwrite(outputFileBuf, sizeof(uint8_t), fileSize, currentFilePtr); - // Set read position to current questlog - fseek(currentFilePtr, questLogReadOffset, SEEK_SET); + fclose(currentFilePtr); + + std::cout << "Contents written to: '" << Settings.OUTPUT_FILE << "'" << std::endl; + } + catch (const std::runtime_error &ex) + { + std::cerr << "error saving file " << Settings.OUTPUT_FILE << ": " << ex.what() << std::endl; + exit(1); + } + catch (...) + { + std::cerr << "unknown error saving file " << Settings.OUTPUT_FILE << std::endl; + exit(1); + } + } + + // Reads current active checksums (no calculation) + void readChecksums() + { + try + { + std::cout << "Reading checksums:" << std::endl; + std::cout << "+Checksum: " << Converter::toStr(&questLogData[questLogLength - 8], TwilightEditor::offsetType::TPSINT, 4, true) << std::endl; + std::cout << "-Checksum: " << Converter::toStr(&questLogData[questLogLength - 4], TwilightEditor::offsetType::TPSINT, 4, true) << std::endl; + } + catch (const std::runtime_error & ex) + { + std::cerr << "error reading checksums " << Settings.INPUT_FILE << " QuestLog: " << Settings.QUESTLOG << ": " << ex.what() << std::endl; + exit(1); + } + catch (...) + { + std::cerr << "unknown error while reading checksums " << Settings.INPUT_FILE << " QuestLog: " << Settings.QUESTLOG << std::endl; + exit(1); + } + } + + void setChecksums() + { + try + { + uint32_t* csum = reinterpret_cast<uint32_t*>(&questLogData[questLogLength - 8]); + uint32_t* nsum = reinterpret_cast<uint32_t*>(&questLogData[questLogLength - 4]); - // Read the entire questlog (- checksums) - fread(questLogData, sizeof(uint8_t), questLogDataLength, currentFilePtr); + checkSum(questLogData, questLogLength - 8, csum, nsum); - checkSum(questLogData, questLogDataLength, &checksum, &nchecksum); + // Update endianess + *csum = Converter::bigEndian(*csum); + *nsum = Converter::bigEndian(*nsum); - printf("Calculated: %08x %08x\n", checksum, nchecksum); + std::cout << "New checksums:" << std::endl; + std::cout << "+Checksum: " << Converter::toStr(&questLogData[questLogLength - 8], TwilightEditor::offsetType::TPSINT, 4, true) << std::endl; + std::cout << "-Checksum: " << Converter::toStr(&questLogData[questLogLength - 4], TwilightEditor::offsetType::TPSINT, 4, true) << std::endl; } catch (...) { diff --git a/source/converter.cpp b/source/converter.cpp index 0e47598..66fe8da 100644 --- a/source/converter.cpp +++ b/source/converter.cpp @@ -4,6 +4,7 @@ namespace TwilightEditor { namespace Converter { + // String to u32 uint32_t u32(std::string& value) { try @@ -27,6 +28,7 @@ namespace TwilightEditor } } + // String to u16 uint16_t u16(std::string& value) { try @@ -50,6 +52,7 @@ namespace TwilightEditor } } + // String to u8 uint8_t u8(std::string& value) { try @@ -73,6 +76,81 @@ namespace TwilightEditor } } + + // String to s32 + int32_t s32(std::string & value) + { + try + { + return static_cast<int32_t>(std::stol(value, nullptr, 0)); + } + catch (const std::invalid_argument & ia) + { + std::cerr << "error: " << ia.what() << std::endl; + exit(1); + } + catch (const std::out_of_range & oor) + { + std::cerr << "error: " << oor.what() << std::endl; + exit(1); + } + catch (...) + { + std::cerr << "unknown error while parsing s32" << value << std::endl; + exit(1); + } + } + + // String to s16 + int16_t s16(std::string& value) + { + try + { + return static_cast<uint16_t>(std::stol(value, nullptr, 0)); + } + catch (const std::invalid_argument & ia) + { + std::cerr << "error: " << ia.what() << std::endl; + exit(1); + } + catch (const std::out_of_range & oor) + { + std::cerr << "error: " << oor.what() << std::endl; + exit(1); + } + catch (...) + { + std::cerr << "unknown error while parsing s16" << value << std::endl; + exit(1); + } + } + + // String to s8 + int8_t s8(std::string& value) + { + try + { + return static_cast<int8_t>(std::stol(value, nullptr, 0)); + } + catch (const std::invalid_argument & ia) + { + std::cerr << "error: " << ia.what() << std::endl; + exit(1); + } + catch (const std::out_of_range & oor) + { + std::cerr << "error: " << oor.what() << std::endl; + exit(1); + } + catch (...) + { + std::cerr << "unknown error while parsing s8" << value << std::endl; + exit(1); + } + } + + + // byteswap uint32_t bigEndian(uint32_t value) { try @@ -86,6 +164,7 @@ namespace TwilightEditor } } + // byteswap uint16_t bigEndian(uint16_t value) { try @@ -99,11 +178,40 @@ namespace TwilightEditor } } - void flag(uint8_t* value, std::string& flag, bool set) + // byteswap + int32_t bigEndian(int32_t value) + { + try + { + return ((value & 0xFF000000) >> 24 | (value & 0x000000FF) << 24 | (value & 0x00FF0000) >> 8 | (value & 0x0000FF00) << 8); + } + catch (...) + { + std::cerr << "unknown error while converting little s32 to big s32" << value << std::endl; + exit(1); + } + } + + // byteswap + int16_t bigEndian(int16_t value) + { + try + { + return ((value & 0x00FF) << 8 | (value & 0xFF00) >> 8); + } + catch (...) + { + std::cerr << "unknown error while converting little s16 to big s16" << value << std::endl; + exit(1); + } + } + + // String to gc8 + void flag(uint8_t* value, std::string& flag_value, bool set) { try { - uint8_t _flag = u8(flag); + uint8_t _flag = u8(flag_value); if (set) { @@ -123,7 +231,8 @@ namespace TwilightEditor } } - std::string toStr(uint8_t* data, offsetType type, std::size_t length, uint8_t flag) + // GC data to String + std::string toStr(uint8_t* data, offsetType type, std::size_t length, bool hex, uint8_t flag_value) { try { @@ -138,13 +247,13 @@ namespace TwilightEditor uint32_t t32 = 0; - if (type == offsetType::TPINT) + if (type == offsetType::TPUINT) { switch (length) { case 1: value = std::to_string(data[0]); - if (Settings.HEX) + if (hex) { ss << std::hex << static_cast<unsigned>(data[0]); value = ss.str(); @@ -154,7 +263,7 @@ namespace TwilightEditor case 2: t16 = (data[1]| data[0] << 8); value = std::to_string(t16); - if (Settings.HEX) + if (hex) { ss << std::hex << t16; value = ss.str(); @@ -164,7 +273,7 @@ namespace TwilightEditor case 4: t32 = (data[3] | data[2] << 8 | data[1] << 16 | data[0] << 24); value = std::to_string(t32); - if (Settings.HEX) + if (hex) { ss << std::hex << t32; value = ss.str(); @@ -177,18 +286,59 @@ namespace TwilightEditor } } - else if (type == offsetType::TPFLAG || type == offsetType::TPUFLAG) + else if (type == offsetType::TPSINT) { - flagstate = (flag == (data[0] & flag)); + switch (length) + { + case 1: + value = std::to_string(*reinterpret_cast<int8_t*>(data[0])); + if (hex) + { + ss << std::hex << *reinterpret_cast<int8_t*>(data[0]); + value = ss.str(); + } + break; - value = flagstate ? "true" : "false"; + case 2: + t16 = (data[1] | data[0] << 8); + value = std::to_string(*reinterpret_cast<int16_t*>(&t16)); + if (hex) + { + ss << std::hex << *reinterpret_cast<int16_t*>(&t16); + value = ss.str(); + } + break; + + case 4: + t32 = (data[3] | data[2] << 8 | data[1] << 16 | data[0] << 24); + value = std::to_string(*reinterpret_cast<int32_t*>(&t32)); + if (hex) + { + ss << std::hex << *reinterpret_cast<int32_t*>(&t32); + value = ss.str(); + } + break; + + default: + throw std::runtime_error("invalid length supplied for type int"); + break; + } + } + + else if (type == offsetType::TPFLAG || type == offsetType::TPUFLAG) + { + value = (flag_value == (data[0] & flag_value)) ? "true" : "false"; + if (hex) + { + value = (flag_value == (data[0] & flag_value)) ? "1" : "0"; + } } else { for (int i = 0; i < length; i++) { - if (Settings.HEX) + if (hex) { // Not really optimized but functional ss << std::hex << static_cast<unsigned>(data[i]) << " "; diff --git a/source/settings.cpp b/source/settings.cpp index a54fc1c..d458cf2 100644 --- a/source/settings.cpp +++ b/source/settings.cpp @@ -2,5 +2,5 @@ namespace TwilightEditor { - settings Settings = { "", "", GET, 0, false, false, 0, 0, TPINT, "0", false, false }; + settings Settings = { "", "", GET, 0, false, false, 0, 0, TPUINT, "0", false, false }; }
\ No newline at end of file |