If you are still using the old URL (datacrystal.romhacking.net), please update your bookmarks! The old URL may stop working soon.
The current URL is datacrystal.tcrf.net.
The current URL is datacrystal.tcrf.net.
Pokémon Red and Blue/Notes
Jump to navigation
Jump to search
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% RGBY Map Headers & Stuff That Goes With It Version 1.5 -Feel free to distribute this document and/or edit it. -Try and credit people you get info from and/or write how you updated. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Things that need adding: ------------------------ More information about tilesets, and info about what sprites get loaded for which maps. Updates: -------- v1.5.1 By Sawakita: Fixed Tileset Header, completely (including last byte: Animation Flag) v1.5 By phire: Completed Tileset Header, except for that last byte. v1.4 Complete object data info with details about picture id. v1.3 Edit by Cartmic to include almost completed tileset header information and Hat's further clarification on what the X/Y Movement of the Connection means. v1.2: By ubitux: Add some information about connections and distinction between entities (People/Trainers/Items) v1.11: Typo fixed by Hat: "01 = North" changed to "01 = East". Thanks to IIMarckus for pointing that out. v1.1: By Hat, minor improvements. v1.0: Original version typed up by Hat. Main Credits (Structure Information): ------------------------------------- [Xeon] Wrote some stuff about Map Headers and Object Data. Which this document expands upon, a bit. [F-Zero] & [Tauwasser] Wrote a document (in German) explaining how GSC connection data is stored. RGBY connection data is stored almost the same way, it turns out, so that helped a great deal. All that is really different is the values you add the amount of blocks to. ............................................................................... Notes: R/B Pointers to Map Headers: 0x01AE R/B Map Header Banks: 0xC23D R/B Pointer to Tileset Headers: 0xC767 Maximum tileset size in VRAM: 6 rows of 16 tiles (9000-95FF) ............................................................................... =============================================================================== Tileset Header Structure (Almost complete) =============================================================================== 12 bytes per header... Format: ~~~~~~~ [1 BYTE: Bank No. of Blocks/Tiles] [2 BYTES: Pointer to Blocks] [2 BYTES: Pointer to Tiles] [2 BYTES: Pointer to Collision Data] [3 BYTES: Upto 3 'talking over tiles' tile numbers, FF if unused.] [1 BYTE: Grass Tile or FF if unused] [1 BYTE: Animation Flag] Blocks: ~~~~~~~ Maps are made up of 4x4 tile blocks. Collision Data: ~~~~~~~~~~~~~~~ This is a pointer to a list of tile numbers which the player can walk over, Terminated with a FF byte. Talking over tiles: ~~~~~~~~~~~~~~~~~~~ These are tiles which allow the player to talk to a person on the other side, such as the counters in the Pokemon Centers or Pokemarts. Since the player snaps to a 2x2 tile grid you only need list the tile number of the lower left tile of the group of 4 tiles in front of the player. Each tileset can have upto 3 talking over tiles. Use FF instead if they aren't used. Animation Flag: ~~~~~~~~~~~~~~~~~~~ This byte defines whether tileset has animated tiles. There are three possible states: byte = 0: no animated tiles bit0 = 1: tile number 0x14 (2nd row, 5th column) is water animation (waving left and right). This animation edits the tile. bit0 = 0 & byte!=0: is like 0x01, but also has flower's animation (tile number 0x03, i.e. first row, 4th column). Flower's animation doesn't edit the tile, but overwrites it with tiles stored sequentially at address 0x1F19,0x1F29 and 0x1F39, respectively. =============================================================================== Map Header Structure =============================================================================== Explanation: ~~~~~~~~~~~~ This contains all the data (pointers count as data) to build the map. Format: ~~~~~~~ #1: [Tileset Number] #2: [(Y Size) Map Height] #3: [(X Size) Map Width] #4-5: [*2 Bytes*: Pointer to Map] #6-7: [*2 Bytes*: Pointer to Maps Text Pointers] #8-9: [*2 Bytes*: Pointer to Maps "Script"] #10: [Connection Byte] ?: [*11 Bytes per Connection*, No connections? Straight to "Object Data"!] Last: [*2 Bytes*: Pointer to Object Data] =============================================================================== 1) Tileset Numbers =============================================================================== The tileset descriptions are copied from a document compiled by Cartmic, called "Pokemon Red Documents", which may help you with other stuff too. Unchanged R/B Locations/Tileset No./Tileset Descriptions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C7BE; 00: "Outside" C7CA; 01: "Ash's House (#1)" C7D6; 02: "Pokemon Center (#1)" C7E2; 03: "Viridian Forest" C7EE; 04: "Ash's House (#2)" C7FA; 05: "Gym (#1)" C806; 06: "Pokemon Center (#2)" C812; 07: "Gym (#2)" C81E; 08: "House" C82A; 09: "Museum (#1)" C836; 0A: "Museum (#2)" C842; 0B: "Underground Path" C84E; 0C: "Museum (#3)" C85A; 0D: "S.S. Anne" C866; 0E: "Vermilion Port" C872; 0F: "Pokemon Cemetery" C87E; 10: "Silph Co." C88A; 11: "Cave" C896; 12: "Celadon Mart" C8A2; 13: "Game Freak HQ" C8AE; 14: "Lab" C8BA; 15: "Bike Shop/Cable Center" C8C6; 16: "Cinnabar Mansion/Power Plant etc" C8D2; 17: "Indigo Plateau" NOTE: As you can see there's multiple copies of some tileset headers. They are literally copies, you only need 1 copy, but you will need to make sure all maps using that tileset are set to using that tileset number, then you can use the free space for more tilesets. =============================================================================== 2 & 3) Map Height (Y) & Width (X) =============================================================================== Exactly that, the amount of blocks high and wide the map data is. =============================================================================== 4 & 5) Map Data Pointer =============================================================================== You can use the GoldMap engine for hacking map data quite easily. The map you walk around on and stuff is stored as block indexes. A single block consists of 4*4 tiles. =============================================================================== 6 & 7) Pointer to Maps Text Pointers =============================================================================== 2 byte pointers to text that is used on that map. =============================================================================== 8 & 9) Pointer to Maps "Script" =============================================================================== ASM used on that map, chances are if there's something on a map you can't find elsewhere you might easily be able to find it here, using a hex search function. You can find things like XY positions of Poke Balls and 1-time only Pokemon. =============================================================================== 10) Connection Byte =============================================================================== Note: ~~~~~ If this value is 00h it is immediately followed by the Object Data Pointer, no gap. Repeated list: Connection Byte: 00 = No Connections 01 = East 02 = West 03 = West + East 04 = South 05 = South + East 06 = South + West 07 = South + West + East 08 = North 09 = North + East 0A = North + West 0B = North + West + East 0C = North + South 0D = North + South + East 0E = North + South + West 0F = North + South + West + East Connections can be obtained with binary masks: 1. connect_byte & (1 << 3) -> North 2. connect_byte & (1 << 2) -> South 3. connect_byte & (1 << 1) -> West 4. connect_byte & (1 << 0) -> East You have to respect this order to get the correct list. =============================================================================== ?) Connection Data (0-44 bytes, explained in more depth: further down) =============================================================================== =============================================================================== Last) Object Data Pointer =============================================================================== The last thing in the Map Header. It points to a bunch of certain stuff that is stored in similar structures. Object Data is discussed at the end of this document. ............................................................................... =============================================================================== *** Hacking Connections *** This will certainly require planning, with no background distractions. Unless a editor gets built that can hack the connections for RGBY. =============================================================================== Explanation: ~~~~~~~~~~~~ The "Connection Byte" determines how many connections are in this space, including none at all. X/Y_Movement_Of_Connection ~~~~~~~~~~~~~~~~~~~~~~~~~~ A X movement is how many map blocks there are to the left of one of your north/south connections. A Y movement is how many map blocks there are above your west/east connection. Structure: ~~~~~~~~~~ #1: [Map Index of Connected Map] #2-3: [Pointer to "Connection Strip"s Upperleft Block (Connected Map)] #4-5: [Pointer to "Connection Strip"s Upperleft Block (Current Map)] #6: ["Bigness"] #7: [Map Width] #8: [Y alignment] #9: [X alignment] #10-11: [Window] PKMN Red Example -- Saffron City (Header: 0x509A4) Diagram: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Saffrons need-to-know stats: Block Height (Y): 12 Block Width (X): 14 Connection Byte: 0F (North + South + West + East) - - - - + = current maps border blocks ++++++++NNNNNNNNNN++++++++ ++++++++NNNNNNNNNN++++++++ ++++++++NNNNNNNNNN++++++++ +++####################+++ +++####################+++ +++####### My #########+++ +++####################+++ WWW####### Name's #####EEE WWW####################EEE WWW###### Saffron #####EEE WWW####################EEE WWW###### City! #######EEE WWW####################EEE WWW####################EEE WWW####################EEE WWW####################EEE +++####################+++ +++####################+++ +++####################+++ +++####################+++ +++####################+++ ++++++++SSSSSSSSSS++++++++ ++++++++SSSSSSSSSS++++++++ ++++++++SSSSSSSSSS++++++++ Connection to Route 5 (to the North) *Y: 12 *X: 0A *X_Movement_of_Connection Strip = 5 Map Index: 10 Connection Strip: 4668 Where Connected: C6F0 (C6EB + 5) "Bigness": 0A Width: 0A Y alignment: 23 (12 * 2 - 1) X alignment: F6 (5 * -2) Window: C809 (C6E9 + (12 * (0A + 6))) Connection to Route 6 (to the South) *Y: 12 *X: 0A *X_Movement_of_Connection Strip = 5 Map Index: 11 Connection Strip: 4079 Where Connected: C912 (C6EB + ((12 + 3) * (14 + 6)) + 5) "Bigness": 0A Width: 0A Y alignment: 00 X alignment: F6 (5 * -2) Window: C6F9 (C6EF + 0A) Connection to Route 7 (to the West) *Y: 09 *X: 0A *Y_Movement_of_Connection Strip = 4 Map Index: 12 Connection Strip: 4058 Where Connected: C79E (C6E8 + (14 + 6) * (4 + 3)) "Bigness": 09 Width: 0A Y alignment: F8 (4 * -2) X alignment: 13 ((0A * 2) - 1) Window: C702 (C6EE + (0A * 2)) Connection to Route 8 (to the East) *Y: 09 *X: 1E *Y_Movement_of_Connection Strip = 4 Map Index: 13 Connection Strip: 41C6 Where Connected: C7B5 (C6E5 + (14 + 6) * (4 + 4)) "Bigness": 09 Width: 1E Y alignment: F8 (4 * -2) X alignment: 00 Window: C70D (C6EF + 1E) =============================================================================== #1 : Map Indexes =============================================================================== Not included! Download UltraMap, the text file known as "RedEnglish.ini" contains all the Map Indexes in decimal for R/B, which you'll obviously need to convert to hex. =============================================================================== #2-#3 : "Connection Strip" Location =============================================================================== The "connection strip" pointer -- points to the area of the connected map that is visible when standing before you even enter it. Points to the upperleft block of the "connection strip". * connection strip is always 3 blocks wide (E/W connection) 3 blocks high (N/S connection) =============================================================================== #4-#5 : Current Map Position =============================================================================== This points to the part of the current map (further up in RAM) that the connection strips upperleft block is placed on the current map. ____________________ Connection | Direction | Formula ___________|_______ North: C6EB + X_Movement_of_Connection Strip South: C6EB + (Height of Map + 3) * (Width of Map + 6) + X_Movement_of_Connection Strip West: C6E8 + (Width of Map + 6) * (Y_Movement_of_"Connection Strip" + 3) East: C6E5 + (Width of Map + 6) * (Y_Movement_of_"Connection Strip" + 4) =============================================================================== #6 : Map "Bigness" =============================================================================== North/South Connection = Connected Maps Width East/West Connection = Connected Maps Height =============================================================================== #7 : Map Width =============================================================================== The width of the connected map. =============================================================================== #8 : Y alignment =============================================================================== Relative Y-position of player after entering connected map. ____________________ Connection | Direction | Formula ___________|_______ North: (Height_of_connected_map * 2) - 1 South: 0 West/East: (Y_movement_of_connection_strip_in_blocks * -2) =============================================================================== #9 : X alignment =============================================================================== Relative X-Position of player after entering connected map. ____________________ Connection | Direction | Formula ___________|_______ North/South: (X_movement_of_connection_strip_in_blocks * -2) West: (Width_of_connected_map * 2) - 1 East: 0 =============================================================================== #10-#11 : Window =============================================================================== Position of the upper left block after entering the Map. ____________________ Connection | Direction | Formula ___________|_______ Above: C6E9h + Height_of_connected_map * (Width_of_connected_map + 6) South/East: C6EFh + Width_of_connected_map West: C6EEh + 2 * Width_of_connected_map ............................................................................... =============================================================================== Object Data: General Structure =============================================================================== Object Data =========== [Maps Border Tile] [Number of Warps][Warp Data] [Number of Signs][Sign Data] [Number of People/Trainers/Items] [People Data] [Trainer Data] [Item Data] [Warp-To Data] Warps: ------ [Y position][X position][Warp-To Point][Warp-To Map] Signposts: ---------- [Y position][X position][Text String Number] Normal People: -------------- [Picture Number][Y position + 4][X position + 4] [Movement 1][Movement 2][Text String Number] Trainers: --------- [Picture Number][Y position + 4][X position + 4] [Movement 1][Movement 2][Text String Number] [Trainer Type][Pokemon Set] Items: --------------------- [Picture Number][Y position + 4][X position + 4] [Movement 1][Movement 2][Text String Number] [Item Number] Warp-To Points -------------- [*2 Bytes*: Event Displacement][Y position][X position] In order to distinguish People, Trainers and Items, you must use the Text String Number: text_str_n & (1 << 6) -> Trainer (2 more byte to read, the trainer type and the pokémon set) text_str_n & (1 << 7) -> Item (just one more byte to read, the item id) Picture Numbers ~~~~~~~~~~~~~~~ In order to get the ROM address of the tile relative to an entity (people/trainers/items), here is the formula to focus on the entity information: 5 * 0x4000 + (0x7b27 + 4 * (picture_id - 1)) % 0x4000 Then the entity information is stored according to this: [*2 Bytes*: Tile address][Total size of tile data][Bank id] So then, address = bank_id * 0x4000 + tile_addr % 0x4000 Event Displacement Formula: ~~~~~~~~~~~~~~~~~~~~~~~~~~~ C6EF + (Map width) + (Map width + 6) * (rows above) + (X movement) ###############################################################################