1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-04-09 21:37:31 +00:00

working on sprite movement

This commit is contained in:
Jesper Gravgaard 2019-06-12 16:38:56 +02:00
parent 440da0eaee
commit 8b3264fffa

View File

@ -1,13 +1,20 @@
// Black Hole at the center of the BASIC screen sucking in any letters
// Black Hole at the center of the BASIC screen sucking in letters
import "c64"
import "multiply"
// Address of the screen
const byte* SCREEN = 0x0400;
// Copy of the screen used for finding chars to process
byte[1000] SCREEN_COPY;
// Max number of chars processed at once
const byte NUM_PROCESSING = 8;
// Sprite data for the animating sprites
const align(64) byte[NUM_PROCESSING*64] SPRITE_DATA;
// Struct holding char being processed
struct ProcessingChar {
// x-position (0-39)
@ -21,23 +28,43 @@ struct ProcessingChar {
// Distance value meaning not found
const word NOT_FOUND = 0xffff;
// Struct holding sprite being processed
struct ProcessingSprite {
// sprite x-position (24-336)
word x;
// sprite y-position (30-228)
byte y;
// sprite ID (0-7)
byte id;
// sprite pointer (0-255)
byte ptr;
// status of the processing (0: free, 1: new, 2: processing)
byte status;
// Pointer to screen char being processed (used for deletion)
byte* screenPtr;
};
// Values for ProcessingSprite.status
const byte STATUS_FREE = 0;
const byte STATUS_NEW = 1;
const byte STATUS_PROCESSING = 2;
// Sprites currently being processed in the interrupt
struct ProcessingSprite[NUM_PROCESSING] PROCESSING;
void main() {
// Init processing array
for( byte i: 0..NUM_PROCESSING-1 ) PROCESSING[i] = { 0, 0, NOT_FOUND };
for( byte i: 0..NUM_PROCESSING-1 ) PROCESSING[i] = { 0, 0, 0, 0, STATUS_FREE, 0};
// Clear sprites
for( byte* sp = SPRITE_DATA; sp<SPRITE_DATA+sizeof(SPRITE_DATA); sp++) *sp = 0;
// Set-up raster interrupts
setupRasterIrq(RASTER_IRQ_TOP, &irqTop);
// Fill screen with some chars
//for( byte* sc: SCREEN..SCREEN+999) *sc = 'a'+(<sc&0x1f);
// Copy screen to screen copy
for( byte* src=SCREEN, dst=SCREEN_COPY; src!=SCREEN+1000; src++, dst++) *dst = *src;
// Init squares table
initSquareTables();
// Main loop
do {
// Look for the non-space closest to the screen center
@ -49,43 +76,63 @@ void main() {
do {
(*(SCREEN+999))++;
} while (true);
}
const byte NUM_PROCESSING = 16;
// Chars currently being processed in the interrupt
struct ProcessingChar[NUM_PROCESSING] PROCESSING;
// Start processing a char - by inserting it into the PROCESSING array
void startProcessing(struct ProcessingChar center) {
// Busy-wait while finding an empty slot in the PROCESSING array
byte freeIdx = 0xff;
do {
for( byte i: 0..NUM_PROCESSING-1 ) {
if(PROCESSING[i].dist==NOT_FOUND) {
if(PROCESSING[i].status==STATUS_FREE) {
freeIdx = i;
break;
}
}
} while (freeIdx==0xff);
// Put the char into the PROCESSING array
PROCESSING[freeIdx] = center;
// Found a free sprite
byte spriteIdx = freeIdx;
// Copy char into sprite
// TODO: Copy chargen data
byte* spriteData = SPRITE_DATA+(word)spriteIdx*64;
for( byte i: 0..7) *spriteData++ = 0xff;
word spriteX = 24 + (word)center.x*8;
byte spriteY = 30 + center.y*8;
byte spritePtr = (byte)(SPRITE_DATA/64)+spriteIdx;
byte* screenPtr = SCREEN+(word)center.y*40+center.x;
// Put the sprite into the PROCESSING array
PROCESSING[spriteIdx] = { spriteX, spriteY, spriteIdx, spritePtr, STATUS_NEW, screenPtr };
}
// Process any chars in the PROCESSING array
void processChars() {
for( byte i: 0..NUM_PROCESSING-1 ) {
if(PROCESSING[i].dist!=NOT_FOUND) {
struct ProcessingChar processing = PROCESSING[i];
*(COLS+(word)processing.y*40+processing.x) = WHITE;
byte* processing_ptr = SCREEN+(word)processing.y*40+processing.x;
if(*processing_ptr==' ')
PROCESSING[i].dist = NOT_FOUND;
else if(*processing_ptr>' ')
(*processing_ptr)--;
else // must be <' '
(*processing_ptr)++;
if(PROCESSING[i].status!=STATUS_FREE) {
if(PROCESSING[i].status==STATUS_NEW) {
// Clear the char on the screen
*PROCESSING[i].screenPtr = ' ';
// Enable the sprite
*SPRITES_ENABLE |= 1<<PROCESSING[i].id;
// Set sprite pointer
*(SCREEN+SPRITE_PTRS+PROCESSING[i].id) = PROCESSING[i].ptr;
// Set status
PROCESSING[i].status = STATUS_PROCESSING;
}
// Set sprite position
if(>PROCESSING[i].x) {
*SPRITES_XMSB |= (1<<PROCESSING[i].id);
} else {
*SPRITES_XMSB &= 0xff ^ (1<<PROCESSING[i].id);
}
SPRITES_XPOS[i<<2] = (byte)PROCESSING[i].x;
SPRITES_YPOS[i<<2] = PROCESSING[i].y;
// Move sprite
if(--(PROCESSING[i].x)==0) {
// Set status
PROCESSING[i].status = STATUS_FREE;
// Disable the sprite
*SPRITES_ENABLE &= 0xff ^ (1<<PROCESSING[i].id);
}
}
}
}