// assemblers private void Disassemble() { animationOffset = Bits.GetInt24(rom, 0x252000 + (index * 3)) - 0xC00000; int animationLength = Bits.GetShort(rom, animationOffset); buffer = Bits.GetBytes(rom, animationOffset, animationLength); // int offset = 2; ushort sequencePacketPointer = Bits.GetShort(buffer, offset); offset += 2; ushort moldPacketPointer = Bits.GetShort(buffer, offset); offset += 2; byte sequenceCount = buffer[offset++]; byte moldCount = buffer[offset++]; vramAllocation = (ushort)(buffer[offset] << 8); offset += 2; unknown = Bits.GetShort(buffer, offset); // offset = sequencePacketPointer; for (int i = 0; i < sequenceCount; i++) { Sequence tSequence = new Sequence(); tSequence.Disassemble(buffer, offset); sequences.Add(tSequence); offset += 2; } offset = moldPacketPointer; for (int i = 0; i < moldCount; i++) { Mold tMold = new Mold(); tMold.Disassemble(buffer, offset, uniqueTiles, index, animationOffset); molds.Add(tMold); offset += 2; } }
public void SetScreenImages() { if (MinecartData == null) { return; } screenImages = new List <Bitmap>(); for (int i = 0; i < L1Indexes.Count; i++) { if (L1Indexes[i] < 16) { byte[] tilemapL1 = Bits.GetBytes(Model.MinecartSSTilemap, L1Indexes[i] * 256, 256); byte[] tilemapL2; if (Index == 2) { tilemapL2 = Bits.GetBytes(Model.MinecartSSTilemap, L2Indexes[i] * 256, 256); } else { tilemapL2 = new byte[256]; } SideTilemap tilemap = new SideTilemap(tilemapL1, tilemapL2, tileset, paletteSet); Bitmap screenImage = Do.PixelsToImage(tilemap.Pixels, 256, 256); screenImages.Add(new Bitmap(screenImage)); } else { screenImages.Add(new Bitmap(256, 256)); } } pictureBoxScreens.Invalidate(); }
// main title tileset public Tileset(PaletteSet paletteSet, string type) { this.paletteSet = paletteSet; this.Width = 16; this.Height = 32; this.HeightL3 = 6; this.tilesize = 2; this.Type = TilesetType.Title; // Decompress data at offsets tilesets_bytes[0] = Bits.GetBytes(Model.TitleData, 0x0000, 0x1000); tilesets_bytes[1] = Bits.GetBytes(Model.TitleData, 0x1000, 0x1000); tilesets_bytes[2] = Bits.GetBytes(Model.TitleData, 0xBBE0, 0x300); // Create buffer the size of the combined graphicSets graphics = Bits.GetBytes(Model.TitleData, 0x6C00, 0x4FE0); graphicsL3 = Bits.GetBytes(Model.TitleData, 0xBEA0, 0x1BC0); // tilesets_tiles[0] = new Tile[16 * 32]; tilesets_tiles[1] = new Tile[16 * 32]; tilesets_tiles[2] = new Tile[16 * 6]; for (int i = 0; i < tilesets_tiles[0].Length; i++) { tilesets_tiles[0][i] = new Tile(i); } for (int i = 0; i < tilesets_tiles[1].Length; i++) { tilesets_tiles[1][i] = new Tile(i); } for (int i = 0; i < tilesets_tiles[2].Length; i++) { tilesets_tiles[2][i] = new Tile(i); } DrawTileset(tilesets_bytes[0], tilesets_tiles[0], graphics, 0x20); DrawTileset(tilesets_bytes[1], tilesets_tiles[1], graphics, 0x20); DrawTileset(tilesets_bytes[2], tilesets_tiles[2], graphicsL3, 0x20); }
public void SetScreenImage() { if (MinecartData == null) { return; } if (screenIndex >= L1Indexes.Count) { return; } if (L1Indexes[screenIndex] < 16) { byte[] tilemapL1 = Bits.GetBytes(Model.MinecartSSTilemap, L1Indexes[screenIndex] * 256, 256); byte[] tilemapL2; if (Index == 2) { tilemapL2 = Bits.GetBytes(Model.MinecartSSTilemap, L2Indexes[screenIndex] * 256, 256); } else { tilemapL2 = new byte[256]; } SideTilemap tilemap = new SideTilemap(tilemapL1, tilemapL2, tileset, paletteSet); screenImages[screenIndex] = Do.PixelsToImage(tilemap.Pixels, 256, 256); } else { screenImages[screenIndex] = new Bitmap(256, 256); } pictureBoxScreens.Invalidate(); }
private void fillWith_KeyDown(object sender, KeyEventArgs e) { if (e.KeyData != Keys.Enter) { return; } if (currentROMData.SelectionLength < 3) { return; } int column = ROMData.SelectionStart / 3; byte value; try { value = Convert.ToByte(fillWith.Text, 16); byte[] values = new byte[currentROMData.SelectionLength / 3]; Bits.Fill(values, value); oldProperties.Add(new Change(offset + column, Bits.GetBytes(current, offset + column, values.Length), Color.Red)); Bits.Fill(current, value, offset + column, values.Length); } catch { return; } RefreshHexEditor(); }
// assemblers private void Disassemble() { animationOffset = Bits.GetInt24(rom, 0x252C00 + (index * 3)) - 0xC00000; ushort animationLength = Bits.GetShort(rom, animationOffset); buffer = Bits.GetBytes(rom, animationOffset, Bits.GetShort(rom, animationOffset)); // int offset = 2; ushort graphicSetPointer = Bits.GetShort(buffer, offset); offset += 2; ushort paletteSetPointer = Bits.GetShort(buffer, offset); offset += 2; ushort sequencePacketPointer = Bits.GetShort(buffer, offset); offset += 2; ushort moldPacketPointer = Bits.GetShort(buffer, offset); offset += 2; // skip 2 unknown bytes offset += 2; // width = buffer[offset++]; height = buffer[offset++]; codec = Bits.GetShort(buffer, offset); offset += 2; // int tileSetPointer = Bits.GetShort(buffer, offset); graphicSetLength = paletteSetPointer - graphicSetPointer; graphicSet = new byte[0x2000]; Buffer.BlockCopy(buffer, graphicSetPointer, graphicSet, 0, graphicSetLength); paletteSetLength = (ushort)(tileSetPointer - paletteSetPointer); paletteSet = new PaletteSet(buffer, 0, paletteSetPointer, 8, 16, 32); tilesetLength = sequencePacketPointer - tileSetPointer - 2; tileset_bytes = new byte[64 * 4 * 2 * 4]; Buffer.BlockCopy(buffer, tileSetPointer, tileset_bytes, 0, tilesetLength); // offset = sequencePacketPointer; for (int i = 0; Bits.GetShort(buffer, offset) != 0x0000; i++) { E_Sequence tSequence = new E_Sequence(); tSequence.Disassemble(buffer, offset); sequences.Add(tSequence); offset += 2; } offset = moldPacketPointer; ushort end = 0; for (int i = 0; Bits.GetShort(buffer, offset) != 0x0000; i++) { if (Bits.GetShort(buffer, offset + 2) == 0x0000) { end = animationLength; } else { end = Bits.GetShort(buffer, offset + 2); } E_Mold tMold = new E_Mold(); tMold.Disassemble(buffer, offset, end); molds.Add(tMold); offset += 2; } }
public static byte[] BRRToWAV(byte[] inBrr, int rate, int loopStart) { if (inBrr == null) { inBrr = new byte[9]; } p1 = 0; p2 = 0; short[] samples = new short[0]; byte[] BRR = new byte[9]; int size = (int)inBrr.Length; //if (size % 9 != 0) //{ // MessageBox.Show("Error : BRR file isn't a multiple of 9 bytes or is too big."); // return null; //} int blockamount = size / 9; int offset = 0; size = 0; for (int i = 0; i < blockamount; i++) { BRR = Bits.GetBytes(inBrr, offset, 9); offset += 9; samples = append(samples, DecodeBRR(BRR)); //Append 16 BRR samples to existing array size += 16; } // int position = loopStart / 9 * 16; if (position >= size) { position = 0; } size -= position; // byte[] outWav = new byte[(size << 1) + 44]; offset = 0; Bits.SetChars(outWav, offset, "RIFF".ToCharArray()); offset += 4; Bits.SetInt32(outWav, offset, (size << 1) + 36); offset += 4; Bits.SetChars(outWav, offset, "WAVEfmt ".ToCharArray()); offset += 8; Bits.SetInt32(outWav, offset, 16); offset += 4; Bits.SetShort(outWav, offset, 1); offset += 2; Bits.SetShort(outWav, offset, 1); offset += 2; Bits.SetInt32(outWav, offset, rate); offset += 4; Bits.SetInt32(outWav, offset, rate * 2); offset += 4; Bits.SetShort(outWav, offset, 2); offset += 2; Bits.SetShort(outWav, offset, 16); offset += 2; Bits.SetChars(outWav, offset, "data".ToCharArray()); offset += 4; Bits.SetInt32(outWav, offset, size << 1); offset += 4; // for (int i = position; i < size + position; i++) { Bits.SetShort(outWav, offset, samples[i]); offset += 2; } return(outWav); }
private void copy_Click(object sender, EventArgs e) { if (ROMData.SelectionLength < 3) { return; } int column = ROMData.SelectionStart / 3; clipboard = Bits.GetBytes(rom, offset + column, ROMData.SelectionLength / 3); }
private void paste_Click(object sender, EventArgs e) { int column = ROMData.SelectionStart / 3; if (offset + column + clipboard.Length >= 0x400000) { return; } oldProperties.Add(new Change(offset + column, Bits.GetBytes(current, offset + column, clipboard.Length), Color.Red)); Bits.SetBytes(current, offset + column, clipboard); RefreshHexEditor(); }
private void redo_Click(object sender, EventArgs e) { if (newProperties.Count == 0) { return; } int offset = newProperties[newProperties.Count - 1].Offset; byte[] newValues = newProperties[newProperties.Count - 1].Values; newProperties.RemoveAt(newProperties.Count - 1); byte[] oldValues = Bits.GetBytes(current, offset, newValues.Length); oldProperties.Add(new Change(offset, oldValues, Color.Red)); Bits.SetBytes(current, offset, newValues); RefreshHexEditor(); }
// assemblers private void Disassemble() { int offset = Bits.GetInt24(rom, index * 3 + 0x042333); if (offset == 0) { return; } offset -= 0xC00000; int size = Bits.GetShort(rom, offset); offset += 2; sample = Bits.GetBytes(rom, offset, size); loopStart = Bits.GetShort(rom, index * 2 + 0x04248F); relGain = (short)Bits.GetShort(rom, index * 2 + 0x042577); relFreq = (short)Bits.GetShort(rom, index * 2 + 0x04265F); }
// event handlers private void browseFreshRom_Click(object sender, EventArgs e) { OpenFileDialog openFileDialog1 = new OpenFileDialog(); openFileDialog1.InitialDirectory = settings.LastRomPath; openFileDialog1.Title = "Select a SMRPG ROM"; openFileDialog1.Filter = "SMC files (*.SMC)|*.SMC|All files (*.*)|*.*"; openFileDialog1.FilterIndex = 2; openFileDialog1.RestoreDirectory = true; if (openFileDialog1.ShowDialog() != DialogResult.Cancel) { Retry: try { FileInfo fInfo = new FileInfo(openFileDialog1.FileName); long numBytes = fInfo.Length; FileStream fStream = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fStream); byte[] temp = br.ReadBytes((int)numBytes); br.Close(); fStream.Close(); // remove header if it has one if ((temp.Length & 0x200) == 0x200) { temp = Bits.GetBytes(temp, 0x200); } // Check if valid rom System.Text.Encoding encoding = System.Text.Encoding.UTF8; if (encoding.GetString(Bits.GetBytes(temp, 0x7FB2, 4)) != "ARWE") { MessageBox.Show("The game code for this ROM is invalid.", "LAZY SHELL"); return; } romSrc = temp; freshRomTextBox.Text = openFileDialog1.FileName; buttonOK.Enabled = true; } catch (Exception ex) { if (MessageBox.Show("Lazy Shell was unable to load the rom.\n\n" + ex.Message, "LAZY SHELL", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error) != DialogResult.Cancel) { goto Retry; } } } }
// assemblers private void Disassemble() { int offset; if (type == 0) { offset = index * 4 + 0x042826; } else { offset = index * 4 + 0x043E26; } // activeChannels = new bool[2]; channels = new List <SPCCommand> [2]; for (int i = 0; i < 2; i++) { channels[i] = new List <SPCCommand>(); int soundOffset = Bits.GetShort(Model.ROM, offset); offset += 2; if (soundOffset == 0) { activeChannels[i] = false; continue; } activeChannels[i] = true; if (type == 0) { soundOffset = soundOffset - 0x3400 + 0x042C26; } else { soundOffset = soundOffset - 0x3400 + 0x044226; } int length = 0; do { soundOffset += length; int opcode = rom[soundOffset]; length = SPCScriptEnums.CommandLengths[opcode]; byte[] commandData = Bits.GetBytes(rom, soundOffset, length); channels[i].Add(new SPCCommand(commandData, this, i)); }while (rom[soundOffset] != 0xD0 && rom[soundOffset] != 0xCD && rom[soundOffset] != 0xCE); } }
public int[] GetTilesetPixels() { int offset = image * 4 + 0x251800; int bank = (int)(((rom[offset] & 0x0F) << 16) + 0x280000); int graphicOffset = (int)((Bits.GetShort(rom, offset) & 0xFFF0) + bank); offset += 2; // byte[] graphics = Bits.GetBytes(rom, graphicOffset, 0x4000); int[] palette = Palette; Animation animation = Model.Animations[animationPacket]; Mold mold = animation.Molds[0]; foreach (Mold.Tile tile in mold.Tiles) { tile.DrawSubtiles(graphics, palette, mold.Gridplane); } // return(animation.TilesetPixels()); }
// assemblers private void Disassemble() { switch (type) { case FontType.Menu: // menu font width = (byte)rom[index + 0x249300]; maxWidth = 8; height = 12; graphics = Bits.GetBytes(rom, index * 0x18 + 0x249400, 0x18); break; case FontType.Dialogue: // dialogue font width = (byte)rom[index + 0x249280]; maxWidth = 16; height = 12; graphics = Bits.GetBytes(rom, index * 0x30 + 0x37C000, 0x30); break; case FontType.Description: // description font width = (byte)rom[index + 0x249380]; maxWidth = 8; height = 8; graphics = Bits.GetBytes(rom, index * 0x10 + 0x37D800, 0x10); break; case FontType.Triangles: // triangles if (index < 7) { width = maxWidth = 8; height = 16; } else { width = maxWidth = 16; height = 8; } graphics = Bits.GetBytes(rom, index * 0x20 + 0x3DFA00, 0x20); break; case FontType.BattleMenu: // battle menu font width = 8; maxWidth = 8; height = 8; graphics = Bits.GetBytes(Model.BattleMenuGraphics, index * 0x20, 0x20); break; case FontType.FlowerBonus: // flower bonus font width = 8; maxWidth = 8; height = 8; graphics = Bits.GetBytes(Model.BonusFontGraphics, index * 0x20, 0x20); break; } }
// assemblers private void Disassemble() { int offset = Bits.GetInt24(rom, index * 3 + 0x042748) - 0xC00000; delayTime = rom[offset++]; decayFactor = rom[offset++]; echo = rom[offset++]; samples = new SampleIndex[20]; int i = 0; while (rom[offset] != 0xFF && i < 20) { samples[i++] = new SampleIndex(rom[offset++], rom[offset++]); } offset++; Length = Bits.GetShort(rom, offset); offset += 2; spcData = Bits.GetBytes(rom, offset, Length); // CreateCommands(); }
public void CreateCommands() { int offset = 0; percussives = new List <Percussives>(); while (spcData[offset] != 0xFF) { percussives.Add(new Percussives(spcData[offset++], spcData[offset++], spcData[offset++], spcData[offset++], spcData[offset++])); } offset++; // now disassemble the scripts for each channel activeChannels = new bool[8]; channels = new List <SPCCommand> [8]; for (int i = 0; i < 8; i++) { channels[i] = new List <SPCCommand>(); int spcOffset = Bits.GetShort(spcData, offset); offset += 2; if (spcOffset == 0) { activeChannels[i] = false; continue; } activeChannels[i] = true; spcOffset -= 0x2000; int length = 0; do { spcOffset += length; int opcode = spcData[spcOffset]; length = SPCScriptEnums.CommandLengths[opcode]; byte[] commandData = Bits.GetBytes(spcData, spcOffset, length); channels[i].Add(new SPCCommand(commandData, this, i)); }while (spcData[spcOffset] != 0xD0 && spcData[spcOffset] != 0xCE); } }
// constructor public Opening(Intro intro) { this.intro = intro; // openingTileset = Bits.GetBytes(Model.OpeningData, 0, 0x480); openingGraphics = Bits.GetBytes(Model.OpeningData, 0x480); tileset = new Tileset(openingTileset, openingGraphics, paletteSet, 16, 9, TilesetType.Opening); InitializeComponent(); if (Model.ROM[0x00087D] == 0xEA && Model.ROM[0x00087E] == 0xEA && Model.ROM[0x00087F] == 0xEA && Model.ROM[0x000880] == 0xEA) { disableGardenLoad.Checked = true; } if (Model.ROM[0x034872] == 0x4C && Model.ROM[0x034873] == 0x44 && Model.ROM[0x034874] == 0x00) { disableGardenNew.Checked = true; } // SetTilesetImage(); }
// accessor functions public byte[] Graphics(byte[] spriteGraphics) { return(Bits.GetBytes(spriteGraphics, graphicOffset - 0x280000, 0x4000)); }
// assemblers public void Disassemble(byte[] buffer, int offset, bool gridplane) { this.buffer = buffer; this.gridplane = gridplane; length = 0; if (offset >= buffer.Length) { return; } // if (gridplane) { format = (byte)buffer[offset++]; // is16bit = (format & 0x08) == 0x08; yPlusOne = (format & 0x10) == 0x10 ? (byte)1 : (byte)0; yMinusOne = (format & 0x20) == 0x20 ? (byte)1 : (byte)0; mirror = (format & 0x40) == 0x40; invert = (format & 0x80) == 0x80; length++; // format &= 3; // int subtiles16bit = 0; if (is16bit) { subtiles16bit = Bits.GetShort(buffer, offset); offset += 2; length += 2; } // byte[] temp; switch (format) { case 0: temp = Bits.GetBytes(buffer, offset, 9); length += 9; break; case 1: temp = Bits.GetBytes(buffer, offset, 12); length += 12; break; case 2: temp = Bits.GetBytes(buffer, offset, 12); length += 12; break; case 3: temp = Bits.GetBytes(buffer, offset, 16); length += 16; break; default: goto case 0; } subtile_bytes = new ushort[16]; for (int i = 0; i < 16; i++) { subtile_bytes[i] = 1; } temp.CopyTo(subtile_bytes, 0); if (is16bit) { for (int i = 0, b = 1; i < temp.Length; i++, b *= 2) { if ((subtiles16bit & b) == b) { subtile_bytes[i] += 0x100; } } } } else { format = (byte)(buffer[offset] & 0x0F); mirror = (format & 0x04) == 0x04; invert = (format & 0x08) == 0x08; format &= 3; // Set active quadrants bool[] quadrants = new bool[4]; for (int i = 0, b = 128; i < 4; i++, b /= 2) { quadrants[i] = (buffer[offset] & b) == b; } // offset++; length++; y = (byte)(buffer[offset] ^ 0x80); offset++; length++; x = (byte)(buffer[offset] ^ 0x80); offset++; length++; // Set the subtiles subtile_bytes = new ushort[4]; for (int i = 0; i < 4; i++) { if (quadrants[i]) { if (format == 1) { subtile_bytes[i] = (ushort)(Bits.GetShort(buffer, offset) & 0x1FF); offset++; length++; } else { subtile_bytes[i] = (ushort)buffer[offset]; } offset++; length++; } } } }
// accessor functions /// <summary> /// Creates a pixel array of the sprite. /// </summary> /// <param name="byMold">Create the pixels by mold index.</param> /// <param name="byFCoord">Create the pixels by facing index.</param> /// <param name="moldIndex">The index of the mold (ignored if byMold == false).</param> /// <param name="fCoord">The index of the facing (ignored if byFacing == false)</param> /// <param name="palette">If want to use a particular palette.</param> /// <param name="mirror">Mirror the sprite pixels.</param> /// <param name="crop">Crop the sprite pixels to their edges.</param> /// <returns></returns> public int[] GetPixels(bool byMold, bool byFCoord, int moldIndex, int fCoord, int[] palette, bool mirror, bool crop, ref Size size) { // set palette to use if (palette == null) { palette = Palette; } // get offsets int animationNum = Bits.GetShort(rom, this.index * 4 + 0x250002); int animationOffset = Bits.GetInt24(rom, 0x252000 + (animationNum * 3)) - 0xC00000; int animationLength = Bits.GetShort(rom, animationOffset); // get mold data byte[] sm = Bits.GetBytes(rom, animationOffset, animationLength); int offset = Bits.GetShort(sm, 2); if (byFCoord) { switch (fCoord) { case 0: mirror = !mirror; if (sm[6] < 13) { break; } offset += 24; break; case 1: mirror = !mirror; break; case 2: if (sm[6] < 11) { break; } offset += 20; break; case 4: if (sm[6] < 13) { break; } offset += 24; break; case 5: if (sm[6] < 2) { break; } offset += 2; break; case 6: if (sm[6] < 12) { break; } offset += 22; break; case 7: mirror = !mirror; if (sm[6] < 2) { break; } offset += 2; break; default: break; } } offset = Bits.GetShort(sm, offset); if (!byMold) { moldIndex = offset != 0xFFFF && sm[offset + 1] != 0 && sm[offset + 1] < sm[7] ? (int)sm[offset + 1] : 0; } offset = Bits.GetShort(sm, 4); offset += moldIndex * 2; // create mold from data Mold mold = new Mold(); mold.Disassemble(sm, offset, new List <Mold.Tile>(), animationNum, animationOffset); // generate subtiles in mold, then grab pixel array foreach (Mold.Tile t in mold.Tiles) { t.DrawSubtiles(Graphics, palette, mold.Gridplane); } int[] pixels = mold.MoldPixels(); // crop image int lowY = 0, highY = 0, lowX = 0, highX = 0; if (crop) { bool stop = false; for (int y = 0; y < 256 && !stop; y++) { for (int x = 0; x < 256; x++) { if (pixels[y * 256 + x] != 0) { lowY = y; lowX = x; stop = true; break; } } } stop = false; for (int y = 255; y >= 0 && !stop; y--) { for (int x = 255; x >= 0; x--) { if (pixels[y * 256 + x] != 0) { highY = y; highX = x; stop = true; break; } } } stop = false; for (int y = 0; y < 256; y++) { for (int x = 0; x < 256; x++) { if (pixels[y * 256 + x] != 0 && x < lowX) { lowX = x; break; } } } stop = false; for (int y = 255; y >= 0; y--) { for (int x = 255; x >= 0; x--) { if (pixels[y * 256 + x] != 0 && x > highX) { highX = x; break; } } } stop = false; highY++; highX++; } else { highY = 256; highX = 256; } int imageHeight = highY - lowY; int imageWidth = highX - lowX; if (crop) { int[] tempPixels = new int[imageWidth * imageHeight]; for (int y = 0; y < imageHeight; y++) { for (int x = 0; x < imageWidth; x++) { tempPixels[y * imageWidth + x] = pixels[(y + lowY) * 256 + x + lowX]; } } pixels = tempPixels; } int temp; if (mirror) { for (int y = 0; y < imageHeight; y++) { for (int a = 0, c = imageWidth - 1; a < imageWidth / 2; a++, c--) { temp = pixels[(y * imageWidth) + a]; pixels[(y * imageWidth) + a] = pixels[(y * imageWidth) + c]; pixels[(y * imageWidth) + c] = temp; } } } size = new Size(imageWidth, imageHeight); return(pixels); }