mirror of
https://github.com/nippur72/apple1-videocard-lib.git
synced 2024-12-22 13:30:38 +00:00
improve sprites and balloon demo
This commit is contained in:
parent
0b2ff3eb8a
commit
75b96830b4
@ -1,62 +1,136 @@
|
||||
#include <font8x8.h>
|
||||
|
||||
// the balloon sprite, manually copied from C64 User's guide
|
||||
#include "cbm_balloon.h"
|
||||
|
||||
void move_balloon(byte x, byte y, byte color) {
|
||||
tms_sprite spr0,spr1;
|
||||
spr0.x = x;
|
||||
spr0.y = y;
|
||||
spr0.name = 0;
|
||||
spr0.color = color;
|
||||
spr1.x = spr0.x;
|
||||
spr1.y = spr0.y + 16*1;
|
||||
spr1.name = spr0.name + 4;
|
||||
spr1.color = spr0.color;
|
||||
tms_set_sprite(0, &spr0);
|
||||
tms_set_sprite(1, &spr1);
|
||||
// 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);
|
||||
tms_set_color(COLOR_LIGHT_BLUE);
|
||||
|
||||
byte text_color = FG_BG(COLOR_GREY,COLOR_DARK_BLUE);
|
||||
// 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);
|
||||
// 12345678901234567890123456789012
|
||||
|
||||
// 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);
|
||||
screen2_puts(" " , 0, 5, FG_BG(COLOR_DARK_BLUE,COLOR_GREY));
|
||||
|
||||
// ballon demo
|
||||
|
||||
// define sprites using bitmap fonts
|
||||
|
||||
// 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 double pixel sprites
|
||||
|
||||
int x = 200;
|
||||
int y = 80;
|
||||
int dx = 1;
|
||||
int dy = 1;
|
||||
int delay = 0;
|
||||
byte sprcolor = COLOR_LIGHT_YELLOW;
|
||||
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(;;) {
|
||||
for(delay=0; delay<800; delay++) {
|
||||
|
||||
// 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(x>=228 || x<=0) { dx = -dx; sprcolor++; }
|
||||
if(y>=148 || y<=0) { dy = -dy; sprcolor++; }
|
||||
|
||||
x += dx;
|
||||
y += dy;
|
||||
move_balloon((byte)x,(byte)y, COLOR_WHITE);
|
||||
// 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; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,24 +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<4;t++) {
|
||||
spr.x = 200;
|
||||
spr.y = 5 + t*32;
|
||||
spr.name = t*4;
|
||||
spr.color = t+1;
|
||||
tms_set_sprite(t, &spr);
|
||||
}
|
||||
screen2_plot_mode = PLOT_MODE_SET;
|
||||
}
|
||||
|
||||
|
@ -48,12 +48,12 @@ void screen1_scroll_up() {
|
||||
}
|
||||
|
||||
void screen1_prepare() {
|
||||
// clear all the sprites
|
||||
tms_set_total_sprites(0);
|
||||
|
||||
// fill name table with spaces (32)
|
||||
screen1_cls();
|
||||
|
||||
// clear all the sprites
|
||||
tms_clear_sprites();
|
||||
|
||||
// fill pattern table with 0
|
||||
tms_set_vram_write_addr(TMS_PATTERN_TABLE);
|
||||
for(word i=256*8;i!=0;i--) {
|
||||
|
@ -10,8 +10,8 @@ const word SCREEN2_SIZE = (32*24);
|
||||
|
||||
// prepare the screen 2 to be used as a bitmap
|
||||
void screen2_init_bitmap(byte color) {
|
||||
// erases all the sprites
|
||||
tms_clear_sprites();
|
||||
// clear all the sprites
|
||||
tms_set_total_sprites(0);
|
||||
|
||||
// fill pattern table with 0 (clear screen)
|
||||
tms_set_vram_write_addr(TMS_PATTERN_TABLE);
|
||||
|
@ -2,13 +2,22 @@
|
||||
#define SPRITES_H
|
||||
|
||||
typedef struct {
|
||||
byte y;
|
||||
signed char y;
|
||||
byte x;
|
||||
byte name;
|
||||
byte color;
|
||||
} tms_sprite;
|
||||
|
||||
#define SIZEOF_SPRITE 4
|
||||
#define SPRITE_OFF_MARKER 0xD0
|
||||
#define EARLY_CLOCK 128
|
||||
|
||||
void tms_set_total_sprites(byte num) {
|
||||
// write the value 0xD0 as Y coordinate of the first unused sprite
|
||||
word addr = TMS_SPRITE_ATTRS + (word) (num * SIZEOF_SPRITE);
|
||||
tms_set_vram_write_addr(addr);
|
||||
TMS_WRITE_DATA_PORT(SPRITE_OFF_MARKER); // 0xD0 oi the sprite off indicator
|
||||
}
|
||||
|
||||
void tms_set_sprite(byte sprite_num, tms_sprite *s) {
|
||||
word addr = TMS_SPRITE_ATTRS + (word) (sprite_num * SIZEOF_SPRITE);
|
||||
@ -34,21 +43,8 @@ void tms_set_sprite_magnification(byte m) {
|
||||
tms_write_reg(1, regval);
|
||||
}
|
||||
|
||||
// clears all the sprites
|
||||
void tms_clear_sprites() {
|
||||
// fills first sprite pattern with 0
|
||||
tms_set_vram_write_addr(TMS_SPRITE_PATTERNS);
|
||||
for(byte i=0;i<8;i++) {
|
||||
TMS_WRITE_DATA_PORT(0);
|
||||
}
|
||||
|
||||
// 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(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
|
||||
}
|
||||
// clear the collision flag by reading the status register
|
||||
inline void tms_clear_collisions() {
|
||||
asm { lda VDP_REG };
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user