示例#1
0
        public void LoadVertices(long command)
        {
            int w0          = (int)(command >> 0x20);
            int numVertices = Utility.GetBits(w0, 12, 4);

            //int numVertices2 = Utility.GetBits(w0, 4, 16);
            tmpSegmentedPointer = (int)(command & 0xFFFFFFFF);
            if (!EmulationState.instance.AssertRead(tmpSegmentedPointer, numVertices * 0x10))
            {
                return;
            }
            EmulationState.RAMBank bank = EmulationState.instance.banks[tmpSegmentedPointer >> 0x18];
            for (int i = 0; i < numVertices; i++)
            {
                int offset = tmpSegmentedPointer + i * 0x10;
                if (vertexIndices.TryGetValue(offset, out tmpVertexIndices[i]))
                {
                    continue;
                }
                tmpVertexAddresses[i] = offset;
                tmpVertexIndices[i]   = tmpMaxVertex++;
                int o = offset & 0xFFFFFF;
                vertexAddresses[offset] = new Vertex(new DX.Vector3(cvt.int16(bank.value, o + 0), cvt.int16(bank.value, o + 2), cvt.int16(bank.value, o + 4)),
                                                     new DX.Vector2(Utility.Fixed2Float(cvt.int16(bank.value, o + 8), 5), Utility.Fixed2Float(cvt.int16(bank.value, o + 10), 5)),
                                                     new DX.Vector4((sbyte)bank.value[o + 12] / (float)sbyte.MaxValue, (sbyte)bank.value[o + 13] / (float)sbyte.MaxValue, (sbyte)bank.value[o + 14] / (float)sbyte.MaxValue, bank.value[o + 15] / 255f));
            }
        }
示例#2
0
        private void backgroundToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            EmulationState.RAMBank backgroundBank = EmulationState.instance.banks[0xA]; //0xA holds background images.
            if (backgroundBank == null)
            {
                EmulationState.messages.AppendMessage("No background bank loaded for this level.", "Information");
                return;
            }
            SaveFileDialog sfd = new SaveFileDialog();

            sfd.Filter = "image files|*.png";
            if (sfd.ShowDialog() != System.Windows.Forms.DialogResult.OK)
            {
                return;
            }

            Bitmap   final = new Bitmap(249, 249);
            Graphics g     = Graphics.FromImage(final);

            g.Clear(Color.Black);
            for (int x = 0; x < 8; x++)
            {
                for (int y = 0; y < 8; y++)
                {
                    Bitmap patch = SM64Renderer.ImageConverter.ReadRGBA16(backgroundBank.value, (x + y * 8) * 0x800, 32, 32);
                    g.DrawImage(patch, x * 31, y * 31);
                }
            }
            g.Flush();
            final.Save(sfd.FileName);
        }
示例#3
0
        public int Import(int segmentOffset)
        {
            foreach (Control ctrl in panelCollisionTypes.Controls)
            {
                CollisionTypeControl patchControl = ctrl as CollisionTypeControl;
                if (patchControl != null && !patchControl.enableImport)
                {
                    collision.patches.Remove(patchControl.patch);
                }
            }
            int totalSize = collision.GetLength();

            this.segmentOffset = segmentOffset;
            int segment      = segmentOffset >> 0x18;
            int offsetInBank = segmentOffset & 0xFFFFFF;

            EmulationState.RAMBank bank = EmulationState.instance.banks[segment];
            if (EmulationState.instance.AssertRead(segmentOffset, totalSize) && bank.compressed)
            {
                EmulationState.messages.AppendMessage("The selected bank 0x" + segment.ToString("X") + " is compressed in the ROM and can therefore not be altered.", "Error");
                return(-1);
            }
            collision.Write(ref bank.value, offsetInBank);

            Array.Copy(bank.value, offsetInBank, EmulationState.instance.ROM, bank.ROMStart + offsetInBank, totalSize);
            pointerControl1.WritePointers(segmentOffset);
            specialPointerControl1.WritePointers(segmentOffset);
            return(segmentOffset + totalSize);
        }
示例#4
0
        public int Import(int segmentOffset)
        {
            this.segmentOffset = segmentOffset;
            UpdateAll();
            int segment = segmentOffset >> 0x18;

            EmulationState.RAMBank bank = EmulationState.instance.banks[segment];
            if (!EmulationState.instance.AssertRead(segmentOffset, totalSize))
            {
                return(-1);
            }
            if (bank.compressed)
            {
                EmulationState.messages.AppendMessage("The selected bank 0x" + segment.ToString("X") + " is compressed in the ROM and can therefore not be altered.", "Error");
                return(-1);
            }
            WriteVertices();
            WriteCommands();
            int offsetInBank = segmentOffset & 0xFFFFFF;

            for (int i = 0; i < displayList.lightValues.Length; i++)
            {
                cvt.writeInt32(bank.value, offsetInBank + 0x20 * i, displayList.lightValues[i].color);
                cvt.writeInt32(bank.value, offsetInBank + 0x20 * i + 4, displayList.lightValues[i].color);
                cvt.writeInt32(bank.value, offsetInBank + 0x20 * i + 8, displayList.lightValues[i].direction);
                cvt.writeInt32(bank.value, offsetInBank + 0x20 * i + 0xC, displayList.lightValues[i].ambient);


                cvt.writeInt32(bank.value, offsetInBank + 0x20 * i + 0x10, 0x7f7f7fFF); //displayList.lightValues[i].color);
                cvt.writeInt32(bank.value, offsetInBank + 0x20 * i + 0x14, 0x7f7f7fFF); //displayList.lightValues[i].color);
                cvt.writeInt32(bank.value, offsetInBank + 0x20 * i + 0x18, displayList.lightValues[i].direction);
                cvt.writeInt32(bank.value, offsetInBank + 0x20 * i + 0x1C, displayList.lightValues[i].ambient);
            }

            Array.Copy(bank.value, offsetInBank, EmulationState.instance.ROM, bank.ROMStart + offsetInBank, totalSize);

            pointerControl.WritePointers(segmentOffset + commandOffset);
            foreach (Subset subset in displayList.subsets)
            {
                int    value    = subset.Texture.scrollingTextureRelativePointer + segmentOffset + commandOffset;
                byte[] ptrValue = new byte[] { (byte)(value >> 0x18), (byte)((value & 0xFF0000) >> 0x10), (byte)((value & 0xFF00) >> 0x8), (byte)(value & 0xFF) };
                foreach (int ptr in subset.Texture.stRAMPointers)
                {
                    if (EmulationState.instance.AssertWrite(ptr, 4))
                    {
                        Array.Copy(ptrValue, 0, EmulationState.instance.ROM, EmulationState.instance.banks[ptr >> 0x18].ROMStart + (ptr & 0xFFFFFF), 4);
                    }
                }
                foreach (int ptr in subset.Texture.stROMPointers)
                {
                    if (EmulationState.instance.AssertWrite(ptr, 4))
                    {
                        Array.Copy(ptrValue, 0, EmulationState.instance.ROM, ptr, 4);
                    }
                }
            }
            return(segmentOffset + totalSize);
        }
示例#5
0
        void ExportBank(EmulationState.RAMBank bank)
        {
            SaveFileDialog dlg = new SaveFileDialog();

            if (dlg.ShowDialog() != System.Windows.Forms.DialogResult.OK)
            {
                return;
            }
            System.IO.File.WriteAllBytes(dlg.FileName, bank.value);
        }
示例#6
0
        public void WriteBytes(ref int cursor)
        {
            EmulationState.RAMBank target = EmulationState.instance.banks[segmentOffset >> 0x18];
            int cursorInBank = cursor & 0xFFFFFF;
            int bank         = (int)(cursor & 0xFF000000);

            if (target == null)
            {
                throw new Exception("Bad Texture");
            }
            ImageConverter.ConvertRGBA(format, bpp, file, target.value, ref cursorInBank);
            cursor = bank | cursorInBank;
        }
示例#7
0
        public void UpdateCustom()
        {
            int segmentNumber = customAddress >> 0x18;

            EmulationState.RAMBank bank = EmulationState.instance.banks[segmentNumber];
            if (bank == null || !EmulationState.instance.AssertRead(customAddress, customWidth * customHeight * (4 << (int)customBpp)))
            {
                rom = new Bitmap(customWidth, customHeight);
            }
            else
            {
                rom = ImageConverter.ReadRGBA16(bank.value, customAddress & 0xFFFFFF, customWidth, customHeight);
            }
            UpdateSizeInfo();
        }
示例#8
0
        public void SetCustomAddress(int newAddress)
        {
            int segmentNumber = newAddress >> 0x18;

            if (segmentNumber >= EmulationState.instance.banks.Length || segmentNumber < 0)
            {
                return;
            }
            EmulationState.RAMBank bank = EmulationState.instance.banks[newAddress >> 0x18];
            if (bank == null)
            {
                return;
            }
            customAddress = newAddress;
            UpdateCustom();
        }
示例#9
0
        void WriteCommands()
        {
            int segment = segmentOffset >> 0x18;

            EmulationState.RAMBank target = EmulationState.instance.banks[segment];
            if (target == null)
            {
                throw new Exception("Bad commands");
            }

            int cursor = (segmentOffset & 0xFFFFFF) + commandOffset;

            foreach (DisplayList.Command cmd in displayList.commands)
            {
                Array.Copy(cmd.values, 0, target.value, cursor, cmd.values.Length);
                cursor += cmd.values.Length;
            }
        }
示例#10
0
        public static DisplayList Read(int segmentedPointer, EmulationState state, TextureManager texMan)
        {
            StringBuilder     log    = new StringBuilder();
            DisplayListReader reader = new DisplayListReader();

            reader.output = new DisplayList(texMan);
            int bank   = segmentedPointer >> 0x18;
            int offset = segmentedPointer & 0xFFFFFF;

            if (!state.AssertRead(segmentedPointer, 8))
            {
                return(null);
            }
            EmulationState.RAMBank b = state.banks[bank];
            reader.cursor    = segmentedPointer;
            reader.callStack = new Stack <int>();
            long currentCommand;

            do
            {
                b              = state.banks[reader.cursor >> 0x18];
                offset         = reader.cursor & 0xFFFFFF;
                currentCommand = ((long)cvt.uint32(b.value, offset) << 0x20) | (long)cvt.uint32(b.value, offset + 4);
                byte commandByte = b.value[offset];
                DisplayListCommand cmd;
                if (commands.TryGetValue(commandByte, out cmd))
                {
                    cmd(reader, currentCommand);
                }
                else
                {
                    log.Append("Skipped command " + Enum.GetName(typeof(GBI), commandByte) + " - " + currentCommand.ToString("X16") + "\n");
                }

                reader.cursor += 8;
            } while (!reader.terminated);

            System.Diagnostics.Debug.WriteLine(log.ToString());
            return(reader.output);
        }
示例#11
0
        public void WriteBytes(int texMulX, int texMulY)
        {
            int segment = segmentedPointer >> 0x18;

            EmulationState.RAMBank target = EmulationState.instance.banks[segment];
            if (target == null)
            {
                throw new Exception("Bad Vertex Data");
            }

            int i      = 0;
            int cursor = segmentedPointer & 0xFFFFFF;

            byte[] bytes = target.value;
            foreach (Vertex v in vertices)
            {
                byte[] b = BitConverter.GetBytes(v.x);
                bytes[cursor + 1] = b[0]; bytes[cursor + 0] = b[1];
                b = BitConverter.GetBytes(v.y);
                bytes[cursor + 3] = b[0]; bytes[cursor + 2] = b[1];
                b = BitConverter.GetBytes(v.z);
                bytes[cursor + 5] = b[0]; bytes[cursor + 4] = b[1];
                b = BitConverter.GetBytes((short)(v.u * texMulX * (1 << 5)));
                bytes[cursor + 9] = b[0]; bytes[cursor + 8] = b[1];
                b = BitConverter.GetBytes((short)(v.v * texMulY * (1 << 5)));
                bytes[cursor + 0xB] = b[0]; bytes[cursor + 0xA] = b[1];
                bytes[cursor + 0xC] = (byte)v.nx;
                bytes[cursor + 0xD] = (byte)v.ny;
                bytes[cursor + 0xE] = (byte)v.nz;
                bytes[cursor + 0xF] = v.c;
                cursor += 0x10;
                if (i++ >= numVertices)
                {
                    break;
                }
            }
        }
示例#12
0
        private void btnImport_Click(object sender, EventArgs e)
        {
            if (!EmulationState.instance.AssertWrite(segmentedAddress, 1))
            {
                return;
            }

            EmulationState.instance.RefreshROM();
            int numObjects = 0;

            foreach (TabPage page in tabImports.TabPages)
            {
                foreach (Control c in page.Controls[0].Controls)
                {
                    Importable import = c as Importable;
                    if (import != null)
                    {
                        if (import.PrepareForImport() == -1)
                        {
                            EmulationState.messages.AppendMessage("Import failed.", "Error");
                            return;
                        }
                        numObjects++;
                    }
                }
            }

            StringBuilder log    = new StringBuilder();
            int           cursor = segmentedAddress;

            cursor = globalsControl.Import(cursor);

            foreach (KeyValuePair <string, TextureImage> texture in textureLibrary.textures)
            {
                texture.Value.segmentOffset = cursor;
                texture.Value.WriteBytes(ref cursor);
                cursor = (cursor + 7) / 8 * 8;
            }
            int offsetInBank = segmentedAddress & 0xFFFFFF;

            EmulationState.RAMBank bank = EmulationState.instance.banks[segmentedAddress >> 0x18];
            Array.Copy(bank.value, offsetInBank, EmulationState.instance.ROM, bank.ROMStart + offsetInBank, cursor - segmentedAddress);

            foreach (TabPage page in tabImports.TabPages)
            {
                foreach (Control c in page.Controls[0].Controls)
                {
                    Importable import = c as Importable;
                    if (import != null)
                    {
                        int newCursor = import.Import(cursor);
                        if (newCursor == -1)
                        {
                            EmulationState.messages.AppendMessage("Import failed.", "Error");
                            return;
                        }
                        else if (newCursor != 0)
                        {
                            cursor = newCursor;
                        }
                    }
                }
            }
            File.WriteAllBytes(EmulationState.instance.ROMName, EmulationState.instance.ROM);
            PatchEngine.RecalculateChecksum();
            EmulationState.messages.AppendMessage("Imported " + numObjects + " objects.", "Info");
        }