mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-12-22 12:30:01 +00:00
working on vector presets
This commit is contained in:
parent
15354fce71
commit
c0e51bb460
@ -36,8 +36,8 @@ void dvgwrite(word w) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void VCTR(int dx, int dy, byte bright) {
|
inline void VCTR(int dx, int dy, byte bright) {
|
||||||
dvgwrite((dx & 0x1fff));
|
dvgwrite((dy & 0x1fff));
|
||||||
dvgwrite(((bright & 7) << 13) | (dy & 0x1fff));
|
dvgwrite(((bright & 7) << 13) | (dx & 0x1fff));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SVEC(signed char dx, signed char dy, byte bright) {
|
inline void SVEC(signed char dx, signed char dy, byte bright) {
|
||||||
|
575
presets/vector-z80color/game.c
Normal file
575
presets/vector-z80color/game.c
Normal file
@ -0,0 +1,575 @@
|
|||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
typedef unsigned char byte;
|
||||||
|
typedef unsigned short word;
|
||||||
|
typedef signed char sbyte;
|
||||||
|
|
||||||
|
word __at(0xa000) dvgram[0x1000];
|
||||||
|
byte __at(0x8840) _dvgstart;
|
||||||
|
|
||||||
|
int __at(0x8100) mathbox_sum;
|
||||||
|
sbyte __at(0x8102) mathbox_arg1;
|
||||||
|
sbyte __at(0x8103) mathbox_arg2;
|
||||||
|
byte __at(0x810f) mathbox_go_mul;
|
||||||
|
|
||||||
|
byte __at (0x8000) input0;
|
||||||
|
byte __at (0x8001) input1;
|
||||||
|
byte __at (0x8002) input2;
|
||||||
|
|
||||||
|
#define LEFT1 !(input1 & 0x8)
|
||||||
|
#define RIGHT1 !(input1 & 0x4)
|
||||||
|
#define UP1 !(input1 & 0x10)
|
||||||
|
#define DOWN1 !(input1 & 0x20)
|
||||||
|
#define FIRE1 !(input1 & 0x2)
|
||||||
|
#define BOMB1 !(input1 & 0x1)
|
||||||
|
#define COIN1 (input0 & 0x2)
|
||||||
|
#define COIN2 (input0 & 0x1)
|
||||||
|
#define START1 (input2 & 0x20)
|
||||||
|
#define START2 (input2 & 0x40)
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
void main();
|
||||||
|
void _sdcc_heap_init(void); // for malloc()
|
||||||
|
|
||||||
|
void start() {
|
||||||
|
__asm
|
||||||
|
LD SP,#0x0
|
||||||
|
DI
|
||||||
|
; copy initialized data
|
||||||
|
LD BC, #l__INITIALIZER
|
||||||
|
LD A, B
|
||||||
|
LD DE, #s__INITIALIZED
|
||||||
|
LD HL, #s__INITIALIZER
|
||||||
|
LDIR
|
||||||
|
__endasm;
|
||||||
|
// init heap for malloc() and run main pgm.
|
||||||
|
_sdcc_heap_init();
|
||||||
|
main();
|
||||||
|
}
|
||||||
|
|
||||||
|
// VECTOR ROUTINES
|
||||||
|
|
||||||
|
int dvgwrofs; // write offset for DVG buffer
|
||||||
|
|
||||||
|
inline word ___swapw(word j) {
|
||||||
|
return ((j << 8) | (j >> 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void dvgreset() {
|
||||||
|
dvgwrofs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void dvgstart() {
|
||||||
|
_dvgstart = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvgwrite(word w) {
|
||||||
|
dvgram[dvgwrofs++] = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void VCTR(int dx, int dy, byte bright) {
|
||||||
|
dvgwrite((dy & 0x1fff));
|
||||||
|
dvgwrite(((bright & 7) << 13) | (dx & 0x1fff));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SVEC(signed char dx, signed char dy, byte bright) {
|
||||||
|
dvgwrite(0x4000 | (dx & 0x1f) | ((bright&7)<<5) | ((dy & 0x1f)<<8));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void JSRL(word offset) {
|
||||||
|
dvgwrite(0xa000 | offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void JMPL(word offset) {
|
||||||
|
dvgwrite(0xe000 | offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RTSL() {
|
||||||
|
dvgwrite(0xc000);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CNTR() {
|
||||||
|
dvgwrite(0x8000);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void HALT() {
|
||||||
|
dvgwrite(0x2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void STAT(byte rgb, byte intens) {
|
||||||
|
dvgwrite(0x6000 | ((intens & 0xf)<<4) | (rgb & 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SCAL(word scale) {
|
||||||
|
dvgwrite(0x7000 | scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, YELLOW, WHITE
|
||||||
|
} Color;
|
||||||
|
|
||||||
|
|
||||||
|
/// https://trmm.net/Asteroids_font
|
||||||
|
|
||||||
|
#define P(x,y) ((((x) & 0xF) << 4) | (((y) & 0xF) << 0))
|
||||||
|
#define FONT_UP 0xFE
|
||||||
|
#define FONT_LAST 0xFF
|
||||||
|
|
||||||
|
const byte vecfont[95][8] = {
|
||||||
|
['0' - 0x20] = { P(0,0), P(8,0), P(8,12), P(0,12), P(0,0), P(8,12), FONT_LAST },
|
||||||
|
['1' - 0x20] = { P(4,0), P(4,12), P(3,10), FONT_LAST },
|
||||||
|
['2' - 0x20] = { P(0,12), P(8,12), P(8,7), P(0,5), P(0,0), P(8,0), FONT_LAST },
|
||||||
|
['3' - 0x20] = { P(0,12), P(8,12), P(8,0), P(0,0), FONT_UP, P(0,6), P(8,6), FONT_LAST },
|
||||||
|
['4' - 0x20] = { P(0,12), P(0,6), P(8,6), FONT_UP, P(8,12), P(8,0), FONT_LAST },
|
||||||
|
['5' - 0x20] = { P(0,0), P(8,0), P(8,6), P(0,7), P(0,12), P(8,12), FONT_LAST },
|
||||||
|
['6' - 0x20] = { P(0,12), P(0,0), P(8,0), P(8,5), P(0,7), FONT_LAST },
|
||||||
|
['7' - 0x20] = { P(0,12), P(8,12), P(8,6), P(4,0), FONT_LAST },
|
||||||
|
['8' - 0x20] = { P(0,0), P(8,0), P(8,12), P(0,12), P(0,0), FONT_UP, P(0,6), P(8,6), },
|
||||||
|
['9' - 0x20] = { P(8,0), P(8,12), P(0,12), P(0,7), P(8,5), FONT_LAST },
|
||||||
|
[' ' - 0x20] = { FONT_LAST },
|
||||||
|
['.' - 0x20] = { P(3,0), P(4,0), FONT_LAST },
|
||||||
|
[',' - 0x20] = { P(2,0), P(4,2), FONT_LAST },
|
||||||
|
['-' - 0x20] = { P(2,6), P(6,6), FONT_LAST },
|
||||||
|
['+' - 0x20] = { P(1,6), P(7,6), FONT_UP, P(4,9), P(4,3), FONT_LAST },
|
||||||
|
['!' - 0x20] = { P(4,0), P(3,2), P(5,2), P(4,0), FONT_UP, P(4,4), P(4,12), FONT_LAST },
|
||||||
|
['#' - 0x20] = { P(0,4), P(8,4), P(6,2), P(6,10), P(8,8), P(0,8), P(2,10), P(2,2) },
|
||||||
|
['^' - 0x20] = { P(2,6), P(4,12), P(6,6), FONT_LAST },
|
||||||
|
['=' - 0x20] = { P(1,4), P(7,4), FONT_UP, P(1,8), P(7,8), FONT_LAST },
|
||||||
|
['*' - 0x20] = { P(0,0), P(4,12), P(8,0), P(0,8), P(8,8), P(0,0), FONT_LAST },
|
||||||
|
['_' - 0x20] = { P(0,0), P(8,0), FONT_LAST },
|
||||||
|
['/' - 0x20] = { P(0,0), P(8,12), FONT_LAST },
|
||||||
|
['\\' - 0x20] = { P(0,12), P(8,0), FONT_LAST },
|
||||||
|
['@' - 0x20] = { P(8,4), P(4,0), P(0,4), P(0,8), P(4,12), P(8,8), P(4,4), P(3,6) },
|
||||||
|
['$' - 0x20] = { P(6,2), P(2,6), P(6,10), FONT_UP, P(4,12), P(4,0), FONT_LAST },
|
||||||
|
['&' - 0x20] = { P(8,0), P(4,12), P(8,8), P(0,4), P(4,0), P(8,4), FONT_LAST },
|
||||||
|
['[' - 0x20] = { P(6,0), P(2,0), P(2,12), P(6,12), FONT_LAST },
|
||||||
|
[']' - 0x20] = { P(2,0), P(6,0), P(6,12), P(2,12), FONT_LAST },
|
||||||
|
['(' - 0x20] = { P(6,0), P(2,4), P(2,8), P(6,12), FONT_LAST },
|
||||||
|
[')' - 0x20] = { P(2,0), P(6,4), P(6,8), P(2,12), FONT_LAST },
|
||||||
|
['{' - 0x20] = { P(6,0), P(4,2), P(4,10), P(6,12), FONT_UP, P(2,6), P(4,6), FONT_LAST },
|
||||||
|
['}' - 0x20] = { P(4,0), P(6,2), P(6,10), P(4,12), FONT_UP, P(6,6), P(8,6), FONT_LAST },
|
||||||
|
['%' - 0x20] = { P(0,0), P(8,12), FONT_UP, P(2,10), P(2,8), FONT_UP, P(6,4), P(6,2) },
|
||||||
|
['<' - 0x20] = { P(6,0), P(2,6), P(6,12), FONT_LAST },
|
||||||
|
['>' - 0x20] = { P(2,0), P(6,6), P(2,12), FONT_LAST },
|
||||||
|
['|' - 0x20] = { P(4,0), P(4,5), FONT_UP, P(4,6), P(4,12), FONT_LAST },
|
||||||
|
[':' - 0x20] = { P(4,9), P(4,7), FONT_UP, P(4,5), P(4,3), FONT_LAST },
|
||||||
|
[';' - 0x20] = { P(4,9), P(4,7), FONT_UP, P(4,5), P(1,2), FONT_LAST },
|
||||||
|
['"' - 0x20] = { P(2,10), P(2,6), FONT_UP, P(6,10), P(6,6), FONT_LAST },
|
||||||
|
['\'' - 0x20] = { P(2,6), P(6,10), FONT_LAST },
|
||||||
|
['`' - 0x20] = { P(2,10), P(6,6), FONT_LAST },
|
||||||
|
['~' - 0x20] = { P(0,4), P(2,8), P(6,4), P(8,8), FONT_LAST },
|
||||||
|
['?' - 0x20] = { P(0,8), P(4,12), P(8,8), P(4,4), FONT_UP, P(4,1), P(4,0), FONT_LAST },
|
||||||
|
['A' - 0x20] = { P(0,0), P(0,8), P(4,12), P(8,8), P(8,0), FONT_UP, P(0,4), P(8,4) },
|
||||||
|
['B' - 0x20] = { P(0,0), P(0,12), P(4,12), P(8,10), P(4,6), P(8,2), P(4,0), P(0,0) },
|
||||||
|
['C' - 0x20] = { P(8,0), P(0,0), P(0,12), P(8,12), FONT_LAST },
|
||||||
|
['D' - 0x20] = { P(0,0), P(0,12), P(4,12), P(8,8), P(8,4), P(4,0), P(0,0), FONT_LAST },
|
||||||
|
['E' - 0x20] = { P(8,0), P(0,0), P(0,12), P(8,12), FONT_UP, P(0,6), P(6,6), FONT_LAST },
|
||||||
|
['F' - 0x20] = { P(0,0), P(0,12), P(8,12), FONT_UP, P(0,6), P(6,6), FONT_LAST },
|
||||||
|
['G' - 0x20] = { P(6,6), P(8,4), P(8,0), P(0,0), P(0,12), P(8,12), FONT_LAST },
|
||||||
|
['H' - 0x20] = { P(0,0), P(0,12), FONT_UP, P(0,6), P(8,6), FONT_UP, P(8,12), P(8,0) },
|
||||||
|
['I' - 0x20] = { P(0,0), P(8,0), FONT_UP, P(4,0), P(4,12), FONT_UP, P(0,12), P(8,12) },
|
||||||
|
['J' - 0x20] = { P(0,4), P(4,0), P(8,0), P(8,12), FONT_LAST },
|
||||||
|
['K' - 0x20] = { P(0,0), P(0,12), FONT_UP, P(8,12), P(0,6), P(6,0), FONT_LAST },
|
||||||
|
['L' - 0x20] = { P(8,0), P(0,0), P(0,12), FONT_LAST },
|
||||||
|
['M' - 0x20] = { P(0,0), P(0,12), P(4,8), P(8,12), P(8,0), FONT_LAST },
|
||||||
|
['N' - 0x20] = { P(0,0), P(0,12), P(8,0), P(8,12), FONT_LAST },
|
||||||
|
['O' - 0x20] = { P(0,0), P(0,12), P(8,12), P(8,0), P(0,0), FONT_LAST },
|
||||||
|
['P' - 0x20] = { P(0,0), P(0,12), P(8,12), P(8,6), P(0,5), FONT_LAST },
|
||||||
|
['Q' - 0x20] = { P(0,0), P(0,12), P(8,12), P(8,4), P(0,0), FONT_UP, P(4,4), P(8,0) },
|
||||||
|
['R' - 0x20] = { P(0,0), P(0,12), P(8,12), P(8,6), P(0,5), FONT_UP, P(4,5), P(8,0) },
|
||||||
|
['S' - 0x20] = { P(0,2), P(2,0), P(8,0), P(8,5), P(0,7), P(0,12), P(6,12), P(8,10) },
|
||||||
|
['T' - 0x20] = { P(0,12), P(8,12), FONT_UP, P(4,12), P(4,0), FONT_LAST },
|
||||||
|
['U' - 0x20] = { P(0,12), P(0,2), P(4,0), P(8,2), P(8,12), FONT_LAST },
|
||||||
|
['V' - 0x20] = { P(0,12), P(4,0), P(8,12), FONT_LAST },
|
||||||
|
['W' - 0x20] = { P(0,12), P(2,0), P(4,4), P(6,0), P(8,12), FONT_LAST },
|
||||||
|
['X' - 0x20] = { P(0,0), P(8,12), FONT_UP, P(0,12), P(8,0), FONT_LAST },
|
||||||
|
['Y' - 0x20] = { P(0,12), P(4,6), P(8,12), FONT_UP, P(4,6), P(4,0), FONT_LAST },
|
||||||
|
['Z' - 0x20] = { P(0,12), P(8,12), P(0,0), P(8,0), FONT_UP, P(2,6), P(6,6), FONT_LAST },
|
||||||
|
};
|
||||||
|
|
||||||
|
void draw_char(char ch) {
|
||||||
|
const byte* p = vecfont[ch-0x20];
|
||||||
|
byte bright = 0;
|
||||||
|
byte x = 0;
|
||||||
|
byte y = 0;
|
||||||
|
byte i;
|
||||||
|
for (i=0; i<8; i++) {
|
||||||
|
byte b = *p++;
|
||||||
|
if (b == FONT_LAST) break; // last move
|
||||||
|
else if (b == FONT_UP) bright = 0; // pen up
|
||||||
|
else {
|
||||||
|
byte x2 = b>>4;
|
||||||
|
byte y2 = b&15;
|
||||||
|
SVEC((char)(x2-x), (char)(y2-y), bright);
|
||||||
|
bright = 4;
|
||||||
|
x = x2;
|
||||||
|
y = y2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SVEC((char)12-x, (char)-y, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_string(const char* str, byte spacing) {
|
||||||
|
while (*str) {
|
||||||
|
draw_char(*str++);
|
||||||
|
if (spacing) SVEC(spacing, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MATH/3D ROUTINES
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
sbyte m[3][3];
|
||||||
|
} Matrix;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
sbyte x,y,z;
|
||||||
|
} Vector8;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int x,y,z;
|
||||||
|
} Vector16;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
byte numverts;
|
||||||
|
const Vector8* verts; // array of vertices
|
||||||
|
const sbyte* edges; // array of vertex indices (edges)
|
||||||
|
} Wireframe;
|
||||||
|
|
||||||
|
void mat_identity(Matrix* m) {
|
||||||
|
memset(m, 0, sizeof(*m));
|
||||||
|
m->m[0][0] = 127;
|
||||||
|
m->m[1][1] = 127;
|
||||||
|
m->m[2][2] = 127;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void mul16(sbyte a, sbyte b) {
|
||||||
|
mathbox_arg1 = a;
|
||||||
|
mathbox_arg2 = b;
|
||||||
|
mathbox_go_mul=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vec_mat_transform(Vector16* dest, const Vector8* v, const Matrix* m) {
|
||||||
|
byte i;
|
||||||
|
int* result = &dest->x;
|
||||||
|
const sbyte* mval = &m->m[0][0];
|
||||||
|
for (i=0; i<3; i++) {
|
||||||
|
mathbox_sum = 0;
|
||||||
|
mul16(*mval++, v->x);
|
||||||
|
mul16(*mval++, v->y);
|
||||||
|
mul16(*mval++, v->z);
|
||||||
|
*result++ = mathbox_sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sbyte sintbl[64] = {
|
||||||
|
0, 3, 6, 9, 12, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46,
|
||||||
|
49, 51, 54, 57, 60, 63, 65, 68, 71, 73, 76, 78, 81, 83, 85, 88,
|
||||||
|
90, 92, 94, 96, 98, 100, 102, 104, 106, 107, 109, 111, 112, 113, 115, 116,
|
||||||
|
117, 118, 120, 121, 122, 122, 123, 124, 125, 125, 126, 126, 126, 127, 127, 127,
|
||||||
|
};
|
||||||
|
|
||||||
|
sbyte isin(byte x0) {
|
||||||
|
byte x = x0;
|
||||||
|
if (x0 & 0x40) x = 127-x;
|
||||||
|
if (x0 & 0x80) {
|
||||||
|
return -sintbl[x+128];
|
||||||
|
} else {
|
||||||
|
return sintbl[x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sbyte icos(byte x) {
|
||||||
|
return isin(x+64);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat_rotate(Matrix* m, byte axis, byte angle) {
|
||||||
|
sbyte sin = isin(angle);
|
||||||
|
sbyte cos = icos(angle);
|
||||||
|
mat_identity(m);
|
||||||
|
switch (axis) {
|
||||||
|
case 0:
|
||||||
|
m->m[1][1] = cos;
|
||||||
|
m->m[2][1] = sin;
|
||||||
|
m->m[1][2] = -sin;
|
||||||
|
m->m[2][2] = cos;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
m->m[2][2] = cos;
|
||||||
|
m->m[0][2] = sin;
|
||||||
|
m->m[2][0] = -sin;
|
||||||
|
m->m[0][0] = cos;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
m->m[0][0] = cos;
|
||||||
|
m->m[1][0] = sin;
|
||||||
|
m->m[0][1] = -sin;
|
||||||
|
m->m[1][1] = cos;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void xform_vertices(Vector16* dest, const Vector8* src, const Matrix* m, byte nv) {
|
||||||
|
byte i;
|
||||||
|
for (i=0; i<nv; i++) {
|
||||||
|
vec_mat_transform(dest++, src++, m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_wireframe_ortho(const Wireframe* wf, const Matrix* m) {
|
||||||
|
const char* e = wf->edges;
|
||||||
|
byte bright = 0;
|
||||||
|
int x1 = 0;
|
||||||
|
int y1 = 0;
|
||||||
|
Vector16 scrnverts[16];
|
||||||
|
xform_vertices(scrnverts, wf->verts, m, wf->numverts);
|
||||||
|
do {
|
||||||
|
sbyte i = *e++;
|
||||||
|
if (i == -1)
|
||||||
|
bright = 0;
|
||||||
|
else if (i == -2)
|
||||||
|
break;
|
||||||
|
else {
|
||||||
|
int x2 = scrnverts[i].x>>8;
|
||||||
|
int y2 = scrnverts[i].y>>8;
|
||||||
|
VCTR(x2-x1, y2-y1, bright);
|
||||||
|
x1 = x2;
|
||||||
|
y1 = y2;
|
||||||
|
}
|
||||||
|
bright = 2;
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static word lfsr = 1;
|
||||||
|
|
||||||
|
word rand() {
|
||||||
|
word lsb = lfsr & 1;
|
||||||
|
lfsr >>= 1;
|
||||||
|
if (lsb) lfsr ^= 0xd400;
|
||||||
|
return lfsr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SHAPE CACHE
|
||||||
|
|
||||||
|
const Vector8 tetra_v[] = { {0,-86,86},{86,86,86},{-86,86,86},{0,0,-86} };
|
||||||
|
const char tetra_e[] = { 0, 1, 2, 0, 3, 1, -1, 3, 2, -2 };
|
||||||
|
const Wireframe tetra_wf = { 4, tetra_v, tetra_e };
|
||||||
|
|
||||||
|
const Vector8 ship_v[] = { {0,-86,0},{-30,30,0},{-50,0,0},{50,0,0},{30,30,0} };
|
||||||
|
const char ship_e[] = { 0, 1, 2, 3, 4, 0, -2 };
|
||||||
|
const Wireframe ship_wf = { 5, ship_v, ship_e };
|
||||||
|
|
||||||
|
const Vector8 thrust_v[] = { {-20,30,0},{-30,50,0},{0,86,0},{30,50,0},{20,30,0} };
|
||||||
|
const char thrust_e[] = { 0, 1, 2, 3, 4, -2 };
|
||||||
|
const Wireframe thrust_wf = { 5, thrust_v, thrust_e };
|
||||||
|
|
||||||
|
word ship_shapes[32];
|
||||||
|
word thrust_shapes[32];
|
||||||
|
word tetra_shapes[32];
|
||||||
|
|
||||||
|
void make_cached_shapes() {
|
||||||
|
Matrix mat;
|
||||||
|
byte i;
|
||||||
|
for (i=0; i<32; i++) {
|
||||||
|
ship_shapes[i] = dvgwrofs;
|
||||||
|
mat_rotate(&mat, 2, i<<3);
|
||||||
|
draw_wireframe_ortho(&ship_wf, &mat);
|
||||||
|
RTSL();
|
||||||
|
thrust_shapes[i] = dvgwrofs;
|
||||||
|
draw_wireframe_ortho(&thrust_wf, &mat);
|
||||||
|
RTSL();
|
||||||
|
tetra_shapes[i] = dvgwrofs;
|
||||||
|
mat_rotate(&mat, 0, i<<3);
|
||||||
|
draw_wireframe_ortho(&tetra_wf, &mat);
|
||||||
|
RTSL();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MAIN PROGRAM
|
||||||
|
|
||||||
|
struct Actor;
|
||||||
|
|
||||||
|
typedef void ActorUpdateFn(struct Actor*);
|
||||||
|
|
||||||
|
typedef struct Actor {
|
||||||
|
word* shapes;
|
||||||
|
ActorUpdateFn* update_fn;
|
||||||
|
byte angshift;
|
||||||
|
byte scale;
|
||||||
|
byte color;
|
||||||
|
byte intens;
|
||||||
|
byte angle;
|
||||||
|
word xx;
|
||||||
|
word yy;
|
||||||
|
int velx;
|
||||||
|
int vely;
|
||||||
|
struct Actor* next;
|
||||||
|
} Actor;
|
||||||
|
|
||||||
|
#define WORLD_SCALE 0x2c0
|
||||||
|
|
||||||
|
void draw_actor(const Actor* a) {
|
||||||
|
CNTR(); // center beam (0,0)
|
||||||
|
SCAL(WORLD_SCALE); // world scale
|
||||||
|
VCTR(a->xx>>3, a->yy>>3, 0); // go to object center
|
||||||
|
SCAL(a->scale); // object scale
|
||||||
|
STAT(a->color, a->intens); // set color/intensity
|
||||||
|
JSRL(a->shapes[a->angle >> a->angshift]); // draw
|
||||||
|
}
|
||||||
|
|
||||||
|
void move_actor(Actor* a) {
|
||||||
|
a->xx += a->velx;
|
||||||
|
a->yy += a->vely;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Actor* first_actor = NULL;
|
||||||
|
|
||||||
|
Actor* new_actor(const Actor* base) {
|
||||||
|
Actor* a = (Actor*) malloc(sizeof(Actor));
|
||||||
|
memcpy(a, base, sizeof(Actor));
|
||||||
|
a->next = first_actor;
|
||||||
|
first_actor = a;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void obstacle_update_fn(struct Actor* a) {
|
||||||
|
a->angle += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Actor ship_actor = {
|
||||||
|
ship_shapes, NULL, 3, 0xb0, WHITE, 7, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Actor tetra_actor = {
|
||||||
|
tetra_shapes, obstacle_update_fn, 3, 0x80, CYAN, 7, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
void create_obstacles(byte count) {
|
||||||
|
while (count--) {
|
||||||
|
Actor* a = new_actor(&tetra_actor);
|
||||||
|
a->xx = rand();
|
||||||
|
a->yy = rand();
|
||||||
|
a->velx = (int)rand()<<8>>8;
|
||||||
|
a->vely = (int)rand()<<8>>8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_actors() {
|
||||||
|
Actor* a = first_actor;
|
||||||
|
while (a) {
|
||||||
|
draw_actor(a);
|
||||||
|
move_actor(a);
|
||||||
|
if (a->update_fn) a->update_fn(a);
|
||||||
|
a = a->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_actor_rect(Actor* a) {
|
||||||
|
CNTR(); // center beam (0,0)
|
||||||
|
SCAL(WORLD_SCALE); // world scale
|
||||||
|
VCTR(a->xx>>3, a->yy>>3, 0); // go to object center
|
||||||
|
SCAL(a->scale); // object scale
|
||||||
|
STAT(RED, 7); // set color/intensity
|
||||||
|
VCTR(-86,-86,0);
|
||||||
|
VCTR(86*2,0,2);
|
||||||
|
VCTR(0,86*2,2);
|
||||||
|
VCTR(-86*2,0,2);
|
||||||
|
VCTR(0,-86*2,2);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline byte abs(sbyte x) {
|
||||||
|
return (x>=0) ? x : -x;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline sbyte get_distance(byte x1, byte y1, byte x2, byte y2) {
|
||||||
|
sbyte dx = abs(x2-x1);
|
||||||
|
sbyte dy = abs(y2-y1);
|
||||||
|
return (dx>>1) + (dy>>1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Actor* test_actor_distance(ActorUpdateFn* fn, Actor* act1, byte mindist) {
|
||||||
|
Actor* a = first_actor;
|
||||||
|
byte xx1 = act1->xx >> 8;
|
||||||
|
byte yy1 = act1->yy >> 8;
|
||||||
|
while (a) {
|
||||||
|
if (a != act1) {
|
||||||
|
sbyte dist = get_distance(xx1, yy1, a->xx >> 8, a->yy >> 8);
|
||||||
|
if (dist < mindist) fn(a);
|
||||||
|
}
|
||||||
|
a = a->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int frame = 0;
|
||||||
|
|
||||||
|
static Actor* curship;
|
||||||
|
|
||||||
|
void draw_thrust() {
|
||||||
|
word rnd = rand();
|
||||||
|
// save old values in actor
|
||||||
|
byte oldcolor = curship->color;
|
||||||
|
byte oldintens = curship->intens;
|
||||||
|
// temporarily give new thrust values
|
||||||
|
curship->shapes = thrust_shapes;
|
||||||
|
curship->scale ^= rnd; // random thrust scale
|
||||||
|
curship->intens = 15;
|
||||||
|
curship->color = (rnd&1) ? RED : YELLOW;
|
||||||
|
// draw thrust using player's ship actor
|
||||||
|
draw_actor(curship);
|
||||||
|
// restore previous values
|
||||||
|
curship->shapes = ship_shapes;
|
||||||
|
curship->scale ^= rnd;
|
||||||
|
curship->color = oldcolor;
|
||||||
|
curship->intens = oldintens;
|
||||||
|
}
|
||||||
|
|
||||||
|
void thrust_ship() {
|
||||||
|
sbyte sin = isin(curship->angle);
|
||||||
|
sbyte cos = icos(curship->angle);
|
||||||
|
curship->velx += sin>>3;
|
||||||
|
curship->vely -= cos>>3;
|
||||||
|
}
|
||||||
|
|
||||||
|
int apply_friction(int vel) {
|
||||||
|
int delta = vel >> 8;
|
||||||
|
if (delta == 0 && vel > 0) delta++;
|
||||||
|
return vel - delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
void move_player() {
|
||||||
|
if (!curship) return;
|
||||||
|
if (LEFT1) curship->angle += 2;
|
||||||
|
if (RIGHT1) curship->angle -= 2;
|
||||||
|
if ((frame&3)==1) {
|
||||||
|
curship->velx = apply_friction(curship->velx);
|
||||||
|
curship->vely = apply_friction(curship->vely);
|
||||||
|
}
|
||||||
|
if (UP1) {
|
||||||
|
// draw colorful flame
|
||||||
|
draw_thrust();
|
||||||
|
// thrust every 4 frames, to avoid precision issues
|
||||||
|
if (!(frame&3)) thrust_ship();
|
||||||
|
}
|
||||||
|
test_actor_distance(draw_actor_rect, curship, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
memset(dvgram, 0x20, sizeof(dvgram)); // HALTs
|
||||||
|
dvgwrofs = 0x800;
|
||||||
|
//draw_string("HELLO WORLD", 0);
|
||||||
|
//RTSL();
|
||||||
|
make_cached_shapes();
|
||||||
|
create_obstacles(5);
|
||||||
|
curship = new_actor(&ship_actor);
|
||||||
|
while (1) {
|
||||||
|
dvgreset();
|
||||||
|
update_actors();
|
||||||
|
move_player();
|
||||||
|
HALT();
|
||||||
|
dvgstart();
|
||||||
|
frame++;
|
||||||
|
}
|
||||||
|
}
|
@ -43,8 +43,8 @@ void dvgwrite(word w) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void VCTR(int dx, int dy, byte bright) {
|
inline void VCTR(int dx, int dy, byte bright) {
|
||||||
dvgwrite((dx & 0x1fff));
|
dvgwrite((dy & 0x1fff));
|
||||||
dvgwrite(((bright & 7) << 13) | (dy & 0x1fff));
|
dvgwrite(((bright & 7) << 13) | (dx & 0x1fff));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SVEC(sbyte dx, sbyte dy, byte bright) {
|
inline void SVEC(sbyte dx, sbyte dy, byte bright) {
|
||||||
|
@ -125,7 +125,7 @@ mainElement.appendChild(borderElement);
|
|||||||
var VectorVideo = function(mainElement, width, height) {
|
var VectorVideo = function(mainElement, width, height) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var canvas, ctx;
|
var canvas, ctx;
|
||||||
var persistenceAlpha = 0.8;
|
var persistenceAlpha = 0.5;
|
||||||
var jitter = 1.0;
|
var jitter = 1.0;
|
||||||
var gamma = 0.8;
|
var gamma = 0.8;
|
||||||
var sx = width/1024.0;
|
var sx = width/1024.0;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
var VECTOR_PRESETS = [
|
var VECTOR_PRESETS = [
|
||||||
{id:'font.c', name:'Vector Fonts'},
|
{id:'font.c', name:'Vector Fonts'},
|
||||||
{id:'threed.c', name:'3D Transformations'},
|
{id:'threed.c', name:'3D Transformations'},
|
||||||
|
{id:'game.c', name:'Space Game'},
|
||||||
]
|
]
|
||||||
|
|
||||||
var ASTEROIDS_KEYCODE_MAP = makeKeycodeMap([
|
var ASTEROIDS_KEYCODE_MAP = makeKeycodeMap([
|
||||||
@ -29,6 +30,7 @@ var GRAVITAR_KEYCODE_MAP = makeKeycodeMap([
|
|||||||
[Keys.VK_1, 2, 0x20],
|
[Keys.VK_1, 2, 0x20],
|
||||||
[Keys.VK_2, 2, 0x40],
|
[Keys.VK_2, 2, 0x40],
|
||||||
[Keys.VK_UP, 1, -0x10],
|
[Keys.VK_UP, 1, -0x10],
|
||||||
|
[Keys.VK_DOWN, 1, -0x20],
|
||||||
[Keys.VK_RIGHT, 1, -0x4],
|
[Keys.VK_RIGHT, 1, -0x4],
|
||||||
[Keys.VK_LEFT, 1, -0x8],
|
[Keys.VK_LEFT, 1, -0x8],
|
||||||
]);
|
]);
|
||||||
@ -192,9 +194,9 @@ var AtariColorVectorPlatform = function(mainElement) {
|
|||||||
earom = new RAM(0x40);
|
earom = new RAM(0x40);
|
||||||
rom = padBytes(new lzgmini().decode(GRAVITAR_ROM).slice(0), 0x7000+1);
|
rom = padBytes(new lzgmini().decode(GRAVITAR_ROM).slice(0), 0x7000+1);
|
||||||
vecrom = padBytes(new lzgmini().decode(GRAVITAR_VECROM).slice(0), 0x6000-0x2800+1);
|
vecrom = padBytes(new lzgmini().decode(GRAVITAR_VECROM).slice(0), 0x6000-0x2800+1);
|
||||||
switches[0] = 0xff;
|
switches[0] = 0x0;
|
||||||
switches[1] = 0xff;
|
switches[1] = 0xff;
|
||||||
switches[2] = 0xff;
|
switches[2] = 0x0;
|
||||||
// bus
|
// bus
|
||||||
bus = {
|
bus = {
|
||||||
|
|
||||||
@ -376,7 +378,7 @@ var Z80ColorVectorPlatform = function(mainElement, proto) {
|
|||||||
cpu.requestInterrupt();
|
cpu.requestInterrupt();
|
||||||
self.restartDebugState();
|
self.restartDebugState();
|
||||||
});
|
});
|
||||||
setKeyboardFromMap(video, switches, ASTEROIDS_KEYCODE_MAP);
|
setKeyboardFromMap(video, switches, GRAVITAR_KEYCODE_MAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadROM = function(title, data) {
|
this.loadROM = function(title, data) {
|
||||||
|
Loading…
Reference in New Issue
Block a user