mirror of
https://github.com/imaginaryPineapple/OpenRayman.git
synced 2024-10-19 22:47:37 -04:00
Add rebindable keyboard keys
This commit is contained in:
parent
c277fb918d
commit
11ff4b30fb
|
@ -1,6 +1,5 @@
|
|||
{
|
||||
"info":
|
||||
{
|
||||
"info": {
|
||||
"name": "Rayman 2: The Great Escape (OpenRayman)",
|
||||
"description": "Rayman 2: The Great Escape with modifications for OpenRayman"
|
||||
},
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <json.hpp>
|
||||
#ifndef USE_LIBRETRO
|
||||
#include <SDL2/SDL.h>
|
||||
#endif
|
||||
|
||||
namespace openrayman
|
||||
{
|
||||
|
@ -13,6 +16,28 @@ namespace openrayman
|
|||
max_fps(0),
|
||||
game("rayman2_openrayman")
|
||||
{
|
||||
#ifndef USE_LIBRETRO
|
||||
keyboard_map["stick(strength)"] = SDL_GetScancodeName(SDL_SCANCODE_LSHIFT);
|
||||
|
||||
keyboard_map["stick(x, -)"] = SDL_GetScancodeName(SDL_SCANCODE_LEFT);
|
||||
keyboard_map["stick(x, +)"] = SDL_GetScancodeName(SDL_SCANCODE_RIGHT);
|
||||
keyboard_map["stick(y, -)"] = SDL_GetScancodeName(SDL_SCANCODE_UP);
|
||||
keyboard_map["stick(y, +)"] = SDL_GetScancodeName(SDL_SCANCODE_DOWN);
|
||||
|
||||
keyboard_map["start"] = SDL_GetScancodeName(SDL_SCANCODE_ESCAPE);
|
||||
|
||||
keyboard_map["a"] = SDL_GetScancodeName(SDL_SCANCODE_A);
|
||||
keyboard_map["b"] = SDL_GetScancodeName(SDL_SCANCODE_SPACE);
|
||||
|
||||
keyboard_map["l"] = SDL_GetScancodeName(SDL_SCANCODE_LCTRL);
|
||||
keyboard_map["r"] = SDL_GetScancodeName(SDL_SCANCODE_F1);
|
||||
keyboard_map["z"] = SDL_GetScancodeName(SDL_SCANCODE_J);
|
||||
|
||||
keyboard_map["cbtn(x, -)"] = SDL_GetScancodeName(SDL_SCANCODE_Q);
|
||||
keyboard_map["cbtn(x, +)"] = SDL_GetScancodeName(SDL_SCANCODE_W);
|
||||
keyboard_map["cbtn(y, -)"] = SDL_GetScancodeName(SDL_SCANCODE_O);
|
||||
keyboard_map["cbtn(y, +)"] = SDL_GetScancodeName(SDL_SCANCODE_END);
|
||||
#endif
|
||||
if(!reload())
|
||||
save();
|
||||
}
|
||||
|
@ -32,14 +57,37 @@ namespace openrayman
|
|||
if(config_stream.is_open())
|
||||
{
|
||||
config_stream >> config_json;
|
||||
if(config_json.count("vsync") > 0)
|
||||
vsync = config_json["vsync"];
|
||||
if(config_json.count("fullscreen") > 0)
|
||||
fullscreen = config_json["fullscreen"];
|
||||
if(config_json.count("max_fps") > 0)
|
||||
max_fps = config_json["max_fps"];
|
||||
if(config_json.count("game") > 0)
|
||||
game = config_json["game"];
|
||||
if(config_json.count("gfx") > 0)
|
||||
{
|
||||
vsync = config_json["gfx"]["vsync"];
|
||||
fullscreen = config_json["gfx"]["fullscreen"];
|
||||
max_fps = config_json["gfx"]["max_fps"];
|
||||
}
|
||||
if(config_json.count("keyboard_map") > 0)
|
||||
{
|
||||
keyboard_map["stick(strength)"] = config_json["keyboard_map"]["stick(strength)"];
|
||||
|
||||
keyboard_map["stick(x, -)"] = config_json["keyboard_map"]["stick(x, -)"];
|
||||
keyboard_map["stick(x, +)"] = config_json["keyboard_map"]["stick(x, +)"];
|
||||
keyboard_map["stick(y, -)"] = config_json["keyboard_map"]["stick(y, -)"];
|
||||
keyboard_map["stick(y, +)"] = config_json["keyboard_map"]["stick(y, +)"];
|
||||
|
||||
keyboard_map["start"] = config_json["keyboard_map"]["start"];
|
||||
|
||||
keyboard_map["a"] = config_json["keyboard_map"]["a"];
|
||||
keyboard_map["b"] = config_json["keyboard_map"]["b"];
|
||||
|
||||
keyboard_map["l"] = config_json["keyboard_map"]["l"];
|
||||
keyboard_map["r"] = config_json["keyboard_map"]["r"];
|
||||
keyboard_map["z"] = config_json["keyboard_map"]["z"];
|
||||
|
||||
keyboard_map["cbtn(x, -)"] = config_json["keyboard_map"]["cbtn(x, -)"];
|
||||
keyboard_map["cbtn(x, +)"] = config_json["keyboard_map"]["cbtn(x, +)"];
|
||||
keyboard_map["cbtn(y, -)"] = config_json["keyboard_map"]["cbtn(y, -)"];
|
||||
keyboard_map["cbtn(y, +)"] = config_json["keyboard_map"]["cbtn(y, +)"];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -47,14 +95,41 @@ namespace openrayman
|
|||
return false;
|
||||
}
|
||||
|
||||
bool config::save() const
|
||||
bool config::save()
|
||||
{
|
||||
std::string config_json_file = file::fix_string(m_backend_specifics.get_storage_path() + "/config.json");
|
||||
nlohmann::json config_json;
|
||||
config_json["vsync"] = vsync;
|
||||
config_json["fullscreen"] = fullscreen;
|
||||
config_json["max_fps"] = max_fps;
|
||||
config_json["game"] = game;
|
||||
|
||||
config_json["gfx"] = nlohmann::json::object();
|
||||
|
||||
config_json["gfx"]["vsync"] = vsync;
|
||||
config_json["gfx"]["fullscreen"] = fullscreen;
|
||||
config_json["gfx"]["max_fps"] = max_fps;
|
||||
|
||||
config_json["keyboard_map"] = nlohmann::json::object();
|
||||
|
||||
config_json["keyboard_map"]["stick(strength)"] = keyboard_map["stick(strength)"];
|
||||
|
||||
config_json["keyboard_map"]["stick(x, -)"] = keyboard_map["stick(x, -)"];
|
||||
config_json["keyboard_map"]["stick(x, +)"] = keyboard_map["stick(x, +)"];
|
||||
config_json["keyboard_map"]["stick(y, -)"] = keyboard_map["stick(y, -)"];
|
||||
config_json["keyboard_map"]["stick(y, +)"] = keyboard_map["stick(y, +)"];
|
||||
|
||||
config_json["keyboard_map"]["start"] = keyboard_map["start"];
|
||||
|
||||
config_json["keyboard_map"]["a"] = keyboard_map["a"];
|
||||
config_json["keyboard_map"]["b"] = keyboard_map["b"];
|
||||
|
||||
config_json["keyboard_map"]["l"] = keyboard_map["l"];
|
||||
config_json["keyboard_map"]["r"] = keyboard_map["r"];
|
||||
config_json["keyboard_map"]["z"] = keyboard_map["z"];
|
||||
|
||||
config_json["keyboard_map"]["cbtn(x, -)"] = keyboard_map["cbtn(x, -"];
|
||||
config_json["keyboard_map"]["cbtn(x, +)"] = keyboard_map["cbtn(x, +)"];
|
||||
config_json["keyboard_map"]["cbtn(y, -)"] = keyboard_map["cbtn(y, -)"];
|
||||
config_json["keyboard_map"]["cbtn(y, +)"] = keyboard_map["cbtn(y, +)"];
|
||||
|
||||
std::ofstream config_stream(config_json_file, std::ofstream::out | std::ofstream::trunc);
|
||||
if(config_stream.is_open())
|
||||
config_stream << std::setw(4) << config_json;
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
#define CONFIG_H
|
||||
|
||||
#include <string>
|
||||
#include <input/input_state.h>
|
||||
#include <platform/backend_specifics.h>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace openrayman
|
||||
{
|
||||
|
@ -23,7 +25,7 @@ public:
|
|||
// Saves the config file and all changes to the disk.
|
||||
// Returns true if the config was saved successfully.
|
||||
// This is done automatically in the destructor.
|
||||
bool save() const;
|
||||
bool save();
|
||||
|
||||
// If the game should be synchronized to the vertical blank of the screen.
|
||||
// This might introduce additional input lag (though we do use glFinish to minimize it).
|
||||
|
@ -39,6 +41,9 @@ public:
|
|||
// The user selected game to load.
|
||||
// Defaults to the game "rayman2_openrayman".
|
||||
std::string game;
|
||||
|
||||
// User mappings for keyboard when running standalone.
|
||||
std::unordered_map<std::string, std::string> keyboard_map;
|
||||
private:
|
||||
const backend_specifics& m_backend_specifics;
|
||||
};
|
||||
|
|
|
@ -26,12 +26,11 @@ public:
|
|||
engine() :
|
||||
m_exit_requested(false),
|
||||
#ifdef LIBRETRO_CORE
|
||||
m_window(*(new libretro_window())),
|
||||
m_backend_specifics(*(new libretro_backend_specifics())),
|
||||
#else
|
||||
m_window(*(new sdl_window())),
|
||||
m_backend_specifics(*(new standalone_backend_specifics())),
|
||||
#endif
|
||||
m_config(m_backend_specifics),
|
||||
m_current_input(0, 0, 0),
|
||||
m_last_input(0, 0, 0),
|
||||
m_last_timer_value(0),
|
||||
|
@ -43,7 +42,11 @@ public:
|
|||
m_total_fixed_updates(0),
|
||||
m_accumulated_frames_fps(0),
|
||||
m_fps(0),
|
||||
m_config(m_backend_specifics)
|
||||
#ifdef LIBRETRO_CORE
|
||||
m_window(*(new libretro_window()))
|
||||
#else
|
||||
m_window(*(new sdl_window(m_config)))
|
||||
#endif
|
||||
{ };
|
||||
|
||||
// Starts the game loop and loads the specified game.
|
||||
|
|
|
@ -10,10 +10,11 @@ namespace openrayman
|
|||
enum input_button : std::uint16_t
|
||||
{
|
||||
// All four dpad axises.
|
||||
dpad_left = (1 << 1),
|
||||
dpad_right = (1 << 2),
|
||||
dpad_up = (1 << 3),
|
||||
dpad_down = (1 << 4),
|
||||
// These are never used in Rayman 2
|
||||
// dpad_left = (1 << 1),
|
||||
// dpad_right = (1 << 2),
|
||||
// dpad_up = (1 << 3),
|
||||
// dpad_down = (1 << 4),
|
||||
|
||||
// The start button. Used for pausing.
|
||||
start = (1 << 5),
|
||||
|
|
|
@ -3,16 +3,6 @@
|
|||
|
||||
namespace openrayman
|
||||
{
|
||||
standalone_input_provider::standalone_input_provider(SDL_Window* window) :
|
||||
m_input(0, 0, 0),
|
||||
m_window(window)
|
||||
{
|
||||
}
|
||||
|
||||
standalone_input_provider::~standalone_input_provider()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string standalone_input_provider::get_description() const
|
||||
{
|
||||
return "SDL2 input provider (standalone)";
|
||||
|
@ -38,18 +28,18 @@ namespace openrayman
|
|||
// This simulates a slower walk done by the control stick
|
||||
// Used in some areas to avoid pirates
|
||||
// TODO: Is half (64) accurate?!?!
|
||||
int walk_strength = keyboard_state[SDL_SCANCODE_LSHIFT] ? 64 : 127;
|
||||
int walk_strength = keyboard_state[SDL_GetScancodeFromName(m_config.keyboard_map["stick(strength)"].c_str())] ? 64 : 127;
|
||||
|
||||
int new_stick_x = m_input.stick_x;
|
||||
int new_stick_y = m_input.stick_y;
|
||||
|
||||
if(keyboard_state[SDL_SCANCODE_LEFT])
|
||||
if(keyboard_state[SDL_GetScancodeFromName(m_config.keyboard_map["stick(x, -)"].c_str())])
|
||||
new_stick_x -= walk_strength;
|
||||
if(keyboard_state[SDL_SCANCODE_RIGHT])
|
||||
if(keyboard_state[SDL_GetScancodeFromName(m_config.keyboard_map["stick(x, +)"].c_str())])
|
||||
new_stick_x += walk_strength;
|
||||
if(keyboard_state[SDL_SCANCODE_UP])
|
||||
if(keyboard_state[SDL_GetScancodeFromName(m_config.keyboard_map["stick(y, -)"].c_str())])
|
||||
new_stick_y -= walk_strength;
|
||||
if(keyboard_state[SDL_SCANCODE_DOWN])
|
||||
if(keyboard_state[SDL_GetScancodeFromName(m_config.keyboard_map["stick(y, +)"].c_str())])
|
||||
new_stick_y += walk_strength;
|
||||
|
||||
new_stick_x = std::min(127, std::max(-127, new_stick_x));
|
||||
|
@ -59,31 +49,31 @@ namespace openrayman
|
|||
m_input.stick_y = new_stick_y;
|
||||
|
||||
// Front buttons
|
||||
if(keyboard_state[SDL_SCANCODE_SPACE])
|
||||
if(keyboard_state[SDL_GetScancodeFromName(m_config.keyboard_map["a"].c_str())])
|
||||
m_input.buttons |= input_button::a;
|
||||
if(keyboard_state[SDL_SCANCODE_A])
|
||||
if(keyboard_state[SDL_GetScancodeFromName(m_config.keyboard_map["b"].c_str())])
|
||||
m_input.buttons |= input_button::b;
|
||||
|
||||
// Triggers
|
||||
if(keyboard_state[SDL_SCANCODE_LCTRL])
|
||||
if(keyboard_state[SDL_GetScancodeFromName(m_config.keyboard_map["z"].c_str())])
|
||||
m_input.buttons |= input_button::z;
|
||||
if(keyboard_state[SDL_SCANCODE_F1])
|
||||
if(keyboard_state[SDL_GetScancodeFromName(m_config.keyboard_map["l"].c_str())])
|
||||
m_input.buttons |= input_button::l;
|
||||
if(keyboard_state[SDL_SCANCODE_J])
|
||||
if(keyboard_state[SDL_GetScancodeFromName(m_config.keyboard_map["r"].c_str())])
|
||||
m_input.buttons |= input_button::r;
|
||||
|
||||
// Start button
|
||||
if(keyboard_state[SDL_SCANCODE_ESCAPE])
|
||||
if(keyboard_state[SDL_GetScancodeFromName(m_config.keyboard_map["start"].c_str())])
|
||||
m_input.buttons |= input_button::start;
|
||||
|
||||
// C buttons
|
||||
if(keyboard_state[SDL_SCANCODE_Q])
|
||||
if(keyboard_state[SDL_GetScancodeFromName(m_config.keyboard_map["cbtn(x, -)"].c_str())])
|
||||
m_input.commands |= input_button::cbtn_left;
|
||||
if(keyboard_state[SDL_SCANCODE_W])
|
||||
if(keyboard_state[SDL_GetScancodeFromName(m_config.keyboard_map["cbtn(x, +)"].c_str())])
|
||||
m_input.commands |= input_button::cbtn_right;
|
||||
if(keyboard_state[SDL_SCANCODE_O])
|
||||
if(keyboard_state[SDL_GetScancodeFromName(m_config.keyboard_map["cbtn(y, -)"].c_str())])
|
||||
m_input.commands |= input_button::cbtn_up;
|
||||
if(keyboard_state[SDL_SCANCODE_END])
|
||||
if(keyboard_state[SDL_GetScancodeFromName(m_config.keyboard_map["cbtn(y, +)"].c_str())])
|
||||
m_input.commands |= input_button::cbtn_down;
|
||||
|
||||
// Commands
|
||||
|
@ -98,6 +88,9 @@ namespace openrayman
|
|||
// the N64 version is not the same as the PC version and the original game
|
||||
// was not meant to be played with Xbox controllers and frankly, the original
|
||||
// layout is shit and doesn't work most of the time (dinput)
|
||||
// TODO: rebindable?
|
||||
// probably not...
|
||||
// GUIDs?
|
||||
|
||||
for(const std::pair<int, SDL_GameController*>& pair : m_game_controllers)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <input/input_state.h>
|
||||
#include <input/input_provider.h>
|
||||
#include <config/config.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
@ -15,8 +16,11 @@ namespace openrayman
|
|||
{
|
||||
friend class sdl_window;
|
||||
public:
|
||||
standalone_input_provider(SDL_Window* window);
|
||||
~standalone_input_provider();
|
||||
standalone_input_provider(config& config) :
|
||||
m_input(0, 0, 0),
|
||||
m_config(config)
|
||||
{
|
||||
}
|
||||
|
||||
const std::string get_description() const override;
|
||||
const input_state& poll() override;
|
||||
|
@ -24,7 +28,7 @@ private:
|
|||
void poll_keyboard();
|
||||
void poll_game_controller();
|
||||
input_state m_input;
|
||||
SDL_Window* m_window;
|
||||
config& m_config;
|
||||
std::unordered_map<int, SDL_GameController*> m_game_controllers;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,12 +6,12 @@ namespace openrayman
|
|||
{
|
||||
int sdl_window::m_sdl_ref_count = 0;
|
||||
|
||||
sdl_window::sdl_window() :
|
||||
sdl_window::sdl_window(config& config) :
|
||||
m_window(nullptr),
|
||||
m_current_fullscreen(false),
|
||||
m_vsync_enabled(false),
|
||||
m_wants_close(false),
|
||||
m_input_provider(nullptr)
|
||||
m_input_provider(config)
|
||||
{
|
||||
if(m_sdl_ref_count <= 0)
|
||||
{
|
||||
|
@ -61,8 +61,6 @@ namespace openrayman
|
|||
return false;
|
||||
}
|
||||
|
||||
m_input_provider = standalone_input_provider(m_window);
|
||||
|
||||
SDL_GL_SetSwapInterval(0);
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <SDL2/SDL_opengl.h>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include <config/config.h>
|
||||
#include <window/window.h>
|
||||
#include <input/input_provider.h>
|
||||
#include <input/standalone_input_provider.h>
|
||||
|
@ -15,12 +16,12 @@ namespace openrayman
|
|||
class sdl_window : public window
|
||||
{
|
||||
public:
|
||||
sdl_window(config& config);
|
||||
~sdl_window();
|
||||
|
||||
bool open(const std::string& title, int w, int h, bool initial_fullscreen) override;
|
||||
void close() override;
|
||||
|
||||
sdl_window();
|
||||
~sdl_window();
|
||||
|
||||
void gl_make_current() override;
|
||||
void present() override;
|
||||
void poll_events() override;
|
||||
|
|
|
@ -11,14 +11,14 @@ namespace openrayman
|
|||
class window
|
||||
{
|
||||
public:
|
||||
virtual ~window() { };
|
||||
|
||||
// Opens or reopens the window, and creates a GL context.
|
||||
virtual bool open(const std::string& title, int w, int h, bool initial_fullscreen) = 0;
|
||||
|
||||
// Closes the window if it's not already closed.
|
||||
virtual void close() = 0;
|
||||
|
||||
virtual ~window() { };
|
||||
|
||||
// Makes the GL context associated with the window the current one.
|
||||
virtual void gl_make_current() = 0;
|
||||
|
||||
|
|
Loading…
Reference in a new issue