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; }
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); }
int button_pressed(void) { int i, j; os_poll(); joystickb_poll(); target_idle(); for (i = 0; i < joystickb_count_get(); ++i) { for (j = 0; j < joystickb_button_count_get(i); ++j) { if (joystickb_button_get(i, j)) return 1; } } return 0; }
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; } }
int os_main(int argc, char* argv[]) { int keyboard_id; adv_conf* context; const char* s; char* section_map[1]; const char** file_map; unsigned file_mac; int i; double latency_time; double buffer_time; double volume; unsigned rate; int attenuation; adv_bool opt_log; adv_bool opt_logsync; opt_log = 0; opt_logsync = 0; file_map = 0; file_mac = 0; context = conf_init(); if (os_init(context) != 0) goto err_conf; mixer_reg(context); conf_int_register_limit_default(context, "sound_volume", -32, 0, 0); conf_int_register_limit_default(context, "sound_samplerate", 5000, 96000, 44100); conf_float_register_limit_default(context, "sound_latency", 0.01, 2.0, 0.1); conf_float_register_limit_default(context, "sound_buffer", 0.05, 2.0, 0.1); if (conf_input_args_load(context, 0, "", &argc, argv, error_callback, 0) != 0) goto err_os; file_map = malloc(argc * sizeof(const char*)); for(i=1;i<argc;++i) { if (target_option_compare(argv[i], "log")) { opt_log = 1; } else if (target_option_compare(argv[i], "logsync")) { opt_logsync = 1; } else if (target_option_extract(argv[i]) == 0) { file_map[file_mac++] = argv[i]; } else { target_err("Unknown command line option '%s'.\n", argv[i]); goto err_os; } } if (argc <= 1 || file_mac == 0) { target_err("Syntax: advs FILES...\n"); goto err_os; } if (opt_log || opt_logsync) { const char* log = "advs.log"; remove(log); log_init(log, opt_logsync); } section_map[0] = ""; conf_section_set(context, section_map, 1); if (mixer_load(context) != 0) { goto err_os; } attenuation = conf_int_get_default(context, "sound_volume"); latency_time = conf_float_get_default(context, "sound_latency"); buffer_time = conf_float_get_default(context, "sound_buffer"); rate = conf_int_get_default(context, "sound_samplerate"); volume = 1.0; while (attenuation++ < 0) volume /= 1.122018454; /* = (10 ^ (1/20)) = 1dB */ if (os_inner_init("AdvanceSOUND") != 0) goto err_os; if (file_mac > MIXER_CHANNEL_MAX) { target_err("Too many files\n"); goto err_os_inner; } if (mixer_init(rate, file_mac, 1, buffer_time + latency_time, latency_time) != 0) { target_err("%s\n", error_get()); goto err_os_inner; } mixer_volume(volume); for(i=0;i<file_mac;++i) run(i, file_map[i]); free(file_map); signal(SIGINT, sigint); while (!done) { for(i=0;i<file_mac;++i) if (mixer_is_playing(i)) break; if (i==file_mac) break; mixer_poll(); target_idle(); } log_std(("s: shutdown\n")); mixer_done(); os_inner_done(); log_std(("s: the end\n")); if (opt_log || opt_logsync) { log_done(); } os_done(); conf_done(context); return EXIT_SUCCESS; err_os_inner: os_inner_done(); log_done(); err_os: os_done(); err_conf: conf_done(context); err: return EXIT_FAILURE; }
unsigned inputb_tty_get(void) { const unsigned max = 32; char map[max+1]; unsigned mac; log_debug(("inputb:tty: inputb_tty_button_count_get()\n")); mac = 0; while (mac<max && (mac==0 || tty_state.last)) { if (tty_state.last) { map[mac] = tty_state.last; if (mac > 0 && map[mac] == 27) { break; } ++mac; tty_state.last = 0; } else { target_idle(); } tty_state.last = tty_getkey(); } map[mac] = 0; if (strcmp(map, "\033[A")==0) return INPUTB_UP; if (strcmp(map, "\033[B")==0) return INPUTB_DOWN; if (strcmp(map, "\033[D")==0) return INPUTB_LEFT; if (strcmp(map, "\033[C")==0) return INPUTB_RIGHT; if (strcmp(map, "\033[1~")==0) return INPUTB_HOME; if (strcmp(map, "\033[4~")==0) return INPUTB_END; if (strcmp(map, "\033[5~")==0) return INPUTB_PGUP; if (strcmp(map, "\033[6~")==0) return INPUTB_PGDN; if (strcmp(map, "\033[[A")==0) return INPUTB_F1; if (strcmp(map, "\033[[B")==0) return INPUTB_F2; if (strcmp(map, "\033[[C")==0) return INPUTB_F3; if (strcmp(map, "\033[[D")==0) return INPUTB_F4; if (strcmp(map, "\033[[E")==0) return INPUTB_F5; if (strcmp(map, "\033[17~")==0) return INPUTB_F6; if (strcmp(map, "\033[18~")==0) return INPUTB_F7; if (strcmp(map, "\033[19~")==0) return INPUTB_F8; if (strcmp(map, "\033[20~")==0) return INPUTB_F9; if (strcmp(map, "\033[21~")==0) return INPUTB_F10; if (strcmp(map, "\r")==0 || strcmp(map, "\n")==0) return INPUTB_ENTER; if (strcmp(map, "\x7F")==0) return INPUTB_BACKSPACE; if (mac != 1) return 0; else return (unsigned char)map[0]; return 0; }
/* 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_animate(void) { adv_mode mode; adv_crtc* crtc; unsigned i; int counter; 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; } update_init(2); draw_graphics_palette(); for(i=0;i<3;++i) { update_start(); video_clear(update_x_get(), update_y_get(), video_size_x(), video_size_y(), 0); update_stop(update_x_get(), update_y_get(), video_size_x(), video_size_y(), 1); } counter = update_page_max_get(); while (!inputb_hit()) { os_poll(); update_start(); draw_graphics_animate(update_x_get(), update_y_get(), video_size_x(), video_size_y(), counter - update_page_max_get() + 1, 1); ++counter; draw_graphics_animate(update_x_get(), update_y_get(), video_size_x(), video_size_y(), counter, 0); update_stop(update_x_get(), update_y_get(), video_size_x(), video_size_y(), 1); } update_done(); do { target_idle(); os_poll(); } while (inputb_get()==INPUTB_NONE); return 0; }
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; }