mirror of
https://github.com/deater/dos33fsprogs.git
synced 2024-11-17 14:12:58 +00:00
314 lines
5.8 KiB
C
314 lines
5.8 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <math.h>
|
|
|
|
#include "6502_emulate.h"
|
|
#include "gr-sim.h"
|
|
|
|
// Based on BASIC program posted by FozzTexx, originally written in 1987
|
|
|
|
//140 REM MS is max steps, CS is current step, X/Y/X1/Y1/X2/Y2 is rocket position
|
|
//150 REM CL is Apple II hi-res color group
|
|
|
|
const int ysize=160,xsize=280,margin=24;
|
|
|
|
int xpos;
|
|
|
|
signed char o,i;
|
|
signed char color_group,x_velocity,cs,max_steps;
|
|
unsigned char xpos_l;
|
|
unsigned char ypos_h,ypos_l;
|
|
signed char y_velocity_h;
|
|
unsigned char y_velocity_l;
|
|
unsigned char y_old=0,y_even_older;
|
|
unsigned char x_old=0,x_even_older;
|
|
unsigned char peak;
|
|
|
|
#define NUMSTARS 16
|
|
|
|
struct star_type {
|
|
unsigned char x;
|
|
unsigned char y;
|
|
|
|
} stars[NUMSTARS] = {
|
|
// even x so they are purple
|
|
{28,107},
|
|
{108,88},
|
|
{126,88},
|
|
{136,95},
|
|
{150,105},
|
|
{148,120},
|
|
{172,124},
|
|
{180,109},
|
|
{216,21},
|
|
{164,40},
|
|
{124,18},
|
|
{60,12},
|
|
{240,124},
|
|
{94,125},
|
|
{12,22},
|
|
{216,116},
|
|
};
|
|
|
|
|
|
#define SEED 0
|
|
#define MAGIC "vW" // $7657
|
|
|
|
/* based on Linear feedback shift register type of PRNG by White Flame */
|
|
/* http://codebase64.org/doku.php?id=base:small_fast_16-bit_prng */
|
|
void random_6502(void) {
|
|
|
|
lda(SEED); // lda seed
|
|
if (a==0) goto lowZero; // beq lowZero ; $0000 and $8000 are special values to test for
|
|
// ; Do a normal shift
|
|
asl_mem(SEED); // asl seed
|
|
lda(SEED+1); // lda seed+1
|
|
rol(); // rol
|
|
if (c==0) goto noEor; // bcc noEor
|
|
|
|
doEor:
|
|
// ; high byte is in .A
|
|
a=a^0x76; // eor #>magic
|
|
ram[SEED+1]=a; // sta seed+1
|
|
lda(SEED); // lda seed
|
|
a=a^0x57; // eor #<magic
|
|
ram[SEED]=a; // sta seed
|
|
return; // rts
|
|
|
|
|
|
lowZero:
|
|
lda(SEED+1); // lda seed+1
|
|
if (a==0) goto doEor;
|
|
// beq doEor ; High byte is also zero, so apply the EOR
|
|
// ; For speed, you could store 'magic' into 'seed' directly
|
|
// ; instead of running the EORs
|
|
|
|
// ; wasn't zero, check for $8000
|
|
asl(); // asl
|
|
if (a==0) goto noEor;
|
|
// beq noEor ; if $00 is left after the shift, then it was $80
|
|
if (c==1) goto doEor;
|
|
// bcs doEor ; else, do the EOR based on the carry bit as usual
|
|
|
|
noEor:
|
|
ram[SEED+1]=a; // sta seed+1
|
|
|
|
return; // rts
|
|
}
|
|
|
|
static void add16(unsigned char *a1h, unsigned char *a1l,
|
|
unsigned char a2h,unsigned char a2l) {
|
|
|
|
short i,j;
|
|
|
|
i=(*a1h<<8)|(*a1l);
|
|
j=(a2h<<8)|(a2l);
|
|
i+=j;
|
|
*a1h=i>>8;
|
|
*a1l=i&0xff;
|
|
|
|
return;
|
|
}
|
|
|
|
static void sadd16(signed char *a1h, unsigned char *a1l,
|
|
unsigned char a2h,unsigned char a2l) {
|
|
|
|
short i,j;
|
|
|
|
i=(*a1h<<8)|(*a1l);
|
|
j=(a2h<<8)|(a2l);
|
|
i+=j;
|
|
*a1h=i>>8;
|
|
*a1l=i&0xff;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void routine_370(void) {
|
|
|
|
hplot(xpos+o,ypos_h+o); // NE
|
|
hplot(xpos-o,ypos_h-o); // SW
|
|
|
|
hplot(xpos+o,ypos_h-o); // SE
|
|
hplot(xpos-o,ypos_h+o); // NW
|
|
|
|
hplot(xpos,ypos_h+(o*1.5)); // N
|
|
hplot(xpos+(o*1.5),ypos_h); // E
|
|
|
|
hplot(xpos,ypos_h-(o*1.5)); // S
|
|
hplot(xpos-(o*1.5),ypos_h); // W
|
|
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
int ch;
|
|
|
|
grsim_init();
|
|
|
|
for(i=0;i<100;i++) {
|
|
random_6502();
|
|
printf("%02x%02x\n",ram[SEED+1],ram[SEED]);
|
|
}
|
|
|
|
home();
|
|
|
|
hgr();
|
|
soft_switch(MIXCLR); // Full screen
|
|
|
|
|
|
|
|
label_180:
|
|
random_6502();
|
|
color_group=ram[SEED]&1; // HGR color group (PG or BO)
|
|
random_6502();
|
|
x_velocity=(ram[SEED]&0x3)+1; // x velocity = 1..4
|
|
random_6502();
|
|
y_velocity_h=-((ram[SEED]&0x3)+3); // y velocity = -3..-6
|
|
y_velocity_l=0;
|
|
|
|
random_6502();
|
|
max_steps=(ram[SEED]&0x1f)+33; // 33..64
|
|
|
|
/* launch from the two hills */
|
|
random_6502();
|
|
xpos_l=ram[SEED]&0x3f;
|
|
random_6502();
|
|
if (ram[SEED]&1) {
|
|
xpos_l+=24; // 24-88 (64)
|
|
}
|
|
else {
|
|
xpos_l+=191; // 191-255 (64)
|
|
}
|
|
|
|
|
|
ypos_h=ysize; // start at ground
|
|
ypos_l=0;
|
|
|
|
peak=ypos_h; // peak starts at ground?
|
|
|
|
/* Aim towards center of screen */
|
|
/* TODO: merge this with hill location? */
|
|
if (xpos_l>xsize/2) {
|
|
x_velocity=-x_velocity;
|
|
}
|
|
|
|
/* Draw rocket */
|
|
for(cs=1;cs<=max_steps;cs++) {
|
|
y_even_older=y_old;
|
|
y_old=ypos_h;
|
|
x_even_older=x_old;
|
|
x_old=xpos_l;
|
|
|
|
/* Move rocket */
|
|
xpos_l=xpos_l+x_velocity;
|
|
|
|
/* 16 bit add */
|
|
add16(&ypos_h,&ypos_l,y_velocity_h,y_velocity_l);
|
|
|
|
/* adjust Y velocity, slow it down */
|
|
// c=0;
|
|
// a=y_velocity_l;
|
|
// adc(0x20); // 0x20 = 0.125
|
|
// y_velocity_l=a;
|
|
// a=y_velocity_h;
|
|
// adc(0);
|
|
// y_velocity_h=a;
|
|
sadd16(&y_velocity_h,&y_velocity_l,0x00,0x20);
|
|
|
|
/* if we went higher, adjust peak */
|
|
if (ypos_h<peak) peak=ypos_h;
|
|
|
|
/* check if out of bounds and stop moving */
|
|
if (xpos_l<=margin) {
|
|
cs=max_steps; // too far left
|
|
}
|
|
|
|
if (xpos_l>=(xsize-margin)) {
|
|
cs=max_steps; // too far right
|
|
}
|
|
|
|
if (ypos_h<=margin) {
|
|
cs=max_steps; // too far up
|
|
}
|
|
|
|
|
|
// if falling downward
|
|
if (y_velocity_h>0) {
|
|
// if too close to ground, explode
|
|
if (ypos_h>=ysize-margin) {
|
|
cs=max_steps;
|
|
}
|
|
// if fallen a bit past peak, explode
|
|
if (ypos_h>ysize-(ysize-peak)/2) {
|
|
cs=max_steps;
|
|
}
|
|
}
|
|
|
|
// if not done, draw rocket
|
|
if (cs<max_steps) {
|
|
hcolor_equals(color_group*4+3);
|
|
hplot(x_old,y_old);
|
|
hplot_to(xpos_l,ypos_h);
|
|
|
|
}
|
|
// erase with proper color black
|
|
hcolor_equals(color_group*4);
|
|
hplot(x_even_older,y_even_older);
|
|
hplot_to(x_old,y_old);
|
|
|
|
grsim_update();
|
|
ch=grsim_input();
|
|
if (ch=='q') exit(0);
|
|
usleep(50000);
|
|
|
|
}
|
|
|
|
|
|
label_290:
|
|
/* Draw explosion near x_old, y_old */
|
|
xpos=x_old;
|
|
xpos+=(random()%20)-10; // x +/- 10
|
|
|
|
ypos_h=y_old;
|
|
ypos_h+=(random()%20)-10; // y +/- 10
|
|
|
|
hcolor_equals(color_group*4+3); // draw white (with fringes)
|
|
|
|
hplot(xpos,ypos_h); // draw at center of explosion
|
|
|
|
/* Spread the explosion */
|
|
for(i=1;i<=9;i++) {
|
|
/* Draw spreading dots in white */
|
|
if (i<9) {
|
|
o=i;
|
|
hcolor_equals(color_group*4+3);
|
|
routine_370();
|
|
}
|
|
/* erase old */
|
|
o=i-1;
|
|
hcolor_equals(color_group*4);
|
|
routine_370();
|
|
|
|
grsim_update();
|
|
ch=grsim_input();
|
|
if (ch=='q') break;
|
|
usleep(50000);
|
|
}
|
|
|
|
/* randomly draw more explosions */
|
|
random_6502();
|
|
if (ram[SEED]&1) goto label_290;
|
|
|
|
hcolor_equals(3);
|
|
for(i=0;i<NUMSTARS;i++) {
|
|
hplot(stars[i].x,stars[i].y);
|
|
}
|
|
|
|
goto label_180;
|
|
|
|
return 0;
|
|
}
|