예제 #1
0
        public static PhysicalObject Read(Reader reader, Pointer offset, SuperObject so = null, Radiosity radiosity = null)
        {
            PhysicalObject po = new PhysicalObject(offset, so);

            //MapLoader.Loader.print("PO @ " + offset);
            // Header
            po.off_visualSet            = Pointer.Read(reader);
            po.off_collideSet           = Pointer.Read(reader);
            po.off_visualBoundingVolume = Pointer.Read(reader);
            if (Settings.s.engineVersion > Settings.EngineVersion.TT && Settings.s.game != Settings.Game.LargoWinch)
            {
                if (Settings.s.engineVersion < Settings.EngineVersion.R3)
                {
                    po.off_collideBoundingVolume = po.off_visualBoundingVolume;
                    reader.ReadUInt32();
                }
                else
                {
                    po.off_collideBoundingVolume = Pointer.Read(reader);
                }
            }

            // Parse visual set
            Pointer.DoAt(ref reader, po.off_visualSet, () => {
                ushort numberOfLOD = 1;
                po.visualSetType   = 0;
                if (Settings.s.game == Settings.Game.LargoWinch)
                {
                    po.visualSet                = new VisualSetLOD[1];
                    po.visualSet[0]             = new VisualSetLOD();
                    po.visualSet[0].obj         = null;
                    po.visualSet[0].off_data    = po.off_visualSet;
                    po.visualSet[0].LODdistance = 5f;
                }
                else if (Settings.s.game == Settings.Game.R2Revolution)
                {
                    po.visualSet                = new VisualSetLOD[1];
                    po.visualSet[0]             = new VisualSetLOD();
                    po.visualSet[0].obj         = MapLoader.Loader.meshObjects.FirstOrDefault(p => p.offset == po.off_visualSet);
                    po.visualSet[0].off_data    = po.off_visualSet;
                    po.visualSet[0].LODdistance = 5f;
                }
                else
                {
                    if (Settings.s.platform != Settings.Platform.DC)
                    {
                        reader.ReadUInt32();                         // 0
                        numberOfLOD = reader.ReadUInt16();
                        //if (numberOfLOD > 1) MapLoader.Loader.print("Found a PO with " + numberOfLOD + " levels of detail @ " + offset);
                        po.visualSetType = reader.ReadUInt16();
                        if (numberOfLOD > 0)
                        {
                            Pointer off_LODDistances   = Pointer.Read(reader);
                            Pointer off_LODDataOffsets = Pointer.Read(reader);
                            reader.ReadUInt32();                             // always 0? RLI table offset
                            if (Settings.s.engineVersion > Settings.EngineVersion.Montreal)
                            {
                                reader.ReadUInt32();                                                                                         // always 0? number of RLI
                            }
                            po.visualSet = new VisualSetLOD[numberOfLOD];
                            for (uint i = 0; i < numberOfLOD; i++)
                            {
                                po.visualSet[i] = new VisualSetLOD();
                            }
                            Pointer.DoAt(ref reader, off_LODDistances, () => {
                                for (uint i = 0; i < numberOfLOD; i++)
                                {
                                    // if distance > the float at this offset, game engine uses next LOD if there is one
                                    po.visualSet[i].LODdistance = reader.ReadSingle();
                                }
                            });
                            Pointer.DoAt(ref reader, off_LODDataOffsets, () => {
                                for (uint i = 0; i < numberOfLOD; i++)
                                {
                                    po.visualSet[i].off_data = Pointer.Read(reader);
                                }
                            });
                        }
                    }
                    else
                    {
                        // Platform = Dreamcast
                        Pointer.Read(reader);                        // Material pointer?
                        Pointer off_data = Pointer.Read(reader);
                        reader.ReadUInt32();                         // always 0?
                        reader.ReadUInt32();                         // always 0?
                        po.visualSet                = new VisualSetLOD[1];
                        po.visualSet[0].off_data    = off_data;
                        po.visualSet[0].LODdistance = 5f;
                    }
                }
                int radiosityLODIndex = 0;
                for (uint i = 0; i < numberOfLOD; i++)
                {
                    Pointer.DoAt(ref reader, po.visualSet[i].off_data, () => {
                        switch (po.visualSetType)
                        {
                        case 0:
                            if (po.visualSet[i].obj == null)
                            {
                                po.visualSet[i].obj = GeometricObject.Read(reader, po.visualSet[i].off_data, radiosity: radiosity?.lod?[radiosityLODIndex++]);
                            }
                            break;

                        case 1:
                            if (po.visualSet[i].obj == null)
                            {
                                po.visualSet[i].obj = PatchGeometricObject.Read(reader, po, po.visualSet[i].off_data);
                            }
                            break;

                        default:
                            MapLoader.Loader.print("unknown type " + po.visualSetType + " at offset: " + offset);
                            break;
                        }
                    });
                }
            });

            // Parse collide set
            Pointer.DoAt(ref reader, po.off_collideSet, () => {
                if (Settings.s.game == Settings.Game.R2Revolution)
                {
                    // Read collide mesh object here directly
                    po.collideMesh = GeometricObjectCollide.Read(reader, po.off_collideSet);
                }
                else
                {
                    // Read collide set containing collide mesh
                    uint u1         = reader.ReadUInt32();             // 0, zdm
                    uint u2         = reader.ReadUInt32();             // 0, zdd
                    uint u3         = reader.ReadUInt32();             // 0, zde
                    Pointer off_zdr = Pointer.Read(reader);
                    Pointer.DoAt(ref reader, off_zdr, () => {
                        po.collideMesh = GeometricObjectCollide.Read(reader, off_zdr);
                    });
                }
            });
            MapLoader.Loader.physicalObjects.Add(po);
            return(po);
        }
예제 #2
0
        public static PhysicalObject Read(Reader reader, Pointer offset, SuperObject so = null)
        {
            PhysicalObject po = new PhysicalObject(offset, so);

            //MapLoader.Loader.print("PO @ " + offset);
            // Header
            po.off_visualSet            = Pointer.Read(reader);
            po.off_collideSet           = Pointer.Read(reader);
            po.off_visualBoundingVolume = Pointer.Read(reader);
            if (Settings.s.engineVersion > Settings.EngineVersion.TT && Settings.s.game != Settings.Game.LargoWinch)
            {
                if (Settings.s.engineVersion < Settings.EngineVersion.R3)
                {
                    po.off_collideBoundingVolume = po.off_visualBoundingVolume;
                    reader.ReadUInt32();
                }
                else
                {
                    po.off_collideBoundingVolume = Pointer.Read(reader);
                }
            }

            // Parse visual set
            Pointer.DoAt(ref reader, po.off_visualSet, () => {
                ushort numberOfLOD = 1;
                po.visualSetType   = 0;
                if (Settings.s.game == Settings.Game.LargoWinch)
                {
                    po.visualSet                = new VisualSetLOD[1];
                    po.visualSet[0]             = new VisualSetLOD();
                    po.visualSet[0].obj         = null;
                    po.visualSet[0].off_data    = po.off_visualSet;
                    po.visualSet[0].LODdistance = 5f;
                }
                else if (Settings.s.game == Settings.Game.R2Revolution)
                {
                    po.visualSet                = new VisualSetLOD[1];
                    po.visualSet[0]             = new VisualSetLOD();
                    po.visualSet[0].obj         = MapLoader.Loader.meshObjects.FirstOrDefault(p => p.offset == po.off_visualSet);
                    po.visualSet[0].off_data    = po.off_visualSet;
                    po.visualSet[0].LODdistance = 5f;
                }
                else
                {
                    if (Settings.s.platform != Settings.Platform.DC)
                    {
                        reader.ReadUInt32();                         // 0
                        numberOfLOD = reader.ReadUInt16();
                        //if (numberOfLOD > 1) MapLoader.Loader.print("Found a PO with " + numberOfLOD + " levels of detail @ " + offset);
                        po.visualSetType = reader.ReadUInt16();
                        if (numberOfLOD > 0)
                        {
                            Pointer off_LODDistances   = Pointer.Read(reader);
                            Pointer off_LODDataOffsets = Pointer.Read(reader);
                            reader.ReadUInt32();                             // always 0? RLI table offset
                            if (Settings.s.engineVersion > Settings.EngineVersion.Montreal)
                            {
                                reader.ReadUInt32();                                                                                         // always 0? number of RLI
                            }
                            po.visualSet = new VisualSetLOD[numberOfLOD];
                            for (uint i = 0; i < numberOfLOD; i++)
                            {
                                po.visualSet[i] = new VisualSetLOD();
                            }
                            Pointer.DoAt(ref reader, off_LODDistances, () => {
                                for (uint i = 0; i < numberOfLOD; i++)
                                {
                                    // if distance > the float at this offset, game engine uses next LOD if there is one
                                    po.visualSet[i].LODdistance = reader.ReadSingle();
                                }
                            });
                            Pointer.DoAt(ref reader, off_LODDataOffsets, () => {
                                for (uint i = 0; i < numberOfLOD; i++)
                                {
                                    po.visualSet[i].off_data = Pointer.Read(reader);
                                }
                            });
                        }
                    }
                    else
                    {
                        // Platform = Dreamcast
                        Pointer.Read(reader);                        // Material pointer?
                        Pointer off_data = Pointer.Read(reader);
                        reader.ReadUInt32();                         // always 0?
                        reader.ReadUInt32();                         // always 0?
                        po.visualSet                = new VisualSetLOD[1];
                        po.visualSet[0].off_data    = off_data;
                        po.visualSet[0].LODdistance = 5f;
                    }
                }
                for (uint i = 0; i < numberOfLOD; i++)
                {
                    Pointer.DoAt(ref reader, po.visualSet[i].off_data, () => {
                        switch (po.visualSetType)
                        {
                        case 0:
                            if (po.visualSet[i].obj == null)
                            {
                                po.visualSet[i].obj = GeometricObject.Read(reader, po.visualSet[i].off_data);
                            }
                            GeometricObject m = ((GeometricObject)po.visualSet[i].obj);
                            if (m.name != "Mesh")
                            {
                                po.Gao.name = "[PO] " + m.name;
                            }
                            break;

                        case 1:
                            if (po.visualSet[i].obj == null)
                            {
                                po.visualSet[i].obj = MeshModificationObject.Read(reader, po, po.visualSet[i].off_data);
                            }
                            MeshModificationObject mod = po.visualSet[i].obj as MeshModificationObject;
                            if (mod != null && mod.mesh != null && mod.mesh.name != "Mesh")
                            {
                                po.Gao.name = "[PO] " + mod.mesh.name;
                            }
                            break;

                        default:
                            MapLoader.Loader.print("unknown type " + po.visualSetType + " at offset: " + offset);
                            break;
                        }
                        if (po.visualSet[i].obj.Gao != null)
                        {
                            po.visualSet[i].obj.Gao.transform.parent = po.Gao.transform;
                        }
                    });
                }
                if (numberOfLOD > 1)
                {
                    float bestLOD = po.visualSet.Min(v => v.LODdistance);
                    foreach (VisualSetLOD lod in po.visualSet)
                    {
                        if (lod.obj.Gao != null && lod.LODdistance != bestLOD)
                        {
                            lod.obj.Gao.SetActive(false);
                        }
                    }
                }
            });

            // Parse collide set
            Pointer.DoAt(ref reader, po.off_collideSet, () => {
                if (Settings.s.game == Settings.Game.R2Revolution)
                {
                    // Read collide mesh object here directly
                    po.collideMesh = GeometricObjectCollide.Read(reader, po.off_collideSet);
                    po.collideMesh.gao.transform.parent = po.Gao.transform;
                }
                else
                {
                    // Read collide set containing collide mesh
                    uint u1         = reader.ReadUInt32();             // 0, zdm
                    uint u2         = reader.ReadUInt32();             // 0, zdd
                    uint u3         = reader.ReadUInt32();             // 0, zde
                    Pointer off_zdr = Pointer.Read(reader);
                    Pointer.DoAt(ref reader, off_zdr, () => {
                        po.collideMesh = GeometricObjectCollide.Read(reader, off_zdr);
                        po.collideMesh.gao.transform.parent = po.Gao.transform;
                    });
                }
            });
            MapLoader.Loader.physicalObjects.Add(po);
            return(po);
        }
예제 #3
0
        async Task LoadPS2()
        {
            await WaitIfNecessary();

            textures = new TextureInfo[0];

            loadingState = "Loading fixed memory";
            await WaitIfNecessary();

            files_array[Mem.Fix].GotoHeader();
            Reader  reader       = files_array[Mem.Fix].reader;
            Pointer off_base_fix = Pointer.Current(reader);

            loadingState = "Loading input struct";
            await WaitIfNecessary();

            for (int i = 0; i < Settings.s.numEntryActions; i++)
            {
                Pointer.Read(reader);                 // 3DOS_EntryActions
            }

            inputStruct = InputStructure.Read(reader, Pointer.Current(reader));
            foreach (EntryAction ea in inputStruct.entryActions)
            {
                print(ea.ToString());
            }
            localization = FromOffsetOrRead <LocalizationStructure>(reader, Pointer.Current(reader), inline: true);

            /*
             * Pointer off_inputStructure = Pointer.Read(reader);
             * Pointer.DoAt(ref reader, off_inputStructure, () => {
             * inputStruct = InputStructure.Read(reader, off_inputStructure);
             *      foreach (EntryAction ea in inputStruct.entryActions) {
             *              print(ea.ToString());
             *      }
             * });*/


            /*uint base_language = reader.ReadUInt32(); //Pointer off_language = Pointer.Read(reader);
             * reader.ReadUInt32();
             * uint num_text_language = reader.ReadUInt32();
             * reader.ReadUInt16();
             * reader.ReadUInt16();
             * reader.ReadUInt32(); // base
             * Pointer off_text_general = Pointer.Read(reader);
             * Pointer.DoAt(ref reader, off_text_general, () => {
             * fontStruct = FontStructure.Read(reader, off_text_general);
             * });
             * Pointer off_inputStructure = Pointer.Read(reader);
             * Pointer.DoAt(ref reader, off_inputStructure, () => {
             * inputStruct = InputStructure.Read(reader, off_inputStructure);
             *      foreach (EntryAction ea in inputStruct.entryActions) {
             *              print(ea.ToString());
             *      }
             * });
             *
             * await WaitIfNecessary();
             * Pointer.Read(reader);
             * Pointer.Read(reader);
             * Pointer.Read(reader);
             * Pointer.Read(reader);
             * Pointer.Read(reader);
             * Pointer.Read(reader);
             * Pointer.Read(reader);
             * Pointer.Read(reader);
             * Pointer.Read(reader);
             * Pointer.Read(reader);
             * Pointer.Read(reader);
             * Pointer.Read(reader);
             * reader.ReadUInt32();
             * reader.ReadUInt32();
             * reader.ReadUInt32();
             * reader.ReadUInt32();
             * reader.ReadUInt32();
             * reader.ReadUInt32();
             * reader.ReadUInt32();
             * reader.ReadUInt32();
             * reader.ReadUInt32();
             * reader.ReadUInt32();
             * Pointer.Read(reader);
             * Pointer off_levelNames = Pointer.Read(reader);
             * Pointer off_languages = Pointer.Read(reader);
             * uint num_levelNames = reader.ReadUInt32();
             * uint num_languages = reader.ReadUInt32();
             * reader.ReadUInt32(); // same as num_levelNames
             * Pointer.DoAt(ref reader, off_levelNames, () => {
             * lvlNames = new string[num_levelNames];
             * for (uint i = 0; i < num_levelNames; i++) {
             * lvlNames[i] = reader.ReadString(0x1E);
             * }
             * });
             * Pointer.DoAt(ref reader, off_languages, () => {
             * ReadLanguages(reader, off_languages, num_languages);
             * });
             * if (languages != null && fontStruct != null) {
             * for (int i = 0; i < num_languages; i++) {
             * loadingState = "Loading text files: " + (i+1) + "/" + num_languages;
             * string langFilePath = gameDataBinFolder + "TEXTS/" + languages[i].ToUpper() + ".LNG";
             * await PrepareFile(langFilePath));
             * files_array[2] = new DCDAT(languages[i], langFilePath, 2);
             * ((DCDAT)files_array[2]).SetHeaderOffset(base_language);
             * files_array[2].GotoHeader();
             * fontStruct.ReadLanguageTableDreamcast(files_array[2].reader, i, (ushort)num_text_language);
             * files_array[2].Dispose();
             * }
             * }
             *
             * loadingState = "Loading fixed textures";
             * await WaitIfNecessary();
             * Pointer off_events_fix = Pointer.Read(reader);
             * uint num_events_fix = reader.ReadUInt32();
             * uint num_textures_fix = reader.ReadUInt32();
             * Pointer off_textures_fix = Pointer.Read(reader);
             * Pointer.DoAt(ref reader, off_textures_fix, () => {
             * Array.Resize(ref textures, (int)num_textures_fix);
             * for (uint i = 0; i < num_textures_fix; i++) {
             * Pointer off_texture = Pointer.Read(reader);
             * textures[i] = null;
             * Pointer.DoAt(ref reader, off_texture, () => {
             * textures[i] = TextureInfo.Read(reader, off_texture);
             * });
             * }
             * TEX tex = new TEX(tplPaths[0]);
             * for (uint i = 0; i < num_textures_fix; i++) {
             * if (textures[i] != null && tex.Count > i) {
             * textures[i].Texture = tex.textures[i];
             * }
             * }
             * });*/
            loadingState = "Loading level memory";
            await WaitIfNecessary();

            files_array[Mem.Lvl].GotoHeader();
            reader = files_array[Mem.Lvl].reader;
            string build = reader.ReadString(0x20);

            reader.ReadUInt32();
            reader.ReadUInt32();             // 0xc
            reader.ReadUInt32();             // 0
            Pointer.Read(reader);
            Pointer.Read(reader);

            // Globals
            globals.off_actualWorld  = Pointer.Read(reader);
            globals.off_dynamicWorld = Pointer.Read(reader);
            globals.off_fatherSector = Pointer.Read(reader);
            globals.num_always       = reader.ReadUInt32();
            globals.spawnablePersos  = LinkedList <Perso> .ReadHeader(reader, Pointer.Current(reader), LinkedList.Type.Double);

            //globals.spawnablePersos.FillPointers(reader, globals.spawnablePersos.off_tail, globals.spawnablePersos.offset);
            Pointer.Read(reader);                                 // format: (0x4 number, number * 0x4: null)
            globals.off_always_reusableSO = Pointer.Read(reader); // There are (num_always) empty SuperObjects starting with this one.
            Pointer.Read(reader);
            Pointer.Read(reader);
            Pointer.Read(reader);
            Pointer.Read(reader);
            Pointer.Read(reader);

            LinkedList <Perso> cameras = LinkedList <Perso> .ReadHeader(reader, Pointer.Current(reader), LinkedList.Type.Double);

            families = LinkedList <Family> .ReadHeader(reader, Pointer.Current(reader), type : LinkedList.Type.Double);

            LinkedList <Perso> mainChars = LinkedList <Perso> .ReadHeader(reader, Pointer.Current(reader), LinkedList.Type.Double);

            Pointer.Read(reader);                      // Rayman
            reader.ReadUInt32();
            globals.off_camera = Pointer.Read(reader); // Camera
            Pointer.Read(reader);
            Pointer.Read(reader);
            Pointer.Read(reader);

            uint numMeshes             = (uint)files_array[Mem.Lvl].extraData["numMeshes"];
            uint numMaterials          = (uint)files_array[Mem.Lvl].extraData["numMaterials"];
            uint numTextures           = (uint)files_array[Mem.Lvl].extraData["numTextures"];
            uint numLightmappedObjects = (uint)files_array[Mem.Lvl].extraData["numLightmappedObjects"];

            //print("numTextures " + numTextures + " - " + txds[0].Count + " - " + numMeshes + " - " + ato.numAtomics + " - " + numLightmappedObjects);


            textures = new TextureInfo[numTextures];
            Pointer[] off_meshes = new Pointer[numMeshes];
            off_materials = new Pointer[numMaterials];
            for (int i = 0; i < numMeshes; i++)
            {
                off_meshes[i] = Pointer.Read(reader);
            }
            for (int i = 0; i < numMaterials; i++)
            {
                off_materials[i] = Pointer.Read(reader);
            }
            for (int i = 0; i < numTextures; i++)
            {
                Pointer off_textureInfo = Pointer.Read(reader);
                int     texture_index   = reader.ReadInt32();
                Pointer.DoAt(ref reader, off_textureInfo, () => {
                    textures[i]         = TextureInfo.Read(reader, off_textureInfo);
                    textures[i].Texture = txds[0].Lookup(texture_index.ToString("D3"));
                    //textures[i].Texture = txds[0].textures[txds[0].Count - 1 - texture_index];
                });
            }
            Pointer.Read(reader);
            reader.ReadUInt32();
            reader.ReadUInt32();
            Pointer.Read(reader);
            uint num_unk = reader.ReadUInt32();

            for (int i = 0; i < num_unk; i++)
            {
                Pointer.Read(reader);
            }
            uint num_unk2 = reader.ReadUInt32();

            for (int i = 0; i < num_unk2; i++)
            {
                Pointer.Read(reader);
            }
            Pointer.Read(reader);
            reader.ReadSingle();             // a bounding volume most likely
            reader.ReadSingle();
            reader.ReadSingle();
            reader.ReadSingle();
            reader.ReadSingle();
            reader.ReadSingle();
            Pointer.Read(reader);
            reader.ReadUInt32();             // 2?
            uint    num_poTable = reader.ReadUInt32();
            Pointer off_poTable = Pointer.Read(reader);

            reader.ReadUInt32();             // 1. 10x 0
            reader.ReadUInt32();             // 2
            reader.ReadUInt32();             // 3
            reader.ReadUInt32();             // 4
            reader.ReadUInt32();             // 5
            reader.ReadUInt32();             // 6
            reader.ReadUInt32();             // 7
            reader.ReadUInt32();             // 8
            reader.ReadUInt32();             // 9
            reader.ReadUInt32();             // 10
            uint num_lightCookies = reader.ReadUInt32();

            lightCookieColors = new Color[num_lightCookies];
            for (int i = 0; i < num_lightCookies; i++)
            {
                reader.ReadUInt32();
                reader.ReadUInt32();
                reader.ReadUInt32();
                reader.ReadUInt32();
                byte b = reader.ReadByte();
                byte g = reader.ReadByte();
                byte r = reader.ReadByte();
                reader.ReadByte();
                lightCookieColors[i] = new Color(r / 255f, g / 255f, b / 255f, 1f);
                reader.ReadUInt32();
                reader.ReadInt32();
                reader.ReadUInt32();
            }
            for (int i = 0; i < num_lightCookies; i++)
            {
                reader.ReadByte();
            }
            reader.Align(0x4);
            Pointer off_lightCookieMaterial = Pointer.Read(reader);

            lightCookieMaterial = VisualMaterial.FromOffsetOrRead(off_lightCookieMaterial, reader);
            off_lightmapUV      = new Pointer[numLightmappedObjects];
            for (int i = 0; i < numLightmappedObjects; i++)
            {
                reader.ReadUInt32();
                reader.ReadUInt32();
                reader.ReadUInt32();
                off_lightmapUV[i] = Pointer.Read(reader);
            }



            for (int i = 0; i < numMaterials; i++)
            {
                VisualMaterial.FromOffsetOrRead(off_materials[i], reader);
            }
            for (int i = 0; i < numMeshes; i++)
            {
                Pointer.DoAt(ref reader, off_meshes[i], () => {
                    GeometricObject mesh = GeometricObject.Read(reader, off_meshes[i]);
                    meshObjects.Add(mesh);
                    //print("Mesh " + i + ": " + mesh.num_vertices + " - " + mesh.subblock_types[0] + " - " + mesh.num_subblocks);
                });
            }

            loadingState = "Loading families";
            await WaitIfNecessary();

            ReadFamilies(reader);
            //print("Families: " + families.Count);
            loadingState = "Loading superobject hierarchy";
            await WaitIfNecessary();

            ReadSuperObjects(reader);
            loadingState = "Loading always structure";
            await WaitIfNecessary();

            ReadAlways(reader);
            loadingState = "Filling in cross-references";
            await WaitIfNecessary();

            ReadCrossReferences(reader);
            await WaitIfNecessary();
        }