Compare commits

...

5 Commits

Author SHA1 Message Date
Vince Weaver
ff0b9953d3 bubble_tiny: feed back what we know 2024-05-06 01:40:50 -04:00
Vince Weaver
6570ba6153 keen: work on story 2024-05-06 01:32:33 -04:00
Vince Weaver
04e2f98a18 demos: work on a new entry 2024-05-06 01:03:55 -04:00
Vince Weaver
533e59c6f9 bubble_gr: clean up comments 2024-05-06 00:54:59 -04:00
Vince Weaver
313dc4092a bubble_gr: figured out how to get it down to 256 2024-05-06 00:52:48 -04:00
14 changed files with 1442 additions and 23 deletions

View File

@ -0,0 +1,56 @@
include ../../Makefile.inc
DOS33 = ../../utils/dos33fs-utils/dos33
TOKENIZE = ../../utils/asoft_basic-utils/tokenize_asoft
EMPTYDISK = ../../empty_disk/empty.dsk
LINKERSCRIPTS = ../../linker_scripts/
all: cosmic_fish.dsk
cosmic_fish.dsk: HELLO COSMIC_FISH
cp $(EMPTYDISK) cosmic_fish.dsk
$(DOS33) -y cosmic_fish.dsk SAVE A HELLO
$(DOS33) -y cosmic_fish.dsk BSAVE -a 0x2000 COSMIC_FISH
###
submit: cosmic_fish.zip cosmic_fish_small.zip
cosmic_fish.zip: COSMIC_FISH cosmic_fish.s file_id.diz cosmic_fish.dsk
mkdir -p outline2024_cosmic_fish
cp COSMIC_FISH ./outline2024_cosmic_fish
cp cosmic_fish.s ./outline2024_cosmic_fish
cp file_id.diz ./outline2024_cosmic_fish
cp cosmic_fish.dsk ./outline2024_cosmic_fish
cp cosmic_fish_720p.mp4 ./outline2024_cosmic_fish
cp cosmic_fish_screen.png ./outline2024_cosmic_fish
zip -r cosmic_fish.zip outline2024_cosmic_fish
###
cosmic_fish_small.zip: COSMIC_FISH cosmic_fish.s file_id.diz cosmic_fish.dsk
mkdir -p outline2024_cosmic_fish_small
cp COSMIC_FISH ./outline2024_cosmic_fish_small
cp cosmic_fish.s ./outline2024_cosmic_fish_small
cp file_id.diz ./outline2024_cosmic_fish_small
cp cosmic_fish.dsk ./outline2024_cosmic_fish_small
zip -r cosmic_fish_small.zip outline2024_cosmic_fish_small
###
HELLO: hello.bas
$(TOKENIZE) < hello.bas > HELLO
###
COSMIC_FISH: cosmic_fish.o
ld65 -o COSMIC_FISH cosmic_fish.o -C $(LINKERSCRIPTS)/apple2_2000.inc
cosmic_fish.o: cosmic_fish.s
ca65 -o cosmic_fish.o cosmic_fish.s -l cosmic_fish.lst
####
clean:
rm -f *~ *.o *.lst HELLO COSMIC_FISH *.zip

View File

@ -0,0 +1,441 @@
; cosmic fish
; a variation on bubble universe tiny -- Apple II Lores
; what if you zoom into a bubble universe and it's full of
; space fish?
; by Vince `deater` Weaver
; this version based on fast c64 code by serato_fig
; as posted to the sizecoding discord
; based on his TIC-80 variant
; originally was working off the BASIC code posted on the pouet forum
; original effect by yuruyrau on twitter
; 578 bytes = original color
; 531 bytes = remove keyboard code
; 527 bytes = inline sine gen
; 523 bytes = optimize init a bit
; 301 bytes = generate color lookup table
; 297 bytes = optimize color lookup table
; 282 bytes = optimize color shift
; 266 bytes = reduce resolution of sine table x2
; 260 bytes = shave off some bytes with unneeded compares
; 255 bytes = reoptimize the sine doubler
; 264 bytes = add sound (urgh)
; 265 bytes = fix colors
; 263 bytes = waste a lot of time optimizing color lookup table
; 259 bytes = undo self modifying code
; 247 bytes = remove extra cosine table
; 245 bytes = minor fixes
; 268 bytes = back to 64 byte lookup
; 264 bytes = optimize sine/cosine init
; 262 bytes = optimize var init
; 259 bytes = use sine_base in place
; 262 bytes = add in movement, reduce sound
; 255 bytes = rediculous code that moved table setup to be overwritten
; and the linear parts and $59 of sine table generated
; 260 bytes = modify panning to be more interesting
; 258 bytes = make assumptions on value of Y
; 256 bytes = extend linear adjust of sine table
; soft-switches
SPEAKER = $C030
FULLGR = $C052
; ROM routines
PLOT = $F800 ; PLOT AT Y,A
SETGR = $FB40 ; enable lores 40x48 mode, split text screen
; and clear top of screen
; zero page
COLOR = $30 ; used by PLOT
;SINES_BASE = $C0
I = $D0
J = $D1
T = $D7
U = $D8
V = $D9
IS = $DA
IT = $DB
PAN = $DC
INL = $FC
INH = $FD
sines = sines_base-$1A ; overlaps some code
sines2 = sines+$100 ; duplicate so we can index cosine into it
cosines = sines+$c0
color_map = $1000
bubble_gr:
;=======================
; init graphics
;=======================
jsr SETGR
; can't rely on registers after this as different on IIe
; with 80 col card
bit FULLGR
;========================
;========================
; initialize lookup tables
;========================
;========================
; these moved to the end (at expense of 4 bytes)
; so we can over-write part of sine table on top of it
jsr init_code_to_be_destroyed
; X=0 here
;=========================
; reconstruct sine base
;=========================
; generate the linear $30..$42 part
; and also string of $59 on end
; removes 26 bytes from table
; at expense of 16+4 bytes of code
; (4 from jsr/rts of moving over-writable table code)
;sines:
; .byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F
; .byte $40,$41,$42
;
;old_sines_base:
; .byte $42,$43,$44,$45,$46,$47,$48,
;sines_base:
; .byte $48,$49,$4A,$4B,$4C,$4C
; .byte $4D,$4E,$4E,$4F,$50,$50,$51,$52,$52,$53,$53,$54,$54,$55,$55,$55
; .byte $56,$56,$57,$57,$57,$58,$58,$58,$58,$58
;fifty_nines:
; .byte $59,$59,$59,$59,$59,$59
; .byte $59
ldy #$19 ; offset
ldx #$48 ; want to write $48 downto $30
; with $42 doubled
looper:
txa
sta sines,Y ; sines+12 .... sines
lda #$59 ; also write $59 off the top
sta fifty_nines,Y
cpy #$13 ; we could save more bytes if we didn't
beq skipper ; bother trying to be exact
dex
skipper:
dey
bpl looper
;==========================
; make sine/cosine tables
;==========================
; floor(s*sin((x-96)*PI*2/256.0)+48.5);
;===================================
;
;
; final_sine[i]=quarter_sine[i]; // 0..64
; final_sine[128-i]=quarter_sine[i]; // 64..128
; final_sine[128+i]=0x60-quarter_sine[i]; // 128..192
; final_sine[256-i]=0x60-quarter_sine[i]; // 192..256
setup_sine_table:
ldx #64
ldy #64
setup_sine_loop:
lda sines,X
; sta sines,X
sta sines,Y
lda #$60
sec
sbc sines,X
sta sines+128,X
sta sines+128,Y
iny
dex
bpl setup_sine_loop
; X is $ff here
; Y is $81?
;=======================
; init variables
;=======================
; wipe all of zero page but $FF
; we only care about one value, the color at $30
; in theory we only need to clear/copy $00..$C0
; but not sure how to use to our advantage
; X is $FF
inx ; X=0
ldy #0 ; Y=0
init_loop:
; sta a:$D0,X ; force 16-bit so doesn't wrap
; because I guess it's bad to wipe zero page?
; maybe it isn't?
sty $D0,X ; clear zero page
lda sines,X ; duplicate sine table for cosine use
sta sines2,X
dex
bne init_loop
; lda #0
; stx U
; stx V
; stx T
; stx INL
; X = 0 here
; Y = 0 here
dex
stx COLOR ; $FF (color white)
;=========================
;=========================
; main loop
;=========================
;=========================
; in theory Y=0 from previous loop, and also from init?
next_frame:
; reset I*T
lda T
sta IT
; reset I*S
; Y should always be 0 at this point...
; lda #0
sty IS
i_smc:
lda #13 ; 13
sta I
i_loop:
j_smc:
lda #$18 ; 24
sta J
j_loop:
; bit SPEAKER ; click speaker
; where S=41 (approximately 1/6.28)
; calc: a=i*s+v;
; calc: b=i+t+u;
; u=sines[a]+sines[b];
; v=cosines[a]+cosines[b];
clc ; 2
lda IS
adc V
tay
clc
lda IT
adc U
tax
clc
lda cosines,Y ; 4+
adc cosines,X ; 4+
sta V
; max value for both is $60 so never sets carry
lda sines,Y ; 4+
adc sines,X ; 4+
sta U ; 3
; bit SPEAKER ; click speaker
;===========================================================
; original code is centered at 96,96 (on hypothetical 192x192 screen)
; we adjust to be 40x48 window centered at 48,48
; PLOT U-48,V-48
; U already in A
; sec
u_smc:
sbc #48
tay ; 2
cpy #40
bcs no_plot
; calculate Ypos
lda V
; sec
vsmc:
sbc #48
cmp #48
bcs no_plot
bit SPEAKER ; click speaker
jsr PLOT ; PLOT AT Y,A
no_plot:
dec J
bne j_loop
done_j:
clc
lda IS
adc #41 ; 1/6.28 = 0.16 = 0 0 1 0 1 0 0 0 = 0x28
sta IS
dec I
bne i_loop
done_i:
inc T
; no panning first 256 times
bne no_t_oflo
inc PAN
no_t_oflo:
clc
lda u_smc+1
adc PAN
sta u_smc+1
;=================
; cycle colors
;=================
cycle_colors:
ldy #$0 ; 2
lda #4 ; 2
sta INH ; 2
cycle_color_loop:
lda (INL),Y ; 2
tax ; 1
lda color_map,X ; 3
sta (INL),Y ; 2
iny ; 1
bne cycle_color_loop ; 2
; need to do this for pages 4-7
inc INH ; 2
lda INH ; 2
cmp #$8 ; 2
bne cycle_color_loop ; 2
beq next_frame ; bra ; 2
init_code_to_be_destroyed:
;========================
; color lookup
;========================
; 34 original
; 30 updated
; 31 fixed
; 29 improved
setup_color_lookup:
;================
; current best
ldx #0 ; init output pointer ; 2
first_loop:
ldy #$ff ; reset current value ; 2
loop1:
yloop:
iny ; current output value ; 1
yloop2:
tya ; 1
sta color_map,X ; values[y]=a; ; 3
iny ; 1
inx ; 1
beq done ; 2
cpx #16 ; 2
beq first_loop ; 2
txa ; 1
and #$f ; 2
beq yloop ; if nextcol==0, skip f->0 ; 2
lsr ; 1
bne yloop2 ; if nextcol!=1, y=y+1 ; 2
dey ; if nextcol==1, repeat y ; 1
jmp yloop2 ; 3
done:
rts
; .byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F
; .byte $40,$41,$42
;old_sines_base:
; .byte $42,$43,$44,$45,$46,$47,$48,
sines_base:
.byte $48,$49,$4A,$4B,$4C,$4C
.byte $4D,$4E,$4E,$4F,$50,$50,$51,$52,$52,$53,$53,$54,$54,$55,$55,$55
.byte $56,$56,$57,$57,$57,$58,$58,$58,$58,$58
fifty_nines:
; .byte $59,$59,$59,$59,$59,$59
; .byte $59
; floor(s*cos((x-96)*PI*2/256.0)+48.5);

View File

@ -0,0 +1,23 @@
Cosmic Fish
-
256-byte Intro for Apple II, Outline 2024
by Deater / dSr
If you zoom in on the bubble universe
you may find cosmic fish.
Apple II 'lo-res' 40x48 15 color mode
Core routine based on serato_fig's
C64 version
A lot of the fun was generating
256-entry sine and cosine tables
Also a 256 entry color-fade table
(complicated as two pixels are in the
top/bottom of a byte and they fade
independently)
There is sound but admittedly it
isn't the best.

View File

@ -0,0 +1,8 @@
5 HOME
10 PRINT " COSMIC_FISH -- 256 BYTES FOR OUTLINE 2024"
15 PRINT " BY DEATER / DSR"
20 PRINT CHR$(4)"CATALOG"
25 PRINT:PRINT "PRESS ANY KEY TO 'BRUN COSMIC_FISH'"
30 GET A$
35 PRINT
40 PRINT CHR$(4)"BRUN COSMIC_FISH"

View File

@ -10,7 +10,8 @@ PNG2GR = ../../../utils/gr-utils/png2gr
PNG2SPRITES = ../../../utils/gr-utils/png2sprites
HGR_SPRITE = ../../../utils/hgr-utils/hgr_make_sprite
all: keen1_title.hgr.zx02 level1_bg.gr.zx02 parts.gr.zx02
all: keen1_title.hgr.zx02 level1_bg.gr.zx02 parts.gr.zx02 \
keen1_story.hgr.zx02
####
@ -27,6 +28,15 @@ keen1_title.hgr: keen1_title.png
####
keen1_story.hgr.zx02: keen1_story.hgr
$(ZX02) keen1_story.hgr keen1_story.hgr.zx02
keen1_story.hgr: keen1_story.png
$(PNG_TO_HGR) keen1_story.png > keen1_story.hgr
####
level1_bg.gr.zx02: level1_bg.gr
$(ZX02) level1_bg.gr level1_bg.gr.zx02

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

21
games/keen/story/Makefile Normal file
View File

@ -0,0 +1,21 @@
CFLAGS = -Wall -O2 -g
LFLAGS =
ZX02 = ~/research/6502_compression/zx02.git/build/zx02 -f
all: story_data.zx02
story_data.zx02: story_data.out
$(ZX02) story_data.out story_data.zx02
story_data.out: story.txt make_story
./make_story < story.txt > story_data.out
make_story: make_story.o
$(CC) $(LFLAGS) -o make_story make_story.c
make_story.o: make_story.c
$(CC) $(CFLAGS) -c make_story.c
clean:
rm -f *~ *.o make_story story_data.out story_data.zx02

View File

@ -0,0 +1,18 @@
#include <stdio.h>
int main(int argc, char **argv) {
char string[BUFSIZ];
char *result;
int inverse=0;
while(1) {
result=fgets(string,BUFSIZ,stdin);
if (result==NULL) break;
printf("%s",string);
}
return 0;
}

151
games/keen/story/story.txt Normal file
View File

@ -0,0 +1,151 @@
#inverse
COMMANDER KEEN
IN
"INVASION OF THE VORTICONS"
#normal
BILLY BLAZE, EIGHT YEAR-OLD GENIUS,
WORKING DILIGENTLY IN HIS BACKYARD
CLUBHOUSE HAS CREATED AN INTERSTELLAR
STARSHIP FROM OLD SOUP CANS, RUBBER
CEMENT AND PLASTIC TUBING. WHILE HIS
FOLKS ARE OUT ON THE TOWN AND THE
BABYSITTER HAS FALLEN ASLEEP, BILLY
TRAVELS INTO HIS BACKYARD WORKSHOP,
DONS HIS BROTHER'S FOOTBALL HELMET,
AND TRANSFORMS INTO...
COMMANDER KEEN--DEFENDER OF EARTH!
IN HIS SHIP, THE BEAN-WITH-BACON
MEGAROCKET, KEEN DISPENSES GALACTIC
JUSTICE WITH AN IRON HAND!
#inverse
EPISONE ONE: MAROONED ON MARS
#normal
IN THIS EPISODE, ALIENS FROM THE
PLANET VORTICON VI FIND OUT ABOUT THE
EIGHT YEAR-OLD GENIUS AND PLAN HIS
DESTRUCTION. WHILE KEEN IS OUT
EXPLORING THE MOUNTAINS OF MARS, THE
VORTICONS STEAL VITAL PARTS OF HIS
SHIP AND TAKE THEM TO DISTANT MARTIAN
CITIES! CAN KEEN RECOVER ALL THE
PIECES OF HIS SHIP AND REPEL THE
VORTICON INVASION? WILL HE MAKE IT
BACK BEFORE HIS PARENTS GET HOME?
STAY TUNED!
#inverse
WHAT THE VORTICONS HAVE STOLEN
#normal
THE BEAN-WITH-BACOM MEGAROCKET WAS
CONSTRUCTED FROM OBJECTS AROUND THE
HOUSE THAT YOU HAVE "MODIFIED" INTO
STARSHIP PARTS:
* JOYSTICK (FROM YOUR BROTHER'S VIDEO
GAME) MANUAL FLIGHT CONTROL.
* CAR BATTERY (FROM YOUR MOM'S CAR)
ELECTRICAL SYSTEMS POWER
* VACUUM CLEANER (FROM THE KITCHEN,
HEAVILY MODIFIED) ION PROPULSION UNIT
(WITH CARPET HEIGHT ADJUSTMENT).
* EVERCLEAR (FROM YOUR DAD'S LIQUOR
CABINET) FUEL.
THE VORTICONS HAVE TAKEN THESE PIECES
TO THE FAR REACHES OF MARS AND ARE
GUARDING THEM. YOU MUST FIND THE
MEMBERS OF THIS VORTICON OUTPOST AND
WREST THE PARTS BACK FROM THEIR
WICKED, CLAWED HANDS!
#inverse
INFORMATION ON MARS
#normal
UNBEKNOWNST TO NASA, WHEN THE VIKING
LANDER SETTLED TO THE SURFACE OF MARS,
IT CAUSED A MAJOR POLITICAL UPHEVAL.
VIKING ACTUALLY LANDED ON THE DESPOTIC
MARTIAN KING! THE YORPS (THE
EXTREMELY FRIENDLY ONE-EYED MARTIANS)
WERE FREE FROM ENSLAVEMENT, AND THE
GARGS (THE VICIOUS, AGGRESSIVE
MARTIANS) WERE ANGRY.
THE MARTIANS CREATED ROBOTS FOR MENIAL
WORK AND GUARD DUTIES. BEWARE OF THE
TANK-LIKE GUARD ROBOTS--THEY ARE VERY
GOOD AT WHAT THEY DO.
MARTIANS HAVE BEEN VISITING EARTH IN
UFOS FOR DECADES. WHY? THEY COME TO
EARTH FOR ONE REASON--THEY WANT OUR
TOYS. HULA HOOPS AND SKATEBOARDS ARE
HOLY OBJECTS TO THEM! WHO KNOWS...YOU
MAY FIND SOME TOYS USEFUL!
THERE ARE SIGNS EVERYWHERE. YOU
HAVEN'T BEEN ABLE TO DECIPHER THEM
YET....
#inverse
THE ADVENTURE BEGINS...
#normal
YOUR TASK IS BEFORE YOU. GO GET 'EM,
COMMANDER KEEN!
#inverse
#normal
AND DON'T MISS EPISODES TWO AND THREE
IN THE "INVASION OF THE VORTICONS"
TRILOGY!
#inverse
EPISODE TWO: THE EARTH EXPLODES
#normal
KEEN HAS ASSEMBLED HIS SHIP AND
RETURNED HOME, ONLY TO FIND THE
VORTICON MOTHERSHIP HOVERING OVER THE
EARTH, READY TO DESTROY ALL OF EARTH'S
CITIES AND WONDERS! KEEN MUST SNEAK
ABOART, STOP THE IMMINENT DESTRUCTION
OF EARTH, AND FIND A WAY TO NEUTRALIZE
THE MOTHERSHIP! IF HE FAILS...THE
EARTH EXPLODES! (NO PRESSURE.)
#inverse
EPISODE THREE: KEEN MUST DIE!
#normal
KEEN FLIST TO THE PLANET VORTICON VI
TO ONCE AND FOR ALL RID THE GALAXY OF
THE VORTICON MENACE . THE ENTIRE
PLANET IS WAITING FOR HIS ARRIVAL,
WITH ONLY ONE ORDER GIVEN--COMMANDER
KEEN MUST DIE! WHAT EVIL BEING IS
BEHIND ALL THIS? STAY TUNED FOR THE
CLIMACTIC, SHOCKING FINALE!
(..) COMMANDER KEEN SAYS:
/\ "YOU WON'T BELIEVE WHAT HAPPENS
IN EPISODE THREE!"
#ESC TO EXIT / ARROWS TO READ

View File

@ -1,9 +1,9 @@
; bubble universe tiny -- Apple II Lores
; cosmic fish
; cosmic fish?
; a variation on bubble universe tiny -- Apple II Lores
; what if you zoom into a bubble universe and it's full of
; angry bees
; space fish?
; by Vince `deater` Weaver
@ -39,22 +39,24 @@
; and the linear parts and $59 of sine table generated
; 260 bytes = modify panning to be more interesting
; 258 bytes = make assumptions on value of Y
; 256 bytes = extend linear adjust of sine table
; soft-switches
SPEAKER = $C030
FULLGR = $C052
SPEAKER = $C030
FULLGR = $C052
; ROM routines
PLOT = $F800 ;; PLOT AT Y,A
SETGR = $FB40
PLOT = $F800 ; PLOT AT Y,A
SETGR = $FB40 ; enable lores 40x48 mode, split text screen
; and clear top of screen
; zero page
COLOR = $30
COLOR = $30 ; used by PLOT
SINES_BASE = $C0
;SINES_BASE = $C0
I = $D0
J = $D1
@ -68,7 +70,7 @@ PAN = $DC
INL = $FC
INH = $FD
sines = sines_base-$13 ; overlaps some code
sines = sines_base-$1A ; overlaps some code
sines2 = sines+$100 ; duplicate so we can index cosine into it
cosines = sines+$c0
@ -115,26 +117,33 @@ bubble_gr:
; .byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F
; .byte $40,$41,$42
;
;old_sines_base:
; .byte $42,$43,$44,$45,$46,$47,$48,
;sines_base:
; .byte $42,$43,$44,$45,$46,$47,$48,$48,$49,$4A,$4B,$4C,$4C
; .byte $48,$49,$4A,$4B,$4C,$4C
; .byte $4D,$4E,$4E,$4F,$50,$50,$51,$52,$52,$53,$53,$54,$54,$55,$55,$55
; .byte $56,$56,$57,$57,$57,$58,$58,$58,$58,$58
;fifty_nines:
; .byte $59,$59,$59,$59,$59,$59
; .byte $59
]
ldx #$42 ; want to write $42 downto $30
ldy #$19 ; offset
ldx #$48 ; want to write $48 downto $30
; with $42 doubled
looper:
txa
sta sines-$30,X ; sines+12 .... sines
sta sines,Y ; sines+12 .... sines
lda #$59
sta fifty_nines-$30,X
lda #$59 ; also write $59 off the top
sta fifty_nines,Y
cpy #$13 ; we could save more bytes if we didn't
beq skipper ; bother trying to be exact
dex
cpx #$2F
bne looper
skipper:
dey
bpl looper
;==========================
@ -323,11 +332,12 @@ done_i:
; no panning first 256 times
bne ook
bne no_t_oflo
inc PAN
ook:
no_t_oflo:
clc
lda u_smc+1
adc PAN
@ -356,7 +366,7 @@ cycle_color_loop:
; need to do this for pages 4-7
inc INH ; 2
lda INH ; 2g
lda INH ; 2
cmp #$8 ; 2
bne cycle_color_loop ; 2
@ -416,8 +426,10 @@ done:
; .byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F
; .byte $40,$41,$42
;old_sines_base:
; .byte $42,$43,$44,$45,$46,$47,$48,
sines_base:
.byte $42,$43,$44,$45,$46,$47,$48,$48,$49,$4A,$4B,$4C,$4C
.byte $48,$49,$4A,$4B,$4C,$4C
.byte $4D,$4E,$4E,$4F,$50,$50,$51,$52,$52,$53,$53,$54,$54,$55,$55,$55
.byte $56,$56,$57,$57,$57,$58,$58,$58,$58,$58
fifty_nines:
@ -426,3 +438,4 @@ fifty_nines:
; floor(s*cos((x-96)*PI*2/256.0)+48.5);

View File

@ -0,0 +1,32 @@
include ../../../Makefile.inc
DOS33 = ../../../utils/dos33fs-utils/dos33
TOKENIZE = ../../../utils/asoft_basic-utils/tokenize_asoft
LINKER_SCRIPTS = ../../../linker_scripts
EMPTY_DISK = ../../../empty_disk
all: bubble.dsk make_table make_table2 make_table3 compact_sine
bubble.dsk: HELLO BUBBLE_TINY
cp $(EMPTY_DISK)/empty.dsk bubble.dsk
$(DOS33) -y bubble.dsk SAVE A HELLO
$(DOS33) -y bubble.dsk BSAVE -a 0x0C00 BUBBLE_TINY
###
HELLO: hello.bas
$(TOKENIZE) < hello.bas > HELLO
###
BUBBLE_TINY: bubble_tiny.o
ld65 -o BUBBLE_TINY bubble_tiny.o -C $(LINKER_SCRIPTS)/apple2_c00.inc
bubble_tiny.o: bubble_tiny.s
ca65 -o bubble_tiny.o bubble_tiny.s -l bubble_tiny.lst
###
clean:
rm -f *~ *.o *.lst HELLO BUBBLE_TINY

View File

@ -0,0 +1,507 @@
; bubble universe -- Apple II Hires
; even more size optimized version
; by Vince `deater` Weaver
; this version based on fast c64 code by serato_fig
; as posted to the sizecoding discord
; based on his TIC-80 variant
; originally was working off the BASIC code posted on the pouet forum
; original effect by yuruyrau on twitter
; 534 bytes -- original tiny version
; soft-switches
KEYPRESS = $C000
KEYRESET = $C010
PAGE1 = $C054
PAGE2 = $C055
; ROM routines
BKGND0 = $F3F4 ; clear current page to A
HGR2 = $F3D8 ; set hires page2 and clear $4000-$5fff
HGR = $F3E2 ; set hires page1 and clear $2000-$3fff
HPLOT0 = $F457 ; plot at (Y,X), (A)
;HCOLOR1 = $F6F0 ; set HGR_COLOR to value in X
;COLORTBL = $F6F6
;WAIT = $FCA8 ; delay 1/2(26+27A+5A^2) us
; zero page
GBASL = $26
GBASH = $27
HPLOTYL = $92
I = $D0
J = $D1
T = $D7
U = $D8
V = $D9
HGR_PAGE = $E6
INL = $FC
INH = $FD
OUTL = $FE
OUTH = $FF
; const
;NUM = 32
;NUM = 24
bubble:
;========================
; setup lookup tables
jsr hgr_make_tables
jsr hgr_clear_codegen
jsr setup_sine_table
;=======================
; init graphics
jsr HGR
jsr HGR2
;=======================
; init variables
; HGR leaves A at 0
; lda #0
sta U
sta V
sta T
;=========================
;=========================
; main loop
;=========================
;=========================
next_frame:
; reset I*T
lda T
sta it1_smc+1
sta it2_smc+1
; reset I*S
lda #0
sta is1_smc+1
sta is2_smc+1
num1_smc:
lda #24 ; 40
sta I
i_loop:
num2_smc:
lda #24 ; 200
sta J
j_loop:
ldx U
ldy V
; where S=41 (approximately 1/6.28)
clc ; 2
; calc: b=i+t+u;
; u=cosines[a]+cosines[b];
is2_smc:
lda cosines,Y ; 4+
it2_smc:
adc cosines,X ; 4+
sta V
; calc: a=i*s+v;
; u=sines[a]+sines[b];
is1_smc:
lda sines,Y ; 4+
it1_smc:
adc sines,X ; 4+
sta U ; 3
;===========================================================
; HPLOT U+44,V+96
; U is centered at 96, to get to center of 280 screen add 44
; U already in A
adc #44 ; 2
tax ; 2
; calculate Ypos
ldy V
; "fast" hplot, Xpos in X, Ypos in A
; Apple II hi-res is more-or-less 280x192
; two consecutive pixels on are white
; single pixels are colored based on palette
; we treat things as a monochrome display, on a color
; display odd/even pixels will have different colors
; The Y memory offset is a horrible interleaved mess, so we use
; a lookup table we generated at start. We also add in
; the proper value for page-flipping
; Apple II hi-res is 7 pixels/byte, so we also pre-generate
; div and mod by 7 tables at start and use those
; instead of dividing by 7
; We cheat and don't worry about the X positions larger
; than 256 because our algorithm only goes up to 208
lda hposn_low,Y ; 4
sta GBASL ; 3
lda hposn_high,Y ; 4
ora HGR_PAGE ; 3
sta GBASH ; 3
; 21
ldy div7_table,X ; 4
lda mod7_table,X ; 4
tax ; 2
; 31
; get current 7-bit pixel range, OR in to set new pixel
lda (GBASL),Y ; 5
ora log_lookup,X ; 4
; eor log_lookup,X ; 4
sta (GBASL),Y ; 6
; 46
dec J
bne j_loop
done_j:
lda is1_smc+1
clc
adc #41 ; 1/6.28 = 0.16 = 0 0 1 0 1 0 0 0 = 0x28
sta is1_smc+1
sta is2_smc+1
dec I
bne i_loop
done_i:
; sty V
inc T
end:
lda KEYPRESS
bpl flip_pages
bit KEYRESET
; 0110 -> 0100
and #$5f ; to handle lowercase too...
cmp #'A'
bne check_z
inc num1_smc+1
jmp done_keys
check_z:
cmp #'Z'
bne check_j
dec num1_smc+1
jmp done_keys
check_j:
cmp #'J'
bne check_m
inc num2_smc+1
jmp done_keys
check_m:
cmp #'M'
bne done_keys
dec num2_smc+1
done_keys:
flip_pages:
; flip pages
; if $20 (draw PAGE1) draw PAGE2, SHOW page1
; if $40 (draw PAGE2) draw PAGE1, SHOW page2
lda HGR_PAGE
eor #$60
sta HGR_PAGE
cmp #$40
bne flip2
flip1:
bit PAGE1
lda #0
jsr hgr_page2_clearscreen
jmp next_frame
flip2:
bit PAGE2
lda #0
jsr hgr_page1_clearscreen
jmp next_frame
div7_table = $6800
mod7_table = $6900
hposn_high = $6a00
hposn_low = $6b00
hgr_make_tables:
;=====================
; make /7 %7 tables
;=====================
hgr_make_7_tables:
lda #0
tax
tay
div7_loop:
sta div7_table,Y
mod7_smc:
stx mod7_table
inx
cpx #7
bne div7_not7
clc
adc #1
ldx #0
div7_not7:
inc mod7_smc+1 ; assume on page boundary
iny
bne div7_loop
; Hposn table
; hposn_low, hposn_high will each be filled with $C0 bytes
; based on routine by John Brooks
; posted on comp.sys.apple2 on 2018-07-11
; https://groups.google.com/d/msg/comp.sys.apple2/v2HOfHOmeNQ/zD76fJg_BAAJ
; clobbers A,X
; preserves Y
; vmw note: version I was using based on applesoft HPOSN was ~64 bytes
; this one is 37 bytes
build_hposn_tables:
ldx #0
btmi:
txa
and #$F8
bpl btpl1
ora #5
btpl1:
asl
bpl btpl2
ora #5
btpl2:
asl
asl
sta hposn_low, X
txa
and #7
rol
asl hposn_low, X
rol
; ora #$20
sta hposn_high, X
inx
cpx #$C0
bne btmi
rts
; which of 7 pixels to draw
; note high bit is set to pick blue/orange palette
; clear to get purple/green instead
log_lookup:
.byte $81,$82,$84,$88,$90,$A0,$C0,$80
; the current "fast" code expects to be aligned on boundary
; also have to double things up as the code can go up to 255 off
; end for speed reasons
; floor(s*sin((x-96)*PI*2/256.0)+48.5);
.include "hgr_clear_codegen.s"
; note: min=7, around 32
; max=89 ($59), around 160
; subtract 7, so 0...82? halfway = 41 = $29 + 7 = $30
; halfway= 6*16 = 96
sines = $6c00
sines2 = $6d00
cosines = $6e00
cosines2= $6f00
;===================================
;
;
; final_sine[i]=quarter_sine[i]; // 0..64
; final_sine[128-i]=quarter_sine[i]; // 64..128
; final_sine[128+i]=0x60-quarter_sine[i]; // 128..192
; final_sine[256-i]=0x60-quarter_sine[i]; // 192..256
setup_sine_table:
ldy #64
ldx #64
setup_sine_loop:
lda sines_base,Y
sta sines,Y
sta sines2,Y
sta sines,X
sta sines2,X
lda #$60
sec
sbc sines_base,Y
sta sines+128,Y
sta sines2+128,Y
sta sines+128,X
sta sines2+128,X
inx
dey
bpl setup_sine_loop
ldy #0
cosine_loop:
lda sines+192,Y
sta cosines,Y
sta cosines2,Y
iny
bne cosine_loop
rts
sines_base:
.byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F
.byte $40,$41,$42,$42,$43,$44,$45,$46,$47,$48,$48,$49,$4A,$4B,$4C,$4C
.byte $4D,$4E,$4E,$4F,$50,$50,$51,$52,$52,$53,$53,$54,$54,$55,$55,$55
.byte $56,$56,$57,$57,$57,$58,$58,$58,$58,$58,$59,$59,$59,$59,$59,$59
.byte $59
.if 0
sines:
.byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F
.byte $40,$41,$42,$42,$43,$44,$45,$46,$47,$48,$48,$49,$4A,$4B,$4C,$4C
.byte $4D,$4E,$4E,$4F,$50,$50,$51,$52,$52,$53,$53,$54,$54,$55,$55,$55
.byte $56,$56,$57,$57,$57,$58,$58,$58,$58,$58,$59,$59,$59,$59,$59,$59
.byte $59,$59,$59,$59,$59,$59,$59,$58,$58,$58,$58,$58,$57,$57,$57,$56
.byte $56,$55,$55,$55,$54,$54,$53,$53,$52,$52,$51,$50,$50,$4F,$4E,$4E
.byte $4D,$4C,$4C,$4B,$4A,$49,$48,$48,$47,$46,$45,$44,$43,$42,$42,$41
.byte $40,$3F,$3E,$3D,$3C,$3B,$3A,$39,$38,$37,$36,$35,$34,$33,$32,$31
.byte $30,$2F,$2E,$2D,$2C,$2B,$2A,$29,$28,$27,$26,$25,$24,$23,$22,$21
.byte $20,$1F,$1E,$1E,$1D,$1C,$1B,$1A,$19,$18,$18,$17,$16,$15,$14,$14
; original start
.byte $13,$12,$12,$11,$10,$10,$0F,$0E,$0E,$0D,$0D,$0C,$0C,$0B,$0B,$0B
.byte $0A,$0A,$09,$09,$09,$08,$08,$08,$08,$08,$07,$07,$07,$07,$07,$07
.byte $07,$07,$07,$07,$07,$07,$07,$08,$08,$08,$08,$08,$09,$09,$09,$0A
.byte $0A,$0B,$0B,$0B,$0C,$0C,$0D,$0D,$0E,$0E,$0F,$10,$10,$11,$12,$12
.byte $13,$14,$14,$15,$16,$17,$18,$18,$19,$1A,$1B,$1C,$1D,$1E,$1E,$1F
.byte $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2A,$2B,$2C,$2D,$2E,$2F
sines2:
.byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F
.byte $40,$41,$42,$42,$43,$44,$45,$46,$47,$48,$48,$49,$4A,$4B,$4C,$4C
.byte $4D,$4E,$4E,$4F,$50,$50,$51,$52,$52,$53,$53,$54,$54,$55,$55,$55
.byte $56,$56,$57,$57,$57,$58,$58,$58,$58,$58,$59,$59,$59,$59,$59,$59
.byte $59,$59,$59,$59,$59,$59,$59,$58,$58,$58,$58,$58,$57,$57,$57,$56
.byte $56,$55,$55,$55,$54,$54,$53,$53,$52,$52,$51,$50,$50,$4F,$4E,$4E
.byte $4D,$4C,$4C,$4B,$4A,$49,$48,$48,$47,$46,$45,$44,$43,$42,$42,$41
.byte $40,$3F,$3E,$3D,$3C,$3B,$3A,$39,$38,$37,$36,$35,$34,$33,$32,$31
.byte $30,$2F,$2E,$2D,$2C,$2B,$2A,$29,$28,$27,$26,$25,$24,$23,$22,$21
.byte $20,$1F,$1E,$1E,$1D,$1C,$1B,$1A,$19,$18,$18,$17,$16,$15,$14,$14
.byte $13,$12,$12,$11,$10,$10,$0F,$0E,$0E,$0D,$0D,$0C,$0C,$0B,$0B,$0B
.byte $0A,$0A,$09,$09,$09,$08,$08,$08,$08,$08,$07,$07,$07,$07,$07,$07
.byte $07,$07,$07,$07,$07,$07,$07,$08,$08,$08,$08,$08,$09,$09,$09,$0A
.byte $0A,$0B,$0B,$0B,$0C,$0C,$0D,$0D,$0E,$0E,$0F,$10,$10,$11,$12,$12
.byte $13,$14,$14,$15,$16,$17,$18,$18,$19,$1A,$1B,$1C,$1D,$1E,$1E,$1F
.byte $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2A,$2B,$2C,$2D,$2E,$2F
; floor(s*cos((x-96)*PI*2/256.0)+48.5);
cosines:
; sine[64]
.byte $59,$59,$59,$59,$59,$59,$59,$58,$58,$58,$58,$58,$57,$57,$57,$56
.byte $56,$55,$55,$55,$54,$54,$53,$53,$52,$52,$51,$50,$50,$4F,$4E,$4E
.byte $4D,$4C,$4C,$4B,$4A,$49,$48,$48,$47,$46,$45,$44,$43,$42,$42,$41
.byte $40,$3F,$3E,$3D,$3C,$3B,$3A,$39,$38,$37,$36,$35,$34,$33,$32,$31
; sine[128]
.byte $30,$2F,$2E,$2D,$2C,$2B,$2A,$29,$28,$27,$26,$25,$24,$23,$22,$21
.byte $20,$1F,$1E,$1E,$1D,$1C,$1B,$1A,$19,$18,$18,$17,$16,$15,$14,$14
.byte $13,$12,$12,$11,$10,$10,$0F,$0E,$0E,$0D,$0D,$0C,$0C,$0B,$0B,$0B
.byte $0A,$0A,$09,$09,$09,$08,$08,$08,$08,$08,$07,$07,$07,$07,$07,$07
; sine[192]
.byte $07,$07,$07,$07,$07,$07,$07,$08,$08,$08,$08,$08,$09,$09,$09,$0A
.byte $0A,$0B,$0B,$0B,$0C,$0C,$0D,$0D,$0E,$0E,$0F,$10,$10,$11,$12,$12
.byte $13,$14,$14,$15,$16,$17,$18,$18,$19,$1A,$1B,$1C,$1D,$1E,$1E,$1F
.byte $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2A,$2B,$2C,$2D,$2E,$2F
; sine[0]
.byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F
.byte $40,$41,$42,$42,$43,$44,$45,$46,$47,$48,$48,$49,$4A,$4B,$4C,$4C
.byte $4D,$4E,$4E,$4F,$50,$50,$51,$52,$52,$53,$53,$54,$54,$55,$55,$55
.byte $56,$56,$57,$57,$57,$58,$58,$58,$58,$58,$59,$59,$59,$59,$59,$59
cosines2:
.byte $59,$59,$59,$59,$59,$59,$59,$58,$58,$58,$58,$58,$57,$57,$57,$56
.byte $56,$55,$55,$55,$54,$54,$53,$53,$52,$52,$51,$50,$50,$4F,$4E,$4E
.byte $4D,$4C,$4C,$4B,$4A,$49,$48,$48,$47,$46,$45,$44,$43,$42,$42,$41
.byte $40,$3F,$3E,$3D,$3C,$3B,$3A,$39,$38,$37,$36,$35,$34,$33,$32,$31
.byte $30,$2F,$2E,$2D,$2C,$2B,$2A,$29,$28,$27,$26,$25,$24,$23,$22,$21
.byte $20,$1F,$1E,$1E,$1D,$1C,$1B,$1A,$19,$18,$18,$17,$16,$15,$14,$14
.byte $13,$12,$12,$11,$10,$10,$0F,$0E,$0E,$0D,$0D,$0C,$0C,$0B,$0B,$0B
.byte $0A,$0A,$09,$09,$09,$08,$08,$08,$08,$08,$07,$07,$07,$07,$07,$07
.byte $07,$07,$07,$07,$07,$07,$07,$08,$08,$08,$08,$08,$09,$09,$09,$0A
.byte $0A,$0B,$0B,$0B,$0C,$0C,$0D,$0D,$0E,$0E,$0F,$10,$10,$11,$12,$12
.byte $13,$14,$14,$15,$16,$17,$18,$18,$19,$1A,$1B,$1C,$1D,$1E,$1E,$1F
.byte $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2A,$2B,$2C,$2D,$2E,$2F
.byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F
.byte $40,$41,$42,$42,$43,$44,$45,$46,$47,$48,$48,$49,$4A,$4B,$4C,$4C
.byte $4D,$4E,$4E,$4F,$50,$50,$51,$52,$52,$53,$53,$54,$54,$55,$55,$55
.byte $56,$56,$57,$57,$57,$58,$58,$58,$58,$58,$59,$59,$59,$59,$59,$59
.endif

View File

@ -0,0 +1,13 @@
5 HOME
10 PRINT " BUBBLE UNIVERSE EXPERIMENTS"
15 PRINT " BY DEATER / FAST CODE BY SERATO_FIG"
20 PRINT
25 PRINT "THIS VERSION YOU CAN CHANGE"
27 PRINT "PARAMETERS ON THE FLY"
28 PRINT "+ TRY PRESSING A/Z TO INC/DEC I"
29 PRINT "+ TRY PRESSING J/M TO INC/DEC J"
30 PRINT:PRINT "PRESS ANY KEY TO START"
40 GET A$
50 IF A$="Q" THEN END
60 PRINT:PRINT CHR$(4)"BRUN BUBBLE_TINY"

View File

@ -0,0 +1,126 @@
hgr_page1_clearscreen = $7000
hgr_page2_clearscreen = $7300
hgr_clear_codegen:
;========================
; set up output pointers
lda #<(hgr_page1_clearscreen) ; assume both start page boundary
sta OUTL
sta INL
lda #>(hgr_page1_clearscreen)
sta OUTH
lda #>(hgr_page2_clearscreen)
sta INH
;=====================
; set up prolog
lda #$A0 ; ldy
jsr write_both
lda #8 ; only part of screen
jsr write_both
ldx #0
hgr_clear_codegen_loop:
lda #$99 ; STA
jsr write_both
lda hposn_low,X ; low is same both
jsr write_both
lda hposn_high,X
ora #$20
pha
jsr write_p1
pla
eor #$60
jsr write_p2
inx
cpx #192
bne hgr_clear_codegen_loop
;======================================
; write epilog
; TODO: replace with memcpy of some sort?
lda #$C8 ; INY
jsr write_both
lda #$C0 ; CPY
jsr write_both
lda #32 ; end value
jsr write_both
lda #$F0 ; beq
jsr write_both
lda #$03 ; +3
jsr write_both
lda #$4C ; JMP
jsr write_both
lda #<(hgr_page1_clearscreen+2)
jsr write_both
lda #>(hgr_page1_clearscreen+2)
jsr write_p1
lda #>(hgr_page2_clearscreen+2)
jsr write_p2
lda #$60 ; RTS
; jsr write_both
; rts ; tail call
; fallthrough
;=============================
;
write_both:
pha
jsr write_p2
pla
; fallthrough
write_p1:
ldy #0
sta (OUTL),Y
clc
lda OUTL
adc #1
sta OUTL
lda #0
adc OUTH
sta OUTH
rts
write_p2:
ldy #0
sta (INL),Y
clc
lda INL
adc #1
sta INL
lda #0
adc INH
sta INH
rts