git.y1.nz

gbdk-2020

GameBoy Development Kit
download: https://git.y1.nz/archives/gbdk.tar.gz
README | Files | Log | Refs | LICENSE

commit cd120cebbfc1c42520a25ca42bf3d68957164f26
parent 4e67919132770c30af4375e5af8a3d82618ad041
Author: Toxa <untoxa@mail.ru>
Date:   Wed, 18 Aug 2021 00:30:10 +0300

SMS/GG: metasprites

Diffstat:
Agbdk-lib/examples/gg/metasprites/Makefile30++++++++++++++++++++++++++++++
Agbdk-lib/examples/gg/metasprites/metasprites.c145+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agbdk-lib/examples/gg/metasprites/sprite.c59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agbdk-lib/examples/gg/metasprites/sprite.h9+++++++++
Agbdk-lib/examples/sms/metasprites/Makefile30++++++++++++++++++++++++++++++
Agbdk-lib/examples/sms/metasprites/metasprites.c145+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agbdk-lib/examples/sms/metasprites/sprite.c59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agbdk-lib/examples/sms/metasprites/sprite.h9+++++++++
Agbdk-lib/include/sms/metasprites.h116+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mgbdk-lib/libc/targets/gbz80/metasprites.s2+-
Mgbdk-lib/libc/targets/gbz80/metasprites_flip.s6+++---
Mgbdk-lib/libc/targets/z80/gg/Makefile1+
Agbdk-lib/libc/targets/z80/metasprites.s82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agbdk-lib/libc/targets/z80/metasprites_hide.s37+++++++++++++++++++++++++++++++++++++
Agbdk-lib/libc/targets/z80/metasprites_hide_spr.s41+++++++++++++++++++++++++++++++++++++++++
Mgbdk-lib/libc/targets/z80/sms/Makefile1+
16 files changed, 768 insertions(+), 4 deletions(-)

diff --git a/gbdk-lib/examples/gg/metasprites/Makefile b/gbdk-lib/examples/gg/metasprites/Makefile @@ -0,0 +1,30 @@ +CC = ../../../bin/lcc -mz80:gg -Wm-yoA -Wa-l -Wl-j + +BINS = metasprites.gg + +all: $(BINS) + +ASRC = $(wildcard *.s) +CSRC = $(wildcard *.c) + +OBJS = $(CSRC:%.c=%.o) $(ASRC:%.s=%.o) + +compile.bat: Makefile + @echo "REM Automatically generated from Makefile" > compile.bat + @make -sn | sed y/\\//\\\\/ | grep -v make >> compile.bat + +# Compile and link single file in one pass + +%.o: %.c + $(CC) -c -o $@ $< + +%.o: %.s + $(CC) -c -o $@ $< + +$(BINS): $(OBJS) + $(CC) -Wm-yS -o $@ $^ + rm -f *.map *.noi *.ihx *.lst + +clean: + rm -f *.o *.lst *.map *.gg *~ *.rel *.cdb *.ihx *.lnk *.sym *.asm *.noi + diff --git a/gbdk-lib/examples/gg/metasprites/metasprites.c b/gbdk-lib/examples/gg/metasprites/metasprites.c @@ -0,0 +1,145 @@ +#include <sms/sms.h> +#include <sms/metasprites.h> + +#include <stdint.h> + +#include "sprite.h" + +const unsigned char pattern[] = {0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x02,0x02,0x01,0x01}; + +joypads_t joypads; + +#define ACC_X 1 +#define ACC_Y 2 + +// The metasprite will be built starting with hardware sprite zero (the first) +#define SPR_NUM_START 0 + +// Metasprite tiles are loaded into VRAM starting at tile number 0 +#define TILE_NUM_START 0 + +// sprite coords +uint16_t PosX, PosY; +int16_t SpdX, SpdY; +uint8_t PosF; +uint8_t hide, jitter; +uint8_t idx, rot; + +// main funxction +void main(void) { + // Fill the screen background with a single tile pattern +// fill_bkg_rect(0, 0, 20, 18, 0); + set_bkg_2bpp_data(0, 1, pattern); + + // Load metasprite tile data into VRAM + set_sprite_2bpp_data(TILE_NUM_START, sizeof(sprite_data) >> 4, sprite_data); + + // show bkg and sprites + SHOW_SPRITES; + + // Check what size hardware sprite the metasprite is using (from sprite.h) + #if sprite_TILE_H == 16 + SPRITES_8x16; + #else + SPRITES_8x8; + #endif + DISPLAY_ON; + + // init 1 joypad + joypad_init(1, &joypads); + + // Set initial position, zero out speed + PosX = PosY = 64 << 4; + SpdX = SpdY = 0; + + hide = 0; jitter = 0; idx = 0; rot = 0; + + while(1) { + // poll joypads + joypad_ex(&joypads); + + PosF = 0; + // game object + if (joypads.joy0 & J_UP) { + SpdY -= 2; + if (SpdY < -32) SpdY = -32; + PosF |= ACC_Y; + } else if (joypads.joy0 & J_DOWN) { + SpdY += 2; + if (SpdY > 32) SpdY = 32; + PosF |= ACC_Y; + } + + if (joypads.joy0 & J_LEFT) { + SpdX -= 2; + if (SpdX < -32) SpdX = -32; + PosF |= ACC_X; + } else if (joypads.joy0 & J_RIGHT) { + SpdX += 2; + if (SpdX > 32) SpdX = 32; + PosF |= ACC_X; + } + + + // Press A button to show/hide metasprite + if ((joypads.joy0 & J_A) && (!jitter)) { + hide = (!hide); + jitter = 20; + } + + // Press B button to cycle through metasprite animations + if ((joypads.joy0 & J_B) && (!jitter) && (!hide)) { + idx++; if (idx >= (sizeof(sprite_metasprites) >> 1)) idx = 0; + jitter = 10; + } + + // Press SELECT button to cycle metasprite through Normal/Flip-Y/Flip-XY/Flip-X + if ((joypads.joy0 & J_SELECT) && (!jitter) && (!hide)) { + rot++; rot &= 3; + jitter = 20; + } + + // Hide/Animate/Flip input throttling + if (jitter) jitter--; + + PosX += SpdX, PosY += SpdY; + + uint8_t hiwater = 0; + + // NOTE: In a real game it would be better to only call the move_metasprite..() + // functions if something changed (such as movement or rotation). That + // reduces CPU usage on frames that don't need udpates. + // + // In this example they are called every frame to simplify the example code + + // Hide the metasprite or move it & apply any rotation settings + if (hide) + hide_metasprite(sprite_metasprites[idx], SPR_NUM_START); + else + hiwater = move_metasprite(sprite_metasprites[idx], TILE_NUM_START, SPR_NUM_START, (PosX >> 4), (PosY >> 4)); + + // Hide rest of the hardware sprites, because amount of sprites differ between animation frames. + hide_sprites_range(hiwater, 64); + + // Y Axis: update velocity (reduce speed) if no U/D button pressed + if (!(PosF & ACC_Y)) { + if (SpdY != 0) { + if (SpdY < 0) SpdY++; + else SpdY --; + } + } + + // X Axis: update velocity (reduce speed) if no L/R button pressed + if (!(PosF & ACC_X)) { + if (SpdX != 0) { + if (SpdX < 0) SpdX++; + else SpdX --; + } + } + + + // wait for VBlank to slow down everything and reduce cpu use when idle + wait_vbl_done(); + } +} + diff --git a/gbdk-lib/examples/gg/metasprites/sprite.c b/gbdk-lib/examples/gg/metasprites/sprite.c @@ -0,0 +1,59 @@ +//AUTOGENERATED FILE FROM png2mtspr + +#include <sms/sms.h> +#include <sms/metasprites.h> + +const UINT8 sprite_data[896] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x0d,0x0e,0x1f,0x10,0x3f,0x20,0x3f,0x20, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0xfd,0xfe,0x3f,0xc0,0xff,0x0c,0xff,0x13,0xf7,0x08,0xc1,0x3e, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x7f,0x9f,0xe0,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x80,0xff,0x40, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xf0,0xcf,0x3f,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0x3c,0xfc,0xf3,0x0f,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, +0x3f,0x20,0x3f,0x20,0x3f,0x20,0x3f,0x20,0x3f,0x20,0x3f,0x23,0x3d,0x23,0x5e,0x61,0x5e,0x61,0x7c,0x43,0x78,0x47,0x79,0x47,0xbb,0xc7,0xb3,0xcf,0xf2,0x8e,0xf4,0x8c, +0xc0,0x3f,0xc0,0x3f,0xc0,0x3f,0xcf,0x30,0xff,0x08,0xbf,0xc4,0xe7,0xdc,0x07,0xfc,0x02,0xff,0x03,0xff,0x00,0xff,0x87,0xff,0xff,0xff,0xc1,0xc1,0x01,0x01,0x00,0x00, +0xff,0x20,0x7f,0xa0,0x7f,0x90,0xff,0x10,0xff,0x10,0xdf,0x30,0xff,0x60,0xbf,0xc0,0xbd,0xc2,0x3c,0xc3,0x7e,0x81,0xff,0x80,0xff,0x80,0xbf,0xc0,0xff,0xc0,0xff,0xc0, +0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0x3f,0xc0,0x07,0xf8,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x40,0xff,0x40,0xff, +0xfe,0x02,0xfe,0x02,0xfd,0x03,0xff,0x01,0xff,0x01,0xff,0x01,0xff,0x00,0x7f,0x80,0x7f,0x80,0xff,0x00,0xfe,0x01,0xff,0x01,0xfd,0x03,0xfd,0x03,0x79,0x87,0x71,0x8f, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x40,0xc0,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xe0,0x20,0x60,0xa0,0x60,0xa0,0xa0,0xe0, +0xf4,0x8c,0xf4,0x8c,0xb4,0xcc,0xb8,0xc8,0xb8,0xc8,0x78,0x48,0x78,0x48,0x78,0x48,0x74,0x4c,0x5c,0x64,0x3c,0x24,0x3e,0x22,0x19,0x17,0x0b,0x0f,0x06,0x06,0x00,0x00, +0xdf,0xe0,0x7f,0x60,0x7e,0x61,0x6e,0x71,0x7e,0x71,0x7c,0x73,0x70,0x7f,0x78,0x7f,0x78,0x7f,0x78,0x7f,0x7c,0x7f,0x7c,0x7f,0x7c,0x7f,0xfb,0xfc,0xfb,0xfc,0x0f,0x0f, +0x70,0xff,0x4f,0xcf,0x41,0xc1,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x20,0xe0,0x20,0xe0,0x20,0xe0,0x20,0xe0,0x20,0xe0,0x10,0xf0,0x10,0xf0,0x90,0x70,0xd0,0x30,0xe0,0xe0, +0x02,0xff,0xfe,0xff,0xfe,0xff,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00, +0x01,0xff,0x01,0xff,0x01,0xff,0x01,0xff,0x01,0xff,0x82,0xfe,0x82,0xfe,0xc2,0xfe,0xc2,0xfe,0x42,0x7e,0x42,0x7e,0x42,0x7e,0x81,0xff,0xb9,0xc7,0xfd,0x83,0xfe,0xfe, +0x50,0x70,0x50,0x70,0x50,0x70,0x50,0x70,0x30,0x30,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x40,0xc0,0xc0,0x40,0xc0,0x40,0xe0,0x20,0x60,0xa0,0xb0,0xd0,0x70,0x50,0x50,0x70, +0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xf4,0x8c,0xf4,0x8c,0xf4,0x8c,0x78,0x88,0xe8,0x18,0xf0,0x10,0xf0,0x10,0xf0,0x10,0x70,0x90,0xf0,0x90,0xe8,0x98,0x78,0x48,0x64,0x5c,0x2c,0x3c,0x18,0x18,0x00,0x00, +0x38,0x28,0x38,0x28,0x28,0x38,0x18,0x18,0x18,0x18,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x40,0xc0,0xc0,0x40,0xe0,0x20,0xe0,0x20,0xf0,0x90,0xb0,0xd0,0x78,0x48,0x34,0x2c, +0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x03,0x02,0x03,0x02,0x05,0x06,0x07,0x04,0x07,0x04,0x07,0x04,0x07,0x04,0x05,0x06,0x03,0x02,0x02,0x03,0x01,0x01,0x00,0x00, +0x74,0x8c,0xf4,0x0c,0xe8,0x18,0xf8,0x18,0xd0,0x30,0xe0,0x20,0xc0,0x40,0x40,0xc0,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0xc0,0x40,0xc0,0x40,0xc0,0xc0,0xc0,0x00,0x00, +0x1c,0x14,0x0e,0x0a,0x07,0x05,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x03,0x02,0x07,0x04,0x07,0x04,0x0f,0x08,0x0f,0x09,0x15,0x1b,0x1e,0x12,0x1e,0x12,0x1a,0x16,0x12,0x1e,0x1e,0x1e,0x00,0x00, +0x74,0x8c,0xf4,0x0c,0xe8,0x18,0xf8,0x18,0xd0,0x30,0xe0,0x20,0xc0,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x03,0x02,0x07,0x04,0x0b,0x0c,0x0f,0x08,0x1f,0x11,0x1e,0x12,0x2a,0x36,0x3c,0x24,0x24,0x3c,0x28,0x38,0x38,0x38,0x00,0x00 +}; + +const metasprite_t sprite_metasprite0[] = { + {-24, -24, 0}, {0, 8, 2}, {0, 8, 4}, {0, 8, 6}, {0, 8, 8}, {0, 8, 0}, {16, -40, 10}, {0, 8, 12}, {0, 8, 14}, {0, 8, 16}, {0, 8, 16}, {0, 8, 18}, {0, 8, 20}, {16, -48, 22}, {0, 16, 24}, {0, 8, 26}, {0, 8, 28}, {0, 8, 30}, {0, 8, 32}, {metasprite_end} +}; + +const metasprite_t sprite_metasprite1[] = { + {-24, -24, 0}, {0, 8, 2}, {0, 8, 4}, {0, 8, 6}, {0, 8, 8}, {0, 8, 0}, {16, -40, 10}, {0, 8, 12}, {0, 8, 14}, {0, 8, 16}, {0, 8, 16}, {0, 8, 18}, {0, 8, 34}, {16, -56, 36}, {0, 8, 38}, {0, 16, 24}, {0, 8, 26}, {0, 8, 28}, {0, 8, 30}, {0, 8, 40}, {metasprite_end} +}; + +const metasprite_t sprite_metasprite2[] = { + {-24, -24, 0}, {0, 8, 2}, {0, 8, 4}, {0, 8, 6}, {0, 8, 8}, {0, 8, 0}, {16, -40, 10}, {0, 8, 12}, {0, 8, 14}, {0, 8, 16}, {0, 8, 16}, {0, 8, 18}, {0, 8, 42}, {16, -56, 44}, {0, 8, 46, 0}, {0, 16, 24}, {0, 8, 26}, {0, 8, 28}, {0, 8, 30}, {0, 8, 48}, {metasprite_end} +}; + +const metasprite_t sprite_metasprite3[] = { + {-24, -24, 0}, {0, 8, 2}, {0, 8, 4}, {0, 8, 6}, {0, 8, 8}, {0, 8, 0}, {16, -40, 10}, {0, 8, 12}, {0, 8, 14}, {0, 8, 16}, {0, 8, 16}, {0, 8, 18}, {0, 8, 34}, {16, -56, 50}, {0, 8, 52}, {0, 16, 24}, {0, 8, 26}, {0, 8, 28}, {0, 8, 30}, {0, 8, 40}, {metasprite_end} +}; + +const metasprite_t sprite_metasprite4[] = { + {-24, -24, 0}, {0, 8, 2}, {0, 8, 4}, {0, 8, 6}, {0, 8, 8}, {0, 8, 0}, {16, -40, 10}, {0, 8, 12}, {0, 8, 14}, {0, 8, 16}, {0, 8, 16}, {0, 8, 18}, {0, 8, 20}, {16, -56, 54}, {0, 8, 52}, {0, 16, 24}, {0, 8, 26}, {0, 8, 28}, {0, 8, 30}, {0, 8, 32}, {metasprite_end} +}; + +const metasprite_t* const sprite_metasprites[5] = { + sprite_metasprite0, sprite_metasprite1, sprite_metasprite2, sprite_metasprite3, sprite_metasprite4 +}; diff --git a/gbdk-lib/examples/gg/metasprites/sprite.h b/gbdk-lib/examples/gg/metasprites/sprite.h @@ -0,0 +1,9 @@ +//AUTOGENERATED FILE FROM png2mtspr +#define sprite_TILE_H 16 +#define sprite_WIDTH 64 +#define sprite_HEIGHT 48 +#define sprite_PIVOT_X 32 +#define sprite_PIVOT_Y 24 + +extern const UINT8 sprite_data[896]; +extern const metasprite_t* const sprite_metasprites[5]; diff --git a/gbdk-lib/examples/sms/metasprites/Makefile b/gbdk-lib/examples/sms/metasprites/Makefile @@ -0,0 +1,30 @@ +CC = ../../../bin/lcc -mz80:sms -Wm-yoA -Wa-l -Wl-j + +BINS = metasprites.sms + +all: $(BINS) + +ASRC = $(wildcard *.s) +CSRC = $(wildcard *.c) + +OBJS = $(CSRC:%.c=%.o) $(ASRC:%.s=%.o) + +compile.bat: Makefile + @echo "REM Automatically generated from Makefile" > compile.bat + @make -sn | sed y/\\//\\\\/ | grep -v make >> compile.bat + +# Compile and link single file in one pass + +%.o: %.c + $(CC) -c -o $@ $< + +%.o: %.s + $(CC) -c -o $@ $< + +$(BINS): $(OBJS) + $(CC) -Wm-yS -o $@ $^ + rm -f *.map *.noi *.ihx *.lst + +clean: + rm -f *.o *.lst *.map *.sms *~ *.rel *.cdb *.ihx *.lnk *.sym *.asm *.noi + diff --git a/gbdk-lib/examples/sms/metasprites/metasprites.c b/gbdk-lib/examples/sms/metasprites/metasprites.c @@ -0,0 +1,145 @@ +#include <sms/sms.h> +#include <sms/metasprites.h> + +#include <stdint.h> + +#include "sprite.h" + +const unsigned char pattern[] = {0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x02,0x02,0x01,0x01}; + +joypads_t joypads; + +#define ACC_X 1 +#define ACC_Y 2 + +// The metasprite will be built starting with hardware sprite zero (the first) +#define SPR_NUM_START 0 + +// Metasprite tiles are loaded into VRAM starting at tile number 0 +#define TILE_NUM_START 0 + +// sprite coords +uint16_t PosX, PosY; +int16_t SpdX, SpdY; +uint8_t PosF; +uint8_t hide, jitter; +uint8_t idx, rot; + +// main funxction +void main(void) { + // Fill the screen background with a single tile pattern +// fill_bkg_rect(0, 0, 20, 18, 0); + set_bkg_2bpp_data(0, 1, pattern); + + // Load metasprite tile data into VRAM + set_sprite_2bpp_data(TILE_NUM_START, sizeof(sprite_data) >> 4, sprite_data); + + // show bkg and sprites + SHOW_SPRITES; + + // Check what size hardware sprite the metasprite is using (from sprite.h) + #if sprite_TILE_H == 16 + SPRITES_8x16; + #else + SPRITES_8x8; + #endif + DISPLAY_ON; + + // init 1 joypad + joypad_init(1, &joypads); + + // Set initial position, zero out speed + PosX = PosY = 64 << 4; + SpdX = SpdY = 0; + + hide = 0; jitter = 0; idx = 0; rot = 0; + + while(1) { + // poll joypads + joypad_ex(&joypads); + + PosF = 0; + // game object + if (joypads.joy0 & J_UP) { + SpdY -= 2; + if (SpdY < -32) SpdY = -32; + PosF |= ACC_Y; + } else if (joypads.joy0 & J_DOWN) { + SpdY += 2; + if (SpdY > 32) SpdY = 32; + PosF |= ACC_Y; + } + + if (joypads.joy0 & J_LEFT) { + SpdX -= 2; + if (SpdX < -32) SpdX = -32; + PosF |= ACC_X; + } else if (joypads.joy0 & J_RIGHT) { + SpdX += 2; + if (SpdX > 32) SpdX = 32; + PosF |= ACC_X; + } + + + // Press A button to show/hide metasprite + if ((joypads.joy0 & J_A) && (!jitter)) { + hide = (!hide); + jitter = 20; + } + + // Press B button to cycle through metasprite animations + if ((joypads.joy0 & J_B) && (!jitter) && (!hide)) { + idx++; if (idx >= (sizeof(sprite_metasprites) >> 1)) idx = 0; + jitter = 10; + } + + // Press SELECT button to cycle metasprite through Normal/Flip-Y/Flip-XY/Flip-X + if ((joypads.joy0 & J_SELECT) && (!jitter) && (!hide)) { + rot++; rot &= 3; + jitter = 20; + } + + // Hide/Animate/Flip input throttling + if (jitter) jitter--; + + PosX += SpdX, PosY += SpdY; + + uint8_t hiwater = 0; + + // NOTE: In a real game it would be better to only call the move_metasprite..() + // functions if something changed (such as movement or rotation). That + // reduces CPU usage on frames that don't need udpates. + // + // In this example they are called every frame to simplify the example code + + // Hide the metasprite or move it & apply any rotation settings + if (hide) + hide_metasprite(sprite_metasprites[idx], SPR_NUM_START); + else + hiwater = move_metasprite(sprite_metasprites[idx], TILE_NUM_START, SPR_NUM_START, (PosX >> 4), (PosY >> 4)); + + // Hide rest of the hardware sprites, because amount of sprites differ between animation frames. + hide_sprites_range(hiwater, 64); + + // Y Axis: update velocity (reduce speed) if no U/D button pressed + if (!(PosF & ACC_Y)) { + if (SpdY != 0) { + if (SpdY < 0) SpdY++; + else SpdY --; + } + } + + // X Axis: update velocity (reduce speed) if no L/R button pressed + if (!(PosF & ACC_X)) { + if (SpdX != 0) { + if (SpdX < 0) SpdX++; + else SpdX --; + } + } + + + // wait for VBlank to slow down everything and reduce cpu use when idle + wait_vbl_done(); + } +} + diff --git a/gbdk-lib/examples/sms/metasprites/sprite.c b/gbdk-lib/examples/sms/metasprites/sprite.c @@ -0,0 +1,59 @@ +//AUTOGENERATED FILE FROM png2mtspr + +#include <sms/sms.h> +#include <sms/metasprites.h> + +const UINT8 sprite_data[896] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x0d,0x0e,0x1f,0x10,0x3f,0x20,0x3f,0x20, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0xfd,0xfe,0x3f,0xc0,0xff,0x0c,0xff,0x13,0xf7,0x08,0xc1,0x3e, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x7f,0x9f,0xe0,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x80,0xff,0x40, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xf0,0xcf,0x3f,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0x3c,0xfc,0xf3,0x0f,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, +0x3f,0x20,0x3f,0x20,0x3f,0x20,0x3f,0x20,0x3f,0x20,0x3f,0x23,0x3d,0x23,0x5e,0x61,0x5e,0x61,0x7c,0x43,0x78,0x47,0x79,0x47,0xbb,0xc7,0xb3,0xcf,0xf2,0x8e,0xf4,0x8c, +0xc0,0x3f,0xc0,0x3f,0xc0,0x3f,0xcf,0x30,0xff,0x08,0xbf,0xc4,0xe7,0xdc,0x07,0xfc,0x02,0xff,0x03,0xff,0x00,0xff,0x87,0xff,0xff,0xff,0xc1,0xc1,0x01,0x01,0x00,0x00, +0xff,0x20,0x7f,0xa0,0x7f,0x90,0xff,0x10,0xff,0x10,0xdf,0x30,0xff,0x60,0xbf,0xc0,0xbd,0xc2,0x3c,0xc3,0x7e,0x81,0xff,0x80,0xff,0x80,0xbf,0xc0,0xff,0xc0,0xff,0xc0, +0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0x3f,0xc0,0x07,0xf8,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x40,0xff,0x40,0xff, +0xfe,0x02,0xfe,0x02,0xfd,0x03,0xff,0x01,0xff,0x01,0xff,0x01,0xff,0x00,0x7f,0x80,0x7f,0x80,0xff,0x00,0xfe,0x01,0xff,0x01,0xfd,0x03,0xfd,0x03,0x79,0x87,0x71,0x8f, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x40,0xc0,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xe0,0x20,0x60,0xa0,0x60,0xa0,0xa0,0xe0, +0xf4,0x8c,0xf4,0x8c,0xb4,0xcc,0xb8,0xc8,0xb8,0xc8,0x78,0x48,0x78,0x48,0x78,0x48,0x74,0x4c,0x5c,0x64,0x3c,0x24,0x3e,0x22,0x19,0x17,0x0b,0x0f,0x06,0x06,0x00,0x00, +0xdf,0xe0,0x7f,0x60,0x7e,0x61,0x6e,0x71,0x7e,0x71,0x7c,0x73,0x70,0x7f,0x78,0x7f,0x78,0x7f,0x78,0x7f,0x7c,0x7f,0x7c,0x7f,0x7c,0x7f,0xfb,0xfc,0xfb,0xfc,0x0f,0x0f, +0x70,0xff,0x4f,0xcf,0x41,0xc1,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x20,0xe0,0x20,0xe0,0x20,0xe0,0x20,0xe0,0x20,0xe0,0x10,0xf0,0x10,0xf0,0x90,0x70,0xd0,0x30,0xe0,0xe0, +0x02,0xff,0xfe,0xff,0xfe,0xff,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00, +0x01,0xff,0x01,0xff,0x01,0xff,0x01,0xff,0x01,0xff,0x82,0xfe,0x82,0xfe,0xc2,0xfe,0xc2,0xfe,0x42,0x7e,0x42,0x7e,0x42,0x7e,0x81,0xff,0xb9,0xc7,0xfd,0x83,0xfe,0xfe, +0x50,0x70,0x50,0x70,0x50,0x70,0x50,0x70,0x30,0x30,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x40,0xc0,0xc0,0x40,0xc0,0x40,0xe0,0x20,0x60,0xa0,0xb0,0xd0,0x70,0x50,0x50,0x70, +0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xf4,0x8c,0xf4,0x8c,0xf4,0x8c,0x78,0x88,0xe8,0x18,0xf0,0x10,0xf0,0x10,0xf0,0x10,0x70,0x90,0xf0,0x90,0xe8,0x98,0x78,0x48,0x64,0x5c,0x2c,0x3c,0x18,0x18,0x00,0x00, +0x38,0x28,0x38,0x28,0x28,0x38,0x18,0x18,0x18,0x18,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x40,0xc0,0xc0,0x40,0xe0,0x20,0xe0,0x20,0xf0,0x90,0xb0,0xd0,0x78,0x48,0x34,0x2c, +0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x03,0x02,0x03,0x02,0x05,0x06,0x07,0x04,0x07,0x04,0x07,0x04,0x07,0x04,0x05,0x06,0x03,0x02,0x02,0x03,0x01,0x01,0x00,0x00, +0x74,0x8c,0xf4,0x0c,0xe8,0x18,0xf8,0x18,0xd0,0x30,0xe0,0x20,0xc0,0x40,0x40,0xc0,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0xc0,0x40,0xc0,0x40,0xc0,0xc0,0xc0,0x00,0x00, +0x1c,0x14,0x0e,0x0a,0x07,0x05,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x03,0x02,0x07,0x04,0x07,0x04,0x0f,0x08,0x0f,0x09,0x15,0x1b,0x1e,0x12,0x1e,0x12,0x1a,0x16,0x12,0x1e,0x1e,0x1e,0x00,0x00, +0x74,0x8c,0xf4,0x0c,0xe8,0x18,0xf8,0x18,0xd0,0x30,0xe0,0x20,0xc0,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x03,0x02,0x07,0x04,0x0b,0x0c,0x0f,0x08,0x1f,0x11,0x1e,0x12,0x2a,0x36,0x3c,0x24,0x24,0x3c,0x28,0x38,0x38,0x38,0x00,0x00 +}; + +const metasprite_t sprite_metasprite0[] = { + {-24, -24, 0}, {0, 8, 2}, {0, 8, 4}, {0, 8, 6}, {0, 8, 8}, {0, 8, 0}, {16, -40, 10}, {0, 8, 12}, {0, 8, 14}, {0, 8, 16}, {0, 8, 16}, {0, 8, 18}, {0, 8, 20}, {16, -48, 22}, {0, 16, 24}, {0, 8, 26}, {0, 8, 28}, {0, 8, 30}, {0, 8, 32}, {metasprite_end} +}; + +const metasprite_t sprite_metasprite1[] = { + {-24, -24, 0}, {0, 8, 2}, {0, 8, 4}, {0, 8, 6}, {0, 8, 8}, {0, 8, 0}, {16, -40, 10}, {0, 8, 12}, {0, 8, 14}, {0, 8, 16}, {0, 8, 16}, {0, 8, 18}, {0, 8, 34}, {16, -56, 36}, {0, 8, 38}, {0, 16, 24}, {0, 8, 26}, {0, 8, 28}, {0, 8, 30}, {0, 8, 40}, {metasprite_end} +}; + +const metasprite_t sprite_metasprite2[] = { + {-24, -24, 0}, {0, 8, 2}, {0, 8, 4}, {0, 8, 6}, {0, 8, 8}, {0, 8, 0}, {16, -40, 10}, {0, 8, 12}, {0, 8, 14}, {0, 8, 16}, {0, 8, 16}, {0, 8, 18}, {0, 8, 42}, {16, -56, 44}, {0, 8, 46, 0}, {0, 16, 24}, {0, 8, 26}, {0, 8, 28}, {0, 8, 30}, {0, 8, 48}, {metasprite_end} +}; + +const metasprite_t sprite_metasprite3[] = { + {-24, -24, 0}, {0, 8, 2}, {0, 8, 4}, {0, 8, 6}, {0, 8, 8}, {0, 8, 0}, {16, -40, 10}, {0, 8, 12}, {0, 8, 14}, {0, 8, 16}, {0, 8, 16}, {0, 8, 18}, {0, 8, 34}, {16, -56, 50}, {0, 8, 52}, {0, 16, 24}, {0, 8, 26}, {0, 8, 28}, {0, 8, 30}, {0, 8, 40}, {metasprite_end} +}; + +const metasprite_t sprite_metasprite4[] = { + {-24, -24, 0}, {0, 8, 2}, {0, 8, 4}, {0, 8, 6}, {0, 8, 8}, {0, 8, 0}, {16, -40, 10}, {0, 8, 12}, {0, 8, 14}, {0, 8, 16}, {0, 8, 16}, {0, 8, 18}, {0, 8, 20}, {16, -56, 54}, {0, 8, 52}, {0, 16, 24}, {0, 8, 26}, {0, 8, 28}, {0, 8, 30}, {0, 8, 32}, {metasprite_end} +}; + +const metasprite_t* const sprite_metasprites[5] = { + sprite_metasprite0, sprite_metasprite1, sprite_metasprite2, sprite_metasprite3, sprite_metasprite4 +}; diff --git a/gbdk-lib/examples/sms/metasprites/sprite.h b/gbdk-lib/examples/sms/metasprites/sprite.h @@ -0,0 +1,9 @@ +//AUTOGENERATED FILE FROM png2mtspr +#define sprite_TILE_H 16 +#define sprite_WIDTH 64 +#define sprite_HEIGHT 48 +#define sprite_PIVOT_X 32 +#define sprite_PIVOT_Y 24 + +extern const UINT8 sprite_data[896]; +extern const metasprite_t* const sprite_metasprites[5]; diff --git a/gbdk-lib/include/sms/metasprites.h b/gbdk-lib/include/sms/metasprites.h @@ -0,0 +1,116 @@ +/** @file sms/metasprites.h + + # Metasprite support + + A metasprite is a larger sprite made up from a + collection of smaller individual hardware sprites. + Different frames of the same metasprites can share + tile data. + + The api supports metasprites in both + @ref SPRITES_8x8 and @ref SPRITES_8x16 mode. If + 8x16 mode is used then the height of the metasprite + must be a multiple of 16. + + The origin (pivot) for the metasprite is not required + to be in the upper left-hand corner as with regular + hardware sprites. + + Use the @ref utility_png2mtspr tool to convert single + or multiple frames of graphics into metasprite + structured data for use with the ...metasprite...() + functions. + + # Metasprites composed of variable numbers of sprites + + When using png2mtspr, it's common for the output of + different frames to be composed of different numbers + of hardware sprites (since it's trying to create each + frame as efficiently as possible). Due to that, it's + good practice to clear out (hide) unused sprites in the + shadow_OAM that have been set by previous frames. +*/ + +#ifndef _METASPRITES_H_INCLUDE +#define _METASPRITES_H_INCLUDE + +#include <gb/hardware.h> +#include <stdint.h> + +/** Metasprite sub-item structure + @param dy (int8_t) Y coordinate of the sprite relative to the metasprite origin (pivot) + @param dx (int8_t) X coordinate of the sprite relative to the metasprite origin (pivot) + @param dtile (uint8_t) Start tile relative to the metasprites own set of tiles + + Metasprites are built from multiple metasprite_t items (one for each sub-sprite) + and a pool of tiles they reference. If a metasprite has multiple frames then each + frame will be built from some number of metasprite_t items (which may vary based + on how many sprites are required for that particular frame). + + A metasprite frame is terminated with a {metasprite_end} entry. +*/ +typedef struct metasprite_t { + int8_t dy, dx; + uint8_t dtile; +} metasprite_t; + +#define metasprite_end -128 + +extern const void * __current_metasprite; +extern uint8_t __current_base_tile; +extern uint8_t __render_shadow_OAM; + + +static uint8_t __move_metasprite(uint8_t id, uint8_t x, uint8_t y) __z88dk_callee __preserves_regs(iyh,iyl); +static void __hide_metasprite(uint8_t id) __z88dk_fastcall __preserves_regs(iyh,iyl); + +/** + * Hides all hardware sprites in range from <= X < to + * @param from start OAM index + * @param to finish OAM index + */ +void hide_sprites_range(UINT8 from, UINT8 to) __z88dk_callee __preserves_regs(iyh,iyl); + +/** Moves metasprite to the absolute position x and y + + @param metasprite Pointer to the first struct of the metasprite (for the desired frame) + @param base_tile Number of the first tile where the metasprite's tiles start + @param base_sprite Number of the first hardware sprite to be used by the metasprite + @param x Absolute x coordinate of the sprite + @param y Absolute y coordinate of the sprite + + Moves __metasprite__ to the absolute position __x__ and __y__ + (with __no flip__ on the X or Y axis). Hardware sprites are + allocated starting from __base_sprite__, using tiles + starting from __base_tile__. + + Sets: + \li __current_metasprite = metasprite; + \li __current_base_tile = base_tile; + + Note: Overwrites OAM sprite properties (such as CGB Palette), see + @ref metasprite_and_sprite_properties "Metasprites and sprite properties". + + @return Number of hardware sprites used to draw this metasprite + */ +inline uint8_t move_metasprite(const metasprite_t * metasprite, uint8_t base_tile, uint8_t base_sprite, uint8_t x, uint8_t y) { + __current_metasprite = metasprite; + __current_base_tile = base_tile; + return __move_metasprite(base_sprite, x, y); +} + +/** Hides a metasprite from the screen + + @param metasprite Pointer to first struct of the desired metasprite frame + @param base_sprite Number of hardware sprite to start with + + Sets: + \li __current_metasprite = metasprite; + + **/ +inline void hide_metasprite(const metasprite_t * metasprite, uint8_t base_sprite) { + __current_metasprite = metasprite; + __hide_metasprite(base_sprite); +} + +#endif diff --git a/gbdk-lib/libc/targets/gbz80/metasprites.s b/gbdk-lib/libc/targets/gbz80/metasprites.s @@ -27,7 +27,7 @@ ___move_metasprite:: ld b, a ld a, (hl-) ld c, a - ld a, (hl-) + ld a, (hl) add a add a ld e, a diff --git a/gbdk-lib/libc/targets/gbz80/metasprites_flip.s b/gbdk-lib/libc/targets/gbz80/metasprites_flip.s @@ -17,7 +17,7 @@ ___move_metasprite_hflip:: ld b, a ld a, (hl-) ld c, a - ld a, (hl-) + ld a, (hl) add a add a ld e, a @@ -74,7 +74,7 @@ ___move_metasprite_vflip:: ld b, a ld a, (hl-) ld c, a - ld a, (hl-) + ld a, (hl) add a add a ld e, a @@ -131,7 +131,7 @@ ___move_metasprite_hvflip:: ld b, a ld a, (hl-) ld c, a - ld a, (hl-) + ld a, (hl) add a add a ld e, a diff --git a/gbdk-lib/libc/targets/z80/gg/Makefile b/gbdk-lib/libc/targets/z80/gg/Makefile @@ -10,6 +10,7 @@ CSRC = ASSRC = outi.s vmemcpy.s \ set_data.s set_2bpp_data.s \ set_tile_map.s set_tile_map_xy.s set_tile_map_compat.s set_tile_map_xy_compat.s \ + metasprites.s metasprites_hide.s metasprites_hide_spr.s \ palette.s \ pad.s pad_ex.s \ int.s nmi.s \ diff --git a/gbdk-lib/libc/targets/z80/metasprites.s b/gbdk-lib/libc/targets/z80/metasprites.s @@ -0,0 +1,82 @@ + .include "global.s" + + .title "Metasprites" + .module Metasprites + + .area _DATA + +___current_metasprite:: + .ds 0x02 +___current_base_tile:: + .ds 0x01 + + .area _INITIALIZED +___render_shadow_OAM:: + .ds 0x01 + + .area _INITIALIZER + .db #>_shadow_OAM + + .area _CODE + +; uint8_t __move_metasprite(uint8_t id, uint8_t x, uint8_t y) __z88dk_callee __preserves_regs(iyh,iyl); + +___move_metasprite:: + ld hl, #4 + add hl, sp + + ld b, (hl) + dec hl + ld c, (hl) + dec hl + ld e, (hl) + + ld hl, (___current_metasprite) + + ld a, (___render_shadow_OAM) + ld d, a +1$: + ld a, (hl) ; dy + inc hl + cp #0x80 + jr z, 2$ + add b + ld b, a + cp #0xD0 + jp nz, 3$ + ld a, #0xC0 +3$: + ld (de), a + + push de + + ld a, e + add a + add #0x40 + ld e, a + + ld a, (hl) ; dx + inc hl + add c + ld c, a + ld (de), a + inc e + + ld a, (___current_base_tile) + add (hl) ; tile + inc hl + ld (de), a + + pop de + inc e + + jr 1$ +2$: + pop hl + pop bc + inc sp + push hl + ld a, e + sub c + ld l, a + ret diff --git a/gbdk-lib/libc/targets/z80/metasprites_hide.s b/gbdk-lib/libc/targets/z80/metasprites_hide.s @@ -0,0 +1,37 @@ + .include "global.s" + + .title "Metasprites" + .module Metasprites + + .globl ___current_metasprite, ___render_shadow_OAM + + .area _CODE + + +; void __hide_metasprite(uint8_t id) __z88dk_fastcall __preserves_regs(iyh,iyl); + +___hide_metasprite:: + ld e, l + + ld hl, (___current_metasprite) + + ld bc, #3 + + ld a, (___render_shadow_OAM) + ld d, a +1$: + ld a, (hl) + cp #0x80 + ret z + + ld a, #0x40 + cp e + ret nc + + add hl, bc + + ld a, #0xC0 + ld (de), a + + inc e + jp 1$ diff --git a/gbdk-lib/libc/targets/z80/metasprites_hide_spr.s b/gbdk-lib/libc/targets/z80/metasprites_hide_spr.s @@ -0,0 +1,41 @@ + .include "global.s" + + .title "Metasprites" + .module Metasprites + + .globl ___render_shadow_OAM + + .area _CODE + +; void hide_sprites_range(UINT8 from, UINT8 to) __z88dk_callee __preserves_regs(iyh,iyl); + +_hide_sprites_range:: + pop hl + pop de + push hl + + ld a, d + cp #64 + ret nc + + sub e + ret c + ret z + + ld c, a + xor a + ld b, a + + ld hl, #___render_shadow_OAM + ld h, (hl) + ld l, e + + ld d, h + inc e + ld (hl), #0xC0 + + dec c + ret z + + ldir + ret diff --git a/gbdk-lib/libc/targets/z80/sms/Makefile b/gbdk-lib/libc/targets/z80/sms/Makefile @@ -10,6 +10,7 @@ CSRC = ASSRC = outi.s vmemcpy.s \ set_data.s set_2bpp_data.s \ set_tile_map.s set_tile_map_xy.s set_tile_map_compat.s set_tile_map_xy_compat.s \ + metasprites.s metasprites_hide.s metasprites_hide_spr.s \ palette.s \ pad.s pad_ex.s \ int.s nmi.s \

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.