233 lines
7.9 KiB
C
233 lines
7.9 KiB
C
/******
|
|
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);
|
|
}
|