Sign Up
Romhack.me connects you to ROM Hackers around the world.
Search all tutorials.
How to use 240 tiles in pokecrystal

How to use 240 tiles in pokecrystal

Category:
Posted By: On July 8, 2017
Comments: 1
Views: 502
0 Ratings

There's already a technique by comet to allow 256-block tilesets. In home/map.asm:LoadMetatiles, you change this:

    ; Set hl to the address of the current metatile data ([TilesetBlocksAddress] + (a) tiles).
    add a
    ld l, a
    ld h, 0
    add hl, hl
    add hl, hl
    add hl, hl


to this:

    ; Set hl to the address of the current metatile data ([TilesetBlocksAddress] + (a) tiles).
    ld l, a
    ld h, 0
    add hl, hl
    add hl, hl
    add hl, hl
    add hl, hl


However, you still have only 192 tiles to compose blocks with. Look at BGB's VRAM viewer:



The bottom 256 tiles are for the tileset. The left ones have IDs $00 to $7F, and the the right ones $80 to $FF.
  • The green area, $C0 to $DF, can be used already just by extending the tileset graphics (gfx/tilesets/##.2bpp.lz) and palette map (tilesets/##_palette_map.asm).
  • The red area, $E0 to $FF, is unused.
  • The blue area, $60 to $6F, has only a few tiles that you need, all of which can be moved to the unused font tiles.
  • The yellow area, $70 to $7F, is needed for the text box frame and the pop-up location name sign.

    I'll explain how to free up the blue and red areas, allowing 48 more tiles for a total of 240.

    Step 1: Edit home.map.asm:LoadTileset.

    Change this:

        ld hl, wDecompressScratch
        ld de, VTiles2
        ld bc, $60 tiles
        call CopyBytes


    to this:

        ld hl, wDecompressScratch
        ld de, VTiles2
        ld bc, $70 tiles
        call CopyBytes


    and this:

        ld hl, w6_d600
        ld de, VTiles2
        ld bc, $60 tiles
        call CopyBytes


    to this:

        ld hl, wDecompressScratch + $70 tiles
        ld de, VTiles2
        ld bc, $80 tiles
        call CopyBytes


    Now the tileset graphics will get loaded into the blue and red areas too.

    Step 2: Edit tilesets/##_metatiles.bin.

    The tileset graphics are being loaded differently now. Tiles $80–$8F have become $60–$6F, $90–$DF have become $80–CF, and the 48 tiles $D0–$FF are free to be used. So you'll need to update the metatiles. This would be tedious to do by hand in a hex editor, so here's a Python script that will do it:

    # Edit this to be the pokecrystal path on your computer
    path = '/cygdrive/c/Users/Rangi/pokecrystal/tilesets/%02d_metatiles.bin'
    # If you have more tilesets than the original 36, edit this
    max_tileset_id = 36
    for i in range(0, max_tileset_id + 1):
        filename = path % i
        with open(filename, 'rb') as f:
            data = f.read()
        with open(filename, 'wb') as f:
            for b in data:
                b = ord(b)
                if 0x60 <= b < 0x80:
                    b = 0xff
                elif 0x80 <= b < 0x90:
                    b -= 0x20
                elif 0x90 <= b:
                    b -= 0x10
                f.write(chr(b))


    Save that as convert.py and run "python convert.py" in the Cygwin terminal.

    Step 3: Edit tilesets/##_palette_map.asm.

    This will have to be done manually for each one, but it's text so it won't take too long. You have to change the middle parts like this:

        ...
        tilepal 0, BROWN, BROWN, BROWN, BROWN, BROWN, BROWN, BROWN, BROWN
        tilepal 0, WATER, GRAY, GRAY, GRAY, BROWN, BROWN, GRAY, GRAY
    
    rept 16
        db $ff
    endr
    
        tilepal 1, BROWN, BROWN, BROWN, RED, RED, RED, RED, RED
        tilepal 1, RED, RED, RED, RED, RED, RED, RED, RED
        ...


    to this:

        ...
        tilepal 0, BROWN, BROWN, BROWN, BROWN, BROWN, BROWN, BROWN, BROWN
        tilepal 0, WATER, GRAY, GRAY, GRAY, BROWN, BROWN, GRAY, GRAY
        tilepal 0, BROWN, BROWN, BROWN, RED, RED, RED, RED, RED
        tilepal 0, RED, RED, RED, RED, RED, RED, RED, RED
    
    rept 8
        db $ff
    endr
    
        ...


    Basically you move the tilepal entries for tiles $80–$8F to $60–$6F (and change the 1 to a 0, since they're in VRAM0 instead of VRAM1), and then delete the eight "db $ff" that were occupying tiles $60–$6F. (The eight that remain are occupying tiles $70–$7F.)

    Step 4: Edit engine/map_objects.asm:Function56cd.

    Change this:

        ld a, [hl]
        cp $60
        jr nc, .nope


    to this:

        ld a, [hl]
        cp $70
        jr nc, .nope


    This will let NPCs or the player stand on top of tiles $00–$6F and $80–$EF.

    Important! Tiles $F0–$FF cannot be stood on. If you do, and then open a text box or menu, the sprite standing on those tiles will disappear. This is necessary for tiles $70–$7F, since those are text box frames: you want the text box to appear "above" the sprites, so they get hidden while the text box is open. But for tiles $F0–$FF, it means you need to use them for obstacles like trees or buildings that will never have sprites on them.

    Step 5: Edit engine/events_3.asm.

    Change this:

    LoadMapNameSignGFX: ; b80c6
        ld de, MapEntryFrameGFX
        ld hl, VTiles2 tile $60
        lb bc, BANK(MapEntryFrameGFX), $e
        jp Get2bpp


    to this:

    LoadMapNameSignGFX: ; b80c6
        ld de, MapEntryFrameGFX
        ld hl, VTiles2 tile $70
        lb bc, BANK(MapEntryFrameGFX), $e
        jp Get2bpp


    Now the pop-up location sign graphics will be loaded starting at tile $70 instead of $60. Then you need to update their tile map to agree with this. In PlaceMapNameFrame, change all the $6x constants to $7x. For example, change this:

        hlcoord 0, 0
        ; top left
        ld a, $61
        ld [hli], a


    to this:

        hlcoord 0, 0
        ; top left
        ld a, $71
        ld [hli], a


    Step 6: Edit gfx/font.asm.

    In _LoadFontsExtra1, change this:

        ld de, MobilePhoneTilesGFX
        ld hl, VTiles2 tile $60
        lb bc, BANK(MobilePhoneTilesGFX), 1
        call Get1bpp_2
        ld de, OverworldPhoneIconGFX
        ld hl, VTiles2 tile $62
        lb bc, BANK(OverworldPhoneIconGFX), 1
        call Get2bpp_2
        ld de, FontExtra + 3 * LEN_2BPP_TILE
        ld hl, VTiles2 tile $63
        lb bc, BANK(FontExtra), $16
        call Get2bpp_2


    to this:

        ld de, FontExtra + 16 * LEN_2BPP_TILE
        ld hl, VTiles2 tile $70
        lb bc, BANK(FontExtra), $6
        call Get2bpp_2


    In _LoadFontsExtra2, delete this:

        ld de, FontsExtra2_UpArrowGFX
        ld hl, VTiles2 tile $61
        ld b, BANK(FontsExtra2_UpArrowGFX)
        ld c, 1
        call Get2bpp_2


    Now you're no longer loading font graphics into tiles $60–$6F.

    Step 7: Edit gfx/misc/font.png.

    Add the five highlighted characters.



    They're no longer being loaded from FontExtra, OverworldPhoneIconGFX, and FontsExtra2_UpArrowGFX, so now they're in the standard font.

    Step 8: Update code that uses the changed font characters.

    In macros/charmap.asm, change this:

        charmap "▲",        $61
        charmap "_",        $62
        charmap "<COLON>",  $6d ; necessary because ":" is already used
        charmap "′",        $6e
        charmap "<LV>",     $6e
        charmap "″",        $6f


    to this:

        charmap "<BOLDV>",  $c6
        charmap "<BOLDS>",  $c7
        charmap "<COLON>",  $c8 ; necessary because ":" is already used
        charmap "<PHONE>",  $e4
        charmap "▲",        $e5
        charmap "_",        $62 ; from FontBattleExtra
        charmap "<LV>",     $6e ; from FontBattleExtra
        charmap "′",        $c6 ; in event/magikarp.asm
        charmap "″",        $c7 ; in event/magikarp.asm


    In engine/phone.asmTonguehone_CallerTextboxWithName2 and engine/phone.asm:Function90363, change this:

        ld [hl], $62


    to this:

        ld [hl], "<PHONE>"


    Finally, in battle/trainer_huds.asm:_ShowLinkBattleParticipants, change this:

        ld a, $69 ; "V"
        ld [hli], a
        ld [hl], $6a ; "S"


    to this:

        ld a, "<BOLDV>"
        ld [hli], a
        ld [hl], "<BOLDS>"


    I believe that's all of the font changes. I may have missed some. Regardless, the core functionality works, and if you see any tile errors with font characters it should not be difficult to track down their source.

    Done! You'll end up with lots of new tile space to use:



    And in my experience, tilesets obey Parkinson's Law of Data: "Data expands to fill the space available for storage". If you have 240 tiles, you'll find ways to use them. Like this: