Login

Subversion Repositories NedoOS

Rev

Rev 2047 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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
        LD HL,(IMcurXx+1)
        LD a,(IMcurYy+1)
        ld h,a
        ;корректировать адрес стены в зависимости от направления
        ld a,(IMavision+1)
        sub 32
        cp 64
        jr nc,$+3
         inc h      
        bit 6,a
        jr z,$+4
         SET mapdifbit,L        
        cp -64
        jr c,$+3
         inc l
        ld (touchedwalladdr),hl

        ld a,0xf7
        in a,(0xfe)
        and 0x1f
oldeditkeys=$+1
        ld c,0
        ld (oldeditkeys),a
        cp c
        jr z,noedit
        ld c,a
        bit 0,c
        jr nz,noedit1
        ld a,(hl)
        or a
        ld (hl),0xc0
        jr z,edit1q
         set 6,a
        add a,2
        cp 0xc0+(2*12)
        jr c,$+4
        ld a,0xc0
         xor (hl)
         and 0x3f
         xor (hl)
        ld (hl),a
edit1q
noedit1
        bit 1,c
        jr nz,noedit2
        ld a,(hl)
        or a
        ld (hl),0xc0
        jr z,edit2q
         set 6,a
        sub 2
        cp 0xc0
        jr nc,$+4
        ld a,0xc0+(2*11)
         xor (hl)
         and 0x3f
         xor (hl)
        ld (hl),a
edit2q
noedit2
        bit 2,c
        jr nz,noedit3
        ld a,(hl)
        xor 1 ;mirror
        ld (hl),a
noedit3
        bit 3,c
        jr nz,noedit4
        ld (hl),0
noedit4
        bit 4,c
        jr nz,noedit5
        ld a,(hl)
        or a
        jr z,noedit5
        xor 64 ;page
        ld (hl),a
noedit5
noedit

;режимы двери:
;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
touchedwalladdr=$+1
        ld hl,0
        ld c,ID_DOOR*2
        ld a,(hl)
        add a,a
        cp c
        jr nz,noopendoor
        bit mapdifbit,l
        jr z,opendoor_h
opendoor_l
        push hl
        res 7,(hl)
        inc l
        ld a,(hl)
        add a,a
        cp c
        jr z,opendoorok
        dec l
        dec l
        ;ld a,(hl)
        ;add a,a
        ;cp c
        jr opendoorok
opendoor_h
        push hl
        res 7,(hl)
        inc h
        ld a,(hl)
        add a,a
        cp c
        jr z,opendoorok
        dec h
        dec h
        ;ld a,(hl)
        ;add a,a
        ;cp c
opendoorok
        res 7,(hl)
;ничего не делать, если 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 ;open sfx
        call sfxplay
noopendoor

;сколько фреймов прошло с прошлого fire? считать независимо от fire!
        ld a,(firedelaycounter)
        dec a
        ;jp m,fire_timeok
        ;ld (firedelaycounter),a
        jp p,firedelaycounter_popnofire
;fire_timeok

       pop af
;a=%ofADdurl
       bit 6,a
       jp nz,nofire
       push af
     
        ld a,(bullets)
        or a
        jp z,popnofire
        dec a
        ld (bullets),a

        push hl
        ld a,1 ;shot sfx
        call sfxplay
        pop hl

       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 4;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
        jp 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+5 ;Xx,Yy,TYPEphase_dir,TIMEenergy
        add hl,bc ;TYPEphase
        ld a,(hl)
        cp 5*8;4*8
        jr nc,fire_skip ;not a monster/ammo
        and 7
        cp 6
        jr z,fire_skip ;dead monster
        dec l
        ld (hl),0 ;dir = no move
        inc l
       ld a,(hl)
       cp 4*8 ;ammo?
        ld (hl),3*8+4 ;wounded, go
       jr c,$+4 ;not ammo
       ld (hl),4*8+4 ;ammo wounded
        inc l
        ld a,(hl) ;energy
        sub 20
        ld (hl),a ;energy
        jr c,fire_kill
        inc l
        ld (hl),TIME_WOUNDED ;time
        ld a,2 ;wound sfx
        jr fire_killq
fire_kill
        dec l
        ld (hl),3*8+6 ;dead
        ;ld a,l
        ;and 0xf8
        ;ld l,a
        ;inc l ;X
        ;ld (hl),0xc0 ;impossible X
        ld a,0 ;kill sfx
fire_killq
        call sfxplay
fire_skip
        pop hl
fire_miss
       if CURSPRITES_RECSZ == 5
       inc l
       endif
        inc l
        jp fire_scan0
fire_scan0q

       endif
        ld a,10
firedelaycounter_popnofire
        ld (firedelaycounter),a
popnofire
       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 b,e
        LD HL,(IMcurXx)
        LD de,(IMcurYy)
;hl=x
;de=y
;c=dx/4
;b=dy/4
        call moveandcollideX
        ex de,hl
        call moveandcollideY
;hl=y
;de=x
        LD (IMcurYy),HL
        LD (IMcurXx),de

        call collideobjects
        call movemonsters
        ret

collideobjects
;collide with objects
;все объекты - в центре своей клетки
        LD HL,MONSTRS+1 ;1+начало табл.монстров/предметов
        ld hx,-1 ;monster index
       jp logCOLLIDE0 ;цикл скан-я видимых монстров/предметов
logCOLLIDENx
        LD A,L
        ADD A,8
        LD L,A
        JR C,logCOLLIDExIH
logCOLLIDE0
       inc hx ;monster index
        LD A,(HL) ;X
        INC A
       RET Z
        ld a,(IMcurXx+1)
        cp (hl)
        jr nz,logCOLLIDENx
        inc l
        inc l
        ld a,(IMcurYy+1)
        cp (hl)
        jr z,logCOLLIDEY
        LD A,L
        ADD A,6
        LD L,A
        JP NC,logCOLLIDE0
logCOLLIDExIH
        INC H
        JP logCOLLIDE0
logCOLLIDEY
        inc l
        ;ld a,(hl) ;dir
        inc l
        ld a,(hl) ;TYPE*8+phase
        cp 4*8
        jr c,logCOLLIDEnobj
        and 0xf8 ;иначе фаза шевелится 0..1
        push hl
        ;ld a,l
        ;and 0xf8
        ;ld l,a
        ;inc l ;X
        res 1,l
        res 2,l
        ld (hl),0xc0 ;impossible X
        cp 4*8
        jr nz,logCOLLIDEnammo
        ld hl,bullets
        ld bc,40*256+50 ;ADDmax
        call addmax
logCOLLIDEnammo
        cp 5*8
        jr nz,logCOLLIDEnhealth
        ld hl,health
        ld bc,40*256+100 ;ADDmax
        call addmax
logCOLLIDEnhealth
       
        ld a,3 ;get obj
        call sfxplay
        pop hl
logCOLLIDEnobj
        inc l
        ;ld a,(hl) ;energy
        inc l
        ;ld a,(hl) ;time
        inc hl
       INC L ;skip x
        jp logCOLLIDE0

movemonsters
;move monsters
        LD A,(IMcurXx+1);d;(curX)
        SUB viewrange
        LD (logscmonX),A
        LD A,(IMcurYy+1);h;(curY)
        SUB viewrange
        LD (logscmonY),A
        LD HL,MONSTRS+1 ;1+начало табл.монстров/предметов
        ld hx,-1 ;monster index
       jp logSCMONS0 ;цикл скан-я видимых монстров/предметов
logSCMONNx
        LD A,L
        ADD A,8
        LD L,A
        JR C,logSCMxIH
logSCMONS0
       inc hx ;monster index
        LD A,(HL) ;X
        INC A
       RET Z
logscmonX=$+1
        SUB 0
        CP viewrange*2+1
        JP NC,logSCMONNx
        INC L
        inc L
        LD A,(HL)
logscmonY=$+1
        SUB 0
        CP viewrange*2+1
        JR C,logSCMONY
        LD A,L
        ADD A,6
        LD L,A
        JP NC,logSCMONS0
logSCMxIH
        INC H
        JP logSCMONS0
logSCMONY
        DEC L
        dec L
        dec L
       push hl
        LD C,(HL)
        INC L
        LD B,(HL) ;Xx
        INC L
        LD E,(HL)
        INC L
        LD D,(HL) ;Yy
        INC L
        ld a,(hl) ;dir
        or a
        jr z,logSCMONS_nomove
       push af ;dir
        push bc ;x
        ld l,a
        LD H,tcos/256 ;-pi/4..+pi/4
        LD c,(HL)
        LD A,64
        SUB L
        LD L,A
        LD b,(HL)
        pop hl ;x
        dup 3
        sra b
        sra c
        edup
;hl=x
;de=y
;c=dx/4
;b=dy/4
        call moveandcollideX
        ex de,hl
        call nc,moveandcollideY
;hl=y
;de=x
       pop bc ;b=dir
       ld a,b
       jr nc,movemons_nochagedir
       ld a,r
       add a,a
       inc a
movemons_nochagedir
        ld b,d
        ld c,e ;x
        ex de,hl ;y
logSCMONS_nomove
       pop hl
        ld (hl),c
        inc l
        ld (hl),b ;Xx
        inc l
        ld (hl),e
        inc l
        ld (hl),d ;Yy
        inc l
        ld (hl),a ;dir
        inc l ;skip dir

      if 1
      ld a,0xfe
      in a,(0xfe)
      rra
      jr c,logSCMONS_noattack
;если (1..3)*8+(0..1) и близко, то wantattack:
        ld a,(hl) ;TYPE*8+phase        
        and (30*8)+6
        cp 0*8+0 ;стоит спиной
        ld e,MONSTERBACKviewrange
        jr z,logSCMONS_startattack
        cp 2*8+0 ;стоит лицом или идёт
        ld e,MONSTERviewrange
        jr nz,logSCMONS_noattack
logSCMONS_startattack
        ld a,(IMcurYy+1)
        sub d ;Y
        jr nc,$+4
        neg
        cp e;MONSTERviewrange
        jr nc,logSCMONS_noattack
        ld a,(IMcurXx+1)
        sub b ;X
        jr nc,$+4
        neg
        cp e;MONSTERviewrange
        jr nc,logSCMONS_noattack
        ld (hl),3*8+2 ;wantattack
        inc l
        inc l
        ld (hl),TIME_WANTATTACK
        dec l
        dec l
        push hl
        ld a,4 ;shout
        call sfxplay
        pop hl
logSCMONS_noattack
      endif
        ld c,(hl) ;TYPE*8+phase
        INC L ;skip TYPE*8+phase
        inc L ;skip energy
        dec (hl) ;time
        jr nz,logSCMONS_notime
        ld (hl),TIME_STEP ;time
        dec l
        dec l ;hl points to TYPE*8+phase
        ld a,c
        and 7
        jr z,logSCMONS_step
        dec a
        jr z,logSCMONS_step
        dec a
        jr z,logSCMONS_wantattack
        dec a ;attack
        jr z,logSCMONS_attack
        dec a
        jr z,logSCMONS_wounded
        jr logSCMONS_nosetphase
logSCMONS_wantattack
        inc l
        inc l
        ld (hl),TIME_ATTACK
        dec l
        dec l
        dec l
        ld (hl),0 ;dir (no move)
        inc l
        ld a,3*8+3 ;moving attack
        jr logSCMONS_setphase
logSCMONS_attack
;todo shot

;дальше продолжаем движение
logSCMONS_wounded
       ld a,(hl)
       cp 4*8 ;ammo?
       ld a,4*8+5 ;explode2
       jr nc,logSCMONS_setphase;logSCMONS_wounded_ammo
        ld a,r
        add a,a ;dir
        dec l
        ld (hl),a ;dir
        inc l
        ld a,3*8+0 ;moving
        jr logSCMONS_setphase ;not ammo
;logSCMONS_wounded_ammo
;       ld a,4*8+6 ;explode2
;       jr logSCMONS_setphase
logSCMONS_step
        ld a,c
        xor 1
logSCMONS_setphase
        ld (hl),a
logSCMONS_nosetphase
        inc l
        inc l
logSCMONS_notime
        inc hl ;skip TIME
       INC L ;skip x
        jp logSCMONS0

moveandcollideX
;hl=x
;de=y
;c=dx/4
;b=dy/4
        ;ADD HL,BC
       PUSH HL
;|..............|
;.....<---*--->..      
        ;or a:sbc hl,bc;LD HL,(IMcurXx)
         ld a,l
         sub mindist ;dx<0
         ;dec h
        BIT 7,c;B
        jr nz,$+6
         ld a,l
         add a,mindist ;dx>0
         inc h
        jr nc,CTRLXpass ;проходимо (CY=0)
        ;LD A,H
        ;LD HL,(IMcurYy)
        ;LD L,A
        ld l,h
        ld h,d ;Y
        SET mapdifbit,L
        LD A,(HL)
        RLA ;проходимо?
CTRLXpass
       POP HL
        jr nc,CTRLnXq ;проходимо (CY=0)
CTRLnX
;непроходимо
        ;LD HL,(IMcurXx)
        BIT 7,c;B
        LD l,256-mindist ;dx>0
        ret z ;C
        LD l,mindist ;dx<0
        ret ;C
CTRLnXq
        ;add hl,bc
        ld a,c
        add a,l
        ld l,a
        adc a,h
        sub l
        ld h,a
         or a ;NC
        bit 7,c
        ret z ;NC
        dec h
        ret ;NC
moveandcollideY
;hl=y
;b=dy/4
        ;ADD HL,DE
       PUSH HL
        ;or a:sbc hl,de;LD HL,(IMcurYy)
         ld a,l
         sub mindist ;dx<0
         ;dec h
        BIT 7,b;D
        jr nz,$+6
         ld a,l
         add a,mindist ;dx>0
         inc h
        jr nc,CTRLYpass ;проходимо (CY=0)
        ;LD A,H
        ;LD HL,(IMcurXx)
        ;LD L,H
        ;LD H,A
        ld l,d ;X
        LD A,(HL)
        RLA ;проходимо?
CTRLYpass
       POP HL
       jr nc,CTRLnYq ;проходимо (CY=0)
;непроходимо
        ;LD HL,(IMcurYy)
        BIT 7,b;d
        LD l,256-mindist ;dy>0
        ret z ;C
        LD l,mindist ;dy<0
        ret ;C
CTRLnYq
        ;add hl,de
        ld a,b
        add a,l
        ld l,a
        adc a,h
        sub l
        ld h,a
         or a ;NC
        bit 7,b
        ret z ;NC
        dec h
        RET ;NC

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

addmax
;add b, max c
        ld a,(hl)
        cp c;100
        ret nc
        add a,b;40
        ld (hl),a
        cp c;100
        ret c
        ld (hl),c;100
        ret