From dcee4b09ea16d9f8aa8d941bbf14c99293f55dfd Mon Sep 17 00:00:00 2001 From: Antoine Bache Date: Thu, 17 Aug 2017 23:29:00 +0200 Subject: [PATCH] Menu is now fully in assembly + a small C-wrapper for readdir --- include/cdefs.h | 9 +++++ src/menu.asm | 99 +++++++++++++++++++++++++++++++++++++++++++++++-- src/menu_c.c | 62 +++++-------------------------- 3 files changed, 115 insertions(+), 55 deletions(-) diff --git a/include/cdefs.h b/include/cdefs.h index 7ecac2b..b051c29 100644 --- a/include/cdefs.h +++ b/include/cdefs.h @@ -35,6 +35,11 @@ SDL_Event game_events __asm__("game_events"); typedef struct wolfasm_weapon_s wolfasm_weapon_t; +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + // Player informations struct wolfasm_player { double pos_x, pos_y; @@ -56,6 +61,10 @@ typedef struct wolfasm_map_case { } wolfasm_map_case_t; _Static_assert(sizeof(wolfasm_map_case_t) == 32, "Invalid map case size"); +#if defined __clang__ +#pragma clang diagnostic pop +#endif + // Window informations extern SDL_Window *window_ptr __asm__("window_ptr"); extern SDL_Surface *window_surface __asm__("window_surface"); diff --git a/src/menu.asm b/src/menu.asm index de13dad..1a5eb58 100644 --- a/src/menu.asm +++ b/src/menu.asm @@ -12,7 +12,10 @@ wolfasm_menu_event_key_up, wolfasm_menu_event_key_down, \ wolfasm_menu_event_key_left, \ wolfasm_menu_event_key_right, \ - wolfasm_menu_event_key_tab + wolfasm_menu_event_key_tab, \ + wolfasm_menu_event_key_enter, \ + wolfasm_menu_event_key_backspace, \ + wolfasm_menu_event_textinput extern gui_font, wolfasm_display_text, window_height, \ window_width, wolfasm, wolfasm_menu_play_music, \ @@ -28,10 +31,10 @@ ;; LibC functions extern _strncpy, _strncat, _snprintf, _strtol, _memset, \ _strlen, _printf, _exit, _opendir, _free, \ - _strdup, _closedir, _srand, _time + _strdup, _closedir, _srand, _time, _strlen ;; TODO: rm - global selected_text_field_max_len, selected_text_field_len, selected_text_field, wolfasm_connect, wolfasm_connect_len, wolfasm_port, wolfasm_port_len, callbacks_main_menu, menu, selected_button, wolfasm_menu_nb_buttons, running, callback_sm_solo, wolfasm_selected_map, callbacks_multiplayer_menu, callback_mp_co, callback_mp_host, callbacks, wolfasm_regulate_framerate, wolfasm_maps, wolfasm_nb_maps, wolfasm_load_maps, wolfasm_current_map + global selected_text_field, selected_text_field_len, selected_text_field_max_len extern _wolfasm_join_game, _wolfasm_host_game, _print_dir section .text @@ -1033,6 +1036,96 @@ wolfasm_menu_event_key_tab: pop rbp ret +wolfasm_menu_event_key_enter: + push rbp + mov rbp, rsp + + lea rdi, [rel callbacks] + mov eax, [rel menu] + mov rdi, [rdi + rax * 8] + mov eax, [rel selected_button] + mov rdi, [rdi + rax * 8] + call rdi + + mov rsp, rbp + pop rbp + ret + +wolfasm_menu_event_key_backspace: + push rbp + mov rbp, rsp + + cmp dword [rel menu], MENU_MULTIPLAYER_CONNECT + je .ok + cmp dword [rel menu], MENU_MULTIPLAYER_HOST + jne .end + +.ok: + mov rax, [rel selected_text_field_len] + cmp dword [rax], 0 + jle .end + + mov rdi, [rel selected_text_field] + mov dword r8d, [rax] + dec r8d + mov byte [rdi + r8], 0 + + mov edi, [eax] + dec edi + mov dword [rax], edi + +.end: + mov rsp, rbp + pop rbp + ret + +;; str in rdi +wolfasm_menu_event_textinput: + push rbp + mov rbp, rsp + + sub rsp, 8 + push rdi + + call _strlen + mov r10, [rel selected_text_field_len] + mov r8d, [r10] + add r8d, eax + + mov r9d, [rel selected_text_field_max_len] + sub r9d, 1 + + cmp r8d, r9d + jl .copy + + sub r9d, [r10] + mov eax, r9d +.copy: + cmp eax, 0 + jle .done + + push r10 + push rax + + mov rdi, [rel selected_text_field] + add rdi, [r10] + mov rsi, [rsp + 16] + mov edx, eax + call _strncpy + + pop rax + pop r10 + + add eax, [r10] + mov [r10], eax +.done: + pop rdi + add rsp, 8 + + mov rsp, rbp + pop rbp + ret + section .rodata ;; Text strings play_txt: db "Play", 0x00 diff --git a/src/menu_c.c b/src/menu_c.c index 809fbad..c44c349 100644 --- a/src/menu_c.c +++ b/src/menu_c.c @@ -1,27 +1,5 @@ #include "cdefs.h" -#include #include -#include - -enum wolfasm_menus { - MENU_MAIN, - MENU_MULTIPLAYER, - MENU_SELECT_MAP_SOLO, - MENU_MULTIPLAYER_CONNECT, - MENU_MULTIPLAYER_HOST, - NB_MENUS -}; - -// -// Menu -// -extern enum wolfasm_menus menu __asm__("menu"); -extern int32_t selected_button __asm__("selected_button"); - -extern int32_t - selected_text_field_max_len __asm__("selected_text_field_max_len"); -extern int32_t *selected_text_field_len __asm__("selected_text_field_len"); -extern char *selected_text_field __asm__("selected_text_field"); // Wrapper for struct dirent extern char const *wolfasm_read_dir(DIR *d) __asm__("wolfasm_read_dir"); @@ -34,8 +12,6 @@ char const *wolfasm_read_dir(DIR *d) { return NULL; } -extern void (**callbacks[])() __asm__("callbacks"); - // // Menu events // @@ -50,11 +26,17 @@ extern void wolfasm_menu_event_key_right(void) __asm__("wolfasm_menu_event_key_right"); extern void wolfasm_menu_event_key_tab(void) __asm__("wolfasm_menu_event_key_tab"); +extern void +wolfasm_menu_event_key_enter(void) __asm__("wolfasm_menu_event_key_enter"); +extern void wolfasm_menu_event_key_backspace(void) __asm__( + "wolfasm_menu_event_key_backspace"); +extern void wolfasm_menu_event_textinput(char const *) __asm__( + "wolfasm_menu_event_textinput"); extern void wolfasm_menu_events_cwrapper(void) __asm__("wolfasm_menu_events_cwrapper"); void wolfasm_menu_events_cwrapper(void) { - SDL_Event event = {}; + SDL_Event event; // Handle events while (SDL_PollEvent(&event)) { @@ -65,7 +47,6 @@ void wolfasm_menu_events_cwrapper(void) { case SDL_KEYDOWN: switch (event.key.keysym.sym) { - // Menu controls case SDLK_LEFT: wolfasm_menu_event_key_left(); @@ -80,47 +61,24 @@ void wolfasm_menu_events_cwrapper(void) { wolfasm_menu_event_key_down(); break; case SDLK_RETURN: - (callbacks[menu][selected_button])(); + wolfasm_menu_event_key_enter(); break; case SDLK_BACKSPACE: - if (menu == MENU_MULTIPLAYER_CONNECT || menu == MENU_MULTIPLAYER_HOST) { - assert(selected_text_field_len); - if (*selected_text_field_len > 0) { - selected_text_field[*selected_text_field_len - 1] = '\0'; - --(*selected_text_field_len); - } - } + wolfasm_menu_event_key_backspace(); break; case SDLK_TAB: wolfasm_menu_event_key_tab(); break; - case SDLK_ESCAPE: wolfasm_menu_event_quit(); break; - default: break; } break; case SDL_TEXTINPUT: - assert(selected_text_field_len); - assert(selected_text_field); - assert(menu == MENU_MULTIPLAYER_CONNECT || menu == MENU_MULTIPLAYER_HOST); - { - size_t const cur_len = strlen(event.text.text); - size_t real_len = cur_len; - if (*selected_text_field_len + cur_len >= - selected_text_field_max_len - 1) { - real_len = selected_text_field_max_len - 1 - *selected_text_field_len; - } - if (real_len) { - strncpy(selected_text_field + *selected_text_field_len, - event.text.text, real_len); - } - *selected_text_field_len += real_len; - } + wolfasm_menu_event_textinput(event.text.text); break; default: