/*\r
- * (C) Gražvydas "notaz" Ignotas, 2006-2010\r
+ * (C) Gražvydas "notaz" Ignotas, 2006-2011\r
*\r
* This work is licensed under the terms of any of these licenses\r
* (at your option):\r
#include <string.h>\r
#include <stdlib.h>\r
#include <stdarg.h>\r
+#include <time.h>\r
\r
#include "menu.h"\r
#include "fonts.h"\r
return ret;\r
}\r
\r
+static unsigned int me_read_onoff(const menu_entry *ent)\r
+{\r
+ // guess var size based on mask to avoid reading too much\r
+ if (ent->mask & 0xffff0000)\r
+ return *(unsigned int *)ent->var & ent->mask;\r
+ else if (ent->mask & 0xff00)\r
+ return *(unsigned short *)ent->var & ent->mask;\r
+ else\r
+ return *(unsigned char *)ent->var & ent->mask;\r
+}\r
+\r
+static void me_toggle_onoff(menu_entry *ent)\r
+{\r
+ // guess var size based on mask to avoid reading too much\r
+ if (ent->mask & 0xffff0000)\r
+ *(unsigned int *)ent->var ^= ent->mask;\r
+ else if (ent->mask & 0xff00)\r
+ *(unsigned short *)ent->var ^= ent->mask;\r
+ else\r
+ *(unsigned char *)ent->var ^= ent->mask;\r
+}\r
+\r
static void me_draw(const menu_entry *entries, int sel, void (*draw_more)(void))\r
{\r
const menu_entry *ent, *ent_sel = entries;\r
for (ent = entries; ent->name; ent++)\r
{\r
const char **names;\r
- int len;\r
+ int len, leftname_end = 0;\r
\r
if (!ent->enabled)\r
continue;\r
if (ent->generate_name)\r
name = ent->generate_name(ent->id, &offs);\r
}\r
- if (name != NULL)\r
+ if (name != NULL) {\r
text_out16(x, y, name);\r
+ leftname_end = x + (strlen(name) + 1) * me_mfont_w;\r
+ }\r
\r
switch (ent->beh) {\r
case MB_NONE:\r
break;\r
case MB_OPT_ONOFF:\r
- text_out16(x + col2_offs, y, (*(int *)ent->var & ent->mask) ? "ON" : "OFF");\r
+ text_out16(x + col2_offs, y, me_read_onoff(ent) ? "ON" : "OFF");\r
break;\r
case MB_OPT_RANGE:\r
text_out16(x + col2_offs, y, "%i", *(int *)ent->var);\r
break;\r
case MB_OPT_ENUM:\r
names = (const char **)ent->data;\r
- offs = 0;\r
for (i = 0; names[i] != NULL; i++) {\r
+ offs = x + col2_offs;\r
len = strlen(names[i]);\r
if (len > 10)\r
- offs = 10 - len - 2;\r
+ offs += (10 - len - 2) * me_mfont_w;\r
+ if (offs < leftname_end)\r
+ offs = leftname_end;\r
if (i == *(unsigned char *)ent->var) {\r
- text_out16(x + col2_offs + offs * me_mfont_w, y, "%s", names[i]);\r
+ text_out16(offs, y, "%s", names[i]);\r
break;\r
}\r
}\r
{\r
case MB_OPT_ONOFF:\r
case MB_OPT_CUSTONOFF:\r
- *(int *)entry->var ^= entry->mask;\r
+ me_toggle_onoff(entry);\r
return 1;\r
case MB_OPT_RANGE:\r
case MB_OPT_CUSTRANGE:\r
\r
static void debug_menu_loop(void);\r
\r
-static void me_loop(menu_entry *menu, int *menu_sel, void (*draw_more)(void))\r
+static int me_loop_d(menu_entry *menu, int *menu_sel, void (*draw_prep)(void), void (*draw_more)(void))\r
{\r
- int ret, inp, sel = *menu_sel, menu_sel_max;\r
+ int ret = 0, inp, sel = *menu_sel, menu_sel_max;\r
\r
menu_sel_max = me_count(menu) - 1;\r
if (menu_sel_max < 0) {\r
lprintf("no enabled menu entries\n");\r
- return;\r
+ return 0;\r
}\r
\r
while ((!menu[sel].enabled || !menu[sel].selectable) && sel < menu_sel_max)\r
\r
for (;;)\r
{\r
+ if (draw_prep != NULL)\r
+ draw_prep();\r
+\r
me_draw(menu, sel, draw_more);\r
inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|\r
PBTN_MOK|PBTN_MBACK|PBTN_MENU|PBTN_L|PBTN_R, 70);\r
}\r
}\r
*menu_sel = sel;\r
+\r
+ return ret;\r
+}\r
+\r
+static int me_loop(menu_entry *menu, int *menu_sel)\r
+{\r
+ return me_loop_d(menu, menu_sel, NULL, NULL);\r
}\r
\r
/* ***************************************** */\r
\r
// ------------ savestate loader ------------\r
\r
+#define STATE_SLOT_COUNT 10\r
+\r
static int state_slot_flags = 0;\r
+static int state_slot_times[STATE_SLOT_COUNT];\r
\r
static void state_check_slots(void)\r
{\r
\r
state_slot_flags = 0;\r
\r
- for (slot = 0; slot < 10; slot++) {\r
- if (emu_check_save_file(slot))\r
+ for (slot = 0; slot < STATE_SLOT_COUNT; slot++) {\r
+ state_slot_times[slot] = 0;\r
+ if (emu_check_save_file(slot, &state_slot_times[slot]))\r
state_slot_flags |= 1 << slot;\r
}\r
}\r
static void draw_savestate_menu(int menu_sel, int is_loading)\r
{\r
int i, x, y, w, h;\r
+ char time_buf[32];\r
\r
if (state_slot_flags & (1 << menu_sel))\r
draw_savestate_bg(menu_sel);\r
\r
w = (13 + 2) * me_mfont_w;\r
- h = (1+2+10+1) * me_mfont_h;\r
+ h = (1+2+STATE_SLOT_COUNT+1) * me_mfont_h;\r
x = g_menuscreen_w / 2 - w / 2;\r
if (x < 0) x = 0;\r
y = g_menuscreen_h / 2 - h / 2;\r
text_out16(x, y, is_loading ? "Load state" : "Save state");\r
y += 3 * me_mfont_h;\r
\r
- menu_draw_selection(x - me_mfont_w * 2, y + menu_sel * me_mfont_h, (13 + 2) * me_mfont_w + 4);\r
+ menu_draw_selection(x - me_mfont_w * 2, y + menu_sel * me_mfont_h, (23 + 2) * me_mfont_w + 4);\r
\r
- /* draw all 10 slots */\r
- for (i = 0; i < 10; i++, y += me_mfont_h)\r
+ /* draw all slots */\r
+ for (i = 0; i < STATE_SLOT_COUNT; i++, y += me_mfont_h)\r
{\r
- text_out16(x, y, "SLOT %i (%s)", i, (state_slot_flags & (1 << i)) ? "USED" : "free");\r
+ if (!(state_slot_flags & (1 << i)))\r
+ strcpy(time_buf, "free");\r
+ else {\r
+ strcpy(time_buf, "USED");\r
+ if (state_slot_times[i] != 0) {\r
+ time_t time = state_slot_times[i];\r
+ struct tm *t = localtime(&time);\r
+ strftime(time_buf, sizeof(time_buf), "%x %R", t);\r
+ }\r
+ }\r
+\r
+ text_out16(x, y, "SLOT %i (%s)", i, time_buf);\r
}\r
text_out16(x, y, "back");\r
\r
\r
static int menu_loop_savestate(int is_loading)\r
{\r
- static int menu_sel = 10;\r
- int menu_sel_max = 10;\r
+ static int menu_sel = STATE_SLOT_COUNT;\r
+ int menu_sel_max = STATE_SLOT_COUNT;\r
unsigned long inp = 0;\r
int ret = 0;\r
\r
} while (!(state_slot_flags & (1 << menu_sel)) && menu_sel != menu_sel_max && is_loading);\r
}\r
if (inp & PBTN_MOK) { // save/load\r
- if (menu_sel < 10) {\r
+ if (menu_sel < STATE_SLOT_COUNT) {\r
state_slot = menu_sel;\r
if (emu_save_load_game(is_loading, 0)) {\r
me_update_msg(is_loading ? "Load failed" : "Save failed");\r