+ if (inp & PBTN_X) return;
+ }
+}
+
+// --------- display options ----------
+
+menu_entry opt3_entries[] =
+{
+ { NULL, MB_NONE, MA_OPT3_SCALE, NULL, 0, 0, 0, 1, 1 },
+ { NULL, MB_NONE, MA_OPT3_HSCALE32, NULL, 0, 0, 0, 1, 1 },
+ { NULL, MB_NONE, MA_OPT3_HSCALE40, NULL, 0, 0, 0, 1, 1 },
+ { NULL, MB_ONOFF, MA_OPT3_FILTERING, ¤tConfig.scaling, 1, 0, 0, 1, 1 },
+ { NULL, MB_RANGE, MA_OPT3_GAMMAA, ¤tConfig.gamma, 0, -4, 16, 1, 1 },
+ { NULL, MB_RANGE, MA_OPT3_BLACKLVL, ¤tConfig.gamma2, 0, 0, 2, 1, 1 },
+ { NULL, MB_NONE, MA_OPT3_VSYNC, NULL, 0, 0, 0, 1, 1 },
+ { "Set to unscaled centered", MB_NONE, MA_OPT3_PRES_NOSCALE, NULL, 0, 0, 0, 1, 0 },
+ { "Set to 4:3 scaled", MB_NONE, MA_OPT3_PRES_SCALE43, NULL, 0, 0, 0, 1, 0 },
+ { "Set to fullscreen", MB_NONE, MA_OPT3_PRES_FULLSCR, NULL, 0, 0, 0, 1, 0 },
+ { "done", MB_NONE, MA_OPT3_DONE, NULL, 0, 0, 0, 1, 0 },
+};
+
+#define OPT3_ENTRY_COUNT (sizeof(opt3_entries) / sizeof(opt3_entries[0]))
+const int opt3_entry_count = OPT3_ENTRY_COUNT;
+
+
+static void menu_opt3_cust_draw(const menu_entry *entry, int x, int y, void *param)
+{
+ switch (entry->id)
+ {
+ case MA_OPT3_SCALE:
+ text_out16(x, y, "Scale factor: %.2f", currentConfig.scale);
+ break;
+ case MA_OPT3_HSCALE32:
+ text_out16(x, y, "Hor. scale (for low res. games): %.2f", currentConfig.hscale32);
+ break;
+ case MA_OPT3_HSCALE40:
+ text_out16(x, y, "Hor. scale (for hi res. games): %.2f", currentConfig.hscale40);
+ break;
+ case MA_OPT3_FILTERING:
+ text_out16(x, y, "Bilinear filtering %s", currentConfig.scaling?"ON":"OFF");
+ break;
+ case MA_OPT3_GAMMAA:
+ text_out16(x, y, "Gamma adjustment %2i", currentConfig.gamma);
+ break;
+ case MA_OPT3_BLACKLVL:
+ text_out16(x, y, "Black level %2i", currentConfig.gamma2);
+ break;
+ case MA_OPT3_VSYNC: {
+ char *val = " never";
+ if (currentConfig.EmuOpt & 0x2000)
+ val = (currentConfig.EmuOpt & 0x10000) ? "sometimes" : " always";
+ text_out16(x, y, "Wait for vsync (slow) %s", val);
+ break;
+ }
+ default: break;
+ }
+}
+
+static void menu_opt3_preview(int is_32col)
+{
+ void *oldstate = NULL;
+
+ if (!rom_loaded || ((Pico.video.reg[12]&1)^1) != is_32col)
+ {
+ extern char bgdatac32_start[], bgdatac40_start[];
+ extern int bgdatac32_size, bgdatac40_size;
+ void *bgdata = is_32col ? bgdatac32_start : bgdatac40_start;
+ unsigned long insize = is_32col ? bgdatac32_size : bgdatac40_size, outsize = 65856;
+ int ret;
+ ret = uncompress((Bytef *)bg_buffer, &outsize, bgdata, insize);
+ if (ret == 0)
+ {
+ if (rom_loaded) oldstate = get_oldstate_for_preview();
+ memcpy(Pico.vram, bg_buffer, sizeof(Pico.vram));
+ memcpy(Pico.cram, (char *)bg_buffer + 0x10000, 0x40*2);
+ memcpy(Pico.vsram, (char *)bg_buffer + 0x10080, 0x40*2);
+ memcpy(&Pico.video,(char *)bg_buffer + 0x10100, 0x40);
+ }
+ else
+ lprintf("uncompress returned %i\n", ret);
+ }
+
+ memset32_uncached(psp_screen, 0, 512*272*2/4);
+ emu_forcedFrame(0);
+ menu_prepare_bg(1, 0);
+
+ if (oldstate) restore_oldstate(oldstate);
+}
+
+static void draw_dispmenu_options(int menu_sel)
+{
+ int tl_x = 80, tl_y = 16+50;
+
+ menu_draw_begin();
+
+ menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 316);
+
+ me_draw(opt3_entries, OPT3_ENTRY_COUNT, tl_x, tl_y, menu_opt3_cust_draw, NULL);
+
+ menu_draw_end();
+}
+
+static void dispmenu_loop_options(void)
+{
+ static int menu_sel = 0;
+ int menu_sel_max, is_32col = (Pico.video.reg[12]&1)^1;
+ unsigned long inp = 0;
+ menu_id selected_id;
+
+ menu_sel_max = me_count_enabled(opt3_entries, OPT3_ENTRY_COUNT) - 1;
+
+ for (;;)
+ {
+ draw_dispmenu_options(menu_sel);
+ inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_X|PBTN_CIRCLE, 0);
+ if (inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
+ if (inp & PBTN_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
+ selected_id = me_index2id(opt3_entries, OPT3_ENTRY_COUNT, menu_sel);
+ if (selected_id == MA_OPT3_HSCALE40 && is_32col) { is_32col = 0; menu_opt3_preview(is_32col); }
+ if (selected_id == MA_OPT3_HSCALE32 && !is_32col) { is_32col = 1; menu_opt3_preview(is_32col); }
+
+ if (inp & (PBTN_LEFT|PBTN_RIGHT)) // multi choise
+ {
+ float *setting = NULL;
+ int tmp;
+ me_process(opt3_entries, OPT3_ENTRY_COUNT, selected_id, (inp&PBTN_RIGHT) ? 1 : 0);
+ switch (selected_id) {
+ case MA_OPT3_SCALE: setting = ¤tConfig.scale; break;
+ case MA_OPT3_HSCALE40: setting = ¤tConfig.hscale40; is_32col = 0; break;
+ case MA_OPT3_HSCALE32: setting = ¤tConfig.hscale32; is_32col = 1; break;
+ case MA_OPT3_FILTERING:
+ case MA_OPT3_GAMMAA:
+ case MA_OPT3_BLACKLVL: menu_opt3_preview(is_32col); break;
+ case MA_OPT3_VSYNC:
+ tmp = ((currentConfig.EmuOpt>>13)&1) | ((currentConfig.EmuOpt>>15)&2);
+ tmp = (inp & PBTN_LEFT) ? (tmp>>1) : ((tmp<<1)|1);
+ if (tmp > 3) tmp = 3;
+ currentConfig.EmuOpt &= ~0x12000;
+ currentConfig.EmuOpt |= ((tmp&2)<<15) | ((tmp&1)<<13);
+ break;
+ default: break;
+ }
+ if (setting != NULL) {
+ while ((inp = psp_pad_read(0)) & (PBTN_LEFT|PBTN_RIGHT)) {
+ *setting += (inp & PBTN_LEFT) ? -0.01 : 0.01;
+ if (*setting <= 0) *setting = 0.01;
+ menu_opt3_preview(is_32col);
+ draw_dispmenu_options(menu_sel); // will wait vsync
+ }
+ }
+ }
+ if (inp & PBTN_CIRCLE) { // toggleable options
+ me_process(opt3_entries, OPT3_ENTRY_COUNT, selected_id, 1);
+ switch (selected_id) {
+ case MA_OPT3_DONE:
+ return;
+ case MA_OPT3_PRES_NOSCALE:
+ currentConfig.scale = currentConfig.hscale40 = currentConfig.hscale32 = 1.0;
+ menu_opt3_preview(is_32col);
+ break;
+ case MA_OPT3_PRES_SCALE43:
+ currentConfig.scale = 1.20;
+ currentConfig.hscale40 = 1.00;
+ currentConfig.hscale32 = 1.25;
+ menu_opt3_preview(is_32col);
+ break;
+ case MA_OPT3_PRES_FULLSCR:
+ currentConfig.scale = 1.20;
+ currentConfig.hscale40 = 1.25;
+ currentConfig.hscale32 = 1.56;
+ menu_opt3_preview(is_32col);
+ break;
+ case MA_OPT3_FILTERING:
+ menu_opt3_preview(is_32col);
+ break;
+ default: break;
+ }
+ }
+ if (inp & PBTN_X) return;