Pokemon-Gen3-to-Gen-X/source/graphics_handler.c
Lorenzo Carletti 08bde102bd Kind of optimize sprites for space
Enabled stripping of top row when always empty (all pokemon but smoochum). Did not enable 3bpp. It would save 7 KBs extra, but it's extremely slow...
2022-12-29 22:49:18 +01:00

80 lines
3.0 KiB
C

#include <gba.h>
#include "graphics_handler.h"
#include "gender_symbols_bin.h"
#define MAX_SIZE_POKEMON_SPRITE 0x400
#define GRAPHICS_BUFFER_SHIFT 10
#define GRAPHICS_BUFFER_SIZE (1 << GRAPHICS_BUFFER_SHIFT)
#define CPUFASTSET_FILL (0x1000000)
void init_gender_symbols(){
u8 colors[] = {0,1};
convert_1bpp(gender_symbols_bin, (u32*)(VRAM+(0x88<<5)), gender_symbols_bin_size, colors, 1);
}
void load_pokemon_sprite_gfx(u32 src, u32 dst, u8 info){
u8 is_3bpp = info&2;
u8 zero_fill = info&1;
u32 zero = 0;
u32 buffer[2][MAX_SIZE_POKEMON_SPRITE>>2];
LZ77UnCompWram(src, buffer[0]);
if(is_3bpp) {
u8 colors[8];
for(int i = 0; i < 8; i++)
colors[i] = (buffer[0][0]>>(4*i))&0xF;
if(zero_fill) {
CpuFastSet(&zero, buffer[1], (MAX_SIZE_POKEMON_SPRITE>>2)|CPUFASTSET_FILL);
convert_3bpp(buffer[0]+1, (u32*)(((u32)buffer[1])+0x80), (((MAX_SIZE_POKEMON_SPRITE>>2)*3)>>1)-0x60, colors, 0);
convert_3bpp(buffer[0]+1+(((((MAX_SIZE_POKEMON_SPRITE>>2)*3)>>1)-0x60)>>2), (u32*)(((u32)buffer[1])+0x280), (((MAX_SIZE_POKEMON_SPRITE>>2)*3)>>1)-0x60, colors, 0);
CpuFastSet(buffer[1], dst, (MAX_SIZE_POKEMON_SPRITE>>2));
}
else
convert_3bpp(buffer[0]+1, dst, (MAX_SIZE_POKEMON_SPRITE>>2)*3, colors, 0);
}
else {
if(zero_fill) {
CpuFastSet(&zero, buffer[1], (MAX_SIZE_POKEMON_SPRITE>>2)|CPUFASTSET_FILL);
CpuFastSet(buffer[0], ((u32)buffer[1])+0x80, ((MAX_SIZE_POKEMON_SPRITE>>1)-0x80)>>2);
CpuFastSet(buffer[0]+(((MAX_SIZE_POKEMON_SPRITE>>1)-0x80)>>2), ((u32)buffer[1])+0x280, ((MAX_SIZE_POKEMON_SPRITE>>1)-0x80)>>2);
CpuFastSet(buffer[1], dst, (MAX_SIZE_POKEMON_SPRITE>>2));
}
else
CpuFastSet(buffer[0], dst, MAX_SIZE_POKEMON_SPRITE>>2);
}
}
void convert_xbpp(u8* src, u32* dst, u16 src_size, u8* colors, u8 is_forward, u8 num_bpp) {
if(num_bpp == 0 || num_bpp > 4)
return;
u16 num_rows = Div(src_size, num_bpp);
if(DivMod(src_size, num_bpp))
num_rows += 1;
for(int i = 0; i < num_rows; i++) {
u32 src_data = 0;
for(int j = 0; j < num_bpp; j++)
src_data |= src[(i*num_bpp)+j]<<(8*j);
u32 row = 0;
for(int j = 0; j < 8; j++)
if(!is_forward)
row |= (colors[(src_data>>(num_bpp*j))&((1<<num_bpp)-1)]&0xF) << (4*j);
else
row |= (colors[(src_data>>(num_bpp*j))&((1<<num_bpp)-1)]&0xF) << (4*(7-j));
dst[i] = row;
}
}
void convert_1bpp(u8* src, u32* dst, u16 src_size, u8* colors, u8 is_forward) {
convert_xbpp(src, dst, src_size, colors, is_forward, 1);
}
void convert_2bpp(u8* src, u32* dst, u16 src_size, u8* colors, u8 is_forward) {
convert_xbpp(src, dst, src_size, colors, is_forward, 2);
}
void convert_3bpp(u8* src, u32* dst, u16 src_size, u8* colors, u8 is_forward) {
convert_xbpp(src, dst, src_size, colors, is_forward, 3);
}