2017-03-27 15:21:17 +00:00
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
typedef unsigned char byte;
|
|
|
|
typedef signed char sbyte;
|
2017-04-13 19:48:37 +00:00
|
|
|
typedef unsigned short word;
|
|
|
|
typedef enum { false, true } bool;
|
|
|
|
|
|
|
|
byte __at (0x0) vidmem[152][256]; // 304x256x4bpp video memory
|
|
|
|
byte __at (0xc000) palette[16];
|
|
|
|
volatile byte __at (0xc804) input0;
|
|
|
|
volatile byte __at (0xc806) input1;
|
|
|
|
volatile byte __at (0xc80c) input2;
|
|
|
|
byte __at (0xc900) rom_select;
|
|
|
|
volatile byte __at (0xcb00) video_counter;
|
|
|
|
byte __at (0xcbff) watchdog0x39;
|
|
|
|
byte __at (0xcc00) nvram[0x400];
|
|
|
|
|
|
|
|
__sfr __at (0) debug;
|
|
|
|
|
|
|
|
// blitter flags
|
|
|
|
#define SRCSCREEN 0x1
|
|
|
|
#define DSTSCREEN 0x2
|
|
|
|
#define ESYNC 0x4
|
|
|
|
#define FGONLY 0x8
|
|
|
|
#define SOLID 0x10
|
|
|
|
#define RSHIFT 0x20
|
|
|
|
#define EVENONLY 0x40
|
|
|
|
#define ODDONLY 0x80
|
|
|
|
|
|
|
|
struct {
|
|
|
|
byte flags;
|
|
|
|
byte solid;
|
|
|
|
word sstart;
|
|
|
|
word dstart;
|
|
|
|
byte width;
|
|
|
|
byte height;
|
|
|
|
} __at (0xca00) blitter;
|
|
|
|
|
|
|
|
// switch flags
|
|
|
|
#define UP1 (input0 & 0x1)
|
|
|
|
#define DOWN1 (input0 & 0x2)
|
|
|
|
#define LEFT1 (input0 & 0x4)
|
|
|
|
#define RIGHT1 (input0 & 0x8)
|
|
|
|
#define START1 (input0 & 0x10)
|
|
|
|
#define START2 (input0 & 0x20)
|
|
|
|
#define UP2 (input0 & 0x40)
|
|
|
|
#define DOWN2 (input0 & 0x80)
|
|
|
|
#define LEFT2 (input1 & 0x1)
|
|
|
|
#define RIGHT2 (input1 & 0x2)
|
|
|
|
#define AUTOUP (input2 & 0x1)
|
|
|
|
#define ADVANCE (input2 & 0x2)
|
|
|
|
#define COIN2 (input2 & 0x4)
|
|
|
|
#define HIGHSCORERESET (input2 & 0x8)
|
|
|
|
#define COIN1 (input2 & 0x10)
|
|
|
|
#define COIN3 (input2 & 0x20)
|
|
|
|
#define TILTSWITCH (input2 & 0x40)
|
|
|
|
#define SOUNDACK (input2 & 0x80)
|
|
|
|
|
|
|
|
#define WATCHDOG watchdog0x39=0x39;
|
2017-03-27 15:21:17 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
void main();
|
|
|
|
void _sdcc_heap_init(void); // for malloc()
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
// start routine @ 0x0
|
|
|
|
// set stack pointer, enable interrupts
|
2017-03-27 15:21:17 +00:00
|
|
|
void start() {
|
|
|
|
__asm
|
2017-04-13 19:48:37 +00:00
|
|
|
LD SP,#0xc000
|
2017-03-27 15:21:17 +00:00
|
|
|
DI
|
|
|
|
; copy initialized data
|
|
|
|
LD BC, #l__INITIALIZER
|
|
|
|
LD A, B
|
|
|
|
LD DE, #s__INITIALIZED
|
|
|
|
LD HL, #s__INITIALIZER
|
|
|
|
LDIR
|
|
|
|
__endasm;
|
2017-04-13 19:48:37 +00:00
|
|
|
|
2017-03-27 15:21:17 +00:00
|
|
|
_sdcc_heap_init();
|
|
|
|
main();
|
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
#define LOCHAR 0x21
|
|
|
|
#define HICHAR 0x5e
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
const byte font8x8[HICHAR-LOCHAR+1][8] = {
|
|
|
|
{ 0x18,0x18,0x18,0x18,0x00,0x00,0x18,0x00 }, { 0x66,0x66,0x66,0x00,0x00,0x00,0x00,0x00 }, { 0x66,0x66,0xff,0x66,0xff,0x66,0x66,0x00 }, { 0x18,0x3e,0x60,0x3c,0x06,0x7c,0x18,0x00 }, { 0x62,0x66,0x0c,0x18,0x30,0x66,0x46,0x00 }, { 0x3c,0x66,0x3c,0x38,0x67,0x66,0x3f,0x00 }, { 0x06,0x0c,0x18,0x00,0x00,0x00,0x00,0x00 }, { 0x0c,0x18,0x30,0x30,0x30,0x18,0x0c,0x00 }, { 0x30,0x18,0x0c,0x0c,0x0c,0x18,0x30,0x00 }, { 0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00 }, { 0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00 }, { 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30 }, { 0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00 }, { 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00 }, { 0x00,0x03,0x06,0x0c,0x18,0x30,0x60,0x00 }, { 0x3c,0x66,0x6e,0x76,0x66,0x66,0x3c,0x00 }, { 0x18,0x18,0x38,0x18,0x18,0x18,0x7e,0x00 }, { 0x3c,0x66,0x06,0x0c,0x30,0x60,0x7e,0x00 }, { 0x3c,0x66,0x06,0x1c,0x06,0x66,0x3c,0x00 }, { 0x06,0x0e,0x1e,0x66,0x7f,0x06,0x06,0x00 }, { 0x7e,0x60,0x7c,0x06,0x06,0x66,0x3c,0x00 }, { 0x3c,0x66,0x60,0x7c,0x66,0x66,0x3c,0x00 }, { 0x7e,0x66,0x0c,0x18,0x18,0x18,0x18,0x00 }, { 0x3c,0x66,0x66,0x3c,0x66,0x66,0x3c,0x00 }, { 0x3c,0x66,0x66,0x3e,0x06,0x66,0x3c,0x00 }, { 0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00 }, { 0x00,0x00,0x18,0x00,0x00,0x18,0x18,0x30 }, { 0x0e,0x18,0x30,0x60,0x30,0x18,0x0e,0x00 }, { 0x00,0x00,0x7e,0x00,0x7e,0x00,0x00,0x00 }, { 0x70,0x18,0x0c,0x06,0x0c,0x18,0x70,0x00 }, { 0x3c,0x66,0x06,0x0c,0x18,0x00,0x18,0x00 }, { 0x3c,0x66,0x6e,0x6e,0x60,0x62,0x3c,0x00 }, { 0x18,0x3c,0x66,0x7e,0x66,0x66,0x66,0x00 }, { 0x7c,0x66,0x66,0x7c,0x66,0x66,0x7c,0x00 }, { 0x3c,0x66,0x60,0x60,0x60,0x66,0x3c,0x00 }, { 0x78,0x6c,0x66,0x66,0x66,0x6c,0x78,0x00 }, { 0x7e,0x60,0x60,0x78,0x60,0x60,0x7e,0x00 }, { 0x7e,0x60,0x60,0x78,0x60,0x60,0x60,0x00 }, { 0x3c,0x66,0x60,0x6e,0x66,0x66,0x3c,0x00 }, { 0x66,0x66,0x66,0x7e,0x66,0x66,0x66,0x00 }, { 0x3c,0x18,0x18,0x18,0x18,0x18,0x3c,0x00 }, { 0x1e,0x0c,0x0c,0x0c,0x0c,0x6c,0x38,0x00 }, { 0x66,0x6c,0x78,0x70,0x78,0x6c,0x66,0x00 }, { 0x60,0x60,0x60,0x60,0x60,0x60,0x7e,0x00 }, { 0x63,0x77,0x7f,0x6b,0x63,0x63,0x63,0x00 }, { 0x66,0x76,0x7e,0x7e,0x6e,0x66,0x66,0x00 }, { 0x3c,0x66,0x66,0x66,0x66,0x66,0x3c,0x00 }, { 0x7c,0x66,0x66,0x7c,0x60,0x60,0x60,0x00 }, { 0x3c,0x66,0x66,0x66,0x66,0x3c,0x0e,0x00 }, { 0x7c,0x66,0x66,0x7c,0x78,0x6c,0x66,0x00 }, { 0x3c,0x66,0x60,0x3c,0x06,0x66,0x3c,0x00 }, { 0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x00 }, { 0x66,0x66,0x66,0x66,0x66,0x66,0x3c,0x00 }, { 0x66,0x66,0x66,0x66,0x66,0x3c,0x18,0x00 }, { 0x63,0x63,0x63,0x6b,0x7f,0x77,0x63,0x00 }, { 0x66,0x66,0x3c,0x18,0x3c,0x66,0x66,0x00 }, { 0x66,0x66,0x66,0x3c,0x18,0x18,0x18,0x00 }, { 0x7e,0x06,0x0c,0x18,0x30,0x60,0x7e,0x00 }, { 0x3c,0x30,0x30,0x30,0x30,0x30,0x3c,0x00 }, { 0x00,0x60,0x30,0x18,0x0c,0x06,0x03,0x00 }, { 0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,0x00 }, { 0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x18 }
|
|
|
|
};
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
static byte font_table[HICHAR-LOCHAR+1][8*4];
|
|
|
|
|
|
|
|
void fill_char_table_entry(char ch) {
|
|
|
|
const byte* src = &font8x8[ch-LOCHAR][0];
|
|
|
|
byte* data = &font_table[ch-LOCHAR][0];
|
|
|
|
int i,j,pixels;
|
|
|
|
for (i=0; i<8; i++) {
|
|
|
|
byte b = *src++;
|
|
|
|
for (j=0; j<4; j++) {
|
|
|
|
pixels = 0;
|
|
|
|
if (b & 0x80) pixels |= 0xf0;
|
|
|
|
if (b & 0x40) pixels |= 0x0f;
|
|
|
|
*data++ = pixels;
|
|
|
|
b <<= 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
WATCHDOG;
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
void fill_char_table() {
|
|
|
|
char ch;
|
|
|
|
for (ch=LOCHAR; ch<=HICHAR; ch++) {
|
|
|
|
fill_char_table_entry(ch);
|
|
|
|
}
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
inline word swapw(word j) {
|
|
|
|
return ((j << 8) | (j >> 8));
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
// x1: 0-151
|
|
|
|
// y1: 0-255
|
|
|
|
inline void blit_solid(byte x1, byte y1, byte w, byte h, byte color) {
|
|
|
|
blitter.width = w^4;
|
|
|
|
blitter.height = h^4;
|
|
|
|
blitter.dstart = x1+y1*256; // swapped
|
|
|
|
blitter.solid = color;
|
|
|
|
blitter.flags = DSTSCREEN|SOLID;
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
inline void draw_solid(word x1, byte y1, byte w, byte h, byte color) {
|
|
|
|
blitter.width = w^4;
|
|
|
|
blitter.height = h^4;
|
|
|
|
blitter.dstart = (x1>>1)+y1*256; // swapped
|
|
|
|
blitter.solid = color;
|
|
|
|
blitter.flags = (x1&1) ? DSTSCREEN|SOLID|RSHIFT : DSTSCREEN|SOLID;
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
inline void draw_vline(word x1, byte y1, byte h, byte color) {
|
|
|
|
blitter.width = 1^4;
|
|
|
|
blitter.height = h^4;
|
|
|
|
blitter.dstart = (x1>>1)+y1*256; // swapped
|
|
|
|
blitter.solid = color;
|
|
|
|
blitter.flags = (x1&1) ? DSTSCREEN|SOLID|ODDONLY : DSTSCREEN|SOLID|EVENONLY;
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
inline void blit_copy(byte x1, byte y1, byte w, byte h, const byte* data) {
|
|
|
|
blitter.width = w^4;
|
|
|
|
blitter.height = h^4;
|
|
|
|
blitter.sstart = swapw((word)data);
|
|
|
|
blitter.dstart = x1+y1*256; // swapped
|
|
|
|
blitter.flags = DSTSCREEN|FGONLY;
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
inline void blit_copy_solid(byte x1, byte y1, byte w, byte h, const byte* data, byte solid) {
|
|
|
|
blitter.width = w^4;
|
|
|
|
blitter.height = h^4;
|
|
|
|
blitter.sstart = swapw((word)data);
|
|
|
|
blitter.dstart = x1+y1*256; // swapped
|
|
|
|
blitter.solid = solid;
|
|
|
|
blitter.flags = DSTSCREEN|FGONLY|SOLID;
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
// bias sprites by +12 pixels
|
|
|
|
#define XBIAS 6
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
inline void draw_sprite(const byte* data, byte x, byte y) {
|
|
|
|
blitter.width = data[0]^4;
|
|
|
|
blitter.height = data[1]^4;
|
|
|
|
blitter.sstart = swapw((word)(data+2));
|
|
|
|
blitter.dstart = (x>>1)+y*256+XBIAS; // swapped
|
|
|
|
blitter.flags = (x&1) ? DSTSCREEN|FGONLY|RSHIFT : DSTSCREEN|FGONLY;
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
inline void draw_sprite_solid(const byte* data, byte x, byte y, byte color) {
|
|
|
|
blitter.width = data[0]^4;
|
|
|
|
blitter.height = data[1]^4;
|
|
|
|
blitter.sstart = swapw((word)(data+2));
|
|
|
|
blitter.dstart = (x>>1)+y*256+XBIAS; // swapped
|
|
|
|
blitter.solid = color;
|
|
|
|
blitter.flags = (x&1) ? DSTSCREEN|FGONLY|RSHIFT|SOLID : DSTSCREEN|FGONLY|SOLID;
|
|
|
|
}
|
2017-03-28 16:22:33 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
void draw_sprite_strided(const byte* data, byte x, byte y, byte stride) {
|
|
|
|
byte i;
|
|
|
|
byte width = data[0];
|
|
|
|
byte height = data[1];
|
|
|
|
byte yy = y-(height*(stride-1)/2);
|
|
|
|
word dest = (x>>1)+yy*256+XBIAS;
|
|
|
|
blitter.width = width^4;
|
|
|
|
blitter.height = 1^4;
|
|
|
|
for (i=0; i<height; i++) {
|
|
|
|
if ((dest & 0xff) < 0x90) {
|
|
|
|
blitter.sstart = swapw((word)(data+2));
|
|
|
|
blitter.dstart = dest; // swapped
|
|
|
|
blitter.flags = DSTSCREEN|FGONLY;
|
|
|
|
}
|
|
|
|
dest += stride << 8;
|
|
|
|
data += width;
|
2017-03-28 16:22:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
void erase_sprite_strided(const byte* data, byte x, byte y, byte stride) {
|
|
|
|
byte i;
|
|
|
|
byte width = data[0];
|
|
|
|
byte height = data[1];
|
|
|
|
byte yy = y-(height*(stride-1)/2);
|
|
|
|
word dest = (x>>1)+yy*256+XBIAS;
|
|
|
|
blitter.width = width^4;
|
|
|
|
blitter.height = 1^4;
|
|
|
|
blitter.solid = 0;
|
|
|
|
for (i=0; i<height; i++) {
|
|
|
|
if ((dest & 0xff) < 0x90) {
|
|
|
|
blitter.dstart = dest; // swapped
|
|
|
|
blitter.flags = DSTSCREEN|SOLID;
|
|
|
|
}
|
|
|
|
dest += stride << 8;
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
inline void draw_char(char ch, byte x, byte y, byte color) {
|
|
|
|
if (ch < LOCHAR || ch > HICHAR) return;
|
|
|
|
blit_copy_solid(x, y, 4, 8, font_table[ch - LOCHAR], color);
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
void draw_string(const char* str, byte x, byte y, byte color) {
|
|
|
|
while (*str) {
|
|
|
|
draw_char(*str++, x, y, color);
|
|
|
|
x += 4;
|
|
|
|
}
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
void draw_box(word x1, byte y1, word x2, byte y2, byte color) {
|
|
|
|
draw_solid(x1, y1, (x2-x1)>>1, 1, color);
|
|
|
|
draw_solid(x1, y2, (x2-x1)>>1, 1, color);
|
|
|
|
draw_vline(x1, y1, y2-y1, color);
|
|
|
|
draw_vline(x2, y1, y2-y1, color);
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
// GRAPHIC DATA
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
const byte palette_data[16] = {
|
|
|
|
0x00, 0x03, 0x19, 0x50, 0x52, 0x07, 0x1f, 0x37, 0xe0, 0xa4, 0xfd, 0xff, 0x38, 0x70, 0x7f, 0xf8, };
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
const byte laser_vert[2+1*8] = {
|
|
|
|
1,8,
|
|
|
|
0xff,
|
|
|
|
0xff,
|
|
|
|
0xff,
|
|
|
|
0xff,
|
|
|
|
0xff,
|
|
|
|
0xff,
|
|
|
|
0xff,
|
|
|
|
0xff,
|
|
|
|
};
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
const byte laser_horiz[2+4*2] = {
|
|
|
|
4,2,
|
|
|
|
0xff,
|
|
|
|
0xff,
|
|
|
|
0xff,
|
|
|
|
0xff,
|
|
|
|
0xff,
|
|
|
|
0xff,
|
|
|
|
0xff,
|
|
|
|
0xff,
|
|
|
|
};
|
2017-03-27 15:21:17 +00:00
|
|
|
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
const byte playersprite1[] = {
|
|
|
|
7,16,
|
|
|
|
0x00,0x00,0xef,0xef,0xe0,0x00,0x00,
|
|
|
|
0x00,0xee,0xee,0xfe,0xee,0xe0,0x00,
|
|
|
|
0x0e,0xed,0xef,0xef,0xed,0xee,0x00,
|
|
|
|
0x0e,0xee,0xdd,0xdd,0xde,0xee,0x00,
|
|
|
|
0x0e,0xee,0xed,0xde,0xee,0xee,0x00,
|
|
|
|
0x00,0xee,0xee,0xde,0xee,0xe0,0x00,
|
|
|
|
0x00,0xee,0xee,0xde,0xee,0xe0,0x00,
|
|
|
|
0x00,0x00,0xed,0xdd,0xe0,0x00,0x0d,
|
|
|
|
0xdd,0xdd,0xee,0xee,0xed,0xdd,0xd0,
|
|
|
|
0x0d,0xee,0xee,0xee,0xee,0xee,0x00,
|
|
|
|
0x0e,0xe0,0xee,0xee,0xe0,0xee,0x00,
|
|
|
|
0x0e,0xe0,0xee,0xee,0xe0,0xee,0x00,
|
|
|
|
0x0e,0xe0,0xdd,0xdd,0xd0,0xde,0x00,
|
|
|
|
0x0d,0x00,0xee,0x0e,0xe0,0x0d,0x00,
|
|
|
|
0x00,0x00,0xed,0x0e,0xe0,0x00,0x00,
|
|
|
|
0x00,0x0d,0xdd,0x0d,0xdd,0x00,0x18,
|
|
|
|
};
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
const byte sprite1[2+16*16/2] = {
|
|
|
|
8,16,
|
|
|
|
0x00,0x09,0x99,0x00,0x00,0x99,0x90,0x00,
|
|
|
|
0x00,0x94,0x94,0x90,0x09,0x49,0x49,0x00,
|
|
|
|
0x04,0x49,0x49,0x90,0x09,0x94,0x94,0x90,
|
|
|
|
0x94,0x99,0x94,0x90,0x09,0x49,0x99,0x49,
|
|
|
|
0x99,0x99,0x49,0x93,0x39,0x94,0x99,0x99,
|
|
|
|
0x04,0x49,0x99,0x94,0x49,0x99,0x94,0x90,
|
|
|
|
0x00,0x94,0x94,0x43,0x34,0x49,0x49,0x00,
|
|
|
|
0x00,0x09,0x43,0x94,0x49,0x34,0x90,0x00,
|
|
|
|
0x00,0x90,0x00,0x39,0x93,0x00,0x09,0x00,
|
|
|
|
0x00,0x09,0x83,0x33,0x33,0x33,0x90,0x00,
|
|
|
|
0x00,0x09,0x32,0x23,0x32,0x23,0x90,0x00,
|
|
|
|
0x00,0x03,0x03,0x23,0x82,0x30,0x30,0x00,
|
|
|
|
0x03,0x30,0x00,0x33,0x33,0x00,0x03,0x30,
|
|
|
|
0x00,0x30,0x03,0x00,0x00,0x30,0x03,0x00,
|
|
|
|
0x00,0x00,0x00,0x30,0x03,0x00,0x00,0x00,
|
|
|
|
0x00,0x09,0x99,0x00,0x00,0x99,0x90,0x00,
|
|
|
|
};
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
const byte sprite2[2+16*16/2] = {
|
|
|
|
8,16,
|
|
|
|
0x00,0x94,0x94,0x90,0x09,0x49,0x49,0x00,
|
|
|
|
0x04,0x49,0x49,0x90,0x09,0x94,0x94,0x90,
|
|
|
|
0x94,0x99,0x94,0x90,0x09,0x49,0x99,0x49,
|
|
|
|
0x99,0x99,0x49,0x93,0x39,0x94,0x99,0x99,
|
|
|
|
0x04,0x49,0x99,0x94,0x49,0x99,0x94,0x90,
|
|
|
|
0x00,0x94,0x94,0x43,0x34,0x49,0x49,0x00,
|
|
|
|
0x00,0x09,0x43,0x94,0x49,0x34,0x90,0x00,
|
|
|
|
0x00,0x90,0x00,0x39,0x93,0x00,0x09,0x00,
|
|
|
|
0x00,0x09,0x83,0x33,0x33,0x33,0x90,0x00,
|
|
|
|
0x00,0x09,0x32,0x23,0x32,0x23,0x90,0x00,
|
|
|
|
0x00,0x03,0x03,0x23,0x82,0x30,0x30,0x00,
|
|
|
|
0x03,0x30,0x00,0x33,0x33,0x00,0x03,0x30,
|
|
|
|
0x00,0x30,0x03,0x00,0x00,0x30,0x03,0x00,
|
|
|
|
0x00,0x00,0x00,0x30,0x03,0x00,0x00,0x00,
|
|
|
|
0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,
|
|
|
|
};
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
const byte sprite3[2+16*16/2] = {
|
|
|
|
8,16,
|
|
|
|
0x00,0x00,0x00,0x01,0x10,0x00,0x00,0x00,
|
|
|
|
0x00,0x00,0x00,0x11,0x11,0x00,0x00,0x00,
|
|
|
|
0x00,0x00,0x00,0x01,0x10,0x00,0x00,0x00,
|
|
|
|
0x00,0x00,0x00,0x01,0x10,0x00,0x00,0x00,
|
|
|
|
0x00,0x11,0x10,0x01,0x10,0x01,0x11,0x00,
|
|
|
|
0x11,0x00,0x10,0x11,0x11,0x01,0x00,0x11,
|
|
|
|
0x10,0x00,0x11,0x11,0x11,0x11,0x00,0x01,
|
|
|
|
0x10,0x00,0x00,0x11,0x11,0x00,0x00,0x01,
|
|
|
|
0x00,0x01,0x10,0x11,0x41,0x01,0x10,0x00,
|
|
|
|
0x00,0x10,0x11,0x11,0x11,0x11,0x01,0x00,
|
|
|
|
0x01,0x00,0x00,0x51,0x15,0x00,0x00,0x10,
|
|
|
|
0x01,0x00,0x01,0x10,0x01,0x10,0x00,0x10,
|
|
|
|
0x01,0x00,0x10,0x00,0x00,0x01,0x00,0x10,
|
|
|
|
0x00,0x10,0x01,0x00,0x00,0x10,0x01,0x00,
|
|
|
|
0x00,0x10,0x00,0x00,0x00,0x00,0x01,0x00,
|
|
|
|
0x00,0x01,0x10,0x00,0x00,0x01,0x10,0x00,
|
|
|
|
};
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
const byte sprite4[2+16*16/2] = {
|
|
|
|
8,16,
|
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
|
0x00,0x00,0x00,0xbb,0xbb,0x00,0x00,0x00,
|
|
|
|
0x00,0x00,0x00,0xbb,0xbb,0x00,0x00,0x00,
|
|
|
|
0x00,0x00,0xbb,0xbb,0xbb,0xbb,0x00,0x00,
|
|
|
|
0x00,0x0b,0x4b,0xbb,0xbb,0xb4,0xb0,0x00,
|
|
|
|
0x00,0x0b,0x44,0xbb,0xbb,0x49,0xb0,0x00,
|
|
|
|
0x00,0xbb,0x99,0x4b,0xb4,0x99,0xbb,0x00,
|
|
|
|
0x00,0x4b,0xb9,0x9b,0xb4,0x4b,0xb4,0x00,
|
|
|
|
0x00,0x04,0xbb,0x4b,0xb9,0xbb,0x40,0x00,
|
|
|
|
0x00,0x00,0x4b,0xbb,0xbb,0xb4,0x00,0x00,
|
|
|
|
0x11,0x00,0x0b,0xbb,0xbb,0xb0,0x00,0x11,
|
|
|
|
0x10,0x10,0x0b,0x41,0x14,0xb0,0x01,0x01,
|
|
|
|
0x10,0x00,0x05,0x11,0x11,0x50,0x00,0x01,
|
|
|
|
0x01,0x00,0x01,0x51,0x15,0x10,0x00,0x10,
|
|
|
|
0x00,0x10,0x01,0x10,0x01,0x10,0x01,0x00,
|
|
|
|
0x01,0x01,0x10,0x10,0x01,0x01,0x10,0x10,
|
|
|
|
};
|
2017-03-28 16:22:33 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
const byte sprite5[2+16*16/2] = {
|
|
|
|
8,16,
|
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
|
0x00,0x00,0x22,0x00,0x00,0x22,0x00,0x00,
|
|
|
|
0x00,0x20,0x20,0x00,0x00,0x02,0x02,0x00,
|
|
|
|
0x02,0x22,0x12,0x00,0x00,0x21,0x22,0x20,
|
|
|
|
0x00,0x02,0x11,0x00,0x00,0x11,0x20,0x00,
|
|
|
|
0x00,0x00,0x02,0x11,0x11,0x20,0x00,0x00,
|
|
|
|
0x00,0x00,0x02,0x22,0x22,0x20,0x00,0x00,
|
|
|
|
0x00,0x00,0x21,0x22,0x22,0x12,0x00,0x00,
|
|
|
|
0x00,0x00,0x22,0x12,0x21,0x22,0x00,0x00,
|
|
|
|
0x02,0x00,0x22,0x12,0x21,0x22,0x00,0x20,
|
|
|
|
0x20,0x02,0x21,0x11,0x11,0x12,0x20,0x02,
|
|
|
|
0x02,0x22,0x15,0x12,0x21,0x51,0x22,0x20,
|
|
|
|
0x02,0x11,0x15,0x52,0x25,0x51,0x11,0x20,
|
|
|
|
0x20,0x00,0x22,0x12,0x21,0x22,0x00,0x02,
|
|
|
|
0x20,0x02,0x20,0x20,0x02,0x02,0x20,0x02,
|
|
|
|
0x02,0x02,0x00,0x20,0x02,0x00,0x20,0x20,
|
|
|
|
};
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
const byte sprite6[2+12*16/2] = {
|
|
|
|
8,12,
|
|
|
|
0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x00,
|
|
|
|
0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x40,
|
|
|
|
0x00,0x00,0x04,0x04,0x49,0x49,0x99,0x44,
|
|
|
|
0x00,0x00,0x44,0x44,0x99,0x94,0x44,0x40,
|
|
|
|
0x00,0x04,0x49,0x99,0x94,0x49,0x99,0x40,
|
|
|
|
0x00,0x44,0x99,0x94,0x49,0x99,0x44,0x00,
|
|
|
|
0x04,0x49,0x44,0x99,0x99,0x44,0x00,0x00,
|
|
|
|
0x04,0x44,0x00,0x49,0x44,0x40,0x00,0x00,
|
|
|
|
0x04,0x40,0x00,0x04,0x00,0x00,0x00,0x00,
|
|
|
|
0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
|
};
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
const byte sprite7[2+16*16/2] = {
|
|
|
|
8,16,
|
|
|
|
0x00,0x60,0x00,0x00,0x00,0x00,0x06,0x00,
|
|
|
|
0x60,0x60,0x00,0x00,0x00,0x00,0x06,0x06,
|
|
|
|
0x60,0x60,0x50,0x00,0x00,0x05,0x06,0x06,
|
|
|
|
0x60,0x60,0x06,0x00,0x00,0x60,0x06,0x06,
|
|
|
|
0x66,0x60,0x06,0x06,0x60,0x60,0x06,0x66,
|
|
|
|
0x66,0x60,0x66,0x66,0x66,0x66,0x06,0x66,
|
|
|
|
0x66,0x60,0x6b,0x6b,0xb6,0xb6,0x06,0x66,
|
|
|
|
0x06,0x66,0x66,0xb6,0x6b,0x66,0x66,0x60,
|
|
|
|
0x00,0x67,0x66,0x66,0x66,0x66,0x66,0x00,
|
|
|
|
0x00,0x11,0x11,0x66,0x66,0x11,0x11,0x00,
|
|
|
|
0x01,0x11,0x21,0x11,0x11,0x12,0x11,0x10,
|
|
|
|
0x00,0x10,0x01,0x01,0x10,0x10,0x01,0x00,
|
|
|
|
0x00,0x10,0x11,0x00,0x00,0x11,0x01,0x00,
|
|
|
|
0x00,0x00,0x10,0x00,0x00,0x01,0x00,0x00,
|
|
|
|
};
|
2017-03-28 16:22:33 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
const byte sprite8[2+16*16/2] = {
|
|
|
|
8,16,
|
|
|
|
0x00,0x00,0x11,0x11,0x11,0x11,0x00,0x00,
|
|
|
|
0x00,0x01,0x61,0x11,0x21,0x12,0x10,0x00,
|
|
|
|
0x00,0x11,0x12,0x11,0x61,0x11,0x11,0x00,
|
|
|
|
0x00,0x11,0x71,0x21,0x61,0x17,0x11,0x00,
|
|
|
|
0x00,0x11,0x77,0x11,0x12,0x77,0x11,0x00,
|
|
|
|
0x00,0x11,0x17,0x17,0x71,0x72,0x11,0x00,
|
|
|
|
0x00,0x16,0x21,0x78,0x87,0x11,0x11,0x00,
|
|
|
|
0x00,0x01,0x81,0x88,0x88,0x18,0x10,0x00,
|
|
|
|
0x00,0x08,0x18,0x58,0x85,0x81,0x80,0x00,
|
|
|
|
0x00,0x88,0x01,0x88,0x88,0x10,0x88,0x00,
|
|
|
|
0x00,0x08,0x07,0x78,0x87,0x70,0x80,0x00,
|
|
|
|
0x08,0x80,0x07,0x80,0x08,0x70,0x08,0x80,
|
|
|
|
0x88,0x00,0x88,0x00,0x00,0x88,0x00,0x88,
|
|
|
|
0x80,0x00,0x08,0x80,0x08,0x80,0x00,0x08,
|
|
|
|
0x00,0x00,0x00,0x80,0x08,0x00,0x00,0x00,
|
|
|
|
};
|
2017-03-28 16:22:33 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
const byte sprite9[2+13*16/2] = {
|
|
|
|
8,13,
|
|
|
|
0x00,0x00,0xaa,0x00,0x00,0xaa,0x00,0x00,
|
|
|
|
0x00,0x00,0xa0,0x0a,0xa0,0x0a,0x00,0x00,
|
|
|
|
0x0a,0xaa,0xa4,0xaa,0xaa,0x3a,0xaa,0xa0,
|
|
|
|
0x00,0x0a,0x3a,0x9a,0xa9,0xa3,0xa0,0x00,
|
|
|
|
0x00,0x0a,0xaa,0x99,0xa4,0xaa,0xa0,0x00,
|
|
|
|
0x00,0x0a,0xaa,0x99,0x94,0xaa,0xa0,0x00,
|
|
|
|
0x00,0xaa,0x33,0xaa,0xaa,0x43,0xaa,0x00,
|
|
|
|
0x0a,0x3a,0xaa,0x3a,0xa3,0xaa,0xa3,0xa0,
|
|
|
|
0x00,0xaa,0xaa,0x30,0x03,0xaa,0xaa,0x00,
|
|
|
|
0x00,0x0a,0xa0,0x30,0x03,0x0a,0xa0,0x00,
|
|
|
|
0x00,0xa3,0xa0,0x00,0x00,0x0a,0x4a,0x00,
|
|
|
|
0x00,0xaa,0xa0,0x00,0x00,0x0a,0xaa,0x00,
|
|
|
|
0x00,0x0a,0xa0,0x00,0x00,0x0a,0xa0,0x00,
|
|
|
|
};
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
const byte* const all_sprites[9] = {
|
|
|
|
sprite1,
|
|
|
|
sprite2,
|
|
|
|
sprite3,
|
|
|
|
sprite4,
|
|
|
|
sprite5,
|
|
|
|
sprite6,
|
|
|
|
sprite7,
|
|
|
|
sprite8,
|
|
|
|
sprite9,
|
|
|
|
};
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
// GAME CODE
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
typedef struct Actor;
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
typedef void (*ActorUpdateFn)(struct Actor* a);
|
|
|
|
typedef void (*ActorDrawFn)(struct Actor* a);
|
2017-03-27 15:21:17 +00:00
|
|
|
|
|
|
|
typedef struct Actor {
|
|
|
|
struct Actor* next;
|
2017-04-13 19:48:37 +00:00
|
|
|
struct Actor** prevptr;
|
|
|
|
byte x,y;
|
|
|
|
byte* shape;
|
|
|
|
ActorUpdateFn update;
|
|
|
|
ActorDrawFn draw;
|
|
|
|
union {
|
|
|
|
struct { sbyte dx,dy; } laser;
|
|
|
|
struct { byte exploding; } enemy;
|
|
|
|
} u;
|
2017-03-27 15:21:17 +00:00
|
|
|
} Actor;
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
#define MAX_ACTORS 128
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
static Actor actors[MAX_ACTORS];
|
|
|
|
static Actor* player_list;
|
|
|
|
static Actor* fast_list;
|
|
|
|
static Actor* slow_lists[4];
|
|
|
|
static Actor* obstacle_list;
|
|
|
|
static Actor* free_list;
|
|
|
|
static Actor* effects_list;
|
|
|
|
static byte frame;
|
|
|
|
|
|
|
|
#define PLAYER 1
|
|
|
|
#define LASER 2
|
|
|
|
|
|
|
|
void add_actor(Actor** list, Actor* a) {
|
|
|
|
if (*list) (*list)->prevptr = &a->next;
|
|
|
|
a->next = *list;
|
|
|
|
a->prevptr = list;
|
|
|
|
*list = a;
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
void remove_actor(Actor* a) {
|
|
|
|
if (a->next) a->next->prevptr = a->prevptr;
|
|
|
|
*a->prevptr = a->next;
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
char in_rect(const Actor* e, byte x, byte y, byte w, byte h) {
|
|
|
|
byte eh = e->shape[0];
|
|
|
|
byte ew = e->shape[1];
|
|
|
|
return (x >= e->x-w && x <= e->x+ew && y >= e->y-h && y <= e->y+eh);
|
|
|
|
}
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
void draw_actor_normal(Actor* a) {
|
|
|
|
draw_sprite(a->shape, a->x, a->y);
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
void draw_actor_exploding(Actor* a) {
|
|
|
|
erase_sprite_strided(a->shape, a->x, a->y, a->u.enemy.exploding);
|
|
|
|
if (a->u.enemy.exploding > 10) {
|
|
|
|
a->draw = NULL;
|
|
|
|
} else {
|
|
|
|
draw_sprite_strided(a->shape, a->x, a->y, ++a->u.enemy.exploding);
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
void update_actor(Actor* a) {
|
|
|
|
// if NULL shape, we don't have anything
|
|
|
|
if (a->shape) {
|
|
|
|
// erase the sprite
|
|
|
|
draw_sprite_solid(a->shape, a->x, a->y, 0);
|
|
|
|
// call update callback
|
|
|
|
if (a->update) {
|
|
|
|
a->update(a);
|
|
|
|
}
|
|
|
|
// did we delete it?
|
|
|
|
if (a->shape) {
|
|
|
|
// draw the sprite
|
|
|
|
if (a->draw) {
|
|
|
|
a->draw(a);
|
|
|
|
}
|
2017-03-28 16:22:33 +00:00
|
|
|
} else {
|
2017-04-13 19:48:37 +00:00
|
|
|
// shape became null, remove from list
|
|
|
|
remove_actor(a);
|
2017-03-28 16:22:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
word lfsr = 1;
|
|
|
|
|
|
|
|
word rand() {
|
|
|
|
byte lsb = lfsr & 1;
|
|
|
|
lfsr >>= 1;
|
|
|
|
if (lsb) lfsr ^= 0xd400;
|
|
|
|
return lfsr;
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
signed char random_dir() {
|
|
|
|
byte x = rand();
|
|
|
|
if (x < 85) return 0;
|
|
|
|
else if (x < 85*2) return -1;
|
|
|
|
else return 1;
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
void random_walk(Actor* a) {
|
|
|
|
a->x += random_dir();
|
|
|
|
a->y += random_dir();
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
static byte g_section;
|
2017-03-28 16:22:33 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
void update_actor_list(Actor* a) {
|
2017-03-27 15:21:17 +00:00
|
|
|
while (a) {
|
2017-04-13 19:48:37 +00:00
|
|
|
update_actor(a);
|
2017-03-27 15:21:17 +00:00
|
|
|
a = a->next;
|
|
|
|
}
|
2017-03-28 16:22:33 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
void update_actors_partial(Actor* a) {
|
|
|
|
while (a) {
|
|
|
|
if (g_section ^ (a->y < 0x80)) {
|
|
|
|
update_actor(a);
|
|
|
|
}
|
|
|
|
a = a->next;
|
2017-03-28 16:22:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
void update_screen_section(byte section) {
|
|
|
|
g_section = section;
|
|
|
|
update_actors_partial(player_list);
|
|
|
|
update_actors_partial(fast_list);
|
|
|
|
update_actors_partial(slow_lists[frame & 3]);
|
2017-03-28 16:22:33 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
byte did_overflow() {
|
|
|
|
__asm
|
|
|
|
ld l,#0
|
|
|
|
ret nc
|
|
|
|
inc l
|
|
|
|
__endasm;
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
static byte test_x, test_y;
|
|
|
|
static Actor* test_collided;
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
Actor* test_collision(Actor* a) {
|
|
|
|
while (a) {
|
|
|
|
if (test_y >= a->y && test_x >= a->x &&
|
|
|
|
test_y < a->y+16 && test_x < a->x+16) {
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
a = a->next;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void laser_move(Actor* a) {
|
|
|
|
// did we hit something?
|
|
|
|
test_x = a->x;
|
|
|
|
test_y = a->y;
|
|
|
|
test_collided = test_collision(fast_list);
|
|
|
|
if (!test_collided) test_collided = test_collision(slow_lists[0]);
|
|
|
|
if (!test_collided) test_collided = test_collision(slow_lists[1]);
|
|
|
|
if (!test_collided) test_collided = test_collision(slow_lists[2]);
|
|
|
|
if (!test_collided) test_collided = test_collision(slow_lists[3]);
|
|
|
|
if (test_collided) {
|
|
|
|
// get rid of laser (we can do this in our 'update' fn)
|
|
|
|
a->shape = NULL;
|
|
|
|
// set exploding flag for enemy (we're not in its update)
|
|
|
|
test_collided->draw = draw_actor_exploding;
|
|
|
|
test_collided->update = NULL;
|
|
|
|
test_collided->u.enemy.exploding = 1;
|
|
|
|
remove_actor(test_collided);
|
|
|
|
add_actor(&effects_list, test_collided);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// move laser
|
|
|
|
// check for wall collisions
|
|
|
|
a->x += a->u.laser.dx;
|
|
|
|
if (a->x > 255-8) a->shape = NULL;
|
|
|
|
a->y += a->u.laser.dy;
|
|
|
|
if (a->y > 255-8) a->shape = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void shoot_laser(sbyte dx, sbyte dy, const byte* shape) {
|
|
|
|
Actor* a = &actors[LASER];
|
|
|
|
a->shape = (void*) shape;
|
|
|
|
a->x = actors[PLAYER].x + 6;
|
|
|
|
a->y = actors[PLAYER].y + 8;
|
|
|
|
a->u.laser.dx = dx;
|
|
|
|
a->u.laser.dy = dy;
|
|
|
|
add_actor(&player_list, a);
|
|
|
|
}
|
|
|
|
|
|
|
|
void player_laser() {
|
|
|
|
// is the laser being used?
|
|
|
|
if (actors[LASER].shape == NULL) { // no, check controls
|
|
|
|
if (UP2) shoot_laser(0,-8,laser_vert);
|
|
|
|
else if (DOWN2) shoot_laser(0,8,laser_vert);
|
|
|
|
else if (LEFT2) shoot_laser(-8,0,laser_horiz);
|
|
|
|
else if (RIGHT2) shoot_laser(8,0,laser_horiz);
|
|
|
|
}
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
void player_move(Actor* a) {
|
|
|
|
byte x = a->x;
|
|
|
|
byte y = a->y;
|
|
|
|
if (UP1) y-=1;
|
|
|
|
if (DOWN1) y+=1;
|
|
|
|
if (LEFT1) x-=1;
|
|
|
|
if (RIGHT1) x+=1;
|
|
|
|
a->x = x;
|
|
|
|
a->y = y;
|
|
|
|
player_laser();
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
static Actor* current_effect;
|
2017-03-27 15:21:17 +00:00
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
void effects_new_frame() {
|
|
|
|
current_effect = effects_list;
|
2017-03-28 16:22:33 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
void effects_next() {
|
|
|
|
if (current_effect) {
|
|
|
|
if (current_effect->draw) {
|
|
|
|
current_effect->draw(current_effect);
|
|
|
|
} else {
|
|
|
|
remove_actor(current_effect);
|
|
|
|
}
|
|
|
|
current_effect = current_effect->next;
|
2017-03-28 16:22:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
Actor* new_actor() {
|
|
|
|
Actor* a = free_list;
|
|
|
|
remove_actor(a);
|
|
|
|
return a;
|
2017-03-28 16:22:33 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
void redraw_playfield(Actor* a) {
|
|
|
|
a;
|
|
|
|
draw_box(0,0,303,255,0x11);
|
2017-03-28 16:22:33 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 19:48:37 +00:00
|
|
|
Actor* new_effect(ActorDrawFn draw) {
|
|
|
|
Actor* a = new_actor();
|
|
|
|
a->draw = draw;
|
|
|
|
add_actor(&effects_list, a);
|
|
|
|
return a;
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void main() {
|
2017-04-13 19:48:37 +00:00
|
|
|
byte i;
|
|
|
|
byte num_actors = 32;
|
|
|
|
blit_solid(0, 0, 255, 255, 0);
|
|
|
|
memset(actors, 0, sizeof(actors));
|
|
|
|
memcpy(palette, palette_data, 16);
|
|
|
|
fill_char_table();
|
|
|
|
player_list = fast_list = obstacle_list = free_list = NULL;
|
|
|
|
memset(slow_lists, 0, sizeof(slow_lists));
|
|
|
|
// add all actors to free list
|
|
|
|
for (i=MAX_ACTORS-1; i>0; i--) {
|
|
|
|
add_actor(&free_list, &actors[i]);
|
|
|
|
}
|
|
|
|
// make actors
|
|
|
|
for (i=1; i<num_actors; i++) {
|
|
|
|
Actor* a = new_actor();
|
|
|
|
do {
|
|
|
|
a->x = rand() + rand();
|
|
|
|
a->y = rand() + rand();
|
|
|
|
} while ((byte)(a->x - 96) < 64 && (byte)(a->y - 96) < 64);
|
|
|
|
a->shape = (void*) all_sprites[i%9];
|
|
|
|
a->update = random_walk;
|
|
|
|
a->draw = draw_actor_normal;
|
|
|
|
if (i == PLAYER) {
|
|
|
|
a->x = 128;
|
|
|
|
a->y = 120;
|
|
|
|
add_actor(&player_list, a);
|
|
|
|
}
|
|
|
|
else if (i == LASER) ; //add_actor(&player_list, a);
|
|
|
|
else if (i < 5) add_actor(&fast_list, a);
|
|
|
|
else add_actor(&slow_lists[i&3], a);
|
|
|
|
WATCHDOG;
|
|
|
|
}
|
|
|
|
actors[PLAYER].shape = (void*) playersprite1;
|
|
|
|
actors[PLAYER].update = player_move;
|
|
|
|
actors[LASER].update = laser_move;
|
|
|
|
actors[LASER].shape = NULL;
|
|
|
|
new_effect(redraw_playfield);
|
|
|
|
WATCHDOG;
|
|
|
|
while (1) {
|
|
|
|
effects_new_frame();
|
|
|
|
while (video_counter >= 0x90) effects_next();
|
|
|
|
update_screen_section(1);
|
|
|
|
while (video_counter < 0x90) effects_next();
|
|
|
|
update_screen_section(0);
|
|
|
|
switch (frame & 7) {
|
|
|
|
case 0:
|
|
|
|
draw_box(0,0,303,255,0x11);
|
|
|
|
break;
|
|
|
|
}
|
2017-03-27 15:21:17 +00:00
|
|
|
frame++;
|
2017-04-13 19:48:37 +00:00
|
|
|
WATCHDOG;
|
2017-03-27 15:21:17 +00:00
|
|
|
}
|
|
|
|
}
|