Code:
# NOTE: Injection addresses are in the following order: PAL, NTSC-U, NTSC-J, NTSC-K
##########################
# Exception Vector Flags #
##########################
#### BEGIN SAMPLE CODE ####
# These flags can be customized at will
.set AlwaysWinVote, 0x800001B0
.set MirrorMode, 0x800001B1
#### END SAMPLE CODE ####
##############
# Host Flags #
##############
# INJECT: 0x8065AE70, 0x806569E8, 0x8065A4DC, 0x80649188
# This is used by the host to store the flags on his console temporarily, and to send them at room start.
# Get message type
HostFlags:
srwi r11, r4, 24
cmpwi r11, 1
bne+ normalRoomMessage
#### BEGIN SAMPLE CODE ####
# The code below places the two 1 bit flags at the topmost bits of the message type.
# There are 14 free bits here, use them wisely.
# It's a Room Start message, attach all flags! Load 0x8000 in r11
lis r11, AlwaysWinVote@ha
# Attach AlwaysWinVote
lbz r12, AlwaysWinVote@l(r11)
slwi r12, r12, 23
or r4, r4, r12
# Attach MirrorMode
lbz r12, MirrorMode@l(r11)
slwi r12, r12, 22
or r4, r4, r12
#### END SAMPLE CODE ####
# Return
b end
# Check if it's a Room Message otherwise
normalRoomMessage:
cmpwi r11, 4
bne end
# It's a Room Chat message! Get message subtype
srwi r11, r4, 8
rlwinm r12, r11, 0, 0xFFFF
#### BEGIN SAMPLE CODE ####
# The sample code uses the first and second message to enable/disable AlwaysWinVote, and the third and fourth to enable/disable MirrorMode
# Flag = !(subtype & 1)
rlwinm r11, r11, 0, 31, 31
xori r11, r11, 1
# Load 0x8000 in r6
lis r6, AlwaysWinVote@ha
# Check if it's AlwaysWinVote (ID 0/1)
cmpwi r12, 1
bgt+ notAlwaysWinVote
stb r11, AlwaysWinVote@l(r6)
b end
# Check if it's MirrorMode (ID 2/3)
notAlwaysWinVote:
cmpwi r12, 3
bgt+ end
stb r11, MirrorMode@l(r6)
#### END SAMPLE CODE ####
# Original instruction
end:
li r0, 2
###############
# Guest Flags #
###############
# INJECT: 0x8065AF70, 0x80656AE8, 0x8065A5DC, 0x80649288
# This is used by guests to parse the host's modified messages
# Set region here
.set REGION, ''
.if (region == 'P' || region == 'p')
.set RKNetController, 0x809C20D8
.elseif (region == 'U' || region == 'u' || region == 'E' || region == 'e')
.set RKNetController, 0x809BD918
.elseif (region == 'J' || region == 'j')
.set RKNetController, 0x809C1138
.elseif (region == 'K' || region == 'k')
.set RKNetController, 0x809B0718
.else
.err
.endif
# Check if the message's mainType is 1 (ROOM START)
srwi r11, r3, 24
cmpwi r11, 1
bnelr+
# This snippet is optional, you can remove it if needed
# Get RKNetController->subs[currentSub].hostAid and check that it matches the aid in r4
# This prevents guests from starting the room, code by Seeky
lwz r11, RKNetController@l(r24)
lwz r12, 0x291C(r11)
mulli r12, r12, 0x58
add r11, r11, r12
lbz r11, 0x5A(r11)
cmpw r11, r4
beq realHost
li r3, 0
blr
#### BEGIN SAMPLE CODE ####
# You can use any bit from 9 to 22 for this
# These two values only take one bit, but can take more if necessary, again you must change this to suit your needs
# Load 0x8000 in r12
realHost:
lis r12, AlwaysWinVote@ha
# Store AlwaysWinVote
rlwinm r11, r3, 9, 31, 31
stb r11, AlwaysWinVote@l(r12)
# Store MirrorMode
rlwinm r11, r3, 10, 31, 31
stb r11, MirrorMode@l(r12)
#### END SAMPLE CODE ####
# Finally, clean up the subType to remove any flag
rlwinm r3, r3, 0, 22, 7
blr
###############
# Reset Flags #
###############
# This code resets the flags in order to prevent them from being preserved when joining/creating a new room or going offline.
# INJECTS:
# DWC_SetupGameServer = 0x800D1AB0, 0x800D1A10, 0x800D19D0, 0x800D1B10
# DWC_ConnectToAnybodyAsync = 0x800D1980, 0x800D18E0, 0x800D18A0, 0x800D19E0
# DWC_ConnectToGameServerAsync = 0x800D1D64, 0x800D1CC4, 0x800D1C84, 0x800D1DC4
# DWC_ConnectToGameServerFromGroupId = 0x800D2CD0, 0x800D2C30, 0x800D2BF0, 0x800D2D30
# DWC_Shutdown = 0x800CCDA8, 0x800CCD08, 0x800CCCC8, 0x800CCE08
#### BEGIN SAMPLE CODE ####
# Reset the flags so they don't affect the game
li r12, 0
lis r11, AlwaysWinVote@ha
sth r12, AlwaysWinVote@l(r11)
#### END SAMPLE CODE ####
# Keep the blr though, we're hooking at a function return
blr