/* * 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