npi-build/source/main.cpp
2023-11-24 14:42:57 +01:00

232 lines
6.9 KiB
C++

#include <algorithm>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <vector>
#include <banner.hpp>
#include <banner_audio.hpp>
#include <helper.hpp>
#include <icon.hpp>
#include <logo_lz11.hpp>
#include <samplefiles.hpp>
#include <fileHash.hpp>
#define cons_clear std::cout << "\x1B[2J\x1B[H"
void ToUpperCase(std::string &str) {
std::transform(str.begin(), str.end(), str.begin(),
[](unsigned char c) { return std::toupper(c); });
}
bool isValidHex(const std::string &str) {
for (char c : str) {
if (!isxdigit(c)) {
return false;
}
}
return true;
}
void CheckTools() {
std::vector<std::string> installed;
std::vector<std::string> not_installed;
int res = 0;
res = system("makerom");
if (!res) {
not_installed.push_back("makerom");
} else {
installed.push_back("makerom");
}
res = system("bannertool");
if (!res) {
not_installed.push_back("bannertool");
} else {
installed.push_back("bannertool");
}
std::cout << "<DEVKITPRO> is set to: " << getenv("DEVKITPRO") << "\n";
std::cout << "Tools-Check:\n";
for (auto const &it : installed) {
std::cout << "[+]" << it << " is installed!\n";
}
for (auto const &it : not_installed) {
std::cout << "[+]" << it << " is not installed!\n";
}
}
void PrintHelp() {
std::cout << "npi-build v0.1\n";
std::cout << "Commands:\n";
std::cout << "help: Display this\n";
std::cout << "generate <type> <dir>: Create Project Files!\n";
std::cout << " type: 3dsx | cia3dsx\n";
std::cout << "generate-assist: Create Project Files with assistent!\n";
std::cout << "build: Build the Project!\n";
std::cout << "clean: Delete all files from build.\n";
std::cout << "edit-assist: Edit Project files with assist!\n";
std::cout << "check-tools: Check for Missing Tools!\n";
return;
}
void ProcessArgs(int argc, char *argv[]) {
if (argc < 2) {
PrintHelp();
return;
} else if (std::string(argv[1]) == "help") {
PrintHelp();
return;
} else if (std::string(argv[1]) == "generate") {
if (argc < 4) {
std::cout << "Wrong Number of Arguments!\n";
return;
}
std::string type = std::string(argv[2]);
int res = 1;
int type_ = -1;
if (type == "3dsx" | type == "cia3dsx") {
res = 0;
if (type == "3dsx")
type_ = 0;
else if (type == "cia3dsx")
type_ = 1;
}
if (res) {
std::cout << "Unknown type!\n";
return;
}
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::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) {
char *ret = new char[10000];
std::string uid = helper::GenerateUniqueId();
sprintf(ret, ciaRSF, default_title, default_code, default_romfs_path,
uid.c_str());
std::ofstream test(dst_dir + "/app/build-cia.rsf");
test << ret;
test.close();
delete[] ret;
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");
NpiProject npr;
Prj_InitDefault(npr);
helper::GenerateTemplateFile(dst_dir + "/build.json", npr);
} else if (std::string(argv[1]) == "generate-assist") {
// define vars
std::string prj_name;
std::string prodcode;
std::string unique_id;
int type_;
std::string dst_dir;
std::cout << "Npi-Build Project-Assist:";
std::cout << "\ntype Project Name >";
std::cin >> prj_name;
std::cout << "\ntype Project Code 4 chars [NPI7] >";
std::cin >> prodcode;
if (prodcode.length() != 4) {
std::cout << "\nWrong Length!\n";
return;
}
ToUpperCase(prodcode);
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;
bool rnd = false;
if (unique_id == "random") {
unique_id = helper::GenerateUniqueId();
rnd = true;
}
if (unique_id.length() != 5 && !rnd) {
std::cout << "\nWrong Length!\n";
return;
}
if (!isValidHex(unique_id) && !rnd) {
std::cout << "\nId is not valid\n";
return;
}
if (!rnd) {
unique_id.insert(0, "0x");
}
std::cout << "\nProject type: type 0 for 3dsx\nonly or 1 for cia and 3dsx>";
std::cin >> type_;
if (!(type_ == 0 | type_ == 1)) {
std::cout << "\nunknown type!\n";
return;
}
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::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) {
char *ret = new char[10000];
sprintf(ret, ciaRSF, prj_name.c_str(), prodcode.c_str(),
default_romfs_path, unique_id.c_str());
std::ofstream test(dst_dir + "/app/build-cia.rsf");
test << ret;
test.close();
delete[] ret;
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");
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") {
helper::CompileProject(fix_path(std::filesystem::current_path().string()));
}
else if (std::string(argv[1]) == "check-tools")
CheckTools();
else if (std::string(argv[1]) == "clean")
helper::CleanProject(fix_path(std::filesystem::current_path().string()));
}
int main(int argc, char *argv[]) {
// std::cout << std::filesystem::current_path() << std::endl;
ProcessArgs(argc, argv);
std::cout << "Exitting...\n";
return 0;
}