diff --git a/src/backend/GameDB.cpp b/src/backend/GameDB.cpp index a8cde05d..e2f7dc61 100644 --- a/src/backend/GameDB.cpp +++ b/src/backend/GameDB.cpp @@ -1,18 +1,17 @@ #include #include -#include -#include namespace n64 { void GameDB::match(Mem& mem) { ROM& rom = mem.rom; bool found = false; - std::for_each(std::execution::par, std::begin(gamedb), std::end(gamedb), [&](const auto& i) { - bool matches_code = i.code == rom.code; + + for(const auto& i : {std::begin(gamedb), std::end(gamedb)}) { + bool matches_code = i->code == rom.code; bool matches_region = false; - for (int j = 0; j < i.regions.size() && !matches_region; j++) { - if (i.regions[j] == rom.header.countryCode[0]) { + for (int j = 0; j < i->regions.size() && !matches_region; j++) { + if (i->regions[j] == rom.header.countryCode[0]) { matches_region = true; } } @@ -20,18 +19,18 @@ void GameDB::match(Mem& mem) { if (matches_code) { found = true; if (matches_region) { - mem.saveType = i.saveType; - mem.rom.gameNameDB = i.name; - return; + mem.saveType = i->saveType; + mem.rom.gameNameDB = i->name; + break; } else { Util::warn("Matched code for {}, but not region! Game supposedly exists in regions [{}] but this image has region {}", - i.name, i.regions, rom.header.countryCode[0]); - mem.saveType = i.saveType; - mem.rom.gameNameDB = i.name; - return; + i->name, i->regions, rom.header.countryCode[0]); + mem.saveType = i->saveType; + mem.rom.gameNameDB = i->name; + break; } } - }); + } if(!found) { Util::debug("Did not match any Game DB entries. Code: {} Region: {}", mem.rom.code, mem.rom.header.countryCode[0]); diff --git a/src/backend/core/mmio/Audio.cpp b/src/backend/core/mmio/Audio.cpp index 900924d7..06fff418 100644 --- a/src/backend/core/mmio/Audio.cpp +++ b/src/backend/core/mmio/Audio.cpp @@ -1,5 +1,6 @@ #include #include +#include namespace n64 { #define AUDIO_SAMPLE_RATE 44100 diff --git a/src/backend/core/mmio/Audio.hpp b/src/backend/core/mmio/Audio.hpp index 25cc1730..487a221c 100644 --- a/src/backend/core/mmio/Audio.hpp +++ b/src/backend/core/mmio/Audio.hpp @@ -1,6 +1,6 @@ #pragma once #include -#include +#include namespace n64 { struct AudioDevice { diff --git a/src/backend/core/mmio/PIF.cpp b/src/backend/core/mmio/PIF.cpp index 7b92782c..e494265e 100644 --- a/src/backend/core/mmio/PIF.cpp +++ b/src/backend/core/mmio/PIF.cpp @@ -5,10 +5,81 @@ #include #include #include +#include #define MEMPAK_SIZE 32768 namespace n64 { +PIF::PIF(n64::Mem &mem, n64::Registers ®s) : mem(mem), regs(regs) { + SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER); + + if(SDL_GameControllerAddMappingsFromFile("resources/gamecontrollerdb.txt") < 0) { + Util::warn("[SDL] Could not load game controller DB"); + } +} + +void PIF::UpdateController(int index) { + SDL_Event e; + while(SDL_PollEvent(&e)) { + switch(e.type) { + case SDL_CONTROLLERDEVICEADDED: { + const int controllerIndex = e.cdevice.which; + controller = SDL_GameControllerOpen(controllerIndex); + Util::info("Found controller!"); + auto serial = SDL_GameControllerGetSerial(controller); + auto name = SDL_GameControllerName(controller); + auto path = SDL_GameControllerPath(controller); + Util::info("\tName: {}", name ? name : "Not available"); + Util::info("\tSerial: {}", serial ? serial : "Not available"); + Util::info("\tPath: {}", path ? path : "Not available"); + controllerConnected = true; + } break; + case SDL_CONTROLLERDEVICEREMOVED: { + controllerConnected = false; + SDL_GameControllerClose(controller); + } break; + } + } + + if(controllerConnected) { + UpdateButton(index, Controller::Key::A, SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_A)); + UpdateButton(index, Controller::Key::B, SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_X)); + UpdateButton(index, Controller::Key::Z, SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT) == SDL_JOYSTICK_AXIS_MAX); + UpdateButton(index, Controller::Key::Start, SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_START)); + UpdateButton(index, Controller::Key::DUp, SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_UP)); + UpdateButton(index, Controller::Key::DDown, SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_DOWN)); + UpdateButton(index, Controller::Key::DLeft, SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_LEFT)); + UpdateButton(index, Controller::Key::DRight, SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_RIGHT)); + UpdateButton(index, Controller::Key::LT, SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_LEFTSHOULDER)); + UpdateButton(index, Controller::Key::RT, SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)); + UpdateButton(index, Controller::Key::CUp, SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY) <= -127); + UpdateButton(index, Controller::Key::CDown, SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY) >= 127); + UpdateButton(index, Controller::Key::CLeft, SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX) <= -127); + UpdateButton(index, Controller::Key::CRight, SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX) >= 127); + + float xclamped = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTX); + if(xclamped < 0) { + xclamped /= float(std::abs(SDL_JOYSTICK_AXIS_MIN)); + } else { + xclamped /= SDL_JOYSTICK_AXIS_MAX; + } + + xclamped *= 86; + + float yclamped = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); + if(yclamped < 0) { + yclamped /= float(std::abs(SDL_JOYSTICK_AXIS_MIN)); + } else { + yclamped /= SDL_JOYSTICK_AXIS_MAX; + } + + yclamped *= 86; + + UpdateAxis(0, Controller::Axis::Y, -yclamped); + UpdateAxis(0, Controller::Axis::X, xclamped); + } +} + void PIF::Reset() { memset(joybusDevices, 0, sizeof(JoybusDevice) * 6); memset(bootrom, 0, PIF_BOOTROM_SIZE); diff --git a/src/backend/core/mmio/PIF.hpp b/src/backend/core/mmio/PIF.hpp index 5945c274..1a3b935e 100644 --- a/src/backend/core/mmio/PIF.hpp +++ b/src/backend/core/mmio/PIF.hpp @@ -4,12 +4,12 @@ #include #include #include -#include "MupenMovie.hpp" +#include +#include namespace fs = std::filesystem; namespace n64 { - enum AccessoryType : u8 { ACCESSORY_NONE, ACCESSORY_MEMPACK, @@ -152,7 +152,7 @@ enum CICType { }; struct PIF { - PIF(Mem& mem, Registers& regs) : mem(mem), regs(regs) {} + PIF(Mem& mem, Registers& regs); ~PIF() = default; void Reset(); void MaybeLoadMempak(); @@ -177,6 +177,7 @@ struct PIF { joybusDevices[index].controller.UpdateAxis(a, state); } + bool controllerConnected = false; bool mempakOpen = false; JoybusDevice joybusDevices[6]{}; u8 bootrom[PIF_BOOTROM_SIZE]{}, ram[PIF_RAM_SIZE]{}; @@ -187,6 +188,7 @@ struct PIF { MupenMovie movie; Mem& mem; Registers& regs; + SDL_GameController* controller = nullptr; FORCE_INLINE u8 Read(u32 addr) { addr &= 0x7FF; @@ -207,5 +209,7 @@ struct PIF { return joybusDevices[channel].accessoryType; } } + + void UpdateController(int); }; } \ No newline at end of file diff --git a/src/backend/core/mmio/PIF/Device.cpp b/src/backend/core/mmio/PIF/Device.cpp index 441108be..18c62119 100644 --- a/src/backend/core/mmio/PIF/Device.cpp +++ b/src/backend/core/mmio/PIF/Device.cpp @@ -96,11 +96,11 @@ bool PIF::ReadButtons(u8* res) { case JOYBUS_16KB_EEPROM: case JOYBUS_CONTROLLER: if (movie.IsLoaded()) { - Controller controller = movie.NextInputs(); - res[0] = controller.byte1; - res[1] = controller.byte2; - res[2] = controller.joyX; - res[3] = controller.joyY; + Controller inputs = movie.NextInputs(); + res[0] = inputs.byte1; + res[1] = inputs.byte2; + res[2] = inputs.joyX; + res[3] = inputs.joyY; } else { res[0] = joybusDevices[channel].controller.byte1; res[1] = joybusDevices[channel].controller.byte2; diff --git a/src/frontend/CMakeLists.txt b/src/frontend/CMakeLists.txt index 67245770..9ff6d82b 100644 --- a/src/frontend/CMakeLists.txt +++ b/src/frontend/CMakeLists.txt @@ -4,7 +4,6 @@ project(kaizen-qt) set(CMAKE_CXX_STANDARD 17) find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets) -find_package(SDL2 CONFIG REQUIRED) include_directories( . @@ -32,7 +31,6 @@ include_directories( ../../external/imgui/imgui ../../external/imgui/imgui/backends ../../external/unarr - ${SDL2_INCLUDE_DIRS} ) option(RAPIDJSON_BUILD_DOC "Build rapidjson documentation." OFF) @@ -73,7 +71,6 @@ add_executable(kaizen-qt InputSettings.cpp) target_link_libraries(kaizen-qt PUBLIC Qt6::Core Qt6::Gui Qt6::Widgets fmt mio nlohmann_json nfd parallel-rdp backend) -target_compile_definitions(kaizen-qt PUBLIC SDL_MAIN_HANDLED) file(COPY ../../resources/ DESTINATION ${PROJECT_BINARY_DIR}/resources/) file(REMOVE diff --git a/src/frontend/EmuThread.cpp b/src/frontend/EmuThread.cpp index 61772f07..a88f5a06 100644 --- a/src/frontend/EmuThread.cpp +++ b/src/frontend/EmuThread.cpp @@ -6,41 +6,11 @@ EmuThread::EmuThread(std::unique_ptr&& instance_, std::unique_ptr&& wsiPlatform_, std::unique_ptr&& windowInfo_, SettingsWindow& settings) noexcept : instance(std::move(instance_)), wsiPlatform(std::move(wsiPlatform_)), windowInfo(std::move(windowInfo_)), - controller(SDL_GameControllerClose, "GameController"), core(parallel), settings(settings) {} [[noreturn]] void EmuThread::run() noexcept { parallel.Init(instance.get(), std::move(wsiPlatform), std::move(windowInfo), core.cpu->GetMem().GetRDRAMPtr()); - SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER); - bool controllerConnected = false; - - if(SDL_GameControllerAddMappingsFromFile("resources/gamecontrollerdb.txt") < 0) { - Util::warn("[SDL] Could not load game controller DB"); - } - - auto pollEvents = [&]() { - SDL_Event e; - while(SDL_PollEvent(&e)) { - switch(e.type) { - case SDL_CONTROLLERDEVICEADDED: { - const int index = e.cdevice.which; - controller.Construct(SDL_GameControllerOpen, index); - Util::info("Found controller!"); - auto serial = SDL_GameControllerGetSerial(controller.get()); - auto name = SDL_GameControllerName(controller.get()); - auto path = SDL_GameControllerPath(controller.get()); - Util::info("\tName: {}", name ? name : "Not available"); - Util::info("\tSerial: {}", serial ? serial : "Not available"); - Util::info("\tPath: {}", path ? path : "Not available"); - controllerConnected = true; - } break; - case SDL_CONTROLLERDEVICEREMOVED: { - controllerConnected = false; - controller.Destroy(); - } break; - } - } - }; + n64::PIF& pif = core.cpu->GetMem().mmio.si.pif; while (true) { if (!core.pause) { @@ -54,45 +24,6 @@ EmuThread::EmuThread(std::unique_ptr&& instance_, std::unique } } - pollEvents(); - - if(controllerConnected) { - n64::PIF& pif = core.cpu->GetMem().mmio.si.pif; - pif.UpdateButton(0, n64::Controller::Key::A, SDL_GameControllerGetButton(controller.get(), SDL_CONTROLLER_BUTTON_A)); - pif.UpdateButton(0, n64::Controller::Key::B, SDL_GameControllerGetButton(controller.get(), SDL_CONTROLLER_BUTTON_X)); - pif.UpdateButton(0, n64::Controller::Key::Z, SDL_GameControllerGetAxis(controller.get(), SDL_CONTROLLER_AXIS_TRIGGERLEFT) == SDL_JOYSTICK_AXIS_MAX); - pif.UpdateButton(0, n64::Controller::Key::Start, SDL_GameControllerGetButton(controller.get(), SDL_CONTROLLER_BUTTON_START)); - pif.UpdateButton(0, n64::Controller::Key::DUp, SDL_GameControllerGetButton(controller.get(), SDL_CONTROLLER_BUTTON_DPAD_UP)); - pif.UpdateButton(0, n64::Controller::Key::DDown, SDL_GameControllerGetButton(controller.get(), SDL_CONTROLLER_BUTTON_DPAD_DOWN)); - pif.UpdateButton(0, n64::Controller::Key::DLeft, SDL_GameControllerGetButton(controller.get(), SDL_CONTROLLER_BUTTON_DPAD_LEFT)); - pif.UpdateButton(0, n64::Controller::Key::DRight, SDL_GameControllerGetButton(controller.get(), SDL_CONTROLLER_BUTTON_DPAD_RIGHT)); - pif.UpdateButton(0, n64::Controller::Key::LT, SDL_GameControllerGetButton(controller.get(), SDL_CONTROLLER_BUTTON_LEFTSHOULDER)); - pif.UpdateButton(0, n64::Controller::Key::RT, SDL_GameControllerGetButton(controller.get(), SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)); - pif.UpdateButton(0, n64::Controller::Key::CUp, SDL_GameControllerGetAxis(controller.get(), SDL_CONTROLLER_AXIS_RIGHTY) <= -127); - pif.UpdateButton(0, n64::Controller::Key::CDown, SDL_GameControllerGetAxis(controller.get(), SDL_CONTROLLER_AXIS_RIGHTY) >= 127); - pif.UpdateButton(0, n64::Controller::Key::CLeft, SDL_GameControllerGetAxis(controller.get(), SDL_CONTROLLER_AXIS_RIGHTX) <= -127); - pif.UpdateButton(0, n64::Controller::Key::CRight, SDL_GameControllerGetAxis(controller.get(), SDL_CONTROLLER_AXIS_RIGHTX) >= 127); - - float xclamped = SDL_GameControllerGetAxis(controller.get(), SDL_CONTROLLER_AXIS_LEFTX); - if(xclamped < 0) { - xclamped /= float(std::abs(SDL_JOYSTICK_AXIS_MIN)); - } else { - xclamped /= SDL_JOYSTICK_AXIS_MAX; - } - - xclamped *= 86; - - float yclamped = SDL_GameControllerGetAxis(controller.get(), SDL_CONTROLLER_AXIS_LEFTY); - if(yclamped < 0) { - yclamped /= float(std::abs(SDL_JOYSTICK_AXIS_MIN)); - } else { - yclamped /= SDL_JOYSTICK_AXIS_MAX; - } - - yclamped *= 86; - - pif.UpdateAxis(0, n64::Controller::Axis::Y, -yclamped); - pif.UpdateAxis(0, n64::Controller::Axis::X, xclamped); - } + pif.UpdateController(0); } } \ No newline at end of file diff --git a/src/frontend/EmuThread.hpp b/src/frontend/EmuThread.hpp index 6963aeee..d3b8707d 100644 --- a/src/frontend/EmuThread.hpp +++ b/src/frontend/EmuThread.hpp @@ -4,7 +4,6 @@ #include #include #include -#include class EmuThread : public QThread { @@ -17,7 +16,6 @@ class EmuThread : public QThread [[noreturn]] void run() noexcept override; - Util::AutoRelease controller; ParallelRDP parallel; n64::Core core; SettingsWindow& settings;