[gnome-games] retro-runner: Use temporary savestate
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games] retro-runner: Use temporary savestate
- Date: Fri, 9 Aug 2019 13:38:58 +0000 (UTC)
commit 1f1357edaa768d17db331f044f34de1016523158
Author: Yetizone <andreii lisita gmail com>
Date: Thu Jun 6 16:16:11 2019 +0300
retro-runner: Use temporary savestate
src/command/command-runner.vala | 2 +-
src/core/runner.vala | 2 +-
src/dummy/dummy-runner.vala | 2 +-
src/retro/retro-runner.vala | 231 +++++++++++++++++++---------------------
src/ui/display-view.vala | 2 +-
5 files changed, 115 insertions(+), 124 deletions(-)
---
diff --git a/src/command/command-runner.vala b/src/command/command-runner.vala
index 03256016..43dcca95 100644
--- a/src/command/command-runner.vala
+++ b/src/command/command-runner.vala
@@ -28,7 +28,7 @@ public class Games.CommandRunner : Object, Runner {
this.args = args;
}
- public bool check_is_valid (out string error_message) throws Error {
+ public bool try_init_phase_one (out string error_message) {
if (args.length > 0) {
error_message = "";
diff --git a/src/core/runner.vala b/src/core/runner.vala
index df28e351..f4b9bd68 100644
--- a/src/core/runner.vala
+++ b/src/core/runner.vala
@@ -9,7 +9,7 @@ public interface Games.Runner : Object {
public abstract MediaSet? media_set { get; }
public abstract InputMode input_mode { get; set; }
- public abstract bool check_is_valid (out string error_message) throws Error;
+ public abstract bool try_init_phase_one (out string error_message);
public abstract Gtk.Widget get_display ();
public abstract Gtk.Widget? get_extra_widget ();
public abstract void start () throws Error;
diff --git a/src/dummy/dummy-runner.vala b/src/dummy/dummy-runner.vala
index b8e697f1..595f3583 100644
--- a/src/dummy/dummy-runner.vala
+++ b/src/dummy/dummy-runner.vala
@@ -22,7 +22,7 @@ private class Games.DummyRunner : Object, Runner {
set { }
}
- public bool check_is_valid (out string error_message) throws Error {
+ public bool try_init_phase_one (out string error_message) {
error_message = "";
return true;
diff --git a/src/retro/retro-runner.vala b/src/retro/retro-runner.vala
index 17b4900e..ad5bc925 100644
--- a/src/retro/retro-runner.vala
+++ b/src/retro/retro-runner.vala
@@ -13,24 +13,7 @@ public class Games.RetroRunner : Object, Runner {
}
public bool can_resume {
- get {
- try {
- init ();
-
- // Check if the core can support savestates
- if (!core.get_can_access_state ())
- return false;
-
- // Check if there are any existing savestates
- if (game_savestates.length != 0)
- return true;
- }
- catch (Error e) {
- warning (e.message);
- }
-
- return false;
- }
+ get { return game_savestates.length != 0; }
}
private MediaSet _media_set;
@@ -60,6 +43,7 @@ public class Games.RetroRunner : Object, Runner {
private Title game_title;
private Savestate[] game_savestates;
private Savestate latest_savestate;
+ private Savestate tmp_live_savestate;
private bool _running;
private bool running {
@@ -106,10 +90,16 @@ public class Games.RetroRunner : Object, Runner {
deinit ();
}
- public bool check_is_valid (out string error_message) throws Error {
+ // init_phase_one attempts to init everything that can be init-ed right away
+ // It is called by the DisplayView to check if a runner can be used
+ // This method must be called before other methods/properties
+ public bool try_init_phase_one (out string error_message) {
+ // Step 1) Check for the two RetroErrors -------------------------------
+ // FIXME: Write this properly using RetroCoreManager
+ /*
try {
media_set.selected_media_number = 0;
- init ();
+ //init ();
}
catch (RetroError.MODULE_NOT_FOUND e) {
debug (e.message);
@@ -123,9 +113,49 @@ public class Games.RetroRunner : Object, Runner {
return false;
}
+ */
- error_message = "";
+ // Step 2) Load the game's savestates ----------------------------------
+ try {
+ core_source.get_module_path (); // FIXME: Hack needed to get core_id
+ string core_id = null;
+
+ if (core_descriptor != null) {
+ core_id = core_descriptor.get_id ();
+ }
+ else {
+ core_id = core_source.get_core_id ();
+ }
+
+ game_savestates = Savestate.get_game_savestates (uid, core_id);
+ if (game_savestates.length != 0)
+ latest_savestate = game_savestates[0];
+ }
+ catch (Error e) {
+ error_message = e.message;
+ return false;
+ }
+ // Step 3) Init the CoreView -------------------------------------------
+ // This is done here such that get_display() won't return null
+ view = new Retro.CoreView ();
+ settings.changed["video-filter"].connect (on_video_filter_changed);
+ on_video_filter_changed ();
+
+ // Step 4) Display the screenshot of the latest_savestate --------------
+ // FIXME: This does not work currently, but perhaps we can fix it
+ // somehow in retro-gtk ? We should be able to render a picture on the
+ // screen without having to boot the core itself
+ try {
+ load_screenshot ();
+ }
+ catch (Error e) {
+ error_message = e.message;
+ return false;
+ }
+
+ // Nothing went wrong
+ error_message = "";
return true;
}
@@ -141,10 +171,14 @@ public class Games.RetroRunner : Object, Runner {
if (latest_savestate != null && latest_savestate.has_media_data ())
media_set.selected_media_number = latest_savestate.get_media_data ();
- if (!is_initialized)
- init ();
+ if (!is_initialized) {
+ if (latest_savestate != null)
+ tmp_live_savestate = latest_savestate.clone_in_tmp ();
+ else
+ tmp_live_savestate = Savestate.create_empty_in_tmp ();
- loop.stop ();
+ init_phase_two (tmp_live_savestate.get_save_directory_path ());
+ }
if (!is_ready) {
if (latest_savestate != null)
@@ -159,41 +193,34 @@ public class Games.RetroRunner : Object, Runner {
}
public void resume () throws Error {
- if (!is_initialized)
- init ();
-
- loop.stop ();
-
- if (!is_ready) {
- load_latest_savestate ();
+ if (is_ready) {
+ // In this case, the effect is to simply "unpause" an already running game
+ loop.start ();
}
+ else {
+ // In this case, the effect is to load the data from a savestate and
+ // run the game
+ if (!is_initialized) {
+ tmp_live_savestate = latest_savestate.clone_in_tmp ();
+ init_phase_two (tmp_live_savestate.get_save_directory_path ());
+ }
- loop.start ();
- running = true;
- }
+ loop.stop ();
- private void load_latest_savestate () throws Error {
- // TODO: This method assumes that there exists at least a savestate
- // [Yeti]: Perhaps we should bug-proof this using an Assert ?
- load_save_ram (latest_savestate.get_save_ram_path ());
- core.reset ();
- core.set_state (latest_savestate.get_snapshot_data ());
+ // TODO: This will become "load_data_from_arbitrary_savestate ()"
+ load_data_from_latest_savestate ();
- if (latest_savestate.has_media_data ())
- media_set.selected_media_number = latest_savestate.get_media_data ();
+ loop.start ();
+ }
- is_ready = true;
+ // In both cases the game is now running
+ running = true;
}
- private void init () throws Error {
- if (is_initialized)
- return;
-
- view = new Retro.CoreView ();
- settings.changed["video-filter"].connect (on_video_filter_changed);
- on_video_filter_changed ();
-
- prepare_core ();
+ // init_phase_two is used to setup the core, which needs to have the savestate
+ // in /tmp created and ready
+ private void init_phase_two (string core_save_directory_path) throws Error {
+ prepare_core (core_save_directory_path);
var present_analog_sticks = input_capabilities == null ||
input_capabilities.get_allow_analog_gamepads ();
input_manager = new RetroInputManager (core, view, present_analog_sticks);
@@ -207,23 +234,20 @@ public class Games.RetroRunner : Object, Runner {
loop = new Retro.MainLoop (core);
running = false;
- // Load the game's savestates if there are any
- string core_id = null;
-
- if (core_descriptor != null) {
- core_id = core_descriptor.get_id ();
- }
- else {
- core_id = core_source.get_core_id ();
- }
+ is_initialized = true;
+ }
- game_savestates = Savestate.get_game_savestates (uid, core_id);
- if (game_savestates.length != 0)
- latest_savestate = game_savestates[0];
+ private void load_data_from_latest_savestate () throws Error {
+ // TODO: This method assumes that there exists at least a savestate
+ // [Yeti]: Perhaps we should bug-proof this using an Assert ?
+ load_save_ram (latest_savestate.get_save_ram_path ());
+ core.reset ();
+ core.set_state (latest_savestate.get_snapshot_data ());
- load_screenshot ();
+ if (latest_savestate.has_media_data ())
+ media_set.selected_media_number = latest_savestate.get_media_data ();
- is_initialized = true;
+ is_ready = true;
}
private void deinit () {
@@ -252,7 +276,7 @@ public class Games.RetroRunner : Object, Runner {
view.set_filter (filter);
}
- private void prepare_core () throws Error {
+ private void prepare_core (string save_directory_path) throws Error {
string module_path;
if (core_descriptor != null) {
var module_file = core_descriptor.get_module_file ();
@@ -282,11 +306,7 @@ public class Games.RetroRunner : Object, Runner {
var platform_id = platform.get_id ();
core.system_directory = @"$platforms_dir/$platform_id/system";
- if (latest_savestate != null) {
- var save_directory = latest_savestate.get_save_directory_path ();
- Application.try_make_dir (save_directory);
- core.save_directory = save_directory;
- }
+ core.save_directory = save_directory_path;
core.log.connect (Retro.g_log);
view.set_core (core);
@@ -411,29 +431,28 @@ public class Games.RetroRunner : Object, Runner {
}
public void attempt_create_savestate () throws Error {
+ if (!core.get_can_access_state ()) // Check if the core can support savestates
+ return;
+
if (!should_save)
return;
- // Create a new savestate
- var game_savestates_dir_path = get_game_savestates_dir_path ();
- var now_time_str = TimeVal ().to_iso8601 ();
- var new_savestate_path = Path.build_filename (game_savestates_dir_path, now_time_str);
- var new_savestate_dir = File.new_for_path (new_savestate_path);
+ store_save_ram_in_tmp ();
+ // TODO: Also save the media data in tmp_savestate
+ tmp_live_savestate.set_snapshot_data (core.get_state ());
+ save_screenshot_in_tmp ();
- new_savestate_dir.make_directory ();
+ // Save the tmp_live_savestate into the game savestates directory
+ var game_savestates_dir_path = get_game_savestates_dir_path ();
+ tmp_live_savestate.save_in (game_savestates_dir_path);
+ should_save = false;
+ /*
store_save_ram (new_savestate_dir);
if (media_set.get_size () > 1)
save_media_data (new_savestate_dir);
-
- if (!core.get_can_access_state ())
- return;
-
- save_snapshot (new_savestate_dir);
- save_screenshot (new_savestate_dir);
-
- should_save = false;
+ */
}
private string get_options_path () throws Error {
@@ -448,16 +467,13 @@ public class Games.RetroRunner : Object, Runner {
return @"$(Config.OPTIONS_DIR)/$options_name.options";
}
- private void store_save_ram (File savestate_dir) throws Error{
+ private void store_save_ram_in_tmp () throws Error {
var bytes = core.get_memory (Retro.MemoryType.SAVE_RAM);
var save = bytes.get_data ();
if (save.length == 0)
return;
- var savestate_dir_path = savestate_dir.get_path ();
- var save_ram_path = Path.build_filename (savestate_dir_path, "save");
-
- FileUtils.set_data (save_ram_path, save);
+ tmp_live_savestate.set_save_ram_data (save);
}
private void load_save_ram (string save_ram_path) throws Error {
@@ -475,35 +491,12 @@ public class Games.RetroRunner : Object, Runner {
core.set_memory (Retro.MemoryType.SAVE_RAM, bytes);
}
- private void save_snapshot (File savestate_dir) throws Error {
- var bytes = core.get_state ();
- var buffer = bytes.get_data ();
-
- var savestate_dir_path = savestate_dir.get_path ();
- var snapshot_path = Path.build_filename (savestate_dir_path, "snapshot");
-
- FileUtils.set_data (snapshot_path, buffer);
- }
-
- private void save_media_data (File savestate_dir) throws Error {
- var savestate_dir_path = savestate_dir.get_path ();
- var media_path = Path.build_filename (savestate_dir_path, "media");
-
- string contents = media_set.selected_media_number.to_string ();
-
- FileUtils.set_contents (media_path, contents, contents.length);
- }
-
- private void save_screenshot (File savestate_dir) throws Error {
- if (!core.get_can_access_state ())
- return;
-
+ private void save_screenshot_in_tmp () throws Error {
var pixbuf = view.get_pixbuf ();
if (pixbuf == null)
return;
- var savestate_dir_path = savestate_dir.get_path ();
- var screenshot_path = Path.build_filename (savestate_dir_path, "screenshot");
+ var screenshot_path = tmp_live_savestate.get_screenshot_path ();
var now = new GLib.DateTime.now_local ();
var creation_time = now.to_string ();
@@ -532,14 +525,11 @@ public class Games.RetroRunner : Object, Runner {
null);
}
+ // Display the screenshot of the latest savestate
private void load_screenshot () throws Error {
- if (!core.get_can_access_state ())
- return;
-
if (game_savestates.length == 0)
return;
- // Load the screenshot of the latest savestate
var screenshot_path = latest_savestate.get_screenshot_path ();
if (!FileUtils.test (screenshot_path, FileTest.EXISTS))
@@ -567,3 +557,4 @@ public class Games.RetroRunner : Object, Runner {
return core;
}
}
+
diff --git a/src/ui/display-view.vala b/src/ui/display-view.vala
index d053ddbc..65812275 100644
--- a/src/ui/display-view.vala
+++ b/src/ui/display-view.vala
@@ -228,7 +228,7 @@ private class Games.DisplayView : Object, UiView {
try {
var runner = game.get_runner ();
string error_message;
- if (runner.check_is_valid (out error_message))
+ if (runner.try_init_phase_one (out error_message))
return runner;
reset_display_page ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]