.set dbl_9A0, 0x11000014
lis r12, dbl_9A0@h
ori r12, r12, dbl_9A0@l
lis r11, 0x4265
ori r11, r11, 0x2EE1
stw r11, 0 (r12)
.set flt_998, 0x11000010
lis r12, flt_998@h
ori r12, r12, flt_998@l
lis r11, 0x4000
ori r11, r11, 0x0000
stw r11, 0 (r12)
.set flt_994, 0x1100000C
lis r12, flt_994@h
ori r12, r12, flt_994@l
lis r11, 0x5980
ori r11, r11, 0x0004
stw r11, 0 (r12)
.set flt_990, 0x11000008
lis r12, flt_990@h
ori r12, r12, flt_990@l
lis r11, 0x0000
ori r11, r11, 0x0000
stw r11, 0 (r12)
.set flt_98C, 0x11000004
lis r12, flt_98C@h
ori r12, r12, flt_98C@l
lis r11, 0x3F80
ori r11, r11, 0x0000
stw r11, 0 (r12)
.set flt_988, 0x11000000
lis r12, flt_988@h
ori r12, r12, flt_988@l
lis r11, 0x420C
ori r11, r11, 0x0000
stw r11, 0 (r12)
b arcsin
arcsin:
.set back_chain, -0x18
.set var_10, -0x10
lis r1, 0xFREE
ori r1, r1, 0xMEMM
lis r9, flt_988@ha
addi r9, r9, flt_988@l
lfs f8, 0x4 (r9)
li r8, 1
stwu r1, back_chain(r1)
lis r6, 0x4330
fmr f0, f8
lfs f7, 0x8 (r9)
lfs f12, 0(XXXX)
li r10, 3
loc_840:
addi r7, r10, -2
mtctr r7
loc_848:
fmuls f0, f0, f12
bdnz loc_848
cmplwi cr7, r8, 1
beq cr7, loc_8D8
xoris r7, r8, 0x8000
stw r6, 0x18+var_10(r1)
stw r7, 0x18+var_10+4(r1)
cmplwi cr7, r10, 0x3E9
lfs f11, 0xC (r9)
lfd f9, 0x18+var_10(r1)
lfs f10, 0x10 (r9)
fsub f11, f9, f11
lfs f9, 0x4 (r9)
fsub f10, f11, f10
fsub f9, f11, f9
frsp f11, f11
fdiv f10, f10, f9
frsp f10, f10
fmuls f8, f8, f10
fmuls f0, f0, f8
fdivs f0, f0, f11
fadds f7, f7, f0
beq cr7, loc_8B4
loc_8A4:
addi r10, r10, 2
addi r8, r8, 2
lfs f0, 0x4 (r9)
b loc_840
loc_8B4:
fmr f0, f7
lfs f12, 0x14 (r9)
fmul f0, f0, f12
frsp f0, f0
stfs f0, 0(r9)
addi r1, r1, 0x18
b RETURN
loc_8D8:
fadds f7, f7, f0
b loc_8A4
RETURN: nop
Instructions:
First Make sure all of the first highlighted addresses are free. In some games, that area of memory is free, but other games it might not be. (In BoTW it is NOT free memory)
Fill in the Load r1 with another valid memory region for the code to use. It needs about -20 bytes to store things. Essentially make sure the 20 bytes before the address you enter is free. Not 20 bytes after the address... It stores using negative offsets from the value you enter into r1..
Then replace the highlighted XXXX's with a register containing the sin to calculate the arcsin of. Reminder: it should be a Float value between -1.0 to 1.0
All that matters is that f12 contains the value to calculate, thats all that matters.. You could technically move another F register into f12 if you have the value already loaded in another register.
There is a value to do with the precision of the arcsin function. it is the highlighted 0x3E9. This number should be the amount of iterations you want to do, times 2... The loop increments in steps of 2 so even though that number is 1001, it only does about 500 iterations. More iterations = more precise.
HOWEVER, you should know that the function will become less accurate as the value to calculate gets close to -1.0 or 1.0.
In other words, an arcsin of 0.5 will easily return 6 digits of accuracy.. but arcsin of 1.0 will be about 1.40 instead of the correct 1.57 due to the approximation becoming less accurate around the value of 1.0.
if you really need more precision you can increase that number essentially but the frame rate will drop if you increase it a lot more. But again, it will be flawless at values not near 1.0.
If you are going to call the arcsin function multiple times in your code, you will probably have to lower the iterations in order to avoid lagging the game.
Thats all really....
f0 contains the arcsin of the value you entered in f12 at the beginning. It returns the angle in degrees. NOT radians.
change the stfs instruction to store the result wherever you want.