From 66017f83165916f71b7b5e5c63b1e68e5619a0c2 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Tue, 9 Aug 2022 09:47:55 -0500 Subject: [PATCH] c64: presets --- presets/c64/climber.c | 11 ++-- presets/c64/common.c | 10 ++- presets/c64/common.h | 6 +- presets/c64/joymove.c | 115 +++++++++++++-------------------- presets/c64/rasterirq.ca65 | 8 ++- presets/c64/scroll4.c | 11 ++-- presets/c64/scroll5.c | 4 +- presets/c64/scrolling.c | 3 +- presets/c64/scrolling.h | 15 +++++ presets/c64/sprite_collision.c | 4 +- presets/c64/sprite_test.c | 10 +-- presets/c64/sprites.c | 8 ++- presets/c64/sprites.h | 4 +- presets/c64/spritesinborder.c | 6 +- src/platform/c64.ts | 1 + test/cli/testworker.js | 3 +- 16 files changed, 119 insertions(+), 100 deletions(-) diff --git a/presets/c64/climber.c b/presets/c64/climber.c index fc775437..c776ea3f 100644 --- a/presets/c64/climber.c +++ b/presets/c64/climber.c @@ -385,8 +385,9 @@ void refresh_floor(byte floor) { byte explode_timer = 0; +#define SPRITE_SHAPE_FIRST 192 #define SPRITE_XPLODE 7 -#define SHAPE_XPLODE0 (32+10) +#define SHAPE_XPLODE0 (SPRITE_SHAPE_FIRST+10) #define NUM_XPLODE_SHAPES 3 void explode(int x, byte y) { @@ -459,7 +460,7 @@ void draw_actor(byte i) { a->onscreen = 0; return; // offscreen vertically } - name = 32 + (a->state - WALKING); + name = SPRITE_SHAPE_FIRST + (a->state - WALKING); switch (a->state) { case INACTIVE: a->onscreen = 0; @@ -760,9 +761,9 @@ void play_scene() { // main display list void game_displaylist(void) { - VIC.bordercolor = 2; +// VIC.bordercolor = 2; sid_update(); - VIC.bordercolor = 0; +// VIC.bordercolor = 0; // DLIST_NEXT(42); // VIC.bordercolor = 3; DLIST_RESTART(20); @@ -777,7 +778,7 @@ void main() { // set up sprites sprite_clear(); for (i=0; i #include #include -#include #include +#include #include +#include #include -/*{w:24,h:21,bpp:1,brev:1}*/ -const char sprite[3*21] = { - 0x00,0x7F,0x00,0x01,0xFF,0xC0,0x03,0xFF,0xE0, - 0x03,0xE7,0xE0,0x07,0xD9,0xF0,0x07,0xDF,0xF0, - 0x07,0xD9,0xF0,0x03,0xE7,0xE0,0x03,0xFF,0xE0, - 0x03,0xFF,0xE0,0x02,0xFF,0xA0,0x01,0x7F,0x40, - 0x01,0x3E,0x40,0x00,0x9C,0x80,0x00,0x9C,0x80, - 0x00,0x49,0x00,0x00,0x49,0x00,0x00,0x3E,0x00, - 0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,0x1C,0x00 +/*{w:24,h:21,bpp:1,brev:1,count:1}*/ +const char SPRITE_DATA[64] = { + 0x0f,0xff,0x80,0x17,0xff,0x40,0x2b,0xfe, + 0xa0,0x7f,0xff,0xf0,0xff,0xc0,0x3f,0xe0, + 0x3f,0xc0,0x17,0xbe,0xc0,0x2d,0x7f,0xf0, + 0x2b,0x7f,0xf8,0x2a,0xff,0xf8,0x15,0xf6, + 0x00,0x3f,0xf8,0x00,0xfd,0xfc,0x00,0xfd, + 0xff,0x00,0xfe,0xff,0x80,0xff,0x7f,0xc0, + 0xff,0xff,0xc0,0xff,0xff,0xc0,0x0a,0xa8, + 0x00,0x0f,0xf8,0x00,0x0f,0xff,0x80,0x03, }; -/*{w:12,h:21,bpp:2,brev:1}*/ -const char spritemc[3*21] = { - 0x00,0xFF,0xC0,0x03,0xFF,0xF0,0x0F,0xFF,0xFC, - 0x0F,0xFB,0xFC,0x0F,0xEE,0xFC,0x0F,0xEF,0xFC, - 0x0F,0xEE,0xFC,0x0F,0xFB,0xFC,0x0F,0xFF,0xFC, - 0x09,0xFF,0xD8,0x08,0x7F,0x48,0x08,0x1D,0x08, - 0x02,0x0C,0x20,0x02,0x0C,0x20,0x02,0x0C,0x20, - 0x00,0x8C,0x80,0x00,0x8C,0x80,0x00,0x55,0x40, - 0x00,0x77,0x40,0x00,0x5D,0x40,0x00,0x15,0x00 +/*{w:12,h:21,bpp:2,brev:1,count:1,aspect:2}*/ +const char SPRITE_MC_DATA[64] = { + 0x0a,0xaa,0x80,0x0a,0xaa,0x80,0x2a,0xaa, + 0xa0,0x2a,0xaa,0xa0,0xaa,0xaa,0xaa,0xff, + 0xd5,0x40,0x0d,0xd7,0x40,0x3d,0xd5,0x54, + 0x37,0x55,0x54,0x37,0x55,0x54,0x35,0x55, + 0x00,0x3a,0xa0,0x00,0xea,0xa8,0x00,0xab, + 0xaa,0x00,0xab,0xaa,0x00,0xab,0xaa,0x80, + 0xaa,0xea,0x80,0xaa,0xaa,0x80,0x0f,0xfc, + 0x00,0x0f,0xfc,0x00,0x0f,0xff,0xc0,0x83, }; -// Raster wait with line argument -void rasterWait(unsigned char line) { - while (VIC.rasterline < line) ; -} +void main(void) { + // variables + int x = 172; // sprite X position (16-bit) + char y = 145; // sprite Y position (8-bit) + char bgcoll; // sprite background collision flags + char joy; // joystick flags -int main (void) -{ - int n; - int x,y; - char bgcoll; // install the joystick driver joy_install (joy_static_stddrv); - // set background color - VIC.bgcolor0 = 3; - // clear interrupts to avoid glitching - __asm__("SEI"); - // set sprite bitmap data - for (n = 0 ; n < sizeof(sprite) ; n++) { - POKE(0x340 + n, sprite[n]); - POKE(0x380 + n, spritemc[n]); - } - // enable 1st and 2nd sprite - VIC.spr_ena = 0x03; - VIC.spr_mcolor = 0x02; - // set colors - VIC.spr_mcolor0 = 4; - VIC.spr_mcolor1 = 7; - // 2x zoom 1st sprite - VIC.spr_exp_x = 0x01; - VIC.spr_exp_y = 0x01; - // set address of sprite data - POKE(0x7f8, 13); - POKE(0x7f9, 14); - // set initial x/y positions - x = 160; - y = 128; - // loop + // copy sprite pattern to RAM address 0x3800 + memcpy((char*)0x3800, SPRITE_DATA, sizeof(SPRITE_DATA)); + // set sprite #0 shape entry (224) + POKE(0x400 + 0x3f8, 0x3800 / 64); + // enable sprite #0 + VIC.spr_ena = 0b00000001; + + // loop forever while (1) { // get joystick bits - char joy = joy_read(0); - // move sprite based on arrow keys + joy = joy_read(0); + // move sprite based on joystick if (JOY_LEFT(joy)) --x; if (JOY_UP(joy)) --y; if (JOY_RIGHT(joy)) ++x; if (JOY_DOWN(joy)) ++y; - // set VIC registers based on position + // set sprite registers based on position VIC.spr0_x = x; - VIC.spr0_y = y-32; - VIC.spr1_x = x; - VIC.spr1_y = y+32; - VIC.spr_hi_x = (x & 256) ? 1 : 0; - // change color when we collide with background + VIC.spr0_y = y; + VIC.spr_hi_x = (x & 256) ? 1 : 0; // set X hi bit? + // grab and reset collision flags bgcoll = VIC.spr_bg_coll; - VIC.spr0_color = (bgcoll & 1) ? 10 : 0; - VIC.spr1_color = (bgcoll & 2) ? 10 : 0; + // change color when we collide with background + VIC.spr0_color = (bgcoll & 1) ? 10 : 3; // wait for end of frame - rasterWait(255); + waitvsync(); } - // uninstall joystick driver (not really necessary) - joy_uninstall(); - return EXIT_SUCCESS; } diff --git a/presets/c64/rasterirq.ca65 b/presets/c64/rasterirq.ca65 index ad58d1fb..e9aca76d 100644 --- a/presets/c64/rasterirq.ca65 +++ b/presets/c64/rasterirq.ca65 @@ -78,7 +78,13 @@ DLIST_ACK: clc rts .else - JMP $EA31 ; jump into KERNAL's standard interrupt service routine to handle keyboard scan, cursor display etc. + pla + tay + pla + tax + pla + rti ; return from interrupt +; JMP $EA31 ; jump into KERNAL's standard interrupt service routine to handle keyboard scan, cursor display etc. .endif NullDlist: diff --git a/presets/c64/scroll4.c b/presets/c64/scroll4.c index 7c3c07c7..ca859611 100644 --- a/presets/c64/scroll4.c +++ b/presets/c64/scroll4.c @@ -45,13 +45,13 @@ void scroll_draw_row(byte row) { /*{w:24,h:21,bpp:1,brev:1}*/ const char SPRITE1[3*21] = { - 0x00,0x7F,0x00,0x01,0xFF,0xC0,0x03,0xFF,0xE0, + 0x80,0x7F,0x01,0x01,0xFF,0xC0,0x03,0xFF,0xE0, 0x03,0xE7,0xE0,0x07,0xD9,0xF0,0x07,0xDF,0xF0, 0x07,0xD9,0xF0,0x03,0xE7,0xE0,0x03,0xFF,0xE0, 0x03,0xFF,0xE0,0x02,0xFF,0xA0,0x01,0x7F,0x40, 0x01,0x3E,0x40,0x00,0x9C,0x80,0x00,0x9C,0x80, 0x00,0x49,0x00,0x00,0x49,0x00,0x00,0x3E,0x00, - 0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,0x1C,0x00 + 0x00,0x3E,0x00,0x00,0x3E,0x00,0x80,0x1C,0x01 }; void main(void) { @@ -69,7 +69,7 @@ void main(void) { // setup sprite library and copy sprite to VIC bank sprite_clear(); - sprite_shape(hidbuf, 32, SPRITE1); + sprite_shape(192, SPRITE1); // install the joystick driver joy_install (joy_static_stddrv); @@ -87,7 +87,10 @@ void main(void) { if (JOY_RIGHT(joy)) scroll_horiz(speed); if (JOY_DOWN(joy)) scroll_vert(speed); // animate sprite in shadow sprite ram - sprite_draw(0, n++, 70, 32); + //VIC.ctrl1 |= 0x08; // 24 lines + //VIC.ctrl2 |= 0x08; // 38 columns + sprite_draw(0, n++, 70, 192); + sprite_draw(0, 172, 145, 192); // wait for vblank wait_vblank(); // update scroll registers diff --git a/presets/c64/scroll5.c b/presets/c64/scroll5.c index a032114a..b9fab836 100644 --- a/presets/c64/scroll5.c +++ b/presets/c64/scroll5.c @@ -60,7 +60,7 @@ int camerax = 0; int cameray = 0; void update_player() { - sprite_draw(0, playerx-camerax+160, playery-cameray+140, 32); + sprite_draw(0, playerx-camerax+160, playery-cameray+140, 192); } void camera_follow(byte moving) { @@ -96,7 +96,7 @@ void main(void) { // setup sprite library and copy sprite to VIC bank sprite_clear(); - sprite_shape(hidbuf, 32, SPRITE1); + sprite_shape(192, SPRITE1); sprshad.spr_color[0] = 13; // install the joystick driver diff --git a/presets/c64/scrolling.c b/presets/c64/scrolling.c index 45788e80..b4f5c6f0 100644 --- a/presets/c64/scrolling.c +++ b/presets/c64/scrolling.c @@ -115,7 +115,6 @@ void scroll_left(void) { ++origin_x; scroll_draw_column(COLS-1); swap_needed = true; - VIC.bordercolor = 0; } void scroll_up(void) { @@ -171,7 +170,7 @@ void scroll_vert(sbyte delta_y) { void scroll_setup(void) { scroll_fine_x = scroll_fine_y = 0; - origin_x = origin_y = 0x80; + origin_x = origin_y = 0; swap_needed = true; copy_needed = true; diff --git a/presets/c64/scrolling.h b/presets/c64/scrolling.h index a12ec19c..60dc25ff 100644 --- a/presets/c64/scrolling.h +++ b/presets/c64/scrolling.h @@ -30,4 +30,19 @@ void scroll_update(void); void scroll_draw_column(byte col); void scroll_draw_row(byte row); + +/* incremental scrolling library */ +extern int pixofs_x; // X scroll pixel offset +extern int pixofs_y; // Y scroll pixel offset + +void scroll_start(byte dir); +void scroll_finish(void); +void scroll_refresh(void); + +#define SCROLL_LEFT 1 +#define SCROLL_RIGHT 2 +#define SCROLL_UP 4 +#define SCROLL_DOWN 8 + + #endif diff --git a/presets/c64/sprite_collision.c b/presets/c64/sprite_collision.c index 7b299c16..fe051da7 100644 --- a/presets/c64/sprite_collision.c +++ b/presets/c64/sprite_collision.c @@ -43,7 +43,7 @@ void move_sprites(void) { byte i; for (i=0; i<8; i++) { //VIC.bordercolor = i; - sprite_draw(i, (xpos[i]>>7)+0x80, (ypos[i]>>8)+0x80, 255); + sprite_draw(i, (xpos[i]>>7)+0x80, (ypos[i]>>8)+0x80, 192); // update position xpos[i] += xvel[i]; ypos[i] += yvel[i]; @@ -134,7 +134,7 @@ void main(void) { // setup sprite library and copy sprite to VIC bank sprite_clear(); - sprite_shape((void*)0x0, 255, SPRITEMC); + sprite_shape(192, SPRITEMC); // set colors sprshad.spr_mcolor = 0xff; diff --git a/presets/c64/sprite_test.c b/presets/c64/sprite_test.c index 23f8a3b1..85e6d54c 100644 --- a/presets/c64/sprite_test.c +++ b/presets/c64/sprite_test.c @@ -32,15 +32,17 @@ const char SPRITE_MC_DATA[64] = { }; void main(void) { + // clear the screen + clrscr(); // copy sprite pattern to RAM address 0x3800 memcpy((char*)0x3800, SPRITE_DATA, sizeof(SPRITE_DATA)); - // set sprite shape entry (224) + // set sprite #0 shape entry (224) POKE(0x400 + 0x3f8, 0x3800 / 64); - // set X and Y coordinate + // set X and Y coordinate for sprite #0 VIC.spr_pos[0].x = 172; VIC.spr_pos[0].y = 145; - // set color + // set color for sprite #0 VIC.spr_color[0] = COLOR_GREEN; - // enable sprite 0 + // enable sprite #0 VIC.spr_ena = 0b00000001; } diff --git a/presets/c64/sprites.c b/presets/c64/sprites.c index 5c52ed8d..c0822884 100644 --- a/presets/c64/sprites.c +++ b/presets/c64/sprites.c @@ -20,12 +20,14 @@ void sprite_update(char* screenmem) { VIC.spr_mcolor = sprshad.spr_mcolor; } -void sprite_shape(char* vicbank, byte index, const char* sprite_data) { - memcpy(vicbank + index*64, sprite_data, 64); +void sprite_shape(byte index, const char* sprite_data) { + memcpy(get_vic_bank_start() + index * 64, + sprite_data, + 64); } const byte BITS[8] = { - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; void sprite_draw(byte i, word x, byte y, byte shape) { diff --git a/presets/c64/sprites.h b/presets/c64/sprites.h index 158b94a7..54f1d43e 100644 --- a/presets/c64/sprites.h +++ b/presets/c64/sprites.h @@ -3,8 +3,6 @@ #include "common.h" -#define DEFAULT_SCREEN ((void*)0x400) - typedef struct { struct { byte x; /* X coordinate */ @@ -24,7 +22,7 @@ extern SpriteShadow sprshad; void sprite_clear(void); void sprite_update(char* screenmem); -void sprite_shape(char* vicbank, byte index, const char* sprite_data); +void sprite_shape(byte index, const char* sprite_data); void sprite_draw(byte i, word x, byte y, byte shape); byte sprite_get_closest_collision(byte i, byte spr_coll); diff --git a/presets/c64/spritesinborder.c b/presets/c64/spritesinborder.c index cb532a0d..6c741168 100644 --- a/presets/c64/spritesinborder.c +++ b/presets/c64/spritesinborder.c @@ -4,6 +4,7 @@ #include #include +//#link "common.c" #include "common.h" //#link "rasterirq.ca65" @@ -25,6 +26,7 @@ const char spriteshape[3*21] = { void dlist_example(void) { static byte i = 0; + VIC.bordercolor = 6; VIC.bordercolor = 5; VIC.ctrl1 = 0x18; @@ -50,13 +52,13 @@ void main(void) { clrscr(); sprite_clear(); - sprite_shape((void*)0x400, 32/2, spriteshape); + sprite_shape(192, spriteshape); // set colors sprshad.spr_exp_x = 0xff; for (i=0; i<8; i++) { sprshad.spr_color[i] = i+3; - sprite_draw(i, i*38+24, 248, 32); + sprite_draw(i, i*38+24, 248, 192); } // TODO: can't do in IRQ diff --git a/src/platform/c64.ts b/src/platform/c64.ts index 9518d9d2..d52bf947 100644 --- a/src/platform/c64.ts +++ b/src/platform/c64.ts @@ -9,6 +9,7 @@ const C64_PRESETS = [ {id:'eliza.c', name:'Eliza (C)'}, {id:'tgidemo.c', name:'TGI Graphics Demo (C)'}, {id:'upandaway.c', name:'Up, Up and Away (C)'}, + {id:'sprite_test.c', name:'Sprite Setup (C)'}, {id:'joymove.c', name:'Joystick Movement (C)'}, {id:'siegegame.c', name:'Siege Game (C)'}, {id:'scroll1.c', name:'Scrolling 1 (C)'}, diff --git a/test/cli/testworker.js b/test/cli/testworker.js index 43fd983c..73ba5d6d 100644 --- a/test/cli/testworker.js +++ b/test/cli/testworker.js @@ -44,6 +44,7 @@ async function doBuild(msgs, callback, outlen, nlines, nerrors, options) { } assert.ok(err.msg); } + if (nerrors != msg.errors.length) console.log(msg); assert.equal(nerrors, msg.errors.length); } else { assert.equal(nerrors||0, 0); @@ -242,7 +243,7 @@ describe('Worker', function() { }); it('should compile C64 cc65 skeleton', function(done) { var csource = ab2str(fs.readFileSync('presets/c64/skeleton.cc65')); - compile('cc65', csource, 'c64.wasm', done, 2663, 2, 0); + compile('cc65', csource, 'c64.wasm', done, 3001, 3, 0); }); it('should compile zmachine inform6 skeleton', function(done) { var csource = ab2str(fs.readFileSync('presets/zmachine/skeleton.inform6'));