private List <UInt32> writeSubroutineForceFetchFakeVentureCard(VAVAddr fakeVentureCard) { PowerPcAsm.Pair16Bit v = PowerPcAsm.make16bitValuePair((UInt32)fakeVentureCard); // precondition: r3 is ChanceCardUI * // ChanceCardUI->field_0x34 is ChanceBoard * // ChanceBoard->field_0x158 is current venture card id var asm = new List <UInt32>(); asm.Add(PowerPcAsm.lis(6, v.upper16Bit)); // \ asm.Add(PowerPcAsm.addi(6, 6, v.lower16Bit)); // / r6 <- forceVentureCardVariable asm.Add(PowerPcAsm.lwz(4, 0x0, 6)); // | r4 <- forceVentureCard asm.Add(PowerPcAsm.cmpwi(4, 0x0)); // | if(forceVentureCard != 0) asm.Add(PowerPcAsm.beq(7)); // | { asm.Add(PowerPcAsm.lwz(5, 0x34, 3)); // | r5 <- ChanceCardUI.ChanceBoard asm.Add(PowerPcAsm.stw(4, 0x158, 5)); // | ChanceBoard.currentVentureCardId <- r4 asm.Add(PowerPcAsm.li(5, 0)); // |\ forceVentureCard <- 0 asm.Add(PowerPcAsm.stw(5, 0x0, 6)); // |/ asm.Add(PowerPcAsm.li(8, 0x0)); // | r8 <- 0 (the venture card is initialized) asm.Add(PowerPcAsm.blr()); // | return r4 and r8 // | } asm.Add(PowerPcAsm.li(4, -0x1)); // | r4 <- -1 asm.Add(PowerPcAsm.li(8, 0x3)); // | r8 <- 3 (the venture card is continued to be executed) asm.Add(PowerPcAsm.blr()); // | return r4 and r8 return(asm); }
private List <UInt32> writeProcStopEventSquareRoutine(AddressMapper addressMapper, VAVAddr forceVentureCardVariable, VAVAddr routineStartAddress) { PowerPcAsm.Pair16Bit v = PowerPcAsm.make16bitValuePair((UInt32)forceVentureCardVariable); var gameProgressChangeModeRoutine = addressMapper.toVersionAgnosticAddress((BSVAddr)0x800c093c); var endOfSwitchCase = addressMapper.toVersionAgnosticAddress((BSVAddr)0x800fac38); var asm = new List <UInt32>(); asm.Add(PowerPcAsm.lwz(3, 0x188, 28)); // \ asm.Add(PowerPcAsm.lwz(3, 0x74, 3)); // / r3_place = gameChara.currentPlace asm.Add(PowerPcAsm.lbz(6, 0x18, 3)); // | r6_ventureCardId = r3_place.districtId asm.Add(PowerPcAsm.lis(3, v.upper16Bit)); // \ asm.Add(PowerPcAsm.addi(3, 3, v.lower16Bit)); // | forceVentureCardVariable <- r6_ventureCardId asm.Add(PowerPcAsm.stw(6, 0x0, 3)); // / asm.Add(PowerPcAsm.lwz(3, 0x18, 20)); // \ lwz r3,0x18(r20) asm.Add(PowerPcAsm.li(4, 0x1f)); // | li r4,0x1f (the GameProgress mode id 0x1f is for executing a venture card) asm.Add(PowerPcAsm.li(5, -0x1)); // | li r5,-0x1 asm.Add(PowerPcAsm.li(6, -0x1)); // | li r6,-0x1 asm.Add(PowerPcAsm.li(7, 0x0)); // | li r7,0x0 asm.Add(PowerPcAsm.bl(routineStartAddress, asm.Count, gameProgressChangeModeRoutine)); // | bl Game::GameProgress::changeMode asm.Add(PowerPcAsm.b(routineStartAddress, asm.Count, endOfSwitchCase)); // / goto end of switch case return(asm); }
private List <UInt32> writeSubroutineGetMapsInZone(AddressMapper addressMapper, List <MapDescriptor> mapDescriptors, VAVAddr mapSetZoneOrderTable, VAVAddr entryAddr, VAVAddr returnAddr) { PowerPcAsm.Pair16Bit v = PowerPcAsm.make16bitValuePair((UInt32)mapSetZoneOrderTable); // precondition: r5 MapSet // r29 _ZONE_TYPE // r30 int* array containing map ids // r3,r4,r6,r7,r31 unused // postcondition: r3 num maps (must be same as in SubroutineGetNumMapsInZone) var asm = new List <UInt32>(); var asm_l2 = new List <UInt32>(); var asm_l3 = new List <UInt32>(); asm.Add(PowerPcAsm.li(3, 0)); var mapSets = (from m in mapDescriptors where m.MapSet != -1 orderby m.MapSet select m.MapSet).Distinct(); foreach (var mapSet in mapSets) { asm.Add(PowerPcAsm.cmpwi(5, mapSet)); var zones = (from m in mapDescriptors where m.MapSet == mapSet && m.Zone != -1 orderby m.Zone select m.Zone).Distinct(); asm_l2.Clear(); foreach (var zone in zones) { asm_l2.Add(PowerPcAsm.cmpwi(29, zone)); IOrderedEnumerable <MapDescriptor> maps; if (zone == 0) { maps = from m in mapDescriptors where m.MapSet == mapSet && m.Zone == 1 orderby m.Order select m; } else if (zone == 1) { maps = from m in mapDescriptors where m.MapSet == mapSet && m.Zone == 0 orderby m.Order select m; } else { maps = from m in mapDescriptors where m.MapSet == mapSet && m.Zone == zone orderby m.Order select m; } short i = 0; asm_l3.Clear(); asm_l3.Add(PowerPcAsm.li(3, (short)maps.Count())); foreach (var map in maps) { short mapId = (short)mapDescriptors.IndexOf(map); var mapDescriptor = mapDescriptors[i]; asm_l3.Add(PowerPcAsm.li(4, mapId)); asm_l3.Add(PowerPcAsm.stw(4, i, 30)); i += 4; } asm_l2.Add(PowerPcAsm.bne(asm_l3.Count + 1)); asm_l2.AddRange(asm_l3); } asm.Add(PowerPcAsm.bne(asm_l2.Count + 1)); asm.AddRange(asm_l2); } asm.Add(PowerPcAsm.b(entryAddr, asm.Count, returnAddr)); return(asm); }
private List <UInt32> writeRuleSetFromMapRoutine(AddressMapper addressMapper, VAVAddr routineStartAddress) { var Game_GetRuleFlag = addressMapper.toVersionAgnosticAddress((BSVAddr)0x801cca98); // precondition: r24 is mapId // precondition: r25 is global rule set which we are gonna use to store the linkreturn var asm = new List <UInt32>(); asm.Add(PowerPcAsm.mflr(25)); asm.Add(PowerPcAsm.mr(3, 24)); // r3 <- r24 asm.Add(PowerPcAsm.bl(routineStartAddress, asm.Count, Game_GetRuleFlag)); // r3 <- bl Game_GetRuleFlag(r3) asm.Add(PowerPcAsm.stw(3, 0x53f4, 29)); // gameRule <- r3 asm.Add(PowerPcAsm.mtlr(25)); asm.Add(PowerPcAsm.blr()); // return return(asm); }
private List <UInt32> writeUploadSimulatedButtonPress(AddressMapper addressMapper, VAVAddr routineStartAddress, VAVAddr returnAddr) { var asm = new List <UInt32>(); // 0x804363b4 (4 bytes): force simulated button press var forceSimulatedButtonPress = PowerPcAsm.make16bitValuePair((UInt32)addressMapper.toVersionAgnosticAddress((BSVAddr)0x804363b4)); var pressedButtonsBitArray = PowerPcAsm.make16bitValuePair((UInt32)addressMapper.toVersionAgnosticAddress((BSVAddr)0x8078C880)); asm.Add(PowerPcAsm.lis(6, forceSimulatedButtonPress.upper16Bit)); // \ asm.Add(PowerPcAsm.addi(6, 6, forceSimulatedButtonPress.lower16Bit)); // / r6 <- &forceSimulatedButtonPress asm.Add(PowerPcAsm.lis(7, pressedButtonsBitArray.upper16Bit)); // \ asm.Add(PowerPcAsm.addi(7, 7, pressedButtonsBitArray.lower16Bit)); // / r7 <- &pressedButtonsBitArray asm.Add(PowerPcAsm.lwz(0, 0x0, 6)); // r0 <- forceSimulatedButtonPress asm.Add(PowerPcAsm.cmpwi(0, 0x0)); // if (forceSimulatedButtonPress != 0) asm.Add(PowerPcAsm.beq(4)); // { asm.Add(PowerPcAsm.stw(0, 0x0, 7)); // pressedButtonsBitArray <- forceSimulatedButtonPress asm.Add(PowerPcAsm.li(0, 0x0)); // \ asm.Add(PowerPcAsm.stw(0, 0x0, 6)); // / forceSimulatedButtonPress <- 0 // } asm.Add(PowerPcAsm.lwz(0, 0x4, 3)); // *replaced opcode* asm.Add(PowerPcAsm.b(routineStartAddress, asm.Count, returnAddr)); // return return(asm); }