Esempio n. 1
0
    public static Bitmap getTextureImage(int textureId)
    {
        RatchetTexture_General tex = DataStore.textures.Find(x => x.ID == textureId);
        int textureIndex           = DataStore.textures.IndexOf(tex);

        if (tex.renderedImage == null)
        {
            Bitmap texImageBMap;
            byte[] imgRaw;
            byte[] newbytes;
            int    width  = tex.width;
            int    height = tex.height;
            imgRaw = DecompressDxt5(tex.texData, width, height);
            if (imgRaw != null)
            {
                texImageBMap      = new Bitmap(width, height, 4 * width, PixelFormat.Format32bppArgb, Marshal.UnsafeAddrOfPinnedArrayElement(imgRaw, 0));
                tex.renderedImage = texImageBMap;
            }

            //Update our data store with the updated texture
            //DataStore.textures[textureIndex] = tex;
            //return tex.renderedImage;// !tex.reverseRGB ? imgReverseRGB(texImageBMap) : texImageBMap;
        }

        return(tex.renderedImage);
    }
        public void addNewTexture(byte[] image, int width, int height)
        {
            // MessageBox.Show("Broken for now");
            byte[] zeros  = new byte[0x10];
            byte[] texDef = Constants.textureTemplate;

            //Writes our image size
            writeBytes(texDef, 0x18, (uint)width << 16, 2);
            writeBytes(texDef, 0x1A, (uint)height << 16, 2);

            RatchetTexture_General newTex = new RatchetTexture_General()
            {
                ID         = DataStore.textures.Count,
                height     = height,
                width      = width,
                texHeader  = texDef,
                texData    = image,
                reverseRGB = false
            };

            DataStore.textures.Add(newTex);
            updateTextureList();
            //Inserts 4 lines of 0s which indicates start of new texture
            // Form1.vramData = insertNew(Form1.vramData, zeros, Form1.vramData.Length);

            //Writes our new pointer for texture data
            //writeBytes(texDef, 0x00, (uint)Form1.vramData.Length, 4);

            //Writes our image size
            //writeBytes(texDef, 0x18, (uint)width << 16, 2);
            //writeBytes(texDef, 0x1A, (uint)height << 16, 2);

            //Inserts our newest texture def into engine file byte array
            //Form1.engineConfig = insertNew(Form1.engineConfig, texDef, (textureStart + (0x24 * (textureAmount))));

            //Inserts our new texture data into vram file byte array
            //Form1.vramData = insertNew(Form1.vramData, image, Form1.vramData.Length);

            //Increase any pointers that might have had data moved by the data insertion
            //updatePointers(Form1.engineConfig, 0x60, 0x20, 0x88);

            //Increase texture amount + 1
            //writeBytes(Form1.engineConfig, 0x64, (uint)textureAmount + 1, 4);

            //Refresh to show newest texture
            //updateTextureList(texFile);
        }
        public void updateTextureImage(RatchetTexture_General tex)
        {
            textureImage.Image = getTextureImage(tex.ID);

            if (tex.height > textureImage.Height)
            {
                textureImage.SizeMode = PictureBoxSizeMode.StretchImage;
            }
            if (tex.width > textureImage.Width)
            {
                textureImage.SizeMode = PictureBoxSizeMode.StretchImage;
            }
            else
            {
                textureImage.SizeMode = PictureBoxSizeMode.CenterImage;
            }
        }
        public static void parseMap(string path, string fileName)
        {
            FileStream fs = File.OpenRead(path + "/" + fileName);

            FileStream vfs = null;

            if (File.Exists(path + "/vram.ps3"))
            {
                vfs = File.OpenRead(path + "/vram.ps3");
            }

            FileStream gpf = null;

            if (File.Exists(path + "/gameplay_ntsc"))
            {
                gpf = File.OpenRead(path + "/gameplay_ntsc");
            }

            uint racNum = 0;

            ushort magic = BAToUInt16(ReadBlock(fs, 0xB0, 2), 0);

            switch (magic)
            {
            case 0x7533:
                racNum = 1;
                break;

            case 0xEA9C:
                racNum = 2;
                break;

            case 0x0000:
            case 0x755D:
                racNum = 3;
                break;
            }
            Console.WriteLine("Game determined to be ratchet" + racNum.ToString());

            List <MobyPropertyVariables> pVarConfigs = new List <MobyPropertyVariables>();
            string jsonString = File.ReadAllText(String.Format("./Config/Rac{0}/MobyPropertyVariables.json", racNum));

            pVarConfigs       = JsonConvert.DeserializeObject <List <MobyPropertyVariables> >(jsonString);
            DataStore.pVarMap = pVarConfigs;

            #region GameplayHeader
            GameplayHeader gameplayHeader = new GameplayHeader(gpf, racNum);

            DataStore.gameplayHeader = gameplayHeader;

            #endregion

            #region pVars
            List <byte[]> pVars;
            uint          numpVars;
            byte[]        pVarHeadBlock;
            uint          pVarSectionLength;
            byte[]        pVarBlock;
            switch (racNum)
            {
            case 1:
            case 2:
            case 3:
                pVars             = new List <byte[]>();
                numpVars          = (gameplayHeader.pVarPointer - gameplayHeader.pVarListPointer) / 8;
                pVarHeadBlock     = ReadBlock(gpf, gameplayHeader.pVarListPointer, numpVars * 8);
                pVarSectionLength = 0;
                for (uint i = 0; i < numpVars; i++)
                {
                    pVarSectionLength += BAToUInt32(pVarHeadBlock, (i * 8) + 0x04);
                }
                pVarBlock = ReadBlock(gpf, gameplayHeader.pVarPointer, pVarSectionLength);
                for (uint i = 0; i < numpVars; i++)
                {
                    uint   mobpVarsStart = BAToUInt32(pVarHeadBlock, (i * 8));
                    uint   mobpVarsCount = BAToUInt32(pVarHeadBlock, (i * 8) + 0x04);
                    byte[] mobpVars      = new byte[mobpVarsCount];
                    mobpVars = getBytes(pVarBlock, (int)mobpVarsStart, (int)mobpVarsCount);
                    pVars.Add(mobpVars);
                }
                DataStore.pVarList = pVars;
                break;
            }
            #endregion pVars

            #region Mobies

            uint   mobyCount = BAToUInt32(ReadBlock(gpf, gameplayHeader.mobyPointer, 4), 0);
            byte[] mobyBlock = ReadBlock(gpf, gameplayHeader.mobyPointer + 0x10, mobyCount * gameplayHeader.mobyElemSize);

            for (uint i = 0; i < mobyCount; i++)
            {
                RatchetMoby mob = new RatchetMoby(racNum, mobyBlock, i);
                DataStore.mobs.Add(mob);
            }
            #endregion

            DataStore.splines = new List <Spline>();

            uint   splineCount       = BAToUInt32(ReadBlock(gpf, gameplayHeader.splinePointer, 4), 0);
            uint   splineOffset      = BAToUInt32(ReadBlock(gpf, gameplayHeader.splinePointer + 4, 4), 0);
            uint   splineSectionSize = BAToUInt32(ReadBlock(gpf, gameplayHeader.splinePointer + 8, 4), 0);
            byte[] splineHeadBlock   = ReadBlock(gpf, gameplayHeader.splinePointer + 0x10, splineCount * 4);
            byte[] splineBlock       = ReadBlock(gpf, gameplayHeader.splinePointer + splineOffset, splineSectionSize);
            for (uint i = 0; i < splineCount; i++)
            {
                uint offset = BAToUInt32(splineHeadBlock, (i * 4));
                DataStore.splines.Add(new Spline(splineBlock, offset));
            }


            gpf.Close();

            EngineHeader engineHeader = new EngineHeader(fs, 1);
            DataStore.engineHeader = engineHeader;

            //Load UYA Spawnable Models
            #region Spawnables
            uint   spawnablesCount = BAToUInt32(ReadBlock(fs, engineHeader.spawnablesPointer, 4), 0);
            byte[] idBlock         = ReadBlock(fs, engineHeader.spawnablesPointer + 4, spawnablesCount * 8);

            for (int x = 0; x < spawnablesCount; x++)
            {
                RatchetModel_General model = new RatchetModel_General();
                model.modelType = ModelType.Spawnable;

                model.modelID = BAToShort(idBlock, (uint)(x * 8) + 2);
                model.offset  = BAToUInt32(idBlock, (uint)(x * 8) + 4);

                if (model.offset != 0)
                {
                    uint modelHeadSize = BAToUInt32(ReadBlock(fs, model.offset, 4), 0);

                    if (modelHeadSize > 0)
                    {
                        byte[] headBlock = ReadBlock(fs, model.offset, modelHeadSize + 0x20); //Head + objectDetails
                        uint   objectPtr = BAToUInt32(headBlock, 0);
                        model.animationsCount = headBlock[0x0C];
                        //(0x04)null
                        //(0x08)[count for 0x14 and 0x18][unknown][unknown][unknown]
                        //(0x0c)[animation count][unknown][unknown][unknown]
                        //(0x10)Pointer to list
                        //(0x14)Pointer to skeleton joints (0x40 structure)
                        //(0x18)Pointer to skeleton somethings (0x16 structure)
                        //(0x1C)Pointer to left arm animations (Ratchet)
                        //(0x20)null
                        model.size = BAToFloat(headBlock, 0x24);
                        uint texCount          = BAToUInt32(headBlock, objectPtr + 0x00);
                        uint otherCount        = BAToUInt32(headBlock, objectPtr + 0x04);
                        uint texBlockPointer   = BAToUInt32(headBlock, objectPtr + 0x08);
                        uint otherBlockPointer = BAToUInt32(headBlock, objectPtr + 0x0C);
                        uint vertPointer       = BAToUInt32(headBlock, objectPtr + 0x10);
                        uint indexPointer      = BAToUInt32(headBlock, objectPtr + 0x14);
                        model.vertexCount = BAToUInt16(headBlock, objectPtr + 0x18);
                        //(0x1A)count
                        //(0x1C)count
                        //(0x1E)null


                        //model.rawData = getModelDataRaw(model.modelType, model.modelID, path + "/" + fileName);

                        model.animPointer = new List <uint>();
                        for (uint i = 0; i < model.animationsCount; i++)
                        {
                            model.animPointer.Add(BAToUInt32(headBlock, (i * sizeof(uint)) + 0x48));
                        }

                        uint   texElemSize = 0x10;
                        byte[] texBlock    = ReadBlock(fs, model.offset + texBlockPointer, texCount * texElemSize);
                        model.textureConfig = new List <RatchetTexture_Model>();
                        model.faceCount     = 0;
                        for (uint t = 0; t < texCount; t++)
                        {
                            RatchetTexture_Model modTex = new RatchetTexture_Model();
                            modTex.ID    = BAToUInt32(texBlock, (t * texElemSize) + 0x0);
                            modTex.start = BAToUInt32(texBlock, (t * texElemSize) + 0x04);
                            modTex.size  = BAToUInt32(texBlock, (t * texElemSize) + 0x08);
                            model.textureConfig.Add(modTex);
                            model.faceCount += modTex.size;
                        }


                        //Flip endianness of vertex array float[vert_x, vert_y, vert_z, norm_x, norm_y, norm_z, uv_u, uv_v, reserved reserved]
                        uint   vertElemSize = 0x28;
                        uint   vertBuffSize = model.vertexCount * vertElemSize;
                        byte[] vertBlock    = ReadBlock(fs, model.offset + vertPointer, vertBuffSize);
                        model.vertBuff = new List <float>();
                        for (uint i = 0; i < model.vertexCount; i++)
                        {
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x00));    //Vertx
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x04));    //Verty
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x08));    //Vertz
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x0C));    //Nomrx
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x10));    //Normy
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x14));    //Normz
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x18));    //UVu
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x1C));    //UVv
                        }

                        //Flip endianness of index array
                        byte[] indiceBuff = ReadBlock(fs, model.offset + indexPointer, model.faceCount * sizeof(ushort));
                        model.indiceBuff = new List <ushort>();
                        for (uint i = 0; i < model.faceCount; i++)
                        {
                            model.indiceBuff.Add(BAToUInt16(indiceBuff, i * sizeof(ushort)));
                        }
                    }
                }
                DataStore.spawnableModels.Add(model);
            }
            #endregion

            //Load UYA Level Models
            #region Level Models
            uint   levelElemSize = 0x40;
            byte[] levelBlock    = ReadBlock(fs, engineHeader.levelModelsPointer, engineHeader.levelModelsCount * levelElemSize);

            for (uint x = 0; x < engineHeader.levelModelsCount; x++)
            {
                RatchetModel_General model = new RatchetModel_General();
                model.modelType = ModelType.Level;
                model.size      = 0.5f;

                uint vertPointer   = BAToUInt32(levelBlock, (x * levelElemSize) + 0x10);
                uint UVPointer     = BAToUInt32(levelBlock, (x * levelElemSize) + 0x14);
                uint indicePointer = BAToUInt32(levelBlock, (x * levelElemSize) + 0x18);
                uint texPointer    = BAToUInt32(levelBlock, (x * levelElemSize) + 0x1C);
                model.vertexCount = (ushort)BAToUInt32(levelBlock, (x * levelElemSize) + 0x24);
                ushort texCount = BAToUInt16(levelBlock, (x * levelElemSize) + 0x28);
                model.modelID = BAToShort(levelBlock, (x * levelElemSize) + 0x30);

                model.offset    = (uint)(x * 0x40) + engineHeader.levelModelsPointer;
                model.modelType = ModelType.Level;

                uint   texElemSize = 0x18;
                byte[] texBlock    = ReadBlock(fs, texPointer, texCount * texElemSize);
                model.textureConfig = new List <RatchetTexture_Model>();
                model.faceCount     = 0;
                for (uint t = 0; t < texCount; t++)
                {
                    RatchetTexture_Model dlt = new RatchetTexture_Model();
                    dlt.ID    = BAToUInt32(texBlock, (t * texElemSize) + 0x00);
                    dlt.start = BAToUInt32(texBlock, (t * texElemSize) + 0x08);
                    dlt.size  = BAToUInt32(texBlock, (t * texElemSize) + 0x0C);
                    model.textureConfig.Add(dlt);
                    model.faceCount += dlt.size;
                }

                //Flip endianness of vertex array float[vert_x, vert_y, vert_z, norm_x, norm_y, norm_z, uv_u, uv_v, reserved reserved]
                uint   vertElemSize = 0x18;
                uint   vertBuffSize = model.vertexCount * vertElemSize;
                byte[] vertBlock    = ReadBlock(fs, vertPointer, vertBuffSize);

                uint   UVElemsize = 0x08;
                uint   UVBuffSize = model.vertexCount * UVElemsize;
                byte[] UVBlock    = ReadBlock(fs, UVPointer, UVBuffSize);


                model.vertBuff = new List <float>();
                for (uint i = 0; i < model.vertexCount; i++)
                {
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x00)); //vertx
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x04)); //verty
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x08)); //vertz
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x0C)); //normx
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x10)); //normy
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x14)); //normz

                    model.vertBuff.Add(BAToFloat(UVBlock, (i * UVElemsize) + 0x00));     //UVu
                    model.vertBuff.Add(BAToFloat(UVBlock, (i * UVElemsize) + 0x04));     //UVv
                }

                //Flip endianness of index array
                byte[] indiceBuff = ReadBlock(fs, indicePointer, model.faceCount * sizeof(ushort));
                model.indiceBuff = new List <ushort>();
                for (uint i = 0; i < model.faceCount; i++)
                {
                    model.indiceBuff.Add(BAToUInt16(indiceBuff, i * sizeof(ushort)));
                }

                DataStore.levelModels.Add(model);
            }
            #endregion

            //Load UYA Scenery Models
            #region Scenery Models
            uint   sceneElemSize = 0x40;
            byte[] sceneBlock    = ReadBlock(fs, engineHeader.sceneryModelsPointer, engineHeader.sceneryModelsCount * sceneElemSize);

            for (uint x = 0; x < engineHeader.sceneryModelsCount; x++)
            {
                RatchetModel_General model = new RatchetModel_General();
                model.modelType = ModelType.Scenery;
                model.size      = 0.5f;

                uint vertPointer   = BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x10);
                uint UVPointer     = BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x14);
                uint indicePointer = BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x18);
                uint texPointer    = BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x1C);
                model.vertexCount = (ushort)BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x24);
                ushort texCount = BAToUInt16(sceneBlock, (x * sceneElemSize) + 0x28);
                model.modelID = BAToShort(sceneBlock, (x * sceneElemSize) + 0x30);

                uint   texElemSize = 0x10;
                byte[] texBlock    = ReadBlock(fs, texPointer, texCount * texElemSize);
                model.textureConfig = new List <RatchetTexture_Model>();
                model.faceCount     = 0;
                for (uint t = 0; t < texCount; t++)
                {
                    RatchetTexture_Model dlt = new RatchetTexture_Model();
                    dlt.ID    = BAToUInt32(texBlock, (t * texElemSize) + 0x00);
                    dlt.start = BAToUInt32(texBlock, (t * texElemSize) + 0x04);
                    dlt.size  = BAToUInt32(texBlock, (t * texElemSize) + 0x08);
                    model.textureConfig.Add(dlt);
                    model.faceCount += dlt.size;
                }

                //Flip endianness of vertex array float[vert_x, vert_y, vert_z, norm_x, norm_y, norm_z, uv_u, uv_v, reserved reserved]
                uint   vertElemSize = 0x18;
                uint   vertBuffSize = model.vertexCount * vertElemSize;
                byte[] vertBlock    = ReadBlock(fs, vertPointer, vertBuffSize);

                uint   UVElemsize = 0x08;
                uint   UVBuffSize = model.vertexCount * UVElemsize;
                byte[] UVBlock    = ReadBlock(fs, UVPointer, UVBuffSize);


                model.vertBuff = new List <float>();
                for (uint i = 0; i < model.vertexCount; i++)
                {
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x00)); //vertx
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x04)); //verty
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x08)); //vertz
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x0C)); //normx
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x10)); //normy
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x14)); //normz

                    model.vertBuff.Add(BAToFloat(UVBlock, (i * UVElemsize) + 0x00));     //UVu
                    model.vertBuff.Add(BAToFloat(UVBlock, (i * UVElemsize) + 0x04));     //UVv
                }

                //Flip endianness of index array
                byte[] indiceBuff = ReadBlock(fs, indicePointer, model.faceCount * sizeof(ushort));
                model.indiceBuff = new List <ushort>();
                for (uint i = 0; i < model.faceCount; i++)
                {
                    model.indiceBuff.Add(BAToUInt16(indiceBuff, i * sizeof(ushort)));
                }

                DataStore.sceneryModels.Add(model);
                //Console.WriteLine("Scenery Model Added: 0x" + model.modelID.ToString("X4"));
            }
            #endregion

            //Load Terrain
            #region Terrain
            {
                uint terrainElemSize = 0x30;
                uint texElemSize     = 0x10;
                uint vertElemSize    = 0x1c;
                uint UVElemSize      = 0x08;
                uint ColorElemSize   = 0x04;

                RatchetModel_Terrain model = new RatchetModel_Terrain();
                model.offset    = engineHeader.terrainPointer;
                model.modelID   = 1111;
                model.modelType = ModelType.Terrain;
                byte[] terrainHeadBlock = ReadBlock(fs, engineHeader.terrainPointer, 0x60);

                uint   headPointer = BAToUInt32(terrainHeadBlock, 0x0);
                ushort headCount   = BAToUInt16(terrainHeadBlock, 0x06);

                byte[] terrainBlock = ReadBlock(fs, headPointer, headCount * terrainElemSize);
                model.textureConfig = new List <RatchetTexture_Model>();
                model.vertBuff      = new List <float>();
                model.indiceBuff    = new List <uint>();
                uint vertCount         = 0;
                uint prevVertCount     = 0;
                uint prevFaceCount     = 0;
                uint prevHeadCount     = 0;
                uint prevPrevFaceCount = 0;

                for (uint i = 0; i < 4; i++)    //I have yet to see any level have more than two of these, but the header theoretically has space for 4
                {
                    uint vertPointer   = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x08);
                    uint colPointer    = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x18);
                    uint UVPointer     = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x28);
                    uint indicePointer = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x38);

                    prevFaceCount = 0;
                    if (vertPointer != 0 && UVPointer != 0 && indicePointer != 0)    //Check that there's data at the pointers
                    {
                        //Loop throught the heads, and stop when the overflow counter increases
                        for (uint ii = prevHeadCount; ii < headCount && i == BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x22); ii++)
                        {
                            uint   localFaceCount = 0;
                            uint   texPointer     = BAToUInt32(terrainBlock, (ii * terrainElemSize) + 0x10);
                            uint   texCount       = BAToUInt32(terrainBlock, (ii * terrainElemSize) + 0x14);
                            ushort vertStart      = BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x18);
                            ushort headVertCount  = BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x1A);
                            vertCount += headVertCount;

                            byte[] texBlock = ReadBlock(fs, texPointer, texElemSize * texCount);
                            for (uint iii = 0; iii < texCount; iii++)
                            {
                                RatchetTexture_Model tex = new RatchetTexture_Model();
                                tex.ID          = BAToUInt32(texBlock, (iii * texElemSize) + 0x00);
                                tex.start       = BAToUInt32(texBlock, (iii * texElemSize) + 0x04) + prevPrevFaceCount;
                                tex.size        = BAToUInt32(texBlock, (iii * texElemSize) + 0x08) + prevPrevFaceCount;
                                localFaceCount += BAToUInt32(texBlock, (iii * texElemSize) + 0x08);
                                model.textureConfig.Add(tex);
                            }

                            byte[] vertBlock = ReadBlock(fs, vertPointer + vertStart * vertElemSize, headVertCount * vertElemSize);
                            byte[] colBlock  = ReadBlock(fs, colPointer + vertStart * ColorElemSize, headVertCount * ColorElemSize);
                            byte[] UVBlock   = ReadBlock(fs, UVPointer + vertStart * UVElemSize, headVertCount * UVElemSize);

                            for (uint iii = 0; iii < headVertCount; iii++)
                            {
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x00)); //vertx
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x04)); //verty
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x08)); //vertz
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x0C)); //normx
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x10)); //normy
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x14)); //normz

                                model.vertBuff.Add(BAToFloat(UVBlock, (iii * UVElemSize) + 0x00));     //UVu
                                model.vertBuff.Add(BAToFloat(UVBlock, (iii * UVElemSize) + 0x04));     //UVv

                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x00] / 255f);     //color r
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x01] / 255f);     //color g
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x02] / 255f);     //color b
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x03] / 255f);     //color a
                            }

                            byte[] indiceBuff = ReadBlock(fs, indicePointer + prevFaceCount * sizeof(ushort), localFaceCount * sizeof(ushort));
                            for (uint iii = 0; iii < localFaceCount; iii++)
                            {
                                model.indiceBuff.Add(BAToUInt16(indiceBuff, iii * sizeof(ushort)) + prevVertCount);
                            }
                            prevFaceCount += localFaceCount;
                            prevHeadCount  = ii + 1;
                        }
                        prevVertCount     = vertCount;
                        prevPrevFaceCount = prevFaceCount;
                    }
                }
                model.vertexCount      = vertCount;
                model.faceCount        = prevFaceCount;
                DataStore.terrainModel = model;
            }
            #endregion

            //Load Level Objects
            #region Level objects
            byte[] levelObjectBlock = ReadBlock(fs, engineHeader.levelObjectPointer, engineHeader.levelObjectCount * 0x70);
            DataStore.levelObjects = new List <LevelObject>();
            for (uint i = 0; i < engineHeader.levelObjectCount; i++)
            {
                LevelObject levObj = new LevelObject(levelObjectBlock, i);
                DataStore.levelObjects.Add(levObj);
            }
            #endregion

            //Load Scenery Objects
            #region Scenery objects
            byte[] sceneryObjectBlock = ReadBlock(fs, engineHeader.sceneryObjectsPointer, engineHeader.sceneryObjectsCount * 0x70);
            DataStore.sceneryObjects = new List <LevelObject>();
            for (uint i = 0; i < engineHeader.sceneryObjectsCount; i++)
            {
                LevelObject levObj = new LevelObject(sceneryObjectBlock, i);
                DataStore.sceneryObjects.Add(levObj);
            }
            #endregion

            //Load Textures
            #region Textures
            RatchetTexture_General texture = new RatchetTexture_General();
            for (int x = 0; x < engineHeader.UYATextureCount; x++)
            {
                texture.texHeader = ReadBlock(fs, engineHeader.texturesPointer + (uint)(0x24 * x), 0x24);
                uint nextTexturePointer    = x < engineHeader.UYATextureCount - 1 ? ReadUInt32(ReadBlock(fs, engineHeader.texturesPointer + (uint)(0x24 * (x + 1)), 0x4), 0) : vfs != null ? (uint)vfs.Length : 0;
                uint currentTexturePointer = ReadUInt32(texture.texHeader, 0);
                //Console.WriteLine("Parsing texture " + x + " " + currentTexturePointer.ToString("X") + " " + nextTexturePointer.ToString("X"));
                texture.ID      = x;
                texture.width   = BAToShort(texture.texHeader, 0x18);
                texture.height  = BAToShort(texture.texHeader, 0x1A);
                texture.texData = vfs != null?ReadBlock(vfs, currentTexturePointer, nextTexturePointer - currentTexturePointer) : null;

                texture.reverseRGB = false;
                DataStore.textures.Add(texture);
                //Console.WriteLine("Texture : " + x + " Width: " + texture.width + " Height: " + texture.height);
            }
            #endregion



            //Terrain Collision
            #region Terrain Collision
            float div = 1024f;

            uint collisionVertCount = 0;

            uint   collisionStart  = engineHeader.collisionPointer + BAToUInt32(ReadBlock(fs, engineHeader.collisionPointer + 0x00, 4), 0);
            uint   collisionLength = engineHeader.collisionPointer + collisionStart + BAToUInt32(ReadBlock(fs, engineHeader.collisionPointer + 0x04, 4), 0);
            byte[] collision       = ReadBlock(fs, collisionStart, collisionLength);

            List <float> collisionVertexBuff = new List <float>();
            List <uint>  collisionIndiceBuff = new List <uint>();

            ushort zShift = BAToUInt16(collision, 0);
            ushort zCount = BAToUInt16(collision, 2);

            for (uint z = 0; z < zCount; z++)
            {
                uint yOffset = BAToUInt32(collision, (z * 4) + 0x04);
                if (yOffset != 0)
                {
                    ushort yShift = BAToUInt16(collision, yOffset + 0);
                    ushort yCount = BAToUInt16(collision, yOffset + 2);
                    for (uint y = 0; y < yCount; y++)
                    {
                        uint xOffset = BAToUInt32(collision, yOffset + (y * 4) + 0x04);
                        if (xOffset != 0)
                        {
                            ushort xShift = BAToUInt16(collision, xOffset + 0);
                            ushort xCount = BAToUInt16(collision, xOffset + 2);
                            for (uint x = 0; x < xCount; x++)
                            {
                                uint   vOffset     = BAToUInt32(collision, xOffset + (x * 4) + 4);
                                ushort faceCount   = BAToUInt16(collision, vOffset);
                                byte   vertexCount = collision[vOffset + 2];
                                byte   rCount      = collision[vOffset + 3];

                                if (vOffset != 0)
                                {
                                    byte[] collisionType = new byte[vertexCount];
                                    //Console.WriteLine("Facecount: " + faceCount.ToString("X2") + "VertCount: " + vertexCount.ToString("X2"));
                                    for (uint f = 0; f < faceCount; f++)
                                    {
                                        uint   fOffset = vOffset + ((uint)12 * vertexCount) + 4 + (f * 4);
                                        byte[] fArray  = new byte[4];
                                        Array.Copy(collision, fOffset, fArray, 0, 4);

                                        collisionType[fArray[0]] = fArray[3];
                                        collisionType[fArray[1]] = fArray[3];
                                        collisionType[fArray[2]] = fArray[3];

                                        uint f1 = collisionVertCount + fArray[0];
                                        uint f2 = collisionVertCount + fArray[1];
                                        uint f3 = collisionVertCount + fArray[2];
                                        collisionIndiceBuff.Add(f1);
                                        collisionIndiceBuff.Add(f2);
                                        collisionIndiceBuff.Add(f3);
                                        if (f < rCount)
                                        {
                                            uint rOffset = vOffset + 4 + (uint)(12 * vertexCount) + (uint)(4 * faceCount) + f;
                                            uint f4      = collisionVertCount + collision[rOffset];
                                            collisionIndiceBuff.Add(f1);
                                            collisionIndiceBuff.Add(f3);
                                            collisionIndiceBuff.Add(f4);
                                            collisionType[collision[rOffset]] = fArray[3];
                                        }
                                    }

                                    for (uint v = 0; v < vertexCount; v++)
                                    {
                                        uint  pOffset = vOffset + (12 * v) + 4;
                                        float pX      = BAToFloat(collision, pOffset + 0) / div + 4 * (xShift + x + 0.5f);
                                        float pY      = BAToFloat(collision, pOffset + 4) / div + 4 * (yShift + y + 0.5f);
                                        float pZ      = BAToFloat(collision, pOffset + 8) / div + 4 * (zShift + z + 0.5f);
                                        collisionVertexBuff.Add(pX);
                                        collisionVertexBuff.Add(pY);
                                        collisionVertexBuff.Add(pZ);
                                        switch (collisionType[v])
                                        {
                                        case 0x1F:
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            break;

                                        case 0x08:
                                            collisionVertexBuff.Add(1.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            break;

                                        case 0x0C:
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(1.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            break;

                                        case 0x01:
                                            //This
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            break;

                                        case 0x3F:
                                            collisionVertexBuff.Add(0.5f);
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            break;

                                        case 0x0B:
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.5f);
                                            collisionVertexBuff.Add(0.0f);
                                            break;

                                        case 0x0A:
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.5f);
                                            break;

                                        case 0x28:
                                            collisionVertexBuff.Add(0.25f);
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            break;

                                        case 0x5F:
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.25f);
                                            collisionVertexBuff.Add(0.0f);
                                            break;

                                        case 0x09:
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.25f);
                                            break;

                                        case 0x00:
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(1.0f);
                                            break;

                                        case 0x6C:
                                            collisionVertexBuff.Add(0.5f);
                                            collisionVertexBuff.Add(0.5f);
                                            collisionVertexBuff.Add(0.5f);
                                            break;

                                        default:
                                            collisionVertexBuff.Add(1.0f);
                                            collisionVertexBuff.Add(1.0f);
                                            collisionVertexBuff.Add(1.0f);
                                            break;
                                        }
                                        collisionVertCount++;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            DataStore.collVertBuff = collisionVertexBuff;
            DataStore.collIndBuff  = collisionIndiceBuff;
            #endregion

            #region Chunks
            List <int> chunkIds = new List <int>();
            for (int chunkIndex = 0; chunkIndex < 5; chunkIndex++)
            {
                if (File.Exists(path + "/chunk" + chunkIndex + ".ps3"))
                {
                    chunkIds.Add(chunkIndex);
                }
            }

            foreach (int chunkId in chunkIds)
            {
                FileStream cfs = File.OpenRead(path + "/chunk" + chunkId + ".ps3");
                Console.WriteLine("Loading chunk " + chunkId);
                uint terrainElemSize = 0x30;
                uint texElemSize     = 0x10;
                uint vertElemSize    = 0x1c;
                uint UVElemSize      = 0x08;
                uint ColorElemSize   = 0x04;

                RatchetModel_Terrain model = new RatchetModel_Terrain();
                model.offset    = 0x10;
                model.modelID   = 1111;
                model.modelType = ModelType.Terrain;
                byte[] terrainHeadBlock = ReadBlock(cfs, 0x10, 0x60);

                uint   headPointer = BAToUInt32(terrainHeadBlock, 0x0);
                ushort headCount   = BAToUInt16(terrainHeadBlock, 0x06);

                byte[] terrainBlock = ReadBlock(cfs, headPointer, headCount * terrainElemSize);

                model.textureConfig = new List <RatchetTexture_Model>();
                model.vertBuff      = new List <float>();
                model.indiceBuff    = new List <uint>();
                uint vertCount         = 0;
                uint prevVertCount     = 0;
                uint prevFaceCount     = 0;
                uint prevHeadCount     = 0;
                uint prevPrevFaceCount = 0;

                for (uint i = 0; i < 4; i++)   //I have yet to see any level have more than two of these, but the header theoretically has space for 4
                {
                    uint vertPointer   = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x08);
                    uint colPointer    = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x18);
                    uint UVPointer     = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x28);
                    uint indicePointer = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x38);

                    prevFaceCount = 0;
                    if (vertPointer != 0 && UVPointer != 0 && indicePointer != 0)    //Check that there's data at the pointers
                    {
                        //Loop throught the heads, and stop when the overflow counter increases
                        for (uint ii = prevHeadCount; ii < headCount && i == BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x22); ii++)
                        {
                            uint   localFaceCount = 0;
                            uint   texPointer     = BAToUInt32(terrainBlock, (ii * terrainElemSize) + 0x10);
                            uint   texCount       = BAToUInt32(terrainBlock, (ii * terrainElemSize) + 0x14);
                            ushort vertStart      = BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x18);
                            ushort headVertCount  = BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x1A);
                            vertCount += headVertCount;

                            byte[] texBlock = ReadBlock(cfs, texPointer, texElemSize * texCount);
                            for (uint iii = 0; iii < texCount; iii++)
                            {
                                RatchetTexture_Model tex = new RatchetTexture_Model();
                                tex.ID    = BAToUInt32(texBlock, (iii * texElemSize) + 0x00);
                                tex.start = BAToUInt32(texBlock, (iii * texElemSize) + 0x04) + prevPrevFaceCount;
                                tex.size  = BAToUInt32(texBlock, (iii * texElemSize) + 0x08) + prevPrevFaceCount;

                                localFaceCount += BAToUInt32(texBlock, (iii * texElemSize) + 0x08);

                                model.textureConfig.Add(tex);
                            }


                            byte[] vertBlock = ReadBlock(cfs, vertPointer + vertStart * vertElemSize, headVertCount * vertElemSize);
                            byte[] colBlock  = ReadBlock(cfs, colPointer + vertStart * ColorElemSize, headVertCount * ColorElemSize);
                            byte[] UVBlock   = ReadBlock(cfs, UVPointer + vertStart * UVElemSize, headVertCount * UVElemSize);

                            for (uint iii = 0; iii < headVertCount; iii++)
                            {
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x00)); //vertx
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x04)); //verty
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x08)); //vertz
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x0C)); //normx
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x10)); //normy
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x14)); //normz

                                model.vertBuff.Add(BAToFloat(UVBlock, (iii * UVElemSize) + 0x00));     //UVu
                                model.vertBuff.Add(BAToFloat(UVBlock, (iii * UVElemSize) + 0x04));     //UVv


                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x00] / 255f);    //color r
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x01] / 255f);    //color g
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x02] / 255f);    //color b
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x03] / 255f);    //color a
                            }



                            byte[] indiceBuff = ReadBlock(cfs, indicePointer + prevFaceCount * sizeof(ushort), localFaceCount * sizeof(ushort));
                            //Console.WriteLine(localFaceCount.ToString("X8"));
                            for (uint iii = 0; iii < localFaceCount; iii++)
                            {
                                model.indiceBuff.Add(BAToUInt16(indiceBuff, iii * sizeof(ushort)) + prevVertCount);
                            }

                            prevFaceCount += localFaceCount;
                            prevHeadCount  = ii + 1;
                        }
                        prevVertCount     = vertCount;
                        prevPrevFaceCount = prevFaceCount;
                    }
                }
                model.vertexCount = vertCount;
                model.faceCount   = prevFaceCount;
                DataStore.chunks.Add(model);
            }
            #endregion

            //TODO: textureConfig - Menus

            //TODO: textureConfig - 2D GFX

            //TODO: Sprites


            //Load the remaining unknown or unhandled data
            #region Remaining Data

            /*
             * DataStore.mapRenderDefintions = getSection(fs, 0x04);
             * DataStore.Ptr_08 = getSection(fs, 0x08);
             * DataStore.Ptr_0C = getSection(fs, 0x0C);
             * DataStore.skyBox = getSection(fs, 0x10);
             * DataStore.collisionMap = getSection(fs, 0x14);
             * DataStore.campaignPlayerAnimations = getSection(fs, 0x18);
             * DataStore.Ptr_40 = getSection(fs, 0x40);
             * DataStore.Ptr_44 = getSection(fs, 0x44);
             * DataStore.soundsConfig = getSection(fs, 0x48);
             * DataStore.Ptr_4C = getSection(fs, 0x4C);
             * DataStore.Ptr_50 = getSection(fs, 0x50);
             * DataStore.lighting = getSection(fs, 0x5C);
             * DataStore.lightingConfig = getSection(fs, 0x64);
             * DataStore.textureConfigMenu = getSection(fs, 0x68);
             * DataStore.textureConfig2DGFX = getSection(fs, 0x70);
             * DataStore.spriteDef = getSection(fs, 0x74);
             */
            #endregion

            #region raw Data //need to properly handle these eventually
            //DataStore.terrainModel.rawData = getSection(fs, 0x3C);
            //rawLevelModelBlock = getSection(fs, 0x1C);
            //rawSceneryModelBlock = getSection(fs, 0x2C);
            #endregion

            fs.Close();

            Console.WriteLine("Engine data loaded with new engine parser for UYA.");
        }
Esempio n. 5
0
        public static void parseMap(string path, string fileName)
        {
            FileStream fs = File.OpenRead(path + "/" + fileName);

            FileStream vfs = null;

            if (File.Exists(path + "/vram.ps3"))
            {
                vfs = File.OpenRead(path + "/vram.ps3");
            }

            FileStream gpf = null;

            if (File.Exists(path + "/gameplay_ntsc"))
            {
                gpf = File.OpenRead(path + "/gameplay_ntsc");
            }

            loadMobyPvarMap();


            uint racNum = 4;

            #region GameplayHeader
            GameplayHeader gameplayHeader = new GameplayHeader(gpf, racNum);
            DataStore.gameplayHeader = gameplayHeader;

            #endregion

            #region pVars
            List <byte[]> pVars;
            uint          numpVars;
            byte[]        pVarHeadBlock;
            uint          pVarSectionLength;
            byte[]        pVarBlock;
            switch (racNum)
            {
            case 4:
                pVars             = new List <byte[]>();
                numpVars          = (gameplayHeader.pVarPointer - gameplayHeader.pVarListPointer) / 8;
                pVarHeadBlock     = ReadBlock(gpf, gameplayHeader.pVarListPointer, numpVars * 8);
                pVarSectionLength = 0;
                for (uint i = 0; i < numpVars; i++)
                {
                    pVarSectionLength += BAToUInt32(pVarHeadBlock, (i * 8) + 0x04);
                }
                pVarBlock = ReadBlock(gpf, gameplayHeader.pVarPointer, pVarSectionLength);
                for (uint i = 0; i < numpVars; i++)
                {
                    uint   mobpVarsStart = BAToUInt32(pVarHeadBlock, (i * 8));
                    uint   mobpVarsCount = BAToUInt32(pVarHeadBlock, (i * 8) + 0x04);
                    byte[] mobpVars      = new byte[mobpVarsCount];
                    mobpVars = getBytes(pVarBlock, (int)mobpVarsStart, (int)mobpVarsCount);
                    pVars.Add(mobpVars);
                }
                DataStore.pVarList = pVars;
                break;
            }
            #endregion pVars

            #region Mobies

            uint   mobyCount = BAToUInt32(ReadBlock(gpf, gameplayHeader.mobyPointer, 4), 0);
            byte[] mobyBlock = ReadBlock(gpf, gameplayHeader.mobyPointer + 0x10, mobyCount * gameplayHeader.mobyElemSize);

            for (uint i = 0; i < mobyCount; i++)
            {
                RatchetMoby mob = new RatchetMoby(racNum, mobyBlock, i);
                DataStore.mobs.Add(mob);
            }
            #endregion

            DataStore.splines = new List <Spline>();

            uint   splineCount       = BAToUInt32(ReadBlock(gpf, gameplayHeader.splinePointer, 4), 0);
            uint   splineOffset      = BAToUInt32(ReadBlock(gpf, gameplayHeader.splinePointer + 4, 4), 0);
            uint   splineSectionSize = BAToUInt32(ReadBlock(gpf, gameplayHeader.splinePointer + 8, 4), 0);
            byte[] splineHeadBlock   = ReadBlock(gpf, gameplayHeader.splinePointer + 0x10, splineCount * 4);
            byte[] splineBlock       = ReadBlock(gpf, gameplayHeader.splinePointer + splineOffset, splineSectionSize);
            for (uint i = 0; i < splineCount; i++)
            {
                uint offset = BAToUInt32(splineHeadBlock, (i * 4));
                DataStore.splines.Add(new Spline(splineBlock, offset));
            }


            #region EngineHeader
            byte[] engineHeader = ReadBlock(fs, 0, 0x90);

            //Data from header
            uint spawnablesPointer = BAToUInt32(engineHeader, 0x00);
            //(0x04)Map render definitions
            //(0x08)null
            //(0x0C)null
            //(0x14)Skybox
            //(0x18)Collisionmap
            uint levelModelsPointer            = BAToUInt32(engineHeader, 0x20);
            uint levelModelsCount              = BAToUInt32(engineHeader, 0x24);
            uint levelModelsPlacementPointer   = BAToUInt32(engineHeader, 0x28);
            uint levelObjectsCount             = BAToUInt32(engineHeader, 0x2C);
            uint sceneryModelsPointer          = BAToUInt32(engineHeader, 0x34);
            uint sceneryModelsCount            = BAToUInt32(engineHeader, 0x38);
            uint sceneryModelsPlacementPointer = BAToUInt32(engineHeader, 0x3C);
            uint sceneryObjectsCount           = BAToUInt32(engineHeader, 0x40);
            uint terrainPointer = BAToUInt32(engineHeader, 0x48);
            //(0x44) ??
            //(0x54)Sound config (Menus + terrain)
            uint texturesPointer = BAToUInt32(engineHeader, 0x60);
            uint textureCount    = BAToUInt32(engineHeader, 0x64);
            //(0x68)Lighting pointer
            uint lightingLevel          = BAToUInt32(engineHeader, 0x6C);
            uint textureConfigMenuCount = BAToUInt32(engineHeader, 0x78);
            //(0x7C)textureConfig2DGFX
            //(0x80)Sprite def
            //(0x88) sound config (spawnables + everything else)

            EngineHeader engHead = new EngineHeader(fs, 4);
            DataStore.engineHeader = engHead;
            #endregion

            //Load DL Spawnable Models
            #region Spawnables
            uint   spawnablesCount = BAToUInt32(ReadBlock(fs, spawnablesPointer, 4), 0);
            byte[] idBlock         = ReadBlock(fs, spawnablesPointer + 4, spawnablesCount * 8);

            for (int x = 0; x < spawnablesCount; x++)
            {
                RatchetModel_General model = new RatchetModel_General();
                model.modelType = ModelType.Spawnable;

                model.modelID = BAToShort(idBlock, (uint)(x * 8) + 2);
                model.offset  = BAToUInt32(idBlock, (uint)(x * 8) + 4);

                if (model.offset != 0)
                {
                    uint modelHeadSize = BAToUInt32(ReadBlock(fs, model.offset, 4), 0);

                    if (modelHeadSize > 0)
                    {
                        byte[] headBlock = ReadBlock(fs, model.offset, modelHeadSize + 0x20); //Head + objectDetails
                        uint   objectPtr = BAToUInt32(headBlock, 0);
                        model.animationsCount = headBlock[0x0C];
                        //(0x04)null
                        //(0x08)[count for 0x14 and 0x18][unknown][unknown][unknown]
                        //(0x0c)[animation count][unknown][unknown][unknown]
                        //(0x10)Pointer to list
                        //(0x14)Pointer to skeleton joints (0x40 structure)
                        //(0x18)Pointer to skeleton somethings (0x16 structure)
                        //(0x1C)Pointer to left arm animations (Ratchet)
                        //(0x20)null
                        model.size = BAToFloat(headBlock, 0x24);
                        uint texCount          = BAToUInt32(headBlock, objectPtr + 0x00);
                        uint otherCount        = BAToUInt32(headBlock, objectPtr + 0x04);
                        uint texBlockPointer   = BAToUInt32(headBlock, objectPtr + 0x08);
                        uint otherBlockPointer = BAToUInt32(headBlock, objectPtr + 0x0C);
                        uint vertPointer       = BAToUInt32(headBlock, objectPtr + 0x10);
                        uint indexPointer      = BAToUInt32(headBlock, objectPtr + 0x14);
                        model.vertexCount = BAToUInt16(headBlock, objectPtr + 0x18);
                        //(0x1A)count
                        //(0x1C)count
                        //(0x1E)null


                        //model.rawData = getModelDataRaw(model.modelType, model.modelID, path + "/" + fileName);

                        model.animPointer = new List <uint>();
                        for (uint i = 0; i < model.animationsCount; i++)
                        {
                            model.animPointer.Add(BAToUInt32(headBlock, (i * sizeof(uint)) + 0x48));
                        }

                        uint   texElemSize = 0x10;
                        byte[] texBlock    = ReadBlock(fs, model.offset + texBlockPointer, texCount * texElemSize);
                        model.textureConfig = new List <RatchetTexture_Model>();
                        model.faceCount     = 0;
                        for (uint t = 0; t < texCount; t++)
                        {
                            RatchetTexture_Model modTex = new RatchetTexture_Model();
                            modTex.ID    = BAToUInt32(texBlock, (t * texElemSize) + 0x0);
                            modTex.start = BAToUInt32(texBlock, (t * texElemSize) + 0x04);
                            modTex.size  = BAToUInt32(texBlock, (t * texElemSize) + 0x08);
                            model.textureConfig.Add(modTex);
                            model.faceCount += modTex.size;
                        }


                        //Flip endianness of vertex array float[vert_x, vert_y, vert_z, norm_x, norm_y, norm_z, uv_u, uv_v, reserved reserved]
                        uint   vertElemSize = 0x28;
                        uint   vertBuffSize = model.vertexCount * vertElemSize;
                        byte[] vertBlock    = ReadBlock(fs, model.offset + vertPointer, vertBuffSize);
                        model.vertBuff = new List <float>();
                        for (uint i = 0; i < model.vertexCount; i++)
                        {
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x00));    //Vertx
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x04));    //Verty
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x08));    //Vertz
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x0C));    //Nomrx
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x10));    //Normy
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x14));    //Normz
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x18));    //UVu
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x1C));    //UVv
                        }

                        //Flip endianness of index array
                        byte[] indiceBuff = ReadBlock(fs, model.offset + indexPointer, model.faceCount * sizeof(ushort));
                        model.indiceBuff = new List <ushort>();
                        for (uint i = 0; i < model.faceCount; i++)
                        {
                            model.indiceBuff.Add(BAToUInt16(indiceBuff, i * sizeof(ushort)));
                        }
                    }
                }
                DataStore.spawnableModels.Add(model);
            }
            #endregion

            //Load DL Level Models
            #region Level Models
            uint   levelElemSize = 0x40;
            byte[] levelBlock    = ReadBlock(fs, levelModelsPointer, levelModelsCount * levelElemSize);

            for (uint x = 0; x < levelModelsCount; x++)
            {
                RatchetModel_General model = new RatchetModel_General();
                model.modelType = ModelType.Level;
                model.size      = 0.5f;

                uint vertPointer   = BAToUInt32(levelBlock, (x * levelElemSize) + 0x10);
                uint UVPointer     = BAToUInt32(levelBlock, (x * levelElemSize) + 0x14);
                uint indicePointer = BAToUInt32(levelBlock, (x * levelElemSize) + 0x18);
                uint texPointer    = BAToUInt32(levelBlock, (x * levelElemSize) + 0x1C);
                model.vertexCount = (ushort)BAToUInt32(levelBlock, (x * levelElemSize) + 0x24);
                ushort texCount = BAToUInt16(levelBlock, (x * levelElemSize) + 0x28);
                model.modelID = BAToShort(levelBlock, (x * levelElemSize) + 0x30);

                model.offset    = (uint)(x * 0x40) + levelModelsPointer;
                model.modelType = ModelType.Level;

                uint   texElemSize = 0x18;
                byte[] texBlock    = ReadBlock(fs, texPointer, texCount * texElemSize);
                model.textureConfig = new List <RatchetTexture_Model>();
                model.faceCount     = 0;
                for (uint t = 0; t < texCount; t++)
                {
                    RatchetTexture_Model dlt = new RatchetTexture_Model();
                    dlt.ID    = BAToUInt32(texBlock, (t * texElemSize) + 0x00);
                    dlt.start = BAToUInt32(texBlock, (t * texElemSize) + 0x08);
                    dlt.size  = BAToUInt32(texBlock, (t * texElemSize) + 0x0C);
                    model.textureConfig.Add(dlt);
                    model.faceCount += dlt.size;
                }

                //Flip endianness of vertex array float[vert_x, vert_y, vert_z, norm_x, norm_y, norm_z, uv_u, uv_v, reserved reserved]
                uint   vertElemSize = 0x18;
                uint   vertBuffSize = model.vertexCount * vertElemSize;
                byte[] vertBlock    = ReadBlock(fs, vertPointer, vertBuffSize);

                uint   UVElemsize = 0x08;
                uint   UVBuffSize = model.vertexCount * UVElemsize;
                byte[] UVBlock    = ReadBlock(fs, UVPointer, UVBuffSize);


                model.vertBuff = new List <float>();
                for (uint i = 0; i < model.vertexCount; i++)
                {
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x00)); //vertx
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x04)); //verty
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x08)); //vertz
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x0C)); //normx
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x10)); //normy
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x14)); //normz

                    model.vertBuff.Add(BAToFloat(UVBlock, (i * UVElemsize) + 0x00));     //UVu
                    model.vertBuff.Add(BAToFloat(UVBlock, (i * UVElemsize) + 0x04));     //UVv
                }

                //Flip endianness of index array
                byte[] indiceBuff = ReadBlock(fs, indicePointer, model.faceCount * sizeof(ushort));
                model.indiceBuff = new List <ushort>();
                for (uint i = 0; i < model.faceCount; i++)
                {
                    model.indiceBuff.Add(BAToUInt16(indiceBuff, i * sizeof(ushort)));
                }

                DataStore.levelModels.Add(model);
            }
            #endregion

            //Load DL Scenery Models
            #region Scenery Models
            uint   sceneElemSize = 0x40;
            byte[] sceneBlock    = ReadBlock(fs, sceneryModelsPointer, sceneryModelsCount * sceneElemSize);

            for (uint x = 0; x < sceneryModelsCount; x++)
            {
                RatchetModel_General model = new RatchetModel_General();
                model.modelType = ModelType.Scenery;
                model.size      = 0.5f;

                uint vertPointer   = BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x10);
                uint UVPointer     = BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x14);
                uint indicePointer = BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x18);
                uint texPointer    = BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x1C);
                model.vertexCount = (ushort)BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x24);
                ushort texCount = BAToUInt16(sceneBlock, (x * sceneElemSize) + 0x28);
                model.modelID = BAToShort(sceneBlock, (x * sceneElemSize) + 0x30);

                uint   texElemSize = 0x10;
                byte[] texBlock    = ReadBlock(fs, texPointer, texCount * texElemSize);
                model.textureConfig = new List <RatchetTexture_Model>();
                model.faceCount     = 0;
                for (uint t = 0; t < texCount; t++)
                {
                    RatchetTexture_Model dlt = new RatchetTexture_Model();
                    dlt.ID    = BAToUInt32(texBlock, (t * texElemSize) + 0x00);
                    dlt.start = BAToUInt32(texBlock, (t * texElemSize) + 0x04);
                    dlt.size  = BAToUInt32(texBlock, (t * texElemSize) + 0x08);
                    model.textureConfig.Add(dlt);
                    model.faceCount += dlt.size;
                }

                //Flip endianness of vertex array float[vert_x, vert_y, vert_z, norm_x, norm_y, norm_z, uv_u, uv_v, reserved reserved]
                uint   vertElemSize = 0x18;
                uint   vertBuffSize = model.vertexCount * vertElemSize;
                byte[] vertBlock    = ReadBlock(fs, vertPointer, vertBuffSize);

                uint   UVElemsize = 0x08;
                uint   UVBuffSize = model.vertexCount * UVElemsize;
                byte[] UVBlock    = ReadBlock(fs, UVPointer, UVBuffSize);


                model.vertBuff = new List <float>();
                for (uint i = 0; i < model.vertexCount; i++)
                {
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x00)); //vertx
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x04)); //verty
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x08)); //vertz
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x0C)); //normx
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x10)); //normy
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x14)); //normz

                    model.vertBuff.Add(BAToFloat(UVBlock, (i * UVElemsize) + 0x00));     //UVu
                    model.vertBuff.Add(BAToFloat(UVBlock, (i * UVElemsize) + 0x04));     //UVv
                }

                //Flip endianness of index array
                byte[] indiceBuff = ReadBlock(fs, indicePointer, model.faceCount * sizeof(ushort));
                model.indiceBuff = new List <ushort>();
                for (uint i = 0; i < model.faceCount; i++)
                {
                    model.indiceBuff.Add(BAToUInt16(indiceBuff, i * sizeof(ushort)));
                }

                DataStore.sceneryModels.Add(model);
                //Console.WriteLine("Scenery Model Added: 0x" + model.modelID.ToString("X4"));
            }
            #endregion

            //Load Terrain
            #region Terrain
            {
                uint terrainElemSize = 0x30;
                uint texElemSize     = 0x10;
                uint vertElemSize    = 0x1c;
                uint UVElemSize      = 0x08;
                uint ColorElemSize   = 0x04;

                RatchetModel_Terrain model = new RatchetModel_Terrain();
                model.offset    = terrainPointer;
                model.modelID   = 1111;
                model.modelType = ModelType.Terrain;
                byte[] terrainHeadBlock = ReadBlock(fs, terrainPointer, 0x60);

                uint   headPointer = BAToUInt32(terrainHeadBlock, 0x0);
                ushort headCount   = BAToUInt16(terrainHeadBlock, 0x06);

                byte[] terrainBlock = ReadBlock(fs, headPointer, headCount * terrainElemSize);
                model.textureConfig = new List <RatchetTexture_Model>();
                model.vertBuff      = new List <float>();
                model.indiceBuff    = new List <uint>();
                uint vertCount         = 0;
                uint prevVertCount     = 0;
                uint prevFaceCount     = 0;
                uint prevHeadCount     = 0;
                uint prevPrevFaceCount = 0;

                for (uint i = 0; i < 4; i++)    //I have yet to see any level have more than two of these, but the header theoretically has space for 4
                {
                    uint vertPointer   = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x08);
                    uint colPointer    = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x18);
                    uint UVPointer     = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x28);
                    uint indicePointer = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x38);

                    prevFaceCount = 0;
                    if (vertPointer != 0 && UVPointer != 0 && indicePointer != 0)    //Check that there's data at the pointers
                    {
                        //Loop throught the heads, and stop when the overflow counter increases
                        for (uint ii = prevHeadCount; ii < headCount && i == BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x22); ii++)
                        {
                            uint   localFaceCount = 0;
                            uint   texPointer     = BAToUInt32(terrainBlock, (ii * terrainElemSize) + 0x10);
                            uint   texCount       = BAToUInt32(terrainBlock, (ii * terrainElemSize) + 0x14);
                            ushort vertStart      = BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x18);
                            ushort headVertCount  = BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x1A);
                            vertCount += headVertCount;

                            byte[] texBlock = ReadBlock(fs, texPointer, texElemSize * texCount);
                            for (uint iii = 0; iii < texCount; iii++)
                            {
                                RatchetTexture_Model tex = new RatchetTexture_Model();
                                tex.ID          = BAToUInt32(texBlock, (iii * texElemSize) + 0x00);
                                tex.start       = BAToUInt32(texBlock, (iii * texElemSize) + 0x04) + prevPrevFaceCount;
                                tex.size        = BAToUInt32(texBlock, (iii * texElemSize) + 0x08) + prevPrevFaceCount;
                                localFaceCount += BAToUInt32(texBlock, (iii * texElemSize) + 0x08);
                                model.textureConfig.Add(tex);
                            }


                            byte[] vertBlock = ReadBlock(fs, vertPointer + vertStart * vertElemSize, headVertCount * vertElemSize);
                            byte[] colBlock  = ReadBlock(fs, colPointer + vertStart * ColorElemSize, headVertCount * ColorElemSize);
                            byte[] UVBlock   = ReadBlock(fs, UVPointer + vertStart * UVElemSize, headVertCount * UVElemSize);

                            for (uint iii = 0; iii < headVertCount; iii++)
                            {
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x00)); //vertx
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x04)); //verty
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x08)); //vertz
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x0C)); //normx
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x10)); //normy
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x14)); //normz

                                model.vertBuff.Add(BAToFloat(UVBlock, (iii * UVElemSize) + 0x00));     //UVu
                                model.vertBuff.Add(BAToFloat(UVBlock, (iii * UVElemSize) + 0x04));     //UVv


                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x00] / 255f);    //color r
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x01] / 255f);    //color g
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x02] / 255f);    //color b
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x03] / 255f);    //color a
                            }

                            byte[] indiceBuff = ReadBlock(fs, indicePointer + prevFaceCount * sizeof(ushort), localFaceCount * sizeof(ushort));
                            for (uint iii = 0; iii < localFaceCount; iii++)
                            {
                                model.indiceBuff.Add(BAToUInt16(indiceBuff, iii * sizeof(ushort)) + prevVertCount);
                            }
                            prevFaceCount += localFaceCount;
                            prevHeadCount  = ii + 1;
                        }
                        prevVertCount     = vertCount;
                        prevPrevFaceCount = prevFaceCount;
                    }
                }
                model.vertexCount      = vertCount;
                model.faceCount        = prevFaceCount;
                DataStore.terrainModel = model;
            }
            #endregion

            #region Chunks
            List <int> chunkIds = new List <int>();
            for (int chunkIndex = 0; chunkIndex < 5; chunkIndex++)
            {
                if (File.Exists(path + "/chunk" + chunkIndex + ".ps3"))
                {
                    chunkIds.Add(chunkIndex);
                }
            }

            foreach (int chunkId in chunkIds)
            {
                FileStream cfs = File.OpenRead(path + "/chunk" + chunkId + ".ps3");
                Console.WriteLine("Loading chunk " + chunkId);
                uint terrainElemSize = 0x30;
                uint texElemSize     = 0x10;
                uint vertElemSize    = 0x1c;
                uint UVElemSize      = 0x08;
                uint ColorElemSize   = 0x04;

                RatchetModel_Terrain model = new RatchetModel_Terrain();
                model.offset    = 0x10;
                model.modelID   = 1111;
                model.modelType = ModelType.Terrain;
                byte[] terrainHeadBlock = ReadBlock(cfs, 0x10, 0x60);

                uint   headPointer = BAToUInt32(terrainHeadBlock, 0x0);
                ushort headCount   = BAToUInt16(terrainHeadBlock, 0x06);

                byte[] terrainBlock = ReadBlock(cfs, headPointer, headCount * terrainElemSize);

                model.textureConfig = new List <RatchetTexture_Model>();
                model.vertBuff      = new List <float>();
                model.indiceBuff    = new List <uint>();
                uint vertCount         = 0;
                uint prevVertCount     = 0;
                uint prevFaceCount     = 0;
                uint prevHeadCount     = 0;
                uint prevPrevFaceCount = 0;

                for (uint i = 0; i < 4; i++)   //I have yet to see any level have more than two of these, but the header theoretically has space for 4
                {
                    uint vertPointer   = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x08);
                    uint colPointer    = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x18);
                    uint UVPointer     = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x28);
                    uint indicePointer = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x38);

                    prevFaceCount = 0;
                    if (vertPointer != 0 && UVPointer != 0 && indicePointer != 0)    //Check that there's data at the pointers
                    {
                        //Loop throught the heads, and stop when the overflow counter increases
                        for (uint ii = prevHeadCount; ii < headCount && i == BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x22); ii++)
                        {
                            uint   localFaceCount = 0;
                            uint   texPointer     = BAToUInt32(terrainBlock, (ii * terrainElemSize) + 0x10);
                            uint   texCount       = BAToUInt32(terrainBlock, (ii * terrainElemSize) + 0x14);
                            ushort vertStart      = BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x18);
                            ushort headVertCount  = BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x1A);
                            vertCount += headVertCount;

                            byte[] texBlock = ReadBlock(cfs, texPointer, texElemSize * texCount);
                            for (uint iii = 0; iii < texCount; iii++)
                            {
                                RatchetTexture_Model tex = new RatchetTexture_Model();
                                tex.ID    = BAToUInt32(texBlock, (iii * texElemSize) + 0x00);
                                tex.start = BAToUInt32(texBlock, (iii * texElemSize) + 0x04) + prevPrevFaceCount;
                                tex.size  = BAToUInt32(texBlock, (iii * texElemSize) + 0x08) + prevPrevFaceCount;

                                localFaceCount += BAToUInt32(texBlock, (iii * texElemSize) + 0x08);

                                model.textureConfig.Add(tex);
                            }


                            byte[] vertBlock = ReadBlock(cfs, vertPointer + vertStart * vertElemSize, headVertCount * vertElemSize);
                            byte[] colBlock  = ReadBlock(cfs, colPointer + vertStart * ColorElemSize, headVertCount * ColorElemSize);
                            byte[] UVBlock   = ReadBlock(cfs, UVPointer + vertStart * UVElemSize, headVertCount * UVElemSize);

                            for (uint iii = 0; iii < headVertCount; iii++)
                            {
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x00)); //vertx
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x04)); //verty
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x08)); //vertz
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x0C)); //normx
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x10)); //normy
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x14)); //normz

                                model.vertBuff.Add(BAToFloat(UVBlock, (iii * UVElemSize) + 0x00));     //UVu
                                model.vertBuff.Add(BAToFloat(UVBlock, (iii * UVElemSize) + 0x04));     //UVv


                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x00] / 255f);    //color r
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x01] / 255f);    //color g
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x02] / 255f);    //color b
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x03] / 255f);    //color a
                            }



                            byte[] indiceBuff = ReadBlock(cfs, indicePointer + prevFaceCount * sizeof(ushort), localFaceCount * sizeof(ushort));
                            //Console.WriteLine(localFaceCount.ToString("X8"));
                            for (uint iii = 0; iii < localFaceCount; iii++)
                            {
                                model.indiceBuff.Add(BAToUInt16(indiceBuff, iii * sizeof(ushort)) + prevVertCount);
                            }

                            prevFaceCount += localFaceCount;
                            prevHeadCount  = ii + 1;
                        }
                        prevVertCount     = vertCount;
                        prevPrevFaceCount = prevFaceCount;
                    }
                }
                model.vertexCount = vertCount;
                model.faceCount   = prevFaceCount;
                DataStore.chunks.Add(model);
            }
            #endregion


            //Load Level Model Placement
            byte[] levelObjectBlock = ReadBlock(fs, levelModelsPlacementPointer, levelObjectsCount * 0x70);
            DataStore.levelObjects = new List <LevelObject>();
            for (uint i = 0; i < levelObjectsCount; i++)
            {
                LevelObject levObj = new LevelObject(levelObjectBlock, i);
                DataStore.levelObjects.Add(levObj);
            }

            //Load Scenery Model Placement
            byte[] sceneryObjectBlock = ReadBlock(fs, sceneryModelsPlacementPointer, sceneryObjectsCount * 0x70);
            DataStore.sceneryObjects = new List <LevelObject>();
            for (uint i = 0; i < sceneryObjectsCount; i++)
            {
                LevelObject levObj = new LevelObject(sceneryObjectBlock, i);
                DataStore.sceneryObjects.Add(levObj);
            }

            /*
             * //Load Level Model Placement
             #region Level Model Placement
             * for (int x = 0; x < UYALevelObjectsCount; x++)
             * {
             *  UYALevelObjectConfig levelObject = new UYALevelObjectConfig();
             *  byte[] objectBlock = ReadBlock(fs, levelModelsPlacementPointer + (uint)(0x70 * x), 0x70);
             *
             *  levelObject.v1 = BAToQuaternion(objectBlock, 0x00);
             *  levelObject.v2 = BAToQuaternion(objectBlock, 0x10);
             *  levelObject.v3 = BAToQuaternion(objectBlock, 0x20);
             *  levelObject.off = BAToQuaternion(objectBlock, 0x30);
             *  levelObject.size = BAToFloat(objectBlock, 0x3C);
             *  levelObject.off_40 = BAToUInt32(objectBlock, 0x40);
             *  levelObject.off_44 = BAToUInt32(objectBlock, 0x44);
             *  levelObject.off_48 = BAToUInt32(objectBlock, 0x48);
             *  levelObject.off_4C = BAToUInt32(objectBlock, 0x4C);
             *  levelObject.ID = (ushort)BAToShort(objectBlock, 0x52);
             *  levelObject.off_54 = BAToUInt32(objectBlock, 0x54);
             *  levelObject.off_58 = BAToUInt32(objectBlock, 0x58);
             *  levelObject.off_5C = BAToUInt32(objectBlock, 0x5C);
             *  levelObject.ptr_60 = BAToUInt32(objectBlock, 0x60);
             *  levelObject.off_64 = BAToUInt32(objectBlock, 0x64);
             *  levelObject.off_68 = BAToUInt32(objectBlock, 0x68);
             *  levelObject.off_6C = BAToUInt32(objectBlock, 0x6C);
             *  if (x + 1 < UYALevelObjectsCount)
             *      levelObject.unknown_data_block = ReadBlock(fs, levelObject.ptr_60, (BAToUInt32(ReadBlock(fs, levelModelsPlacementPointer + (uint)(0x70 * (x + 1)) + 0x60, 4), 0x00) - levelObject.ptr_60));
             *  else
             *      levelObject.unknown_data_block = ReadBlock(fs, levelObject.ptr_60, FindNextLargest(engineHeader, 0x24) - levelObject.ptr_60);
             *  UYALevelObjects.Add(levelObject);
             * }
             #endregion
             *
             * //Load Scenery Models Placement
             #region Scenery Model Placement
             * for (int x = 0; x < UYASceneryObjectsCount; x++)
             * {
             *  UYASceneryObjectConfig sceneryObject = new UYASceneryObjectConfig();
             *  byte[] objectBlock = ReadBlock(fs, sceneryModelsPlacementPointer + (uint)(0x70 * x), 0x70);
             *
             *  sceneryObject.v1 = BAToQuaternion(objectBlock, 0x00);
             *  sceneryObject.v2 = BAToQuaternion(objectBlock, 0x10);
             *  sceneryObject.v3 = BAToQuaternion(objectBlock, 0x20);
             *  sceneryObject.off = BAToQuaternion(objectBlock, 0x30);
             *  sceneryObject.size = BAToFloat(objectBlock, 0x3C);
             *  sceneryObject.off_40 = BAToUInt32(objectBlock, 0x40);
             *  sceneryObject.off_44 = BAToUInt32(objectBlock, 0x44);
             *  sceneryObject.off_48 = BAToUInt32(objectBlock, 0x48);
             *  sceneryObject.off_4C = BAToUInt32(objectBlock, 0x4C);
             *  sceneryObject.ID = (ushort)BAToShort(objectBlock, 0x52);
             *  sceneryObject.off_54 = BAToUInt32(objectBlock, 0x54);
             *  sceneryObject.off_54 = BAToUInt32(objectBlock, 0x58);
             *  sceneryObject.off_54 = BAToUInt32(objectBlock, 0x5C);
             *  sceneryObject.off_60 = BAToUInt32(objectBlock, 0x60);
             *  sceneryObject.off_64 = BAToUInt32(objectBlock, 0x64);
             *  sceneryObject.off_64 = BAToUInt32(objectBlock, 0x68);
             *  sceneryObject.off_64 = BAToUInt32(objectBlock, 0x6C);
             *
             *  UYASceneryObjects.Add(sceneryObject);
             * }
             #endregion
             */
            //Load Textures
            #region Textures
            RatchetTexture_General texture = new RatchetTexture_General();
            for (int x = 0; x < textureCount; x++)
            {
                texture.texHeader = ReadBlock(fs, texturesPointer + (uint)(0x24 * x), 0x24);
                uint nextTexturePointer    = x < textureCount - 1 ? ReadUInt32(ReadBlock(fs, texturesPointer + (uint)(0x24 * (x + 1)), 0x4), 0) : vfs != null ? (uint)vfs.Length : 0;
                uint currentTexturePointer = ReadUInt32(texture.texHeader, 0);
                //Console.WriteLine("Parsing texture " + x + " " + currentTexturePointer.ToString("X") + " " + nextTexturePointer.ToString("X"));
                texture.ID      = x;
                texture.width   = BAToShort(texture.texHeader, 0x18);
                texture.height  = BAToShort(texture.texHeader, 0x1A);
                texture.texData = vfs != null?ReadBlock(vfs, currentTexturePointer, nextTexturePointer - currentTexturePointer) : null;

                texture.reverseRGB = false;
                DataStore.textures.Add(texture);
                //Console.WriteLine("Texture : " + x + " Width: " + texture.width + " Height: " + texture.height);
            }
            #endregion

            //TODO: textureConfig - Menus

            //TODO: textureConfig - 2D GFX

            //TODO: Sprites


            //Load the remaining unknown or unhandled data
            #region Remaining Data

            DataStore.mapRenderDefintions = getSection(fs, 0x04);
            DataStore.Ptr_08             = getSection(fs, 0x08);
            DataStore.Ptr_0C             = getSection(fs, 0x0C);
            DataStore.skyBox             = getSection(fs, 0x14);
            DataStore.collisionMap       = getSection(fs, 0x18);
            DataStore.Ptr_44             = getSection(fs, 0x44);
            DataStore.soundsConfig       = getSection(fs, 0x54);
            DataStore.Ptr_4C             = getSection(fs, 0x4C);
            DataStore.Ptr_50             = getSection(fs, 0x50);
            DataStore.lighting           = getSection(fs, 0x68);
            DataStore.lightingConfig     = getSection(fs, 0x6C);
            DataStore.textureConfigMenu  = getSection(fs, 0x74);
            DataStore.textureConfig2DGFX = getSection(fs, 0x7C);
            DataStore.spriteDef          = getSection(fs, 0x80);

            #endregion

            #region raw Data //need to properly handle these eventually
            DataStore.terrainModel.rawData = getSection(fs, 0x48);
            //rawLevelModelBlock = getSection(fs, 0x1C);
            //rawSceneryModelBlock = getSection(fs, 0x2C);
            #endregion

            #region Missions
            MissionParser.parseMissions(path);
            #endregion

            fs.Close();
            gpf.Close();


            Console.WriteLine("Engine data loaded with new engine parser for DL.");
        }
Esempio n. 6
0
        public static void parseMissions(string path)
        {
            List <int> missionIds = new List <int>();

            //Because its unlikely there will be more than 50 missions in a map
            //We use a list because some missions might be missing/cut so we cant simply break the loop
            for (int fileIndex = 0; fileIndex < 50; fileIndex++)
            {
                if (File.Exists(path + "/gameplay_mission_classes[" + fileIndex + "].ps3"))
                {
                    missionIds.Add(fileIndex);
                }
            }


            foreach (int missionIndex in missionIds)
            {
                RatchetMission mission = new RatchetMission();
                FileStream     fs      = File.OpenRead(path + "/gameplay_mission_classes[" + missionIndex + "].ps3");
                FileStream     vfs     = File.OpenRead(path + "/gameplay_mission_classes[" + missionIndex + "].vram");
                Console.WriteLine("Loading mission " + missionIndex);

                byte[] header          = ReadBlock(fs, 0, 0x0c);
                uint   spawnablesCount = BAToUInt32(ReadBlock(fs, 0x00, 4), 0);

                byte[] idBlock = ReadBlock(fs, 0x10, spawnablesCount * 8);

                #region Spawnables
                mission.spawnableModels = new List <RatchetModel_General>();
                for (int x = 0; x < spawnablesCount; x++)
                {
                    RatchetModel_General model = new RatchetModel_General();
                    model.modelType = ModelType.Spawnable;

                    model.modelID = BAToShort(idBlock, (uint)(x * 8) + 2);
                    model.offset  = BAToUInt32(idBlock, (uint)(x * 8) + 4);

                    if (model.offset != 0)
                    {
                        uint modelHeadSize = BAToUInt32(ReadBlock(fs, model.offset, 4), 0);

                        if (modelHeadSize > 0)
                        {
                            byte[] headBlock = ReadBlock(fs, model.offset, modelHeadSize + 0x20); //Head + objectDetails
                            uint   objectPtr = BAToUInt32(headBlock, 0);
                            model.animationsCount = headBlock[0x0C];
                            //(0x04)null
                            //(0x08)[count for 0x14 and 0x18][unknown][unknown][unknown]
                            //(0x0c)[animation count][unknown][unknown][unknown]
                            //(0x10)Pointer to list
                            //(0x14)Pointer to skeleton joints (0x40 structure)
                            //(0x18)Pointer to skeleton somethings (0x16 structure)
                            //(0x1C)Pointer to left arm animations (Ratchet)
                            //(0x20)null
                            model.size = BAToFloat(headBlock, 0x24);
                            uint texCount          = BAToUInt32(headBlock, objectPtr + 0x00);
                            uint otherCount        = BAToUInt32(headBlock, objectPtr + 0x04);
                            uint texBlockPointer   = BAToUInt32(headBlock, objectPtr + 0x08);
                            uint otherBlockPointer = BAToUInt32(headBlock, objectPtr + 0x0C);
                            uint vertPointer       = BAToUInt32(headBlock, objectPtr + 0x10);
                            uint indexPointer      = BAToUInt32(headBlock, objectPtr + 0x14);
                            model.vertexCount = BAToUInt16(headBlock, objectPtr + 0x18);
                            //(0x1A)count
                            //(0x1C)count
                            //(0x1E)null


                            //model.rawData = getModelDataRaw(model.modelType, model.modelID, path + "/" + fileName);

                            model.animPointer = new List <uint>();
                            for (uint i = 0; i < model.animationsCount; i++)
                            {
                                model.animPointer.Add(BAToUInt32(headBlock, (i * sizeof(uint)) + 0x48));
                            }

                            uint   texElemSize = 0x10;
                            byte[] texBlock    = ReadBlock(fs, model.offset + texBlockPointer, texCount * texElemSize);
                            model.textureConfig = new List <RatchetTexture_Model>();
                            model.faceCount     = 0;
                            for (uint t = 0; t < texCount; t++)
                            {
                                RatchetTexture_Model modTex = new RatchetTexture_Model();
                                modTex.ID    = BAToUInt32(texBlock, (t * texElemSize) + 0x0);
                                modTex.start = BAToUInt32(texBlock, (t * texElemSize) + 0x04);
                                modTex.size  = BAToUInt32(texBlock, (t * texElemSize) + 0x08);
                                model.textureConfig.Add(modTex);
                                model.faceCount += modTex.size;
                            }


                            //Flip endianness of vertex array float[vert_x, vert_y, vert_z, norm_x, norm_y, norm_z, uv_u, uv_v, reserved reserved]
                            uint   vertElemSize = 0x28;
                            uint   vertBuffSize = model.vertexCount * vertElemSize;
                            byte[] vertBlock    = ReadBlock(fs, model.offset + vertPointer, vertBuffSize);
                            model.vertBuff = new List <float>();
                            for (uint i = 0; i < model.vertexCount; i++)
                            {
                                model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x00));    //Vertx
                                model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x04));    //Verty
                                model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x08));    //Vertz
                                model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x0C));    //Nomrx
                                model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x10));    //Normy
                                model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x14));    //Normz
                                model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x18));    //UVu
                                model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x1C));    //UVv
                            }

                            //Flip endianness of index array
                            byte[] indiceBuff = ReadBlock(fs, model.offset + indexPointer, model.faceCount * sizeof(ushort));
                            model.indiceBuff = new List <ushort>();
                            for (uint i = 0; i < model.faceCount; i++)
                            {
                                model.indiceBuff.Add(BAToUInt16(indiceBuff, i * sizeof(ushort)));
                            }
                        }
                    }
                    mission.spawnableModels.Add(model);
                }
                #endregion

                #region Textures
                int  textureCount    = (int)BAToUInt32(ReadBlock(fs, 0x04, 4), 0);
                uint texturesPointer = BAToUInt32(ReadBlock(fs, 0x08, 4), 0);
                mission.textures = new List <RatchetTexture_General>();
                RatchetTexture_General texture = new RatchetTexture_General();
                for (int x = 0; x < textureCount; x++)
                {
                    texture.texHeader = ReadBlock(fs, texturesPointer + (uint)(0x24 * x), 0x24);
                    uint nextTexturePointer    = x < textureCount - 1 ? ReadUInt32(ReadBlock(fs, texturesPointer + (uint)(0x24 * (x + 1)), 0x4), 0) : vfs != null ? (uint)vfs.Length : 0;
                    uint currentTexturePointer = ReadUInt32(texture.texHeader, 0);
                    texture.ID      = x;
                    texture.width   = BAToShort(texture.texHeader, 0x18);
                    texture.height  = BAToShort(texture.texHeader, 0x1A);
                    texture.texData = vfs != null?ReadBlock(vfs, currentTexturePointer, nextTexturePointer - currentTexturePointer) : null;

                    texture.reverseRGB = false;
                    mission.textures.Add(texture);
                }
                #endregion
                DataStore.missions.Add(mission);
                fs.Close();
            }
        }
Esempio n. 7
0
    public static void parseMoby(string path, string fileName)
    {
        FileStream fs = File.OpenRead(path + "/" + fileName);

        Console.WriteLine("Loading file " + path + "/" + fileName);

        #region Moby Textures
        uint texturePointer     = BAToUInt32(ReadBlock(fs, 0x08, 4), 0);
        uint textureDataPointer = BAToUInt32(ReadBlock(fs, 0x0C, 4), 0);
        uint textureCount       = BAToUInt32(ReadBlock(fs, 0x04, 4), 0);

        MemoryStream vfs = new MemoryStream(ReadBlock(fs, textureDataPointer, (uint)fs.Length - textureDataPointer));

        Console.WriteLine("Texture Count: " + textureCount);

        for (int x = 0; x < textureCount; x++)
        {
            RatchetTexture_General texture = new RatchetTexture_General();
            texture.texHeader = ReadBlock(fs, texturePointer + (uint)(0x24 * x), 0x24);
            uint nextTexturePointer    = x < textureCount - 1 ? ReadUInt32(ReadBlock(fs, texturePointer + (uint)(0x24 * (x + 1)), 0x4), 0) : vfs != null ? (uint)vfs.Length : 0;
            uint currentTexturePointer = ReadUInt32(texture.texHeader, 0);
            //Console.WriteLine("Parsing texture " + x + " " + currentTexturePointer.ToString("X") + " " + nextTexturePointer.ToString("X"));
            texture.ID      = x;
            texture.width   = BAToShort(texture.texHeader, 0x18);
            texture.height  = BAToShort(texture.texHeader, 0x1A);
            texture.texData = vfs != null?ReadBlock(vfs, currentTexturePointer, nextTexturePointer - currentTexturePointer) : null;

            texture.reverseRGB = false;
            DataStore.textures.Add(texture);
        }
        #endregion

        #region Moby Model
        uint mobyCount = BAToUInt32(ReadBlock(fs, 0x00, 4), 0);

        byte[] pointerBlock = ReadBlock(fs, 0x10, (mobyCount * 0x0C));

        //Used for mapping textures to models
        int modelIndex = 0;

        for (int x = 0; x < mobyCount; x++)
        {
            RatchetModel_General model = new RatchetModel_General();
            model.modelID = (short)BAToUInt32(pointerBlock, (uint)(x * 0x0C) + 0x04);
            Console.WriteLine("Model ID: " + model.modelID.ToString("X"));
            model.offset = BAToUInt32(pointerBlock, (uint)(x * 0x0C));
            // Console.WriteLine("Model: " + model.modelID.ToString("X4") + " Offset: " + model.offset.ToString("X"));

            if (model.offset != 0)
            {
                uint modelHeadSize = BAToUInt32(ReadBlock(fs, model.offset, 4), 0);
                if (modelHeadSize > 0)
                {
                    byte[] headBlock = ReadBlock(fs, model.offset, modelHeadSize + 0x20); //Head + objectDetails
                    uint   objectPtr = BAToUInt32(headBlock, 0);
                    model.animationsCount = headBlock[0x0C];

                    model.size = BAToFloat(headBlock, 0x24);
                    uint texCount          = BAToUInt32(headBlock, objectPtr + 0x00);
                    uint otherCount        = BAToUInt32(headBlock, objectPtr + 0x04);
                    uint texBlockPointer   = BAToUInt32(headBlock, objectPtr + 0x08);
                    uint otherBlockPointer = BAToUInt32(headBlock, objectPtr + 0x0C);
                    uint vertPointer       = BAToUInt32(headBlock, objectPtr + 0x10);
                    uint indexPointer      = BAToUInt32(headBlock, objectPtr + 0x14);
                    model.vertexCount = BAToUInt16(headBlock, objectPtr + 0x18);
                    //(0x1A)count
                    //(0x1C)count
                    //(0x1E)null

                    model.modelType = ModelType.Spawnable;
                    //model.rawData = getModelDataRaw(model.modelType, model.modelID, path + "/" + fileName);

                    model.animPointer = new List <uint>();
                    for (uint i = 0; i < model.animationsCount; i++)
                    {
                        model.animPointer.Add(BAToUInt32(headBlock, (i * sizeof(uint)) + 0x48));
                    }

                    uint   texElemSize = 0x10;
                    byte[] texBlock    = ReadBlock(fs, model.offset + texBlockPointer, texCount * texElemSize);
                    model.textureConfig = new List <RatchetTexture_Model>();
                    model.faceCount     = 0;
                    for (uint t = 0; t < texCount; t++)
                    {
                        RatchetTexture_Model modTex = new RatchetTexture_Model();
                        modTex.ID    = (uint)BAToUInt32(texBlock, (t * texElemSize) + 0x0);
                        modTex.start = BAToUInt32(texBlock, (t * texElemSize) + 0x04);
                        modTex.size  = BAToUInt32(texBlock, (t * texElemSize) + 0x08);
                        model.textureConfig.Add(modTex);
                        model.faceCount += modTex.size;
                    }


                    //Flip endianness of vertex array float[vert_x, vert_y, vert_z, norm_x, norm_y, norm_z, uv_u, uv_v, reserved reserved]
                    uint   vertElemSize = 0x28;
                    uint   vertBuffSize = model.vertexCount * vertElemSize;
                    byte[] vertBlock    = ReadBlock(fs, model.offset + vertPointer, vertBuffSize);
                    model.vertBuff = new List <float>();
                    for (uint i = 0; i < model.vertexCount; i++)
                    {
                        model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x00));    //Vertx
                        model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x04));    //Verty
                        model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x08));    //Vertz
                        model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x0C));    //Nomrx
                        model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x10));    //Normy
                        model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x14));    //Normz
                        model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x18));    //UVu
                        model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x1C));    //UVv
                    }
                    if (model.vertBuff != null)
                    {
                        modelIndex++;
                    }
                    //Flip endianness of index array
                    byte[] indiceBuff = ReadBlock(fs, model.offset + indexPointer, model.faceCount * sizeof(ushort));
                    model.indiceBuff = new List <ushort>();
                    for (uint i = 0; i < model.faceCount; i++)
                    {
                        model.indiceBuff.Add(BAToUInt16(indiceBuff, i * sizeof(ushort)));
                    }
                }
            }
            DataStore.spawnableModels.Add(model);
        }
        #endregion
    }