IF corr_coord
CORR_COORD
LD A,L
OR A
jr NZ,$+3
INC L
INC A
jr NZ,$+3
DEC L
LD A,H
OR A
jr NZ,$+3
INC H
INC A
RET NZ
DEC H
RET
ENDIF
SCAN
IF optfast
LD HL,(IMcurDX)
LD A,H
OR L
LD HL,(IMcurDY)
OR H
OR L
LD A,lowmaxscale
jr Z,$+4
LD A,0;-1
LD (foptfast),A
ENDIF
IMcurXx=$+1
LD HL,#0F80 ;#0580
IF corr_coord
CALL CORR_COORD
ENDIF
LD (curXx),HL
IMcurYy=$+1
LD HL,#0180+(map&#FF00) ;#A580
IF corr_coord
CALL CORR_COORD
ENDIF
LD (curYy),HL
LD A,(IMavision+1)
LD (curangle),A
SUB 32
LD L,A
LD H,0
ADD HL,HL
ADD HL,HL
LD A,L
LD (avision4L),A
LD A,H
LD (avision4H),A
LD HL,(cury-1)
LD A,(curx)
LD L,A
LD (cur00yx),HL
LD (cur01yx),HL
;LD A,L ;основное направление
CPL ;1-основное направление
LD L,A
LD (cur10yx),HL
LD (cur11yx),HL
CPL ;основное направление
LD L,H,H,A
LD (cur00xy),HL
LD (cur01xy),HL
LD A,L ;1-основное направление
CPL ;основное направление
LD L,A
LD (cur10xy),HL
LD (cur11xy),HL
LD HL,(curX)
LD A,(curY)
LD H,A
;LD (curYX),HL
LD (ray00yx_YX),HL
LD (ray01yx_YX),HL
LD (ray10yx_YX),HL
LD (ray11yx_YX),HL
LD (ray00xy_YX),HL
LD (ray01xy_YX),HL
LD (ray10xy_YX),HL
LD (ray11xy_YX),HL
SET mapdifbit,L
LD (ray00xy_YX2),HL
LD (ray01xy_YX2),HL
LD (ray10xy_YX2),HL
LD (ray11xy_YX2),HL
IF showscans
LD A,(scans)
LD DE,#411E
LD C,10
CALL PRDIG
LD C,1
CALL PRDIG
XOR A
LD (scans),A
ENDIF
IF interpolate == 0
IF lores
LD L,0;2*(32-scrwid)
LD HY,scrwid*4
ELSE
LD L,0;4*(32-scrwid)
LD HY,scrwid*8
ENDIF
RAY0
LD A,L
LD (cura),A
CALL RAYCAST
LD HL,(cura)
LD H,distbuf/256+2
LD (HL),C ;dist
DEC H
LD (HL),B ;texx
DEC H
RRCA ;CY=0
LD A,(DE) ;YX
LD (HL),A ;ID
INC L
DEC HY
JP NZ,RAY0
ELSE ;interpolate
main_step=interpolate;16
;oldscan=RAYCAST(0)
XOR A
LD L,A
LD (cura),A
CALL RAYCAST
EXX
;main_a=main_step-1
LD L,main_step-1
IF lores
LD HY,scrwid*4/main_step
ELSE
LD HY,scrwid*8/main_step
ENDIF
;repeat {
;L=main_a
;BCDE'=oldscan
;BCDE=newscan
RAY0
;newscan=RAYCAST(main_a)
LD A,L
LD (cura),A
CALL RAYCAST
LD HL,(cura)
;INTERPOLATE_SUB(main_a, main_step, oldscan, newscan)
LD A,main_step
LD H,distbuf/256+2
LD (HL),C ;dist
DEC H
LD (HL),B ;texx
DEC H
RRCA ;CY=0
CALL INTERPOLATE_SUB
LD A,(DE) ;YX
LD (HL),A ;ID
;oldscan=newscan
LD A,L
EXX
;main_a+=main_step
ADD A,main_step
LD L,A
;} until(main_a>255)
DEC HY
JP NZ,RAY0
ENDIF ;interpolate
RET
;((b+f)/2)^2-b^2/4-f^2/4
;a=e
MACRO MULPOS
LD H,tsqr2/256
ADD A,C
RRA
LD L,A
LD A,(HL)
INC H
LD L,C
SUB (HL)
LD L,E
SUB (HL)
ENDM
MACRO DIVPOS
SRL C
DUP 7
ADD A,C
jr NC,$+3
SUB C
RL B
ADD A,A
EDUP
ADD A,C
LD A,B
RLA
ENDM
MACRO DIVNEG
SRL C
DUP 7
SUB C
jr NC,$+3
ADD A,C
RL B
ADD A,A
EDUP
SUB C
LD A,B
RLA
ENDM
;Y растёт вверх
RAYCAST
;L=(cura)=угол на экране
;портит ABCDEHLIX
IF showscans
scans=$+1
LD A,0
INC A
LD (scans),A
ENDIF
LD H,tda/256
LD A,(HL)
avision4L=$+1
ADD A,0
LD (rayrealangle),A
LD L,A
avision4H=$+1
ADC A,0
SUB L ;a1..0 = 0..3 ~ sector 1..4
;LD H,tctg/256 ;-pi/4..+pi/4
INC H
LD C,(HL) ;ystep or xstep
LD HX,-1 ;IX=dist*cos
;jr $
RRA
jr NC,ray13
RRA
JP NC,ray2
JP ray4
ray13 RRA
JP NC,ray1
JP ray3
macro INCR num ;0..5 = bcdehl
db 0x04+(8*num)
endm
macro DECR num ;0..5 = bcdehl
db 0x05+(8*num)
endm
;RAY 1,1,H,L,D,E,y,x
MACRO RAY mainplus,secplus,maindirhlreg,secdirhlreg,maindirdereg,secdirdereg,maindir,secdir
;mainplus=\0 ;основное направление положительно
;secplus=\1 ;побочное направление положительно
;\2=основное направление для hl
;\3=побочное направление для hl
;\4=основное направление для de
;\5=побочное направление для de
;\6=основное направление
;\7=побочное направление
;LD DE,(cur\7\6)
;cur0176=$+1
; LD DE,0
LD A,E ;основное направление
;IF mainplus ;основное направление положительно
; CPL ;1-основное направление
; LD E,A
;ENDIF
LD LX,A ;IX=dist*cos
MULPOS
IF secplus ;побочное направление положительно
ADD A,D ;побочное направление
LD B,A
;LD HL,(curYX)
ray0176_YX=$+1
LD HL,0
IF maindir != 0 ;"\6\6"-"xx"
;LD D,H,E,L
;SET mapdifbit,E
ray0176_YX2=$+1
LD DE,0
ELSE
LD D,H
ld E,L
ENDIF
jr NC,2f;raynshort\0\1\7\6
INCR secdirdereg;INC \5 ;e/d
LD A,(DE)
RLA
jr C,1f;raysec\0\1\7\6
INCR secdirhlreg;INC \3 ;l/h
2;raynshort\0\1\7\6
IF maindir != 1 ;"\6\6"-"yy"
SET mapdifbit,L
ENDIF
ELSE
LD L,A
LD A,D ;побочное направление
SUB L
LD B,A
;LD HL,(curYX)
ray0176_YX=$+1
LD HL,0
IF maindir != 0 ;"\6\6"-"xx"
;LD D,H,E,L
;SET mapdifbit,E
ray0176_YX2=$+1
LD DE,0
ELSE
LD D,H
ld E,L
ENDIF
jr NC,2f;raynshort\0\1\7\6
LD A,(DE)
RLA
jr C,1f;raysec\0\1\7\6
;DEC \3,\5 ;l/h,e/d
DECR secdirhlreg
DECR secdirdereg
2;raynshort\0\1\7\6
IF maindir != 1 ;"\6\6"-"yy"
SET mapdifbit,L
ENDIF
ENDIF
3;raynsec=$;\0\1\7\6
INC HX
IF mainplus ;основное направление положительно
INCR maindirhlreg;INC \2 ;h/l
ENDIF
LD A,(HL)
RLA
JP C,rayhlq ;b=texx
IF mainplus ;основное направление положительно
INCR maindirdereg;INC \4 ;d/e
ELSE
;DEC \2,\4 ;h/l,d/e
DECR maindirhlreg
DECR maindirdereg
ENDIF
LD A,B
IF secplus ;побочное направление положительно
ADD A,C
ELSE
SUB C
ENDIF
LD B,A
jr NC,3b;raynsec;\0\1\7\6
IF secplus ;побочное направление положительно
INCR secdirdereg;INC \5 ;e/d
ENDIF
LD A,(DE)
RLA
jr C,1f;raysec\0\1\7\6
IF secplus ;побочное направление положительно
INCR secdirhlreg;INC \3 ;l/h
ELSE ;побочное направление отрицательно
;DEC \3,\5 ;l/h,e/d
DECR secdirhlreg
DECR secdirdereg
ENDIF
JP 3b;raynsec;\0\1\7\6
1;raysec\0\1\7\6
EXD
LD A,B
IF secplus ;побочное направление положительно
SUB C
DIVPOS
ELSE
ADD A,C
DIVNEG
ENDIF
IF mainplus ;основное направление положительно
CPL
LD B,A ;b=texx
ELSE
LD B,A ;b=texx
CPL
ENDIF
JP raydeq
ENDM
;mainplus=\0 ;основное направление положительно
;secplus=\1 ;побочное направление положительно
;\2=основное направление для hl = 4..5
;\3=побочное направление для hl = 4..5
;\4=основное направление для de = 2..3
;\5=побочное направление для de = 2..3
;\6=основное направление
;\7=побочное направление
;сейчас l=angle
ray1
BIT 7,L
JP NZ,ray1b
;RAY 1,1,L,H,E,D,x,y ;1a
cur11yx=$+1
LD DE,0
RAY 1,1,5,4,3,2,0,1;x,y ;1a
;cur11yx=cur0176
ray11yx_YX=ray0176_YX
;ray11yx_YX2=ray0176_YX2
ray1b
;RAY 1,1,H,L,D,E,y,x ;1b
cur11xy=$+1
LD DE,0
RAY 1,1,4,5,2,3,1,0;y,x ;1b
;cur11xy=cur0176
ray11xy_YX=ray0176_YX
ray11xy_YX2=ray0176_YX2
ray2
BIT 7,L
JP NZ,ray2b
;RAY 1,0,H,L,D,E,y,x ;2a
cur10xy=$+1
LD DE,0
RAY 1,0,4,5,2,3,1,0;y,x ;2a
;cur10xy=cur0176
ray10xy_YX=ray0176_YX
ray10xy_YX2=ray0176_YX2
ray2b
;RAY 0,1,L,H,E,D,x,y ;2b
cur01yx=$+1
LD DE,0
RAY 0,1,5,4,3,2,0,1;x,y ;2b
;cur01yx=cur0176
ray01yx_YX=ray0176_YX
;ray01yx_YX2=ray0176_YX2
ray3
BIT 7,L
JP NZ,ray3b
;RAY 0,0,L,H,E,D,x,y ;3a
cur00yx=$+1
LD DE,0
RAY 0,0,5,4,3,2,0,1;x,y ;3a
;cur00yx=cur0176
ray00yx_YX=ray0176_YX
;ray00yx_YX2=ray0176_YX2
ray3b
;RAY 0,0,H,L,D,E,y,x ;3b
cur00xy=$+1
LD DE,0
RAY 0,0,4,5,2,3,1,0;y,x ;3b
;cur00xy=cur0176
ray00xy_YX=ray0176_YX
ray00xy_YX2=ray0176_YX2
ray4
BIT 7,L
JP NZ,ray4b
;RAY 0,1,H,L,D,E,y,x ;4a
cur01xy=$+1
LD DE,0
RAY 0,1,4,5,2,3,1,0;y,x ;4a
;cur01xy=cur0176
ray01xy_YX=ray0176_YX
ray01xy_YX2=ray0176_YX2
ray4b
;RAY 1,0,L,H,E,D,x,y ;4b
cur10yx=$+1
LD DE,0
RAY 1,0,5,4,3,2,0,1;x,y ;4b
;cur10yx=cur0176
ray10yx_YX=ray0176_YX
;ray10yx_YX2=ray0176_YX2
rayhlq
XOR A
raydeq
;b=texx
;hl=YX
;dist*cos=ix+a
PUSH HL
ADD A,LX
LD L,A
ADC A,HX
SUB L
LD H,A
;HL=dist*cos=128..#3fff
;приводим к 128..255
LD DE,#000
LD A,L
jr Z,TOLOGRLQ
DUP 5;6
INC D
SRL H
RRA
jr Z,TOLOGRLE
EDUP
TOLOGRLQ ;
OR A
JP M,$+5 ;>=128
LD A,128 ;<128
TOLOGRLE ;
LD L,A ;128..255
;D=0..5
LD H,tlogd/256
;2.делим на cos
rayrealangle=$+1
LD A,(tlogcos) ;0..63
ADD A,(HL) ;log(dist/2^N) = 128..255 for arg>=128
IF debug
jr NC,$+3
INC D
ENDIF
;3.умножение на corrdist(scrX) - получаем k/масштаб
;(сокращаем расстояние по краям в sqrt(2) раз)
;corrdist(scrX)=1/sqrt(1+scrX^2), где scrX=-1..+1
;из него номер таблицы масштабирования
cura=$+1
LD HL,tcorrlogd ;L=scrX=0..255="-127.5..127.5"
SUB (HL) ;64..128
IF debug
jr NC,DEBBP
DEC D
JP P,DEBBP
INC D
XOR A
DEBBP ;
ENDIF
LD L,A
LD H,tlogd2sca/256
SRA D
RR E ;DE=+0,+#80,..+#300
ADD HL,DE
IF debug
BIT 7,(HL)
jr NZ,$
ENDIF
LD C,(HL) ;dist=127..1
;todo linear scale, recalc in DRAWWALLS
SCF
RR B ;texx=0x80..0xFF
IF scale64
SRL B ;texx=0x40..0x7F
ENDIF
POP DE
RET
IF interpolate
IF 0
I_SUB_INTERt ;
POP HL ;
PUSH HL ;de
LD A,D
SUB H
jr NZ,holeny
LD A,E
SUB L
JP Z,I_SUB_INTER ;продолжение стены
DEC A
CP 3
jr C,nhole
JP isubneq
holeny ;
DEC A
CP 3
jr NC,isubneq
LD A,E
CP L
jr NZ,isubneq
nhole ;
ENDIF
I_SUB_INTER
; rightscan=Middlescan
LD A,C
EXX
ADD A,C
RRA
LD C,A ;dist
EXX
LD A,B
EXX
ADD A,B
RRA
LD B,A ;texx
I_SUB_SCANQ ;
;INTERPOLATE_SUB(a-step, step, leftscan, rightscan);r=M
PUSH HL ;step,a
LD A,L
SUB H
LD L,A ;a-step
LD A,H
LD H,distbuf/256+2
LD (HL),C ;dist
DEC H
LD (HL),B ;texx
DEC H
RRCA
CALL NC,INTERPOLATE_SUB
LD A,(DE) ;YX
LD (HL),A ;ID
;leftscan=rightscan ;=Middlescan
EXX
POP HL ;step,a
;pop(rightscan)
POP DE
pop BC
;INTERPOLATE_SUB(a, step, leftscan, rightscan) ;l=M,r=R
;scan[a]=rightscan
;if (step==1) exit
LD A,H
LD H,distbuf/256+2
LD (HL),C ;dist
DEC H
LD (HL),B ;texx
DEC H
RRCA
RET C
INTERPOLATE_SUB
;L=a
;A=step/2 ;not preserved
;BCDE'=leftscan ;(a-step) ;not preserved
;BCDE=rightscan ;(a)
;CY=0
EXA
LD A,(DE) ;YX
LD (HL),A ;ID ;texx,dist are written already
EXA
;step=step/2
LD H,A
;push(rightscan)
PUSH BC
push DE
;if(rightscan.yx==leftscan.yx)
;LD A,(DE)
EXX
;EXD
;XOR (HL)
;EXD
;JP Z,I_SUB_INTERt
POP HL ;
PUSH HL ;de
;OR A
SBC HL,DE ;CY=0
JP Z,I_SUB_INTER
isubneq
; rightscan=RAYCAST(a-step)
EXX
PUSH HL
LD A,L
SUB H
LD L,A ;a-step
LD (cura),A
CALL RAYCAST
POP HL
JP I_SUB_SCANQ
;else - see above
ENDIF ;interpolate
;============================
IF sprites
viewrange=6
SCANMONS
LD A,(curX)
SUB viewrange
LD (scmonX),A
LD A,(curY)
SUB viewrange
LD (scmonY),A
LD HL,cursprites
LD (HL),0 ;end of sprites
LD (scaneof),HL
LD HL,MONSTRS+1 ;1+начало табл.монстров/предметов
CALL SCMONS0 ;цикл скан-я видимых монстров/предметов
RET
SCMONNx
LD A,L
ADD A,8
LD L,A
JR C,SCMxIH
SCMONS0
LD A,(HL)
INC A
RET Z
scmonX=$+1
SUB 0
CP viewrange*2+1
JP NC,SCMONNx
INC L
inc L
LD A,(HL)
scmonY=$+1
SUB 0
CP viewrange*2+1
JR C,SCMONY
LD A,L
ADD A,6
LD L,A
JP NC,SCMONS0
SCMxIH INC H
JP SCMONS0
SCMONY DEC L
dec L
dec L
LD C,(HL)
INC L
LD B,(HL) ;Xx
INC L
LD E,(HL)
INC L
LD D,(HL) ;Yy
INC L
PUSH HL
PUSH BC
display $
LD L,(HL) ;TYPE = 1..63
;ld a,l
;cp 6
;jr z,$
;ld l,0
LD B,0
ld H,B
ADD HL,HL
ADD HL,HL
ADD HL,HL
;ADD HL,BC
;ADD HL,HL
LD BC,MONSTAB-8
ADD HL,BC
;LD A,(HL) ;texx
;LD HX,A
;INC HL
LD A,(HL) ;ID текстуры
ld lx,a
POP BC
;calculate sprite position
LD HL,(curYy)
SBC HL,DE ;Yy
EXD
LD HL,(curXx)
SBC HL,BC ;Xx
CALL OBJMUL
;BC=dist
;DE=xscr
IF lores
SRA D
RR E
ENDIF
LD HL,pixperchr*scrwid/2-256
SBC HL,DE
INC H
jr NZ,SCANnSPR ;X out of screen
IF lores
BIT 7,L
jr NZ,SCANnSPR ;X out of screen
ENDIF
;write data to cursprites
PUSH BC
EXX
POP BC
LD HL,cursprites+((-2)&0xff)
SCANsort0
INC L
inc L
LD A,(HL)
OR A
jr Z,SCANins
INC L
LD E,(HL)
INC L
LD D,(HL)
EXD
SBC HL,BC
EXD
jr NC,SCANsort0
DEC L
dec L
SCANins
PUSH BC
scaneof=$+1
LD DE,0
LD A,E
SUB L
INC A ;bytes to move
LD C,A
LD B,0
LD H,D
ld L,E
LD A,E
ADD A,4
LD E,A
LD (scaneof),A
LDDR
INC HL
POP BC
LD A,lx;1
;A=ID текстуры
;BC'=dist
;L'=xscr
LD (HL),A
INC L
LD (HL),C
INC L
LD (HL),B
INC L
EXX
LD A,L
EXX
LD (HL),A ;xscr
INC L
EXX
SCANnSPR ;
POP HL
INC L
inc L
inc L
inc HL
INC L
JP SCMONS0
DRAWSPRITES
LD IY,cursprites
DRAWSPRITES0 ;
LD A,(IY)
OR A
RET Z
INC IY
LD C,(IY)
INC IY
LD B,(IY)
INC IY
;A=ID
if atm==0
EXX
LD D,a;#EA ;ID
EXX
endif
add a,a
add a,a
ld hl,tsprites-4
add a,l
ld l,a
jr nc,$+3
inc h
display $
;jr $
ld a,(hl)
ld (drawspritepg),a
inc hl
ld a,(hl)
LD HX,a;#80+22;#C0 ;texx_center
;ld hx,22/2
inc hl
ld a,(hl)
ld (drawspritetexxleft),a
inc hl
ld a,(hl)
ld (drawspritetexxright),a
LD L,(IY)
INC IY
;L=xscr
;BC=dist
INC B
DJNZ gFILLNCLOSE
LD A,108;64 ;от этого числа зависит только ширина спрайта при максимальном приближении, но не максимальная высота (она ограничена этим числом и сравнением дальше, закомментированным) ;108 чуть ниже ATM экрана, 128 запас около 8 пикс снизу
CP C
jr nc,DRAWSPRITES0 ;лампы не уменьшаем ;TODO уметь отличать врагов от ламп
jr C,$+3
LD C,A ;спрайт слишком близко!!! уменьшим
gFILLNCLOSE
PUSH BC ;dist
;приводим к 128..255
LD DE,#000
INC B
DEC B
LD A,C
jr Z,MOTOLOGRLQ
DUP 5;6
INC D
SRL B
RRA
jr Z,MOTOLOGRLE
EDUP
MOTOLOGRLQ ;
;OR A
;JP M,$+5 ;>=128
;LD A,128 ;<128
;;cp 96
;;jr nc,$+4
;;ld a,96 ;спрайт слишком близко!!! увеличим dist для уменьшения высоты
MOTOLOGRLE ;
LD C,A ;128..255 ;D=0..5
LD B,tlogd/256
LD A,(BC) ;log(dist) = 128..255 for arg>=128
if atm==0
SUB 16;64 ;0..127 for arg=64..127 ;???
endif
LD C,A ;0 for arg<64
LD B,tlogd2sca/256
SRA D
RR E ;DE=+0,+#80,..+#300
EXD
ADD HL,BC
display "getscale#=",$
LD C,(HL) ;scale#
EXD
;
POP DE ;dist
if atm
ld a,l
ld h,d
ld l,e
srl h
rr l
add hl,de
ex de,hl ;de = de * 1.5
ld l,a
else
IF loresspr
SLA E
RL D
ENDIF
SLA E
RL D ;DE=texx step = de * 4
endif
IF loresspr_hires|optresspr
RES 0,L
ENDIF
LD H,distbuf/256+2 ;ID,texx,dist
LD A,C ;scale#
CP (HL)
CALL NC,DRAWSPRITE ;object center is visible ;TODO независимо от видимости центра
JP DRAWSPRITES0
OBJMULQ
POP AF ;X
LD D,#40 ;X out of screen
RET
;пересчет координат объекта (Xx=HL, Yy=DE)
;в координаты на экране (DE=xscr, BC=расстояние)
OBJMUL
PUSH HL ;X
PUSH DE ;Y
PUSH HL ;X
LD HL,(curangle) ;L=центр взгляда
LD C,(HL) ;sin=шаг по Y
LD A,-64
SUB L
LD L,A
LD B,(HL) ;-COS=шаг по X
;Bc=DXdy=COSsin
LD A,C
CPL
CALL MULT ;HL=A*DE=-sin*Y
POP DE ;X
LD A,B
CALL MULTADD ;HL=-COS*X-sin*Y=d(расстояние по объекта)
POP DE ;Y
BIT 7,H
jr NZ,OBJMULQ ;если расстояние<0,то объект за спиной=>exit
LD (_OBJd1),HL
CALL MULT;A=B=-COS, HL=-COS*Y
POP DE ;X
LD A,C
CALL MULTADD ;HL=-COS*Y+sin*X=xscr*d
EXD
_OBJd1=$+1
LD BC,0 ;BC=d ;после MONDIV получим DE=xscr
;деление
;DE=+-7.8;BC=+7.8
;DE=DE/BC=+-8.7/2
;BC сохраняется!!!
MONDIV
LD H,0
LD A,D
SLA E
RLA
JP C,MONDIVNEG ;если делимое<0
LD L,A
INC E
LD A,E
DUP 7
SBC HL,BC
JR NC,$+3
ADD HL,BC
RLA
ADC HL,HL
EDUP
CPL
LD D,A
DUP 7
SBC HL,BC
JR NC,$+3
ADD HL,BC
RLA
ADD HL,HL
EDUP
SBC HL,BC
JR NC,$+3
ADD HL,BC
RLA
CPL
LD E,A
RET
;если делимое<0
MONDIVNEG
CPL
LD L,A
SBC A,A
XOR E
DUP 7
SBC HL,BC
JR NC,$+3
ADD HL,BC
RLA
ADC HL,HL
EDUP
LD D,A
DUP 7
SBC HL,BC
JR NC,$+3
ADD HL,BC
RLA
ADD HL,HL
EDUP
SBC HL,BC
JR NC,$+3
ADD HL,BC
RLA
LD E,A
RET
;умножение
;A=+-0.7
;HL=A*DE
;A сохраняется!!!
MULT
LD HL,0
MULTADD
RLCA
JR NC,MULTPLU
DUP 6
SRA D
RR E
RLCA
JR C,$+4
SBC HL,DE
EDUP
RLCA
RET C
SRA D
RR E
OR A
SBC HL,DE
RET
MULTPLU DUP 6
SRA D
RR E
RLCA
JR NC,$+3
ADD HL,DE
EDUP
RLCA
RET NC
SRA D
RR E
ADD HL,DE
RET
ENDIF ;sprites