Skeetendo

’Cause all games were better on the GBC

You are not logged in.

#1 2017-07-08 22:36:47

Rangi
Member
Registered: 2016-05-09
Post 762/870

How to use 240 tiles in pokecrystal

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:

bnTUKI5.png

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.

rF39Cs2.png

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.asm:Phone_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:

6nLRKvB.png

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:

QCUKZ7Y.png

Last edited by Rangi (2017-11-26 00:11:57)


Pokémon Polished Crystal (GitHub) — version 2.2.0 released
Pokémon Red★ and Blue★: Space World Edition (GitHub) — updated August 19!
Polished Map: pokered+pokecrystal map, tileset, and palette editor — version 3.5.1 released!

Offline

Board footer

Powered by FluxBB