예제 #1
0
        public static void ParseUVTRs(byte[] romBytes)
        {
            //Directory.CreateDirectory(outputDir + "Converted");
            //string fullOutputPath = outputDir + "Converted/UVTR/";
            //Directory.CreateDirectory(fullOutputPath);

            // ok this is dumb i need to fix this
            Filesystem.Filesystem filesystem = new Filesystem.Filesystem(romBytes);

            foreach (Filesystem.Filesystem.File file in filesystem.AllFiles.Where(file => file.fileTypeFromFileHeader == "UVTR"))
            {
                PowerByteArray data = new PowerByteArray(file.Section("COMM"));

                UVTR uvtr = new UVTR();
                uvtr.h_6float = data.NextSubArray(24).AsFloats();
                uvtr.h_b1     = data.NextU8();
                uvtr.h_b2     = data.NextU8();
                uvtr.h_f1     = data.NextFloat();
                uvtr.h_f2     = data.NextFloat();
                uvtr.h_f3     = data.NextFloat();

                using (ThreeDDisplayWindow window = new ThreeDDisplayWindow())
                {
                    Console.WriteLine(uvtr.h_b1 * uvtr.h_b2);
                    uvtr.pB1xB2Mem = new UVTR140Struct[uvtr.h_b1 * uvtr.h_b2];
                    for (int i = 0; i < uvtr.pB1xB2Mem.Length; i++)
                    {
                        UVTR140Struct oneFourty = new UVTR140Struct();
                        if (data.NextU8() == 0)
                        {
                            continue;
                        }
                        oneFourty.m1 = new Matrix(data.NextSubArray(64).AsFloats());
                        byte unkByte = data.NextU8();

                        // m2 = identity matrix
                        oneFourty.m2 = new Matrix(new float[] { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 });

                        // Copy translation from m1 to m2
                        oneFourty.m2[12] = oneFourty.m1[12];
                        oneFourty.m2[13] = oneFourty.m1[13];
                        oneFourty.m2[14] = oneFourty.m1[14];

                        /* FUN_801360cc(m2, m2) */
                        Console.WriteLine(oneFourty.m1);
                        oneFourty.uvctFileIndex = data.NextU16();
                        var uvct = filesystem.GetFile("UVCT", oneFourty.uvctFileIndex);
                        Console.WriteLine($"{uvct.formLocationInROM:x6}");
                        var uvctFile = new UVCTFile(new PowerByteArray(uvct.Section("COMM")), filesystem);
                        uvctFile.AddToWindow(window, oneFourty.m1);


                        /* oneFourty.pUVCT = processed filesystem.GetFile("UVCT", oneFourty.uvctFileIndex); */

                        /* if uvct does not exist, set oneFourty.unkFloat to 0 and move to next loop*/

                        /* at this point some stuff happens with the UVCT, idk what exactly */

                        uvtr.pB1xB2Mem[i] = oneFourty;
                    }

                    window.Run();
                }

                uvtr.ushort1       = data.NextU16();
                uvtr.uvrwFileIndex = data.NextU16();

                /*
                 * if (DAT_8002d1a8 == 0) {
                 *  uvtrObj->ushort1 = 0;
                 *  uVar1 = uvtrObj->ushort1;
                 * }
                 * else {
                 *  uVar1 = uvtrObj->ushort1;
                 * }
                 */

                if (uvtr.ushort1 != 0)
                {
                    /* Load UVRW COMM section */

                    uvtr.unk4Bytes = data.NextU32();

                    data.NextU16();
                    data.NextU16();
                    data.NextU16();

                    /* a whole bunch of nonsense */

                    /* includes reading a few more shorts (maybe) */
                }
            }
        }
예제 #2
0
        public UVMDFile(PowerByteArray fileBytes, Filesystem.Filesystem filesystem)
        {
            Console.WriteLine("NEW UVMD");

            {
                lodCount    = fileBytes.NextU8();
                partsPerLOD = fileBytes.NextU8();
                b3          = fileBytes.NextU8();
                byte alwaysZero = fileBytes.NextU8();
                if (alwaysZero != 0)
                {
                    throw new Exception();
                }

                vertexCount = fileBytes.NextU16();
                // These are here for memory allocation, but we don't care!
                ushort totalMaterials = fileBytes.NextU16(); //24 structs
                ushort totalCommands  = fileBytes.NextU16();

                if ((b3 & 0x80) != 0)
                {
                    // appears to be 10 floats, 3 signed shorts, 1 byte
                    // TODO
                    UnknownOptionalHeaderData unknownOptionalData = new UnknownOptionalHeaderData(fileBytes.NextSubArray(0x2F));
                }

                float1 = fileBytes.NextFloat();
                float2 = fileBytes.NextFloat();
                float3 = fileBytes.NextFloat();
            }

            // Lets allocate all memory here since this is where it happens anyway
            // 36 bytes: already done, that's the response struct

            // b1 * 12: subsections
            pLODs = new LOD[lodCount];

            // b2 * 64: matrices
            pMatrices = new Matrix[partsPerLOD];

            // b1 * b2 * 44: parts
            // this is initialized in the loop

            // short1 * 16
            // this is initialized in the loop

            // short2 * 24
            // this is initialized in the loop

            // short3 * 8
            // this is initialized in the loop

            ////////////////////////////////

            // Overall structure here is correct, but the processing is not implemented yet



            for (int i = 0; i < lodCount; i++)
            {
                Console.WriteLine("  LOD " + i);
                LOD lodInfo;

                lodInfo.partCount = fileBytes.NextU8();
                lodInfo.b2        = fileBytes.NextU8();
                lodInfo.f         = fileBytes.NextFloat();
                lodInfo.f         = lodInfo.f * lodInfo.f;

                lodInfo.pModelParts = new ModelPart[lodInfo.partCount];

                for (int j = 0; j < lodInfo.partCount; j++)
                {
                    Console.WriteLine("    PART " + j);

                    ModelPart modelPart;

                    modelPart.b5        = fileBytes.NextU8();
                    modelPart.b6        = fileBytes.NextU8();
                    modelPart.b7        = fileBytes.NextU8();
                    modelPart.sixFloats = fileBytes.NextSubArray(24).AsFloats();

                    modelPart.sixFloats = modelPart.sixFloats.Select(fl => fl * float2).ToArray();

                    byte stackByte1 = fileBytes.NextU8();
                    byte stackByte2 = fileBytes.NextU8();
                    modelPart.materialCount = fileBytes.NextU8();

                    modelPart.pMaterials = new Material[modelPart.materialCount];

                    byte firstWordEverHadHighBitSet = 0;

                    for (int k = 0; k < modelPart.materialCount; k++)
                    {
                        Console.WriteLine("      MATERIAL " + k);

                        Material material = new Material();

                        material.unk4 = fileBytes.NextU32();
                        float unk2 = fileBytes.NextFloat();
                        float unk3 = fileBytes.NextFloat();
                        float unk4 = fileBytes.NextFloat();
                        material.vertCount = fileBytes.NextU16();
                        material.unksh18   = fileBytes.NextU16();
                        material.unksh16   = fileBytes.NextU16();
                        material.unksh20   = fileBytes.NextU16();
                        ushort shortsCount  = fileBytes.NextU16();
                        ushort commandCount = fileBytes.NextU16();

                        uint textureRef = material.unk4 & 0xFFF;
                        Console.WriteLine($"      {material.unk4:X8}");
                        if (textureRef != 0xFFF)
                        {
                            //Filesystem.Filesystem.File textureFile = filesystem.GetFile("UVTX", (int)textureRef);
                            // TODO: load texture
                            Console.WriteLine("      Textured!");
                        }

                        if ((int)(material.unk4 << 13) < 0)
                        {
                            //Console.WriteLine($"{twentyFourStruct.unk4:X8} {twentyFourStruct.unk4 << 13:X8}");

                            // TODO: lighting information?
                            // twentyFourStruct.unksh12 = response from light function
                            Console.WriteLine("      Lit!");
                        }
                        else
                        {
                            material.unk_someLightingThing = -1;
                        }

                        if ((material.unk4 & 0x08_000000) != 0)
                        {
                            firstWordEverHadHighBitSet = 1;
                        }

                        material.pVertices = fileBytes.NextSubArray(material.vertCount * 16).InGroupsOf(16).Select(d => new Vertex(d)).ToArray();


                        if (textureRef != 0xFFF)
                        {
                            foreach (var x in material.pVertices)
                            {
                                Console.WriteLine(x);
                            }
                        }

                        RSPCommand[] commands = UnpackTriangleCommands(fileBytes, shortsCount, commandCount);

                        material.pCommandsInRDRAM = commands;

                        modelPart.pMaterials[k] = material;
                    }

                    modelPart.unk1 = firstWordEverHadHighBitSet;

                    lodInfo.pModelParts[j] = modelPart;
                }

                pLODs[i] = lodInfo;
            }

            for (int m = 0; m < partsPerLOD; m++)
            {
                pMatrices[m] = new Matrix(fileBytes.NextSubArray(64).AsFloats());
            }

            if (fileBytes.Length != (int)Math.Ceiling(fileBytes.Position / 8f) * 8)
            {
                throw new Exception();
            }



            ////////////////////////////////

            using (ThreeDDisplayWindow window = new ThreeDDisplayWindow())
            {
                foreach (LOD lod in pLODs)
                {
                    bool hadTextured = false;
                    for (int i = 0; i < lod.partCount; i++)
                    {
                        ModelPart part = lod.pModelParts[i];
                        Matrix    m    = pMatrices[i];

                        foreach (Material material in part.pMaterials)
                        {
                            List <Vertex> verts      = MaterialToVertexData(material.pVertices, material.pCommandsInRDRAM, m);
                            uint          textureRef = material.unk4 & 0xFFF;
                            if (textureRef != 0xFFF)
                            {
                                Filesystem.Filesystem.File textureFile = filesystem.GetFile("UVTX", (int)textureRef) !;
                                Console.WriteLine($"{textureFile.formLocationInROM:x6}");
                                window.AddTexturedVertices(verts, new UVTX.UVTXFile(textureFile.Section("COMM")));
                                hadTextured = true;
                            }
                            else
                            {
                                window.AddVertices(verts);
                            }
                        }

                        //lodData.AddRange(part.pMaterials.SelectMany(material => MaterialToVertexData(material.pVertices, material.pCommandsInRDRAM, m)));
                    }

                    if (hadTextured)
                    {
                        window.Run();
                    }
                }
            }
        }