Go Back   The PokéCommunity Forums > ROM Hacking > Research & Development
Reload this Page Quick Research & Development Thread

Notices
For all updates, view the main page.

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
 
Thread Tools
  #126    
Old May 29th, 2011 (1:04 AM).
knizz's Avatar
knizz knizz is offline
 
Join Date: Aug 2007
Posts: 192

Nice find. Also congratulations on your first post.

__________________
Firered IDA 6.5 DB: https://www.dropbox.com/s/d856o3pyndyr5sr/firered.idb
VBA-M with lua scripting support
Reply With Quote

Relevant Advertising!

  #127    
Old June 13th, 2011 (1:40 AM).
linkandzelda's Avatar
linkandzelda linkandzelda is offline
n00b desu ka?
 
Join Date: Dec 2006
Location: Hastings, England
Gender: Male
Nature: Careful
Posts: 775

Hello,
I'm trying to run an item's asm, from within a script using callasm. At 080A1D9D is the ask for the VS SEEKER. i would like to run that but as i'm not in the bag it will run the bag close routine which results in a fade screen.

Hope i can ask this here,
Thanks

__________________
Reply With Quote
  #128    
Old June 13th, 2011 (4:41 AM).
Darthatron's Avatar
Darthatron Darthatron is offline
巨大なトロール。
Silver Tier
 
Join Date: Jan 2006
Location: Melbourne, Australia
Age: 24
Gender: Male
Nature: Modest
Posts: 1,152

Quote originally posted by linkandzelda:
Hello,
I'm trying to run an item's asm, from within a script using callasm. At 080A1D9D is the ask for the VS SEEKER. i would like to run that but as i'm not in the bag it will run the bag close routine which results in a fade screen.

Hope i can ask this here,
Thanks

Try running it from 080A1DF4+1. This bypasses most of the checks (like "Now isn't the time to use that...") but I don't think it work correctly since the routine seems to have at least one parameter (in R0.)

__________________
あなた は しきしゃ です
わたし は ばか です
Reply With Quote
  #129    
Old June 13th, 2011 (5:47 AM).
linkandzelda's Avatar
linkandzelda linkandzelda is offline
n00b desu ka?
 
Join Date: Dec 2006
Location: Hastings, England
Gender: Male
Nature: Careful
Posts: 775

Quote originally posted by Darthatron:
Try running it from 080A1DF4+1. This bypasses most of the checks (like "Now isn't the time to use that...") but I don't think it work correctly since the routine seems to have at least one parameter (in R0.)

Thanks for the help, but it went straight to the fadescreen again.

__________________
Reply With Quote
  #130    
Old June 16th, 2011 (1:39 PM).
hi sir tomato my password is syvniti's Avatar
hi sir tomato my password is syvniti hi sir tomato my password is syvniti is offline
gggggggggggggggggg
 
Join Date: Jan 2007
Location: My user name _ asciii_ +&h1!" lulz
Posts: 581

http://www.youtube.com/watch?v=EUzj-6IvCoI
I can do it! :p
- But I can't post videos with these youtube thingys

__________________
THE CAKE IS A LIE!!!!!!!!!!!!!!!!!!!!!!!
Reply With Quote
  #131    
Old August 10th, 2011 (4:33 AM).
tinix's Avatar
tinix tinix is offline
PearlShipper & C Programmer
 
Join Date: Feb 2010
Location: Bratislava, Slovakia
Age: 19
Gender: Male
Posts: 86

Hello everybody,
Recently I have been experimenting with C, trying to compile working code for Pokemon ROMs, because I find ASM very messy and I cant get the grip of it.
I chosen C because there is available compiler for GBA/ARM and because I am
familiar with it.
After a while of experimenting, messing with compiler flags and pointers, I have managed to successfully compile, insert and test a function that returned lowest level of your party Pokémon, and a function that jumped/branched into (standard) ASM routine. This process has a few drawbacks, mainly that resulting binary code is larger.

In attachment you will find C files along with instructions how to compile them (Code is set up for FIRE RED!). If you have any issues with compiling PM me and i will try to help you.

I want to know your opinion on this subject as whole.

Attached Files
File Type: zip CPKMN.zip‎ (717.9 KB, 28 views) (Save to Dropbox)
__________________
Pokémon games I own:
Pokémon Diamond
Pokémon Platinum
Pokémon Ranger: Shadows of Almia
Pokémon HeartGold Version
Reply With Quote
  #132    
Old August 10th, 2011 (7:21 AM).
Full Metal's Avatar
Full Metal Full Metal is offline
C(++) Developer.
Silver Tier
 
Join Date: Jan 2008
Location: In my mind.
Age: 20
Gender: Male
Nature: Timid
Posts: 805
Send a message via Windows Live Messenger to Full Metal

@Above - C seems a bit overkill for this. By judging on the size of the file, you didn't optimize the output or anything, which makes for a HUGE output, when you probably could have accomplished the same thing in a smaller routine. :\
On the other hand, congrats on getting it all to work properly. (:

__________________

★ full metal.

I like to push it,
and push it,
until my luck is over.
Reply With Quote
  #133    
Old August 10th, 2011 (3:39 PM).
Alice's Avatar
Alice Alice is offline
(>^.(>0.0)>
Crystal Tier
 
Join Date: Mar 2009
Location: Oregon
Age: 24
Gender: Female
Nature: Careful
Posts: 3,081
Send a message via Skype™ to Alice

I'm not entirely sure the best place to post ideas like this is, but this seems to be close enough.

I have no clue how feasible this is, but it was just an idea I had, and since I really don't hack anymore, I thought I'd post it, and see if anyone might want to try it.

The idea is that you would be able to only use a single pokemon throughout the game, but on every level up it would evolve (no b cancel allowed) into a completely random pokemon. It could go from caterpie to mewtwo at level 6, and then from mewtwo to magikarp at level 7. Completely random. It would also attempt to learn a completely random move from the new pokemon's list of moves learnable by level up.

Just an interesting gimmick that I'd like try, if anyone wants to incorporate it into a hack. Maybe even just a mod of firered/ruby, if nothing else.

(Now that I think about it, this is basically gungame, but with pokemon, haha.)

Reply With Quote
  #134    
Old August 10th, 2011 (6:09 PM).
Full Metal's Avatar
Full Metal Full Metal is offline
C(++) Developer.
Silver Tier
 
Join Date: Jan 2008
Location: In my mind.
Age: 20
Gender: Male
Nature: Timid
Posts: 805
Send a message via Windows Live Messenger to Full Metal

Quote originally posted by QuilavaKing:
I'm not entirely sure the best place to post ideas like this is, but this seems to be close enough.

I have no clue how feasible this is, but it was just an idea I had, and since I really don't hack anymore, I thought I'd post it, and see if anyone might want to try it.

The idea is that you would be able to only use a single pokemon throughout the game, but on every level up it would evolve (no b cancel allowed) into a completely random pokemon. It could go from caterpie to mewtwo at level 6, and then from mewtwo to magikarp at level 7. Completely random. It would also attempt to learn a completely random move from the new pokemon's list of moves learnable by level up.

Just an interesting gimmick that I'd like try, if anyone wants to incorporate it into a hack. Maybe even just a mod of firered/ruby, if nothing else.

(Now that I think about it, this is basically gungame, but with pokemon, haha.)

Good Grief No.
Who in their right minds would play that?

__________________

★ full metal.

I like to push it,
and push it,
until my luck is over.
Reply With Quote
  #135    
Old August 11th, 2011 (3:07 PM).
EdensElite's Avatar
EdensElite EdensElite is offline
No0b, but getting there.
 
Join Date: Jun 2011
Location: UK
Gender: Male
Nature: Bold
Posts: 190

I was just wonderig if it's possible to edit the box backgrounds on the pc, I couldnt find it in unLZ but since its a image it should be at some offset :/

__________________

ROM Hacking was getting frustrating for me. I've now stopped productions and writing the game from scratch in HTML 5.

That means it will be playable in the browser, and across multiple devices such as the iPod touch.
Reply With Quote
  #136    
Old August 12th, 2011 (10:56 AM).
Alice's Avatar
Alice Alice is offline
(>^.(>0.0)>
Crystal Tier
 
Join Date: Mar 2009
Location: Oregon
Age: 24
Gender: Female
Nature: Careful
Posts: 3,081
Send a message via Skype™ to Alice

Quote originally posted by Full Metal:

Good Grief No.
Who in their right minds would play that?

I would?

Like I said, it's just a gimmick, but it would be fun to mess around with.

Reply With Quote
  #137    
Old August 12th, 2011 (10:45 PM).
DavidJCobb DavidJCobb is offline
RESIDENT RAAAAAAAAAAAAGEMASTER
 
Join Date: Jul 2010
Gender: Male
Nature: Lonely
Posts: 275

Just in case anyone was wondering, there's no (practically-achievable) limit to how many times a script can recurse in FR. That is to say, scripts can call scripts that call scripts that... all the way up to 65535 nesting levels (though of course, there is some noticeable lag associated with running 65535 call statements almost directly after each other).

Test script 1 (master A calls sub B calls sub B...):

Spoiler:
Code:
#dynamic 0x800000

/* Vars: 4000 Number of levels to recurse to 4001 How deep are we right now? 4002 How deep did we get? */

#org @start lock setvar 0x4000 0x0005 setvar 0x4001 0x0000 setvar 0x4002 0x0000 call @recursive buffernumber 0x00 0x4002 buffernumber 0x01 0x4000 msgbox @sAllReturnsWorked 0x02 release end

#org @recursive addvar 0x4001 0x0001 addvar 0x4002 0x0001 comparevars 0x4001 0x4000 if 0x0 call @recursive subvar 0x4001 0x0001 return

#org @sAllReturnsWorked = Successfully returned to the\noutermost script.\pDepth: [buffer1] / [buffer2]

Test script 2 (master A calls sub B calls sub C calls sub B...):

Spoiler:
Code:
#dynamic 0x800000

/* Vars: 4000 Number of levels to recurse to 4001 How deep are we right now? 4002 How deep did we get? */

#org @start lock setvar 0x4000 0xFFFF setvar 0x4001 0x0000 setvar 0x4002 0x0000 call @recursive1 buffernumber 0x00 0x4002 buffernumber 0x01 0x4000 msgbox @sAllReturnsWorked 0x02 release end

#org @recursive1 addvar 0x4001 0x0001 addvar 0x4002 0x0001 comparevars 0x4001 0x4000 if 0x0 call @recursive2 subvar 0x4001 0x0001 return

#org @recursive2 addvar 0x4001 0x0001 addvar 0x4002 0x0001 comparevars 0x4001 0x4000 if 0x0 call @recursive1 subvar 0x4001 0x0001 return

#org @sAllReturnsWorked = Successfully returned to the\noutermost script.\pDepth: [buffer1] / [buffer2]

So if you need to do something such as creating a recursive function to count how much of a certain item a player has, you should be able to do so without having to worry about hitting any kind of recursion limit. Again, though, efficiency is something to keep in mind.

__________________
Reply With Quote
  #138    
Old August 13th, 2011 (2:43 AM). Edited August 13th, 2011 by TheDarkShark.
TheDarkShark TheDarkShark is offline
Metal Headed Hacker
 
Join Date: May 2010
Location: Germany
Gender: Male
Nature: Calm
Posts: 56

Actually you don't need to worry about how many returns you may use in a recursive script. I wrote a standard script to check an item's amount (item number stored in some variable I'd need to look up...) which use goto to loop. When you use goto return will not jump to that branch, which means it will jump right back to the callstd command instead of the last recursion (I wonder if that's an actual word. We have a similar one in German for sure... ).
Nice find anyway.

Oh, and before I forget to write that:
@EdensElite: Of course it is possible, when you have the needed offsets. There are two possible reasons why you couldn't find them in unLZ. 1 - They aren't lz-compressed, which would mean you'd need to edit them via tile molester or a similar program, like NSE. 2 - They are strored as a tileset/tilemap-combo which you usually can't guess without the right palette. That would mean, you've already found them but don't know it (sounds weird, huh?).
A good way to find the ROM-offset of some graphics is to lookup the RAM-offset via Tile-/Map-Viewer in the VBA, put a break point on write on that offset (via VBA-SDL-H) and make the game load the graphics. With next-to-no-but-still-some ASM-knowledge you are then able to lookup the correct offset (plus you know if and how the graphic is compressed by checking the swi-function used). Also you could use logging to find the graphics, but I'm not 100 % sure if I can explain that right now...
I hop that helped a bit. I recommend to read a tutorial anyway

__________________
There are two things every Rom-Hacker should learn:
1. Don't give away everything you know!

Reply With Quote
  #139    
Old August 14th, 2011 (2:18 PM).
JPAN JPAN is offline
pokemon rom researcher
 
Join Date: Dec 2008
Posts: 104

Quote originally posted by QuilavaKing:
I'm not entirely sure the best place to post ideas like this is, but this seems to be close enough.

I have no clue how feasible this is, but it was just an idea I had, and since I really don't hack anymore, I thought I'd post it, and see if anyone might want to try it.

The idea is that you would be able to only use a single pokemon throughout the game, but on every level up it would evolve (no b cancel allowed) into a completely random pokemon. It could go from caterpie to mewtwo at level 6, and then from mewtwo to magikarp at level 7. Completely random. It would also attempt to learn a completely random move from the new pokemon's list of moves learnable by level up.

Or a stone-like item that has that behaviour. In fact, it would be quite simple to implement such a feature. For simplicity, let's say we would get rid of evolution nº2, and that any pokemon is elligible from the original 251 (so we don't deal with the 21 empty slots.)
At 08042FC8 you would place a pointer to this function (with no +1, as this is a mov to PC and not a bx)
Code:
.thumb
bl getRandomHalfword
mov r1, #0xfb /*Celebi number*/
bl module
add r0, r0, #0x1 /*so that ? is not an option*/
ADD     SP, SP, #0x14 /*we exit the function for them*/
POP     {R3-R5}
MOV     R8, R3
MOV     R9, R4
MOV     R10, R5
POP     {R4-R7, pc}
.align 4
getRandomHalfword: ldr r0, rng_addr
   bx r0
rng_addr: 0x08044EC9
module: ldr r2, mod_addr
 bx r2
mod_addr: 0x081E4685
PS:untested, but looks bug-free from here
And with this, you have a random evolution, that always takes place when a level changes.
To use, place in the evolution type 0x02
You can always extend the Evolution table at 08042FC4 and use this with other number, if you want

Quote originally posted by DavidJCobb:
Just in case anyone was wondering, there's no (practically-achievable) limit to how many times a script can recurse in FR. That is to say, scripts can call scripts that call scripts that... all the way up to 65535 nesting levels (though of course, there is some noticeable lag associated with running 65535 call statements almost directly after each other).

So if you need to do something such as creating a recursive function to count how much of a certain item a player has, you should be able to do so without having to worry about hitting any kind of recursion limit. Again, though, efficiency is something to keep in mind.

Actually, no. Script depth is locked at 0x0806988E, to 20 pointers stored.
The infinite recursion displayed by your example scripts is an illusuion caused by the fact that when the limit is reached, it jumps instead of going back recusively. As the return value will be the same for all called code (or almost all), it will return to the location it should correctly. And this value can't be changed (well, it could but would cause trouble) as the memory where it is located is surrounded by usefull data, and it is stored on the smallest RAM (0x0300XXXX).

__________________
Here are the links for my work


Currently working on:
Battle Script Documentation
Another large project
Reply With Quote
  #140    
Old August 14th, 2011 (3:34 PM).
DavidJCobb DavidJCobb is offline
RESIDENT RAAAAAAAAAAAAGEMASTER
 
Join Date: Jul 2010
Gender: Male
Nature: Lonely
Posts: 275

Quote originally posted by JPAN:
Actually, no. Script depth is locked at 0x0806988E, to 20 pointers stored.
The infinite recursion displayed by your example scripts is an illusuion caused by the fact that when the limit is reached, it jumps instead of going back recusively. As the return value will be the same for all called code (or almost all), it will return to the location it should correctly. And this value can't be changed (well, it could but would cause trouble) as the memory where it is located is surrounded by usefull data, and it is stored on the smallest RAM (0x0300XXXX).
So FireRed remembers the outermost caller, but after a certain point it treats "return" as "goto"? That is clever... And it explains why after a certain number of tests, the screen lag caused by the calls stopped increasing.

Thanks for sharing that info.

__________________
Reply With Quote
  #141    
Old August 14th, 2011 (4:35 PM). Edited August 14th, 2011 by Crimson5M.
Crimson5M's Avatar
Crimson5M Crimson5M is offline
what
Crystal Tier
 
Join Date: Feb 2011
Location: Scotland
Age: 20
Gender: Male
Nature: Quiet
Posts: 1,085

If anyone's interested to know, 251FEE is the start of the FireRed Pokedex order. Not exactly sure if it can be considered "Research and Development" but I thought I'd share anyway.

__________________
Youtube
Reply With Quote
  #142    
Old August 14th, 2011 (5:23 PM). Edited August 14th, 2011 by MikeBricks.
MikeBricks MikeBricks is offline
 
Join Date: Aug 2011
Gender: Female
Posts: 1

You are wrong! It is 251FEE! You have to make there is a pointer for offsets you find! You are stupid for not doing so.

No you are wrong! It is 251FEE!
Reverse it which is EE1F2508. Then search that. You will get 2 results which mean I am right.

No you are wrong! It is 251FEE!
Reverse it which is EE1F2508. Then search that. You will get 2 results which mean I am right.

__________________
Excuse my English, I am from Argentina.
Reply With Quote
  #143    
Old August 14th, 2011 (6:04 PM).
Gamer2020's Avatar
Gamer2020 Gamer2020 is offline
Accept no Imitations!
 
Join Date: Jun 2008
Location: Distant Land
Gender: Male
Nature: Bold
Posts: 846
Send a message via Skype™ to Gamer2020

MikeBricks is correct. His offset is the same one I have in my ini.

__________________

Pokemon Game Editor Download!
Accept no imitations!
Reply With Quote
  #144    
Old August 14th, 2011 (6:12 PM).
Crimson5M's Avatar
Crimson5M Crimson5M is offline
what
Crystal Tier
 
Join Date: Feb 2011
Location: Scotland
Age: 20
Gender: Male
Nature: Quiet
Posts: 1,085

Quote originally posted by Gamer2020:
MikeBricks is correct. His offset is the same one I have in my ini.

Yeah, I know, it was a mistake. I interpreted the first byte of two 0s to be the beginning, because I thought it went:
00 01 00 02
When it was actually:
01 00 02 00

Who's stalking now

__________________
Youtube
Reply With Quote
  #145    
Old August 14th, 2011 (6:51 PM).
mystletainn mystletainn is offline
Master of the Elements
Crystal Tier
 
Join Date: Jun 2007
Location: New York
Age: 27
Gender: Male
Nature: Naughty
Posts: 7,802

Cut the crap Gamer and Fireworks. This is the last straw before infractions and even temp bans are going to be put in place for you. A timeout from PC might do both of you good.

__________________
The bloody blade
Reply With Quote
  #146    
Old August 14th, 2011 (7:37 PM).
Gamer2020's Avatar
Gamer2020 Gamer2020 is offline
Accept no Imitations!
 
Join Date: Jun 2008
Location: Distant Land
Gender: Male
Nature: Bold
Posts: 846
Send a message via Skype™ to Gamer2020

Quote originally posted by Luke:
Cut the crap Gamer2020 and Fireworks. This is the last straw before infractions and even temp bans are going to be put in place for you. A timeout from PC might do both of you good.
I actually did not do anything.

Here are some offsets I found in BPEE. I didn't give them proper names because I'm lazy...

copyright - 080A9179
fadescreen - 0816CF19
- 0816D12D
Gamefreak - 0816D191
Grassup and flygon flies - 0816D355
white screen - 0816D459
white screen - 0816D48D
white screen - 0816D4E5
Bike ride1 - 0816D651
Bike ride fadeout - 0816D7E8
white screen - 0816DBAD
Intro Battle start - 0816DC65
White screen - 0816DCFD
white screen - 0816DD29
White screen - 0816DDD9
lava fade in - 0816DE7D
lava fade in2 - 0816DED1
lava fade in3 - 0816DEED
GROUDON! - 0816DF2D
White screen - 0816E21
Kyorge! - 0816E359
White screen - 0816E889
White screen - 0816E955
White screen - 0816E999
Sky gets dark - 0816E9DD
still dark - 0816EAB9
Is it a bird? - 0816EB45
dark - 0816ED21
That bird did something scary - 0816EDB5
White screen - 0816EE91
White screen - 080A9179
Pokemon TitleScreen- 080AAB45
Emerald Vesion - 080AAC51
Press Start - 080AAD65
White screen - 080A9179
Fade in blue - 0802F8D9
still blue - 0802FAB1
blue... - 802FBA5
blue....... - 080300B1
New Game - 0803024D
Black screen - 0803027D
Black screen - 080307B1
Background loaded for birch- 080308B1
Birch appears - 08030928
Hi! Sorry to keep you waiting! - 080309CD
This is what is called a Pokemon. - 08030A2D
This world is widely... - 08030BCD
And You Are? - 08030C19
Spotlight went right - 08030C91
OMG he left! - 08030CD5
Is that me? - 08030D85
Nothing? - 08030DC9
Are you a boy? Or are you a girl? - 08030E09
Boy - Girl Multichoice - 08030E39
prepare - 08030FD5
All right. What's your name? - 08031015
press a - 08031041
fade to black - 08031091
still black - 080A9179
Your name? - 080E465D
black - 080A9179
black - 0803261D
I'm back! - 08031105
so it's?- 08031145
yes no - 08031189
spotlight to left - 08031221
I'm gone - 08031259
Ah, okay! - 0803133D
birch gone - 080313E5
All right are you ready? - 080314C5
I'm shrinking - 08031581
nothing? - 080315BD
I'm white? - 08031631
black - 080A9179
black - 080AB161
Overworld - 080AB1B1

__________________

Pokemon Game Editor Download!
Accept no imitations!
Reply With Quote
  #147    
Old August 14th, 2011 (10:49 PM).
DavidJCobb DavidJCobb is offline
RESIDENT RAAAAAAAAAAAAGEMASTER
 
Join Date: Jul 2010
Gender: Male
Nature: Lonely
Posts: 275

I'm about to start trying to reverse-engineer the COIN CASE ASM script in FireRed. My aim is to identify the functionality that makes the "COINS: XXXX COINS" message box work, so that I can call/clone it and be able to show two message boxes at once in script. (I can already imagine the possibilities...)

I've done a small amount of work, but before I go any further, I have three questions:

  • Uh... How do I know when I've found the ASM that actually creates a secondary message box?
    .
  • My understanding of ASM is as basic as it gets, so I'll ask right now: has anyone already done what I'm trying to do? Because if someone's already done it, there's little point in me doing it. :\
    .
  • I'll check this one on my own if it goes unanswered when I wake up later.
    The "showcoins" command shows a secondary box. And I'm pretty sure that the COIN CASE item code shows both a secondary box and a standard box, but my memory's a little hazy. When you use the COIN CASE from the Bag, does it show the same box that appears when "showcoins" is called?

__________________
Reply With Quote
  #148    
Old August 15th, 2011 (2:08 AM).
TheDarkShark TheDarkShark is offline
Metal Headed Hacker
 
Join Date: May 2010
Location: Germany
Gender: Male
Nature: Calm
Posts: 56

1. I'm not really sure (I'm new to code hacking too, I've only built ASM functions to call them from a script...), but I think when data is copied from the graphic's ROM-offset. While debugging, watch registers r0-r2 carefully. They are used by the data-copying swi-functions. r0 is the source- and r1 the aim-offset.

2. I don't know if anyone has researched opening a second message box. I'm currently researching the Text-Box palette loading routine, just in case that sounds important. But as I'm using a German ROM, I can only be of little help. Not that I could be of much help if I used another ROM, lol.

3. I don't know, sorry.

__________________
There are two things every Rom-Hacker should learn:
1. Don't give away everything you know!

Reply With Quote
  #149    
Old August 15th, 2011 (10:52 PM). Edited August 18th, 2011 by DavidJCobb.
DavidJCobb DavidJCobb is offline
RESIDENT RAAAAAAAAAAAAGEMASTER
 
Join Date: Jul 2010
Gender: Male
Nature: Lonely
Posts: 275

Turns out, the COIN CASE item script does not generate a secondary box as I recalled. However, through hours of brute-force near-blind-searching, I have managed to locate the assembly code used by the scripting engine. I've confirmed that my findings matched those presented here.

I have thus managed to locate the offsets of the ASM that runs when the scripting engine is processing the showcoins command. I anticipate that if I simply examine what data is passed to where, I can figure out the offset of the ASM that generates a secondary box. Manipulating that ASM should allow the script-based generation of a non-blocking second message box alongside the standard scriptable one, without either replacing or forcibly closing the other.

I feel the need to mention that I have barely any idea what I'm doing. I am so incompetent at ASM that I cannot even get code that I've written to compile, let alone actually work. So I'm going to share what I find, so that if I fail, I'll at least have saved other people some time.

All offsets are in hex.

Spoiler:
08069873
Part of the scripting engine. Calls 08069842.

08069842
Part of the scripting engine. Part of some code that reads the current command byte from the script and interprets it. If the current script byte is 0x00 (nop), this code calls 08069832. Otherwise, it calls 08069858.

08069858
Loads the current command byte into r1. Stores offset of the next byte of the script somewhere in the script engine's RAM (this is used later to grab the arguments). Examines some kind of table located at 0815F9B4 -- the table seems to map each command byte to the offset of its respective ASM code. For showcoins, this code loads 0x0806C259 into r1. Calls 081E3BAC.

081E3BAC
Calls whatever address has been stored in r1. For showcoins, that would be 0806C259.

0806C258
ASM for showcoins? Loads first and second argument (X and Y) into r5 and r4, respectively. Stores a pointer to the next command byte (the byte directly after the last argument) somewhere in the script engine's RAM (that RAM offset being held in r0). Calls 081119D4 (I haven't deciphered that yet). I haven't deciphered what this chunk of code does next, but it involves conditional (if r0 != 0x1) calls to 080D0554 and 080D072C, and then it goes back to 08069873, which processes the next command in the script.

- - - - - - - - - -

Ergo the ASM at 081119D4, and possibly also 080D0554 and 080D072C, are somehow responsible for loading a predetermined string ("[buffer] COINS", at 084162C4) into RAM (specifically, to offset 02021D18), drawing the frame of the secondary box, and drawing that string as the box's contents.

There are other things that I discovered in my blind search, though I do not know exactly where or how they fit into the showcoins functionality as a whole. They are:

I do not fully understand the assembly code at 08005ED4, but I do know that it loops through each character of the string after that string has been loaded into RAM and retrieves some value (stored in ROM) for each character. I suspect that it is obtaining the pixel widths that correspond to each charcode, though I do not know what it does with the numbers.

Multiple calls are made to 08002C48, a chunk of ASM code that seems to also be called on every frame of animation. Presumably it is called either to check for keypresses or to update what is on-screen, though I don't know why such checks would be run before the secondary box has even appeared. Perhaps it is done to prevent showcoins from blocking music and the playtime counter.

I suspect that assembly code at 08008FCC is what loads the message string into RAM, but I am not sure.

- - - - - - - - - -

EDIT1: ADDITIONAL FINDINGS

Spoiler:
Still don't know what exactly 081119D4, above, does. But I know that 080D0554 loads the number of coins from DMA-protected memory, and 080D072C initiates a huge volume of code that eventually produces the secondary box.

08008E78 is the offset of an ASM function that buffers a number. It appears to divide the input by a number (hardcoded 0xA) and process the remainder, thereby splitting the number into digits. Each digit is compared to 0x9; if lower or equal to, the charcode for it is found; if greater than, the charcode AC ("?") is returned. I have no idea which register holds the number to be buffered, however.

08003CE4 calls different blocks of code depending on what kind of message is to be displayed. It runs once when the message is to be displayed, and then I think it runs on every frame of animation thereafter. I'm not sure, however; VBA-SDL-H is... temperamental, shall we say. Moving on:

When a message box is created, its data -- a 12-byte structure that was partially documented here -- is written either into the stack or into some memory area very close to it. (The stack pointer itself is frequently shifted and unshifted throughout the process. Confusing!) When the first eight bytes of the data have been put together, code at 08003DE8 generates the last four bytes (based on the last four bytes of the preceding message box data) and then moves the new structure from the stack-or-near-the-stack area into the proper RAM area. Note that there is always one chunk of message box data already in RAM -- that of the standard message box, even if that box is inactive.

08008FCC appears to be used to load the string from ROM into RAM. r0 is the destination offset, r1 is the source; for showcoins, they are 0x02021D18 (message to be displayed) and 0x084162C4 ("[buffer] COINS"), respectively. Characters are transferred one at a time. Most charcodes are handled by a copying code at 080090A6, but codes FA through FF each have some kind of special handler, with FA's being at 08008FEC. I haven't investigated that further; it's not relevant to what I'm trying to find.

Here's a hierarchical chart of my findings:

Spoiler:
Code:
0x08069842
Load and proess script byte.

0x08069858 Identify script command byte.

0x0806C258 ASM for showcoins. Retrieves arguments.

0x081119D4 Unknown. But if it sets r0 to 0x1, then showcoins doesn't do anything.

0x080D0554 Retrieve coins from DMA-protected memory and store in r0.

0x080D072C Unknown. Starts generation of secondary msgbox data.

0x0810FE50 Gathers certain attributes for box sizing? Uses bitmasks of some sort.

0x08003CE4 Calls different code blocks depending on what kind of message box is being shown. It seems as though every kind of message box passes through here -- even the Start Menu!

It also locates the first unused slot for message box position data in RAM.

0x08003D96 Unknown. Runs once for most message boxes. Runs twice for the Start Menu (once mid-sound, once after). Does not run for signbox or msgbox.

0x08002B9C Unknown.

0x08003DE8 Transfers the new message box position data from some space near the stack to the proper RAM offset.

0x0800445C Unknown. Uses a software interrupt to copy a section of memory.

0x08003FA0 Unknown. Some of the code it calls runs a TON of weird and complicated comparisons, returning 0x0 or 0x1 based on the result.

0x080D06D0 Triggers loading of the "[buffer] COINS" display.

0x08008E78 Buffers a number. r2 specifies the buffer to use?

0x08008FCC Copies the string at r1 into the offset at r0, one character at a time. Calls special codes for each charcode between 0xFA and 0xFF, inclusive.

0x08005ED4 Unknown. But it seems important.

0x0806C287 (cont'd from 0x0806C258) ...Returns to the script engine ASM to process the next command.


- - - - - - - - - -

EDIT2: ADDITIONAL FINDINGS

Spoiler:
08002C48 is not actually called on every frame; that was just the debugger going haywire. It's only called a few times, and I suspect that it -- or code called by it -- triggers drawing and erasing of message boxes.

0800445C is the code that uses a software interrupt to copy data. It copies a very large chunk of data; I think it loads the tiles for either a box's frame or its interior.

And finally, I have managed to just barely manipulate secondary box generation. Have a look at this screenshot:

You'll notice that there is a problem with the palettes... But look in the upper-left corner. That is the bottom corner of a secondary box! It even vanishes when another secondary box (or a multichoice) is displayed. However, I couldn't find the tiles for the secondary's text content in VBA's Tile Viewer... According to the Memory Viewer, however, a pointer to my text was successfully loaded to 0x02021D18, so it appears that the only issues left to solve are graphical ones.

Here's the ASM code I used, if anyone wants to have a look and see what they can find. You would use loadpointer to load a string into memory, and then call this with callasm. The code was modeled after that used by the game; essentially, it's a copy that loads the string you feed with loadpointer. (Apparently, it isn't a very accurate copy...)

Spoiler:
Code:
.align 2
.thumb

main: push {r0-r7,lr} mov r4, #0x0 mov r3, #0x0 lsl r4, r4, #0x18 lsl r3, r3, #0x18 mov r0, #0x80 lsr r0, r0, #0x11 add r4, r4, r0 add r3, r3, r0 lsr r4, r4, #0x18 lsr r3, r3, #0x18 mov r0, #0x08 str r0, [sp] mov r0, #0x03 str r0, [sp, #0x4] mov r0, #0x0F str r0, [sp, #0x8] mov r0, #0x20 str r0, [sp, #0xC] add r0, sp, #0x10 mov r1, #0x0 mov r2, r4 push {r7} ldr r7, DATA_ASSEMBLE bl CALL_GAME_ASM pop {r7} ldr r0, [sp, #0x18] ldr r1, [sp, #0x14] str r0, [sp, #0x18] str r1, [sp, #0x1C] ldr r4, UNKNOWN_DATA_1 add r0, sp, #0x18 strb r0, [r4] ldrb r0, [r4] mov r1, #0x0 push {r7} ldr r7, UNKNOWN_FUNCTION_1 bl CALL_GAME_ASM pop {r7} ldrb r0, [r4] push {r7} ldr r7, UNKNOWN_FUNCTION_2 bl CALL_GAME_ASM pop {r7} ldrb r0, [r4] ldr r5, UNKNOWN_DATA_2 mov r1, r5 mov r2, #0x0 push {r7} ldr r7, UNKNOWN_FUNCTION_4 bl CALL_GAME_ASM pop {r7} ldrb r0, [r4] mov r1, #0x0 mov r2, r5 mov r3, #0xD push {r7} ldr r7, UNKNOWN_FUNCTION_5 bl CALL_GAME_ASM pop {r7} ldrb r0, [r4] ldr r2, SECONDARY_BOX_HEADER_STRING mov r3, #0x0 str r3, [sp] mov r1, #0xFF str r1, [sp, #0x4] str r3, [sp, #0x8] mov r1, #0x2 push {r7} ldr r7, UNKNOWN_FUNCTION_3 bl CALL_GAME_ASM pop {r7} mov r0, r6 bl COBB_SUBFUNCTION add sp, #0x20 pop {r0-r7,pc}

COBB_SUBFUNCTION: push {r4,lr} add sp, #-0xC ldr r0, STRING_RAM_OFFSET ldr r1, SCRIPT_LOADED_POINTER_0 mov r3, #0x4 mov r4, r0 push {r7} ldr r7, BODY_STRING_LOADER bl CALL_GAME_ASM pop {r7} mov r0, #0x0 mov r1, r4 mov r2, #0x0 push {r7} ldr r7, UNKNOWN_FUNCTION_6 bl CALL_GAME_ASM pop {r7} ldr r1, UNKNOWN_DATA_1 ldrb r1, [r1] mov r3, #0x40 sub r3, r0 lsl r3, r3, #0x18 lsr r3, r3, #0x18 mov r0, #0xC str r0, [sp] mov r0, #0x0 str r0, [sp, #0x4] str r0, [sp, #0x8] mov r0, r1 mov r1, #0x0 mov r2, r4 push {r7} ldr r7, UNKNOWN_FUNCTION_3 bl CALL_GAME_ASM pop {r7} add sp, #0xC pop {r4} pop {r0} bx r0

CALL_GAME_ASM: bx r7

SECONDARY_BOX_HEADER_STRING: .word 0x08417C2D

SCRIPT_LOADED_POINTER_0: .word 0x03000F14

STRING_RAM_OFFSET: .word 0x02021D18

DATA_ASSEMBLE: .word 0x810FE51

UNKNOWN_DATA_1: .word 0x02039A28

UNKNOWN_FUNCTION_1: .word 0x0800445D

UNKNOWN_FUNCTION_2: .word 0x08003FA1

UNKNOWN_DATA_2: .word 0x0000021D

UNKNOWN_FUNCTION_3: .word 0x08002C49

UNKNOWN_FUNCTION_4: .word 0x0814FF2D

UNKNOWN_FUNCTION_5: .word 0x0810F2E9

BODY_STRING_LOADER: .word 0x08008FCD

UNKNOWN_FUNCTION_6: .word 0x08005ED5

- - - - - - - - - -

EDIT3:

Removing the call to 0814FF2C prevents palette damage, but it also prevents any messageboxes from appearing. It would seem that I am not providing the correct values to it; I'll have to investigate it further.

__________________
Reply With Quote
  #150    
Old August 19th, 2011 (6:40 AM).
Mr.Pkmn's Avatar
Mr.Pkmn Mr.Pkmn is offline
Ordinary ASM Magician
 
Join Date: May 2008
Posts: 39

How can we fix the broken sun weather in FRLG? Heavy rain works fine but intense sunlight makes the screen black.
Also I wonder if the snowy weather could set auto-hail, like other weathers do...

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

Forum Jump


All times are GMT -8. The time now is 7:36 PM.