/****** State entry for the main menu ******/ #include "state_menu.h" /* allocate memory for menu */ void initMenuState() { s_menu_elements = newElementList(); s_menu_elements->user = g_screen; s_active_element = NULL; s_submenu_elements = newElementList(); s_submenu_elements->user = g_screen; s_focus_elements = s_menu_elements; s_quit_message = NULL; s_quit_yes = NULL; s_quit_no = NULL; s_settings_message = NULL; struct Dimension dimen = { 0, 0, 128, 32}; struct Element *element = newElement(E_TYPE_BUTTON, 0, g_r_setupElement, dimen); element->sx = 0.05f; element->sy = 0.5f; setElementFont(element, g_font_large); setElementText(element, "START GAME LONG BUTTON"); setElementKey(element, 13, 0); addElementToList(s_menu_elements, element); element = newElement(E_TYPE_BUTTON, 0, g_r_setupElement, dimen); element->sx = 0.05f; element->sy = 1.0f; setElementFont(element, g_font_large); setElementText(element, "SETTINGS"); setElementEvent(element, E_EVENT_ACTIVE, &showMenuSettings); setElementKey(element, 'S', 0); addElementToList(s_menu_elements, element); element = newElement(E_TYPE_BUTTON, 0, g_r_setupElement, dimen); element->sx = 0.05f; element->sy = 1.5f; setElementFont(element, g_font_large); setElementText(element, "QUIT"); setElementKey(element, 'Q', 0); setElementEvent(element, E_EVENT_ACTIVE, &showMenuQuit); addElementToList(s_menu_elements, element); s_bg_offset = 0; } /* free memory for menu */ void freeMenuState() { freeElementList(s_menu_elements); } void processMenuState(int delta) { s_bg_offset -= 0.25; if (s_bg_offset < -1280) s_bg_offset = 0; } void renderMenuState() { g_renderSprite(menu_bg, g_screen, 0, s_bg_offset, 0); g_renderElements(s_focus_elements); } /* handles events */ void handleMenuState(struct TSEvent event) { int x, y; struct Element *current; struct Element *next; switch(event.type) { case TS_KEYBOARD: handleMenuKeyInput(event.keyboard); break; case TS_MOUSECLICK: switch(event.mouseclick.state) { case 0: // mouse up if (s_active_element != NULL) { x = getElementX(s_active_element); y = getElementY(s_active_element); if (x <= event.mouseclick.x && x+s_active_element->dimen.w >= event.mouseclick.x) { if (y <= event.mouseclick.y && y+s_active_element->dimen.h >= event.mouseclick.y) { printf("activate callback here :3\n"); if (s_active_element->onEvent[E_EVENT_ACTIVE] != NULL) { s_active_element->onEvent[E_EVENT_ACTIVE](s_active_element); } } } if (s_active_element != NULL) { s_active_element->state = E_STATE_NORMAL; s_active_element->flags |= E_FLAG_UPDATE; s_active_element = NULL; } } break; case 1: // mouse down current = s_focus_elements->last; while(current) { next = current->prev; x = getElementX(current); y = getElementY(current); if (x <= event.mouseclick.x && current->dimen.w+x >= event.mouseclick.x) { if (y <= event.mouseclick.y && current->dimen.h+y >= event.mouseclick.y) { current->state = E_STATE_ACTIVE; current->flags |= E_FLAG_UPDATE; s_active_element = current; break; } } current = next; } break; } printf("button: %d, state: %d, x: %d, y: %d\n", event.mouseclick.button, event.mouseclick.state, event.mouseclick.x, event.mouseclick.y); break; default: break; } } void handleMenuKeyInput(struct TSEvent_Keyboard key_event) { if (key_event.key.mod & KMOD_CTRL) { if (key_event.key.sym == 113) g_running = 0; } if (key_event.key.mod & KMOD_SHIFT) { printf("shift is held\n"); } // TODO: if not in some sort of text area // TODO: we need to operate on the top-level of elements so shortcuts don't interfere with eachother // TODO: elements should have multiple shortcut keys struct Element *current = s_focus_elements->first; while(current != NULL) { struct Element *next = current->next; if (current->key == key_event.key.unicode) { if (current->onEvent[E_EVENT_ACTIVE] != NULL) { current->onEvent[E_EVENT_ACTIVE](current); } break; } current = next; } printf("state is %d, scan is %d, sym is %d(%c), and unicode is %d(%c)\n", key_event.state, key_event.key.scancode, key_event.key.sym, key_event.key.sym, key_event.key.unicode, key_event.key.unicode); }; void showMenuQuit(struct Element *element) { if (s_quit_message != NULL) return; // already displayed, return s_focus_elements = s_submenu_elements; struct Dimension dimen = { 0, 0, 128, 32 }; s_quit_message = newElement(E_TYPE_TEXT, 1, g_r_setupElement, dimen); setElementText(s_quit_message, "You really wanna quit?"); setElementFont(s_quit_message, g_font_large); s_quit_message->dimen.x = g_video_width/2 - (s_quit_message->dimen.w/2); s_quit_message->sy = 1.0f; //s_quit_message->sx = 0.15f; addElementToList(s_submenu_elements, s_quit_message); s_quit_yes = newElement(E_TYPE_BUTTON, 2, g_r_setupElement, dimen); setElementText(s_quit_yes, "YEA"); setElementFont(s_quit_yes, g_font_medium); setElementEvent(s_quit_yes, E_EVENT_ACTIVE, stopRunning); setElementKey(s_quit_yes, 'y', 0); s_quit_yes->dimen.x = g_video_width/2; s_quit_yes->sy = 1.5f; //s_quit_yes->sx = 0.25f; addElementToList(s_submenu_elements, s_quit_yes); s_quit_no = newElement(E_TYPE_BUTTON, 3, g_r_setupElement, dimen); setElementText(s_quit_no, "NAE"); setElementFont(s_quit_no, g_font_medium); setElementEvent(s_quit_no, E_EVENT_ACTIVE, closeMenuQuit); setElementKey(s_quit_no, 'n', 0); s_quit_no->dimen.x = g_video_width/2 - (s_quit_no->dimen.w); s_quit_no->sy = 1.5f; //s_quit_no->sx = 1.25f; addElementToList(s_submenu_elements, s_quit_no); } void closeMenuQuit(struct Element *element) { freeElementsFromList(s_submenu_elements); s_focus_elements = s_menu_elements; s_quit_message = NULL; } void showMenuSettings(struct Element *element) { if (s_settings_message != NULL) return; // already displayed, return s_focus_elements = s_submenu_elements; struct Dimension dimen = { 0, 0, 128, 32 }; s_settings_message = newElement(E_TYPE_TEXT, 1, g_r_setupElement, dimen); setElementText(s_settings_message, "Settings"); setElementFont(s_settings_message, g_font_large); s_settings_message->dimen.x = g_video_width/2 - (s_settings_message->dimen.w/2); s_settings_message->sy = 0.10f; //s_settings_message->sx = 0.15f; addElementToList(s_submenu_elements, s_settings_message); s_settings_ok = newElement(E_TYPE_BUTTON, 2, g_r_setupElement, dimen); setElementText(s_settings_ok, "Ok"); setElementFont(s_settings_ok, g_font_large); s_settings_ok->sy = 3.00f; s_settings_ok->dimen.y = -s_settings_ok->dimen.h; s_settings_ok->dimen.x = g_video_width/2; setElementEvent(s_settings_ok, E_EVENT_ACTIVE, saveMenuSettings); addElementToList(s_submenu_elements, s_settings_ok); s_settings_cancel = newElement(E_TYPE_BUTTON, 2, g_r_setupElement, dimen); setElementText(s_settings_cancel, "Cancel"); setElementFont(s_settings_cancel, g_font_large); s_settings_cancel->sy = 3.00f; s_settings_cancel->dimen.y = -s_settings_cancel->dimen.h; s_settings_cancel->dimen.x = g_video_width/2 - s_settings_ok->dimen.w; setElementEvent(s_settings_cancel, E_EVENT_ACTIVE, closeMenuSettings); addElementToList(s_submenu_elements, s_settings_cancel); } void closeMenuSettings(struct Element *element) { freeElementsFromList(s_submenu_elements); s_settings_message = NULL; s_focus_elements = s_menu_elements; } void saveMenuSettings(struct Element *element) { printf("Saving\n"); closeMenuSettings(element); }