CPU Control Cycler [Ro]
#1
CPU Control Cycler [Ro]

This code allows playing as other CPUs, you can cycle the camera thru all CPUs and you will be able to play as the one that the camera is targetting, you can drive and throw items as if you were really them. Once you change the CPU, the CPU you were previously controlling will return back to normal and will start driving by itself again. Your real player will not move or use items while you control CPUs.

This code can be fun in many ways, you can mess with CPUs, use it for testing and pictures (you can use Joshua's Disable CPU Driving code to make all CPUs not move and then control each individually to position them for a picture) or even changing CPUs combos with Vega's code and then using it for different things.

Most of the HUD is still based on your real player but minimap icon for controlled CPU was coded in.

Here's an example of a picture that I took using the code:
[Image: image.png?ex=66d6b1cb&is=66d5604b&hm=7a2...y=lossless]

XXXX: Controller Address Second Half [Example: 14C2 for Classic Controller NTSC-U]
YYYY: Both cycle buttons masked together (Button to cycle to previous+ Button to cycle to next button = YYYY) [Example: 8002 for D-Pad Left/Right for Classic Controller ]
ZZZZ: Button to cycle to previous [Example: 0002 for D-Pad Left for Classic Controller ]

No need to input button to cycle to next, YYYY logic does it, plus, makes code shorter and cleaner.

This code makes uses of addresses 0x80001620 thru 0x80001621. Make sure no other codes use these addresses.

NTSC-U
C2581B2C 00000006
819D0000 818C0000
898C0010 3D608000
896B1620 2C0B0000
4182000C 2C0C0000
4D820020 9421FFF0
60000000 00000000
C258E058 00000006
819D0000 818C0000
898C0010 3D608000
896B1620 2C0B0000
4182000C 2C0C0000
4D820020 9421FFD0
60000000 00000000
C2589BE4 00000004
88030010 3D808000
898C1620 7C006000
40820008 38000000
60000000 00000000
C25971F8 00000010
3FC08000 889E1620
3D808034 A06CXXXX
3D80809C 818CEE20
898C0010 398CFFFF
7063YYYY 41820044
897E1621 2C0B0000
40820038 706BZZZZ
41820018 2C040000
3884FFFF 4082001C
7D846378 48000014
7C0C2000 38840001
40820008 38800000
989D009C 989E1620
7063YYYY 39600001
40820008 39600000
997E1621 00000000
C2728F84 00000007
3D808000 898C1620
817D0000 814B0000
894A0010 7C0C5000
40820018 818B0004
816C0014 556B003C
916C0014 4E800020
9421FFF0 00000000
C278ED0C 00000005
A01D000C 3D808000
898C1620 2C0C0000
41820010 2C1B0000
40820008 38000000
60000000 00000000
C27E1CA8 00000002
3D808000 898C1620
7C046000 00000000
C27E2018 0000000A
80030B90 3D808000
898C1620 817CFFFC
2C0B0000 41820038
816B0000 816B0000
896B0010 396B0001
7C0B6000 40820020
38000002 819C01BC
39600001 996C00BB
819C01C0 39600005
996C00BB 00000000

PAL
C2588350 00000006
819D0000 818C0000
898C0010 3D608000
896B1620 2C0B0000
4182000C 2C0C0000
4D820020 9421FFF0
60000000 00000000
C257AB68 00000006
819D0000 818C0000
898C0010 3D608000
896B1620 2C0B0000
4182000C 2C0C0000
4D820020 9421FFD0
60000000 00000000
C2590408 00000004
88030010 3D808000
898C1620 7C006000
40820008 38000000
60000000 00000000
C25A2230 00000010
3FC08000 889E1620
3D808034 A06CXXXX
3D80809C 818C3618
898C0010 398CFFFF
7063YYYY 41820044
897E1621 2C0B0000
40820038 706BZZZZ
41820018 2C040000
3884FFFF 4082001C
7D846378 48000014
7C0C2000 38840001
40820008 38800000
989D009C 989E1620
7063YYYY 39600001
40820008 39600000
997E1621 00000000
C27255F8 00000007
3D808000 898C1620
817D0000 814B0000
894A0010 7C0C5000
40820018 818B0004
816C0014 556B003C
916C0014 4E800020
9421FFF0 00000000
C2797D18 00000005
A01D000C 3D808000
898C1620 2C0C0000
41820010 2C1B0000
40820008 38000000
60000000 00000000
C27EB554 00000002
3D808000 898C1620
7C046000 00000000
C27EB8C4 0000000A
80030B90 3D808000
898C1620 817CFFFC
2C0B0000 41820038
816B0000 816B0000
896B0010 396B0001
7C0B6000 40820020
38000002 819C01BC
39600001 996C00BB
819C01C0 39600005
996C00BB 00000000

NTSC-J
C2587CD0 00000006
819D0000 818C0000
898C0010 3D608000
896B1620 2C0B0000
4182000C 2C0C0000
4D820020 9421FFF0
60000000 00000000
C257A4E8 00000006
819D0000 818C0000
898C0010 3D608000
896B1620 2C0B0000
4182000C 2C0C0000
4D820020 9421FFD0
60000000 00000000
C258FD88 00000004
88030010 3D808000
898C1620 7C006000
40820008 38000000
60000000 00000000
C25A1BB0 00000010
3FC08000 889E1620
3D808034 A06CXXXX
3D80809C 818C2678
898C0010 398CFFFF
7063YYYY 41820044
897E1621 2C0B0000
40820038 706BZZZZ
41820018 2C040000
3884FFFF 4082001C
7D846378 48000014
7C0C2000 38840001
40820008 38800000
989D009C 989E1620
7063YYYY 39600001
40820008 39600000
997E1621 00000000
C2724C64 00000007
3D808000 898C1620
817D0000 814B0000
894A0010 7C0C5000
40820018 818B0004
816C0014 556B003C
916C0014 4E800020
9421FFF0 00000000
C2797384 00000005
A01D000C 3D808000
898C1620 2C0C0000
41820010 2C1B0000
40820008 38000000
60000000 00000000
C27EABC0 00000002
3D808000 898C1620
7C046000 00000000
C27EAF30 0000000A
80030B90 3D808000
898C1620 817CFFFC
2C0B0000 41820038
816B0000 816B0000
896B0010 396B0001
7C0B6000 40820020
38000002 819C01BC
39600001 996C00BB
819C01C0 39600005
996C00BB 00000000

NTSC-K
C25763A8 00000006
819D0000 818C0000
898C0010 3D608000
896B1620 2C0B0000
4182000C 2C0C0000
4D820020 9421FFF0
60000000 00000000
C2568BC0 00000006
819D0000 818C0000
898C0010 3D608000
896B1620 2C0B0000
4182000C 2C0C0000
4D820020 9421FFD0
60000000 00000000
C257E460 00000004
88030010 3D808000
898C1620 7C006000
40820008 38000000
60000000 00000000
C2590288 00000010
3FC08000 889E1620
3D808033 A06CXXXX
3D80809B 818C1C58
898C0010 398CFFFF
7063YYYY 41820044
897E1621 2C0B0000
40820038 706BZZZZ
41820018 2C040000
3884FFFF 4082001C
7D846378 48000014
7C0C2000 38840001
40820008 38800000
989D009C 989E1620
7063YYYY 39600001
40820008 39600000
997E1621 00000000
C27139A0 00000007
3D808000 898C1620
817D0000 814B0000
894A0010 7C0C5000
40820018 818B0004
816C0014 556B003C
916C0014 4E800020
9421FFF0 00000000
C27860D8 00000005
A01D000C 3D808000
898C1620 2C0C0000
41820010 2C1B0000
40820008 38000000
60000000 00000000
C27D9914 00000002
3D808000 898C1620
7C046000 00000000
C27D9C84 0000000A
80030B90 3D808000
898C1620 817CFFFC
2C0B0000 41820038
816B0000 816B0000
896B0010 396B0001
7C0B6000 40820020
38000002 819C01BC
39600001 996C00BB
819C01C0 39600005
996C00BB 00000000

Code creator: Ro
Code credits: JoshuaMK and B_squo (Both had important addresses that helped me find CPU AI functions), acaruso (Player camera address) and probably more people
Reply
#2
Nice work!
Reply
#3
While taking a bath today I remembered that I forgot to change another button to YYYY. I updated it so everything works properly.
Reply
#4
It works an absolute charm!
There's just one thing I wonder, could it be possible to make the detached player self drive while controlling the others?
Reply
#5
It is possible by modifying the CPU bot code. There's one code there that does something with inputs that only runs once though, so you might need to find another way to toggle CPU on and off in game.


For making you the CPU when the camera isnt targetting you, you need to compare if the camera target ID (in 0x80001620) is 0 (you), if it is, skip code, otherwise, check if "CPU" ID is 0 (you) and if it isnt, skip code too, otherwise set CPU

I say skip code but you likely have to do something else to disable CPU

You will also need to remove one of the 8058XXXX and maybe modify 8072XXXX
Reply
#6
Can you post the source to this code? Would like to take a closer look at it.
Reply
#7
I don't have it anymore but I can port it from C2 and write what each thing do
Reply
#8
(Yesterday, 04:06 AM)Vega Wrote: Can you post the source to this code? Would like to take a closer look at it.


Code:
Prevent you from controlling your kart when spectating others

Wheelie
80581B2C
lwz      r12, 0x0(r29)
lwz      r12, 0x0(r12)
lbz      r12, 0x10(r12)
lis      r11, 0x8000
lbz      r11, 0x1620(r11) # Load camera target ID
cmpwi    r11, 0 # If camera target is you
beq      end # End code
cmpwi    r12, 0 # Else, check if kart is yours
beqlr  # If it is, return to avoid you from doing wheelies if you are spectating other players
end: # original
stwu      r1, -0x10(r1)


All other controls (except wheelie - done above)
8058E058
lwz      r12, 0x0(r29)
lwz      r12, 0x0(r12)
lbz      r12, 0x10(r12)
lis      r11, 0x8000
lbz      r11, 0x1620(r11) # Load camera target ID
cmpwi    r11, 0 # If camera target is you
beq      end # End code
cmpwi    r12, 0 # Else, check if kart is yours
beqlr  # if it is, return to avoid you from doing moving or doing any control if you are spectating other players
end: # original
stwu      r1, -0x30(r1)

Item usage
8078ED0C
  lhz       r0, 0xC(r29)
  lis       r12, 0x8000
  lbz       r12, 0x1620(r12) # load camera target ID
  cmpwi     r12, 0              # If camera target is you
  beq-      end                 # If it isn't, end code
  cmpwi     r27, 0             # Else, check if item user ID is you
  bne-      end         # If it isn't, end code
  li        r0, 0             # If it is, prevent you from using item
end:

Code:
Manipulate return pointer to control targetted CPU inputs (kart, items etc)
80589BE4
  lbz      r0, 0x10(r3)
  lis      r12, 0x8000
  lbz      r12, 0x1620(r12) # Load camera target ID
  cmpw      r0, r12 # Check if camera target is equal to player ID
  bne      end # If not, end code
  li        r0, 0 # If it is, set ID to mine so pointer calculation will return my pointer
end:
Code:
Cycle camera through everyone
805971F8
.set controller, 0x803414C2 # Controller address
.set buttonMask, 0xYYYY # Both previous and next button masked together
.set buttonPrev, 0xZZZZ # Button to cycle to previous
  lis      r30, 0x8000
  lbz      r4, 0x1620(r30) # Load camera target ID (stored in EVA)
  lis      r12, 0x8034
  lhz      r3, controller@l(r12) # Load controller address
  lis      r12, 0x809C
  lwz      r12, -0x11E0(r12)
  lbz      r12, 0x10(r12) # Obtain amount of players in the race
  subi      r12, r12, 0x1 # Subtract by one so it's correct
  andi.    r3, r3, buttonMask # Check if either cycle buttons are being pressed
  beq-      setPressState # If it isn't, skip code and go to setPressState to set isPress to false
  lbz      r11, 0x1621(r30) # Load pressState
  cmpwi    r11, 0 # Check if button is not pressed
  bne-      setPressState # If pressed, skip code (Since it sets it after first execution, code below will only execute for a frame)
  andi.    r11, r3, buttonPrev # Check if cycle to previous button is pressed
  beq-      cycleNext # If it isn't, cycle to the next
  cmpwi    r4, 0 # Checks if camera target ID is zero
  subi      r4, r4, 0x1 # Cycle to previous (NOTE: If you are in a race and targetting player ID above 1 then go to TT, you will freeze when increasing because it is invalid ID. I forgot to check it while making the code)
  bne      storeCam # If not zero, branch to store
  mr        r4, r12 # If it is zero, cycle back to last player ID (player amount - 1)
  b        storeCam # Store cam
cycleNext:
  cmpw      r12, r4 # Checks if last player ID (player amount - 1) is equal to camera target ID (camera is targetting last player)
  addi      r4, r4, 0x1 # Cycle to next (NOTE: If you are in a race and targetting player ID above 4 then go to TT, you will freeze when increasing because it is invalid ID. I forgot to check it while making the code)
  bne-      storeCam # If not equal, branch to store
  li        r4, 0 # If it is, reset back to first player
storeCam:
  stb      r4, 0x9C(r29) # Store camera target ID to camera ID
  stb      r4, 0x1620(r30) # Store camera target ID to EVA
setPressState:
  andi.    r3, r3, buttonMask # Check if either cycle buttons are being pressed
  li        r11, 0x1 # Set to true
  bne-      .loc_0x78 # If either pressed, store true to pressState
  li        r11, 0 # Else, it is not pressed, so set to false
pressState:
  stb      r11, 0x1621(r30) # Store pressState
Disable CPU AI for targetted CPU (avoid turning to route, stuck respawn etc)
80728F84
  lis      r12, 0x8000
  lbz      r12, 0x1620(r12) # Load camera target ID
  lwz      r11, 0x0(r29)
  lwz      r10, 0x0(r11)
  lbz      r10, 0x10(r10) # Load CPU ID
  cmpw      r12, r10 # If camera target ID is equal to CPU ID
  bne      end # Skip code if not equal
  lwz      r12, 0x4(r11)
  lwz      r11, 0x14(r12)
  rlwinm    r11,r11,0,0,30 # If it is, clear isCpu bit
  stw      r11, 0x14(r12)
  blr     
end: # original
  stwu      r1, -0x10(r1)
Code:
Targetted CPU has player minimap icon elements (Big icon, searchlight, outline etc)

Big icon and searchlight
807E1CA8
  lis      r12, 0x8000
  lbz      r12, 0x1620(r12) # Load camera target ID
  cmpw      r4, r12 # Compare minimap player ID with camera target ID for check

Outline
807E2018
  lwz      r0, 0xB90(r3)
  lis      r12, 0x8000
  lbz      r12, 0x1620(r12) # Load camera target ID
  lwz      r11, -0x4(r28)  # Load pointer
  cmpwi    r11, 0 # if nullptr
  beq-      end # End code if (pointer == NULL)
  lwz      r11, 0x0(r11)
  lwz      r11, 0x0(r11)
  lbz      r11, 0x10(r11)  # Load player ID
  addi      r11, r11, 0x1 # Increment by one so it's correct
  cmpw      r11, r12 # If player ID is equal to camera target ID
  bne      end # End code if not
# If it is, load and store values necessary to give outline to minimap 
  li        r0, 0x2
  lwz      r12, 0x1BC(r28)
  li        r11, 0x1
  stb      r11, 0xBB(r12)
  lwz      r12, 0x1C0(r28)
  li        r11, 0x5
  stb      r11, 0xBB(r12)
end:
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)