ref: 33858fb5e004863ff58b525ebf596a038bf849aa
dir: /src/input.c/
#include "input.h"
#include "backends/rtmidi.h"
#include "backends/serialport.h"
#include "config.h"
#include "gamecontrollers.h"
#include "render.h"
#include "audio.h"
#include <SDL3/SDL.h>
uint8_t keyjazz_enabled = 0;
uint8_t keyjazz_base_octave = 2;
uint8_t keyjazz_velocity = 0x64;
static uint8_t keycode = 0; // value of the pressed key
static input_msg_s key = {normal, 0, 0, 0};
int input_process(config_params_s conf, enum app_state *app_state) {
static uint8_t prev_input = 0;
static uint8_t prev_note = 0;
// get current inputs
const input_msg_s input = input_get_msg(&conf);
switch (input.type) {
case normal:
if (input.value != prev_input) {
prev_input = input.value;
send_msg_controller(input.value);
}
break;
case keyjazz:
if (input.value != 0) {
if (input.eventType == SDL_EVENT_KEY_DOWN && input.value != prev_input) {
send_msg_keyjazz(input.value, input.value2);
prev_note = input.value;
} else if (input.eventType == SDL_EVENT_KEY_UP && input.value == prev_note) {
send_msg_keyjazz(0xFF, 0);
}
}
prev_input = input.value;
break;
case special:
if (input.value != prev_input) {
prev_input = input.value;
switch (input.value) {
case msg_quit:
SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "Received msg_quit from input device.");
*app_state = 0;
break;
case msg_reset_display:
reset_display();
break;
case msg_toggle_audio:
conf.audio_enabled = !conf.audio_enabled;
audio_toggle(conf.audio_device_name, conf.audio_buffer_size);
break;
default:
break;
}
break;
}
}
return 1;
}
uint8_t toggle_input_keyjazz() {
keyjazz_enabled = !keyjazz_enabled;
SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, keyjazz_enabled ? "Keyjazz enabled" : "Keyjazz disabled");
return keyjazz_enabled;
}
static input_msg_s handle_keyjazz(SDL_Event *event, uint8_t keyvalue, config_params_s *conf) {
input_msg_s key = {keyjazz, keyvalue, keyjazz_velocity, event->type};
switch (event->key.scancode) {
case SDL_SCANCODE_Z:
key.value = keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_S:
key.value = 1 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_X:
key.value = 2 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_D:
key.value = 3 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_C:
key.value = 4 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_V:
key.value = 5 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_G:
key.value = 6 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_B:
key.value = 7 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_H:
key.value = 8 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_N:
key.value = 9 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_J:
key.value = 10 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_M:
key.value = 11 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_Q:
key.value = 12 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_2:
key.value = 13 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_W:
key.value = 14 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_3:
key.value = 15 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_E:
key.value = 16 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_R:
key.value = 17 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_5:
key.value = 18 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_T:
key.value = 19 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_6:
key.value = 20 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_Y:
key.value = 21 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_7:
key.value = 22 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_U:
key.value = 23 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_I:
key.value = 24 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_9:
key.value = 25 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_O:
key.value = 26 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_0:
key.value = 27 + keyjazz_base_octave * 12;
break;
case SDL_SCANCODE_P:
key.value = 28 + keyjazz_base_octave * 12;
break;
default:
key.type = normal;
if (event->key.repeat > 0 || event->key.type == SDL_EVENT_KEY_UP) {
break;
}
if (event->key.scancode == conf->key_jazz_dec_octave) {
if (keyjazz_base_octave > 0) {
keyjazz_base_octave--;
display_keyjazz_overlay(1, keyjazz_base_octave, keyjazz_velocity);
}
} else if (event->key.scancode == conf->key_jazz_inc_octave) {
if (keyjazz_base_octave < 8) {
keyjazz_base_octave++;
display_keyjazz_overlay(1, keyjazz_base_octave, keyjazz_velocity);
}
} else if (event->key.scancode == conf->key_jazz_dec_velocity) {
if ((event->key.mod & SDL_KMOD_ALT) > 0) {
if (keyjazz_velocity > 1)
keyjazz_velocity -= 1;
} else {
if (keyjazz_velocity > 0x10)
keyjazz_velocity -= 0x10;
}
display_keyjazz_overlay(1, keyjazz_base_octave, keyjazz_velocity);
} else if (event->key.scancode == conf->key_jazz_inc_velocity) {
if ((event->key.mod & SDL_KMOD_ALT) > 0) {
if (keyjazz_velocity < 0x7F)
keyjazz_velocity += 1;
} else {
if (keyjazz_velocity < 0x6F)
keyjazz_velocity += 0x10;
}
display_keyjazz_overlay(1, keyjazz_base_octave, keyjazz_velocity);
}
break;
}
return key;
}
static input_msg_s handle_normal_keys(const SDL_Event *event, const config_params_s *conf) {
input_msg_s key = {normal, 0, 0, 0};
if (event->key.scancode == conf->key_up) {
key.value = key_up;
} else if (event->key.scancode == conf->key_left) {
key.value = key_left;
} else if (event->key.scancode == conf->key_down) {
key.value = key_down;
} else if (event->key.scancode == conf->key_right) {
key.value = key_right;
} else if (event->key.scancode == conf->key_select ||
event->key.scancode == conf->key_select_alt) {
key.value = key_select;
} else if (event->key.scancode == conf->key_start ||
event->key.scancode == conf->key_start_alt) {
key.value = key_start;
} else if (event->key.scancode == conf->key_opt ||
event->key.scancode == conf->key_opt_alt) {
key.value = key_opt;
} else if (event->key.scancode == conf->key_edit ||
event->key.scancode == conf->key_edit_alt) {
key.value = key_edit;
} else if (event->key.scancode == conf->key_delete) {
key.value = key_opt | key_edit;
} else if (event->key.scancode == conf->key_reset) {
key = (input_msg_s){special, msg_reset_display, 0, 0};
} else if (event->key.scancode == conf->key_toggle_audio) {
key = (input_msg_s){special, msg_toggle_audio, 0, 0};
} else {
key.value = 0;
}
return key;
}
// Handles SDL input events
void handle_sdl_events(config_params_s *conf) {
static int prev_key_analog = 0;
static unsigned int ticks_window_resized = 0;
SDL_Event event;
// Read joysticks
const int key_analog = gamecontrollers_handle_buttons(conf);
if (prev_key_analog != key_analog) {
keycode = key_analog;
prev_key_analog = key_analog;
}
const input_msg_s gamepad_msg = gamecontrollers_handle_special_messages(conf);
if (gamepad_msg.type == special) {
key = gamepad_msg;
}
while (SDL_PollEvent(&event)) {
switch (event.type) {
// Reinitialize game controllers on controller add/remove/remap
case SDL_EVENT_GAMEPAD_ADDED:
case SDL_EVENT_GAMEPAD_REMOVED:
gamecontrollers_initialize();
break;
// Handle SDL quit events (for example, window close)
case SDL_EVENT_QUIT:
key = (input_msg_s){special, msg_quit, 0, 0};
break;
case SDL_EVENT_WINDOW_RESIZED:
if (SDL_GetTicks() - ticks_window_resized > 500) {
SDL_Log("Resizing window...");
key = (input_msg_s){special, msg_reset_display, 0, 0};
ticks_window_resized = SDL_GetTicks();
}
break;
case SDL_EVENT_KEY_DOWN:
if (event.key.repeat > 0) {
break;
}
// ALT+ENTER toggles fullscreen
if (event.key.key == SDLK_RETURN && (event.key.mod & SDL_KMOD_ALT) > 0) {
toggle_fullscreen();
break;
}
// ALT+F4 quits program
if (event.key.key == SDLK_F4 && (event.key.mod & SDL_KMOD_ALT) > 0) {
key = (input_msg_s){special, msg_quit, 0, 0};
break;
}
// ESC = toggle keyjazz
if (event.key.key == SDLK_ESCAPE) {
display_keyjazz_overlay(toggle_input_keyjazz(), keyjazz_base_octave, keyjazz_velocity);
break;
}
// Intentional fallthrough
case SDL_EVENT_KEY_UP:
// Normal keyboard inputs
key = handle_normal_keys(&event, conf);
if (keyjazz_enabled) {
key = handle_keyjazz(&event, key.value, conf);
}
break;
default:
break;
}
switch (key.type) {
case normal:
if (event.type == SDL_EVENT_KEY_DOWN) {
keycode |= key.value;
} else if (event.type == SDL_EVENT_KEY_UP) {
keycode &= ~key.value;
}
break;
case keyjazz:
// Do not allow pressing multiple keys with keyjazz
case special:
if (event.type == SDL_EVENT_KEY_DOWN) {
keycode = key.value;
} else if (event.type == SDL_EVENT_KEY_UP) {
keycode = 0;
}
break;
default:
break;
}
}
}
// Returns the currently pressed keys to main
input_msg_s input_get_msg(config_params_s *conf) {
key = (input_msg_s){normal, 0, 0, 0};
// Query for SDL events
handle_sdl_events(conf);
if (!keyjazz_enabled && keycode == (key_start | key_select | key_opt | key_edit)) {
key = (input_msg_s){special, msg_reset_display, 0, 0};
}
if (key.type == normal) {
/* Normal input keys go through some event-based manipulation in
handle_sdl_events(), the value is stored in keycode variable */
const input_msg_s input = (input_msg_s){key.type, keycode, 0, 0};
return input;
}
// Special event keys already have the correct keycode baked in
return key;
}