gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
commit 23c7efba2837f8761eee6f797baa50684550fe95 parent 87776e0b465a2b4f86d1343b3ebf51c102aae323 Author: Toxa <untoxa@mail.ru> Date: Fri, 22 Jan 2021 11:43:55 +0300 metasprites support Diffstat:
| A | gbdk-lib/examples/gb/metasprites/Makefile | 17 | +++++++++++++++++ |
| A | gbdk-lib/examples/gb/metasprites/metasprites.c | 180 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | gbdk-lib/include/gb/metasprites.h | 56 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | gbdk-lib/libc/gb/Makefile | 1 | + |
| A | gbdk-lib/libc/gb/metasprites.s | 126 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
5 files changed, 380 insertions(+), 0 deletions(-)
diff --git a/gbdk-lib/examples/gb/metasprites/Makefile b/gbdk-lib/examples/gb/metasprites/Makefile @@ -0,0 +1,17 @@ +CC = ../../../bin/lcc -Wa-l -Wl-m -Wl-j + +BINS = metasprites.gb + +all: $(BINS) + +make.bat: Makefile + @echo "REM Automatically generated from Makefile" > make.bat + @make -sn | sed y/\\//\\\\/ | grep -v make >> make.bat + +# Compile and link single file in one pass +%.gb: %.c + $(CC) -o $@ $< + +clean: + rm -f *.o *.lst *.map *.gb *~ *.rel *.cdb *.ihx *.lnk *.sym *.asm *.noi + diff --git a/gbdk-lib/examples/gb/metasprites/metasprites.c b/gbdk-lib/examples/gb/metasprites/metasprites.c @@ -0,0 +1,179 @@ +#include <gb/gb.h> +#include <gb/sgb.h> +#include <gb/metasprites.h> + +#include <stdio.h> + +UINT8 sprite_data[] = { +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 metasprite0 = { + 19, + { + {0, 0, 8, 0, 0}, {1, 0, 16, 2, 0}, {1, 0, 24, 4, 0}, {1, 0, 32, 6, 0}, {1, 0, 40, 8, 0}, {1, 0, 48, 0, 32}, + {1, 16, 8, 10, 0}, {1, 16, 16, 12, 0}, {1, 16, 24, 14, 0}, {1, 16, 32, 16, 0}, {1, 16, 40, 16, 32}, {1, 16, 48, 18, 0}, {1, 16, 56, 20, 0}, + {1, 32, 8, 22, 0}, {1, 32, 24, 24, 0}, {1, 32, 32, 26, 0}, {1, 32, 40, 28, 0}, {1, 32, 48, 30, 0}, {1, 32, 56, 32, 0}, + {metasprite_end} + } +}; +const metasprite_t metasprite1 = { + 20, + { + {0, 0, 8, 0, 0}, {1, 0, 16, 2, 0}, {1, 0, 24, 4, 0}, {1, 0, 32, 6, 0}, {1, 0, 40, 8, 0}, {1, 0, 48, 0, 32}, + {1, 16, 8, 10, 0}, {1, 16, 16, 12, 0}, {1, 16, 24, 14, 0}, {1, 16, 32, 16, 0}, {1, 16, 40, 16, 32}, {1, 16, 48, 18, 0}, {1, 16, 56, 34, 0}, + {1, 32, 0, 36, 0}, {1, 32, 8, 38, 0}, {1, 32, 24, 24, 0}, {1, 32, 32, 26, 0}, {1, 32, 40, 28, 0}, {1, 32, 48, 30, 0}, {1, 32, 56, 40, 0}, + {metasprite_end} + } +}; +const metasprite_t metasprite2 = { + 20, + { + {0, 0, 8, 0, 0}, {1, 0, 16, 2, 0}, {1, 0, 24, 4, 0}, {1, 0, 32, 6, 0}, {1, 0, 40, 8, 0}, {1, 0, 48, 0, 32}, + {1, 16, 8, 10, 0}, {1, 16, 16, 12, 0}, {1, 16, 24, 14, 0}, {1, 16, 32, 16, 0}, {1, 16, 40, 16, 32}, {1, 16, 48, 18, 0}, {1, 16, 56, 42, 0}, + {1, 32, 0, 44, 0}, {1, 32, 8, 46, 0}, {1, 32, 24, 24, 0}, {1, 32, 32, 26, 0}, {1, 32, 40, 28, 0}, {1, 32, 48, 30, 0}, {1, 32, 56, 48, 0}, + {metasprite_end} + } +}; +const metasprite_t metasprite3 = { + 20, + { + {0, 0, 8, 0, 0}, {1, 0, 16, 2, 0}, {1, 0, 24, 4, 0}, {1, 0, 32, 6, 0}, {1, 0, 40, 8, 0}, {1, 0, 48, 0, 32}, + {1, 16, 8, 10, 0}, {1, 16, 16, 12, 0}, {1, 16, 24, 14, 0}, {1, 16, 32, 16, 0}, {1, 16, 40, 16, 32}, {1, 16, 48, 18, 0}, {1, 16, 56, 34, 0}, + {1, 32, 0, 50, 0}, {1, 32, 8, 52, 0}, {1, 32, 24, 24, 0}, {1, 32, 32, 26, 0}, {1, 32, 40, 28, 0}, {1, 32, 48, 30, 0}, {1, 32, 56, 40, 0}, + {metasprite_end} + } +}; +const metasprite_t metasprite4 = { + 20, + { + {0, 0, 8, 0, 0}, {1, 0, 16, 2, 0}, {1, 0, 24, 4, 0}, {1, 0, 32, 6, 0}, {1, 0, 40, 8, 0}, {1, 0, 48, 0, 32}, + {1, 16, 8, 10, 0}, {1, 16, 16, 12, 0}, {1, 16, 24, 14, 0}, {1, 16, 32, 16, 0}, {1, 16, 40, 16, 32}, {1, 16, 48, 18, 0}, {1, 16, 56, 20, 0}, + {1, 32, 0, 54, 0}, {1, 32, 8, 52, 0}, {1, 32, 24, 24, 0}, {1, 32, 32, 26, 0}, {1, 32, 40, 28, 0}, {1, 32, 48, 30, 0}, {1, 32, 56, 32, 0}, + {metasprite_end} + } +}; +const metasprite_t * const metasprites[] = { &metasprite0, &metasprite1, &metasprite2, &metasprite3, &metasprite4, &metasprite3, &metasprite2, &metasprite1 }; + +joypads_t joypads; + +#define ACC_X 1 +#define ACC_Y 2 + +// sprite coords +UINT16 PosX, PosY; +INT16 SpdX, SpdY; +UINT8 PosF; +UINT8 hide, jitter; +UINT8 idx; + +// main funxction +void main(void) { + puts("D-Pad: Move\nA : hide\nB : animate"); + + // init palettes + BGP_REG = OBP0_REG = OBP1_REG = 0xE4; + + // load tile data into VRAM + set_sprite_data(0, sizeof(sprite_data) >> 4, sprite_data); + + // set sprite tile + set_sprite_tile(0, 0); + + // show bkg and sprites + SPRITES_8x16; SHOW_SPRITES; + + // init 2 joypads + joypad_init(1, &joypads); + + PosX = PosY = 64 << 4; + SpdX = SpdY = 0; + + hide = 0; jitter = 0; idx = 0; + + while(1) { + // poll joypads + joypad_ex(&joypads); + + PosF = 0; + // game object + if (joypads.joy0 & J_UP) { + SpdY -= 2; + if (SpdY < -64) SpdY = -64; + PosF |= ACC_Y; + } else if (joypads.joy0 & J_DOWN) { + SpdY += 2; + if (SpdY > 64) SpdY = 64; + PosF |= ACC_Y; + } + if (joypads.joy0 & J_LEFT) { + SpdX -= 2; + if (SpdX < -64) SpdX = -64; + PosF |= ACC_X; + } else if (joypads.joy0 & J_RIGHT) { + SpdX += 2; + if (SpdX > 64) SpdX = 64; + PosF |= ACC_X; + } + if ((joypads.joy0 & J_A) && (!jitter)) { + hide = (!hide); + jitter = 10; + } + if ((joypads.joy0 & J_B) && (!jitter) && (!hide)) { + idx++; if (idx >= 8) idx = 0; + jitter = 10; + } + + // anti-jitter + if (jitter) jitter--; + + PosX += SpdX, PosY += SpdY; + + // hide or move sprite + if (hide) hide_metasprite(metasprites[idx], 0); else move_metasprite(metasprites[idx], 0, 0, PosX >> 4, PosY >> 4); + + // hide rest of the hardware sprites, because amount of sprites differ between animation frames + for (UBYTE i = metasprites[idx]->count; i < 40; i++) shadow_OAM[i].y = 0; + + if (!(PosF & ACC_Y)) { + if (SpdY >= 0) { + if (SpdY) SpdY--; + } else SpdY ++; + } + if (!(PosF & ACC_X)) { + if (SpdX >= 0) { + if (SpdX) SpdX--; + } else SpdX ++; + } + + // wait for VBlank to slow down everything + wait_vbl_done(); + } +} + diff --git a/gbdk-lib/include/gb/metasprites.h b/gbdk-lib/include/gb/metasprites.h @@ -0,0 +1,55 @@ +#ifndef _METASPRITES_H_INVCLUDE +#define _METASPRITES_H_INVCLUDE + +/** + * metasprite item description + */ +typedef struct metasprite_item_t { + INT8 did; + INT8 dy, dx; + UINT8 dtile; + UINT8 props; +} metasprite_item_t; + +/** + * Metasprite description + */ +typedef struct metasprite_t { + UINT8 count; + metasprite_item_t items[]; +} metasprite_t; + +#define metasprite_end 0 + +extern const void * __current_metasprite; +extern UBYTE __current_base_tile; +extern UBYTE __render_shadow_OAM; + +static UBYTE __move_metasprite(UINT8 id, UINT8 x, UINT8 y); +static void __hide_metasprite(UINT8 id); + +/** + * Moves metasprite to the absolute position x and y, allocating hardware sprites from base_sprite using tiles from bast_tile + * @param metasprite metasprite description + * @param base_tile start tile where tiles for that metasprite begin + * @param base_sprite start hardware sprite + * @param x absolute x coordinate of the sprite + * @param y absolute y coordinate of the sprite + **/ +inline UBYTE move_metasprite(const void * metasprite, UINT8 base_tile, UINT8 base_sprite, UINT8 x, UINT8 y) { + __current_metasprite = metasprite; + __current_base_tile = base_tile; + return __move_metasprite(base_sprite, x, y); +} + +/** + * Hides metasprite from screen + * @param metasprite metasprite description + * @param base_sprite start hardware sprite + **/ +inline void hide_metasprite(const void * metasprite, UINT8 base_sprite) { + __current_metasprite = metasprite; + __hide_metasprite(base_sprite); +} + +#endif + diff --git a/gbdk-lib/libc/gb/Makefile b/gbdk-lib/libc/gb/Makefile @@ -29,6 +29,7 @@ ASSRC = cgb.s cpy_data.s \ mode.s clock.s \ get_t.s set_t.s init_vram.s \ fill_rect.s fill_rect_bk.s fill_rect_wi.s \ + metasprites.s \ crt0.s ifeq ($(ASM),asxxxx) diff --git a/gbdk-lib/libc/gb/metasprites.s b/gbdk-lib/libc/gb/metasprites.s @@ -0,0 +1,126 @@ + .include "global.s" + + .title "Metasprites" + .module Metasprites + + .area _DATA + +___current_metasprite:: + .ds 0x02 +___current_base_tile:: + .ds 0x01 +___render_shadow_OAM:: + .ds 0x01 + + .area _GSINIT + + ld a, #>_shadow_OAM + ld (___render_shadow_OAM), a + + .area _CODE + +; UBYTE __move_metasprite(UINT8 id, UINT8 x, UINT8 y) + +___move_metasprite:: + ldhl sp, #4 + ld a, (hl-) + ld b, a + ld a, (hl-) + ld c, a + ld a, (hl-) + add a + add a + ld e, a + + ld hl, #___current_metasprite + ld a, (hl+) + ld h, (hl) + ld l, a + push hl + + inc hl + + ld a, (___render_shadow_OAM) + ld d, a + + ld a, (hl+) + inc a +1$: + dec a + add a + add a + add e + ld e, a + + ld a, (hl+) ; dy + add b + ld (de), a + inc e + + ld a, (hl+) ; dx + add c + ld (de), a + inc e + + ld a, (___current_base_tile) + add (hl) ; tile + inc hl + ld (de), a + inc e + + ld a, (hl+) ; props + ld (de), a + inc e + + ld a, (hl+) + or a + jr nz, 1$ + + pop hl + ld e,(hl) + + ret + +; void __hide_metasprite(UINT8 id) + +___hide_metasprite:: + ldhl sp, #2 + ld a, (hl-) + add a + add a + ld e, a + + ld hl, #___current_metasprite + ld a, (hl+) + ld h, (hl) + ld l, a + inc hl + + ld bc, #4 + + ld a, (___render_shadow_OAM) + ld d, a + + ld a, (hl+) + inc a +1$: + dec a + add a + add a + add e + ld e, a + + xor a + ld (de), a + + inc e + inc e + inc e + inc e + add hl, bc + + ld a, (hl+) + or a + jr nz, 1$ + + ret
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.