(libretro) Prevent illegal usage of RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO/RETRO_ENVIRO...
authorjdgleaver <james@leaver.myzen.co.uk>
Tue, 5 Apr 2022 09:53:16 +0000 (10:53 +0100)
committeririxxxx <31696370+irixxxx@users.noreply.github.com>
Fri, 8 Apr 2022 16:24:53 +0000 (18:24 +0200)
platform/libretro/libretro.c

index 00cf4da..fb10bd9 100644 (file)
@@ -102,6 +102,9 @@ static int vout_width, vout_height, vout_offset;
 static float vout_aspect = 0.0;
 static int vout_ghosting = 0;
 
+static bool libretro_update_av_info = false;
+static bool libretro_update_geometry = false;
+
 #if defined(RENDER_GSKIT_PS2)
 #define VOUT_8BIT_WIDTH 328
 #define VOUT_8BIT_HEIGHT 256
@@ -603,8 +606,6 @@ static void apply_renderer()
 
 void emu_video_mode_change(int start_line, int line_count, int start_col, int col_count)
 {
-   struct retro_system_av_info av_info;
-
    vm_current_start_line = start_line;
    vm_current_line_count = line_count;
    vm_current_start_col = start_col;
@@ -653,9 +654,8 @@ void emu_video_mode_change(int start_line, int line_count, int start_col, int co
 #endif
    Pico.m.dirtyPal = 1;
 
-   // Update the geometry
-   retro_get_system_av_info(&av_info);
-   environ_cb(RETRO_ENVIRONMENT_SET_GEOMETRY, &av_info);
+   /* Notify frontend of geometry update */
+   libretro_update_geometry = true;
 }
 
 void emu_32x_startup(void)
@@ -1327,6 +1327,15 @@ bool retro_load_game(const struct retro_game_info *info)
 
    init_frameskip();
 
+   /* Initialisation routines may have 'triggered'
+    * a libretro AV info or geometry update; this
+    * happens automatically after retro_load_game(),
+    * so disable the relevant flags here to avoid
+    * redundant updates on the first call of
+    * retro_run() */
+   libretro_update_av_info = false;
+   libretro_update_geometry = false;
+
    return true;
 }
 
@@ -1585,13 +1594,9 @@ static void update_variables(bool first_run)
          vout_aspect = VOUT_PAR;
    }
 
+   /* Notify frontend of geometry update */
    if (vout_aspect != old_vout_aspect)
-   {
-      // Update the geometry
-      struct retro_system_av_info av_info;
-      retro_get_system_av_info(&av_info);
-      environ_cb(RETRO_ENVIRONMENT_SET_GEOMETRY, &av_info);
-   }
+      libretro_update_geometry = true;
 
    var.value = NULL;
    var.key = "picodrive_sprlim";
@@ -1690,16 +1695,15 @@ static void update_variables(bool first_run)
    var.value = NULL;
    var.key = "picodrive_sound_rate";
    if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
-      new_sound_rate = atoi(var.value);
       if (!strcmp(var.value, "native"))
-        new_sound_rate = YM2612_NATIVE_RATE();
+         new_sound_rate = YM2612_NATIVE_RATE();
+      else
+         new_sound_rate = atoi(var.value);
       if (new_sound_rate != PicoIn.sndRate) {
          /* Update the sound rate */
          PicoIn.sndRate = new_sound_rate;
          PsndRerate(!first_run);
-         struct retro_system_av_info av_info;
-         retro_get_system_av_info(&av_info);
-         environ_cb(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &av_info);
+         libretro_update_av_info = true;
       }
    }
 
@@ -1787,6 +1791,19 @@ void retro_run(void)
 
    PicoFrame();
 
+   /* Check whether frontend needs to be notified
+    * of timing/geometry changes */
+   if (libretro_update_av_info || libretro_update_geometry) {
+      struct retro_system_av_info av_info;
+      retro_get_system_av_info(&av_info);
+      environ_cb(libretro_update_av_info ?
+            RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO :
+            RETRO_ENVIRONMENT_SET_GEOMETRY,
+            &av_info);
+      libretro_update_av_info = false;
+      libretro_update_geometry = false;
+   }
+
    /* If frame was skipped, call video_cb() with
     * a NULL buffer and return immediately */
    if (PicoIn.skipFrame) {