Exemple #1
0
 void ResetRoomObjects()
 {
     int j = 1;
     for (int i = 0; i < roomData.Objects.Count; i++)
     {
         for (; j < _objs.Length; j++)
         {
             if (_objs[j].FloatingObjectIndex == 0)
                 break;
         }
         _objs[j] = roomData.Objects[i];
         // HACK: This is done since an angle doesn't fit into a byte (360 > 256)
         _objs[j].ActorDir = Game.Version == 8 ? (byte)ScummMath.ToSimpleDir(true, roomData.Objects[i].ActorDir) : roomData.Objects[i].ActorDir;
         j++;
     }
     for (int i = j; i < _objs.Length; i++)
     {
         if (_objs[i].FloatingObjectIndex == 0)
         {
             _objs[i] = new ObjectData();
         }
     }
 }
Exemple #2
0
        void ClearOwnerOf(int obj)
        {
            // Stop the associated object script code (else crashes might occurs)
            StopObjectScriptCore((ushort)obj);

            if (GetOwnerCore(obj) == OwnerRoom)
            {
                for (var i = 0; i < _objs.Length; i++)
                {
                    if (_objs[i].Number == obj && (_objs[i].FloatingObjectIndex != 0))
                    {
                        // Removing an flObject from a room means we can nuke it
//                        _res->nukeResource(rtFlObject, _objs[i].fl_object_index);
                        _objs[i] = new ObjectData();
                    }
                }
            }
            else
            {
                // Alternatively, scan the inventory to see if the object is in there...
                for (int i = 0; i < _resManager.NumInventory; i++)
                {
                    if (_inventory[i] == obj)
                    {
                        // Found the object! Nuke it from the inventory.
                        _inventory[i] = 0;

                        // Now fill up the gap removing the object from the inventory created.
                        for (i = 0; i < _resManager.NumInventory - 1; i++)
                        {
                            if (_inventory[i] == 0 && _inventory[i + 1] != 0)
                            {
                                _inventory[i] = _inventory[i + 1];
                                _invData[i] = _invData[i + 1];
                                _inventory[i + 1] = 0;
                                // FIXME FIXME FIXME: This is incomplete, as we do not touch flags, status... BUG
                                // TODO:
                                //_res->_types[rtInventory][i]._address = _res->_types[rtInventory][i + 1]._address;
                                //_res->_types[rtInventory][i]._size = _res->_types[rtInventory][i + 1]._size;
                                //_res->_types[rtInventory][i + 1]._address = NULL;
                                //_res->_types[rtInventory][i + 1]._size = 0;
                            }
                        }
                        break;
                    }
                }
            }
        }
        protected bool LoadState(string path)
        {
            using (var file = ServiceLocator.FileStorage.OpenFileRead(path))
            {
                var br = new BinaryReader(file);
                var hdr = LoadSaveGameHeader(br);
                var serializer = Serializer.CreateReader(br, hdr.Version);

                // Since version 56 we save additional information about the creation of
                // the save game and the save time.
                if (hdr.Version >= 56)
                {
                    var infos = LoadInfos(br);
                    if (infos == null)
                    {
                        //warning("Info section could not be found");
                        //delete in;
                        return false;
                    }

                    //SetTotalPlayTime(infos.playtime * 1000);
                }
                //else
                //{
                // start time counting
                //setTotalPlayTime();
                //}

                // Due to a bug in scummvm up to and including 0.3.0, save games could be saved
                // in the V8/V9 format but were tagged with a V7 mark. Ouch. So we just pretend V7 == V8 here
                if (hdr.Version == 7)
                    hdr.Version = 8;

                //_saveLoadDescription = hdr.name;

                // Unless specifically requested with _saveSound, we do not save the iMUSE
                // state for temporary state saves - such as certain cutscenes in DOTT,
                // FOA, Sam and Max, etc.
                //
                // Thus, we should probably not stop music when restoring from one of
                // these saves. This change stops the Mole Man theme from going quiet in
                // Sam & Max when Doug tells you about the Ball of Twine, as mentioned in
                // patch #886058.
                //
                // If we don't have iMUSE at all we may as well stop the sounds. The previous
                // default behavior here was to stopAllSounds on all state restores.

                if (IMuse == null || _saveSound || !_saveTemporaryState)
                    Sound.StopAllSounds();

                //            Sound->stopCD();

                Sound.PauseSounds(true);

                //closeRoom();

                _inventory = new ushort[_inventory.Length];
                _invData = new ObjectData[_invData.Length];
                _newNames.Clear();

                // Because old savegames won't fill the entire gfxUsageBits[] array,
                // clear it here just to be sure it won't hold any unforseen garbage.
                Gdi.ClearGfxUsageBits();

                // Nuke all resources
                //for (ResType type = rtFirst; type <= rtLast; type = ResType(type + 1))
                //    if (type != rtTemp && type != rtBuffer && (type != rtSound || _saveSound || !compat))
                //        for (ResId idx = 0; idx < _res->_types[type].size(); idx++)
                //        {
                //            _res->nukeResource(type, idx);
                //        }
                Array.Clear(_strings, 0, _strings.Length);

                ResetScummVars();

                //if (_game.features & GF_OLD_BUNDLE)
                //    loadCharset(0); // FIXME - HACK ?

                //
                // Now do the actual loading
                //
                SaveOrLoad(serializer);

                // Update volume settings
//                SyncSoundSettings();

                if (Game.Version < 7)
                {
                    Camera.LastPosition.X = Camera.CurrentPosition.X;
                }

                var sb = _screenB;
                var sh = _screenH;

                // Restore the virtual screens and force a fade to black.
                InitScreens(0, ScreenHeight);

                Gdi.Fill(MainVirtScreen.Surfaces[0].Pixels, MainVirtScreen.Pitch, 0, MainVirtScreen.Width, MainVirtScreen.Height);
                MainVirtScreen.SetDirtyRange(0, MainVirtScreen.Height);
                UpdateDirtyScreen(MainVirtScreen);
                //UpdatePalette();
                _gfxManager.SetPalette(_currentPalette.Colors);
                InitScreens(sb, sh);

                _completeScreenRedraw = true;

                // Reset charset mask
                _charset.HasMask = false;
                ClearTextSurface();
                ClearDrawObjectQueue();
                _verbMouseOver = 0;

                CameraMoved();

                Gdi.NumZBuffer = GetNumZBuffers();
                Gdi.SetMaskHeight(roomData.Header.Height);

                if (VariableRoomFlag.HasValue)
                {
                    Variables[VariableRoomFlag.Value] = 1;
                }

                // Sync with current config setting
                if (VariableVoiceMode.HasValue)
                {
                    Variables[VariableVoiceMode.Value] = (int)VoiceMode.VoiceAndText;
                }

                Sound.PauseSounds(false);
            }

            return true;
        }
        void LoadResource(BinaryReader reader, ResType type, ushort idx)
        {
            bool dynamic = false;
            switch (type)
            {
                case ResType.Inventory:
                case ResType.String:
                case ResType.Verb:
                case ResType.VerbImage:
                case ResType.ActorName:
                case ResType.ScaleTable:
                case ResType.Temp:
                case ResType.FlObject:
                case ResType.Matrix:
                case ResType.ObjectName:
                    dynamic = true;
                    break;
            }

            if (dynamic)
            {
                int size = reader.ReadInt32();
                var ptr = reader.ReadBytes(size);

                //Console.WriteLine("Type: {0}, Index: {1}, Data: {2}", type, idx, size);

                switch (type)
                {
                    case ResType.Inventory:
                        {
                            var index = reader.ReadUInt16();
                            _inventory[idx] = index;
                            _invData[idx] = new ObjectData(index);
                            var br = new BinaryReader(new MemoryStream(ptr));
                            br.BaseStream.Seek(18, SeekOrigin.Begin);
                            var offset = br.ReadByte();
                            br.BaseStream.Seek(offset, SeekOrigin.Begin);
                            // read name
                            var name = new List<byte>();
                            var c = br.ReadByte();
                            while (c != 0)
                            {
                                name.Add(c);
                                c = br.ReadByte();
                            }
                            _invData[idx].Name = name.ToArray();
                            // read script
                            _invData[idx].Script.Data = br.ReadBytes((int)(br.BaseStream.Length - br.BaseStream.Position));
                            // read verb table
                            br.BaseStream.Seek(19, SeekOrigin.Begin);
                            if (Game.Version == 8)
                            {
                                while (true)
                                {
                                    var id = br.ReadInt32();
                                    var off = br.ReadInt32();
                                    if (id == 0)
                                        break;
                                    _invData[idx].ScriptOffsets.Add(id, off);
                                }
                                _invData[idx].Script.Offset = _invData[idx].ScriptOffsets.Count * 8 + 4;
                            }
                            else
                            {
                                while (true)
                                {
                                    var id = br.ReadByte();
                                    var off = br.ReadUInt16();
                                    if (id == 0)
                                        break;
                                    _invData[idx].ScriptOffsets.Add(id, off);
                                }
                                _invData[idx].Script.Offset = _invData[idx].ScriptOffsets.Count * 3 + 1 + 8;
                            }
                        }
                        break;

                    case ResType.ActorName:
                        {
                            Actors[idx].Name = ptr;
                        }
                        break;

                    case ResType.ObjectName:
                        {
                            var index = reader.ReadUInt16();
                            _newNames[index] = ptr;
                        }
                        break;

                    case ResType.Matrix:
                        {
                            if (idx == 1)
                            {
                                // BOXM
                                _boxMatrix.Clear();
                                _boxMatrix.AddRange(ptr);
                            }
                            else if (idx == 2)
                            {
                                // BOXD
                                var br = new BinaryReader(new MemoryStream(ptr));

                                var numBoxes = br.ReadByte();
                                _boxes = new Box[numBoxes];
                                for (int i = 0; i < numBoxes; i++)
                                {
                                    var box = new Box();
                                    box.Ulx = br.ReadInt16();
                                    box.Uly = br.ReadInt16();
                                    box.Urx = br.ReadInt16();
                                    box.Ury = br.ReadInt16();
                                    box.Lrx = br.ReadInt16();
                                    box.Lry = br.ReadInt16();
                                    box.Llx = br.ReadInt16();
                                    box.Lly = br.ReadInt16();
                                    box.Mask = br.ReadByte();
                                    box.Flags = (BoxFlags)br.ReadByte();
                                    box.Scale = br.ReadUInt16();
                                    if (Game.Version == 8)
                                    {
                                        box.ScaleSlot = br.ReadByte();
                                    }
                                    _boxes[i] = box;
                                }
                            }
                        }
                        break;

                    case ResType.Verb:
                        {
                            Verbs[idx].Text = ptr;
                        }
                        break;

                    case ResType.VerbImage:
                        {
                            var br = new BinaryReader(new MemoryStream(ptr));
                            Verbs[idx].ImageWidth = br.ReadUInt16();
                            Verbs[idx].ImageHeight = br.ReadUInt16();
                            var imgSize = (int)(br.BaseStream.Length - 4);
                            Verbs[idx].ImageData = new ImageData{ Data = br.ReadBytes(imgSize) };
                        }
                        break;

                    case ResType.String:
                        {
                            _strings[idx] = ptr;
                        }
                        break;
                }
            }
//            else
//            {
//                Console.WriteLine("Type: {0}", type);
//            }
        }
Exemple #5
0
        void DumpRoomObjectImages(Room room, ObjectData obj, Gdi gdi)
        {
            var text = new ScummText(obj.Name);
            var sb = new StringBuilder();
            sb.Append("Object #" + obj.Number).Append(" ");

            var decoder = new TextDecoder(sb);
            text.Decode(decoder);

            sb.AppendFormat(" size: {0}x{1}", obj.Width, obj.Height);
            Console.WriteLine(sb);

            var j = 0;
            foreach (var img in obj.Images)
            {
//                try
//                {
                var screen = new VirtScreen(0, obj.Width, obj.Height, PixelFormat.Indexed8, 2);
                if (img.IsBomp)
                {
                    var bdd = new BompDrawData();
                    bdd.Src = img.Data;
                    bdd.Dst = new PixelNavigator(screen.Surfaces[0]);
                    bdd.X = 0;
                    bdd.Y = 0;

                    bdd.Width = obj.Width;
                    bdd.Height = obj.Height;

                    bdd.ScaleX = 255;
                    bdd.ScaleY = 255;
                    bdd.DrawBomp();
                }
                else
                {
                    gdi.DrawBitmap(img, screen, new Point(0, 0), obj.Width, obj.Height & 0xFFF8, 0, obj.Width / 8, room.Header.Width, DrawBitmaps.None, true);
                }

                using (var bmp = ToBitmap(room, screen))
                {
                    bmp.Save("obj_" + obj.Number + "_" + (++j) + ".png");
                }
//                }
//                catch (Exception e)
//                {
//                    Console.ForegroundColor = ConsoleColor.Red;
//                    Console.WriteLine(e);
//                    Console.ResetColor();
//                    Console.ReadLine();
//                }
            }
        }
Exemple #6
0
        protected ScummEngine(GameSettings settings, IGraphicsManager gfxManager, IInputManager inputManager, IMixer mixer)
        {
            Settings = settings;
            var game = (GameInfo)settings.Game;
            _resManager = ResourceManager.Load(game);

            _game = game;
            InvalidBox = _game.Version < 5 ? (byte)255 : (byte)0;
            _gameMD5 = ToMd5Bytes(game.MD5);
            _gfxManager = gfxManager;
            _inputManager = inputManager;
            _inputState = inputManager.GetState();
            _strings = new byte[_resManager.NumArray][];
            _inventory = new ushort[_resManager.NumInventory];
            _invData = new ObjectData[_resManager.NumInventory];
            CurrentScript = 0xFF;
            Mixer = mixer;
            ScreenWidth = Game.Width;
            ScreenHeight = Game.Height;

            AudioCDManager = new DefaultAudioCDManager(this, mixer);
            Sound = new Sound(this, mixer);

            SetupMusic();

            _variables = new int[_resManager.NumVariables];
            _bitVars = new BitArray(_resManager.NumBitVariables);
            _slots = new ScriptSlot[NumScriptSlot];
            for (int i = 0; i < NumScriptSlot; i++)
            {
                _slots[i] = new ScriptSlot();
            }
            for (int i = 0; i < 200; i++)
            {
                _objs[i] = new ObjectData();
            }
            for (int i = 0; i < 6; i++)
            {
                _string[i] = new TextSlot();
                if (game.Version != 3)
                {
                    _string[i].Default.Position = new Point(2, 5);
                }
            }
            _colorCycle = new ColorCycle[16];
            for (int i = 0; i < _colorCycle.Length; i++)
            {
                _colorCycle[i] = new ColorCycle();
            }
            _nest = new NestedScript[MaxScriptNesting + 1];
            for (int i = 0; i < _nest.Length; i++)
            {
                _nest[i] = new NestedScript();
            }
            _scaleSlots = new ScaleSlot[20];
            for (int i = 0; i < _scaleSlots.Length; i++)
            {
                _scaleSlots[i] = new ScaleSlot();
            }

            Gdi = Gdi.Create(this, game);
            switch (game.Version)
            {
                case 0:
                    _costumeLoader = new CostumeLoader0(this);
                    _costumeRenderer = new CostumeRenderer0(this);
                    break;
                case 7:
                case 8:
                    _costumeLoader = new AkosCostumeLoader(this);
                    _costumeRenderer = new AkosRenderer(this);
                    break;
                default:
                    _costumeLoader = new ClassicCostumeLoader(this);
                    _costumeRenderer = new ClassicCostumeRenderer(this);
                    break;
            }

            CreateCharset();
            ResetCursors();

            // Create the text surface
            var pixelFormat = _game.Features.HasFlag(GameFeatures.Is16BitColor) ? PixelFormat.Rgb16 : PixelFormat.Indexed8;
            _textSurface = new Surface(ScreenWidth * _textSurfaceMultiplier, ScreenHeight * _textSurfaceMultiplier, PixelFormat.Indexed8, false);
            ClearTextSurface();

            if (Game.Platform == Platform.FMTowns)
            {
                _townsScreen = new TownsScreen(_gfxManager, ScreenWidth * _textSurfaceMultiplier, ScreenHeight * _textSurfaceMultiplier, PixelFormat.Rgb16);
                _townsScreen.SetupLayer(0, ScreenWidth, ScreenHeight, 32767);
                _townsScreen.SetupLayer(1, ScreenWidth * _textSurfaceMultiplier, ScreenHeight * _textSurfaceMultiplier, 16, _textPalette);
            }

            if (Game.Version == 0)
            {
                InitScreens(8, 144);
            }
            else if ((Game.GameId == GameId.Maniac) && (_game.Version <= 1) && _game.Platform != Platform.NES)
            {
                InitScreens(16, 152);
            }
            else if (Game.Version >= 7)
            {
                InitScreens(0, ScreenHeight);
            }
            else
            {
                InitScreens(16, 144);
            }
            // Allocate gfx compositing buffer (not needed for V7/V8 games).
            if (Game.Version < 7)
            {
                _composite = new Surface(ScreenWidth, ScreenHeight, pixelFormat, false);
            }
            InitActors();
            OwnerRoom = Game.Version >= 7 ? 0x0FF : 0x0F;

            if (Game.Version < 7)
            {
                Camera.LeftTrigger = 10;
                Camera.RightTrigger = 30;
            }

            InitPalettes();
            InitializeVerbs();

            // WORKAROUND for bug in boot script of Loom (CD)
            // The boot script sets the characters of string 21,
            // before creating the string.resource.
            if (_game.GameId == GameId.Loom)
            {
                _strings[21] = new byte[13];
            }
        }
Exemple #7
0
        void ClearRoomObjects()
        {
            if (Game.Version < 5)
            {
                for (var i = 0; i < _objs.Length; i++)
                {
                    _objs[i] = new ObjectData();
                }
            }
            else
            {
                for (var i = 0; i < _objs.Length; i++)
                {
                    if (_objs[i].Number < 1)    // Optimise codepath
                                continue;

                    // Nuke all non-flObjects (flObjects are nuked in script.cpp)
                    if (_objs[i].FloatingObjectIndex == 0)
                    {
                        _objs[i] = new ObjectData();
                    }
                    else
                    {
                        // Nuke all unlocked flObjects
                        if (!_objs[i].IsLocked)
                        {
//                            _res->nukeResource(rtFlObject, _objs[i].fl_object_index);
                            _objs[i] = new ObjectData();
                        }
                    }
                }
            }
        }