if keyboard config doesn't exist, autogenerate it

This commit is contained in:
kalaposfos13 2024-10-14 18:53:09 +02:00
parent 17e44de58f
commit 1ec9dc085a

View File

@ -35,7 +35,8 @@
#define SDL_EVENT_MOUSE_WHEEL_RIGHT SDL_EVENT_MOUSE_WHEEL + 6 #define SDL_EVENT_MOUSE_WHEEL_RIGHT SDL_EVENT_MOUSE_WHEEL + 6
Uint32 getMouseWheelEvent(const SDL_Event* event) { Uint32 getMouseWheelEvent(const SDL_Event* event) {
if(event->type != SDL_EVENT_MOUSE_WHEEL) return 0; if (event->type != SDL_EVENT_MOUSE_WHEEL)
return 0;
// std::cout << "We got a wheel event! "; // std::cout << "We got a wheel event! ";
if (event->wheel.y > 0) { if (event->wheel.y > 0) {
return SDL_EVENT_MOUSE_WHEEL_UP; return SDL_EVENT_MOUSE_WHEEL_UP;
@ -241,12 +242,87 @@ std::map<KeyBinding, AxisMapping> axis_map = {};
int mouse_joystick_binding = 0; int mouse_joystick_binding = 0;
Uint32 mouse_polling_id = 0; Uint32 mouse_polling_id = 0;
bool mouse_enabled = true; bool mouse_enabled = true;
const std::string default_config =
R"(## SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
## SPDX-License-Identifier: GPL-2.0-or-later
#Default controller button mappings
#Taken keys:
#F11 : fullscreen
#F10 : FPS counter
#F9 : toggle mouse capture
#F8 : reparse keyboard input(this)
#F7 : toggle mouse-to-joystick input
# (it overwrites everything else to that joystick, so this is required)
#This is a mapping for Bloodborne, inspired by other Souls titles on PC.
#This is a quick and dirty implementation of binding the mouse to a user-specified joystick
mouse_to_joystick = left;
#Use another item(healing), change status in inventory
triangle = f;
#Dodge, back in inventory
circle = space;
#Interact, select item in inventory
cross = e;
#Use quick item, remove item in inventory
square = r;
#Emergency extra bullets
up = w, lalt;
#Change quick item
down = s, lalt;
#Change weapon in left hand
left = a, lalt;
#Change weapon in right hand
right = d, lalt;
#Menu
options = escape;
#Gestures
touchpad = g;
#Transform
l1 = rightbutton, lshift;
#Shoot
r1 = leftbutton;
#Light attack
l2 = rightbutton;
#Heavy attack
r2 = leftbutton, lshift;
#Does nothing
l3 = x;
#Center cam, lock on
r3 = q;
#Axis mappings
#Move
axis_left_x_minus = a;
axis_left_x_plus = d;
axis_left_y_minus = w;
axis_left_y_plus = s;
)";
void WindowSDL::parseInputConfig(const std::string& filename) { void WindowSDL::parseInputConfig(const std::string& filename) {
// Read configuration file. // Read configuration file.
// std::cout << "Reading keyboard config...\n"; // std::cout << "Reading keyboard config...\n";
const auto user_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir); const auto config_file = Common::FS::GetUserPath(Common::FS::PathType::UserDir) / filename;
std::ifstream file(user_dir / filename); if (!std::filesystem::exists(config_file)) {
// create it
std::ofstream file;
file.open(config_file, std::ios::out);
if (file.is_open()) {
file << default_config;
file.close();
std::cout << "Config file generated.\n";
} else {
std::cerr << "Error creating file!\n";
}
}
std::ifstream file(config_file);
if (!file.is_open()) { if (!file.is_open()) {
std::cerr << "Error opening file: " << filename << std::endl; std::cerr << "Error opening file: " << filename << std::endl;
return; return;
@ -258,38 +334,35 @@ void WindowSDL::parseInputConfig(const std::string& filename) {
std::string line; std::string line;
while (std::getline(file, line)) { while (std::getline(file, line)) {
lineCount++; lineCount++;
// strip the ; and whitespace
line.erase(std::remove(line.begin(), line.end(), ' '), line.end());
if (line[line.length() - 1] == ';') {
line = line.substr(0, line.length() - 1);
}
// Ignore comment lines // Ignore comment lines
if (line.empty() || line[0] == '#') { if (line.empty() || line[0] == '#') {
continue; continue;
} }
// strip the ; and whitespace that we put there so that the braindead clang-format is happy
line = line.substr(0, line.length() - 1);
line.erase(std::remove(line.begin(), line.end(), ' '), line.end());
// Split the line by '=' // Split the line by '='
std::size_t equal_pos = line.find('='); std::size_t equal_pos = line.find('=');
if (equal_pos == std::string::npos) { if (equal_pos == std::string::npos) {
std::cerr << "Invalid line format: " << line << std::endl; std::cerr << "Invalid line format at line: " << lineCount << " data: " << line
<< std::endl;
continue; continue;
} }
std::string controller_input = line.substr(0, equal_pos); std::string controller_input = line.substr(0, equal_pos);
std::string kbm_input = line.substr(equal_pos + 1); std::string kbm_input = line.substr(equal_pos + 1);
KeyBinding binding = {0, SDL_KMOD_NONE}; // Initialize KeyBinding KeyBinding binding = {0, SDL_KMOD_NONE};
// quick hack to configure the mouse // special check for mouse to joystick input
if (controller_input == "mouse_to_joystick") { if (controller_input == "mouse_to_joystick") {
switch (kbm_input[0]) { if (kbm_input == "left") {
case 'l':
mouse_joystick_binding = 1; mouse_joystick_binding = 1;
break; } else if (kbm_input == "right") {
case 'r':
mouse_joystick_binding = 2; mouse_joystick_binding = 2;
break; } else {
case 'n': mouse_joystick_binding = 0; // default to 'none' or invalid
default:
mouse_joystick_binding = 0;
break;
} }
continue; continue;
} }
@ -344,6 +417,7 @@ Uint32 WindowSDL::keyRepeatCallback(void* param, Uint32 id, Uint32 interval) {
auto* data = (std::pair<WindowSDL*, SDL_Event*>*)param; auto* data = (std::pair<WindowSDL*, SDL_Event*>*)param;
KeyBinding binding(data->second); KeyBinding binding(data->second);
if (data->second->type == SDL_EVENT_MOUSE_WHEEL) { if (data->second->type == SDL_EVENT_MOUSE_WHEEL) {
// send an off signal a frame later
auto button_it = button_map.find(binding); auto button_it = button_map.find(binding);
auto axis_it = axis_map.find(binding); auto axis_it = axis_map.find(binding);
if (button_it != button_map.end()) { if (button_it != button_map.end()) {
@ -351,7 +425,7 @@ Uint32 WindowSDL::keyRepeatCallback(void* param, Uint32 id, Uint32 interval) {
} else if (axis_it != axis_map.end()) { } else if (axis_it != axis_map.end()) {
data->first->controller->Axis(0, axis_it->second.axis, Input::GetAxis(-0x80, 0x80, 0)); data->first->controller->Axis(0, axis_it->second.axis, Input::GetAxis(-0x80, 0x80, 0));
} }
return 0;
} }
data->first->updateModKeyedInputsManually(binding); data->first->updateModKeyedInputsManually(binding);
delete data->second; delete data->second;
@ -366,7 +440,8 @@ Uint32 WindowSDL::mousePolling(void* param, Uint32 id, Uint32 interval) {
} }
void WindowSDL::updateMouse() { void WindowSDL::updateMouse() {
if(!mouse_enabled) return; if (!mouse_enabled)
return;
Input::Axis axis_x, axis_y; Input::Axis axis_x, axis_y;
switch (mouse_joystick_binding) { switch (mouse_joystick_binding) {
case 1: case 1:
@ -595,9 +670,7 @@ void WindowSDL::onKeyPress(const SDL_Event* event) {
} }
if (axis_it != axis_map.end()) { if (axis_it != axis_map.end()) {
axis = axis_it->second.axis; axis = axis_it->second.axis;
axis_value = (input_down) axis_value = (input_down) ? axis_it->second.value : 0;
? axis_it->second.value
: 0;
int ax = Input::GetAxis(-0x80, 0x80, axis_value); int ax = Input::GetAxis(-0x80, 0x80, axis_value);
controller->Axis(0, axis, ax); controller->Axis(0, axis, ax);
} }