mirror of
https://github.com/MadeOfJelly/MushMachine.git
synced 2025-06-18 18:56:36 +02:00
initial import, >900commits predate this
This commit is contained in:
27
framework/input/CMakeLists.txt
Normal file
27
framework/input/CMakeLists.txt
Normal file
@ -0,0 +1,27 @@
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
project(input_service CXX)
|
||||
|
||||
add_library(input_service
|
||||
src/mm/services/input_service.hpp
|
||||
src/mm/services/input_service.cpp
|
||||
)
|
||||
|
||||
target_include_directories(input_service PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
|
||||
target_link_libraries(input_service
|
||||
engine
|
||||
glm
|
||||
sdl_service
|
||||
)
|
||||
|
||||
if(EMSCRIPTEN)
|
||||
set_target_properties(input_service PROPERTIES COMPILE_FLAGS "-s USE_SDL=2")
|
||||
set_target_properties(input_service PROPERTIES LINK_FLAGS "-s USE_SDL=2")
|
||||
else()
|
||||
target_include_directories(input_service PUBLIC "${SDL2_INCLUDE_DIR}")
|
||||
endif()
|
||||
|
||||
if (BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
|
600
framework/input/src/mm/services/input_service.cpp
Normal file
600
framework/input/src/mm/services/input_service.cpp
Normal file
@ -0,0 +1,600 @@
|
||||
#include "./input_service.hpp"
|
||||
|
||||
#include <glm/common.hpp>
|
||||
#include <glm/geometric.hpp>
|
||||
#include <glm/trigonometric.hpp>
|
||||
#include <glm/gtc/constants.hpp>
|
||||
|
||||
#include <tracy/Tracy.hpp>
|
||||
|
||||
#include <mm/logger.hpp>
|
||||
#define LOG_CRIT(...) __LOG_CRIT( "InputService", __VA_ARGS__)
|
||||
#define LOG_ERROR(...) __LOG_ERROR("InputService", __VA_ARGS__)
|
||||
#define LOG_WARN(...) __LOG_WARN( "InputService", __VA_ARGS__)
|
||||
#define LOG_INFO(...) __LOG_INFO( "InputService", __VA_ARGS__)
|
||||
#define LOG_DEBUG(...) __LOG_DEBUG("InputService", __VA_ARGS__)
|
||||
#define LOG_TRACE(...) __LOG_TRACE("InputService", __VA_ARGS__)
|
||||
|
||||
namespace MM::Services {
|
||||
|
||||
InputService::input_action_t InputService::keyboard_mapping::get(SDL_Keycode key) {
|
||||
for (unsigned int i = 0; i < InputService::input_action_t::INPUT_ACTION_MAX; i++) {
|
||||
if (actions[i] == key)
|
||||
return (InputService::input_action_t)i;
|
||||
}
|
||||
|
||||
return INPUT_ACTION_MAX;
|
||||
}
|
||||
|
||||
InputService::input_action_t InputService::controller_mapping::get(SDL_GameControllerButton button) {
|
||||
for (unsigned int i = 0; i < InputService::input_action_t::INPUT_ACTION_MAX; i++) {
|
||||
if (actions[i] == button)
|
||||
return (InputService::input_action_t)i;
|
||||
}
|
||||
|
||||
return INPUT_ACTION_MAX;
|
||||
}
|
||||
|
||||
InputService::InputService(void) {
|
||||
MM::Logger::initSectionLogger("InputService");
|
||||
LOG_TRACE("constructing InputService...");
|
||||
|
||||
// TODO: integrate with config system
|
||||
_k_map.move_up = loadKey("keyboard_move_up", SDLK_w);
|
||||
_k_map.move_down = loadKey("keyboard_move_down", SDLK_s);
|
||||
_k_map.move_left = loadKey("keyboard_move_left", SDLK_a);
|
||||
_k_map.move_right = loadKey("keyboard_move_right", SDLK_d);
|
||||
|
||||
_k_map.actions[SPELL_WEAPON] = loadKey("keyboard_spell_weapon", SDLK_SPACE);
|
||||
|
||||
_k_map.actions[SPELL_1] = loadKey("keyboard_spell_1", SDLK_1);
|
||||
_k_map.actions[SPELL_2] = loadKey("keyboard_spell_2", SDLK_2);
|
||||
_k_map.actions[SPELL_3] = loadKey("keyboard_spell_3", SDLK_3);
|
||||
_k_map.actions[SPELL_4] = loadKey("keyboard_spell_4", SDLK_4);
|
||||
_k_map.actions[SPELL_5] = loadKey("keyboard_spell_5", SDLK_5);
|
||||
_k_map.actions[SPELL_6] = loadKey("keyboard_spell_6", SDLK_6);
|
||||
|
||||
_k_map.actions[USE] = loadKey("keyboard_use", SDLK_f);
|
||||
|
||||
_c_map.actions[SPELL_WEAPON] = loadButton("controller_spell_weapon", SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
|
||||
|
||||
_c_map.actions[SPELL_1] = loadButton("controller_spell_1", SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
|
||||
_c_map.actions[SPELL_2] = loadButton("controller_spell_2", SDL_CONTROLLER_BUTTON_A);
|
||||
_c_map.actions[SPELL_3] = loadButton("controller_spell_3", SDL_CONTROLLER_BUTTON_DPAD_UP);
|
||||
_c_map.actions[SPELL_4] = loadButton("controller_spell_4", SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
|
||||
_c_map.actions[SPELL_5] = loadButton("controller_spell_5", SDL_CONTROLLER_BUTTON_DPAD_DOWN);
|
||||
_c_map.actions[SPELL_6] = loadButton("controller_spell_6", SDL_CONTROLLER_BUTTON_DPAD_LEFT);
|
||||
|
||||
_c_map.actions[USE] = loadButton("controller_use", SDL_CONTROLLER_BUTTON_X);
|
||||
|
||||
|
||||
for (auto& it : _player_active)
|
||||
it = false;
|
||||
}
|
||||
|
||||
InputService::~InputService(void) {
|
||||
}
|
||||
|
||||
bool InputService::enable(Engine& engine) {
|
||||
auto* sdl_ss = engine.tryService<SDLService>();
|
||||
if (!sdl_ss) {
|
||||
LOG_ERROR("InputService requires SDLService in engine!");
|
||||
return false;
|
||||
}
|
||||
|
||||
_event_handle = sdl_ss->addEventHandler([this, &engine](const SDL_Event& e) -> bool { return this->handleSDL_Event(e, engine); });
|
||||
if (!_event_handle) {
|
||||
LOG_ERROR("couldnt register event handler!");
|
||||
return false;
|
||||
}
|
||||
|
||||
_update_handle = engine.addFixedUpdate([this](MM::Engine&) {
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
if (!_player_active[i])
|
||||
continue;
|
||||
|
||||
auto& p = _player[i];
|
||||
if (p.is_controller) {
|
||||
} else {
|
||||
updateKPlayerDirs(p);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (_update_handle.expired()) {
|
||||
LOG_ERROR("couldnt register update handler!");
|
||||
return false;
|
||||
}
|
||||
_update_handle.lock()->priority = 1; // scene is 0
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void InputService::disable(Engine& engine) {
|
||||
if (_event_handle) {
|
||||
auto* sdl_ss = engine.tryService<SDLService>();
|
||||
if (!sdl_ss) {
|
||||
// error?
|
||||
return;
|
||||
}
|
||||
|
||||
sdl_ss->removeEventHandler(_event_handle);
|
||||
}
|
||||
|
||||
if (!_update_handle.expired()) {
|
||||
engine.removeFixedUpdate(_update_handle);
|
||||
_update_handle.reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool InputService::handleSDL_Event(const SDL_Event& e, MM::Engine& engine) {
|
||||
ZoneScopedN("MM::InputService::handleSDL_Event");
|
||||
switch (e.type) {
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
auto p_id = findPlayerState(false, 0);
|
||||
if (p_id == UINT16_MAX)
|
||||
break;
|
||||
|
||||
auto& p = _player[p_id];
|
||||
|
||||
input_action_t a = _k_map.get(e.key.keysym.sym);
|
||||
if (a != INPUT_ACTION_MAX) {
|
||||
p.active[a] = true;
|
||||
return true;
|
||||
} else if (e.key.keysym.sym == _k_map.move_up) {
|
||||
p.u.keyboard.up = true;
|
||||
//updateKPlayerDirs(p);
|
||||
return true;
|
||||
} else if (e.key.keysym.sym == _k_map.move_down) {
|
||||
p.u.keyboard.down = true;
|
||||
//updateKPlayerDirs(p);
|
||||
return true;
|
||||
} else if (e.key.keysym.sym == _k_map.move_left) {
|
||||
p.u.keyboard.left = true;
|
||||
//updateKPlayerDirs(p);
|
||||
return true;
|
||||
} else if (e.key.keysym.sym == _k_map.move_right) {
|
||||
p.u.keyboard.right = true;
|
||||
//updateKPlayerDirs(p);
|
||||
return true;
|
||||
} else if (e.key.keysym.sym == SDLK_ESCAPE) {
|
||||
if (p.u.keyboard.view_mode == k_view_mode_t::MOUSE_RELATIVE) {
|
||||
p.u.keyboard.mouse_button_down = false;
|
||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
auto p_id = findPlayerState(false, 0);
|
||||
if (p_id == UINT16_MAX)
|
||||
break;
|
||||
|
||||
auto& p = _player[p_id];
|
||||
|
||||
input_action_t a = _k_map.get(e.key.keysym.sym);
|
||||
if (a != INPUT_ACTION_MAX) {
|
||||
p.active[a] = false;
|
||||
return true;
|
||||
} else if (e.key.keysym.sym == _k_map.move_up) {
|
||||
p.u.keyboard.up = false;
|
||||
//updateKPlayerDirs(p);
|
||||
return true;
|
||||
} else if (e.key.keysym.sym == _k_map.move_down) {
|
||||
p.u.keyboard.down = false;
|
||||
//updateKPlayerDirs(p);
|
||||
return true;
|
||||
} else if (e.key.keysym.sym == _k_map.move_left) {
|
||||
p.u.keyboard.left = false;
|
||||
//updateKPlayerDirs(p);
|
||||
return true;
|
||||
} else if (e.key.keysym.sym == _k_map.move_right) {
|
||||
p.u.keyboard.right = false;
|
||||
//updateKPlayerDirs(p);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
{
|
||||
auto p_id = findPlayerState(false, 0);
|
||||
if (p_id == UINT16_MAX)
|
||||
break;
|
||||
|
||||
auto* sdl_ss = engine.tryService<MM::Services::SDLService>();
|
||||
auto[win_x, win_y] = sdl_ss->getWindowSize();
|
||||
auto& p = _player[p_id];
|
||||
|
||||
if (p.u.keyboard.view_mode == k_view_mode_t::MOUSE_RELATIVE) {
|
||||
p.u.keyboard.curr_x += e.motion.xrel;
|
||||
p.u.keyboard.curr_y += e.motion.yrel;
|
||||
} else {
|
||||
p.u.keyboard.curr_x = e.motion.x;
|
||||
p.u.keyboard.curr_y = e.motion.y;
|
||||
}
|
||||
|
||||
if (p.u.keyboard.view_mode == k_view_mode_t::MOUSE_RELATIVE_TO_CENTER) {
|
||||
glm::vec2 mouse_vec{e.motion.x - win_x/2., -(e.motion.y - win_y/2.)};
|
||||
|
||||
//LOGIS("mouse vec x:" + std::to_string(mouse_vec.x) + " y:" + std::to_string(mouse_vec.y));
|
||||
|
||||
p.view_dir = glm::mod(glm::atan(mouse_vec.y, mouse_vec.x) + 2*glm::pi<float>(), 2*glm::pi<float>());
|
||||
p.view_force = glm::length(mouse_vec) * 0.01f;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
{
|
||||
auto p_id = findPlayerState(false, 0);
|
||||
if (p_id == UINT16_MAX)
|
||||
break;
|
||||
|
||||
if (e.button.button == SDL_BUTTON_LEFT) {
|
||||
auto& p = _player[p_id];
|
||||
if (p.u.keyboard.view_mode == k_view_mode_t::MOUSE_DRAG || p.u.keyboard.view_mode == k_view_mode_t::MOUSE_RELATIVE) {
|
||||
p.u.keyboard.mouse_button_down = true;
|
||||
if (p.u.keyboard.view_mode == k_view_mode_t::MOUSE_RELATIVE) {
|
||||
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1"); // not needed if fullscreen
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
{
|
||||
auto p_id = findPlayerState(false, 0);
|
||||
if (p_id == UINT16_MAX)
|
||||
break;
|
||||
|
||||
if (e.button.button == SDL_BUTTON_LEFT) {
|
||||
auto& p = _player[p_id];
|
||||
if (p.u.keyboard.view_mode == k_view_mode_t::MOUSE_DRAG) {
|
||||
p.u.keyboard.mouse_button_down = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
{
|
||||
auto p_id = findPlayerState(true, e.caxis.which);
|
||||
if (p_id == UINT16_MAX)
|
||||
break;
|
||||
|
||||
auto& p = _player[p_id];
|
||||
switch (e.caxis.axis) {
|
||||
case SDL_CONTROLLER_AXIS_LEFTX:
|
||||
p.u.controller.left_x = e.caxis.value;
|
||||
updateCPlayerDirs(p);
|
||||
return true;
|
||||
case SDL_CONTROLLER_AXIS_LEFTY:
|
||||
p.u.controller.left_y = e.caxis.value;
|
||||
updateCPlayerDirs(p);
|
||||
return true;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTX:
|
||||
p.u.controller.right_x = e.caxis.value;
|
||||
updateCPlayerDirs(p);
|
||||
return true;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTY:
|
||||
p.u.controller.right_y = e.caxis.value;
|
||||
updateCPlayerDirs(p);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
{
|
||||
auto p_id = findPlayerState(true, e.caxis.which);
|
||||
if (p_id == UINT16_MAX)
|
||||
break;
|
||||
|
||||
auto& p = _player[p_id];
|
||||
|
||||
input_action_t a = _c_map.get((SDL_GameControllerButton)e.cbutton.button);
|
||||
if (a != INPUT_ACTION_MAX) {
|
||||
p.active[a] = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
{
|
||||
auto p_id = findPlayerState(true, e.caxis.which);
|
||||
if (p_id == UINT16_MAX)
|
||||
break;
|
||||
|
||||
auto& p = _player[p_id];
|
||||
|
||||
input_action_t a = _c_map.get((SDL_GameControllerButton)e.cbutton.button);
|
||||
if (a != INPUT_ACTION_MAX) {
|
||||
p.active[a] = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Input::PlayerID InputService::addPlayer(bool keyboard, SDL_JoystickID controller_id) {
|
||||
Input::PlayerID p_id = UINT16_MAX;
|
||||
for (Input::PlayerID i = 0; i < max_player_id; i++) {
|
||||
if (!_player_active[i]) {
|
||||
p_id = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_id == UINT16_MAX) {
|
||||
LOG_ERROR("adding player, all player slots active");
|
||||
return p_id;
|
||||
}
|
||||
|
||||
LOG_DEBUG("added new player with id {}", p_id);
|
||||
|
||||
_player_active[p_id] = true;
|
||||
// TODO: reset player
|
||||
|
||||
auto& p = _player[p_id];
|
||||
p.is_controller = !keyboard;
|
||||
p.controller_instance_id = controller_id;
|
||||
|
||||
// initialize player
|
||||
if (p.is_controller) {
|
||||
p.u.controller = {0, 0, 0, 0};
|
||||
} else {
|
||||
p.u.keyboard = {
|
||||
false, false, false, false,
|
||||
false,
|
||||
0, 0,
|
||||
0, 0,
|
||||
k_view_mode_t::NO_VIEW,
|
||||
};
|
||||
}
|
||||
|
||||
return p_id;
|
||||
}
|
||||
|
||||
bool InputService::get(Input::PlayerID id, InputService::input_action_t action) {
|
||||
assert(id < max_player_id);
|
||||
if (!_player_active[id]) {
|
||||
LOG_WARN("use of inactive player {}", id);
|
||||
return false;
|
||||
}
|
||||
|
||||
return _player[id].active[action];
|
||||
}
|
||||
|
||||
const char* InputService::getKeyString(Input::PlayerID id, InputService::input_action_t action) {
|
||||
assert(id < max_player_id);
|
||||
if (!_player_active[id]) {
|
||||
LOG_WARN("use of inactive player {}", id);
|
||||
return "INACTIVE_PLAYER";
|
||||
}
|
||||
|
||||
if (_player[id].is_controller) {
|
||||
return SDL_GameControllerGetStringForButton(_c_map.actions[action]);
|
||||
} else {
|
||||
return SDL_GetKeyName(_k_map.actions[action]);
|
||||
}
|
||||
|
||||
//return _player[id].active[action];
|
||||
return "UNK";
|
||||
}
|
||||
|
||||
float InputService::getMoveForce(Input::PlayerID id) {
|
||||
assert(id < max_player_id);
|
||||
if (!_player_active[id]) {
|
||||
LOG_WARN("use of inactive player {}", id);
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
if (_player[id].move_force <= 0.01f)
|
||||
return 0.f;
|
||||
|
||||
return _player[id].move_force;
|
||||
|
||||
}
|
||||
|
||||
float InputService::getViewForce(Input::PlayerID id) {
|
||||
assert(id < max_player_id);
|
||||
if (!_player_active[id]) {
|
||||
LOG_WARN("use of inactive player {}", id);
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
if (_player[id].view_force <= 0.01f)
|
||||
return 0.f;
|
||||
|
||||
return _player[id].view_force;
|
||||
|
||||
}
|
||||
|
||||
glm::vec2 InputService::getMoveVec(Input::PlayerID id) {
|
||||
assert(id < max_player_id);
|
||||
if (!_player_active[id]) {
|
||||
LOG_WARN("use of inactive player {}", id);
|
||||
return {0.f, 0.f};
|
||||
}
|
||||
|
||||
return {
|
||||
glm::cos(_player[id].move_dir) * getMoveForce(id),
|
||||
-glm::sin(_player[id].move_dir) * getMoveForce(id)
|
||||
};
|
||||
}
|
||||
|
||||
glm::vec2 InputService::getViewVec(Input::PlayerID id) {
|
||||
assert(id < max_player_id);
|
||||
if (!_player_active[id]) {
|
||||
LOG_WARN("use of inactive player {}", id);
|
||||
return {0.f, 0.f};
|
||||
}
|
||||
|
||||
return {
|
||||
glm::cos(_player[id].view_dir),
|
||||
-glm::sin(_player[id].view_dir)
|
||||
};
|
||||
}
|
||||
|
||||
float InputService::getMoveDir(Input::PlayerID id) {
|
||||
assert(id < max_player_id);
|
||||
if (!_player_active[id]) {
|
||||
LOG_WARN("use of inactive player {}", id);
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
return glm::mod(_player[id].move_dir + 2*glm::pi<float>(), 2*glm::pi<float>());
|
||||
}
|
||||
|
||||
float InputService::getViewDir(Input::PlayerID id) {
|
||||
assert(id < max_player_id);
|
||||
if (!_player_active[id]) {
|
||||
LOG_WARN("use of inactive player {}", id);
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
return glm::mod(_player[id].view_dir + 2*glm::pi<float>(), 2*glm::pi<float>());
|
||||
}
|
||||
|
||||
// TODO: use config service
|
||||
SDL_Keycode InputService::loadKey(const std::string& name, const SDL_Keycode default_key) {
|
||||
(void) name;
|
||||
//auto k = SDL_GetKeyFromName(_pref->get(name.c_str(), SDL_GetKeyName(default_key)).c_str());
|
||||
auto k = SDLK_UNKNOWN;
|
||||
if (k == SDLK_UNKNOWN) {
|
||||
//_pref->set(name.c_str(), SDL_GetKeyName(default_key));
|
||||
return default_key;
|
||||
}
|
||||
|
||||
return k;
|
||||
|
||||
}
|
||||
|
||||
// TODO: use config service
|
||||
SDL_GameControllerButton InputService::loadButton(const std::string& name, const SDL_GameControllerButton default_button) {
|
||||
(void) name;
|
||||
//auto b = SDL_GameControllerGetButtonFromString(_pref->get(name.c_str(), SDL_GameControllerGetStringForButton(default_button)).c_str());
|
||||
auto b = SDL_CONTROLLER_BUTTON_INVALID;
|
||||
if (b == SDL_CONTROLLER_BUTTON_INVALID) {
|
||||
//_pref->set(name.c_str(), SDL_GameControllerGetStringForButton(default_button));
|
||||
return default_button;
|
||||
}
|
||||
|
||||
return b;
|
||||
|
||||
}
|
||||
|
||||
bool InputService::setKPlayerViewMode(Input::PlayerID id, k_view_mode_t mode) {
|
||||
if (!_player_active[id]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_player[id].is_controller) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_player[id].u.keyboard.view_mode = mode;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Input::PlayerID InputService::findPlayerState(bool controller, SDL_JoystickID controller_id) {
|
||||
for (Input::PlayerID id = 0; id < max_player_id; id++) {
|
||||
if (!_player_active[id])
|
||||
continue;
|
||||
|
||||
auto& it = _player[id];
|
||||
if (it.is_controller == controller && it.controller_instance_id == controller_id) {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
return UINT16_MAX;
|
||||
}
|
||||
|
||||
void InputService::updateKPlayerDirs(player_input_action_state& p) {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
if (p.u.keyboard.right)
|
||||
x++;
|
||||
if (p.u.keyboard.left)
|
||||
x--;
|
||||
if (p.u.keyboard.up)
|
||||
y--;
|
||||
if (p.u.keyboard.down)
|
||||
y++;
|
||||
|
||||
if (x == -1 && y == -1)
|
||||
p.move_dir = (glm::pi<float>()*3.f)/4.f;
|
||||
else if (x == 0 && y == -1)
|
||||
p.move_dir = glm::pi<float>()/2.f;
|
||||
else if (x == 1 && y == -1)
|
||||
p.move_dir = glm::pi<float>()/4.f;
|
||||
else if (x == -1 && y == 0)
|
||||
p.move_dir = glm::pi<float>();
|
||||
else if (x == 1 && y == 0)
|
||||
p.move_dir = 0.f;
|
||||
else if (x == -1 && y == 1)
|
||||
p.move_dir = -(glm::pi<float>()*3.f)/4.f;
|
||||
else if (x == 0 && y == 1)
|
||||
p.move_dir = -glm::pi<float>()/2.f;
|
||||
else if (x == 1 && y == 1)
|
||||
p.move_dir = -glm::pi<float>()/4.f;
|
||||
|
||||
//p.view_dir = 0.f; // TODO: view
|
||||
|
||||
if (!x && !y)
|
||||
p.move_force = 0.f;
|
||||
else
|
||||
p.move_force = 1.f;
|
||||
|
||||
glm::vec2 mouse_delta;
|
||||
if (p.u.keyboard.view_mode == k_view_mode_t::MOUSE_RELATIVE) {
|
||||
mouse_delta = {-p.u.keyboard.curr_x, p.u.keyboard.curr_y}; // invert
|
||||
p.u.keyboard.curr_x = 0;
|
||||
p.u.keyboard.curr_y = 0;
|
||||
} else {
|
||||
mouse_delta = {
|
||||
p.u.keyboard.curr_x - p.u.keyboard.last_x,
|
||||
-(p.u.keyboard.curr_y - p.u.keyboard.last_y)
|
||||
};
|
||||
}
|
||||
|
||||
//std::cout << "got mouse delta: " << mouse_delta.x << " " << mouse_delta.y << "\n";
|
||||
|
||||
if (p.u.keyboard.view_mode == k_view_mode_t::MOUSE_DRAG || p.u.keyboard.view_mode == k_view_mode_t::MOUSE_RELATIVE) {
|
||||
if (p.u.keyboard.mouse_button_down) {
|
||||
p.view_dir = glm::mod(glm::atan(mouse_delta.y, mouse_delta.x) + glm::pi<float>(), glm::two_pi<float>());
|
||||
p.view_force = glm::length(mouse_delta) * 0.08f;
|
||||
} else {
|
||||
p.view_force = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
// new gos old
|
||||
p.u.keyboard.last_x = p.u.keyboard.curr_x;
|
||||
p.u.keyboard.last_y = p.u.keyboard.curr_y;
|
||||
}
|
||||
|
||||
void InputService::updateCPlayerDirs(player_input_action_state& p) {
|
||||
p.move_dir = glm::atan(p.u.controller.left_y / -32768.f, p.u.controller.left_x / 32767.f);
|
||||
p.view_dir = glm::atan(p.u.controller.right_y / -32768.f, p.u.controller.right_x / 32767.f);
|
||||
|
||||
p.move_force = (glm::abs(p.u.controller.left_x * glm::cos(p.move_dir)) + glm::abs(p.u.controller.left_y * glm::sin(p.move_dir)) + 0.5f) / 32768.f;
|
||||
if (p.move_force > 1.f) {
|
||||
p.move_force = 1.f;
|
||||
} else if (p.move_force < -1.f) {
|
||||
p.move_force = -1.f;
|
||||
}
|
||||
|
||||
p.view_force = (glm::abs(p.u.controller.right_x * glm::cos(p.view_dir)) + glm::abs(p.u.controller.right_y * glm::sin(p.view_dir)) + 0.5f) / 32768.f;
|
||||
p.view_force = glm::clamp(p.view_force, -1.f, 1.f);
|
||||
}
|
||||
|
||||
} // namespace MM::Services
|
||||
|
153
framework/input/src/mm/services/input_service.hpp
Normal file
153
framework/input/src/mm/services/input_service.hpp
Normal file
@ -0,0 +1,153 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include <glm/vec2.hpp>
|
||||
|
||||
#include <mm/services/sdl_service.hpp>
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace MM::Input {
|
||||
using PlayerID = uint16_t;
|
||||
} // MM::Input
|
||||
|
||||
namespace MM::Services {
|
||||
|
||||
class InputService : public Service {
|
||||
public:
|
||||
// TDO: rework
|
||||
enum input_action_t {
|
||||
SPELL_WEAPON,
|
||||
SPELL_1,
|
||||
SPELL_2,
|
||||
SPELL_3,
|
||||
SPELL_4,
|
||||
SPELL_5,
|
||||
SPELL_6,
|
||||
USE,
|
||||
INPUT_ACTION_MAX
|
||||
};
|
||||
|
||||
enum class k_view_mode_t {
|
||||
NO_VIEW, // disables any kplayer view processing
|
||||
USE_ARROWS, // TODO: implement
|
||||
MOUSE_DRAG,
|
||||
MOUSE_RELATIVE, // TODO: implement
|
||||
MOUSE_RELATIVE_TO_CENTER, // TODO: refactor
|
||||
};
|
||||
|
||||
struct keyboard_mapping {
|
||||
SDL_Keycode move_up;
|
||||
SDL_Keycode move_down;
|
||||
SDL_Keycode move_left;
|
||||
SDL_Keycode move_right;
|
||||
|
||||
SDL_Keycode actions[INPUT_ACTION_MAX];
|
||||
|
||||
input_action_t get(SDL_Keycode key);
|
||||
};
|
||||
|
||||
struct controller_mapping {
|
||||
SDL_GameControllerButton actions[INPUT_ACTION_MAX];
|
||||
|
||||
input_action_t get(SDL_GameControllerButton key);
|
||||
};
|
||||
|
||||
private:
|
||||
struct player_input_action_state {
|
||||
|
||||
bool is_controller;
|
||||
SDL_JoystickID controller_instance_id;
|
||||
union {
|
||||
struct {
|
||||
int16_t left_x;
|
||||
int16_t left_y;
|
||||
|
||||
int16_t right_x;
|
||||
int16_t right_y;
|
||||
} controller;
|
||||
struct {
|
||||
bool up;
|
||||
bool down;
|
||||
bool left;
|
||||
bool right;
|
||||
|
||||
bool mouse_button_down; // for MOUSE_DRAG
|
||||
|
||||
int32_t last_x, last_y;
|
||||
int32_t curr_x, curr_y;
|
||||
|
||||
k_view_mode_t view_mode;
|
||||
} keyboard;
|
||||
} u; // union
|
||||
|
||||
bool active[INPUT_ACTION_MAX] = {false};
|
||||
|
||||
float move_force = 0.f;
|
||||
float move_dir = 0.f;
|
||||
float view_force = 0.f;
|
||||
float view_dir = 0.f;
|
||||
};
|
||||
|
||||
public: // HACK: proper methods
|
||||
keyboard_mapping _k_map;
|
||||
controller_mapping _c_map;
|
||||
|
||||
private:
|
||||
// TODO: max player
|
||||
static const Input::PlayerID max_player_id = 4;
|
||||
std::array<player_input_action_state, max_player_id> _player;
|
||||
std::array<bool, max_player_id> _player_active;
|
||||
|
||||
public:
|
||||
InputService(void);
|
||||
~InputService(void);
|
||||
|
||||
private:
|
||||
SDLService::EventHandlerHandle _event_handle = nullptr;
|
||||
MM::Engine::FunctionDataHandle _update_handle;
|
||||
|
||||
|
||||
public:
|
||||
bool enable(Engine& engine) override;
|
||||
void disable(Engine& engine) override;
|
||||
|
||||
const char* name(void) override { return "InputService"; }
|
||||
|
||||
// returns true if event was relevant
|
||||
bool handleSDL_Event(const SDL_Event& e, MM::Engine& engine);
|
||||
|
||||
Input::PlayerID addPlayer(bool keyboard, SDL_JoystickID controller_id);
|
||||
|
||||
bool setKPlayerViewMode(Input::PlayerID id, k_view_mode_t mode);
|
||||
|
||||
// returns UINT16_MAX on error
|
||||
Input::PlayerID findPlayerState(bool controller, SDL_JoystickID controller_id);
|
||||
|
||||
// check if action is set
|
||||
bool get(Input::PlayerID id, input_action_t action);
|
||||
const char* getKeyString(Input::PlayerID id, input_action_t action);
|
||||
|
||||
float getMoveForce(Input::PlayerID id);
|
||||
float getViewForce(Input::PlayerID id);
|
||||
|
||||
glm::vec2 getMoveVec(Input::PlayerID id);
|
||||
glm::vec2 getViewVec(Input::PlayerID id);
|
||||
|
||||
// returns values [0, 2PI)
|
||||
float getMoveDir(Input::PlayerID id);
|
||||
|
||||
// returns values [0, 2PI)
|
||||
float getViewDir(Input::PlayerID id);
|
||||
|
||||
private:
|
||||
SDL_Keycode loadKey(const std::string& name, const SDL_Keycode default_key);
|
||||
SDL_GameControllerButton loadButton(const std::string& name, const SDL_GameControllerButton default_button);
|
||||
|
||||
|
||||
void updateKPlayerDirs(player_input_action_state& p);
|
||||
void updateCPlayerDirs(player_input_action_state& p);
|
||||
};
|
||||
} // namespace MM::Services
|
||||
|
33
framework/input/test/CMakeLists.txt
Normal file
33
framework/input/test/CMakeLists.txt
Normal file
@ -0,0 +1,33 @@
|
||||
add_executable(input_service_test
|
||||
start_test.cpp
|
||||
)
|
||||
|
||||
target_include_directories(input_service_test PRIVATE ".")
|
||||
|
||||
target_link_libraries(input_service_test
|
||||
input_service
|
||||
sdl_service
|
||||
gtest_main
|
||||
)
|
||||
|
||||
add_test(NAME input_service_test COMMAND input_service_test)
|
||||
|
||||
######################
|
||||
|
||||
add_executable(input_service_visualizer_test
|
||||
input_visualizer.cpp
|
||||
)
|
||||
|
||||
target_include_directories(input_service_visualizer_test PRIVATE ".")
|
||||
|
||||
target_link_libraries(input_service_visualizer_test
|
||||
input_service
|
||||
sdl_service
|
||||
imgui_service
|
||||
imgui_render_task
|
||||
imgui_tools
|
||||
gtest_main
|
||||
)
|
||||
|
||||
add_test(NAME input_service_visualizer_test COMMAND input_service_visualizer_test)
|
||||
|
162
framework/input/test/input_visualizer.cpp
Normal file
162
framework/input/test/input_visualizer.cpp
Normal file
@ -0,0 +1,162 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/services/input_service.hpp>
|
||||
#include <mm/services/sdl_service.hpp>
|
||||
#include <mm/services/filesystem.hpp>
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
#include <mm/services/imgui_s.hpp>
|
||||
|
||||
#include <mm/opengl/render_tasks/imgui.hpp>
|
||||
|
||||
#include <mm/imgui/fps_overlay.hpp>
|
||||
|
||||
#include <imgui/imgui.h>
|
||||
|
||||
|
||||
class InputVisualizer : public MM::Services::Service {
|
||||
private:
|
||||
MM::Input::PlayerID _player_id;
|
||||
MM::Engine::FunctionDataHandle _render_handle;
|
||||
MM::Services::SDLService::EventHandlerHandle _event_handle = nullptr;
|
||||
|
||||
public:
|
||||
bool enable(MM::Engine& engine) override {
|
||||
_player_id = UINT16_MAX;
|
||||
|
||||
auto* sdl_ss = engine.tryService<MM::Services::SDLService>();
|
||||
if (sdl_ss) {
|
||||
_event_handle = sdl_ss->addEventHandler([this, &engine](const SDL_Event& e) -> bool {
|
||||
return this->handleEvent(e, engine);
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < SDL_NumJoysticks(); i++) {
|
||||
if (SDL_IsGameController(i)) {
|
||||
std::cerr << "got controller " << i << "\n";
|
||||
SDL_GameControllerOpen(i);
|
||||
}
|
||||
}
|
||||
|
||||
_render_handle = engine.addUpdate([this](MM::Engine& e){ this->renderImGui(e); });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void disable(MM::Engine& engine) override {
|
||||
if (!_render_handle.expired()) {
|
||||
engine.removeUpdate(_render_handle);
|
||||
_render_handle.reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
void renderImGui(MM::Engine& engine) {
|
||||
ImGui::Begin("InputVisualizer", NULL, ImGuiWindowFlags_AlwaysAutoResize);
|
||||
if (_player_id == UINT16_MAX) {
|
||||
ImGui::Text("press [SPACE](keyboard) or [A](controller)");
|
||||
} else {
|
||||
auto* input = engine.tryService<MM::Services::InputService>();
|
||||
ImGui::Text("InputAction active:");
|
||||
|
||||
ImGui::Value("SPELL_WEAPON", input->get(_player_id, MM::Services::InputService::SPELL_WEAPON));
|
||||
ImGui::Value("SPELL_1", input->get(_player_id, MM::Services::InputService::SPELL_1));
|
||||
ImGui::Value("SPELL_2", input->get(_player_id, MM::Services::InputService::SPELL_2));
|
||||
ImGui::Value("SPELL_3", input->get(_player_id, MM::Services::InputService::SPELL_3));
|
||||
ImGui::Value("SPELL_4", input->get(_player_id, MM::Services::InputService::SPELL_4));
|
||||
ImGui::Value("SPELL_5", input->get(_player_id, MM::Services::InputService::SPELL_5));
|
||||
ImGui::Value("SPELL_6", input->get(_player_id, MM::Services::InputService::SPELL_6));
|
||||
ImGui::Value("USE", input->get(_player_id, MM::Services::InputService::USE));
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
{
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
|
||||
static ImVec4 col = ImVec4(1.0f, 1.0f, 0.4f, 1.0f);
|
||||
const ImU32 col32 = ImColor(col);
|
||||
|
||||
const ImVec2 p = ImGui::GetCursorScreenPos();
|
||||
|
||||
float scaling = 50.f;
|
||||
float x = p.x + scaling;
|
||||
float y = p.y + scaling;
|
||||
float spacing = 8.0f;
|
||||
|
||||
draw_list->AddCircleFilled(ImVec2(x, y), scaling, ImColor(0.2f, 0.2f, 0.2f, 0.7f), 24);
|
||||
auto move_vec = input->getMoveVec(_player_id);
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x + move_vec.x * scaling, y + move_vec.y * scaling), col32, 3.f);
|
||||
|
||||
x += scaling*2 + spacing;
|
||||
|
||||
draw_list->AddCircleFilled(ImVec2(x, y), scaling, ImColor(0.2f, 0.2f, 0.2f, 0.7f), 24);
|
||||
auto view_vec = input->getViewVec(_player_id);
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x + view_vec.x * scaling, y + view_vec.y * scaling), col32, 3.f);
|
||||
|
||||
ImGui::Dummy(ImVec2(scaling*4 + spacing, scaling*2));
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
private:
|
||||
bool handleEvent(const SDL_Event& e, MM::Engine& engine) {
|
||||
auto* input = engine.tryService<MM::Services::InputService>();
|
||||
if (_player_id == UINT16_MAX) {
|
||||
if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_SPACE) {
|
||||
_player_id = input->addPlayer(true, 0);
|
||||
return true;
|
||||
} else if (e.type == SDL_CONTROLLERDEVICEADDED) {
|
||||
SDL_GameControllerOpen(e.cdevice.which);
|
||||
std::cout << "added: " << e.cdevice.which << std::endl;
|
||||
return true;
|
||||
} else if (e.type == SDL_CONTROLLERBUTTONDOWN && e.cbutton.button == SDL_CONTROLLER_BUTTON_A) {
|
||||
_player_id = input->addPlayer(false, e.cbutton.which);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(input_service, input_visualizer) {
|
||||
MM::Engine engine;
|
||||
|
||||
auto& sdl_ss = engine.addService<MM::Services::SDLService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SDLService>());
|
||||
|
||||
sdl_ss.createGLWindow("service_input_visualizer_test", 1280, 720);
|
||||
|
||||
engine.addService<InputVisualizer>();
|
||||
ASSERT_TRUE(engine.enableService<InputVisualizer>());
|
||||
|
||||
engine.addService<MM::Services::InputService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::InputService>());
|
||||
|
||||
engine.addService<MM::Services::ImGuiService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::ImGuiService>());
|
||||
|
||||
auto& rs = engine.addService<MM::Services::OpenGLRenderer>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::OpenGLRenderer>());
|
||||
|
||||
rs.addRenderTask<MM::OpenGL::RenderTasks::ImGuiRT>(engine);
|
||||
|
||||
{
|
||||
MM::ImGuiSimpleFPSOverlay fps_overlay;
|
||||
|
||||
engine.addUpdate([&](MM::Engine&) {
|
||||
fps_overlay.renderImGui();
|
||||
}
|
||||
);
|
||||
|
||||
engine.run();
|
||||
}
|
||||
|
||||
sdl_ss.destroyWindow();
|
||||
}
|
||||
|
221
framework/input/test/start_test.cpp
Normal file
221
framework/input/test/start_test.cpp
Normal file
@ -0,0 +1,221 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/services/input_service.hpp>
|
||||
#include <mm/services/sdl_service.hpp>
|
||||
|
||||
TEST(input_service, add_en_dis) {
|
||||
MM::Engine engine;
|
||||
|
||||
// sdl dep
|
||||
{
|
||||
engine.addService<MM::Services::SDLService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SDLService>());
|
||||
|
||||
auto* sdl_ss_ptr = engine.tryService<MM::Services::SDLService>();
|
||||
ASSERT_NE(sdl_ss_ptr, nullptr);
|
||||
}
|
||||
|
||||
engine.addService<MM::Services::InputService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::InputService>());
|
||||
|
||||
auto* input_service_ptr = engine.tryService<MM::Services::InputService>();
|
||||
ASSERT_NE(input_service_ptr, nullptr);
|
||||
|
||||
////
|
||||
|
||||
engine.disableService<MM::Services::InputService>();
|
||||
|
||||
engine.disableService<MM::Services::SDLService>();
|
||||
}
|
||||
|
||||
TEST(input_service, initial_error) {
|
||||
MM::Engine engine;
|
||||
|
||||
// sdl dep
|
||||
{
|
||||
engine.addService<MM::Services::SDLService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SDLService>());
|
||||
|
||||
auto* sdl_ss_ptr = engine.tryService<MM::Services::SDLService>();
|
||||
ASSERT_NE(sdl_ss_ptr, nullptr);
|
||||
}
|
||||
|
||||
engine.addService<MM::Services::InputService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::InputService>());
|
||||
|
||||
auto* input_service_ptr = engine.tryService<MM::Services::InputService>();
|
||||
ASSERT_NE(input_service_ptr, nullptr);
|
||||
|
||||
auto& input = *input_service_ptr;
|
||||
|
||||
// actions (spells)
|
||||
{
|
||||
for (unsigned int action = 0; action < MM::Services::InputService::INPUT_ACTION_MAX; action++) {
|
||||
ASSERT_FALSE(input.get(0, (MM::Services::InputService::input_action_t)action));
|
||||
}
|
||||
|
||||
ASSERT_FALSE(input.get(2, MM::Services::InputService::SPELL_1));
|
||||
}
|
||||
|
||||
// move and view
|
||||
{
|
||||
{
|
||||
auto m = input.getMoveVec(0);
|
||||
ASSERT_EQ(m.x, 0.f);
|
||||
ASSERT_EQ(m.y, 0.f);
|
||||
}
|
||||
|
||||
{
|
||||
auto v = input.getViewVec(0);
|
||||
ASSERT_EQ(v.x, 0.f);
|
||||
ASSERT_EQ(v.y, 0.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(input_service, adding_players) {
|
||||
MM::Engine engine;
|
||||
|
||||
// sdl dep
|
||||
{
|
||||
engine.addService<MM::Services::SDLService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SDLService>());
|
||||
|
||||
auto* sdl_ss_ptr = engine.tryService<MM::Services::SDLService>();
|
||||
ASSERT_NE(sdl_ss_ptr, nullptr);
|
||||
}
|
||||
|
||||
engine.addService<MM::Services::InputService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::InputService>());
|
||||
|
||||
auto* input_service_ptr = engine.tryService<MM::Services::InputService>();
|
||||
ASSERT_NE(input_service_ptr, nullptr);
|
||||
|
||||
auto& input = *input_service_ptr;
|
||||
|
||||
MM::Input::PlayerID p1_id = input.addPlayer(true, 0);
|
||||
ASSERT_NE(p1_id, UINT16_MAX);
|
||||
|
||||
{
|
||||
// TODO: check
|
||||
//ASSERT_EQ(input.addPlayer(true, 0), UINT16_MAX);
|
||||
}
|
||||
|
||||
// actions (spells)
|
||||
{
|
||||
for (unsigned int action = 0; action < MM::Services::InputService::INPUT_ACTION_MAX; action++) {
|
||||
ASSERT_FALSE(input.get(p1_id, (MM::Services::InputService::input_action_t)action));
|
||||
}
|
||||
}
|
||||
|
||||
// move and view
|
||||
{
|
||||
{
|
||||
auto m = input.getMoveVec(p1_id);
|
||||
ASSERT_EQ(m.x, 0.f);
|
||||
ASSERT_EQ(m.y, 0.f);
|
||||
}
|
||||
|
||||
{
|
||||
// never (0, 0)
|
||||
auto v = input.getViewVec(p1_id);
|
||||
ASSERT_EQ(v.x, 1.f);
|
||||
ASSERT_EQ(v.y, 0.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(input_service, basic_handling_keyboard) {
|
||||
MM::Engine engine;
|
||||
|
||||
// sdl dep
|
||||
{
|
||||
engine.addService<MM::Services::SDLService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SDLService>());
|
||||
|
||||
auto* sdl_ss_ptr = engine.tryService<MM::Services::SDLService>();
|
||||
ASSERT_NE(sdl_ss_ptr, nullptr);
|
||||
}
|
||||
|
||||
engine.addService<MM::Services::InputService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::InputService>());
|
||||
|
||||
auto* input_service_ptr = engine.tryService<MM::Services::InputService>();
|
||||
ASSERT_NE(input_service_ptr, nullptr);
|
||||
|
||||
auto& input = *input_service_ptr;
|
||||
|
||||
MM::Input::PlayerID p_id = input.addPlayer(true, 0);
|
||||
ASSERT_NE(p_id, UINT16_MAX);
|
||||
|
||||
// actions (spells)
|
||||
{
|
||||
for (unsigned int action = 0; action < MM::Services::InputService::INPUT_ACTION_MAX; action++) {
|
||||
ASSERT_FALSE(input.get(p_id, (MM::Services::InputService::input_action_t)action));
|
||||
}
|
||||
|
||||
// forging sdl event spell 1
|
||||
{
|
||||
SDL_Event tmp_e;
|
||||
tmp_e.key.keysym.sym = SDLK_1;
|
||||
tmp_e.type = SDL_KEYDOWN;
|
||||
|
||||
ASSERT_TRUE(input.handleSDL_Event(tmp_e, engine));
|
||||
}
|
||||
|
||||
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::SPELL_WEAPON));
|
||||
ASSERT_TRUE(input.get(p_id, MM::Services::InputService::SPELL_1));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::SPELL_2));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::SPELL_3));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::SPELL_4));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::SPELL_5));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::SPELL_6));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::USE));
|
||||
|
||||
// forging sdl event spell weapon
|
||||
{
|
||||
SDL_Event tmp_e;
|
||||
tmp_e.key.keysym.sym = SDLK_SPACE;
|
||||
tmp_e.type = SDL_KEYDOWN;
|
||||
|
||||
ASSERT_TRUE(input.handleSDL_Event(tmp_e, engine));
|
||||
}
|
||||
|
||||
ASSERT_TRUE(input.get(p_id, MM::Services::InputService::SPELL_WEAPON));
|
||||
ASSERT_TRUE(input.get(p_id, MM::Services::InputService::SPELL_1));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::SPELL_2));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::SPELL_3));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::SPELL_4));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::SPELL_5));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::SPELL_6));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::USE));
|
||||
|
||||
// forging sdl event spell 1 end
|
||||
{
|
||||
SDL_Event tmp_e;
|
||||
tmp_e.key.keysym.sym = SDLK_1;
|
||||
tmp_e.type = SDL_KEYUP;
|
||||
|
||||
ASSERT_TRUE(input.handleSDL_Event(tmp_e, engine));
|
||||
}
|
||||
|
||||
|
||||
ASSERT_TRUE(input.get(p_id, MM::Services::InputService::SPELL_WEAPON));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::SPELL_1));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::SPELL_2));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::SPELL_3));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::SPELL_4));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::SPELL_5));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::SPELL_6));
|
||||
ASSERT_FALSE(input.get(p_id, MM::Services::InputService::USE));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
Reference in New Issue
Block a user