; Vector Graphics Demo - 06-03-01
; Michael Vincent - michael@detacheds.com
;
;
; This is demonstration code only. The code is a mess; it can be optimized very greatly.
;
;
; Coordinate System:
; 	The center of the screen is (0,0), points are stored in that
;	(x,y) format, with the left side being (-48,y); the right side
;	is (47,y). Top is (x,-32), bottom is (x,31). All inputs are signed bytes.
.nolist
#include "asm.inc"
.list
#define tempx $9872
#define tempy $9873
#define x1 $9874
#define y1 $9875
#define stepx $9876
#define stepy $9877
#define tempx2 $9878
#define tempy2 $9879

#define scalefactor $9872+50
.org $9D93
	.db $BB,$6D
	ld hl,NumberOne
	ld de,scalefactor
	ld bc,9
	ldir
	call ShowMap
	bcall(_homeup)
	ld hl,Welcome_Message
	bcall(_puts)
MainLoop:
	ld a,$ff
	out (1),a
	ld a,Group1
	out (1),a
	in a,(1)
	cp kUp
	jr z,MakeSmaller
	cp kDown
	jr z,MakeLarger
	ld a,$ff
	out (1),a
	ld a,Group7
	out (1),a
	in a,(1)
	cp kMode
	ret z
	jr MainLoop
MakeSmaller:
	ld hl,scalefactor
	rst 20h
	ld hl,ScaleMovement
	bcall(_mov9toop2)
	bcall(_fpsub)
	ld de,scalefactor
	bcall(_movfrop1)
	call ShowMap
	jr MainLoop
MakeLarger:
	ld hl,scalefactor
	rst 20h
	ld hl,ScaleMovement
	bcall(_mov9toop2)
	bcall(_fpadd)
	ld de,scalefactor
	bcall(_movfrop1)
	call ShowMap
	jr MainLoop
ShowMap:
	bcall(_grbufclr)
	ld hl,VectorDemo
	ld de,scalefactor
	ld b,6
	jp DisplayVectorMap
DisplayVectorMap:
	;Inputs - HL points to vector map
	;	  B contains the number of points
	;	  DE points to floating point number (multip. factor)
ScaleLoop:
	ld a,(hl)
	call MoveByteToOP2
	push bc
	push de
	push hl
	ex de,hl
	rst 20h
	bcall(_fpmult)
	bcall(_convop1)
	ld e,a
	ld a,(OP1)
	or a
	jr z,skipneg1
	ld a,e
	neg
	jr skipneg2
skipneg1:
	ld a,e
skipneg2:
	ld b,48
	add a,b
	ld (tempx),a
	pop hl
	pop de
	pop bc
	inc hl

	ld a,(hl)
	call MoveByteToOP2
	push bc
	push de
	push hl
	ex de,hl
	rst 20h
	bcall(_fpmult)
	bcall(_convop1)
	ld e,a
	ld a,(OP1)
	or a
	jr z,skipneg3
	ld a,e
	neg
	jr skipneg4
skipneg3:
	ld a,e
skipneg4:
	ld b,32
	add a,b
	ld (tempy),a
	pop hl
	pop de
	pop bc
	inc hl

	ld a,(hl)
	call MoveByteToOP2
	push bc
	push de
	push hl
	ex de,hl
	rst 20h
	bcall(_fpmult)
	bcall(_convop1)
	ld e,a
	ld a,(OP1)
	or a
	jr z,skipneg5
	ld a,e
	neg
	jr skipneg6
skipneg5:
	ld a,e
skipneg6:
	ld b,48
	add a,b
	ld (tempx2),a
	pop hl
	pop de
	pop bc
	inc hl

	ld a,(hl)
	call MoveByteToOP2
	push bc
	push de
	push hl
	ex de,hl
	rst 20h
	bcall(_fpmult)
	bcall(_convop1)
	ld e,a
	ld a,(OP1)
	or a
	jr z,skipneg7
	ld a,e
	neg
	jr skipneg8
skipneg7:
	ld a,e
skipneg8:
	ld b,32
	add a,b
	ld (tempy2),a

	ld a,(tempx)
	ld b,a
	ld a,(tempy)
	ld c,a
	ld a,(tempx2)
	ld d,a
	ld a,(tempy2)
	ld e,a
	call drawLine

	pop hl
	pop de
	pop bc
	inc hl

	dec b
	ld a,b
	or a
	jp nz,ScaleLoop
	bcall(_grbufcpy)
	ret
MoveByteToOP2:
	push bc
	ld b,9
	ld ix,OP2
OP2ClearLoop:
	ld (ix),0
	inc ix
	djnz OP2ClearLoop
	;OP2 now cleared.
	;A still contains byte from map
	bit 7,a
	jr z,skipinverse
	ld ix,OP2
	ld (ix),$80
	neg
skipinverse:
	;A is now ready to be loaded, first we must convert from normal byte to floating point.
	ld c,-1
subloop:
	inc c
	sub 10
	jr nc,subloop
	sla c
	sla c
	sla c
	sla c	;C now contains the first half of the number (tens)
	add a,10
	or c	;Combine C and A
	ld (OP2+2),a
	ld a,$81
	ld (OP2+1),a
	pop bc
	ret
VectorDemo:
	.db -5,0,5,0
	.db 0,5,0,-5

	.db -10,-10,10,-10
	.db -10,10,10,10
	.db -10,10,-10,-10
	.db 10,10,10,-10
NumberOne:
	.db $00,$80,$10,$00,$00,$00,$00,$00,$00
ScaleMovement:
	.db $00,$7F,$10,$00,$00,$00,$00,$00,$00
; FUNCTION: drawLine - Draws a line on the graph buffer
; b=x0, c=y0, d=x1, e=y1
drawLine:

 ; Draw first pixel
 push de
 ld a, b
 ld e, c
 call drawPoint
 pop de

 ; Save x1 and y1
 ld a, d
 ld (x1), a
 ld a, e
 ld (y1), a

 ; Calculate dy and stepy
 ld h, 1
 ld a, e
 sub c
 jr nc, posDy
 neg
 ld h, -1
posDy:
 ld e, a
 ld a, h
 ld (stepy), a

 ; Calculate dx and stepx
 ld h, 1
 ld a, d
 sub b
 jr nc, posDx
 neg
 ld h, -1
posDx:
 ld d, a
 ld a, h
 ld (stepx), a

 ; Compare dx and dy
 ld a, e
 cp d
 jr nc, dx_lte_dy
 
 ; ** dx > dy

 ; Calulate fraction
 ld h, d
 sra h
 sub h
 ld h, a

 ; Load x1 into l
 ld a, (x1)
 ld l, a

 ; Draw line
lineLoop1:
 ld a, l
 cp b
 ret z

 ; Check if fraction is positive
 bit 7, h
 jp nz, skipLine1

 ; Add stepy to y0
 ld a, (stepy)
 add a, c
 ld c, a

 ; Subtract dx from fraction
 ld a, h
 sub d
 ld h, a
skipLine1:

 ; Add dy to fraction
 ld a, h
 add a, e
 ld h, a

 ; Add stepx to x0
 ld a, (stepx)
 add a, b
 ld b, a

 ; Display pixel
 push de
 push hl
 ld a, b
 ld e, c
 call drawPoint
 pop hl
 pop de
 jp lineLoop1

 ; ** dx <= dy
dx_lte_dy:

 ; Calculate fraction
 ld h, e
 sra h
 ld a, d
 sub h
 ld h, a

 ; Load y1 into l
 ld a, (y1)
 ld l, a

 ; Draw line
lineLoop2:
 ld a, l
 cp c
 ret z

 ; Check if fraction is positive
 bit 7, h
 jp nz, skipLine2

 ; Add stepx to x0
 ld a, (stepx)
 add a, b
 ld b, a

 ; Subtract dy from fraction
 ld a, h
 sub e
 ld h, a
skipLine2:

 ; Add dx to fraction
 ld a, h
 add a, d
 ld h, a

 ; Add stepy to y0
 ld a, (stepy)
 add a, c
 ld c, a

 ; Display pixel
 push de
 push hl
 ld a, b
 ld e, c
 call drawPoint
 pop hl
 pop de
 jp lineLoop2
drawPoint:	;Draws point on graph buffer (a,e)=(x,y)
	push af
	push de
	cp 95
	jr nc,popandret
	ld a,e
	cp 63
	jr nc,popandret
	pop de
	pop af
	ld d,0
	sla e
	sla e
	ld hl,0
	add hl,de
	add hl,de
	add hl,de
	ld d,0
	ld e,a
	srl e
	srl e
	srl e   
	add hl,de
	ld de,plotsscreen
	add hl,de
	ld de,0007h
	and e
	ld e,a
	ld ix,drawPointTable
	add ix,de
	ld a,(ix+0)
	or (hl)
	ld (hl),a
	ret
popandret:
	pop hl
	pop hl
	ret
drawPointTable:
	.db %10000000
	.db %01000000
	.db %00100000
	.db %00010000
	.db %00001000
	.db %00000100
	.db %00000010
	.db %00000001
Welcome_Message:
	.db "Up/down - scale "
	.db "Mode - exit",0
.end

