コード例 #1
0
ファイル: InstrumentAdLib.cs プロジェクト: scemino/nscumm
 public void SaveOrLoad(Serializer s)
 {
     if (!s.IsLoading)
         s.Writer.WriteBytes(_instrument, 30);
     else
         _instrument = s.Reader.ReadBytes(30);
 }
コード例 #2
0
ファイル: VerbSlot.cs プロジェクト: scemino/nscumm
 public void SaveOrLoad(Serializer serializer)
 {
     var verbEntries = new[]
     {
         LoadAndSaveEntry.Create(reader => CurRect.Left = reader.ReadInt16(), writer => writer.WriteInt16(CurRect.Left), 8),
         LoadAndSaveEntry.Create(reader => CurRect.Top = reader.ReadInt16(), writer => writer.WriteInt16(CurRect.Top), 8),
         LoadAndSaveEntry.Create(reader => CurRect.Right = reader.ReadInt16(), writer => writer.WriteInt16(CurRect.Right), 8),
         LoadAndSaveEntry.Create(reader => CurRect.Bottom = reader.ReadInt16(), writer => writer.WriteInt16(CurRect.Bottom), 8),
         LoadAndSaveEntry.Create(reader => OldRect.Left = reader.ReadInt16(), writer => writer.WriteInt16(OldRect.Left), 8),
         LoadAndSaveEntry.Create(reader => OldRect.Top = reader.ReadInt16(), writer => writer.WriteInt16(OldRect.Top), 8),
         LoadAndSaveEntry.Create(reader => OldRect.Right = reader.ReadInt16(), writer => writer.WriteInt16(OldRect.Right), 8),
         LoadAndSaveEntry.Create(reader => OldRect.Bottom = reader.ReadInt16(), writer => writer.WriteInt16(OldRect.Bottom), 8),
                                        
         LoadAndSaveEntry.Create(reader => VerbId = reader.ReadByte(), writer => writer.WriteByte(VerbId), 8, 11),
         LoadAndSaveEntry.Create(reader => VerbId = reader.ReadUInt16(), writer => writer.WriteUInt16(VerbId), 12),
                                        
         LoadAndSaveEntry.Create(reader => Color = reader.ReadByte(), writer => writer.WriteByte(Color), 8),
         LoadAndSaveEntry.Create(reader => HiColor = reader.ReadByte(), writer => writer.WriteByte(HiColor), 8),
         LoadAndSaveEntry.Create(reader => DimColor = reader.ReadByte(), writer => writer.WriteByte(DimColor), 8),
         LoadAndSaveEntry.Create(reader => BkColor = reader.ReadByte(), writer => writer.WriteByte(BkColor), 8),
         LoadAndSaveEntry.Create(reader => Type = (VerbType)reader.ReadByte(), writer => writer.WriteByte((byte)Type), 8),
         LoadAndSaveEntry.Create(reader => CharsetNr = reader.ReadByte(), writer => writer.WriteByte(CharsetNr), 8),
         LoadAndSaveEntry.Create(reader => CurMode = reader.ReadByte(), writer => writer.WriteByte(CurMode), 8),
         LoadAndSaveEntry.Create(reader => SaveId = reader.ReadByte(), writer => writer.WriteByte(SaveId), 8),
         LoadAndSaveEntry.Create(reader => Key = reader.ReadByte(), writer => writer.WriteByte(Key), 8),
         LoadAndSaveEntry.Create(reader => Center = reader.ReadBoolean(), writer => writer.WriteByte(Center), 8),
         LoadAndSaveEntry.Create(reader => Prep = reader.ReadByte(), writer => writer.WriteByte(Prep), 8),
         LoadAndSaveEntry.Create(reader => ImgIndex = reader.ReadUInt16(), writer => writer.WriteUInt16(ImgIndex), 8),
     };
     verbEntries.ForEach(e => e.Execute(serializer));
 }
コード例 #3
0
ファイル: NestedScript.cs プロジェクト: scemino/nscumm
 public void SaveOrLoad(Serializer serializer)
 {
     var nestedScriptEntries = new[]
     {
         LoadAndSaveEntry.Create(reader => Number = reader.ReadUInt16(), writer => writer.WriteUInt16(Number), 8),
         LoadAndSaveEntry.Create(reader => Where = (WhereIsObject)reader.ReadByte(), writer => writer.WriteByte((byte)Where), 8),
         LoadAndSaveEntry.Create(reader => Slot = reader.ReadByte(), writer => writer.WriteByte(Slot), 8),
     };
     nestedScriptEntries.ForEach(e => e.Execute(serializer));
 }
コード例 #4
0
ファイル: ImTrigger.cs プロジェクト: scemino/nscumm
 public void SaveOrLoad(Serializer ser)
 {
     var snmTriggerEntries = new []
     {
         LoadAndSaveEntry.Create(r => Sound = r.ReadInt16(), w => w.WriteInt16(Sound), 54),
         LoadAndSaveEntry.Create(r => Id = r.ReadByte(), w => w.WriteByte(Id), 54),
         LoadAndSaveEntry.Create(r => Expire = r.ReadUInt16(), w => w.WriteUInt16(Expire), 54),
             LoadAndSaveEntry.Create(r => Command = r.ReadUInt16s(8).Select(i => (int)i).ToArray(), w => w.WriteUInt16s(Command.Select(i => (ushort)i).ToArray(), 8), 54),
     };
     snmTriggerEntries.ForEach(e => e.Execute(ser));
 }
コード例 #5
0
ファイル: Sentence.cs プロジェクト: scemino/nscumm
 public void SaveOrLoad(Serializer serializer)
 {
     var sentenceEntries = new[]
     {
         LoadAndSaveEntry.Create(reader => Verb = reader.ReadByte(), writer => writer.WriteByte(Verb), 8),
         LoadAndSaveEntry.Create(reader => Preposition = reader.ReadBoolean(), writer => writer.WriteByte(Preposition), 8),
         LoadAndSaveEntry.Create(reader => ObjectA = reader.ReadUInt16(), writer => writer.WriteUInt16(ObjectA), 8),
         LoadAndSaveEntry.Create(reader => ObjectB = reader.ReadUInt16(), writer => writer.WriteUInt16(ObjectB), 8),
         LoadAndSaveEntry.Create(reader => freezeCount = reader.ReadByte(), writer => writer.WriteByte(freezeCount), 8),
     };
     sentenceEntries.ForEach(e => e.Execute(serializer));
 }
コード例 #6
0
ファイル: ParameterFader.cs プロジェクト: scemino/nscumm
        public void SaveOrLoad(Serializer ser)
        {
            var parameterFaderEntries = new []  {
                LoadAndSaveEntry.Create(r => Param = (ParameterFaderType)r.ReadInt16(), w => w.WriteInt16((short)Param), 17),
                LoadAndSaveEntry.Create(r => Start = r.ReadInt16(), w => w.WriteInt16(Start), 17),
                LoadAndSaveEntry.Create(r => End = r.ReadInt16(), w => w.WriteInt16(End), 17),
                LoadAndSaveEntry.Create(r => TotalTime = r.ReadUInt32(), w => w.WriteUInt32(TotalTime), 17),
                LoadAndSaveEntry.Create(r => CurrentTime = r.ReadUInt32(), w => w.WriteUInt32(CurrentTime), 17)
            };

            parameterFaderEntries.ForEach(e => e.Execute(ser));
        }
コード例 #7
0
ファイル: ColorCycle.cs プロジェクト: scemino/nscumm
 public void SaveOrLoad(Serializer serializer)
 {
     var colorCycleEntries = new[]
     {
         LoadAndSaveEntry.Create(reader => Delay = reader.ReadUInt16(), writer => writer.WriteUInt16(Delay), 8),
         LoadAndSaveEntry.Create(reader => Counter = reader.ReadUInt16(), writer => writer.WriteUInt16(Counter), 8),
         LoadAndSaveEntry.Create(reader => Flags = reader.ReadUInt16(), writer => writer.WriteUInt16(Flags), 8),
         LoadAndSaveEntry.Create(reader => Start = reader.ReadByte(), writer => writer.WriteByte(Start), 8),
         LoadAndSaveEntry.Create(reader => End = reader.ReadByte(), writer => writer.WriteByte(End), 8),
     };
     colorCycleEntries.ForEach(e => e.Execute(serializer));
 }
コード例 #8
0
ファイル: InstrumentProgram.cs プロジェクト: scemino/nscumm
 public void SaveOrLoad(Serializer s)
 {
     if (!s.IsLoading)
     {
         s.Writer.WriteByte(_program);
         s.Writer.WriteByte(_mt32 ? 1 : 0);
     }
     else
     {
         _program = s.Reader.ReadByte();
         _mt32 = s.Reader.ReadByte() > 0;
     }
 }
コード例 #9
0
ファイル: ScaleSlot.cs プロジェクト: scemino/nscumm
 public void SaveOrLoad(Serializer serializer)
 {
     var scaleSlotsEntries = new[]
     {
         LoadAndSaveEntry.Create(reader => X1 = reader.ReadInt16(), writer => writer.WriteInt16(X1), 13),
         LoadAndSaveEntry.Create(reader => Y1 = reader.ReadInt16(), writer => writer.WriteInt16(Y1), 13),
         LoadAndSaveEntry.Create(reader => Scale1 = reader.ReadInt16(), writer => writer.WriteInt16(Scale1), 13),
         LoadAndSaveEntry.Create(reader => X2 = reader.ReadInt16(), writer => writer.WriteInt16(X2), 13),
         LoadAndSaveEntry.Create(reader => Y2 = reader.ReadInt16(), writer => writer.WriteInt16(Y2), 13),
         LoadAndSaveEntry.Create(reader => Scale2 = reader.ReadInt16(), writer => writer.WriteInt16(Scale2), 13),
     };
     scaleSlotsEntries.ForEach(e => e.Execute(serializer));
 }
コード例 #10
0
ファイル: Serializer.cs プロジェクト: scemino/nscumm
 public void Execute(Serializer serializer)
 {
     if (serializer.Version >= _minVersion && serializer.Version <= _maxVersion)
     {
         if (serializer.IsLoading)
         {
             _load(serializer.Reader);
         }
         else
         {
             _save(serializer.Writer);
         }
     }
 }
コード例 #11
0
ファイル: Player_Towns.cs プロジェクト: scemino/nscumm
        public virtual void SaveOrLoad(Serializer ser)
        {
            for (int i = 1; i < 9; i++)
            {
                if (_pcmCurrentSound[i].index == 0)
                    continue;

                if (_intf.Callback(40, i + 0x3f))
                    continue;

                _intf.Callback(39, i + 0x3f);

                _pcmCurrentSound[i].index = 0;
            }

            _pcmCurrentSound.ForEach(s => s.SaveOrLoad(ser));
        }
コード例 #12
0
ファイル: CutScene.cs プロジェクト: scemino/nscumm
        public void SaveOrLoad(Serializer serializer)
        {
            var entries = new LoadAndSaveEntry[]
            {
                LoadAndSaveEntry.Create(reader =>
                    {
                        StackPointer = reader.ReadByte();
                        var cutScenePtr = reader.ReadInt32s(MaxCutsceneNum);
                        var cutSceneScript = reader.ReadBytes(MaxCutsceneNum);
                        var cutSceneData = reader.ReadInt16s(MaxCutsceneNum);

                        // load Cut Scene Data
                        for (var i = 0; i < MaxCutsceneNum; i++)
                        {
                            var data = new CutSceneData
                            {
                                Pointer = cutScenePtr[i],
                                Script = cutSceneScript[i],
                                Data = cutSceneData[i]
                            };
                            Data[i] = data;
                        }
                        ScriptIndex = reader.ReadInt16();
                    }, writer =>
                    {
                        var cutScenePtr = new int[MaxCutsceneNum];
                        var cutSceneScript = new byte[MaxCutsceneNum];
                        var cutSceneData = new short[MaxCutsceneNum];
                        var cutSceneStack = Data;
                        for (var i = 0; i < cutSceneStack.Length; i++)
                        {
                            cutScenePtr[i] = cutSceneStack[i].Pointer;   
                            cutSceneScript[i] = cutSceneStack[i].Script;   
                            cutSceneData[i] = (short)cutSceneStack[i].Data;   
                        }
                        writer.WriteByte(StackPointer);
                        writer.WriteInt32s(cutScenePtr, MaxCutsceneNum);
                        writer.WriteBytes(cutSceneScript, MaxCutsceneNum);
                        writer.WriteInt16s(cutSceneData, MaxCutsceneNum);
                        writer.WriteInt16(ScriptIndex);
                    }, 8)
            };
            entries.ForEach(e => e.Execute(serializer));
        }
コード例 #13
0
ファイル: TextSlot.cs プロジェクト: scemino/nscumm
 public void SaveOrLoad(Serializer serializer)
 {
     var stringTabEntries = new[]
     {
         LoadAndSaveEntry.Create(reader =>
             {
                 var xPos = reader.ReadInt16(); 
                 var defaultXPos = reader.ReadInt16();
                 var yPos = reader.ReadInt16();
                 var defaultYPos = reader.ReadInt16();
                 Position = new Point(xPos, yPos);
                 _default.Position = new Point(defaultXPos, defaultYPos);
             }, writer =>
             {
                 writer.WriteInt16(Position.X);
                 writer.WriteInt16(_default.Position.X);
                 writer.WriteInt16(Position.Y);
                 writer.WriteInt16(_default.Position.Y);
             }, 8),
         LoadAndSaveEntry.Create(reader => Right = reader.ReadInt16(), writer => writer.WriteInt16(Right), 8),
         LoadAndSaveEntry.Create(reader => _default.Right = reader.ReadInt16(), writer => writer.WriteInt16(_default.Right), 8),
         LoadAndSaveEntry.Create(reader => Color = reader.ReadByte(), writer => writer.WriteByte(Color), 8),
         LoadAndSaveEntry.Create(reader => _default.Color = reader.ReadByte(), writer => writer.WriteByte(_default.Color), 8),
         LoadAndSaveEntry.Create(reader => Charset = reader.ReadByte(), writer => writer.WriteByte(Charset), 8),
         LoadAndSaveEntry.Create(reader => _default.Charset = reader.ReadByte(), writer => writer.WriteByte(_default.Charset), 8),
         LoadAndSaveEntry.Create(reader => Center = reader.ReadBoolean(), writer => writer.WriteByte(Center), 8),
         LoadAndSaveEntry.Create(reader => _default.Center = reader.ReadBoolean(), writer => writer.WriteByte(_default.Center), 8),
         LoadAndSaveEntry.Create(reader => Overhead = reader.ReadBoolean(), writer => writer.WriteByte(Overhead), 8),
         LoadAndSaveEntry.Create(reader => _default.Overhead = reader.ReadBoolean(), writer => writer.WriteByte(_default.Overhead), 8),
         LoadAndSaveEntry.Create(reader => NoTalkAnim = reader.ReadBoolean(), writer => writer.WriteByte(NoTalkAnim), 8),
         LoadAndSaveEntry.Create(reader => _default.NoTalkAnim = reader.ReadBoolean(), writer => writer.WriteByte(_default.NoTalkAnim), 8),
         LoadAndSaveEntry.Create(reader => Wrapping = reader.ReadBoolean(), writer => writer.WriteByte(Wrapping), 71),
         LoadAndSaveEntry.Create(reader => _default.Wrapping = reader.ReadBoolean(), writer => writer.WriteByte(_default.Wrapping), 71)
     };
     stringTabEntries.ForEach(e => e.Execute(serializer));
 }
コード例 #14
0
ファイル: IMuseDigital.cs プロジェクト: scemino/nscumm
 public void SaveOrLoad(Serializer serializer)
 {
     // TODO: vs
 }
コード例 #15
0
ファイル: Player_Mac.cs プロジェクト: scemino/nscumm
            public void SaveOrLoad(Serializer ser)
            {
                var channelEntries = new []
                {
                    LoadAndSaveEntry.Create(r => _pos = r.ReadUInt16(), w => w.WriteUInt16(_pos), 94),
                    LoadAndSaveEntry.Create(r => _pitchModifier = r.ReadInt32(), w => w.WriteInt32(_pitchModifier), 94),
                    LoadAndSaveEntry.Create(r => _velocity = r.ReadByte(), w => w.WriteByte(_velocity), 94),
                    LoadAndSaveEntry.Create(r => _remaining = r.ReadUInt32(), w => w.WriteUInt32(_remaining), 94),
                    LoadAndSaveEntry.Create(r => _notesLeft = r.ReadBoolean(), w => w.WriteByte(_notesLeft), 94),
                };

                channelEntries.ForEach(e => e.Execute(ser));
            }
コード例 #16
0
ファイル: Player.cs プロジェクト: scemino/nscumm
        public void SaveOrLoad(Serializer ser)
        {
            var playerEntries = new []
            {
                LoadAndSaveEntry.Create(r => _active = r.ReadBoolean(), w => w.Write(_active), 8),
                LoadAndSaveEntry.Create(r => _id = r.ReadUInt16(), w => w.WriteUInt16(_id), 8),
                LoadAndSaveEntry.Create(r => _priority = r.ReadByte(), w => w.WriteByte(_priority), 8),
                LoadAndSaveEntry.Create(r => _volume = r.ReadByte(), w => w.WriteByte(_volume), 8),
                LoadAndSaveEntry.Create(r => _pan = r.ReadSByte(), w => w.Write(_pan), 8),
                LoadAndSaveEntry.Create(r => _transpose = r.ReadSByte(), w => w.Write(_transpose), 8),
                LoadAndSaveEntry.Create(r => _detune = r.ReadSByte(), w => w.Write(_detune), 8),
                LoadAndSaveEntry.Create(r => VolChan = r.ReadUInt16(), w => w.WriteUInt16(VolChan), 8),
                LoadAndSaveEntry.Create(r => _vol_eff = r.ReadByte(), w => w.WriteByte(_vol_eff), 8),
                LoadAndSaveEntry.Create(r => _speed = r.ReadByte(), w => w.WriteByte(_speed), 8),
                LoadAndSaveEntry.Create(r => r.ReadUInt16(), w => w.WriteUInt16(0), 8, 19), //_song_index
                LoadAndSaveEntry.Create(r => _track_index = r.ReadUInt16(), w => w.WriteUInt16(_track_index), 8),
                LoadAndSaveEntry.Create(r => r.ReadUInt16(), w => w.WriteUInt16(0), 8, 17), //_timer_counter
                LoadAndSaveEntry.Create(r => _loop_to_beat = r.ReadUInt16(), w => w.WriteUInt16(_loop_to_beat), 8),
                LoadAndSaveEntry.Create(r => _loop_from_beat = r.ReadUInt16(), w => w.WriteUInt16(_loop_from_beat), 8),
                LoadAndSaveEntry.Create(r => _loop_counter = r.ReadUInt16(), w => w.WriteUInt16(_loop_counter), 8),
                LoadAndSaveEntry.Create(r => _loop_to_tick = r.ReadUInt16(), w => w.WriteUInt16(_loop_to_tick), 8),
                LoadAndSaveEntry.Create(r => _loop_from_tick = r.ReadUInt16(), w => w.WriteUInt16(_loop_from_tick), 8),
                LoadAndSaveEntry.Create(r => r.ReadUInt32(), w => w.WriteUInt32(0), 8, 19), //_tempo
                LoadAndSaveEntry.Create(r => r.ReadUInt32(), w => w.WriteUInt32(0), 8, 17), //_cur_pos
                LoadAndSaveEntry.Create(r => r.ReadUInt32(), w => w.WriteUInt32(0), 8, 17), //_next_pos
                LoadAndSaveEntry.Create(r => r.ReadUInt32(), w => w.WriteUInt32(0), 8, 17), //_song_offset
                LoadAndSaveEntry.Create(r => r.ReadUInt16(), w => w.WriteUInt16(0), 8, 17), //_tick_index
                LoadAndSaveEntry.Create(r => r.ReadUInt16(), w => w.WriteUInt16(0), 8, 17), //_beat_index
                LoadAndSaveEntry.Create(r => r.ReadUInt16(), w => w.WriteUInt16(0), 8, 17), // _ticks_per_beat
                LoadAndSaveEntry.Create(r => _music_tick = r.ReadUInt32(), w => w.WriteUInt32(_music_tick), 19),
            };

            if (ser.IsLoading && _parser != null)
            {
                _parser = null;
            }
            _music_tick = _parser != null ? (uint)_parser.Tick : 0;

            int num;
            if (!ser.IsLoading)
            {
                num = _parts != null ? Array.IndexOf(_se._parts, _parts) + 1 : 0;
                ser.Writer.WriteUInt16(num);
            }
            else
            {
                num = ser.Reader.ReadUInt16();
                _parts = num != 0 ? _se._parts[num - 1] : null;
            }

            playerEntries.ForEach(e => e.Execute(ser));
            _hook.SaveOrLoad(ser);
            _parameterFaders.ForEach(pf => pf.SaveOrLoad(ser));
        }
コード例 #17
0
ファイル: CommandQueue.cs プロジェクト: scemino/nscumm
 public void SaveOrLoad(Serializer ser)
 {
     LoadAndSaveEntry.Create(r => array = r.ReadInt16s(8).Select(i => (int)i).ToArray(), w => w.WriteInt16s(array.Cast<int>().ToArray(), 8), 54).Execute(ser);
 }
コード例 #18
0
ファイル: Actor.cs プロジェクト: scemino/nscumm
        public virtual void SaveOrLoad(Serializer serializer)
        {
            var actorEntries = new[]
            {
                LoadAndSaveEntry.Create(reader => _position.X = reader.ReadInt16(), writer => writer.WriteInt16(_position.X), 8),
                LoadAndSaveEntry.Create(reader => _position.Y = reader.ReadInt16(), writer => writer.WriteInt16(_position.Y), 8),
                                                    
                LoadAndSaveEntry.Create(reader => reader.ReadInt16(), writer => writer.WriteInt16(0xCDCD), 32),
                LoadAndSaveEntry.Create(reader => reader.ReadInt16(), writer => writer.WriteInt16(0xCDCD), 32),
                LoadAndSaveEntry.Create(reader => Top = reader.ReadInt16(), writer => writer.WriteInt16(Top), 8),
                LoadAndSaveEntry.Create(reader => Bottom = reader.ReadInt16(), writer => writer.WriteInt16(Bottom), 8),
                LoadAndSaveEntry.Create(reader => _elevation = reader.ReadInt16(), writer => writer.WriteInt16(_elevation), 8),
                LoadAndSaveEntry.Create(reader => Width = reader.ReadUInt16(), writer => writer.WriteUInt16(Width), 8),
                LoadAndSaveEntry.Create(reader => Facing = reader.ReadUInt16(), writer => writer.WriteUInt16(Facing), 8),
                LoadAndSaveEntry.Create(reader => Costume = reader.ReadUInt16(), writer => writer.WriteUInt16(Costume), 8),
                LoadAndSaveEntry.Create(reader => Room = reader.ReadByte(), writer => writer.WriteByte(Room), 8),
                LoadAndSaveEntry.Create(reader => TalkColor = reader.ReadByte(), writer => writer.WriteByte(TalkColor), 8),
                LoadAndSaveEntry.Create(reader => _talkFrequency = reader.ReadInt16(), writer => writer.WriteInt16(_talkFrequency), 16),
                LoadAndSaveEntry.Create(reader => _talkPan = (byte)reader.ReadInt16(), writer => writer.WriteInt16(_talkPan), 24),
                LoadAndSaveEntry.Create(reader => _talkVolume = (byte)reader.ReadInt16(), writer => writer.WriteInt16(_talkVolume), 29),
                LoadAndSaveEntry.Create(reader => BoxScale = reader.ReadUInt16(), writer => writer.WriteUInt16(BoxScale), 34),
                LoadAndSaveEntry.Create(reader => ScaleX = reader.ReadByte(), writer => writer.WriteByte(ScaleX), 8),
                LoadAndSaveEntry.Create(reader => ScaleY = reader.ReadByte(), writer => writer.WriteByte(ScaleY), 8),
                LoadAndSaveEntry.Create(reader => Charset = reader.ReadByte(), writer => writer.WriteByte(Charset), 8),
		            
                // Actor sound grew from 8 to 32 bytes and switched to uint16 in HE games
                LoadAndSaveEntry.Create(
                    reader => Sound = reader.ReadBytes(8).ToArray()[0],
                    writer =>
                    {
                        var sounds = new byte[8];
                        sounds[0] = (byte)Sound;
                        writer.Write(sounds);
                    },
                    8, 36),
                LoadAndSaveEntry.Create(
                    reader => Sound = reader.ReadBytes(32).ToArray()[0],
                    writer =>
                    {
                        var sounds = new byte[32];
                        sounds[0] = (byte)Sound;
                        writer.Write(sounds);
                    },
                    37, 61),
                LoadAndSaveEntry.Create(
                    reader => Sound = (int)reader.ReadUInt16s(32)[0],
                    writer =>
                    {
                        var sounds = new ushort[32];
                        sounds[0] = (ushort)Sound;
                        writer.WriteUInt16s(sounds, 32);
                    },
                    62),
                    
                // Actor animVariable grew from 8 to 27
                LoadAndSaveEntry.Create(reader => _animVariable = reader.ReadInt16s(8), writer => writer.WriteInt16s(_animVariable, 8), 8, 40),
                LoadAndSaveEntry.Create(reader => _animVariable = reader.ReadInt16s(27), writer => writer.WriteInt16s(_animVariable, 27), 41),
                                                   
                LoadAndSaveEntry.Create(reader => _targetFacing = reader.ReadUInt16(), writer => writer.WriteUInt16(_targetFacing), 8),
                LoadAndSaveEntry.Create(reader => Moving = (MoveFlags)reader.ReadByte(), writer => writer.WriteByte((byte)Moving), 8),
                LoadAndSaveEntry.Create(reader => IgnoreBoxes = reader.ReadByte() != 0, writer => writer.WriteByte(IgnoreBoxes), 8),
                LoadAndSaveEntry.Create(reader => ForceClip = reader.ReadByte(), writer => writer.WriteByte(ForceClip), 8),
                LoadAndSaveEntry.Create(reader => InitFrame = reader.ReadByte(), writer => writer.WriteByte(InitFrame), 8),
                LoadAndSaveEntry.Create(reader => WalkFrame = reader.ReadByte(), writer => writer.WriteByte(WalkFrame), 8),
                LoadAndSaveEntry.Create(reader => StandFrame = reader.ReadByte(), writer => writer.WriteByte(StandFrame), 8),
                LoadAndSaveEntry.Create(reader => TalkStartFrame = reader.ReadByte(), writer => writer.WriteByte(TalkStartFrame), 8),
                LoadAndSaveEntry.Create(reader => TalkStopFrame = reader.ReadByte(), writer => writer.WriteByte(TalkStopFrame), 8),
                LoadAndSaveEntry.Create(reader => _speedx = reader.ReadUInt16(), writer => writer.WriteUInt16(_speedx), 8),
                LoadAndSaveEntry.Create(reader => _speedy = reader.ReadUInt16(), writer => writer.WriteUInt16(_speedy), 8),
                LoadAndSaveEntry.Create(reader => Cost.AnimCounter = reader.ReadUInt16(), writer => writer.WriteUInt16(Cost.AnimCounter), 8),
                LoadAndSaveEntry.Create(reader => Cost.SoundCounter = reader.ReadByte(), writer => writer.WriteByte(Cost.SoundCounter), 8),
                LoadAndSaveEntry.Create(reader => DrawToBackBuf = reader.ReadByte() != 0, writer => writer.WriteByte(DrawToBackBuf), 32),
                LoadAndSaveEntry.Create(reader => Flip = reader.ReadByte() != 0, writer => writer.WriteByte(Flip), 32),
                LoadAndSaveEntry.Create(reader => reader.ReadByte(), writer => writer.WriteByte(0xCD), 32),

                // Actor palette grew from 64 to 256 bytes and switched to uint16 in HE games
                LoadAndSaveEntry.Create(
                    reader => _palette = reader.ReadBytes(64).Cast<ushort>().ToArray(),
                    writer => writer.WriteBytes(_palette, 64),
                    8, 9),
                LoadAndSaveEntry.Create(
                    reader => _palette = reader.ReadBytes(256).Cast<ushort>().ToArray(),
                    writer => writer.WriteBytes(_palette, 256),
                    10, 79),
                LoadAndSaveEntry.Create(
                    reader => _palette = reader.ReadUInt16s(256),
                    writer => writer.WriteUInt16s(_palette, 256)
                        , 80),

                LoadAndSaveEntry.Create(reader => reader.ReadByte(), writer => writer.WriteByte(0), 8, 9),
                LoadAndSaveEntry.Create(reader => ShadowMode = reader.ReadByte(), writer => writer.WriteByte(ShadowMode), 8),
                LoadAndSaveEntry.Create(reader => IsVisible = reader.ReadByte() != 0, writer => writer.WriteByte(IsVisible), 8),
                LoadAndSaveEntry.Create(reader => _frame = reader.ReadByte(), writer => writer.WriteByte(_frame), 8),
                LoadAndSaveEntry.Create(reader => _animSpeed = reader.ReadByte(), writer => writer.WriteByte(_animSpeed), 8),
                LoadAndSaveEntry.Create(reader => _animProgress = reader.ReadByte(), writer => writer.WriteByte(_animProgress), 8),
                LoadAndSaveEntry.Create(reader => Walkbox = reader.ReadByte(), writer => writer.WriteByte(Walkbox), 8),
                LoadAndSaveEntry.Create(reader => NeedRedraw = reader.ReadByte() != 0, writer => writer.WriteByte(NeedRedraw), 8),
                LoadAndSaveEntry.Create(reader => NeedBackgroundReset = reader.ReadByte() != 0, writer => writer.WriteByte(NeedBackgroundReset), 8),
                LoadAndSaveEntry.Create(reader => _costumeNeedsInit = reader.ReadByte() != 0, writer => writer.WriteByte(_costumeNeedsInit), 8),
                LoadAndSaveEntry.Create(reader => reader.ReadUInt32(), writer => writer.WriteUInt32(0xCDCDCDCD), 38),
                LoadAndSaveEntry.Create(reader => reader.ReadUInt32(), writer => writer.WriteUInt32(0xCDCDCDCD), 59),
                LoadAndSaveEntry.Create(reader => reader.ReadUInt32(), writer => writer.WriteUInt32(0xCDCDCDCD), 59),

                LoadAndSaveEntry.Create(reader =>
                    {
                        TalkPosition = new Point(reader.ReadInt16(), reader.ReadInt16());
                    }, writer =>
                    {
                        writer.WriteInt16(TalkPosition.X);
                        writer.WriteInt16(TalkPosition.Y);
                    }, 8),
                LoadAndSaveEntry.Create(reader => IgnoreTurns = reader.ReadByte() != 0, writer => writer.WriteByte(IgnoreTurns), 8),

                // Actor layer switched to int32 in HE games
                LoadAndSaveEntry.Create(reader => Layer = reader.ReadByte(), writer => writer.WriteByte(Layer), 8, 57),
                LoadAndSaveEntry.Create(reader => Layer = reader.ReadInt32(), writer => writer.WriteInt32(Layer), 58),
                                             
                LoadAndSaveEntry.Create(reader => TalkScript = reader.ReadUInt16(), writer => writer.WriteUInt16(TalkScript), 8),
                LoadAndSaveEntry.Create(reader => WalkScript = reader.ReadUInt16(), writer => writer.WriteUInt16(WalkScript), 8),

                LoadAndSaveEntry.Create(reader => _walkdata.Dest.X = reader.ReadInt16(), writer => writer.WriteInt16(_walkdata.Dest.X), 8),
                LoadAndSaveEntry.Create(reader => _walkdata.Dest.Y = reader.ReadInt16(), writer => writer.WriteInt16(_walkdata.Dest.Y), 8),
                LoadAndSaveEntry.Create(reader => _walkdata.DestBox = reader.ReadByte(), writer => writer.WriteByte(_walkdata.DestBox), 8),
                LoadAndSaveEntry.Create(reader => _walkdata.DestDir = reader.ReadInt16(), writer => writer.WriteInt16(_walkdata.DestDir), 8),
                LoadAndSaveEntry.Create(reader => _walkdata.CurBox = reader.ReadByte(), writer => writer.WriteByte(_walkdata.CurBox), 8),
                LoadAndSaveEntry.Create(reader => _walkdata.Cur.X = reader.ReadInt16(), writer => writer.WriteInt16(_walkdata.Cur.X), 8),
                LoadAndSaveEntry.Create(reader => _walkdata.Cur.Y = reader.ReadInt16(), writer => writer.WriteInt16(_walkdata.Cur.Y), 8),
                LoadAndSaveEntry.Create(reader => _walkdata.Next.X = reader.ReadInt16(), writer => writer.WriteInt16(_walkdata.Next.X), 8),
                LoadAndSaveEntry.Create(reader => _walkdata.Next.Y = reader.ReadInt16(), writer => writer.WriteInt16(_walkdata.Next.Y), 8),
                LoadAndSaveEntry.Create(reader => _walkdata.DeltaXFactor = reader.ReadInt32(), writer => writer.WriteInt32(_walkdata.DeltaXFactor), 8),
                LoadAndSaveEntry.Create(reader => _walkdata.DeltaYFactor = reader.ReadInt32(), writer => writer.WriteInt32(_walkdata.DeltaYFactor), 8),
                LoadAndSaveEntry.Create(reader => _walkdata.XFrac = reader.ReadUInt16(), writer => writer.WriteUInt16(_walkdata.XFrac), 8),
                LoadAndSaveEntry.Create(reader => _walkdata.YFrac = reader.ReadUInt16(), writer => writer.WriteUInt16(_walkdata.YFrac), 8),

                LoadAndSaveEntry.Create(reader => _walkdata.Point3.X = reader.ReadInt16(), writer => writer.WriteInt16(_walkdata.Point3.X), 42),
                LoadAndSaveEntry.Create(reader => _walkdata.Point3.Y = reader.ReadInt16(), writer => writer.WriteInt16(_walkdata.Point3.Y), 42),

                LoadAndSaveEntry.Create(reader => Cost.Active = reader.ReadBytes(16), writer => writer.WriteBytes(Cost.Active, 16), 8),
                LoadAndSaveEntry.Create(reader => Cost.Stopped = reader.ReadUInt16(), writer => writer.WriteUInt16(Cost.Stopped), 8),
                LoadAndSaveEntry.Create(reader => Cost.Curpos = reader.ReadUInt16s(16), writer => writer.WriteUInt16s(Cost.Curpos, 16), 8),
                LoadAndSaveEntry.Create(reader => Cost.Start = reader.ReadUInt16s(16), writer => writer.WriteUInt16s(Cost.Start, 16), 8),
                LoadAndSaveEntry.Create(reader => Cost.End = reader.ReadUInt16s(16), writer => writer.WriteUInt16s(Cost.End, 16), 8),
                LoadAndSaveEntry.Create(reader => Cost.Frame = reader.ReadUInt16s(16), writer => writer.WriteUInt16s(Cost.Frame, 16), 8),
                                             
                LoadAndSaveEntry.Create(reader => reader.ReadUInt16s(16), writer => writer.WriteUInt16s(new ushort[16], 16), 65),
                LoadAndSaveEntry.Create(reader => reader.ReadUInt16s(16), writer => writer.WriteUInt16s(new ushort[16], 16), 65),
                LoadAndSaveEntry.Create(reader => reader.ReadUInt32s(16), writer => writer.WriteUInt32s(new uint[16], 16), 65),
            };

            if (serializer.IsLoading)
            {
                // Not all actor data is saved; so when loading, we first reset
                // the actor, to ensure completely reproducible behavior (else,
                // some not saved value in the actor class can cause odd things)
                Init(-1);
            }

            actorEntries.ForEach(e => e.Execute(serializer));

            if (serializer.IsLoading && _scumm.Game.Version <= 2 && serializer.Version < 70)
            {
                _position.X >>= ScummEngine.V12_X_SHIFT;
                _position.Y >>= ScummEngine.V12_Y_SHIFT;

                _speedx >>= ScummEngine.V12_X_SHIFT;
                _speedy >>= ScummEngine.V12_Y_SHIFT;
                _elevation >>= ScummEngine.V12_Y_SHIFT;

                if (_walkdata.Dest.X != -1)
                {
                    _walkdata.Dest.X >>= ScummEngine.V12_X_SHIFT;
                    _walkdata.Dest.Y >>= ScummEngine.V12_Y_SHIFT;
                }

                _walkdata.Cur.X >>= ScummEngine.V12_X_SHIFT;
                _walkdata.Cur.Y >>= ScummEngine.V12_Y_SHIFT;

                _walkdata.Next.X >>= ScummEngine.V12_X_SHIFT;
                _walkdata.Next.Y >>= ScummEngine.V12_Y_SHIFT;

                if (_walkdata.Point3.X != 32000)
                {
                    _walkdata.Point3.X >>= ScummEngine.V12_X_SHIFT;
                    _walkdata.Point3.Y >>= ScummEngine.V12_Y_SHIFT;
                }
            }
        }
コード例 #19
0
ファイル: InstrumentProgram.cs プロジェクト: scemino/nscumm
 public InstrumentProgram(Serializer s)
 {
     _program = 255;
     SaveOrLoad(s);
 }
コード例 #20
0
ファイル: Player_V2Base.cs プロジェクト: scemino/nscumm
 /// <summary>
 /// Save or load the music state.
 /// </summary>
 /// <param name="serializer">Serializer.</param>
 public virtual void SaveOrLoad(Serializer serializer)
 {
 }
コード例 #21
0
ファイル: Instrument.cs プロジェクト: scemino/nscumm
        public void SaveOrLoad(Serializer s)
        {
            if (!s.IsLoading)
            {
                s.Writer.WriteByte((byte)_type);
                if (_instrument != null)
                    _instrument.SaveOrLoad(s);
            }
            else
            {
                Clear();
                _type = (InstrumentType)s.Reader.ReadByte();
                switch (_type)
                {
                    case InstrumentType.None:
                        break;
                    case InstrumentType.Program:
                        _instrument = new InstrumentProgram(s);
                        break;
                    case InstrumentType.AdLib:
                        _instrument = new InstrumentAdLib(s.Reader.BaseStream);
                        break;
                // TODO: vs: Roland, MacSfx
//                    case InstrumentType.Roland:
//                        _instrument = new InstrumentRoland(s);
//                        break;
                    case InstrumentType.PcSpk:
                        _instrument = new InstrumentPcSpk(s.Reader.BaseStream);
                        break;
//                    case InstrumentType.MacSfx:
//                        _instrument = new InstrumentMacSfx(s);
//                        break;
                    default:
                        throw new NotSupportedException(string.Format("No known instrument classification #{0}", (int)_type));
                }
            }
        }
コード例 #22
0
ファイル: Player_V3A.cs プロジェクト: scemino/nscumm
 void IMusicEngine.SaveOrLoad(Serializer serializer)
 {
 }
コード例 #23
0
        void SaveOrLoadResources(Serializer serializer)
        {
            var entry = LoadAndSaveEntry.Create(
                            reader =>
                {
                    ResType type;
                    ushort idx;
                    while ((type = (ResType)reader.ReadUInt16()) != (ResType)0xFFFF)
                    {
                        while ((idx = reader.ReadUInt16()) != 0xFFFF)
                        {
                            LoadResource(reader, type, idx);
                        }
                    }
                },
                            writer =>
                {
                    // inventory
                    writer.WriteUInt16((ushort)ResType.Inventory);
                    for (int i = 0; i < _invData.Length; i++)
                    {
                        var data = _invData[i];
                        if (data == null)
                            break;
                        // write index
                        writer.WriteUInt16(i);
                        var verbTableLength = Game.Version == 8 ? 8 * data.ScriptOffsets.Count + 4 : 3 * data.ScriptOffsets.Count + 1;
                        var nameOffset = 18 + 1 + verbTableLength;
                        // write size
                        writer.WriteInt32(nameOffset + data.Name.Length + 1 + data.Script.Data.Length);
                        // write image offset
                        writer.WriteBytes(new byte[18], 18);
                        // write name offset
                        writer.WriteByte(nameOffset);
                        // write verb table
                        if (Game.Version == 8)
                        {
                            foreach (var scriptOffset in data.ScriptOffsets)
                            {
                                writer.WriteInt32(scriptOffset.Key);
                                writer.WriteInt32(scriptOffset.Value);
                            }
                            // write end of table
                            writer.WriteUInt32(0);
                        }
                        else
                        {
                            foreach (var scriptOffset in data.ScriptOffsets)
                            {
                                writer.WriteByte(scriptOffset.Key);
                                writer.WriteUInt16(scriptOffset.Value);
                            }
                            // write end of table
                            writer.WriteByte(0);
                        }
                        var name = EncodeName(data.Name);
                        // write name
                        for (int c = 0; c < name.Length; c++)
                        {
                            writer.WriteByte(name[c]);
                        }
                        writer.WriteByte(0);
                        // write script
                        writer.Write(data.Script.Data);
                        // write index
                        writer.WriteUInt16(_inventory[i]);
                    }
                    writer.WriteUInt16(0xFFFF);

                    // actors name
                    writer.WriteUInt16((ushort)ResType.ActorName);
                    for (int i = 0; i < Actors.Length; i++)
                    {
                        var actor = Actors[i];
                        if (actor.Name != null)
                        {
                            // write index
                            writer.WriteUInt16(i);
                            // write name
                            writer.WriteInt32(actor.Name.Length);
                            writer.WriteBytes(actor.Name, actor.Name.Length);
                        }
                    }
                    writer.WriteUInt16(0xFFFF);

                    // objects name
                    writer.WriteUInt16((ushort)ResType.ObjectName);
                    var objs = _invData.Where(obj => obj != null && obj.Number != 0).ToArray();
                    for (var i = 0; i < objs.Length; i++)
                    {
                        var obj = objs[i];
                        var name = GetObjectOrActorName(obj.Number);
                        if (name.Length > 0)
                        {
                            // write index
                            writer.WriteUInt16(i);
                            // write name
                            writer.WriteInt32(name.Length);
                            writer.WriteBytes(name, name.Length);
                            // writer obj number
                            writer.WriteUInt16(obj.Number);
                        }
                    }
                    writer.WriteUInt16(0xFFFF);

                    // matrix
                    writer.WriteUInt16((ushort)ResType.Matrix);
                    // write BoxMatrix
                    writer.WriteUInt16(1);
                    writer.WriteInt32(_boxMatrix.Count);
                    writer.WriteBytes(_boxMatrix.ToArray(), _boxMatrix.Count);

                    // write boxes
                    writer.WriteUInt16(2);
                    writer.WriteInt32((Game.Version == 8 ? 21 : 20) * _boxes.Length + 1);
                    writer.WriteByte(_boxes.Length);
                    for (int i = 0; i < _boxes.Length; i++)
                    {
                        Box box = _boxes[i];
                        writer.WriteInt16(box.Ulx);
                        writer.WriteInt16(box.Uly);
                        writer.WriteInt16(box.Urx);
                        writer.WriteInt16(box.Ury);
                        writer.WriteInt16(box.Lrx);
                        writer.WriteInt16(box.Lry);
                        writer.WriteInt16(box.Llx);
                        writer.WriteInt16(box.Lly);
                        writer.WriteByte(box.Mask);
                        writer.WriteByte((byte)box.Flags);
                        writer.WriteUInt16(box.Scale);
                        if (Game.Version == 8)
                        {
                            writer.WriteByte(box.ScaleSlot);
                        }
                    }
                    writer.WriteUInt16(0xFFFF);

                    // verbs
                    writer.WriteUInt16((ushort)ResType.Verb);
                    for (int i = 0; i < Verbs.Length; i++)
                    {
                        var verb = Verbs[i];
                        if (verb.Text != null)
                        {
                            // write index
                            writer.WriteUInt16(i);
                            // write text
                            writer.WriteInt32(verb.Text.Length);
                            writer.WriteBytes(verb.Text, verb.Text.Length);
                        }
                    }
                    writer.WriteUInt16(0xFFFF);

                    // verb images
                    writer.WriteUInt16((ushort)ResType.VerbImage);
                    for (int i = 0; i < Verbs.Length; i++)
                    {
                        var verb = Verbs[i];
                        if (verb.ImageData != null)
                        {
                            // write index
                            writer.WriteUInt16(i);
                            // write size
                            writer.WriteInt32(4 + verb.ImageData.Data.Length);
                            // wrie width and height
                            writer.WriteUInt16(verb.ImageWidth);
                            writer.WriteUInt16(verb.ImageHeight);
                            // write
                            writer.WriteBytes(verb.ImageData.Data, verb.ImageData.Data.Length);
                        }
                    }
                    writer.WriteUInt16(0xFFFF);

                    // strings
                    writer.WriteUInt16((ushort)ResType.String);
                    for (int i = 0; i < _strings.Length; i++)
                    {
                        var str = _strings[i];
                        if (str != null)
                        {
                            // write index
                            writer.WriteUInt16(i);
                            // write text
                            writer.WriteInt32(str.Length);
                            writer.WriteBytes(str, str.Length);
                        }
                    }
                    writer.WriteUInt16(0xFFFF);

                    // write end of resources
                    writer.WriteUInt16(0xFFFF);

                });
            entry.Execute(serializer);
        }
コード例 #24
0
        protected virtual void SaveOrLoad(Serializer serializer)
        {
            uint ENCD_offs = 0;
            uint EXCD_offs = 0;
            uint IM00_offs = 0;
            uint CLUT_offs = 0;
            uint EPAL_offs = 0;
            uint PALS_offs = 0;
            byte numObjectsInRoom = (byte)_objs.Length;

            #region MainEntries

            var mainEntries = new[]
            {
                LoadAndSaveEntry.Create(reader => _gameMD5 = reader.ReadBytes(16), writer => writer.Write(_gameMD5), 39),
                LoadAndSaveEntry.Create(reader => reader.ReadUInt16(), writer => writer.Write(roomData.Header.Width), 8, 50),
                LoadAndSaveEntry.Create(reader => reader.ReadUInt16(), writer => writer.Write(roomData.Header.Height), 8, 50),
                LoadAndSaveEntry.Create(reader => ENCD_offs = reader.ReadUInt32(), writer => writer.Write(ENCD_offs), 8, 50),
                LoadAndSaveEntry.Create(reader => EXCD_offs = reader.ReadUInt32(), writer => writer.Write(EXCD_offs), 8, 50),
                LoadAndSaveEntry.Create(reader => IM00_offs = reader.ReadUInt32(), writer => writer.Write(IM00_offs), 8, 50),
                LoadAndSaveEntry.Create(reader => CLUT_offs = reader.ReadUInt32(), writer => writer.Write(CLUT_offs), 8, 50),
                LoadAndSaveEntry.Create(reader => EPAL_offs = reader.ReadUInt32(), writer => writer.Write(EPAL_offs), 8, 9),
                LoadAndSaveEntry.Create(reader => PALS_offs = reader.ReadUInt32(), writer => writer.Write(PALS_offs), 8, 50),
                LoadAndSaveEntry.Create(reader => _curPalIndex = reader.ReadByte(), writer => writer.WriteByte(_curPalIndex), 8),
                LoadAndSaveEntry.Create(reader => _currentRoom = reader.ReadByte(), writer => writer.Write(_currentRoom), 8),
                LoadAndSaveEntry.Create(reader => _roomResource = reader.ReadByte(), writer => writer.Write(_roomResource), 8),
                LoadAndSaveEntry.Create(reader => numObjectsInRoom = reader.ReadByte(), writer => writer.Write(numObjectsInRoom), 8),
                LoadAndSaveEntry.Create(reader => CurrentScript = reader.ReadByte(), writer => writer.Write(CurrentScript), 8),
                LoadAndSaveEntry.Create(reader => reader.ReadUInt32s(NumLocalScripts), writer => writer.Write(new uint[NumLocalScripts], NumLocalScripts), 8, 50),
                // vm.localvar grew from 25 to 40 script entries and then from
                // 16 to 32 bit variables (but that wasn't reflect here)... and
                // THEN from 16 to 25 variables.
                LoadAndSaveEntry.Create(reader =>
                    {
                        for (int i = 0; i < 25; i++)
                        {
                            _slots[i].InitializeLocals(reader.ReadUInt16s(17));
                        }
                    }, writer =>
                    {
                        for (int i = 0; i < 25; i++)
                        {
                            writer.WriteUInt16s(_slots[i].LocalVariables.Cast<ushort>().ToArray(), 17);
                        }
                    }, 8, 8),
                LoadAndSaveEntry.Create(reader =>
                    {
                        for (int i = 0; i < 40; i++)
                        {
                            _slots[i].InitializeLocals(reader.ReadUInt16s(17));
                        }
                    }, writer =>
                    {
                        for (int i = 0; i < 40; i++)
                        {
                            writer.WriteUInt16s(_slots[i].LocalVariables.Cast<ushort>().ToArray(), 17);
                        }
                    }, 9, 14),
                // We used to save 25 * 40 = 1000 blocks; but actually, each 'row consisted of 26 entry,
                // i.e. 26 * 40 = 1040. Thus the last 40 blocks of localvar where not saved at all. To be
                // able to load this screwed format, we use a trick: We load 26 * 38 = 988 blocks.
                // Then, we mark the followin 12 blocks (24 bytes) as obsolete.
                LoadAndSaveEntry.Create(reader =>
                    {
                        for (int i = 0; i < 38; i++)
                        {
                            _slots[i].InitializeLocals(reader.ReadUInt16s(26));
                        }
                    }, writer =>
                    {
                        for (int i = 0; i < 38; i++)
                        {
                            writer.WriteUInt16s(_slots[i].LocalVariables.Cast<ushort>().ToArray(), 26);
                        }
                    }, 15, 17),
                // TODO
                //MK_OBSOLETE_ARRAY(ScummEngine, vm.localvar[39][0], sleUint16, 12, VER(15), VER(17)),
                // This was the first proper multi dimensional version of the localvars, with 32 bit values
                LoadAndSaveEntry.Create(reader =>
                    {
                        for (int i = 0; i < 40; i++)
                        {
                            _slots[i].InitializeLocals(reader.ReadInt32s(26));
                        }
                    }, writer =>
                    {
                        for (int i = 0; i < 40; i++)
                        {
                            writer.WriteInt32s(_slots[i].LocalVariables, 26);
                        }
                    }, 18, 19),

                // Then we doubled the script slots again, from 40 to 80
                LoadAndSaveEntry.Create(reader =>
                    {
                        for (int i = 0; i < NumScriptSlot; i++)
                        {
                            _slots[i].InitializeLocals(reader.ReadInt32s(26));
                        }
                    }, writer =>
                    {
                        for (int i = 0; i < NumScriptSlot; i++)
                        {
                            writer.WriteInt32s(_slots[i].LocalVariables, 26);
                        }
                    }, 20),

                LoadAndSaveEntry.Create(reader => _resourceMapper = reader.ReadBytes(128), writer => writer.Write(_resourceMapper), 8),
                LoadAndSaveEntry.Create(reader => CharsetColorMap = reader.ReadBytes(16), writer => writer.Write(CharsetColorMap), 8),

                // _charsetData grew from 10*16, to 15*16, to 23*16 bytes
                LoadAndSaveEntry.Create(reader => reader.ReadMatrixBytes(10, 16), writer => writer.WriteMatrixBytes(new byte[16, 10], 10, 16), 8, 9),
                LoadAndSaveEntry.Create(reader => reader.ReadMatrixBytes(15, 16), writer => writer.WriteMatrixBytes(new byte[16, 15], 15, 16), 10, 66),
                LoadAndSaveEntry.Create(reader => reader.ReadMatrixBytes(23, 16), writer => writer.WriteMatrixBytes(new byte[16, 23], 23, 16), 67),

                LoadAndSaveEntry.Create(reader => reader.ReadUInt16(), writer => writer.WriteUInt16(0), 8, 62),

                LoadAndSaveEntry.Create(reader => _camera.DestinationPosition.X = reader.ReadInt16(), writer => writer.WriteInt16(_camera.DestinationPosition.X), 8),
                LoadAndSaveEntry.Create(reader => _camera.DestinationPosition.Y = reader.ReadInt16(), writer => writer.WriteInt16(_camera.DestinationPosition.Y), 8),
                LoadAndSaveEntry.Create(reader => _camera.CurrentPosition.X = reader.ReadInt16(), writer => writer.WriteInt16(_camera.CurrentPosition.X), 8),
                LoadAndSaveEntry.Create(reader => _camera.CurrentPosition.Y = reader.ReadInt16(), writer => writer.WriteInt16(_camera.CurrentPosition.Y), 8),
                LoadAndSaveEntry.Create(reader => _camera.LastPosition.X = reader.ReadInt16(), writer => writer.WriteInt16(_camera.LastPosition.X), 8),
                LoadAndSaveEntry.Create(reader => _camera.LastPosition.Y = reader.ReadInt16(), writer => writer.WriteInt16(_camera.LastPosition.Y), 8),
                LoadAndSaveEntry.Create(reader => _camera.Accel.X = reader.ReadInt16(), writer => writer.WriteInt16(_camera.Accel.X), 8),
                LoadAndSaveEntry.Create(reader => _camera.Accel.Y = reader.ReadInt16(), writer => writer.WriteInt16(_camera.Accel.Y), 8),
                LoadAndSaveEntry.Create(reader => _screenStartStrip = reader.ReadInt16(), writer => writer.WriteInt16(_screenStartStrip), 8),
                LoadAndSaveEntry.Create(reader => _screenEndStrip = reader.ReadInt16(), writer => writer.WriteInt16(_screenEndStrip), 8),
                LoadAndSaveEntry.Create(reader => _camera.Mode = (CameraMode)reader.ReadByte(), writer => writer.Write((byte)_camera.Mode), 8),
                LoadAndSaveEntry.Create(reader => _camera.ActorToFollow = reader.ReadByte(), writer => writer.Write(_camera.ActorToFollow), 8),
                LoadAndSaveEntry.Create(reader => _camera.LeftTrigger = reader.ReadInt16(), writer => writer.WriteInt16(_camera.LeftTrigger), 8),
                LoadAndSaveEntry.Create(reader => _camera.RightTrigger = reader.ReadInt16(), writer => writer.WriteInt16(_camera.RightTrigger), 8),
                LoadAndSaveEntry.Create(reader => _camera.MovingToActor = reader.ReadUInt16() != 0, writer => writer.WriteUInt16(_camera.MovingToActor), 8),

                LoadAndSaveEntry.Create(reader => _actorToPrintStrFor = reader.ReadByte(), writer => writer.WriteByte(_actorToPrintStrFor), 8),
                LoadAndSaveEntry.Create(reader => _charsetColor = reader.ReadByte(), writer => writer.WriteByte(_charsetColor), 8),

                // _charsetBufPos was changed from byte to int
                LoadAndSaveEntry.Create(reader => _charsetBufPos = reader.ReadByte(), writer => writer.WriteByte(_charsetBufPos), 8, 9),
                LoadAndSaveEntry.Create(reader => _charsetBufPos = reader.ReadInt16(), writer => writer.WriteInt16(_charsetBufPos), 10),

                LoadAndSaveEntry.Create(reader => _haveMsg = reader.ReadByte(), writer => writer.WriteByte(_haveMsg), 8),
                LoadAndSaveEntry.Create(reader => _haveActorSpeechMsg = reader.ReadByte() != 0, writer => writer.WriteByte(_haveActorSpeechMsg), 61),
                LoadAndSaveEntry.Create(reader => _useTalkAnims = reader.ReadByte() != 0, writer => writer.WriteByte(_useTalkAnims), 8),

                LoadAndSaveEntry.Create(reader => _talkDelay = reader.ReadInt16(), writer => writer.WriteInt16(_talkDelay), 8),
                LoadAndSaveEntry.Create(reader => reader.ReadInt16(), writer => writer.WriteInt16(0), 8),
                LoadAndSaveEntry.Create(reader => reader.ReadInt16(), writer => writer.WriteInt16(0), 8, 27),
                LoadAndSaveEntry.Create(reader => SentenceNum = reader.ReadByte(), writer => writer.WriteByte(SentenceNum), 8),

                LoadAndSaveEntry.Create(reader => cutScene.SaveOrLoad(serializer), writer => cutScene.SaveOrLoad(serializer), 8),

                LoadAndSaveEntry.Create(reader => _numNestedScripts = reader.ReadByte(), writer => writer.WriteByte(_numNestedScripts), 8),
                LoadAndSaveEntry.Create(reader => _userPut = (sbyte)reader.ReadByte(), writer => writer.WriteByte(_userPut), 8),
                LoadAndSaveEntry.Create(reader => reader.ReadUInt16(), writer => writer.WriteUInt16(0), 17),
                LoadAndSaveEntry.Create(reader => _cursor.State = (sbyte)reader.ReadByte(), writer => writer.WriteByte(_cursor.State), 8),
                LoadAndSaveEntry.Create(reader => reader.ReadByte(), writer => writer.WriteByte(0), 8, 20),
                LoadAndSaveEntry.Create(reader => _currentCursor = reader.ReadByte(), writer => writer.WriteByte(_currentCursor), 8),
                LoadAndSaveEntry.Create(reader => _cursorData = reader.ReadBytes(8192), writer =>
                    {
                        var data = new byte[8192];
                        if (_cursorData != null)
                        {
                            Array.Copy(_cursorData, data, _cursorData.Length);
                        }
                        writer.Write(data);
                    }, 20),
                LoadAndSaveEntry.Create(reader => _cursor.Width = reader.ReadInt16(), writer => writer.WriteInt16(_cursor.Width), 20),
                LoadAndSaveEntry.Create(reader => _cursor.Height = reader.ReadInt16(), writer => writer.WriteInt16(_cursor.Height), 20),
                LoadAndSaveEntry.Create(reader => _cursor.Hotspot = new Point(reader.ReadInt16(), reader.ReadInt16()), writer =>
                    {
                        writer.WriteInt16(_cursor.Hotspot.X);
                        writer.WriteInt16(_cursor.Hotspot.Y);
                    }, 20),
                LoadAndSaveEntry.Create(reader => _cursor.Animate = reader.ReadByte() != 0, writer => writer.WriteByte(_cursor.Animate), 20),
                LoadAndSaveEntry.Create(reader => _cursor.AnimateIndex = reader.ReadByte(), writer => writer.WriteByte(_cursor.AnimateIndex), 20),
                LoadAndSaveEntry.Create(reader => reader.ReadInt16(), writer => writer.WriteInt16(0), 20),
                LoadAndSaveEntry.Create(reader => reader.ReadInt16(), writer => writer.WriteInt16(0), 20),

                LoadAndSaveEntry.Create(reader => reader.ReadBytes(256), writer => writer.Write(new byte[256]), 60),
                LoadAndSaveEntry.Create(reader => _doEffect = reader.ReadByte() != 0, writer => writer.WriteByte(_doEffect), 8),
                LoadAndSaveEntry.Create(reader => _switchRoomEffect = reader.ReadByte(), writer => writer.WriteByte(_switchRoomEffect), 8),
                LoadAndSaveEntry.Create(reader => _newEffect = reader.ReadByte(), writer => writer.WriteByte(_newEffect), 8),
                LoadAndSaveEntry.Create(reader => _switchRoomEffect2 = reader.ReadByte(), writer => writer.WriteByte(_switchRoomEffect2), 8),
                LoadAndSaveEntry.Create(reader => _bgNeedsRedraw = reader.ReadByte() != 0, writer => writer.WriteByte(_bgNeedsRedraw), 8),

                // The state of palManipulate is stored only since V10
                LoadAndSaveEntry.Create(reader => _palManipStart = reader.ReadByte(), writer => writer.WriteByte(_palManipStart), 10),
                LoadAndSaveEntry.Create(reader => _palManipEnd = reader.ReadByte(), writer => writer.WriteByte(_palManipEnd), 10),
                LoadAndSaveEntry.Create(reader => _palManipCounter = reader.ReadUInt16(), writer => writer.WriteUInt16(_palManipCounter), 10),

                // gfxUsageBits grew from 200 to 410 entries. Then 3 * 410 entries:
                LoadAndSaveEntry.Create(reader => Gdi.SaveOrLoad(serializer), writer => Gdi.SaveOrLoad(serializer), 0),

                LoadAndSaveEntry.Create(reader => Gdi.TransparentColor = reader.ReadByte(), writer => writer.WriteByte(Gdi.TransparentColor), 8, 50),
                LoadAndSaveEntry.Create(reader =>
                    {
                        for (int i = 0; i < 256; i++)
                        {
                            _currentPalette.Colors[i] = Color.FromRgb(reader.ReadByte(), reader.ReadByte(), reader.ReadByte());
                        }
                    }, writer =>
                    {
                        for (int i = 0; i < 256; i++)
                        {
                            var l_color = _currentPalette.Colors[i];
                            writer.WriteByte(l_color.R);
                            writer.WriteByte(l_color.G);
                            writer.WriteByte(l_color.B);
                        }
                    }, 8),
                LoadAndSaveEntry.Create(reader => reader.ReadBytes(768), writer => writer.Write(new byte[768]), 53),

                // Sam & Max specific palette replaced by _shadowPalette now.
                LoadAndSaveEntry.Create(reader => reader.ReadBytes(256), writer => writer.Write(new byte[256]), 8, 33),

                LoadAndSaveEntry.Create(reader => _charsetBuffer = reader.ReadBytes(256), writer => writer.WriteBytes(_charsetBuffer, 256), 8),

                LoadAndSaveEntry.Create(reader => EgoPositioned = reader.ReadByte() != 0, writer => writer.WriteByte(EgoPositioned), 8),

                // _gdi->_imgBufOffs grew from 4 to 5 entries. Then one day we realized
                // that we don't have to store it since initBGBuffers() recomputes it.
                LoadAndSaveEntry.Create(reader => reader.ReadUInt16s(4), writer => writer.WriteUInt16s(new ushort[4], 4), 8, 9),
                LoadAndSaveEntry.Create(reader => reader.ReadUInt16s(5), writer => writer.WriteUInt16s(new ushort[5], 5), 10, 26),

                // See _imgBufOffs: _numZBuffer is recomputed by initBGBuffers().
                LoadAndSaveEntry.Create(reader => Gdi.NumZBuffer = reader.ReadByte(), writer => writer.WriteByte(Gdi.NumZBuffer), 8, 26),

                LoadAndSaveEntry.Create(reader => _screenEffectFlag = reader.ReadByte() != 0, writer => writer.WriteByte(_screenEffectFlag), 8),

                LoadAndSaveEntry.Create(reader => reader.ReadByte(), writer => writer.WriteByte(0), 8, 9),
                LoadAndSaveEntry.Create(reader => reader.ReadByte(), writer => writer.WriteByte(0), 8, 9),

                // Converted _shakeEnabled to boolean and added a _shakeFrame field.
                LoadAndSaveEntry.Create(reader => _shakeEnabled = reader.ReadInt16() == 1, writer => writer.WriteInt16(_shakeEnabled ? 1 : 0), 8, 9),
                LoadAndSaveEntry.Create(reader => _shakeEnabled = reader.ReadBoolean(), writer => writer.WriteByte(_shakeEnabled), 10),
                LoadAndSaveEntry.Create(reader => _shakeFrame = (int)reader.ReadUInt32(), writer => writer.WriteUInt32((uint)_shakeFrame), 10),

                LoadAndSaveEntry.Create(reader => _keepText = reader.ReadByte() != 0, writer => writer.WriteByte(_keepText), 8),

                LoadAndSaveEntry.Create(reader => _screenB = reader.ReadUInt16(), writer => writer.WriteUInt16(_screenB), 8),
                LoadAndSaveEntry.Create(reader => _screenH = reader.ReadUInt16(), writer => writer.WriteUInt16(_screenH), 8),

                LoadAndSaveEntry.Create(reader => reader.ReadUInt16(), writer => writer.WriteUInt16(0), 47),

                LoadAndSaveEntry.Create(reader => reader.ReadInt16(), writer => writer.WriteInt16(0), 9, 9),
                LoadAndSaveEntry.Create(reader => reader.ReadInt16(), writer => writer.WriteInt16(0), 9, 9),
                LoadAndSaveEntry.Create(reader => reader.ReadInt16(), writer => writer.WriteInt16(0), 9, 9),
                LoadAndSaveEntry.Create(reader => reader.ReadInt16(), writer => writer.WriteInt16(0), 9, 9)
            };

            #endregion MainEntries

            var md5Backup = new byte[16];
            Array.Copy(_gameMD5, md5Backup, 16);

            for (int i = 0; i < mainEntries.Length; i++)
            {
                mainEntries[i].Execute(serializer);
            }

            if (serializer.IsLoading)
            {
                roomData = _resManager.GetRoom(_roomResource);
            }
            //if (!Array.Equals(md5Backup, _gameMD5))
            //{
            //    //warning("Game was saved with different gamedata - you may encounter problems");
            //    //debug(1, "You have %s and save is %s.", md5str2, md5str1);
            //    return false;
            //}

            // Starting V14, we extended the usage bits, to be able to cope with games
            // that have more than 30 actors (up to 94 are supported now, in theory).
            // Since the format of the usage bits was changed by this, we have to
            // convert them when loading an older savegame.
//            if (serializer.IsLoading && serializer.Version < 14)
//                Gdi.UpgradeGfxUsageBits();

            // When loading, move the mouse to the saved mouse position.
            //if (serializer.Version >= 20)
            //{
            //    UpdateCursor();
            //    _system->warpMouse(_mouse.x, _mouse.y);
            //}

            // Before V61, we re-used the _haveMsg flag to handle "alternative" speech
            // sound files (see charset code 10).
            if (serializer.IsLoading && serializer.Version < 61)
            {
                if (_haveMsg == 0xFE)
                {
                    _haveActorSpeechMsg = false;
                    _haveMsg = 0xFF;
                }
                else
                {
                    _haveActorSpeechMsg = true;
                }
            }

            //
            // Save/load actors
            //
            for (int i = 0; i < Actors.Length; i++)
            {
                Actors[i].SaveOrLoad(serializer);
            }

            //
            // Save/load sound data
            //
            Sound.SaveOrLoad(serializer);

            //
            // Save/load script data
            //
            if (serializer.Version < 9)
            {
                for (int i = 0; i < 25; i++)
                {
                    _slots[i].SaveOrLoad(serializer, roomData.LocalScripts, ResourceManager.NumGlobalScripts);
                }
            }
            else if (serializer.Version < 20)
            {
                for (int i = 0; i < 40; i++)
                {
                    _slots[i].SaveOrLoad(serializer, roomData.LocalScripts, ResourceManager.NumGlobalScripts);
                }
            }
            else
            {
                for (int i = 0; i < NumScriptSlot; i++)
                {
                    _slots[i].SaveOrLoad(serializer, roomData.LocalScripts, ResourceManager.NumGlobalScripts);
                }
            }
            if (serializer.IsLoading)
            {
                _slots.ForEach(slot =>
                    {
                        if (slot.Where == WhereIsObject.Global)
                        {
                            slot.Offset -= 6;
                        }
                        else if (slot.Where == WhereIsObject.Local && slot.Number >= ResourceManager.NumGlobalScripts && roomData.LocalScripts[slot.Number - ResourceManager.NumGlobalScripts] != null)
                        {
                            slot.Offset = (uint)(slot.Offset - roomData.LocalScripts[slot.Number - ResourceManager.NumGlobalScripts].Offset);
                        }
                    });

                ResetRoomObjects();
            }

            //
            // Save/load local objects
            //
            for (int i = 0; i < _objs.Length; i++)
            {
                _objs[i].SaveOrLoad(serializer);
            }

            //
            // Save/load misc stuff
            //
            for (int i = 0; i < Verbs.Length; i++)
            {
                Verbs[i].SaveOrLoad(serializer);
            }
            for (int i = 0; i < 16; i++)
            {
                _nest[i].SaveOrLoad(serializer);
            }
            for (int i = 0; i < 6; i++)
            {
                _sentence[i].SaveOrLoad(serializer);
            }
            for (int i = 0; i < 6; i++)
            {
                _string[i].SaveOrLoad(serializer);
            }
            for (int i = 0; i < 16; i++)
            {
                _colorCycle[i].SaveOrLoad(serializer);
            }
            if (serializer.Version >= 13)
            {
                for (int i = 0; i < 20; i++)
                {
                    if (serializer.IsLoading)
                    {
                        _scaleSlots[i] = new ScaleSlot();
                    }
                    if (_scaleSlots[i] != null)
                    {
                        _scaleSlots[i].SaveOrLoad(serializer);
                    }
                }
            }

            //
            // Save/load resources
            //
            SaveOrLoadResources(serializer);

            //
            // Save/load global object state
            //
            var objStatesEntries = new[]
            {
                LoadAndSaveEntry.Create(reader =>
                    {
                        var objectOwnerTable = reader.ReadBytes(_resManager.ObjectOwnerTable.Length);
                        Array.Copy(objectOwnerTable, _resManager.ObjectOwnerTable, _resManager.ObjectOwnerTable.Length);
                    },
                    writer => writer.WriteBytes(_resManager.ObjectOwnerTable, _resManager.ObjectOwnerTable.Length)),
                LoadAndSaveEntry.Create(reader =>
                    {
                        var objectStateTable = reader.ReadBytes(_resManager.ObjectStateTable.Length);
                        Array.Copy(objectStateTable, _resManager.ObjectStateTable, _resManager.ObjectStateTable.Length);
                    },
                    writer => writer.WriteBytes(_resManager.ObjectStateTable, _resManager.ObjectStateTable.Length))
            };
            objStatesEntries.ForEach(e => e.Execute(serializer));

            //if (_objectRoomTable)
            //    s->saveLoadArrayOf(_objectRoomTable, _numGlobalObjects, sizeof(_objectRoomTable[0]), sleByte);

            //
            // Save/load palette data
            // Don't save 16 bit palette in FM-Towns and PCE games, since it gets regenerated afterwards anyway.
            //if (_16BitPalette && !(_game.platform == Common::kPlatformFMTowns && s->getVersion() < VER(82)) && !((_game.platform == Common::kPlatformFMTowns || _game.platform == Common::kPlatformPCEngine) && s->getVersion() > VER(87))) {
            //    s->saveLoadArrayOf(_16BitPalette, 512, sizeof(_16BitPalette[0]), sleUint16);
            //}

            var paletteEntries = new[]
            {
                LoadAndSaveEntry.Create(
                    reader => _shadowPalette = reader.ReadBytes(_shadowPalette.Length),
                    writer => writer.WriteBytes(_shadowPalette, _shadowPalette.Length)),
                // _roomPalette didn't show up until V21 save games
                // Note that we also save the room palette for Indy4 Amiga, since it
                // is used as palette map there too, but we do so slightly a bit
                // further down to group it with the other special palettes needed.
                LoadAndSaveEntry.Create(
                    reader => Gdi.RoomPalette = reader.ReadBytes(256),
                    writer => writer.WriteBytes(Gdi.RoomPalette, 256)
                        , 21),

                // PalManip data was not saved before V10 save games
                LoadAndSaveEntry.Create(reader =>
                    {
                        if (_palManipCounter != 0)
                        {
                            var colors = reader.ReadBytes(0x300);
                            for (int i = 0; i < 0x100; i++)
                            {
                                _palManipPalette.Colors[i] = Color.FromRgb(colors[i * 3], colors[i * 3 + 1], colors[i * 3 + 2]);    
                            }
                            var colors2 = reader.ReadUInt16s(0x300);
                            for (int i = 0; i < 0x100; i++)
                            {
                                _palManipIntermediatePal.Colors[i] = Color.FromRgb(colors2[i * 3], colors2[i * 3 + 1], colors2[i * 3 + 2]);    
                            }
                        }
                    },
                    writer =>
                    {
                        if (_palManipCounter != 0)
                        {
                            for (int i = 0; i < 0x100; i++)
                            {
                                writer.WriteByte(_palManipPalette.Colors[i].R);
                                writer.WriteByte(_palManipPalette.Colors[i].G);
                                writer.WriteByte(_palManipPalette.Colors[i].B);
                            }
                            for (int i = 0; i < 0x100; i++)
                            {
                                writer.WriteUInt16(_palManipIntermediatePal.Colors[i].R);
                                writer.WriteUInt16(_palManipIntermediatePal.Colors[i].G);
                                writer.WriteUInt16(_palManipIntermediatePal.Colors[i].B);
                            }
                        }
                    }, 10),


                // darkenPalette was not saved before V53
                LoadAndSaveEntry.Create(reader =>
                    {
                        // TODO?
                        //Array.Copy(currentPalette, darkenPalette, 768);
                    }, 0, 53),
                
            };
            paletteEntries.ForEach(entry => entry.Execute(serializer));

            // _colorUsedByCycle was not saved before V60
            if (serializer.IsLoading)
            {
                if (serializer.Version < 60)
                {
                    //Array.Clear(_colorUsedByCycle, 0, _colorUsedByCycle.Length);
                }
            }

            // Indy4 Amiga specific palette tables were not saved before V85
            //if (_game.platform == Common::kPlatformAmiga && _game.id == GID_INDY4) {
            //    if (s->getVersion() >= 85) {
            //        s->saveLoadArrayOf(_roomPalette, 256, 1, sleByte);
            //        s->saveLoadArrayOf(_verbPalette, 256, 1, sleByte);
            //        s->saveLoadArrayOf(_amigaPalette, 3 * 64, 1, sleByte);

            //        // Starting from version 86 we also save the first used color in
            //        // the palette beyond the verb palette. For old versions we just
            //        // look for it again, which hopefully won't cause any troubles.
            //        if (s->getVersion() >= 86) {
            //            s->saveLoadArrayOf(&_amigaFirstUsedColor, 1, 2, sleUint16);
            //        } else {
            //            amigaPaletteFindFirstUsedColor();
            //        }
            //    } else {
            //        warning("Save with old Indiana Jones 4 Amiga palette handling detected");
            //        // We need to restore the internal state of the Amiga palette for Indy4
            //        // Amiga. This might lead to graphics glitches!
            //        setAmigaPaletteFromPtr(_currentPalette);
            //    }
            //}

            //
            // Save/load more global object state
            //
            var globalObjStatesEntries = new[]
            {
                LoadAndSaveEntry.Create(
                    reader => Array.Copy(reader.ReadUInt32s(_resManager.ClassData.Length), _resManager.ClassData, _resManager.ClassData.Length),
                    writer => writer.WriteUInt32s(_resManager.ClassData, _resManager.ClassData.Length))
            };
            globalObjStatesEntries.ForEach(entry => entry.Execute(serializer));

            //
            // Save/load script variables
            //
            var var120Backup = _variables[120];
            var var98Backup = _variables[98];

            //if (serializer.Version > 37)
            //{
            //    s->saveLoadArrayOf(_roomVars, _numRoomVariables, sizeof(_roomVars[0]), sleInt32);
            //}

            // The variables grew from 16 to 32 bit.
            var variablesEntries = new[]
            {
                LoadAndSaveEntry.Create(
                    reader => _variables = reader.ReadInt16s(_variables.Length).ConvertAll(s => (int)s),
                    writer => writer.WriteInt16s(_variables, _variables.Length)
                        , 0, 15),
                LoadAndSaveEntry.Create(
                    reader => _variables = reader.ReadInt32s(_variables.Length),
                    writer => writer.WriteInt32s(_variables, _variables.Length), 15),
                LoadAndSaveEntry.Create(
                    reader => _bitVars = new BitArray(reader.ReadBytes(_bitVars.Length / 8)),
                    writer => writer.Write(_bitVars.ToByteArray())
                ),
            };
            variablesEntries.ForEach(entry => entry.Execute(serializer));

            if (_game.GameId == GameId.Tentacle) // Maybe misplaced, but that's the main idea
            {
                _variables[120] = var120Backup;
            }
            if (_game.GameId == GameId.Indy4)
            {
                _variables[98] = var98Backup;
            }

            //
            // Save/load a list of the locked objects
            //
            var lockedObjEntries = new[]
            {
                LoadAndSaveEntry.Create(reader =>
                    {
                        ResType tmp;
                        while ((tmp = (ResType)reader.ReadByte()) != (ResType)0xFF)
                        {
                            var index = reader.ReadUInt16();
                            if (tmp == ResType.FlObject)
                            {
                                _objs[index].IsLocked = true;
                            }
                        }
                    },
                    writer =>
                    {
                        for (int i = 0; i < _objs.Length; i++)
                        {
                            if (_objs[i].IsLocked)
                            {
                                writer.WriteByte((byte)ResType.FlObject);
                                writer.WriteUInt16(i);
                            }
                        }
                        writer.Write((byte)0xFF);
                    }
                )
            };
            lockedObjEntries.ForEach(entry => entry.Execute(serializer));

            //
            // Save/load the Audio CD status
            //
            //if (serializer.Version >= 24)
            //{
            //    AudioCDManager::Status info;
            //    if (s->isSaving())
            //        info = _system->getAudioCDManager()->getStatus();
            //    s->saveLoadArrayOf(&info, 1, sizeof(info), audioCDEntries);
            //     If we are loading, and the music being loaded was supposed to loop
            //     forever, then resume playing it. This helps a lot when the audio CD
            //     is used to provide ambient music (see bug #788195).
            //    if (s->isLoading() && info.playing && info.numLoops < 0)
            //      _system->getAudioCDManager()->play(info.track, info.numLoops, info.start, info.duration);
            //}

            //
            // Save/load the iMuse status
            //
            if (IMuse != null && (_saveSound || !_saveTemporaryState))
            {
                IMuse.SaveOrLoad(serializer);
            }

            //
            // Save/load music engine status
            //
            if (MusicEngine != null)
            {
                MusicEngine.SaveOrLoad(serializer);
            }

            //
            // Save/load the charset renderer state
            //
            //if (s->getVersion() >= VER(73))
            //{
            //    _charset->saveLoadWithSerializer(s);
            //}
            //else if (s->isLoading())
            //{
            //    if (s->getVersion() == VER(72))
            //    {
            //        _charset->setCurID(s->loadByte());
            //    }
            //    else
            //    {
            //        // Before V72, the charset id wasn't saved. This used to cause issues such
            //        // as the one described in the bug report #1722153. For these savegames,
            //        // we reinitialize the id using a, hopefully, sane value.
            //        _charset->setCurID(_string[0]._default.charset);
            //    }
            //}
        }
コード例 #25
0
ファイル: Sound.cs プロジェクト: scemino/nscumm
        public void SaveOrLoad(Serializer serializer)
        {
            short _currentMusic = 0;
            var soundEntries = new[]
            {
                LoadAndSaveEntry.Create(r => _currentCDSound = r.ReadInt16(), writer => writer.WriteInt16(_currentCDSound), 35),
                LoadAndSaveEntry.Create(r => _currentMusic = r.ReadInt16(), writer => writer.WriteInt16(_currentMusic), 35),
            };

            soundEntries.ForEach(e => e.Execute(serializer));
        }
コード例 #26
0
ファイル: ObjectData.cs プロジェクト: scemino/nscumm
 public void SaveOrLoad(Serializer serializer)
 {
     if (serializer.IsLoading)
     {
         Images.Clear();
     }
     var objectEntries = new[]
     {
         LoadAndSaveEntry.Create(reader => reader.ReadUInt32(), writer => writer.WriteUInt32(0), 8),
         LoadAndSaveEntry.Create(reader => reader.ReadUInt32(), writer => writer.WriteUInt32(0), 8),
         LoadAndSaveEntry.Create(reader =>
             {
                 Walk = new Point(reader.ReadInt16(), reader.ReadInt16());
             }, writer =>
             {
                 writer.WriteInt16(Walk.X);
                 writer.WriteInt16(Walk.Y);
             }, 8),
         LoadAndSaveEntry.Create(reader => Number = reader.ReadUInt16(), writer => writer.Write(Number), 8),
         LoadAndSaveEntry.Create(reader =>
             {
                 Position = new Point(reader.ReadInt16(), reader.ReadInt16());
             }, writer =>
             {
                 writer.WriteInt16(Position.X);
                 writer.WriteInt16(Position.Y);
             }, 8),
         LoadAndSaveEntry.Create(reader => Width = reader.ReadUInt16(), writer => writer.WriteUInt16(Width), 8),
         LoadAndSaveEntry.Create(reader => Height = reader.ReadUInt16(), writer => writer.WriteUInt16(Height), 8),
         LoadAndSaveEntry.Create(reader => ActorDir = reader.ReadByte(), writer => writer.WriteByte(ActorDir), 8),
         LoadAndSaveEntry.Create(reader => ParentState = reader.ReadByte(), writer => writer.WriteByte(ParentState), 8),
         LoadAndSaveEntry.Create(reader => Parent = reader.ReadByte(), writer => writer.WriteByte(Parent), 8),
         LoadAndSaveEntry.Create(reader => State = reader.ReadByte(), writer => writer.WriteByte(State), 8),
         LoadAndSaveEntry.Create(reader => reader.ReadByte(), writer => writer.WriteByte(0), 8),
         LoadAndSaveEntry.Create(reader => Flags = (DrawBitmaps)reader.ReadByte(), writer => writer.WriteByte((byte)Flags), 46),
     };
     objectEntries.ForEach(e => e.Execute(serializer));
 }
コード例 #27
0
ファイル: Part.cs プロジェクト: scemino/nscumm
        public void SaveOrLoad(Serializer ser)
        {
            var partEntries = new []
            {
                LoadAndSaveEntry.Create(r => _pitchbend = r.ReadInt16(), w => w.WriteInt16(_pitchbend), 8),
                LoadAndSaveEntry.Create(r => _pitchbend_factor = r.ReadByte(), w => w.WriteByte(_pitchbend_factor), 8),
                LoadAndSaveEntry.Create(r => Transpose = r.ReadSByte(), w => w.Write((sbyte)Transpose), 8),
                LoadAndSaveEntry.Create(r => _vol = r.ReadByte(), w => w.WriteByte(_vol), 8),
                LoadAndSaveEntry.Create(r => _detune = r.ReadSByte(), w => w.Write((sbyte)_detune), 8),
                LoadAndSaveEntry.Create(r => _pan = r.ReadSByte(), w => w.Write((sbyte)_pan), 8),
                LoadAndSaveEntry.Create(r => On = r.ReadBoolean(), w => w.Write(On), 8),
                LoadAndSaveEntry.Create(r => _modwheel = r.ReadByte(), w => w.WriteByte(_modwheel), 8),
                LoadAndSaveEntry.Create(r => Pedal = r.ReadBoolean(), w => w.Write(Pedal), 8),
                LoadAndSaveEntry.Create(r => r.ReadByte(), w => w.WriteByte(0), 8, 16),
                LoadAndSaveEntry.Create(r => priority = r.ReadByte(), w => w.WriteByte(priority), 8),
                LoadAndSaveEntry.Create(r => Channel = r.ReadByte(), w => w.WriteByte(Channel), 8),
                LoadAndSaveEntry.Create(r => _effect_level = r.ReadByte(), w => w.WriteByte(_effect_level), 8),
                LoadAndSaveEntry.Create(r => _chorus = r.ReadByte(), w => w.WriteByte(_chorus), 8),
                LoadAndSaveEntry.Create(r => Percussion = r.ReadBoolean(), w => w.Write(Percussion), 8),
                LoadAndSaveEntry.Create(r => _bank = r.ReadByte(), w => w.WriteByte(_bank), 8)
            };

            int num;
            if (!ser.IsLoading)
            {
                num = Next != null ? Array.IndexOf(Se._parts, Next) + 1 : 0;
                ser.Writer.WriteUInt16(num);

                num = Previous != null ? Array.IndexOf(Se._parts, Previous) + 1 : 0;
                ser.Writer.WriteUInt16(num);

                num = Player != null ? Array.IndexOf(Se._players, Player) + 1 : 0;
                ser.Writer.WriteUInt16(num);
            }
            else
            {
                num = ser.Reader.ReadUInt16();
                Next = num != 0 ? Se._parts[num - 1] : null;

                num = ser.Reader.ReadUInt16();
                Previous = num != 0 ? Se._parts[num - 1] : null;

                num = ser.Reader.ReadUInt16();
                Player = num != 0 ? Se._players[num - 1] : null;
            }
            partEntries.ForEach(e => e.Execute(ser));
        }
コード例 #28
0
ファイル: Actor0.cs プロジェクト: scemino/nscumm
        public override void SaveOrLoad(Serializer serializer)
        {
            base.SaveOrLoad(serializer);

            var actorEntries = new[]
            {
                LoadAndSaveEntry.Create(reader => CostCommand = reader.ReadByte(), writer => writer.WriteByte(CostCommand), 84),
                LoadAndSaveEntry.Create(reader => MiscFlags = (ActorV0MiscFlags)reader.ReadByte(), writer => writer.WriteByte((byte)MiscFlags), 84),
                LoadAndSaveEntry.Create(reader => Speaking = reader.ReadByte(), writer => writer.WriteByte(Speaking), 84),
                LoadAndSaveEntry.Create(reader => AnimFrameRepeat = reader.ReadSByte(), writer => writer.WriteByte(AnimFrameRepeat), 89),
                LoadAndSaveEntry.Create(reader => LimbFrameRepeatNew = reader.ReadSBytes(8), writer => writer.WriteSBytes(LimbFrameRepeatNew, 8), 89),
                LoadAndSaveEntry.Create(reader => LimbFrameRepeat = reader.ReadSBytes(8), writer => writer.WriteSBytes(LimbFrameRepeat, 8), 90),
                LoadAndSaveEntry.Create(reader =>
                    {
                        CurrentWalkTo = new Point(reader.ReadInt16(), reader.ReadInt16());
                    }, writer =>
                    {
                        writer.WriteInt16(CurrentWalkTo.X);
                        writer.WriteInt16(CurrentWalkTo.Y);
                    }, 97),
                LoadAndSaveEntry.Create(reader =>
                    {
                        NewWalkTo = new Point(reader.ReadInt16(), reader.ReadInt16());
                    }, writer =>
                    {
                        writer.WriteInt16(NewWalkTo.X);
                        writer.WriteInt16(NewWalkTo.Y);
                    }, 97),
                LoadAndSaveEntry.Create(reader => _walkCountModulo = reader.ReadByte(), writer => writer.WriteByte(_walkCountModulo), 97),
                LoadAndSaveEntry.Create(reader => _walkDirX = reader.ReadByte(), writer => writer.WriteByte(_walkDirX), 97),
                LoadAndSaveEntry.Create(reader => _walkDirY = reader.ReadByte(), writer => writer.WriteByte(_walkDirY), 97),
                LoadAndSaveEntry.Create(reader => _walkYCountGreaterThanXCount = reader.ReadByte(), writer => writer.WriteByte(_walkYCountGreaterThanXCount), 97),
                LoadAndSaveEntry.Create(reader => _walkXCount = reader.ReadByte(), writer => writer.WriteByte(_walkXCount), 97),
                LoadAndSaveEntry.Create(reader => _walkXCountInc = reader.ReadByte(), writer => writer.WriteByte(_walkXCountInc), 97),
                LoadAndSaveEntry.Create(reader => _walkYCount = reader.ReadByte(), writer => writer.WriteByte(_walkYCount), 97),
                LoadAndSaveEntry.Create(reader => _walkYCountInc = reader.ReadByte(), writer => writer.WriteByte(_walkYCountInc), 97),
                LoadAndSaveEntry.Create(reader => _walkMaxXYCountInc = reader.ReadByte(), writer => writer.WriteByte(_walkMaxXYCountInc), 97)
            };

            actorEntries.ForEach(e => e.Execute(serializer));
        }
コード例 #29
0
ファイル: ScummEngine2.cs プロジェクト: scemino/nscumm
        protected override void SaveOrLoad(Serializer serializer)
        {
            base.SaveOrLoad(serializer);

            if (Game.Version <= 2)
            {
                var v2Entries = new[]
                {
                    LoadAndSaveEntry.Create(reader => _inventoryOffset = reader.ReadUInt16(), writer => writer.WriteUInt16(_inventoryOffset), 39)
                };
                v2Entries.ForEach(entry => entry.Execute(serializer));

                // In old saves we didn't store _inventoryOffset -> reset it to
                // a sane default when loading one of those.
                if (serializer.Version < 79 && serializer.IsLoading)
                {
                    _inventoryOffset = 0;
                }
            }
        }
コード例 #30
0
ファイル: Player_AD.cs プロジェクト: scemino/nscumm
        public void SaveOrLoad(Serializer ser)
        {
            lock (_mutex)
            {

//            if (ser.Version < 95) {
//                IMuse *dummyImuse = IMuse::create(_vm._system, null, null);
//                dummyImuse.save_or_load(ser, _vm, false);
//                delete dummyImuse;
//                return;
//            }

                if (ser.Version >= 96)
                {

                    int[] res = null;
                    // The first thing we save is a list of sound resources being played
                    // at the moment.
                    LoadAndSaveEntry.Create(r => res = r.ReadInt32s(4), w => w.WriteInt32s(new int[]{ _soundPlaying, _sfx[0].Resource, _sfx[1].Resource, _sfx[2].Resource }, 4), 96).Execute(ser);

                    // If we are loading start the music again at this point.
                    if (ser.IsLoading)
                    {
                        if (res[0] != -1)
                        {
                            StartSound(res[0]);
                        }
                    }

                    uint musicOffset = _curOffset;

                    var musicData = new []
                    {
                        LoadAndSaveEntry.Create(r => _engineMusicTimer = r.ReadInt32(), w => w.WriteInt32(_engineMusicTimer), 96),
                        LoadAndSaveEntry.Create(r => _musicTimer = r.ReadInt32(), w => w.WriteInt32(_musicTimer), 96),
                        LoadAndSaveEntry.Create(r => _internalMusicTimer = r.ReadUInt32(), w => w.WriteUInt32(_internalMusicTimer), 96),
                        LoadAndSaveEntry.Create(r => _curOffset = r.ReadUInt32(), w => w.WriteUInt32(_curOffset), 96),
                        LoadAndSaveEntry.Create(r => _nextEventTimer = r.ReadUInt32(), w => w.WriteUInt32(_nextEventTimer), 96)
                    };

                    musicData.ForEach(e => e.Execute(ser));

                    // We seek back to the old music position.
                    if (ser.IsLoading)
                    {
                        ScummHelper.Swap(ref musicOffset, ref _curOffset);
                        MusicSeekTo(musicOffset);
                    }

                    // Finally start up the SFX. This makes sure that they are not
                    // accidently stopped while seeking to the old music position.
                    if (ser.IsLoading)
                    {
                        for (int i = 1; i < res.Length; ++i)
                        {
                            if (res[i] != -1)
                            {
                                StartSound(res[i]);
                            }
                        }
                    }
                }
            }
        }