From c7083ac77e2ffbbef24d1b32db741be198bc2092 Mon Sep 17 00:00:00 2001 From: tobid7 Date: Sat, 9 Mar 2024 13:16:30 +0100 Subject: [PATCH] # CLEANUP # - Cleanup main.cpp - fix sample_code - Add CMakeLists.txt --- .gitignore | 1 + .vscode/settings.json | 80 +++++++++++++- CMakeLists.txt | 15 +++ source/main.cpp | 236 +++++++++++++++++++++++++---------------- source/samplefiles.cpp | 2 +- 5 files changed, 243 insertions(+), 91 deletions(-) create mode 100644 CMakeLists.txt diff --git a/.gitignore b/.gitignore index e257658..b8f0893 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ *.out *.app +build/ \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index ecc013c..1daa3c2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,84 @@ "files.associations": { "utility": "cpp", "ostream": "cpp", - "xstring": "cpp" + "xstring": "cpp", + "algorithm": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "cctype": "cpp", + "charconv": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "deque": "cpp", + "exception": "cpp", + "coroutine": "cpp", + "resumable": "cpp", + "filesystem": "cpp", + "format": "cpp", + "forward_list": "cpp", + "fstream": "cpp", + "functional": "cpp", + "future": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "iterator": "cpp", + "limits": "cpp", + "list": "cpp", + "locale": "cpp", + "map": "cpp", + "memory": "cpp", + "mutex": "cpp", + "new": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ranges": "cpp", + "ratio": "cpp", + "span": "cpp", + "sstream": "cpp", + "stack": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "string": "cpp", + "system_error": "cpp", + "thread": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "typeinfo": "cpp", + "unordered_map": "cpp", + "valarray": "cpp", + "vector": "cpp", + "xfacet": "cpp", + "xhash": "cpp", + "xiosbase": "cpp", + "xlocale": "cpp", + "xlocbuf": "cpp", + "xlocinfo": "cpp", + "xlocmes": "cpp", + "xlocmon": "cpp", + "xlocnum": "cpp", + "xloctime": "cpp", + "xmemory": "cpp", + "xstddef": "cpp", + "xtr1common": "cpp", + "xtree": "cpp", + "xutility": "cpp" } } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..fa37d30 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.18) + +project(npi-build) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED TRUE) + +add_executable(npi-build +source/main.cpp +source/banner_audio.cpp +source/banner.cpp +source/helper.cpp +source/icon.cpp +source/logo_lz11.cpp +source/samplefiles.cpp) +target_include_directories(npi-build PUBLIC include) \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index 319b15e..2bb5a24 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -12,49 +12,69 @@ #include #include +// Console CLear String #define cons_clear std::cout << "\x1B[2J\x1B[H" -void ToUpperCase(std::string &str) { +// Make String Uppercase +void ToUpperCase(std::string &str) +{ std::transform(str.begin(), str.end(), str.begin(), - [](unsigned char c) { return std::toupper(c); }); + [](unsigned char c) + { return std::toupper(c); }); } -bool isValidHex(const std::string &str) { - for (char c : str) { - if (!isxdigit(c)) { +// Check if String is Valid Hex String +bool isValidHex(const std::string &str) +{ + for (char c : str) + { + if (!isxdigit(c)) + { return false; } } return true; } -void CheckTools() { +// Check for tools +void CheckTools() +{ std::vector installed; std::vector not_installed; int res = 0; res = system("makerom"); - if (!res) { + if (!res) + { not_installed.push_back("makerom"); - } else { + } + else + { installed.push_back("makerom"); } res = system("bannertool"); - if (!res) { + if (!res) + { not_installed.push_back("bannertool"); - } else { + } + else + { installed.push_back("bannertool"); } std::cout << " is set to: " << getenv("DEVKITPRO") << "\n"; std::cout << "Tools-Check:\n"; - for (auto const &it : installed) { + for (auto const &it : installed) + { std::cout << "[+]" << it << " is installed!\n"; } - for (auto const &it : not_installed) { - std::cout << "[+]" << it << " is not installed!\n"; + for (auto const &it : not_installed) + { + std::cout << "[-]" << it << " is not installed!\n"; } } -void PrintHelp() { +// Print Usage/Help +void PrintHelp() +{ std::cout << "npi-build v0.1\n"; std::cout << "Commands:\n"; std::cout << "help: Display this\n"; @@ -68,49 +88,95 @@ void PrintHelp() { return; } -void ProcessArgs(int argc, char *argv[]) { - if (argc < 2) { +// Function to generate Directories and Default Files +void GenerateProjectDir(const std::string &dst_dir, int type_) +{ + // Create Directories + std::filesystem::create_directories( + std::filesystem::path(dst_dir + "/app")); + std::filesystem::create_directories( + std::filesystem::path(dst_dir + "/gfx")); + std::filesystem::create_directories( + std::filesystem::path(dst_dir + "/romfs/gfx")); + std::filesystem::create_directories(dst_dir + "/source"); + std::filesystem::create_directories(dst_dir + "/include"); + + // Create .gitkeep for empty dirs + std::ofstream gfx_keep(dst_dir + "/gfx/.gitkeep"); + gfx_keep.close(); + std::ofstream rgfx_keep(dst_dir + "/romfs/gfx/.gitkeep"); + rgfx_keep.close(); + std::ofstream sample_source(dst_dir + "/source/main.cpp"); + sample_source << sample_code; + sample_source.close(); + std::ofstream sample_hdr(dst_dir + "/include/common.hpp"); + sample_hdr << sample_header; + sample_hdr.close(); + if (type_ == 1) + { + helper::ArrayToFile(banner_audio, banner_audio_size, + dst_dir + "/app/banner_audio.wav"); + helper::ArrayToFile(logo_lz11, logo_lz11_size, + dst_dir + "/app/logo.lz11"); + helper::ArrayToFile(banner, banner_size, dst_dir + "/app/banner.png"); + } + // Create icon.png + helper::ArrayToFile(icon, icon_size, dst_dir + "/app/icon.png"); +} + +// Process Input Args +void ProcessArgs(int argc, char *argv[]) +{ + if (argc < 2) + { + // No Args PrintHelp(); return; - } else if (std::string(argv[1]) == "help") { + } + else if (std::string(argv[1]) == "help") + { + // Requested Help PrintHelp(); return; - } else if (std::string(argv[1]) == "generate") { - if (argc < 4) { + } + else if (std::string(argv[1]) == "generate") + { + // Generator + if (argc != 4) + { + // Missing Args / ot too much std::cout << "Wrong Number of Arguments!\n"; return; } + // read type std::string type = std::string(argv[2]); int res = 1; int type_ = -1; - if (type == "3dsx" | type == "cia3dsx") { + // TODO: + // change this if statement + if (type == "3dsx" | type == "cia3dsx") + { res = 0; if (type == "3dsx") type_ = 0; else if (type == "cia3dsx") type_ = 1; } - if (res) { + // Print Error if re is not 0 + if (res) + { std::cout << "Unknown type!\n"; return; } + // get destination std::string dst_dir = argv[3]; - std::cout << "\nDestination: " << dst_dir << "/\n"; - std::filesystem::create_directories( - std::filesystem::path(dst_dir + "/app")); - std::filesystem::create_directories( - std::filesystem::path(dst_dir + "/gfx")); - std::filesystem::create_directories(dst_dir + "/source"); - std::filesystem::create_directories(dst_dir + "/include"); - std::ofstream gfx_keep(dst_dir + "/gfx/.gitkeep"); - gfx_keep.close(); - std::filesystem::create_directories( - std::filesystem::path(dst_dir + "/romfs/gfx")); - std::ofstream rgfx_keep(dst_dir + "/romfs/gfx/.gitkeep"); - rgfx_keep.close(); - if (type_ == 1) { + // Generate Project + GenerateProjectDir(dst_dir, type_); + // Create rsf if cia mode + if (type_ == 1) + { char *ret = new char[10000]; std::string uid = helper::GenerateUniqueId(); sprintf(ret, ciaRSF, default_title, default_code, default_romfs_path, @@ -119,87 +185,87 @@ void ProcessArgs(int argc, char *argv[]) { test << ret; test.close(); delete[] ret; - std::ofstream sample_source(dst_dir + "/source/main.cpp"); - sample_source << sample_code; - sample_source.close(); - std::ofstream sample_hdr(dst_dir + "/include/common.hpp"); - sample_hdr << sample_header; - sample_hdr.close(); - helper::ArrayToFile(banner_audio, banner_audio_size, - dst_dir + "/app/banner_audio.wav"); - helper::ArrayToFile(logo_lz11, logo_lz11_size, - dst_dir + "/app/logo.lz11"); - helper::ArrayToFile(banner, banner_size, dst_dir + "/app/banner.png"); } - helper::ArrayToFile(icon, icon_size, dst_dir + "/app/icon.png"); + // Generate Default build.json NpiProject npr; Prj_InitDefault(npr); helper::GenerateTemplateFile(dst_dir + "/build.json", npr); - } else if (std::string(argv[1]) == "generate-assist") { + } + else if (std::string(argv[1]) == "generate-assist") + { + // Generate with Assistant // define vars std::string prj_name; std::string prodcode; std::string unique_id; - int type_; std::string dst_dir; + // Request Name std::cout << "Npi-Build Project-Assist:"; std::cout << "\ntype Project Name >"; std::cin >> prj_name; - std::cout << "\ntype Project Code 4 chars [NPI7] >"; + // Request Prod Code + std::cout << "\ntype Product Code 4 chars [NPI7] >"; std::cin >> prodcode; - if (prodcode.length() != 4) { + if (prodcode.length() != 4) + { + // Handle Wrong lengh Error std::cout << "\nWrong Length!\n"; return; } + // Make Sure its Uppercase ToUpperCase(prodcode); + // Output Prod Code and request unique_id std::cout << "Code set to [" << prodcode << "]"; std::cout << "\ntype project's unique id [ff3ff]\n or type random to " "generate a random one>"; std::cin >> unique_id; + // Check if random keyword was used bool rnd = false; - if (unique_id == "random") { + if (unique_id == "random") + { + // Generate random one unique_id = helper::GenerateUniqueId(); rnd = true; } - if (unique_id.length() != 5 && !rnd) { + if (unique_id.length() != 5 && !rnd) + { + // Handle wrong lengh std::cout << "\nWrong Length!\n"; return; } - if (!isValidHex(unique_id) && !rnd) { + if (!isValidHex(unique_id) && !rnd) + { + // Handle not hex digits std::cout << "\nId is not valid\n"; return; } - if (!rnd) { + if (!rnd) + { + // Add 0x if not random unique_id.insert(0, "0x"); } + // Request Project type std::cout << "\nProject type: type 0 for 3dsx\nonly or 1 for cia and 3dsx>"; std::cin >> type_; - if (!(type_ == 0 | type_ == 1)) { + if (!(type_ == 0 | type_ == 1)) + { std::cout << "\nunknown type!\n"; return; } + // Request Destination Directory std::cout << "\nProjects Directpry: type . for current>"; std::cin >> dst_dir; - std::cout << "\nDestination: " << dst_dir << "/\n"; - std::filesystem::create_directories( - std::filesystem::path(dst_dir + "/app")); - std::filesystem::create_directories( - std::filesystem::path(dst_dir + "/gfx")); - std::filesystem::create_directories(dst_dir + "/source"); - std::filesystem::create_directories(dst_dir + "/include"); - std::ofstream gfx_keep(dst_dir + "/gfx/.gitkeep"); - gfx_keep.close(); - std::filesystem::create_directories( - std::filesystem::path(dst_dir + "/romfs/gfx")); - std::ofstream rgfx_keep(dst_dir + "/romfs/gfx/.gitkeep"); - rgfx_keep.close(); + // Generate default dirs and files + GenerateProjectDir(dst_dir, type_); - if (type_ == 1) { + // Generate RSF if cia mode + if (type_ == 1) + { char *ret = new char[10000]; sprintf(ret, ciaRSF, prj_name.c_str(), prodcode.c_str(), default_romfs_path, unique_id.c_str()); @@ -207,45 +273,37 @@ void ProcessArgs(int argc, char *argv[]) { test << ret; test.close(); delete[] ret; - std::ofstream sample_source(dst_dir + "/source/main.cpp"); - sample_source << sample_code; - sample_source.close(); - std::ofstream sample_hdr(dst_dir + "/include/common.hpp"); - sample_hdr << sample_header; - sample_hdr.close(); - helper::ArrayToFile(banner_audio, banner_audio_size, - dst_dir + "/app/banner_audio.wav"); - helper::ArrayToFile(logo_lz11, logo_lz11_size, - dst_dir + "/app/logo.lz11"); - helper::ArrayToFile(banner, banner_size, dst_dir + "/app/banner.png"); } - helper::ArrayToFile(icon, icon_size, dst_dir + "/app/icon.png"); + // Create build.json NpiProject npr; Prj_InitDefault(npr); npr.name = prj_name; npr.prod = prodcode; npr.unique_id = unique_id; - helper::GenerateTemplateFile(dst_dir + "/build.json", npr); } - else if (std::string(argv[1]) == "build") { + else if (std::string(argv[1]) == "build") + { + // Run over build.json and build project helper::CompileProject(fix_path(std::filesystem::current_path().string())); } + // Check for makerom and bannertool else if (std::string(argv[1]) == "check-tools") CheckTools(); + // Cleanup else if (std::string(argv[1]) == "clean") helper::CleanProject(fix_path(std::filesystem::current_path().string())); } -int main(int argc, char *argv[]) { - //Lapi::Init(); - //Lapi::Exit(); - //return 0; - // std::cout << std::filesystem::current_path() << std::endl; +// Main Entrypoint +int main(int argc, char *argv[]) +{ + // Process Input ProcessArgs(argc, argv); + // Finished std::cout << "Exitting...\n"; return 0; } \ No newline at end of file diff --git a/source/samplefiles.cpp b/source/samplefiles.cpp index db6e461..97c8bc3 100644 --- a/source/samplefiles.cpp +++ b/source/samplefiles.cpp @@ -16,7 +16,7 @@ const char *sample_code = " gfxInitDefault();\n" " consoleInit(GFX_TOP, NULL);\n" " printf(\"Hello World!\\n\");\n" - " printf(\"Press START to exit!\\n\")" + " printf(\"Press START to exit!\\n\");\n" " while(aptMainLoop()) {\n" " hidScanInput();\n" " if(hidKeysDown() & KEY_START) break;\n"