The PokéCommunity Forums  

Go Back   The PokéCommunity Forums > ROM Hacking > Research & Development
Sign Up Rules/FAQ Live Battle Blogs Mark Forums Read

Notices

Research & Development Got a well-founded knack with ROM hacking? Love reverse-engineering the Pokémon games? Or perhaps you love your assembly language. This is the spot for polling and gathering your ideas, and then implementing them! Share your hypothesis, get ideas from others, and collaborate to create!
Research & Development programs in this forum are subject to moderator approval before they are displayed.


Reply
Click here to go to the first staff post in this thread.  
Thread Tools
  #1    
Old December 2nd, 2010, 02:58 PM
Jambo51's Avatar
Jambo51
Glory To Arstotzka
 
Join Date: Jun 2009
Gender: Male
Nature: Quiet
I would like to note that the general framework for these hacks were based on an idea that a Brazilian hacker had, his name escapes me right now, but some credit must be given to him/her!

These routines DO NOT support the new RTC and Day and Night Feature developed by Prime unless you use the same RAM offsets. Even if you do, I would ideally like to redevelop these routines to use the new system Prime has developed as it would be more efficient.

FireRed (Extensively Tested)

Spoiler:
First up is the routine which will make the wild Pokémon's level load correctly, rather than loading random garbage data after the repointing process is complete.

Wild Pokémon Day/Night Level Loading Routine

Code:
.text /*Basic THUMB Headers, should be included in all ASM Routines*/
.align 2
.thumb
.thumb_func
.global daynightlevelswitch
 
main:
sub r0, r0, r4 /*Subtracts the value of R4 from R0, giving us a clean pointer to use*/
ldr r2, hour /*Loads the ram offset 0x03005542 to R2*/
ldrb r2, [r2, #0x0] /*Loads the byte contained in the offset*/
cmp r2, #0x15 /*Compares R2 (The Hour) with 0x15 - 9PM - Change it if you want*/
bge night /*If greater than or equal to, go to "night"*/
cmp r2, #0x12
bge evening
cmp r2, #0x9 /*Compares R2 (The Hour) with 0x9 - 9AM - Change it if you want*/
bge day /*If greater than or equal to, go to "day"*/
cmp r2, #0x6
bge morning
night: add r2, r0, #0x4
b check
evening: add r2, r0, #0x0
add r2, #0xC
b check
morning: add r2, r0, #0x0
add r2, #0x8
b check
day: add r2, r0, #0x0
check: ldrb r1, [r2, #0x3] /*Loads the byte stored at the pointer's location plus 3 for checking*/
cmp r1, #0xFF
beq nodata
cmp r1, #0x8 /*Compares R2 with 0x08, the tell tale sign of a rom pointer, which is what should be stored here if you are using this hack*/
bne nextnormal /*If not equal, load as usual - Thanks Shiny Quagsire!*/
ldr r0, [r2, #0x0] /*Loads the word stored at the location pointed to in R2, the pointer to the wild data*/
nextnormal: add r0, r4, r0 /*Adds the number of bytes from the start of the table that the wild Pokémon slot the game has selected is*/
add r4, r0, #0x0 /*Adds the contents of R0 into R4*/
ldrb r0, [r4, #0x1] /*Loads the upper level limit for the Pokémon if they're stored systematically*/
ldrb r1, [r4, #0x0] /*Loads the lower level limit*/
cmp r0, r1 /*Compares the levels*/
bcc here /*If R0 < R1 goto "here"*/
ldrb r5, [r4, #0x0] /*Loads the lower level limit into R5*/
b here2
here: ldrb r5, [r4, #0x1] /*Reverses the lower and upper level limits to*/
ldrb r0, [r4, #0x0] /*avoid bugs if R0 was smaller than R1 above*/
here2: sub r4, r0, r5 /*Subtracts upper and lower level limits and stores results into R4*/
add r4, #0x1 /*Not entirely sure why, but it's from the original code, and is important for level loading, as leaving it out leads to odd bugs*/
lsl r4, r4, #0x18 /*This line and the next line make sure that you are only passing a byte to the next part of the routine, so it doesn't bug out*/
lsr r4, r4, #0x18
ldr r2, return /*Loads the return offset to R2*/
bx r2 /*Executes a Branch and Exchange goto to the offset contained within the register, ensuring it remains in THUMB mode by being 1 greater than the wanted location*/
var_decrypt: ldr r1, vardecrypt
bx r1
nodata: sub r2, r2, r0
cmp r2, #0xC
beq night
b day
.align
hour: .word 0x03005542
return: .word 0x08082915
vardecrypt: .word 0x0806E455
var_4fff: .word 0x00004FFF /*Replace this with whatever variable you would like to use*/
So, insert the code below at 0x080828FA where the XXXXXX is replaced with the reverse hex pointer plus one of the newly inserted code.

Code:
01 4A 10 47 00 00 XX XX XX 08
This sorts the level loading part of the routine, but we haven't actually modified the Pokémon loading part of it yet. So, now we have to insert another routine to actually make that work.

Code:
.text
.align 2
.thumb
.thumb_func
.global daynightwildswitch
main:
ldr r0, [r7, #0x4]
push {r0}
ldr r0, var_4fff
bl var_decrypt
ldrh r0, [r0, #0x0]
cmp r0, #0x1
bge swarm
pop {r0}
push {r2}
daynight: ldr r2, hour
ldrb r2, [r2, #0x0]
cmp r2, #0x15 /*9PM - Change it if you want*/
bge night
cmp r2, #0x12
bge evening
cmp r2, #0x9 /*9AM - Change it if you want*/
bge day
cmp r2, #0x6
bge morning
night: add r2, r0, #0x4
b check
evening: add r2, r0, #0x0
add r2, #0xC
b check
morning: add r2, r0, #0x0
add r2, #0x8
b check
day: add r2, r0, #0x0
check: ldrb r1, [r2, #0x3]
cmp r1, #0xFF
beq nodata
cmp r1, #0x8
bne nextnormal
ldr r0, [r2, #0x0]
nextnormal: add r0, r4, r0
ldrh r0, [r0, #0x2]
back: ldr r1, lastpokemon
strh r0, [r1, #0x0]
add r1, r5, #0x0
pop {r2}
ldr r3, Back
bx r3
swarm: pop {r0}
ldr r0, var_4ffe
bl var_decrypt
sub r2, r0, #0x2
ldr r1, currentmap
ldrb r1, [r1, #0x0]
ldrh r2, [r2, #0x0]
cmp r1, r2
bne daynightone
ldrh r0, [r0, #0x0]
b back
var_decrypt: ldr r1, vardecrypt
bx r1
daynightone: ldr r0, [r7, #0x4]
push {r0}
b daynight
nodata: sub r2, r2, r0
cmp r2, #0xC
beq night
b day
.align
Back: .word 0x08082b51
lastpokemon: .word 0x0300555C
hour: .word 0x03005542
vardecrypt: .word 0x0806E455
var_4fff: .word 0x00004FFF /*Replace this with whatever variable you would like to use*/
var_4ffe: .word 0x00004FFE /*Replace this with whatever variable you would like to use*/
currentmap: .word 0x03005558
This routine performs a similar function to the level modification part from above. Changing the pointer to the wild data into a pointer to a table of pointers to wild data.

Insert the assembled routine and then modify the data at 0x08082B48 so that it repoints to the new routine's location plus 1:
Code:
00490847XXXXXX08
For the swarming code, you need to set the variable 0x4FFF to 0x2 or greater, and then set the variable 0x4FFE with the Pokémon number you want to be swarming.
eg. I want Taillow to swarm on Route 4:

Code:
setvar 0x4FFF 0x2
setvar 0x4FFE PKMN_TAILLOW
setvar 0x4FFD 0x68
The way the code works is that it always overwrites the standard Pokémon loading routine for the given map until you change one of the above parameters. How you do this is entirely up to you.

These 2 routines together allow you to have different pokémon at day and night, but read in more or less exactly the same way as before, meaning you can rely on it to produce common Pokémon more often than rare ones in the same way as any modified data in A-Map.

There is another, entirely optional, hack related to this, which is having different wild Pokémon encounter rates between day and night. This hack also reads the ability byte of your first Pokémon, looking for specific conditions to be met. If your lead Pokémon has certain abilities (the list isn't yet complete, and some of the effects still need some research) then the wild encounter rate can be halved or doubled. For all of the abilities listed below, they only apply if the Pokémon with the ability is in slot 1. Otherwise, it'll work as per usual.

Current list of supported abilities:
Spoiler:
Arena Trap (Doubles)
Illuminate (Doubles)
Sand Veil (Halves in Sandstorm)
Stench (Halves)
Swarm (Doubles)
White Smoke (Halves)


Anyhoo, the game reads the encounter rate like so:
This is for Route 1, but all encounter rates are stored in the same style:
Code:
 DD 00 00 00
But it only reads the first byte of this. What a waste of space! So, I figured we could use this space to store upto an extra 3 encounter rates, making a total of 4 for every map! (Remember, the maximum encounter rate is 255 or 0xFF, meaning that even with all of them set to maximum, it will fit in here snugly. :D

This code makes the bytes following the normal encounter rate become encounter rates too, separate from the normal one, and only read when the hour byte is above or below a certain value.

Code:
 
.text
.align 2
.thumb
.thumb_func
.global daynightencounterratehack
main:
 push {r0}
 ldr r0, hour
 ldrb r0, [r0, #0x0]
 cmp r0, #0x15          /*9PM - Change it if you want*/
 bge night
 cmp r0, #0x12
 bge evening
 cmp r0, #0x9           /*9AM - Change it if you want*/
 bge day
 cmp r0, #0x6
 bge morning
night: pop {r0}
 ldrb r1, [r0, #0x3]
 b check
evening: pop {r0}
 ldrb r1, [r0, #0x2]
 b check
morning: pop {r0}
 ldrb r1, [r0, #0x1]
check: cmp r1, #0x0
 beq day2
 b new
day: pop {r0}
day2: ldrb r1, [r0, #0x0]
new: push {r0-r7}
 ldr r0, partystart    /*Everything from here until the next comment is HackMew's code*/
 mov r5, #0x6
 add r0, r4, #0x0
 mov r1, #0x8
 ldr r3, readdata
 bl bxr3
 add r6, r0, #0x0
 add r0, r4, #0x0
 mov r1, #0x2E
 ldr r3, readdata
 bl bxr3 
 add r1, r0, #0x0
 add r0, r6, #0x0
 ldr r3, getability
 bl bxr3             /*End of HackMew's code*/
 cmp r0, #0x1
 beq divide
 cmp r0, #0x8
 beq sandveil
 cmp r0, #0x38
 beq double
 cmp r0, #0x44
 beq double
 cmp r0, #0x47
 beq double
 cmp r0, #0x49
 beq divide
 pop {r0-r7}
return: cmp r1, #0x4F
 bhi one
 cmp r1, #0x9
 bls two
 add r0, r1, #0x0
 ldr r1, place
 bx r1
divide: pop {r0-r7}
 push {r0}
 push {r1}
 push {r2}
 add r0, r1, #0x0
 mov r1, #0x2
 mov r2, #0x0
 swi #0x6
 pop {r2}
 pop {r1}
 add r1, r0, #0x0
 pop {r0}
 b return
double: pop {r0-r7}
 push {r2}
 mov r2, #0x2
 mul r1, r2
 pop {r2}
 b return
bxr3: bx r3                 /*This one line of code is also HackMew's, but it somehow ended up down here*/
two: mov r0, #0x8
 b Back
one: mov r0, #0x0
Back: ldr r4, placetwo
 bx r4
sandveil: ldr r0, weatherlocation
 ldrb r0, [r0, #0x0]
 cmp r0, #0x8
 bne no
 b divide
no: pop {r0-r7}
 b return
.align
placetwo: .word 0x080832CF
weatherlocation: .word 0x03005564
hour:  .word 0x03005542
partystart: .word 0x02024284
readdata: .word 0x0803FBE9
getability: .word 0x08040D39
place:  .word 0x080832BB
Insert the following hex string at 0x08083278:
Code:
00 49 08 47 XX XX XX 08
Where one again, the XXXXXX is the reverse hex pointer to the new routine's location.

So, it marks them out like so for the 4 time set up I have created.
Code:
 DD MM EE NN
I left the day encounter rate at the start in order to have the routine be as compatible with the original rom's data as possible.

Anyway, the code reads this byte, then runs some simple checks (credit for that particular part of the code goes to HackMew as it is taken almost wholesale from his Flame Body hack, which I suggest you all try out!), and based on the results of these checks, either halves, doubles, or continues with the given encounter rate. It then returns to the original routine for writing to memory.

OK, now a quick lesson on how to get the tables set up right.
Again, for a benchmark I'll use Route 1's data, but it can be expanded to every single wild data table in the game.

This is the Route 1 grass wild data as standard in the rom:
Code:
15 00 00 00 60 8E 3C 08
In order for the game to read this properly with the new routines, you need to repoint the pointer to a free space location in the rom. A good location for this would be 0x08B00000 as it's empty and has more than enough free space to hold the new data.

So, at 0xB00000, copy and paste the pointer to the original wild data. This will serve as our daytime data. Then after it, place another pointer to an empty area of the rom. Anywhere will do, as long as you have enough free space to put the correct number of wild Pokémon in. That will make it work, although you should obviously fill the new table with Pokémon data. This new table serves as our night time data. So, now whenever we encounter a wild Pokémon at night, it'll be loaded from the night time data, rather than the day time data.

Here is one final, separate routine which writes the map you are currently in and the weather on said map to a ram offset so that the routines above can use them to determine whether certain conditional modifications should be activated. (This is because I couldn't find either written to the ram although they are obviously written to the ram at some point by the actual routine).

Code:
.text
.align 2
.thumb
.thumb_func
.global headerreadinghack
main:
 stmia r1!, {r2, r3, r6}
 ldr r0, [r0, #0x0]
 push {r5}
 push {r6}
 lsl r6, r6, #0x8
 lsr r6, r6, #0x18
 ldr r5, currentmaploc
 strb r6, [r5, #0xC]
 pop {r6}
 push {r6}
 lsl r6, r6, #0x18
 lsr r6, r6, #0x18
 strb r6, [r5, #0x0]
 pop {r6}
 pop {r5}
 mov r7, #0x4
 str r0, [r1, #0x0]
 ldr r1, [r5, #0x0]
 ldrh r0, [r4, #0x12]
 strh r0, [r1, #0x32]
 ldr r0, returntooriginal
 bx r0
.align
currentmaploc: .word 0x03005558
returntooriginal:  .word 0x080552A7
Insert the following code at 0x0805529A:
Code:
01 4F 38 47 00 00 XX XX XX 08


Emerald (Basic Testing)

Spoiler:

Level Loading Routine:
Code:
.text
.align 2
.thumb
.thumb_func
.global daynightlevelswitch
 
main:
 ldr r2, hour
 ldrb r2, [r2, #0x0]
 cmp r2, #0x21
 bge night
 cmp r2, #0x18
 bge even
 cmp r2, #0x9
 bge day
 cmp r2, #0x6
 bge morn
night: add r2, r0, #0x4
 b check
even: add r2, r0, #0x0
 add r2, #0xC
 b check
morn: add r2, r0, #0x0
 add r2, #0x8
 b check
day: add r2, r0, #0x0
check: ldrb r1, [r2, #0x3]
 cmp r1, #0xFF
 beq nodata
 cmp r1, #0x8
 bne nextnormal
 ldr r0, [r2, #0x0]
 nextnormal: add r4, r0, r4
 ldrb r0, [r4, #0x1]
 ldrb r1, [r4, #0x0]
 cmp r0, r1
 bcc here
 ldrb r7, [r4, #0x0]
 add r6, r0, #0x0
 b here2
here: ldrb r7, [r4, #0x1]
 ldrb r6, [r4, #0x0]
here2: sub r4, r6, r7
 add r4, #0x1
 lsl r4, r4, #0x18
 lsr r4, r4, #0x18
 ldr r2, return
 bx r2
nodata: sub r2, r2, r0
 cmp r2, #0xC
 beq night
 b day
night2: add r2, r0, #0x4
 b check
timeupdate: ldr r1, time
 bx r1
.align
hour: .word 0x03000DC4
return: .word 0x080B4C93
time: .word 0x0802F589
Insert at 0x080B4C76:
Code:
01 4A 10 47 00 00 XX XX XX XX
Pokémon Loading Routine
Code:
.text
.align 2
.thumb
.thumb_func
.global daynightwildswitch
main:
 pop {r0}
 ldrb r0, [r0, #0x0]
 push {r3,r4}
 lsl r4, r0, #0x2
 ldr r0, [r5, #0x4]
daynight: ldr r1, hour
 ldrb r1, [r1, #0x0]
 cmp r1, #0x21
 bge night
 cmp r1, #0x18
 bge evening
 cmp r1, #0x9
 bge day
 cmp r1, #0x6
 bge morning
night: add r1, r0, #0x4
 b check
evening: add r1, r0, #0x0
 add r2, #0xC
 b check
day: add r1, r0, #0x0
 b check
morning: add r1, r0, #0x0
 add r2, #0x8
check: ldrb r3, [r1, #0x3]
 cmp r3, #0xFF
 beq nodata
 cmp r3, #0x8
 bne nextnormal
 ldr r0, [r1, #0x0]
 nextnormal: add r0, r0, r4
 ldrh r0, [r0, #0x2]
 pop {r3,r4}
 add r1, r4, #0x0
 ldr r6, Back
 bx r6
nodata: sub r2, r2, r0
 cmp r2, #0xC
 beq night
 b day
.align
Back:  .word 0x080B5015
hour:  .word 0x03000DC4
Overwrite the code at 0x080B500A onwards with the following:
Code:
01 B4 00 48 00 47 XX XX XX XX
In order for this to work properly, you need to update the RTC's time appropriately. But how to do this when Emerald only calls the time update routine when warping or connecting? Use the code shown in this post: http://www.pokecommunity.com/showpos...3&postcount=41. If you use that code and patch the time update routine onto the main loop of the game, the time updates once every frame! This means it works more like interdpth's RTC code for FireRed. A much better solution IMHO.


Ruby (Not Started Yet)

Spoiler:

__________________
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!

Last edited by Jambo51; April 2nd, 2011 at 11:15 PM. Reason: New Routines and Info
Reply With Quote
  #2    
Old December 3rd, 2010, 10:21 PM
Shiny Quagsire's Avatar
Shiny Quagsire
Unexpectedly Gone until Aug 13
 
Join Date: May 2009
Location: Hoenn Safari Zone
Age: 16
Gender: Male
Nature: Jolly
Nice job! I haven't read it through completely, but I will after I get some rest. :p

One thing you could do is explain what each original routine does, what arguments are loaded through the registers, and how the routine modifies this.
__________________



Reply With Quote
  #3    
Old December 4th, 2010, 04:11 PM
aSeRo141414's Avatar
aSeRo141414
zZJoennZz inside
 
Join Date: Jun 2009
Location: In your head
Age: 18
Gender: Male
Nature: Jolly
Send a message via Yahoo to aSeRo141414 Send a message via Skype™ to aSeRo141414
nice! this looks nice, keep it up and I see some of it is from HackMew
__________________
Regards,
aSeRo141414
Reply With Quote
  #4    
Old December 6th, 2010, 11:54 AM
Elite Trainer Red's Avatar
Elite Trainer Red
Beginning Trainer
 
Join Date: Apr 2010
Location: Mt.Silver
Gender: Male
Nature: Adamant
:D I've been working on the tool so far got the GUI down got most of the code but running into a few bugs will post it here and the tool section when i've finished doing it preview attatched as an attatchment
Attached Images
File Type: png D&N Preview.png‎ (161.5 KB, 255 views) (Save to Dropbox)
File Type: png D&N Preview2.png‎ (151.3 KB, 161 views) (Save to Dropbox)
File Type: png D&N Preview3.png‎ (211.7 KB, 182 views) (Save to Dropbox)
__________________
This signature has been disabled.
Reason: Spoilers in signature
Please review and fix the issues by reading the signature rules.

You must edit it to meet the limits set by the rules before you may remove the [sig-reason] code from your signature. Removing this tag will re-enable it.

Do not remove the tag until you fix the issues in your signature. You may be infracted for removing this tag if you do not fix the specified issues. Do not use this tag for decoration purposes.
Reply With Quote
  #5    
Old December 6th, 2010, 02:41 PM
Shiny Quagsire's Avatar
Shiny Quagsire
Unexpectedly Gone until Aug 13
 
Join Date: May 2009
Location: Hoenn Safari Zone
Age: 16
Gender: Male
Nature: Jolly
I could help with the tool. But some advice from me is:

1. Make the window smaller, or items bigger. There is too much empty space
2. More options, if possible and simpler user interface. Instead of making them insert hex, make the program convert it to hex.
3.Why make a program? If you do that, then D/N Pokemon will be less common.
__________________



Reply With Quote
  #6    
Old December 6th, 2010, 05:16 PM
itari's Avatar
itari
Community Supporter
 
Join Date: Mar 2010
Location: 渦潮隠れの里
Age: 17
Gender: Female
Nature: Relaxed
Quote:
Originally Posted by shiny quagsire View Post
3.Why make a program? If you do that, then D/N Pokemon will be less common.
I believe you mean more common, not less common.

Plus, this routine is very useful. I have been looking into information on this for quite some time now, to no avail. Thanks!
__________________
Reply With Quote
  #7    
Old December 6th, 2010, 07:13 PM
Shiny Quagsire's Avatar
Shiny Quagsire
Unexpectedly Gone until Aug 13
 
Join Date: May 2009
Location: Hoenn Safari Zone
Age: 16
Gender: Male
Nature: Jolly
Yeah, I meant that. Anyways, I improved the code so that it is backward compatible with original game data. At the beginning, add this before pushing r0:
Code:
mov r1, r0
 ldrb r1, [r1, #0x3]
 cmp r1, #0x8
 bne normal

//Add the following lines after back:
normal:
add r0, r4, r0
ldrh r0, [r0, #0x2]
ldr r3, Back
 bx r3
What this does is it checks for an 08 3 bytes after r0, which would be where your day pointer is. If not, it uses the pokemon table as normal data, like the game normally would. The byte that is actually checked is the flipped byte of the pokemon's species. Luckily, no pokemon goes over the number 2,048, so the check works. Another check you could add is to, instead of loading another pokemon data table, check the byte loaded into r0 after this instruction:
Code:
ldrh r0, [r0, #0x2]
This loads the pokemon's data, and once loaded, it can be checked. So let's say we wanted a pidgey to turn into a hoothoot. You could add this to next:
Code:
next: 
ldr r0, [r0, #0x0]
 add r0, r4, r0
 ldrh r0, [r0, #0x2]
ldr r3, hour
 ldrb r3, [r0, #0x0]
 cmp r3, #0x15          /*9PM - Change it if you want*/
 bge hoothoot
b back
hoothoot: cmp r0, #0x10 /*Is it pidgey?*/
bne back /*If not, return to normal*?
mov r0, #0xA3 /*Change pokemon to hoothoot*/
b back
Also, It's pretty tedious to hex edit pokemon, so I'm going to create a tool sometime. It's not too hard in fact, since it's such a simple format:
Code:
[MinLV][MaxLV][Species][Species]
edit: I've also added backward support for the levels. Simply add this before pushing r0 at the beginning:
Code:
 ldrb r2, [r2, #0x3]
 cmp r2, #0x8
 bne nextnormal
Add nextnormal to the second line in next:

Code:
next: ldr r0, [r0, #0x0]        /*Loads the word stored at the location pointed to in R0, the pointer to the wild data*/
 nextnormal:add r0, r4, r0                    /*Adds the number of bytes from the start of the table that the wild Pokémon slot the game has selected is*/
 add r4, r0, #0x0                /*Adds the contents of R0 into R4*/
 ldrb r0, [r4, #0x1]             /*Loads the upper level limit for the Pokémon if they're stored systematically*/

...
This essentially does the same thing as before. It checks if the pointer exists, and if not, it treats the table data as the normal pokemon data.
__________________




Last edited by Shiny Quagsire; December 6th, 2010 at 08:02 PM.
Reply With Quote
  #8    
Old December 7th, 2010, 08:47 AM
Jambo51's Avatar
Jambo51
Glory To Arstotzka
 
Join Date: Jun 2009
Gender: Male
Nature: Quiet
Quote:
Originally Posted by shiny quagsire View Post
Yeah, I meant that. Anyways, I improved the code so that it is backward compatible with original game data. At the beginning, add this before pushing r0:
Code:
mov r1, r0
 ldrb r1, [r1, #0x3]
 cmp r1, #0x8
 bne normal

//Add the following lines after back:
normal:
add r0, r4, r0
ldrh r0, [r0, #0x2]
ldr r3, Back
 bx r3
What this does is it checks for an 08 3 bytes after r0, which would be where your day pointer is. If not, it uses the pokemon table as normal data, like the game normally would. The byte that is actually checked is the flipped byte of the pokemon's species. Luckily, no pokemon goes over the number 2,048, so the check works. Another check you could add is to, instead of loading another pokemon data table, check the byte loaded into r0 after this instruction:
Code:
ldrh r0, [r0, #0x2]
This loads the pokemon's data, and once loaded, it can be checked. So let's say we wanted a pidgey to turn into a hoothoot. You could add this to next:
Code:
next: 
ldr r0, [r0, #0x0]
 add r0, r4, r0
 ldrh r0, [r0, #0x2]
ldr r3, hour
 ldrb r3, [r0, #0x0]
 cmp r3, #0x15          /*9PM - Change it if you want*/
 bge hoothoot
b back
hoothoot: cmp r0, #0x10 /*Is it pidgey?*/
bne back /*If not, return to normal*?
mov r0, #0xA3 /*Change pokemon to hoothoot*/
b back
Also, It's pretty tedious to hex edit pokemon, so I'm going to create a tool sometime. It's not too hard in fact, since it's such a simple format:
Code:
[MinLV][MaxLV][Species][Species]
edit: I've also added backward support for the levels. Simply add this before pushing r0 at the beginning:
Code:
 ldrb r2, [r2, #0x3]
 cmp r2, #0x8
 bne nextnormal
Add nextnormal to the second line in next:

Code:
next: ldr r0, [r0, #0x0]        /*Loads the word stored at the location pointed to in R0, the pointer to the wild data*/
 nextnormal:add r0, r4, r0                    /*Adds the number of bytes from the start of the table that the wild Pokémon slot the game has selected is*/
 add r4, r0, #0x0                /*Adds the contents of R0 into R4*/
 ldrb r0, [r4, #0x1]             /*Loads the upper level limit for the Pokémon if they're stored systematically*/

...
This essentially does the same thing as before. It checks if the pointer exists, and if not, it treats the table data as the normal pokemon data.
Thanks man! I'll add these improvements in when I get home from work. I can't believe i didn't put these checks in myself XD. I don't pretend to br a great ASM hacker, i'm still learning most of it.
__________________
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!
Reply With Quote
  #9    
Old December 7th, 2010, 10:55 AM
Elite Trainer Red's Avatar
Elite Trainer Red
Beginning Trainer
 
Join Date: Apr 2010
Location: Mt.Silver
Gender: Male
Nature: Adamant
I have taken the critisism (Spelling Fail) and am now working with it
will update soon
__________________
This signature has been disabled.
Reason: Spoilers in signature
Please review and fix the issues by reading the signature rules.

You must edit it to meet the limits set by the rules before you may remove the [sig-reason] code from your signature. Removing this tag will re-enable it.

Do not remove the tag until you fix the issues in your signature. You may be infracted for removing this tag if you do not fix the specified issues. Do not use this tag for decoration purposes.
Reply With Quote
  #10    
Old December 7th, 2010, 04:14 PM
diegoisawesome's Avatar
diegoisawesome
Not the Script Help Thread
Community Supporter
 
Join Date: Dec 2007
Location: Goldenrod City, Johto
Age: 17
Gender: Male
Nature: Quirky
I would totally love this addition if it could support Emerald and have Morning added, too.
It would probably be simple to do, but I'm too lazy to do it myself ATM.
__________________


My other resources:
My Website
diegoisawesome's MEGA-HUGE XSE Scripting Tutorial
diegoisawesome's Miscellaneous Finds
The Ruins of Alph Puzzles
Reply With Quote
  #11    
Old December 7th, 2010, 04:18 PM
Shiny Quagsire's Avatar
Shiny Quagsire
Unexpectedly Gone until Aug 13
 
Join Date: May 2009
Location: Hoenn Safari Zone
Age: 16
Gender: Male
Nature: Jolly
Quote:
Originally Posted by diegoisawesome View Post
I would totally love this addition if it could support Emerald and have Morning added, too.
It would probably be simple to do, but I'm too lazy to do it myself ATM.
Since emerald is based off of fire red, it was actually only a search for a few bytes. The routine is at 080b4c76 for the level routine. However, it may be loaded differently, so I'll have to check if it's safe.

edit: Actually, the code from all games is exactly the same, except for when the data is written. Here are the level offsets:

Code:
Emerald: 080b4c76
Ruby: 08084d32
Unfortunatly, the wild data loading is very different. I'll have to dive a bit deeper on that one.
__________________



Reply With Quote
  #12    
Old December 7th, 2010, 04:22 PM
colcolstyles's Avatar
colcolstyles
Yours truly
 
Join Date: May 2008
Location: The Bay Area
Gender: Male
Nature: Lonely
Quote:
Originally Posted by shiny quagsire View Post
Since emerald is based off of fire red, it was actually only a search for a few bytes.
Mind backing that up with some evidence?
__________________

Brother of Vrai
Reply With Quote
  #13    
Old December 7th, 2010, 04:44 PM
Shiny Quagsire's Avatar
Shiny Quagsire
Unexpectedly Gone until Aug 13
 
Join Date: May 2009
Location: Hoenn Safari Zone
Age: 16
Gender: Male
Nature: Jolly
Quote:
Originally Posted by colcolstyles View Post
Mind backing that up with some evidence?
Sure. I'm not a liar, and I always back up my evidence.

Level loading from Fire Red:
Code:
080828FA 00C                 MOVS    R4, R0
080828FC 00C                 LDRB    R0, [R4,#1]
080828FE 00C                 LDRB    R1, [R4]
08082900 00C                 CMP     R0, R1
08082902 00C                 BCC     loc_08082908
Level Loading From Emerald:

Code:
ROM:080B4C76                 MOVS    R4, R0
ROM:080B4C78                 LDRB    R0, [R4,#1]
ROM:080B4C7A                 LDRB    R1, [R4]
ROM:080B4C7C                 CMP     R0, R1
ROM:080B4C7E                 BCC     loc_80B4C86
And finally, Ruby:

Code:
ROM:08084D32                 MOVS    R4, R0
ROM:08084D34                 LDRB    R0, [R4,#1]
ROM:08084D36                 LDRB    R1, [R4]
ROM:08084D38                 CMP     R0, R1
ROM:08084D3A                 BCC     loc_8084D40
As you can see, it's essencially the same thing. If you were to look in IDA or VBA's decompiler, you'd see the same thing, but with a few different registers here and there.
__________________



Reply With Quote
  #14    
Old December 7th, 2010, 05:56 PM
colcolstyles's Avatar
colcolstyles
Yours truly
 
Join Date: May 2008
Location: The Bay Area
Gender: Male
Nature: Lonely
I meant provide evidence that Emerald is based off of Fire Red.
__________________

Brother of Vrai
Reply With Quote
  #15    
Old December 8th, 2010, 05:17 AM
Jambo51's Avatar
Jambo51
Glory To Arstotzka
 
Join Date: Jun 2009
Gender: Male
Nature: Quiet
Quote:
Originally Posted by diegoisawesome View Post
I would totally love this addition if it could support Emerald and have Morning added, too.
It would probably be simple to do, but I'm too lazy to do it myself ATM.
Adding morning would be very easy. In fact I originally developed it to support 4 times of day, morning, day, evening and night, but decided to cut it down for use as it takes a lot of work to manually hex edit the Pokémon in. As for Emerald support, I guess I could have a look and see if I can apply the principle, if not necessarily the exact same routine, to the rom. Although in order for me to do that, someone would need to supply me with the ram location of the RTC in an Emerald rom, as, unlike FR, it already has an RTC built in so I can't just look at the inserted routine of the D/N routine.
__________________
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!

Last edited by Jambo51; December 8th, 2010 at 05:27 AM.
Reply With Quote
  #16    
Old December 8th, 2010, 06:57 AM
I-shadez's Avatar
I-shadez
Beginning Trainer
 
Join Date: Mar 2010
Gender: Male
another tutorial thats helped alot, thanks OP
Reply With Quote
  #17    
Old December 8th, 2010, 03:35 PM
Shiny Quagsire's Avatar
Shiny Quagsire
Unexpectedly Gone until Aug 13
 
Join Date: May 2009
Location: Hoenn Safari Zone
Age: 16
Gender: Male
Nature: Jolly
Quote:
Originally Posted by Jambo51 View Post
Adding morning would be very easy. In fact I originally developed it to support 4 times of day, morning, day, evening and night, but decided to cut it down for use as it takes a lot of work to manually hex edit the Pokémon in. As for Emerald support, I guess I could have a look and see if I can apply the principle, if not necessarily the exact same routine, to the rom. Although in order for me to do that, someone would need to supply me with the ram location of the RTC in an Emerald rom, as, unlike FR, it already has an RTC built in so I can't just look at the inserted routine of the D/N routine.
Yeah, I'll be doing morning, and I'm developing a wild pokemon data editor for this D/N System. I'll post some pics later. As for the RTC, I'm sure ColColStyles might know it, since he does a lot of emerald hacking.
__________________



Reply With Quote
  #18    
Old December 8th, 2010, 04:43 PM
Jambo51's Avatar
Jambo51
Glory To Arstotzka
 
Join Date: Jun 2009
Gender: Male
Nature: Quiet
I look forward to seeing this tool, for my own use as well as for other XD :D.

I, in the mean time, will endeavour to port the code over to as many versions of the roms as I can. I'll start by extending support to Ruby and Emerald's english versions, and then go from there. Hopefully, the routines will be in exactly the same place for other language roms, thus requiring no modification. The routines should, in theory, be identical, if not necessarily in exactly the same place.

And I asked colcolstyles for any info he may have on the RTC in Emerald, hopefully he'll be able to provide me with at least a starting point to go from :D
__________________
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!
Reply With Quote
  #19    
Old December 8th, 2010, 06:06 PM
Shiny Quagsire's Avatar
Shiny Quagsire
Unexpectedly Gone until Aug 13
 
Join Date: May 2009
Location: Hoenn Safari Zone
Age: 16
Gender: Male
Nature: Jolly
Quote:
Originally Posted by Jambo51 View Post
I look forward to seeing this tool, for my own use as well as for other XD :D.

I, in the mean time, will endeavour to port the code over to as many versions of the roms as I can. I'll start by extending support to Ruby and Emerald's english versions, and then go from there. Hopefully, the routines will be in exactly the same place for other language roms, thus requiring no modification. The routines should, in theory, be identical, if not necessarily in exactly the same place.

And I asked colcolstyles for any info he may have on the RTC in Emerald, hopefully he'll be able to provide me with at least a starting point to go from :D
The code isn't in the exact same place.

Quote:
Originally Posted by shiny quagsire View Post
Sure. I'm not a liar, and I always back up my evidence.

Level loading from Fire Red:
Code:
080828FA 00C                 MOVS    R4, R0
080828FC 00C                 LDRB    R0, [R4,#1]
080828FE 00C                 LDRB    R1, [R4]
08082900 00C                 CMP     R0, R1
08082902 00C                 BCC     loc_08082908
Level Loading From Emerald:

Code:
ROM:080B4C76                 MOVS    R4, R0
ROM:080B4C78                 LDRB    R0, [R4,#1]
ROM:080B4C7A                 LDRB    R1, [R4]
ROM:080B4C7C                 CMP     R0, R1
ROM:080B4C7E                 BCC     loc_80B4C86
And finally, Ruby:

Code:
ROM:08084D32                 MOVS    R4, R0
ROM:08084D34                 LDRB    R0, [R4,#1]
ROM:08084D36                 LDRB    R1, [R4]
ROM:08084D38                 CMP     R0, R1
ROM:08084D3A                 BCC     loc_8084D40
As you can see, it's essencially the same thing. If you were to look in IDA or VBA's decompiler, you'd see the same thing, but with a few different registers here and there.
__________________



Reply With Quote
  #20    
Old December 9th, 2010, 08:37 AM
Jambo51's Avatar
Jambo51
Glory To Arstotzka
 
Join Date: Jun 2009
Gender: Male
Nature: Quiet
I know it's not in exactly the same place between Ruby, FireRed and Emerald, but it may be in exactly the same locations in an English Fire Red rom and a Spanish Fire Red rom. I'll need to have a look. I don't expect them to be, but they'll more than likely be very similarly placed, and the actual routine should (in theory) be identical. So no rewriting for a Spanish rom, simply insert at a different location. I will have to rewrite the routines to work with Emerald after having a quick look at the offsets posted by shiny quagsire, but only because it uses different registers. I couldn't get Ruby to open in VHA-SDL-H (probably a messed up rom) but I'll have a look shortly.
__________________
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!
Reply With Quote
  #21    
Old December 17th, 2010, 05:33 PM
Shiny Quagsire's Avatar
Shiny Quagsire
Unexpectedly Gone until Aug 13
 
Join Date: May 2009
Location: Hoenn Safari Zone
Age: 16
Gender: Male
Nature: Jolly
Alrighty! I've finally finished DN Pokemon Data Editor! The download is in an attachment as a zip file. Keep in mind this is only in it's early versions, and may have a bug in it. If you find a bug, contact me by way of PM.
Attached Images
File Type: jpg window 1.JPG‎ (48.7 KB, 135 views) (Save to Dropbox)
File Type: jpg window 2.JPG‎ (20.5 KB, 91 views) (Save to Dropbox)
Attached Files
File Type: zip DN Pokemon Data Editor.zip‎ (653.6 KB, 152 views) (Save to Dropbox)
__________________



Reply With Quote
  #22    
Old December 18th, 2010, 03:32 PM
destinedjagold's Avatar
destinedjagold
Oh Hai Thar~ 'ω'
Community Supporter
 
Join Date: May 2007
Location: Philippines
Gender: Male
Nature: Careful
So, is this research, and this new tool, can change the PKMN in the wild depending if it's day or night, just like in the 2nd generation of games?
__________________
3DS FC: 0061-1111-6462
SV: 1364 | Rock Safari: Dwebble, Corsola and Barbaracle
Reply With Quote
  #23    
Old December 18th, 2010, 03:36 PM
Shiny Quagsire's Avatar
Shiny Quagsire
Unexpectedly Gone until Aug 13
 
Join Date: May 2009
Location: Hoenn Safari Zone
Age: 16
Gender: Male
Nature: Jolly
Quote:
Originally Posted by destinedjagold View Post
So, is this research, and this new tool, can change the PKMN in the wild depending if it's day or night, just like in the 2nd generation of games?
Yup. And soon morning and evening, if everything goes along right.
__________________



Reply With Quote
  #24    
Old December 18th, 2010, 03:43 PM
altariaking's Avatar
altariaking
Needs NO VMs...
 
Join Date: Dec 2009
Location: Scotland, Lesmahagow
Age: 39
Gender: Male
Nature: Naive
Send a message via Windows Live Messenger to altariaking
I have an idea for the tool. How about instead of having the Pokemons names listed alphabetically, have the names of Pokemon from the rom listed by their pokedex order? Because I inserted a fakemon over another Pokemon, and since it's name isn't there, I can't remember which Pokemon I replaced, and the Pokemon are listed alphabetically, it makes it hard to find :\

Edit: For some reason it freezes when I run into a wild Pokemon at night :\
__________________
http://www.pokecommunity.com/member.php?u=253113

Last edited by altariaking; December 18th, 2010 at 03:56 PM.
Reply With Quote
  #25    
Old December 18th, 2010, 03:48 PM
diegoisawesome's Avatar
diegoisawesome
Not the Script Help Thread
Community Supporter
 
Join Date: Dec 2007
Location: Goldenrod City, Johto
Age: 17
Gender: Male
Nature: Quirky
I THOUGHT I had the offset for the time in Emerald! I looked through my notes, and here it is: 0x03005CFA.
The reason that you probably didn't find it is probably that it doesn't update unless you do special things, like entering a new map, using a command\special that causes the time to be reloaded, etc.
__________________


My other resources:
My Website
diegoisawesome's MEGA-HUGE XSE Scripting Tutorial
diegoisawesome's Miscellaneous Finds
The Ruins of Alph Puzzles
Reply With Quote
Reply
Quick Reply

Sponsored Links
Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Minimum Characters Per Post: 25



All times are UTC -8. The time now is 11:26 PM.


Style by Nymphadora, artwork by Sa-Dui.
Like our Facebook Page Follow us on Twitter © 2002 - 2014 The PokéCommunity™, pokecommunity.com.
Pokémon characters and images belong to The Pokémon Company International and Nintendo. This website is in no way affiliated with or endorsed by Nintendo, Creatures, GAMEFREAK, The Pokémon Company or The Pokémon Company International. We just love Pokémon.
All forum styles, their images (unless noted otherwise) and site designs are © 2002 - 2014 The PokéCommunity / PokéCommunity.com.
PokéCommunity™ is a trademark of The PokéCommunity. All rights reserved. Sponsor advertisements do not imply our endorsement of that product or service. User generated content remains the property of its creator.