Game list uses new DB

This commit is contained in:
CocoSimone
2022-12-19 00:06:37 +01:00
parent 60ad309eb7
commit 5905529982
7 changed files with 12739 additions and 7234 deletions

View File

@@ -187,7 +187,7 @@ void InitParallelRDP(const u8* rdram, SDL_Window* window) {
LoadParallelRDP(rdram, window); LoadParallelRDP(rdram, window);
} }
void DrawFullscreenTexturedQuad(Util::IntrusivePtr<Image> image, Util::IntrusivePtr<CommandBuffer> cmd) { void DrawFullscreenTexturedQuad(float mainMenuBarHeight, Util::IntrusivePtr<Image> image, Util::IntrusivePtr<CommandBuffer> cmd) {
cmd->set_texture(0, 0, image->get_view(), Vulkan::StockSampler::LinearClamp); cmd->set_texture(0, 0, image->get_view(), Vulkan::StockSampler::LinearClamp);
cmd->set_program(fullscreen_quad_program); cmd->set_program(fullscreen_quad_program);
cmd->set_quad_state(); cmd->set_quad_state();
@@ -202,12 +202,20 @@ void DrawFullscreenTexturedQuad(Util::IntrusivePtr<Image> image, Util::Intrusive
int sdlWinWidth, sdlWinHeight; int sdlWinWidth, sdlWinHeight;
SDL_GetWindowSize(g_Window, &sdlWinWidth, &sdlWinHeight); SDL_GetWindowSize(g_Window, &sdlWinWidth, &sdlWinHeight);
float zoom = std::min( sdlWinHeight -= mainMenuBarHeight;
(float)sdlWinWidth / wsi->get_platform().get_surface_width(),
(float)sdlWinHeight / wsi->get_platform().get_surface_height());
float width = (wsi->get_platform().get_surface_width() / (float)sdlWinWidth) * zoom; float platform_width = wsi->get_platform().get_surface_width();
float height = (wsi->get_platform().get_surface_height() / (float)sdlWinHeight) * zoom; float platform_height = wsi->get_platform().get_surface_height();
platform_height -= mainMenuBarHeight;
float zoom = std::min(
(float)sdlWinWidth / platform_width,
(float)sdlWinHeight / platform_height);
float width = (platform_width / (float)sdlWinWidth) * zoom;
float height = (platform_height / (float)sdlWinHeight) * zoom;
float uniform_data[] = { float uniform_data[] = {
// Size // Size
@@ -253,9 +261,11 @@ void UpdateScreen(n64::Core& core, Window& imguiWindow, Util::IntrusivePtr<Image
Util::IntrusivePtr<CommandBuffer> cmd = wsi->get_device().request_command_buffer(); Util::IntrusivePtr<CommandBuffer> cmd = wsi->get_device().request_command_buffer();
cmd->begin_render_pass(wsi->get_device().get_swapchain_render_pass(SwapchainRenderPass::ColorOnly)); cmd->begin_render_pass(wsi->get_device().get_swapchain_render_pass(SwapchainRenderPass::ColorOnly));
DrawFullscreenTexturedQuad(image, cmd); DrawData data = imguiWindow.Present(core);
ImGui_ImplVulkan_RenderDrawData(imguiWindow.Present(core), cmd->get_command_buffer()); DrawFullscreenTexturedQuad(data.second, image, cmd);
ImGui_ImplVulkan_RenderDrawData(data.first, cmd->get_command_buffer());
cmd->end_render_pass(); cmd->end_render_pass();
wsi->get_device().submit(cmd); wsi->get_device().submit(cmd);

File diff suppressed because it is too large Load Diff

View File

@@ -37,24 +37,59 @@ inline std::string CountryCodeToStr(u8 code) {
GameList::GameList(const std::string& path) { GameList::GameList(const std::string& path) {
if(!path.empty()) { if(!path.empty()) {
std::for_each(std::execution::par_unseq, begin(recursive_directory_iterator{path}), end(recursive_directory_iterator{path}), [&](const auto& p) { std::ifstream gameDbFile("resources/db.json");
json gameDb = json::parse(gameDbFile);
std::vector<u8> rom{};
std::for_each(std::execution::par, begin(directory_iterator{path}), end(directory_iterator{path}), [&](const auto& p) {
const auto filename = p.path().string();
if(p.path().extension() == ".n64" || p.path().extension() == ".z64" || p.path().extension() == ".v64" || if(p.path().extension() == ".n64" || p.path().extension() == ".z64" || p.path().extension() == ".v64" ||
p.path().extension() == ".N64" || p.path().extension() == ".Z64" || p.path().extension() == ".V64") { p.path().extension() == ".N64" || p.path().extension() == ".Z64" || p.path().extension() == ".V64") {
std::ifstream file(filename, std::ios::binary);
file.unsetf(std::ios::skipws);
if(!file.is_open()) {
util::panic("Unable to open {}!", filename);
}
file.seekg(0, std::ios::end);
auto size = file.tellg();
auto sizeAdjusted = util::NextPow2(size);
file.seekg(0, std::ios::beg);
std::fill(rom.begin(), rom.end(), 0);
rom.resize(sizeAdjusted);
rom.insert(rom.begin(), std::istream_iterator<u8>(file), std::istream_iterator<u8>());
file.close();
u32 crc{};
util::SwapN64RomJustCRC(sizeAdjusted, rom.data(), crc);
std::for_each(std::execution::par, gameDb["items"].begin(), gameDb["items"].end(), [&](const auto& item) {
const auto& crcEntry = item["crc"];
if(!crcEntry.empty()) {
if(crcEntry.template get<std::string>() == fmt::format("{:08X}", crc)) {
gamesList.push_back({
item["name"].template get<std::string>(),
item["region"].template get<std::string>(),
fmt::format("{:.2f} MiB", float(size) / 1024 / 1024),
"Good",
p.path().string()
});
}
}
});
} }
}); });
gameDbFile.close();
} }
} }
bool GameList::RenderWidget(bool showMainMenuBar, float mainMenuBarHeight, std::string& rom) { bool GameList::RenderWidget(float mainMenuBarHeight, std::string& rom) {
const auto windowSize = ImGui::GetIO().DisplaySize; const auto windowSize = ImGui::GetIO().DisplaySize;
if (showMainMenuBar) { ImGui::SetNextWindowPos(ImVec2(0, mainMenuBarHeight));
ImGui::SetNextWindowPos(ImVec2(0, mainMenuBarHeight)); ImGui::SetNextWindowSize(ImVec2(windowSize.x, windowSize.y - mainMenuBarHeight));
ImGui::SetNextWindowSize(ImVec2(windowSize.x, windowSize.y - mainMenuBarHeight));
} else {
ImGui::SetNextWindowPos(ImVec2(0, 0));
ImGui::SetNextWindowSize(windowSize);
}
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.f, 0.f)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.f, 0.f));
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.f); ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.f);
@@ -72,17 +107,18 @@ bool GameList::RenderWidget(bool showMainMenuBar, float mainMenuBarHeight, std::
| ImGuiTableFlags_SizingStretchProp; | ImGuiTableFlags_SizingStretchProp;
bool toOpen = false; bool toOpen = false;
if (ImGui::BeginTable("Games List", 3, flags)) { if (ImGui::BeginTable("Games List", 4, flags)) {
ImGui::TableSetupColumn("Title"); ImGui::TableSetupColumn("Title");
ImGui::TableSetupColumn("Region"); ImGui::TableSetupColumn("Region");
ImGui::TableSetupColumn("Status");
ImGui::TableSetupColumn("Size"); ImGui::TableSetupColumn("Size");
ImGui::TableHeadersRow(); ImGui::TableHeadersRow();
for (int row = 0; row < gamesList.size(); row++) { int i = 0;
GameInfo entry = gamesList[row];
for (const auto& entry : gamesList) {
ImGui::TableNextRow(ImGuiTableRowFlags_None); ImGui::TableNextRow(ImGuiTableRowFlags_None);
ImGui::PushID(row); ImGui::PushID(i);
ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.0f, 0.5f)); ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.0f, 0.5f));
ImGui::TableSetColumnIndex(0); ImGui::TableSetColumnIndex(0);
@@ -100,6 +136,13 @@ bool GameList::RenderWidget(bool showMainMenuBar, float mainMenuBarHeight, std::
ImGui::TableSetColumnIndex(2); ImGui::TableSetColumnIndex(2);
if (ImGui::Selectable(entry.status.c_str(), false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap, ImVec2(0.0f, 20.f))) {
toOpen = true;
rom = entry.path;
}
ImGui::TableSetColumnIndex(3);
if (ImGui::Selectable(entry.size.c_str(), false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap, ImVec2(0.0f, 20.f))) { if (ImGui::Selectable(entry.size.c_str(), false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap, ImVec2(0.0f, 20.f))) {
toOpen = true; toOpen = true;
rom = entry.path; rom = entry.path;
@@ -107,6 +150,7 @@ bool GameList::RenderWidget(bool showMainMenuBar, float mainMenuBarHeight, std::
ImGui::PopStyleVar(); ImGui::PopStyleVar();
ImGui::PopID(); ImGui::PopID();
i++;
} }
ImGui::EndTable(); ImGui::EndTable();

View File

@@ -3,16 +3,16 @@
#include <string> #include <string>
struct GameInfo { struct GameInfo {
std::string name, region, size, path; std::string name, region, size, status, path;
}; };
struct GameList { struct GameList {
GameList(const std::string&); GameList(const std::string&);
~GameList() = default; ~GameList() = default;
bool RenderWidget(bool, float, std::string&); bool RenderWidget(float, std::string&);
std::vector<GameInfo> GetGamesList() const { return gamesList; } std::vector<GameInfo> GetGamesList() const { return gamesList; }
private: private:
std::vector<GameInfo> gamesList{}; std::vector<GameInfo> gamesList{}, notMatch{};
}; };

View File

@@ -144,15 +144,15 @@ Window::~Window() {
SDL_Quit(); SDL_Quit();
} }
ImDrawData* Window::Present(n64::Core& core) { DrawData Window::Present(n64::Core& core) {
ImGui_ImplVulkan_NewFrame(); ImGui_ImplVulkan_NewFrame();
ImGui_ImplSDL2_NewFrame(window); ImGui_ImplSDL2_NewFrame(window);
ImGui::NewFrame(); ImGui::NewFrame();
Render(core); float mainMenuBarHeight = Render(core);
ImGui::Render(); ImGui::Render();
return ImGui::GetDrawData(); return {ImGui::GetDrawData(), mainMenuBarHeight};
} }
void Window::LoadROM(n64::Core& core, const std::string &path) { void Window::LoadROM(n64::Core& core, const std::string &path) {
@@ -160,35 +160,35 @@ void Window::LoadROM(n64::Core& core, const std::string &path) {
n64::CartInfo cartInfo = core.LoadROM(path); n64::CartInfo cartInfo = core.LoadROM(path);
std::ifstream gameDbFile("resources/db.json"); std::ifstream gameDbFile("resources/db.json");
json gameDb = json::parse(gameDbFile); json gameDb = json::parse(gameDbFile);
gameName = "";
for(const auto& item : gameDb["titles"]) { for(const auto& item : gameDb["items"]) {
auto temp = item["part"]["dataarea"]; auto crc = item["crc"];
std::cout << temp << "\n"; if(!crc.empty()) {
//if(!crc.empty()) { if(crc.get<std::string>() == fmt::format("{:08X}", cartInfo.crc)) {
// if(crc.get<std::string>() == fmt::format("{:08x}", cartInfo.crc)) { auto name = item["name"];
// auto desc = item["description"]; if(!name.empty()) {
// if(desc.empty()) { gameName = name.get<std::string>();
// gameName = desc.get<std::string>(); }
// } }
// } }
//}
}; };
if(gameName.empty()) { if(gameName.empty()) {
gameName = std::filesystem::path(path).stem().string(); gameName = std::filesystem::path(path).stem().string();
} }
std::cout << gameName << "\n";
util::UpdateRPC(util::Playing, gameName); util::UpdateRPC(util::Playing, gameName);
windowTitle = "Gadolinium - " + gameName; windowTitle = "Gadolinium - " + gameName;
shadowWindowTitle = windowTitle; shadowWindowTitle = windowTitle;
renderGameList = false;
SDL_SetWindowTitle(window, windowTitle.c_str()); SDL_SetWindowTitle(window, windowTitle.c_str());
gameDbFile.close();
} }
} }
void Window::Render(n64::Core& core) { float Window::Render(n64::Core& core) {
ImGui::PushFont(uiFont); ImGui::PushFont(uiFont);
u32 ticks = SDL_GetTicks(); u32 ticks = SDL_GetTicks();
@@ -201,78 +201,74 @@ void Window::Render(n64::Core& core) {
windowTitle = shadowWindowTitle; windowTitle = shadowWindowTitle;
} }
static bool renderGameList = true;
static bool showSettings = false; static bool showSettings = false;
bool showMainMenuBar = windowID == SDL_GetWindowID(SDL_GetMouseFocus());
static float mainMenuBarHeight = 0; static float mainMenuBarHeight = 0;
if(showMainMenuBar) { ImGui::BeginMainMenuBar();
ImGui::BeginMainMenuBar(); mainMenuBarHeight = ImGui::GetWindowSize().y;
mainMenuBarHeight = ImGui::GetWindowSize().y; if (ImGui::BeginMenu("File")) {
if (ImGui::BeginMenu("File")) { if (ImGui::MenuItem("Open", "O")) {
if (ImGui::MenuItem("Open", "O")) { nfdchar_t *outpath;
nfdchar_t *outpath; const nfdu8filteritem_t filter{"Nintendo 64 roms", "n64,z64,v64,N64,Z64,V64"};
const nfdu8filteritem_t filter{"Nintendo 64 roms", "n64,z64,v64,N64,Z64,V64"}; nfdresult_t result = NFD_OpenDialog(&outpath, &filter, 1, nullptr);
nfdresult_t result = NFD_OpenDialog(&outpath, &filter, 1, nullptr); if (result == NFD_OKAY) {
if (result == NFD_OKAY) { LoadROM(core, outpath);
LoadROM(core, outpath); util::UpdateRPC(util::Playing, gameName);
util::UpdateRPC(util::Playing, gameName); NFD_FreePath(outpath);
NFD_FreePath(outpath);
renderGameList = false;
}
} }
if (ImGui::MenuItem("Dump RDRAM")) {
core.mem.DumpRDRAM();
}
if (ImGui::MenuItem("Dump IMEM")) {
core.mem.DumpIMEM();
}
if (ImGui::MenuItem("Dump DMEM")) {
core.mem.DumpDMEM();
}
if (ImGui::MenuItem("Exit")) {
core.done = true;
}
ImGui::EndMenu();
} }
if (ImGui::BeginMenu("Emulation")) { if (ImGui::MenuItem("Dump RDRAM")) {
if (ImGui::MenuItem("Reset")) { core.mem.DumpRDRAM();
LoadROM(core, core.rom);
renderGameList = false;
}
if (ImGui::MenuItem("Stop")) {
renderGameList = true;
windowTitle = "Gadolinium";
core.rom.clear();
util::UpdateRPC(util::Idling);
SDL_SetWindowTitle(window, windowTitle.c_str());
core.Stop();
}
if (ImGui::MenuItem(core.pause ? "Resume" : "Pause", nullptr, false, core.romLoaded)) {
core.TogglePause();
if(core.pause) {
shadowWindowTitle = windowTitle;
windowTitle += " | Paused";
util::UpdateRPC(util::Paused, gameName);
} else {
windowTitle = shadowWindowTitle;
util::UpdateRPC(util::Playing, gameName);
}
SDL_SetWindowTitle(window, windowTitle.c_str());
}
if (ImGui::MenuItem("Settings")) {
showSettings = true;
}
ImGui::EndMenu();
} }
ImGui::EndMainMenuBar(); if (ImGui::MenuItem("Dump IMEM")) {
core.mem.DumpIMEM();
}
if (ImGui::MenuItem("Dump DMEM")) {
core.mem.DumpDMEM();
}
if (ImGui::MenuItem("Exit")) {
core.done = true;
}
ImGui::EndMenu();
} }
if (ImGui::BeginMenu("Emulation")) {
if (ImGui::MenuItem("Reset")) {
LoadROM(core, core.rom);
}
if (ImGui::MenuItem("Stop")) {
renderGameList = true;
windowTitle = "Gadolinium";
core.rom.clear();
util::UpdateRPC(util::Idling);
SDL_SetWindowTitle(window, windowTitle.c_str());
core.Stop();
}
if (ImGui::MenuItem(core.pause ? "Resume" : "Pause", nullptr, false, core.romLoaded)) {
core.TogglePause();
if(core.pause) {
shadowWindowTitle = windowTitle;
windowTitle += " | Paused";
util::UpdateRPC(util::Paused, gameName);
} else {
windowTitle = shadowWindowTitle;
util::UpdateRPC(util::Playing, gameName);
}
SDL_SetWindowTitle(window, windowTitle.c_str());
}
if (ImGui::MenuItem("Settings")) {
showSettings = true;
}
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
static std::string rom{}; static std::string rom{};
if(renderGameList && gameList.RenderWidget(showMainMenuBar, mainMenuBarHeight, rom)) { if(renderGameList && gameList.RenderWidget(mainMenuBarHeight, rom)) {
LoadROM(core, rom); LoadROM(core, rom);
renderGameList = false; renderGameList = false;
} }
settings.RenderWidget(showSettings); settings.RenderWidget(showSettings);
ImGui::PopFont(); ImGui::PopFont();
return mainMenuBarHeight;
} }

View File

@@ -9,10 +9,15 @@
#include <Settings.hpp> #include <Settings.hpp>
#include <GameList.hpp> #include <GameList.hpp>
struct DrawData {
ImDrawData* first;
float second;
};
struct Window { struct Window {
explicit Window(n64::Core& core); explicit Window(n64::Core& core);
~Window(); ~Window();
ImDrawData* Present(n64::Core& core); DrawData Present(n64::Core& core);
[[nodiscard]] bool gotClosed(SDL_Event event); [[nodiscard]] bool gotClosed(SDL_Event event);
ImFont *uiFont{}, *codeFont{}; ImFont *uiFont{}, *codeFont{};
@@ -21,13 +26,14 @@ struct Window {
GameList gameList; GameList gameList;
void LoadROM(n64::Core& core, const std::string& path); void LoadROM(n64::Core& core, const std::string& path);
private: private:
bool renderGameList = true;
SDL_Window* window{}; SDL_Window* window{};
std::string windowTitle{"Gadolinium"}; std::string windowTitle{"Gadolinium"};
std::string shadowWindowTitle{windowTitle}; std::string shadowWindowTitle{windowTitle};
std::string gameName{}; std::string gameName{};
void InitSDL(); void InitSDL();
void InitImgui(); void InitImgui();
void Render(n64::Core& core); float Render(n64::Core& core);
VkPhysicalDevice physicalDevice{}; VkPhysicalDevice physicalDevice{};
VkDevice device{}; VkDevice device{};

View File

@@ -170,6 +170,28 @@ enum RomTypes {
V64 = 0x37804012 V64 = 0x37804012
}; };
inline void SwapN64RomJustCRC(size_t size, u8* rom, u32& crc) {
RomTypes endianness;
memcpy(&endianness, rom, 4);
endianness = static_cast<RomTypes>(be32toh(endianness));
switch(endianness) {
case RomTypes::V64: {
SwapBuffer16(size, rom);
crc = crc32(0, rom, size);
} break;
case RomTypes::N64: {
SwapBuffer32(size, rom);
crc = crc32(0, rom, size);
} break;
case RomTypes::Z64:
crc = crc32(0, rom, size);
break;
default:
panic("Unrecognized rom format! Make sure this is a valid Nintendo 64 ROM dump!\n");
}
}
inline void SwapN64Rom(size_t size, u8* rom, u32& crc, u32& cicChecksum) { inline void SwapN64Rom(size_t size, u8* rom, u32& crc, u32& cicChecksum) {
RomTypes endianness; RomTypes endianness;
memcpy(&endianness, rom, 4); memcpy(&endianness, rom, 4);