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)); } }
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); }
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); }
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); }
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); }
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; }
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(); }
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(); }
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; } }
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); }
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; } } }
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"); }