 |
Komrade |
 |
Joined: Tue Mar 27, 2007 10:18 am Posts: 1328
|
The hell? Dude, the aim bot is at version 3.9.3, and the last version released was 3.9.1 (originally just referred to as 3.9). I don't know where you get this "4.0" number from. The reason ARP is being so crude to Megablast is because the last thing we need is Rune stealing more codes from us, and since he clearly enjoys stealing from me the most, anything posted aim bot related is guaranteed to be stolen. The reason Rune stealing codes is a problem is because he hands them out to people while insulting the creators in the process. Therefore, it's just as bad to post the code in plain view as it is to ask Rune for it. Megablast asked Rune for it and then rubbed it in my face in a PM, so he deserves any shit talk he gets. I hope his parents crap on his face in his sleep so he can choke on it; same goes for Rune. Since WiFi is already ruined and Rune can't really insult me more than he already has, I thought I'd go ahead and Public Domain:Code: @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 :D
.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 Note: SubDrag would laugh at this. I was asking him stuff about "wtf why did Nintendo use Euclidean coordinates?" and "Well how the hell do I calculate the angles now?" and he linked me to the associated wikipedia article filled with all these matrix transforms I didn't bother reading about. So that just left me with that nasty hack ^. Now you know why it still doesn't aim perfectly (although some of the imperfection is due to the fact that when you're aiming at a certain angle, the game stops automatically centering the cursor and instead allows it to float off center; this is not the aim bot's fault, the game is just dorky). Oh, also note, I didn't use the CLZ instruction. I was going to, but it wasn't working in No$GBA, so I assumed it wouldn't work on the hardware. Hurfadurf, it probably would. I really don't know. Silly me for thinking No$GBA was precise enough to give me a good idea of what I had to play with.
_________________ 
Last edited by Hextator on Fri Apr 18, 2008 5:15 pm, edited 1 time in total.
|
|