From 1c483ec420323ef2e3a06b72c79f0a63bbd382b5 Mon Sep 17 00:00:00 2001 From: alice Date: Sun, 25 Aug 2024 15:13:55 +0100 Subject: [PATCH 1/4] Initial naive implementation --- src/studio/studio.c | 8 ++++++-- src/studio/system.h | 3 ++- src/system/sdl/main.c | 16 +++++++++++++++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/studio/studio.c b/src/studio/studio.c index 6dbe8a420..bd2b3d9ac 100644 --- a/src/studio/studio.c +++ b/src/studio/studio.c @@ -214,6 +214,7 @@ struct Studio tic_net* net; Bytebattle bytebattle; + bool isFrenchKeyboard; #endif @@ -1816,6 +1817,7 @@ static void processShortcuts(Studio* studio) bool alt = tic_api_key(tic, tic_key_alt); bool ctrl = tic_api_key(tic, tic_key_ctrl); + bool isFrenchKeyboard = studio->isFrenchKeyboard; #if defined(CRT_SHADER_SUPPORT) if(keyWasPressedOnce(studio, tic_key_f6)) switchCrtMonitor(studio); @@ -1825,8 +1827,9 @@ static void processShortcuts(Studio* studio) { if (enterWasPressedOnce(studio)) gotoFullscreen(studio); #if defined(BUILD_EDITORS) - else if(studio->mode != TIC_RUN_MODE) + else if(studio->mode != TIC_RUN_MODE && !isFrenchKeyboard) { + printf("We are in here even though the keyboard is not french\n"); if(keyWasPressedOnce(studio, tic_key_grave)) setStudioMode(studio, TIC_CONSOLE_MODE); else if(keyWasPressedOnce(studio, tic_key_1)) setStudioMode(studio, TIC_CODE_MODE); else if(keyWasPressedOnce(studio, tic_key_2)) setStudioMode(studio, TIC_SPRITE_MODE); @@ -2683,7 +2686,7 @@ static bool onEnumModule(const char* name, const char* title, const char* hash, } #endif -Studio* studio_create(s32 argc, char **argv, s32 samplerate, tic80_pixel_color_format format, const char* folder, s32 maxscale) +Studio* studio_create(s32 argc, char **argv, s32 samplerate, tic80_pixel_color_format format, const char* folder, s32 maxscale, bool isFrenchKeyboard) { setbuf(stdout, NULL); @@ -2737,6 +2740,7 @@ Studio* studio_create(s32 argc, char **argv, s32 samplerate, tic80_pixel_color_f .net = tic_net_create(TIC_WEBSITE), .bytebattle = {0}, + .isFrenchKeyboard = isFrenchKeyboard, #endif .tic = tic_core_create(samplerate, format), }; diff --git a/src/studio/system.h b/src/studio/system.h index a1ba3a81e..0ed2100f1 100644 --- a/src/studio/system.h +++ b/src/studio/system.h @@ -152,6 +152,7 @@ typedef struct int fft; int fftcaptureplaybackdevices; const char *fftdevice; + } StudioConfig; typedef struct Studio Studio; @@ -167,7 +168,7 @@ void studio_exit(Studio* studio); void studio_delete(Studio* studio); const StudioConfig* studio_config(Studio* studio); -Studio* studio_create(s32 argc, char **argv, s32 samplerate, tic80_pixel_color_format format, const char* appFolder, s32 maxscale); +Studio* studio_create(s32 argc, char **argv, s32 samplerate, tic80_pixel_color_format format, const char* appFolder, s32 maxscale, bool isFrenchKeyboard); #ifdef __cplusplus } diff --git a/src/system/sdl/main.c b/src/system/sdl/main.c index fc0f1f9af..b40660d70 100644 --- a/src/system/sdl/main.c +++ b/src/system/sdl/main.c @@ -1870,6 +1870,20 @@ s32 determineMaximumScale() } } +bool is_french_keyboard() { + SDL_Scancode scancode = SDL_SCANCODE_A; + SDL_Keycode key = SDL_GetKeyFromScancode(scancode); + + // On a French AZERTY layout, SDL_SCANCODE_A should map to SDLK_q + // On a QWERTY layout, it maps to SDLK_a + if (key == SDLK_q) { + printf("French keyboard detected.\n"); + } else { + printf("French keyboard not detected.\n"); + } + return (key == SDLK_q); +} + static s32 start(s32 argc, char **argv, const char* folder) { #if defined(__MACOSX__) @@ -1894,7 +1908,7 @@ static s32 start(s32 argc, char **argv, const char* folder) SDL_Log("Unable to initialize SDL Game Controller: %i, %s\n", result, SDL_GetError()); } - platform.studio = studio_create(argc, argv, TIC80_SAMPLERATE, SCREEN_FORMAT, folder, determineMaximumScale()); + platform.studio = studio_create(argc, argv, TIC80_SAMPLERATE, SCREEN_FORMAT, folder, determineMaximumScale(), is_french_keyboard()); SCOPE(studio_delete(platform.studio)) { From 3c255ecb8797562836df1da6b61c7358931c7b16 Mon Sep 17 00:00:00 2001 From: alice Date: Sun, 25 Aug 2024 16:31:06 +0100 Subject: [PATCH 2/4] Reorganize code --- src/studio/studio.c | 12 ++++++++---- src/studio/system.h | 3 +++ src/system/sdl/main.c | 33 +++++++++++++++++++-------------- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/studio/studio.c b/src/studio/studio.c index bd2b3d9ac..6d2588706 100644 --- a/src/studio/studio.c +++ b/src/studio/studio.c @@ -214,7 +214,6 @@ struct Studio tic_net* net; Bytebattle bytebattle; - bool isFrenchKeyboard; #endif @@ -1817,7 +1816,7 @@ static void processShortcuts(Studio* studio) bool alt = tic_api_key(tic, tic_key_alt); bool ctrl = tic_api_key(tic, tic_key_ctrl); - bool isFrenchKeyboard = studio->isFrenchKeyboard; + bool isFrenchKeyboard = studio->config->data.isFrenchKeyboard; #if defined(CRT_SHADER_SUPPORT) if(keyWasPressedOnce(studio, tic_key_f6)) switchCrtMonitor(studio); @@ -1829,7 +1828,6 @@ static void processShortcuts(Studio* studio) #if defined(BUILD_EDITORS) else if(studio->mode != TIC_RUN_MODE && !isFrenchKeyboard) { - printf("We are in here even though the keyboard is not french\n"); if(keyWasPressedOnce(studio, tic_key_grave)) setStudioMode(studio, TIC_CONSOLE_MODE); else if(keyWasPressedOnce(studio, tic_key_1)) setStudioMode(studio, TIC_CODE_MODE); else if(keyWasPressedOnce(studio, tic_key_2)) setStudioMode(studio, TIC_SPRITE_MODE); @@ -2655,6 +2653,12 @@ static void setPopupHide(void* data) #endif +void studio_keymapchanged(Studio* studio, bool isFrenchKeyboard) +{ + studio->config->data.isFrenchKeyboard = isFrenchKeyboard; + printf("Keyboard layout change detected, isFrenchKeyboard: %d\n", isFrenchKeyboard); +} + bool studio_alive(Studio* studio) { return studio->alive; @@ -2740,7 +2744,6 @@ Studio* studio_create(s32 argc, char **argv, s32 samplerate, tic80_pixel_color_f .net = tic_net_create(TIC_WEBSITE), .bytebattle = {0}, - .isFrenchKeyboard = isFrenchKeyboard, #endif .tic = tic_core_create(samplerate, format), }; @@ -2861,6 +2864,7 @@ Studio* studio_create(s32 argc, char **argv, s32 samplerate, tic80_pixel_color_f studio->config->data.fft = args.fft; studio->config->data.fftcaptureplaybackdevices = args.fftcaptureplaybackdevices; studio->config->data.fftdevice = args.fftdevice; + studio->config->data.isFrenchKeyboard = isFrenchKeyboard; #endif studioConfigChanged(studio); diff --git a/src/studio/system.h b/src/studio/system.h index 0ed2100f1..2f3a6bc8a 100644 --- a/src/studio/system.h +++ b/src/studio/system.h @@ -153,6 +153,8 @@ typedef struct int fftcaptureplaybackdevices; const char *fftdevice; + bool isFrenchKeyboard; + } StudioConfig; typedef struct Studio Studio; @@ -163,6 +165,7 @@ const tic_mem* studio_mem(Studio* studio); void studio_tick(Studio* studio, tic80_input input); void studio_sound(Studio* studio); void studio_load(Studio* studio, const char* file); +void studio_keymapchanged(Studio *studio, bool isFrenchKeyboard); bool studio_alive(Studio* studio); void studio_exit(Studio* studio); void studio_delete(Studio* studio); diff --git a/src/system/sdl/main.c b/src/system/sdl/main.c index b40660d70..90e2038a0 100644 --- a/src/system/sdl/main.c +++ b/src/system/sdl/main.c @@ -145,6 +145,7 @@ static struct { bool state[tic_keys_count]; bool pressed[tic_keys_count]; + bool isFrenchKeyboard; char text; #if defined(TOUCH_INPUT_SUPPORT) @@ -1062,6 +1063,21 @@ static void handleKeydown(SDL_Keycode keycode, bool down, bool* state, bool* pre #endif } +bool is_french_keyboard() { + char q = SDL_GetKeyFromScancode(SDL_SCANCODE_Q); + char w = SDL_GetKeyFromScancode(SDL_SCANCODE_W); + char y = SDL_GetKeyFromScancode(SDL_SCANCODE_Y); + + char* layout = "unknown"; + + if (q == 'q' && w == 'w' && y == 'y') layout = "qwerty"; + if (q == 'a' && w == 'z' && y == 'y') layout = "azerty"; + if (q == 'q' && w == 'w' && y == 'z') layout = "qwertz"; + if (q == 'q' && w == 'z' && y == 'y') layout = "qzerty"; + + return layout == "azerty"; +} + static void pollEvents() { // check if releative mode was enabled @@ -1193,6 +1209,9 @@ static void pollEvents() case SDL_KEYUP: handleKeydown(event.key.keysym.sym, false, platform.keyboard.state, platform.keyboard.pressed); break; + case SDL_KEYMAPCHANGED: + studio_keymapchanged(platform.studio, is_french_keyboard()); + break; case SDL_TEXTINPUT: if(strlen(event.text.text) == 1) platform.keyboard.text = event.text.text[0]; @@ -1870,20 +1889,6 @@ s32 determineMaximumScale() } } -bool is_french_keyboard() { - SDL_Scancode scancode = SDL_SCANCODE_A; - SDL_Keycode key = SDL_GetKeyFromScancode(scancode); - - // On a French AZERTY layout, SDL_SCANCODE_A should map to SDLK_q - // On a QWERTY layout, it maps to SDLK_a - if (key == SDLK_q) { - printf("French keyboard detected.\n"); - } else { - printf("French keyboard not detected.\n"); - } - return (key == SDLK_q); -} - static s32 start(s32 argc, char **argv, const char* folder) { #if defined(__MACOSX__) From c41bdea588899686934437963e56bba95c8cd79e Mon Sep 17 00:00:00 2001 From: alice Date: Sun, 25 Aug 2024 16:35:59 +0100 Subject: [PATCH 3/4] Generalize & future-proof Detects more keyboard layouts etc. --- src/studio/studio.c | 12 +++++------- src/studio/system.h | 7 +++---- src/system/sdl/main.c | 29 ++++++++++++++++------------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/studio/studio.c b/src/studio/studio.c index 6d2588706..1fec12cee 100644 --- a/src/studio/studio.c +++ b/src/studio/studio.c @@ -1816,7 +1816,6 @@ static void processShortcuts(Studio* studio) bool alt = tic_api_key(tic, tic_key_alt); bool ctrl = tic_api_key(tic, tic_key_ctrl); - bool isFrenchKeyboard = studio->config->data.isFrenchKeyboard; #if defined(CRT_SHADER_SUPPORT) if(keyWasPressedOnce(studio, tic_key_f6)) switchCrtMonitor(studio); @@ -1826,7 +1825,7 @@ static void processShortcuts(Studio* studio) { if (enterWasPressedOnce(studio)) gotoFullscreen(studio); #if defined(BUILD_EDITORS) - else if(studio->mode != TIC_RUN_MODE && !isFrenchKeyboard) + else if(studio->mode != TIC_RUN_MODE && strcmp(studio->config->data.keyboardLayout, "azerty") != 0) { if(keyWasPressedOnce(studio, tic_key_grave)) setStudioMode(studio, TIC_CONSOLE_MODE); else if(keyWasPressedOnce(studio, tic_key_1)) setStudioMode(studio, TIC_CODE_MODE); @@ -2653,10 +2652,9 @@ static void setPopupHide(void* data) #endif -void studio_keymapchanged(Studio* studio, bool isFrenchKeyboard) +void studio_keymapchanged(Studio* studio, char* keyboardLayout) { - studio->config->data.isFrenchKeyboard = isFrenchKeyboard; - printf("Keyboard layout change detected, isFrenchKeyboard: %d\n", isFrenchKeyboard); + studio->config->data.keyboardLayout = keyboardLayout; } bool studio_alive(Studio* studio) @@ -2690,7 +2688,7 @@ static bool onEnumModule(const char* name, const char* title, const char* hash, } #endif -Studio* studio_create(s32 argc, char **argv, s32 samplerate, tic80_pixel_color_format format, const char* folder, s32 maxscale, bool isFrenchKeyboard) +Studio* studio_create(s32 argc, char **argv, s32 samplerate, tic80_pixel_color_format format, const char* folder, s32 maxscale, char* keyboardLayout) { setbuf(stdout, NULL); @@ -2864,7 +2862,7 @@ Studio* studio_create(s32 argc, char **argv, s32 samplerate, tic80_pixel_color_f studio->config->data.fft = args.fft; studio->config->data.fftcaptureplaybackdevices = args.fftcaptureplaybackdevices; studio->config->data.fftdevice = args.fftdevice; - studio->config->data.isFrenchKeyboard = isFrenchKeyboard; + studio->config->data.keyboardLayout = keyboardLayout; #endif studioConfigChanged(studio); diff --git a/src/studio/system.h b/src/studio/system.h index 2f3a6bc8a..43293614c 100644 --- a/src/studio/system.h +++ b/src/studio/system.h @@ -153,8 +153,7 @@ typedef struct int fftcaptureplaybackdevices; const char *fftdevice; - bool isFrenchKeyboard; - + char* keyboardLayout; } StudioConfig; typedef struct Studio Studio; @@ -165,13 +164,13 @@ const tic_mem* studio_mem(Studio* studio); void studio_tick(Studio* studio, tic80_input input); void studio_sound(Studio* studio); void studio_load(Studio* studio, const char* file); -void studio_keymapchanged(Studio *studio, bool isFrenchKeyboard); +void studio_keymapchanged(Studio *studio, char* keyboardLayout); bool studio_alive(Studio* studio); void studio_exit(Studio* studio); void studio_delete(Studio* studio); const StudioConfig* studio_config(Studio* studio); -Studio* studio_create(s32 argc, char **argv, s32 samplerate, tic80_pixel_color_format format, const char* appFolder, s32 maxscale, bool isFrenchKeyboard); +Studio* studio_create(s32 argc, char **argv, s32 samplerate, tic80_pixel_color_format format, const char* appFolder, s32 maxscale, char* keyboardLayout); #ifdef __cplusplus } diff --git a/src/system/sdl/main.c b/src/system/sdl/main.c index 90e2038a0..37f9af5d7 100644 --- a/src/system/sdl/main.c +++ b/src/system/sdl/main.c @@ -145,7 +145,6 @@ static struct { bool state[tic_keys_count]; bool pressed[tic_keys_count]; - bool isFrenchKeyboard; char text; #if defined(TOUCH_INPUT_SUPPORT) @@ -1063,19 +1062,23 @@ static void handleKeydown(SDL_Keycode keycode, bool down, bool* state, bool* pre #endif } -bool is_french_keyboard() { - char q = SDL_GetKeyFromScancode(SDL_SCANCODE_Q); - char w = SDL_GetKeyFromScancode(SDL_SCANCODE_W); - char y = SDL_GetKeyFromScancode(SDL_SCANCODE_Y); +char* detect_keyboard_layout() { + char q = SDL_GetKeyFromScancode(SDL_SCANCODE_Q); + char w = SDL_GetKeyFromScancode(SDL_SCANCODE_W); + char y = SDL_GetKeyFromScancode(SDL_SCANCODE_Y); char* layout = "unknown"; - if (q == 'q' && w == 'w' && y == 'y') layout = "qwerty"; - if (q == 'a' && w == 'z' && y == 'y') layout = "azerty"; - if (q == 'q' && w == 'w' && y == 'z') layout = "qwertz"; - if (q == 'q' && w == 'z' && y == 'y') layout = "qzerty"; - - return layout == "azerty"; + if (q == 'q' && w == 'w' && y == 'y') layout = "qwerty"; // US etc. + if (q == 'a' && w == 'z' && y == 'y') layout = "azerty"; // French + if (q == 'q' && w == 'w' && y == 'z') layout = "qwertz"; // German etc. + if (q == 'q' && w == 'z' && y == 'y') layout = "qzerty"; // Italian + // Don't ask me why it detects k instead of l + if (q == 'x' && w == 'v' && y == 'k') layout = "xvlcwk"; // German Neo 2 + // ...or why it detects p instead of u + if (q == 'j' && w == 'd' && y == 'p') layout = "jduaxp"; // German Bone + + return layout; } static void pollEvents() @@ -1210,7 +1213,7 @@ static void pollEvents() handleKeydown(event.key.keysym.sym, false, platform.keyboard.state, platform.keyboard.pressed); break; case SDL_KEYMAPCHANGED: - studio_keymapchanged(platform.studio, is_french_keyboard()); + studio_keymapchanged(platform.studio, detect_keyboard_layout()); break; case SDL_TEXTINPUT: if(strlen(event.text.text) == 1) @@ -1913,7 +1916,7 @@ static s32 start(s32 argc, char **argv, const char* folder) SDL_Log("Unable to initialize SDL Game Controller: %i, %s\n", result, SDL_GetError()); } - platform.studio = studio_create(argc, argv, TIC80_SAMPLERATE, SCREEN_FORMAT, folder, determineMaximumScale(), is_french_keyboard()); + platform.studio = studio_create(argc, argv, TIC80_SAMPLERATE, SCREEN_FORMAT, folder, determineMaximumScale(), detect_keyboard_layout()); SCOPE(studio_delete(platform.studio)) { From e7af6b6e9e4b48c3434840eeb0eda5f1d6d71e4c Mon Sep 17 00:00:00 2001 From: alice Date: Sun, 25 Aug 2024 20:56:57 +0100 Subject: [PATCH 4/4] Unbreak other platforms --- src/system/baremetalpi/kernel.cpp | 4 ++-- src/system/n3ds/main.c | 2 +- src/system/sdl/main.c | 3 ++- src/system/sokol/sokol.c | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/system/baremetalpi/kernel.cpp b/src/system/baremetalpi/kernel.cpp index abc181b8c..0f6f96c32 100644 --- a/src/system/baremetalpi/kernel.cpp +++ b/src/system/baremetalpi/kernel.cpp @@ -392,7 +392,7 @@ TShutdownMode Run(void) char* argv[] = { &arg0[0], NULL }; int argc = 1; malloc(88); - platform.studio = studio_create(argc, argv, 44100, TIC80_PIXEL_COLOR_BGRA8888, "tic80", INT32_MAX); + platform.studio = studio_create(argc, argv, 44100, TIC80_PIXEL_COLOR_BGRA8888, "tic80", INT32_MAX, "qwerty"); malloc(99); } @@ -404,7 +404,7 @@ TShutdownMode Run(void) char* argv[] = { &arg0[0], &arg1[0], NULL }; int argc = 2; dbg("Without keyboard\n"); - platform.studio = studio_create(argc, argv, 44100, TIC80_PIXEL_COLOR_BGRA8888, "tic80", INT32_MAX); + platform.studio = studio_create(argc, argv, 44100, TIC80_PIXEL_COLOR_BGRA8888, "tic80", INT32_MAX, "qwerty"); } dbg("studio_create OK\n"); diff --git a/src/system/n3ds/main.c b/src/system/n3ds/main.c index 3b51f122e..45f4def3d 100644 --- a/src/system/n3ds/main.c +++ b/src/system/n3ds/main.c @@ -580,7 +580,7 @@ int main(int argc, char **argv) { n3ds_draw_init(); n3ds_keyboard_init(&platform.keyboard); - platform.studio = studio_create(argc_used, argv_used, AUDIO_FREQ, TIC80_PIXEL_COLOR_ABGR8888, "./", INT32_MAX); + platform.studio = studio_create(argc_used, argv_used, AUDIO_FREQ, TIC80_PIXEL_COLOR_ABGR8888, "./", INT32_MAX, "qwerty"); n3ds_sound_init(AUDIO_FREQ); diff --git a/src/system/sdl/main.c b/src/system/sdl/main.c index 37f9af5d7..095cd9ea9 100644 --- a/src/system/sdl/main.c +++ b/src/system/sdl/main.c @@ -1062,7 +1062,8 @@ static void handleKeydown(SDL_Keycode keycode, bool down, bool* state, bool* pre #endif } -char* detect_keyboard_layout() { +char* detect_keyboard_layout() +{ char q = SDL_GetKeyFromScancode(SDL_SCANCODE_Q); char w = SDL_GetKeyFromScancode(SDL_SCANCODE_W); char y = SDL_GetKeyFromScancode(SDL_SCANCODE_Y); diff --git a/src/system/sokol/sokol.c b/src/system/sokol/sokol.c index b89345b9b..66b962839 100644 --- a/src/system/sokol/sokol.c +++ b/src/system/sokol/sokol.c @@ -414,7 +414,7 @@ sapp_desc sokol_main(s32 argc, char* argv[]) platform.audio.desc.num_channels = TIC80_SAMPLE_CHANNELS; saudio_setup(&platform.audio.desc); - platform.studio = studio_create(argc, argv, saudio_sample_rate(), TIC80_PIXEL_COLOR_RGBA8888, "./", INT32_MAX); + platform.studio = studio_create(argc, argv, saudio_sample_rate(), TIC80_PIXEL_COLOR_RGBA8888, "./", INT32_MAX, "qwerty"); if(studio_config(platform.studio)->cli) {