[gnome-games] playstation: Parse disc images to detect games



commit 1f52eb5b9146fa7c44b1fda49106082cfabd3192
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Sat Jul 15 11:42:30 2017 +0200

    playstation: Parse disc images to detect games
    
    Replace the detection of games and the extraction of data like the disc
    ID for lucky guesses of the position of the PlayStation header by proper
    parsing of the disc image.
    
    This should detect previously undetected games without any regression.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=775255

 plugins/playstation/src/playstation-header.vala |  104 ++++++-----------------
 1 files changed, 26 insertions(+), 78 deletions(-)
---
diff --git a/plugins/playstation/src/playstation-header.vala b/plugins/playstation/src/playstation-header.vala
index 19d1275..b63c447 100644
--- a/plugins/playstation/src/playstation-header.vala
+++ b/plugins/playstation/src/playstation-header.vala
@@ -1,24 +1,7 @@
 // This file is part of GNOME Games. License: GPL-3.0+.
 
 private class Games.PlayStationHeader : Object {
-       private const size_t[] HEADER_OFFSETS = {
-               0x85D2, // .bin.ecm
-               0x9320, // .bin
-               0x9360, // .iso 
-       };
-       private const size_t HEADER_TITLE_OFFSET = 0x20;
-       private const string HEADER_MAGIC_VALUE = "PLAYSTATION";
-
-       private const size_t[] BOOT_OFFSETS = {
-               0xBE64, // .bin.ecm
-               0xD368, // .bin
-               0xD3A8, // .iso
-               0xA9F98, // .bin
-       };
-       private const string BOOT_MAGIC_VALUE = "BOOT";
-
        // The ID prefixes must always be in uppercase.
-       private const string[] IDS = { "SLUS", "SCUS", "SLES", "SCES", "SLPS", "SLPM", "SCPS" };
        private const size_t DISC_ID_SIZE = 10;
 
        private static Regex disc_id_regex;
@@ -38,83 +21,45 @@ private class Games.PlayStationHeader : Object {
                if (_disc_id != null)
                        return;
 
-               _disc_id = get_id_from_boot ();
+               string label;
+               string exe;
+               if (!get_playstation_info (file.get_path (), out label, out exe))
+                       throw new PlayStationError.INVALID_HEADER (_("Not a PlayStation disc: ā€œ%sā€."), 
file.get_uri ());
+
+               _disc_id = parse_id_from_exe (exe);
                if (_disc_id != null)
                        return;
 
-               _disc_id = search_id_in_header ();
+               _disc_id = parse_id_from_label (label);
                if (_disc_id != null)
                        return;
 
                throw new PlayStationError.INVALID_HEADER (_("Invalid PlayStation header: disc ID not found 
in ā€œ%sā€."), file.get_uri ());
        }
 
-       private string? search_id_in_header () throws Error {
-               var offset = get_header_offset ();
-               if (offset == null)
-                       return null;
-
-               var stream = new StringInputStream (file);
-               var header = stream.read_string_for_size (offset + HEADER_TITLE_OFFSET, DISC_ID_SIZE);
-
-               var raw_id = header.up ();
-               raw_id = raw_id.replace ("_", "-");
-
-               foreach (var id in IDS) {
-                       if (!(id in header))
-                               continue;
-
-                       if (is_a_disc_id (raw_id))
-                               return raw_id;
-               }
-
-               return null;
-       }
-
-       private size_t? get_header_offset () throws Error {
-               var stream = new StringInputStream (file);
+       private string? parse_id_from_exe (string exe) throws Error {
+               var disc_id = exe.strip ();
+               disc_id = disc_id.split (";")[0];
+               disc_id = disc_id.replace ("_", "-");
+               disc_id = disc_id.replace (".", "");
+               disc_id = disc_id.up ();
 
-               foreach (var offset in HEADER_OFFSETS)
-                       if (stream.has_string (offset, HEADER_MAGIC_VALUE))
-                               return offset;
-
-               return null;
-       }
-
-       private string? get_id_from_boot () throws Error {
-               var offset = get_boot_offset ();
-               if (offset == null)
+               if (!is_a_disc_id (disc_id))
                        return null;
 
-               var stream = new StringInputStream (file);
-               var header = stream.read_string (offset);
-               header = header.up ();
-
-               foreach (var id in IDS) {
-                       if (!(id in header))
-                               continue;
-
-                       var raw_id = header.split (id)[1];
-                       raw_id = raw_id.split (";")[0];
-                       raw_id = raw_id.replace ("_", "-");
-                       raw_id = raw_id.replace (".", "");
-                       raw_id = (id + raw_id).up ();
-
-                       if (is_a_disc_id (raw_id))
-                               return raw_id;
-               }
-
-               return null;
+               return disc_id;
        }
 
-       private size_t? get_boot_offset () throws Error {
-               var stream = new StringInputStream (file);
+       private string? parse_id_from_label (string label) throws Error {
+               var disc_id = label.strip ();
+               disc_id = disc_id.replace ("_", "-");
+               disc_id = disc_id.strip ();
+               disc_id = disc_id.up ();
 
-               foreach (var offset in BOOT_OFFSETS)
-                       if (stream.has_string (offset, BOOT_MAGIC_VALUE))
-                               return offset;
+               if (!is_a_disc_id (disc_id))
+                       return null;
 
-               return null;
+               return disc_id;
        }
 
        private static bool is_a_disc_id (string disc_id) {
@@ -123,4 +68,7 @@ private class Games.PlayStationHeader : Object {
 
                return disc_id_regex.match (disc_id);
        }
+
+       [CCode (cname = "get_playstation_info")]
+       private static extern bool get_playstation_info (string filename, out string label, out string exe) 
throws Error;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]