Exemplo n.º 1
0
        internal static void RenderTriangles(F3DEX2Interpreter f3dex2, int[] idx)
        {
            GL.Begin(PrimitiveType.Triangles);

            foreach (int i in idx)
            {
                if (i >= f3dex2.VertexBuffer.Length)
                {
                    continue;
                }

                double[] S = new double[2], T = new double[2];

                for (int j = 0; j < (OpenGLHelpers.Initialization.SupportsFunction("glActiveTextureARB") ? f3dex2.Textures.Length : 1); j++)
                {
                    if (f3dex2.Textures[j].MaskS != 0)
                    {
                        S[j] = (f3dex2.VertexBuffer[i].TexCoord.X * f3dex2.Textures[j].ShiftScaleS * f3dex2.ScaleS[j] -
                                (f3dex2.Textures[j].ULS * Fixed2Float[2] % (1 << f3dex2.Textures[j].MaskS))) * f3dex2.Textures[j].ScaleS;
                    }
                    else
                    {
                        S[j] = (f3dex2.VertexBuffer[i].TexCoord.X * f3dex2.Textures[j].ShiftScaleS * f3dex2.ScaleS[j] -
                                (f3dex2.Textures[j].ULS * Fixed2Float[2])) * f3dex2.Textures[j].ScaleS;
                    }

                    if (f3dex2.Textures[j].MaskT != 0)
                    {
                        T[j] = (f3dex2.VertexBuffer[i].TexCoord.Y * f3dex2.Textures[j].ShiftScaleT * f3dex2.ScaleT[j] -
                                (f3dex2.Textures[j].ULT * Fixed2Float[2] % (1 << f3dex2.Textures[j].MaskT))) * f3dex2.Textures[j].ScaleT;
                    }
                    else
                    {
                        T[j] = (f3dex2.VertexBuffer[i].TexCoord.Y * f3dex2.Textures[j].ShiftScaleT * f3dex2.ScaleT[j] -
                                (f3dex2.Textures[j].ULT * Fixed2Float[2])) * f3dex2.Textures[j].ScaleT;
                    }

                    OpenGLHelpers.Initialization.MultiTexCoord2Checked(TextureUnit.Texture0 + j, S[j], T[j]);
                }

                if (!Convert.ToBoolean(f3dex2.GeometryMode & (uint)GeometryMode.LIGHTING))
                {
                    GL.Color4(f3dex2.VertexBuffer[i].Colors);
                }
                GL.Normal3(f3dex2.VertexBuffer[i].Normals);
                GL.Vertex3(f3dex2.VertexBuffer[i].Position);
            }

            GL.End();
        }
Exemplo n.º 2
0
        internal static void PerformModeChanges(F3DEX2Interpreter f3dex2)
        {
            /* Textures */
            if (Configuration.RenderTextures)
            {
                GL.Enable(EnableCap.Texture2D);

                /* Texgen */
                if (Convert.ToBoolean(f3dex2.GeometryMode & (uint)GeometryMode.TEXTURE_GEN))
                {
                    GL.TexGen(TextureCoordName.S, TextureGenParameter.TextureGenMode, (int)TextureGenMode.NormalMap);
                    GL.TexGen(TextureCoordName.T, TextureGenParameter.TextureGenMode, (int)TextureGenMode.NormalMap);
                    GL.Enable(EnableCap.TextureGenS);
                    GL.Enable(EnableCap.TextureGenT);
                }
                else
                {
                    GL.Disable(EnableCap.TextureGenS);
                    GL.Disable(EnableCap.TextureGenT);
                }
            }
            else
            {
                GL.Disable(EnableCap.Texture2D);
            }

            /* Culling */
            if (Convert.ToBoolean(f3dex2.GeometryMode & (uint)GeometryMode.CULL_BOTH))
            {
                GL.Enable(EnableCap.CullFace);
                if (Convert.ToBoolean(f3dex2.GeometryMode & (uint)GeometryMode.CULL_BACK))
                {
                    GL.CullFace(CullFaceMode.Back);
                }
                else
                {
                    GL.CullFace(CullFaceMode.Front);
                }
            }
            else
            {
                GL.Disable(EnableCap.CullFace);
            }

            /* Lighting */
            if (Convert.ToBoolean(f3dex2.GeometryMode & (uint)GeometryMode.LIGHTING))
            {
                GL.Enable(EnableCap.Lighting);
                GL.Enable(EnableCap.Normalize);
            }
            else
            {
                GL.Disable(EnableCap.Lighting);
                GL.Disable(EnableCap.Normalize);
            }

            /* Fog */
            if (Configuration.EmulateFog)
            {
                if (Convert.ToBoolean(f3dex2.GeometryMode & (uint)GeometryMode.FOG))
                {
                    GL.Enable(EnableCap.Fog);
                }
                else
                {
                    GL.Disable(EnableCap.Fog);
                }
            }
            else
            {
                GL.Disable(EnableCap.Fog);
            }

            /* Decal */
            if (f3dex2.OtherModeL.ZModeDec)
            {
                GL.Enable(EnableCap.PolygonOffsetFill);
                GL.PolygonOffset(-1.0f, -1.0f);
            }
            else
            {
                GL.Disable(EnableCap.PolygonOffsetFill);
            }

            /* Alpha test */
            if (f3dex2.OtherModeL.CvgXAlpha || f3dex2.OtherModeL.AlphaCvgSel)
            {
                GL.Enable(EnableCap.AlphaTest);
                GL.Disable(EnableCap.Blend);
                if (f3dex2.OtherModeL.AlphaCvgSel)
                {
                    GL.AlphaFunc(AlphaFunction.Gequal, 0.125f);
                }
                else
                {
                    GL.AlphaFunc(AlphaFunction.Greater, 0.0f);
                }
            }
            else
            {
                GL.Disable(EnableCap.AlphaTest);
            }

            /* Force blending */
            if (f3dex2.OtherModeL.ForceBl)
            {
                GL.Disable(EnableCap.AlphaTest);
                GL.Enable(EnableCap.Blend);
            }
            else
            {
                GL.Disable(EnableCap.Blend);
            }

            /* Z-compare */
            if (f3dex2.OtherModeL.ZCmp)
            {
                GL.DepthFunc(DepthFunction.Lequal);
            }
            else
            {
                GL.DepthFunc(DepthFunction.Always);
            }

            /* Z-update */
            if (f3dex2.OtherModeL.ZUpd)
            {
                GL.DepthMask(true);
            }
            else
            {
                GL.DepthMask(false);
            }

            /* Blend modes */
            switch (f3dex2.OtherModeL.Data >> 16)
            {
            case 0x0448:
            case 0x055A:
                GL.BlendFunc(BlendingFactor.One, BlendingFactor.One);
                break;

            case 0x0382:
            case 0x0091:
            case 0x0C08:
            case 0x0F0A:
            case 0x0302:
                GL.BlendFunc(BlendingFactor.One, BlendingFactor.Zero);
                break;

            case 0xAF50:
            case 0x0F5A:
            case 0x0FA5:
            case 0x5055:
                GL.BlendFunc(BlendingFactor.Zero, BlendingFactor.One);
                break;

            case 0x5F50:
                GL.BlendFunc(BlendingFactor.Zero, BlendingFactor.OneMinusSrcAlpha);
                break;

            default:
                GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
                break;
            }
        }
Exemplo n.º 3
0
        public ROMHandler(string fn)
        {
            #if !DEBUG
            try
            #endif
            {
            reload:
                DMATableAddress = FileNameTableAddress = SceneTableAddress = -1;

                Filename = fn;

                /* Initialize segment and rendering systems */
                SegmentMapping = new Hashtable();
                Renderer = new F3DEX2Interpreter(this);

                /* Read ROM */
                System.IO.BinaryReader br = new System.IO.BinaryReader(System.IO.File.Open(fn, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read));
                if (br.BaseStream.Length < MinROMSize) throw new ROMHandlerException(string.Format("File size is less than {0}MB; ROM appears to be invalid.", (MinROMSize / 0x100000)));
                Data = new byte[br.BaseStream.Length];
                br.Read(Data, 0, (int)br.BaseStream.Length);
                br.Close();

                /* Detect byte order */
                DetectByteOrder();

                if (DetectedByteOrder != ByteOrder.BigEndian)
                {
                    if (MessageBox.Show("The ROM file you have selected uses an incompatible byte order, and needs to be converted to Big Endian format to be used." + Environment.NewLine + Environment.NewLine +
                        "Convert the ROM now? (You will be asked for the target filename; the converted ROM will also be reloaded.)", "Byte Order Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        /* Ask for new filename */
                        string fnnew = GUIHelpers.ShowSaveFileDialog("Nintendo 64 ROMs (*.z64;*.bin)|*.z64;*.bin|All Files (*.*)|*.*");
                        if (fnnew != string.Empty)
                        {
                            fn = fnnew;

                            /* Perform byte order conversion */
                            byte[] datanew = new byte[Data.Length];
                            byte[] conv = null;
                            for (int i = 0, j = 0; i < Data.Length; i += 4, j += 4)
                            {
                                if (DetectedByteOrder == ByteOrder.MiddleEndian) conv = new byte[4] { Data[i + 1], Data[i], Data[i + 3], Data[i + 2] };
                                else if (DetectedByteOrder == ByteOrder.LittleEndian) conv = new byte[4] { Data[i + 3], Data[i + 2], Data[i + 1], Data[i] };
                                Buffer.BlockCopy(conv, 0, datanew, j, conv.Length);
                            }

                            /* Save converted ROM, then reload it */
                            System.IO.BinaryWriter bw = new System.IO.BinaryWriter(System.IO.File.Create(fn));
                            bw.Write(datanew);
                            bw.Close();

                            goto reload;
                        }
                    }
                    else
                    {
                        /* Wrong byte order, no conversion performed */
                        throw new ByteOrderException(string.Format("Incompatible byte order {0} detected; ROM cannot be used.", DetectedByteOrder));
                    }
                }
                else
                {
                    /* Read header */
                    ReadROMHeader();

                    /* Create XML actor definition reader */
                    XMLActorDefReader = new XMLActorDefinitionReader(System.IO.Path.Combine("XML", "ActorDefinitions", GameID.Substring(1, 2)));

                    if (XMLActorDefReader.Definitions.Count > 0)
                    {
                        /* Create remaining XML-related objects */
                        XMLActorNames = new XMLHashTableReader(System.IO.Path.Combine("XML", "GameDataGeneric", GameID.Substring(1, 2)), "ActorNames.xml");
                        XMLObjectNames = new XMLHashTableReader(System.IO.Path.Combine("XML", "GameDataGeneric", GameID.Substring(1, 2)), "ObjectNames.xml");
                        XMLSongNames = new XMLHashTableReader(System.IO.Path.Combine("XML", "GameDataGeneric", GameID.Substring(1, 2)), "SongNames.xml");

                        XMLSceneNames = new XMLHashTableReader(System.IO.Path.Combine("XML", "GameDataSpecific", string.Format("{0}{1:X1}", GameID, Version)), "SceneNames.xml");
                        XMLRoomNames = new XMLHashTableReader(System.IO.Path.Combine("XML", "GameDataSpecific", string.Format("{0}{1:X1}", GameID, Version)), "RoomNames.xml");
                        XMLStageDescriptions = new XMLHashTableReader(System.IO.Path.Combine("XML", "GameDataSpecific", string.Format("{0}{1:X1}", GameID, Version)), "StageDescriptions.xml");

                        /* Determine if ROM uses z64tables hack */
                        HasZ64TablesHack = (Version == 15 && Endian.SwapUInt32(BitConverter.ToUInt32(Data, 0x1238)) != 0x0C00084C);

                        /* Find and read build information, DMA table, etc. */
                        FindBuildInfo();
                        FindFileNameTable();
                        ReadDMATable();
                        ReadFileNameTable();

                        /* Try to identify files */
                        foreach (DMATableEntry dte in Files) dte.Identify(this);

                        /* Find the code file */
                        FindCodeFile();

                        /* Find other Zelda-specific stuff */
                        FindActorTable();
                        FindObjectTable();
                        FindSceneTable();
                        ReadEntranceTable();

                        /* Some sanity checking & exception handling*/
                        if (Scenes == null || Scenes.Count == 0) throw new ROMHandlerException("No valid scenes could be recognized in the ROM.");

                        /* Done */
                        Loaded = true;
                    }
                }
            }
            #if !DEBUG
            catch (Exception ex)
            {
                Loaded = false;
                if (MessageBox.Show(ex.Message + "\n\n" + "Show detailed information?", "Exception", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
                {
                    MessageBox.Show(ex.ToString(), "Exception Details", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
            #endif
        }