static void draw_text_error(void) { int x = 0; int y = 0; int dx = text_size_x(); int dy = text_size_y(); text_clear(); draw_text_center(x, y, dx, "ERROR! An error occurred in your last action!" , COLOR_REVERSE); ++y; ++y; y = draw_text_para(x, y, dx, dy, "Your action has generated an error. Probably you have requested an " "unsupported feature by your hardware or software." , COLOR_NORMAL); if (*error_get()) { y = draw_text_para(x, y, dx, dy-y, "\nThe video software reports this error:", COLOR_NORMAL); log_std(("v: error \"%s\"\n", error_get())); y = draw_text_para(x, y, dx, dy-y, error_get(), COLOR_ERROR); } y = draw_text_para(x, y, dx, dy-y, "\nPress ESC", COLOR_NORMAL); video_wait_vsync(); do { target_idle(); os_poll(); } while (inputb_get()==INPUTB_NONE); }
static adv_error cmd_onvideo_calib(void) { adv_mode mode; adv_crtc* crtc; unsigned speed; char buffer[128]; mode_reset(&mode); if (the_mode_index == MODE_FLAGS_INDEX_TEXT) { error_set("Command supported only in graphics mode"); return -1; } crtc = menu_current(); if (!crtc) return -1; if (!crtc_is_fake(crtc) && !crtc_clock_check(&the_monitor, crtc)) return -1; if (video_mode_generate(&mode, crtc, the_mode_index)!=0) { return -1; } if (text_mode_set(&mode) != 0) { text_reset(); return -1; } video_write_lock(); draw_graphics_palette(); /* draw_graphics_out_of_screen(0); */ draw_graphics_clear(); speed = draw_graphics_speed(0, 0, video_size_x(), video_size_y()); draw_graphics_calib(0, 0, video_size_x(), video_size_y()); snprintf(buffer, sizeof(buffer), " %.2f MB/s", speed / (double)(1024*1024)); draw_string(0, 0, buffer, DRAW_COLOR_WHITE); video_write_unlock(0, 0, 0, 0, 0); video_wait_vsync(); do { target_idle(); os_poll(); } while (inputb_get()==INPUTB_NONE); return 0; }
void show_fatal_error(void) { if (fatal_error) { int sx, sy, ex, ey; int width = uifont_get_string_width(fatal_error_message); int update = 1; sx = (SCR_WIDTH - width) >> 1; sy = (SCR_HEIGHT - FONTSIZE) >> 1; ex = sx + width; ey = sy + (FONTSIZE - 1); video_set_mode(32); load_background(WP_LOGO); while (Loop != LOOP_EXIT) { if (update) { show_background(); small_icon_shadow(6, 3, UI_COLOR(UI_PAL_TITLE), ICON_SYSTEM); uifont_print_shadow(32, 5, UI_COLOR(UI_PAL_TITLE), TEXT(FATAL_ERROR)); draw_dialog(sx - FONTSIZE/2, sy - FONTSIZE/2, ex + FONTSIZE/2, ey + FONTSIZE/2); uifont_print_shadow_center(sy, UI_COLOR(UI_PAL_SELECT), fatal_error_message); update = draw_battery_status(1); update |= draw_volume_status(1); video_flip_screen(1); } else { update = draw_battery_status(0); update |= draw_volume_status(0); video_wait_vsync(); } pad_update(); if (pad_pressed(PSP_CTRL_ANY)) break; } pad_wait_clear(); fatal_error = 0; } }
static void draw_text_help(void) { int x = 0; int y = 0; int dx = text_size_x(); int dy = text_size_y(); text_clear(); y = draw_text_para(x, y, dx, dy, " HELP" , COLOR_REVERSE); y = draw_text_para(x, y, dx, dy-y, "F2 Save the selected modes\n" "F5 Create a new modeline (favourite modes with the specified size)\n" "F6 Create a new modeline (favourite modes with the specified clock)\n" "F7 Duplicate the current mode\n" "F8 Set an arbitrary clock value\n" "F9 Show a static test screen for the current video mode\n" "F10 Show a dynamic test screen for the current video mode\n" "SPACE Select/Unselect the current video mode\n" "ENTER Test the current video mode\n" "TAB Rename the current video mode\n" "ESC Exit\n" "\n" "q/a Increase the x/y Display End register (SHIFT to decrease)\n" "w/s Increase the x/y Blank Start register (SHIFT to decrease)\n" "e/d Increase the x/y Retrace Start register (SHIFT to decrease)\n" "r/f Increase the x/y Retrace End register (SHIFT to decrease)\n" "t/g Increase the x/y Blank End register (SHIFT to decrease)\n" "y/h Increase the x/y Total End register (SHIFT to decrease)\n" "u/j Change the polarization\n" "i/k Expand the x/y size (SHIFT to shrink)\n" "v Increase the pixel clock (SHIFT to decrease)\n" "x/c Change the scan line mode\n" "n/m Change the tv mode\n" "\n" "Press ESC" , COLOR_NORMAL); video_wait_vsync(); do { target_idle(); os_poll(); } while (inputb_get()==INPUTB_NONE); }
static adv_error cmd_input_key(const char* tag, const char* keys) { draw_text_fill(0, text_size_y()-1, ' ', text_size_x(), COLOR_REVERSE); draw_text_string(2, text_size_y()-1, tag, COLOR_REVERSE); draw_text_string(2+strlen(tag), text_size_y()-1, keys, COLOR_INPUT); while (1) { int i; unsigned k; video_wait_vsync(); target_idle(); os_poll(); k = inputb_get(); if (k == INPUTB_ESC) return -1; for(i=0;keys[i];++i) if (toupper(k)==toupper(keys[i])) return i; } }
static void video_frame_sync(struct advance_video_context* context) { double current; double expected; current = advance_timer(); if (context->state.sync_warming_up_flag) { /* syncronize the first time */ if (context->state.vsync_flag) { video_wait_vsync(); current = advance_timer(); } context->state.sync_pivot = 0; context->state.sync_last = current; context->state.sync_skip_counter = 0; context->state.sync_warming_up_flag = 0; log_debug(("advance:sync: throttle warming up\n")); } else { double time_before_sync, time_after_delay, time_after_sync; time_before_sync = current; expected = context->state.sync_last + context->state.skip_step * (1 + context->state.sync_skip_counter); context->state.sync_skip_counter = 0; /* take only a part of the error, this increase the stability */ context->state.sync_pivot *= 0.99; /* adjust with the previous error */ expected += context->state.sync_pivot; /* the vsync is used only if all the frames are displayed */ if ((video_flags() & MODE_FLAGS_RETRACE_WAIT_SYNC) != 0 && context->state.vsync_flag && context->state.skip_level_full == SYNC_MAX ) { /* wait until the retrace is near (3% early), otherwise if the */ /* mode has a double freq the retrace may be the wrong one. */ double early = 0.03 / video_measured_vclock(); if (current < expected - early) { current = video_frame_wait(current, expected - early); time_after_delay = current; if (current < expected) { double after; video_wait_vsync(); after = advance_timer(); if (after - current > 1.05 / (double)video_measured_vclock()) { log_std(("ERROR:emu:video: sync wait too long. %g instead of %g (max %g)\n", after - current, early, 1.0 / (double)video_measured_vclock())); } else if (after - current > 1.05 * early) { log_std(("WARNING:emu:video: sync wait too long. %g instead of %g (max %g)\n", after - current, early, 1.0 / (double)video_measured_vclock())); } /* if a sync complete correctly reset the error to 0 */ /* in this case the vsync is used for the correct clocking */ expected = after; current = after; } else { log_std(("ERROR:emu:video: sync delay too big\n")); } } else { log_std(("ERROR:emu:video: too late for a video sync\n")); current = video_frame_wait(current, expected); time_after_delay = current; } } else { current = video_frame_wait(current, expected); time_after_delay = current; } time_after_sync = current; /* update the error state */ context->state.sync_pivot = expected - current; if (fabs(context->state.sync_pivot) > context->state.skip_step / 50) log_std(("advance:sync: %.5f (err %6.1f%%) = %.5f + %.5f + %.5f < %.5f (compute + sleep + sync < max)\n", current - context->state.sync_last, context->state.sync_pivot * 100 / context->state.skip_step, time_before_sync - context->state.sync_last, time_after_delay - time_before_sync, time_after_sync - time_after_delay, context->state.skip_step)); if (context->state.sync_pivot < - context->state.skip_step * 16) { /* if the error is too big (negative) the delay is unrecoverable */ /* generally it happen with a virtual terminal switch */ /* the best solution is to restart the sync computation */ advance_video_update_skip(context); advance_video_update_sync(context); } context->state.sync_last = current; } }
/* Menu */ static int menu_run(void) { adv_bool done; int userkey; menu_base = 0; menu_rel = 0; menu_rel_max = MENU_DY; menu_max = crtc_container_max(&the_modes); menu_base_max = menu_max - menu_rel_max; if (menu_base_max < 0) menu_base_max = 0; done = 0; while (!done) { draw_text_index(BAR_X, BAR_Y1+1, BAR_DX); draw_text_bar(BAR_X, BAR_Y1, BAR_Y2, BAR_DX); draw_text_info(INFO_X, INFO_Y, INFO_DX, INFO_DY, menu_base + menu_rel); menu_draw(MENU_X, MENU_Y, MENU_DX, MENU_DY); video_wait_vsync(); target_idle(); os_poll(); userkey = inputb_get(); switch (userkey) { case INPUTB_UP: cmd_gotopos(menu_base + menu_rel - 1); break; case INPUTB_DOWN: cmd_gotopos(menu_base + menu_rel + 1); break; case INPUTB_HOME: { int i = menu_base + menu_rel - 1; if (i<0) i = 0; while (i>0 && !(crtc_container_pos(&the_modes, i)->user_flags & MODE_FLAGS_USER_BIT0)) --i; cmd_gotopos(i); break; } case INPUTB_END: { int i = menu_base + menu_rel + 1; if (i >= menu_max) i = menu_max - 1; while (i < menu_max - 1 && !(crtc_container_pos(&the_modes, i)->user_flags & MODE_FLAGS_USER_BIT0)) ++i; cmd_gotopos(i); break; } case INPUTB_PGDN: cmd_gotopos(menu_base + menu_rel + menu_rel_max); break; case INPUTB_PGUP: cmd_gotopos(menu_base + menu_rel - menu_rel_max); break; case INPUTB_F2: cmd_save(); break; case INPUTB_LEFT : case INPUTB_RIGHT : cmd_type(userkey); break; case INPUTB_ESC: done = cmd_exit(); break; case INPUTB_SPACE: cmd_select(); cmd_gotopos(menu_base + menu_rel + 1); break; case INPUTB_ENTER: if (cmd_onvideo_test() != 0) { text_reset(); draw_text_error(); } else { text_reset(); } break; case INPUTB_F9: if (cmd_onvideo_calib() != 0) { text_reset(); draw_text_error(); } else { text_reset(); } break; case INPUTB_F10: if (cmd_onvideo_animate() != 0) { text_reset(); draw_text_error(); } else { text_reset(); } break; case INPUTB_TAB : cmd_rename(); break; case INPUTB_F5 : if (cmd_modeline_create(1) !=0) { text_reset(); draw_text_error(); } else { text_reset(); } break; case INPUTB_F6 : if (cmd_modeline_create(0) !=0) { text_reset(); draw_text_error(); } else { text_reset(); } break; case INPUTB_F7 : cmd_copy(); break; case INPUTB_F8 : if (cmd_mode_clock() !=0) { text_reset(); draw_text_error(); } else { text_reset(); } break; case INPUTB_DEL : cmd_del(); cmd_gotopos(menu_base + menu_rel); break; case INPUTB_F1: draw_text_help(); break; default: if (cmd_offvideo_test(userkey) != 0) { draw_text_error(); } break; } } return userkey; }
static adv_error cmd_onvideo_test(void) { adv_crtc* crtc; adv_mode mode; adv_bool done; adv_crtc crtc_save; adv_bool dirty = 1; adv_bool crtc_save_modified; mode_reset(&mode); crtc = menu_current(); if (!crtc) return -1; if (!crtc_is_fake(crtc) && !crtc_clock_check(&the_monitor, crtc)) return -1; if (video_mode_generate(&mode, crtc, the_mode_index)!=0) { return -1; } if (text_mode_set(&mode) != 0) { text_reset(); return -1; } crtc_save = *crtc; crtc_save_modified = the_modes_modified; done = 0; while (!done) { int userkey; adv_bool modify = 0; adv_crtc last_crtc = *crtc; adv_mode last_mode = mode; adv_bool vm_last_modified = the_modes_modified; if (dirty) { video_write_lock(); test_draw(1, 1, &mode); video_write_unlock(0, 0, 0, 0, 0); dirty = 0; } video_wait_vsync(); target_idle(); os_poll(); userkey = inputb_get(); switch (userkey) { case INPUTB_ESC : done = 1; /* restore */ *crtc = crtc_save; the_modes_modified = crtc_save_modified; break; case INPUTB_ENTER : done = 1; break; } if (!done) { modify = test_exe_crtc(userkey, crtc); if (modify) { the_modes_modified = 1; dirty = 1; if ((crtc_is_fake(crtc) || crtc_clock_check(&the_monitor, crtc)) && video_mode_generate(&mode, crtc, the_mode_index)==0) { if (text_mode_set(&mode) != 0) { text_reset(); /* abort */ *crtc = crtc_save; the_modes_modified = crtc_save_modified; return -1; } } else { /* restore */ mode = last_mode; *crtc = last_crtc; the_modes_modified = vm_last_modified; dirty = 1; sound_error(); } } else { sound_warn(); } } } return 0; }
void bios_select(int flag) { int sel = 0, rows = 13, top = 0; int i, prev_sel, update = 1; int old_bios = neogeo_bios; if (!bios_check(flag)) return; if (neogeo_bios == -1) { sel = 0; while (sel < BIOS_MAX) { if (bios_exist[sel]) break; sel++; } } else sel = neogeo_bios; if (top > BIOS_MAX - rows) top = BIOS_MAX - rows; if (top < 0) top = 0; if (sel >= BIOS_MAX) sel = 0; if (sel < 0) sel = BIOS_MAX - 1; if (sel >= top + rows) top = sel - rows + 1; if (sel < top) top = sel; pad_wait_clear(); load_background(BG_DEFAULT); ui_popup_reset(); while (1) { if (update) { int width = uifont_get_string_width(TEXT(SELECT_BIOS_AND_PRESS_CIRCLE_BUTTON)); show_background(); small_icon(8, 3, UI_COLOR(UI_PAL_TITLE), ICON_SYSTEM); uifont_print(36, 5, UI_COLOR(UI_PAL_TITLE), TEXT(BIOS_SELECT_MENU)); uifont_print(477 - width, 271 - 16, UI_COLOR(UI_PAL_SELECT), TEXT(SELECT_BIOS_AND_PRESS_CIRCLE_BUTTON)); if (sel != 0) uifont_print(118, 24, UI_COLOR(UI_PAL_SELECT), FONT_UPTRIANGLE); for (i = 0; i < rows; i++) { if (top + i >= BIOS_MAX) break; if (top + i == sel) { uifont_print(12, 40 + i * 17, UI_COLOR(UI_PAL_SELECT), FONT_RIGHTTRIANGLE); uifont_print(32, 40 + i * 17, UI_COLOR(UI_PAL_SELECT), bios_name[top + i]); } else { if (bios_exist[top + i]) uifont_print(32, 40 + i * 17, UI_COLOR(UI_PAL_NORMAL), bios_name[top + i]); else uifont_print(32, 40 + i * 17, COLOR_DARKGRAY, bios_name[top + i]); } } if (sel + rows < BIOS_MAX) uifont_print(118, 260, UI_COLOR(UI_PAL_SELECT), FONT_DOWNTRIANGLE); update = draw_battery_status(1); update |= ui_show_popup(1); video_flip_screen(1); } else { update = draw_battery_status(0); update |= ui_show_popup(0); video_wait_vsync(); } prev_sel = sel; if (pad_pressed(PSP_CTRL_UP)) { if (sel > 0) { if (bios_exist[sel - 1]) { sel--; } else { for (i = sel - 2; i >= 0; i--) if (bios_exist[i]) break; if (i != -1) sel = i; } } } else if (pad_pressed(PSP_CTRL_DOWN)) { if (sel < BIOS_MAX - 1) { if (bios_exist[sel + 1]) { sel++; } else { for (i = sel + 2; i < BIOS_MAX; i++) if (bios_exist[i]) break; if (i != BIOS_MAX) sel = i; } } } else if (pad_pressed(PSP_CTRL_CIRCLE)) { neogeo_bios = sel; break; } if (top > BIOS_MAX - rows) top = BIOS_MAX - rows; if (top < 0) top = 0; if (sel >= BIOS_MAX) sel = 0; if (sel < 0) sel = BIOS_MAX - 1; if (sel >= top + rows) top = sel - rows + 1; if (sel < top) top = sel; if (prev_sel != sel) update = 1; pad_update(); if (Loop == LOOP_EXIT) break; } pad_wait_clear(); ui_popup_reset(); if (flag) load_background(WP_LOGO); else load_background(WP_FILER); #ifdef ADHOC if (flag != 2) #endif { if (old_bios != neogeo_bios) { if (!flag) ui_popup(TEXT(ALL_NVRAM_FILES_ARE_REMOVED)); delete_files("nvram", ".nv"); } } }