#include "ncdz.h"

#define NORMAL_COLOR	MAKECOL15(200,200,200)
#define SELECT_COLOR	MAKECOL15(255,255,255)
#define INFOBAR_COLOR 	MAKECOL15(200,200,255)

#define SHADOW_LEVEL	4

static int state_loaded;

static const int keycfg_button_map[13] =
{
	0,
	PSP_CTRL_UP,
	PSP_CTRL_DOWN,
	PSP_CTRL_LEFT,
	PSP_CTRL_RIGHT,
	PSP_CTRL_CIRCLE,
	PSP_CTRL_CROSS,
	PSP_CTRL_SQUARE,
	PSP_CTRL_TRIANGLE,
	PSP_CTRL_LTRIGGER,
	PSP_CTRL_RTRIGGER,
	PSP_CTRL_START,
	PSP_CTRL_SELECT
};

static const char *keycfg_button_name[13] =
{
	"Not use",
	"\x01",
	"\x02",
	"\x03",
	"\x04",
	"\x05",
	"\x06",
	"\x07",
	"\x08",
	"L TRIGGER",
	"R TRIGGER",
	"START",
	"SELECT"
};

typedef struct {
	const char label[64];
	int	type;
	int	code;
} keycfg_menu_t;


#define KEYCFG_MENU_ITEMS 34
keycfg_menu_t keycfg_menu[KEYCFG_MENU_ITEMS] =
{
	{ "\x01", 1, P1_UP },
	{ "\x02", 1, P1_DOWN },
	{ "\x03", 1, P1_LEFT },
	{ "\x04", 1, P1_RIGHT },
	{ "Button A",  1, P1_BUTTONA },
	{ "Button B",  1, P1_BUTTONB },
	{ "Button C",  1, P1_BUTTONC },
	{ "Button D",  1, P1_BUTTOND },
	{ "Start",  1, P1_START },
	{ "Select",  1, P1_SELECT },
	{ "\n", },

	{ "Autofire A",  1, P1_AF_A },
	{ "Autofire B",  1, P1_AF_B },
	{ "Autofire C",  1, P1_AF_C },
	{ "Autofire D",  1, P1_AF_D },
	{ "Autofire Interval",  2, 0 },
	{ "\n", },

	{ "Hotkey A+B",  1, P1_AB },
	{ "Hotkey A+C",  1, P1_AC },
	{ "Hotkey A+D",  1, P1_AD },
	{ "Hotkey B+C",  1, P1_BC },
	{ "Hotkey B+D",  1, P1_BD },
	{ "Hotkey C+D",  1, P1_CD },
	{ "Hotkey A+B+C",  1, P1_ABC },
	{ "Hotkey A+B+D",  1, P1_ABD },
	{ "Hotkey A+C+D",  1, P1_ACD },
	{ "Hotkey B+C+D",  1, P1_BCD },
	{ "Hotkey A+B+C+D",  1, P1_ABCD },
	{ "\n", },

	{ "Show menu",  1, SHOWMENU },
	{ "Save snapshot",  1, SNAPSHOT },
	{ "Switch player",  1, SWPLAYER },
	{ "\n", },
	{ "Return to main menu", }
};

static int keycfg_value[KEYCFG_MENU_ITEMS];


static int menu_keycfg(void)
{
	int sel = 0, rows = 12, top = 0;
	int i, j, arrowl, arrowr;

	for (i = 0; i < KEYCFG_MENU_ITEMS; i++)
	{
		keycfg_value[i] = 0;

		if (keycfg_menu[i].type == 1)
		{
			int code = input_map[keycfg_menu[i].code];

			if (code)
			{
				for (j = 0; j < 13; j++)
				{
					if (code == keycfg_button_map[j])
					{
						keycfg_value[i] = j;
						break;
					}
				}
			}
		}
		else if (keycfg_menu[i].type == 2)
		{
			keycfg_value[i] = af_interval;
		}
	}

	pad_wait_clear();

	while (1)
	{
	  	show_background();

		if (pad_pressed_memory(PSP_CTRL_CIRCLE))
		{
			if (sel == KEYCFG_MENU_ITEMS - 1)
				break;
		}
		else if (pad_pressed_memory(PSP_CTRL_CROSS))
		{
			break;
		}
		else if (pad_pressed_memory(PSP_CTRL_UP))
		{
			sel--;
			if (keycfg_menu[sel].label[0] == '\n') sel--;
		}
		else if (pad_pressed_memory(PSP_CTRL_DOWN))
		{
			sel++;
			if (keycfg_menu[sel].label[0] == '\n') sel++;
		}
		else if (pad_pressed_memory(PSP_CTRL_LEFT))
		{
			if (keycfg_menu[sel].type)
			{
				if (keycfg_value[sel] - 1 >= 0)
					keycfg_value[sel]--;
			}
		}
		else if (pad_pressed_memory(PSP_CTRL_RIGHT))
		{
			if (keycfg_menu[sel].type == 1)
			{
				if (keycfg_value[sel] + 1 < 13)
					keycfg_value[sel]++;
			}
			else if (keycfg_menu[sel].type == 2)
			{
				if (keycfg_value[sel] + 1 < 11)
					keycfg_value[sel]++;
			}
		}

		if (top > KEYCFG_MENU_ITEMS - rows) top = KEYCFG_MENU_ITEMS - rows;
		if (top < 0) top = 0;
		if (sel >= KEYCFG_MENU_ITEMS) sel = 0;
		if (sel < 0) sel = KEYCFG_MENU_ITEMS - 1;
		if (sel >= top + rows) top = sel - rows + 1;
		if (sel < top) top = sel;

		small_icon_shadow(8, 24, INFOBAR_COLOR, ICON_S_KEYCONFIG, SHADOW_LEVEL);
		small_icon(8, 24, INFOBAR_COLOR, ICON_S_KEYCONFIG);
		font_print_shadow(36, 24, INFOBAR_COLOR, "Key configration menu", SHADOW_LEVEL);

		boxfill(0, 254, 479, 271, MAKECOL15(76,76,76));
		font_print_shadow(8, 252, MAKECOL15(220,220,220), " \x01\x02 Browse list   \x03\x04 Change value  \x06 Return to main menu", SHADOW_LEVEL);

		draw_scrollbar(470, 47, 479, 251, 16, KEYCFG_MENU_ITEMS, sel);

		arrowl = 0;
		arrowr = 0;
		if (keycfg_menu[sel].type)
		{
			if (keycfg_value[sel] > 0) arrowl = 1;
			if (keycfg_menu[sel].type == 1 && keycfg_value[sel] < 12) arrowr = 1;
			if (keycfg_menu[sel].type == 2 && keycfg_value[sel] < 10) arrowr = 1;
		}

		for (i = 0; i < rows; i++)
		{
			if ((top + i) >= KEYCFG_MENU_ITEMS) break;

			if (keycfg_menu[top + i].label[0] == '\n')
				continue;

			if ((top + i) == sel)
			{
				font_print_shadow(16, 50 + i * 16, SELECT_COLOR, keycfg_menu[top + i].label, SHADOW_LEVEL);
				if (arrowl) font_print_shadow(170 - 20, 50 + i * 16, SELECT_COLOR, "\x0b", SHADOW_LEVEL);
			}
			else
				font_print(16, 50 + i * 16, NORMAL_COLOR, keycfg_menu[top + i].label);

			if (keycfg_menu[top + i].type == 1)
			{
				if ((top + i) == sel)
				{
					font_print_shadow(170, 50 + i * 16, SELECT_COLOR, keycfg_button_name[keycfg_value[top + i]], SHADOW_LEVEL);
					if (arrowr) font_print_shadow(170 + font_get_string_width(keycfg_button_name[keycfg_value[top + i]]) + 4, 50 + i * 16, SELECT_COLOR, "\x0c", SHADOW_LEVEL);
				}
				else
					font_print(170, 50 + i * 16, NORMAL_COLOR, keycfg_button_name[keycfg_value[top + i]]);
			}
			else if (keycfg_menu[top + i].type == 2)
			{
				char s[8];

				if (keycfg_value[top + i] == 0)
					sprintf(s, "%d frame", keycfg_value[top + i] + 1);
				else
					sprintf(s, "%d frames", keycfg_value[top + i] + 1);

				if ((top + i) == sel)
				{
					font_print_shadow(170, 50 + i * 16, SELECT_COLOR, s, SHADOW_LEVEL);
					if (arrowr) font_print_shadow(170 + font_get_string_width(s) + 4, 50 + i * 16, SELECT_COLOR, "\x0c", SHADOW_LEVEL);
				}
				else
					font_print(170, 50 + i * 16, NORMAL_COLOR, s);
			}
		}

		draw_battery_status(1);
		video_flip_screen(1);
		pad_update();

		if (get_app_status()) break;
	}

	for (i = 0; i < KEYCFG_MENU_ITEMS; i++)
	{
		if (keycfg_menu[i].type == 1)
		{
			input_map[keycfg_menu[i].code] = keycfg_button_map[keycfg_value[i]];
		}
		else if (keycfg_menu[i].type == 2)
		{
			af_interval = keycfg_value[i];
		}
	}

	if (input_map[SHOWMENU] == 0)
		input_map[SHOWMENU] = PSP_CTRL_LTRIGGER;

	pad_wait_clear();

	return 0;
}


int menu_reset(void)
{
	boxfill_alpha(0, 0, 479, 271, 0, 16);

	draw_dialog(240-110+1, 136-32+1, 240+110-1, 136+32-1);
	font_print_shadow_center(136-26+1, MAKECOL15(255,255,127), "Reset NEOGEO emulation.", SHADOW_LEVEL);
	font_print_shadow_center(136+4+1, MAKECOL15(255,255,255), "\x05 to confirm, \x06 to cancel", SHADOW_LEVEL);

	video_flip_screen(1);

	pad_wait_clear();

	do
	{
		pad_update();

		if (pad_pressed_memory(PSP_CTRL_CIRCLE))
		{
			video_clear_screen();
			video_flip_screen(1);
			bLoop = LOOP_RESET;
			bSleep = 0;
			return 1;
		}

   	    if (get_app_status()) break;

	} while (!pad_pressed_memory(PSP_CTRL_CROSS));

	return 0;
}


int menu_restart(void)
{
	boxfill_alpha(0, 0, 479, 271, 0, 16);

	draw_dialog(240-110+1, 136-32+1, 240+110-1, 136+32-1);
	font_print_shadow_center(136-26+1, MAKECOL15(255,255,127), "Need to restart NEOGEO.", SHADOW_LEVEL);
	font_print_shadow_center(136+4+1, MAKECOL15(255,255,255), "Press \x05 button", SHADOW_LEVEL);

	video_flip_screen(1);

	pad_wait_clear();

	while (1)
	{
		pad_update();

		if (pad_pressed_memory(PSP_CTRL_CIRCLE))
		{
			video_clear_screen();
			video_flip_screen(1);
			bLoop = LOOP_RESTART;
			bSleep = 0;
			break;
		}

   	    if (get_app_status()) break;
	}

	return 1;
}


int menu_browser(void)
{
	bLoop = LOOP_BROWSER;
	bSleep = 0;
	return 1;
}

int menu_exit(void)
{
	bLoop = LOOP_EXIT;
	bSleep = 0;
	return 1;
}


typedef struct {
	const char label[32];
	int	*value;
	int flag;
	int old_value;
	int	value_max;
	char *values_label[32];
} gamecfg_t;


#define CFG_CONTINUE	0
#define CFG_RESTART		1
#define CFG_RESET		2

#define GAMECFG_MENU_ITEMS 24

gamecfg_t gamecfg_menu[GAMECFG_MENU_ITEMS] =
{
	{
		"Machine region", &neogeo_region, CFG_RESTART, 0,
		2, { "Japan", "USA", "Europe" }
	},
	{
		"Emulate load screen", &neogeo_loadscreen, CFG_RESTART, 0,
		1, { "No", "Yes" }
	},
	{"\n" },

	{
		"Render", &neogeo_blitter, CFG_CONTINUE, 0,
		3, { "1:1", "Zoom1", "Zoom2", "Full" }
	},
	{
		"Video sync", &neogeo_vsync, CFG_CONTINUE, 0,
		1, { "Off", "On" }
	},
	{
		"Auto frameskip", &neogeo_autoframeskip, CFG_CONTINUE, 0,
		1, { "Disable", "Enable" }
	},
	{
		"Auto frameskip limit", &neogeo_autoframeskip_limit, CFG_CONTINUE, 0,
		9, { "90%","91%","92%","93%","94%","95%","96%","97%","98%","99%" }
	},
	{
		"Frameskip", &neogeo_frameskip, CFG_CONTINUE, 0,
		11, { "0","1","2","3","4","5","6","7","8","9","10","11" }
	},
	{
		"Show FPS", &neogeo_showfps, CFG_CONTINUE, 0,
		1, { "Off", "On" }
	},
	{
		"60fps limit", &neogeo_speedlimit, CFG_CONTINUE, 0,
		1, { "Off","On" }
	},
	{
		"Cache clear timing", &neogeo_cacheclear, CFG_CONTINUE, 0,
		6,{"Not clear","Over 10frames","Over 20frames","Over 30frames","Over 40frames","Over 50frames","Over 60frames"}
	},
	{
		"Palette refresh type", &neogeo_paletterefresh, CFG_CONTINUE, 0,
		1, { "Clear all caches","Clear dirty palette only" }
	},
	{"\n" },

	{
		"Enable Sound", &neogeo_sound_enable, CFG_RESTART, 0,
		1, { "No","Yes" }
	},
	{
		"Sample Rate", &neogeo_samplerate, CFG_RESTART, 0,
		2, {"11025Hz","22050Hz","44100Hz"}
	},
	{
		"Sound Volume", &neogeo_sound_volume, CFG_CONTINUE, 0,
		10, {"0%","10%","20%","30%","40%","50%","60%","70%","80%","90%","100%"}
	},
	{
		"Enable CD-DA", &neogeo_cdda_enable, CFG_RESTART, 0,
		1, {"No","Yes"}
	},
	{
		"CDDA Volume", &neogeo_cdda_volume, CFG_CONTINUE, 0,
		10, {"0%", "10%","20%","30%","40%","50%","60%","70%","80%","90%","100%"}
	},
	{ "\n" },

	{
		"Controler", &neogeo_input_port, CFG_CONTINUE, 0,
		1, {"Player 1","Player 2"}
	},
	{ "\n" },

	{
		"PSP clock", &psp_cpuclock, CFG_CONTINUE, 0,
		2, {"222MHz","266MHz","333MHz"}
	},
	{ "\n" },

	{"Return to main menu" }
};


int menu_gamecfg(void)
{
	int sel = 0, rows = 12, top = 0;
	int i, arrowl, arrowr;

	for (i = 0; i < GAMECFG_MENU_ITEMS; i++)
	{
		if (gamecfg_menu[i].value)
		{
			if (*gamecfg_menu[i].value < 0)
				*gamecfg_menu[i].value = 0;
			if (*gamecfg_menu[i].value > gamecfg_menu[i].value_max)
				*gamecfg_menu[i].value = gamecfg_menu[i].value_max;

			gamecfg_menu[i].old_value = *gamecfg_menu[i].value;
		}
	}

	while (1)
	{
	  	show_background();

		if (pad_pressed_memory(PSP_CTRL_CIRCLE))
		{
			if (sel == GAMECFG_MENU_ITEMS - 1)
				break;
		}
	    else if (pad_pressed_memory(PSP_CTRL_CROSS))
	    {
	    	break;
	    }
		else if (pad_pressed_memory(PSP_CTRL_UP))
		{
			sel--;
			if (gamecfg_menu[sel].label[0] == '\n') sel--;
		}
		else if (pad_pressed_memory(PSP_CTRL_DOWN))
		{
			sel++;
			if (gamecfg_menu[sel].label[0] == '\n') sel++;
		}
	    else if (pad_pressed_memory(PSP_CTRL_LEFT))
		{
			if (gamecfg_menu[sel].value)
			{
	    		int cur = *gamecfg_menu[sel].value;

				if (cur > 0)
					*gamecfg_menu[sel].value = cur - 1;
			}
		}
		else if (pad_pressed_memory(PSP_CTRL_RIGHT))
		{
	    	if (gamecfg_menu[sel].value)
	    	{
	    		int cur = *gamecfg_menu[sel].value;

				if (cur < gamecfg_menu[sel].value_max)
					*gamecfg_menu[sel].value = cur + 1;
			}
		}

		if (top > GAMECFG_MENU_ITEMS - rows) top = GAMECFG_MENU_ITEMS - rows;
		if (top < 0) top = 0;
		if (sel >= GAMECFG_MENU_ITEMS) sel = 0;
		if (sel < 0) sel = GAMECFG_MENU_ITEMS - 1;
		if (sel >= top + rows) top = sel - rows + 1;
		if (sel < top) top = sel;

		arrowl = 0;
		arrowr = 0;
		if (gamecfg_menu[sel].value)
		{
    		int cur = *gamecfg_menu[sel].value;

			if (cur > 0) arrowl = 1;
			if (cur < gamecfg_menu[sel].value_max) arrowr = 1;
		}

		small_icon_shadow(8+1, 24+1, INFOBAR_COLOR, ICON_S_CONFIG, SHADOW_LEVEL);
		small_icon(8, 24, INFOBAR_COLOR, ICON_S_CONFIG);
		font_print_shadow(36, 24, INFOBAR_COLOR, "Game configration menu", SHADOW_LEVEL);
		boxfill(0, 254, 479, 271, MAKECOL15(76,76,76));
		font_print_shadow(8, 252, MAKECOL15(220,220,220), " \x01\x02 Browse list   \x03\x04 Change value  \x06 Return to main menu", SHADOW_LEVEL);

		draw_scrollbar(470, 47, 479, 251, 16, GAMECFG_MENU_ITEMS, sel);

		for (i = 0; i < rows; i++)
		{
			if (top + i >= GAMECFG_MENU_ITEMS) break;

			if (gamecfg_menu[top + i].label[0] == '\n')
				continue;

			if ((top + i) == sel)
			{
				font_print_shadow(16, 50 + i * 16, SELECT_COLOR, gamecfg_menu[top + i].label, SHADOW_LEVEL);
				if (arrowl) font_print_shadow(200 - 20, 50 + i * 16, SELECT_COLOR, "\x0b", SHADOW_LEVEL);
			}
			else
				font_print(16, 50 + i * 16, NORMAL_COLOR, gamecfg_menu[top + i].label);

			if (gamecfg_menu[top + i].value)
			{
				int val = *gamecfg_menu[top + i].value;

				if ((top + i) == sel)
				{
					font_print_shadow(200, 50 + i * 16, SELECT_COLOR, gamecfg_menu[top + i].values_label[val], SHADOW_LEVEL);
					if (arrowr) font_print_shadow(200 + font_get_string_width(gamecfg_menu[top + i].values_label[val]) + 4, 50 + i * 16, SELECT_COLOR, "\x0c", SHADOW_LEVEL);
				}
				else
					font_print(200, 50 + i * 16, NORMAL_COLOR, gamecfg_menu[top + i].values_label[val]);
			}
		}

		draw_battery_status(1);
		video_flip_screen(1);
		pad_update();

   	    if (get_app_status()) break;
	}

	for (i = 0; i < GAMECFG_MENU_ITEMS; i++)
	{
		if (gamecfg_menu[i].value && gamecfg_menu[i].flag == CFG_RESTART)
		{
			if (gamecfg_menu[i].old_value != *gamecfg_menu[i].value)
			{
				menu_restart();
				return 1;
			}
		}
	}

	return 0;
}


#ifdef SAVE_STATE

static u8 slot[10];
static int st_which;
static int st_sel;
static int st_light_level;
static int st_light_dir;


static void menu_delete_slot(void)
{
	boxfill_alpha(0, 0, 479, 271, 0, 16);

	draw_dialog(240-110+1, 136-32+1, 240+110-1, 136+32-1);
	font_print_shadow_center(136-26+1, MAKECOL15(255,255,127), "Delete save state.", SHADOW_LEVEL);
	font_print_shadow_center(136+4+1, MAKECOL15(255,255,255), "\x05 to confirm, \x06 to cancel", SHADOW_LEVEL);

	video_flip_screen(1);

	pad_wait_clear();

	do
	{
		pad_update();

		if (pad_pressed_memory(PSP_CTRL_CIRCLE))
		{
			char path[MAX_PATH];

			sprintf(path, "%sstate/%s.sv%d", launchDir, game_name, st_sel);
			sceIoRemove(path);
			slot[st_sel] = 0;
			st_which = 0;
			break;
		}

   	    if (get_app_status()) break;

	} while (!pad_pressed_memory(PSP_CTRL_CROSS));

	pad_wait_clear();
}


int draw_state_menu(int progress)
{
	int x, y;

  	show_background();

	st_light_level += st_light_dir;
	if (st_light_level > 31)
	{
		st_light_level = 31;
		st_light_dir = -1;
	}
	else if (st_light_level < 0)
	{
		st_light_level = 0;
		st_light_dir = 1;
	}

	font_print(8, 24, NORMAL_COLOR, "Main menu");
	font_print(88, 24, NORMAL_COLOR, "\x0bL    R\x0c");
	font_print_shadow(158, 24, INFOBAR_COLOR, "Save/Load state", SHADOW_LEVEL);
	draw_battery_status(0);

	for (y = 0; y < 10; y++)
	{
		char name[16], state[32];

		sprintf(name, "Slot %d:", y);
		if (slot[y])
			sprintf(state, "%s.sv%d", game_name, y);
		else
			strcpy(state, "Empty");

		if (y == st_sel)
		{
			small_icon_lightshadow(16, 54 + y * 20, SELECT_COLOR, ICON_S_MEMSTICK, st_light_level);
			small_icon_shadow(16, 54 + y * 20, SELECT_COLOR, ICON_S_MEMSTICK, SHADOW_LEVEL);
			small_icon(16, 54 + y * 20, SELECT_COLOR, ICON_S_MEMSTICK);

			font_print_shadow(40, 54 + y * 20, SELECT_COLOR, name, SHADOW_LEVEL);
			font_print_shadow(90, 54 + y * 20, SELECT_COLOR, state, SHADOW_LEVEL);

			if (slot[st_sel])
			{
				if (st_which == 1)
				{
					font_print_shadow(192, 54 + y * 20, SELECT_COLOR, "\x0b", SHADOW_LEVEL);
					font_print_shadow(210, 54 + y * 20, SELECT_COLOR, "load", SHADOW_LEVEL);
					font_print_shadow(244, 54 + y * 20, SELECT_COLOR, "\x0c", SHADOW_LEVEL);
				}
				else if (st_which == 2)
				{
					font_print_shadow(192, 54 + y * 20, SELECT_COLOR, "\x0b", SHADOW_LEVEL);
					font_print_shadow(210, 54 + y * 20, SELECT_COLOR, "Delete", SHADOW_LEVEL);
				}
				else
				{
					font_print_shadow(210, 54 + y * 20, SELECT_COLOR, "Save", SHADOW_LEVEL);
					font_print_shadow(244, 54 + y * 20, SELECT_COLOR, "\x0c", SHADOW_LEVEL);
				}
			}
			else
			{
				font_print_shadow(210, 54 + y * 20, SELECT_COLOR, "Save", SHADOW_LEVEL);
			}

			hline_gradation(40, 260, 54 + y * 20 + 18, NORMAL_COLOR, SELECT_COLOR, 28);
			hline_gradation(41, 261, 54 + y * 20 + 19, 0, 0, 15);
		}
		else
		{
			small_icon(16, 54 + y * 20, NORMAL_COLOR, ICON_S_MEMSTICK);
			font_print(40, 54 + y * 20, NORMAL_COLOR, name);
			font_print(90, 54 + y * 20, NORMAL_COLOR, state);
		}
	}

	u16 *p = video_draw_frame(0, 0);
	for (y = 0; y < 112; y++)
	{
		for (x = 0; x < 152; x++)
		{
			p[(62 + y) * BUF_WIDTH + (298 + x)] = thumbnail_buf[y * 152 + x];
		}
	}

	font_print(290, 182, NORMAL_COLOR, "Play Date");
	font_print(368, 182, NORMAL_COLOR, date_str);
	font_print(290, 202, NORMAL_COLOR, "Save Time");
	font_print(368, 202, NORMAL_COLOR, time_str);
	font_print(290, 222, NORMAL_COLOR, "Version");
	font_print(368, 222, NORMAL_COLOR, stver_str);

	if (progress != 0)
	{
		if (st_which == 2) return;

		boxfill_alpha(0, 0, 479, 271, 0, 16);
		draw_dialog(80, 16, 479-80, 271-16);

		if (st_which)
		{
			font_print_shadow_center(20, MAKECOL15(255,255, 127), "Load state", SHADOW_LEVEL);

			if (progress == 1)
			{
				font_print_shadow(90, 40, MAKECOL15(255,255, 255), "Press \05 to start load state. (\x06 to cancel)", SHADOW_LEVEL);
				video_flip_screen(1);

				pad_wait_clear();

				do
				{
					if (pad_pressed_memory(PSP_CTRL_CIRCLE))
					{
						pad_wait_clear();
						return 1;
					}

			   	    if (get_app_status()) break;

					pad_update();
				} while (!pad_pressed_memory(PSP_CTRL_CROSS));

				pad_wait_clear();
				return 0;
			}
			if (progress > 1) font_print_shadow(90, 40, MAKECOL15(255,255, 255), "Read header...", SHADOW_LEVEL);
			if (progress > 2) font_print_shadow(90, 40 + 18, MAKECOL15(255,255, 255), "Skip snap shot...", SHADOW_LEVEL);
			if (progress > 3) font_print_shadow(90, 40 + 18*2, MAKECOL15(255,255, 255), "Read state data...", SHADOW_LEVEL);
			if (progress > 4) font_print_shadow(90, 40 + 18*3, MAKECOL15(255,255, 255), "Uncompress state data...", SHADOW_LEVEL);
			if (progress > 5) font_print_shadow(90, 40 + 18*4, MAKECOL15(255,255, 255), "Restore state data...", SHADOW_LEVEL);
			if (progress > 6)
			{
				font_print_shadow(90, 40 + 18*5, MAKECOL15(255,255, 255), "Complete.", SHADOW_LEVEL);
				font_print_shadow_center(231, MAKECOL15(255,255, 255), "Press any button to return to game.", SHADOW_LEVEL);
				video_flip_screen(1);
				pad_wait_press(-1);
				pad_wait_clear();
				return 0;
			}
		}
		else
		{
			font_print_shadow_center(20, MAKECOL15(255,255,127), "Save state", SHADOW_LEVEL);

			if (progress <= 8)
			{
				font_print_shadow_center(211, MAKECOL15(255,127,127), "Save state is very slow.", SHADOW_LEVEL);
				font_print_shadow_center(231, MAKECOL15(255,127,127), "Please wait for a while.", SHADOW_LEVEL);
			}

			if (progress == 1)
			{
				font_print_shadow(90, 40, MAKECOL15(255,255, 255), "Press \05 to start save state. (\x06 to cancel)", SHADOW_LEVEL);
				video_flip_screen(1);

				pad_wait_clear();

				do
				{
					if (pad_pressed_memory(PSP_CTRL_CIRCLE))
					{
						pad_wait_clear();
						return 1;
					}

			   	    if (get_app_status()) break;

					pad_update();
				} while (!pad_pressed_memory(PSP_CTRL_CROSS));

				pad_wait_clear();
				return 0;
			}
			if (progress > 1) font_print_shadow(90, 40, MAKECOL15(255,255, 255), "Write header...", SHADOW_LEVEL);
			if (progress > 2) font_print_shadow(90, 40 + 18*1, MAKECOL15(255,255, 255), "Capture snap shot...", SHADOW_LEVEL);
			if (progress > 3) font_print_shadow(90, 40 + 18*2, MAKECOL15(255,255, 255), "Compress snap shot...", SHADOW_LEVEL);
			if (progress > 4) font_print_shadow(90, 40 + 18*3, MAKECOL15(255,255, 255), "Write snap shot...", SHADOW_LEVEL);
			if (progress > 5) font_print_shadow(90, 40 + 18*4, MAKECOL15(255,255, 255), "Register state data...", SHADOW_LEVEL);
			if (progress > 6) font_print_shadow(90, 40 + 18*5, MAKECOL15(255,255, 255), "Compress state data...", SHADOW_LEVEL);
			if (progress > 7) font_print_shadow(90, 40 + 18*6, MAKECOL15(255,255, 255), "Write state data...", SHADOW_LEVEL);
			if (progress > 8)
			{
				font_print_shadow(90, 40 + 18*7, MAKECOL15(255,255, 255), "Complete.", SHADOW_LEVEL);
				font_print_shadow_center(211, MAKECOL15(255,255, 255), "Press \x06 to return to game.", SHADOW_LEVEL);
				font_print_shadow_center(231, MAKECOL15(255,255, 255), "Press other button to return to menu.", SHADOW_LEVEL);
				video_flip_screen(1);
				pad_wait_clear();

				do
				{
					if (pad_pressed_memory(PSP_CTRL_CROSS))
					{
						pad_wait_clear();
						return 1;
					}

			   	    if (get_app_status()) break;

					pad_update();
				} while (!pad_pressed_any(PSP_CTRL_CROSS));

				pad_wait_clear();
				return 0;
			}
		}
	}

	video_flip_screen(1);

	return 0;
}


int menu_state(void)
{
	int i, prev_sel = -1;
	int thumbnail_loaded = 0;

	st_which = 0;
	st_sel = 0;
	st_light_level = 0;
	st_light_dir = 1;
	thumbnail_loaded = 0;

	memset(slot, 0, sizeof(slot));

	find_state_file(slot);

	while (1)
	{
		if (prev_sel == st_sel)
		{
			if (pad_pressed_memory(PSP_CTRL_CIRCLE))
			{
				if (st_which == 1)
				{
					if (slot[st_sel])
					{
						if (draw_state_menu(1))
						{
							state_load(st_sel);
							state_loaded = 1;
							draw_state_menu(7);
							return 1;
						}
						continue;
					}
				}
				else if (st_which == 2)
				{
					if (slot[st_sel])
					{
						draw_state_menu(1);
						menu_delete_slot();
						prev_sel = -1;
						continue;
					}
				}
				else
				{
					if (draw_state_menu(1))
					{
						state_save(st_sel);
						find_state_file(slot);
						state_load_screen(st_sel);

						if (draw_state_menu(9))
							return 1;
					}
					continue;
				}
			}
			draw_state_menu(0);
		}
		else
		{
			prev_sel = st_sel;
			st_light_level = 0;
			st_light_dir = 1;

			if (neogeo_region)
				strcpy(date_str, "--/--/----");
			else
				strcpy(date_str, "----/--/--");
			strcpy(time_str, "--:--:--");
			strcpy(stver_str, "--------");

			if (slot[st_sel] == 1)
			{
				state_load_screen(st_sel);
			}
			else
			{
				st_which = 0;
				memset(thumbnail_buf, 0, sizeof(thumbnail_buf));
			}
		}

		if (pad_pressed_memory(PSP_CTRL_UP))
		{
			st_sel--;
			if (st_sel < 0) st_sel = 10 - 1;
		}
		else if (pad_pressed_memory(PSP_CTRL_DOWN))
		{
			st_sel++;
			if (st_sel >= 10) st_sel = 0;
		}
		else if (pad_pressed_memory(PSP_CTRL_LEFT))
		{
			if (st_which > 0) st_which--;
		}
		else if (pad_pressed_memory(PSP_CTRL_RIGHT))
		{
			if (slot[st_sel])
			{
				if (st_which < 2) st_which++;
			}
		}
		else if (pad_pressed_memory(PSP_CTRL_LTRIGGER))
		{
			break;
		}

		pad_update();

   	    if (get_app_status()) break;
	}

	pad_wait_clear();

	return 0;
}

#endif


typedef struct
{
	const char label[64];
	int (*menu_func)(void);
	int	icon;
	const char help[128];
} menu_t;


#define MENU_ITEMS 6

menu_t main_menu[MENU_ITEMS] =
{
	{"Game configration", menu_gamecfg, ICON_L_CONFIG, "Change game settings." },
	{"Key configration", menu_keycfg, ICON_L_KEYCONFIG, "Change buttons and autofire/hotkey settings." },
	{"Reset NEOGEO", menu_reset, ICON_L_RESET, "Reset NEOGEO CDZ emulation."},
	{"Return to file browser", menu_browser, ICON_L_FOLDER, "Stop emulation and return to file browser." },
	{"Return to game", NULL, ICON_L_RETURN, "Return to game emulation." },
	{"Exit emulator", menu_exit, ICON_L_EXIT, "Exit emulation and return to PSP menu." },
};


void showmenu(void)
{
	static int sel = 0;
	int y, light_level = 0, light_dir = 1, prev_sel = 0;
	int mp3_paused = 0;

	load_background();

	state_loaded = 0;

	if (mp3_get_status() == MP3_PLAY)
	{
		mp3_pause(1);
		mp3_paused = 1;
	}

	sound_enable(0);

	scePowerSetClockFrequency(222, 222, 111);
	video_clear_screen();

	pad_wait_clear();

	while (1)
	{
	  	show_background();

		if (prev_sel == sel)
		{
			light_level += light_dir;
			if (light_level > 31)
			{
				light_level = 31;
				light_dir = -1;
			}
			else if (light_level < 0)
			{
				light_level = 0;
				light_dir = 1;
			}

			font_print_shadow(8, 24, INFOBAR_COLOR, "Main menu", SHADOW_LEVEL);
#ifdef SAVE_STATE
			font_print(88, 24, NORMAL_COLOR, "\x0bL    R\x0c");
			font_print(158, 24, NORMAL_COLOR, "Save/Load state");
#endif

			for (y = 0; y < MENU_ITEMS; y++)
			{
				if (y == sel)
				{
					large_icon_lightshadow(16, 54 + y * 35, SELECT_COLOR, main_menu[y].icon, light_level);
					large_icon_shadow(16, 54 + y * 35, SELECT_COLOR, main_menu[y].icon, SHADOW_LEVEL);
					large_icon(16, 54 + y * 35, SELECT_COLOR, main_menu[y].icon);

					font_print_shadow(56, 45 + y * 35, SELECT_COLOR, main_menu[y].label, SHADOW_LEVEL);
					font_print_shadow(56, 49 + y * 35 + 16, SELECT_COLOR, main_menu[y].help, SHADOW_LEVEL);

					hline_gradation(56, 460, 47 + y * 35 + 19, NORMAL_COLOR, SELECT_COLOR, 28);
					hline_gradation(57, 460, 47 + y * 35 + 20, 0, 0, 15);
				}
				else
				{
					large_icon(16, 54 + y * 35, NORMAL_COLOR, main_menu[y].icon);
					font_print(56, 47 + y * 35 + 8, NORMAL_COLOR, main_menu[y].label);
				}
			}

			if (pad_pressed_memory(PSP_CTRL_CIRCLE))
			{
				if (main_menu[sel].menu_func)
				{
					if (main_menu[sel].menu_func())
						break;
				}
				else break;
			}
		    else if (pad_pressed_memory(PSP_CTRL_CROSS))
		    {
		    	break;
		    }
		    else if (pad_pressed_memory(PSP_CTRL_RTRIGGER))
		    {
		    	if (menu_state()) break;
		    }

			draw_battery_status(1);
			ui_show_popup();
			video_flip_screen(1);
		}
		else
		{
			prev_sel = sel;
			light_level = 0;
			light_dir = 1;
		}

		if (pad_pressed_memory(PSP_CTRL_UP))
		{
			sel--;
			if (sel < 0) sel = MENU_ITEMS - 1;
		}
		else if (pad_pressed_memory(PSP_CTRL_DOWN))
		{
			sel++;
			if (sel >= MENU_ITEMS) sel = 0;
		}

		pad_update();

   	    if (get_app_status()) break;
	}

	pad_wait_clear();

	set_cpu_clock();

	init_autoframeskip();
	blit_clear_cache();

	sound_set_volume();

	mp3_file_reopen();
	mp3_set_volume();

	if (state_loaded)
	{
		if (mp3_get_status() == MP3_SEEK)
		{
			mp3_seek_start();

			while (mp3_get_status() == MP3_SEEK)
				wait(100);
		}
	}
	else if (!neogeo_cdda_enable)
	{
		cdda_stop();
	}
	else if (mp3_paused)
	{
		mp3_pause(0);
	}

	if (neogeo_sound_enable)
	{
		timer_suspend_cpu(CPU_Z80, 1, SUSPEND_REASON_NOTSUSPEND);
		sound_enable(1);
	}
	else
	{
		timer_suspend_cpu(CPU_Z80, 0, SUSPEND_REASON_DISABLE);
		sound_enable(0);
	}

	video_clear_screen();
}
