mirror of
https://github.com/libretro/blastem.git
synced 2026-11-07 10:15:58 -10:00
Draw border lines uncropped while a game runs, say why a load failed, accept bios_MD.bin as the TMSS ROM (#73)
* vdp: pick up a changed overscan crop between frames The crop was only read when a mode register was written. The libretro core's overscan options can be changed while a game runs, and cropping less then left the newly uncropped border lines undrawn - black instead of the backdrop and the CRAM dots in it - until the game happened to change modes. Sonic 1 with the crop switched from Auto to 0 kept 11 black lines at the top and 8 at the bottom (issue #69). Re-read it between frames when it has changed. * libretro: say why a load failed, and take bios_MD.bin as the TMSS ROM Warnings and fatal errors went to stderr only, so a load that failed for a missing file - the TMSS ROM that the Mega Drive 2 models need, say - looked like the core doing nothing at all (issue #69). They now go to the frontend's log, and a failed load puts the reason on screen. Genesis Plus GX reads the same TMSS ROM as bios_MD.bin, the name it is most likely to have in a RetroArch system directory already, so that is used when there is no tmss.md.
This commit is contained in:
1 parent
fd3b7405c7
commit
42db375ba2
2 files changed
+71
-2
No files matched your search
+56
-2
@@ -183,7 +183,7 @@ static const core_option core_options[] = {
|
||||
},
|
||||
{
|
||||
"blastem_model", "Mega Drive Model",
|
||||
"Which revision of the console to emulate. Models from the Mega Drive 2 on have TMSS, which needs a TMSS ROM named tmss.md in the system directory.",
|
||||
"Which revision of the console to emulate. Models from the Mega Drive 2 on have TMSS, which shows the licensed-by-Sega screen at boot and needs the TMSS ROM in the system directory, named tmss.md or bios_MD.bin.",
|
||||
"system", "system\0model\0", model_values
|
||||
},
|
||||
{
|
||||
@@ -512,7 +512,21 @@ RETRO_API void retro_set_environment(retro_environment_t re)
|
||||
//which looks next to the standalone binary and finds nothing in a libretro build.
|
||||
config = tern_insert_path(config, "system\0laseractive_upd_rom\0", (tern_val){.ptrval = alloc_concat(system_dir, "/laseractive_dyw_1322a.bin")}, TVAL_PTR);
|
||||
//Same story for the TMSS ROM every model from the Mega Drive 2 on needs.
|
||||
config = tern_insert_path(config, "system\0tmss_path\0", (tern_val){.ptrval = alloc_concat(system_dir, "/tmss.md")}, TVAL_PTR);
|
||||
//Genesis Plus GX reads the same ROM as bios_MD.bin, which is the name it
|
||||
//is most likely to have in a RetroArch system directory already.
|
||||
char *tmss = alloc_concat(system_dir, "/tmss.md");
|
||||
char *gpgx_tmss = alloc_concat(system_dir, "/bios_MD.bin");
|
||||
FILE *f;
|
||||
if (!(f = fopen(tmss, "rb")) && (f = fopen(gpgx_tmss, "rb"))) {
|
||||
free(tmss);
|
||||
tmss = gpgx_tmss;
|
||||
} else {
|
||||
free(gpgx_tmss);
|
||||
}
|
||||
if (f) {
|
||||
fclose(f);
|
||||
}
|
||||
config = tern_insert_path(config, "system\0tmss_path\0", (tern_val){.ptrval = tmss}, TVAL_PTR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,8 +592,33 @@ const system_media *current_media(void)
|
||||
return &media;
|
||||
}
|
||||
|
||||
//Warnings and errors - a missing BIOS or TMSS ROM among them - otherwise went
|
||||
//to stderr only: not into the frontend's log, and not in front of the user,
|
||||
//for whom a load that failed for a missing file looked like the core doing
|
||||
//nothing at all (issue #69). The last one is kept for retro_load_game() to put
|
||||
//on screen if the load fails.
|
||||
static retro_log_printf_t retro_log;
|
||||
static char last_warning[256];
|
||||
static void lib_log_handler(log_level level, char *message)
|
||||
{
|
||||
if (level < WARN) {
|
||||
return;
|
||||
}
|
||||
snprintf(last_warning, sizeof(last_warning), "%s", message);
|
||||
size_t len = strlen(last_warning);
|
||||
while (len && (last_warning[len - 1] == '\n' || last_warning[len - 1] == '\r')) {
|
||||
last_warning[--len] = 0;
|
||||
}
|
||||
if (retro_log) {
|
||||
retro_log(level > WARN ? RETRO_LOG_ERROR : RETRO_LOG_WARN, "%s\n", last_warning);
|
||||
}
|
||||
}
|
||||
|
||||
RETRO_API void retro_init(void)
|
||||
{
|
||||
struct retro_log_callback log_cb;
|
||||
retro_log = retro_environment(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log_cb) ? log_cb.log : NULL;
|
||||
register_log_handler(lib_log_handler);
|
||||
render_audio_initialized(RENDER_AUDIO_S16, 53693175 / (7 * 6 * 4), 2, AUDIO_BATCH_FRAMES, sizeof(int16_t));
|
||||
}
|
||||
|
||||
@@ -958,7 +997,22 @@ static void release_media(void)
|
||||
|
||||
/* Loads a game. */
|
||||
static system_type stype;
|
||||
static bool load_game(const struct retro_game_info *game);
|
||||
RETRO_API bool retro_load_game(const struct retro_game_info *game)
|
||||
{
|
||||
last_warning[0] = 0;
|
||||
if (load_game(game)) {
|
||||
return 1;
|
||||
}
|
||||
//The frontend only says the content failed to load, or not even that; say why.
|
||||
if (last_warning[0]) {
|
||||
struct retro_message msg = { last_warning, 600 };
|
||||
retro_environment(RETRO_ENVIRONMENT_SET_MESSAGE, &msg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool load_game(const struct retro_game_info *game)
|
||||
{
|
||||
serialize_size_cache = 0;
|
||||
stype = SYSTEM_UNKNOWN;
|
||||
|
||||
@@ -82,10 +82,16 @@ static uint32_t calc_crop(uint32_t crop, uint32_t border)
|
||||
return crop >= border ? 0 : border - crop;
|
||||
}
|
||||
|
||||
//render_overscan_top/bot() as update_video_params() last saw them. Not in
|
||||
//vdp_context: there is only ever one VDP whose output is shown.
|
||||
static uint32_t applied_top_crop, applied_bot_crop;
|
||||
|
||||
static void update_video_params(vdp_context *context)
|
||||
{
|
||||
uint32_t top_crop = render_overscan_top();
|
||||
uint32_t bot_crop = render_overscan_bot();
|
||||
applied_top_crop = top_crop;
|
||||
applied_bot_crop = bot_crop;
|
||||
uint32_t border_top;
|
||||
if (context->regs[REG_MODE_2] & BIT_MODE_5) {
|
||||
if (context->regs[REG_MODE_2] & BIT_PAL) {
|
||||
@@ -3108,6 +3114,15 @@ static void advance_output_line(vdp_context *context)
|
||||
context->h40_lines = 0;
|
||||
context->frame++;
|
||||
context->output_lines = 0;
|
||||
//The crop is otherwise only read when a mode register is written, so
|
||||
//cropping less while a game runs - the libretro core's overscan options
|
||||
//can be changed at any time - left the uncropped border lines undrawn,
|
||||
//black instead of the backdrop and the CRAM dots in it, until the game
|
||||
//happened to change modes. Between frames is the one safe place to pick
|
||||
//it up.
|
||||
if (applied_top_crop != render_overscan_top() || applied_bot_crop != render_overscan_bot()) {
|
||||
update_video_params(context);
|
||||
}
|
||||
}
|
||||
|
||||
if (output_line < context->inactive_start + context->border_bot) {
|
||||
|
||||
Reference in new issue
Block a user