diff --git a/demos/demo/cbm_balloon.data.h b/demos/demo/cbm_balloon.data.h new file mode 100644 index 0000000..896e7a7 --- /dev/null +++ b/demos/demo/cbm_balloon.data.h @@ -0,0 +1,65 @@ +// file generated automatically by mkfont.js -- do not edit + 0b00001111, + 0b00111111, + 0b01111111, + 0b01111100, + 0b11111011, + 0b11111011, + 0b11111011, + 0b01111100, + 0b01111111, + 0b01111111, + 0b01011111, + 0b00101111, + 0b00100111, + 0b00010011, + 0b00010011, + 0b00001001, + 0b11100000, + 0b11111000, + 0b11111100, + 0b11111100, + 0b00111110, + 0b11111110, + 0b00111110, + 0b11111100, + 0b11111100, + 0b11111100, + 0b11110100, + 0b11101000, + 0b11001000, + 0b10010000, + 0b10010000, + 0b00100000, + 0b00001001, + 0b00000111, + 0b00000111, + 0b00000111, + 0b00000011, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00100000, + 0b11000000, + 0b11000000, + 0b11000000, + 0b10000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, diff --git a/demos/demo/cbm_balloon.h b/demos/demo/cbm_balloon.h new file mode 100644 index 0000000..daff455 --- /dev/null +++ b/demos/demo/cbm_balloon.h @@ -0,0 +1,7 @@ +// file generated automatically by mkfont.js -- do not edit +const byte cbm_balloon[] = { + +#include "cbm_balloon.data.h" + +}; + diff --git a/demos/demo/demo.c b/demos/demo/demo.c index b1f8de0..74d8c05 100644 --- a/demos/demo/demo.c +++ b/demos/demo/demo.c @@ -2,6 +2,7 @@ #include "demo_screen1.h" #include "demo_screen2.h" +#include "demo_balloon.h" #include "demo_amiga_hand.h" #include "demo_interrupt.h" #include "demo_extvid.h" @@ -14,6 +15,7 @@ void help() { "=============\r" "1 SCREEN1\r" "2 SCREEN2\r" + "3 BALLOON\r" "A AMIGA HAND\r" "I INTERRUPT\r" "E FLIP EXT VIDEO\r" @@ -26,7 +28,7 @@ void help() { void main() { -#ifdef APPLE1 +#ifdef APPLE1_JUKEBOX apple1_eprom_init(); #endif @@ -34,6 +36,7 @@ void main() { for(;;) { if(key == '1') demo_screen1(); else if(key == '2') demo_screen2(); + else if(key == '3') demo_balloon(); else if(key == 'A') demo_amiga_hand(); else if(key == 'I') demo_interrupt(); else if(key == 'E') flip_external_input(); diff --git a/demos/demo/demo_balloon.h b/demos/demo/demo_balloon.h new file mode 100644 index 0000000..e82a8f5 --- /dev/null +++ b/demos/demo/demo_balloon.h @@ -0,0 +1,136 @@ +#include + +// the balloon sprite, manually copied from C64 User's guide +#include "cbm_balloon.h" + +// a balloon is two 16x16 sprites, one above the other +typedef struct { + int x; // x coordinate of the balloon + int y; // y coordinate of the balloon + int dx; // x velocity of the balloon + int dy; // y velocity of the balloon + byte color; // color of the balloon + byte sprite_number; // sprite number (0-31) of the balloon + tms_sprite upper; // the upper sprite portion of the balloon + tms_sprite lower; // the lower sprite portion of the balloon +} balloon; + +// move ballon on the screen by its velocity +// and make it bounce over the borders +void animate_balloon(balloon *b) { + + // use temporary variables as KickC has issues dealing with "->" operator + int x = b->x; + int y = b->y; + int dx = b->dx; + int dy = b->dy; + + // border collision detection + if(x>=240 || x<=0) dx = -dx; + if(y>=172 || y<=0) dy = -dy; + + // move the balloon + x += dx; + y += dy; + + // write back temporary variables + b->x = x; + b->y = y; + b->dx = dx; + b->dy = dy; + + // update the sprite part of the balloon + b->upper.x = (byte) x; + b->upper.y = (signed char) y; + b->upper.name = 0; + b->upper.color = b->color; + b->lower.x = b->upper.x; + b->lower.y = b->upper.y + 16; // 16 pixels below the upper sprite + b->lower.name = b->upper.name + 4; + b->lower.color = b->color; + tms_set_sprite(b->sprite_number, &(b->upper)); + tms_set_sprite(b->sprite_number+1, &(b->lower)); +} + +void demo_balloon() { + tms_init_regs(SCREEN2_TABLE); + + // we use only 4 sprites, two for each ot the two balloons on the screen + tms_set_total_sprites(4); + + // fake C64 bootup screen colors + tms_set_color(COLOR_LIGHT_BLUE); + byte text_color = FG_BG(COLOR_GREY,COLOR_DARK_BLUE); // alas, COLOR_LIGHT_BLUE doesn't fit well so we use GREY instead + + screen2_init_bitmap(text_color); + + // C64-like screen text + screen2_puts("*** COMMODORE-APPLE BASIC V2 ***", 0, 0, text_color); + screen2_puts("38911 BASIC BYTES FREE" , 0, 2, text_color); + screen2_puts("READY." , 0, 4, text_color); + + // copy the ballon graphic to VRAM + tms_copy_to_vram(cbm_balloon, 4*8*2, TMS_SPRITE_PATTERNS); + + tms_set_sprite_double_size(1); // set 16x16 sprites + tms_set_sprite_magnification(0); // set single pixel sprites + + // we have two balloons bouncing around the screen + + // first balloon + balloon b1; + b1.x = 20; + b1.y = 20; + b1.dx = 1; + b1.dy = 1; + b1.color = COLOR_LIGHT_YELLOW; + b1.sprite_number = 0; + + // second balloon + balloon b2; + b2.x = 150; + b2.y = 150; + b2.dx = -1; + b2.dy = -1; + b2.color = COLOR_LIGHT_RED; + b2.sprite_number = 2; + + // counter for a fake blinking cursor + byte blink_counter=0; + + for(;;) { + + // delay the animation + for(int delay=0; delay<400; delay++) { + delay = delay+1; + delay = delay-1; + } + + // RETURN key ends the demo + if(apple1_readkey()==0x0d) break; + + // if there's a collision invert the motion of the balloons + if(COLLISION_BIT(TMS_READ_CTRL_PORT)) { + int temp; + temp = b1.dx; b1.dx = -temp; // b1.dx = -b1.dx; // due to KickC issue + temp = b1.dy; b1.dy = -temp; // b1.dy = -b1.dy; // due to KickC issue + temp = b2.dx; b2.dx = -temp; // b2.dx = -b2.dx; // due to KickC issue + temp = b2.dy; b2.dy = -temp; // b2.dy = -b2.dy; // due to KickC issue + } + + // move the two balloons + animate_balloon(&b1); + animate_balloon(&b2); + + // since a balloon is made of two sprites, sometimes they overlap + // by one line during the move, causing a false collision + // so we clear the collision bit by simply reading the status register + tms_clear_collisions(); + + // fake a blinking cursor + blink_counter++; + if(blink_counter == 16) { screen2_puts(" ", 0, 5, FG_BG(COLOR_DARK_BLUE,COLOR_GREY)); } + if(blink_counter == 32) { screen2_puts(" ", 0, 5, FG_BG(COLOR_GREY,COLOR_DARK_BLUE)); blink_counter = 0; } + } +} + diff --git a/demos/demo/demo_screen2.h b/demos/demo/demo_screen2.h index 542c899..e2f7f95 100644 --- a/demos/demo/demo_screen2.h +++ b/demos/demo/demo_screen2.h @@ -28,23 +28,6 @@ void demo_screen2() { screen2_line(18+5+5, 45,232+5+5,187); screen2_line(18+5+5,187,232+5+5, 45); - screen2_plot_mode = PLOT_MODE_SET; - - // define sprites using bitmap fonts - tms_copy_to_vram(&FONT[64*8], 32*8, TMS_SPRITE_PATTERNS); - - // set 16x16 sprites - tms_set_sprite_double_size(1); - - // set double pixel sprites - tms_set_sprite_magnification(1); - - tms_sprite spr; - for(byte t=0;t<32;t++) { - spr.x = 10 + t*32; - spr.y = 5 + t*32; - spr.name = t; - spr.color = t+1; - tms_set_sprite(t, &spr); - } + screen2_plot_mode = PLOT_MODE_SET; } + diff --git a/demos/demo/mk_baloon.js b/demos/demo/mk_baloon.js new file mode 100644 index 0000000..cd6e276 --- /dev/null +++ b/demos/demo/mk_baloon.js @@ -0,0 +1,120 @@ +function e(s) { + let b = 0; + for(let t=0;t