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
 
       
 
        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
 
        EXD 
 
        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
 
       
 
       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
 
        EXD 
 
        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