• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Quick Research & Development Thread

tinix

PearlShipper & C Programmer
86
Posts
14
Years
  • 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.
     

    Full Metal

    C(++) Developer.
    810
    Posts
    16
    Years
  • @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. (:
     

    Alice

    (>^.(>0.0)>
    3,077
    Posts
    15
    Years
  • 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.)
     

    Full Metal

    C(++) Developer.
    810
    Posts
    16
    Years
  • 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?
     

    EdensElite

    No0b, but getting there.
    190
    Posts
    12
    Years
    • Age 29
    • UK
    • Seen Jul 4, 2014
    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 :/
     
    275
    Posts
    13
    Years
    • Seen Oct 9, 2019
    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:

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

    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.
     

    TheDarkShark

    Metal Headed Hacker
    56
    Posts
    13
    Years
  • 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 :P
     
    Last edited:

    JPAN

    pokemon rom researcher
    104
    Posts
    15
    Years
    • Seen Jul 2, 2016
    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

    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).
     
    275
    Posts
    13
    Years
    • Seen Oct 9, 2019
    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. :)
     

    marcc5m

    what
    1,116
    Posts
    13
    Years
  • 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.
     
    Last edited:
    1
    Posts
    12
    Years
    • Seen Aug 16, 2011
    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.
     
    Last edited:

    marcc5m

    what
    1,116
    Posts
    13
    Years
  • 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
     

    luke

    Master of the Elements
    7,809
    Posts
    16
    Years
  • 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.
     

    Gamer2020

    Accept no Imitations!
    1,062
    Posts
    15
    Years
  • 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
     
    275
    Posts
    13
    Years
    • Seen Oct 9, 2019
    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?
     

    TheDarkShark

    Metal Headed Hacker
    56
    Posts
    13
    Years
  • 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.
     
    275
    Posts
    13
    Years
    • Seen Oct 9, 2019
    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:


    - - - - - - - - - -​

    EDIT1: ADDITIONAL FINDINGS

    Spoiler:


    - - - - - - - - - -​

    EDIT2: ADDITIONAL FINDINGS

    Spoiler:

    - - - - - - - - - -

    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.
     
    Last edited:
    Back
    Top