Skip to content

Commit 639e2eb

Browse files
committed
Update to latest dev
2 parents 7b1d1a6 + 7f76a34 commit 639e2eb

10 files changed

Lines changed: 639 additions & 183 deletions

File tree

src/port/Engine.cpp

Lines changed: 493 additions & 115 deletions
Large diffs are not rendered by default.

src/port/Engine.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,11 @@ class GameEngine {
4949
std::unordered_map<std::string, std::vector<uint8_t>>* dictionary;
5050

5151
GameEngine();
52-
static void Create();
52+
static void Create(int argc, char* argv[]);
5353
static bool GenAssetFile(bool exitOnFail = true);
54+
void RunExtract(int argc, char* argv[]);
5455
void AudioInit();
56+
void FinishInit();
5557
void StartFrame() const;
5658
static void RunCommands(Gfx* Commands, const std::vector<std::unordered_map<Mtx*, MtxF>>& mtx_replacements);
5759
static uint32_t GetInterpolationFPS();
@@ -64,7 +66,7 @@ class GameEngine {
6466
static int ShowYesNoBox(const char* title, const char* box);
6567
static ImFont *CreateFontWithSize(float size, std::string fontPath);
6668
static void ScaleImGui();
67-
static void ShowMessage(const char* title, const char* message, SDL_MessageBoxFlags type = SDL_MESSAGEBOX_ERROR);
69+
// static void ShowMessage(const char* title, const char* message, SDL_MessageBoxFlags type = SDL_MESSAGEBOX_ERROR);
6870
static bool IsAltAssetsEnabled();
6971
void LoadDictionary();
7072
void LoadPlayerAnims();

src/port/Game.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ void push_frame() {
2929
#ifdef _WIN32
3030
int SDL_main(int argc, char** argv) {
3131
#else
32-
int main() {
32+
int main(int argc, char* argv[]) {
3333
#endif
34-
GameEngine::Create();
34+
GameEngine::Create(argc, argv);
3535
alloc_pool();
3636
audio_init();
3737
sound_init();

src/port/GameExtractor.cpp

Lines changed: 107 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -33,72 +33,86 @@ std::unordered_map<std::string, std::string> mGameList = {
3333
{ "9bef1128717f958171a4afac3ed78ee2bb4e86ce", "Super Mario 64 (US)" },
3434
};
3535

36-
bool GameExtractor::SelectGameFromUI() {
37-
std::vector<std::string> roms;
38-
GetRoms(roms);
39-
40-
bool foundGame = false;
41-
36+
bool GameExtractor::RunStandalone(std::string rom) {
4237
// Store both path and already-read data
4338
std::string romPath;
4439
std::vector<uint8_t> romData;
4540

46-
// Auto detect first baserom with valid hash
47-
for (const auto& rom : roms) {
48-
if (!std::filesystem::exists(rom))
49-
continue;
41+
if (!std::filesystem::exists(rom)) {
42+
return false;
43+
}
5044

51-
std::ifstream inFile(rom, std::ios::binary);
52-
if (!inFile.is_open()) {
53-
SPDLOG_INFO("Failed to open ROM at path: {}, continuing", rom);
54-
continue;
55-
}
45+
std::ifstream inFile(rom, std::ios::binary);
46+
if (!inFile.is_open()) {
47+
SPDLOG_INFO("Failed to open ROM at path: {}, continuing", rom);
48+
return false;
49+
}
5650

57-
inFile.seekg(0, std::ios::end);
58-
size_t fileSize = inFile.tellg();
59-
inFile.seekg(0, std::ios::beg);
51+
inFile.seekg(0, std::ios::end);
52+
size_t fileSize = inFile.tellg();
53+
inFile.seekg(0, std::ios::beg);
6054

61-
std::vector<uint8_t> data(fileSize);
62-
if (!inFile.read(reinterpret_cast<char*>(data.data()), fileSize)) {
63-
SPDLOG_INFO("Failed to read ROM at path: {}, continuing", rom);
64-
continue;
65-
}
55+
std::vector<uint8_t> data(fileSize);
56+
if (!inFile.read(reinterpret_cast<char*>(data.data()), fileSize)) {
57+
SPDLOG_INFO("Failed to read ROM at path: {}, continuing", rom);
58+
return false;
59+
}
6660

67-
inFile.close();
68-
std::string hash = Companion::CalculateHash(data);
61+
inFile.close();
62+
std::string hash = Companion::CalculateHash(data);
6963

70-
if (mGameList.find(hash) != mGameList.end()) {
71-
romPath = rom;
72-
romData = std::move(data);
73-
foundGame = true;
74-
break;
75-
}
64+
if (mGameList.find(hash) != mGameList.end()) {
65+
romPath = rom;
66+
romData = std::move(data);
7667
}
7768

78-
#if !defined(__IOS__) && !defined(__ANDROID__) && !defined(__SWITCH__)
79-
// Desktop: fallback to file dialogue if no baserom found
80-
if (!foundGame) {
81-
if (!pfd::settings::available()) {
82-
SPDLOG_ERROR("portable-file-dialogs is not available on this system.");
69+
// Load file if it is not already open
70+
if (romData.empty()) {
71+
std::ifstream inFile(romPath, std::ios::binary);
72+
if (!inFile.is_open()) {
8373
return false;
8474
}
8575

86-
auto selection = pfd::open_file("Select a file", ".", { "N64 Roms", "*.z64" }).result();
87-
if (selection.empty())
88-
return false;
76+
romData = std::vector<uint8_t>(std::istreambuf_iterator<char>(inFile), {});
77+
inFile.close();
78+
}
79+
80+
this->mGamePath = romPath;
81+
this->mGameData = std::move(romData);
82+
83+
return true;
84+
}
85+
86+
bool GameExtractor::SelectGameFromUI() {
87+
//// Store both path and already-read data
88+
std::string romPath;
89+
std::vector<uint8_t> romData;
8990

90-
romPath = selection[0];
91+
#if !defined(__IOS__) && !defined(__ANDROID__) && !defined(__SWITCH__)
92+
// Desktop: fallback to file dialogue if no baserom found
93+
// if (!foundGame) {
94+
if (!pfd::settings::available()) {
95+
SPDLOG_ERROR("portable-file-dialogs is not available on this system.");
96+
return false;
9197
}
98+
99+
auto selection = pfd::open_file("Select a file", ".", { "N64 Roms", "*.z64" }).result();
100+
if (selection.empty()) {
101+
return false;
102+
}
103+
104+
romPath = selection[0];
105+
//}
92106
#else
93107
// Mobile: fallback to baserom.us.z64
94-
if (!foundGame && !std::filesystem::exists(Ship::Context::GetPathRelativeToAppDirectory("baserom.us.z64"))) {
108+
if (/*!foundGame && */ !std::filesystem::exists(Ship::Context::GetPathRelativeToAppDirectory("baserom.us.z64"))) {
95109
SPDLOG_ERROR("baserom not found");
96110
return false;
97111
}
98112

99-
if (!foundGame) {
100-
romPath = Ship::Context::GetPathRelativeToAppDirectory("baserom.us.z64");
101-
}
113+
// if (!foundGame) {
114+
romPath = Ship::Context::GetPathRelativeToAppDirectory("baserom.us.z64");
115+
//}
102116
#endif
103117

104118
// Load file if it is not already open
@@ -109,8 +123,9 @@ bool GameExtractor::SelectGameFromUI() {
109123
}
110124

111125
std::ifstream inFile(romPath, std::ios::binary);
112-
if (!inFile.is_open())
126+
if (!inFile.is_open()) {
113127
return false;
128+
}
114129

115130
romData = std::vector<uint8_t>(std::istreambuf_iterator<char>(inFile), {});
116131
inFile.close();
@@ -122,17 +137,23 @@ bool GameExtractor::SelectGameFromUI() {
122137
return true;
123138
}
124139

140+
void GameExtractor::SetSearchPath(const std::string& path) {
141+
mSearchPath = path;
142+
}
143+
125144
void GameExtractor::GetRoms(std::vector<std::string>& roms) {
126145
#ifdef _WIN32
127146
WIN32_FIND_DATAA ffd;
128-
HANDLE h = FindFirstFileA(".\\*", &ffd);
147+
std::string search = std::string(mSearchPath + "\\*");
148+
HANDLE h = FindFirstFileA(search.c_str(), &ffd);
129149

130150
do {
131151
if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
132152
char* ext = PathFindExtensionA(ffd.cFileName);
133153

134154
// Check for any standard N64 rom file extensions.
135-
if ((strcmp(ext, ".z64") == 0))
155+
if (ext != NULL &&
156+
(strcmp(ext, ".z64") == 0) /* || (strcmp(ext, ".n64") == 0) || (strcmp(ext, ".v64") == 0)*/)
136157
roms.push_back(ffd.cFileName);
137158
}
138159
} while (FindNextFileA(h, &ffd) != 0);
@@ -141,37 +162,36 @@ void GameExtractor::GetRoms(std::vector<std::string>& roms) {
141162
//}
142163
#elif unix
143164
// Open the directory of the app.
144-
DIR* d = opendir(".");
165+
DIR* d = opendir(mSearchPath.c_str());
145166
struct dirent* dir;
146167

147168
if (d != NULL) {
148169
// Go through each file in the directory
149170
while ((dir = readdir(d)) != NULL) {
150171
struct stat path;
151172

152-
auto fullPath = std::filesystem::path(".") / dir->d_name;
153-
auto fullPathString = fullPath.string();
154-
const char* fullPathCStr = fullPathString.c_str();
155-
156173
// Check if current entry is not folder
157-
stat(fullPathCStr, &path);
174+
stat(dir->d_name, &path);
158175
if (S_ISREG(path.st_mode)) {
159176

160177
// Get the position of the extension character.
161178
char* ext = strrchr(dir->d_name, '.');
162-
if (ext != NULL && (strcmp(ext, ".z64") == 0)) {
163-
roms.push_back(fullPathCStr);
179+
if (ext != NULL &&
180+
(strcmp(ext, ".z64") == 0 /* || strcmp(ext, ".n64") == 0 || strcmp(ext, ".v64") == 0*/)) {
181+
roms.push_back(dir->d_name);
164182
}
165183
}
166184
}
167185
}
168186
closedir(d);
169187
#else
170-
for (const auto& file : std::filesystem::directory_iterator(".")) {
171-
if (file.is_directory())
188+
for (const auto& file : std::filesystem::directory_iterator(mSearchPath)) {
189+
if (file.is_directory()) {
172190
continue;
173-
if (file.path().extension() == ".z64") {
174-
roms.push_back((file.path()));
191+
}
192+
if (/*(file.path().extension() == ".n64") || */(file.path().extension() == ".z64")/* ||
193+
(file.path().extension() == ".v64")*/) {
194+
roms.push_back((file.path().generic_string()));
175195
}
176196
}
177197
#endif
@@ -200,14 +220,39 @@ void GameExtractor::WritePortVersion() {
200220
Companion::Instance->RegisterCompanionFile("portVersion", writer.ToVector());
201221
}
202222

203-
bool GameExtractor::GenerateOTR() {
223+
std::string GameExtractor::GetRomPath() {
224+
return mGamePath.generic_string();
225+
}
226+
227+
bool GameExtractor::Parse(std::atomic_ref<size_t> totalAssets, std::string appShortName) {
228+
const std::string assets_path = Ship::Context::GetAppBundlePath();
229+
const std::string game_path = Ship::Context::GetAppDirectoryPath(appShortName);
230+
231+
Companion::Instance = new Companion(this->mGameData, ArchiveType::O2R, false, assets_path, game_path);
232+
Companion::Instance->SetProcess(false);
233+
try {
234+
Companion::Instance->Init(ExportType::Binary, std::atomic_ref<size_t>(totalAssets));
235+
} catch (const std::exception& e) {
236+
SPDLOG_INFO("Failed to process O2R {}", e.what());
237+
return false;
238+
}
239+
240+
return true;
241+
}
242+
243+
bool GameExtractor::GenerateOTR(std::string appShortName) {
244+
size_t assetCount = 0;
245+
return GenerateOTR(std::atomic_ref<size_t>(assetCount));
246+
}
247+
248+
bool GameExtractor::GenerateOTR(std::atomic_ref<size_t> assetCount, std::string appShortName) {
204249
const std::string assets_path = Ship::Context::GetAppBundlePath();
205-
const std::string game_path = Ship::Context::GetAppDirectoryPath();
250+
const std::string game_path = Ship::Context::GetAppDirectoryPath(appShortName);
206251

207252
Companion::Instance = new Companion(this->mGameData, ArchiveType::O2R, false, assets_path, game_path);
208253
this->WritePortVersion();
209254
try {
210-
Companion::Instance->Init(ExportType::Binary);
255+
Companion::Instance->Init(ExportType::Binary, std::atomic_ref<size_t>(assetCount));
211256
} catch (const std::exception& e) {
212257
SPDLOG_INFO("Failed to process O2R {}", e.what());
213258
return false;

src/port/GameExtractor.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,25 @@
44
#include <vector>
55
#include <cstdint>
66
#include <optional>
7+
#include <atomic>
78

89
namespace fs = std::filesystem;
910

1011
class GameExtractor {
1112
public:
1213
static bool GenAssetFile();
1314
std::optional<std::string> ValidateChecksum() const;
15+
bool RunStandalone(std::string rom);
1416
bool SelectGameFromUI();
17+
void SetSearchPath(const std::string& path);
1518
void GetRoms(std::vector<std::string>& roms);
16-
bool GenerateOTR();
19+
std::string GetRomPath();
20+
bool Parse(std::atomic_ref<size_t> assetCount, std::string appShortName = "");
21+
bool GenerateOTR(std::string appShortName = "");
22+
bool GenerateOTR(std::atomic_ref<size_t> assetCount, std::string appShortName = "");
1723
void WritePortVersion();
1824
private:
1925
fs::path mGamePath;
2026
std::vector<uint8_t> mGameData;
27+
std::string mSearchPath;
2128
};

src/port/ui/GhostshipGui.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@ UIWidgets::Colors GetMenuThemeColor() {
3939
return mGhostshipMenu->GetMenuThemeColor();
4040
}
4141

42+
void SetupMenu() {
43+
auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui();
44+
mGhostshipMenu = std::make_shared<GhostshipGui::GhostshipMenu>(CVAR_WINDOW("Menu"), "Port Menu");
45+
gui->SetMenu(mGhostshipMenu);
46+
47+
mModalWindow = std::make_shared<GhostshipModalWindow>(CVAR_WINDOW("ModalWindow"), "Modal Window");
48+
gui->AddGuiWindow(mModalWindow);
49+
mModalWindow->Show();
50+
}
51+
4252
void SetupGuiElements() {
4353
auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui();
4454

@@ -72,6 +82,7 @@ void SetupGuiElements() {
7282
mInputViewerSettings = std::make_shared<InputViewerSettingsWindow>(CVAR_WINDOW("InputViewerSettings"),
7383
"Input Viewer Settings", ImVec2(500, 525));
7484
gui->AddGuiWindow(mInputViewerSettings);
85+
7586
mModalWindow = std::make_shared<GhostshipModalWindow>(CVAR_WINDOW("ModalWindow"), "Modal Window");
7687
gui->AddGuiWindow(mModalWindow);
7788
mModalWindow->Show();
@@ -117,4 +128,8 @@ void RegisterPopup(std::string title, std::string message, std::string button1,
117128
mModalWindow->RegisterPopup(title, message, button1, button2, button1callback, button2callback);
118129
}
119130

131+
size_t PopupsQueued() {
132+
return mModalWindow->PopupsQueued();
133+
}
134+
120135
} // namespace GhostshipGui

src/port/ui/GhostshipGui.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@
77

88
namespace GhostshipGui {
99
void SetupHooks();
10+
void SetupMenu();
1011
void SetupGuiElements();
1112
void Draw();
1213
void Destroy();
14+
void RegisterPopup(std::string title, std::string message, std::string button1 = "OK", std::string button2 = "",
15+
std::function<void()> button1callback = nullptr, std::function<void()> button2callback = nullptr);
16+
size_t PopupsQueued();
1317
UIWidgets::Colors GetMenuThemeColor();
1418
extern std::shared_ptr<GhostshipMenu> mGhostshipMenu;
1519
} // namespace GhostshipGui

src/port/ui/GhostshipModals.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ void GhostshipModalWindow::RegisterPopup(std::string title, std::string message,
7474
modals.push_back({ title, message, button1, button2, button1callback, button2callback });
7575
}
7676

77+
size_t GhostshipModalWindow::PopupsQueued() {
78+
return modals.size();
79+
}
80+
7781
bool GhostshipModalWindow::IsPopupOpen(std::string title) {
7882
return !modals.empty() && modals.at(0).title_ == title;
7983
}

src/port/ui/GhostshipModals.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ class GhostshipModalWindow final : public Ship::GuiWindow {
1515
std::function<void()> button1callback = nullptr,
1616
std::function<void()> button2callback = nullptr);
1717
bool IsPopupOpen(std::string title);
18+
size_t PopupsQueued();
1819
void DismissPopup();
1920
};

0 commit comments

Comments
 (0)