-
Notifications
You must be signed in to change notification settings - Fork 995
Expanding Tilesets Technique
First, this code not has development for me. This code is from Dannye, Rangi42 (in Red Star/Blue Star) and I think others persons from iimarckus, but I don't remenber who.
At a first moment, let see the tiles in vChars2 who are used in vanilla RGBY and move they to gfx/font/font.png.
Obs.: in gfx/font/font.png you don't need to let a empty space for space between words. This space is the last tile in gfx/font/font_extra.png.
Use charmap.asm to know tile's number in the VRAM.
Here some tiles than can be replaced:
A 8x8 tile complete unused in vanilla.
A 8x8 tile with limited use, you choose if want to remove.
Limited use: [
and ]
are only used in the Naming Screen (data/text/alphabets.asm).
(
and )
only are used in data/text/alphabets.asm and _Museum2FText7
in text/Museum2F.asm:
...
_Museum2FText7::
text "Meteorite that"
line "fell on MT.MOON."
- cont "(MOON STONE?)"
done
;
only used in data/text/alphabets.asm and _Mansion4Text7
in text/PokemonMansionB1F.asm, one diary in Cinnabar's Mansion. This is odd, because the others diarys use :
(typo?):
...
_Mansion4Text7::
- text "Diary; Sept. 1"
+ text "Diary: Sept. 1"
line "MEWTWO is far too"
cont "powerful."
para "We have failed to"
line "curb its vicious"
cont "tendencies..."
done
That second .
(next to /
, known in charmap.asm as <DOT>
) is used in data/text/alphabets.asm, beyond engine/movies/trade2.asm:
...
Trade_MonInfoText:
- db "──№<DOT>"
+ db "──№."
next ""
next "OT/"
- next "<ID>№<DOT>@"
+ next "<ID>№.@"
...
ShowPokedexDataInternal:
...
call IndexToPokedex
hlcoord 2, 8
ld a, "№"
ld [hli], a
- ld a, "<DOT>"
+ ld a, "."
ld [hli], a
ld de, wd11e
lb bc, LEADING_ZEROES | 1, 3
call PrintNumber ; print pokedex number
ld hl, wPokedexOwned
...
...
jr nc, .next
ld [hl], "0" ; if the weight is less than 10, put a 0 before the decimal point
.next
inc hl
ld a, [hli]
ld [hld], a ; make space for the decimal point by moving the last digit forward one tile
- ld [hl], "<DOT>" ; decimal point tile
+ ld [hl], "."
pop af
ldh [hDexWeight + 1], a ; restore original value of [hDexWeight + 1]
pop af
ldh [hDexWeight], a ; restore original value of [hDexWeight]
pop hl
inc hl ; hl = address of pokedex description text
bccoord 1, 11
ld a, %10
ldh [hClearLetterPrintingDelayFlags], a
call TextCommandProcessor ; print pokedex description text
...
and finally in engine/pokemon/status_screen.asm:
...
StatusScreen:
...
ldh [hTileAnimations], a
hlcoord 19, 1
lb bc, 6, 10
call DrawLineBox ; Draws the box around name, HP and status
ld de, -6
add hl, de
- ld [hl], "<DOT>"
+ ld [hl], "."
dec hl
ld [hl], "№"
...
The diference between the <DOT>
to the default final point .
next to ァ
(katakana small "a") is one pixel to the right.
Unused tiles: ァ
(katakana small "a"), ゥ
(katakana small "u"), ェ
(katakana small "e").
The empty space below z
is の
in the japanese version (hiragana "no") and it remains in the nickname screen, as you can see in PrintNamingText in engine/menus/naming_screen.asm:
...
PrintNamingText:
hlcoord 0, 1
ld a, [wNamingScreenType]
ld de, YourTextString
and a
jr z, .notNickname
ld de, RivalsTextString
dec a
jr z, .notNickname
ld a, [wcf91]
ld [wMonPartySpriteSpecies], a
push af
farcall WriteMonPartySpriteOAMBySpecies
pop af
ld [wd11e], a
call GetMonName
hlcoord 4, 1
call PlaceString
- ld hl, $1
- add hl, bc
- ld [hl], "の" ; leftover from Japanese version; blank tile $c9 in English
hlcoord 1, 3
ld de, NicknameTextString
jr .placeString
.notNickname
...
To delete this code, just delete the red lines above, but, thanks to this code, can make print 's
after Mon's name with this change:
...
PrintNamingText:
...
hlcoord 4, 1
call PlaceString
- ld hl, $1
- add hl, bc
- ld [hl], "の" ; leftover from Japanese version; blank tile $c9 in English
+ ld hl, $0
+ add hl, bc
+ ld [hl], "'s"
hlcoord 1, 3
ld de, NicknameTextString
jr .placeString
.notNickname
...
This font is load in Battle Scene, Pokémon Party, Mon's Status Screens, when you Startup the PC and Naming Screen.
Limited use: 『
(japanese opening quote) this tile itself is unused, but when you see the 2nd page in Status Screen the BOLD P to print PP
is load above this one. You can make this tutorial to remove gfx/font/P.png and move his to gfx/font/font_battle_extra.png.
┌
, ─
, ┐
, │
, └
, ┘
and
(tiles for Text Box and the empty space) that ones are complete desnecessary since they are load above the ones from gfx/font/font_extra.png.
Unused tiles: …
(japanese ellipsis). This is mencioned in home/text.asm, but I don't known what this means, I just replace with another random character:
...
PlaceCommandCharacter::
call PlaceString
ld h, b
ld l, c
pop de
inc de
jp PlaceNextChar
TMCharText:: db "TM@"
TrainerCharText:: db "TRAINER@"
PCCharText:: db "PC@"
RocketCharText:: db "ROCKET@"
PlacePOKeText:: db "POKé@"
-SixDotsCharText:: db "……@"
+SixDotsCharText:: db "..@"
EnemyText:: db "Enemy @"
PlacePKMNText:: db "<PK><MN>@"
ContText::
...
...
TextCommand_DOTS::
-; wait for button press or 30 frames while printing "…"s
+; wait for button press or 30 frames while printing "."s
pop hl
ld a, [hli]
ld d, a
push hl
ld h, b
ld l, c
.loop
- ld a, "…"
+ ld a, "."
ld [hli], a
push de
call Joypad
pop de
ldh a, [hJoyHeld] ; joypad state
and A_BUTTON | B_BUTTON
jr nz, .next ; if so, skip the delay
ld c, 10
call DelayFrames
.next
dec d
jr nz, .loop
ld b, h
ld c, l
pop hl
jp NextTextCommand
TextCommand_WAIT_BUTTON::
...
The two others indent/hyphen are underscore tiles used in engine/menus/naming_screen.asm. There's no charmap for they.
If your gfx/font/font_extra.png become like above, your engine/menus/naming_screen.asm need to be supposed like this:
...
PrintNicknameAndUnderscores:
...
.pokemon1
ld b, 10 ; pokemon max name length
.playerOrRival1
- ld a, $76 ; underscore tile id
+ ld a, $75 ; underscore tile id
.placeUnderscoreLoop
ld [hli], a
dec b
jr nz, .placeUnderscoreLoop
ld a, [wNamingScreenType]
cp NAME_MON_SCREEN
ld a, [wNamingScreenNameLength]
jr nc, .pokemon2
cp 7 ; player or rival max name length
jr .playerOrRival2
.pokemon2
cp 10 ; pokemon max name length
.playerOrRival2
jr nz, .emptySpacesRemaining
; when all spaces are filled, force the cursor onto the ED tile
call EraseMenuCursor
ld a, $11 ; "ED" x coord
ld [wTopMenuItemX], a
ld a, $5 ; "ED" y coord
ld [wCurrentMenuItem], a
ld a, [wNamingScreenType]
cp NAME_MON_SCREEN
ld a, 9 ; keep the last underscore raised
jr nc, .pokemon3
ld a, 6 ; keep the last underscore raised
.pokemon3
.emptySpacesRemaining
ld c, a
ld b, $0
hlcoord 10, 3
add hl, bc
- ld [hl], $77 ; raised underscore tile id
+ ld [hl], $76 ; raised underscore tile id
ret
; calculates the length of the string at wStringBuffer and stores it in c
CalcStringLength:
...
This font is load in Overworld.
Unused tiles: the BOLD incomplete alphabet A
, B
, C
, D
, E
, F
, G
, H
, I
, L
, M
. Probably this has come from Yoshi no Tamago (JP)/Yoshi (US)/Mario & Yoshi (EU), who too has developt earlier by Game Freak, as seen here.
ぃ
(hiragana small "i"), ぅ
(hiragana small "u"), ‘
, ’
, “
, ”
, ·
, …
, ぁ
(hiragana small "a"), ぇ
(hiragana small "e") and ぉ
(hiragana small "o").
The Bold V
and S
has used in the Link Battle Screen (engine/battle/link_battle_versus_text.asm):
; display "[player] VS [enemy]" text box with pokeballs representing their parties next to the names
DisplayLinkBattleVersusTextBox:
call LoadTextBoxTilePatterns
hlcoord 3, 4
ld b, 7
ld c, 12
call TextBoxBorder
hlcoord 4, 5
ld de, wPlayerName
call PlaceString
hlcoord 4, 10
ld de, wLinkEnemyTrainerName
call PlaceString
; place bold "VS" tiles between the names
hlcoord 9, 8
- ld a, $69
+ ld a, "<BOLD_V>"
ld [hli], a
- ld [hl], $6a
+ ld [hl], "<BOLD_S>"
xor a
ld [wUpdateSpritesEnabled], a
callfar SetupPlayerAndEnemyPokeballs
ld c, 150
jp DelayFrames
The alternative : (known in charmap.asm as <COLON>
) is used to print Time in engine/movie/hall_of_fame.asm:
...
HoFDisplayPlayerStats:
SetEvent EVENT_HALL_OF_FAME_DEX_RATING
predef DisplayDexRating
hlcoord 0, 4
ld b, 6
ld c, 10
call TextBoxBorder
hlcoord 5, 0
ld b, 2
ld c, 9
call TextBoxBorder
hlcoord 7, 2
ld de, wPlayerName
call PlaceString
hlcoord 1, 6
ld de, HoFPlayTimeText
call PlaceString
hlcoord 5, 7
ld de, wPlayTimeHours
lb bc, 1, 3
call PrintNumber
- ld [hl], $6d
+ ld [hl], "<COLON>"
inc hl
ld de, wPlayTimeMinutes
...
in engine/menus/main_menu.asm:
...
PrintPlayTime:
ld de, wPlayTimeHours
lb bc, 1, 3
call PrintNumber
- ld [hl], $6d
+ ld [hl], "<COLON>"
inc hl
ld de, wPlayTimeMinutes
lb bc, LEADING_ZEROES | 1, 2
jp PrintNumber
...
in engine/menus/start_sub_menus.asm:
...
; loads tile patterns and draws everything except for gym leader faces / badges
DrawTrainerInfo:
...
ld de, wPlayerName
call PlaceString
hlcoord 8, 4
ld de, wPlayerMoney
ld c, $e3
call PrintBCDNumber
hlcoord 9, 6
ld de, wPlayTimeHours ; hours
lb bc, LEFT_ALIGN | 1, 3
call PrintNumber
- ld [hl], $d6 ; colon tile ID
+ ld [hl], "<COLON>"
inc hl
ld de, wPlayTimeMinutes ; minutes
lb bc, LEADING_ZEROES | 1, 2
jp PrintNumber
TrainerInfo_FarCopyData:
ld a, BANK(TrainerInfoTextBoxTileGraphics)
jp FarCopyData2
...
and in _DexRatingText
in data/text/text_2.asm:
...
_DexRatingText::
- text "#DEX Rating<COLON>"
+ text "#DEX Rating:"
done
...
Now delete unused staff in charmap.asm:
...
; Actual characters (from gfx/font/font_extra.png)
- charmap "<BOLD_A>", $60 ; unused
- charmap "<BOLD_B>", $61 ; unused
- charmap "<BOLD_C>", $62 ; unused
- charmap "<BOLD_D>", $63 ; unused
- charmap "<BOLD_E>", $64 ; unused
- charmap "<BOLD_F>", $65 ; unused
- charmap "<BOLD_G>", $66 ; unused
- charmap "<BOLD_H>", $67 ; unused
- charmap "<BOLD_I>", $68 ; unused
- charmap "<BOLD_V>", $69
- charmap "<BOLD_S>", $6a
- charmap "<BOLD_L>", $6b ; unused
- charmap "<BOLD_M>", $6c ; unused
- charmap "<COLON>", $6d ; colon with tinier dots than ":"
- charmap "ぃ", $6e ; hiragana small i, unused
- charmap "ぅ", $6f ; hiragana small u, unused
- charmap "‘", $70 ; opening single quote
- charmap "’", $71 ; closing single quote
- charmap "“", $72 ; opening quote
- charmap "”", $73 ; closing quote
- charmap "·", $74 ; middle dot, unused
- charmap "…", $75 ; ellipsis
- charmap "ぁ", $76 ; hiragana small a, unused
- charmap "ぇ", $77 ; hiragana small e, unused
- charmap "ぉ", $78 ; hiragana small o, unused
charmap "┌", $79
charmap "─", $7a
charmap "┐", $7b
charmap "│", $7c
charmap "└", $7d
charmap "┘", $7e
charmap " ", $7f
; Actual characters (from gfx/font/font_battle_extra.png)
...
This is one of three Battle Huds who obviously load in Battle Scene.
Unused tiles: …
(japanese ellipsis).
Making the above alternance, now go to engine/battle/draw_hud_pokeball_gfx.asm and make that edit:
...
PlayerBattleHUDGraphicsTiles:
; The tile numbers for specific parts of the battle display for the player's pokemon
db $73 ; unused ($73 is hardcoded into the routine that uses these bytes)
- db $77 ; lower-right corner tile of the HUD
+ db $76 ; lower-right corner tile of the HUD
db $6F ; lower-left triangle tile of the HUD
...
...
EnemyBattleHUDGraphicsTiles:
; The tile numbers for specific parts of the battle display for the enemy
db $73 ; unused ($73 is hardcoded in the routine that uses these bytes)
db $74 ; lower-left corner tile of the HUD
- db $78 ; lower-right triangle tile of the HUD
+ db $77 ; lower-right triangle tile of the HUD
...
PlaceHUDTiles:
ld [hl], $73
ld bc, SCREEN_WIDTH
add hl, bc
ld a, [wHUDGraphicsTiles + 1] ; leftmost tile
ld [hl], a
ld a, 8
.loop
add hl, de
- ld [hl], $76
+ ld [hl], $75
dec a
jr nz, .loop
add hl, de
ld a, [wHUDGraphicsTiles + 2] ; rightmost tile
ld [hl], a
ret
...
Limited use: <LV>
(level symbol), lower-left triangle tile of the HUD (no charmap) and lower-right triangle tile of the HUD (no charmap) are complete desnecessary since they are load above the ones from gfx/font/font_battle_extra.png.
You only need to edit engine/pokemon/status_screen.asm:
...
; Predef 0x37
StatusScreen:
call LoadMonData
ld a, [wMonDataLocation]
cp BOX_DATA
jr c, .DontRecalculate
; mon is in a box or daycare
ld a, [wLoadedMonBoxLevel]
ld [wLoadedMonLevel], a
ld [wCurEnemyLVL], a
ld hl, wLoadedMonHPExp - 1
ld de, wLoadedMonStats
ld b, $1
call CalcStats ; Recalculate stats
.DontRecalculate
ld hl, wd72c
set 1, [hl]
ld a, $33
ldh [rNR50], a ; Reduce the volume
call GBPalWhiteOutWithDelay3
call ClearScreen
call UpdateSprites
call LoadHpBarAndStatusTilePatterns
ld de, BattleHudTiles1 ; source
ld hl, vChars2 tile $6d ; dest
- lb bc, BANK(BattleHudTiles1), 3
- call CopyVideoDataDouble ; ·│ :L and halfarrow line end
+ lb bc, BANK(BattleHudTiles1), 1
+ call CopyVideoDataDouble ; ·│
ld de, BattleHudTiles2
ld hl, vChars2 tile $78
lb bc, BANK(BattleHudTiles2), 1
call CopyVideoDataDouble ; │
ld de, BattleHudTiles3
ld hl, vChars2 tile $76
lb bc, BANK(BattleHudTiles3), 2
call CopyVideoDataDouble ; ─ ┘
...
Determine tileset's maximum tile number in home/overworld.asm:
...
INCLUDE "data/tilesets/bike_riding_tilesets.asm"
; load the tile pattern data of the current tileset into VRAM
LoadTilesetTilePatternData::
ld a, [wTilesetGfxPtr]
ld l, a
ld a, [wTilesetGfxPtr + 1]
ld h, a
ld de, vTileset
- ld bc, $600
+ ld bc, $790
ld a, [wTilesetBank]
jp FarCopyData2
; this loads the current maps complete tile map (which references blocks, not individual tiles) to C6E8
...
Now determine where gfx/font/font_extra.png is loaded in VRAM.
Go to home/load_font.asm:
...
LoadTextBoxTilePatterns::
ldh a, [rLCDC]
bit 7, a ; is the LCD enabled?
jr nz, .on
.off
ld hl, TextBoxGraphics
- ld de, vChars2 tile $60
+ ld de, vChars2 tile $79
ld bc, TextBoxGraphicsEnd - TextBoxGraphics
ld a, BANK(TextBoxGraphics)
jp FarCopyData2 ; if LCD is off, transfer all at once
.on
ld de, TextBoxGraphics
- ld hl, vChars2 tile $60
+ ld hl, vChars2 tile $79
lb bc, BANK(TextBoxGraphics), (TextBoxGraphicsEnd - TextBoxGraphics) / $10
jp CopyVideoData ; if LCD is on, transfer during V-blank
LoadHpBarAndStatusTilePatterns::
...
If you don't edit engine/overworld/movement.asm, characters above the new tiles will dissapears:
-DEF MAP_TILESET_SIZE EQU $60
+DEF MAP_TILESET_SIZE EQU $79
UpdatePlayerSprite:
...
The last thing now.
We need to use the function call ReloadMapData
to some menus don't be load above the new tileset space.
engine/menus/start_sub_menus.asm:
...
StartMenu_Pokemon::
ld a, [wPartyCount]
and a
jp z, RedisplayStartMenu
xor a
ld [wMenuItemToSwap], a
ld [wPartyMenuTypeOrMessageID], a
ld [wUpdateSpritesEnabled], a
call DisplayPartyMenu
jr .checkIfPokemonChosen
.loop
xor a
ld [wMenuItemToSwap], a
ld [wPartyMenuTypeOrMessageID], a
call GoBackToPartyMenu
.checkIfPokemonChosen
jr nc, .chosePokemon
.exitMenu
call GBPalWhiteOutWithDelay3
call RestoreScreenTilesAndReloadTilePatterns
call LoadGBPal
+ call ReloadMapData
jp RedisplayStartMenu
.chosePokemon
call SaveScreenTilesToBuffer1
ld a, FIELD_MOVE_MON_MENU
...
...
ld a, POTION
ld [wcf91], a
ld [wPseudoItemID], a
call UseItem
pop af
ld [wPartyAndBillsPCSavedMenuItem], a
jp .loop
.notHealthyEnough ; if current HP is less than 1/5 of max HP
ld hl, .notHealthyEnoughText
call PrintText
jp .loop
.notHealthyEnoughText
text_far _NotHealthyEnoughText
text_end
.goBackToMap
call RestoreScreenTilesAndReloadTilePatterns
+ call ReloadMapData
jp CloseTextDisplay
.newBadgeRequired
ld hl, .newBadgeRequiredText
call PrintText
jp .loop
.newBadgeRequiredText
text_far _NewBadgeRequiredText
text_end
; writes a blank tile to all possible menu cursor positions on the party menu
ErasePartyMenuCursors::
...
...
.useItem_closeMenu
xor a
ld [wPseudoItemID], a
call UseItem
ld a, [wActionResultOrTookBattleTurn]
and a
jp z, ItemMenuLoop
jp CloseStartMenu
.useItem_partyMenu
ld a, [wUpdateSpritesEnabled]
push af
call UseItem
ld a, [wActionResultOrTookBattleTurn]
cp $02
jp z, .partyMenuNotDisplayed
call GBPalWhiteOutWithDelay3
call RestoreScreenTilesAndReloadTilePatterns
+ call ReloadMapData
pop af
ld [wUpdateSpritesEnabled], a
jp StartMenu_Item
.partyMenuNotDisplayed
pop af
engine/menus/naming_screen.asm:
AskName:
call SaveScreenTilesToBuffer1
call GetPredefRegisters
push hl
ld a, [wIsInBattle]
dec a
hlcoord 0, 0
ld b, 4
ld c, 11
call z, ClearScreenArea ; only if in wild battle
ld a, [wcf91]
ld [wd11e], a
call GetMonName
ld hl, DoYouWantToNicknameText
call PrintText
hlcoord 14, 7
lb bc, 8, 15
ld a, TWO_OPTION_MENU
ld [wTextBoxID], a
call DisplayTextBoxID
pop hl
ld a, [wCurrentMenuItem]
and a
jr nz, .declinedNickname
ld a, [wUpdateSpritesEnabled]
push af
xor a
ld [wUpdateSpritesEnabled], a
push hl
ld a, NAME_MON_SCREEN
ld [wNamingScreenType], a
call DisplayNamingScreen
ld a, [wIsInBattle]
and a
jr nz, .inBattle
call ReloadMapSpriteTilePatterns
+ call ReloadTilesetTilePatterns
.inBattle
...
...
CompressedMap:
INCBIN "gfx/town_map/town_map.rle"
ExitTownMap:
; clear town map graphics data and load usual graphics data
xor a
ld [wTownMapSpriteBlinkingEnabled], a
call GBPalWhiteOut
call ClearScreen
call ClearSprites
call LoadPlayerSpriteGraphics
call LoadFontTilePatterns
+ call ReloadTilesetTilePatterns
call UpdateSprites
jp RunDefaultPaletteCommand
DrawPlayerOrBirdSprite:
; a = map number
...
You can have a arrangement like this:
in charmap.asm:
...
charmap "é", $ba
charmap "'d", $bb
charmap "'l", $bc
charmap "'s", $bd
charmap "'t", $be
charmap "'v", $bf
charmap "'", $e0
charmap "<PK>", $e1
charmap "<MN>", $e2
charmap "-", $e3
charmap "'r", $e4
charmap "'m", $e5
charmap "?", $e6
charmap "!", $e7
charmap ".", $e8
- charmap "ァ", $e9 ; katakana small a, unused
- charmap "ゥ", $ea ; katakana small u, unused
- charmap "ェ", $eb ; katakana small e, unused
+ charmap "<COLON>", $e9
+ charmap "<BOLD_V>", $ea
+ charmap "<BOLD_S>", $eb
charmap "▷", $ec
charmap "▶", $ed
charmap "▼", $ee
charmap "♂", $ef
charmap "¥", $f0
charmap "×", $f1
- charmap "<DOT>", $f2 ; decimal point; same as "." in English
charmap "/", $f3
charmap ",", $f4
charmap "♀", $f5
charmap "0", $f6
...
note who I have centered the .
, diffent from vanilla, and I removed the <DOT>
.
The last square tile represent the last tile who you can use.
When you let bigger the gfx/tilesets/overworld.png like above, will pass the ROMX limit. You can move to a new SECTION in gfx/tilesets.asm:
SECTION "Tilesets 1", ROMX
-Overworld_GFX:: INCBIN "gfx/tilesets/overworld.2bpp"
-Overworld_Block:: INCBIN "gfx/blocksets/overworld.bst"
RedsHouse1_GFX::
RedsHouse2_GFX:: INCBIN "gfx/tilesets/reds_house.2bpp"
RedsHouse1_Block::
RedsHouse2_Block:: INCBIN "gfx/blocksets/reds_house.bst"
House_GFX:: INCBIN "gfx/tilesets/house.2bpp"
House_Block:: INCBIN "gfx/blocksets/house.bst"
Mansion_GFX:: INCBIN "gfx/tilesets/mansion.2bpp"
Mansion_Block:: INCBIN "gfx/blocksets/mansion.bst"
ShipPort_GFX:: INCBIN "gfx/tilesets/ship_port.2bpp"
ShipPort_Block:: INCBIN "gfx/blocksets/ship_port.bst"
Interior_GFX:: INCBIN "gfx/tilesets/interior.2bpp"
Interior_Block:: INCBIN "gfx/blocksets/interior.bst"
Plateau_GFX:: INCBIN "gfx/tilesets/plateau.2bpp"
Plateau_Block:: INCBIN "gfx/blocksets/plateau.bst"
SECTION "Tilesets 2", ROMX
...
...
+SECTION "Tilesets 4", ROMX
+Overworld_GFX:: INCBIN "gfx/tilesets/overworld.2bpp"
+Overworld_Block:: INCBIN "gfx/blocksets/overworld.bst"