Funnily enough, I don't think you have permission to post it online. I would remove it from that post.
However, the public domained source code can be posted:
<div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space
re;overflow:auto'>@the aim bot 3.9.3 source:
@.org 0x37FBACC
@mov pc, #0x2000000
@037FBACC E3A0F402
@037FBACC E3A00005 //Disabler for reloading test script
@.org 0x2000000
@Let's go ahead and make it so arm-eabi of our favorite GNU compiler adds the
@AR friendly lines on there for us <img src="style_emoticons/<#EMO_DIR#>/biggrin.gif" style="vertical-align:middle" emoid="
" border="0" alt="biggrin.gif" />
.long 0xE2000000
@This ought to make the second half of the E code type work regardless of the
@program's size
@The 8 is the size of the above stuff that isn't part of the program that the
@E type code is copying to WRAM
.long ReferenceLabel-8
@Preserve registers
ldr r0, CustomStack
stmdb r0!, {r1-r11, lr}
@Load player ID of who to lock on to
ldrb r3, Target
@Load latch that must be off in order to change "Target"
ldrb r2, Latch
@Load keypad info
ldr r4, IOKeys
ldrh r4, [r4]
@Check if Start is pressed
tst r4, #0x8
@If it isn't, enable changes to Target for the next time it is pressed
@and skip target change routine
movne r2, #0x0
bne NoTargetChange
@Else, check if "Latch" is disabled, and if it is, increment "Target",
@and set the latch
cmp r2, #0x1
addne r3, r3, #0x1
movne r2, #0x1
NoTargetChange:
@Store "Latch" value and set "Target" to 0 if it is 4, then store "Target" value
strb r2, Latch
and r3, r3, #0x3
strb r3, Target
@Load user's player ID
ldr r1, PlayerID
ldr r1, [r1]
@Check to see if it matches the target and exit the routine if it does
cmp r1, r3
beq AimAtSelf
@Otherwise, load pointers to data of user and target
mov r2, #0xF30
mul r0, r1, r2
mul r5, r3, r2
ldr r4, PlayerData
add r5, r5, r4
add r4, r4, r0
@Load X, Z, and Y positions of user and target and calculate the difference between them
@Also load the speed vectors of the target and add them to the differences so that the aim bot
@will "lead" the shot
@The difference between Y values is made negative because the game's Y coordinate
@is...BACKWARDS?!
@In the process, check if the target is in alt form and aim lower if it is
@and higher if it isn't
ldr r8, [r4]
ldr r9, [r5]
ldr r10, [r5, #0x1C]
add r9, r9, r10
sub r8, r9, r8
ldr r9, [r4, #0x4]
ldr r10, [r5, #0x4]
ldr r11, [r5, #0x20]
add r10, r10, r11
sub r9, r10, r9
ldrb r10, [r5, #0x4BA]
cmp r10, #0x1
addne r9, r9, #0x200
subeq r9, r9, #0xA00
ldr r10, [r4, #0x8]
ldr r3, [r5, #0x8]
ldr r11, [r5, #0x24]
add r3, r3, r11
sub r10, r10, r3
@Divide each value by 2 until all three are less than 65535
@so they can be used by the math functions later
@Mostly handled by a sub routine
mov r3, r8
bl Setto16Bit
mov r3, r9
bl Setto16Bit
mov r3, r10
bl Setto16Bit
@Pythagorean theorem is used to find distance between the vertical axes of the user and target
mul r0, r8, r8
mul r1, r10, r10
add r0, r0, r1
swi #0xD0000
@The arctangent of the height difference between the user and target divided
@by the distance between their vertical axes is the angle that the user needs to aim
@up or down
@The arctangent function isn't made to handle negative inputs, so we copy whether
@the input is negative to a separate register in the mean time and use the
@absolute values (this is done for both uses of the arctangent)
@The pythagorean formula above may possibly make one of the inputs greater
@than 65535, which is too big to use, so the following snippet fixes that
mov r1, r9
ands r6, r1, #0x80000000
rsbmi r1, r1, #0x0
orr r11, r0, #0x4000
mov r3, #0x0
WidthCheckTwo:
tst r11, #0x80000000
moveq r11, r11, lsl #0x1
addeq r3, r3, #0x1
beq WidthCheckTwo
rsb r3, r3, #0x11
mov r0, r0, asr r3
mov r1, r1, asr r3
@First, the arctangent:
bl Arctan
@Now, the arctangent returns the wrong result, because the math the aim bot uses is
@based on spherical coordinates, but the game uses Euclidean coordinates
@so another formula is needed to take the result and convert it to the correct result
@seen below (and also after the other arctangent)
bl Recalc
@Check if the input was negative and correct the output if it was:
cmp r6, #0x0
rsbne r0, r0, #0x0
@Finally done with that angle. Two to go! Let's store our result:
str r0, [r4, #0x84]
@The next angle is the arctangent of the difference between the Y values
@of the user and target divided by the difference of the X values;
@this is the angle the user must face left or right to aim at the target
@The values must be made into positive values and the signs of the values
@set aside (like last time)
mov r0, r8
mov r1, r10
ands r6, r0, #0x80000000
rsbmi r0, r0, #0x0
ands r7, r1, #0x80000000
rsbmi r1, r1, #0x0
bl Arctan
bl Recalc
@Check if the inputs were negative and correct the results accordingly, again:
cmp r7, #0x0
rsbeq r0, r0, #0x0
@Store the angle we just calculated:
str r0, [r4, #0x88]
@Now this is some magic. Remember how we converted to Euclidean coordinates the wrong way?
@This was made possible by making one of the Euclidean coordinates no longer able to hold
@values other than the maximum positive and negative values. Seriously, this is hax.
@We use the sign of one of the inputs on the previous function to determine which value
@to use, and store it just like that.
mov r1, #0x1000
cmp r6, #0x0
rsbne r1, r1, #0x0
str r1, [r4, #0x80]
@So...we're done, right? That was all three angles.
@No, of course we're not done. Why else would there be more code?
@Remember that first angle we stored?
@It was wrong. We need more magic in order to completely convert to Euclidean coordinates.
@...BEHOLD!
tst r0, #0x80000000
rsbmi r0, r0, #0x0
mul r1, r0, r0
ldrh r2, aFour
umull r3, r11, r1, r2
movs r3, r3, lsr #0x1F
addne r11, r11, #0x1
ldr r2, bFour
umull r3, r1, r2, r0
movs r3, r3, lsr #0x1F
addne r11, r11, #0x1
add r0, r1, r11
ldrh r1, cFour
add r0, r0, r1
ldr r1, [r4, #0x84]
ands r2, r1, #0x80000000
rsbmi r1, r1, #0x0
mul r0, r1, r0
mov r0, r0, lsr #0xC
cmp r2, #0x0
rsbne r0, r0, #0x0
@I inlined the programming instead of putting it in a sub routine
@because this routine is only used once (the others are used at least
@twice each).
@The magic is complete! All recalculation formulas were derived using the TI-83's
@curve of best fit functionality given empirical data collected from the game.
@The formulas were converted to the programming you've just seen, and plugged in
@where necessary to make this ugly thing work.
@Let's save that angle before we forget:
str r0, [r4, #0x84]
@Now, here's where the program finally dies. But wait, where is that "Arctan" sub routine
@we called? Or the Recalc and Setto16Bit routines, for that matter?
AimAtSelf:
ldr r0, CustomStack
sub r0, r0, #0x30
ldmia r0!, {r1-r11, lr}
mov r0, #0x5
ldr r12, Return
bx r12
@This isn't it. This is just a bunch of variables we used. Most of which
@belong to the recalculation magic. If you really want to make a "miss" bot,
@change the values that look like "aOne" or "bTwo". Then, feel like an idiot
@for doing so. DO NOT MESS WITH MAGIC.
IOKeys:
.long 0x4000130
PlayerID:
.long 0x20D9CB8
PlayerData:
.long 0x20DA730
Return:
.long 0x37FBB2C
@Some literals for the final bit of magic:
aFour:
.short 0x6829
cFour:
.short 0xB4F
bFour:
.long 0xE2B912F3
@Here's "Setto16Bit". The maximum value a 16 bit variable can
@hold is 655535. This routine converts those differences
@between user and target coordinates into usable 16 bit
@values (values all less than 65535).
Setto16Bit:
tst r3, #0x80000000
rsbmi r3, r3, #0x0
orr r3, r3, #0x4000
mov r6, #0x0
WidthCheckOne:
tst r3, #0x80000000
moveq r3, r3, lsl #0x1
addeq r6, #0x1
beq WidthCheckOne
rsb r6, r6, #0x11
mov r8, r8, asr r6
mov r9, r9, asr r6
mov r10, r10, asr r6
bx lr
@Oh. HERE'S the Arctan. Off all by itself at the end.
@Optimized by yours truly, and yoinked from YE OLDE GBA BIOS.
@I'll give you a hint. It's a recursive fraction. Look up
@Arctan and recursive fraction stuff on Wikipedia. I'm not
@your math professor. GET OUTTA HERE.
@"Wry is Arctan missing? What that mean?"
@Back when I left it out, it was because the Arctan I
@was using was a direct rip from copyrighted code
@that I did not feel like openly distributing out of
@morality. However, since the code has been optimized and
@mostly rewritten, it not only is quite different from
@the original code, but the original code was being "sold"
@as part of the GBA "package" so long ago that no profits
@could possibly be injured by the use of the code.
@If you disagree, you got jokes.
Arctan:
stmdb sp!, {r3, lr}
cmp r1, #0x0
moveq r0, #0x0
beq End
cmp r0, #0x0
moveq r0, #0x4000
beq End
mov r2, r0, lsl #0xE
mov r3, r1, lsl #0xE
cmp r0, r1
blt OverOne
cmp r0, r1
moveq r0, #0x2000
beq End
mov r1, r0
mov r0, r3
bl Recursive
b End
OverOne:
mov r0, r2
bl Recursive
rsb r0, r0, #0x4000
End:
ldmia sp!, {r3, lr}
bx lr
Recursive:
mov r2, r1
DivOne:
cmp r2, r0, lsr #0x1
movls r2, r2, lsl #0x1
bcc DivOne
mov r3, #0x0
DivTwo:
cmp r0, r2
adc r3, r3, r3
subcs r0, r0, r2
teq r2, r1
movne r2, r2, lsr #0x1
bne DivTwo
mov r1, r0
mov r0, r3
mul r1, r0, r0
mov r1, r1, asr #0xE
rsb r1, r1, #0x0
mov r3, #0xA9
mul r3, r1, r3
mov r3, r3, asr #0xE
add r3, r3, #0x390
mul r3, r1, r3
mov r3, r3, asr #0xE
add r3, r3, #0x900
add r3, r3, #0x1C
mul r3, r1, r3
mov r3, r3, asr #0xE
add r3, r3, #0xFA0
add r3, r3, #0x16
mul r3, r1, r3
mov r3, r3, asr #0xE
add r3, r3, #0x1680
add r3, r3, #0x2A
mul r3, r1, r3
mov r3, r3, asr #0xE
add r3, r3, #0x2080
add r3, r3, #0x1
mul r3, r1, r3
mov r3, r3, asr #0xE
add r3, r3, #0x3600
add r3, r3, #0x51
mul r3, r1, r3
mov r3, r3, asr #0xE
add r3, r3, #0xA200
add r3, r3, #0xF9
mul r0, r3, r0
mov r0, r0, asr #0x10
bx lr
@The actual recalculation formula (that's all that will be said;
@the formula is just a big hack...not just for this code, but for life! Converting
@spherical coordinates to Euclidean coordinates is NOT supposed to be done with
@polynomials!):
Recalc:
mov r0, r0, lsr #0x2
mov r1, #0x1C
cmp r0, r1
blt CorrectDone
mov r1, #0xFE0
cmp r0, r1
movlt r2, r0
mullt r0, r2, r0
@ldrlt r1, aOne
movlt r1, #0x77
mullt r11, r1, r0
ldrlt r1, bOne
mullt r0, r1, r2
movlt r11, r11, lsr #0x13
movlt r0, r0, lsr #0x10
sublt r0, r0, r11
movlt r1, #0x35
sublt r0, r0, r1
movge r0, #0x18000
bge CorrectDone
mov r1, #0xD00
cmp r0, r1
movge r1, r0
mulge r0, r1, r0
umullge r3, r2, r0, r1
ldrge r0, aThree
mulge r2, r0, r2
umullge r12, r11, r3, r0
addge r2, r2, r11
movge r12, r2, lsr #0x4
mulge r0, r1, r1
ldrge r2, bThree
umullge r11, r3, r0, r2
movge r11, r11, lsr #0x1B
movge r3, r3, lsl #0x5
addge r11, r3, r11
ldrge r2, cThree
mulge r0, r1, r2
movge r0, r0, lsr #0x8
subge r1, r12, r11
addge r1, r1, r0
ldrge r0, dThree
subge r0, r1, r0
bge CorrectDone
mov r1, #0x800
add r1, #0xD0
cmp r0, r1
movge r2, r0
mulge r0, r2, r0
@ldrge r1, aTwo
movge r1, #0xD9
mulge r11, r1, r0
ldrge r1, bTwo
mulge r0, r1, r2
movge r11, r11, lsr #0x11
movge r0, r0, lsr #0x11
subge r0, r11, r0
ldrgeh r1, cTwo
addge r0, r0, r1
CorrectDone:
bx lr
@Literals used by above magic and a couple used by the input
@routine at the beginning
@aOne:
@.byte 0x77
bOne:
.long 0x1F27D
@aTwo:
@.byte 0xD9
bTwo:
.long 0xD0310
cTwo:
.short 0x220A
.short 0
aThree:
.long 0x1F8F58
bThree:
.long 0x256C62B
cThree:
.long 0x3B1BB
dThree:
.long 0xF767A
@For those of you who have made sense of this, you may have been wondering where
@the heck "CustomStack" was. It's right here at the end, so no lines of all 0s
@are necessary in the E type code to make room for the custom stack.
CustomStack:
.long CustomStack+0x200002C
@Last AR line (the hook that's at the top of the file):
EndofProgram:
@Let's put in a spacer in case the program size isn't a multiple of 8
@so the resulting output is guaranteed to fit right into an AR handler
.org (EndofProgram+4)&0xFFFFFFF8
ReferenceLabel:
@The hook itself, as seen at the beginning of the source code
.long 0x037FBACC
mov pc, #0x2000000
@The following is so that the E type code won't overwrite these variables
@but it will add extra lines of "0" that must be erased from the end of
@the code
.org CustomStack+0x34
Target:
.byte 0
Latch:
.byte 0
.short 0
</div>