1
0
Fork 0
mirror of https://github.com/Detanup01/gbe_fork.git synced 2025-06-07 17:55:55 +02:00
This commit is contained in:
f8ith 2025-06-05 17:38:10 +08:00 committed by GitHub
commit 63ed264619
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 4258 additions and 2890 deletions

View file

@ -146,7 +146,7 @@ static inline void reset_LastError()
#endif #endif
// Other libs includes // Other libs includes
#include "gamepad/gamepad.h" // #include "gamepad/gamepad.h"
// Steamsdk includes // Steamsdk includes
#include "steam/steam_api.h" #include "steam/steam_api.h"

View file

@ -307,7 +307,10 @@ public:
//controller //controller
struct Controller_Settings controller_settings{}; struct Controller_Settings controller_settings{};
std::string glyphs_directory{}; std::string glyphs_directory{};
bool flip_nintendo_layout = false;
bool combine_joycons = true;
uint16 inner_deadzone = 2000;
uint16 outer_deadzone = 3000;
// allow Steam_User_Stats::FindLeaderboard() to always succeed and create the given unknown leaderboard // allow Steam_User_Stats::FindLeaderboard() to always succeed and create the given unknown leaderboard
bool disable_leaderboards_create_unknown = false; bool disable_leaderboards_create_unknown = false;

View file

@ -17,9 +17,10 @@
#ifndef __INCLUDED_STEAM_CONTROLLER_H__ #ifndef __INCLUDED_STEAM_CONTROLLER_H__
#define __INCLUDED_STEAM_CONTROLLER_H__ #define __INCLUDED_STEAM_CONTROLLER_H__
#define GAMEPAD_COUNT 4
#include "base.h" #include "base.h"
#include "gamepad_provider/gamepad_provider.hpp"
struct Controller_Map { struct Controller_Map {
std::map<ControllerDigitalActionHandle_t, std::set<int>> active_digital{}; std::map<ControllerDigitalActionHandle_t, std::set<int>> active_digital{};
@ -30,10 +31,13 @@ struct Controller_Action {
ControllerHandle_t controller_handle{}; ControllerHandle_t controller_handle{};
struct Controller_Map active_map{}; struct Controller_Map active_map{};
ControllerDigitalActionHandle_t active_set{}; ControllerDigitalActionHandle_t active_set{};
std::map<ControllerActionSetHandle_t, struct Controller_Map> active_layers{};
Controller_Action(ControllerHandle_t controller_handle); Controller_Action(ControllerHandle_t controller_handle);
void activate_action_set(ControllerDigitalActionHandle_t active_set, std::map<ControllerActionSetHandle_t, struct Controller_Map> &controller_maps); void activate_action_set(ControllerDigitalActionHandle_t active_set, std::map<ControllerActionSetHandle_t, struct Controller_Map> &controller_maps);
void activate_action_set_layer(ControllerActionSetHandle_t active_layer, std::map<ControllerActionSetHandle_t, struct Controller_Map> &controller_maps);
void deactivate_action_set_layer(ControllerActionSetHandle_t active_layer);
std::set<int> button_id(ControllerDigitalActionHandle_t handle); std::set<int> button_id(ControllerDigitalActionHandle_t handle);
std::pair<std::set<int>, enum EInputSourceMode> analog_id(ControllerAnalogActionHandle_t handle); std::pair<std::set<int>, enum EInputSourceMode> analog_id(ControllerAnalogActionHandle_t handle);
}; };
@ -101,6 +105,7 @@ public ISteamInput
std::map<EInputActionOrigin, std::string> steaminput_glyphs{}; std::map<EInputActionOrigin, std::string> steaminput_glyphs{};
std::map<EControllerActionOrigin, std::string> steamcontroller_glyphs{}; std::map<EControllerActionOrigin, std::string> steamcontroller_glyphs{};
std::thread sdl_thread{};
std::thread background_rumble_thread{}; std::thread background_rumble_thread{};
Rumble_Thread_Data *rumble_thread_data{}; Rumble_Thread_Data *rumble_thread_data{};
@ -108,7 +113,8 @@ public ISteamInput
bool initialized{}; bool initialized{};
bool explicitly_call_run_frame{}; bool explicitly_call_run_frame{};
void set_handles(std::map<std::string, std::map<std::string, std::pair<std::set<std::string>, std::string>>> action_sets); void set_handles(std::map<std::string, std::map<std::string, std::pair<std::set<std::string>, std::string>>> action_sets,
std::map<std::string, std::map<std::string, std::pair<std::set<std::string>, std::string>>> action_set_layers);
void RunCallbacks(); void RunCallbacks();

View file

@ -21,6 +21,7 @@
#define SI_SUPPORT_IOSTREAMS #define SI_SUPPORT_IOSTREAMS
#define SI_NO_MBCS #define SI_NO_MBCS
#include "simpleini/SimpleIni.h" #include "simpleini/SimpleIni.h"
#include "gamepad_provider/gamepad_provider.hpp"
constexpr const static char config_ini_app[] = "configs.app.ini"; constexpr const static char config_ini_app[] = "configs.app.ini";
@ -452,33 +453,32 @@ static void split_string(const std::string &s, char delim, Out result) {
// folder "controller" // folder "controller"
static void load_gamecontroller_settings(Settings *settings) static void load_gamecontroller_settings(Settings *settings)
{ {
std::string path = Local_Storage::get_game_settings_path() + "controller"; auto process_paths = [&](std::string path, std::map<std::string, std::map<std::string, std::pair<std::set<std::string>, std::string>>> action_sets) {
std::vector<std::string> paths = Local_Storage::get_filenames_path(path); std::vector<std::string> paths = Local_Storage::get_filenames_path(path);
for (auto& p : paths) {
for (auto & p: paths) {
size_t length = p.length(); size_t length = p.length();
if (length < 4) continue; if (length < 4) continue;
if ( std::toupper(p.back()) != 'T') continue; if (std::toupper(p.back()) != 'T') continue;
if ( std::toupper(p[length - 2]) != 'X') continue; if (std::toupper(p[length - 2]) != 'X') continue;
if ( std::toupper(p[length - 3]) != 'T') continue; if (std::toupper(p[length - 3]) != 'T') continue;
if (p[length - 4] != '.') continue; if (p[length - 4] != '.') continue;
PRINT_DEBUG("controller config %s", p.c_str()); PRINT_DEBUG("controller config %s", p.c_str());
std::string action_set_name = p.substr(0, length - 4); std::string action_set_name = p.substr(0, length - 4);
std::transform(action_set_name.begin(), action_set_name.end(), action_set_name.begin(),[](unsigned char c){ return std::toupper(c); }); std::transform(action_set_name.begin(), action_set_name.end(), action_set_name.begin(), [](unsigned char c) { return std::toupper(c); });
std::string controller_config_path = path + PATH_SEPARATOR + p; std::string controller_config_path = path + PATH_SEPARATOR + p;
std::ifstream input( std::filesystem::u8path(controller_config_path) ); std::ifstream input(std::filesystem::u8path(controller_config_path));
if (input.is_open()) { if (input.is_open()) {
common_helpers::consume_bom(input); common_helpers::consume_bom(input);
std::map<std::string, std::pair<std::set<std::string>, std::string>> button_pairs; std::map<std::string, std::pair<std::set<std::string>, std::string>> button_pairs;
for( std::string line; getline( input, line ); ) { for (std::string line; getline(input, line); ) {
if (!line.empty() && line[line.length()-1] == '\n') { if (!line.empty() && line[line.length() - 1] == '\n') {
line.pop_back(); line.pop_back();
} }
if (!line.empty() && line[line.length()-1] == '\r') { if (!line.empty() && line[line.length() - 1] == '\r') {
line.pop_back(); line.pop_back();
} }
@ -494,24 +494,31 @@ static void load_gamecontroller_settings(Settings *settings)
if (deliminator2 != std::string::npos && deliminator2 != line.size()) { if (deliminator2 != std::string::npos && deliminator2 != line.size()) {
button_name = line.substr(deliminator + 1, deliminator2 - (deliminator + 1)); button_name = line.substr(deliminator + 1, deliminator2 - (deliminator + 1));
source_mode = line.substr(deliminator2 + 1); source_mode = line.substr(deliminator2 + 1);
} else { }
else {
button_name = line.substr(deliminator + 1); button_name = line.substr(deliminator + 1);
source_mode = ""; source_mode = "";
} }
} }
std::transform(action_name.begin(), action_name.end(), action_name.begin(),[](unsigned char c){ return std::toupper(c); }); std::transform(action_name.begin(), action_name.end(), action_name.begin(), [](unsigned char c) { return std::toupper(c); });
std::transform(button_name.begin(), button_name.end(), button_name.begin(),[](unsigned char c){ return std::toupper(c); }); std::transform(button_name.begin(), button_name.end(), button_name.begin(), [](unsigned char c) { return std::toupper(c); });
std::pair<std::set<std::string>, std::string> button_config = {{}, source_mode}; std::pair<std::set<std::string>, std::string> button_config = { {}, source_mode };
split_string(button_name, ',', std::inserter(button_config.first, button_config.first.begin())); split_string(button_name, ',', std::inserter(button_config.first, button_config.first.begin()));
button_pairs[action_name] = button_config; button_pairs[action_name] = button_config;
PRINT_DEBUG("Added %s %s %s", action_name.c_str(), button_name.c_str(), source_mode.c_str()); PRINT_DEBUG("Added %s %s %s", action_name.c_str(), button_name.c_str(), source_mode.c_str());
} }
settings->controller_settings.action_sets[action_set_name] = button_pairs; action_sets[action_set_name] = button_pairs;
PRINT_DEBUG("Added %zu action names to %s", button_pairs.size(), action_set_name.c_str()); PRINT_DEBUG("Added %zu action names to %s", button_pairs.size(), action_set_name.c_str());
} }
} }
};
std::string path = Local_Storage::get_game_settings_path() + "controller";
std::string layers_path = path + (PATH_SEPARATOR "layers" PATH_SEPARATOR);
process_paths(path, settings->controller_settings.action_sets);
process_paths(layers_path, settings->controller_settings.action_set_layers);
settings->glyphs_directory = path + (PATH_SEPARATOR "glyphs" PATH_SEPARATOR); settings->glyphs_directory = path + (PATH_SEPARATOR "glyphs" PATH_SEPARATOR);
} }
@ -1513,6 +1520,20 @@ static void parse_simple_features(class Settings *settings_client, class Setting
settings_server->enable_builtin_preowned_ids = ini.GetBoolValue("main::misc", "enable_steam_preowned_ids", settings_server->enable_builtin_preowned_ids); settings_server->enable_builtin_preowned_ids = ini.GetBoolValue("main::misc", "enable_steam_preowned_ids", settings_server->enable_builtin_preowned_ids);
} }
// [main::gamepad]
static void parse_user_gamepad_settings(class Settings* settings_client, class Settings* settings_server) {
settings_client->flip_nintendo_layout = ini.GetBoolValue("main::gamepad", "flip_nintendo_layout", settings_client->flip_nintendo_layout);
settings_server->flip_nintendo_layout = ini.GetBoolValue("main::gamepad", "flip_nintendo_layout", settings_server->flip_nintendo_layout);
settings_client->combine_joycons = ini.GetBoolValue("main::gamepad", "combine_joycons", settings_client->combine_joycons);
settings_server->combine_joycons = ini.GetBoolValue("main::gamepad", "combine_joycons", settings_server->combine_joycons);
settings_client->inner_deadzone = std::min(static_cast<uint16>(ini.GetLongValue("main::gamepad", "inner_deadzone", settings_client->inner_deadzone)), static_cast<uint16>(JOYSTICK_MAX));
settings_server->inner_deadzone = std::min(static_cast<uint16>(ini.GetLongValue("main::gamepad", "inner_deadzone", settings_server->inner_deadzone)), static_cast<uint16>(JOYSTICK_MAX));
settings_client->outer_deadzone = std::min(static_cast<uint16>(ini.GetLongValue("main::gamepad", "outer_deadzone", settings_client->outer_deadzone)), static_cast<uint16>(JOYSTICK_MAX));
settings_server->outer_deadzone = std::min(static_cast<uint16>(ini.GetLongValue("main::gamepad", "outer_deadzone", settings_server->outer_deadzone)), static_cast<uint16>(JOYSTICK_MAX));
}
// [main::stats] // [main::stats]
static void parse_stats_features(class Settings *settings_client, class Settings *settings_server) static void parse_stats_features(class Settings *settings_client, class Settings *settings_server)
{ {
@ -1791,6 +1812,7 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s
parse_simple_features(settings_client, settings_server); parse_simple_features(settings_client, settings_server);
parse_stats_features(settings_client, settings_server); parse_stats_features(settings_client, settings_server);
parse_user_gamepad_settings(settings_client, settings_server);
parse_dlc(settings_client, settings_server); parse_dlc(settings_client, settings_server);
parse_installed_app_Ids(settings_client, settings_server); parse_installed_app_Ids(settings_client, settings_server);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,250 @@
#include "gamepad_provider/gamepad_provider.hpp"
#include <array>
#include <algorithm>
#include <string>
#define GAMEPAD_COUNT 16
#if !defined(CONTROLLER_SUPPORT)
int gamepad_provider::sdl::DetectGamepads(std::vector<ControllerHandle_t>& handlesOut, std::vector<ControllerHandle_t>& newHandlesOut) { return 0; }
bool gamepad_provider::sdl::GamepadInit(bool combine_joycons) { return false; };
void gamepad_provider::sdl::GamepadShutdown(void) {};
void gamepad_provider::sdl::GamepadUpdate(void) {};
bool gamepad_provider::sdl::GamepadButtonDown(ControllerHandle_t id, GAMEPAD_BUTTON button) { return false; };
float gamepad_provider::sdl::GamepadTriggerLength(ControllerHandle_t id, GAMEPAD_TRIGGER trigger) { return 0.0f; };
void gamepad_provider::sdl::GamepadStickXY(ControllerHandle_t id, GAMEPAD_STICK stick, float* out_x, float* out_y) {};
void gamepad_provider::sdl::GamepadStickNormXY(ControllerHandle_t id, GAMEPAD_STICK stick, float* out_x, float* out_y, int inner_deadzone, int outer_deadzone) {};
void gamepad_provider::sdl::GamepadSetRumble(ControllerHandle_t id, unsigned short left, unsigned short right, unsigned int rumble_length_ms) {};
ESteamInputType gamepad_provider::sdl::GamepadGetType(ControllerHandle_t id) { return k_ESteamInputType_Unknown; };
#else
namespace gamepad_provider {
namespace sdl {
namespace {
static std::map<ControllerHandle_t, SDL_JoystickID> sdl_controller_map{};
static std::map<std::string, std::vector<ControllerHandle_t>> guid_controller_map{};
static ControllerHandle_t current_controller_index = 1; // Must start from 1
inline SDL_Gamepad* GamepadGetFromHandle(ControllerHandle_t controller) {
auto sdl_controller = sdl_controller_map.find(controller);
if (sdl_controller == sdl_controller_map.end()) return nullptr;
return SDL_GetGamepadFromID(sdl_controller->second);
}
}
}
}
bool gamepad_provider::sdl::GamepadInit(bool combine_joycons) {
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_ENHANCED_REPORTS, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS, combine_joycons ? "1" : "0"); // Joycons are combined by default
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_STADIA, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_STEAM, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_LUNA, "1");
if (!SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD | SDL_INIT_HAPTIC | SDL_INIT_EVENTS))
return false;
SDL_SetGamepadEventsEnabled(false);
return true;
}
void gamepad_provider::sdl::GamepadShutdown(void) {
for (auto& c : sdl_controller_map) {
SDL_Gamepad* gamepad = SDL_GetGamepadFromID(c.second);
if (gamepad)
SDL_CloseGamepad(gamepad);
}
SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD | SDL_INIT_HAPTIC | SDL_INIT_EVENTS);
}
void gamepad_provider::sdl::GamepadUpdate(void) {
SDL_UpdateGamepads();
}
/* Detects gamepad connect/disconnects. */
int gamepad_provider::sdl::DetectGamepads(std::vector<ControllerHandle_t> &handlesOut, std::vector<ControllerHandle_t> &newHandlesOut) {
SDL_UpdateGamepads();
int count = 0;
SDL_JoystickID* gamepads = SDL_GetGamepads(&count);
for (int i = 0; i < count && i < GAMEPAD_COUNT; ++i) {
bool newHandleCreated = false;
SDL_JoystickID instance_id = gamepads[i];
SDL_GUID guid = SDL_GetGamepadGUIDForID(instance_id);
char guid_string[33];
SDL_GUIDToString(guid, guid_string, 33);
auto guid_handles = guid_controller_map.find(guid_string);
// Always open gamepad, since a disconnected controller could be in the map
SDL_Gamepad* gamepadHandle = SDL_OpenGamepad(instance_id);
ControllerHandle_t curr_index = 0;
if (guid_handles == guid_controller_map.end()) {
newHandlesOut.push_back(current_controller_index);
char guid_string[33];
SDL_GUIDToString(guid, guid_string, 33);
sdl_controller_map.insert(std::pair<ControllerHandle_t, SDL_JoystickID>(current_controller_index, instance_id));
guid_controller_map.insert(std::pair<std::string, std::vector<ControllerHandle_t>>(guid_string, std::vector<ControllerHandle_t>{current_controller_index}));
curr_index = current_controller_index;
newHandleCreated = true;
++current_controller_index;
}
else {
bool replaced = false;
// GUID already exists
for (auto& c : guid_handles->second) {
SDL_Gamepad* gamepadHandle = GamepadGetFromHandle(c);
if (!gamepadHandle || !SDL_GamepadConnected(gamepadHandle)) {
// Gamepad is not connected, replace this index
if (gamepadHandle)
SDL_CloseGamepad(gamepadHandle);
gamepadHandle = SDL_OpenGamepad(instance_id);
sdl_controller_map[c] = instance_id;
replaced = true;
curr_index = c;
break;
}
if (SDL_GetGamepadID(gamepadHandle) == instance_id) {
// Gamepad is connected and already in controller_map
replaced = true;
curr_index = c;
break;
}
}
if (!replaced) {
sdl_controller_map.insert(std::pair<ControllerHandle_t, SDL_JoystickID>(current_controller_index, instance_id));
guid_handles->second.push_back(current_controller_index);
curr_index = current_controller_index;
newHandleCreated = true;
++current_controller_index;
}
}
handlesOut.push_back(curr_index);
if (newHandleCreated) {
newHandlesOut.push_back(curr_index);
}
}
SDL_free(gamepads);
return count;
}
bool gamepad_provider::sdl::GamepadButtonDown(ControllerHandle_t id, GAMEPAD_BUTTON button) {
SDL_Gamepad* gamepad = GamepadGetFromHandle(id);
if (!gamepad)
return false;
return SDL_GetGamepadButton(gamepad, (SDL_GamepadButton)button);
}
float gamepad_provider::sdl::GamepadTriggerLength(ControllerHandle_t id, GAMEPAD_TRIGGER trigger) {
SDL_Gamepad* gamepad = GamepadGetFromHandle(id);
if (!gamepad)
return 0.0f;
if (trigger == TRIGGER_LEFT)
return static_cast<float>(SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER));
else if (trigger == TRIGGER_RIGHT)
return static_cast<float>(SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER));
return 0.0f;
}
void gamepad_provider::sdl::GamepadStickNormXY(ControllerHandle_t id, GAMEPAD_STICK stick, float* out_x, float* out_y, int inner_deadzone, int outer_deadzone) {
float x = 0.0f, y = 0.0f;
GamepadStickXY(id, stick, &x, &y);
// normalize X and Y
float length = static_cast<float>(sqrt(x * x + y * y));
if (length > inner_deadzone) {
// clamp length to maximum value
length = std::min(length, 32767.f);
// normalized X and Y values
x /= (JOYSTICK_MAX - outer_deadzone);
y /= (JOYSTICK_MAX - outer_deadzone);
//fix special case
x = std::clamp(x, -1.0f, 1.0f);
y = std::clamp(y, -1.0f, 1.0f);
}
else {
x = 0.0f;
y = 0.0f;
}
*out_x = x;
*out_y = y;
}
void gamepad_provider::sdl::GamepadStickXY(ControllerHandle_t id, GAMEPAD_STICK stick, float* out_x, float* out_y) {
SDL_Gamepad* gamepad = GamepadGetFromHandle(id);
if (!gamepad)
return;
if (stick == STICK_LEFT) {
*out_x = static_cast<float>(SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFTX));
*out_y = static_cast<float>(-SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFTY));
}
else if (stick == STICK_RIGHT) {
*out_x = static_cast<float>(SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTX));
*out_y = static_cast<float>(-SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTY));
}
}
void gamepad_provider::sdl::GamepadSetRumble(ControllerHandle_t id, unsigned short left, unsigned short right, unsigned int rumble_length_ms) {
SDL_Gamepad* gamepad = GamepadGetFromHandle(id);
if (!gamepad)
return;
SDL_RumbleGamepad(gamepad, left, right, rumble_length_ms);
}
void gamepad_provider::sdl::GamepadSetTriggersRumble(ControllerHandle_t id, unsigned short left, unsigned short right, unsigned int rumble_length_ms) {
SDL_Gamepad* gamepad = GamepadGetFromHandle(id);
if (!gamepad)
return;
SDL_RumbleGamepadTriggers(gamepad, left, right, rumble_length_ms);
}
ESteamInputType gamepad_provider::sdl::GamepadGetType(ControllerHandle_t id) {
SDL_Gamepad* gamepad = GamepadGetFromHandle(id);
if (!gamepad)
return k_ESteamInputType_Unknown;
switch (SDL_GetGamepadType(gamepad)) {
case SDL_GAMEPAD_TYPE_XBOX360:
return k_ESteamInputType_XBox360Controller;
case SDL_GAMEPAD_TYPE_XBOXONE:
return k_ESteamInputType_XBoxOneController;
case SDL_GAMEPAD_TYPE_PS3:
return k_ESteamInputType_PS3Controller;
case SDL_GAMEPAD_TYPE_PS4:
return k_ESteamInputType_PS4Controller;
case SDL_GAMEPAD_TYPE_PS5:
return k_ESteamInputType_PS5Controller;
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT:
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT:
return k_ESteamInputType_SwitchJoyConSingle;
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR:
return k_ESteamInputType_SwitchJoyConPair;
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO:
return k_ESteamInputType_SwitchProController;
case SDL_GAMEPAD_TYPE_STANDARD:
return k_ESteamInputType_GenericGamepad;
default:
return k_ESteamInputType_Unknown;
}
}
#endif

View file

@ -0,0 +1,90 @@
#pragma once
#include <map>
#include <vector>
#include <steam/steamtypes.h>
#include <steam/isteamcontroller.h>
#if !defined(CONTROLLER_SUPPORT)
#define JOYSTICK_MAX 32767
enum GAMEPAD_BUTTON {
BUTTON_DPAD_UP, /* UP on the direction pad */
BUTTON_DPAD_DOWN, /**< DOWN on the direction pad */
BUTTON_DPAD_LEFT, /**< LEFT on the direction pad */
BUTTON_DPAD_RIGHT, /**< RIGHT on the direction pad */
BUTTON_START, /**< START button */
BUTTON_BACK, /**< BACK button */
BUTTON_LEFT_THUMB, /**< Left analog stick button */
BUTTON_RIGHT_THUMB, /**< Right analog stick button */
BUTTON_LEFT_SHOULDER, /**< Left bumper button */
BUTTON_RIGHT_SHOULDER, /**< Right bumper button */
BUTTON_A, /**< A button */
BUTTON_B, /**< B button */
BUTTON_X, /**< X button */
BUTTON_Y, /**< Y button */
BUTTON_COUNT = 16
};
#else
#include <SDL3/SDL.h>
#include <SDL3/SDL_joystick.h>
#define JOYSTICK_MAX SDL_JOYSTICK_AXIS_MAX
enum GAMEPAD_BUTTON {
BUTTON_DPAD_UP = SDL_GAMEPAD_BUTTON_DPAD_UP, /**< UP on the direction pad */
BUTTON_DPAD_DOWN = SDL_GAMEPAD_BUTTON_DPAD_DOWN, /**< DOWN on the direction pad */
BUTTON_DPAD_LEFT = SDL_GAMEPAD_BUTTON_DPAD_LEFT, /**< LEFT on the direction pad */
BUTTON_DPAD_RIGHT = SDL_GAMEPAD_BUTTON_DPAD_RIGHT, /**< RIGHT on the direction pad */
BUTTON_START = SDL_GAMEPAD_BUTTON_START, /**< START button */
BUTTON_BACK = SDL_GAMEPAD_BUTTON_BACK, /**< BACK button */
BUTTON_LEFT_THUMB = SDL_GAMEPAD_BUTTON_LEFT_STICK, /**< Left analog stick button */
BUTTON_RIGHT_THUMB = SDL_GAMEPAD_BUTTON_RIGHT_STICK, /**< Right analog stick button */
BUTTON_LEFT_SHOULDER = SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, /**< Left bumper button */
BUTTON_RIGHT_SHOULDER = SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, /**< Right bumper button */
BUTTON_A = SDL_GAMEPAD_BUTTON_SOUTH, /**< A button */
BUTTON_B = SDL_GAMEPAD_BUTTON_EAST, /**< B button */
BUTTON_X = SDL_GAMEPAD_BUTTON_WEST, /**< X button */
BUTTON_Y = SDL_GAMEPAD_BUTTON_NORTH, /**< Y button */
BUTTON_COUNT = 16
};
#endif
/**
* Enumeration of the possible pressure/trigger buttons.
*/
enum GAMEPAD_TRIGGER {
TRIGGER_LEFT = 0, /**< Left trigger */
TRIGGER_RIGHT = 1, /**< Right trigger */
TRIGGER_COUNT /**< Number of triggers */
};
/**
* Enumeration of the analog sticks.
*/
enum GAMEPAD_STICK {
STICK_LEFT = 0, /**< Left stick */
STICK_RIGHT = 1, /**< Right stick */
STICK_COUNT /**< Number of analog sticks */
};
namespace gamepad_provider {
namespace sdl
{
int DetectGamepads(std::vector<ControllerHandle_t> &handlesOut, std::vector<ControllerHandle_t>& newHandlesOut);
bool GamepadInit(bool combine_joycons);
void GamepadShutdown(void);
void GamepadUpdate(void);
bool GamepadButtonDown(ControllerHandle_t id, GAMEPAD_BUTTON button);
float GamepadTriggerLength(ControllerHandle_t id, GAMEPAD_TRIGGER trigger);
void GamepadStickXY(ControllerHandle_t id, GAMEPAD_STICK stick, float* out_x, float* out_y);
void GamepadStickNormXY(ControllerHandle_t id, GAMEPAD_STICK stick, float* out_x, float* out_y, int inner_deadzone, int outer_deadzone);
void GamepadSetRumble(ControllerHandle_t id, unsigned short left, unsigned short right, unsigned int rumble_length_ms);
void GamepadSetTriggersRumble(ControllerHandle_t id, unsigned short left, unsigned short right, unsigned int rumble_length_ms);
ESteamInputType GamepadGetType(ControllerHandle_t id);
}
}

View file

@ -93,6 +93,11 @@ newoption {
trigger = "ext-ingame_overlay", trigger = "ext-ingame_overlay",
description = "Extract ingame_overlay", description = "Extract ingame_overlay",
} }
newoption {
category = "extract",
trigger = "ext-sdl3",
description = "Extract sdl3",
}
-- build -- build
newoption { newoption {
@ -146,6 +151,11 @@ newoption {
trigger = "build-ingame_overlay", trigger = "build-ingame_overlay",
description = "Build ingame_overlay", description = "Build ingame_overlay",
} }
newoption {
category = "build",
trigger = "build-sdl3",
description = "Build sdl3",
}
local function merge_list(src, dest) local function merge_list(src, dest)
@ -185,7 +195,9 @@ else
mycmake = mycmake .. '.exe' mycmake = mycmake .. '.exe'
end end
if not os.isfile(mycmake) then if not os.isfile(mycmake) then
error('cmake is missing from third-party dir, you can specify custom cmake location, run the script with --help. cmake: ' .. mycmake) error(
'cmake is missing from third-party dir, you can specify custom cmake location, run the script with --help. cmake: ' ..
mycmake)
end end
end end
@ -243,7 +255,8 @@ local function cmake_build(dep_folder, is_32, extra_cmd_defs, c_flags_init, cxx_
return return
end end
local cmake_common_defs_str = '-D' .. table.concat(cmake_common_defs, ' -D') .. ' -DCMAKE_INSTALL_PREFIX="' .. install_dir .. '"' local cmake_common_defs_str = '-D' ..
table.concat(cmake_common_defs, ' -D') .. ' -DCMAKE_INSTALL_PREFIX="' .. install_dir .. '"'
local cmd_gen = mycmake .. ' -S "' .. dep_base .. '" -B "' .. build_dir .. '" ' .. cmake_common_defs_str local cmd_gen = mycmake .. ' -S "' .. dep_base .. '" -B "' .. build_dir .. '" ' .. cmake_common_defs_str
local all_cflags_init = {} local all_cflags_init = {}
@ -308,7 +321,7 @@ local function cmake_build(dep_folder, is_32, extra_cmd_defs, c_flags_init, cxx_
-- write toolchain file -- write toolchain file
local toolchain_file_content = '' local toolchain_file_content = ''
if _OPTIONS["cmake-toolchain"] then if _OPTIONS["cmake-toolchain"] then
toolchain_file_content='include(' .. _OPTIONS["cmake-toolchain"] .. ')\n\n' toolchain_file_content = 'include(' .. _OPTIONS["cmake-toolchain"] .. ')\n\n'
end end
if #cflags_init_str > 0 then if #cflags_init_str > 0 then
toolchain_file_content = toolchain_file_content .. 'set(CMAKE_C_FLAGS_INIT "' .. cflags_init_str .. '" )\n' toolchain_file_content = toolchain_file_content .. 'set(CMAKE_C_FLAGS_INIT "' .. cflags_init_str .. '" )\n'
@ -317,12 +330,15 @@ local function cmake_build(dep_folder, is_32, extra_cmd_defs, c_flags_init, cxx_
toolchain_file_content = toolchain_file_content .. 'set(CMAKE_CXX_FLAGS_INIT "' .. cxxflags_init_str .. '" )\n' toolchain_file_content = toolchain_file_content .. 'set(CMAKE_CXX_FLAGS_INIT "' .. cxxflags_init_str .. '" )\n'
end end
if string.match(_ACTION, 'vs.+') then -- because libssq doesn't care about CMAKE_C/XX_FLAGS_INIT if string.match(_ACTION, 'vs.+') then -- because libssq doesn't care about CMAKE_C/XX_FLAGS_INIT
toolchain_file_content = toolchain_file_content .. 'set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT /D_MT" ) \n' toolchain_file_content = toolchain_file_content ..
toolchain_file_content = toolchain_file_content .. 'set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT /D_MT" ) \n' 'set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT /D_MT" ) \n'
toolchain_file_content = toolchain_file_content ..
'set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT /D_MT" ) \n'
end end
if #toolchain_file_content > 0 then if #toolchain_file_content > 0 then
local toolchain_file = path.join(dep_base, 'toolchain_' .. tostring(is_32) .. '_' .. _ACTION .. '_' .. os_iden .. '.precmt') local toolchain_file = path.join(dep_base,
'toolchain_' .. tostring(is_32) .. '_' .. _ACTION .. '_' .. os_iden .. '.precmt')
if not io.writefile(toolchain_file, toolchain_file_content) then if not io.writefile(toolchain_file, toolchain_file_content) then
error("failed to write cmake toolchain") error("failed to write cmake toolchain")
return return
@ -365,7 +381,8 @@ local function cmake_build(dep_folder, is_32, extra_cmd_defs, c_flags_init, cxx_
if _OPTIONS['j'] then if _OPTIONS['j'] then
parallel_str = parallel_str .. ' ' .. _OPTIONS['j'] parallel_str = parallel_str .. ' ' .. _OPTIONS['j']
end end
local ok = os.execute(mycmake .. ' --build "' .. build_dir .. '" --config Release' .. parallel_str .. verbose_build_str) local ok = os.execute(mycmake ..
' --build "' .. build_dir .. '" --config Release' .. parallel_str .. verbose_build_str)
if not ok then if not ok then
error("failed to build") error("failed to build")
return return
@ -377,7 +394,7 @@ local function cmake_build(dep_folder, is_32, extra_cmd_defs, c_flags_init, cxx_
return return
end end
local cmd_install = mycmake.. ' --install "' .. build_dir .. '" --prefix "' .. install_dir .. '"' local cmd_install = mycmake .. ' --install "' .. build_dir .. '" --prefix "' .. install_dir .. '"'
print(cmd_install) print(cmd_install)
local ok = os.execute(cmd_install) local ok = os.execute(cmd_install)
if not ok then if not ok then
@ -427,6 +444,9 @@ end
if _OPTIONS["ext-ingame_overlay"] or _OPTIONS["all-ext"] then if _OPTIONS["ext-ingame_overlay"] or _OPTIONS["all-ext"] then
table.insert(deps_to_extract, { 'ingame_overlay/ingame_overlay.tar.gz', 'ingame_overlay' }) table.insert(deps_to_extract, { 'ingame_overlay/ingame_overlay.tar.gz', 'ingame_overlay' })
end end
if _OPTIONS["ext-sdl3"] or _OPTIONS["all-ext"] then
table.insert(deps_to_extract, { 'sdl3/sdl3.tar.gz', 'sdl3' })
end
-- start extraction -- start extraction
for _, dep in pairs(deps_to_extract) do for _, dep in pairs(deps_to_extract) do
@ -460,7 +480,9 @@ for _, dep in pairs(deps_to_extract) do
local ext = string.lower(string.sub(archive_file, -7)) -- ".tar.gz" local ext = string.lower(string.sub(archive_file, -7)) -- ".tar.gz"
local ok_cmd = false local ok_cmd = false
if ext == ".tar.gz" then if ext == ".tar.gz" then
ok_cmd = os.execute(extractor .. ' -bso0 -bse2 x "' .. archive_file .. '" -so | "' .. extractor .. '" -bso0 -bse2 x -si -ttar -y -aoa -o"' .. deps_dir .. '"') ok_cmd = os.execute(extractor ..
' -bso0 -bse2 x "' ..
archive_file .. '" -so | "' .. extractor .. '" -bso0 -bse2 x -si -ttar -y -aoa -o"' .. deps_dir .. '"')
else else
ok_cmd = os.execute(extractor .. ' -bso0 -bse2 x "' .. archive_file .. '" -y -aoa -o"' .. out_folder .. '"') ok_cmd = os.execute(extractor .. ' -bso0 -bse2 x "' .. archive_file .. '" -y -aoa -o"' .. out_folder .. '"')
end end
@ -479,7 +501,6 @@ for _, dep in pairs(deps_to_extract) do
-- end -- end
-- os.rmdir(inner_folder) -- os.rmdir(inner_folder)
-- end -- end
end end
@ -737,3 +758,15 @@ if _OPTIONS["build-ingame_overlay"] or _OPTIONS["all-build"] then
cmake_build('ingame_overlay', false, ingame_overlay_common_defs, nil, ingame_overlay_fixes) cmake_build('ingame_overlay', false, ingame_overlay_common_defs, nil, ingame_overlay_fixes)
end end
end end
if _OPTIONS["build-sdl3"] or _OPTIONS["all-build"] then
local sdl3_common_defs = {
}
if _OPTIONS["32-build"] then
cmake_build('sdl3', true, sdl3_common_defs)
end
if _OPTIONS["64-build"] then
cmake_build('sdl3', false, sdl3_common_defs)
end
end

File diff suppressed because it is too large Load diff