tkeyangle=$-5
;LRDU
;DB -1 ;0000
;DB 128;0001
;DB 0 ;0010
;DB -1 ;0011
;DB 64 ;0100
DB 96 ;0101
DB 32 ;0110
DB 64 ;0111
DB 192;1000
DB 160;1001
DB 224;1010
DB 192;1011
DB -1 ;1100
DB 128;1101
DB 0 ;1110
DB -1 ;1111
tkeyangleend
;в 0x4000 включена pgmap
CONTROL
;режимы двери:
;0: дверь закрыта
;1: дверь открывается, doortimer увеличивается
;2: дверь открыта, dooropentimer уменьшается
;3: дверь закрывается, doortimer уменьшается
doortimer=$+1
ld a,0
doortimermode=$+1
ld b,0
djnz control_door_noopening
add a,2
ld (doortimer),a
jr nz,control_doorq
dec a ;-1
ld (doortimer),a ;stay opened
ld a,50 ;a=door open time
ld (dooropentimer),a
ld a,2
ld (doortimermode),a
jr control_doorq
control_door_noopening
djnz control_door_noopened
dooropentimer=$+1
ld a,0
dec a
ld (dooropentimer),a
jr nz,control_doorq
;call closecurrentdoor ;keeps hl
ld a,-2
ld (doortimer),a ;stay opened
ld a,3
ld (doortimermode),a
jr control_doorq
control_door_noopened
djnz control_door_noclosing
;если игрок стоит в дверях, то не закрываем, а открываем
LD HL,(IMcurXx+1)
LD a,(IMcurYy+1)
ld h,a
ld a,ID_DOOR
cp (hl)
jr z,control_door_setopened
inc h
cp (hl)
jr z,control_door_setopened
dec h
set mapdifbit,l
cp (hl)
jr z,control_door_setopened
inc l
cp (hl)
jr z,control_door_setopened
ld a,(doortimer)
sub 2
ld (doortimer),a
jr nz,control_doorq
;xor a
ld (doortimermode),a
call closecurrentdoor ;keeps hl
jr control_doorq
control_door_setopened
ld a,1
ld (doortimermode),a
control_door_noclosing
control_doorq
IF kempston
LD C,#FF
IN A,(#1F)
LD B,A
AND #E0
jr NZ,nKEMPSTON
LD A,B
RRA
jr NC,$+4
RES 1,C
RRA
jr NC,$+4
RES 0,C
RRA
jr NC,$+4
RES 3,C
RRA
jr NC,$+4
RES 2,C
RRA
jr NC,$+4
RES 6,C
nKEMPSTON
;C=%1f11durl
ENDIF
IF autostrafe
BIT 3,C ;down
jr NZ,nAUTOSTRAFE
LD A,C
BIT 1,A
jr NZ,$+6
AND %01101111 ;strafe + rotate flag
OR %00001011 ;block down & rotate
BIT 0,A
jr NZ,$+6
AND %01011111 ;strafe + rotate flag
OR %00001011 ;block down & rotate
LD C,A
nAUTOSTRAFE
ENDIF
LD B,#FF
ld a,#fe
in a,(#fe)
rra
rl b ;cs (open)
LD A,#7F
IN A,(#FE)
RRA
RL B ;space (fire)
LD A,#FD
IN A,(#FE)
RRA
RL B ;A
RRA
RRA
RL B ;D
RLA
RL B ;S (down)
LD A,#FB
IN A,(#FE)
RRA
RRA
RL B ;W (up)
LD A,#DF
IN A,(#FE)
RRA
RL B ;P (right)
RRA
LD A,B
RLA ;O (left)
IF kempston
AND C
ENDIF
;A=%ofADdurl
IF demoplay
demoplayoff=$
OR A
jr C,demoplayQ
BIT 4,A ;"D"
jr NZ,demoplaynOFF
LD A,#37 ;scf
LD (demoplayoff),A
LD A,#91 ;sub c
LD (mouseon),A
LD A,#FF
demoplaynOFF
democursor=$+1
LD HL,demobegin
demokey=$+1
LD A,%00111111
demokeytime=$+1
LD C,1
DEC C
jr NZ,CnNEWKEY
LD A,(HL)
LD (demokey),A
INC HL
LD C,(HL)
INC HL
LD (democursor),HL
CnNEWKEY
LD HL,demokeytime
LD (HL),C
demoplayQ
ELSE
IF demorec
democursor=$+1
LD HL,demobegin
demokeytime=$+1
LD C,0
INC C
jr Z,CNEWKEY
CP (HL)
jr Z,CnNEWKEY
CNEWKEY
INC HL
LD (HL),C
LD C,0
INC HL
CnNEWKEY
LD (HL),A
LD (democursor),HL
LD HL,demokeytime
LD (HL),C
ENDIF
ENDIF
;a=%ofADdurl
PUSH AF
bit 7,a
jr nz,noopendoor
;call closecurrentdoor ;keeps hl
LD HL,(IMcurXx+1)
LD a,(IMcurYy+1)
ld h,a
ld c,ID_DOOR*2
ld a,(hl)
add a,a
cp c
jr z,opendoor_h_dec
inc h ;dec h
ld a,(hl)
add a,a
cp c
jr z,opendoor_h_inc
dec h ;inc h
set mapdifbit,l
ld a,(hl)
add a,a
cp c
jr z,opendoor_l_dec
inc l
ld a,(hl)
add a,a
cp c
;jr z,opendoor
jr nz,noopendoor
opendoor_l_inc
push hl
res 7,(hl)
inc l
res 7,(hl)
jr opendoorok
opendoor_l_dec
push hl
res 7,(hl)
dec l
res 7,(hl)
jr opendoorok
opendoor_h_dec
push hl
res 7,(hl)
dec h
res 7,(hl)
jr opendoorok
opendoor_h_inc
push hl
res 7,(hl)
inc h
res 7,(hl)
opendoorok
;ничего не делать, если hl==(oldopendooraddr2)
ld de,(oldopendooraddr2)
or a
sbc hl,de
add hl,de
pop de
jr z,noopendoor
call closecurrentdoor ;keeps hl,de
ld (oldopendooraddr2),hl
ld (oldopendooraddr),de
xor a
ld (doortimer),a
inc a
ld (doortimermode),a
ld a,5
call sfxplay
noopendoor
pop af
;a=%ofADdurl
bit 6,a
jp nz,nofire
push af
if sprites
call RAYPREPXY
LD A,SCRWIDPIX/2;0x40;TODO связано с scrwid/2
ld l,a
LD (cura),A
CALL RAYCAST
;C=dist(scale#)
;B=texx
ld a,c
ld (fire_walldist),a
if 1==0
call getuser_scr_high_cur
SETPG8000
ld a,(fire_walldist)
ld hl,0x8000
ld bc,40
dup 8
ld (hl),7
rla
rr (hl)
add hl,bc
edup
endif
call SCANMONS
;в cursprites лежат данные о видимых спрайтах (от задних к передним)
;ID 8 (0=end)
;dist 16
;xscr 8
;monster index
ld hl,cursprites
fire_scan0
ld a,(hl)
or a
jp z,fire_scan0q
inc l
ld c,(hl)
inc l
ld b,(hl) ;bc=dist
ld d,b
ld e,c
inc l
dup 3;4
srl d
rr e
edup
ld a,d
or a
jr z,$+4
ld e,255
or e
jr nz,$+3
inc e
ld d,t1x/256
ld a,(de) ;width*k (for typical sprite width)
ld e,a
ld a,(hl) ;xscr (центр = 0x40)
sub e
jr nc,$+3
xor a ;a=sprite left margin
cp SCRWIDPIX/2;0x40;TODO связано с scrwid/2
jr nc,fire_miss
ld a,(hl) ;xscr
add a,e
jr nc,$+3
sbc a,a ;a=sprite right margin
cp SCRWIDPIX/2;0x40;TODO связано с scrwid/2
jr c,fire_miss
push hl
;не убивать, если стена впереди закрывает монстра (т.е. стена ближе)
;bc=dist
;приводим к 128..255
LD DE,#000
INC B
DEC B
LD A,C
jr Z,fire_MOTOLOGRLQ
DUP 5;6
INC D
SRL B
RRA
jr Z,fire_MOTOLOGRLE
EDUP
fire_MOTOLOGRLQ ;
fire_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
ex de,hl
ADD HL,BC
LD a,(HL) ;scale#
pop hl
fire_walldist=$+1
cp 0
jr c,fire_miss
push hl
;найти этого монстра в таблице монстров
inc l
ld l,(hl) ;monster index
ld h,0
add hl,hl
add hl,hl
add hl,hl ;*8
ld bc,MONSTRS+1 ;Xx,Yy,TYPEphase,TIMEenergy
add hl,bc
ld (hl),0xc0 ;impossible X
ld a,0;5
call sfxplay
pop hl
fire_miss
if CURSPRITES_RECSZ == 5
inc l
endif
inc l
jp fire_scan0
fire_scan0q
endif
pop af
nofire
push af
IMavision=$+1
LD HL,32*256
IMdavision=$+1
LD DE,100
AND %10110011
CP 0
LD ($-1),A
jr Z,$+4
LD E,50 ;key just pressed/released
IF kempston&autostrafe
BIT 7,A
jr NZ,nAUTOROTATE
BIT 4,A
jr NZ,$+3
ADD HL,DE
BIT 5,A
jr NZ,$+4
SBC HL,DE
nAUTOROTATE
ENDIF
IF doublerotate
RRA
jr C,$+4
ADD HL,DE
ADD HL,DE
RRA
jr C,$+6
SBC HL,DE
SBC HL,DE
ELSE
RRA
jr C,$+3
ADD HL,DE
RRA
jr C,$+4
SBC HL,DE
ENDIF
LD A,E
ADD A,12;10
jr C,$+3
LD E,A ;key held: increase rotspd
LD (IMdavision),DE
IF mouse
LD BC,#FBDF
IN A,(C)
mouseoldx=$+1
LD C,0
LD ($-1),A
mouseon=$
IF demoplay
XOR A
ELSE
SUB C
ENDIF
NEG
LD E,A
RLA
SBC A,A
LD D,A
ex de,hl
DUP 6
ADD HL,HL
EDUP
ADD HL,DE
ENDIF
LD (IMavision),HL
;делим вектор на коэфф замедления
IMcurDX=$+1
LD HL,0
LD B,H
ld A,L
SRA B
RRA
IF doublespeed
SRA B
RRA
ENDIF
LD C,A
CP B
jr NZ,$+3
LD C,L
SBC HL,BC
LD B,H
ld C,L
CSLOWXQ
IMcurDY=$+1
LD HL,0
LD D,H
ld A,L
SRA D
RRA
IF doublespeed
SRA D
RRA
ENDIF
LD E,A
CP D
jr NZ,$+3
LD E,L
SBC HL,DE
LD D,H
ld E,L
CSLOWYQ
POP AF ;%00ADSWPO
RRCA
RRCA
AND 15
LD HL,tkeyangle
ADD A,L
LD L,A
IF (tkeyangle^tkeyangleend)&256
ADC A,H
SUB L
LD H,A
ENDIF
LD A,(HL)
;прибавляем вектор направления
;sin и cos (IMavision+32*N), где N=0..7 в зав. от клавиш
;0=forth
;64=left
CP -1
JP Z,CTRLnspeed
LD HL,IMavision+1
ADD A,(HL)
LD L,A
LD H,tcos/256 ;-pi/4..+pi/4
LD A,(HL)
ADD A,C
LD C,A
BIT 7,(HL)
jr NZ,$+3
INC B
jr C,$+3
DEC B
LD A,64
SUB L
LD L,A
LD A,(HL)
ADD A,E
LD E,A
BIT 7,(HL)
jr NZ,$+3
INC D
jr C,$+3
DEC D
CTRLnspeed
LD (IMcurDX),BC
LD (IMcurDY),DE
DUP 2
SRA D
RR E
SRA B
RR C
EDUP
LD HL,(IMcurXx)
ADD HL,BC
BIT 7,B
PUSH DE,HL
LD HL,(IMcurXx)
LD DE,256-mindist ;dx>0
jr Z,$+4
LD E,mindist ;dx<0
ADD HL,DE
LD A,H
LD HL,(IMcurYy)
LD E,mindist
SBC HL,DE
LD B,H
ADD HL,DE
ADD HL,DE
LD L,A
SET mapdifbit,L
LD A,(HL)
LD H,B
OR (HL)
POP HL,DE
RLA ;проходимо?
jr C,CTRLnX
LD (IMcurXx),HL
;jr CTRLnXq
CTRLnX
;непроходимо
;CTRLnXq
LD HL,(IMcurYy)
ADD HL,DE
BIT 7,D
PUSH HL
LD HL,(IMcurYy)
LD DE,256-mindist ;dx>0
jr Z,$+4
LD E,mindist ;dx<0
ADD HL,DE
LD A,H
LD HL,(IMcurXx)
LD E,mindist
SBC HL,DE
LD B,H
ADD HL,DE
ADD HL,DE
LD L,H
LD H,A
LD A,(HL)
LD L,B
OR (HL)
POP HL
RLA ;проходимо?
RET C
LD (IMcurYy),HL ;H!=0
RET
closecurrentdoor
;keeps hl,de
ld a,128+ID_DOOR;(hl)
oldopendooraddr=$+1
ld (killablebyte),a
oldopendooraddr2=$+1
ld (killablebyte),a
ld bc,killablebyte
ld (oldopendooraddr),bc
ld (oldopendooraddr2),bc
ret
killablebyte
db 0