diff --git a/Content/scripts/fighting_game.lua b/Content/scripts/fighting_game.lua index fc522ab3b..4f4e35be1 100644 --- a/Content/scripts/fighting_game.lua +++ b/Content/scripts/fighting_game.lua @@ -1234,7 +1234,7 @@ local function Character(face, skin_color, shirt_color, hair_color, shoe_color) -- We use a custom scene because if two models are loaded into the global scene, they will have name collisions -- and thus we couldn't properly query entities by name local model_scene = Scene() - self.model = LoadModel(model_scene, "../models/havoc/havoc.wiscene") + self.model = LoadModel(model_scene, "../models/Havoc/havoc.wiscene") -- Place model according to starting facing direction: self.face = face diff --git a/WickedEngine/wiInput.cpp b/WickedEngine/wiInput.cpp index 4a09f80de..29f9a894d 100644 --- a/WickedEngine/wiInput.cpp +++ b/WickedEngine/wiInput.cpp @@ -71,6 +71,7 @@ namespace wiInput DISCONNECTED, XINPUT, RAWINPUT, + SDLINPUT, }; DeviceType deviceType; int deviceIndex; @@ -272,18 +273,52 @@ namespace wiInput } } + // Check if low-level SDLINPUT controller is not registered for playerindex slot and register: + for (int i = 0; i < wiSDLInput::GetMaxControllerCount(); ++i) + { + if (wiSDLInput::GetControllerState(nullptr, i)) + { + int slot = -1; + for (int j = 0; j < (int)controllers.size(); ++j) + { + if (slot < 0 && controllers[j].deviceType == Controller::DISCONNECTED) + { + // take the first disconnected slot + slot = j; + } + if (controllers[j].deviceType == Controller::SDLINPUT && controllers[j].deviceIndex == i) + { + // it is already registered to this slot + slot = j; + break; + } + } + if (slot == -1) + { + // no disconnected slot was found, and it was not registered + slot = (int)controllers.size(); + controllers.emplace_back(); + } + controllers[slot].deviceType = Controller::SDLINPUT; + controllers[slot].deviceIndex = i; + } + } + // Read low-level controllers: for (auto& controller : controllers) { bool connected = false; switch (controller.deviceType) { - case Controller::XINPUT: - connected = wiXInput::GetControllerState(&controller.state, controller.deviceIndex); - break; - case Controller::RAWINPUT: - connected = wiRawInput::GetControllerState(&controller.state, controller.deviceIndex); - break; + case Controller::XINPUT: + connected = wiXInput::GetControllerState(&controller.state, controller.deviceIndex); + break; + case Controller::RAWINPUT: + connected = wiRawInput::GetControllerState(&controller.state, controller.deviceIndex); + break; + case Controller::SDLINPUT: + connected = wiSDLInput::GetControllerState(&controller.state, controller.deviceIndex); + break; } if (!connected) diff --git a/WickedEngine/wiSDLInput.cpp b/WickedEngine/wiSDLInput.cpp index c01c8cf34..3e9b7b8ae 100644 --- a/WickedEngine/wiSDLInput.cpp +++ b/WickedEngine/wiSDLInput.cpp @@ -1,11 +1,17 @@ -#include "CommonInclude.h" -#include "wiInput.h" #include "wiSDLInput.h" #ifdef SDL2 +#include "CommonInclude.h" +#include "wiBackLog.h" +#include "wiInput.h" #include +#include +#include +#include +#include #include +#include namespace wiSDLInput { @@ -22,9 +28,37 @@ namespace wiSDLInput //}; //std::vector controllers; - int to_wiInput(const SDL_Scancode &key); + struct Internal_ControllerState + { + Sint32 portID; + SDL_JoystickID internalID; + SDL_GameController* controller; + wiInput::ControllerState state; + }; + std::vector controllers; + int numSticks = 0; + + int to_wiInput(const SDL_Scancode &key); + void controller_to_wiInput(uint32_t *current, Uint8 button, bool pressed); + + void AddController(Sint32 id); + void RemoveController(Sint32 id); + void RemoveController(); + + void Initialize() { + if(!SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt")){ + wiBackLog::post("[SDL Input] No controller config loaded, add gamecontrollerdb.txt file next to the executable or download it from https://github.com/gabomdq/SDL_GameControllerDB"); + } + + // Attempt to add joysticks at initialization + numSticks = SDL_NumJoysticks(); + if(numSticks > 0){ + for(int i = 0; i numSticks){ + numSticks = SDL_NumJoysticks(); + for(int i = 0; i events(1000); // This removes the only the inputs events from the event queue, leaving audio and window events for other @@ -52,7 +104,6 @@ namespace wiSDLInput return; } else if (ret > 0) { events.resize(ret); - for (const SDL_Event &event : events) { switch (event.type) { // Keyboard events @@ -143,6 +194,33 @@ namespace wiSDLInput mouse.left_button_press = mouse_buttons_state & SDL_BUTTON_LMASK; mouse.right_button_press = mouse_buttons_state & SDL_BUTTON_RMASK; mouse.middle_button_press = mouse_buttons_state & SDL_BUTTON_MMASK; + + //Get controller axis and button values here instead + for(auto& controller : controllers){ + if(controller.controller){ + //Get controller buttons + for(int btn=SDL_CONTROLLER_BUTTON_INVALID; btn 0.01) ? rawLx : 0; + controller.state.thumbstick_L.y = (rawLy < -0.01 || rawLy > 0.01) ? rawLy : 0; + controller.state.thumbstick_R.x = (rawRx < -0.01 || rawRx > 0.01) ? rawRx : 0; + controller.state.thumbstick_R.y = (rawRy < -0.01 || rawRy > 0.01) ? rawRy : 0; + controller.state.trigger_L = (rawLT > 0.01) ? rawLT : 0; + controller.state.trigger_R = (rawRT > 0.01) ? rawRT : 0; + } + } } void GetKeyboardState(wiInput::KeyboardState* state) { @@ -151,8 +229,18 @@ namespace wiSDLInput void GetMouseState(wiInput::MouseState* state) { *state = mouse; } - int GetMaxControllerCount() { return 0; } - bool GetControllerState(wiInput::ControllerState* state, int index) { return false; } + int GetMaxControllerCount() { return numSticks; } + bool GetControllerState(wiInput::ControllerState* state, int index) { + if(index < controllers.size()){ + if(controllers[index].controller){ + if(state){ + *state = controllers[index].state; + } + return true; + } + } + return false; + } void SetControllerFeedback(const wiInput::ControllerFeedback& data, int index) {} @@ -163,6 +251,67 @@ namespace wiSDLInput } return -1; } + + void controller_to_wiInput(uint32_t *current, Uint8 button, bool pressed){ + uint32_t btnenum; + switch(button){ + case SDL_CONTROLLER_BUTTON_DPAD_UP: btnenum = wiInput::GAMEPAD_BUTTON_UP; break; + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: btnenum = wiInput::GAMEPAD_BUTTON_LEFT; break; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: btnenum = wiInput::GAMEPAD_BUTTON_DOWN; break; + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: btnenum = wiInput::GAMEPAD_BUTTON_RIGHT; break; + case SDL_CONTROLLER_BUTTON_X: btnenum = wiInput::GAMEPAD_BUTTON_1; break; + case SDL_CONTROLLER_BUTTON_A: btnenum = wiInput::GAMEPAD_BUTTON_2; break; + case SDL_CONTROLLER_BUTTON_B: btnenum = wiInput::GAMEPAD_BUTTON_3; break; + case SDL_CONTROLLER_BUTTON_Y: btnenum = wiInput::GAMEPAD_BUTTON_4; break; + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: btnenum = wiInput::GAMEPAD_BUTTON_5; break; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: btnenum = wiInput::GAMEPAD_BUTTON_6; break; + case SDL_CONTROLLER_BUTTON_LEFTSTICK: btnenum = wiInput::GAMEPAD_BUTTON_7; break; + case SDL_CONTROLLER_BUTTON_RIGHTSTICK: btnenum = wiInput::GAMEPAD_BUTTON_8; break; + case SDL_CONTROLLER_BUTTON_BACK: btnenum = wiInput::GAMEPAD_BUTTON_9; break; + case SDL_CONTROLLER_BUTTON_START: btnenum = wiInput::GAMEPAD_BUTTON_10; break; + } + btnenum = 1 << (btnenum - wiInput::GAMEPAD_RANGE_START - 1); + if(pressed){ + *current |= btnenum; + }else{ + *current &= ~btnenum; + } + } + + void AddController(Sint32 id){ + if(SDL_IsGameController(id)){ + bool opened = false; + for(auto& controller : controllers){ + if(!controller.controller){ + controller.controller = SDL_GameControllerOpen(id); + if(controller.controller){ + controller.portID = id; + controller.internalID = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(controller.controller)); + opened = true; + } + } + } + if(!opened){ + auto& controller = controllers.emplace_back(); + controller.controller = SDL_GameControllerOpen(id); + if(controller.controller){ + controller.portID = id; + controller.internalID = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(controller.controller)); + opened = true; + } + } + } + } + + //Attempt to remove controller by checking if controller is attached or not + void RemoveController(){ + for(auto& controller : controllers){ + if(!SDL_JoystickGetAttached(SDL_GameControllerGetJoystick(controller.controller))){ + SDL_GameControllerClose(controller.controller); + controller.controller = nullptr; + } + } + } } #else