diff options
Diffstat (limited to 'Triple-layer-metatiles.md')
-rw-r--r-- | Triple-layer-metatiles.md | 110 |
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. |