You are not logged in.
http://hax.iimarck.us/files/rbheaders.txt
Last edited by IIMarckus (2011-06-28 01:09:06)
I'm really sorry to bump this thread but after trying to manage by myself I haven't solved a problem.. I don't understand fully what you say in this part:
Quote:
Warp-To Points
--------------
[*2 Bytes*: Event Displacement][Y position][X position]Event Displacement Formula:
~~~~~~~~~~~~~~~~~~~~~~~~~~~
C6E3 + ((Map width + 8) * (rows above + 1)) + (X movement + 4)
1) When you say "warp-to points" do you mean the place where you are warped exiting from a door?
2) Is map width meant to be calculated in blocks (2x2 tiles) or in tiles (example: pallet town's width is 0x0A in blocks, but 0x14 in tiles)?
3)What do you mean with "X movement"?
4)Looking in the hex, the event displacement bytes look switched, or am i looking the wrong address? Here they are (starting offset 0x182f1):
Hiro's house...........1B C7 05 05
Rival's house..........1F C7 05 0D
Lab......................4F C7 0B 0C
first two bytes are event displacement formula, while the two following are Y and X position, isn't it?
I have troubles when exiting from two houses, while the other house's warp works fine..
Offline
Here's a little update on that:
================
v1.1.2: 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.
================================================================
Tileset Header Structure
===============================================================================
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?
===============================================================================
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.
=====================
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.
Offline
I try to explain what is wrong (I use the lab in Pallet town as example)
[map width = 0x0A;
rows above lab door = 0x0B;
X movement = 0]
The formula is
Quote:
0xC6E3 + ((Map width + 8) * (rows above + 1)) + (X movement + 4)
.
So i do:
Quote:
0xC6E3 + ((0x0A + 8) * (0x0B + 1)) + ([here I put zero] + 4) = 0xC7BF
instead of "4F C7" that I think is bigendian for C74F. I really don't understand what's wrong..
Offline
Ah, but that 4F C7 is C7 BF! It's a pointer
I don't think so. what's the sense of a pointer, since the task of "event displacement" is to define how tiles and events are displaced when you re-enter the map from a warp (a door) and not from a border.
Quote:
which you can learn about here
Do I look such a noob? I clearly know what a pointer is and how it works, thanks for concern...
[...going to light a candle to invoke IIMarkus...]
EDIT: sorry, I become ill-mannered sometimes..
Offline
Don't worry about it, I was being an idiot when I posted that.
Anyways, I have my own question regarding bytes 6-7 of the MapHeader. "Pointers to Maps Text Pointers" What text, exactly? In RedMap, those two bytes are referred to as "ObjectScriptPointers".
In fact, RedMap mentions one byte that isn't mentioned here, one at the end of the MapHeaders. It's the Border Block.
Offline
Don't worry about it, I was being an idiot when I posted that.
Anyways, I have my own question regarding bytes 6-7 of the MapHeader. "Pointers to Maps Text Pointers" What text, exactly? In RedMap, those two bytes are referred to as "ObjectScriptPointers".
Let’s look at an existing map, Erika’s gym. Header is at 488FE. Bytes 6–7 point to 489A6. Going there, we find a lot of pointers:
48A11
48A81
etc etc. Eleven pointers total. (The list isn’t terminated, so your event count had better match up. 0220 is where other data starts.)
So what’s at 48A11? Well, text. But it starts with 08, which signals the text engine to start an ASM routine:
ld a,[$D77C]
bit 1,a
jr z,.ErikaBattle@
bit 0,a
jr nz,.ErikaLater@
call z,$4963
call $30B6
jr .end@
.ErikaLater@
ld hl,ErikaLaterText
call PrintText
jr .end@
.ErikaBattle@
ld hl,ErikaIntroText
call PrintText
ld hl,$D72D
set 6,[hl]
set 7,[hl]
ld hl,ErikaDefeatText
ld de,ErikaDefeatText;
call $3354
ld a,[$FF8C]
ld [$CF13],a ;
call PrepareTrainer
call $32D7
ld a,4 ; Monsters will use Mega Drain
ld [$D05C],a
ld a,3
ld [$D5FF],a
ld [$DA39],a
.end@ jp $24D7
Those labels in the code point to more text, by the way. It’s obvious by following the pointers that this block of code is Erika’s script, and (among other things) prints text and starts a battle with a trainer named Erika who uses Mega Drain. Suffice it to say that the rest of the Object Script Pointers determine the behavior of the rest of the trainers in the gym, and they always point to text data (which may of course call an ASM subroutine, as all of these do).
Note that this is not as simple as “one person, one pointer”: the last three pointers in ObjectScriptPointers are for the Rainbow Badge text, the “got Mega Drain” text, and the “bag is full, no Mega Drain” text. There’s more to it but it’s 11PM and I have work tomorrow… you can figure it out on your own. (But feel free to ask if anything is still unclear.)
I try to explain what is wrong (I use the lab in Pallet town as example)
[map width = 0x0A;
rows above lab door = 0x0B;
X movement = 0]The formula is
0xC6E3 + ((Map width + 8) * (rows above + 1)) + (X movement + 4)
.
So i do:0xC6E3 + ((0x0A + 8) * (0x0B + 1)) + ([here I put zero] + 4) = 0xC7BF
instead of "4F C7" that I think is bigendian for C74F. I really don't understand what's wrong..
I think you have that reversed… here 4FC7 is little‐endian for C74F, I believe. I think it points to the map data in WRAM0 (C000–CFFF).
Let’s look at an existing map, Erika’s gym. Header is at 488FE. Bytes 6–7 point to 489A6. Going there, we find a lot of pointers:
48A11
48A81
etc etc. Eleven pointers total. (The list isn’t terminated, so your event count had better match up. 0220 is where other data starts.)So what’s at 48A11? Well, text. But it starts with 08, which signals the text engine to start an ASM routine:
ld a,[$D77C]
bit 1,a
jr z,.ErikaBattle@
bit 0,a
jr nz,.ErikaLater@
call z,$4963
call $30B6
jr .end@
.ErikaLater@
ld hl,ErikaLaterText
call PrintText
jr .end@
.ErikaBattle@
ld hl,ErikaIntroText
call PrintText
ld hl,$D72D
set 6,[hl]
set 7,[hl]
ld hl,ErikaDefeatText
ld de,ErikaDefeatText;call $3354
ld a,[$FF8C]
ld [$CF13],a ;
call PrepareTrainer
call $32D7
ld a,4 ; Monsters will use Mega Drain
ld [$D05C],a
ld a,3
ld [$D5FF],a
ld [$DA39],a
.end@ jp $24D7Those labels in the code point to more text, by the way. It’s obvious by following the pointers that this block of code is Erika’s script, and (among other things) prints text and starts a battle with a trainer named Erika who uses Mega Drain. Suffice it to say that the rest of the Object Script Pointers determine the behavior of the rest of the trainers in the gym, and they always point to text data (which may of course call an ASM subroutine, as all of these do).
Note that this is not as simple as “one person, one pointer”: the last three pointers in ObjectScriptPointers are for the Rainbow Badge text, the “got Mega Drain” text, and the “bag is full, no Mega Drain” text. There’s more to it but it’s 11PM and I have work tomorrow… you can figure it out on your own. (But feel free to ask if anything is still unclear.)
:o RedMap is going to be fun
Offline
I was trying to figure out the lab's script, and in the same time I gave a look to the object data in the mapheader.
I've seen that rival'object is defined as a trainer instead of a normal people as I expected (normale people is defined with 6 bytes, while trainer has 2 more bytes that define respectively "trainer type" and "pokemon set").
So I tried to change his "trainer type" (&hE1=rival1) to another one (i put &hCA=bugcatcher, just to say one), and i found out that supposedly nothing really changed.
Eventually I found out where the information of the battle_enemy is stored (it's hardcoded in a subroutine of the "Lab's script"), I edited it and this time it actually worked.
So I was wondering: what actually does that "trainer type" byte do?
Anyone knows something about that?
Offline
My understanding is that on normal trainers, it does exactly what it sounds like. However, Gary is not a "normal" trainer, and his battle is called by a trigger instead of his event. There is really no point in him being a trainer event as far as I know. But like I say on most trainer events, editing those seems to work.
I am not very active on this forum. I only pop in from time to time.
Offline
There is really no point in him being a trainer event as far as I know.
In fact that's what i was trying to understand: why wasting 2 bytes with useless datas? (also considering that the whole rom is so chaotic because of the programmers' will of reducing space used!!).
Anyway you reassured me saying so. I think I'm going to not giving too much importance to those two bytes..
Offline
Wow! I tried modifying the connection data for Cinnabar Island so that the north connection points to Route 5. So far I managed to get it to go there, but once you step out of cinnabar you end up in a zone filled with Route 5's border block. Walking north a while will cause you to come out in Route 5. How do I pull the map down to touch Cinnabar?
Offline
The garbage might be because you need to edit the connection data on route 5 as well to connect to Cinnabar
I am not very active on this forum. I only pop in from time to time.
Offline
This is hard. No matter what I try it doesn't work. I also don't understand the documentation. It's either I change the connection data or add warps to Route 21...
Offline
Well what part of it is confusing you? Perhaps one of us could better explain it
I am not very active on this forum. I only pop in from time to time.
Offline
Basically....all of it? The only thing I've done is trial and error. I think the worst part is:
#2-3: [Pointer to "Connection Strip"s Upperleft Block (Connected Map)]
#4-5: [Pointer to "Connection Strip"s Upperleft Block (Current Map)]
#6: ["Bigness"]
#10-11: [Window]
I don't understand them.
Offline
Basically....all of it? The only thing I've done is trial and error. I think the worst part is:
#2-3: [Pointer to "Connection Strip"s Upperleft Block (Connected Map)]
#4-5: [Pointer to "Connection Strip"s Upperleft Block (Current Map)]
#6: ["Bigness"]
#10-11: [Window]I don't understand them.
#2-3: [Pointer to "Connection Strip"s Upperleft Block (Connected Map)]
Quote:
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)
Open RedMap. go to connected map.
If it is located:
East of current map: move the mouse on the block located on the first row (top-to-bottom), first column(left-to-right);
West of current map: move the mouse on the block located on the first row (top-to-bottom), third column(right-to-left);
South of current map: move the mouse on the block located on the third row (top-to-bottom), first column(left-to-right);
North of current map: move the mouse on the block located on the third row (bottom-to-top), first column(left-to-right);
Then take note of the offset (bottom left of RedMap's window), transform it in a pointer (little-endian) and there it is.
#4-5: [Pointer to "Connection Strip"s Upperleft Block (Current Map)]
Quote:
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 StripWest: C6E8 + (Width of Map + 6) * (Y_Movement_of_"Connection Strip" + 3)
East: C6E5 + (Width of Map + 6) * (Y_Movement_of_"Connection Strip" + 4)
I can't explain better than it is already.
"Y_Movement_of_"Connection Strip" indicates how many blocks the connected map is shifted vertically("0"=connected map aligned to current map; 1=one block shifted to south; ff=one block shifted to north, and so on..)
"X_Movement_of_"Connection Strip" indicates how many blocks the connected map is shifted horizontally("0"=connected map aligned to current map; 1=one block shifted to right; ff=one block shifted to left, and so on..)
#6: ["Bigness"]
Quote:
North/South Connection = Connected Map's Width
East/West Connection = Connected Map's Height
That's it
#10-11: [Window]
Quote:
Position of the upper left block after entering the Map.
Nord: C6E9h + Height_of_connected_map * (Width_of_connected_map + 6)
South/East: C6EFh + Width_of_connected_map
West: C6EEh + 2 * Width_of_connected_map
IDEM
P.S.:
@IIMarckus or Mateo:
Please edit the first post (typo): Connection Byte -> 01 isn't North, it's East
Offline
Quote:
Position of the upper left block after entering the Map.
Nord: C6E9h + Height_of_connected_map * (Width_of_connected_map + 6)
South/East: C6EFh + Width_of_connected_map
West: C6EEh + 2 * Width_of_connected_map
After doing this I get the value C6FB0? That won't fit into two bytes.
Offline
Quote:
Position of the upper left block after entering the Map.
Nord: C6E9h + Height_of_connected_map * (Width_of_connected_map + 6)
South/East: C6EFh + Width_of_connected_map
West: C6EEh + 2 * Width_of_connected_mapAfter doing this I get the value C6FB0? That won't fit into two bytes.
You probably made some calculation error
I use an example to let you understand best.
For example we want to connect a map north of our current map; size of connected map is: 9 height, 10 (=0a in hex) width.
North formula is:
c6e9 + 09*(0a+06) = c6e9+90 = c779
So the value you have to write is c779 (big endian) --->79c7 (little endian).
EDIT: This stuff i wrote is wrong, don't look at it..
Offline
Is there a tutorial of this for G/S/C too ?
I think it's only a part the same.
Offline
After doing this I get the value C6FB0? That won't fit into two bytes.
You probably made some calculation error
I use an example to let you understand best.For example we want to connect a map north of our current map; size of connected map is: 9 height, 10 (=0a in hex) width.
North formula is:
c6e9 + 09*(0a+06) = c6e9+90 = c779So the value you have to write is c779 (big endian) --->79c7 (little endian).
That just messed it up even more.
Offline
I think that, if your map has more than one connection, the connection must be put following a certain order (even though i'm not sure what it is). I think the order is this:
1st- East
2nd- West
3rd- South
4th- North
Anyway, you could tell us your maps' specifics (maps' size, number of connection, type of connections), so that we can help better.
Offline
Cinnibar Header + North Connection Data (I had it in the correct order):
00 09 0A 69 40 81 4A 19 4A 09 10 68 46 EB C6 0A 0A 23 00 F9 C8
Route 5 Header Data:
00 12 0A D2 45 B5 56 B2 56 0C
Offline
Cinnibar Header + North Connection Data (I had it in the correct order):
00 09 0A 69 40 81 4A 19 4A 09 10 68 46 EB C6 0A 0A 23 00 F9 C8
Route 5 Header Data:
00 12 0A D2 45 B5 56 B2 56 0C
Ok.
I get a different window pointer (10th-11th byte in connection data).
The formula is:
C6E9h + Height_of_connected_map * (Width_of_connected_map + 6) = c6e9 + 12*(0a+6) = c6e9 + 120 = c809
Cinnabar header + north connection data:
00 09 0A 69 40 81 4A 19 4A 09 10 68 46 EB C6 0A 0A 23 00 09 C8
Is it possible?
P.S.:
The order of connection I wrote in my previous post is wrong. In fact it's reversed:
1) N
2) S
3) W
4) E
Offline