; water drops

; based roughly on
; https://github.com/seban-slt/Atari8BitBot/blob/master/ASM/water/water.m65

; for each pixel

;         C
;       A V B
;         D
;
; calculate color as NEW_V = (A+B+C+D)/2 - OLD_V
; then flip buffers


; 211 bytes -- initial
; 208 bytes -- use HGR2 to clear
; 204 bytes -- optimize buffer switch
; 197 bytes -- inline random8
; 169 bytes -- rip out page flipping
; 163 bytes -- use EOR for BUFH setting
; 159 bytes -- put YY in X
; 153 bytes -- fake random by reading ROM
; 151 bytes -- no seed at all, use frame
; 149 bytes -- FRAME saved in Y
; 148 bytes -- beq instead of jmp
; 147 bytes -- reuse color in drop
; 145 bytes -- leave out carry setting
; 142 bytes -- reduce to 4 colors (from 8)
; 141 bytes -- don't dex at beginning ($FF close enough)

.include "hardware.inc"

GBASH	=	$27
MASK	=	$2E
COLOR	=	$30
SEEDL	=	$4E

FRAME	=	$F8
XX	=	$F9
DROPL	=	$FA
DROPH	=	$FB
BUF1L	=	$FC
BUF1H	=	$FD
BUF2L	=	$FE
BUF2H	=	$FF


	;================================
	; Clear screen and setup graphics
	;================================
drops:
	jsr	HGR		; clear $2000-$4000 to zero
				; A is $00 after this
				; Y is $00

	bit	FULLGR		; full page
	bit	LORES		; switch to LORES

drops_outer:

	; in all but first loop X is $FF on arrival

;	inx
	stx	BUF1L
	stx	BUF2L

	;=================================
	; handle new frame
	;=================================

	inc	FRAME
	lda	FRAME
	tay			; save frame for later

	; alternate $20/$28 in BUF1H/BUF2H

	and	#$1
	asl
	asl
	asl			; A now 0 or 8

	ora	#$20
	sta	BUF1H
	eor	#$8
	sta	BUF2H

	; check if we add new raindrop

	tya			; reload FRAME
	and	#$3		; only drop every 4 frames
	bne	no_drop

	; fake random number generator by reading ROM

	lda	$E000,Y

	; buffer is 40x48 = roughly 2k?
	; so random top bits = 0..7

	sta	DROPL
	and	#$7
	ora	#$20
	sta	DROPH

	lda	#31	; $1f	value for drop

	tay		; cheat and draw drop at offset 31 to reuse value

	sta	(DROPL),Y	; draw at offset 31
	iny
	sta	(DROPL),Y	; draw at offset 32

	ldy	#71
	sta	(DROPL),Y	; draw at offset 71 (y+1)
	iny
	sta	(DROPL),Y	; draw at offset 72

no_drop:


	ldx	#47	 ; load 47 into YY


	;=================================
	; yloop
	;=================================

drops_yloop:

	txa		; YY
	tay		; plot YY,YY

	jsr	PLOT	; PLOT Y,A, setting up MASK and putting addr in GBASL/H


	; reset XX to 39

	lda	#39		; XX
	sta	XX


	;=================================
	; xloop
	;=================================

drops_xloop:

	clc
	ldy	#1
	lda	(BUF1L),Y
	ldy	#81
	adc	(BUF1L),Y
	ldy	#40
	adc	(BUF1L),Y
	ldy	#42
	adc	(BUF1L),Y
	lsr
	dey

;	sec
	sbc	(BUF2L),Y
	bpl	done_calc
	eor	#$ff
done_calc:
	sta	(BUF2L),Y

	inc	BUF1L
	inc	BUF2L
	bne	no_oflo

	inc	BUF1H
	inc	BUF2H

no_oflo:

	; adjust color

	lsr
	lsr
	and	#$3
	tay
	lda	colors,Y
	sta	COLOR

	ldy	XX
	jsr	PLOT1		; PLOT AT (GBASL),Y

	dec	XX
	bpl	drops_xloop

	dex	; YY
	bpl	drops_yloop

weird_outer:

	bmi	drops_outer	; small enough now!

colors:
.byte $22,$66,$77,$ff

;colors:
;.byte $00,$22,$66,$EE,$77,$ff,$ff,$ff

; 0       2    6    e    7    f    f    f
; 0000 0010 0110 1110 0111 1111 1111 1111
;    0    1    2    3    4    5    6    7




	; for maximum twitter size we enter this program
	; by using the "&" operator which jumps to $3F5

	; we can't load there though as the code would end up overlapping
	; $400 which is the graphics area

	; this is at 38A
	; we want to be at 3F5, so load program at 36B?

	; called by EXECUTE.STATEMENT at $D828
	; which jumps to CHRGET at $00B1
	; which does a RTS to $3F4 at end

	; CHRGET sets up state based on the char that follows the &
	;  Z==C==1 is colon
	;  Z==1 is EOL (nul)
	;  C==0 is digit

	; when we call with " following
	; A=$22 (") X=$FF Y=$5E
	;	N=0 V=0 Z=0 C=1

	jmp	drops		; entry point from &
;	bcs	drops