Esempio n. 1
0
    public static void newGeoLayout(BTBinFile Bin)
    {
        uint GeoAddress = Bin.ReadFourBytes(0x04);

        Bin.writeByteArray(GeoAddress, BTGeoLayout());
        Bin.changeEndBinAddr(GeoAddress + 0x1C);
    }
Esempio n. 2
0
    public static int LoadCITexture(BTBinFile Binfile)
    {
        int id = GL.GenTexture();

        GL.BindTexture(TextureTarget.Texture2D, id);
        uint TextureDataAddr = Binfile.getTextureDataAddr();

        byte[]  CITex;
        short[] NewTexture;
        if (currentPalette.Length <= 16)
        {
            CITex      = Binfile.copyBytestoArray(TextureDataAddr + currentTexAddr, (uint)(Width * Height / 2));//4bpp
            NewTexture = CI4ToRGB5A1(CITex, currentPalette);
        }
        else
        {
            CITex      = Binfile.copyBytestoArray(TextureDataAddr + currentTexAddr, (uint)(Width * Height));//8bpp
            NewTexture = CI8ToRGB5A1(CITex, currentPalette);
        }
        GL.TexImage2D
        (
            TextureTarget.Texture2D,
            0,
            PixelInternalFormat.Rgb5A1,
            Width,
            Height,
            0,
            OpenTK.Graphics.OpenGL.PixelFormat.Rgba,
            PixelType.UnsignedShort5551,
            NewTexture
        );
        getTSFlags();
        getSTDTextureFilters();
        return(id);
    }
Esempio n. 3
0
    public static int LoadIA8Texture(BTBinFile Binfile)
    {
        int id = GL.GenTexture();

        GL.BindTexture(TextureTarget.Texture2D, id);
        uint TextureDataAddr = Binfile.getTextureDataAddr();

        byte[] TexData = Binfile.copyBytestoArray(TextureDataAddr + currentTexAddr, (uint)(Width * Height));

        GL.TexImage2D
        (
            TextureTarget.Texture2D,
            0,
            PixelInternalFormat.Alpha,
            Width,
            Height,
            0,
            OpenTK.Graphics.OpenGL.PixelFormat.Alpha,
            PixelType.UnsignedByte,
            TexData
        );
        getTSFlags();
        getSTDTextureFilters();
        return(id);
    }
Esempio n. 4
0
    public static int LoadRGBA32Texture(BTBinFile Binfile)
    {
        int id = GL.GenTexture();

        GL.BindTexture(TextureTarget.Texture2D, id);
        uint TexDataAddr = Binfile.getTextureDataAddr();

        UInt32[] TexData = new UInt32[ShortstoLoad]; //actually FloatsToLoad but accounted for as Shorts
        for (uint i = 0; i < ShortstoLoad; i++)
        {
            TexData[i] = Binfile.ReadFourBytes(TexDataAddr + currentTexAddr + (i * 4));
        }
        GL.TexImage2D
        (
            TextureTarget.Texture2D,
            0,
            PixelInternalFormat.Rgba32f,
            Width,
            Height,
            0,
            OpenTK.Graphics.OpenGL.PixelFormat.Rgba,
            PixelType.UnsignedInt8888,
            TexData
        );
        getTSFlags();
        getSTDTextureFilters();
        return(id);
    }
Esempio n. 5
0
    public static Vertex getVertex(UInt32 Addr, BTBinFile BTBin, uint AlphaBin)
    {
        Addr += BTBin.getVTXAddr();
        Vertex NewVert = new Vertex
                         (
            (short)BTBin.ReadTwoBytes(Addr),
            (short)BTBin.ReadTwoBytes(Addr + 2),
            (short)BTBin.ReadTwoBytes(Addr + 4),
            (short)BTBin.ReadTwoBytes(Addr + 8),
            (short)BTBin.ReadTwoBytes(Addr + 10),
            BTBin.getByte(Addr + 12),
            BTBin.getByte(Addr + 13),
            BTBin.getByte(Addr + 14),
            BTBin.getByte(Addr + 15),
            Addr
                         );

        if (Textures.FirstTexLoad[AlphaBin])
        {
            Array.Resize(ref CurrentVertexList, CurrentVertexList.Length + 1);
            CurrentVertexList[CurrentVertexList.Length - 1] = (UInt32)(Addr | (AlphaBin << 31));
            uint[] test = CurrentVertexList;
        }
        return(NewVert);
    }
Esempio n. 6
0
 public static void ConvertBKtoBT(BTBinFile Bin)
 {
     F3DEXtoF3DEX2(Bin);
     TextureHeaderBK2BT(Bin);
     useCommonVertexHeader(Bin);
     newGeoLayout(Bin);
     updateCollision(Bin);
 }
Esempio n. 7
0
 public static void ConvertBTtoBK(BTBinFile Bin)
 {
     if (Bin.getTextureSetupAddr() == 0x38)
     {
         return;                                    //Already BK Bin
     }
     //TODO
 }
Esempio n. 8
0
    public static void TextureHeaderBK2BT(BTBinFile Bin)
    {
        UInt16 SetupAddr = Bin.getTextureSetupAddr();

        Bin.copyBytes(SetupAddr, 0x50, Bin.getEndBinAddr() - SetupAddr); //Shift bin file so TexSetup is at 0x50
        Bin.WriteTwoBytes(0x08, 0x0050);
        UInt32 TriVertCount = Bin.ReadFourBytes(0x30);                   //Keep TriCount & VertCount

        for (int i = 0; i < 4; i++)
        {
            Bin.WriteEightBytes((uint)(SetupAddr - 8 + (i * 8)), 0);
        }                                       //fill ext texture addr with 0
        Bin.WriteFourBytes(0x44, TriVertCount); //Place the Tri/Vert counts back in
        SetupAddr = Bin.getTextureSetupAddr();
        if (Bin.getByte((uint)SetupAddr + 0x06) == 01)
        {
            return;
        }                                                        //External texture flag
        UInt16 numTextures        = Bin.ReadTwoBytes((uint)SetupAddr + 4);
        uint   BKCommandBeginAddr = (uint)SetupAddr + 8;
        uint   BTCommandBeginAddr = (uint)SetupAddr + 8;

        for (int i = 0; i < numTextures; i++)                                 //convert 128bit commands into 64bit commands
        {
            Bin.copyBytes(BKCommandBeginAddr, BTCommandBeginAddr, 6);         //TexAddr & Type
            Bin.copyBytes(BKCommandBeginAddr + 8, BTCommandBeginAddr + 6, 2); //XX and YY grid
            BTCommandBeginAddr += 0x08;
            BKCommandBeginAddr += 0x10;
        }
        Bin.copyBytes(BKCommandBeginAddr, BTCommandBeginAddr, (uint)(Bin.getEndBinAddr() - BKCommandBeginAddr)); //shift all data back
        Bin.changeEndBinAddr((uint)(Bin.getEndBinAddr() - (numTextures * 8)));                                   //remove data at end after backshift
        int    AddressesShift    = (0x18 - (numTextures * 8));
        UInt32 TexLoadBytes      = (uint)(Bin.ReadFourBytes(0x50) - (numTextures * 8));
        UInt32 NewGeoAddr        = (uint)(Bin.ReadFourBytes(0x04) + AddressesShift);//declare new addresses after shift
        UInt32 NewF3DEX2Addr     = (uint)(Bin.ReadFourBytes(0x0C) + AddressesShift);
        UInt32 NewVertAddr       = (uint)(Bin.ReadFourBytes(0x10) + AddressesShift);
        UInt32 NewCollisionAddr  = (uint)(Bin.ReadFourBytes(0x1C) + AddressesShift);
        Int32  NewFXSetupAddr    = (int)Bin.ReadFourBytes(0x24);
        Int32  NewFXSetupEndAddr = (int)Bin.ReadFourBytes(0x20);

        if (NewFXSetupAddr != 0)
        {
            NewFXSetupAddr += AddressesShift;
        }
        if (NewFXSetupEndAddr != 0)
        {
            NewFXSetupEndAddr += AddressesShift;
        }
        Bin.WriteFourBytes(0x50, TexLoadBytes);
        Bin.WriteFourBytes(0x04, NewGeoAddr);
        Bin.WriteFourBytes(0x0C, NewF3DEX2Addr);
        Bin.WriteFourBytes(0x10, NewVertAddr);
        Bin.WriteFourBytes(0x1C, NewCollisionAddr);
        Bin.WriteFourBytes(0x20, (uint)NewFXSetupEndAddr);
        Bin.WriteFourBytes(0x24, (uint)NewFXSetupAddr);
        //Bin.changeByte(0x0B, 0x00); THIS IS A TYPE, 2 for mipmapping may be necessary. 04 for env mapping. So far all match between BK/BT
    }
Esempio n. 9
0
    public static short[] LoadRGBA16TextureData(int ShortsToLoad, BTBinFile Binfile)
    {
        uint TexDataAddr = Binfile.getTextureDataAddr();

        short[] data = new short[ShortsToLoad];
        for (uint i = 0; i < ShortsToLoad; i++)
        {
            data[i] = (short)Binfile.ReadTwoBytes(TexDataAddr + currentTexAddr + (uint)(i * 2));
        }
        return(data);
    }
Esempio n. 10
0
 public static void LoadBIN(String BinDirectory)
 {
     using (FileStream fs = new FileStream(BinDirectory, FileMode.Open, FileAccess.Read))
     {
         byte[] binFile = new byte[fs.Length];
         fs.Read(binFile, 0, (int)fs.Length);
         BTBinFile NewBTBin = new BTBinFile(binFile);
         MainBin = NewBTBin;
         fs.Close();
     }
     Textures.InitialiseTextures(MainBin, 0);
 }
Esempio n. 11
0
    public static void SetVertRGBA(BTBinFile BTBin, uint Addr, UInt32 colour, bool AlphaOnly)
    {
        byte alpha = (byte)(colour & 0xFF);

        if (AlphaOnly)
        {
            BTBin.changeByte(Addr + 15, alpha);
        }
        else
        {
            BTBin.WriteFourBytes(Addr + 12, colour);
        }
    }
Esempio n. 12
0
    public static void updateCollision(BTBinFile Bin)
    {
        //TODO
        uint CollisionAddr = Bin.getCollisionSetupAddr();
        uint CollisionSize = Bin.getGeoAddr() - CollisionAddr;

        for (uint i = CollisionAddr; i < CollisionAddr + CollisionSize; i += 4)
        {
            if (Bin.getByte(i) == 0x88)
            {
                Bin.changeByte(i, 0x41);                        //Update common group header with one that allows HQ Shadow and ambient lighting
            }
        }
    }
Esempio n. 13
0
    public static byte[] BTVertexHeader(BTBinFile Bin)
    {
        uint   VertexStartAddr = Bin.ReadFourBytes(0x10) + 0x18;
        UInt16 numVerts        = ((UInt16)((Bin.ReadFourBytes(0x1C) - VertexStartAddr) / 0x10));
        byte   numVertsByte1;
        byte   numVertsByte2;

        FromShortToByte(numVerts, out numVertsByte1, out numVertsByte2);
        byte[] geolayout = new byte[24];
        geolayout[0]    = 0xBC; geolayout[1] = 0x47; geolayout[2] = 0xED; geolayout[3] = 0xAE;
        geolayout[4]    = 0xC1; geolayout[5] = 0x40; geolayout[6] = 0x3E; geolayout[7] = 0x01;
        geolayout[8]    = 0x37; geolayout[9] = 0x58; geolayout[0x0a] = 0x3D; geolayout[0x0b] = 0x2A;
        geolayout[0x0c] = 0xFD; geolayout[0x0d] = 0x24; geolayout[0x0e] = 0x12; geolayout[0x0f] = 0x83;
        geolayout[0x10] = 0xFF; geolayout[0x11] = 0x35; geolayout[0x12] = 0xA0; geolayout[0x13] = 0xC0;
        geolayout[0x14] = 0xA0; geolayout[0x15] = 0xC0; geolayout[0x16] = numVertsByte1; geolayout[0x17] = numVertsByte2;
        return(geolayout);
    }
Esempio n. 14
0
    public static int LoadTexture(BTBinFile Bin)
    {
        uint CICount    = (uint)currentPalette.Length;
        int  NewTexture = 0;

        if (MODE == CIMODE)
        {
            NewTexture = LoadCITexture(Bin);
        }
        else if (MODE == RGBAMODE && BitSize == 16)
        {
            NewTexture = LoadRGBA16Texture(Bin);
        }
        else if (MODE == RGBAMODE && BitSize == 32)
        {
            NewTexture = LoadRGBA32Texture(Bin);
        }
        else if (MODE == IAMODE)
        {
            NewTexture = LoadIA8Texture(Bin);
        }
        return(NewTexture);
    }
Esempio n. 15
0
    public static int LoadRGBA16Texture(BTBinFile Binfile)
    {
        int id = GL.GenTexture();

        GL.BindTexture(TextureTarget.Texture2D, id);
        uint TextureDataAddr = Binfile.getTextureDataAddr();

        short[] TexData = LoadRGBA16TextureData(Width * Height, Binfile);
        GL.TexImage2D
        (
            TextureTarget.Texture2D,
            0,
            PixelInternalFormat.Rgb5A1,
            Width,
            Height,
            0,
            OpenTK.Graphics.OpenGL.PixelFormat.Rgba,
            PixelType.UnsignedShort5551,
            TexData
        );
        getTSFlags();
        getSTDTextureFilters();
        return(id);
    }
Esempio n. 16
0
    public static void F3DEXtoF3DEX2(BTBinFile Bin)
    {
        uint   CommandsLength = Bin.F3DCommandsLength();
        UInt32 F3DSetupAddr   = Bin.ReadFourBytes(0x0C);

        byte[][] DisplayList    = new byte[CommandsLength][];
        uint     newCommandAddr = F3DSetupAddr + 0x08;

        //Copy DL into 2D Byte array with double loop
        for (int i = 0; i < CommandsLength; i++)
        {
            DisplayList[i] = new byte[8];
            for (int j = 0; j < 8; j++)
            {
                DisplayList[i][j] = Bin.getByte((uint)(newCommandAddr + (i * 8) + j));
            }
        }
        //change or convert commands
        byte MaxVertIndex = 0x00;
        bool firstVTX     = true;
        int  previousVTX  = 0;

        for (int i = 0; i < DisplayList.Length; i++)
        {
            switch (DisplayList[i][0])
            {
            case 0x01:
                DisplayList[i][0] = 0xDA;
                break;

            case 0x03:
                DisplayList[i][0] = 0xDC;
                break;

            case 0x04:
                DisplayList[i][0] = 0x01;
                Int16 numvert = (Int16)(DisplayList[i][2] / 4);
                DisplayList[i][1] = (byte)(numvert >> 4);
                DisplayList[i][2] = (byte)(numvert << 4);
                numvert           = (short)(numvert * 2);
                DisplayList[i][3] = (byte)(numvert);

                //Fix Banjo's Backpack's overloaded 04 commands below, but it breaks conversions from original bins!

                /*if (firstVTX) { firstVTX = false; previousVTX = i; break; }
                 * byte MaxVertNum = (byte)((MaxVertIndex / 2) + 1);
                 * DisplayList[previousVTX][1] = (byte)(MaxVertNum >> 4);
                 * DisplayList[previousVTX][2] = (byte)(MaxVertNum << 4);
                 * DisplayList[previousVTX][3] = (byte)(MaxVertIndex+2);
                 * MaxVertIndex = 0x00;
                 * previousVTX = i;*/
                break;

            case 0x06:
                DisplayList[i][0] = 0xDE;
                break;

            case 0xB1:
                DisplayList[i][0] = 0x06;
                MaxVertIndex      = MaxVertexCheck(MaxVertIndex, DisplayList, i);
                break;

            case 0xB2:
                DisplayList[i][0] = 0x02;
                break;

            case 0xB3:
                DisplayList[i][0] = 0xF1;
                break;

            case 0xB4:
                DisplayList[i][0] = 0xE1;
                break;

            case 0xB5:
                DisplayList[i][0] = 0x07;
                MaxVertIndex      = MaxVertexCheck(MaxVertIndex, DisplayList, i);
                break;

            case 0xB6:
                DisplayList[i][0] = 0xD9;
                if (DisplayList[i + 1][5] == 0x08 && DisplayList[i + 1][6] == 0x22 && DisplayList[i + 1][7] == 0x04)     //VertRGBABackCull, i+1 for SETGEO
                {
                    DisplayList[i][1] = 0xC0;
                    DisplayList[i][2] = 0xFF;
                    DisplayList[i][3] = 0xFB;
                }
                else if (DisplayList[i + 1][5] == 0x08 && DisplayList[i + 1][6] == 0x02 && DisplayList[i + 1][7] == 0x04)     //VertRGBANoCull, i+1 for SETGEO
                {
                    DisplayList[i][1] = 0xC0;
                    DisplayList[i][2] = 0xF9;
                    DisplayList[i][3] = 0xFB;
                }
                else
                {
                    DisplayList[i][1] = 0xC0;
                    DisplayList[i][2] = 0xF9;
                    DisplayList[i][3] = 0xFB;
                }
                DisplayList[i][5] = 0x00;     //NOP Clear for now
                DisplayList[i][6] = 0x00;
                DisplayList[i][7] = 0x00;
                break;

            case 0xB7:
                DisplayList[i][0] = 0xD9;
                DisplayList[i][1] = 0xFF;     //NOP Set for now
                DisplayList[i][2] = 0xFF;
                DisplayList[i][3] = 0xFF;
                if (DisplayList[i][5] == 0x06)
                {
                    DisplayList[i][5] = 0x26;
                }
                else
                {
                    DisplayList[i][5] = 0x20;
                }
                DisplayList[i][5] = 0x20;     //VertRGBA only for now (later env mapping flag)
                DisplayList[i][6] = 0x00;
                DisplayList[i][7] = 0x04;
                break;

            case 0xB9:
                DisplayList[i][0] = 0xE2;
                break;

            case 0xBA:
                DisplayList[i][0] = 0xE3;
                break;

            case 0xBB:
                DisplayList[i][0] = 0xD7;
                if (DisplayList[i][3] == 0x01)
                {
                    DisplayList[i][3] = 0x02;
                }
                break;

            case 0xBC:
                DisplayList[i][0] = 0xDB;
                break;

            case 0xBD:
                DisplayList[i][0] = 0xD8;
                break;

            case 0xBF:
                DisplayList[i][0] = 0x05;
                DisplayList[i][1] = DisplayList[i][5];
                DisplayList[i][2] = DisplayList[i][6];
                DisplayList[i][3] = DisplayList[i][7];
                for (int j = 5; j < 8; j++)
                {
                    DisplayList[i][j] = 0x00;
                }
                MaxVertIndex = MaxVertexCheck(MaxVertIndex, DisplayList, i);
                break;

            case 0xF0:
                if (DisplayList[i][4] == 0x01)
                {
                    DisplayList[i][4] = 0x06;
                }
                break;

            case 0xF5:
                if (DisplayList[i][4] == 0x01)
                {
                    DisplayList[i][4] = 0x06;
                }
                break;

            case 0xB8:
                DisplayList[i][0] = 0xDF;
                if (i != DisplayList.Length - 1)
                {
                    DisplayList[i][0] = 0x00;
                }
                break;
            }
        }
        //Load converted DL back into bin
        for (int i = 0; i < CommandsLength; i++)
        {
            for (int j = 0; j < 8; j++)
            {
                Bin.changeByte((uint)(newCommandAddr + (i * 8) + j), DisplayList[i][j]);
            }
        }
    }
Esempio n. 17
0
 public static void InitialiseTextures(BTBinFile Bin, int BinNum)
 {
     TextureArray[BinNum] = new uint[Bin.getTextureCount()];
     FirstTexLoad[BinNum] = true;
 }
Esempio n. 18
0
    public static void useCommonVertexHeader(BTBinFile Bin)
    {
        UInt32 VertexSetupAddr = Bin.ReadFourBytes(0x10);

        Bin.writeByteArray(VertexSetupAddr, BTVertexHeader(Bin));
    }
Esempio n. 19
0
    public static void ParseF3DEXDL(BTBinFile BinFile, uint BinNum, bool ColourBuffer)
    {
        UInt32 DLAddr         = BinFile.getDLAddr();
        uint   CommandsLength = BinFile.F3DCommandsLength();
        UInt32 F3DSetupAddr   = BinFile.ReadFourBytes(0x0C);

        byte[][] DisplayList    = new byte[CommandsLength][];
        uint     newCommandAddr = F3DSetupAddr + 0x08;
        uint     AllVTXAddr     = BinFile.getVTXAddr();

        Vertex[] GVTXArray    = new Vertex[32];
        int      TextureCount = BinFile.getTextureCount();
        int      CICount      = 0;
        int      TextureIndex = 0;

        Textures.ShortstoLoad = 0;

        Textures.TextureAddrArray[BinNum] = new uint[TextureCount + 1];
        for (int i = 0; i < TextureCount; i++)
        {
            Textures.TextureAddrArray[BinNum][i] = BinFile.ReadFourBytes((uint)(BinFile.getTextureSetupAddr() + 8 + (i * 0x10))); //Load all texture addresses into array
        }
        if (TextureCount != 0)
        {
            Textures.TextureAddrArray[BinNum][TextureCount] = Textures.TextureAddrArray[BinNum][TextureCount - 1] + 0x500;               //allow last item to always be greater than last addr
        }
        //Copy DL into 2D Byte array with double loop
        for (uint i = 0; i < CommandsLength; i++)
        {
            DisplayList[i] = new byte[8];
            for (int j = 0; j < 8; j++)
            {
                DisplayList[i][j] = BinFile.getByte((uint)(newCommandAddr + (i * 8) + j));
            }
        }

        GL.Enable(EnableCap.Blend);
        GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
        if (ColourBuffer || RenderEdges)
        {
            GL.Disable(EnableCap.Blend);
        }
        for (int i = 0; i < DisplayList.Length; i++)
        {
            byte[] CMD = DisplayList[i];
            if (!ColourBuffer)
            {
                switch (DisplayList[i][0])
                {
                case 0x01:
                    break;

                case 0x03: //movemem
                    if (RenderEdges)
                    {
                        break;
                    }
                    if (CMD[1] == 0x86)
                    {
                        float[] light0_diffuse = new float[4];
                        for (uint j = 0; j < 4; j++)
                        {
                            light0_diffuse[j] = (float)0xFF / 255f;
                        }
                        GL.Light(LightName.Light0, LightParameter.Diffuse, light0_diffuse);
                        GL.ColorMaterial(MaterialFace.Front, ColorMaterialParameter.Diffuse);
                    }
                    else if (CMD[1] == 0x88)
                    {
                        float[] light0_ambient = new float[4];
                        for (uint j = 0; j < 4; j++)
                        {
                            light0_ambient[j] = (((float)0x3F / 255f) - 0.2f) * 1.25f;
                        }
                        GL.Light(LightName.Light0, LightParameter.Ambient, light0_ambient);
                        GL.ColorMaterial(MaterialFace.Front, ColorMaterialParameter.Ambient);
                    }
                    GL.Enable(EnableCap.ColorMaterial);
                    break;

                case 0x04:
                    UInt32 VTXStart    = readSegmentAddr(CMD);
                    short  numVerts    = (short)(CMD[2] / 0x04);
                    int    bufferIndex = CMD[1] / 0x02;
                    for (int j = 0; j < numVerts; j++)
                    {
                        GVTXArray[bufferIndex + j] = Vertex.getVertex((uint)(VTXStart + (j * 0x10)), BinFile, (byte)BinNum);
                    }
                    Renderer.VertexCount += (uint)numVerts;
                    break;

                case 0x06:
                    break;

                case 0xB1:
                    GL.Begin(BeginMode.Triangles);
                    for (int j = 1; j < 8; j++)
                    {
                        if (j == 4)
                        {
                            j++;
                        }
                        int VertIndex = CMD[j] / 0x02;
                        if (!EnvMapping)
                        {
                            GL.TexCoord2(GVTXArray[VertIndex].getUVVector());
                        }
                        if (LightingEnabled)     //Normals
                        {
                            Vector3 normals = new Vector3(GVTXArray[VertIndex].getRGBColor());
                            if (!EnvMapping)
                            {
                                GL.Normal3(Vector3.Normalize(normals));
                            }
                            else
                            {
                                Vector4 normals4 = new Vector4(normals, 1f);
                                normals4 = Vector4.Normalize(Renderer.projection * normals4);
                                Vector3 newnorms = new Vector3(normals4.X, normals4.Y, normals4.Z);
                                GL.Normal3(newnorms);
                            }
                        }
                        else
                        {
                            GL.Color4(GVTXArray[VertIndex].getRGBAColor());      //RGBA
                        }
                        if (RenderEdges)
                        {
                            GL.Color4(0, 0, 0, 0xFF);
                        }
                        GL.Vertex3(GVTXArray[VertIndex].getCoordVector());
                    }
                    if (!RenderEdges)
                    {
                        Renderer.TriCount++;
                    }
                    GL.End();
                    break;

                case 0xB2:
                    break;

                case 0xB3:
                    break;

                case 0xB4:
                    break;

                case 0xB5:
                    break;

                case 0xB6: //ClearGeoMode
                    if (RenderEdges)
                    {
                        break;
                    }
                    UInt32 ClearBits = (UInt32)((CMD[4] << 24) | (CMD[5] << 16) | (CMD[6] << 8) | CMD[7]);
                    GeoMode &= ~ClearBits;
                    SetGeoMode(ColourBuffer);
                    break;

                case 0xB7: //SetGeoMode
                    if (RenderEdges)
                    {
                        break;
                    }
                    UInt32 SetBits = (UInt32)((CMD[4] << 24) | (CMD[5] << 16) | (CMD[6] << 8) | CMD[7]);
                    GeoMode |= SetBits;
                    SetGeoMode(ColourBuffer);
                    break;

                case 0xB9:
                    break;

                case 0xBA:
                    break;

                case 0xBB:
                    Textures.S_Scale *= 0x10000 / (float)(CMD[4] * 0x100 + CMD[5]); //0x10000/
                    Textures.T_Scale *= 0x10000 / (float)(CMD[6] * 0x100 + CMD[7]);
                    if (CMD[3] == 0x01 && Renderer.TextureEnabler)
                    {
                        GL.Enable(EnableCap.Texture2D);
                    }
                    else
                    {
                        GL.Disable(EnableCap.Texture2D);
                        Textures.T_Scale = 1f; Textures.S_Scale = 1f;
                    }
                    if (DisplayList[i][2] == 0x12)
                    {
                        Textures.MipMapping = true;
                        Textures.T_Scale    = 32f; Textures.S_Scale = 32f;//Revert mipmapping for now
                    }
                    break;

                case 0xBC:
                    break;

                case 0xBD:
                    break;

                case 0xBF:
                    GL.Begin(BeginMode.Triangles);
                    for (int j = 5; j < 8; j++)
                    {
                        int VertIndex = CMD[j] / 0x02;
                        if (!EnvMapping)
                        {
                            GL.TexCoord2(GVTXArray[VertIndex].getUVVector());
                        }
                        if (LightingEnabled)     //Normals
                        {
                            Vector3 normals = new Vector3(GVTXArray[VertIndex].getRGBColor());
                            if (!EnvMapping)
                            {
                                GL.Normal3(Vector3.Normalize(normals));
                            }
                            else
                            {
                                Vector4 normals4 = new Vector4(normals, 1f);
                                normals4 = Vector4.Normalize(Renderer.projection * normals4);
                                Vector3 newnorms = new Vector3(normals4.X, normals4.Y, normals4.Z);
                                GL.Normal3(newnorms);
                            }
                        }
                        else
                        {
                            GL.Color4(GVTXArray[VertIndex].getRGBAColor());      //RGBA
                        }
                        if (RenderEdges)
                        {
                            GL.Color4(0, 0, 0, 0xFF);
                        }
                        GL.Vertex3(GVTXArray[VertIndex].getCoordVector());
                    }
                    if (!RenderEdges)
                    {
                        Renderer.TriCount++;
                    }
                    GL.End();
                    break;

                case 0xF0:
                    CICount = (((CMD[5] << 4) + ((CMD[6] & 0xF0) >> 4)) >> 2) + 1;
                    Textures.currentPalette = Textures.LoadRGBA16TextureData(CICount, BinFile);
                    break;

                case 0xF2: //Settilesize
                    Textures.S_Scale = Convert.ToSingle((((CMD[5] << 4) | ((CMD[6] & 0xF0) >> 4)) >> 2) + 1);
                    Textures.T_Scale = Convert.ToSingle(((((CMD[6] & 0x0F) << 8) | CMD[7]) >> 2) + 1);
                    break;
                //To avoid TMEM emulation, we will run a hybrid of 0xF3 and 0xF5 in this section to accurately interpret texture sizes

                case 0xF3:
                    TextureIndex = 0;
                    CICount      = Textures.currentPalette.Length;
                    for (int j = 0; j < TextureCount; j++) // Compare currentTexAddr to our texture address array
                    {
                        if (Textures.currentTexAddr >= Textures.TextureAddrArray[BinNum][j] && Textures.currentTexAddr < Textures.TextureAddrArray[BinNum][j + 1])
                        {
                            TextureIndex = j;
                        }
                    }
                    if (Textures.FirstTexLoad[BinNum])
                    {
                        int TexLoadRange = ((CMD[6] & 0x0F) * 0x100 + CMD[7]);
                        Textures.ShortstoLoad = (CMD[5]) * 0x10 + ((CMD[6] & 0xF0) >> 4) + 1;
                        Textures.BytestoLoad  = Textures.ShortstoLoad * 2;
                        byte Mode = Textures.MODE;

                        if (Mode == Textures.CIMODE && CICount == 16)
                        {
                            Textures.Width  = TexLoadRange / 8;
                            Textures.Height = (Textures.BytestoLoad * 2) / Textures.Width;//4bpp
                        }
                        else if (Mode == Textures.CIMODE && CICount == 256)
                        {
                            Textures.Width  = TexLoadRange / 16;
                            Textures.Height = (Textures.BytestoLoad) / Textures.Width;//8bpp
                        }
                        else if (Mode == Textures.RGBAMODE && Textures.BitSize == 16)
                        {
                            if (Textures.MipMapping)
                            {
                                Textures.ShortstoLoad -= 0x200;
                            }
                            Textures.Width  = TexLoadRange / 8;
                            Textures.Height = (Textures.ShortstoLoad) / Textures.Width;//16bpp
                        }
                        else if (Mode == Textures.IAMODE && Textures.BitSize == 16)
                        {
                            Textures.Width  = TexLoadRange / 4;
                            Textures.Height = (Textures.BytestoLoad) / Textures.Width;//16bpp
                        }
                        else if (Textures.MODE == Textures.RGBAMODE && Textures.BitSize == 32)
                        {
                            Textures.Width  = TexLoadRange / 4;
                            Textures.Height = (Textures.ShortstoLoad) / Textures.Width;//32bpp
                        }
                        else
                        {
                            return;
                        }
                        Textures.TextureArray[BinNum][TextureIndex] = (uint)Textures.LoadTexture(BinFile);
                    }
                    GL.BindTexture(TextureTarget.Texture2D, Textures.TextureArray[BinNum][TextureIndex]);
                    break;

                case 0xF5:
                    Textures.MODE    = (byte)(CMD[1] >> 5);
                    Textures.BitSize = (byte)(4 * Math.Pow(2, ((CMD[1] >> 3) & 3)));
                    Textures.TFlags  = (CMD[5] >> 2) & 3;
                    Textures.SFlags  = CMD[6] & 3;
                    int WidthBits = (((CMD[1] & 3) << 7) + CMD[2] >> 1) * 64;
                    if (CMD[4] != 0 || !Textures.FirstTexLoad[BinNum])
                    {
                        break;
                    }
                    int HeightPower = ((CMD[5] & 3) << 2) | (CMD[6] >> 6);
                    int WidthPower  = (CMD[7] >> 4);
                    Textures.Width  = (int)Math.Pow(2, WidthPower);//(int)Math.Pow(2, WidthPower);
                    Textures.Height = (int)Math.Pow(2, HeightPower);
                    GL.DeleteTexture(Textures.TextureArray[BinNum][TextureIndex]);
                    if (Textures.MODE == Textures.CIMODE)
                    {
                        Textures.TextureArray[BinNum][TextureIndex] = (uint)Textures.LoadCITexture(BinFile);
                    }
                    else if (Textures.MODE == Textures.RGBAMODE && Textures.BitSize == 16)
                    {
                        Textures.TextureArray[BinNum][TextureIndex] = (uint)Textures.LoadRGBA16Texture(BinFile);
                    }
                    else if (Textures.MODE == Textures.RGBAMODE && Textures.BitSize == 32)
                    {
                        Textures.TextureArray[BinNum][TextureIndex] = (uint)Textures.LoadRGBA32Texture(BinFile);
                    }
                    else if (Textures.MODE == Textures.IAMODE)
                    {
                        Textures.TextureArray[BinNum][TextureIndex] = (uint)Textures.LoadIA8Texture(BinFile);
                    }
                    GL.BindTexture(TextureTarget.Texture2D, Textures.TextureArray[BinNum][TextureIndex]);
                    break;

                case 0xFD:
                    Textures.BitSize        = (byte)(4 * Math.Pow(2, ((CMD[1] >> 3) & 3)));
                    Textures.MODE           = (byte)(CMD[1] >> 5);
                    Textures.currentTexAddr = readSegmentAddr(CMD);
                    break;

                case 0xB8:
                    Textures.T_Scale = 1;
                    Textures.S_Scale = 1;

                    break;
                }
            }
            else
            {
                switch (DisplayList[i][0])
                {
                case 0x04:
                    UInt32 VTXStart    = readSegmentAddr(CMD);
                    short  numVerts    = (short)(CMD[2] / 0x04);
                    int    bufferIndex = CMD[1] / 0x02;
                    for (int j = 0; j < numVerts; j++)
                    {
                        GVTXArray[bufferIndex + j] = Vertex.getVertex((uint)(VTXStart + (j * 0x10)), BinFile, (byte)(BinNum));
                    }
                    Renderer.VertexCount += (uint)numVerts;
                    break;

                case 0xB6:
                    if (RenderEdges)
                    {
                        break;
                    }
                    UInt32 ClearBits = (UInt32)((CMD[4] << 24) | (CMD[5] << 16) | (CMD[6] << 8) | CMD[7]);
                    GeoMode &= ~ClearBits;
                    SetGeoMode(ColourBuffer);
                    break;

                case 0xB7:
                    if (RenderEdges)
                    {
                        break;
                    }
                    UInt32 SetBits = (UInt32)((CMD[4] << 24) | (CMD[5] << 16) | (CMD[6] << 8) | CMD[7]);
                    GeoMode |= SetBits;
                    SetGeoMode(ColourBuffer);
                    break;

                case 0xB1:
                    if (LightingEnabled)
                    {
                        break;                      //Disable painting on non-RGBA meshes
                    }
                    for (uint j = 0; j < 2; j++)
                    {
                        Vertex[] Triangle2 = new Vertex[3];
                        Color4[] colour2   = new Color4[3];
                        for (int k = 1; k < 4; k++)
                        {
                            int idx       = (int)(k + (j * 4)); //bytes 1-3, and 5-8
                            int VertIndex = CMD[idx] / 0x02;
                            Triangle2[k - 1] = GVTXArray[VertIndex];
                            UInt32 Addr = Triangle2[k - 1].getAddr();
                            colour2[k - 1] = new Color4((byte)((Addr >> 24) | (BinNum << 7)), (byte)((Addr >> 16) & 0xFF), (byte)((Addr >> 8) & 0xFF), (byte)(Addr & 0xFF));   //Addr to RGBA
                        }
                        RenderColourBufferQuads(Triangle2, colour2);
                        //if(BinNum > 0)throw new Exception(((byte)(colour2[0].B)).ToString("x"));
                    }

                    break;

                case 0xBF:
                    if (LightingEnabled)
                    {
                        break;                      //Disable painting on non-RGBA meshes
                    }
                    Vertex[] Triangle = new Vertex[3];
                    Color4[] colour   = new Color4[3];
                    for (int j = 5; j < 8; j++)
                    {
                        int VertIndex = CMD[j] / 0x02;
                        Triangle[j - 5] = GVTXArray[VertIndex];
                        UInt32 Addr = Triangle[j - 5].getAddr();
                        colour[j - 5] = new Color4((byte)((Addr >> 24) | (BinNum << 7)), (byte)((Addr >> 16) & 0xFF), (byte)((Addr >> 8) & 0xFF), (byte)(Addr & 0xFF)); //Addr to RGBA
                    }
                    RenderColourBufferQuads(Triangle, colour);
                    break;

                case 0xB8:
                    break;
                }
            }
        }
        Textures.FirstTexLoad[BinNum] = false;
        GL.Disable(EnableCap.Texture2D);
    }