public void Assemble() { switch (type) { case FontType.Menu: // menu font rom[index + 0x249300] = width; Bits.SetBytes(rom, index * 0x18 + 0x249400, graphics); break; case FontType.Dialogue: // dialogue font rom[index + 0x249280] = width; Bits.SetBytes(rom, index * 0x30 + 0x37C000, graphics); break; case FontType.Description: // description font rom[index + 0x249380] = width; Bits.SetBytes(rom, index * 0x10 + 0x37D800, graphics); break; case FontType.Triangles: // triangles Bits.SetBytes(rom, index * 0x20 + 0x3DFA00, graphics); break; case FontType.BattleMenu: // battle menu font Bits.SetBytes(rom, index * 0x20, graphics); break; } }
private void Delete() { if (overlay.Select.Empty) { return; } if (tileset.Tileset == null || overlay.Select.Size == new Size(0, 0)) { return; } Point location = overlay.Select.Location; Point terminal = overlay.Select.Terminal; byte[] changes = new byte[(overlay.Select.Width / 16) * (overlay.Select.Height / 16)]; Bits.SetBytes(changes, 0xFF); commandStack.Push(new TilemapCommand( mold.Mold, width / 16, height / 16, changes, overlay.Select.X / 16, overlay.Select.Y / 16, overlay.Select.Width / 16, overlay.Select.Height / 16)); commandCount++; SetTilemapImage(); if (sequences != null) { sequences.SetSequenceFrameImages(); sequences.RealignFrames(); } animation.Assemble(); }
public void Assemble(ref int offset) { if (index == 0) { return; } //int offset = Bits.Get24Bit(data, index * 3 + 0x042748) - 0xC00000; Bits.SetInt24(rom, index * 3 + 0x42748, offset + 0xC00000); rom[offset++] = DelayTime; rom[offset++] = DecayFactor; rom[offset++] = Echo; foreach (SampleIndex sample in samples) { if (sample == null || !sample.Active) { continue; } rom[offset++] = (byte)sample.Sample; rom[offset++] = (byte)sample.Volume; } rom[offset++] = 0xFF; Bits.SetShort(rom, offset, Length); offset += 2; // AssembleSPCData(); Bits.SetBytes(rom, offset, spcData); offset += spcData.Length; }
public void Assemble() { fontPalettesDialogue.Assemble(); fontPalettesMenu.Assemble(); Bits.SetBit(Model.ROM, 0x3E2D6C, 7, true); Bits.SetBit(Model.ROM, 0x3E2D74, 7, true); foreach (FontCharacter f in fontMenu) { f.Assemble(); } foreach (FontCharacter f in fontDialogue) { f.Assemble(); } foreach (FontCharacter f in fontDescription) { f.Assemble(); } foreach (FontCharacter f in fontTriangle) { f.Assemble(); } Bits.SetBytes(rom, 0x3DF000, Model.DialogueGraphics, 0, 0x700); Bits.SetBytes(rom, 0x015943, Model.BattleDialogueTileset_bytes, 0, 0x100); // Bits.SetBytes(rom, 0x03F800, Model.NumeralGraphics, 0, 0x400); Model.NumeralPaletteSet.Assemble(); Buffer.BlockCopy(Model.BattleMenuGraphics, 0, rom, 0x1F200, 0x600); Buffer.BlockCopy(Model.BattleMenuGraphics, 0x600, rom, 0x1ED00, 0x140); Model.BattleMenuPalette.Assemble(); }
// tooltips public void Assemble() { Model.ROM[0x037DCF] = (byte)this.music.SelectedIndex; // Model.Compress(Model.WorldMapLogos, 0x3E004C, 0x2000, 0xE1C, "World map logos, banners"); // foreach (WorldMap wm in worldMaps) { wm.Assemble(); } // Graphics Model.WorldMapLogoPalette.Assemble(Model.MenuPalettes, 0xE0); int offset = Bits.GetShort(Model.ROM, 0x3E000C) + 0x3E0000; int maxComp = Bits.GetShort(Model.ROM, 0x3E000E) - Bits.GetShort(Model.ROM, 0x3E000C); Model.Compress(Model.MenuPalettes, offset, 0x200, maxComp, "World map logo palettes"); Model.Compress(Model.WorldMapGraphics, 0x3E2E81, 0x8000, 0x56F6, "Graphics"); // Model.Compress(Model.WorldMapSprites, 0x3E90A7, 0x400, 0x1F8, "Sprite Graphics"); // Tilesets byte[] compress = new byte[0x800]; int totalSize = 0; int pOffset = 0x3E0014; int dOffset = 0x3E929F; int size = 0; for (int i = 0; i < Model.WorldMapTilesets.Length; i++) { Bits.SetShort(Model.ROM, pOffset, (ushort)dOffset); size = Comp.Compress(Model.WorldMapTilesets[i], compress); totalSize += size + 1; if (totalSize > 0x4D8) { MessageBox.Show( "Recompressed tilesets exceed allotted ROM space by " + (totalSize - 0x4D6).ToString() + " bytes.\nSaving has been discontinued for tilesets " + i.ToString() + " and higher.\nChange or delete some tiles to reduce the size.", "LAZY SHELL"); break; } else { Model.ROM[dOffset] = 1; dOffset++; Bits.SetBytes(Model.ROM, dOffset, compress, 0, size - 1); dOffset += size; pOffset += 2; } } Bits.SetShort(Model.ROM, pOffset, (ushort)dOffset); Model.Compress(Model.WorldMapLogoTileset, dOffset, 0x800, 0xC1, "World map logo tileset"); // Palettes palettes.Assemble(Model.WorldMapPalettes, 0); Model.Compress(Model.WorldMapPalettes, 0x3E988C, 0x100, 0xD4, "Palette set"); foreach (Location mp in locations) { mp.Assemble(); } AssembleLocationTexts(); this.Modified = false; }
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(); }
public void AssembleSPCData() { int offset = 0; spcData = new byte[percussives.Count * 5 + 1]; foreach (Percussives percussive in percussives) { spcData[offset++] = (byte)percussive.PitchIndex; spcData[offset++] = percussive.Sample; spcData[offset++] = percussive.Pitch; spcData[offset++] = percussive.Volume; spcData[offset++] = percussive.Balance; } spcData[offset++] = 0xFF; int spcOffset = offset + 16; int length = spcOffset; for (int i = 0; i < channels.Length; i++) { if (activeChannels[i] && channels[i] != null) { foreach (SPCCommand ssc in channels[i]) { length += ssc.Length; } } } this.Length = length; Array.Resize <byte>(ref spcData, length); for (int i = 0; i < 8; i++) { if (activeChannels[i] && channels[i] != null) { Bits.SetShort(spcData, offset, spcOffset + 0x2000); } else { Bits.SetShort(spcData, offset, 0); } offset += 2; if (!activeChannels[i] || channels[i] == null) { continue; } foreach (SPCCommand ssc in channels[i]) { Bits.SetBytes(spcData, spcOffset, ssc.CommandData); spcOffset += ssc.Length; } } }
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(); }
private void Assemble() { int offset = 0; byte[] temp = new byte[0x700]; MenuTexts lastMenuText = null; foreach (MenuTexts menuText in Model.MenuTexts) { if (lastMenuText != null && menuText.Length != 0 && Bits.Compare(menuText.Text, lastMenuText.Text)) { Bits.SetShort(Model.ROM, menuText.Index * 2 + 0x3EEF00, lastMenuText.Offset); menuText.Offset = lastMenuText.Offset; continue; } if (offset + menuText.Length + 1 >= 0x700) { MessageBox.Show("Menu texts exceed allotted ROM space. Stopped saving at index " + menuText.Index + "."); break; } menuText.Offset = offset; lastMenuText = menuText; // Bits.SetShort(Model.ROM, menuText.Index * 2 + 0x3EEF00, offset); Bits.SetChars(temp, offset, menuText.Text); offset += menuText.Length; temp[offset++] = 0; switch (menuText.Index) { case 14: Bits.SetByteBits(Model.ROM, 0x03328E, (byte)(menuText.X * 2), 0x3F); break; case 15: Bits.SetByteBits(Model.ROM, 0x03327E, (byte)(menuText.X * 2), 0x3F); break; case 16: Bits.SetByteBits(Model.ROM, 0x033282, (byte)(menuText.X * 2), 0x3F); break; case 17: Bits.SetByteBits(Model.ROM, 0x033286, (byte)(menuText.X * 2), 0x3F); break; case 18: Bits.SetByteBits(Model.ROM, 0x03328A, (byte)(menuText.X * 2), 0x3F); break; case 19: Bits.SetByteBits(Model.ROM, 0x03327A, (byte)(menuText.X * 2), 0x3F); break; } } Bits.SetBytes(Model.ROM, 0x3EF000, temp); //Bits.SetShort(Model.Data, 0x3EF600, 0x344F); menus.Assemble(); menus.Modified = false; this.Modified = false; }
public void Assemble(ref int offset) { if (sample == null) { Bits.SetInt24(rom, index * 3 + 0x042333, 0); return; } Bits.SetInt24(rom, index * 3 + 0x042333, offset + 0xC00000); Bits.SetShort(rom, offset, sample.Length); offset += 2; Bits.SetBytes(rom, offset, sample); offset += sample.Length; // Bits.SetShort(rom, index * 2 + 0x04248F, loopStart); Bits.SetShort(rom, index * 2 + 0x042577, relGain); Bits.SetShort(rom, index * 2 + 0x04265F, relFreq); }
private void Assemble() { effect.Assemble(); animation.Assemble(); int i = 0; int pointer = 0x252C00; int offset = 0x330000; for (; i < 39 && offset < 0x33FFFF; i++, pointer += 3) { if (animations[i].BUFFER.Length + offset > 0x33FFFF) { break; } Bits.SetShort(Model.ROM, pointer, (ushort)offset); Bits.SetByte(Model.ROM, pointer + 2, (byte)((offset >> 16) + 0xC0)); Bits.SetBytes(Model.ROM, offset, animations[i].BUFFER); offset += animations[i].BUFFER.Length; } if (i < 39) { MessageBox.Show("The available space for animation data in bank 0x330000 has exceeded the alotted space.\nAnimation #'s " + i.ToString() + " through 38 will not saved. Please make sure the available animation bytes is not negative.", "LAZY SHELL"); } offset = 0x340000; for (; i < 64 && offset < 0x34CFFF; i++, pointer += 3) { if (animations[i].BUFFER.Length + offset > 0x34CFFF) { break; } Bits.SetShort(Model.ROM, pointer, (ushort)offset); Bits.SetByte(Model.ROM, pointer + 2, (byte)((offset >> 16) + 0xC0)); Bits.SetBytes(Model.ROM, offset, animations[i].BUFFER); offset += animations[i].BUFFER.Length; } if (i < 64) { MessageBox.Show("The available space for animation data in bank 0x340000 has exceeded the alotted space.\nAnimation #'s " + i.ToString() + " through 63 will not saved. Please make sure the available animation bytes is not negative.", "LAZY SHELL"); } molds.Modified = false; sequences.Modified = false; this.Modified = false; }
public byte[] Recompress(byte[] src, int width, int height) { byte[] dst = new byte[256]; // 256 max size for compressed int srcOffset = 0; int dstOffset = 0; while (srcOffset < width * height) { dst[dstOffset] = src[srcOffset]; // make a filler tile only if next TWO tiles are the same if (srcOffset < 0xFE && srcOffset + 1 < src.Length && srcOffset + 2 < src.Length && src[srcOffset] == src[srcOffset + 1] && src[srcOffset] == src[srcOffset + 2]) { dst[dstOffset] = 0xFE; dstOffset++; dst[dstOffset] = src[srcOffset]; // the tile to fill with byte counter = 1; while (srcOffset < 0xFF && srcOffset < src.Length && srcOffset + 1 < src.Length && src[srcOffset] == src[srcOffset + 1]) { counter++; srcOffset++; } dstOffset++; dst[dstOffset] = counter; // the amount to fill } srcOffset++; dstOffset++; } byte[] temp = new byte[dstOffset]; Bits.SetBytes(temp, 0, dst); return(temp); }
public void Assemble() { // set sm to new byte with largest possible size byte[] temp = new byte[0x10000]; // now start writing dynamic data temp[6] = (byte)sequences.Count; temp[7] = (byte)molds.Count; temp[8] = (byte)(vramAllocation >> 8); // Sequences int offset = 12; // where sequences begin Bits.SetShort(temp, 2, (ushort)0x0C); int fOffset = sequences.Count * 2 + 2; // offset of first frame packet foreach (Sequence s in sequences) { if (s.Frames.Count != 0 && s.Active) { Bits.SetShort(temp, offset, (ushort)(fOffset + offset)); fOffset += s.Frames.Count * 2 - 1; } else if (s.Active) { Bits.SetShort(temp, offset, (ushort)(fOffset + offset)); fOffset -= 1; } else { Bits.SetShort(temp, offset, 0xFFFF); fOffset -= 2; } offset += 2; } Bits.SetShort(temp, offset, 0); offset += 2; foreach (Sequence s in sequences) { foreach (Sequence.Frame f in s.Frames) { Bits.SetByte(temp, offset++, f.Duration); Bits.SetByte(temp, offset++, f.Mold); } if (s.Active) { Bits.SetByte(temp, offset++, 0); } } // Molds Bits.SetShort(temp, 4, (ushort)offset); int mOffset = molds.Count * 2 + 2; // offset of first mold tilemap foreach (Mold m in molds) { if (index == 162 && mOffset == 0x132) { index = 162; } if (m.Tiles.Count != 0) { if (m.Gridplane) { Bits.SetShort(temp, offset, (ushort)(mOffset + offset + 0x8000)); Mold.Tile tile = m.Tiles[0]; if (tile.Subtile_bytes != null) { mOffset += tile.Length - 2; } } else { Bits.SetShort(temp, offset, (ushort)(mOffset + offset)); mOffset += m.Recompress(mOffset + offset, molds).Length - 1; } } else { Bits.SetShort(temp, offset, (ushort)0xFFFF); mOffset -= 2; } offset += 2; } Bits.SetShort(temp, offset += 2, 0); foreach (Mold m in molds) { if (m.Tiles.Count == 0) { continue; } if (m.Gridplane) { Mold.Tile tile = m.Tiles[0]; if (tile.Subtile_bytes == null) { continue; } temp[offset] = (byte)(tile.Format & 3); Bits.SetBit(temp, offset, 3, tile.Is16bit); Bits.SetBit(temp, offset, 4, tile.YPlusOne == 1); Bits.SetBit(temp, offset, 5, tile.YMinusOne == 1); Bits.SetBit(temp, offset, 6, tile.Mirror); Bits.SetBit(temp, offset++, 7, tile.Invert); int size = tile.Is16bit ? tile.Length - 3 : tile.Length - 1; // set bits for tiles that are 16bit if (tile.Is16bit) { for (int i = 0; i < size; i++) { Bits.SetBit(temp, offset, i, tile.Subtile_bytes[i] >= 0x100); } offset += 2; } for (int i = 0; i < size; i++) { temp[offset++] = (byte)tile.Subtile_bytes[i]; } } else { byte[] mold = m.Recompress(offset, molds); mold.CopyTo(temp, offset); offset += mold.Length; temp[offset++] = 0; } } // finally, set the animation length Bits.SetShort(temp, 0, (ushort)offset); buffer = new byte[offset]; Bits.SetBytes(buffer, 0, temp); }
public void Assemble() { ProgressBar progressBar = new ProgressBar("ASSEMBLING ANIMATIONS...", animations.Length); progressBar.Show(); int i = 0; foreach (Animation sm in animations) { sm.Assemble(); progressBar.PerformStep("ASSEMBLING ANIMATION #" + i); i++; } progressBar.Close(); i = 0; int pointer = 0x252000; int offset = 0x259000; for (; i < 42 && offset < 0x25FFFF; i++, pointer += 3) { if (animations[i].BUFFER.Length + offset > 0x25FFFF) { break; } Bits.SetShort(rom, pointer, (ushort)offset); rom[pointer + 2] = (byte)((offset >> 16) + 0xC0); Bits.SetBytes(rom, offset, animations[i].BUFFER); offset += animations[i].BUFFER.Length; } if (i < 42) { MessageBox.Show("The available space for animation data in bank 0x250000 has exceeded the alotted space.\nAnimation #'s " + i.ToString() + " through 41 were not saved. Please make sure the available animation bytes is not negative.", "LAZY SHELL"); } offset = 0x260000; for (; i < 107 && offset < 0x26FFFF; i++, pointer += 3) { if (animations[i].BUFFER.Length + offset > 0x26FFFF) { break; } Bits.SetShort(rom, pointer, (ushort)offset); rom[pointer + 2] = (byte)((offset >> 16) + 0xC0); Bits.SetBytes(rom, offset, animations[i].BUFFER); offset += animations[i].BUFFER.Length; } if (i < 107) { MessageBox.Show("The available space for animation data in bank 0x260000 has exceeded the alotted space.\nAnimation #'s " + i.ToString() + " through 107 were not saved. Please make sure the available animation bytes is not negative.", "LAZY SHELL"); } offset = 0x270000; for (; i < 249 && offset < 0x27FFFF; i++, pointer += 3) { if (animations[i].BUFFER.Length + offset > 0x27FFFF) { break; } Bits.SetShort(rom, pointer, (ushort)offset); rom[pointer + 2] = (byte)((offset >> 16) + 0xC0); Bits.SetBytes(rom, offset, animations[i].BUFFER); offset += animations[i].BUFFER.Length; } if (i < 249) { MessageBox.Show("The available space for animation data in bank 0x270000 has exceeded the alotted space.\nAnimation #'s " + i.ToString() + " through 249 will not saved. Please make sure the available animation bytes is not negative.", "LAZY SHELL"); } offset = 0x360000; for (; i < 444 && offset < 0x36FFFF; i++, pointer += 3) { if (animations[i].BUFFER.Length + offset > 0x36FFFF) { break; } Bits.SetShort(rom, pointer, (ushort)offset); rom[pointer + 2] = (byte)((offset >> 16) + 0xC0); Bits.SetBytes(rom, offset, animations[i].BUFFER); offset += animations[i].BUFFER.Length; } if (i < 444) { MessageBox.Show("The available space for animation data in bank 0x360000 has exceeded the alotted space.\nAnimation #'s " + i.ToString() + " through 444 will not saved. Please make sure the available animation bytes is not negative.", "LAZY SHELL"); } foreach (Sprite s in sprites) { s.Assemble(); } foreach (ImagePacket gp in images) { gp.Assemble(); } foreach (PaletteSet p in palettes) { p.Assemble(0); } Buffer.BlockCopy(Model.SpriteGraphics, 0, rom, 0x280000, 0xB4000); Model.HexEditor.SetOffset(animation.AnimationOffset); Model.HexEditor.Compare(); molds.Modified = false; sequences.Modified = false; this.Modified = false; }
// public void Assemble() { Model.ROM[0x0393EF] = (byte)this.music.SelectedIndex; MinecartData.Assemble(); tilemap.Assemble(); Model.MinecartM7PaletteSet.Assemble(); Model.MinecartObjectPaletteSet.Assemble(); Model.MinecartSSPaletteSet.Assemble(); // int offset = 0x1E; byte[] dst = new byte[0x8000]; Bits.SetShort(dst, 0x00, offset); if (!Model.Compress(Model.MinecartM7Graphics, dst, ref offset, 0x8000 - 0x1E, "stage 1,3 graphics")) { return; } Bits.SetShort(dst, 0x02, offset); if (!Model.Compress(Model.MinecartM7TilesetSubtiles, dst, ref offset, 0x8000 - 0x1E, "stage 1,3 subtiles")) { return; } Bits.SetShort(dst, 0x04, offset); if (!Model.Compress(Model.MinecartM7Palettes, dst, ref offset, 0x8000 - 0x1E, "stage 1,3 palettes")) { return; } Bits.SetShort(dst, 0x06, offset); if (!Model.Compress(Model.MinecartM7TilesetPalettes, dst, ref offset, 0x8000 - 0x1E, "stage 1,3 subtile palettes")) { return; } Bits.SetShort(dst, 0x08, offset); if (!Model.Compress(Model.MinecartM7TilemapA, dst, ref offset, 0x8000 - 0x1E, "stage 1 tilemap")) { return; } Bits.SetShort(dst, 0x0A, offset); if (!Model.Compress(Model.MinecartM7TilemapB, dst, ref offset, 0x8000 - 0x1E, "stage 3 tilemap")) { return; } Bits.SetShort(dst, 0x0C, offset); if (!Model.Compress(Model.MinecartM7TilesetBG, dst, ref offset, 0x8000 - 0x1E, "stage 1,3 background tileset")) { return; } Bits.SetShort(dst, 0x0E, offset); if (!Model.Compress(Model.MinecartObjectGraphics, dst, ref offset, 0x8000 - 0x1E, "object graphics")) { return; } Bits.SetShort(dst, 0x10, offset); if (!Model.Compress(Model.MinecartObjectPalettes, dst, ref offset, 0x8000 - 0x1E, "object palettes")) { return; } Bits.SetShort(dst, 0x12, offset); if (!Model.Compress(Model.MinecartSSTilemap, dst, ref offset, 0x8000 - 0x1E, "stage 2,4 tilemap")) { return; } Bits.SetShort(dst, 0x14, offset); if (!Model.Compress(Model.MinecartSSGraphics, dst, ref offset, 0x8000 - 0x1E, "stage 2,4 graphics")) { return; } Bits.SetShort(dst, 0x16, offset); if (!Model.Compress(Model.MinecartSSTileset, dst, ref offset, 0x8000 - 0x1E, "stage 2,4 tileset")) { return; } Bits.SetShort(dst, 0x18, offset); if (!Model.Compress(Model.MinecartSSPalettes, dst, ref offset, 0x8000 - 0x1E, "stage 2,4 palettes")) { return; } Bits.SetShort(dst, 0x1A, offset); if (!Model.Compress(Model.MinecartSSBGTileset, dst, ref offset, 0x8000 - 0x1E, "stage 4 BG tileset")) { return; } Bits.SetShort(dst, 0x1C, offset); if (!Model.Compress(Model.MinecartObjects, dst, ref offset, 0x8000 - 0x1E, "object & screen data")) { return; } // Bits.SetBytes(Model.ROM, 0x388000, dst); Bits.SetShort(Model.ROM, 0x039670, (ushort)startX.Value); Bits.SetShort(Model.ROM, 0x039679, (ushort)startY.Value); }
public byte[] Recompress(int baseOffset, List <Mold> molds) { byte[] mold = new byte[0x10000]; int offset = 0; int thisCounter = 0; // must be outside loop to avoid resetting for (int i = 0; i < tiles.Count; i++) { Tile tile = (Tile)tiles[i]; #region first compare to find copies int counter = 0; int copySize = 0; Tile tileA = new Tile(); Tile thisTileA = new Tile(); Tile tileB = new Tile(); Tile thisTileB = new Tile(); int copyOffset = 0; int copyDiffX = 0; int copyDiffY = 0; // look through each mold for copies foreach (Mold m in molds) { // cancel if we've reached the same mold if (m == this) { break; } // skip if gridplane; not copyable if (m.Gridplane) { continue; } counter = 0; // look through all mold's tiles for copies while (counter + 1 < m.Tiles.Count && thisCounter + 1 < tiles.Count) { copySize = 0; tileA = (Tile)m.Tiles[counter]; thisTileA = (Tile)tiles[thisCounter]; tileB = (Tile)m.Tiles[counter + 1]; thisTileB = (Tile)tiles[thisCounter + 1]; copyOffset = tileA.TileOffset; // tile's offset wasn't set, thus not a viable tile to copy from if (copyOffset == 0) { counter++; continue; } copyDiffX = thisTileA.X - tileA.X; copyDiffY = thisTileA.Y - tileA.Y; // first check to see if going to be making a copy of more than one, regardless of active quadrants if (tileB.TileOffset != 0 && thisTileA.Subtile_bytes[0] == tileA.Subtile_bytes[0] && thisTileA.Subtile_bytes[1] == tileA.Subtile_bytes[1] && thisTileA.Subtile_bytes[2] == tileA.Subtile_bytes[2] && thisTileA.Subtile_bytes[3] == tileA.Subtile_bytes[3] && thisTileA.Mirror == tileA.Mirror && thisTileA.Invert == tileA.Invert && thisTileB.Subtile_bytes[0] == tileB.Subtile_bytes[0] && thisTileB.Subtile_bytes[1] == tileB.Subtile_bytes[1] && thisTileB.Subtile_bytes[2] == tileB.Subtile_bytes[2] && thisTileB.Subtile_bytes[3] == tileB.Subtile_bytes[3] && thisTileB.Mirror == tileB.Mirror && thisTileB.Invert == tileB.Invert && copyDiffX == thisTileB.X - tileB.X && copyDiffY == thisTileB.Y - tileB.Y) { // v3.8: set TileOffset to 0 to prevent later molds from using as a copy thisTileA.TileOffset = 0; thisTileB.TileOffset = 0; // we will be making a copy of at least 2 copySize = 2; // now keep moving to find more copies counter += 2; thisCounter += 2; // cancel if at end of first mold's tiles if (counter >= m.Tiles.Count || thisCounter >= tiles.Count) { break; } Tile tileC = (Tile)m.Tiles[counter]; Tile thisTileC = (Tile)tiles[thisCounter]; while (copySize < 15 && thisTileC.Subtile_bytes[0] == tileC.Subtile_bytes[0] && thisTileC.Subtile_bytes[1] == tileC.Subtile_bytes[1] && thisTileC.Subtile_bytes[2] == tileC.Subtile_bytes[2] && thisTileC.Subtile_bytes[3] == tileC.Subtile_bytes[3] && thisTileC.Mirror == tileC.Mirror && copyDiffX == thisTileC.X - tileC.X && copyDiffY == thisTileC.Y - tileC.Y) { // stop adding copies if the tile doesn't have an offset // it is probably a copy itself, so we shouldn't add it if (tileC.TileOffset == 0) { break; } // v3.8: set TileOffset to 0 to prevent later molds from using as a copy thisTileC.TileOffset = 0; // adding another copy copySize++; // now set to check next one counter++; thisCounter++; // cancel if at end of first mold's tiles if (counter >= m.Tiles.Count || thisCounter >= tiles.Count) { break; } tileC = (Tile)m.Tiles[counter]; thisTileC = (Tile)tiles[thisCounter]; } // must break out of this loop too if (tileC.TileOffset == 0) { break; } } // otherwise, check to see if going to be making a copy of at least one, // must have at least 3 quadrants active else if (CompareTiles(thisTileA, tileA, true)) { // since a copy, must set to 0 to prevent later molds from using as a copy thisTileA.TileOffset = 0; // we will be making a copy copyOffset = tileA.TileOffset; copyDiffX = thisTileA.X - tileA.X; copyDiffY = thisTileA.Y - tileA.Y; copySize++; // move for next tile thisCounter++; } // last tile wasn't a copy, so move to check next one else { counter++; } // we've found a copy, so don't try checking for more if (copySize > 0) { break; } } // we've found a copy, so don't try checking in any more molds if (copySize > 0) { break; } } #endregion if (copySize > 0) { mold[offset] = 2; mold[offset] |= (byte)(copySize << 4); mold[offset + 1] = (byte)copyDiffY; mold[offset + 2] = (byte)copyDiffX; Bits.SetShort(mold, offset + 3, (ushort)copyOffset); offset += 5; i += copySize - 1; thisCounter--; // must move back one to synchronize counter (it ++'s later) } // set normal tile else { tile.TileOffset = baseOffset + offset; tile.Is16bit = false; for (int s = 0, b = 128; s < 4; s++, b /= 2) { if (tile.Subtile_bytes[s] != 0) { mold[offset] |= (byte)b; } if (tile.Subtile_bytes[s] >= 0x100) { mold[offset] |= 1; tile.Is16bit = true; } } Bits.SetBit(mold, offset, 2, tile.Mirror); Bits.SetBit(mold, offset, 3, tile.Invert); offset++; mold[offset] = (byte)(tile.Y ^ 0x80); offset++; mold[offset] = (byte)(tile.X ^ 0x80); offset++; for (int s = 0; s < 4; s++) { if (tile.Subtile_bytes[s] != 0) { if (!tile.Is16bit) { mold[offset++] = (byte)tile.Subtile_bytes[s]; } else { Bits.SetShort(mold, offset, tile.Subtile_bytes[s]); offset += 2; } } } } thisCounter++; } byte[] temp = new byte[offset]; Bits.SetBytes(temp, 0, mold); return(temp); }
public void Assemble(ref int offset) { // first make sure each channel ends with a termination command for (int i = 0; i < 2; i++) { if (channels[i] != null && channels[i].Count > 0) { SPCCommand lastSSC = channels[i][channels[i].Count - 1]; if (lastSSC.Opcode != 0xD0 && lastSSC.Opcode != 0xCD && lastSSC.Opcode != 0xCE) { channels[i].Add(new SPCCommand(new byte[] { 0xD0 }, this, 0)); } } } // int channelSize1 = 0; int channelSize2 = 0; if (channels[0] != null && activeChannels[0]) { foreach (SPCCommand ssc in channels[0]) { channelSize1 += ssc.Length; } } if (channels[1] != null && activeChannels[1]) { foreach (SPCCommand ssc in channels[1]) { channelSize2 += ssc.Length; } } // int offsetStart1 = offset; int offsetStart2 = offset + channelSize1; if (channels[0] == null || !activeChannels[0]) { offsetStart1 = 0; } if (channels[1] == null || !activeChannels[1]) { offsetStart2 = 0; } // bool channel2in1 = true; if (offsetStart1 != 0 && offsetStart2 != 0 && channelSize2 <= channelSize1) { for (int a = channels[0].Count - 1, b = channels[1].Count - 1; a >= 0 && b >= 0; a--, b--) { if (!Bits.Compare(channels[0][a].CommandData, channels[1][b].CommandData)) { channel2in1 = false; } } } else { channel2in1 = false; } if (channel2in1) { offsetStart2 -= channelSize2; } // if (type == 0) { if (offsetStart1 == 0) { Bits.SetShort(rom, index * 4 + 0x042826, 0); } else { Bits.SetShort(rom, index * 4 + 0x042826, offsetStart1 - 0x042C26 + 0x3400); } if (offsetStart2 == 0) { Bits.SetShort(rom, index * 4 + 0x042826 + 2, 0); } else { Bits.SetShort(rom, index * 4 + 0x042826 + 2, offsetStart2 - 0x042C26 + 0x3400); } } else { if (offsetStart1 == 0) { Bits.SetShort(rom, index * 4 + 0x043E26, 0); } else { Bits.SetShort(rom, index * 4 + 0x043E26, offsetStart1 - 0x044226 + 0x3400); } if (offsetStart2 == 0) { Bits.SetShort(rom, index * 4 + 0x043E26 + 2, 0); } else { Bits.SetShort(rom, index * 4 + 0x043E26 + 2, offsetStart2 - 0x044226 + 0x3400); } } if (channels[0] != null && activeChannels[0]) { foreach (SPCCommand ssc in channels[0]) { Bits.SetBytes(rom, offsetStart1, ssc.CommandData); offsetStart1 += ssc.Length; } } if (channels[1] != null && activeChannels[1]) { foreach (SPCCommand ssc in channels[1]) { Bits.SetBytes(rom, offsetStart2, ssc.CommandData); offsetStart2 += ssc.Length; } } if (channel2in1) { offset += channelSize1; } else { offset += channelSize1 + channelSize2; } }
public int Assemble() { int size = this.buffer.Length; // set sm to new byte with largest possible size byte[] temp = new byte[0x10000]; // not dynamic, can set before others temp[12] = width; temp[13] = height; Bits.SetShort(temp, 14, codec); // now start writing dynamic data int offset = 18; // Graphics Bits.SetShort(temp, 2, 0x12); Buffer.BlockCopy(graphicSet, 0, temp, 18, graphicSetLength); offset += graphicSetLength; // Palettes Bits.SetShort(temp, 4, (ushort)offset); paletteSet.Assemble(temp, offset); offset += paletteSetLength; // Tileset Bits.SetShort(temp, 16, (ushort)offset); int tilesetoffset = offset; foreach (Tile t in tileset_tiles.Tileset) { if (t.Index >= tilesetLength / 8) { break; } if (t.Index > 0 && t.Index % 8 == 0) { offset += 32; } for (int i = 0; i < 4; i++) { Bits.SetShort(temp, offset, (byte)t.Subtiles[i].Index); offset++; Bits.SetBit(temp, offset, 5, t.Subtiles[i].Priority1); Bits.SetBit(temp, offset, 6, t.Subtiles[i].Mirror); Bits.SetBit(temp, offset, 7, t.Subtiles[i].Invert); if (i % 2 == 0) { offset++; } else if (i == 1) { offset += 29; } else if (i == 3) { offset -= 31; } } } Buffer.BlockCopy(temp, tilesetoffset, tileset_bytes, 0, tileset_bytes.Length); // offset += 32; Bits.SetShort(temp, offset, 0xFFFF); offset += 2; // Sequences Bits.SetShort(temp, 6, (ushort)offset); int fOffset = sequences.Count * 2 + 2; // offset of first frame packet foreach (E_Sequence s in sequences) { if (s.Frames.Count != 0) { Bits.SetShort(temp, offset, (ushort)(fOffset + offset)); fOffset += s.Frames.Count * 2 + 1; } else { Bits.SetShort(temp, offset, 0xFFFF); } offset += 2; } Bits.SetShort(temp, offset, 0); offset += 2; foreach (E_Sequence s in sequences) { foreach (E_Sequence.Frame f in s.Frames) { Bits.SetByte(temp, offset, f.Duration); offset++; Bits.SetByte(temp, offset, f.Mold); offset++; } Bits.SetByte(temp, offset, 0); offset++; } // Molds Bits.SetShort(temp, 8, (ushort)offset); int mOffset = molds.Count * 2 + 2; // offset of first mold tilemap foreach (E_Mold m in molds) { if (!m.Empty) { Bits.SetShort(temp, offset, (ushort)(mOffset + offset)); mOffset += m.Recompress(m.Mold, width, height).Length - 2; } else { Bits.SetShort(temp, offset, 0xFFFF); } offset += 2; } Bits.SetShort(temp, offset, 0); offset += 2; foreach (E_Mold m in molds) { if (!m.Empty) { byte[] mold = m.Recompress(m.Mold, width, height); Buffer.BlockCopy(mold, 0, temp, offset, mold.Length); offset += mold.Length; } } // finally, set the animation length Bits.SetShort(temp, 0, (ushort)offset); this.buffer = new byte[offset]; Bits.SetBytes(this.buffer, 0, temp); //Do.Export(sm, "test.bin"); return(size - this.buffer.Length); }