Compress the graphics (mostly), fix potential vram memcpy issue

This greatly decreases the ROM size, from 245 KB to 198 KB with no visual
changes (that I am aware of)

Changes:
- Enable compression on every graphic but the Pokemon sprites (which are
  too large for the GBA to decompress).
- Change grit from emitting .s files to .c files so GCC can strip unused
  palettes and maps
- Fix the empty tiles
- Trim down the font to skip 00-1F and 80-FF which were all zeroes
  - needs a slight workaround because the Pokemon name display was printing
    an invisible FF byte
- Switch memcpy to tonccpy which is vram safe
- Limit palette sizes.

Signed-off-by: easyaspi314 <6258309+easyaspi314@users.noreply.github.com>
This commit is contained in:
easyaspi314
2025-01-17 19:32:48 -05:00
parent a805bbad0a
commit e4ef25e20e
52 changed files with 185 additions and 202 deletions

View File

@@ -20,12 +20,11 @@ void load_background()
int CBB = 0;
int SBB = 1;
// Load palette
memcpy(pal_bg_mem, backgroundPal, backgroundPalLen);
tonccpy(pal_bg_mem, backgroundPal, backgroundPalLen);
// Load tiles into CBB 0
memcpy(&tile_mem[CBB][0], backgroundTiles, backgroundTilesLen);
LZ77UnCompVram(backgroundTiles, &tile_mem[CBB][0]);
// Load map into SBB 30
memcpy(&se_mem[SBB][0], backgroundMap, backgroundMapLen);
LZ77UnCompVram(backgroundMap, &se_mem[SBB][0]);
REG_BG0CNT = BG_CBB(CBB) | BG_SBB(SBB) | BG_4BPP | BG_REG_32x32 | BG_PRIO(3);
}
@@ -84,7 +83,7 @@ void set_background_pal(int curr_rom_id, bool dark, bool fade)
COLOR curr_pal_bg[8];
COLOR old_pal[3];
COLOR new_pal[3];
memcpy(curr_pal_bg, &pal_bg_mem[0], 16);
tonccpy(curr_pal_bg, &pal_bg_mem[0], 16);
for (int n = 0; n <= NUM_CYCLES; n++)
{
for (int i = 1; i < 5; i++)
@@ -104,7 +103,7 @@ void set_background_pal(int curr_rom_id, bool dark, bool fade)
}
else
{
memcpy(pal_bg_mem, &new_pal_bg[0], 16);
tonccpy(pal_bg_mem, &new_pal_bg[0], 16);
// memcpy(&pal_bg_mem[4], &new_pal_bg[4], 2);
}
(pal_obj_mem + (BTN_LIT_PAL * 16))[7] = pal_bg_mem[1];
@@ -126,41 +125,42 @@ void load_flex_background(int background_id, int layer)
{
case (BG_OPENING):
// Load palette
memcpy(pal_bg_mem + 32, openingBGPal, openingBGPalLen);
tonccpy(pal_bg_mem + 32, openingBGPal, openingBGPalLen);
// Load tiles into CBB 0
memcpy(&tile_mem[CBB][0], openingBGTiles, openingBGTilesLen);
LZ77UnCompVram(openingBGTiles, &tile_mem[CBB][0]);
// Load map into SBB 0
memcpy(&se_mem[SBB][0], openingBGMap, openingBGMapLen);
LZ77UnCompVram(openingBGMap, &se_mem[SBB][0]);
REG_BG1VOFS = 96;
break;
case (BG_FENNEL):
// Load palette
memcpy(pal_bg_mem + 32, fennelBGPal, fennelBGPalLen);
tonccpy(pal_bg_mem + 32, fennelBGPal, fennelBGPalLen);
// Load tiles into CBB 0
memcpy(&tile_mem[CBB][0], fennelBGTiles, fennelBGTilesLen);
LZ77UnCompVram(fennelBGTiles, &tile_mem[CBB][0]);
// Load map into SBB 0
memcpy(&se_mem[SBB][0], fennelBGMap, fennelBGMapLen);
LZ77UnCompVram(fennelBGMap, &se_mem[SBB][0]);
REG_BG1VOFS = FENNEL_SHIFT;
break;
case (BG_DEX):
// Load palette
memcpy(pal_bg_mem + 32, dexBGPal, dexBGPalLen);
tonccpy(pal_bg_mem + 32, dexBGPal, dexBGPalLen);
// Load tiles into CBB 0
memcpy(&tile_mem[CBB][0], dexBGTiles, dexBGTilesLen);
LZ77UnCompVram(dexBGTiles, &tile_mem[CBB][0]);
// Load map into SBB 0
memcpy(&se_mem[SBB][0], dexBGMap, dexBGMapLen);
LZ77UnCompVram(dexBGMap, &se_mem[SBB][0]);
REG_BG1VOFS = 0;
break;
case (BG_MAIN_MENU):
// Load palette
memcpy(pal_bg_mem + 32, pal_bg_mem, backgroundPalLen);
tonccpy(pal_bg_mem + 32, pal_bg_mem, backgroundPalLen);
// Load tiles into CBB 0
memcpy(&tile_mem[CBB][0], menu_barsTiles, menu_barsTilesLen);
LZ77UnCompVram(menu_barsTiles, &tile_mem[CBB][0]);
// Load map into SBB 0
memcpy(&se_mem[SBB][0], menu_barsMap, menu_barsMapLen);
LZ77UnCompVram(menu_barsMap, &se_mem[SBB][0]);
REG_BG1VOFS = 0;
break;
}
REG_BG1CNT = BG_CBB(CBB) | BG_SBB(SBB) | BG_4BPP | BG_REG_32x32 | BG_PRIO(layer);
curr_flex_background = background_id;
}
@@ -170,11 +170,11 @@ void load_textbox_background()
int CBB = 2;
int SBB = 17;
// Load palette
memcpy(pal_bg_mem + 16, textBoxBGPal, textBoxBGPalLen);
tonccpy(pal_bg_mem + 16, textBoxBGPal, textBoxBGPalLen);
// Load tiles into CBB 0
memcpy(&tile_mem[CBB][0], textBoxBGTiles, textBoxBGTilesLen);
LZ77UnCompVram(textBoxBGTiles, &tile_mem[CBB][0]);
// Load map into SBB 0
memcpy(&se_mem[SBB][0], textBoxBGMap, textBoxBGMapLen);
LZ77UnCompVram(textBoxBGMap, &se_mem[SBB][0]);
REG_BG2VOFS = 96;
REG_BG2CNT = BG_CBB(CBB) | BG_SBB(SBB) | BG_4BPP | BG_REG_32x32 | BG_PRIO(3);
@@ -183,7 +183,7 @@ void load_textbox_background()
void reload_textbox_background()
{
int SBB = 17;
memcpy(&se_mem[SBB][0], textBoxBGMap, textBoxBGMapLen);
LZ77UnCompVram(textBoxBGMap, &se_mem[SBB][0]);
}
// tile ID, VH Flip, Palette Bank
@@ -321,29 +321,44 @@ OBJ_ATTR *link_blob3 = &obj_buffer[num_sprites++];
u32 global_tile_id_end = 0;
inline void BitUnPack(const void *src, void *dst, uint16_t len, uint8_t from, uint8_t to)
{
BUP bupInfo = {
.src_len = len,
.src_bpp = from,
.dst_bpp = to,
.dst_ofs = 0
};
BitUnPack(src, dst, &bupInfo);
}
void load_eternal_sprites()
{
memcpy(pal_obj_mem + (BTN_PAL * 16), button_noPal, button_noPalLen);
memcpy(pal_obj_mem + (BTN_LIT_PAL * 16), button_yesPal, button_yesPalLen);
memcpy(pal_obj_mem + (LOGO_PAL * 16), ptgb_logo_lPal, ptgb_logo_lPalLen);
memcpy(pal_obj_mem + (TYPES_PAL1 * 16), typesPal, typesPalLen);
memcpy(pal_obj_mem + (LINK_CABLE_PAL * 16), link_frame1Pal, link_frame1PalLen);
tonccpy(pal_obj_mem + (BTN_PAL * 16), button_noPal, button_noPalLen);
tonccpy(pal_obj_mem + (BTN_LIT_PAL * 16), button_yesPal, button_yesPalLen);
tonccpy(pal_obj_mem + (LOGO_PAL * 16), ptgb_logo_lPal, ptgb_logo_lPalLen);
tonccpy(pal_obj_mem + (TYPES_PAL1 * 16), typesPal, typesPalLen);
tonccpy(pal_obj_mem + (LINK_CABLE_PAL * 16), link_frame1Pal, link_frame1PalLen);
u32 curr_tile_id = 0;
load_sprite(ptgb_logo_l, ptgb_logo_lTiles, ptgb_logo_lTilesLen, curr_tile_id, LOGO_PAL, ATTR0_SQUARE, ATTR1_SIZE_64x64, 1);
load_sprite(ptgb_logo_r, ptgb_logo_rTiles, ptgb_logo_rTilesLen, curr_tile_id, LOGO_PAL, ATTR0_SQUARE, ATTR1_SIZE_64x64, 1);
load_sprite(button_yes, button_yesTiles, button_yesTilesLen, curr_tile_id, BTN_PAL, ATTR0_WIDE, ATTR1_SIZE_64x32, 1);
load_sprite(button_no, button_noTiles, button_noTilesLen, curr_tile_id, BTN_PAL, ATTR0_WIDE, ATTR1_SIZE_64x32, 1);
load_sprite(cart_label, &Label_GreenTiles[8], Label_GreenTilesLen - 32, curr_tile_id, GB_CART_PAL, ATTR0_SQUARE, ATTR1_SIZE_32x32, 1);
load_sprite(point_arrow, &arrowsTiles[32], 32, curr_tile_id, BTN_PAL, ATTR0_SQUARE, ATTR1_SIZE_8x8, 1);
load_sprite(down_arrow, &arrowsTiles[0], 64, curr_tile_id, BTN_PAL, ATTR0_WIDE, ATTR1_SIZE_16x8, 1);
load_sprite(up_arrow, &arrowsTiles[16], 64, curr_tile_id, BTN_PAL, ATTR0_WIDE, ATTR1_SIZE_16x8, 1);
load_sprite(link_frame1, link_frame1Tiles, link_frame1TilesLen, curr_tile_id, LINK_CABLE_PAL, ATTR0_SQUARE, ATTR1_SIZE_32x32, 1);
load_sprite(link_frame2, link_frame2Tiles, link_frame2TilesLen, curr_tile_id, LINK_CABLE_PAL, ATTR0_WIDE, ATTR1_SIZE_8x32, 1);
load_sprite(link_frame3, link_frame3Tiles, link_frame3TilesLen, curr_tile_id, LINK_CABLE_PAL, ATTR0_WIDE, ATTR1_SIZE_16x32, 1);
load_sprite(link_blob1, &link_blobsTiles[0], 32, curr_tile_id, LINK_CABLE_PAL, ATTR0_SQUARE, ATTR1_SIZE_8x8, 1);
load_sprite(link_blob2, &link_blobsTiles[8], 32, curr_tile_id, LINK_CABLE_PAL, ATTR0_SQUARE, ATTR1_SIZE_8x8, 1);
load_sprite(link_blob3, &link_blobsTiles[16], 32, curr_tile_id, LINK_CABLE_PAL, ATTR0_SQUARE, ATTR1_SIZE_8x8, 1);
load_sprite_compressed(ptgb_logo_l, ptgb_logo_lTiles, curr_tile_id, LOGO_PAL, ATTR0_SQUARE, ATTR1_SIZE_64x64, 1);
load_sprite_compressed(ptgb_logo_r, ptgb_logo_rTiles, curr_tile_id, LOGO_PAL, ATTR0_SQUARE, ATTR1_SIZE_64x64, 1);
load_sprite_compressed(button_yes, button_yesTiles, curr_tile_id, BTN_PAL, ATTR0_WIDE, ATTR1_SIZE_64x32, 1);
load_sprite_compressed(button_no, button_noTiles, curr_tile_id, BTN_PAL, ATTR0_WIDE, ATTR1_SIZE_64x32, 1);
load_sprite_compressed(cart_label, Label_GreenTiles, curr_tile_id, GB_CART_PAL, ATTR0_SQUARE, ATTR1_SIZE_32x32, 1);
unsigned int tempTileBuf[48];
BitUnPack(arrowsTiles, tempTileBuf, arrowsTilesLen, 1, 4);
load_sprite(point_arrow, &tempTileBuf[32], 32, curr_tile_id, BTN_PAL, ATTR0_SQUARE, ATTR1_SIZE_8x8, 1);
load_sprite(down_arrow, &tempTileBuf[0], 64, curr_tile_id, BTN_PAL, ATTR0_WIDE, ATTR1_SIZE_16x8, 1);
load_sprite(up_arrow, &tempTileBuf[16], 64, curr_tile_id, BTN_PAL, ATTR0_WIDE, ATTR1_SIZE_16x8, 1);
load_sprite_compressed(link_frame1, link_frame1Tiles, curr_tile_id, LINK_CABLE_PAL, ATTR0_SQUARE, ATTR1_SIZE_32x32, 1);
load_sprite_compressed(link_frame2, link_frame2Tiles, curr_tile_id, LINK_CABLE_PAL, ATTR0_WIDE, ATTR1_SIZE_8x32, 1);
load_sprite_compressed(link_frame3, link_frame3Tiles, curr_tile_id, LINK_CABLE_PAL, ATTR0_WIDE, ATTR1_SIZE_16x32, 1);
BitUnPack(link_blobsTiles, tempTileBuf, link_blobsTilesLen, 1, 4);
load_sprite(link_blob1, &tempTileBuf[0], 32, curr_tile_id, LINK_CABLE_PAL, ATTR0_SQUARE, ATTR1_SIZE_8x8, 1);
load_sprite(link_blob2, &tempTileBuf[8], 32, curr_tile_id, LINK_CABLE_PAL, ATTR0_SQUARE, ATTR1_SIZE_8x8, 1);
load_sprite(link_blob3, &tempTileBuf[16], 32, curr_tile_id, LINK_CABLE_PAL, ATTR0_SQUARE, ATTR1_SIZE_8x8, 1);
global_tile_id_end = curr_tile_id;
@@ -374,11 +389,11 @@ void load_temp_box_sprites(Pokemon_Party party_data)
}
curr_tile_id += 4;
}
load_sprite(box_select, box_selectTiles, box_selectTilesLen, curr_tile_id, BTN_PAL, ATTR0_SQUARE, ATTR1_SIZE_16x16, 0);
load_sprite(button_cancel_left, button_cancel_leftTiles, button_cancel_leftTilesLen, curr_tile_id, BTN_PAL, ATTR0_WIDE, ATTR1_SIZE_64x32, 1);
load_sprite(button_cancel_right, button_edgeTiles, button_edgeTilesLen, curr_tile_id, BTN_PAL, ATTR0_TALL, ATTR1_SIZE_8x32, 1);
load_sprite(button_confirm_left, button_confirm_leftTiles, button_confirm_leftTilesLen, curr_tile_id, BTN_PAL, ATTR0_WIDE, ATTR1_SIZE_64x32, 1);
load_sprite(button_confirm_right, button_edgeTiles, button_edgeTilesLen, curr_tile_id, BTN_PAL, ATTR0_TALL, ATTR1_SIZE_8x32, 1);
load_sprite_compressed(box_select, box_selectTiles, curr_tile_id, BTN_PAL, ATTR0_SQUARE, ATTR1_SIZE_16x16, 0);
load_sprite_compressed(button_cancel_left, button_cancel_leftTiles, curr_tile_id, BTN_PAL, ATTR0_WIDE, ATTR1_SIZE_64x32, 1);
load_sprite_compressed(button_cancel_right, button_edgeTiles, curr_tile_id, BTN_PAL, ATTR0_TALL, ATTR1_SIZE_8x32, 1);
load_sprite_compressed(button_confirm_left, button_confirm_leftTiles, curr_tile_id, BTN_PAL, ATTR0_WIDE, ATTR1_SIZE_64x32, 1);
load_sprite_compressed(button_confirm_right, button_edgeTiles, curr_tile_id, BTN_PAL, ATTR0_TALL, ATTR1_SIZE_8x32, 1);
}
void load_type_sprites(int pkmn_index, int dex_offset, bool is_caught)
@@ -389,9 +404,8 @@ void load_type_sprites(int pkmn_index, int dex_offset, bool is_caught)
int type1 = TYPES[pkmn_index][0];
int type2 = TYPES[pkmn_index][1];
// V this is super weird because Grit keeps adding in an extra blank tile. Not sure why.
load_sprite(type_sprites[(dex_offset * 2) + 0], &typesTiles[(type1 * 32) + 8], 128, curr_tile_id, (type1 < 13 ? TYPES_PAL1 : TYPES_PAL2), ATTR0_WIDE, ATTR1_SIZE_32x8, 1);
load_sprite(type_sprites[(dex_offset * 2) + 1], &typesTiles[(type2 * 32) + 8], 128, curr_tile_id, (type2 < 13 ? TYPES_PAL1 : TYPES_PAL2), ATTR0_WIDE, ATTR1_SIZE_32x8, 1);
load_sprite(type_sprites[(dex_offset * 2) + 0], &typesTiles[(type1 * 32)], 128, curr_tile_id, (type1 < 13 ? TYPES_PAL1 : TYPES_PAL2), ATTR0_WIDE, ATTR1_SIZE_32x8, 1);
load_sprite(type_sprites[(dex_offset * 2) + 1], &typesTiles[(type2 * 32)], 128, curr_tile_id, (type2 < 13 ? TYPES_PAL1 : TYPES_PAL2), ATTR0_WIDE, ATTR1_SIZE_32x8, 1);
obj_set_pos(type_sprites[(dex_offset * 2) + 0], 19 * 8, (8 * 2 * dex_offset) + (8 * 4));
obj_set_pos(type_sprites[(dex_offset * 2) + 1], 23 * 8, (8 * 2 * dex_offset) + (8 * 4));
@@ -412,12 +426,24 @@ void load_type_sprites(int pkmn_index, int dex_offset, bool is_caught)
void load_sprite(OBJ_ATTR *sprite, const unsigned int objTiles[], int objTilesLen,
u32 &tile_id, u32 pal_bank, int attr0, int attr1, u32 priority)
{
memcpy(&tile_mem[SPRITE_CHAR_BLOCK][tile_id], objTiles, objTilesLen);
tonccpy(&tile_mem[SPRITE_CHAR_BLOCK][tile_id], objTiles, objTilesLen);
obj_set_attr(sprite, attr0, attr1, ATTR2_PALBANK(pal_bank) | tile_id | ATTR2_PRIO(priority));
tile_id += objTilesLen / 32;
obj_hide(sprite);
};
void load_sprite_compressed(OBJ_ATTR *sprite, const unsigned int objTiles[],
u32 &tile_id, u32 pal_bank, int attr0, int attr1, u32 priority)
{
// bits 8-31 of the header are the length
int objTilesLen = objTiles[0] >> 8;
LZ77UnCompVram(objTiles, &tile_mem[SPRITE_CHAR_BLOCK][tile_id]);
obj_set_attr(sprite, attr0, attr1, ATTR2_PALBANK(pal_bank) | tile_id | ATTR2_PRIO(priority));
tile_id += objTilesLen / 32;
obj_hide(sprite);
};
void load_select_sprites(int game_id, int lang)
{
u32 curr_tile_id = global_tile_id_end;
@@ -535,10 +561,10 @@ void load_select_sprites(int game_id, int lang)
break;
}
memcpy(pal_obj_mem + (GB_CART_PAL * 16), cart_palette, 12);
memcpy(pal_obj_mem + (GB_CART_PAL * 16) + 6, label_palette + 6, 20);
load_sprite(cart_shell, cart_tiles, GB_ShellTilesLen, curr_tile_id, GB_CART_PAL, ATTR0_SQUARE, ATTR1_SIZE_64x64, 1);
load_sprite(cart_label, &label_tiles[8], Label_GreenTilesLen - 32, curr_tile_id, GB_CART_PAL, ATTR0_SQUARE, ATTR1_SIZE_32x32, 1);
tonccpy(pal_obj_mem + (GB_CART_PAL * 16), cart_palette, 12);
tonccpy(pal_obj_mem + (GB_CART_PAL * 16) + 6, label_palette + 6, 20);
load_sprite_compressed(cart_shell, cart_tiles, curr_tile_id, GB_CART_PAL, ATTR0_SQUARE, ATTR1_SIZE_64x64, 1);
load_sprite_compressed(cart_label, label_tiles, curr_tile_id, GB_CART_PAL, ATTR0_SQUARE, ATTR1_SIZE_32x32, 1);
const unsigned int *flag_tiles = 0;
const unsigned short *flag_palette = 0;
@@ -574,8 +600,8 @@ void load_select_sprites(int game_id, int lang)
break;
}
load_sprite(flag, flag_tiles, flag_jpnTilesLen, curr_tile_id, FLAG_PAL, ATTR0_WIDE, ATTR1_SIZE_32x64, 1);
memcpy(pal_obj_mem + (FLAG_PAL * 16), flag_palette, 16); // Grit is being stupid.
load_sprite_compressed(flag, flag_tiles, curr_tile_id, FLAG_PAL, ATTR0_WIDE, ATTR1_SIZE_32x64, 1);
tonccpy(pal_obj_mem + (FLAG_PAL * 16), flag_palette, 16); // Grit is being stupid.
const unsigned int *gba_cart_tiles = 0;
const unsigned short *gba_cart_palette = 0;
@@ -604,8 +630,8 @@ void load_select_sprites(int game_id, int lang)
break;
}
load_sprite(gba_cart, gba_cart_tiles, 1024, curr_tile_id, GBA_CART_PAL, ATTR0_WIDE, ATTR1_SIZE_32x64, 1);
memcpy(pal_obj_mem + (GBA_CART_PAL * 16), gba_cart_palette, 32);
load_sprite_compressed(gba_cart, gba_cart_tiles, curr_tile_id, GBA_CART_PAL, ATTR0_WIDE, ATTR1_SIZE_32x64, 1);
tonccpy(pal_obj_mem + (GBA_CART_PAL * 16), gba_cart_palette, 32);
}
// tile ID, VH Flip, Palette Bank
#define FEN_BLI_L00 (34 | (0b00 << 0xA) | (2 << 0xC))