From 1bed0732febd14fb0b85dbcd9699acb65a2b758e Mon Sep 17 00:00:00 2001 From: Antoine Bache Date: Thu, 17 Aug 2017 20:37:07 +0200 Subject: [PATCH] Menu almost over --- Makefile | 15 +++- src/main.asm | 7 +- src/menu.asm | 220 +++++++++++++++++++++++++++++++++++++++++++++++---- src/menu_c.c | 207 ++++++++++++++++++------------------------------ 4 files changed, 296 insertions(+), 153 deletions(-) diff --git a/Makefile b/Makefile index 4615a42..918e9ae 100644 --- a/Makefile +++ b/Makefile @@ -3,15 +3,26 @@ CC?= clang LD:= ld RM?= rm -f +DEBUG?= yes + NAME:= wolfasm SRC:= $(shell find -E ./src -regex '.*\.(asm|c)') -CFLAGS+= -I./include -Weverything -Wno-nonportable-system-include-path -O3 -g -ASFLAGS+= -f macho64 -I./include/ -O0 +CFLAGS+= -I./include -Weverything -Wno-nonportable-system-include-path \ + -march=native +ASFLAGS+= -f macho64 -I./include/ LDFLAGS+= -lc -ldylib1.o -dynamic -lSDL2 -lSDL2_ttf -lSDL2_Image -lSDL2_Mixer \ -macosx_version_min 10.12 +ifeq ($(DEBUG),yes) +CFLAGS+= -O0 -g +ASFLAGS+= -O0 -g +else +CFLAGS+= -O2 -fomit-frame-pointer +ASFLAGS+= -O2 +endif + OBJ_S:= $(SRC:%.asm=%.o) OBJ_C:= $(SRC:%.c=%.o) OBJ:= $(filter %.o, $(OBJ_C) $(OBJ_S)) diff --git a/src/main.asm b/src/main.asm index 888db86..f9f0012 100644 --- a/src/main.asm +++ b/src/main.asm @@ -6,10 +6,7 @@ extern _exit ;; Functions - extern wolfasm, wolfasm_init, wolfasm_deinit - - ;; TODO: rm - extern _wolfasm_menu + extern wolfasm, wolfasm_init, wolfasm_deinit, wolfasm_menu _main: push rbp @@ -17,7 +14,7 @@ _main: ;; Start the game call wolfasm_init - call _wolfasm_menu + call wolfasm_menu sub rsp, 8 push rax diff --git a/src/menu.asm b/src/menu.asm index 8409d13..de13dad 100644 --- a/src/menu.asm +++ b/src/menu.asm @@ -2,29 +2,93 @@ %include "sdl.inc" %include "menu.inc" + %include "sprite.inc" global wolfasm_menu_render_button, \ - wolfasm_regulate_framerate + wolfasm_regulate_framerate, wolfasm_menu + + ;; events + global wolfasm_menu_event_quit, \ + 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 extern gui_font, wolfasm_display_text, window_height, \ window_width, wolfasm, wolfasm_menu_play_music, \ - wolfasm_read_dir + wolfasm_read_dir, wolfasm_menu_events_cwrapper, \ + window_renderer, wolfasm_render_sprite, wolfasm_sprite ;; SDL functions extern _TTF_SetFontStyle, _Mix_HaltMusic, \ _SDL_StartTextInput, _SDL_StopTextInput, \ - _SDL_GetTicks, _SDL_Delay + _SDL_GetTicks, _SDL_Delay, _SDL_RenderClear, \ + _SDL_RenderPresent ;; LibC functions extern _strncpy, _strncat, _snprintf, _strtol, _memset, \ - _strlen, _printf, _exit, _opendir, _readdir, _free, \ - _strdup, _closedir + _strlen, _printf, _exit, _opendir, _free, \ + _strdup, _closedir, _srand, _time ;; 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 extern _wolfasm_join_game, _wolfasm_host_game, _print_dir section .text +wolfasm_menu: + push rbp + mov rbp, rsp + + ;; Update rand seed + xor rdi, rdi + call _time + mov rdi, rax + call _srand + + call wolfasm_menu_play_music + +.loop: + cmp byte [rel running], 0 + je .loop_end + + ;; Handle events + call wolfasm_menu_events_cwrapper + + ;; Update display + mov rdi, [rel window_renderer] + call _SDL_RenderClear + + ;; Display background + lea rdi, [rel wolfasm_sprite] + mov eax, wolfasm_sprite_s.size + mov ecx, 3 + mul ecx + lea rdi, [rdi + rax] + xor rsi, rsi + xor rdx, rdx + xor rcx, rcx + call wolfasm_render_sprite + + ;; Render buttons + lea rdi, [rel callbacks] + mov eax, [rel menu] + mov rdi, [rdi + rax * 8] + mov eax, [rel wolfasm_menu_nb_buttons] + mov rdi, [rdi + rax * 8] + call rdi + + mov rdi, [rel window_renderer] + call _SDL_RenderPresent + + call wolfasm_regulate_framerate + + jmp .loop +.loop_end: + + mov rsp, rbp + pop rbp + ret + wolfasm_regulate_framerate: push rbp mov rbp, rsp @@ -76,16 +140,6 @@ wolfasm_load_maps: cmp rax, 0 je .loop_end - push rdi - push rax - - mov rdi, found_str - mov rsi, rax - call _printf - - pop rax - pop rdi - cmp byte [rax], '.' je .next_loop @@ -843,11 +897,143 @@ wolfasm_multiplayer_host_buttons: pop rbp ret + ;; + ;; Menu events + ;; +wolfasm_menu_event_quit: + push rbp + mov rbp, rsp + + mov byte [rel running], 0 + + mov rsp, rbp + pop rbp + ret + +wolfasm_menu_event_key_up: + push rbp + mov rbp, rsp + + mov eax, [rel selected_button] + cmp eax, 0 + jne .end_button + mov eax, [rel wolfasm_menu_nb_buttons] +.end_button: + dec eax + mov dword [rel selected_button], eax + + mov rsp, rbp + pop rbp + ret + +wolfasm_menu_event_key_down: + push rbp + mov rbp, rsp + + mov eax, [rel selected_button] + inc eax + cmp eax, [rel wolfasm_menu_nb_buttons] + jne .end_button + xor eax, eax +.end_button: + mov dword [rel selected_button], eax + + mov rsp, rbp + pop rbp + ret + +wolfasm_menu_event_key_left: + push rbp + mov rbp, rsp + + mov eax, [rel menu] + cmp eax, MENU_SELECT_MAP_SOLO + je .ok + + cmp eax, MENU_MULTIPLAYER_HOST + jne .end + +.ok: + mov eax, [rel wolfasm_current_map] + dec eax + cmp eax, 0 + jge .store + + mov eax, [rel wolfasm_nb_maps] + dec eax + +.store: + mov dword [rel wolfasm_current_map], eax + lea rdi, [rel wolfasm_maps] + mov rax, [rdi + rax * 8] + mov qword [rel wolfasm_selected_map], rax +.end: + mov rsp, rbp + pop rbp + ret + +wolfasm_menu_event_key_right: + push rbp + mov rbp, rsp + + mov eax, [rel menu] + cmp eax, MENU_SELECT_MAP_SOLO + je .ok + + cmp eax, MENU_MULTIPLAYER_HOST + jne .end + +.ok: + mov eax, [rel wolfasm_current_map] + inc eax + cmp eax, [rel wolfasm_nb_maps] + jl .store + + xor eax, eax +.store: + mov dword [rel wolfasm_current_map], eax + lea rdi, [rel wolfasm_maps] + mov rax, [rdi + rax * 8] + mov qword [rel wolfasm_selected_map], rax +.end: + + mov rsp, rbp + pop rbp + ret + +wolfasm_menu_event_key_tab: + push rbp + mov rbp, rsp + + mov eax, [rel menu] + cmp eax, MENU_MULTIPLAYER_CONNECT + jne .end + + mov rax, [rel selected_text_field] + lea rdi, [rel wolfasm_connect] + cmp rax, rdi + jne .turn_to_connect + +.turn_to_port: + lea rax, [rel wolfasm_port] + mov qword [rel selected_text_field], rax + mov dword [rel selected_text_field_max_len], 6 + lea rax, [rel wolfasm_port_len] + mov qword [rel selected_text_field_len], rax + jmp .end +.turn_to_connect: + lea rax, [rel wolfasm_connect] + mov qword [rel selected_text_field], rax + mov dword [rel selected_text_field_max_len], 255 + lea rax, [rel wolfasm_connect_len] + mov qword [rel selected_text_field_len], rax +.end: + mov rsp, rbp + pop rbp + ret section .rodata - ;; TODO: rm - found_str: db "Found %s", 0x0A, 0x00 ;; Text strings play_txt: db "Play", 0x00 multiplayer_txt: db "Multiplayer", 0x00 diff --git a/src/menu_c.c b/src/menu_c.c index 941645a..809fbad 100644 --- a/src/menu_c.c +++ b/src/menu_c.c @@ -3,12 +3,6 @@ #include #include -extern void render_sprite(wolfasm_sprite_t *sprite, int x, int y, - SDL_Rect *clip) __asm__("wolfasm_render_sprite"); -extern void wolfasm_menu_play_music(void) __asm__("wolfasm_menu_play_music"); -extern void -wolfasm_regulate_framerate(void) __asm__("wolfasm_regulate_framerate"); - enum wolfasm_menus { MENU_MAIN, MENU_MULTIPLAYER, @@ -21,22 +15,9 @@ enum wolfasm_menus { // // Menu // -extern bool running __asm__("running"); extern enum wolfasm_menus menu __asm__("menu"); -extern int32_t wolfasm_menu_nb_buttons __asm__("wolfasm_menu_nb_buttons"); extern int32_t selected_button __asm__("selected_button"); -extern char const *wolfasm_selected_map __asm__("wolfasm_selected_map"); -extern char const *wolfasm_maps[255] __asm__("wolfasm_maps"); -extern int32_t wolfasm_current_map __asm__("wolfasm_current_map"); -extern int32_t wolfasm_nb_maps __asm__("wolfasm_nb_maps"); - -extern char wolfasm_connect[255] __asm__("wolfasm_connect"); -extern int32_t wolfasm_connect_len __asm__("wolfasm_connect_len"); - -extern char wolfasm_port[sizeof("65535")] __asm__("wolfasm_port"); -extern int32_t wolfasm_port_len __asm__("wolfasm_port_len"); - 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"); @@ -53,129 +34,97 @@ char const *wolfasm_read_dir(DIR *d) { return NULL; } -// Main Menu extern void (**callbacks[])() __asm__("callbacks"); -int wolfasm_menu(void) { - srand((unsigned int)time(NULL)); - wolfasm_menu_play_music(); - while (running) { - SDL_Event event = {}; +// +// Menu events +// +extern void wolfasm_menu_event_quit(void) __asm__("wolfasm_menu_event_quit"); +extern void +wolfasm_menu_event_key_down(void) __asm__("wolfasm_menu_event_key_down"); +extern void +wolfasm_menu_event_key_up(void) __asm__("wolfasm_menu_event_key_up"); +extern void +wolfasm_menu_event_key_left(void) __asm__("wolfasm_menu_event_key_left"); +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"); - // Handle events - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_QUIT: - running = false; +extern void +wolfasm_menu_events_cwrapper(void) __asm__("wolfasm_menu_events_cwrapper"); +void wolfasm_menu_events_cwrapper(void) { + SDL_Event event = {}; + + // Handle events + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + wolfasm_menu_event_quit(); + break; + + case SDL_KEYDOWN: + switch (event.key.keysym.sym) { + + // Menu controls + case SDLK_LEFT: + wolfasm_menu_event_key_left(); break; - - case SDL_KEYDOWN: - switch (event.key.keysym.sym) { - - // Menu controls - case SDLK_LEFT: - if (menu == MENU_SELECT_MAP_SOLO || menu == MENU_MULTIPLAYER_HOST) { - --wolfasm_current_map; - if (wolfasm_current_map < 0) { - assert(wolfasm_nb_maps != 0); - wolfasm_current_map = wolfasm_nb_maps - 1; - } - wolfasm_selected_map = wolfasm_maps[wolfasm_current_map]; - } - break; - case SDLK_RIGHT: - if (menu == MENU_SELECT_MAP_SOLO || menu == MENU_MULTIPLAYER_HOST) { - ++wolfasm_current_map; - if (wolfasm_current_map == wolfasm_nb_maps) { - wolfasm_current_map = 0; - } - wolfasm_selected_map = wolfasm_maps[wolfasm_current_map]; - } - break; - case SDLK_UP: - if (selected_button == 0) { - selected_button = wolfasm_menu_nb_buttons - 1; - } else { - --selected_button; - } - break; - case SDLK_DOWN: - ++selected_button; - if (selected_button == wolfasm_menu_nb_buttons) { - selected_button = 0; - } - break; - case SDLK_RETURN: - (callbacks[menu][selected_button])(); - 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); - } - } - break; - case SDLK_TAB: - if (menu == MENU_MULTIPLAYER_CONNECT) { - if (selected_text_field == wolfasm_connect) { - selected_text_field = wolfasm_port; - selected_text_field_max_len = sizeof(wolfasm_port); - selected_text_field_len = &wolfasm_port_len; - } else { - selected_text_field = wolfasm_connect; - selected_text_field_max_len = sizeof(wolfasm_connect); - selected_text_field_len = &wolfasm_connect_len; - } + case SDLK_RIGHT: + wolfasm_menu_event_key_right(); + break; + case SDLK_UP: + wolfasm_menu_event_key_up(); + break; + case SDLK_DOWN: + wolfasm_menu_event_key_down(); + break; + case SDLK_RETURN: + (callbacks[menu][selected_button])(); + 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); } - break; - - case SDLK_ESCAPE: - running = false; - break; - - default: - break; } break; + case SDLK_TAB: + wolfasm_menu_event_key_tab(); + 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; - } + case SDLK_ESCAPE: + wolfasm_menu_event_quit(); break; default: break; } - } - - // Display Menu - SDL_RenderClear(window_renderer); - render_sprite(&wolfasm_sprite[3], 0, 0, NULL); - - // Render buttons - (callbacks[menu][wolfasm_menu_nb_buttons])(); + 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; + } + break; - SDL_RenderPresent(window_renderer); - wolfasm_regulate_framerate(); + default: + break; + } } - return EXIT_SUCCESS; }