From 1d4c4ddf32e9de6e60881d549b3cc2cb4ed43cd9 Mon Sep 17 00:00:00 2001 From: nino-porcino Date: Wed, 22 Dec 2021 18:41:38 +0100 Subject: [PATCH] add sprite functions --- README.md | 21 +++++++++++++++++++++ lib/sprites.h | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/README.md b/README.md index 08737b7..8152a44 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,27 @@ tms_write_reg(7, 0x1F); byte oldvalue = tms_regs_latch[7]; ``` +### Working with sprites + +```c +// set 8x8 or 16x16 sprites +tms_set_sprite_double_size(0); + +// set single pixel or double pixel sprites +tms_set_sprite_magnification(1); + +// define the sprite pattern 0 +tms_copy_to_vram(ghost, 8, TMS_SPRITE_PATTERNS); + +// define a sprite using the "sprite" struct +tms_sprite spr; +spr.x = 100; +spr.y = 50; +spr.name = 0; // pattern 0 +spr.color = COLOR_BLACK; +tms_set_sprite(0, &spr); +``` + #### Working directly with the I/O chip interface If you want to program the VDP directly you can use the following utility functions: diff --git a/lib/sprites.h b/lib/sprites.h index bbe9a42..44fe62e 100644 --- a/lib/sprites.h +++ b/lib/sprites.h @@ -1,5 +1,39 @@ #ifndef SPRITES_H #define SPRITES_H + +typedef struct { + byte y; + byte x; + byte name; + byte color; +} tms_sprite; + +#define SIZEOF_SPRITE 4 + +void tms_set_sprite(byte sprite_num, tms_sprite *s) { + word addr = TMS_SPRITE_ATTRS + (word) (sprite_num * SIZEOF_SPRITE); + tms_set_vram_write_addr(addr); + + // TODO verify NOPs on real machine + // TODO is it better to use tms_copy_to_vram() ? + TMS_WRITE_DATA_PORT(s->y); NOP; // y coordinate + TMS_WRITE_DATA_PORT(s->x); NOP; // x coordinate + TMS_WRITE_DATA_PORT(s->name); NOP; // name + TMS_WRITE_DATA_PORT(s->color); NOP; // color +} + +void tms_set_sprite_double_size(byte size) { + byte regval = tms_regs_latch[1] & (REG1_SIZE_MASK ^ 0xFF); + if(size) regval |= REG1_SIZE_MASK; + tms_write_reg(1, regval); +} + +void tms_set_sprite_magnification(byte m) { + byte regval = tms_regs_latch[1] & (REG1_MAG_MASK ^ 0xFF); + if(m) regval |= REG1_MAG_MASK; + tms_write_reg(1, regval); +} + // clears all the sprites void tms_clear_sprites() { // fills first sprite pattern with 0