smh nathan closing tabs like what the hell
EXPANDING THE THING THAT MAKES NIDORAN'S/ILLUMISE'S MALE VARIANTS HATCH FROM EGGS
based on a table
first, the routine:
usage:Spoiler:Code:.text .align 2 .thumb @ hook via r1 (00 49 08 47 XX+1 XX XX XX) at 46068 (BPRE) / 70858 (BPEE) / 415F6 (AXVE) main: ldr r7, terminate mov r3, #0x0 loop: ldr r0, table lsl r2, r3, #0x1 add r2, r0, r2 ldrh r5, [r2, #0x0] cmp r5, r7 beq return add r3, #0x1 cmp r5, r4 bne loop mov r0, #0x8C lsl r0, r0, #0x1 add r0, r8 ldrh r1, [r0] mov r0, #0x80 lsl r0, r0, #0x8 and r0, r1 cmp r0, #0x0 beq return ldrh r4, [r2, #0x2] return: ldr r1, getparents bx r1 .align 2 getparents: .word [b]0x0804609B[/b] @ 0x0804609B BPRE; 0x0807088D BPEE; 0x08041F88 AXVE terminate: .word 0x0000FEFE @ end the table below with this table: @change as is necessary .word table1 + [b]0x[place where you plan on inserting this][/b] table1: .hword 0x001D @ nidoran female .hword 0x0020 @ nidoran male .hword 0x0183 @ illumise .hword 0x0182 @ volbeat @ theoretical new entries .word 0x0000FEFE
- table at the end has a structure:
[hword] - species 1
[hword] - species 2
an egg that is supposed to be species 1 has a 50% chance of turning into species 2 (note at the bottom), and it NEEDS to end with FE FE 00 00 as it does in the example.
- i included addresses for emerald and ruby as well. replace as desired (the hook address and the getparents routine address)
- you need to know where you are going to insert the routine BEFORE compiling it; the table is placed right after the routine and is referenced as such.
proof of concept:Spoiler:![]()
![]()
![]()
![]()
first from female bulba x male venusaur, second from male bulba x ditto, third from illumise and volbeat, last from nidoran(f) x ditto
shoutouts to doesntknowhowtoplay for his research on the subject and to chaotix for initial testing and suggesting the idea of a table instead of some extremely inefficient shtuff that was originally going to happen.
notes:
- species 2 does not ever turn into species 1. so you're breeding your volbeat to get an illumise? you'll only ever get volbeat. just add an entry for volbeat to illumise.
- if you want species 1 to turn into multiple species: i have been testing for literally five hours with the game running consistently at about 300% and have yet to see a phanpy come from my illumise. moral of the story: this code, even with modifications telling it to continue looping after setting the id, doesn't support 1 pok?mon to multiple.
i did however manage to get illumise and this after doing like a weird chain thing (illumise -> volbeat -> phanpy), but it negated volbeat, and no we'd not like that:
![]()
- not tested on bpee or axve but there is no reason it shouldn't work (axve is the same thing while bpee i think interchanges two different registers)
- OH ALSO you have 0x2A bytes of unused space at 46070 for you to use for whatever! knock yourself out with all of that free space
just add a second entry for the other way round to the table:Can make a request?
Is it possible to make the species of the egg have a 50/50 chance of belonging to either of the parents?
For example, ditto and bulbasaur egg would result in a either a ditto or a bulbasaur to hatch, or an egg between a male bulbasaur and female charmander would result in either a bulbasaur egg or a charmander one.
table1:
.hword 0x001D @ nidoranf to
.hword 0x0020 @ nidoranm
.hword 0x0020 @ nidoranm to
.hword 0x001D @ nidoranf
.hword 0x0183 @ illumise to
.hword 0x0182 @ volbeat
.hword 0x0182 @ volbeat to
.hword 0x0183 @ illumise
just add a second entry for the other way round to the table:
Code:table1: .hword 0x001D @ nidoranf to .hword 0x0020 @ nidoranm .hword 0x0020 @ nidoranm to .hword 0x001D @ nidoranf .hword 0x0183 @ illumise to .hword 0x0182 @ volbeat .hword 0x0182 @ volbeat to .hword 0x0183 @ illumise
can someone make a simple routine for Pokémon Fire Red that checks the amount of Friendship/Happiness that a Pokémon in the var 0x8004 has, and saves the actual amount of points in a different value.. say, 0x8005?
.text
.align 2
.thumb
.thumb_func
.global GetHappiness
Main:
push {r0-r2, lr}
ldr r0, .var8004
ldrb r0, [r0] @slot num
mov r1, #0x64
mul r0, r1
ldr r1, .PartyData
add r0, r1, r0
mov r1, #0x20 @happiness
bl GetAttribute
ldr r1, .var8004
strb r0, [r1, #0x2] @store into var8005
pop {r0-r2, pc}
GetAttribute:
ldr r2, =(0x0803FBE8 +1)
bx r2
.align 2
.PartyData: .word 0x02024284
.var8004: .word 0x020370C0
Here you go! (admittedly I have not tested it)
Code:.text .align 2 .thumb .thumb_func .global GetHappiness Main: push {r0-r2, lr} ldr r0, .var8004 ldrb r0, [r0] @slot num mov r1, #0x64 mul r0, r1 ldr r1, .PartyData add r0, r1, r0 mov r1, #0x20 @happiness bl GetAttribute ldr r1, .var8004 strb r0, [r1, #0x2] @store into var8005 pop {r0-r2, pc} GetAttribute: ldr r2, =(0x0803FBE8 +1) bx r2 .align 2 .PartyData: .word 0x02024284 .var8004: .word 0x020370C0
Welp, it didn't work.
I compiled the routine and dropped it in the offset 71A250, wrote this script and once I checked it In-Game, this was the result.
![]()
Note: Just for the record, the savefile is right after defeating my Rival for the very first time, so there's no way for my Pokémon to have 76 points.
Dunno if you'll be able to fix it, but in any case thank you very much.
.text
.align 2
.thumb
.thumb_func
.global SetHappiness
Main:
push {r0-r3, lr}
ldr r2, .var8004
ldrb r0, [r2] @slot num
add r2, #0x2 @var 0x8005 address where you stored new happiness
mov r1, #0x64
mul r0, r1
ldr r1, .PartyData
add r0, r1, r0
mov r1, #0x20 @happiness
bl SetAttribute
pop {r0-r3, pc}
SetAttribute:
ldr r3, =(0x0804037C +1)
bx r3
.align 2
.PartyData: .word 0x02024284
.var8004: .word 0x020370C0
Hmm. It seems like it might be working, as 76 is close enough to base happiness of 70. +5 pts for leveling up during the rival battle and +1 for running 128 steps is feasible.
SPEEDING UP FIRERED
All this does is make the turbo button on VBA work faster.
Emerald solution is found here. That's also the source of my implementation of this.
Code:.thumb .org 0x890 main: push {lr} ldr r2, super_bits ldrh r3, [r2] mov r0, #1 bic r3, r0 strh r3, [r2] loop_label: swi #2 ldrh r3, [r2] tst r3, r0 beq loop_label pop {pc} .align 2 super_bits: .word 0x0300310C
Hello.
Is it possible to make turbo unusable by editing this routine?
Basically to prevent the player from abusing it for grinding and so on.
I combined this into 1 routine and cut the total size down a lot. All credit to DizzyEgg of course, this is nothing compared to creating the mod in the first place.
Code:.text .thumb .thumb_func .align 2 @ [B][COLOR="Red"]0x1C379E: 02 30 00 4A 10 47 XX+1 XX XX 08[/COLOR][/B] @ [B][COLOR="Red"]0x1C3864: 00 4A 10 47 XX+1 XX XX 08[/COLOR][/B] main: @ at this point... r0 contains our return address (- 8). Convenient! push {r5-r7} @ save return address for later. mov r6, r0 add r6, #0x8 @ to determine what function we were called from: @ if it was right stats, r9 is 0. if it was left stats, r9 has something in it. mov r7, r9 @ can't really use hi registers in thumb, mov it down. @ so, to check the function type: cmp r7, #0. eq means right stats. sub sp, sp, #0x20 ldr r0, [r4] @pokemon summary pointer. we're free to use r4 after this. add r0, #0xA3 @poke nature ldrb r1, [r0] ldr r0, nature_stat_table mov r2, #5 mul r2, r1 mov r1, sp mov r5, #0 add r2, r2, r0 @r2 contains nature info cmp r7, #0 beq right_stats_begin @@ LEFT STAT COLORING BEGIN @@@ left_stats_begin: ldr r3, left_stats_string handle_hp: ldrb r0, [r3, r5] strb r0, [r1, r5] add r5, #1 cmp r5, #6 bne handle_hp add r3, #6 add r1, #6 mov r5, #0 handle_atk: ldrb r0, [r2] cmp r0, #1 beq red_font_atk cmp r0, #0xFF bne copy_atk bl blue_font b copy_atk red_font_atk: bl red_font copy_atk: ldrb r0, [r3, r5] strb r0, [r1, r5] add r5, #1 cmp r5, #3 bne copy_atk add r3, #3 add r1, #3 mov r5, #0 handle_def: add r2, #1 ldrb r0, [r2] cmp r0, #1 beq red_font_def cmp r0, #0xFF beq blue_font_def bl default_font b copy_def red_font_def: bl red_font b copy_def blue_font_def: bl blue_font copy_def: ldrb r0, [r3, r5] strb r0, [r1, r5] add r5, #1 cmp r5, #3 bne copy_def b return @@@ LEFT STAT COLORING END @@ @@@ RIGHT STAT COLORING BEGIN @@@ right_stats_begin: add r2, #3 @r2 contains beg of spatk stat ldr r3, right_stats_string handle_spatk: ldrb r0, [r2] cmp r0, #1 beq red_font_spatk cmp r0, #0xFF bne copy_spatk bl blue_font b copy_spatk red_font_spatk: bl red_font copy_spatk: ldrb r0, [r3, r5] strb r0, [r1, r5] add r5, #1 cmp r5, #3 bne copy_spatk add r3, #3 add r1, #3 mov r5, #0 handle_spdef: add r2, #1 ldrb r0, [r2] cmp r0, #1 beq red_font_spdef cmp r0, #0xFF beq blue_font_spdef bl default_font b copy_spdef red_font_spdef: bl red_font b copy_spdef blue_font_spdef: bl blue_font copy_spdef: ldrb r0, [r3, r5] strb r0, [r1, r5] add r5, #1 cmp r5, #3 bne copy_spdef add r3, #3 add r1, #3 mov r5, #0 handle_spd: sub r2, #2 ldrb r0, [r2] cmp r0, #1 beq red_font_spd cmp r0, #0xFF beq blue_font_spd bl default_font b copy_spd red_font_spd: bl red_font b copy_spd blue_font_spd: bl blue_font copy_spd: ldrb r0, [r3, r5] strb r0, [r1, r5] add r5, #1 cmp r5, #3 bne copy_spd b return @@@ RIGHT STAT COLORING END @@@ @@@ FONT FUNCTIONS BEGIN @@@ blue_font: @FC 01 07 mov r4, #7 @color of the lowered stat b font_common red_font: @FC 01 05 mov r4, #5 @color of the raised stat b font_common default_font: @FC 01 01 mov r4, #1 @color of the regular stats @ just fall through to font_common (no need to branch) font_common: mov r0, #0xFC strb r0, [r1] add r1, #1 mov r0, #1 strb r0, [r1] add r1, #1 strb r4, [r1] add r1, #1 bx lr @@@ FONT FUNCTIONS END @@@ return: ldr r0, displayed_string mov r1, sp ldr r2, special_f7_string_fct bl x_r2 cmp r7, #0 beq skip_mov_r0_r9 mov r0, r9 skip_mov_r0_r9: add sp, sp, #0x20 mov r2, r6 pop {r5-r7} x_r2: bx r2 .align 2 nature_stat_table: .word 0x0831E818 left_stats_string: .word 0x0861CE82 right_stats_string: .word 0x0861CE8E displayed_string: .word 0x02021FC4 special_f7_string_fct: .word 0x081AFC29
Is it possible to add or subtract a value from a var? For example, if I have var x4000 set to 0x3, could I call ASM that dynamically subtracts 1 from it (making it 0x2)?
.text
.align 2
.thumb
.thumb_func
main:
push {r0-r1, lr}
ldr r0, =(0x[[I]address of var[/I]])
ldrh r0, [r0]
add r0, #0x1
ldr r1, =(0x[[I]address of var[/I]])
strh r0, [r1]
pop {r0-r1, pc}
.align 2
.text
.align 2
.thumb
.thumb_func
main:
push {r0-r1, lr}
ldr r0, =(0x[[I]address of var[/I]])
ldrh r0, [r0]
sub r0, #0x1
ldr r1, =(0x[[I]address of var[/I]])
strh r0, [r1]
pop {r0-r1, pc}
.align 2
Use the addvar scripting command. Look up in the xse commands how it works.Is it possible to add or subtract a value from a var? For example, if I have var x4000 set to 0x3, could I call ASM that dynamically subtracts 1 from it (making it 0x2)?
This would break for every var not in the 0x8000s. Most scripting variables shuffle around with the saveblocks and you need to call the var_access function to get their locations. There is also var_set, var_load and over/underflow to think about. Overall, doing this in scripting is recommended as the callasm setup + execution ends up being slower.Addition:
Spoiler:
Code:.text .align 2 .thumb .thumb_func main: push {r0-r1, lr} ldr r0, =(0x[[I]address of var[/I]]) ldrh r0, [r0] add r0, #0x1 ldr r1, =(0x[[I]address of var[/I]]) strh r0, [r1] pop {r0-r1, pc} .align 2
Subtraction
Spoiler:
Code:.text .align 2 .thumb .thumb_func main: push {r0-r1, lr} ldr r0, =(0x[[I]address of var[/I]]) ldrh r0, [r0] sub r0, #0x1 ldr r1, =(0x[[I]address of var[/I]]) strh r0, [r1] pop {r0-r1, pc} .align 2
.thumb
.align 2
main:
ldr r0, =addr
ldrh r1, [r0]
sub r1, r1, #0x1
strh r1, [r0]
bx lr
.align 2
addr:
.word 0xsomething
This would break for every var not in the 0x8000s. Most scripting variables shuffle around with the saveblocks and you need to call the var_access function to get their locations. There is also var_set, var_load and over/underflow to think about. Overall, doing this in scripting is recommended as the callasm setup + execution ends up being slower.
Btw, you don't need to push scratch registers unless you were hooking (do so on a case by case basis). Nor the link register here because you're not calling a function.
Something like this. But as mentioned before it's unadvisable to do it this way.Code:.thumb .align 2 main: ldr r0, =addr ldrh r1, [r0] sub r1, r1, #0x1 strh r1, [r0] bx lr .align 2 addr: .word 0xsomething
Go into XSE and click on the "Help" tab at the top, then "Command Help."On this note, I want to use something similar to this in the future, but I need the value to stay within a certain range (0x0 - 0x5, for example). Is there a command that checks var values so that the script knows not to add or subtract once the value reaches either end of that range? Or would this require ASM?
Is there a document with all the XSE commands? I can't seem to find one.
Hi. Does anyone over here have an ASM Routine that allows you to hide and show the Trainer Card's access from the Start Menu at will?
![]()
Thanks in advance for reading.
mov r0, #0xX
ldr r1, =(0x806ED94 +1)
bl linker