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/screen1.h b/lib/screen1.h index 26d933a..133e561 100644 --- a/lib/screen1.h +++ b/lib/screen1.h @@ -9,11 +9,8 @@ const word SCREEN1_SIZE = (32*24); void screen1_load_font() { byte *source = FONT; - // start writing into VRAM from space character (32..127) - tms_set_vram_write_addr(TMS_PATTERN_TABLE+(32*8)); - for(word i=768;i!=0;i--) { - TMS_WRITE_DATA_PORT(*source++); - } + // copy normal FONT 32..127 + tms_copy_to_vram(source, 768, TMS_PATTERN_TABLE+(32*8)); // reverse font (32..127) source = FONT; diff --git a/lib/sprites.h b/lib/sprites.h index 65374cf..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 @@ -11,10 +45,10 @@ void tms_clear_sprites() { // set sprite coordinates to (0,0) and set pattern name 0 tms_set_vram_write_addr(TMS_SPRITE_ATTRS); for(byte i=0;i<32;i++) { - TMS_WRITE_DATA_PORT((6+i)*8); NOP; NOP; NOP; NOP; // y coordinate - TMS_WRITE_DATA_PORT((6+i)*8); NOP; NOP; NOP; NOP; // x coordinate - TMS_WRITE_DATA_PORT(0); NOP; NOP; NOP; NOP; // name - TMS_WRITE_DATA_PORT(i); NOP; NOP; NOP; NOP; // color + TMS_WRITE_DATA_PORT(0); NOP; NOP; NOP; NOP; // y coordinate + TMS_WRITE_DATA_PORT(0); NOP; NOP; NOP; NOP; // x coordinate + TMS_WRITE_DATA_PORT(0); NOP; NOP; NOP; NOP; // name + TMS_WRITE_DATA_PORT(0); NOP; NOP; NOP; NOP; // color } } #endif diff --git a/lib/tms9918.h b/lib/tms9918.h index b99321d..33ecfa3 100644 --- a/lib/tms9918.h +++ b/lib/tms9918.h @@ -164,6 +164,15 @@ inline void tms_wait_end_of_frame() { while(!FRAME_BIT(TMS_READ_CTRL_PORT)); } +// loads the font on the pattern table +void tms_copy_to_vram(byte *source, word size, word dest) { + // start writing into VRAM from space character (32..127) + tms_set_vram_write_addr(dest); + for(word i=size;i!=0;i--) { + TMS_WRITE_DATA_PORT(*source++); + } +} + #include "apple1.h" #include "font8x8.h" #include "sprites.h"