summaryrefslogtreecommitdiff
path: root/Triple-layer-metatiles.md
diff options
context:
space:
mode:
Diffstat (limited to 'Triple-layer-metatiles.md')
-rw-r--r--Triple-layer-metatiles.md110
1 files changed, 110 insertions, 0 deletions
diff --git a/Triple-layer-metatiles.md b/Triple-layer-metatiles.md
new file mode 100644
index 0000000..4ff4cd9
--- /dev/null
+++ b/Triple-layer-metatiles.md
@@ -0,0 +1,110 @@
+**--UPDATE THIS WIKI PAGE TO USE TRUE TRIPLE LAYER METATILES IN PORYMAP, AND MENTION PORYMAP--**
+
+Overworld maps are built out of blocks of tiles. Those blocks get placed in three overlapping layers, but only two layers can be used at a time. [A popular binary hack](https://www.pokecommunity.com/showthread.php?t=352725) allows triple-layer blocks, using all three layers at once by combining two blocks: one for the bottom and middle layers, and a subsequent "burner" block for the top layer.
+
+To allow this in pokeemerald, just edit [src/field_camera.c](../blob/master/src/field_camera.c):
+
+```diff
+ static void DrawMetatile(s32 metatileLayerType, u16 *metatiles, u16 offset)
+ {
+ switch (metatileLayerType)
+ {
++ case 3: // LAYER_TYPE_TRIPLE
++ // Draw metatile's bottom layer to the bottom background layer.
++ gBGTilemapBuffers3[offset] = metatiles[0];
++ gBGTilemapBuffers3[offset + 1] = metatiles[1];
++ gBGTilemapBuffers3[offset + 0x20] = metatiles[2];
++ gBGTilemapBuffers3[offset + 0x21] = metatiles[3];
++
++ // Draw metatile's top layer to the middle background layer.
++ gBGTilemapBuffers1[offset] = metatiles[4];
++ gBGTilemapBuffers1[offset + 1] = metatiles[5];
++ gBGTilemapBuffers1[offset + 0x20] = metatiles[6];
++ gBGTilemapBuffers1[offset + 0x21] = metatiles[7];
++
++ // Draw next metatile's top layer to the top background layer
++ gBGTilemapBuffers2[offset] = metatiles[12];
++ gBGTilemapBuffers2[offset + 1] = metatiles[13];
++ gBGTilemapBuffers2[offset + 0x20] = metatiles[14];
++ gBGTilemapBuffers2[offset + 0x21] = metatiles[15];
++ break;
+ case 2: // LAYER_TYPE_
+ // Draw metatile's bottom layer to the bottom background layer.
+ gBGTilemapBuffers3[offset] = metatiles[0];
+ gBGTilemapBuffers3[offset + 1] = metatiles[1];
+ gBGTilemapBuffers3[offset + 0x20] = metatiles[2];
+ gBGTilemapBuffers3[offset + 0x21] = metatiles[3];
+
+ // Draw transparent tiles to the middle background layer.
+ gBGTilemapBuffers1[offset] = 0;
+ gBGTilemapBuffers1[offset + 1] = 0;
+ gBGTilemapBuffers1[offset + 0x20] = 0;
+ gBGTilemapBuffers1[offset + 0x21] = 0;
+
+ // Draw metatile's top layer to the top background layer.
+ gBGTilemapBuffers2[offset] = metatiles[4];
+ gBGTilemapBuffers2[offset + 1] = metatiles[5];
+ gBGTilemapBuffers2[offset + 0x20] = metatiles[6];
+ gBGTilemapBuffers2[offset + 0x21] = metatiles[7];
+ break;
+ case 1: // LAYER_TYPE_COVERED_BY_OBJECTS
+ // Draw metatile's bottom layer to the bottom background layer.
+ gBGTilemapBuffers3[offset] = metatiles[0];
+ gBGTilemapBuffers3[offset + 1] = metatiles[1];
+ gBGTilemapBuffers3[offset + 0x20] = metatiles[2];
+ gBGTilemapBuffers3[offset + 0x21] = metatiles[3];
+
+ // Draw metatile's top layer to the middle background layer.
+ gBGTilemapBuffers1[offset] = metatiles[4];
+ gBGTilemapBuffers1[offset + 1] = metatiles[5];
+ gBGTilemapBuffers1[offset + 0x20] = metatiles[6];
+ gBGTilemapBuffers1[offset + 0x21] = metatiles[7];
+
+ // Draw transparent tiles to the top background layer.
+ gBGTilemapBuffers2[offset] = 0;
+ gBGTilemapBuffers2[offset + 1] = 0;
+ gBGTilemapBuffers2[offset + 0x20] = 0;
+ gBGTilemapBuffers2[offset + 0x21] = 0;
+ break;
+ case 0: // LAYER_TYPE_NORMAL
+ // Draw garbage to the bottom background layer.
+ gBGTilemapBuffers3[offset] = 0x3014;
+ gBGTilemapBuffers3[offset + 1] = 0x3014;
+ gBGTilemapBuffers3[offset + 0x20] = 0x3014;
+ gBGTilemapBuffers3[offset + 0x21] = 0x3014;
+
+ // Draw metatile's bottom layer to the middle background layer.
+ gBGTilemapBuffers1[offset] = metatiles[0];
+ gBGTilemapBuffers1[offset + 1] = metatiles[1];
+ gBGTilemapBuffers1[offset + 0x20] = metatiles[2];
+ gBGTilemapBuffers1[offset + 0x21] = metatiles[3];
+
+ // Draw metatile's top layer to the top background layer, which covers event object sprites.
+ gBGTilemapBuffers2[offset] = metatiles[4];
+ gBGTilemapBuffers2[offset + 1] = metatiles[5];
+ gBGTilemapBuffers2[offset + 0x20] = metatiles[6];
+ gBGTilemapBuffers2[offset + 0x21] = metatiles[7];
+ break;
+ }
+ schedule_bg_copy_tilemap_to_vram(1);
+ schedule_bg_copy_tilemap_to_vram(2);
+ schedule_bg_copy_tilemap_to_vram(3);
+ }
+```
+
+This is slightly different from the binary technique. The topmost third layer comes from the "burner" block's *top* layer, not its *bottom* layer. That means the burner block's bottom layer can still be used. So it's not really "wasted" because it can still be useful on its own.
+
+For example, if the first block has a bottom layer of water and a top layer of shoreline, and the burner block has a bottom layer of grass and a top layer of tree, then the first block will show the tree above the water and shoreline, while the burner block will show the tree above the grass.
+
+The problem is, [porymap](https://github.com/huderlem/porymap/) doesn't support any layer types besides the default ones: "Normal - Middle/Top", "Covered - Bottom/Middle", and "Split - Bottom/Top". (Their correspondence to the cases in the `DrawMetatile` code should be apparent.) Possible workarounds:
+
+- Keep an eye on [this issue](https://github.com/huderlem/porymap/issues/147) to see if porymap adds support for custom layer types.
+- [Build your own](https://github.com/huderlem/porymap/blob/master/INSTALL.md) copy of porymap, but edit [src/ui/tileseteditor.cpp](https://github.com/huderlem/porymap/blob/master/src/ui/tileseteditor.cpp) to support triple-layer blocks. After the line:
+
+ this->ui->comboBox_layerType->addItem("Split - Bottom/Top", 2);
+
+ just add another line:
+
+ this->ui->comboBox_layerType->addItem("Triple - Bottom/Middle/Top", 3);
+
+- Hex-edit the metatile_attributes.bin files to use layer type 3. This is cumbersome compared to using porymap, but it's not a complex format. Every two bytes correspond to a block: the first byte is its behavior value, the second byte is its layer type but shifted to the first nybble. So Normal is $00, Covered is $10, and Split is $20. Just find the pair of bytes for your triple-layer block (the first one, not the burner one) and change its layer type byte to $30.