fireworks: draw stars

This commit is contained in:
Vince Weaver 2018-09-05 15:04:31 -04:00
parent 2b529a332f
commit 1809209c28
6 changed files with 390 additions and 18 deletions

45
asm_routines/random16.s Normal file
View File

@ -0,0 +1,45 @@
; 16-bit 6502 Random Number Generator
; Linear feedback shift register PRNG by White Flame
; http://codebase64.org/doku.php?id=base:small_fast_16-bit_prng
; The Apple II KEYIN routine increments this field
; while waiting for keypress
SEEDL = $4E
SEEDH = $4F
XOR_MAGIC = $7657 ; "vW"
random16:
lda SEEDL
beq lowZero ; $0000 and $8000 are special values // ; Do a normal shift
asl SEEDL
lda SEEDH
rol
bcc noEor
doEor:
; high byte is in .A
eor #>XOR_MAGIC
sta SEEDH
lda SEEDL
eor #<XOR_MAGIC
sta SEEDL
rts
lowZero:
lda SEEDH
beq doEor ; High byte is also zero, so apply the EOR
; wasn't zero, check for $8000
asl
beq noEor ; if $00 is left after the shift
; then it was $80
bcs doEor ; else, do the EOR based on the carry bit
noEor:
sta SEEDH
rts

View File

@ -16,7 +16,7 @@ fireworks.dsk: FIREWORKS.BAS FIREWORKS
FIREWORKS: fireworks.o
ld65 -o FIREWORKS fireworks.o -C ../linker_scripts/apple2_1000.inc
fireworks.o: fireworks.s gr_copy.s \
fireworks.o: fireworks.s gr_copy.s random16.s fw.s \
background_final.inc
ca65 -o fireworks.o fireworks.s -l fireworks.lst

View File

@ -16,6 +16,7 @@ BASL = $28
BASH = $29
FRAME = $60
BLARGH = $69
HGR_COLOR = $E4
DRAW_PAGE = $EE
LASTKEY = $F1
PADDLE_STATUS = $F2
@ -35,13 +36,22 @@ PADDL0 = $C064
PTRIG = $C070
; ROM routines
HGR = $F3E2
HPLOT0 = $F457
TEXT = $FB36 ;; Set text mode
HOME = $FC58 ;; Clear the text screen
WAIT = $FCA8 ;; delay 1/2(26+27A+5A^2) us
COLORTBL= $F6F6
MAX = 3
jsr draw_fireworks
;==================================
;==================================
lda #$ff
sta WHICH
@ -342,6 +352,8 @@ gr_offsets:
.include "../asm_routines/gr_unrle.s"
.include "../asm_routines/keypress.s"
.include "gr_copy.s"
.include "random16.s"
.include "fw.s"
pictures:
.word bg_final_low,bg_final_high

235
fireworks/fw.s Normal file
View File

@ -0,0 +1,235 @@
;=======================================================================
; Based on BASIC program posted by FozzTexx, originally written in 1987
;=======================================================================
NUMSTARS = 16
;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;
;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
;}
draw_fireworks:
jsr HOME ; clear screen
jsr HGR ; set high-res, clear screen, page0
jsr draw_stars ; draw the stars
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;
;
;
; goto label_180;
;
jsr wait_until_keypressed
rts
draw_stars:
; HCOLOR = 3, white (though they are drawn purple)
ldx #3
lda COLORTBL,X ; get color from table
sta HGR_COLOR
ldy #0
star_loop:
tya
pha
; HPLOT X,Y
; X= (y,x), Y=a
ldx stars,Y
lda stars+1,Y
ldy #0
jsr HPLOT0
pla
tay
iny
iny
cpy #NUMSTARS*2
bne star_loop
rts
stars: ; even x so they are purple
.byte 28,107, 108, 88, 126, 88, 136, 95
.byte 150,108, 148,120, 172,124, 180,109
.byte 216, 21, 164, 40, 124, 18, 60, 12
.byte 240,124, 94,125, 12, 22, 216,116

45
fireworks/random16.s Normal file
View File

@ -0,0 +1,45 @@
; 16-bit 6502 Random Number Generator
; Linear feedback shift register PRNG by White Flame
; http://codebase64.org/doku.php?id=base:small_fast_16-bit_prng
; The Apple II KEYIN routine increments this field
; while waiting for keypress
SEEDL = $4E
SEEDH = $4F
XOR_MAGIC = $7657 ; "vW"
random16:
lda SEEDL
beq lowZero ; $0000 and $8000 are special values // ; Do a normal shift
asl SEEDL
lda SEEDH
rol
bcc noEor
doEor:
; high byte is in .A
eor #>XOR_MAGIC
sta SEEDH
lda SEEDL
eor #<XOR_MAGIC
sta SEEDL
rts
lowZero:
lda SEEDH
beq doEor ; High byte is also zero, so apply the EOR
; wasn't zero, check for $8000
asl
beq noEor ; if $00 is left after the shift
; then it was $80
bcs doEor ; else, do the EOR based on the carry bit
noEor:
sta SEEDH
rts

View File

@ -13,10 +13,11 @@
const int ysize=160,xsize=280,margin=24;
double xpos;
int i,o;
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;
@ -24,6 +25,33 @@ 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
@ -130,6 +158,8 @@ int main(int argc, char **argv) {
hgr();
soft_switch(MIXCLR); // Full screen
label_180:
random_6502();
color_group=ram[SEED]&1; // HGR color group (PG or BO)
@ -144,13 +174,13 @@ label_180:
/* launch from the two hills */
random_6502();
xpos=ram[SEED]&0x3f;
xpos_l=ram[SEED]&0x3f;
random_6502();
if (ram[SEED]&1) {
xpos+=24; // 24-88 (64)
xpos_l+=24; // 24-88 (64)
}
else {
xpos+=191; // 191-255 (64)
xpos_l+=191; // 191-255 (64)
}
@ -161,7 +191,7 @@ label_180:
/* Aim towards center of screen */
/* TODO: merge this with hill location? */
if (xpos>xsize/2) {
if (xpos_l>xsize/2) {
x_velocity=-x_velocity;
}
@ -170,10 +200,10 @@ label_180:
y_even_older=y_old;
y_old=ypos_h;
x_even_older=x_old;
x_old=xpos;
x_old=xpos_l;
/* Move rocket */
xpos=xpos+x_velocity;
xpos_l=xpos_l+x_velocity;
/* 16 bit add */
add16(&ypos_h,&ypos_l,y_velocity_h,y_velocity_l);
@ -192,11 +222,11 @@ label_180:
if (ypos_h<peak) peak=ypos_h;
/* check if out of bounds and stop moving */
if (xpos<=margin) {
if (xpos_l<=margin) {
cs=max_steps; // too far left
}
if (xpos>=(xsize-margin)) {
if (xpos_l>=(xsize-margin)) {
cs=max_steps; // too far right
}
@ -221,7 +251,7 @@ label_180:
if (cs<max_steps) {
hcolor_equals(color_group*4+3);
hplot(x_old,y_old);
hplot_to(xpos,ypos_h);
hplot_to(xpos_l,ypos_h);
}
// erase with proper color black
@ -239,10 +269,10 @@ label_180:
label_290:
/* Draw explosion near x_old, y_old */
xpos=floor(x_old);
ypos_h=floor(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)
@ -269,10 +299,15 @@ label_290:
}
/* randomly draw more explosions */
if (random()%2) goto label_290;
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;
}