示例#1
0
        public void try_decompres_recomp_decomp_overworld(byte[] originalCompressed, byte[] expectedDecompress)
        {
            int compsize     = 0;
            var decompressed = Decompress.ALTTPDecompressOverworld(originalCompressed, 0, originalCompressed.Length, ref compsize);
            int i            = 0;

            while (i < expectedDecompress.Length && i < decompressed.Length)
            {
                if (expectedDecompress[i] != decompressed[i])
                {
                    output.WriteLine($"mismatch at {i}, expected: {expectedDecompress[i].ToString("X2")} decompressed: {decompressed[i].ToString("X2")}");
                }
                i++;
            }
            Assert.Equal(expectedDecompress, decompressed);

            // recompress
            var  recomp = Compress.ALTTPCompressOverworld(decompressed, 0, decompressed.Length);
            bool same   = false;

            try
            {
                i = 0;
                while (i < originalCompressed.Length && i < recomp.Length)
                {
                    if (originalCompressed[i] != recomp[i])
                    {
                        output.WriteLine($"recompress mismatch at {i}, expected: {originalCompressed[i].ToString("X2")} recomp: {recomp[i].ToString("X2")}");
                    }
                    i++;
                }

                Assert.Equal(originalCompressed, recomp);
                same = true;
            }
            catch (Exception ex)
            {
                same = false;
            }
            output.WriteLine($"recompress is same as original compresssed? {same}");

            decompressed = Decompress.ALTTPDecompressOverworld(recomp, 0, recomp.Length, ref compsize);
            i            = 0;
            while (i < expectedDecompress.Length && i < decompressed.Length)
            {
                if (expectedDecompress[i] != decompressed[i])
                {
                    output.WriteLine($"mismatch at {i}, expected: {expectedDecompress[i].ToString("X2")} decompressed: {decompressed[i].ToString("X2")}");
                }
                i++;
            }
            Assert.Equal(expectedDecompress, decompressed);
        }
示例#2
0
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("Enter the seed name too.");
                return;
            }

            //todo better (or any lol) file checking
            string fileName = args[0];

            //string fileName = "test0.sfc";

            byte[] data           = File.ReadAllBytes(fileName);
            int    table_address  = 0x27ce0;
            int    c_table_length = 799;
            Random rnd            = new Random();
            string spoiler        = "";

            // decompress the enemy damage table from the ROM (thanks Zarby)
            int f = 0;

            byte[] sdata       = Decompress.ALTTPDecompressOverworld(data, 0x27ce0, c_table_length, ref f);
            byte[] udata       = new byte[3000];
            byte[] enemy_table = new byte[5000];

            // expanding the array (unsure if needed)
            for (int i = 0; i < udata.Length; i++)
            {
                if (i < sdata.Length)
                {
                    udata[i] = sdata[i];
                }
                else
                {
                    udata[i] = 0;
                }
            }

            // split bytes
            for (int i = 0; i < 5000; i += 2)
            {
                enemy_table[i]     = (byte)(udata[i / 2] >> 4);
                enemy_table[i + 1] = (byte)(udata[i / 2] & 0x0F);
            }

            // normalize the enemy damage table
            byte[] new_enemy_table = Enemy_Table_Setup(enemy_table);

            // recombine bytes
            byte[] combined_table = new byte[2048];
            for (int i = 0; i < 2048; i += 1)
            {
                combined_table[i] = (byte)((new_enemy_table[(i * 2)] << 4) | new_enemy_table[(i * 2) + 1]);
            }
            // recompress table
            byte[] compressed_enemy_table = Compress.ALTTPCompressOverworld(combined_table, 0, combined_table.Length);

            // write table to ROM data - table cannot exceed 799 bytes length
            for (int i = 0; (i < c_table_length & i < compressed_enemy_table.Length); i++)
            {
                data[table_address + i] = compressed_enemy_table[i];
            }

            // create new damage table and write to ROM data
            byte[] new_damage_table     = Create_Damage_Table();
            int    damage_table_address = 0x6B8F1;

            for (int i = 0; i < 128; i++)
            {
                data[damage_table_address + i] = new_damage_table[i];
            }
            // write spoiler info
            string[] weaponClassNames = new string[] { "Boomerang", "Level 1", "Level 2", "Level 3", "Level 4", "Level 5",
                                                       "Bow", "Hookshot", "Bombs", "Silvers", "Powder", "Fire Rod", "Ice Rod", "Bombos", "Ether", "Quake" };
            for (int i = 0; i < 16; i++)
            {
                spoiler += weaponClassNames[i] + ": " + Convert.ToString(new_damage_table[i * 8 + 1]) + "\r\n";
            }

            // randomize powder fairy prize
            int fairy_address = 0x36DD0;    // fairy, bees, appl, fish, heart, $5, $20, bomb, magic

            byte[] fairy_options = new byte[] { 0xE3, 0x79, 0xAC, 0xD2, 0xD8, 0xDA, 0xDB, 0xDC, 0xDF };
            data[fairy_address] = fairy_options[rnd.Next(fairy_options.Length)];
            spoiler            += "Fairy prize: " + Convert.ToString(data[fairy_address] + "\r\n");

            // randomize bomb timers lol
            int bomb_timer_address = 0x41543;

            // write fuse timer to ROM, first byte - setting to 00 causes max timer
            data[bomb_timer_address] = (byte)(rnd.Next(254) + 1);
            spoiler += "Bomb timers: " + Convert.ToString(data[bomb_timer_address]) + ", ";
            // bomb explosion speed is next 10 bytes
            byte[,] rates = new byte[, ] {
                { 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02 }, // fastest
                { 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03 }, // double speed
                { 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06 }, // default
                { 0x0C, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0C, 0x0C, 0x0C, 0x0C }, // half speed
                { 0x18, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x18, 0x18, 0x18, 0x18 }, // quarter speed lol
                // repeat 'moderate' ones to increase weight
                { 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03 }, // double speed
                { 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06 }, // default
                { 0x0C, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0C, 0x0C, 0x0C, 0x0C }, // half speed
                // repeat default again for most weight
                { 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06 }
            };                                                                // default

            // choose one of the 9 rows
            int row = rnd.Next(9);

            // write to ROM
            for (int i = 0; i < 10; i++)
            {
                data[bomb_timer_address + i + 1] = rates[row, i];
                spoiler += Convert.ToString(rates[row, i]) + " ";
            }
            spoiler += "\r\n";

            File.WriteAllText("wpn_" + fileName + ".txt", spoiler);

            FileStream fs = new FileStream("wpn_" + fileName, FileMode.CreateNew, FileAccess.Write);

            fs.Write(data, 0, data.Length);
            fs.Close();
        }