-
Notifications
You must be signed in to change notification settings - Fork 3
Custom Border Dimensions
Every map in the game is surrounded by a repeating group of metatiles called the border. In Emerald, these borders are always 2x2, while in FireRed/LeafGreen they can have different dimensions.
This tutorial will go over the steps to allow borders with different dimensions to be created in Emerald.
Note that Porymap version ≥ 4.0.0 supports this feature, so after these changes are made you will be able to edit the border dimensions in Porymap like you would for a pokefirered project.
First we will add 2 new fields to struct MapLayout
in include/global.fieldmap.h to hold the width and height of the border.
struct MapLayout
{
/*0x00*/ s32 width;
/*0x04*/ s32 height;
/*0x08*/ u16 *border;
/*0x0c*/ u16 *map;
/*0x10*/ struct Tileset *primaryTileset;
/*0x14*/ struct Tileset *secondaryTileset;
+ u8 borderWidth;
+ u8 borderHeight;
};
Next we need to use these new fields when we're trying to access border data.
In src/fieldmap.c, find the definition of the macro GetBorderBlockAt
and replace it with the version below:
#define GetBorderBlockAt(x, y) ({ \
u16 block; \
s32 xprime; \
s32 yprime; \
\
const struct MapLayout *mapLayout = gMapHeader.mapLayout; \
\
xprime = x - MAP_OFFSET; \
xprime += 8 * mapLayout->borderWidth; \
xprime %= mapLayout->borderWidth; \
\
yprime = y - MAP_OFFSET; \
yprime += 8 * mapLayout->borderHeight; \
yprime %= mapLayout->borderHeight; \
\
block = mapLayout->border[xprime + yprime * mapLayout->borderWidth] | MAPGRID_COLLISION_MASK; \
})
Now we need to specify what the border dimensions are for each map layout. Because Emerald's are all 2x2 by default, this can be done quickly with a find and replace. In data/layouts/layouts.json, make the following substitution.
Find:
"primary_tileset"
Replace:
"border_width": 2,
"border_height": 2,
"primary_tileset"
The tool that converts layouts.json to data needs to know what to do with these fields. Update generate_layout_headers_text
in tools/mapjson/mapjson.cpp.
<< "\t.4byte " << layout["primary_tileset"].string_value() << "\n"
- << "\t.4byte " << layout["secondary_tileset"].string_value() << "\n\n";
+ << "\t.4byte " << layout["secondary_tileset"].string_value() << "\n"
+ << "\t.byte " << layout["border_width"].int_value() << "\n"
+ << "\t.byte " << layout["border_height"].int_value() << "\n"
+ << "\t.2byte 0\n\n";
Note the .2byte 0
is because structs are aligned to 4 byte boundaries. The new border width/height fields are 1 byte each, so we need an additional 2 bytes of padding. This may not be true if you've already made other changes to struct MapLayout
, or if you use different sizes for the new dimension fields.
-
Make sure to
make clean
and rebuild before attempting changes to ensure mapjson and all the map data gets rebuilt with the new map layout. -
If you've opened your project with Porymap before there will be a
porymap.project.cfg
file in your root folder. In that file, setuse_custom_border_size
to1
. -
Open your project with Porymap and you should now be able to change the size of the border with the
Change Dimensions
button while on the Map tab.