[gnome-games] mega-drive: Add 'system' prop to MegaDriveHeader



commit c296b7a3c1ee5472e64b2192c0b22032a4f9ceaa
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Wed Aug 3 11:08:38 2016 +0200

    mega-drive: Add 'system' prop to MegaDriveHeader
    
    This will be used in the next commit to discriminate the different
    systems of the Mega Drive family.

 plugins/mega-drive/src/mega-drive-header.vala |   73 +++++++++++++++++++++----
 1 files changed, 63 insertions(+), 10 deletions(-)
---
diff --git a/plugins/mega-drive/src/mega-drive-header.vala b/plugins/mega-drive/src/mega-drive-header.vala
index 78f9715..11ca0ef 100644
--- a/plugins/mega-drive/src/mega-drive-header.vala
+++ b/plugins/mega-drive/src/mega-drive-header.vala
@@ -2,13 +2,12 @@
 
 // Documentation: https://en.wikibooks.org/wiki/Genesis_Programming
 private class Games.MegaDriveHeader : Object {
-       private const size_t MAGIC_OFFSET = 0x100;
-       private const size_t MAGIC_SIZE = 0xf;
-       private const string[] MAGIC_VALUES = {
-               "SEGA MEGA DRIVE",
-               "SEGA GENESIS",
-               "SEGA 32X",
-       };
+       private const size_t[] POSSIBLE_HEADER_OFFSETS = { 0x0, 0x10 };
+
+       private const size_t CD_OFFSET = 0x0;
+
+       private const size_t SYSTEM_OFFSET = 0x100;
+       private const size_t SYSTEM_SIZE = 0xf;
 
        private const size_t DOMESTIC_NAME_OFFSET = 0x120;
        private const size_t NAME_SIZE = 0x30;
@@ -31,19 +30,73 @@ private class Games.MegaDriveHeader : Object {
                }
        }
 
+       private MegaDriveSystem? _system;
+       public MegaDriveSystem system {
+               get {
+                       if (_system != null)
+                               return _system;
+
+                       try {
+                               _system = parse_system ();
+                       }
+                       catch (Error e) {
+                               debug (e.message);
+
+                               _system = MegaDriveSystem.INVALID;
+                       }
+
+                       return _system;
+               }
+       }
+
        private File file;
+       private size_t? offset;
 
        public MegaDriveHeader (File file) {
                this.file = file;
        }
 
        public void check_validity () throws Error {
+               if (system == MegaDriveSystem.INVALID)
+                       throw new MegaDriveError.INVALID_HEADER (_("The file doesn't have a Genesis/Sega 
32X/Sega CD/Sega Pico header."));
+       }
+
+       public size_t get_offset () throws Error {
+               if (offset != null)
+                       return offset;
+
                var stream = new StringInputStream (file);
-               var magic = stream.read_string_for_size (MAGIC_OFFSET, MAGIC_SIZE);
-               magic = magic.chomp ();
-               if (!(magic in MAGIC_VALUES))
+
+               foreach (var possible_offset in POSSIBLE_HEADER_OFFSETS)
+                       if (stream.has_string (possible_offset + SYSTEM_OFFSET, "SEGA")) {
+                               offset = possible_offset;
+
+                               return offset;
+                       }
+
                        throw new MegaDriveError.INVALID_HEADER (_("The file doesn't have a Genesis/Sega 
32X/Sega CD/Sega Pico header."));
        }
+
+       private MegaDriveSystem parse_system () throws Error {
+               var stream = new StringInputStream (file);
+
+               var offset = get_offset ();
+               var is_cd = stream.has_string (offset + CD_OFFSET, "SEGADISCSYSTEM");
+               var system_string = stream.read_string_for_size (offset + SYSTEM_OFFSET, SYSTEM_SIZE);
+               system_string = system_string.chomp ();
+
+               switch (system_string) {
+               case "SEGA MEGA DRIVE":
+               case "SEGA GENESIS":
+                       return is_cd ? MegaDriveSystem.MEGA_CD : MegaDriveSystem.MEGA_DRIVE;
+               case "SEGA 32X":
+                       return is_cd ? MegaDriveSystem.MEGA_CD_32X : MegaDriveSystem.32X;
+               case "SEGA PICO":
+                       return is_cd ? MegaDriveSystem.INVALID : MegaDriveSystem.PICO;
+               default:
+                       return MegaDriveSystem.INVALID;
+               }
+       }
 }
 
 errordomain Games.MegaDriveError {


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