From 07ab2d7b465174705117ffba76d59ca35d441c00 Mon Sep 17 00:00:00 2001 From: Lorenzo Carletti Date: Sun, 23 Aug 2020 13:27:52 +0200 Subject: [PATCH] Properly put in the data and fix bugs for the tests --- src/data/cast_roll_arrangement.bin | Bin 40192 -> 0 bytes src/data/cast_roll_arrangements_[c].bin | Bin 0 -> 4485 bytes src/data/cast_roll_graphics.bin | Bin 24576 -> 0 bytes src/data/cast_roll_graphics_[c].bin | Bin 0 -> 3991 bytes src/data/cast_sign_arrangements.bin | Bin 196 -> 196 bytes src/m2-hack.asm | 12 ++ tools/RenderCastRoll/LZ77.cs | 171 +++++++++++++++++++++ tools/RenderCastRoll/Program.cs | 17 +- tools/RenderCastRoll/RenderCastRoll.csproj | 1 + tools/RenderCastRoll/RenderTools.cs | 6 +- 10 files changed, 197 insertions(+), 10 deletions(-) delete mode 100644 src/data/cast_roll_arrangement.bin create mode 100644 src/data/cast_roll_arrangements_[c].bin delete mode 100644 src/data/cast_roll_graphics.bin create mode 100644 src/data/cast_roll_graphics_[c].bin create mode 100644 tools/RenderCastRoll/LZ77.cs diff --git a/src/data/cast_roll_arrangement.bin b/src/data/cast_roll_arrangement.bin deleted file mode 100644 index 8a11a1996c4181cee7a75d860b07433db4875f6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40192 zcmeIw%}#$gbAvnbKeKAgZ%cdB?yq}WH>y4A9quJ?6IUVFEr>>lZI|?KbUF0e^x$|VNfTM>DNf#5HrsD_LFipuJ zgDhMgMU+v+I1xuYV44xZMaZFm5?lo})X~6^`>!MY(8uvocWv4Cd=oA9TIrE4#}xTC zuN9gTMw)+aV8AzH#)t8d@~p|h&?)ue{#omlNWpZ+gX)UEwa~nvt7++{K*)Z zRCmv_=2*40f7g0`pZB`R#gnsojX41V1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C&6c}TR(SOTZBELYs{?_Bm+_2&CQr?+H}$RvLXmLHyvYaUi-jQ1&Bk5crrUadBGubA>VZ`*`@ zX(ZjU5gx*$)kZ`I(Lr=rIIt|ws@!9dlV&D7gh#7Si4JWYDwz2noLugeo7R4mTO4NV nt{OUp8Y3tL<5> (7 - i)) & 1) + { + case 0: + + // Direct copy + if (bPos >= length) break; + output[bPos++] = data[address++]; + break; + + case 1: + + // Compression magic + int t = (data[address++] << 8); + t += data[address++]; + int n = ((t >> 12) & 0xF) + 3; // Number of bytes to copy + int o = (t & 0xFFF); + + // Copy n bytes from bPos-o to the output + for (int j = 0; j < n; j++) + { + if (bPos >= length) break; + output[bPos] = output[bPos - o - 1]; + bPos++; + } + + break; + + default: + break; + } + } + } + + return address - start; + } + + public static byte[] Compress(byte[] data) + { + return Compress(data, 0, data.Length); + } + + public static byte[] Compress(byte[] data, int address, int length) + { + int start = address; + + List obuf = new List(); + List tbuf = new List(); + int control = 0; + + // Let's start by encoding the signature and the length + obuf.Add(0x10); + obuf.Add((byte)(length & 0xFF)); + obuf.Add((byte)((length >> 8) & 0xFF)); + obuf.Add((byte)((length >> 16) & 0xFF)); + + while ((address - start) < length) + { + tbuf.Clear(); + control = 0; + for (int i = 0; i < 8; i++) + { + bool found = false; + + // First byte should be raw + if (address == start) + { + tbuf.Add(data[address++]); + found = true; + } + else if ((address - start) >= length) + { + break; + } + else + { + // We're looking for the longest possible string + // The farthest possible distance from the current address is 0x1000 + int max_length = -1; + int max_distance = -1; + + for (int k = 1; k <= 0x1000; k++) + { + if ((address - k) < start) break; + + int l = 0; + for (; l < 18; l++) + { + if (((address - start + l) >= length) || + (data[address - k + l] != data[address + l])) + { + if (l > max_length) + { + max_length = l; + max_distance = k; + } + break; + } + } + + // Corner case: we matched all 18 bytes. This is + // the maximum length, so don't bother continuing + if (l == 18) + { + max_length = 18; + max_distance = k; + break; + } + } + + if (max_length >= 3) + { + address += max_length; + + // We hit a match, so add it to the output + int t = (max_distance - 1) & 0xFFF; + t |= (((max_length - 3) & 0xF) << 12); + tbuf.Add((byte)((t >> 8) & 0xFF)); + tbuf.Add((byte)(t & 0xFF)); + + // Set the control bit + control |= (1 << (7 - i)); + + found = true; + } + } + + if (!found) + { + // If we didn't find any strings, copy the byte to the output + tbuf.Add(data[address++]); + } + } + + // Flush the temp buffer + obuf.Add((byte)(control & 0xFF)); + obuf.AddRange(tbuf.ToArray()); + } + + return obuf.ToArray(); + } + } +} diff --git a/tools/RenderCastRoll/Program.cs b/tools/RenderCastRoll/Program.cs index a34eec9..14005ea 100644 --- a/tools/RenderCastRoll/Program.cs +++ b/tools/RenderCastRoll/Program.cs @@ -39,14 +39,14 @@ namespace RenderCastRoll List renders = JsonConvert.DeserializeObject(rendersJson).Renders; BitsToNybbleLookup = Asset.ReadAllBytes("bits_to_nybbles.bin"); m12CharByteLookup = JsonConvert.DeserializeObject>(Asset.ReadAllText("m12-byte-lookup.json")); - Graphics = new byte[0x6000]; - Arrangements = new ushort[0x4E80]; + Graphics = new byte[0x8000]; + Arrangements = new ushort[0x48E0]; for (int i = 0; i < Arrangements.Length; i++) Arrangements[i] = 0x3FF; //Empty tile for (int i = 0; i < CastGraphics.Length; i++) - Graphics[0x6000 - CastGraphics.Length + i] = CastGraphics[i]; //Put the CAST graphics in + Graphics[0x8000 - CastGraphics.Length + i] = CastGraphics[i]; //Put the CAST graphics in int castArrPos = readIntLE(CastArrangements, 0); //First 4 bytes are the position of the CAST arrangements for (int i = 0; i < ((CastArrangements.Length - 4) >> 1); i++) //Put the CAST arrangements in @@ -83,18 +83,21 @@ namespace RenderCastRoll //Convert the 1bpp tiles to 4bpp for (int tile = 0; tile < UsedTiles; tile++) { - int basePos = tile * 0x20; + int basePos = (tile * 0x20) + 0x2000; _1bppTile pre_converted_tile = _1bppGraphics[tile]; for (int i = 0; i < 8; i++) { - int row = BitsToNybbleLookup[pre_converted_tile.getRow(i)]; + int row = readIntLE(BitsToNybbleLookup, pre_converted_tile.getRow(i) * 4); for (int j = 0; j < 4; j++) Graphics[basePos + (i * 4) + j] = (byte)((row >> (j * 8)) & 0xFF); } } - File.WriteAllBytes(dataFolder + "cast_roll_graphics.bin", Graphics); - File.WriteAllBytes(dataFolder + "cast_roll_arrangement.bin", convertUShortArrToByteLE(Arrangements)); + //File.WriteAllBytes(dataFolder + "cast_roll_graphics.bin", Graphics); + //File.WriteAllBytes(dataFolder + "cast_roll_arrangements.bin", convertUShortArrToByteLE(Arrangements)); + + File.WriteAllBytes(dataFolder + "cast_roll_graphics_[c].bin", GBA.LZ77.Compress(Graphics)); + File.WriteAllBytes(dataFolder + "cast_roll_arrangements_[c].bin", GBA.LZ77.Compress(convertUShortArrToByteLE(Arrangements))); } static int readIntLE(byte[] arr, int pos) diff --git a/tools/RenderCastRoll/RenderCastRoll.csproj b/tools/RenderCastRoll/RenderCastRoll.csproj index 9daf848..c1ad873 100644 --- a/tools/RenderCastRoll/RenderCastRoll.csproj +++ b/tools/RenderCastRoll/RenderCastRoll.csproj @@ -47,6 +47,7 @@ + diff --git a/tools/RenderCastRoll/RenderTools.cs b/tools/RenderCastRoll/RenderTools.cs index 5be027d..4e38ebb 100644 --- a/tools/RenderCastRoll/RenderTools.cs +++ b/tools/RenderCastRoll/RenderTools.cs @@ -45,13 +45,13 @@ namespace RenderCastRoll public byte getRow(int i) { - return (byte)((tile >> i) & 0xFF); + return (byte)((tile >> (i * 8)) & 0xFF); } public void setRow(int i, byte val) { - UInt64 mask = ~((UInt64)(0xFF) << i); - tile = (tile & mask) | ((UInt64)val << i); + UInt64 mask = ~((UInt64)(0xFF) << (i * 8)); + tile = (tile & mask) | ((UInt64)val << (i * 8)); } public UInt64 getColumn(int i)