; ===============================================================
; Alien Invasion
; ===============================================================
;BTW: store 16bit integer hl in 16.8 fixed point var var: ld (var+1),hl \ xor a \ ld (var),a
; ld hl, (var1) \ ld de, (var2) \ add hl, de \ ld a, (var1+2) \ adc a, 0 \ ld (var1), hl \ ld (var1+2), a
; als var1 negatief is, doe adc a, $FF ipv. adc a, 0
; ld hl,(var1) \ ld de, (var2) \ ld a, h \ rla \ sbc a,a \ add hl, de \ ld b, a \ ld a, (var1+2) \ ld (var2), hl \ adc a, b \ ld (var1+2), a
.org $4000
.db 080h, 00Fh
.db 000h, 000h, 000h, 000h
.db 080h, 012h
.db 001h, 004h
.db 080h, 021h
.db 001h
.db 080h, 031h
.db 001h
.db 080h, 048h
.db "INVASION"
.db 080h, 081h
.db 001h
.db 080h, 090h
.db 003h, 026h, 009h, 004h
.db 01Bh, 053h, 00Bh, 079h
.db 002h, 00Dh, 040h, 0A1h, 06Bh, 099h, 0F6h, 059h, 0BCh, 067h
.db 0F5h, 085h, 09Ch, 009h, 06Ch, 00Fh, 0B4h, 003h, 09Bh, 0C9h
.db 003h, 032h, 02Ch, 0E0h, 003h, 020h, 0E3h, 02Ch, 0F4h, 02Dh
.db 073h, 0B4h, 027h, 0C4h, 0A0h, 072h, 054h, 0B9h, 0EAh, 07Ch
.db 03Bh, 0AAh, 016h, 0F6h, 077h, 083h, 07Ah, 0EEh, 01Ah, 0D4h
.db 042h, 04Ch, 06Bh, 08Bh, 013h, 01Fh, 0BBh, 093h, 08Bh, 0FCh
.db 019h, 01Ch, 03Ch, 0ECh, 04Dh, 0E5h, 075h
.db 080h, 07Fh
.db 000h, 000h, 000h, 000h
.db 000h, 000h, 000h, 000h
.db 000h, 000h, 000h, 000h
.db 000h, 000h, 000h, 000h
.db 000h, 000h, 000h, 000h
.nolist
#include "ti83plus.inc"
.list
#define bcall(label) rst 28h \ .dw label
#define bjump(label) call $50 \ .dw label
#define SubFP xor a \ sbc hl, de
#define cpHLDE or a \ sbc hl, de \ add hl, de
#define gbuf plotsscreen
;;;;;;;;;;;;;;;;;;;;;;;;;; VARIABELEN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
temp .equ SavesScreen
temp2 .equ temp+2
temp3 .equ temp2+2
Asqr .equ temp3+2
Bsqr .equ Asqr+2
Csqr .equ Bsqr+2
xfrom .equ Csqr+2
yfrom .equ xfrom+2
zfrom .equ yfrom+2
xto .equ zfrom+2
yto .equ xto+2
zto .equ yto+2
xup .equ zto+2
yup .equ xup+2
zup .equ yup+2
angle .equ zup+2
xcross .equ angle+1
ycross .equ xcross+2
zcross .equ ycross+2
xpoint .equ zcross+2
ypoint .equ xpoint+2
zpoint .equ ypoint+2
valid .equ zpoint+2
screenX .equ valid+1
screenY .equ screenx+2
screenx2 .equ screeny+2
screeny2 .equ screenx2+2
screenx3 .equ screeny2+2
screeny3 .equ screenx3+2
screenx4 .equ screeny3+2
screeny4 .equ screenx4+2
X .equ screeny4+2
Y .equ X+2
Direction .equ Y+2
x1 .equ Direction+1
y1 .equ x1+2
u1 .equ y1+2
v1 .equ u1+1
x2 .equ v1+1
y2 .equ x2+2
u2 .equ y2+2
v2 .equ u2+1
x3 .equ v2+1
y3 .equ x3+2
u3 .equ y3+2
v3 .equ u3+1
dx1 .equ V3+1
dx2 .equ dx1+2
dx3 .equ dx2+2
dx4 .equ dx3+2
du1 .equ dx4+2
dv1 .equ du1+2
du2 .equ dv1+2
dv2 .equ du2+2
du3 .equ dv2+2
dv3 .equ du3+2
du4 .equ dv3+2
dv4 .equ du4+2
tx1 .equ dv4+2
tx2 .equ tx1+3
tu1 .equ tx2+3
tv1 .equ tu1+2
tu2 .equ tv1+2
tv2 .equ tu2+2
tx12 .equ tv2+2
tx22 .equ tx12+3
tu12 .equ tx22+3
tv12 .equ tu12+2
tu22 .equ tv12+2
tv22 .equ tu22+2
_ty .equ tv22+2
tmpu .equ _ty+2
tmpv .equ tmpu+2
tmpdu .equ tmpv+2
tmpdv .equ tmpdu+2
mask .equ tmpdv+2
pointer .equ mask+1
TempFlags .equ pointer+2
SaveIY .equ TempFlags+1 ;2 bytes
zto2 .equ saveIY+2 ;2 bytes
;;;;;;;;;;;;;;; START PROGRAMMA ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Start:
di
;bcall(_RunIndicOff)
;call InitFPS
call ClearGbuf
call fastCopy
ld a, 64*3
ld (direction), a
in a,($02)
rla
sbc a, a
out ($20), a
;ld l, a
;ld h, a
ld hl, 0
ld (x), hl
ld hl, $0200
ld (y), hl
ld hl, 0
ld (x1), hl
ld (y1), hl
ld a, 0
ld (u1), a
ld (v1), a
ld (v2), a
ld (u3), a
ld a, 8
ld (u2), a
ld (v3), a
ld hl, 40
ld (x2), hl
ld (y3), hl
ld hl, 20
ld (y2), hl
ld (x3), hl
call DrawTriangle
call FastCopy
bcall(_GetKey)
ld hl, 0
ld (zto2), hl
ld (saveIY), IY
ld IY, tempFlags
SpelLus:
call ClearGBuf
#comment
ld a, $FF
ld (plotsscreen), a
ld hl, plotsscreen
ld de, plotsscreen+1
ld bc, 767
ldir
#endcomment
ld hl, (x)
ld (xfrom), hl
ld hl, (y)
ld (yfrom), hl
ld hl, 0
ld (zfrom), hl
;ld (zto), hl
ld a, 64
ld b, a
ld a, (direction)
add a, b
call SinA
ld de, (x)
add hl, de
ld (xto), hl
ld a, (direction)
call SinA
ld de, (y)
add hl, de
ld (yto), hl
ld hl, $0100
ld (zup), hl
ld hl, 0
ld (xup), hl
ld (yup), hl
ld hl, (zto2)
ld (zto), hl
call InitView
ld hl, -$0100
ld (xpoint), hl
ld hl, 0
ld (ypoint), hl
ld hl, -$0100
ld (zpoint), hl
call C3DTo2D
ld hl, (screenx)
ld (screenx2), hl
ld hl, (screeny)
ld (screeny2), hl
ld hl, $0100
ld (xpoint), hl
ld hl, 0
ld (ypoint), hl
ld hl, -$0100
ld (zpoint), hl
call C3DTo2D
ld hl, (screenx)
ld (screenx3), hl
ld hl, (screeny)
ld (screeny3), hl
ld hl, -$0100
ld (xpoint), hl
ld hl, 0
ld (ypoint), hl
ld hl, $0100
ld (zpoint), hl
call C3DTo2D
ld hl, (screenx)
ld (x1), hl
ld hl, (screeny)
ld (y1), hl
ld a, 8
ld (u1), a
ld a, 0
ld (v1), a
ld hl, (screenx2)
ld (x2), hl
ld hl, (screeny2)
ld (y2), hl
ld a, 8
ld (u2), a
ld a, 8
ld (v2), a
ld hl, (screenx3)
ld (x3), hl
ld hl, (screeny3)
ld (y3), hl
ld a, 0
ld (u3), a
ld a, 8
ld (v3), a
call DrawTriangle
;call FastCopy
;call ClearGBuf
ld hl, -$0100
ld (xpoint), hl
ld hl, 0
ld (ypoint), hl
ld hl, $0100
ld (zpoint), hl
call C3DTo2D
ld hl, (screenx)
ld (screenx2), hl
ld hl, (screeny)
ld (screeny2), hl
ld hl, $0100
ld (xpoint), hl
ld hl, 0
ld (ypoint), hl
ld hl, $0100
ld (zpoint), hl
call C3DTo2D
ld hl, (screenx)
ld (screenx3), hl
ld hl, (screeny)
ld (screeny3), hl
ld hl, $0100
ld (xpoint), hl
ld hl, 0
ld (ypoint), hl
ld hl, -$0100
ld (zpoint), hl
call C3DTo2D
ld hl, (screenx)
ld (x1), hl
ld hl, (screeny)
ld (y1), hl
ld a, 0
ld (u1), a
ld a, 8
ld (v1), a
ld hl, (screenx2)
ld (x2), hl
ld hl, (screeny2)
ld (y2), hl
ld a, 8
ld (u2), a
ld a, 0
ld (v2), a
ld hl, (screenx3)
ld (x3), hl
ld hl, (screeny3)
ld (y3), hl
ld a, 0
ld (u3), a
ld (v3), a
call DrawTriangle
call FastCopy
;knoppen
ld a, $FE
out (1), a
push hl \ pop hl ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
in a, (1)
bit 0, a
call z, MoveBack
bit 3, a
call z, MoveForward
bit 1, a
call z, TurnLeft
bit 2, a
call z, TurnRight
ld a, %11111101
out ($01), a
push hl \ pop hl ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
in a, ($01)
bit 6, a
jp z, Einde
ld a, $EF
out (1), a
push hl
pop hl
in a, (1)
bit 0, a
call z, LookDown
bit 1, a
call z, LookUp
jp spelLus
MoveBack:
push af
ld a, (direction)
ld b, 64
add a, b
call SinA
call NegHL
ld de, $0A00
call DivFP
ld de, (X)
add hl, de
ld (X), hl
ld a, (direction)
call SinA
call NegHL
ld de, $0A00
call DivFP
ld de, (Y)
add hl, de
ld (Y), hl
pop af
ret
MoveForward:
push af
ld a, (direction)
ld b, 64
add a, b
call SinA
ld de, $0A00
call DivFP
ld de, (X)
add hl, de
ld (X), hl
ld a, (direction)
call SinA
ld de, $0A00
call DivFP
ld de, (Y)
add hl, de
ld (Y), hl
pop af
ret
TurnLeft:
push af
ld a, (direction)
inc a
ld (direction), a
pop af
ret
TurnRight:
ld a, (direction)
dec a
ld (direction), a
ret
LookUp:
ld hl, (zto2)
inc hl
inc hl
inc hl
inc hl
ld (zto2), hl
ret
LookDown:
ld hl, (zto2)
dec hl
dec hl
dec hl
dec hl
ld (zto2), hl
ret
Einde:
;Key port resetten
ld a, $FF
out ($01), a
call ClearGbuf
call fastCopy
ld hl, 0
ld (CurRow), hl
ld IY, (saveIY)
EI
bjump(_JForceCmdNoChar)
Cto0:
ld c, 0
pop ix
ret
;;;;;;;;;;;;;;;; 3D ENGINE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;TODO: bereken de zoom
InitView:
;call once every frame, before C3DTo2D
;IN: The engine's vars
;OUT: vars are initialised
;DESTROYS: all registers and the engine's variables
ld hl, (xto)
ld de, (xfrom)
SubFP
ld (xto), hl
ld hl, (yto)
ld de, (yfrom)
SubFP
ld (yto), hl
ld hl, (zto)
ld de, (zfrom)
SubFP
ld (zto), hl
ld de, (xto)
ld b, d \ ld c, e
call MulFP
ld (temp), hl
ld de, (yto)
ld b, d \ ld c, e
call MulFP
ld de, (temp)
add hl, de
ld (temp), hl
ld de, (zto)
ld b, d \ ld c, e
call MulFP
ld de, (temp)
add hl, de
call SqrtFP
ld (temp), hl
ld hl, (xto)
ld de, (temp)
call DivFP
ld (xto), hl
ld hl, (yto)
ld de, (temp)
call DivFP
ld (yto), hl
ld hl, (zto)
ld de, (temp)
call DivFP
ld (zto), hl
ld de, (xup)
ld bc, (xto)
call MulFP
ld (temp), hl
ld de, (yup)
ld bc, (yto)
call MulFP
ld de, (temp)
add hl, de
ld (temp), hl
ld de, (zup)
ld bc, (zto)
call MulFP
ld de, (temp)
add hl, de
ld (temp), hl
ld de, (temp)
ld bc, (xto)
call MulFP
ld d, h \ ld e, l
ld hl, (xup)
SubFP
ld (xup), hl
ld de, (temp)
ld bc, (yto)
call MulFP
ld d, h \ ld e, l
ld hl, (yup)
SubFP
ld (yup), hl
ld de, (temp)
ld bc, (zto)
call MulFP
ld d, h \ ld e, l
ld hl, (zup)
SubFP
ld (zup), hl
ld de, (xup)
ld b, d \ ld c, e
call MulFP
ld (temp), hl
ld de, (yup)
ld b, d \ ld c, e
call MulFP
ld de, (temp)
add hl, de
ld (temp), hl
ld de, (zup)
ld b, d \ ld c, e
call MulFP
ld de, (temp)
add hl, de
call sqrtFP
ld (temp), hl
;Multiply (temp) with the tangent of (angle)/2, which is, in this test program, equal to 1, so we don't need to multiply
ld hl, (xup)
ld de, (temp)
call DivFP
ld (xup), hl
ld hl, (yup)
ld de, (temp)
call DivFP
ld (yup), hl
ld hl, (zup)
ld de, (temp)
call DivFP
ld (zup), hl
ld de, (yup)
ld bc, (zto)
call MulFP
ld (temp), hl
ld de, (zup)
ld bc, (yto)
call MulFP
ld d, h \ ld e, l
ld hl, (temp)
SubFP
ld (xcross), hl
ld de, (zup)
ld bc, (xto)
call MulFP
ld (temp), hl
ld de, (xup)
ld bc, (zto)
call MulFP
ld d, h \ ld e, l
ld hl, (temp)
SubFP
ld (ycross), hl
ld de, (xup)
ld bc, (yto)
call MulFP
ld (temp), hl
ld de, (yup)
ld bc, (xto)
call MulFP
ld d, h \ ld e, l
ld hl, (temp)
SubFP
ld (zcross), hl
ret
C3DTo2D:
;IN: xpoint, ypoint and zpoint vars
;OUT: screenx and screeny are set to the onscreen coordinates for the point
;Will not work if InitView wasn't called before this routine
;destroys all registers and xpoint, ypoint and zpoint
ld hl, (xpoint)
ld de, (xfrom)
SubFP
ld (xpoint), hl
ld hl, (ypoint)
ld de, (yfrom)
SubFP
ld (ypoint), hl
ld hl, (zpoint)
ld de, (zfrom)
SubFP
ld (zpoint), hl
ld de, (xpoint)
ld bc, (xto)
call MulFP
ld (temp), hl
ld de, (ypoint)
ld bc, (yto)
call MulFP
ld de, (temp)
add hl, de
ld (temp), hl
ld de, (zpoint)
ld bc, (zto)
call MulFP
ld de, (temp)
add hl, de
ld (temp), hl
;kijk hier of het punt zichtbaar is
bit 7, h
jp nz, InValid
ld de, (xpoint)
ld bc, (xcross)
call MulFP
ld (temp2), hl
ld de, (ypoint)
ld bc, (ycross)
call MulFP
ld de, (temp2)
add hl, de
ld (temp2), hl
ld de, (zpoint)
ld bc, (zcross)
call MulFP
;ld de, (temp2)
;ld bc, (zup)
;call MulFP
ld de, (temp2)
add hl, de
ld de, (temp)
call DivFP
ld (screenx), hl
ld de, (xpoint)
ld bc, (xup)
call MulFP
ld (temp2), hl
ld de, (ypoint)
ld bc, (yup)
call MulFP
ld de, (temp2)
add hl, de
ld (temp2), hl
ld de, (zpoint)
ld bc, (zup)
call MulFP
ld de, (temp2)
add hl, de
ld de, (temp)
call DivFP
ld (screeny), hl
ld hl, $0100
ld de, (screenx)
SubFP
ld b, h \ ld c, l
ld de, 48
call MulFP
ld (screenx), hl
ld de, (screeny)
ld hl, $0100
SubFP
ld b, h \ ld c, l
ld de, 32
call MulFP
ld (screeny), hl
ld a, 1
ret
InValid:
ld a, 0
ret
;;;;;;;;;;;;;;;; GRAPHIC ROUTINES ;;;;;;;;;;;;;;;;;;;;;;;;;
DrawLine: ;(h,l)to(d,e)
pop ix
ld c, h
push bc
ld c, l
push bc
ld c, d
push bc
ld l, e
push ix
p_Line:
.db __LineEnd-$-1
ld ix,plotSScreen
ld a,l
pop hl
pop bc
pop de
ex (sp),hl ;Called with 3 args pushed. Using call-back optimization.
cp 64
ret nc
ld b,a
ld a,e
cp 64
ret nc
ld d,l
ld l,b
ld a,d
cp 96
ret nc
ld a,c
cp 96
ret nc
ld h,a
sub d
jr nc,__LineSkipRev
ex de,hl
neg
__LineSkipRev:
push af ; Saving DX (it will be popped into DE below)
ld a,d ; IX+=D/8+E*12 (actually E*4+E*4+E*4)
rra
rra
rra
and %00011111
ld c,a
ld b,0
add ix,bc
ld a,e
add a,a
add a,a
ld c,a
add ix,bc
add ix,bc
add ix,bc
ld a,d ; Calculating the starting pixel mask
and %00000111
inc a
ld b,a
ld a,%00000001
__LineMaskLoop:
rrca
djnz __LineMaskLoop
ld c,a
ld a,l ; Calculating delta Y and negating the Y increment if necessary
sub e ; This is the last instruction for which we need the original data
ld de,12
jr nc,__LineSkipNeg
ld de,-12
neg
__LineSkipNeg:
pop hl ; Recalling DX
ld l,a ; D=DX, E=DY
cp h
jr c,__LineHoriz ; Line is rather horizontal than vertical
__LineVert:
ld b,l ; Pixel counter
inc b
rra ; nc at this point so (A=E/2)
__LineVLoop:
push af
ld a,(ix+0)
or c ; Writing pixel to current position
ld (ix+0),a
pop af
add ix,de
sub h ; Handling gradient
jr nc,__LineVNext
add a,l
rrc c ; Rotating mask
jr nc,__LineVNext ; Handling byte boundary
inc ix
__LineVNext:
djnz __LineVLoop
ret
__LineHoriz:
ld b,h ; Pixel counter
inc b
ld a,h ; Setting up gradient counter
srl a
__LineHLoop:
push af ; Saving A
ld a,(ix+0)
or c ; Writing pixel to current position
ld (ix+0),a
pop af ; Recalling A
rrc c ; Rotating mask
jr nc,__LineHSkip ; Handling byte boundary
inc ix
__LineHSkip:
sub l ; Handling gradient
jr nc,__LineHNext
add a,h
add ix,de
__LineHNext:
djnz __LineHLoop
ret
__LineEnd:
;;;;;;;;;;;;;;;;;;
;ClearGbuf
;wist de graphics buffer
;
;IN: /
;OUT: wist de graphics buffer
ClearGbuf:
ld hl, gbuf-12-(-(12*64)+1)
ld a, $20
ld c, a
ClearGbufAgain:
ld b, 64
inc c
ld de, -(12*64)+1
add hl, de
ld de, 10
ClearGbufLoop:
add hl, de
inc hl
inc hl
inc de
ld (hl), $00
dec de
djnz ClearGbufLoop
ld a, c
cp $2B+1
jr nz, ClearGbufAgain
ret
;;;;;;;;;;;;;;;;;;
;fastcopy
;IN: /
;OUT: /
;copies the buffer to the screen
fastCopy:
di
ld a,$80
out ($10),a
ld hl,gbuf-12-(-(12*64)+1)
ld a,$20
ld c,a
inc hl
dec hl
fastCopyAgain:
ld b,64
inc c
ld de,-(12*64)+1
out ($10),a
add hl,de
ld de,10
fastCopyLoop:
add hl,de
inc hl
inc hl
inc de
ld a,(hl)
out ($11),a
dec de
djnz fastCopyLoop
ld a,c
cp $2B+1
jr nz,fastCopyAgain
ret
DrawTriangle:
;IN: x1,y1,u1,v1,x2,y2,u2,v2,x3,y3,u3,v3
;scherm = 96*64
ld hl, (y1)
ld de, (y2)
cpHLDE
jr c, Y1SmallerThanY2
ld (y1), de
ld (y2), hl
ld hl, (x1)
ld de, (x2)
ld (x1), de
ld (x2), hl
#comment
ld hl, (u1)
ld de, (u2)
ld (u1), de
ld (u2), hl
#endComment
ld a, (u1)
ld b, a
ld a, (u2)
ld (u1), a
ld a, b
ld (u2), a
ld a, (v1)
ld b, a
ld a, (v2)
ld (v1), a
ld a, b
ld (v2), a
Y1SmallerThanY2:
ld hl, (y1)
ld de, (y3)
cpHLDE
jr c, Y1SmallerThanY3
ld (y1), de
ld (y3), hl
ld hl, (x1)
ld de, (x3)
ld (x1), de
ld (x3), hl
#comment
ld hl, (u1)
ld de, (u3)
ld (u1), de
ld (u3), hl
#endcomment
ld a, (u1)
ld b, a
ld a, (u3)
ld (u1), a
ld a, b
ld (u3), a
ld a, (v1)
ld b, a
ld a, (v3)
ld (v1), a
ld a, b
ld (v3), a
Y1SmallerThanY3:
ld hl, (y2)
ld de, (y3)
cpHLDE
jr c, Y2SmallerThanY3
ld (y2), de
ld (y3), hl
ld hl, (x2)
ld de, (x3)
ld (x2), de
ld (x3), hl
#comment
ld hl, (u2)
ld de, (u3)
ld (u2), de
ld (u3), hl
#endComment
ld a, (u2)
ld b, a
ld a, (u3)
ld (u2), a
ld a, b
ld (u3), a
ld a, (v2)
ld b, a
ld a, (v3)
ld (v2), a
ld a, b
ld (v3), a
Y2SmallerThanY3:
res 0, (IY) ;in bit 0, (IY) wordt opgeslagen bij welke helft het is. 0=eerste helft, 1= tweede helft
res 1, (IY) ;bit 1, (IY) = interval texturen al berekend
ld hl, (y2)
ld de, (y1)
subFP ;hier gebruikt om 16-bit getallen af te trekken I.P.V. fixed-point getallen
bit 7, h
ld h, l
ld l, 0
jr z,$+3 \ dec l
push hl
ld hl, (x2)
ld de, (x1)
subFP
bit 7, h
ld h, l
ld l, 0
jr z,$+3 \ dec l
pop de
call DivFP
ld (dx1), hl
ld hl, (y3)
ld de, (y2)
subFP
bit 7, h
ld h, l
ld l, 0
jr z,$+3 \ dec l
push hl
ld hl, (x3)
ld de, (x2)
subFP
bit 7, h
ld h, l
ld l, 0
jr z,$+3 \ dec l
pop de
call DivFP
ld (dx2), hl
ld hl, (y3)
ld de, (y1)
subFP
bit 7, h
ld h, l
ld l, 0
jr z,$+3 \ dec l
push hl
ld hl, (x3)
ld de, (x1)
subFP
bit 7, h
ld h, l
ld l, 0
jr z,$+3 \ dec l
pop de
call DivFP
ld (dx3), hl
ld hl, (y2)
ld de, (y1)
subFP
bit 7, h
ld h, l
ld l, 0
jr z,$+3 \ dec l
push hl
ld a, (u2)
ld h, a
ld l, 0
ld a, (u1)
ld d, a
ld e, 0
subFP
;ld h, l
;ld l, 0
pop de
call DivFP
ld (du1), hl
ld hl, (y3)
ld de, (y2)
subFP
bit 7, h
ld h, l
ld l, 0
jr z,$+3 \ dec l
push hl
ld a, (u3)
ld h, a
ld l, 0
ld a, (u2)
ld d, a
ld e, 0
subFP
;ld h, l
;ld l, 0
pop de
call DivFP
ld (du2), hl
ld hl, (y3)
ld de, (y1)
subFP
bit 7, h
ld h, l
ld l, 0
jr z,$+3 \ dec l
push hl
ld a, (u3)
ld h, a
ld l, 0
ld a, (u1)
ld d, a
ld e, 0
subFP
;ld h, l
;ld l, 0
pop de
call DivFP
ld (du3), hl
ld hl, (y2)
ld de, (y1)
subFP
bit 7, h
ld h, l
ld l, 0
jr z,$+3 \ dec l
push hl
ld a, (v2)
ld h, a
ld l, 0
ld a, (v1)
ld d, a
ld l, 0
subFP
;ld h, l
;ld l, 0
pop de
call DivFP
ld (dv1), hl
ld hl, (y3)
ld de, (y2)
subFP
bit 7, h
ld h, l
ld l, 0
jr z,$+3 \ dec l
push hl
ld a, (v3)
ld h, a
ld l, 0
ld a, (v2)
ld d, a
ld e, 0
subFP
;ld h, l
;ld l, 0
pop de
call DivFP
ld (dv2), hl
ld hl, (y3)
ld de, (y1)
subFP
bit 7, h
ld h, l
ld l, 0
jr z,$+3 \ dec l
push hl
ld a, (v3)
ld h, a
ld l, 0
ld a, (v1)
ld d, a
ld e, 0
subFP
;ld h, l
;ld l, 0
pop de
call DivFP
ld (dv3), hl
ld hl, (x1)
bit 7, h
jr z, TPos1
ld (tx1+1),hl \ ld a, $FF \ ld (tx1),a
ld (tx2+1),hl \ ld a, $FF \ ld (tx2),a
jr TEnd1
TPos1:
ld (tx1+1),hl \ xor a \ ld (tx1),a ;store the 16bit integer at hl into 16.8 fixed point number tx1
ld (tx2+1),hl \ xor a \ ld (tx2),a
TEnd1:
ld hl, (y1)
ld (_ty), hl
ld a, (u1)
ld h, a
ld l, 0
ld (tu1), hl
ld (tu2), hl
ld a, (v1)
ld h, a
ld l, 0
ld (tv1), hl
ld (tv2), hl
ld hl, (Y1)
ld de, (y2)
cpHLDE
jp z, __TEndLoop
TDrawLoop:
ld a, (_ty)
ld d, a
bit 7, a
jp nz, Clip
ld a, (_ty)
cp 64
ret nc
ld hl, (tu1)
ld (tmpu), hl
ld hl, (tv1)
ld (tmpv), hl
ld hl, (tu2)
ld (temp2), hl
ld hl, (tv2)
ld (temp3), hl
ld a, (tx2+1)
ld (temp+1), a
ld b, a
ld a, (tx1+1)
ld (temp), a
cp b
jr c, TOrdered
ld hl, (tu2)
ld (tmpu), hl
ld hl, (tv2)
ld (tmpv), hl
ld hl, (tu1)
ld (temp2), hl
ld hl, (tv1)
ld (temp3), hl
ld a, (tx2+1)
ld (temp), a
ld a, (tx1+1)
ld (temp+1), a
TOrdered:
ld l, d
ld a, (temp)
call GetPixel
ld (mask), a
ld (pointer), hl
bit 1, (IY)
jr nz, TPlotLoop
ld hl, (tx1)
ld de, (tx2)
cpHLDE
jr z, TPlotLoop
ld a, (temp)
ld h, a
ld l, 0
ld a, (temp+1)
ld d, a
ld e, 0
subFP
push hl
ld hl, (tmpu)
ld de, (temp2)
subFP
pop de
call DivFP
ld (tmpdu), hl
ld a, (temp)
ld h, a
ld l, 0
ld a, (temp+1)
ld d, a
ld e, 0
subFP
push hl
ld hl, (tmpv)
ld de, (temp3)
subFP
pop de
call DivFP
ld (tmpdv), hl
set 1, (IY)
TPlotLoop:
ld a, (temp)
bit 7, a
jr nz, TEndPlot
cp 96
jp nc, Clip
ld a, (tmpv+1)
ld hl, texture
add a, l
ld l, a
ld a, (tmpu+1)
ld b, a
inc b
ld a, (hl)
TshiftLoop:
rla
djnz TshiftLoop
;push af
ld a, (mask)
ld hl, (pointer)
jr c, TSetPixel
TResPixel:
;ld a, b
cpl
and (hl)
ld (hl), a
jr TEndPlot
TSetPixel:
;ld a, b
or (hl)
ld (hl), a
TEndPlot:
ld hl, mask
rrc (hl)
jr nc, TNoCarry
ld hl, (pointer)
inc hl
ld (pointer), hl
TNoCarry:
ld hl, (tmpu)
ld de, (tmpdu)
add hl, de
ld (tmpu), hl
ld hl, (tmpv)
ld de, (tmpdv)
add hl, de
ld (tmpv), hl
ld a, (temp+1)
ld b, a
ld a, (temp)
ld hl, temp
inc (hl)
cp b
jr nz, TPlotLoop
bit 0, (IY)
jr nz, aaaa
res 1, (IY)
aaaa:
Clip:
ld hl,(tx1)
ld de, (dx1)
ld a, d
rla
sbc a, a
ld b, a
add hl, de
ld (tx1), hl
ld a, (tx1+2)
adc a, b
ld (tx1+2), a
ld hl,(tx2)
ld de, (dx3)
ld a, d
rla
sbc a, a
ld b, a
add hl, de
ld (tx2), hl
ld a, (tx2+2)
adc a, b
ld (tx2+2), a
ld hl, (tu1)
ld de, (du1)
add hl, de
ld (tu1), hl
ld hl, (tu2)
ld de, (du3)
add hl, de
ld (tu2), hl
ld hl, (tv1)
ld de, (dv1)
add hl, de
ld (tv1), hl
ld hl, (tv2)
ld de, (dv3)
add hl, de
ld (tv2), hl
ld hl, (_ty)
inc hl
ld (_ty), hl
ld de, (y2)
cpHLDE
jp c, TDrawLoop
bit 0, (IY)
jr nz, _TEnd
__TEndLoop:
;Begin tweede keer tekenen:
ld hl, (y2)
ld (_ty), hl
ld hl, (y3)
ld (y2), hl
ld hl, (dx2)
ld (dx1), hl
ld hl, (du2)
ld (du1), hl
ld hl, (dv2)
ld (dv1), hl
ld hl, (x2)
bit 7, h
jr nz, TPos4
ld (tx1+1),hl \ ld a, $FF \ ld (tx1),a
jr TEnd4
TPos4:
ld (tx1+1),hl \ xor a \ ld (tx1),a
Tend4:
ld a, (u2)
ld h, a
ld l, 0
ld (tu1), hl
ld a, (v2)
ld h, a
ld l, 0
ld (tv1), hl
set 0, (IY)
jp TDrawLoop
_TEnd:
ret
getPixel:
ld h, 0
ld d, h
ld e, l
add hl, hl
add hl, de
add hl, hl
add hl, hl
ld e, a
srl e
srl e
srl e
add hl, de
ld de, PlotSScreen
add hl, de
and 7
ld b, a
ld a, $80
ret z
rrca
djnz $-1
ret
;;;;;;;;;;;;;;;;;;;;;;;;;; MATH ROUTINES ;;;;;;;;;;;;;;;;;;;;;;;;;;;
SqrtA:
LD (Asqr),A
SRL A
JR DataOver
DataOver:
LD (Bsqr),A
LD B,A
LD (Csqr),A
iterate:
LD A,(Bsqr)
ld b, a
LD a,(Asqr)
LD D,A
LD E,B
dividedbyEreturnA:
RL D
RLA
SUB E
JR nc,$+3
ADD A,E
LD E,A
LD A,D
CPL
push af ;1
LD a,(Bsqr)
ld b, a
pop af ;0
ADD A,B
SRL A
LD (Bsqr),A
LD a,(Bsqr)
ld b, a
LD A,(Csqr)
DEC A
CP B
JR z,done
push af ;1
LD (Csqr),a
ld b, a
pop af ;0
JR iterate
done:
LD A,(Bsqr)
RET
;SubFP:
; ;substracts 2 16-bit fixed-point numbers
; ;IN: hl, de
; ;OUT: hl - de in hl
; ;DESTROYS: a, hl
; or a ;clear carry flag
; sbc hl, de
; ret
Div16By8:
;divides a 16-bit number by an 8-bit number
;IN: hl and d
;OUT: hl = hl/d, remainder = a
;DESTROYS: a, b, c, d, hl
xor a
ld b, 16
_D16b8Loop:
add hl, hl
rla
jr c, _D16b8Overflow
cp d
jr c, _D16b8Skip
_D16b8Overflow:
sub b
inc l
_D16b8Skip:
djnz _D16b8Loop
ret
MulFP:
;Multiplies 2 16bit fixed-point numbers
;IN: de, bc
;OUT: de * bc in hl
;DESTROYS: af, bc, de, hl
bit 7, d
jr nz, _MulFP_FirstNeg
bit 7, b
jr nz, _MulFP_AnsNeg
jr z, _MulFP_AnsPos
_MulFP_FirstNeg:
bit 7, b
jr nz, _MulFP_AnsPos
_MulFP_AnsNeg:
ld a, 1
push af ;1
jr _MulFP_Cont
_MulFP_AnsPos:
ld a, 0
push af ;1
_MulFP_Cont:
bit 7, b
jr z, _MulFP_BCPos
call NegBC
_MulFP_BCPos:
bit 7, d
jr z, _MulFP_DEPos
call NegDE
_MulFP_DEPos:
ld hl,0
ld a,16
Mul16Loop:
add hl,hl
rl e
rl d
jp nc,NoMul16
add hl,bc
jp nc,NoMul16
inc de
NoMul16:
dec a
jp nz,Mul16Loop
ld l, h
ld h, e
pop af ;0
cp 1
call z, NegHL
ret
;adding fixed-point numbers:
;load one of the numbers in hl, and the other in an other 16-bit register.
;then, do: add hl, <register>
DivFP:
;IN: hl, de
;OUT: hl = hl / de
;DESTROYS: af, hl, bc, d
bit 7, d
jr nz, _DivFP_FirstNeg
bit 7, h
jr nz, _DivFP_AnsNeg
jr z, _DivFP_AnsPos
_DivFP_FirstNeg:
bit 7, h
jr nz, _DivFP_AnsPos
_DivFP_AnsNeg:
ld a, 1
push af
jr _DivFP_Cont
_DivFP_AnsPos:
ld a, 0
push af
_DivFP_Cont:
bit 7, h
jr z, _DivFP_HLPos
call NegHL
_DivFP_HLPos:
bit 7, d
jr z, _DivFP_DEPos
call NegDE
_DivFP_DEPos
ld a, h
ld h, l
ld l, 0
push hl ;INPUTS: ahl = dividend de = divisor ;1
pop ix ;OUTPUTS: ahl = quotient de = divisor ;0
ld hl,0
ld b,24
_Div24by16loop:
add ix,ix
rla
adc hl,hl
jr c,_Div24by16setbit
or a
sbc hl,de
add hl,de
jr c,_Div24by16skip
_Div24by16setbit:
or a
sbc hl,de
inc ix
_Div24by16skip:
djnz _Div24by16loop
push ix ;1
pop hl ;0
pop af
cp 1
call z, NegHL
ret
SinA:
;calculates the sine of a as a fixed point number
;IN: a
;OUT: hl = sin(a)
LD h, 0
LD l, a
add hl, hl
LD DE, sine_table
ADD HL, DE
LD A, (HL)
INC HL
LD H, (HL)
LD L, A
RET
sine_table:
.dw 0, 6, 13, 19, 25, 31, 38, 44, 50, 56, 62, 68, 74, 80, 86, 92, 98, 104, 109, 115, 121, 126, 132, 137, 142
.dw 147, 152, 157, 162, 167, 172, 177, 181, 185, 190, 194, 198, 202, 206, 209, 213, 216, 220, 223, 226, 229, 231, 234
.dw 237, 239, 241, 243, 245, 247, 248, 250, 251, 252, 253, 254, 255, 255, 256, 256, 256, 256, 256, 255, 255, 254, 253
.dw 252, 251, 250, 248, 247, 245, 243, 241, 239, 237, 234, 231, 229, 226, 223, 220, 216, 213, 209, 206, 202, 198, 194
.dw 190, 185, 181, 177, 172, 167, 162, 157, 152, 147, 142, 137, 132, 126, 121, 115, 109, 104, 98, 92, 86, 80, 74, 68
.dw 62, 56, 50, 44, 38, 31, 25, 19, 13, 6, 0, -6, -13, -19, -25, -31, -38, -44, -50, -56, -62, -68, -74, -80, -86, -92
.dw -98, -104, -109, -115, -121, -126, -132, -137, -142, -147, -152, -157, -162, -167, -172, -177, -181, -185, -190
.dw -194, -198, -202, -206, -209, -213, -216, -220, -223, -226, -229, -231, -234, -237, -239, -241, -243, -245, -247
.dw -248, -250, -251, -252, -253, -254, -255, -255, -256, -256, -256, -256, -256, -255, -255, -254, -253, -252, -251
.dw -250, -248, -247, -245, -243, -241, -239, -237, -234, -231, -229, -226, -223, -220, -216, -213, -209, -206, -202
.dw -198, -194, -190, -185, -181, -177, -172, -167, -162, -157, -152, -147, -142, -137, -132, -126, -121, -115, -109
.dw -104, -98, -92, -86, -80, -74, -68, -62, -56, -50, -44, -38, -31, -25, -19, -13, -6
SqrtFP:
;#####################################################
;square root of fixed point hl
;input: hl
;output: hl=sqrt(hl)
sqrt_hl:
ld a, l
ld l, h
ld de, 0040h ; 40h appends "01" to D
ld h, d
ld b, 7
; need to clear the carry beforehand
or a
_loopz:
sbc hl, de
jr nc, $+3
add hl, de
ccf
rl d
rla
adc hl, hl
rla
adc hl, hl
djnz _loopz
sbc hl, de ; optimised last iteration
ccf
rl d
ld h, d
xor a
ld b, 4
shiftLoopz:
srl h
rra
djnz shiftLoopz
ld l, a
ret
NegHL:
xor a
sub l
ld l,a
sbc a,a
sub h
ld h,a
ret
NegBC:
xor a
sub c
ld c,a
sbc a,a
sub b
ld b,a
ret
NegDE:
xor a
sub e
ld e,a
sbc a,a
sub d
ld d,a
ret
;;;;;;;;;;;;;;;;;;;;;;;;;; OTHER ROUTINES ;;;;;;;;;;;;;;;;;;;;;;;;;;
;###################################
calcFPS:
fpsCounter equ $+1
ld a, 00
inc a
ld (fpsCounter), a
in a, (04)
bit 5, a
jr z, didntChange
initFPS:
ld a, $47
out ($30), a
xor a
out ($31), a
ld a, 8
out ($32), a
ld a, (fpsCounter)
ld (fpsFinal), a
xor a
ld (fpsCounter), a
didntChange:
fpsFinal equ $+1
ld a, 00
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;; Textures ;;;;;;;;;;;;;;;;;;;;;;;;;
Texture:
.db %11111111
.db %11010101
.db %10101011
.db %11010101
.db %10101011
.db %11010101
.db %10101011
.db %11111111
.end