コード例 #1
0
        private List <UInt32> writeSubroutineSkipMapUnlockCheck(AddressMapper addressMapper, VAVAddr entryAddr, VAVAddr returnContinueAddr, VAVAddr returnSkipMapUnlockedCheck)
        {
            // precondition:  r26  is mapid
            //                 r3  is unused
            // postcondition:  r3  is mapid
            var asm = new List <UInt32>();

            asm.Add(PowerPcAsm.or(3, 26, 26));                                         // r3 <- mapid
            asm.Add(PowerPcAsm.cmpwi(3, -1));                                          // mapid == -1 ?
            asm.Add(PowerPcAsm.beq(entryAddr, asm.Count, returnSkipMapUnlockedCheck)); //   goto skipMapUnlockedCheck
            asm.Add(PowerPcAsm.b(entryAddr, asm.Count, returnContinueAddr));           // else goto returnContinueAddr
            return(asm);
        }
コード例 #2
0
        protected override void writeAsm(EndianBinaryWriter stream, AddressMapper addressMapper, List <MapDescriptor> mapDescriptors)
        {
            var tableAddr = writeTable(mapDescriptors);

            // --- Game::GameSequenceDataAdapter::GetNumMapsInZone ---
            var subroutineGetNumMapsInZone = allocate(writeSubroutineGetNumMapsInZone(mapDescriptors), "SubroutineGetNumMapsInZone");
            var hijackAddr = addressMapper.toVersionAgnosticAddress((BSVAddr)0x8020f3ac);

            stream.Seek(addressMapper.toFileAddress(hijackAddr), SeekOrigin.Begin);
            // li r3,0x6 ->  b subroutineGetNumMapsInZone
            stream.Write(PowerPcAsm.b(hijackAddr, subroutineGetNumMapsInZone));

            // --- Game::GameSequenceDataAdapter::GetMapsInZone ---
            hijackAddr = addressMapper.toVersionAgnosticAddress((BSVAddr)0x8020f454);
            var returnAddr = addressMapper.toVersionAgnosticAddress((BSVAddr)0x8020f554);
            var subroutineGetMapsInZone = allocate(writeSubroutineGetMapsInZone(addressMapper, mapDescriptors, tableAddr, VAVAddr.NullAddress, returnAddr), "SubroutineGetMapsInZone");

            stream.Seek(addressMapper.toFileAddress(subroutineGetMapsInZone), SeekOrigin.Begin);
            stream.Write(writeSubroutineGetMapsInZone(addressMapper, mapDescriptors, tableAddr, subroutineGetMapsInZone, returnAddr)); // re-write the routine again since now we know where it is located in the main dol
            stream.Seek(addressMapper.toFileAddress(hijackAddr), SeekOrigin.Begin);
            // cmpwi r29,0x0 ->  b subroutineGetMapsInZone
            stream.Write(PowerPcAsm.b(hijackAddr, subroutineGetMapsInZone));

            // --- Write Table Meta Information ---
            stream.Seek(addressMapper.toFileAddress((BSVAddr)0x8020f458), SeekOrigin.Begin);
            stream.Write((uint)tableAddr);
            stream.Write((short)0);
            stream.Seek(addressMapper.toFileAddress((BSVAddr)0x8020F45E), SeekOrigin.Begin);
            stream.Write((short)mapDescriptors.Count);

            // --- Fix Wifi Map Selection ---
            // bl GameSequenceDataAdapter::GetMapOrigin(r3)                               -> nop
            stream.Seek(addressMapper.toFileAddress((BSVAddr)0x80185ac4), SeekOrigin.Begin); stream.Write(PowerPcAsm.nop());
            // or r31,r3,r3                                                               -> or r31,r4,r4
            stream.Seek(addressMapper.toFileAddress((BSVAddr)0x80185ac8), SeekOrigin.Begin); stream.Write(PowerPcAsm.or(31, 4, 4));
            // li r5,0x1                                                                  -> li r5,0x2
            stream.Seek(addressMapper.toFileAddress((BSVAddr)0x80185b10), SeekOrigin.Begin); stream.Write(PowerPcAsm.li(5, 2));
            // bl GameSequenceDataAdapter::GetMapOrigin(r3)                               -> nop
            stream.Seek(addressMapper.toFileAddress((BSVAddr)0x8024b1b8), SeekOrigin.Begin); stream.Write(PowerPcAsm.nop());
            // bl GameSequenceDataAdapter::GetMapOrigin(r3)                               -> nop
            stream.Seek(addressMapper.toFileAddress((BSVAddr)0x802498a8), SeekOrigin.Begin);
            for (int i = 0; i < 8; i++)
            {
                stream.Write(PowerPcAsm.nop());
            }
            // --- Default selected map button in wifi ---
            // since Standard Mode is selected on default, we use this mapset to find the standard map
            // TODO need asm hack to determine currently selected MapSet and use rather use that ID
            short defaultMap = 0;

            for (short i = 0; i < mapDescriptors.Count; i++)
            {
                var mapDescriptor = mapDescriptors[i];
                if (mapDescriptor.MapSet == 1 && mapDescriptor.Zone == 0 && mapDescriptor.Order == 0)
                {
                    defaultMap = i;
                }
            }
            // 0x9 = Castle Trodain
            // li r3,0x9                                                                  -> li r3,0x9
            stream.Seek(addressMapper.toFileAddress((BSVAddr)0x8024afc8), SeekOrigin.Begin); stream.Write(PowerPcAsm.li(3, defaultMap));
            // TODO 0x13 is some special handling map id. Need to check what is going on with it
            // li r3,0x13                                                                 -> li r3,0x13
            stream.Seek(addressMapper.toFileAddress((BSVAddr)0x80243ae4), SeekOrigin.Begin); stream.Write(PowerPcAsm.li(5, 0x13));
            // --- Fix out of array bounds error when opening tour mode and viewing the zones and having more than 6 maps in a zone ---
            // bl Game::GameSequenceDataAdapter::GetNumMapsInZone    -> li r3,0x6
            stream.Seek(addressMapper.toFileAddress((BSVAddr)0x8021f880), SeekOrigin.Begin); stream.Write(PowerPcAsm.li(3, 0x6));
            // bl Game::GameSequenceDataAdapter::GetNumMapsInZone    -> li r3,0x6
            stream.Seek(addressMapper.toFileAddress((BSVAddr)0x8021ff4c), SeekOrigin.Begin); stream.Write(PowerPcAsm.li(3, 0x6));
        }