mirror of
https://github.com/esuo1198/TaikoArcadeLoader.git
synced 2026-09-28 09:47:58 +03:00
optimized boot speed(use safetyhook) & more optimized IO latency & update SDL3(fix conflict, thanks @asesidaa)
This commit is contained in:
+6
-7
@@ -94,15 +94,15 @@ FetchContent_Declare(
|
||||
set(SAFETYHOOK_FETCH_ZYDIS ON CACHE BOOL "" FORCE)
|
||||
FetchContent_MakeAvailable(safetyhook)
|
||||
|
||||
# Fetch SDL2
|
||||
# Fetch SDL3
|
||||
FetchContent_Declare(
|
||||
SDL2
|
||||
URL https://github.com/libsdl-org/SDL/releases/download/release-2.26.5/SDL2-2.26.5.tar.gz
|
||||
SDL3
|
||||
URL https://github.com/libsdl-org/SDL/releases/download/preview-3.1.6/SDL3-3.1.6.tar.gz
|
||||
)
|
||||
set(SDL_SHARED OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_STATIC ON CACHE BOOL "" FORCE)
|
||||
set(SDL_TEST OFF CACHE BOOL "" FORCE)
|
||||
FetchContent_MakeAvailable(SDL2)
|
||||
FetchContent_MakeAvailable(SDL3)
|
||||
|
||||
# Fetch xxHash
|
||||
FetchContent_Declare(
|
||||
@@ -137,7 +137,6 @@ set(SOURCES
|
||||
src/patches/audio.cpp
|
||||
src/patches/plugins.cpp
|
||||
src/patches/scanner.cpp
|
||||
# src/patches/qr.cpp
|
||||
src/patches/layeredfs.cpp
|
||||
src/patches/testmode.cpp
|
||||
src/patches/timer.cpp
|
||||
@@ -157,7 +156,7 @@ set_target_properties(bnusio PROPERTIES PREFIX "")
|
||||
target_include_directories(bnusio PRIVATE
|
||||
src
|
||||
${tomlc99_SOURCE_DIR}
|
||||
${SDL2_SOURCE_DIR}/include
|
||||
${SDL3_SOURCE_DIR}/include
|
||||
${xxhash_SOURCE_DIR}
|
||||
${zlib_SOURCE_DIR}
|
||||
${libtomcrypt_SOURCE_DIR}/src/headers
|
||||
@@ -177,7 +176,7 @@ endif()
|
||||
# Link libraries
|
||||
target_link_libraries(bnusio PRIVATE
|
||||
tomlc99
|
||||
SDL2-static
|
||||
SDL3-static
|
||||
xxhash
|
||||
zlibstatic
|
||||
libtomcrypt
|
||||
|
||||
+14
-12
@@ -35,7 +35,7 @@ Keybindings SERVICE = {.keycodes = {VK_F2}};
|
||||
Keybindings DEBUG_UP = {.keycodes = {VK_UP}};
|
||||
Keybindings DEBUG_DOWN = {.keycodes = {VK_DOWN}};
|
||||
Keybindings DEBUG_ENTER = {.keycodes = {VK_RETURN}};
|
||||
Keybindings COIN_ADD = {.keycodes = {VK_RETURN}, .buttons = {SDL_CONTROLLER_BUTTON_START}};
|
||||
Keybindings COIN_ADD = {.keycodes = {VK_RETURN}, .buttons = {SDL_GAMEPAD_BUTTON_START}};
|
||||
Keybindings CARD_INSERT_1 = {.keycodes = {'P'}};
|
||||
Keybindings CARD_INSERT_2 = {};
|
||||
Keybindings QR_DATA_READ = {.keycodes = {'Q'}};
|
||||
@@ -52,15 +52,17 @@ Keybindings P2_RIGHT_BLUE = {.keycodes = {'V'}};
|
||||
// CARD_INSERT_1, CARD_INSERT_2, QR_DATA_READ, QR_IMAGE_READ, P1_LEFT_BLUE, P1_LEFT_RED,
|
||||
// P1_RIGHT_RED, P1_RIGHT_BLUE, P2_LEFT_BLUE, P2_LEFT_RED, P2_RIGHT_RED, P2_RIGHT_BLUE };
|
||||
|
||||
const int exitWait = 100;
|
||||
int exited = 0;
|
||||
bool testEnabled = false;
|
||||
int coin_count = 0;
|
||||
int service_count = 0;
|
||||
bool inited = false;
|
||||
bool updateByCoin = false;
|
||||
HWND windowHandle = nullptr;
|
||||
bool usePoll = false;
|
||||
const int exitWait = 100;
|
||||
int exited = 0;
|
||||
bool testEnabled = false;
|
||||
bool insert_coin = false;
|
||||
bool insert_service = false;
|
||||
u16 coin_count = 0;
|
||||
u16 service_count = 0;
|
||||
bool inited = false;
|
||||
bool updateByCoin = false;
|
||||
HWND windowHandle = nullptr;
|
||||
bool usePoll = false;
|
||||
HKL currentLayout;
|
||||
|
||||
namespace bnusio {
|
||||
@@ -293,9 +295,9 @@ UpdateLoop () {
|
||||
#endif
|
||||
std::vector<uint8_t> buffer = {};
|
||||
if (IsButtonTapped (COIN_ADD)) coin_count++;
|
||||
if (IsButtonTapped (SERVICE) && !testEnabled) service_count++;
|
||||
if (IsButtonTapped (SERVICE)) service_count++;
|
||||
if (IsButtonTapped (TEST)) testEnabled = !testEnabled;
|
||||
if (IsButtonTapped (EXIT)) {
|
||||
if (IsButtonTapped (EXIT)) {
|
||||
LogMessage (LogLevel::INFO, "Exit By Press Exit Button!");
|
||||
exited += 1; testEnabled = 1; patches::Plugins::Exit ();
|
||||
}
|
||||
|
||||
+38
-18
@@ -47,8 +47,10 @@ namespace Card {
|
||||
};
|
||||
|
||||
namespace Internal {
|
||||
enum CardErrorCode { ReadError = -201, NotSupport = -400 };
|
||||
|
||||
void
|
||||
AgentInsertCard (uint8_t cardData[168], bool internalInvoke) {
|
||||
InsertCard (uint8_t cardData[168], bool internalInvoke) {
|
||||
if (callbackTouch) {
|
||||
state = internalInvoke ? State::Disable : State::CopyWait;
|
||||
patches::Plugins::UpdateStatus (1, false);
|
||||
@@ -68,7 +70,16 @@ namespace Card {
|
||||
}
|
||||
|
||||
void
|
||||
AgentInsertCardPlugin (int32_t a1, int32_t a2, uint8_t *a3, uint64_t a4) {
|
||||
InsertError (CardErrorCode errorCode) {
|
||||
if (callbackTouch) {
|
||||
state = State::CopyWait;
|
||||
patches::Plugins::UpdateStatus (1, false);
|
||||
callbackTouch (0, errorCode, cardData, touchData);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AgentCallbackTouch (int32_t a1, int32_t a2, uint8_t *a3, uint64_t a4) {
|
||||
if (callbackTouch) {
|
||||
state = State::CopyWait;
|
||||
patches::Plugins::UpdateStatus (1, false);
|
||||
@@ -77,10 +88,11 @@ namespace Card {
|
||||
}
|
||||
|
||||
void
|
||||
AgentInsertCardOfficial (int32_t a1, int32_t a2, uint8_t *a3, uint64_t a4) {
|
||||
AgentCallbackTouchOfficial (int32_t a1, int32_t a2, uint8_t *a3, uint64_t a4) {
|
||||
if (callbackTouch) {
|
||||
state = State::CopyWait;
|
||||
patches::Plugins::UpdateStatus (1, false);
|
||||
LogMessage (LogLevel::DEBUG, "Official CallbackTouch a1={} a2={}", a1, a2);
|
||||
if (acceptInvalidCards && !a3[0]) {
|
||||
char AccessId[21] = "00000000000000000001";
|
||||
uint8_t UID[8] = {a3[12], a3[14], a3[15], a3[16], 0x90, 0x00, 0x00, 0x00};
|
||||
@@ -105,7 +117,7 @@ namespace Card {
|
||||
for (size_t i = 0; i < 32; i++) *(cardData + 0x2C + i) = i < chipId.length() ? chipId[i] : 0;
|
||||
for (size_t i = 0; i < 20; i++) *(cardData + 0x50 + i) = i < accessCode.length() ? accessCode[i] : 0;
|
||||
if (!internalInvoke) LogMessage (LogLevel::INFO, "[Card] Insert Card accessCode: \"{}\" chipId: \"{}\"", accessCode, chipId);
|
||||
patches::Scanner::Card::Internal::AgentInsertCard (cardData, internalInvoke);
|
||||
patches::Scanner::Card::Internal::InsertCard (cardData, internalInvoke);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -143,7 +155,7 @@ namespace Card {
|
||||
FAST_HOOK (u64, bngrw_ReqWaitTouch, PROC_ADDRESS ("bngrw.dll", "BngRwReqWaitTouch"), u32 a1, i32 a2, u32 a3, CallbackTouch callback, u64 a5) {
|
||||
state = State::Ready;
|
||||
patches::Plugins::UpdateStatus (1, true);
|
||||
patches::Plugins::WaitTouch (Internal::AgentInsertCardPlugin, a5);
|
||||
patches::Plugins::WaitTouch (Internal::AgentCallbackTouch, a5);
|
||||
callbackTouch = callback;
|
||||
touchData = a5;
|
||||
return 1;
|
||||
@@ -161,7 +173,7 @@ namespace Card {
|
||||
patches::Plugins::UpdateStatus (1, true);
|
||||
callbackTouch = callback;
|
||||
touchData = a5;
|
||||
return originalbngrw_ReqWaitTouchOfficial (a1, a2, a3, Internal::AgentInsertCardOfficial, a5);
|
||||
return originalbngrw_ReqWaitTouchOfficial (a1, a2, a3, Internal::AgentCallbackTouchOfficial, a5);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -176,10 +188,12 @@ namespace Card {
|
||||
}
|
||||
if (accessCode.length() == 0 || accessCode.length() > 20) {
|
||||
LogMessage (LogLevel::ERROR, "[Card] Not an effective accessCode: \"{}\"", accessCode);
|
||||
patches::Scanner::Card::Internal::InsertError (Internal::CardErrorCode::NotSupport);
|
||||
return false;
|
||||
}
|
||||
if (chipId.length() > 32) {
|
||||
LogMessage (LogLevel::ERROR, "[Card] Not an effective chipId: \"{}\"", chipId);
|
||||
patches::Scanner::Card::Internal::InsertError (Internal::CardErrorCode::NotSupport);
|
||||
return false;
|
||||
}
|
||||
return patches::Scanner::Card::Internal::Commit0 (accessCode, chipId, false);
|
||||
@@ -226,7 +240,7 @@ namespace Card {
|
||||
}
|
||||
}
|
||||
namespace Qr {
|
||||
std::queue<std::vector<uint8_t>> scanQueue;
|
||||
std::queue<std::vector<uint8_t> *> scanQueue;
|
||||
State state = State::Disable;
|
||||
long long lastScan;
|
||||
|
||||
@@ -256,20 +270,26 @@ namespace Qr {
|
||||
patches::Plugins::UsingQr ();
|
||||
lastScan = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now ().time_since_epoch ()).count ();
|
||||
if (state == State::CopyWait && scanQueue.size () > 0) {
|
||||
std::vector<uint8_t> data = scanQueue.front ();
|
||||
if ((int)data.size () > length) {
|
||||
LogMessage (LogLevel::ERROR, "[QR] Not an effective code, length: {} require: {}", data.size (), length);
|
||||
std::vector<uint8_t> *data = scanQueue.front ();
|
||||
if ((int)data->size () > length) {
|
||||
LogMessage (LogLevel::ERROR, "[QR] Not an effective code, length: {} require: {}", data->size (), length);
|
||||
}
|
||||
std::stringstream hexStream;
|
||||
hexStream << std::hex << std::uppercase << std::setfill ('0') << std::setw (2);
|
||||
for (size_t i = 0; i < data.size (); i++) hexStream << static_cast<int> (data[i]) << " ";
|
||||
LogMessage (LogLevel::INFO, "[QR] Read QRData size: {} data: {}\n", data.size (), hexStream.str ());
|
||||
memcpy (dest, data.data (), data.size () + 1);
|
||||
for (size_t i = 0; i < data->size (); i++) hexStream << static_cast<int> ((*data)[i]) << " ";
|
||||
LogMessage (LogLevel::INFO, "[QR] Read QRData size: {} data: {}\n", data->size (), hexStream.str ());
|
||||
size_t finalCopySize = std::min (data->size () + 1, (size_t)length);
|
||||
memcpy (dest, data->data (), finalCopySize);
|
||||
scanQueue.pop ();
|
||||
delete data;
|
||||
if (scanQueue.size () == 0) state = State::Ready;
|
||||
return data.size ();
|
||||
return finalCopySize;
|
||||
} else if (state == State::Disable) {
|
||||
while (!scanQueue.empty ()) scanQueue.pop ();
|
||||
while (!scanQueue.empty ()) {
|
||||
std::vector<uint8_t> *data = scanQueue.front ();
|
||||
delete data;
|
||||
scanQueue.pop ();
|
||||
}
|
||||
state = State::Ready;
|
||||
patches::Plugins::UpdateStatus (2, true);
|
||||
}
|
||||
@@ -290,10 +310,10 @@ namespace Qr {
|
||||
LogMessage (LogLevel::ERROR, "[QR] Not an effective code, length: 0");
|
||||
return false;
|
||||
}
|
||||
if (scanQueue.empty() || scanQueue.back() != buffer) {
|
||||
std::vector<uint8_t> scanData = {};
|
||||
if (scanQueue.empty() || *scanQueue.back() != buffer) {
|
||||
std::vector<uint8_t> *scanData = new std::vector<uint8_t> ();
|
||||
for (uint8_t byte_data : buffer)
|
||||
scanData.push_back (byte_data);
|
||||
scanData->push_back (byte_data);
|
||||
scanQueue.push (scanData);
|
||||
}
|
||||
if (state == State::Ready) state = State::CopyWait;
|
||||
|
||||
+82
-64
@@ -2,18 +2,20 @@
|
||||
|
||||
#ifndef ASYNC_IO
|
||||
#include "polldef.h"
|
||||
#include <SDL3/SDL_main.h>
|
||||
extern bool jpLayout;
|
||||
|
||||
|
||||
bool currentKeyboardState[0xFF];
|
||||
bool lastKeyboardState[0xFF];
|
||||
|
||||
bool currentControllerButtonsState[SDL_CONTROLLER_BUTTON_MAX];
|
||||
bool lastControllerButtonsState[SDL_CONTROLLER_BUTTON_MAX];
|
||||
bool currentControllerButtonsState[SDL_GAMEPAD_BUTTON_COUNT];
|
||||
bool lastControllerButtonsState[SDL_GAMEPAD_BUTTON_COUNT];
|
||||
SDLAxisState currentControllerAxisState;
|
||||
SDLAxisState lastControllerAxisState;
|
||||
|
||||
SDL_Window *window;
|
||||
SDL_GameController *controllers[255];
|
||||
SDL_Gamepad *controllers[255];
|
||||
|
||||
void
|
||||
SetKeyboardButtons () {
|
||||
@@ -32,7 +34,7 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin
|
||||
|
||||
memset (key_bind, 0, sizeof (*key_bind));
|
||||
for (size_t i = 0; i < std::size (key_bind->buttons); i++)
|
||||
key_bind->buttons[i] = SDL_CONTROLLER_BUTTON_INVALID;
|
||||
key_bind->buttons[i] = SDL_GAMEPAD_BUTTON_INVALID;
|
||||
|
||||
for (int idx = 0;; idx++) {
|
||||
const auto [ok, u] = toml_string_at (array, idx);
|
||||
@@ -54,7 +56,7 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin
|
||||
case button: {
|
||||
*usePoll = true;
|
||||
for (int i = 0; i < std::size (key_bind->buttons); i++) {
|
||||
if (key_bind->buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) {
|
||||
if (key_bind->buttons[i] == SDL_GAMEPAD_BUTTON_INVALID) {
|
||||
key_bind->buttons[i] = value.button;
|
||||
break;
|
||||
}
|
||||
@@ -95,36 +97,51 @@ InitializePoll (const HWND windowHandle) {
|
||||
SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5, "1");
|
||||
SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1");
|
||||
|
||||
if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO) != 0) {
|
||||
if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO) == 0) {
|
||||
if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMEPAD | SDL_INIT_EVENTS | SDL_INIT_VIDEO) != 0) {
|
||||
if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD | SDL_INIT_EVENTS | SDL_INIT_VIDEO) == 0) {
|
||||
hasRumble = false;
|
||||
} else {
|
||||
LogMessage (LogLevel::ERROR,
|
||||
std::string ("SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO): ")
|
||||
std::string ("SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMEPAD | SDL_INIT_EVENTS | SDL_INIT_VIDEO): ")
|
||||
+ SDL_GetError ());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto configPath = std::filesystem::current_path () / "gamecontrollerdb.txt";
|
||||
SDL_GameControllerAddMappingsFromFile (configPath.string ().c_str ()) == -1)
|
||||
SDL_AddGamepadMappingsFromFile (configPath.string ().c_str ()) == -1)
|
||||
LogMessage (LogLevel::ERROR, "Cannot read gamecontrollerdb.txt");
|
||||
SDL_GameControllerEventState (SDL_ENABLE);
|
||||
SDL_JoystickEventState (SDL_ENABLE);
|
||||
SDL_SetGamepadEventsEnabled (true);
|
||||
SDL_SetJoystickEventsEnabled (true);
|
||||
|
||||
for (int i = 0; i < SDL_NumJoysticks (); i++) {
|
||||
if (!SDL_IsGameController (i)) continue;
|
||||
int numJoysticks = 0;
|
||||
auto* joyStickIds = SDL_GetJoysticks(&numJoysticks);
|
||||
if (joyStickIds == nullptr) {
|
||||
LogMessage (LogLevel::ERROR, "Error getting joystick ids");
|
||||
exit(1);
|
||||
}
|
||||
for (auto id:joyStickIds) {
|
||||
if (!SDL_IsGamepad (id)) continue;
|
||||
SDL_Gamepad *controller = SDL_OpenGamepad (id);
|
||||
|
||||
SDL_GameController *controller = SDL_GameControllerOpen (i);
|
||||
if (!controller) {
|
||||
LogMessage (LogLevel::WARN, std::string ("Could not open gamecontroller ") + SDL_GameControllerNameForIndex (i) + ": " + SDL_GetError ());
|
||||
LogMessage (LogLevel::WARN, std::string ("Could not open gamecontroller ") + SDL_GetGamepadNameForID (id) + ": " + SDL_GetError ());
|
||||
continue;
|
||||
}
|
||||
controllers[i] = controller;
|
||||
}
|
||||
|
||||
window = SDL_CreateWindowFrom (windowHandle);
|
||||
if (window == nullptr) LogMessage (LogLevel::ERROR, std::string ("SDL_CreateWindowFrom (windowHandle): ") + SDL_GetError ());
|
||||
LogMessage (LogLevel::DEBUG, "Init Controller connected!");
|
||||
controllers[id] = controller;
|
||||
}
|
||||
SDL_free (joyStickIds);
|
||||
|
||||
SDL_PropertiesID props = SDL_CreateProperties();
|
||||
if(props == 0) {
|
||||
LogMessage (LogLevel::ERROR, "Unable to create SDL_Properties");
|
||||
exit(1);
|
||||
}
|
||||
SDL_SetPointerProperty (props, SDL_PROP_WINDOW_CREATE_WIN32_HWND_POINTER, windowHandle);
|
||||
window = SDL_CreateWindowWithProperties (props);
|
||||
if (window == NULL) LogMessage (LogLevel::ERROR, std::string ("SDL_CreateWindowFrom (windowHandle): ") + SDL_GetError ());
|
||||
atexit (DisposePoll);
|
||||
|
||||
return hasRumble;
|
||||
@@ -149,71 +166,71 @@ UpdatePoll (const HWND windowHandle) {
|
||||
ScreenToClient (windowHandle, ¤tMouseState.Position);
|
||||
|
||||
SDL_Event event;
|
||||
SDL_GameController *controller;
|
||||
SDL_Gamepad *controller;
|
||||
while (SDL_PollEvent (&event) != 0) {
|
||||
switch (event.type) {
|
||||
case SDL_CONTROLLERDEVICEADDED:
|
||||
if (!SDL_IsGameController (event.cdevice.which)) break;
|
||||
case SDL_EVENT_GAMEPAD_ADDED:
|
||||
if (!SDL_IsGamepad (event.cdevice.which)) break;
|
||||
|
||||
controller = SDL_GameControllerOpen (event.cdevice.which);
|
||||
controller = SDL_OpenGamepad (event.cdevice.which);
|
||||
if (!controller) {
|
||||
LogMessage (LogLevel::ERROR, std::string ("Could not open gamecontroller ") + SDL_GameControllerNameForIndex (event.cdevice.which)
|
||||
LogMessage (LogLevel::ERROR, std::string ("Could not open gamecontroller ") + SDL_GetGamepadNameForID (event.cdevice.which)
|
||||
+ ": " + SDL_GetError ());
|
||||
continue;
|
||||
}
|
||||
controllers[event.cdevice.which] = controller;
|
||||
break;
|
||||
case SDL_CONTROLLERDEVICEREMOVED:
|
||||
if (!SDL_IsGameController (event.cdevice.which)) break;
|
||||
SDL_GameControllerClose (controllers[event.cdevice.which]);
|
||||
case SDL_EVENT_GAMEPAD_REMOVED:
|
||||
if (!SDL_IsGamepad (event.cdevice.which)) break;
|
||||
SDL_CloseGamepad (controllers[event.cdevice.which]);
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
case SDL_EVENT_MOUSE_WHEEL:
|
||||
if (event.wheel.y > 0) currentMouseState.ScrolledUp = true;
|
||||
else if (event.wheel.y < 0) currentMouseState.ScrolledDown = true;
|
||||
break;
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
case SDL_CONTROLLERBUTTONDOWN: currentControllerButtonsState[event.cbutton.button] = event.cbutton.state; break;
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
if (event.caxis.value > 1) {
|
||||
switch (event.caxis.axis) {
|
||||
case SDL_CONTROLLER_AXIS_LEFTX: currentControllerAxisState.LeftRight = static_cast<float> (event.caxis.value) / 32767; break;
|
||||
case SDL_CONTROLLER_AXIS_LEFTY: currentControllerAxisState.LeftDown = static_cast<float> (event.caxis.value) / 32767; break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTX: currentControllerAxisState.RightRight = static_cast<float> (event.caxis.value) / 32767; break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTY: currentControllerAxisState.RightDown = static_cast<float> (event.caxis.value) / 32767; break;
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERLEFT: currentControllerAxisState.LTriggerDown = static_cast<float> (event.caxis.value) / 32767; break;
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
|
||||
currentControllerAxisState.RTriggerDown = static_cast<float> (event.caxis.value) / 32767;
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_UP:
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_DOWN: currentControllerButtonsState[event.gbutton.button] = event.gbutton.down; break;
|
||||
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
|
||||
if (event.gaxis.value > 1) {
|
||||
switch (event.gaxis.axis) {
|
||||
case SDL_GAMEPAD_AXIS_LEFTX: currentControllerAxisState.LeftRight = static_cast<float> (event.gaxis.value) / 32767; break;
|
||||
case SDL_GAMEPAD_AXIS_LEFTY: currentControllerAxisState.LeftDown = static_cast<float> (event.gaxis.value) / 32767; break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHTX: currentControllerAxisState.RightRight = static_cast<float> (event.gaxis.value) / 32767; break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHTY: currentControllerAxisState.RightDown = static_cast<float> (event.gaxis.value) / 32767; break;
|
||||
case SDL_GAMEPAD_AXIS_LEFT_TRIGGER: currentControllerAxisState.LTriggerDown = static_cast<float> (event.gaxis.value) / 32767; break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHT_TRIGGER:
|
||||
currentControllerAxisState.RTriggerDown = static_cast<float> (event.gaxis.value) / 32767;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
} else if (event.caxis.value < -1) {
|
||||
switch (event.caxis.axis) {
|
||||
case SDL_CONTROLLER_AXIS_LEFTX: currentControllerAxisState.LeftLeft = static_cast<float> (event.caxis.value) / -32768; break;
|
||||
case SDL_CONTROLLER_AXIS_LEFTY: currentControllerAxisState.LeftUp = static_cast<float> (event.caxis.value) / -32768; break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTX: currentControllerAxisState.RightLeft = static_cast<float> (event.caxis.value) / -32768; break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTY: currentControllerAxisState.RightUp = static_cast<float> (event.caxis.value) / -32768; break;
|
||||
} else if (event.gaxis.value < -1) {
|
||||
switch (event.gaxis.axis) {
|
||||
case SDL_GAMEPAD_AXIS_LEFTX: currentControllerAxisState.LeftLeft = static_cast<float> (event.gaxis.value) / -32768; break;
|
||||
case SDL_GAMEPAD_AXIS_LEFTY: currentControllerAxisState.LeftUp = static_cast<float> (event.gaxis.value) / -32768; break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHTX: currentControllerAxisState.RightLeft = static_cast<float> (event.gaxis.value) / -32768; break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHTY: currentControllerAxisState.RightUp = static_cast<float> (event.gaxis.value) / -32768; break;
|
||||
default: break;
|
||||
}
|
||||
} else {
|
||||
switch (event.caxis.axis) {
|
||||
case SDL_CONTROLLER_AXIS_LEFTX:
|
||||
switch (event.gaxis.axis) {
|
||||
case SDL_GAMEPAD_AXIS_LEFTX:
|
||||
currentControllerAxisState.LeftRight = 0;
|
||||
currentControllerAxisState.LeftLeft = 0;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_LEFTY:
|
||||
case SDL_GAMEPAD_AXIS_LEFTY:
|
||||
currentControllerAxisState.LeftDown = 0;
|
||||
currentControllerAxisState.LeftUp = 0;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTX:
|
||||
case SDL_GAMEPAD_AXIS_RIGHTX:
|
||||
currentControllerAxisState.RightRight = 0;
|
||||
currentControllerAxisState.RightLeft = 0;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTY:
|
||||
case SDL_GAMEPAD_AXIS_RIGHTY:
|
||||
currentControllerAxisState.RightDown = 0;
|
||||
currentControllerAxisState.RightUp = 0;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERLEFT: currentControllerAxisState.LTriggerDown = 0; break;
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: currentControllerAxisState.RTriggerDown = 0; break;
|
||||
case SDL_GAMEPAD_AXIS_LEFT_TRIGGER: currentControllerAxisState.LTriggerDown = 0; break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHT_TRIGGER: currentControllerAxisState.RTriggerDown = 0; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -272,7 +289,7 @@ GetInternalButtonState (const Keybindings &bindings) {
|
||||
if (KeyboardIsTapped (bindings.keycodes[i])) buttons.Tapped = true;
|
||||
}
|
||||
for (size_t i = 0; i < std::size (ConfigControllerButtons); i++) {
|
||||
if (bindings.buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) continue;
|
||||
if (bindings.buttons[i] == SDL_GAMEPAD_BUTTON_INVALID) continue;
|
||||
if (ControllerButtonIsReleased (bindings.buttons[i])) buttons.Released = true;
|
||||
if (ControllerButtonIsDown (bindings.buttons[i])) buttons.Down = 1;
|
||||
if (ControllerButtonIsTapped (bindings.buttons[i])) buttons.Tapped = true;
|
||||
@@ -295,11 +312,12 @@ GetInternalButtonState (const Keybindings &bindings) {
|
||||
}
|
||||
|
||||
void
|
||||
SetRumble (const int left, const int right, const int length) {
|
||||
SetRumble (int left, int right, int length) {
|
||||
for (auto &controller : controllers) {
|
||||
if (!controller || !SDL_GameControllerHasRumble (controller)) continue;
|
||||
|
||||
SDL_GameControllerRumble (controller, left, right, length);
|
||||
const auto props = SDL_GetGamepadProperties(controller);
|
||||
const bool hasRumble = SDL_GetBooleanProperty (props, SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN, false);
|
||||
if (!controller || !hasRumble) continue;
|
||||
SDL_RumbleGamepad (controller, left, right, length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,32 +407,32 @@ GetMouseScrollIsTapped (const Scroll scroll) {
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonIsDown (const SDL_GameControllerButton button) {
|
||||
ControllerButtonIsDown (const SDL_GamepadButton button) {
|
||||
return currentControllerButtonsState[button];
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonIsUp (const SDL_GameControllerButton button) {
|
||||
ControllerButtonIsUp (const SDL_GamepadButton button) {
|
||||
return !ControllerButtonIsDown (button);
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonWasDown (const SDL_GameControllerButton button) {
|
||||
ControllerButtonWasDown (const SDL_GamepadButton button) {
|
||||
return lastControllerButtonsState[button];
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonWasUp (const SDL_GameControllerButton button) {
|
||||
ControllerButtonWasUp (const SDL_GamepadButton button) {
|
||||
return !ControllerButtonWasDown (button);
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonIsTapped (const SDL_GameControllerButton button) {
|
||||
ControllerButtonIsTapped (const SDL_GamepadButton button) {
|
||||
return ControllerButtonIsDown (button) && ControllerButtonWasUp (button);
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonIsReleased (const SDL_GameControllerButton button) {
|
||||
ControllerButtonIsReleased (const SDL_GamepadButton button) {
|
||||
return ControllerButtonIsUp (button) && ControllerButtonWasDown (button);
|
||||
}
|
||||
|
||||
|
||||
+14
-14
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include "helpers.h"
|
||||
#include "bnusio.h"
|
||||
|
||||
@@ -41,7 +41,7 @@ enum Scroll { MOUSE_SCROLL_INVALID, MOUSE_SCROLL_UP, MOUSE_SCROLL_DOWN };
|
||||
|
||||
struct Keybindings {
|
||||
u8 keycodes[255];
|
||||
SDL_GameControllerButton buttons[255];
|
||||
SDL_GamepadButton buttons[255];
|
||||
SDLAxis axis[255];
|
||||
Scroll scroll[2];
|
||||
};
|
||||
@@ -52,7 +52,7 @@ struct ConfigValue {
|
||||
EnumType type;
|
||||
union {
|
||||
u8 keycode;
|
||||
SDL_GameControllerButton button;
|
||||
SDL_GamepadButton button;
|
||||
SDLAxis axis;
|
||||
Scroll scroll;
|
||||
};
|
||||
@@ -72,16 +72,16 @@ void SetConfigValue (const toml_table_t *table, const char *key, Keybindings *ke
|
||||
InternalButtonState GetInternalButtonState (const Keybindings &bindings);
|
||||
void SetRumble (int left, int right, int length);
|
||||
|
||||
bool KeyboardIsDown (const uint8_t keycode);
|
||||
bool KeyboardIsTapped (const uint8_t keycode);
|
||||
bool KeyboardIsDown (uint8_t keycode);
|
||||
bool KeyboardIsTapped (uint8_t keycode);
|
||||
bool GetMouseScrollUp ();
|
||||
bool GetMouseScrollDown ();
|
||||
bool GetMouseScrollIsDown (const Scroll scroll);
|
||||
bool GetMouseScrollIsTapped (const Scroll scroll);
|
||||
bool ControllerButtonIsDown (const SDL_GameControllerButton button);
|
||||
bool ControllerButtonIsTapped (const SDL_GameControllerButton button);
|
||||
float ControllerAxisIsDown (const SDLAxis axis);
|
||||
bool ControllerAxisIsTapped (const SDLAxis axis);
|
||||
bool GetMouseScrollIsDown (Scroll scroll);
|
||||
bool GetMouseScrollIsTapped (Scroll scroll);
|
||||
bool ControllerButtonIsDown (SDL_GamepadButton button);
|
||||
bool ControllerButtonIsTapped (SDL_GamepadButton button);
|
||||
float ControllerAxisIsDown (SDLAxis axis);
|
||||
bool ControllerAxisIsTapped (SDLAxis axis);
|
||||
bool IsButtonTapped (const Keybindings &bindings);
|
||||
float IsButtonDown (const Keybindings &bindings);
|
||||
|
||||
@@ -99,9 +99,9 @@ void SetMousePosition (const POINT newPosition);
|
||||
bool GetWasMouseScrollUp ();
|
||||
bool GetWasMouseScrollDown ();
|
||||
bool GetMouseScrollIsReleased (const Scroll scroll);
|
||||
bool ControllerButtonWasDown (const SDL_GameControllerButton button);
|
||||
bool ControllerButtonWasUp (const SDL_GameControllerButton button);
|
||||
bool ControllerButtonIsReleased (const SDL_GameControllerButton button);
|
||||
bool ControllerButtonWasDown (const SDL_GamepadButton button);
|
||||
bool ControllerButtonWasUp (const SDL_GamepadButton button);
|
||||
bool ControllerButtonIsReleased (const SDL_GamepadButton button);
|
||||
bool ControllerAxisIsUp (const SDLAxis axis);
|
||||
float ControllerAxisWasDown (const SDLAxis axis);
|
||||
bool ControllerAxisWasUp (const SDLAxis axis);
|
||||
|
||||
+100
-76
@@ -2,22 +2,21 @@
|
||||
|
||||
#ifdef ASYNC_IO
|
||||
#include "polldef.h"
|
||||
#define SDL_MAIN_NOIMPL
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
extern bool jpLayout;
|
||||
extern int exited;
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
#endif
|
||||
|
||||
bool wndForeground = false;
|
||||
|
||||
bool currentKeyboardState[0xFF] = { false };
|
||||
uint8_t keyboardCount[0xFF] = { 0 };
|
||||
uint8_t keyboardDiff[0xFF] = { 0 };
|
||||
bool keyboardClean = false;
|
||||
bool currentControllerButtonsState[SDL_CONTROLLER_BUTTON_MAX] = { false };
|
||||
uint8_t controllerCount[SDL_CONTROLLER_BUTTON_MAX] = { 0 };
|
||||
uint8_t controllerDiff[SDL_CONTROLLER_BUTTON_MAX] = { 0 };
|
||||
bool currentControllerButtonsState[SDL_GAMEPAD_BUTTON_COUNT] = { false };
|
||||
uint8_t controllerCount[SDL_GAMEPAD_BUTTON_COUNT] = { 0 };
|
||||
uint8_t controllerDiff[SDL_GAMEPAD_BUTTON_COUNT] = { 0 };
|
||||
char currentMouseWheelDirection = 0;
|
||||
uint8_t mouseWheelCount[2] = { 0 };
|
||||
uint8_t mouseWheelDiff[2] = { 0 };
|
||||
@@ -27,7 +26,8 @@ int maxCount = 1;
|
||||
SDLAxisState currentControllerAxisState;
|
||||
|
||||
SDL_Window *window;
|
||||
SDL_GameController *controllers[255];
|
||||
SDL_Gamepad *controllers[255];
|
||||
bool flipped[255];
|
||||
|
||||
std::thread updatePollThread;
|
||||
|
||||
@@ -48,7 +48,7 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin
|
||||
|
||||
memset (key_bind, 0, sizeof (*key_bind));
|
||||
for (size_t i = 0; i < std::size (key_bind->buttons); i++)
|
||||
key_bind->buttons[i] = SDL_CONTROLLER_BUTTON_INVALID;
|
||||
key_bind->buttons[i] = SDL_GAMEPAD_BUTTON_INVALID;
|
||||
|
||||
for (int idx = 0;; idx++) {
|
||||
const auto [ok, u] = toml_string_at (array, idx);
|
||||
@@ -69,7 +69,7 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin
|
||||
case button: {
|
||||
*usePoll = true;
|
||||
for (int i = 0; i < std::size (key_bind->buttons); i++) {
|
||||
if (key_bind->buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) {
|
||||
if (key_bind->buttons[i] == SDL_GAMEPAD_BUTTON_INVALID) {
|
||||
key_bind->buttons[i] = value.button;
|
||||
break;
|
||||
}
|
||||
@@ -108,9 +108,9 @@ LRESULT CALLBACK InputProc(int nCode, WPARAM wParam, LPARAM lParam) {
|
||||
if (nCode == HC_ACTION) {
|
||||
switch (wParam) {
|
||||
case WM_KEYDOWN: if (wndForeground) {
|
||||
KBDLLHOOKSTRUCT* pKeyboard = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
|
||||
auto* pKeyboard = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
|
||||
DWORD keyCode = pKeyboard->vkCode;
|
||||
if (!currentKeyboardState[keyCode]) keyboardCount[keyCode] = MIN (keyboardCount[keyCode] + 1, maxCount);
|
||||
if (!currentKeyboardState[keyCode]) keyboardCount[keyCode] = std::min (keyboardCount[keyCode] + 1, maxCount);
|
||||
currentKeyboardState[keyCode] = true;
|
||||
} break;
|
||||
// keyup will accepted even if you're not focus in this window
|
||||
@@ -123,13 +123,14 @@ LRESULT CALLBACK InputProc(int nCode, WPARAM wParam, LPARAM lParam) {
|
||||
MSLLHOOKSTRUCT *pMouseStruct = (MSLLHOOKSTRUCT*)lParam;
|
||||
int wheelDelta = GET_WHEEL_DELTA_WPARAM(pMouseStruct->mouseData);
|
||||
if (wheelDelta > 0) {
|
||||
mouseWheelCount[0] = MIN (mouseWheelCount[0] + wheelDelta, maxCount);
|
||||
mouseWheelCount[0] = std::min (mouseWheelCount[0] + wheelDelta, maxCount);
|
||||
currentMouseState.ScrolledUp = true;
|
||||
} else if (wheelDelta < 0) {
|
||||
mouseWheelCount[1] = MIN (mouseWheelCount[1] - wheelDelta, maxCount);
|
||||
mouseWheelCount[1] = std::min (mouseWheelCount[1] - wheelDelta, maxCount);
|
||||
currentMouseState.ScrolledDown = true;
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
return CallNextHookEx(keyboardHook, nCode, wParam, lParam);
|
||||
@@ -150,14 +151,12 @@ DisposeKeyboard () {
|
||||
if (mouseHook) UnhookWindowsHookEx(mouseHook);
|
||||
}
|
||||
|
||||
// void
|
||||
// UpdateLoop () {
|
||||
// LogMessage (LogLevel::DEBUG, "Enter Controller UpdateLoop");
|
||||
|
||||
// while (!exited) {
|
||||
|
||||
// }
|
||||
// }
|
||||
void
|
||||
CheckFlipped (uint32_t which, SDL_Gamepad *gamepad) {
|
||||
if (SDL_GetGamepadButtonLabel(gamepad, SDL_GAMEPAD_BUTTON_SOUTH) == SDL_GAMEPAD_BUTTON_LABEL_B) {
|
||||
flipped[which] = true;
|
||||
} else flipped[which] = false;
|
||||
}
|
||||
|
||||
bool
|
||||
InitializePoll (HWND windowHandle) {
|
||||
@@ -171,44 +170,53 @@ InitializePoll (HWND windowHandle) {
|
||||
SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5, "1");
|
||||
SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1");
|
||||
|
||||
if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO) != 0) {
|
||||
if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO) == 0) {
|
||||
if (!SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMEPAD | SDL_INIT_EVENTS | SDL_INIT_VIDEO)) {
|
||||
if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD | SDL_INIT_EVENTS | SDL_INIT_VIDEO)) {
|
||||
hasRumble = false;
|
||||
} else {
|
||||
LogMessage (LogLevel::ERROR,
|
||||
std::string ("SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO): ")
|
||||
+ SDL_GetError ());
|
||||
LogMessage (LogLevel::ERROR, std::string ("SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMEPAD | SDL_INIT_EVENTS | SDL_INIT_VIDEO): ") + SDL_GetError ());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto configPath = std::filesystem::current_path () / "gamecontrollerdb.txt";
|
||||
if (SDL_GameControllerAddMappingsFromFile (configPath.string ().c_str ()) == -1)
|
||||
if (SDL_AddGamepadMappingsFromFile (configPath.string ().c_str ()) == -1)
|
||||
LogMessage (LogLevel::ERROR, "Cannot read gamecontrollerdb.txt");
|
||||
SDL_GameControllerEventState (SDL_ENABLE);
|
||||
SDL_JoystickEventState (SDL_ENABLE);
|
||||
SDL_SetGamepadEventsEnabled (true);
|
||||
SDL_SetJoystickEventsEnabled (true);
|
||||
|
||||
for (int i = 0; i < SDL_NumJoysticks (); i++) {
|
||||
if (!SDL_IsGameController (i)) continue;
|
||||
int numJoysticks = 0;
|
||||
auto* joyStickIds = SDL_GetJoysticks(&numJoysticks);
|
||||
if (joyStickIds == nullptr) {
|
||||
LogMessage (LogLevel::ERROR, "Error getting joystick ids");
|
||||
exit(1);
|
||||
}
|
||||
for (int i = 0; i < numJoysticks; i++) {
|
||||
auto id = joyStickIds[i];
|
||||
if (!SDL_IsGamepad (id)) continue;
|
||||
SDL_Gamepad *controller = SDL_OpenGamepad (id);
|
||||
|
||||
SDL_GameController *controller = SDL_GameControllerOpen (i);
|
||||
if (!controller) {
|
||||
LogMessage (LogLevel::WARN, std::string ("Could not open gamecontroller ") + SDL_GameControllerNameForIndex (i) + ": " + SDL_GetError ());
|
||||
LogMessage (LogLevel::WARN, std::string ("Could not open gamecontroller ") + SDL_GetGamepadNameForID (id) + ": " + SDL_GetError ());
|
||||
continue;
|
||||
}
|
||||
|
||||
LogMessage (LogLevel::DEBUG, "Init Controller connected!");
|
||||
controllers[i] = controller;
|
||||
CheckFlipped (id, controller);
|
||||
controllers[id] = controller;
|
||||
}
|
||||
SDL_free (joyStickIds);
|
||||
|
||||
window = SDL_CreateWindowFrom (windowHandle);
|
||||
SDL_PropertiesID props = SDL_CreateProperties();
|
||||
if(props == 0) {
|
||||
LogMessage (LogLevel::ERROR, "Unable to create SDL_Properties");
|
||||
exit(1);
|
||||
}
|
||||
SDL_SetPointerProperty (props, SDL_PROP_WINDOW_CREATE_WIN32_HWND_POINTER, windowHandle);
|
||||
window = SDL_CreateWindowWithProperties (props);
|
||||
if (window == NULL) LogMessage (LogLevel::ERROR, std::string ("SDL_CreateWindowFrom (windowHandle): ") + SDL_GetError ());
|
||||
|
||||
atexit (DisposePoll);
|
||||
|
||||
// updatePollThread = std::thread (UpdateLoop);
|
||||
// updatePollThread.detach ();
|
||||
|
||||
return hasRumble;
|
||||
}
|
||||
|
||||
@@ -222,6 +230,18 @@ CheckForegroundWindow (HWND processWindow) {
|
||||
return wndForeground;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
CorrectButton (uint32_t which, uint8_t button) {
|
||||
if (!flipped[which]) return button;
|
||||
switch (button) {
|
||||
case SDL_GAMEPAD_BUTTON_SOUTH: return SDL_GAMEPAD_BUTTON_EAST;
|
||||
case SDL_GAMEPAD_BUTTON_EAST: return SDL_GAMEPAD_BUTTON_SOUTH;
|
||||
case SDL_GAMEPAD_BUTTON_WEST: return SDL_GAMEPAD_BUTTON_NORTH;
|
||||
case SDL_GAMEPAD_BUTTON_NORTH: return SDL_GAMEPAD_BUTTON_WEST;
|
||||
default: return button;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UpdatePoll (HWND windowHandle, bool useController) {
|
||||
if (!CheckForegroundWindow (windowHandle)) return;
|
||||
@@ -240,50 +260,52 @@ UpdatePoll (HWND windowHandle, bool useController) {
|
||||
// GetCursorPos (¤tMouseState.Position);
|
||||
// ScreenToClient (windowHandle, ¤tMouseState.Position);
|
||||
if (useController) {
|
||||
for (int i=0; i<SDL_CONTROLLER_BUTTON_MAX; i++) controllerCount[i] -= (bool)controllerDiff[i];
|
||||
memset (controllerDiff, 0, SDL_CONTROLLER_BUTTON_MAX);
|
||||
for (int i=0; i<SDL_GAMEPAD_BUTTON_COUNT; i++) controllerCount[i] -= (bool)controllerDiff[i];
|
||||
memset (controllerDiff, 0, SDL_GAMEPAD_BUTTON_COUNT);
|
||||
SDL_Event event;
|
||||
SDL_GameController *controller;
|
||||
SDL_Gamepad *controller;
|
||||
while (SDL_PollEvent (&event) != 0) {
|
||||
// LogMessage (LogLevel::DEBUG, "Receive SDL Event! type={}", (u64)event.type);
|
||||
switch (event.type) {
|
||||
case SDL_CONTROLLERDEVICEADDED:
|
||||
if (!SDL_IsGameController (event.cdevice.which)) break;
|
||||
controller = SDL_GameControllerOpen (event.cdevice.which);
|
||||
case SDL_EVENT_GAMEPAD_ADDED:
|
||||
if (!SDL_IsGamepad (event.gdevice.which)) break;
|
||||
controller = SDL_OpenGamepad (event.gdevice.which);
|
||||
if (!controller) {
|
||||
LogMessage (LogLevel::ERROR, std::string ("Could not open gamecontroller ") + SDL_GameControllerNameForIndex (event.cdevice.which)
|
||||
+ ": " + SDL_GetError ());
|
||||
LogMessage (LogLevel::ERROR, "Could not open gamecontroller {}: {}", SDL_GetGamepadNameForID (event.gdevice.which), SDL_GetError ());
|
||||
continue;
|
||||
}
|
||||
LogMessage (LogLevel::DEBUG, "Controller connected!");
|
||||
controllers[event.cdevice.which] = controller;
|
||||
CheckFlipped (event.gdevice.which, controller);
|
||||
controllers[event.gdevice.which] = controller;
|
||||
break;
|
||||
case SDL_CONTROLLERDEVICEREMOVED:
|
||||
case SDL_EVENT_GAMEPAD_REMOVED:
|
||||
LogMessage (LogLevel::DEBUG, "Controller removed!");
|
||||
if (!SDL_IsGameController (event.cdevice.which)) break;
|
||||
SDL_GameControllerClose (controllers[event.cdevice.which]);
|
||||
if (!SDL_IsGamepad (event.gdevice.which)) break;
|
||||
SDL_CloseGamepad (controllers[event.gdevice.which]);
|
||||
break;
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
// keyup will accepted even if you're not focus in this window
|
||||
currentControllerButtonsState[event.cbutton.button] = false; break;
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_UP: {
|
||||
uint8_t button = CorrectButton (event.gbutton.which, event.gbutton.button);
|
||||
currentControllerButtonsState[button] = false;
|
||||
} break;
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
|
||||
if (wndForeground) {
|
||||
if (!currentControllerButtonsState[event.cbutton.button]) {
|
||||
controllerCount[event.cbutton.button] = MIN (controllerCount[event.cbutton.button] + 1, maxCount);
|
||||
uint8_t button = CorrectButton (event.gbutton.which, event.gbutton.button);
|
||||
LogMessage (LogLevel::DEBUG, "Controller {}: button {} pressed, remapped to {}", event.gbutton.which, event.gbutton.button, button);
|
||||
if (!currentControllerButtonsState[button]) {
|
||||
controllerCount[button] = std::min (controllerCount[button] + 1, maxCount);
|
||||
}
|
||||
currentControllerButtonsState[event.cbutton.button] = true;
|
||||
} else LogMessage (LogLevel::WARN, "Controller button pressed but window not focused!");
|
||||
currentControllerButtonsState[button] = true;
|
||||
} else LogMessage (LogLevel::DEBUG, "Controller button pressed but window not focused!");
|
||||
break;
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
float sensorValue = event.caxis.value == 0 ? 0 : event.caxis.value / (event.caxis.value > 0 ? 32767.0f : -32768.0f);
|
||||
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
|
||||
float sensorValue = event.gaxis.value == 0 ? 0 : event.gaxis.value / (event.gaxis.value > 0 ? 32767.0f : -32768.0f);
|
||||
if (wndForeground || sensorValue == 0) {
|
||||
switch (event.caxis.axis) {
|
||||
case SDL_CONTROLLER_AXIS_LEFTX: currentControllerAxisState.LeftRight = sensorValue; break;
|
||||
case SDL_CONTROLLER_AXIS_LEFTY: currentControllerAxisState.LeftDown = sensorValue; break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTX: currentControllerAxisState.RightRight = sensorValue; break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTY: currentControllerAxisState.RightDown = sensorValue; break;
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERLEFT: currentControllerAxisState.LTriggerDown = sensorValue; break;
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: currentControllerAxisState.RTriggerDown = sensorValue; break;
|
||||
switch (event.gaxis.axis) {
|
||||
case SDL_GAMEPAD_AXIS_LEFTX: currentControllerAxisState.LeftRight = sensorValue; break;
|
||||
case SDL_GAMEPAD_AXIS_LEFTY: currentControllerAxisState.LeftDown = sensorValue; break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHTX: currentControllerAxisState.RightRight = sensorValue; break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHTY: currentControllerAxisState.RightDown = sensorValue; break;
|
||||
case SDL_GAMEPAD_AXIS_LEFT_TRIGGER: currentControllerAxisState.LTriggerDown = sensorValue; break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHT_TRIGGER: currentControllerAxisState.RTriggerDown = sensorValue; break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -333,8 +355,10 @@ StringToConfigEnum (const char *value) {
|
||||
void
|
||||
SetRumble (int left, int right, int length) {
|
||||
for (auto &controller : controllers) {
|
||||
if (!controller || !SDL_GameControllerHasRumble (controller)) continue;
|
||||
SDL_GameControllerRumble (controller, left, right, length);
|
||||
const auto props = SDL_GetGamepadProperties(controller);
|
||||
const bool hasRumble = SDL_GetBooleanProperty (props, SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN, false);
|
||||
if (!controller || !hasRumble) continue;
|
||||
SDL_RumbleGamepad (controller, left, right, length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,13 +412,13 @@ GetMouseScrollIsTapped (const Scroll scroll) {
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonIsDown (const SDL_GameControllerButton button) {
|
||||
ControllerButtonIsDown (const SDL_GamepadButton button) {
|
||||
return currentControllerButtonsState[button];
|
||||
}
|
||||
|
||||
int maxButtonCount = 1;
|
||||
bool
|
||||
ControllerButtonIsTapped (const SDL_GameControllerButton button) {
|
||||
ControllerButtonIsTapped (const SDL_GamepadButton button) {
|
||||
if (controllerCount[button] > 0) {
|
||||
// if (maxButtonCount < controllerCount[button]) {
|
||||
// maxButtonCount = controllerCount[button];
|
||||
@@ -435,7 +459,7 @@ IsButtonTapped (const Keybindings &bindings) {
|
||||
if (KeyboardIsTapped (bindings.keycodes[i])) return true;
|
||||
}
|
||||
for (size_t i = 0; i < std::size (ConfigControllerButtons); i++) {
|
||||
if (bindings.buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) continue;
|
||||
if (bindings.buttons[i] == SDL_GAMEPAD_BUTTON_INVALID) continue;
|
||||
if (ControllerButtonIsTapped (bindings.buttons[i])) return true;
|
||||
}
|
||||
for (size_t i = 0; i < std::size (ConfigControllerAXIS); i++) {
|
||||
@@ -457,7 +481,7 @@ IsButtonDown (const Keybindings &bindings) {
|
||||
if (KeyboardIsDown (bindings.keycodes[i])) return 1.0f;
|
||||
}
|
||||
for (size_t i = 0; i < std::size (ConfigControllerButtons); i++) {
|
||||
if (bindings.buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) continue;
|
||||
if (bindings.buttons[i] == SDL_GAMEPAD_BUTTON_INVALID) continue;
|
||||
if (ControllerButtonIsDown (bindings.buttons[i])) return 1.0f;
|
||||
}
|
||||
for (size_t i = 0; i < std::size (ConfigControllerAXIS); i++) {
|
||||
|
||||
+22
-22
@@ -254,29 +254,29 @@ KeyCodePair ConfigKeyboardButtons_JP[] = {
|
||||
|
||||
struct {
|
||||
const char *string;
|
||||
SDL_GameControllerButton button;
|
||||
SDL_GamepadButton button;
|
||||
} ConfigControllerButtons[] = {
|
||||
{"SDL_A", SDL_CONTROLLER_BUTTON_A},
|
||||
{"SDL_B", SDL_CONTROLLER_BUTTON_B},
|
||||
{"SDL_X", SDL_CONTROLLER_BUTTON_X},
|
||||
{"SDL_Y", SDL_CONTROLLER_BUTTON_Y},
|
||||
{"SDL_BACK", SDL_CONTROLLER_BUTTON_BACK},
|
||||
{"SDL_GUIDE", SDL_CONTROLLER_BUTTON_GUIDE},
|
||||
{"SDL_START", SDL_CONTROLLER_BUTTON_START},
|
||||
{"SDL_LSTICK_PRESS", SDL_CONTROLLER_BUTTON_LEFTSTICK},
|
||||
{"SDL_RSTICK_PRESS", SDL_CONTROLLER_BUTTON_RIGHTSTICK},
|
||||
{"SDL_LSHOULDER", SDL_CONTROLLER_BUTTON_LEFTSHOULDER},
|
||||
{"SDL_RSHOULDER", SDL_CONTROLLER_BUTTON_RIGHTSHOULDER},
|
||||
{"SDL_DPAD_UP", SDL_CONTROLLER_BUTTON_DPAD_UP},
|
||||
{"SDL_DPAD_DOWN", SDL_CONTROLLER_BUTTON_DPAD_DOWN},
|
||||
{"SDL_DPAD_LEFT", SDL_CONTROLLER_BUTTON_DPAD_LEFT},
|
||||
{"SDL_DPAD_RIGHT", SDL_CONTROLLER_BUTTON_DPAD_RIGHT},
|
||||
{"SDL_MISC", SDL_CONTROLLER_BUTTON_MISC1},
|
||||
{"SDL_PADDLE1", SDL_CONTROLLER_BUTTON_PADDLE1},
|
||||
{"SDL_PADDLE2", SDL_CONTROLLER_BUTTON_PADDLE2},
|
||||
{"SDL_PADDLE3", SDL_CONTROLLER_BUTTON_PADDLE3},
|
||||
{"SDL_PADDLE4", SDL_CONTROLLER_BUTTON_PADDLE4},
|
||||
{"SDL_TOUCHPAD", SDL_CONTROLLER_BUTTON_TOUCHPAD},
|
||||
{"SDL_A", SDL_GAMEPAD_BUTTON_SOUTH},
|
||||
{"SDL_B", SDL_GAMEPAD_BUTTON_EAST},
|
||||
{"SDL_X", SDL_GAMEPAD_BUTTON_WEST},
|
||||
{"SDL_Y", SDL_GAMEPAD_BUTTON_NORTH},
|
||||
{"SDL_BACK", SDL_GAMEPAD_BUTTON_BACK},
|
||||
{"SDL_GUIDE", SDL_GAMEPAD_BUTTON_GUIDE},
|
||||
{"SDL_START", SDL_GAMEPAD_BUTTON_START},
|
||||
{"SDL_LSTICK_PRESS", SDL_GAMEPAD_BUTTON_LEFT_STICK},
|
||||
{"SDL_RSTICK_PRESS", SDL_GAMEPAD_BUTTON_RIGHT_STICK},
|
||||
{"SDL_LSHOULDER", SDL_GAMEPAD_BUTTON_LEFT_SHOULDER},
|
||||
{"SDL_RSHOULDER", SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER},
|
||||
{"SDL_DPAD_UP", SDL_GAMEPAD_BUTTON_DPAD_UP},
|
||||
{"SDL_DPAD_DOWN", SDL_GAMEPAD_BUTTON_DPAD_DOWN},
|
||||
{"SDL_DPAD_LEFT", SDL_GAMEPAD_BUTTON_DPAD_LEFT},
|
||||
{"SDL_DPAD_RIGHT", SDL_GAMEPAD_BUTTON_DPAD_RIGHT},
|
||||
{"SDL_MISC", SDL_GAMEPAD_BUTTON_MISC1},
|
||||
{"SDL_PADDLE1", SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1},
|
||||
{"SDL_PADDLE2", SDL_GAMEPAD_BUTTON_LEFT_PADDLE1},
|
||||
{"SDL_PADDLE3", SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2},
|
||||
{"SDL_PADDLE4", SDL_GAMEPAD_BUTTON_LEFT_PADDLE2},
|
||||
{"SDL_TOUCHPAD", SDL_GAMEPAD_BUTTON_TOUCHPAD},
|
||||
};
|
||||
|
||||
struct {
|
||||
|
||||
Reference in New Issue
Block a user