Example #1
0
        public GGHawkLink(CoreComm comm, GameInfo game_L, byte[] rom_L, GameInfo game_R, byte[] rom_R, /*string gameDbFn,*/ object settings, object syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            linkSettings     = (GGLinkSettings)settings ?? new GGLinkSettings();
            linkSyncSettings = (GGLinkSyncSettings)syncSettings ?? new GGLinkSyncSettings();
            _controllerDeck  = new GGHawkLinkControllerDeck(GGHawkLinkControllerDeck.DefaultControllerName, GGHawkLinkControllerDeck.DefaultControllerName);

            CoreComm = comm;

            var temp_set_L = new SMS.SmsSettings();
            var temp_set_R = new SMS.SmsSettings();

            var temp_sync_L = new SMS.SmsSyncSettings();
            var temp_sync_R = new SMS.SmsSyncSettings();

            L = new SMS(new CoreComm(comm.ShowMessage, comm.Notify)
            {
                CoreFileProvider = comm.CoreFileProvider
            },
                        game_L, rom_L, temp_set_L, temp_sync_L);

            R = new SMS(new CoreComm(comm.ShowMessage, comm.Notify)
            {
                CoreFileProvider = comm.CoreFileProvider
            },
                        game_R, rom_R, temp_set_R, temp_sync_R);

            ser.Register <IVideoProvider>(this);
            ser.Register <ISoundProvider>(this);

            _tracer = new TraceBuffer {
                Header = L.Cpu.TraceHeader
            };
            ser.Register <ITraceable>(_tracer);

            ServiceProvider = ser;

            SetupMemoryDomains();

            HardReset();

            L.stand_alone = false;
            R.stand_alone = false;

            _lStates = L.ServiceProvider.GetService <IStatable>();
            _rStates = R.ServiceProvider.GetService <IStatable>();
        }
Example #2
0
        public GGHawkLink(CoreLoadParameters <GGLinkSettings, GGLinkSyncSettings> lp)
        {
            if (lp.Roms.Count != 2)
            {
                throw new InvalidOperationException("Wrong number of roms");
            }

            var ser = new BasicServiceProvider(this);

            linkSettings     = (GGLinkSettings)lp.Settings ?? new GGLinkSettings();
            linkSyncSettings = (GGLinkSyncSettings)lp.SyncSettings ?? new GGLinkSyncSettings();
            _controllerDeck  = new GGHawkLinkControllerDeck(GGHawkLinkControllerDeck.DefaultControllerName, GGHawkLinkControllerDeck.DefaultControllerName);

            var temp_set_L = new SMS.SmsSettings();
            var temp_set_R = new SMS.SmsSettings();

            var temp_sync_L = new SMS.SmsSyncSettings();
            var temp_sync_R = new SMS.SmsSyncSettings();

            L = new SMS(lp.Comm, lp.Roms[0].Game, lp.Roms[0].RomData, temp_set_L, temp_sync_L);
            R = new SMS(lp.Comm, lp.Roms[1].Game, lp.Roms[1].RomData, temp_set_R, temp_sync_R);

            ser.Register <IVideoProvider>(this);
            ser.Register <ISoundProvider>(this);

            _tracer = new TraceBuffer {
                Header = L.Cpu.TraceHeader
            };
            ser.Register(_tracer);

            ServiceProvider = ser;

            SetupMemoryDomains();

            HardReset();

            L.stand_alone = false;
            R.stand_alone = false;

            _lStates = L.ServiceProvider.GetService <IStatable>();
            _rStates = R.ServiceProvider.GetService <IStatable>();
        }
        protected override void RunImport()
        {
            using var fs = SourceFile.Open(FileMode.Open, FileAccess.Read);
            using var r  = new BinaryReader(fs);

            // 0000: 4-byte signature: "MMV\0"
            string signature = new string(r.ReadChars(4));

            if (signature != "MMV\0")
            {
                Result.Errors.Add("This is not a valid .MMV file.");
                return;
            }

            // 0004: 4-byte little endian unsigned int: dega version
            uint emuVersion = r.ReadUInt32();

            Result.Movie.Comments.Add($"{MovieOrigin} .MMV");
            Result.Movie.Comments.Add($"{EmulationOrigin} Dega version {emuVersion}");

            // 0008: 4-byte little endian unsigned int: frame count
            uint frameCount = r.ReadUInt32();

            // 000c: 4-byte little endian unsigned int: rerecord count
            uint rerecordCount = r.ReadUInt32();

            Result.Movie.Rerecords = rerecordCount;


            // 0010: 4-byte little endian flag: begin from reset?
            uint reset = r.ReadUInt32();

            if (reset == 0)
            {
                Result.Errors.Add("Movies that begin with a savestate are not supported.");
                return;
            }

            // 0014: 4-byte little endian unsigned int: offset of state information
            r.ReadUInt32();

            // 0018: 4-byte little endian unsigned int: offset of input data
            r.ReadUInt32();

            // 001c: 4-byte little endian unsigned int: size of input packet
            r.ReadUInt32();

            // 0020-005f: string: author info (UTF-8)
            string author = NullTerminated(new string(r.ReadChars(64)));

            Result.Movie.HeaderEntries[HeaderKeys.Author] = author;

            // 0060: 4-byte little endian flags
            byte flags = r.ReadByte();

            // bit 0: unused
            // bit 1: "PAL"
            bool pal = ((flags >> 1) & 0x1) != 0;

            Result.Movie.HeaderEntries[HeaderKeys.Pal] = pal.ToString();

            // bit 2: Japan
            bool japan = ((flags >> 2) & 0x1) != 0;

            Result.Movie.HeaderEntries["Japan"] = japan.ToString();

            // bit 3: Game Gear (version 1.16+)
            bool isGameGear;

            if (((flags >> 3) & 0x1) != 0)
            {
                isGameGear = true;
                Result.Movie.HeaderEntries.Add("IsGGMode", "1");
            }
            else
            {
                isGameGear = false;
            }

            Result.Movie.HeaderEntries[HeaderKeys.Platform] = "SMS";             // System Id is still SMS even if game gear

            // bits 4-31: unused
            r.ReadBytes(3);

            // 0064-00e3: string: rom name (ASCII)
            string gameName = NullTerminated(new string(r.ReadChars(128)));

            Result.Movie.HeaderEntries[HeaderKeys.GameName] = gameName;

            // 00e4-00f3: binary: rom MD5 digest
            byte[] md5 = r.ReadBytes(16);
            Result.Movie.HeaderEntries[Md5] = md5.BytesToHexString().ToLower();

            var ss = new SMS.SmsSyncSettings
            {
                ControllerType = SMS.SmsSyncSettings.ControllerTypes.Standard
            };

            var controllers = new SimpleController
            {
                Definition = isGameGear
                                        ? SMS.SmsController
                                        : SMS.GGController
            };

            /*
             * 76543210
             * bit 0 (0x01): up
             * bit 1 (0x02): down
             * bit 2 (0x04): left
             * bit 3 (0x08): right
             * bit 4 (0x10): 1
             * bit 5 (0x20): 2
             * bit 6 (0x40): start (Master System)
             * bit 7 (0x80): start (Game Gear)
             */
            string[] buttons = { "Up", "Down", "Left", "Right", "B1", "B2" };
            for (int frame = 1; frame <= frameCount; frame++)
            {
                /*
                 * Controller data is made up of one input packet per frame. Each packet currently consists of 2 bytes. The
                 * first byte is for controller 1 and the second controller 2. The Game Gear only uses the controller 1 input
                 * however both bytes are still present.
                 */
                for (int player = 1; player <= 2; player++)
                {
                    byte controllerState = r.ReadByte();
                    for (int button = 0; button < buttons.Length; button++)
                    {
                        controllers[$"P{player} {buttons[button]}"] = ((controllerState >> button) & 0x1) != 0;
                    }

                    if (player == 1)
                    {
                        controllers["Pause"] =
                            (((controllerState >> 6) & 0x1) != 0 && !isGameGear) ||
                            (((controllerState >> 7) & 0x1) != 0 && isGameGear);
                    }
                }

                Result.Movie.AppendFrame(controllers);
            }

            Result.Movie.SyncSettingsJson = ConfigService.SaveWithType(ss);
        }