// C64 Flying Toasters #include<stdio.h> #include<stdlib.h> #include<stdbool.h> #include "c64.h" #include "types.h" #define MAXTOASTERS 4 #define SWIDTH 39 #define SHEIGHT 24 #define INRANGE(x, low, high) \ x>=low && x<=high void initToasters(toaster *farToaster, toaster *nearToaster) { int i; _randomize(); for(i = 0; i < MAXTOASTERS; i++) { farToaster[i].x = rand() % SWIDTH; farToaster[i].y = (rand() % (SHEIGHT - 2))+1; farToaster[i].oldX = farToaster[i].x; farToaster[i].oldY = farToaster[i].y; farToaster[i].speed = 1; farToaster[i].frameSpeed = 2; farToaster[i].frame = 0; farToaster[i].color = (rand() % 15) + 1; farToaster[i].frameHeight = 2; farToaster[i].frameWidth = 2; farToaster[i].maxFrame = 3; farToaster[i].frames[0] = farFrame0; farToaster[i].frames[1] = farFrame1; farToaster[i].frames[2] = farFrame2; nearToaster[i].x = rand() % SWIDTH; nearToaster[i].y = (rand() % (SHEIGHT - 3))+1; nearToaster[i].oldX = nearToaster[i].x; nearToaster[i].oldY = nearToaster[i].y; nearToaster[i].speed = 2; nearToaster[i].frameSpeed = 1; nearToaster[i].frame = 0; nearToaster[i].color = (rand() % 15) + 1; nearToaster[i].frameHeight = 3; nearToaster[i].frameWidth = 3; nearToaster[i].maxFrame = 3; nearToaster[i].frames[0] = nearFrame0; nearToaster[i].frames[1] = nearFrame1; nearToaster[i].frames[2] = nearFrame2; } } void initScreen() { CLRSCR; SET_COLORS(C64_COLOR_BLACK,C64_COLOR_BLACK,C64_COLOR_GREEN); GRAPHICS_ON; } bool checkLayerCollision(int x, int y, toaster *layer) { int i; if(layer == NULL) { return false; } for(i = 0; i < MAXTOASTERS; i++) { if(INRANGE(x, layer[i].x, layer[i].x+layer[i].frameWidth) && INRANGE(y, layer[i].y, layer[i].y+layer[i].frameHeight)) { return true; } } return false; } void drawFrame(toaster *target, toaster *prevLayer) { int i,j,edge,frame; edge = target->oldX+target->frameWidth-target->speed; frame = target->maxFrame > 1 ? target->frame : 0; for(j=0; j<target->frameHeight; j++) { for(i=0; i<target->frameWidth; i++) { if(checkLayerCollision(target->x+i, target->y+j, prevLayer)) { continue; } if((INRANGE(target->x+i, 0, SWIDTH)) && (INRANGE(target->y+j, 0, SHEIGHT))) { POKE_INK(target->x+i, target->y+j, target->color); WRITE_CHAR(BASE_SCREEN_ADDRESS, target->x+i, target->y+j, target->frames[frame][(j*target->frameWidth)+i]); } } if((INRANGE(edge, 0, SWIDTH)) && (INRANGE(target->oldY+j, 0, SHEIGHT))) { WRITE_CHAR(BASE_SCREEN_ADDRESS, edge, target->oldY+j, ' '); if(target->speed == 2) { WRITE_CHAR(BASE_SCREEN_ADDRESS, edge+1, target->oldY+j, ' '); } } } } void drawToasters(toaster *farToaster, toaster *nearToaster) { int i; for(i = 0; i < MAXTOASTERS; i++) { drawFrame(&nearToaster[i], NULL); } for(i = 0; i < MAXTOASTERS; i++) { drawFrame(&farToaster[i], &nearToaster[0]); } } void moveToasters(toaster *farToaster, toaster *nearToaster) { int i; for(i = 0; i < MAXTOASTERS; i++) { farToaster[i].oldX = farToaster[i].x; farToaster[i].oldY = farToaster[i].y; farToaster[i].x -= farToaster[i].speed; if(farToaster[i].x < 0-farToaster[i].frameWidth) { farToaster[i].x = SWIDTH; farToaster[i].y = (rand() % (SHEIGHT - farToaster[i].frameHeight))+1; farToaster[i].color = (rand() % 15) + 1; } farToaster[i].frame++; farToaster[i].frame = farToaster[i].frame % farToaster[i].maxFrame; nearToaster[i].oldX = nearToaster[i].x; nearToaster[i].oldY = nearToaster[i].y; nearToaster[i].x -= nearToaster[i].speed; if(nearToaster[i].x < 0-nearToaster[i].frameWidth) { nearToaster[i].x = SWIDTH; nearToaster[i].y = (rand() % (SHEIGHT - nearToaster[i].frameHeight))+1; nearToaster[i].color = (rand() % 15) + 1; } nearToaster[i].frame++; nearToaster[i].frame = nearToaster[i].frame % nearToaster[i].maxFrame; } } bool pollInput() { unsigned char key, joy1, joy2; key = GET_PKEY_VIEW; joy1 = GET_JOY1; joy2 = GET_JOY2; if((joy1 & C64_JOYSTICK_BUTTON) == 0) { return false; } if((joy2 & C64_JOYSTICK_BUTTON) == 0) { return false; } switch(key) { case PKEY_NOKEY: break; case PKEY_Q: return false; break; default: break; } CLRKEY; return true; } int main(void) { toaster farToasters[MAXTOASTERS], nearToasters[MAXTOASTERS]; bool isRunning = true; initScreen(); initToasters(&farToasters[0], &nearToasters[0]); // Main Loop while(isRunning) { drawToasters(&farToasters[0], &nearToasters[0]); moveToasters(&farToasters[0], &nearToasters[0]); isRunning = pollInput(); } CLRSCR; return 0; }