summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLywx <kiritodev01@gmail.com>2025-01-15 19:43:08 -0600
committerGitHub <noreply@github.com>2025-01-15 19:43:08 -0600
commitbeee77da2a199c73fef60f83cde8e2937fb67f2e (patch)
tree90bdf7a5abc4da4d952cb4f910ba1cabc8b19c5e /src
parent5aac47e2fafb99678fc21e7839ec0e9cc7d65f70 (diff)
parent66db2a93282908d18abeba8b10b3c911e6b53210 (diff)
Merge pull request #131 from HarbourMasters/otr-ig-gen
Reimplemented built-in generation
Diffstat (limited to 'src')
-rw-r--r--src/port/Engine.cpp85
-rw-r--r--src/port/Engine.h12
-rw-r--r--src/port/extractor/GameExtractor.cpp58
-rw-r--r--src/port/extractor/GameExtractor.h17
-rw-r--r--src/port/ui/UIWidgets.cpp7
5 files changed, 163 insertions, 16 deletions
diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp
index 9d577583..3cfa5086 100644
--- a/src/port/Engine.cpp
+++ b/src/port/Engine.cpp
@@ -2,6 +2,7 @@
#include "ui/ImguiUI.h"
#include "StringHelper.h"
+#include "extractor/GameExtractor.h"
#include "libultraship/src/Context.h"
#include "resource/type/ResourceType.h"
#include "resource/importers/AnimFactory.h"
@@ -40,14 +41,12 @@
#include "port/mods/PortEnhancements.h"
#include <Fast3D/gfx_pc.h>
-#include <SDL2/SDL.h>
#include <filesystem>
namespace fs = std::filesystem;
extern "C" {
bool prevAltAssets = false;
-float gInterpolationStep = 0.0f;
#include <sf64thread.h>
#include <macros.h>
#include "sf64audio_provisional.h"
@@ -59,14 +58,32 @@ static GamePool MemoryPool = { .chunk = 1024 * 512, .cursor = 0, .length = 0, .m
GameEngine::GameEngine() {
std::vector<std::string> archiveFiles;
- if (const std::string cube_path = Ship::Context::GetPathRelativeToAppDirectory("starship.o2r");
- std::filesystem::exists(cube_path)) {
- archiveFiles.push_back(cube_path);
+ const std::string main_path = Ship::Context::GetPathRelativeToAppDirectory("sf64.o2r");
+ const std::string assets_path = Ship::Context::GetPathRelativeToAppDirectory("starship.o2r");
+
+#ifdef _WIN32
+ AllocConsole();
+#endif
+
+ if (std::filesystem::exists(main_path)) {
+ archiveFiles.push_back(main_path);
+ } else {
+ if (ShowYesNoBox("No O2R Files", "No O2R files found. Generate one now?") == IDYES) {
+ if(!GenAssetFile()){
+ ShowMessage("Error", "An error occured, no O2R file was generated.\n\nExiting...");
+ exit(1);
+ } else {
+ archiveFiles.push_back(main_path);
+ }
+ } else {
+ exit(1);
+ }
}
- if (const std::string sm64_otr_path = Ship::Context::GetPathRelativeToAppDirectory("sf64.o2r");
- std::filesystem::exists(sm64_otr_path)) {
- archiveFiles.push_back(sm64_otr_path);
+
+ if (std::filesystem::exists(assets_path)) {
+ archiveFiles.push_back(assets_path);
}
+
if (const std::string patches_path = Ship::Context::GetPathRelativeToAppDirectory("mods");
!patches_path.empty() && std::filesystem::exists(patches_path)) {
if (std::filesystem::is_directory(patches_path)) {
@@ -187,6 +204,25 @@ GameEngine::GameEngine() {
context->GetResourceManager()->SetAltAssetsEnabled(prevAltAssets);
}
+bool GameEngine::GenAssetFile() {
+ auto extractor = new GameExtractor();
+
+ if (!extractor->SelectGameFromUI()) {
+ ShowMessage("Error", "No ROM selected.\n\nExiting...");
+ exit(1);
+ }
+
+ auto game = extractor->ValidateChecksum();
+ if (!game.has_value()) {
+ ShowMessage("Unsupported ROM", "The provided ROM is not supported.\n\nCheck the readme for a list of supported versions.");
+ exit(1);
+ }
+
+ ShowMessage(("Found " + game.value()).c_str(), "The extraction process will now begin.\n\nThis may take a few minutes.", SDL_MESSAGEBOX_INFORMATION);
+
+ return extractor->GenerateOTR();
+}
+
void GameEngine::Create() {
const auto instance = Instance = new GameEngine();
instance->AudioInit();
@@ -421,6 +457,39 @@ uint32_t GameEngine::GetInterpolationFPS() {
CVarGetInteger("gInterpolationFPS", 60));
}
+void GameEngine::ShowMessage(const char* title, const char* message, SDL_MessageBoxFlags type) {
+#if defined(__SWITCH__)
+ SPDLOG_ERROR(message);
+#else
+ SDL_ShowSimpleMessageBox(type, title, message, nullptr);
+ SPDLOG_ERROR(message);
+#endif
+}
+
+int GameEngine::ShowYesNoBox(const char* title, const char* box) {
+ int ret;
+#ifdef _WIN32
+ ret = MessageBoxA(nullptr, box, title, MB_YESNO | MB_ICONQUESTION);
+#else
+ SDL_MessageBoxData boxData = { 0 };
+ SDL_MessageBoxButtonData buttons[2] = { { 0 } };
+
+ buttons[0].buttonid = IDYES;
+ buttons[0].text = "Yes";
+ buttons[0].flags = SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT;
+ buttons[1].buttonid = IDNO;
+ buttons[1].text = "No";
+ buttons[1].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
+ boxData.numbuttons = 2;
+ boxData.flags = SDL_MESSAGEBOX_INFORMATION;
+ boxData.message = box;
+ boxData.title = title;
+ boxData.buttons = buttons;
+ SDL_ShowMessageBox(&boxData, &ret);
+#endif
+ return ret;
+}
+
extern "C" uint32_t GameEngine_GetSampleRate() {
auto player = Ship::Context::GetInstance()->GetAudio()->GetAudioPlayer();
if (player == nullptr) {
diff --git a/src/port/Engine.h b/src/port/Engine.h
index 62af3283..ef60f012 100644
--- a/src/port/Engine.h
+++ b/src/port/Engine.h
@@ -12,10 +12,16 @@ struct GamePool {
#ifdef __cplusplus
#include <vector>
+#include <SDL2/SDL.h>
#include <Fast3D/gfx_pc.h>
#include "libultraship/src/Context.h"
-
+#ifndef IDYES
+#define IDYES 6
+#endif
+#ifndef IDNO
+#define IDNO 7
+#endif
class GameEngine {
public:
@@ -24,6 +30,7 @@ class GameEngine {
std::shared_ptr<Ship::Context> context;
GameEngine();
+ static bool GenAssetFile();
static void Create();
void StartFrame() const;
static void HandleAudioThread();
@@ -37,6 +44,9 @@ class GameEngine {
static void Destroy();
static void ProcessGfxCommands(Gfx* commands);
static uint32_t GetInterpolationFPS();
+
+ static int ShowYesNoBox(const char* title, const char* box);
+ static void ShowMessage(const char* title, const char* message, SDL_MessageBoxFlags type = SDL_MESSAGEBOX_ERROR);
};
extern "C" void* GameEngine_Malloc(size_t size);
diff --git a/src/port/extractor/GameExtractor.cpp b/src/port/extractor/GameExtractor.cpp
new file mode 100644
index 00000000..3f167c86
--- /dev/null
+++ b/src/port/extractor/GameExtractor.cpp
@@ -0,0 +1,58 @@
+#include "GameExtractor.h"
+
+#include <fstream>
+
+#include "Context.h"
+#include "spdlog/spdlog.h"
+#include "portable-file-dialogs.h"
+#include <port/Engine.h>
+
+std::unordered_map<std::string, std::string> mGameList = {
+ { "d8b1088520f7c5f81433292a9258c1184afa1457", "Star Fox 64 (U) (V1.0)" },
+ { "63b69f0ef36306257481afc250f9bc304c7162b2", "Star Fox 64 (U) (V1.0) (Uncompressed)" },
+ { "09f0d105f476b00efa5303a3ebc42e60a7753b7a", "Star Fox 64 (U) (V1.1)" },
+ { "f7475fb11e7e6830f82883412638e8390791ab87", "Star Fox 64 (U) (V1.1) (Uncompressed)" },
+};
+
+bool GameExtractor::SelectGameFromUI() {
+#if !defined(__IOS__) || !defined(__ANDROID__) || !defined(__SWITCH__)
+ auto selection = pfd::open_file("Select a file", ".", { "N64 Roms", "*.z64 *.n64 *.v64" }).result();
+
+ if (selection.empty()) {
+ return false;
+ }
+
+ this->mGamePath = selection[0];
+#else
+ this->mGamePath = Ship::Context::GetPathRelativeToAppDirectory("baserom.us.rev1.z64");
+#endif
+
+ std::ifstream file(this->mGamePath, std::ios::binary);
+ this->mGameData = std::vector<uint8_t>( std::istreambuf_iterator( file ), {} );
+ file.close();
+ return true;
+}
+
+std::optional<std::string> GameExtractor::ValidateChecksum() const {
+ const auto rom = new N64::Cartridge(this->mGameData);
+ rom->Initialize();
+ auto hash = rom->GetHash();
+
+ if (mGameList.find(hash) == mGameList.end()) {
+ return std::nullopt;
+ }
+
+ return mGameList[hash];
+}
+
+bool GameExtractor::GenerateOTR() const {
+ Companion::Instance = new Companion(this->mGameData, ArchiveType::O2R, false);
+
+ try {
+ Companion::Instance->Init(ExportType::Binary);
+ } catch (const std::exception& e) {
+ return false;
+ }
+
+ return true;
+} \ No newline at end of file
diff --git a/src/port/extractor/GameExtractor.h b/src/port/extractor/GameExtractor.h
new file mode 100644
index 00000000..a6423495
--- /dev/null
+++ b/src/port/extractor/GameExtractor.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "Companion.h"
+#include <filesystem>
+#include <vector>
+#include <cstdint>
+
+class GameExtractor {
+public:
+ static bool GenAssetFile();
+ std::optional<std::string> ValidateChecksum() const;
+ bool SelectGameFromUI();
+ bool GenerateOTR() const;
+private:
+ fs::path mGamePath;
+ std::vector<uint8_t> mGameData;
+}; \ No newline at end of file
diff --git a/src/port/ui/UIWidgets.cpp b/src/port/ui/UIWidgets.cpp
index 3bac9f3a..00f6499b 100644
--- a/src/port/ui/UIWidgets.cpp
+++ b/src/port/ui/UIWidgets.cpp
@@ -1,10 +1,3 @@
-//
-// UIWidgets.cpp
-// soh
-//
-// Created by David Chavez on 25.08.22.
-//
-
#include "UIWidgets.h"
#include "libultraship/src/Context.h"