diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e11940f59..a273b0b56 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,7 @@ add_subdirectory(video_core) add_subdirectory(audio_core) add_subdirectory(network) add_subdirectory(input_common) +add_subdirectory(scripted_input) add_subdirectory(tests) if (ENABLE_SDL2) add_subdirectory(citra) diff --git a/src/citra/CMakeLists.txt b/src/citra/CMakeLists.txt index a885f22f8..154eb4bf4 100644 --- a/src/citra/CMakeLists.txt +++ b/src/citra/CMakeLists.txt @@ -16,7 +16,7 @@ set(HEADERS create_directory_groups(${SRCS} ${HEADERS}) add_executable(citra ${SRCS} ${HEADERS}) -target_link_libraries(citra PRIVATE common core input_common network) +target_link_libraries(citra PRIVATE common core input_common network scripted_input) target_link_libraries(citra PRIVATE inih glad) if (MSVC) target_link_libraries(citra PRIVATE getopt) diff --git a/src/citra/emu_window/emu_window_sdl2.cpp b/src/citra/emu_window/emu_window_sdl2.cpp index b0f808399..91150de12 100644 --- a/src/citra/emu_window/emu_window_sdl2.cpp +++ b/src/citra/emu_window/emu_window_sdl2.cpp @@ -16,6 +16,7 @@ #include "core/settings.h" #include "input_common/keyboard.h" #include "input_common/main.h" +#include "scripted_input/scripted_input.h" #include "network/network.h" void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { @@ -59,6 +60,7 @@ void EmuWindow_SDL2::OnResize() { EmuWindow_SDL2::EmuWindow_SDL2() { InputCommon::Init(); + ScriptedInput::Init(); Network::Init(); motion_emu = std::make_unique(*this); diff --git a/src/scripted_input/CMakeLists.txt b/src/scripted_input/CMakeLists.txt new file mode 100644 index 000000000..ced237e24 --- /dev/null +++ b/src/scripted_input/CMakeLists.txt @@ -0,0 +1,14 @@ +set(SRCS + scripted_input.cpp + scripted_buttons.cpp + ) + +set(HEADERS + scripted_input.h + scripted_buttons.h + ) + +create_directory_groups(${SRCS} ${HEADERS}) + +add_library(scripted_input STATIC ${SRCS} ${HEADERS}) +target_link_libraries(scripted_input PUBLIC common core) diff --git a/src/scripted_input/scripted_buttons.cpp b/src/scripted_input/scripted_buttons.cpp new file mode 100644 index 000000000..742bba3a4 --- /dev/null +++ b/src/scripted_input/scripted_buttons.cpp @@ -0,0 +1,68 @@ +// Copyright 2017 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "scripted_input/scripted_buttons.h" + +std::string button_name_to_index[] = { + "a", + "b", + "x", + "y", + "up", + "down", + "left", + "right", + "l", + "r", + "start", + "select", + "zl", + "zr", + "home" +}; + +int IndexOfButton(const std::string& button) { + for (int i = 0; i < 15; i++) { + if (button_name_to_index[i] == button) { + return i; + } + } + + //TODO: Log an error + return -1; //home +} + +namespace ScriptedInput { + +class ScriptedButton final : public Input::ButtonDevice { + bool GetStatus() const override { + return status.load(); + } + + friend class ScriptedButtons; +private: + std::atomic status{false}; +}; + +class ScriptedButtonList { + //TODO: Do i need to memset(0) buttons? +public: + ScriptedButton* buttons[15]; +}; + + +ScriptedButtons::ScriptedButtons() : scripted_button_list{std::make_shared()} {} + +std::unique_ptr ScriptedButtons::Create(const Common::ParamPackage& params) { + auto button_str = params.Get("button", ""); + + std::unique_ptr button = std::make_unique(); + int index = IndexOfButton(button_str); + if (index >= 0) { + scripted_button_list.get()->buttons[index] = button.get(); + } + + return std::move(button); +} +} \ No newline at end of file diff --git a/src/scripted_input/scripted_buttons.h b/src/scripted_input/scripted_buttons.h new file mode 100644 index 000000000..aae734198 --- /dev/null +++ b/src/scripted_input/scripted_buttons.h @@ -0,0 +1,32 @@ +// Copyright 2017 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include +#include "core/frontend/input.h" + +namespace ScriptedInput { + +class ScriptedButtonList; + +/** +* A button device factory that returns inputs from a script file +*/ +class ScriptedButtons final : public Input::Factory { +public: + ScriptedButtons(); + + /** + * Creates a button device + * @param params unused + */ + std::unique_ptr Create(const Common::ParamPackage& params) override; + +private: + std::shared_ptr scripted_button_list; +}; + +} // namespace InputCommon diff --git a/src/scripted_input/scripted_input.cpp b/src/scripted_input/scripted_input.cpp new file mode 100644 index 000000000..b51fc1a5a --- /dev/null +++ b/src/scripted_input/scripted_input.cpp @@ -0,0 +1,28 @@ +// Copyright 2017 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include "scripted_input/scripted_buttons.h" +#include "scripted_input/scripted_input.h" + + +namespace ScriptedInput { + +static std::shared_ptr scripted_buttons; +//TODO: static std::shared_ptr scripted_analog; + +void Init() { + scripted_buttons = std::make_shared(); + Input::RegisterFactory("scripted", scripted_buttons); +} + +void Shutdown() { + Input::UnregisterFactory("scripted"); +} + +ScriptedButtons* GetScriptedButtons() { + return scripted_buttons.get(); +} + +} // namespace ScriptedInput diff --git a/src/scripted_input/scripted_input.h b/src/scripted_input/scripted_input.h new file mode 100644 index 000000000..43c8c0ff8 --- /dev/null +++ b/src/scripted_input/scripted_input.h @@ -0,0 +1,21 @@ +// Copyright 2017 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include + +namespace ScriptedInput { + +/// Initializes and registers all built-in input device factories. +void Init(); + +/// Unresisters all build-in input device factories and shut them down. +void Shutdown(); + +class ScriptedButtons; + +ScriptedButtons* GetScriptedButtons(); + +} // namespace InputCommon