- 1,315
- Posts
- 17
- Years
- Seen Jun 11, 2024
i haven't a real solution but here(https://www.datacrystal.org/wiki/Pokemon_Gold:ROM_map#Maps ) you should find something useful
for connections i only know a doc for r/b/y versionSpoiler:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
RGBY Map Headers & Stuff That Goes With It
Version 1.3
-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.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 (-10 for some reason)]
[2 BYTES: Pointer to Tiles]
[7 BYTES:
00 00 00 00 00 00 00
|| || || || || || ||
|| || || || || || __ Amount of animated tiles.
|| || || || || _____ x,y location on tileset of 'Grass' tile
|| || || || ________ X,Y Location of 'talking over tiles': East/West
|| || || ___________ X,Y Location of 'talking over tiles': North/South 1
|| || ______________ X,Y Location of 'talking over tiles': North/south 2
|| _________________ Colision Indication - Pointer?
____________________ Colision Indication - Pointer?]
===============================================================================
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][Unknown][Bank id]
So then, address = bank_id * 0x4000 + tile_addr % 0x4000
Event Displacement Formula:
~~~~~~~~~~~~~~~~~~~~~~~~~~~
C6E3 + ((Map width + 8) * (rows above + 1)) + (X movement + 4)
###############################################################################
Thanks for the document.
Also, I have another question. How do I view level G/S/C level scripts in PKSV? Also how do I find out the offsets?