diff --git a/CMakeLists.txt b/CMakeLists.txt index 30541a90..65ec6735 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,45 +1,7 @@ cmake_minimum_required(VERSION 3.20) -project(kaizen) -set(BUILD_SHARED_LIBS OFF) set(CMAKE_CXX_STANDARD 17) -find_package(SDL2 REQUIRED) -find_package(fmt REQUIRED) -find_package(mio REQUIRED) -find_package(nlohmann_json REQUIRED) - -option(RAPIDJSON_BUILD_DOC "Build rapidjson documentation." OFF) -option(RAPIDJSON_BUILD_EXAMPLES "Build rapidjson examples." OFF) -option(RAPIDJSON_BUILD_TESTS "Build rapidjson perftests and unittests." OFF) - -include_directories( - src - src/utils - src/frontend - src/frontend/imgui - src/backend - src/backend/core - src/backend/core/mmio - src/backend/core/registers - src/backend/core/rsp - external - external/xbyak - external/parallel-rdp - external/parallel-rdp/parallel-rdp-standalone/parallel-rdp - external/parallel-rdp/parallel-rdp-standalone/volk - external/parallel-rdp/parallel-rdp-standalone/spirv-cross - external/parallel-rdp/parallel-rdp-standalone/vulkan - external/parallel-rdp/parallel-rdp-standalone/vulkan-headers/include - external/parallel-rdp/parallel-rdp-standalone/util - external/nativefiledialog-extended/src/include - external/imgui/imgui - external/imgui/imgui/backends - external/discord-rpc/include - external/unarr - ${SDL2_INCLUDE_DIRS} -) - add_compile_definitions(SIMD_SUPPORT) if(WIN32) add_definitions(-DNOMINMAX) @@ -56,39 +18,13 @@ if (HAS_SSSE3 AND HAS_SSE4_1) endif () if(${CMAKE_BUILD_TYPE} MATCHES Debug) + add_compile_definitions(VULKAN_DEBUG) #add_compile_options(-fsanitize=address -fsanitize=undefined) #add_link_options(-fsanitize=address -fsanitize=undefined) endif() -add_subdirectory(src/frontend) -add_subdirectory(src/frontend/imgui) -add_subdirectory(src/backend) -add_subdirectory(src/backend/netplay) -add_subdirectory(src/backend/core) -add_subdirectory(src/backend/core/interpreter) -add_subdirectory(src/backend/core/JIT) -add_subdirectory(src/backend/core/mem) -add_subdirectory(src/backend/core/mmio) -add_subdirectory(src/backend/core/registers) -add_subdirectory(src/backend/core/rsp) -add_subdirectory(external/discord-rpc) -add_subdirectory(external/imgui) -add_subdirectory(external/nativefiledialog-extended) -add_subdirectory(external/parallel-rdp) -add_subdirectory(external/unarr) +find_package(Qt6 COMPONENTS Core Gui Widgets) -add_executable(kaizen main.cpp) - -if(MSVC) - target_compile_options(parallel-rdp PUBLIC /EHa) -endif() - -file(COPY ${PROJECT_SOURCE_DIR}/resources/ DESTINATION ${PROJECT_BINARY_DIR}/resources/) -file(REMOVE - ${PROJECT_BINARY_DIR}/resources/mario.png - ${PROJECT_BINARY_DIR}/resources/shader.frag - ${PROJECT_BINARY_DIR}/resources/shader.vert) - -target_link_libraries(kaizen PUBLIC frontend frontend-imgui - discord-rpc imgui nfd parallel-rdp backend fmt::fmt mio::mio nlohmann_json::nlohmann_json core registers jit interpreter mem unarr mmio rsp SDL2::SDL2main SDL2::SDL2) -target_compile_options(kaizen PUBLIC -Wextra) +if (Qt6_FOUND) + add_subdirectory(src/frontend) +endif() \ No newline at end of file diff --git a/external/parallel-rdp/ParallelRDPWrapper.cpp b/external/parallel-rdp/ParallelRDPWrapper.cpp index 4af147db..6176df80 100644 --- a/external/parallel-rdp/ParallelRDPWrapper.cpp +++ b/external/parallel-rdp/ParallelRDPWrapper.cpp @@ -6,7 +6,6 @@ #include #include #include -#include using namespace Vulkan; using namespace RDP; @@ -70,13 +69,13 @@ void SetFramerateUnlocked(bool unlocked) { class SDLWSIPlatform final : public Vulkan::WSIPlatform { public: - SDLWSIPlatform() = default; + SDLWSIPlatform(SDL_Window* window) : window(window) {} std::vector get_instance_extensions() override { const char* extensions[64]; unsigned int num_extensions = 64; - if (!SDL_Vulkan_GetInstanceExtensions(g_Window, &num_extensions, extensions)) { + if (!SDL_Vulkan_GetInstanceExtensions(window, &num_extensions, extensions)) { Util::panic("SDL_Vulkan_GetInstanceExtensions failed: {}", SDL_GetError()); } auto vec = std::vector(); @@ -90,7 +89,7 @@ public: VkSurfaceKHR create_surface(VkInstance instance, VkPhysicalDevice gpu) override { VkSurfaceKHR vk_surface; - if (!SDL_Vulkan_CreateSurface(g_Window, instance, &vk_surface)) { + if (!SDL_Vulkan_CreateSurface(window, instance, &vk_surface)) { Util::panic("Failed to create Vulkan window surface: {}", SDL_GetError()); } return vk_surface; @@ -120,6 +119,8 @@ public: .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, .apiVersion = VK_API_VERSION_1_1 }; +private: + SDL_Window* window; }; Program* fullscreen_quad_program; @@ -184,8 +185,7 @@ void LoadParallelRDP(const u8* rdram) { } void InitParallelRDP(const u8* rdram, SDL_Window* window) { - g_Window = window; - LoadWSIPlatform(new SDLWSIPlatform(), std::make_unique()); + LoadWSIPlatform(new SDLWSIPlatform(window), std::make_unique(window)); LoadParallelRDP(rdram); } @@ -225,7 +225,7 @@ void DrawFullscreenTexturedQuad(Util::IntrusivePtr image, Util::Intrusive cmd->draw(3, 1); } -void UpdateScreen(n64::Core& core, Window& imguiWindow, Util::IntrusivePtr image) { +void UpdateScreen(n64::Core& core, Util::IntrusivePtr image) { wsi->begin_frame(); if (!image) { @@ -253,18 +253,14 @@ void UpdateScreen(n64::Core& core, Window& imguiWindow, Util::IntrusivePtr cmd = wsi->get_device().request_command_buffer(); cmd->begin_render_pass(wsi->get_device().get_swapchain_render_pass(SwapchainRenderPass::ColorOnly)); - ImDrawData* drawData = imguiWindow.Present(core); - DrawFullscreenTexturedQuad(image, cmd); - ImGui_ImplVulkan_RenderDrawData(drawData, cmd->get_command_buffer()); - cmd->end_render_pass(); wsi->get_device().submit(cmd); wsi->end_frame(); } -void UpdateScreenParallelRdp(n64::Core& core, Window& imguiWindow, n64::VI& vi) { +void UpdateScreenParallelRdp(n64::Core& core, n64::VI& vi) { command_processor->set_vi_register(VIRegister::Control, vi.status.raw); command_processor->set_vi_register(VIRegister::Origin, vi.origin); command_processor->set_vi_register(VIRegister::Width, vi.width); @@ -290,12 +286,12 @@ void UpdateScreenParallelRdp(n64::Core& core, Window& imguiWindow, n64::VI& vi) opts.downscale_steps = true; opts.crop_overscan_pixels = true; Util::IntrusivePtr image = command_processor->scanout(opts); - UpdateScreen(core, imguiWindow, image); + UpdateScreen(core, image); command_processor->begin_frame_context(); } -void UpdateScreenParallelRdpNoGame(n64::Core& core, Window& imguiWindow) { - UpdateScreen(core, imguiWindow, static_cast>(nullptr)); +void UpdateScreenParallelRdpNoGame(n64::Core& core) { + UpdateScreen(core, static_cast>(nullptr)); } void ParallelRdpEnqueueCommand(int command_length, u32* buffer) { diff --git a/external/parallel-rdp/ParallelRDPWrapper.hpp b/external/parallel-rdp/ParallelRDPWrapper.hpp index 6370a0da..945285a2 100644 --- a/external/parallel-rdp/ParallelRDPWrapper.hpp +++ b/external/parallel-rdp/ParallelRDPWrapper.hpp @@ -2,9 +2,6 @@ #include #include -struct Window; -static SDL_Window* g_Window; - class ParallelRdpWindowInfo { public: struct CoordinatePair { @@ -16,9 +13,12 @@ public: }; class SDLParallelRdpWindowInfo : public ParallelRdpWindowInfo { + SDL_Window* window; +public: + SDLParallelRdpWindowInfo(SDL_Window* window) : window(window) {} CoordinatePair get_window_size() { int width, height; - SDL_GetWindowSize(g_Window, &width, &height); + SDL_GetWindowSize(window, &width, &height); return CoordinatePair{ static_cast(width), static_cast(height) }; } }; @@ -33,9 +33,9 @@ VkFormat GetVkFormat(); VkCommandBuffer GetVkCommandBuffer(); void SubmitRequestedVkCommandBuffer(); void InitParallelRDP(const u8* rdram, SDL_Window* window); -void UpdateScreenParallelRdp(n64::Core& core, Window& imguiWindow, n64::VI& vi); +void UpdateScreenParallelRdp(n64::Core& core, n64::VI& vi); void ParallelRdpEnqueueCommand(int command_length, u32* buffer); void ParallelRdpOnFullSync(); -void UpdateScreenParallelRdpNoGame(n64::Core& core, Window& imguiWindow); +void UpdateScreenParallelRdpNoGame(n64::Core& core); bool IsFramerateUnlocked(); void SetFramerateUnlocked(bool unlocked); diff --git a/main.cpp b/main.cpp deleted file mode 100644 index 97c21a32..00000000 --- a/main.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include - -int main(int argc, char** argv) { - App app; - - if(argc > 1) { - if(argc > 2) { - LoadTAS(argv[2]); - } - app.window.LoadROM(app.core, argv[1]); - } - - app.Run(); - - return 0; -} \ No newline at end of file diff --git a/src/backend/CMakeLists.txt b/src/backend/CMakeLists.txt index 5206b441..2688032a 100644 --- a/src/backend/CMakeLists.txt +++ b/src/backend/CMakeLists.txt @@ -1,4 +1,8 @@ file(GLOB SOURCES *.cpp) file(GLOB HEADERS *.hpp) -add_library(backend ${SOURCES} ${HEADERS}) \ No newline at end of file +add_subdirectory(core) +add_subdirectory(netplay) + +add_library(backend ${SOURCES} ${HEADERS}) +target_link_libraries(backend PRIVATE core netplay) \ No newline at end of file diff --git a/src/backend/core/CMakeLists.txt b/src/backend/core/CMakeLists.txt index 460cee9a..7723a5a7 100644 --- a/src/backend/core/CMakeLists.txt +++ b/src/backend/core/CMakeLists.txt @@ -1,4 +1,11 @@ file(GLOB SOURCES *.cpp) file(GLOB HEADERS *.hpp) -add_library(core ${SOURCES} ${HEADERS}) \ No newline at end of file +add_subdirectory(interpreter) +add_subdirectory(mem) +add_subdirectory(mmio) +add_subdirectory(registers) +add_subdirectory(rsp) + +add_library(core ${SOURCES} ${HEADERS}) +target_link_libraries(core PRIVATE interpreter mem mmio unarr registers rsp) \ No newline at end of file diff --git a/src/backend/core/mmio/AI.cpp b/src/backend/core/mmio/AI.cpp index 0cce566a..1e64dd52 100644 --- a/src/backend/core/mmio/AI.cpp +++ b/src/backend/core/mmio/AI.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include namespace n64 { void AI::Reset() { diff --git a/src/backend/core/Audio.cpp b/src/backend/core/mmio/Audio.cpp similarity index 100% rename from src/backend/core/Audio.cpp rename to src/backend/core/mmio/Audio.cpp diff --git a/src/backend/core/Audio.hpp b/src/backend/core/mmio/Audio.hpp similarity index 100% rename from src/backend/core/Audio.hpp rename to src/backend/core/mmio/Audio.hpp diff --git a/src/backend/core/mmio/PIF/Device.cpp b/src/backend/core/mmio/PIF/Device.cpp index 8c02d470..d9eacb9e 100644 --- a/src/backend/core/mmio/PIF/Device.cpp +++ b/src/backend/core/mmio/PIF/Device.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include diff --git a/src/backend/MupenMovie.cpp b/src/backend/core/mmio/PIF/MupenMovie.cpp similarity index 99% rename from src/backend/MupenMovie.cpp rename to src/backend/core/mmio/PIF/MupenMovie.cpp index f6476683..99dc31bf 100644 --- a/src/backend/MupenMovie.cpp +++ b/src/backend/core/mmio/PIF/MupenMovie.cpp @@ -1,4 +1,4 @@ -#include +#include #include struct TASMovieHeader { diff --git a/src/backend/MupenMovie.hpp b/src/backend/core/mmio/PIF/MupenMovie.hpp similarity index 100% rename from src/backend/MupenMovie.hpp rename to src/backend/core/mmio/PIF/MupenMovie.hpp diff --git a/src/backend/core/registers/CMakeLists.txt b/src/backend/core/registers/CMakeLists.txt index 8efec528..ab9586cc 100644 --- a/src/backend/core/registers/CMakeLists.txt +++ b/src/backend/core/registers/CMakeLists.txt @@ -2,3 +2,4 @@ file(GLOB_RECURSE SOURCES *.cpp) file(GLOB_RECURSE HEADERS *.cpp) add_library(registers ${SOURCES} ${HEADERS}) +target_link_libraries(registers PRIVATE interpreter) diff --git a/src/frontend/App.cpp b/src/frontend/App.cpp deleted file mode 100644 index e9a0c75a..00000000 --- a/src/frontend/App.cpp +++ /dev/null @@ -1,127 +0,0 @@ -#include -#include - -App::App() : window(core) { - DiscordEventHandlers handlers{}; - Discord_Initialize("1049669178124148806", &handlers, 1, nullptr); - Util::UpdateRPC(Util::Idling); -} - -void App::Run() { - SDL_EventState(SDL_DROPFILE, SDL_ENABLE); - n64::SI& si = core.cpu->mem.mmio.si; - - while (!window.done) { - SDL_Event event; - while (SDL_PollEvent(&event)) { - ImGui_ImplSDL2_ProcessEvent(&event); - switch(event.type) { - case SDL_QUIT: - window.done = true; - break; - case SDL_WINDOWEVENT: - window.handleEvents(event, core); - break; - case SDL_CONTROLLERDEVICEADDED: { - const int index = event.cdevice.which; - si.pif.gamepad = SDL_GameControllerOpen(index); - si.pif.gamepadConnected = false; - if (!si.pif.gamepad) { - Util::warn("[WARN]: Could not initialize gamepad: {}", SDL_GetError()); - } else { - si.pif.gamepadConnected = true; - } - } break; - case SDL_CONTROLLERDEVICEREMOVED: - SDL_GameControllerClose(si.pif.gamepad); - si.pif.gamepadConnected = false; - break; - case SDL_KEYDOWN: - switch (event.key.keysym.sym) { - case SDLK_o: { - OpenROMDialog(window, core); - } break; - case SDLK_F1: { - if(core.romLoaded && event.key.keysym.mod == KMOD_SHIFT) { - core.slot = 0; - } - } break; - case SDLK_F2: { - if(core.romLoaded && event.key.keysym.mod == KMOD_SHIFT) { - core.slot = 1; - } - } break; - case SDLK_F3: { - if(core.romLoaded && event.key.keysym.mod == KMOD_SHIFT) { - core.slot = 2; - } - } break; - case SDLK_F4: { - if(core.romLoaded && event.key.keysym.mod == KMOD_SHIFT) { - core.slot = 3; - } - } break; - case SDLK_F5: { - if(core.romLoaded) { - if(event.key.keysym.mod == KMOD_SHIFT) { - core.slot = 4; - } else { - core.Deserialize(); - } - } - } break; - case SDLK_F6: { - if(core.romLoaded) { - if(event.key.keysym.mod == KMOD_SHIFT) { - core.slot = 5; - } else { - core.Serialize(); - } - } - } break; - case SDLK_F7: { - if(core.romLoaded && event.key.keysym.mod == KMOD_SHIFT) { - core.slot = 6; - } - } break; - case SDLK_F8: { - if(core.romLoaded && event.key.keysym.mod == KMOD_SHIFT) { - core.slot = 7; - } - } break; - case SDLK_F9: { - if(core.romLoaded && event.key.keysym.mod == KMOD_SHIFT) { - core.slot = 8; - } - } break; - case SDLK_F10: { - if(core.romLoaded && event.key.keysym.mod == KMOD_SHIFT) { - core.slot = 9; - } - } break; - } - break; - case SDL_DROPFILE: { - char *droppedDir = event.drop.file; - if (droppedDir) { - window.LoadROM(core, droppedDir); - SDL_free(droppedDir); - } - } break; - } - } - - if(core.romLoaded) { - if(!core.pause) { - core.Run(window.settings.GetVolumeL(), window.settings.GetVolumeR()); - } - if(core.render) { - UpdateScreenParallelRdp(core, window, core.GetVI()); - } - } else { - if(core.render) { - UpdateScreenParallelRdpNoGame(core, window); - } - } - } -} \ No newline at end of file diff --git a/src/frontend/App.hpp b/src/frontend/App.hpp deleted file mode 100644 index 846adb73..00000000 --- a/src/frontend/App.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include -#include - -struct App { - App(); - ~App() { Util::ClearRPC(); } - void Run(); - n64::Core core; - Window window; -}; diff --git a/src/frontend/CMakeLists.txt b/src/frontend/CMakeLists.txt index f51c9e15..4ddb8818 100644 --- a/src/frontend/CMakeLists.txt +++ b/src/frontend/CMakeLists.txt @@ -1,4 +1,62 @@ -file(GLOB SOURCES *.cpp) -file(GLOB HEADERS *.hpp) +cmake_minimum_required(VERSION 3.20) +project(kaizen-qt) -add_library(frontend ${SOURCES} ${HEADERS}) \ No newline at end of file +set(CMAKE_CXX_STANDARD 17) + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets) +find_package(SDL2 REQUIRED) +find_package(fmt REQUIRED) +find_package(mio REQUIRED) +find_package(nlohmann_json REQUIRED) + +include_directories( + . + ../ + ../utils + ../backend + ../backend/core + ../backend/core/mmio + ../backend/core/registers + ../backend/core/rsp + ../../external/ + ../../external/xbyak + ../../external/parallel-rdp + ../../external/parallel-rdp/parallel-rdp-standalone/parallel-rdp + ../../external/parallel-rdp/parallel-rdp-standalone/volk + ../../external/parallel-rdp/parallel-rdp-standalone/spirv-cross + ../../external/parallel-rdp/parallel-rdp-standalone/vulkan + ../../external/parallel-rdp/parallel-rdp-standalone/vulkan-headers/include + ../../external/parallel-rdp/parallel-rdp-standalone/util + ../../external/nativefiledialog-extended/src/include + ../../external/imgui/imgui + ../../external/imgui/imgui/backends + ../../external/discord-rpc/include + ../../external/unarr + ${SDL2_INCLUDE_DIRS} +) + +add_subdirectory(../backend backend) +add_subdirectory(../../external/discord-rpc discord-rpc) +add_subdirectory(../../external/nativefiledialog-extended nfd) +add_subdirectory(../../external/parallel-rdp parallel-rdp) +add_subdirectory(../../external/unarr unarr) + +option(RAPIDJSON_BUILD_DOC "Build rapidjson documentation." OFF) +option(RAPIDJSON_BUILD_EXAMPLES "Build rapidjson examples." OFF) +option(RAPIDJSON_BUILD_TESTS "Build rapidjson perftests and unittests." OFF) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +add_executable(kaizen-qt + main.cpp) + +target_link_libraries(kaizen-qt PUBLIC Qt6::Core Qt6::Gui Qt6::Widgets SDL2::SDL2 fmt::fmt mio::mio nlohmann_json::nlohmann_json + discord-rpc nfd parallel-rdp backend) + +file(COPY ../../resources/ DESTINATION ${PROJECT_BINARY_DIR}/resources/) +file(REMOVE + ${PROJECT_BINARY_DIR}/resources/mario.png + ${PROJECT_BINARY_DIR}/resources/shader.frag + ${PROJECT_BINARY_DIR}/resources/shader.vert) \ No newline at end of file diff --git a/src/frontend/Language.hpp b/src/frontend/Language.hpp deleted file mode 100644 index e6474ce0..00000000 --- a/src/frontend/Language.hpp +++ /dev/null @@ -1,105 +0,0 @@ -#pragma once -#include -#include -#include - -namespace Language { - -enum StringID { - MENU_FILE, - FILE_ITEM_OPEN, - FILE_ITEM_EXIT, - MENU_EMULATION, - EMULATION_ITEM_RESET, - EMULATION_ITEM_STOP, - EMULATION_ITEM_PAUSE, - EMULATION_ITEM_RESUME, - EMULATION_ITEM_SETTINGS, - EMULATION_ITEM_LOAD_STATE, - EMULATION_ITEM_SAVE_STATE, - EMULATION_MENU_STATES, - STATES_ITEM_SLOT, - SETTINGS_CATEGORY_CPU, - SETTINGS_CATEGORY_AUDIO, - SETTINGS_CATEGORY_INTERFACE, - SETTINGS_OPTION_MUTE, - SETTINGS_OPTION_VOLUME_L, - SETTINGS_OPTION_VOLUME_R, - SETTINGS_OPTION_LOCK_CHANNELS, - SETTINGS_OPTION_ENABLE_JIT, - SETTINGS_OPTION_LANGUAGE, - SETTINGS_CLOSE, - STRING_COUNT -}; - -static const std::map english = { - {MENU_FILE, "File"}, - {FILE_ITEM_OPEN, "Open"}, - {FILE_ITEM_EXIT, "Exit"}, - {MENU_EMULATION, "Emulation"}, - {EMULATION_ITEM_RESET, "Reset"}, - {EMULATION_ITEM_STOP, "Stop"}, - {EMULATION_ITEM_PAUSE, "Pause"}, - {EMULATION_ITEM_RESUME, "Resume"}, - {EMULATION_ITEM_SETTINGS, "Settings"}, - {EMULATION_ITEM_LOAD_STATE, "Load state..."}, - {EMULATION_ITEM_SAVE_STATE, "Save state..."}, - {EMULATION_MENU_STATES, "Select save slot"}, - {STATES_ITEM_SLOT, "Slot {}"}, - {SETTINGS_CATEGORY_CPU, "CPU"}, - {SETTINGS_CATEGORY_AUDIO, "Audio"}, - {SETTINGS_CATEGORY_INTERFACE, "Interface"}, - {SETTINGS_OPTION_MUTE, "Mute"}, - {SETTINGS_OPTION_VOLUME_L, "Volume L"}, - {SETTINGS_OPTION_VOLUME_R, "Volume R"}, - {SETTINGS_OPTION_LOCK_CHANNELS, "Lock channels"}, - {SETTINGS_OPTION_ENABLE_JIT, "Enable JIT"}, - {SETTINGS_OPTION_LANGUAGE, "Language"}, - {SETTINGS_CLOSE, "Close"} -}; - -static const std::map italian = { - {MENU_FILE, "File"}, - {FILE_ITEM_OPEN, "Apri"}, - {FILE_ITEM_EXIT, "Esci"}, - {MENU_EMULATION, "Emulazione"}, - {EMULATION_ITEM_RESET, "Reset"}, - {EMULATION_ITEM_STOP, "Stop"}, - {EMULATION_ITEM_PAUSE, "Pausa"}, - {EMULATION_ITEM_RESUME, "Riprendi"}, - {EMULATION_ITEM_SETTINGS, "Opzioni"}, - {EMULATION_ITEM_LOAD_STATE, "Carica stato..."}, - {EMULATION_ITEM_SAVE_STATE, "Salva stato..."}, - {EMULATION_MENU_STATES, "Seleziona slot"}, - {STATES_ITEM_SLOT, "Slot {}"}, - {SETTINGS_CATEGORY_CPU, "CPU"}, - {SETTINGS_CATEGORY_AUDIO, "Audio"}, - {SETTINGS_CATEGORY_INTERFACE, "Interfaccia"}, - {SETTINGS_OPTION_MUTE, "Muta"}, - {SETTINGS_OPTION_VOLUME_L, "Volume L"}, - {SETTINGS_OPTION_VOLUME_R, "Volume R"}, - {SETTINGS_OPTION_LOCK_CHANNELS, "Blocca canali"}, - {SETTINGS_OPTION_ENABLE_JIT, "Abilita JIT"}, - {SETTINGS_OPTION_LANGUAGE, "Lingua"}, - {SETTINGS_CLOSE, "Chiudi"} -}; - -enum AvailableLangs { - ENGLISH, - ITALIAN, - AVAILABLE_LANGS_COUNT -}; - -static const std::array languages = { - "English", - "Italiano" -}; - -static FORCE_INLINE void SetLanguage(std::map& lang, int selectedLang) { - switch (selectedLang) { - case AvailableLangs::ENGLISH: lang = english; break; - case AvailableLangs::ITALIAN: lang = italian; break; - default: Util::panic("Language not supported, index {}\n", selectedLang); - } -} -} \ No newline at end of file diff --git a/src/frontend/imgui/CMakeLists.txt b/src/frontend/imgui/CMakeLists.txt deleted file mode 100644 index 7712496e..00000000 --- a/src/frontend/imgui/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -file(GLOB SOURCES *.cpp) -file(GLOB HEADERS *.hpp) - -if(WIN32) - add_compile_definitions(SDL_MAIN_HANDLED) -endif() - -add_library(frontend-imgui ${SOURCES} ${HEADERS}) \ No newline at end of file diff --git a/src/frontend/imgui/Settings.cpp b/src/frontend/imgui/Settings.cpp deleted file mode 100644 index 9cb279ce..00000000 --- a/src/frontend/imgui/Settings.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include -#include -#include -#include -#include - -namespace fs = std::filesystem; -#define GET_TRANSLATED_STRING(x) languageStrings[(x)] - -#define checknestedjsonentry(name, type, param1, param2, defaultVal) \ - do { \ - auto name##Entry = settings[param1][param2]; \ - if(!name##Entry.empty()) { \ - auto value = name##Entry.get(); \ - (name) = value; \ - } else { \ - settingsFile.clear(); \ - settings[param1][param2] = defaultVal; \ - settingsFile << settings; \ - (name) = defaultVal; \ - } \ - } while(0) - -#define checkjsonentry(name, type, param, defaultVal) \ - do { \ - auto name##Entry = settings[param]; \ - if(!name##Entry.empty()) { \ - auto value = name##Entry.get(); \ - (name) = value; \ - } else { \ - settingsFile.clear(); \ - settings[param] = defaultVal; \ - settingsFile << settings; \ - (name) = defaultVal; \ - } \ - } while(0) - - -Settings::Settings(n64::Core& core) { - auto fileExists = fs::exists("resources/settings.json"); - std::fstream settingsFile; - if(fileExists) { - settingsFile = std::fstream("resources/settings.json", std::fstream::in | std::fstream::out); - settings = json::parse(settingsFile); - - checknestedjsonentry(oldVolumeL, float, "audio", "volumeL", 0.5); - checknestedjsonentry(oldVolumeR, float, "audio", "volumeR", 0.5); - checknestedjsonentry(mute, bool, "audio", "mute", false); - volumeL = mute ? 0 : oldVolumeL; - volumeR = mute ? 0 : oldVolumeR; - checknestedjsonentry(lockChannels, bool, "audio", "lockChannels", true); - checknestedjsonentry(jit, bool, "cpu", "enableJIT", false); - checkjsonentry(selectedLanguage, int, "language", Language::ENGLISH); - } else { - settingsFile = std::fstream("resources/settings.json", std::fstream::trunc | std::fstream::in | std::fstream::out); - settings["audio"]["volumeR"] = 0.5; - settings["audio"]["volumeL"] = 0.5; - settings["audio"]["lockChannels"] = true; - settings["audio"]["mute"] = false; - settings["cpu"]["enableJIT"] = false; - settings["language"] = Language::ENGLISH; - - oldVolumeR = volumeR = 0.5; - oldVolumeL = volumeL = 0.5; - lockChannels = true; - mute = false; - jit = false; - - settingsFile << settings; - } - - Language::SetLanguage(languageStrings, selectedLanguage); - - if(jit) { - core.cpu = std::make_unique(); - } else { - core.cpu = std::make_unique(); - } - settingsFile.close(); -} - -Settings::~Settings() { - auto fileExists = fs::exists("resources/settings.json"); - std::fstream settingsFile; - if(fileExists) { - settingsFile = std::fstream("resources/settings.json", std::fstream::trunc | std::fstream::out); - } else { - settingsFile = std::fstream("resources/settings.json", std::fstream::out); - } - - settings["audio"]["volumeR"] = oldVolumeR; - settings["audio"]["volumeL"] = oldVolumeL; - settings["audio"]["lockChannels"] = lockChannels; - settings["audio"]["mute"] = mute; - settings["cpu"]["enableJIT"] = jit; - settings["language"] = selectedLanguage; - settingsFile << settings; - - settingsFile.close(); -} - -void Settings::RenderWidget(const int& mWw, const int& mWh, bool& show) { - if(show) { - ImGui::OpenPopup("##settings"); - const float posX = (float)mWw * (1.f / 32.f), posY = (float)mWh * (1.f / 32.f) + 20; - const float sizeX = (float)mWw * (30.f / 32.f), sizeY = (float)mWh * (30.f / 32.f) - 20; - ImGui::SetNextWindowPos({ posX, posY }); - ImGui::SetNextWindowSize({ sizeX, sizeY }); - if(ImGui::BeginPopupModal("##settings", &show, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove)) { - if (ImGui::BeginTabBar("##categories")) { - if (ImGui::BeginTabItem(GET_TRANSLATED_STRING(Language::SETTINGS_CATEGORY_CPU))) { - ImGui::Checkbox(GET_TRANSLATED_STRING(Language::SETTINGS_OPTION_ENABLE_JIT), &jit); - ImGui::EndTabItem(); - } - - if (ImGui::BeginTabItem(GET_TRANSLATED_STRING(Language::SETTINGS_CATEGORY_AUDIO))) { - ImGui::Checkbox(GET_TRANSLATED_STRING(Language::SETTINGS_OPTION_LOCK_CHANNELS), &lockChannels); - ImGui::Checkbox(GET_TRANSLATED_STRING(Language::SETTINGS_OPTION_MUTE), &mute); - if (mute) { - volumeL = 0; - volumeR = 0; - - ImGui::BeginDisabled(); - ImGui::SliderFloat(GET_TRANSLATED_STRING(Language::SETTINGS_OPTION_VOLUME_L), &oldVolumeL, 0, 1, "%.2f", ImGuiSliderFlags_NoInput); - if (lockChannels) { - oldVolumeR = oldVolumeL; - } - ImGui::SliderFloat(GET_TRANSLATED_STRING(Language::SETTINGS_OPTION_VOLUME_R), &oldVolumeR, 0, 1, "%.2f", ImGuiSliderFlags_NoInput); - ImGui::EndDisabled(); - } - else { - volumeL = oldVolumeL; - volumeR = oldVolumeR; - - ImGui::SliderFloat(GET_TRANSLATED_STRING(Language::SETTINGS_OPTION_VOLUME_L), &volumeL, 0, 1, "%.2f", ImGuiSliderFlags_NoInput); - if (!lockChannels) { - ImGui::SliderFloat(GET_TRANSLATED_STRING(Language::SETTINGS_OPTION_VOLUME_R), &volumeR, 0, 1, "%.2f", ImGuiSliderFlags_NoInput); - } - else { - volumeR = volumeL; - ImGui::BeginDisabled(); - ImGui::SliderFloat(GET_TRANSLATED_STRING(Language::SETTINGS_OPTION_VOLUME_R), &volumeR, 0, 1, "%.2f", ImGuiSliderFlags_NoInput); - ImGui::EndDisabled(); - } - - oldVolumeL = volumeL; - oldVolumeR = volumeR; - } - - ImGui::EndTabItem(); - } - - if (ImGui::BeginTabItem(GET_TRANSLATED_STRING(Language::SETTINGS_CATEGORY_INTERFACE))) { - static auto currentLang = selectedLanguage; - const char* languages[Language::AVAILABLE_LANGS_COUNT] = { - Language::languages[Language::ENGLISH], - Language::languages[Language::ITALIAN] - }; - ImGui::Text("%s:", GET_TRANSLATED_STRING(Language::SETTINGS_OPTION_LANGUAGE)); - CreateComboList("##language", (int*)&selectedLanguage, languages, (int)Language::AVAILABLE_LANGS_COUNT); - ImGui::Separator(); - - if (currentLang != selectedLanguage) { - currentLang = selectedLanguage; - Language::SetLanguage(languageStrings, selectedLanguage); - } - - ImGui::EndTabItem(); - } - ImGui::EndTabBar(); - } - - const auto style = ImGui::GetStyle(); - ImGui::SetCursorPos({ - ImGui::GetWindowWidth() - ImGui::CalcTextSize(GET_TRANSLATED_STRING(Language::SETTINGS_CLOSE)).x - style.FramePadding.x * 5, - ImGui::GetWindowHeight() - ImGui::CalcTextSize(GET_TRANSLATED_STRING(Language::SETTINGS_CLOSE)).y - style.FramePadding.y * 5, - }); - if (ImGui::Button(GET_TRANSLATED_STRING(Language::SETTINGS_CLOSE))) show = false; - - ImGui::EndPopup(); - } - } -} \ No newline at end of file diff --git a/src/frontend/imgui/Settings.hpp b/src/frontend/imgui/Settings.hpp deleted file mode 100644 index 365c3b32..00000000 --- a/src/frontend/imgui/Settings.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include -#include - -namespace n64 { struct Core; } -using namespace nlohmann; - -struct Settings { - explicit Settings(n64::Core& core); - ~Settings(); - - [[nodiscard]] FORCE_INLINE float GetVolumeL() const { return volumeL; }; - [[nodiscard]] FORCE_INLINE float GetVolumeR() const { return volumeR; }; - - void RenderWidget(const int& mWw, const int& mWh, bool& show); - std::map languageStrings{}; -private: - bool jit = false; - float volumeL, volumeR; - float oldVolumeL, oldVolumeR; - bool lockChannels = true; - bool mute = false; - int selectedLanguage = Language::ENGLISH; - json settings; -}; diff --git a/src/frontend/imgui/Widgets.hpp b/src/frontend/imgui/Widgets.hpp deleted file mode 100644 index ddce214d..00000000 --- a/src/frontend/imgui/Widgets.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once -#include - -FORCE_INLINE bool CreateComboList(const char* label, int* index, const char** items, int items_count) { - if (ImGui::BeginCombo(label, items[*index])) { - for (int n = 0; n < items_count; n++) { - const bool is_selected = (*index == n); - if (ImGui::Selectable(items[n], is_selected)) { - *index = n; - } - - if (is_selected) { - ImGui::SetItemDefaultFocus(); - } - } - ImGui::EndCombo(); - return true; - } - - return false; -} \ No newline at end of file diff --git a/src/frontend/imgui/Window.cpp b/src/frontend/imgui/Window.cpp deleted file mode 100644 index b0751f7f..00000000 --- a/src/frontend/imgui/Window.cpp +++ /dev/null @@ -1,274 +0,0 @@ -#include -#include -#include -#include -#include -#include - -VkInstance instance{}; -namespace fs = std::filesystem; -#define GET_TRANSLATED_STRING(x) settings.languageStrings[(x)] - -Window::Window(n64::Core& core) : settings(core) { - InitSDL(); - InitParallelRDP(core.cpu->mem.GetRDRAM(), window); - InitImgui(); - NFD::Init(); -} - -void Window::handleEvents(SDL_Event event, n64::Core& core) { - done = event.window.event == (u8)SDL_WINDOWEVENT_CLOSE - && event.window.windowID == SDL_GetWindowID(window); - - bool minimized = SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED; - core.pause = event.window.event == (u8)SDL_WINDOWEVENT_FOCUS_LOST || minimized; - core.render = !minimized; -} - -static void check_vk_result(VkResult err) { - if (err != VK_SUCCESS) { - Util::panic("[vulkan] Error: VkResult = {}", static_cast(err)); - } -} - -void Window::InitSDL() { - SDL_Init(SDL_INIT_EVERYTHING); - n64::InitAudio(); - - windowTitle = "Kaizen"; - window = SDL_CreateWindow( - "Kaizen", - SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, - 1024, 768, - SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI - ); - - if(!window) { - Util::panic("Could not create SDL window: {}", SDL_GetError()); - } - - check_vk_result(volkInitialize()); -} - -void Window::InitImgui() { - VkResult err; - - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - ImGuiIO& io = ImGui::GetIO(); - (void)io; - - // Setup Dear ImGui style - ImGui::StyleColorsDark(); - - instance = GetVkInstance(); - physicalDevice = GetVkPhysicalDevice(); - device = GetVkDevice(); - queueFamily = GetVkGraphicsQueueFamily(); - queue = GetGraphicsQueue(); - pipelineCache = nullptr; - descriptorPool = nullptr; - allocator = nullptr; - minImageCount = 2; - - ImGui_ImplVulkan_LoadFunctions([](const char* function_name, void*) { return vkGetInstanceProcAddr(instance, function_name); }); - - { - VkDescriptorPoolSize poolSizes[] = { - { VK_DESCRIPTOR_TYPE_SAMPLER, 1000 }, - { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 }, - { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 }, - { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 }, - { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 }, - { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 }, - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 }, - { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 }, - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 }, - { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 }, - { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 } - }; - - VkDescriptorPoolCreateInfo poolInfo{}; - - poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - poolInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; - poolInfo.maxSets = 1000 * IM_ARRAYSIZE(poolSizes); - poolInfo.poolSizeCount = (uint32_t)IM_ARRAYSIZE(poolSizes); - poolInfo.pPoolSizes = poolSizes; - err = vkCreateDescriptorPool(device, &poolInfo, allocator, &descriptorPool); - check_vk_result(err); - } - - // Setup Platform/Renderer backends - ImGui_ImplSDL2_InitForVulkan(window); - ImGui_ImplVulkan_InitInfo initInfo = {}; - initInfo.Instance = instance; - initInfo.PhysicalDevice = physicalDevice; - initInfo.Device = device; - initInfo.QueueFamily = queueFamily; - initInfo.Queue = queue; - initInfo.PipelineCache = pipelineCache; - initInfo.DescriptorPool = descriptorPool; - initInfo.Allocator = allocator; - initInfo.MinImageCount = minImageCount; - initInfo.ImageCount = 2; - initInfo.MSAASamples = VK_SAMPLE_COUNT_1_BIT; - initInfo.CheckVkResultFn = check_vk_result; - ImGui_ImplVulkan_Init(&initInfo, GetVkRenderPass()); - - int displayIndex = SDL_GetWindowDisplayIndex(window); - float ddpi, hdpi, vdpi; - SDL_GetDisplayDPI(displayIndex, &ddpi, &hdpi, &vdpi); - - ddpi /= 96.f; - - uiFont = io.Fonts->AddFontFromFileTTF("resources/OpenSans.ttf", 16.f * ddpi); - - ImGui::GetStyle().ScaleAllSizes(ddpi); - - { - VkCommandBuffer commandBuffer = GetVkCommandBuffer(); - ImGui_ImplVulkan_CreateFontsTexture(commandBuffer); - SubmitRequestedVkCommandBuffer(); - } -} - -Window::~Window() { - auto err = vkDeviceWaitIdle(device); - check_vk_result(err); - ImGui_ImplVulkan_Shutdown(); - ImGui_ImplSDL2_Shutdown(); - ImGui::DestroyContext(); - - SDL_DestroyWindow(window); - SDL_DestroyWindow(g_Window); - SDL_Quit(); -} - -ImDrawData* Window::Present(n64::Core& core) { - ImGui_ImplVulkan_NewFrame(); - ImGui_ImplSDL2_NewFrame(window); - ImGui::NewFrame(); - - Render(core); - - ImGui::Render(); - return ImGui::GetDrawData(); -} - -void Window::LoadROM(n64::Core& core, const std::string &path) { - if(!path.empty()) { - core.LoadROM(path); - gameName = core.cpu->mem.rom.gameNameDB; - - if(gameName.empty()) { - gameName = fs::path(path).stem().string(); - } - - Util::UpdateRPC(Util::Playing, gameName); - windowTitle = "Kaizen - " + gameName; - shadowWindowTitle = windowTitle; - - SDL_SetWindowTitle(window, windowTitle.c_str()); - } -} - -void Window::RenderMainMenuBar(n64::Core &core) { - ImGui::BeginMainMenuBar(); - - if (ImGui::BeginMenu(GET_TRANSLATED_STRING(Language::MENU_FILE))) { - if (ImGui::MenuItem(GET_TRANSLATED_STRING(Language::FILE_ITEM_OPEN), "O")) { - OpenROMDialog(*this, core); - } - if (ImGui::MenuItem("Dump RDRAM")) { - core.cpu->mem.DumpRDRAM(); - } - if (ImGui::MenuItem("Dump IMEM")) { - core.cpu->mem.DumpIMEM(); - } - if (ImGui::MenuItem("Dump DMEM")) { - core.cpu->mem.DumpDMEM(); - } - if (ImGui::MenuItem(GET_TRANSLATED_STRING(Language::FILE_ITEM_EXIT))) { - done = true; - } - ImGui::EndMenu(); - } - if (ImGui::BeginMenu(GET_TRANSLATED_STRING(Language::MENU_EMULATION))) { - if (ImGui::MenuItem(GET_TRANSLATED_STRING(Language::EMULATION_ITEM_RESET))) { - LoadROM(core, core.rom); - } - if (ImGui::MenuItem(GET_TRANSLATED_STRING(Language::EMULATION_ITEM_STOP))) { - windowTitle = "Kaizen"; - core.rom.clear(); - Util::UpdateRPC(Util::Idling); - SDL_SetWindowTitle(window, windowTitle.c_str()); - core.Stop(); - } - if (ImGui::MenuItem(core.pause ? GET_TRANSLATED_STRING(Language::EMULATION_ITEM_RESUME) - : GET_TRANSLATED_STRING(Language::EMULATION_ITEM_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::BeginMenu(GET_TRANSLATED_STRING(Language::EMULATION_MENU_STATES))) { - if(ImGui::MenuItem(fmt::format(GET_TRANSLATED_STRING(Language::STATES_ITEM_SLOT), 0).c_str())) { core.slot = 0; } - if(ImGui::MenuItem(fmt::format(GET_TRANSLATED_STRING(Language::STATES_ITEM_SLOT), 1).c_str())) { core.slot = 1; } - if(ImGui::MenuItem(fmt::format(GET_TRANSLATED_STRING(Language::STATES_ITEM_SLOT), 2).c_str())) { core.slot = 2; } - if(ImGui::MenuItem(fmt::format(GET_TRANSLATED_STRING(Language::STATES_ITEM_SLOT), 3).c_str())) { core.slot = 3; } - if(ImGui::MenuItem(fmt::format(GET_TRANSLATED_STRING(Language::STATES_ITEM_SLOT), 4).c_str())) { core.slot = 4; } - if(ImGui::MenuItem(fmt::format(GET_TRANSLATED_STRING(Language::STATES_ITEM_SLOT), 5).c_str())) { core.slot = 5; } - if(ImGui::MenuItem(fmt::format(GET_TRANSLATED_STRING(Language::STATES_ITEM_SLOT), 6).c_str())) { core.slot = 6; } - if(ImGui::MenuItem(fmt::format(GET_TRANSLATED_STRING(Language::STATES_ITEM_SLOT), 7).c_str())) { core.slot = 7; } - if(ImGui::MenuItem(fmt::format(GET_TRANSLATED_STRING(Language::STATES_ITEM_SLOT), 8).c_str())) { core.slot = 8; } - if(ImGui::MenuItem(fmt::format(GET_TRANSLATED_STRING(Language::STATES_ITEM_SLOT), 9).c_str())) { core.slot = 9; } - ImGui::EndMenu(); - } - - if(ImGui::MenuItem(GET_TRANSLATED_STRING(Language::EMULATION_ITEM_LOAD_STATE), "F5", false, core.romLoaded)) { - core.Deserialize(); - } - if(ImGui::MenuItem(GET_TRANSLATED_STRING(Language::EMULATION_ITEM_SAVE_STATE), "F6", false, core.romLoaded)) { - core.Serialize(); - } - if (ImGui::MenuItem(GET_TRANSLATED_STRING(Language::EMULATION_ITEM_SETTINGS))) { - showSettings = true; - } - ImGui::EndMenu(); - } - ImGui::EndMainMenuBar(); -} - -void Window::Render(n64::Core& core) { - ImGui::PushFont(uiFont); - - u32 ticks = SDL_GetTicks(); - static u32 lastFrame = 0; - if(!core.pause && core.romLoaded && lastFrame < ticks - 1000) { - lastFrame = ticks; - windowTitle += fmt::format(" | {:02d} VI/s", core.cpu->mem.mmio.vi.swaps); - core.cpu->mem.mmio.vi.swaps = 0; - SDL_SetWindowTitle(window, windowTitle.c_str()); - windowTitle = shadowWindowTitle; - } - - if(SDL_GetMouseFocus()) { - RenderMainMenuBar(core); - } - - int w, h; - SDL_GetWindowSize(window, &w, &h); - - settings.RenderWidget(w, h, showSettings); - - ImGui::PopFont(); -} diff --git a/src/frontend/imgui/Window.hpp b/src/frontend/imgui/Window.hpp deleted file mode 100644 index 0cc0dbcc..00000000 --- a/src/frontend/imgui/Window.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include "Discord.hpp" - -struct Window { - explicit Window(n64::Core& core); - ~Window(); - ImDrawData* Present(n64::Core& core); - - void handleEvents(SDL_Event event, n64::Core&); - ImFont *uiFont{}; - Settings settings; - void LoadROM(n64::Core& core, const std::string& path); - bool done = false; - std::string gameName{}; -private: - bool showSettings = false; - SDL_Window* window{}; - std::string windowTitle{"Kaizen"}; - std::string shadowWindowTitle{windowTitle}; - void InitSDL(); - void InitImgui(); - void Render(n64::Core& core); - void RenderMainMenuBar(n64::Core& core); - - VkPhysicalDevice physicalDevice{}; - VkDevice device{}; - uint32_t queueFamily{uint32_t(-1)}; - VkQueue queue{}; - VkPipelineCache pipelineCache{}; - VkDescriptorPool descriptorPool{}; - VkAllocationCallbacks* allocator{}; - - u32 minImageCount = 2; -}; - -static void FORCE_INLINE OpenROMDialog(Window& window, n64::Core& core) { - nfdchar_t *outpath; - const nfdu8filteritem_t filter{"Nintendo 64 roms/archives", "n64,z64,v64,N64,Z64,V64,zip,tar,rar,7z"}; - nfdresult_t result = NFD_OpenDialog(&outpath, &filter, 1, nullptr); - if (result == NFD_OKAY) { - window.LoadROM(core, outpath); - NFD_FreePath(outpath); - } -} \ No newline at end of file diff --git a/src/frontend/main.cpp b/src/frontend/main.cpp new file mode 100644 index 00000000..a90ecc21 --- /dev/null +++ b/src/frontend/main.cpp @@ -0,0 +1,16 @@ +#include +#include +#include + +int main(int argc, char** argv) { + QApplication app(argc, argv); + app.setStyle("fusion"); + QCoreApplication::setOrganizationName("kaizen"); + QCoreApplication::setApplicationName("Kaizen"); + QCommandLineParser parser; + parser.setApplicationDescription(QCoreApplication::applicationName()); + parser.addHelpOption(); + parser.addPositionalArgument("rom", "Rom to launch from command-line"); + parser.process(app); + return app.exec(); +} \ No newline at end of file