diff --git a/MiSTer.ini b/MiSTer.ini index 2c68286..64be45c 100644 --- a/MiSTer.ini +++ b/MiSTer.ini @@ -34,7 +34,9 @@ recents=0 ; corename - Autoboot first corename_*.rbf found on the SD/USB ; corename_yyyymmdd.rbf - Autoboot first corename_yyyymmdd.rbf found on the SD/USB ;bootcore=lastcore ; uncomment to autoboot a core, as the last loaded core. -bootcore_timeout=10 ; 10-30 timeout before autoboot, comment for autoboot without timeout. + +; 10-30 timeout before autoboot, comment for autoboot without timeout. +bootcore_timeout=10 ; Option to load the custom font. Format is plain bitmap 8x8. ; Supported sizes of font: @@ -52,7 +54,8 @@ font=font/myfont.pf ; 3 - same as 0 (lctrl+lalt+ralt on keyrah) reset_combo=0 -dvi_mode=0 ; set to 1 for DVI mode. Audio won't be transmitted through HDMI in DVI mode. +; set to 1 for DVI mode. Audio won't be transmitted through HDMI in DVI mode. +dvi_mode=0 ; 0 - 1280x720@60 ; 1 - 1024x768@60 @@ -130,3 +133,7 @@ logo=1 ; Path must exist before core start to use it, or it will fail. ; Make sure USB device is mounted before use shared folder on USB! shared_folder= + +; Custom aspect ratio +;custom_aspect_ratio_1=16:10 +;custom_aspect_ratio_2=1:1 diff --git a/cfg.cpp b/cfg.cpp index db76347..e168bc4 100644 --- a/cfg.cpp +++ b/cfg.cpp @@ -74,6 +74,8 @@ static const ini_var_t ini_vars[] = { "SHARED_FOLDER", (void*)(&(cfg.shared_folder)), STRING, 0, sizeof(cfg.shared_folder) - 1 }, { "NO_MERGE_VID", (void*)(&(cfg.no_merge_vid)), UINT16, 0, 0xFFFF }, { "NO_MERGE_PID", (void*)(&(cfg.no_merge_pid)), UINT16, 0, 0xFFFF }, + { "CUSTOM_ASPECT_RATIO_1", (void*)(&(cfg.custom_aspect_ratio[0])), STRING, 0, sizeof(cfg.custom_aspect_ratio[0]) - 1 }, + { "CUSTOM_ASPECT_RATIO_2", (void*)(&(cfg.custom_aspect_ratio[1])), STRING, 0, sizeof(cfg.custom_aspect_ratio[1]) - 1 }, }; static const int nvars = (int)(sizeof(ini_vars) / sizeof(ini_var_t)); @@ -93,7 +95,8 @@ static const int nvars = (int)(sizeof(ini_vars) / sizeof(ini_var_t)); #define CHAR_IS_SPECIAL(c) (((c) == '[') || ((c) == ']') || ((c) == '(') || ((c) == ')') || \ ((c) == '-') || ((c) == '+') || ((c) == '/') || ((c) == '=') || \ ((c) == '#') || ((c) == '$') || ((c) == '@') || ((c) == '_') || \ - ((c) == ',') || ((c) == '.') || ((c) == '!') || ((c) == '*')) + ((c) == ',') || ((c) == '.') || ((c) == '!') || ((c) == '*') || \ + ((c) == ':')) #define CHAR_IS_VALID(c) (CHAR_IS_ALPHANUM(c) || CHAR_IS_SPECIAL(c)) #define CHAR_IS_SPACE(c) (((c) == ' ') || ((c) == '\t')) diff --git a/cfg.h b/cfg.h index 87e4218..9603c0b 100644 --- a/cfg.h +++ b/cfg.h @@ -53,6 +53,7 @@ typedef struct { char video_conf_ntsc[1024]; char font[1024]; char shared_folder[1024]; + char custom_aspect_ratio[2][16]; } cfg_t; extern cfg_t cfg; diff --git a/menu.cpp b/menu.cpp index 77d7be2..6035f76 100644 --- a/menu.cpp +++ b/menu.cpp @@ -187,7 +187,6 @@ extern const char *version; const char *config_tos_wrprot[] = { "None", "A:", "B:", "A: and B:" }; const char *config_scanlines_msg[] = { "Off", "HQ2x", "CRT 25%" , "CRT 50%" , "CRT 75%" }; -const char *config_ar_msg[] = { "4:3", "16:9" }; const char *config_blank_msg[] = { "Blank", "Blank+" }; const char *config_dither_msg[] = { "off", "SPT", "RND", "S+R" }; const char *config_autofire_msg[] = { " AUTOFIRE OFF", " AUTOFIRE FAST", " AUTOFIRE MEDIUM", " AUTOFIRE SLOW" }; @@ -877,6 +876,82 @@ void process_addon(char *ext, uint8_t idx) } } +static int get_arc(const char *str) +{ + int arc = 0; + if (!strcmp(str, "[ARC1]")) arc = 1; + else if(!strcmp(str, "[ARC2]")) arc = 2; + else return 0; + + uint32_t x = 0, y = 0; + if (sscanf(cfg.custom_aspect_ratio[arc - 1], "%u:%u", &x, &y) != 2 || x < 1 || x > 4095 || y < 1 || y > 4095) arc = -1; + + return arc; +} + +static int get_ar_name(int ar, char *str) +{ + switch (ar) + { + case 0: + strcat(str, "Original"); + break; + + case 1: + strcat(str, "Full Screen"); + break; + + case 2: + if (get_arc("[ARC1]") <= 0) + { + strcat(str, "Original"); + ar = 0; + } + else + { + strcat(str, cfg.custom_aspect_ratio[0]); + } + break; + + case 3: + if (get_arc("[ARC2]") <= 0) + { + strcat(str, "Original"); + ar = 0; + } + else + { + strcat(str, cfg.custom_aspect_ratio[1]); + } + break; + } + + return ar; +} + +static int next_ar(int ar, int minus) +{ + if (minus) + { + ar = (ar - 1) & 3; + while (1) + { + if (ar == 3 && get_arc("[ARC2]") > 0 && get_arc("[ARC1]") > 0) break; + if (ar == 2 && get_arc("[ARC1]") > 0) break; + if (ar < 2) break; + ar--; + } + } + else + { + ar = (ar + 1) & 3; + if (ar == 3 && get_arc("[ARC2]") <= 0) ar = 0; + if (ar == 2 && get_arc("[ARC1]") <= 0) ar = 0; + } + + return ar; +} + static int joymap_first = 0; static int wm_x = 0; @@ -1292,26 +1367,26 @@ void HandleUI(void) OsdWrite(m++); - strcpy(s, " Aspect ratio: "); - strcat(s, archie_get_ar() ? "16:9" : "4:3"); + strcpy(s, " Aspect Ratio: "); + archie_set_ar(get_ar_name(archie_get_ar(), s)); OsdWrite(m++, s, menusub == 5); - strcpy(s, " Refresh rate: "); + strcpy(s, " Refresh Rate: "); strcat(s, archie_get_60() ? "Variable" : "60Hz"); OsdWrite(m++, s, menusub == 6); - sprintf(s, " Stereo mix: %s", config_stereo_msg[archie_get_amix()]); + sprintf(s, " Stereo Mix: %s", config_stereo_msg[archie_get_amix()]); OsdWrite(m++, s, menusub == 7); - strcpy(s, " 25MHz audio fix: "); + strcpy(s, " 25MHz Audio Fix: "); strcat(s, archie_get_afix() ? "Enable" : "Disable"); OsdWrite(m++, s, menusub == 8); OsdWrite(m++); - sprintf(s, " Swap joysticks: %s", user_io_get_joyswap() ? "Yes" : "No"); + sprintf(s, " Swap Joysticks: %s", user_io_get_joyswap() ? "Yes" : "No"); OsdWrite(m++, s, menusub == 9); - sprintf(s, " Swap mouse btn 2/3: %s", archie_get_mswap() ? "Yes" : "No"); + sprintf(s, " Swap Btn 2/3: %s", archie_get_mswap() ? "Yes" : "No"); OsdWrite(m++, s, menusub == 10); while(m<15) OsdWrite(m++); @@ -1369,7 +1444,7 @@ void HandleUI(void) break; case 5: - archie_set_ar(!archie_get_ar()); + archie_set_ar(next_ar(archie_get_ar(), minus)); menustate = MENU_ARCHIE_MAIN1; break; @@ -1645,8 +1720,9 @@ void HandleUI(void) // get currently active option substrcpy(s, p, 2 + x); - char l = strlen(s); - if (!l) + int l = strlen(s); + int arc = get_arc(s); + if (!l || arc < 0) { // option's index is outside of available values. // reset to 0. @@ -1654,8 +1730,11 @@ void HandleUI(void) //user_io_8bit_set_status(setStatus(p, status, x), 0xffffffff); substrcpy(s, p, 2 + x); l = strlen(s); + arc = get_arc(s); } + if (arc > 0) l = strlen(cfg.custom_aspect_ratio[arc - 1]); + s[0] = ' '; substrcpy(s + 1, p, 1); @@ -1667,7 +1746,8 @@ void HandleUI(void) l = 28 - l - strlen(s); while (l--) strcat(s, " "); - substrcpy(s + strlen(s), p, 2 + x); + if (arc > 0) strcpy(s + strlen(s), cfg.custom_aspect_ratio[arc - 1]); + else substrcpy(s + strlen(s), p, 2 + x); MenuWrite(entry, s, menusub == selentry, d); @@ -1944,14 +2024,14 @@ void HandleUI(void) while(1) { substrcpy(s, p, 2 + x); - if (strlen(s)) break; + if (strlen(s) && get_arc(s) >= 0) break; x = (x - 1) & mask; } } else { substrcpy(s, p, 2 + x); - if (!strlen(s)) x = 0; + if (!strlen(s) || get_arc(s) < 0) x = 0; } user_io_8bit_set_status(setStatus(p, status, x), 0xffffffff, ex); @@ -3495,7 +3575,7 @@ void HandleUI(void) OsdWrite(m++, s, menusub == 7, enable ? 0 : 1); strcpy(s, " Aspect: "); - strcat(s, (tos_system_ctrl() & TOS_CONTROL_VIDEO_AR) ? "16:9" : "4:3"); + tos_set_ar(get_ar_name(tos_get_ar(), s)); OsdWrite(m++, s, menusub == 8); strcpy(s, " Screen: "); @@ -3626,7 +3706,8 @@ void HandleUI(void) break; case 8: - tos_update_sysctrl(tos_system_ctrl() ^ TOS_CONTROL_VIDEO_AR); + tos_set_ar(next_ar(tos_get_ar(), minus)); + tos_update_sysctrl(tos_system_ctrl()); menustate = MENU_ST_SYSTEM1; break; @@ -4971,21 +5052,21 @@ void HandleUI(void) OsdSetTitle("Video", OSD_ARROW_LEFT | OSD_ARROW_RIGHT); OsdWrite(m++); - strcpy(s, " TV Standard : "); + strcpy(s, " TV Standard : "); strcat(s, minimig_config.chipset & CONFIG_NTSC ? "NTSC" : "PAL"); OsdWrite(m++, s, menusub == 0, 0); OsdWrite(m++, "", 0, 0); - strcpy(s, " Scandoubler FX : "); + strcpy(s, " Scandoubler FX: "); strcat(s, config_scanlines_msg[minimig_config.scanlines & 7]); OsdWrite(m++, s, menusub == 1, 0); - strcpy(s, " Video area by : "); + strcpy(s, " Video area by : "); strcat(s, config_blank_msg[(minimig_config.scanlines >> 6) & 3]); OsdWrite(m++, s, menusub == 2, 0); - strcpy(s, " Aspect Ratio : "); - strcat(s, config_ar_msg[(minimig_config.scanlines >> 4) & 1]); + strcpy(s, " Aspect Ratio : "); + minimig_config.scanlines = (get_ar_name((minimig_config.scanlines >> 4) & 3, s) << 4) | (minimig_config.scanlines & ~0x30); OsdWrite(m++, s, menusub == 3, 0); OsdWrite(m++, "", 0, 0); - strcpy(s, " Stereo mix : "); + strcpy(s, " Stereo mix : "); strcat(s, config_stereo_msg[minimig_config.audio & 3]); OsdWrite(m++, s, menusub == 4, 0); OsdWrite(m++, "", 0, 0); @@ -5031,8 +5112,7 @@ void HandleUI(void) } else if (menusub == 3) { - minimig_config.scanlines &= ~0x20; // reserved for auto-ar - minimig_config.scanlines ^= 0x10; + minimig_config.scanlines = (next_ar((minimig_config.scanlines >> 4) & 3, minus) << 4) | (minimig_config.scanlines & ~0x30); minimig_ConfigVideo(minimig_config.scanlines); } else if (menusub == 4) diff --git a/support/archie/archie.cpp b/support/archie/archie.cpp index 293e83a..1d1d8b3 100644 --- a/support/archie/archie.cpp +++ b/support/archie/archie.cpp @@ -78,21 +78,21 @@ const char *archie_get_rom_name(void) void archie_set_ar(char i) { - if (i) config.system_ctrl |= 1; - else config.system_ctrl &= ~1; - user_io_8bit_set_status((i ? -1 : 0), 2); + config.system_ctrl &= ~0b11000000; + config.system_ctrl |= (i & 3) << 6; + user_io_8bit_set_status(config.system_ctrl, 0b11000000); } int archie_get_ar() { - return config.system_ctrl & 1; + return (config.system_ctrl >> 6) & 3; } void archie_set_60(char i) { if (i) config.system_ctrl |= 0b1000; else config.system_ctrl &= ~0b1000; - user_io_8bit_set_status((i ? -1 : 0), 0b10000); + user_io_8bit_set_status(config.system_ctrl, 0b10000); } int archie_get_60() @@ -104,7 +104,7 @@ void archie_set_afix(char i) { if (i) config.system_ctrl |= 0b10000; else config.system_ctrl &= ~0b10000; - user_io_8bit_set_status((i ? -1 : 0), 0b100000); + user_io_8bit_set_status(config.system_ctrl, 0b100000); } int archie_get_afix() diff --git a/support/st/st_tos.cpp b/support/st/st_tos.cpp index a4d3ad2..027421f 100644 --- a/support/st/st_tos.cpp +++ b/support/st/st_tos.cpp @@ -82,6 +82,24 @@ unsigned long tos_system_ctrl() return config.system_ctrl; } +int tos_get_ar() +{ + int ar = 0; + if (config.system_ctrl & TOS_CONTROL_VIDEO_AR1) ar |= 1; + if (config.system_ctrl & TOS_CONTROL_VIDEO_AR2) ar |= 2; + + return ar; +} + +void tos_set_ar(int ar) +{ + if (ar & 1) config.system_ctrl |= TOS_CONTROL_VIDEO_AR1; + else config.system_ctrl &= ~TOS_CONTROL_VIDEO_AR1; + + if (ar & 2) config.system_ctrl |= TOS_CONTROL_VIDEO_AR2; + else config.system_ctrl &= ~TOS_CONTROL_VIDEO_AR2; +} + void tos_uart_mode(int enable) { uart_mode = enable; @@ -632,7 +650,10 @@ const char* tos_get_cfg_string(int num) strcat(str, " "); if (!((tmp.system_ctrl >> 23) & 3) && (tmp.system_ctrl & TOS_CONTROL_BLITTER)) strcat(str, "B "); if (tmp.system_ctrl & TOS_CONTROL_VIKING) strcat(str, "V "); - if (tmp.system_ctrl & TOS_CONTROL_VIDEO_AR) strcat(str, "W "); + int ar = 0; + if (tmp.system_ctrl & TOS_CONTROL_VIDEO_AR1) ar |= 1; + if (tmp.system_ctrl & TOS_CONTROL_VIDEO_AR2) ar |= 2; + sprintf(str+strlen(str), "A%d ", ar); strcat(str, (tmp.system_ctrl & TOS_CONTROL_VIDEO_COLOR) ? "C " : (tmp.system_ctrl & TOS_CONTROL_MDE60) ? "M6 " : "M "); if (!(tmp.system_ctrl & TOS_CONTROL_BORDER)) strcat(str, "F "); int sl = (tmp.system_ctrl >> 20) & 3; diff --git a/support/st/st_tos.h b/support/st/st_tos.h index a034d21..f09ddcf 100644 --- a/support/st/st_tos.h +++ b/support/st/st_tos.h @@ -34,7 +34,7 @@ #define TOS_CONTROL_FDC_WR_PROT_A 0x00000040 #define TOS_CONTROL_FDC_WR_PROT_B 0x00000080 #define TOS_CONTROL_VIDEO_COLOR 0x00000100 // input to mfp -#define TOS_CONTROL_VIDEO_AR 0x00000200 // 16:9 / 4:3 +#define TOS_CONTROL_VIDEO_AR1 0x00000200 // up to eight acsi devices can be enabled #define TOS_ACSI0_ENABLE 0x00000400 @@ -68,6 +68,8 @@ #define TOS_CONTROL_BORDER 0x20000000 #define TOS_CONTROL_MDE60 0x40000000 +#define TOS_CONTROL_VIDEO_AR2 0x80000000 + extern const char* tos_mem[]; extern const char* tos_scanlines[]; extern const char* tos_stereo[]; @@ -95,4 +97,7 @@ int tos_config_exists(int slot); void tos_uart_mode(int enable); +int tos_get_ar(); +void tos_set_ar(int ar); + #endif diff --git a/user_io.h b/user_io.h index f8b03c8..935f30c 100644 --- a/user_io.h +++ b/user_io.h @@ -65,6 +65,7 @@ #define UIO_SETWIDTH 0x37 // Set max scaled horizontal resolution #define UIO_SETSYNC 0x38 #define UIO_SET_AFILTER 0x39 +#define UIO_SET_AR_CUST 0x3A // codes as used by 8bit for file loading from OSD #define FIO_FILE_TX 0x53 diff --git a/video.cpp b/video.cpp index 17cfd51..9561a00 100644 --- a/video.cpp +++ b/video.cpp @@ -208,6 +208,23 @@ static void setScaler() fileTYPE f = {}; static char filename[1024]; + uint32_t arc[4] = {}; + for (int i = 0; i < 2; i++) + { + if (cfg.custom_aspect_ratio[i][0]) + { + if (sscanf(cfg.custom_aspect_ratio[i], "%u:%u", &arc[i * 2], &arc[(i * 2) + 1]) != 2 || arc[i * 2] < 1 || arc[i * 2] > 4095 || arc[(i * 2) + 1] < 1 || arc[(i * 2) + 1] > 4095) + { + arc[(i * 2) + 0] = 0; + arc[(i * 2) + 1] = 0; + } + } + } + + spi_uio_cmd_cont(UIO_SET_AR_CUST); + for (int i = 0; i < 4; i++) spi_w(arc[i]); + DisableIO(); + if (!spi_uio_cmd_cont(UIO_SET_FLTNUM)) { DisableIO();