diff --git a/MiSTer.ini b/MiSTer.ini index 56164db..e55cc5e 100644 --- a/MiSTer.ini +++ b/MiSTer.ini @@ -195,3 +195,14 @@ bt_reset_before_pair=0 ; This option cannot be used when defmra in CONFSTR is used (i.e. if arcade rbf is loaded directly not through MRA). ; This option is ignored for Menu core. ;waitmount=/media/usb0 + +; Overrides for video mode +; When the core's video mode matches the parameters in the section header, any options in the section override options from MiSTer and core sections. +; Refresh rate in header is optional and, if present, must match exactly the output from video_info or the logs. For example, if it says "60.0Hz", the header needs to be "@60.0" to match. +; When the core changes video mode, MiSTer will first look for a matching WIDTHxHEIGHT@VREFRESH section. +; If no match is found, it will fall back to a matching WIDTHxHEIGHT section with no refresh rate. +; If there is still no match, MiSTer/core options will be used without overrides. +; [video=640x400] +; ... +; [video=640x400@70.1] +; ... diff --git a/cfg.cpp b/cfg.cpp index f5ee87c..46a3fdb 100644 --- a/cfg.cpp +++ b/cfg.cpp @@ -11,6 +11,7 @@ #include "debug.h" #include "file_io.h" #include "user_io.h" +#include "video.h" cfg_t cfg; @@ -121,6 +122,9 @@ static const int nvars = (int)(sizeof(ini_vars) / sizeof(ini_var_t)); fileTYPE ini_file; +static bool has_video_sections = false; +static bool using_video_section = false; + int ini_pt = 0; static char ini_getch() { @@ -148,7 +152,7 @@ static int ini_getline(char* line) return c == 0; } -static int ini_get_section(char* buf) +static int ini_get_section(char* buf, const char *vmode) { int i = 0; int incl = (buf[0] == INCL_SECTION); @@ -161,6 +165,7 @@ static int ini_get_section(char* buf) else buf++; int wc_pos = -1; + int eq_pos = -1; // get section stop marker while (buf[i]) @@ -172,6 +177,7 @@ static int ini_get_section(char* buf) } if (buf[i] == '*') wc_pos = i; + if (buf[i] == '=') eq_pos = i; i++; if (i >= INI_LINE_SIZE) return 0; @@ -192,6 +198,20 @@ static int ini_get_section(char* buf) } return 1; } + else if ((eq_pos >= 0) && !strncasecmp(buf, "video", eq_pos)) + { + has_video_sections = true; + if(!strcasecmp(&buf[eq_pos+1], vmode)) + { + using_video_section = true; + ini_parser_debugf("Got SECTION '%s'", buf); + return 1; + } + else + { + return 0; + } + } return 0; } @@ -279,13 +299,13 @@ static void ini_parse_var(char* buf) } } -static void ini_parse(int alt) +static void ini_parse(int alt, const char *vmode) { static char line[INI_LINE_SIZE]; int section = 0; int eof; - ini_parser_debugf("Start INI parser for core \"%s\"(%s).", user_io_get_core_name(0), user_io_get_core_name(1)); + ini_parser_debugf("Start INI parser for core \"%s\"(%s), video mode \"%s\".", user_io_get_core_name(0), user_io_get_core_name(1), vmode); memset(line, 0, sizeof(line)); memset(&ini_file, 0, sizeof(ini_file)); @@ -307,11 +327,11 @@ static void ini_parse(int alt) if (line[0] == INI_SECTION_START) { // if first char in line is INI_SECTION_START, get section - section = ini_get_section(line); + section = ini_get_section(line, vmode); } else if (line[0] == INCL_SECTION && !section) { - section = ini_get_section(line); + section = ini_get_section(line, vmode); } else if(section) { @@ -351,5 +371,17 @@ void cfg_parse() cfg.browse_expand = 1; cfg.logo = 1; cfg.rumble = 1; - ini_parse(altcfg()); + has_video_sections = false; + using_video_section = false; + ini_parse(altcfg(), video_get_core_mode_name(1)); + if (has_video_sections && !using_video_section) + { + // second pass to look for section without vrefresh + ini_parse(altcfg(), video_get_core_mode_name(0)); + } +} + +bool cfg_has_video_sections() +{ + return has_video_sections; } diff --git a/cfg.h b/cfg.h index 80d9cff..16ca733 100644 --- a/cfg.h +++ b/cfg.h @@ -77,5 +77,6 @@ extern cfg_t cfg; //// functions //// void cfg_parse(); const char* cfg_get_name(uint8_t alt); +bool cfg_has_video_sections(); #endif // __CFG_H__ diff --git a/video.cpp b/video.cpp index 49e3c6d..0e0d25c 100644 --- a/video.cpp +++ b/video.cpp @@ -1145,6 +1145,25 @@ void video_scaler_description(char *str, size_t len) video_scaler_description(¤t_video_info, &v_cur, str, len); } +char* video_get_core_mode_name(int with_vrefresh) +{ + static char tmp[256] = {}; + + if (with_vrefresh) + { + float vrate = 100000000; + if (current_video_info.vtime) vrate /= current_video_info.vtime; else vrate = 0; + + snprintf(tmp, sizeof(tmp), "%dx%d@%.1f", current_video_info.width, current_video_info.height, vrate); + } + else + { + snprintf(tmp, sizeof(tmp), "%dx%d", current_video_info.width, current_video_info.height); + } + + return tmp; +} + static void show_video_info(const VideoInfo *vi, const vmode_custom_t *vm) { float vrate = 100000000; @@ -1230,10 +1249,17 @@ void video_mode_adjust() if (vid_changed || force) { + current_video_info = video_info; + + if (cfg_has_video_sections()) + { + cfg_parse(); + video_mode_load(); + user_io_send_buttons(1); + } + show_video_info(&video_info, &v_cur); video_scaling_adjust(&video_info); - - current_video_info = video_info; } force = false; diff --git a/video.h b/video.h index 2a86464..be553aa 100644 --- a/video.h +++ b/video.h @@ -49,6 +49,7 @@ void video_cmd(char *cmd); bool video_is_rotated(); void video_core_description(char *str, size_t len); void video_scaler_description(char *str, size_t len); +char* video_get_core_mode_name(int with_vrefresh = 1); #endif // VIDEO_H