diff --git a/CMakeLists.txt b/CMakeLists.txt index a5a00237..e0febad6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,10 +112,11 @@ add_executable(psoff main.cpp ) -add_dependencies(psoff logging core psOff_utility) +add_dependencies(psoff logging core psOff_utility gamereport) target_link_libraries(psoff PRIVATE core.lib + gamereport.lib psOff_utility libboost_filesystem $ diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index af70a170..a66d4898 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -10,6 +10,7 @@ add_subdirectory(initParams) add_subdirectory(timer) add_subdirectory(systemContent) add_subdirectory(networking) +add_subdirectory(hotkeys) add_subdirectory(trophies) add_subdirectory(fileManager) add_subdirectory(memory) @@ -24,6 +25,7 @@ add_library(core SHARED $ $ $ + $ $ $ $ @@ -33,7 +35,7 @@ add_library(core SHARED $ ) -add_dependencies(core logging third_party config_emu gamereport psoff_render) +add_dependencies(core logging third_party config_emu psoff_render) target_link_libraries(core PRIVATE libboost_url libboost_thread @@ -42,7 +44,6 @@ target_link_libraries(core PRIVATE libboost_filesystem sdl2 psoff_render.lib - gamereport.lib OptickCore psOff_utility config_emu.lib diff --git a/core/hotkeys/CMakeLists.txt b/core/hotkeys/CMakeLists.txt new file mode 100644 index 00000000..a760ac2d --- /dev/null +++ b/core/hotkeys/CMakeLists.txt @@ -0,0 +1,7 @@ +add_library(hotkeys OBJECT + hotkeys.cpp +) + +add_dependencies(hotkeys third_party config_emu) + +target_compile_definitions(hotkeys PUBLIC WIN32_LEAN_AND_MEAN) diff --git a/core/hotkeys/hotkeys.cpp b/core/hotkeys/hotkeys.cpp new file mode 100644 index 00000000..8f7dcff5 --- /dev/null +++ b/core/hotkeys/hotkeys.cpp @@ -0,0 +1,142 @@ +#define __APICALL_EXTERN +#include "hotkeys.h" +#undef __APICALL_EXTERN + +#include "config_emu.h" + +#include + +class Hotkeys: public IHotkeys { + private: + struct HkBacks { + HkCommand cmd; + HkFunc func; + }; + + struct KBind { + SDL_Keycode kc; + uint16_t mod; + }; + + std::vector m_cbacks = {}; + std::array m_binds = {{SDLK_UNKNOWN, 0}}; + uint32_t m_state = 0; + + HkCommand lookupCommand(SDL_Keycode kc, uint16_t mod) { + for (uint32_t c = uint32_t(HkCommand::UNKNOWN); c < uint32_t(HkCommand::COMMANDS_MAX); ++c) { + auto& bind = m_binds[(uint32_t)c]; + if (kc == bind.kc && mod == bind.mod) return HkCommand(c); + } + + return HkCommand::UNKNOWN; + } + + public: + Hotkeys() { + static std::unordered_map map = { + {"gamereport.send", HkCommand::GAMEREPORT_SEND_REPORT}, + {"controller.l3", HkCommand::CONTROLLER_L3}, + {"controller.r3", HkCommand::CONTROLLER_R3}, + {"controller.options", HkCommand::CONTROLLER_OPTIONS}, + {"controller.dpad_up", HkCommand::CONTROLLER_DPAD_UP}, + {"controller.dpad_right", HkCommand::CONTROLLER_DPAD_RIGHT}, + {"controller.dpad_down", HkCommand::CONTROLLER_DPAD_DOWN}, + {"controller.dpad_left", HkCommand::CONTROLLER_DPAD_LEFT}, + {"controller.l2", HkCommand::CONTROLLER_L2}, + {"controller.r2", HkCommand::CONTROLLER_R2}, + {"controller.l1", HkCommand::CONTROLLER_L1}, + {"controller.r1", HkCommand::CONTROLLER_R1}, + {"controller.triangle", HkCommand::CONTROLLER_TRIANGLE}, + {"controller.circle", HkCommand::CONTROLLER_CIRCLE}, + {"controller.cross", HkCommand::CONTROLLER_CROSS}, + {"controller.square", HkCommand::CONTROLLER_SQUARE}, + {"controller.touchpad", HkCommand::CONTROLLER_TOUCH_PAD}, + {"controller.lx+", HkCommand::CONTROLLER_LX_UP}, + {"controller.lx-", HkCommand::CONTROLLER_LX_DOWN}, + {"controller.ly+", HkCommand::CONTROLLER_LY_UP}, + {"controller.ly-", HkCommand::CONTROLLER_LY_DOWN}, + {"controller.rx+", HkCommand::CONTROLLER_RX_UP}, + {"controller.rx-", HkCommand::CONTROLLER_RX_DOWN}, + {"controller.ry+", HkCommand::CONTROLLER_RY_UP}, + {"controller.ry-", HkCommand::CONTROLLER_RY_DOWN}, + }; + + auto readBind = [](std::string& str, KBind* kb) -> bool { + auto delim = str.find_last_of("||"); + if (delim != std::string::npos) { + auto mod = str.substr(0, delim - 1); + auto key = str.substr(delim + 1); + kb->kc = SDL_GetScancodeFromName(key.c_str()); + + switch (SDL_GetScancodeFromName(mod.c_str())) { + case SDL_SCANCODE_LALT: kb->mod = KMOD_LALT; return true; + case SDL_SCANCODE_LCTRL: kb->mod = KMOD_LCTRL; return true; + case SDL_SCANCODE_LSHIFT: kb->mod = KMOD_LSHIFT; return true; + + case SDL_SCANCODE_RALT: kb->mod = KMOD_RALT; return true; + case SDL_SCANCODE_RCTRL: kb->mod = KMOD_RCTRL; return true; + case SDL_SCANCODE_RSHIFT: kb->mod = KMOD_RSHIFT; return true; + + default: return false; + } + } + + kb->kc = SDL_GetScancodeFromName(str.c_str()); + kb->mod = 0x0000; + return true; + }; + + auto [lock, jData] = accessConfig()->accessModule(ConfigModFlag::CONTROLS); + for (auto& [bname, sdlkeys]: (*jData)["keybinds"].items()) { + auto it = map.find(bname.c_str()); + if (it == map.end()) continue; + std::string temp; + sdlkeys.get_to(temp); + + auto& bind = m_binds[(uint32_t)it->second]; + if (!readBind(temp, &bind)) { + bind = {0, 0}; + continue; + } + + for (uint32_t c = uint32_t(HkCommand::UNKNOWN); c < uint32_t(HkCommand::COMMANDS_MAX); ++c) { + auto& tbind = m_binds[(uint32_t)c]; + if (bind.kc == SDL_SCANCODE_UNKNOWN || tbind.kc == SDL_SCANCODE_UNKNOWN) continue; + if (tbind.kc == bind.kc && tbind.mod == bind.mod && (uint32_t)it->second != c) { + printf("Key conflict found! Please rebind your \"%s\" key.\n", bname.c_str()); + bind = {0, 0}; + continue; + } + } + } + } + + void registerCallback(HkCommand cmd, HkFunc func) final { m_cbacks.emplace_back(cmd, func); } + + bool isPressed(HkCommand cmd) final { return (m_state & (1ull << (uint8_t)cmd)) != 0; } + + int32_t isPressedEx(HkCommand cmd1, HkCommand cmd2, int32_t ifcmd1, int32_t ifcmd2, int32_t def) final { + return isPressed(cmd1) ? ifcmd1 : (isPressed(cmd2) ? ifcmd2 : def); + } + + void update(const SDL_KeyboardEvent* event) final { + bool pressed = event->type == SDL_KEYDOWN; + HkCommand cmd = lookupCommand(event->keysym.scancode, event->keysym.mod & 0x03C3); + if (cmd == HkCommand::UNKNOWN) return; + uint32_t bit = (1ull << (uint8_t)cmd); + + if (pressed && ((m_state & bit) == 0)) { + for (auto& hkc: m_cbacks) + if (hkc.cmd == cmd) hkc.func(cmd); + + m_state |= bit; + } else if (!pressed && ((m_state & bit) != 0)) { + m_state &= ~bit; + } + } +}; + +IHotkeys& accessHotkeys() { + static Hotkeys ih; + return ih; +} diff --git a/core/hotkeys/hotkeys.h b/core/hotkeys/hotkeys.h new file mode 100644 index 00000000..15cdb5e7 --- /dev/null +++ b/core/hotkeys/hotkeys.h @@ -0,0 +1,71 @@ +#pragma once + +#include "utility/utility.h" + +#include +#include + +enum class HkCommand { + UNKNOWN = 0, + + // System commands + GAMEREPORT_SEND_REPORT, + + // Gamepad emulation + CONTROLLER_L3, + CONTROLLER_R3, + CONTROLLER_OPTIONS, + CONTROLLER_DPAD_UP, + CONTROLLER_DPAD_RIGHT, + CONTROLLER_DPAD_DOWN, + CONTROLLER_DPAD_LEFT, + CONTROLLER_L2, + CONTROLLER_R2, + CONTROLLER_L1, + CONTROLLER_R1, + CONTROLLER_TRIANGLE, + CONTROLLER_CIRCLE, + CONTROLLER_CROSS, + CONTROLLER_SQUARE, + CONTROLLER_TOUCH_PAD, + CONTROLLER_LX_UP, + CONTROLLER_LX_DOWN, + CONTROLLER_LY_UP, + CONTROLLER_LY_DOWN, + CONTROLLER_RX_UP, + CONTROLLER_RX_DOWN, + CONTROLLER_RY_UP, + CONTROLLER_RY_DOWN, + + /** + * Warning! If this value ever exceeds 32 you should increase + * the size of `m_state` variable in `class Hotkeys` aswell! + */ + COMMANDS_MAX, +}; + +typedef std::function HkFunc; + +class IHotkeys { + CLASS_NO_COPY(IHotkeys); + CLASS_NO_MOVE(IHotkeys); + + public: + IHotkeys() = default; + virtual ~IHotkeys() = default; + + virtual void registerCallback(HkCommand cmd, HkFunc func) = 0; + virtual bool isPressed(HkCommand cmd) = 0; + virtual int32_t isPressedEx(HkCommand cmd1, HkCommand cmd2, int32_t ifcmd1, int32_t ifcmd2, int32_t def) = 0; + virtual void update(const SDL_KeyboardEvent* event) = 0; +}; + +#if defined(__APICALL_EXTERN) +#define __APICALL __declspec(dllexport) +#elif defined(__APICALL_IMPORT) +#define __APICALL __declspec(dllimport) +#else +#define __APICALL +#endif +__APICALL IHotkeys& accessHotkeys(); +#undef __APICALL diff --git a/core/trophies/trophies.cpp b/core/trophies/trophies.cpp index ac6b3fe3..72e50d21 100644 --- a/core/trophies/trophies.cpp +++ b/core/trophies/trophies.cpp @@ -228,7 +228,7 @@ class Trophies: public ITrophies { // Data decipher context EVP_CIPHER_CTX* data_ctx = EVP_CIPHER_CTX_new(); { - if (!EVP_DecryptInit(data_ctx, EVP_aes_128_cbc(), outbuffer, d_iv)) { + if (!EVP_DecryptInit(data_ctx, EVP_aes_128_cbc(), outbuffer /* the buffer holds the decryption key now */, d_iv)) { EVP_CIPHER_CTX_free(data_ctx); return false; } @@ -250,8 +250,8 @@ class Trophies: public ITrophies { // Seeking to unread encrypted data position (skip Init Vector + Signature Comkment Part) trfile.seekg(ent.pos + TR_AES_BLOCK_SIZE + ENC_SCE_SIGN_SIZE); - size_t copied; - while ((copied = size_t(mem_off - mem.get())) < ent.len) { + size_t copied = ENC_SCE_SIGN_SIZE; + while (copied < ent.len) { size_t len = std::min(ent.len - copied, sizeof(inbuffer)); // Reading the rest of AES data block by block if (!trfile.read((char*)inbuffer, len)) { @@ -264,6 +264,7 @@ class Trophies: public ITrophies { } mem_off += outlen; + copied += len; } if (!EVP_DecryptFinal(data_ctx, (uint8_t*)mem_off, &outlen)) { @@ -280,7 +281,7 @@ class Trophies: public ITrophies { */ auto p = std::string_view(mem.get()).find(""); if (p != std::string_view::npos) *(mem.get() + p + 13) = '\0'; - *mem_off = '\0'; // Finally + *(mem_off + outlen) = '\0'; // Finally } //- Data decipher context diff --git a/core/videoout/CMakeLists.txt b/core/videoout/CMakeLists.txt index 6388c399..4e02915f 100644 --- a/core/videoout/CMakeLists.txt +++ b/core/videoout/CMakeLists.txt @@ -9,7 +9,7 @@ add_library(videoout OBJECT overlay/overtrophy/overtrophy.cpp ) -add_dependencies(videoout third_party psOff_utility gamereport initParams config_emu psoff_render) +add_dependencies(videoout third_party psOff_utility initParams config_emu psoff_render) target_include_directories(videoout PRIVATE ${Vulkan_INCLUDE_DIRS} diff --git a/core/videoout/videoout.cpp b/core/videoout/videoout.cpp index 42f8eab1..b2d63e5e 100644 --- a/core/videoout/videoout.cpp +++ b/core/videoout/videoout.cpp @@ -3,11 +3,11 @@ #undef __APICALL_EXTERN #include "config_emu.h" +#include "core/hotkeys/hotkeys.h" #include "core/initParams/initParams.h" #include "core/kernel/eventqueue.h" #include "core/systemContent/systemContent.h" #include "core/timer/timer.h" -#include "gamereport.h" #include "imageHandler.h" #include "logging.h" #include "modules/libSceVideoOut/codes.h" @@ -242,6 +242,8 @@ class VideoOut: public IVideoOut, private IEventsGraphics { bool SDLEventUnreg(SDLEventFunc func) { return m_sdlEvents.removeListener(func); } + SDL_Window* SDLWindow() { return m_windows[0].window; } + void vblankEnd(int handle, uint64_t curTime, uint64_t curProcTime); // Callback Graphics @@ -794,7 +796,7 @@ void cbWindow_moveresize(SDL_Window* window) { (*jData)["xpos"] = x, (*jData)["ypos"] = y; } -void cbWindow_keyhandler(SDL_Window* window, SDL_Event* event) { +void cbWindow_keyhandler(SDL_Window* window, SDL_Event* event) { // todo: Move these to hotkey handler too? switch (event->key.keysym.scancode) { case SDL_SCANCODE_ESCAPE: return cbWindow_close(window); case SDL_SCANCODE_RETURN: { @@ -808,25 +810,6 @@ void cbWindow_keyhandler(SDL_Window* window, SDL_Event* event) { } } } break; - case GAMEREPORT_USER_SEND_SCANCODE: { - auto title = accessSystemContent().getString("TITLE"); - auto title_id = accessSystemContent().getString("TITLE_ID"); - auto app_ver = accessSystemContent().getString("APP_VER"); - - accessGameReport().ShowReportWindow({ - .title = title ? title.value().data() : "Your PS4 Game Name", - .title_id = title_id ? title_id.value().data() : "CUSA00000", - .app_ver = app_ver ? app_ver.value().data() : "v0.0", - .emu_ver = PSOFF_RENDER_VERSION, - .wnd = window, - - .type = IGameReport::Type::USER, - .add = - { - .ex = nullptr, - }, - }); - } break; default: break; } @@ -847,6 +830,7 @@ std::thread VideoOut::createSDLThread() { SDL_Event event; while (SDL_PollEvent(&event)) { m_overlayHandler->processEvent(&event); + if (event.type == SDL_KEYUP || event.type == SDL_KEYDOWN) accessHotkeys().update(&event.key); switch (event.type) { case SDL_WINDOWEVENT: diff --git a/core/videoout/videoout.h b/core/videoout/videoout.h index de5d1251..5aa8f4d1 100644 --- a/core/videoout/videoout.h +++ b/core/videoout/videoout.h @@ -14,6 +14,7 @@ constexpr int VIDEO_OUT_EVENT_VBLANK = 1; class IGraphics; union SDL_Event; +struct SDL_Window; typedef void (*SDLEventFunc)(SDL_Event*, void*); @@ -183,6 +184,13 @@ class IVideoOut { */ virtual bool SDLEventUnreg(SDLEventFunc eventFunc) = 0; + /** + * @brief Returns the main SDL Window handle + * + * @return SDL_Window* + */ + virtual SDL_Window* SDLWindow() = 0; + /** * @brief Notify a gpu visible memory range * diff --git a/docs/json/controls.json b/docs/json/controls.json index 95c376dc..96a0cdd0 100644 --- a/docs/json/controls.json +++ b/docs/json/controls.json @@ -36,104 +36,108 @@ "description": "Information about keybinds for gamepad emulation, hover your cursor on any key inside this object to get more info.", "additionalProperties": false, "properties": { - "circle": { + "gamereport.send": { "$ref": "#/definitions/button" }, - "cross": { + "controller.circle": { "$ref": "#/definitions/button" }, - "dpad_down": { + "controller.cross": { "$ref": "#/definitions/button" }, - "dpad_left": { + "controller.dpad_down": { "$ref": "#/definitions/button" }, - "dpad_right": { + "controller.dpad_left": { "$ref": "#/definitions/button" }, - "dpad_up": { + "controller.dpad_right": { "$ref": "#/definitions/button" }, - "l1": { + "controller.dpad_up": { "$ref": "#/definitions/button" }, - "l2": { + "controller.l1": { "$ref": "#/definitions/button" }, - "l3": { + "controller.l2": { "$ref": "#/definitions/button" }, - "lx+": { + "controller.l3": { "$ref": "#/definitions/button" }, - "lx-": { + "controller.lx+": { "$ref": "#/definitions/button" }, - "ly+": { + "controller.lx-": { "$ref": "#/definitions/button" }, - "ly-": { + "controller.ly+": { "$ref": "#/definitions/button" }, - "options": { + "controller.ly-": { "$ref": "#/definitions/button" }, - "r1": { + "controller.options": { "$ref": "#/definitions/button" }, - "r2": { + "controller.r1": { "$ref": "#/definitions/button" }, - "r3": { + "controller.r2": { "$ref": "#/definitions/button" }, - "rx+": { + "controller.r3": { "$ref": "#/definitions/button" }, - "rx-": { + "controller.rx+": { "$ref": "#/definitions/button" }, - "ry+": { + "controller.rx-": { "$ref": "#/definitions/button" }, - "ry-": { + "controller.ry+": { "$ref": "#/definitions/button" }, - "square": { + "controller.ry-": { "$ref": "#/definitions/button" }, - "touchpad": { + "controller.square": { "$ref": "#/definitions/button" }, - "triangle": { + "controller.touchpad": { + "$ref": "#/definitions/button" + }, + "controller.triangle": { "$ref": "#/definitions/button" } }, "required": [ - "circle", - "cross", - "dpad_down", - "dpad_left", - "dpad_right", - "dpad_up", - "l1", - "l2", - "l3", - "lx+", - "lx-", - "ly+", - "ly-", - "options", - "r1", - "r2", - "r3", - "rx+", - "rx-", - "ry+", - "ry-", - "square", - "touchpad", - "triangle" + "gamereport.send", + "controller.circle", + "controller.cross", + "controller.dpad_down", + "controller.dpad_left", + "controller.dpad_right", + "controller.dpad_up", + "controller.l1", + "controller.l2", + "controller.l3", + "controller.lx+", + "controller.lx-", + "controller.ly+", + "controller.ly-", + "controller.options", + "controller.r1", + "controller.r2", + "controller.r3", + "controller.rx+", + "controller.rx-", + "controller.ry+", + "controller.ry-", + "controller.square", + "controller.touchpad", + "controller.triangle" ] }, "pads": { diff --git a/main.cpp b/main.cpp index 36999239..b2e1c1f9 100644 --- a/main.cpp +++ b/main.cpp @@ -9,6 +9,7 @@ #include "core/systemContent/systemContent.h" #include "core/timer/timer.h" #include "core/videoout/videoout.h" +#include "gamereport.h" #include "logging.h" #include "utility/progloc.h" @@ -79,6 +80,12 @@ int main(int argc, char** argv) { printf("Renderer version: %s\n", PSOFF_RENDER_VERSION); + /** + * Initialize GameReport before anything else gets loaded. + * TODO: Catch exceptions and pass them to it if possible. + */ + (void)accessGameReport(); + auto initParams = accessInitParams(); // ### Preinit diff --git a/modules/libScePad/CMakeLists.txt b/modules/libScePad/CMakeLists.txt index 003a12bd..041ac2fe 100644 --- a/modules/libScePad/CMakeLists.txt +++ b/modules/libScePad/CMakeLists.txt @@ -8,7 +8,6 @@ add_library(${libName} SHARED entry.cpp interfaces/isdl.cpp interfaces/ixip.cpp interfaces/ikbd.cpp - cconfig.cpp ) add_dependencies(${libName} core config_emu) diff --git a/modules/libScePad/cconfig.cpp b/modules/libScePad/cconfig.cpp deleted file mode 100644 index 9c9fb81a..00000000 --- a/modules/libScePad/cconfig.cpp +++ /dev/null @@ -1,130 +0,0 @@ -#include "cconfig.h" - -#include "gamereport.h" -#include "logging.h" -#include "types.h" - -#include - -LOG_DEFINE_MODULE(libScePad_config); - -ControllerType MapControllerType(json& type) { - LOG_USE_MODULE(libScePad_config); - - if (type == "keyboard") { - return ControllerType::Keyboard; - } else if (type == "sdl") { - return ControllerType::SDL; - } else if (type == "xinput") { - return ControllerType::Xinput; - } - - std::string temp; - type.get_to(temp); - LOG_ERR(L"Unknown controller type \"%S\" falling back to \"SDL\"", temp.c_str()); - return ControllerType::SDL; -} - -static std::unordered_map jsonKeys = { - {"l3", ControllerKey::L3}, - {"r3", ControllerKey::R3}, - {"options", ControllerKey::OPTIONS}, - {"up", ControllerKey::DPAD_UP}, - {"right", ControllerKey::DPAD_RIGHT}, - {"down", ControllerKey::DPAD_DOWN}, - {"left", ControllerKey::DPAD_LEFT}, - {"l2", ControllerKey::L2}, - {"r2", ControllerKey::R2}, - {"l1", ControllerKey::L1}, - {"r1", ControllerKey::R1}, - {"triangle", ControllerKey::TRIANGLE}, - {"circle", ControllerKey::CIRCLE}, - {"cross", ControllerKey::CROSS}, - {"square", ControllerKey::SQUARE}, - {"touchpad", ControllerKey::TOUCH_PAD}, - {"dpad_up", ControllerKey::DPAD_UP}, - {"dpad_down", ControllerKey::DPAD_DOWN}, - {"dpad_left", ControllerKey::DPAD_LEFT}, - {"dpad_right", ControllerKey::DPAD_RIGHT}, - {"lx+", ControllerKey::LX_UP}, - {"lx-", ControllerKey::LX_DOWN}, - {"ly+", ControllerKey::LY_UP}, - {"ly-", ControllerKey::LY_DOWN}, - {"rx+", ControllerKey::RX_UP}, - {"rx-", ControllerKey::RX_DOWN}, - {"ry+", ControllerKey::RY_UP}, - {"ry-", ControllerKey::RY_DOWN}, -}; - -ControllerKey MapControllerKey(const std::string& key) { - LOG_USE_MODULE(libScePad_config); - - if (jsonKeys.find(key) == jsonKeys.end()) { - LOG_CRIT(L"Unknown keytype in controller config: %S", key.c_str()); - return ControllerKey::UNKNOWN_KEY; - } - - return jsonKeys[key]; -} - -static SDL_Scancode ParseScanCodeName(const char* key, const char* name) { - LOG_USE_MODULE(libScePad_config); - - auto code = SDL_GetScancodeFromName(name); - if (code == GAMEREPORT_USER_SEND_SCANCODE) { - LOG_ERR(L"Attempt to bind occupied key is prevented, please change your bind for gpkey:%S", key); - return SDL_SCANCODE_UNKNOWN; - } - - return code; -} - -ControllerConfig::ControllerConfig() { - LOG_USE_MODULE(libScePad_config); - - auto [lock, jData] = accessConfig()->accessModule(ConfigModFlag::CONTROLS); - - auto& pads = (*jData)["pads"]; - - std::string temps; - - for (auto& [key, val]: (*jData)["keybinds"].items()) { - auto& mapEntry = m_keymap[(uint32_t)MapControllerKey(key)]; - val.get_to(temps); - if (temps.size() == 0) { - LOG_ERR(L"Unbound gpkey:%S", key.c_str()); - continue; - } - - size_t fpos; - if ((fpos = temps.find("%+")) != std::string::npos) { // Process keybinds with modifier - std::string mod = temps.substr(0, fpos); - mapEntry.key = ParseScanCodeName(key.c_str(), temps.c_str() + fpos + 2); - mapEntry.mod = ParseScanCodeName(key.c_str(), mod.c_str()); - if (mapEntry.mod == 0 || mapEntry.key == 0) LOG_ERR(L"Failed to resolve bind for gpkey:%S, mapEntry(%d,%d)", key.c_str(), mapEntry.key, mapEntry.mod); - continue; - } - - mapEntry.mod = 0; - if ((mapEntry.key = ParseScanCodeName(key.c_str(), temps.c_str())) == 0) - LOG_ERR(L"Failed to resolve bind for gpkey:%S, unknown or occupied key: %S", key.c_str(), temps.c_str()); - } - - for (int i = 0; i < sizeof(m_pads) / sizeof(*m_pads); i++) { - auto& pad = pads[i]; - - try { - m_pads[i].type = MapControllerType(pad["type"]); - - auto& dls = pad["deadzones"]["left_stick"]; - auto& drs = pad["deadzones"]["right_stick"]; - - dls["x"].get_to(m_pads[i].ls.x); - dls["y"].get_to(m_pads[i].ls.y); - drs["x"].get_to(m_pads[i].rs.x); - drs["y"].get_to(m_pads[i].rs.y); - } catch (const json::exception& e) { - LOG_CRIT(L"Failed to read controllers config file: %S", e.what()); - } - } -} diff --git a/modules/libScePad/cconfig.h b/modules/libScePad/cconfig.h deleted file mode 100644 index 26c72086..00000000 --- a/modules/libScePad/cconfig.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include "config_emu.h" -#include "types.h" - -class ControllerConfig { - struct Key { - uint16_t key; - uint16_t mod; - } m_keymap[(uint32_t)ControllerKey::CONTROLLER_KEYS_COUNT]; - - struct DeadZone { - float x, y; - }; - - struct Settings { - ControllerType type; - DeadZone ls, rs; - } m_pads[4]; - - public: - auto GetPadType(int n) const { - if (n < 1 || n > 4) return ControllerType::Unknown; - return m_pads[n - 1].type; - } - - auto GetBind(ControllerKey key) const { return m_keymap[(uint32_t)key]; } - - ControllerConfig(); - virtual ~ControllerConfig() = default; -}; diff --git a/modules/libScePad/entry.cpp b/modules/libScePad/entry.cpp index 6d52b662..ee54944d 100644 --- a/modules/libScePad/entry.cpp +++ b/modules/libScePad/entry.cpp @@ -1,5 +1,5 @@ -#include "cconfig.h" #include "common.h" +#include "config_emu.h" #include "core/timer/timer.h" #include "interfaces/ikbd.h" #include "interfaces/isdl.h" @@ -7,6 +7,8 @@ #include "logging.h" #include "types.h" +#include + LOG_DEFINE_MODULE(libScePad); namespace { @@ -20,11 +22,10 @@ struct Controller { }; struct Pimpl { - Pimpl(): cfg() {} + Pimpl() = default; std::mutex m_mutexInt; - ControllerConfig cfg; std::array controller; }; @@ -33,6 +34,27 @@ static auto* getData() { return &obj; } +static ControllerType _getPadType(int32_t userId) { + LOG_USE_MODULE(libScePad); + + auto [lock, jData] = accessConfig()->accessModule(ConfigModFlag::CONTROLS); + + auto type = (*jData)["pads"][userId - 1]["type"]; + + if (type == "keyboard") { + return ControllerType::Keyboard; + } else if (type == "sdl") { + return ControllerType::SDL; + } else if (type == "xinput") { + return ControllerType::Xinput; + } + + std::string temp; + type.get_to(temp); + LOG_ERR(L"Unknown controller backend \"%S\" falling back to \"SDL\"", temp.c_str()); + return ControllerType::SDL; +}; + static int _padOpen(int32_t userId, PadPortType type, int32_t index, const void* pParam) { if ((userId < 1 || userId > 4) && userId != 0xFF) return Err::Pad::INVALID_ARG; if (type == PadPortType::REMOTE_CONTROL && userId != 0xFF) return Err::Pad::INVALID_ARG; @@ -56,12 +78,12 @@ static int _padOpen(int32_t userId, PadPortType type, int32_t index, const void* pData->controller[n].prePadData = ScePadData(); pData->controller[n].userId = userId; - switch (pData->cfg.GetPadType(userId)) { - case ControllerType::SDL: padBackend = createController_sdl(&pData->cfg, userId); break; + switch (_getPadType(userId)) { + case ControllerType::SDL: padBackend = createController_sdl(userId); break; - case ControllerType::Xinput: padBackend = createController_xinput(&pData->cfg, userId); break; + case ControllerType::Xinput: padBackend = createController_xinput(userId); break; - case ControllerType::Keyboard: padBackend = createController_keyboard(&pData->cfg, userId); break; + case ControllerType::Keyboard: padBackend = createController_keyboard(userId); break; default: LOG_CRIT(L"Unimplemented controller type!"); return Err::Pad::FATAL; } diff --git a/modules/libScePad/icontroller.h b/modules/libScePad/icontroller.h index 61ab9d93..1a461843 100644 --- a/modules/libScePad/icontroller.h +++ b/modules/libScePad/icontroller.h @@ -1,11 +1,24 @@ #pragma once -#include "cconfig.h" #include "types.h" #include "utility/utility.h" #include +enum class ControllerType { + Unknown, + Keyboard, + Xinput, + SDL, +}; + +enum class ControllerState { + Unknown, + Connected, + Disconnected, + Closed, +}; + class IController { CLASS_NO_COPY(IController); CLASS_NO_MOVE(IController); @@ -20,9 +33,8 @@ class IController { ScePadColor m_lastColor = {0x00, 0x00, 0xFF}; char m_guid[33]; char m_name[33]; - ControllerConfig* m_cfg; - IController(ControllerType type, ControllerConfig* cfg, uint32_t userid): m_type(type), m_cfg(cfg), m_userId(userid) { + IController(ControllerType type, uint32_t userid): m_type(type), m_userId(userid) { ::memset(m_guid, '0', sizeof(m_guid)); ::strcpy_s(m_name, "[NOT YET CONNECTED]"); } diff --git a/modules/libScePad/interfaces/ikbd.cpp b/modules/libScePad/interfaces/ikbd.cpp index e5c34d81..7dfa9675 100644 --- a/modules/libScePad/interfaces/ikbd.cpp +++ b/modules/libScePad/interfaces/ikbd.cpp @@ -1,5 +1,6 @@ #include "ikbd.h" +#include "core/hotkeys/hotkeys.h" #include "core/timer/timer.h" #include "core/videoout/videoout.h" // #include "logging.h" @@ -12,7 +13,7 @@ class KBDController: public IController { public: - KBDController(ControllerConfig* cfg, uint32_t userid): IController(ControllerType::SDL, cfg, userid) { reconnect(); } + KBDController(uint32_t userid): IController(ControllerType::SDL, userid) { reconnect(); } virtual ~KBDController() = default; @@ -26,12 +27,11 @@ class KBDController: public IController { bool setLED(const ScePadColor* pParam) final; bool resetLED() final; - bool resolveBindFor(const uint8_t* keys, ControllerKey key); - uint32_t getButtons(const uint8_t* keys); + uint32_t getButtons(IHotkeys& keys); }; -std::unique_ptr createController_keyboard(ControllerConfig* cfg, uint32_t userid) { - return std::make_unique(cfg, userid); +std::unique_ptr createController_keyboard(uint32_t userid) { + return std::make_unique(userid); } void KBDController::close() { @@ -46,59 +46,50 @@ bool KBDController::reconnect() { return true; } -bool KBDController::resolveBindFor(const uint8_t* keys, ControllerKey key) { - auto bind = m_cfg->GetBind(key); - return keys[bind.key] && (bind.mod != 0 ? keys[bind.mod] : 1); -} - -uint32_t KBDController::getButtons(const uint8_t* keys) { +uint32_t KBDController::getButtons(IHotkeys& hk) { std::bitset<32> bits; - bits[(uint32_t)ScePadButtonDataOffset::L3] = resolveBindFor(keys, ControllerKey::L3); - bits[(uint32_t)ScePadButtonDataOffset::R3] = resolveBindFor(keys, ControllerKey::R3); - bits[(uint32_t)ScePadButtonDataOffset::OPTIONS] = resolveBindFor(keys, ControllerKey::OPTIONS); - bits[(uint32_t)ScePadButtonDataOffset::UP] = resolveBindFor(keys, ControllerKey::DPAD_UP); - bits[(uint32_t)ScePadButtonDataOffset::RIGHT] = resolveBindFor(keys, ControllerKey::DPAD_RIGHT); - bits[(uint32_t)ScePadButtonDataOffset::DOWN] = resolveBindFor(keys, ControllerKey::DPAD_DOWN); - bits[(uint32_t)ScePadButtonDataOffset::LEFT] = resolveBindFor(keys, ControllerKey::DPAD_LEFT); - bits[(uint32_t)ScePadButtonDataOffset::L1] = resolveBindFor(keys, ControllerKey::L1); - bits[(uint32_t)ScePadButtonDataOffset::L2] = resolveBindFor(keys, ControllerKey::L2); - bits[(uint32_t)ScePadButtonDataOffset::R1] = resolveBindFor(keys, ControllerKey::R1); - bits[(uint32_t)ScePadButtonDataOffset::R2] = resolveBindFor(keys, ControllerKey::R2); - bits[(uint32_t)ScePadButtonDataOffset::TRIANGLE] = resolveBindFor(keys, ControllerKey::TRIANGLE); - bits[(uint32_t)ScePadButtonDataOffset::CIRCLE] = resolveBindFor(keys, ControllerKey::CIRCLE); - bits[(uint32_t)ScePadButtonDataOffset::CROSS] = resolveBindFor(keys, ControllerKey::CROSS); - bits[(uint32_t)ScePadButtonDataOffset::SQUARE] = resolveBindFor(keys, ControllerKey::SQUARE); - bits[(uint32_t)ScePadButtonDataOffset::TOUCH_PAD] = resolveBindFor(keys, ControllerKey::TOUCH_PAD); + bits[(uint32_t)ScePadButtonDataOffset::L3] = hk.isPressed(HkCommand::CONTROLLER_L3); + bits[(uint32_t)ScePadButtonDataOffset::R3] = hk.isPressed(HkCommand::CONTROLLER_R3); + bits[(uint32_t)ScePadButtonDataOffset::OPTIONS] = hk.isPressed(HkCommand::CONTROLLER_OPTIONS); + bits[(uint32_t)ScePadButtonDataOffset::UP] = hk.isPressed(HkCommand::CONTROLLER_DPAD_UP); + bits[(uint32_t)ScePadButtonDataOffset::RIGHT] = hk.isPressed(HkCommand::CONTROLLER_DPAD_RIGHT); + bits[(uint32_t)ScePadButtonDataOffset::DOWN] = hk.isPressed(HkCommand::CONTROLLER_DPAD_DOWN); + bits[(uint32_t)ScePadButtonDataOffset::LEFT] = hk.isPressed(HkCommand::CONTROLLER_DPAD_LEFT); + bits[(uint32_t)ScePadButtonDataOffset::L1] = hk.isPressed(HkCommand::CONTROLLER_L1); + bits[(uint32_t)ScePadButtonDataOffset::L2] = hk.isPressed(HkCommand::CONTROLLER_L2); + bits[(uint32_t)ScePadButtonDataOffset::R1] = hk.isPressed(HkCommand::CONTROLLER_R1); + bits[(uint32_t)ScePadButtonDataOffset::R2] = hk.isPressed(HkCommand::CONTROLLER_R2); + bits[(uint32_t)ScePadButtonDataOffset::TRIANGLE] = hk.isPressed(HkCommand::CONTROLLER_TRIANGLE); + bits[(uint32_t)ScePadButtonDataOffset::CIRCLE] = hk.isPressed(HkCommand::CONTROLLER_CIRCLE); + bits[(uint32_t)ScePadButtonDataOffset::CROSS] = hk.isPressed(HkCommand::CONTROLLER_CROSS); + bits[(uint32_t)ScePadButtonDataOffset::SQUARE] = hk.isPressed(HkCommand::CONTROLLER_SQUARE); + bits[(uint32_t)ScePadButtonDataOffset::TOUCH_PAD] = hk.isPressed(HkCommand::CONTROLLER_TOUCH_PAD); return bits.to_ulong(); } -#define MAP_ANALOG(_keys, _up, _down) (uint8_t)(resolveBindFor(_keys, _up) ? 0xFF : resolveBindFor(_keys, _down) ? 0x00 : 0x7F) - -#define MAP_TRIGGER(_keys, _down) (uint8_t)(resolveBindFor(_keys, _down) ? 0xFF : 0x00) - bool KBDController::readPadData(ScePadData& data) { if (m_state == ControllerState::Closed) return false; - const uint8_t* keys = SDL_GetKeyboardState(nullptr); + auto& hk = accessHotkeys(); data = ScePadData { - .buttons = getButtons(keys), + .buttons = getButtons(hk), .leftStick = { - .x = MAP_ANALOG(keys, ControllerKey::LX_UP, ControllerKey::LX_DOWN), - .y = MAP_ANALOG(keys, ControllerKey::LY_UP, ControllerKey::LY_DOWN), + .x = uint8_t(hk.isPressedEx(HkCommand::CONTROLLER_LX_UP, HkCommand::CONTROLLER_LX_DOWN, 0xFF, 0x00, 0x7F)), + .y = uint8_t(hk.isPressedEx(HkCommand::CONTROLLER_LY_UP, HkCommand::CONTROLLER_LY_DOWN, 0xFF, 0x00, 0x7F)), }, .rightStick = { - .x = MAP_ANALOG(keys, ControllerKey::RX_UP, ControllerKey::RX_DOWN), - .y = MAP_ANALOG(keys, ControllerKey::RY_UP, ControllerKey::RY_DOWN), + .x = uint8_t(hk.isPressedEx(HkCommand::CONTROLLER_RX_UP, HkCommand::CONTROLLER_RX_DOWN, 0xFF, 0x00, 0x7F)), + .y = uint8_t(hk.isPressedEx(HkCommand::CONTROLLER_RY_UP, HkCommand::CONTROLLER_RY_DOWN, 0xFF, 0x00, 0x7F)), }, .analogButtons = { - .l2 = MAP_TRIGGER(keys, ControllerKey::L2), - .r2 = MAP_TRIGGER(keys, ControllerKey::R2), + .l2 = uint8_t(hk.isPressed(HkCommand::CONTROLLER_L2) ? 0xFF : 0x00), + .r2 = uint8_t(hk.isPressed(HkCommand::CONTROLLER_R2) ? 0xFF : 0x00), }, .orientation = { diff --git a/modules/libScePad/interfaces/ikbd.h b/modules/libScePad/interfaces/ikbd.h index 91a48ae1..e2938e47 100644 --- a/modules/libScePad/interfaces/ikbd.h +++ b/modules/libScePad/interfaces/ikbd.h @@ -1,8 +1,7 @@ #pragma once -#include "../cconfig.h" #include "../icontroller.h" #include -std::unique_ptr createController_keyboard(ControllerConfig*, uint32_t); +std::unique_ptr createController_keyboard(uint32_t); diff --git a/modules/libScePad/interfaces/isdl.cpp b/modules/libScePad/interfaces/isdl.cpp index 81f4144a..98913824 100644 --- a/modules/libScePad/interfaces/isdl.cpp +++ b/modules/libScePad/interfaces/isdl.cpp @@ -47,7 +47,7 @@ class SDLController: public IController { SceFVector3 m_gyroData = {0.0f, 0.0f, 0.0f}; public: - SDLController(ControllerConfig* cfg, uint32_t userid): IController(ControllerType::SDL, cfg, userid) { + SDLController(uint32_t userid): IController(ControllerType::SDL, userid) { init(); reconnect(); } @@ -69,8 +69,8 @@ class SDLController: public IController { static void init(); }; -std::unique_ptr createController_sdl(ControllerConfig* cfg, uint32_t userid) { - return std::make_unique(cfg, userid); +std::unique_ptr createController_sdl(uint32_t userid) { + return std::make_unique(userid); } void SDLController::init() { diff --git a/modules/libScePad/interfaces/isdl.h b/modules/libScePad/interfaces/isdl.h index 1c64a7ff..38c04335 100644 --- a/modules/libScePad/interfaces/isdl.h +++ b/modules/libScePad/interfaces/isdl.h @@ -1,8 +1,7 @@ #pragma once -#include "../cconfig.h" #include "../icontroller.h" #include -std::unique_ptr createController_sdl(ControllerConfig*, uint32_t); +std::unique_ptr createController_sdl(uint32_t); diff --git a/modules/libScePad/interfaces/ixip.cpp b/modules/libScePad/interfaces/ixip.cpp index 55e77ed7..626c9c35 100644 --- a/modules/libScePad/interfaces/ixip.cpp +++ b/modules/libScePad/interfaces/ixip.cpp @@ -27,7 +27,7 @@ class XIPController: public IController { bool m_xRumblePossible = false; public: - XIPController(ControllerConfig* cfg, uint32_t userid): IController(ControllerType::SDL, cfg, userid) { + XIPController(uint32_t userid): IController(ControllerType::SDL, userid) { init(); reconnect(); } @@ -48,8 +48,8 @@ class XIPController: public IController { void init(); }; -std::unique_ptr createController_xinput(ControllerConfig* cfg, uint32_t userid) { - return std::make_unique(cfg, userid); +std::unique_ptr createController_xinput(uint32_t userid) { + return std::make_unique(userid); } void XIPController::init() { diff --git a/modules/libScePad/interfaces/ixip.h b/modules/libScePad/interfaces/ixip.h index ecd28b70..0dfdac02 100644 --- a/modules/libScePad/interfaces/ixip.h +++ b/modules/libScePad/interfaces/ixip.h @@ -1,8 +1,7 @@ #pragma once -#include "../cconfig.h" #include "../icontroller.h" #include -std::unique_ptr createController_xinput(ControllerConfig*, uint32_t); +std::unique_ptr createController_xinput(uint32_t); diff --git a/modules/libScePad/types.h b/modules/libScePad/types.h index a7d750de..ec2fbeec 100644 --- a/modules/libScePad/types.h +++ b/modules/libScePad/types.h @@ -95,50 +95,6 @@ enum class SceFlightCapability { RADAR_CURSOR_STICK = 0x10, }; -enum class ControllerKey : uint32_t { - L3, - R3, - OPTIONS, - DPAD_UP, - DPAD_RIGHT, - DPAD_DOWN, - DPAD_LEFT, - L2, - R2, - L1, - R1, - TRIANGLE, - CIRCLE, - CROSS, - SQUARE, - TOUCH_PAD, - LX_UP, - LX_DOWN, - LY_UP, - LY_DOWN, - RX_UP, - RX_DOWN, - RY_UP, - RY_DOWN, - - CONTROLLER_KEYS_COUNT, - UNKNOWN_KEY -}; - -enum class ControllerType { - Unknown, - Keyboard, - Xinput, - SDL, -}; - -enum class ControllerState { - Unknown, - Connected, - Disconnected, - Closed, -}; - struct ScePadAnalogStick { uint8_t x; uint8_t y; diff --git a/tools/config_emu/config_emu.cpp b/tools/config_emu/config_emu.cpp index 49ba8e76..672372c3 100644 --- a/tools/config_emu/config_emu.cpp +++ b/tools/config_emu/config_emu.cpp @@ -254,21 +254,23 @@ Config::Config() { std::async(std::launch::async | std::launch::deferred, load, &m_audio, json({{"$schema", "./.schemas/audio.json"}, {"device", "[default]"}, {"padspeakers", defspeakers}, {"volume", 0.5f}}), ConfigModFlag::AUDIO); - m_controls._future = std::async(std::launch::async | std::launch::deferred, load, &m_controls, - json({ - {"$schema", "./.schemas/controls.json"}, - {"pads", defpads}, - {"keybinds", - { - {"triangle", "i"}, {"square", "j"}, {"circle", "l"}, {"cross", "k"}, - {"dpad_up", "up"}, {"dpad_down", "down"}, {"dpad_left", "left"}, {"dpad_right", "right"}, - {"options", "f1"}, {"touchpad", "f4"}, {"l1", "f3"}, {"l2", "f5"}, - {"l3", "space"}, {"r1", "f2"}, {"r2", "f6"}, {"r3", "home"}, - {"lx-", "a"}, {"lx+", "d"}, {"ly-", "w"}, {"ly+", "s"}, - {"rx-", "h"}, {"rx+", "f"}, {"ry-", "t"}, {"ry+", "g"}, - }}, - }), - ConfigModFlag::CONTROLS); + m_controls._future = + std::async(std::launch::async | std::launch::deferred, load, &m_controls, + json({ + {"$schema", "./.schemas/controls.json"}, + {"pads", defpads}, + {"keybinds", + { + {"controller.triangle", "i"}, {"controller.square", "j"}, {"controller.circle", "l"}, {"controller.cross", "k"}, + {"controller.dpad_up", "up"}, {"controller.dpad_down", "down"}, {"controller.dpad_left", "left"}, {"controller.dpad_right", "right"}, + {"controller.options", "f1"}, {"controller.touchpad", "f4"}, {"controller.l1", "f3"}, {"controller.l2", "f5"}, + {"controller.l3", "space"}, {"controller.r1", "f2"}, {"controller.r2", "f6"}, {"controller.r3", "home"}, + {"controller.lx-", "a"}, {"controller.lx+", "d"}, {"controller.ly-", "w"}, {"controller.ly+", "s"}, + {"controller.rx-", "f"}, {"controller.rx+", "h"}, {"controller.ry-", "t"}, {"controller.ry+", "g"}, + {"gamereport.send", "f11"}, + }}, + }), + ConfigModFlag::CONTROLS); m_general._future = std::async(std::launch::async, load, &m_general, json({ diff --git a/tools/gamereport/CMakeLists.txt b/tools/gamereport/CMakeLists.txt index 3db80e64..1022f938 100644 --- a/tools/gamereport/CMakeLists.txt +++ b/tools/gamereport/CMakeLists.txt @@ -16,8 +16,8 @@ target_include_directories(gamereport PRIVATE ${CMAKE_SOURCE_DIR} ) -add_dependencies(gamereport third_party logging check_git) -target_link_libraries(gamereport PUBLIC libboost_url SDL2 libssl libcrypto logging.lib config_emu.lib) +add_dependencies(gamereport third_party logging check_git core) +target_link_libraries(gamereport PUBLIC libboost_url SDL2 libssl libcrypto core.lib logging.lib config_emu.lib) target_compile_definitions(gamereport PUBLIC BOOST_ALL_NO_LIB WIN32_LEAN_AND_MEAN) set_target_properties(gamereport diff --git a/tools/gamereport/entry.cpp b/tools/gamereport/entry.cpp index 0fb976ba..0d2aafdf 100644 --- a/tools/gamereport/entry.cpp +++ b/tools/gamereport/entry.cpp @@ -3,11 +3,15 @@ #undef __APICALL_EXTERN #include "config_emu.h" +#include "core/hotkeys/hotkeys.h" +#include "core/systemContent/systemContent.h" +#include "core/videoout/videoout.h" #include "git_ver.h" #include "logging.h" #include "modules_include/system_param.h" #include "nlohmann/json.hpp" +#include #include #include #include @@ -460,6 +464,25 @@ GameReport::GameReport() { // for (int i = 0; i < LANG_STR_MAX; i++) { // printf("%s\n = \n%s\n*************************\n", strings[Langs::ENGLISH][i], strings[Langs::RUSSIAN][i]); // } + + accessHotkeys().registerCallback(HkCommand::GAMEREPORT_SEND_REPORT, [this](HkCommand) { + auto title = accessSystemContent().getString("TITLE"); + auto title_id = accessSystemContent().getString("TITLE_ID"); + auto app_ver = accessSystemContent().getString("APP_VER"); + + ShowReportWindow({ + .title = title ? title.value().data() : "Your PS4 Game Name", + .title_id = title_id ? title_id.value().data() : "CUSA00000", + .app_ver = app_ver ? app_ver.value().data() : "v0.0", + .emu_ver = PSOFF_RENDER_VERSION, + + .type = IGameReport::Type::USER, + .add = + { + .ex = nullptr, + }, + }); + }); } void GameReport::ShowReportWindow(const Info& info) { @@ -494,7 +517,7 @@ void GameReport::ShowReportWindow(const Info& info) { SDL_MessageBoxData mbd { .flags = SDL_MESSAGEBOX_INFORMATION, - .window = info.wnd, + .window = accessVideoOut().SDLWindow(), .title = get_lang_string(lang_id, LangString::MAIN_TITLE), .message = message, .numbuttons = 2, diff --git a/tools/gamereport/gamereport.h b/tools/gamereport/gamereport.h index 14ef139a..865df141 100644 --- a/tools/gamereport/gamereport.h +++ b/tools/gamereport/gamereport.h @@ -1,10 +1,8 @@ #pragma once -#include "SDL2/SDL.h" #include "utility/utility.h" -#define GAMEREPORT_USER_SEND_SCANCODE SDL_SCANCODE_F11 -#define GAMEREPORT_REPO_NAME "SysRay/psOff_compatibility" +#define GAMEREPORT_REPO_NAME "SysRay/psOff_compatibility" class IGameReport { CLASS_NO_COPY(IGameReport); @@ -35,7 +33,6 @@ class IGameReport { const char* title_id; const char* app_ver; const char* emu_ver; - SDL_Window* wnd; Type type; AdditionalData add;