Camera Toggle [JoshuaMK]
#1
Camera Toggle [JoshuaMK]

Press a mapped button of choice to switch the camera between 3 modes.

(NTSC-U)
C27E4C9C 00000011
3D608034 807FEE20
616BXXXX A16B0000
3D808170 717DYYYY
2C1DYYYY 40A20014
896C0F00 396B0001
280B000F 41A00008
39600000 996C0F00
2C0B0002 40820048
3D808088 618CDBD0
A16C0000 2C0B3F50
41820018 2C0B3FB0
4182001C 39603F50
3BA03ECD 48000018
39603FB8 3BA03F20
4800000C 39603F80
3BA03F00 B16C0000
B3AC0014 00000000
045979c4 60000000

(PAL)
C27EEFAC 00000011
3D608034 807F3618
616BXXXX A16B0000
3D808170 717DYYYY
2C1DYYYY 40A20014
896C0F00 396B0001
280B000F 41A00008
39600000 996C0F00
2C0B0002 40820048
3D808089 618C2310
A16C0000 2C0B3F50
41820018 2C0B3FB0
4182001C 39603F50
3BA03ECD 48000018
39603FB8 3BA03F20
4800000C 39603F80
3BA03F00 B16C0000
B3AC0014 00000000
045A29FC 60000000

(NTSC-J)
C27EE618 00000011
3D608034 807F2678
616BXXXX A16B0000
3D808170 717DYYYY
2C1DYYYY 40A20014
896C0F00 396B0001
280B000F 41A00008
39600000 996C0F00
2C0B0002 40820048
3D808089 618C1960
A16C0000 2C0B3F50
41820018 2C0B3FB0
4182001C 39603F50
3BA03ECD 48000018
39603FB8 3BA03F20
4800000C 39603F80
3BA03F00 B16C0000
B3AC0014 00000000
045A237C 60000000

(NTSC-K)
C27DD36C 00000011
3D608033 807F1C58
616BXXXX A16B0000
3D808170 717DYYYY
2C1DYYYY 40A20014
896C0F00 396B0001
280B000F 41A00008
39600000 996C0F00
2C0B0002 40820048
3D808088 618C0718
A16C0000 2C0B3F50
41820018 2C0B3FB0
4182001C 39603F50
3BA03ECD 48000018
39603FB8 3BA03F20
4800000C 39603F80
3BA03F00 B16C0000
B3AC0014 00000000
04590A54 60000000



Guide

Note: This code makes use of user input. See this guide for reference on filling in values: https://mkwii.com/showthread.php?tid=44

XXXX = Controller Address
YYYY = Button that changes camera view



Suggested Values:

(GCN) 
YYYY = 0880 - Y 
[b](Wavebird GCN) [/b]
YYYY = 0800 - Y 
(Classic Controller) 
YYYY = 8000 - Y 
[b](Wii Remote + Nunchuck) [/b]
YYYY = 1000 - ( - )
[b](Wii Wheel) [/b]
YYYY = 1000 - ( - )



#########
#Source ASM#
#########

###############
#Register Safety Notes#
###############

#r29 is safe to use as it gets overwritten by a mulli instruction the line after this code.

.set region, ' ' #Fill in E, P, J, or K within the quotes for your region when Compiling! Lowercase letters can also be used.

.if (region == 'E' || region == 'e') # RMCE
lis r11, 0x8034
lwz r3, -0x11E0 (r31)
.elseif (region == 'P' || region == 'p') # RMCP
lis r11, 0x8034
lwz r3, 0x3618 (r31)
.elseif (region == 'J' || region == 'j') # RMCJ
lis r11, 0x8034
lwz r3, 0x2678 (r31)
.elseif (region == 'K' || region == 'k') # RMCK
lis r11, 0x8033
lwz r3, 0x1C58 (r31)
.else # Invalid Region
.abort
.endif

ori r11, r11, 0x3e80 #NTSC-U GCN used just for compilation
lhz r11, 0 (r11)

lis r12, 0x8170 #Set Mem81 address, 1st Half, used offset for 2nd half

andi. r29, r11, 0x0880 #Y button used just for compilation
cmpwi r29, 0x0880 #Check if button is at least pressed
bne+ reset_timer #Reset Timer Back to 0 if no Y Button Press

lbz r11, 0x0F00 (r12) #Load Timer Value
addi r11, r11, 1 #Increment Timer

cmplwi r11, 15
blt+ dont_reset_timer #If not greater than 15, do NOT reset timer

reset_timer:
li r11, 0 #Once timer hits 15, reset it

dont_reset_timer:
stb r11, 0x0F00 (r12) #Store updated Timer Value
cmpwi r11, 2 #Check if value is 2 (time to update camera)
bne- no_change #If not 2, skip already down to vannila instruction

#Set Camera Height Address

.if (region == 'E' || region == 'e') # RMCE
lis r12, 0x8088
ori r12, r12, 0xDBD0
.elseif (region == 'P' || region == 'p') # RMCP
lis r12, 0x8089
ori r12, r12, 0x2310
.elseif (region == 'J' || region == 'j') # RMCJ
lis r12, 0x8089
ori r12, r12, 0x1960
.elseif (region == 'K' || region == 'k') # RMCK
lis r12, 0x8088
ori r12, r12, 0x0718
.else # Invalid Region
.abort
.endif

lhz r11, 0 (r12)

cmpwi r11, 0x3f50 #Compare Camera Height to "Close Up" Setting
beq- far_out #If Equal, Set Camera to "Far Out"

cmpwi r11, 0x3fb0 #Compare Camera Height to "Far Out" Setting
beq- normal_value #If Equal, Set Camera to "Normal"

li r11, 0x3f50
li r29, 0x3ecd
b store_value

far_out:
li r11, 0x3fb8
li r29, 0x3f20
b store_value

normal_value:
li r11, 0x3f80
li r29, 0x3f00

store_value:
sth r11, 0 (r12) #Store New Camera Height to Proper RAM Address
sth r29, 0x0014 (r12) #Offset 0x0014 From Camera Height is Camera Distance. Store Camera Distance There.

no_change:



Code Creator: JoshuaMK
Code Contributors: Jae (Camera Height Address), davidevgen (Camera Distance Address), Vega (Optimized Source)
Super Mario Eclipse, what Super Mario Sunshine could've been.
Reply
#2
Since NTSC-J is not working atm, the code will be in this subforum for the time being. Btw, you can make this a C0 codetype (for the first ASM only) instead of using a OSSleepthread subroutine address. Wink

Also, I recommend keeping the code structure the same way for all regions (even though this will you cause you to use an unneeded extra instruction for controller button loading on U, J and K), and use macros to change values that are region dependent. Trying to work with multiple sources doesn't make any sense.

For why the Japan version is not working, that is something wrong with the source. As the ports for the OSSleepthread have been testing on multiple codes countless times. I doubt you messed up porting the address that has the nop. You will need to step by step the japan version in Dolphin to fully diagnose. Have you done step-by-stepping before? This one will be weird cause one address is called nonstop, so you may need to set an instruction BP on the other address (the nop), I'm guessing that address is the one that gets called when track loads???

Anyway good luck with fixing the Japan version. I'm out of town cuz of work so I won't be much help....

And nice code!!
Reply
#3
(07-09-2019, 01:26 AM)Vega Wrote: Since NTSC-J is not working atm, the code will be in this subforum for the time being. Btw, you can make this a C0 codetype (for the first ASM only) instead of  using a OSSleepthread subroutine address. Wink

Also, I recommend keeping the code structure the same way for all regions (even though this will you cause you to use an unneeded extra instruction for controller button loading on U, J and K), and use macros to change values that are region dependent. Trying to work with multiple sources doesn't make any sense.

For why the Japan version is not working, that is something wrong with the source. As the ports for the OSSleepthread have been testing on multiple codes countless times. I doubt you messed up porting the address that has the nop. You will need to step by step the japan version in Dolphin to fully diagnose. Have you done step-by-stepping before? This one will be weird cause one address is called nonstop, so you may need to set an instruction BP on the other address (the nop), I'm guessing that address is the one that gets called when track loads???

Anyway good luck with fixing the Japan version. I'm out of town cuz of work so I won't be much help....

And nice code!!
C0 Is a good idea. Didn't think of it. Also, I went and completely rewrote the Custom Laps code, not only making it about 5-6 lines shorter, but I also lifted the limit from 32769 laps to +60000 laps by changing the cmpwi instructions to cmplwi insructions. Also, the input number now reflects what lap you will be on when laps start counting instead of following a complicated equation.
Super Mario Eclipse, what Super Mario Sunshine could've been.
Reply
#4
First thing's first. I checked every port for every address (address of ASM, address of ur nop, address of camera height, address of camera distance), and they are all Good.

I did some changes to your source, and made it more organized. I also rerouted some non-optimized branch routes, and added branch hints. So when you compile this, you will need to change the region letter at the top for each version you compiled (it is left blank at the moment). They will all compile slightly different. Ofc, don't forget to remove the 0x3E80 & 0x0880 from the compiled code for the user's controller stuff, and don't forget to test this with your 32 bit nop.

I'm still out of town, so I can't actually test this in game.

If you want to change this to a C0 (assuming this new source works on all regions after tests), you just need to change your use of r4 to r5, then remove the vannila instruction (leave the label name there, you can end sources with a label name). For C0 codes, select the C0 option in PyiiASMH before compiling.

Anyway, here's the source...


.set region, '' #Fill in E, P, J, or K within the quotes for your region when Compiling! Lowercase letters can also be used.

.if (region == 'E' || region == 'e') # RMCE
lis r11, 0x8034
.elseif (region == 'P' || region == 'p') # RMCP
lis r11, 0x8034
.elseif (region == 'J' || region == 'j') # RMCJ
lis r11, 0x8034
.elseif (region == 'K' || region == 'k') # RMCK
lis r11, 0x8033
.else # Invalid Region
.abort
.endif

ori r11, r11, 0x3E80 #NTSC-U GCN used just for compilation
lhz r11, 0 (r11)

lis r12, 0x8170 #Set Mem81 address, 1st Half, used offset for 2nd half

andi. r0, r11, 0x0880 #Y button used just for compilation
cmpwi r0, 0x0880 #Check if button is at least pressed
bne+ reset_timer #Reset Timer Back to 0 if no Y Button Press

lbz r11, 0x0F00 (r12) #Load Timer Value
addi r11, r11, 1 #Increment Timer

cmplwi r11, 150
blt+ dont_reset_timer #If not greater than 150, do NOT reset timer

reset_timer:
li r11, 0 #Once timer goes pass 150, reset it

dont_reset_timer:
stb r11, 0x0F00 (r12) #Store updated Timer Value
cmpwi r11, 2 #Check if value is 2 (time to update camera)
bne- no_change #If not 2, skip already down to vannila instruction

#Set Camera Height Address

.if (region == 'E' || region == 'e') # RMCE
lis r12, 0x8088
ori r12, r12, 0xDBD0
.elseif (region == 'P' || region == 'p') # RMCP
lis r12, 0x8089
ori r12, r12, 0x2310
.elseif (region == 'J' || region == 'j') # RMCJ
lis r12, 0x8089
ori r12, r12, 0x1960
.elseif (region == 'K' || region == 'k') # RMCK
lis r12, 0x8088
ori r12, r12, 0x0718
.else # Invalid Region
.abort
.endif

lhz r11, 0 (r12)

cmpwi r11, 0x3f50 #Compare Camera Height to "Close Up" Setting
beq- far_out #If Equal, Set Camera to "Far Out"

cmpwi r11, 0x3fb0 #Compare Camera Height to "Far Out" Setting
beq- normal_value #If Equal, Set Camera to "Normal"

li r11, 0x3f50
li r4, 0x3ecd
b store_value

far_out:
li r11, 0x3fb0
li r4, 0x3f10
b store_value

normal_value:
li r11, 0x3f80
li r4, 0x3f00

store_value:
sth r11, 0 (r12) #Store New Camera Height to Proper RAM Address
sth r4, 0x0014 (r12) #Offset 0x0014 From Camera Height is Camera Distance. Store Camera Distance There.

no_change:
mr r30, r3 #Vannila Instruction

Reply
#5
It still doesn't work on NTSC-J. Also I was looking, and it seems to crash well after the code, to the point to where I got to impatient to continue after 5 minutes of stepping code. It also crashes in the form of getting stuck in an infinite loop rather than the hardcore 00000300 crash...

I think I am going to start playing around with registers
Super Mario Eclipse, what Super Mario Sunshine could've been.
Reply
#6
It appears the floating point RAM changes in NTSC-J causes a bad floating value, which causes an invalid instruction somewhere, then causing a crash and you end in an infinite loop (i know the one you are talking about). There's a few things to try.

Some options....

1. Change the address of the 1st ASM, you can use the Millisecond Display Modifer address so the actual floating point changes to RAM don't start til the timer starts. If it still freezes at track load on JAPAN, then its something with your nop. Ofc, you are nopping some branch, follow the branch again, and double check what you are skipping/not skipping.

2. Try a different set of floating values, if it works on Japan. Then change them for other regions and retest U, P, and K. If all good, it's just something you will have to accept, idk how much time you want to dig into this rabbit hole.

3. Try #1 and #2 with old source first!! Just in case I botched the new source.

--

Also here's a side note when dealing with offset values greater than 0x7FFF when you wanna load from a memory address set by lis...

Let's say you want to load a word value from 0x8045C21C. To load this without using an ori instruction, just increase the lis value by 1, then sign extend the offset value. Like this...

lis r12, 0x8046 #8045 plus 1
lwz r12, 0xFFFFC21C (r12) #0xC21C sign extended

Try that out for future codes.
Reply
#7
(07-09-2019, 08:34 PM)Vega Wrote: It appears the floating point RAM changes in NTSC-J causes a bad floating value, which causes an invalid instruction somewhere, then causing a crash and you end in an infinite loop (i know the one you are talking about). There's a few things to try.

Some options....

1. Change the address of the 1st ASM, you can use the Millisecond Display Modifer address so the actual floating point changes to RAM don't start til the timer starts. If it still freezes at track load on JAPAN, then its something with your nop. Ofc, you are nopping some branch, follow the branch again, and double check what you are skipping/not skipping.

2. Try a different set of floating values, if it works on Japan. Then change them for other regions and retest U, P, and K. If all good, it's just something you will have to accept, idk how much time you want to dig into this rabbit hole.

3. Try #1 and #2 with old source first!! Just in case I botched the new source.

--

Also here's a side note when dealing with offset values greater than 0x7FFF when you wanna load from a memory address set by lis...

Let's say you want to load a word value from 0x8045C21C. To load this without using an ori instruction, just increase the lis value by 1, then sign extend the offset value. Like this...

lis r12, 0x8046 #8045 plus 1
lwz r12, 0xFFFFC21C (r12) #0xC21C sign extended

Try that out for future codes.
Okay! I will let you know shortly what happens.

Okay it is ready to be put in the Codes Thread!
Super Mario Eclipse, what Super Mario Sunshine could've been.
Reply
#8
Nevermind the milliseconds timer keeps camera from being able to toggle when it shows your lap time after crossing onto the next lap. Any other ideas?
Super Mario Eclipse, what Super Mario Sunshine could've been.
Reply
#9
Use the address that the Universal Meter uses.
Reply
#10
(07-09-2019, 11:42 PM)Vega Wrote: Use the address that the Universal Meter uses.
Code is now complete  Rolleyes  Please move this to the codes forum.
Super Mario Eclipse, what Super Mario Sunshine could've been.
Reply


Forum Jump:


Users browsing this thread: 6 Guest(s)