Free Look [JoshuaMK]
#1
This was a code I was wanting to keep to myself until completed, but I just simply can't figure out why the camera's params are corrupting when the camera's angle float values are subtracted from. If I or some other person can figure this out, I can continue with this code. Currently only tilting up or right works. Down and left corrupt everything.



Free Look [JoshuaMK]

28343E80 F7FF0800
C2597F54 0000002A
3D808034 618CC202
3FA08145 8BFD01FF
281F0000 40A20014
999D01FF D05D0200
D01D0204 D03D0208
C05D0200 C01D0204
C03D0208 A3CCFFFE
892C0000 888C0001
886C0002 88AC0003
3929FF80 3884FF80
3863FF80 38A5FF80
2C090041 41810014
2C09FFBF 41810010
3920FFBF 48000008
39200041 2C040041
41810014 2C04FFBF
41810010 3880FFBF
48000008 38800041
2C030041 41810014
2C03FFBF 41810010
3860FFBF 48000008
38600041 2C030041
4181FFF8 2C05FFBF
41810010 38A0FFBF
48000008 38A00041
993D020C 989D0210
987D0214 98BD0218
2C03000F 41810010
2C03FFF1 41800008
4800000C C3FD0214
EC42F82A 2C05000F
41810010 2C05FFF1
41800008 4800000C
C3DD0218 EC00F02A
2C1E0090 40820020
2C05000F 41810010
2C05FFF1 41800008
4800000C C3BD0218
EC21E82A D05D0200
D01D0204 D03D0208
D05C00AC D03C00B4
D01C00B0 00000000
CC000000 00000000
04597F54 D01C00B0
054501FF 00000000
E0000000 80008000



#ASM

#~~~~~~~~~~~#
#Inject > 80597F54#
#~~~~~~~~~~~#

#PARAMS for camera angle
#--------------------------
#f2 = X Axis Position
#f1 = Z Axis Position
#f0 = Y Axis Position

.macro grab_controller_address
lis r12, 0x8034
ori r12, r12, 0xC202
.endm

.macro grab_camera_params
lis r29, 0x8145
lbz r31, 0x01FF (r29)
cmplwi r31, 0
bne+ params_set
stb r12, 0x01FF (r29)
stfs f2, 0x0200 (r29)
stfs f0, 0x0204 (r29)
stfs f1, 0x0208 (r29)
params_set:
lfs f2, 0x0200 (r29)
lfs f0, 0x0204 (r29)
lfs f1, 0x0208 (r29)
.endm

.macro store_floats
stfs f2, 0x0200 (r29)
stfs f0, 0x0204 (r29)
stfs f1, 0x0208 (r29)
stfs f2, 0x00AC (r28)
stfs f1, 0x00B4 (r28)
stfs f0, 0x00B0 (r28)
.endm

.macro subtract
subi r9, r9, 0x80
subi r4, r4, 0x80
subi r3, r3, 0x80
subi r5, r5, 0x80
.endm

.macro divide
li r11, 0x4
divw r9, r9, r11
divw r4, r4, r11
divw r3, r3, r11
divw r5, r5, r11
.endm

.macro multiply
mulli r9, r9, 3
mulli r4, r4, 3
mulli r3, r3, 3
mulli r5, r5, 3
.endm

.macro compare_statements
cmpwi r9, 0x41
bgt shrink_r9
cmpwi r9, -0x41
bgt continue
li r9, -0x41
b continue
shrink_r9:
li r9, 0x41
continue:
cmpwi r4, 0x41
bgt shrink_r4
cmpwi r4, -0x41
bgt continue_1
li r4, -0x41
b continue_1
shrink_r4:
li r4, 0x41
continue_1:
cmpwi r3, 0x41
bgt shrink_r3
cmpwi r3, -0x41
bgt continue_2
li r3, -0x41
b continue_2
shrink_r3:
li r3, 0x41
continue_2:
cmpwi r5, 0x41
bgt shrink_r5
cmpwi r5, -0x41
bgt continue_3
li r5, -0x41
b continue_3
shrink_r5:
li r5, 0x41
continue_3:
.endm

.macro figure_controller_values
lhz r30, -0x2 (r12)
lbz r9, 0 (r12)
lbz r4, 0x1 (r12)
lbz r3, 0x2 (r12)
lbz r5, 0x3 (r12)
subtract
compare_statements
stb r9, 0x020C (r29)
stb r4, 0x0210 (r29)
stb r3, 0x0214 (r29)
stb r5, 0x0218 (r29)
.endm

.macro compare_and_add
cmpwi r3, 15
bgt add_f31
cmpwi r3, -15
blt add_f31
b check_vertical
add_f31:
lfs f31, 0x0214 (r29)
fadds f2, f2, f31
check_vertical:
cmpwi r5, 15
bgt add_f30
cmpwi r5, -15
blt add_f30
b check_z
add_f30:
lfs f30, 0x0218 (r29)
fadds f0, f0, f30
check_z:
cmpwi r30, 0x0090
bne the_end
cmpwi r5, 15
bgt add_f29
cmpwi r5, -15
blt add_f29
b the_end
add_f29:
lfs f29, 0x0218 (r29)
fadds f1, f1, f29
the_end:
.endm

grab_controller_address
grab_camera_params
figure_controller_values
compare_and_add
store_floats



I don't expect anything to come from this, but I wanted to try all options.
Super Mario Eclipse, what Super Mario Sunshine could've been.
Reply
#2
When nopping the 3 store instructions in Memory (80597F4C/F50/F54). The Y Axis (f0) was still getting written to/updated. Some other instruction is also writing to it.

The coordinates obviously have position/negative limits. You will need to find out what those are which can be a pain. For my globe code, I was lucky with it being a sphere. Degrees had a 179.99999~/-179.99999~ (0xB3/-0xB3) limit.

Your use of multiplying/dividing seems too much of a hassle. Look at the source in my globe code https://mkwii.com/showthread.php?tid=1260
Do something like that (using a integer to float conversion) to get rid of mulli/divw.

Take note that when I was doing bgt/blt branches for the sphere degree check. I did NOT do logical compares since negative numbers could occur.

Also double check that you are sure you have the XYZ mapped correctly. On graphs, Z goes north south. Y goes up down. X goes west east.
Reply
#3
To start, yes, XYZ is mapped correctly. I put a lot of testing into that just to make sure it is correct. I have already made each compare be non-logical, and the values I have set for the speed should have it so I can pan down/left for quite some time before anything should corrupt. Something I have also noticed when testing with this code is that on very rare occasions I can hold down/left and actually have it work properly for about a half second before I end up plunged into the darkness.
Super Mario Eclipse, what Super Mario Sunshine could've been.
Reply
#4
Maybe your code could benefit from some simplification. I find that a code is a lot easier to debug when it’s optimized.

Recommendation 1: instead of having multiple branches, take the absolute value of your number you want to check and then just check if it’s greater/less than some bound, in one branch. Here’s the relevant function (parameter r3, return r6) from the PPC CWG:
srawi R4,R3,31
xor R5,R4,R3
subf R6,R4,R5

Recommendation 2: I noticed you have a lot of repeated code for the checks with different registers. There are two ways to fix this: either make your repeated code into a function or implement self-modifying ASM, in which you use the BL trick to get the address of the ASM address you want, then use rlwimi to change the register bits of the opcode. The catch with this is that you have to flush the instruction cache in order to fully “reset” your ASM; since it’s a little overkill so I would probably just use a function.
Reply
#5
Yeah even before putting this on the help thread I was planning to optimize it anyway. I am already planning to turn some of the code into functions since this is only 1/2 of what the code would be. That bit of code you shared is snazzy tho. It will definately be useful for future codes.
Super Mario Eclipse, what Super Mario Sunshine could've been.
Reply
#6
(09-22-2019, 11:39 PM)salmon01 Wrote: Maybe your code could benefit from some simplification. I find that a code is a lot easier to debug when it’s optimized.

Recommendation 1: instead of having multiple branches, take the absolute value of your number you want to check and then just check if it’s greater/less than some bound, in one branch. Here’s the relevant function (parameter r3, return r6) from the PPC CWG:
srawi R4,R3,31
xor R5,R4,R3
subf R6,R4,R5

Recommendation 2: I noticed you have a lot of repeated code for the checks with different registers. There are two ways to fix this: either make your repeated code into a function or implement self-modifying ASM, in which you use the BL trick to get the address of the ASM address you want, then use rlwimi to change the register bits of the opcode. The catch with this is that you have to flush the instruction cache in order to fully “reset” your ASM; since it’s a little overkill so I would probably just use a function.

I know little to nothing about cache on Broadway. Would this correct to do the part in bold?

r4 = Location to write in new instruction
r3 = contains new instruction
r0 = 0

stw r3, 0 (r4) #Store modified instruction to static memory

dcbst r0, r4 #Update memory
sync 0 #wait for update, hard sync

icbi r0, r4 #Invalidate block w/ old instruction
sync 0 #wait for update, hard sync

isync #remove copy in own instruction buffer

--

Is this close to what needs to be done? Or is this overkill?
Reply
#7
(10-09-2019, 10:47 PM)Vega Wrote: Is this close to what needs to be done? Or is this overkill?

I actually haven't tried this myself, looking in the Broadway manual it says to use these instructions (so your extra sync probably isn't necessary):

dcbst 0, r4
sync
icbi 0, r4
isync

The only real use case I see for it is backing up floats to the stack in fewer lines, in case you want to back up like ten floats for whatever reason.
Basically, this process is necessary because the instruction cache on Broadway isn't cache coherent (unlike the data cache which is)
Reply
#8
All of this will be useful for the Free Look code. Reiterating on what I said, this is only 1/2 of what will be the final code, as this just simply changes where the camera is pointing. The second half will move the camera on the x/y/z axis. I haven't actually returned to this code yet, but I plan to in the near future.
Super Mario Eclipse, what Super Mario Sunshine could've been.
Reply


Forum Jump:


Users browsing this thread: 4 Guest(s)