Binary ROM HackingNeed a helping hand or just want to talk about binary ROM hacks? Get comments and answers to any ROM Hacking-related problems, questions or thoughts you have here.
Remove any identation or spacing of the line where the label is. Labels should be aligned to the left with no spacing or else rgbds will interpret them as instructions or macros.
Any suggestions for Hex Editors to open the map files (which are .BLKs)? I've tried THINGY and THING32, but they don't seem to recognize the BLK tag. Supposedly I can open my ROM in a program to find the offsets of map edits I've done with PokeMap, but still need a way to get the changes into the actual files so it doesn't overwrite the mapping when I compile other changes (seems tricky).
Any suggestions for Hex Editors to open the map files (which are .BLKs)? I've tried THINGY and THING32, but they don't seem to recognize the BLK tag. Supposedly I can open my ROM in a program to find the offsets of map edits I've done with PokeMap, but still need a way to get the changes into the actual files so it doesn't overwrite the mapping when I compile other changes (seems tricky).
You could always change the extension of the file to some other type that the hex editor you'd like to use is able to open. Or not totally change it at all, but add another extension to the end if needed.
Anyway, I use GoldFinger for hex editing myself and it has been pretty handy in doing everything, so you might like it as well. I have not only used it for rom hacking but checking the data of several other files as well sometimes when I have needed (mostly related to programming really). But it can open a file with any extension.
So I was initially trying to get a person to give an item, but it looked a little too involved when I compared it against scripts that did it. So now I'm just adding an item ball on the ground. So far so good, but the "GotItemText" isn't appearing in the text box when I g to pick the item up, and one of the other sources of text is doing the same (it wasn't before). Additionally, the item isn't being picked up off the ground.
I'll bet it's some kind of script pointing issue, but up to this point I haven't messed too much with adding material, only changing things that were there before. For the sake of learning, I checked the text, script, and mapObject files for the area I'm adding the item against the files for an area that already had an item. I've matched the mapObject files, but can't figure out what's missing between the text and script files.
Unfortunately it doesn't look like I'm going to have time to spend on hex editing for mapping purposes, so I've saved a spare rom with the map changes and will use it as a reference for just doing the mapping again (since that will be faster for me).
EDITED-- Moot point. There was no initial disassembly on my part. DERP.
In hindsight, I realize how naive the thought of simply disassembling my ROM sounds. If it were that easy, it wouldn't have been such huge initial undertaking. I guess I'm back on the manual re-editing page. Although I still haven't quite the hang of those item issues. So close...
So I've found some resources on adding scripts (which is part of the problem with adding obtainable items), but even these haven't solved my issue. After some reading, it seemed much simpler to have an NPC give a FRESH_WATER, but now I can't figure out why the code I'm using isn't working. I don't know if it's because pokered has been updated since the article was written, but it says that only a few lines of code are necessary (when other examples of similar code are much longer).
Based on the Warden's Gold Teeth script (FuschiaHouse2.asm), I may need to use the jr nz command, but if I do, how do I know what to call the label? Does it even matter? There are some numerical labels and I don't want to repeat one someplace else and not know it. I'm using the Route 1 potion sample guy as an example as well, and I want to make sure any new text sets I use don't overlap others or otherwise cause problems within my new scripts.
So I figured out some more pieces and can receive the item from the NPC! However, it doesn't display all the text I have set up. I have the script file followed by the text file below. What's it missing?
Spoiler:
VermilionCityScript: ; 197a1 (6:57a1)
call EnableAutoTextBoxDrawing
ld hl, wd126
bit 6, [hl]
res 6, [hl]
push hl
call nz, VermilionCityScript_197cb
pop hl
bit 5, [hl]
res 5, [hl]
call nz, VermilionCityScript_197c0
ld hl, VermilionCityScriptPointers
ld a, [wVermilionCityCurScript]
jp CallFunctionInTable
VermilionCityScript_197c0: ; 197c0 (6:57c0)
call Random
ld a, [$ffd4]
and $e
ld [wFirstLockTrashCanIndex], a
ret
VermilionCityScript_197cb: ; 197cb (6:57cb)
CheckEventHL EVENT_SS_ANNE_LEFT
ret z
CheckEventReuseHL EVENT_WALKED_PAST_GUARD_AFTER_SS_ANNE_LEFT
SetEventReuseHL EVENT_WALKED_PAST_GUARD_AFTER_SS_ANNE_LEFT
ret nz
ld a, $2
ld [wVermilionCityCurScript], a
ret
VermilionCityScript0: ; 197e6 (6:57e6)
ld a, [wSpriteStateData1 + 9]
and a ; cp SPRITE_FACING_DOWN
ret nz
ld hl, CoordsData_19823
call ArePlayerCoordsInArray
ret nc
xor a
ld [hJoyHeld], a
ld [wcf0d], a
ld a, $3
ld [hSpriteIndexOrTextID], a
call DisplayTextID
CheckEvent EVENT_SS_ANNE_LEFT
jr nz, .asm_19810
ld b, S_S__TICKET
predef GetQuantityOfItemInBag
ld a, b
and a
ret nz
.asm_19810
ld a, D_UP
ld [wSimulatedJoypadStatesEnd], a
ld a, $1
ld [wSimulatedJoypadStatesIndex], a
call StartSimulatingJoypadStates
ld a, $1
ld [wVermilionCityCurScript], a
ret
CoordsData_19823: ; 19823 (6:5823)
db $1e,$12
db $ff
VermilionCityScript4: ; 19826 (6:5826)
ld hl, CoordsData_19823
call ArePlayerCoordsInArray
ret c
ld a, $0
ld [wVermilionCityCurScript], a
ret
VermilionCityScript2: ; 19833 (6:5833)
ld a, $ff
ld [wJoyIgnore], a
ld a, D_UP
ld [wSimulatedJoypadStatesEnd], a
ld [wSimulatedJoypadStatesEnd + 1], a
ld a, 2
ld [wSimulatedJoypadStatesIndex], a
call StartSimulatingJoypadStates
ld a, $3
ld [wVermilionCityCurScript], a
ret
VermilionCityScript3: ; 1984e (6:584e)
ld a, [wSimulatedJoypadStatesIndex]
and a
ret nz
xor a
ld [wJoyIgnore], a
ld [hJoyHeld], a
ld a, $0
ld [wVermilionCityCurScript], a
ret
VermilionCityScript1: ; 1985f (6:585f)
ld a, [wSimulatedJoypadStatesIndex]
and a
ret nz
ld c, 10
call DelayFrames
ld a, $0
ld [wVermilionCityCurScript], a
ret
Could you be more specific about which is the script that doesn't work? I'm not sure what I should be looking at since you listed the whole viridian city script and text files.
Quote:
Based on the Warden's Gold Teeth script (FuschiaHouse2.asm), I may need to use the jr nz command, but if I do, how do I know what to call the label? Does it even matter? There are some numerical labels and I don't want to repeat one someplace else and not know it. I'm using the Route 1 potion sample guy as an example as well, and I want to make sure any new text sets I use don't overlap others or otherwise cause problems within my new scripts.
Local labels are only relevant within the scope of the function they are at, so you can repeat them anywhere else. If you accidentally create a duplicate label inside the same function the build will fail so you'll notice it.
VermilionCityTextDrink:
TX_FAR _VermilionCityTextDrink
db "@"
VermilionCityGotDrink:
TX_FAR _VermilionCityGotDrink
db "@"
VermilionCityFull:
TX_FAR _VermilionCityFull
db "@"
Spoiler:
_VermilionCityText4:: ; a5805 (29:5805)
text "Boy it's hot out!"
line "My #MON is"
cont "working hard!"
para "You look like"
line "you could use a"
cont "drink!"
done
_VermilionCityTextDrink::
text "Still thirsty?"
done
_VermilionCityGotDrink::
text $52, " got"
line "FRESH WATER!"
done
_VermilionCityFull::
text "Not thirsty?"
done
That should be all the stuff I added. I also added sections of something "dw", which I figured was like "write" or something, since all the other scripts had them.
dw defines a 2-byte word or a list of 2-byte words if you separe them with commas. A two-byte word could be a pointer, a 2-byte number or whatever. For example dw VermilionCityText1 defines a 2-byte pointer to VermilionCityText1. Some function will read that word in order to execute the VermilionCityText1 function from the right location.
Anyway, the script looks good. Which is the text you had trouble displaying?
Well, it skips "VermilionText4" entirely, although that should be the first text written.
I think my problem is somewhere with setting and checking the event, as it seems to run the text
like I've engaged the event already, hence skipping down to "VermilionTextFull" or "VermilionTextDrink" (since I've been playing with it). Even though it still awards me an item.
I see! That fixed all the text, but now i have 2 other issues one big, one not so big:
BIG: I must be missing part of the script that keeps the event from resetting when you leave the area. If I leave Vermilion City and come back I can obtain unlimited Fresh Waters.
Not so big: The text automatically skips to the GotDrink message, instead of waiting for a button press. I tried adding "Prompt" to the end of "VermilionCityText4" in the actual text file, but didn't get any results. Small, but I want it to be as perfect as I can. By a stroke of luck, I also figured out how to get the item music to play. So that's solved.
BIG: I must be missing part of the script that keeps the event from resetting when you leave the area. If I leave Vermilion City and come back I can obtain unlimited Fresh Waters.
Where and how did you define EVENT_GOT_DRINK?
Quote:
Not so big: The text automatically skips to the GotDrink message, instead of waiting for a button press.
I'm not sure but it's probably supposed to work that way between PrintText's.
I'm not sure but it's probably supposed to work that way between PrintText's.
I added a bit for it in Event Constants, because pretty much every event had one. I simply put it at the end as "const EVENT_GOT_DRINK", and then added the next digit in hex on the list.
That section turned green, and it's "; A00, (D887, bit 0)". Did I do it wrong or am missing something?
It wouldn't bug me so much if I hadn't directly compared this new script with the Route 1 potion dude's script. I can confirm that it waits for a button press before giving the item.
You cannot use wram space wildly for script flags. There's a reserved area for that. The script flags buffer is a 320-byte area that ends at address D886. Address D887 isn't unused and it's in fact the byte used to store the wild encounter rate of the current map, a value that is updated everytime you enter a new map. You have to either make use of some unused flag (I bet there are a few, but I personally don't know which ones could be unused), remove an existing one from an existing script that you'll no longer want in your hack, or expand the event flags area in memory. This is one of the many advantages that hacking over the pokered dissasembly offers compared to using conventional tools. You can do it by simply replacing line 3056 with ds 321 in wram.asm so that a space of 321 bytes (an extra byte) is reserved. That will give you room for eight more flags (D887 bits 0-7). It will shift everything following that address by one byte, so for example the grass rate that occupied D887 before will now move to D888 and so on. This means that it will break your save, but it shouldn't break anything else unless there's some fixed address in pokered that slipped under the radar, but at this point I don't think so.
There's no easy way to quicly figure out which are used and which aren't. I'd just expand the area, probably by 10+ bytes at once. It's going to be better in the long run if you are planning on adding more scripts, more trainers, more items, or whatever thing that requires a flag.
You can do it by simply replacing line 3056 with ds 321 in wram.asm so that a space of 321 bytes (an extra byte) is reserved. That will give you room for eight more flags (D887 bits 0-7). It will shift everything following that address by one byte, so for example the grass rate that occupied D887 before will now move to D888 and so on. This means that it will break your save, but it shouldn't break anything else unless there's some fixed address in pokered that slipped under the radar, but at this point I don't think so.
So I could add more than just one byte to this area by changing line 3056 to some number higher than 321? For example something like "ds 323", and should add 24 flags??
If it's not too complicated..could you explain how that works? Everything located after that byte simply gets moved down (or up or whatever), and leaves me some more useable space for flags. But if there's a limited amount of memory for everything after to move to, when do I need to stop expanding at?
Flags are bits, so every byte you add, you get 8 more flags. So yes, you get 24 additional flags in that case.
Yes, everything located after the bytes you add simply gets moved down, and all the references do as well. So, for example, if D8A4 got moved down, say, to D8A9, then any reference in the code to address D8A4 would start referring to D8A9. That's possible because stuff is labeled in the disassembly instead of being hardcoded addresses. D8A4 ins't actually "D8A4", but "wEnemyMons".
WRAM goes from C000 to DFFF. DF00-DFFF is reserved for stack so these cannot be used for anything else. But addresses from DEE2 to DEFF are currently unused in Pokemon/Red blue so you have the possibility of easily expanding the event flags buffer up to 29 bytes (DEFF-DEE2).
I'm trying to write a script that has an Oak Aide give the player character the Starter that didn't get chosen inside of the Cerulean Pokémon Center. Basically, what I'm aiming to do is the following:
Upon entering Cerulean City, insert a phone call requesting a meeting with the Oak Aide in the Pokémon Center (that much I've already mastered);
Keep the guard standing in front of the door of the burglarized house in Cerulean City until the unchosen Starter is picked up or the player character meets with Bill on Cerulean Cape, whichever comes last;
Have the Oak Aide tell the player character about the situation that caused the unchosen Starter to fall into his hands;
Have him give the unchosen Starter to the player character promptly if there are five or less Pokémon in the player's party, then give some parting words, walk away, and disappear; and
Keep him around with an instruction to the player character to make some room for the unchosen Starter if there are six Pokémon in the player's party.
As I experiment with hacking Pokémon Red/Green/Blue, I've already mastered several things, including the insertion of the female player character and the aforementioned phone calls, but I still have a lot to learn; I'm also thinking of giving the player the opportunity to acquire all three of the Starters in-game without trading, among other things.
__________________
I may be more of a Genwunner, but I still host a Gen VI fansite dedicated to Gen VI walkthroughs and game scripts among other things Gen VI: http://pokemongen6.shoutwiki.com
Work-in-progress, but feel free to contribute!
Since I am far from the foremost authority on hacking the disassembly, I can't really give much in the way of detailed instructions. However, based on what I've gathered over the course of this thread I can make some suggestions:
Definitely make it a point to expand your WRAM if you plan to add a lot of scripts and flags. Screwed up the first test save, but as stated above, is very much worth it.
Consider other scripts that already exist in game that are similar in some aspect to what you're aiming to do. It will give you a "template" of sorts to start from. Once you've experimented with those "templates", you can bring more specific questions here.
Here's some I would look at specifically:
The Lapras guy in Silph
Squirtle girl from Yellow
The Rival choosing a starter
OK, I couldn't find the script with the Squirtle girl from Yellow (and by the way, she's not just any girl, she's Officer Jenny), but I was suggested a similar script from Celadon involving the Eevee Poke Ball.
__________________
I may be more of a Genwunner, but I still host a Gen VI fansite dedicated to Gen VI walkthroughs and game scripts among other things Gen VI: http://pokemongen6.shoutwiki.com
Work-in-progress, but feel free to contribute!