4coder/4ed_input_simulation.cpp

223 lines
6.0 KiB
C++

/*
* Mr. 4th Dimention - Allen Webster
*
* 02.03.2018
*
* Input simulation implementation
*
*/
// TOP
internal void
simulate_key(Application_Step_Input *input,
Key_Code keycode, Key_Code character, Key_Code character_no_caps_lock, i8 *modifiers){
Key_Input_Data *keys = &input->keys;
Assert(keys->count < ArrayCount(keys->keys));
Key_Event_Data *key = &keys->keys[keys->count++];
key->keycode = keycode;
key->character = character;
key->character_no_caps_lock = character_no_caps_lock;
memcpy(key->modifiers, modifiers, sizeof(key->modifiers));
}
internal void
simulate_key(Application_Step_Input *input,
Key_Code code, i8 *modifiers){
i32 size = 0;
char *keycode_name = global_key_name(code, &size);
if (keycode_name != 0){
simulate_key(input, code, 0, 0, modifiers);
}
else{
Key_Code no_caps = code;
if (modifiers[MDFR_CAPS_INDEX]){
if (no_caps >= 'a' && no_caps <= 'z'){
no_caps -= (u8)('a' - 'A');
}
else if (no_caps >= 'A' && no_caps <= 'Z'){
no_caps += (u8)('a' - 'A');
}
}
simulate_key(input, code, code, no_caps, modifiers);
}
}
internal void
simulate_key(Application_Step_Input *input,
Key_Code code, u8 modifiers){
i8 mod_array[MDFR_INDEX_COUNT];
memset(mod_array, 0, sizeof(mod_array));
if (modifiers & MDFR_CTRL){
mod_array[MDFR_CONTROL_INDEX] = 1;
}
if (modifiers & MDFR_ALT){
mod_array[MDFR_ALT_INDEX] = 1;
}
if (modifiers & MDFR_CMND){
mod_array[MDFR_COMMAND_INDEX] = 1;
}
if (modifiers & MDFR_SHIFT){
mod_array[MDFR_SHIFT_INDEX] = 1;
}
simulate_key(input, code, mod_array);
}
internal void
simulate_mouse_state(Application_Step_Input *input, Mouse_State state){
input->mouse = state;
}
internal void
simulate_mouse_update(Application_Step_Input *input, Mouse_State prev_mouse){
input->mouse = prev_mouse;
input->mouse.press_l = false;
input->mouse.press_r = false;
input->mouse.release_l = false;
input->mouse.release_r = false;
input->mouse.wheel = 0;
}
internal void
simulate_mouse_xy(Application_Step_Input *input, i32 x, i32 y, i32 width, i32 height){
input->mouse.x = x;
input->mouse.y = y;
input->mouse.out_of_window = (x < 0 || y < 0 || x > width || y > height);
}
internal void
simulate_mouse_left_press(Application_Step_Input *input){
input->mouse.l = true;
input->mouse.press_l = true;
}
internal void
simulate_mouse_left_release(Application_Step_Input *input){
input->mouse.l = false;
input->mouse.release_l = true;
}
internal void
simulate_mouse_right_press(Application_Step_Input *input){
input->mouse.r = true;
input->mouse.press_r = true;
}
internal void
simulate_mouse_right_release(Application_Step_Input *input){
input->mouse.r = false;
input->mouse.release_r = true;
}
internal void
simulate_mouse_wheel(Application_Step_Input *input, i32 wheel){
input->mouse.wheel = wheel;
}
internal void
simulate_exit(Application_Step_Input *input){
input->trying_to_kill = true;
}
////////////////
internal void
simulation_init(Input_Simulation_Controls *sim_controls){
memset(sim_controls, 0, sizeof(*sim_controls));
sim_controls->enforce_regular_mouse = true;
}
internal void
simulation_step_begin(Input_Simulation_Controls *sim_controls,
Application_Step_Input *input,
b32 first_step, f32 dt){
if (sim_controls->enforce_regular_mouse){
simulate_mouse_update(input, sim_controls->prev_mouse);
}
input->first_step = first_step;
input->dt = dt;
}
internal void
simulation_step_end(Input_Simulation_Controls *sim_controls,
Application_Step_Input *input){
sim_controls->counter += 1;
sim_controls->prev_mouse = input->mouse;
}
////////////////
internal void
simulation_stream_init(Simulation_Event_Stream_State *stream){
stream->index = 0;
}
internal void
simulation_drive_from_events(Input_Simulation_Controls *sim_controls,
Simulation_Event_Stream_State *stream,
Application_Step_Input *input,
Simulation_Event *events, i32 event_count,
i32 width, i32 height){
Simulation_Event *event = events + stream->index;
for (; stream->index < event_count; ++stream->index, ++event){
if (event->counter_index > sim_controls->counter){
break;
}
switch (event->type){
case SimulationEvent_Noop:InvalidCodePath;
case SimulationEvent_DebugNumber:
{
input->debug_number = event->debug_number;
}break;
case SimulationEvent_Key:
{
simulate_key(input, event->key.code, event->key.modifiers);
}break;
case SimulationEvent_MouseLeftPress:
{
simulate_mouse_left_press(input);
}break;
case SimulationEvent_MouseLeftRelease:
{
simulate_mouse_left_release(input);
}break;
case SimulationEvent_MouseRightPress:
{
simulate_mouse_right_press(input);
}break;
case SimulationEvent_MouseRightRelease:
{
simulate_mouse_right_release(input);
}break;
case SimulationEvent_MouseWheel:
{
simulate_mouse_wheel(input, event->wheel);
}break;
case SimulationEvent_MouseXY:
{
simulate_mouse_xy(input, event->mouse_xy.x, event->mouse_xy.y,
width, height);
}break;
case SimulationEvent_Exit:
{
simulate_exit(input);
}break;
default:InvalidCodePath;
}
}
}
// BOTTOM