Login

Subversion Repositories NedoOS

Rev

Rev 775 | Rev 1903 | Go to most recent revision | 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
;режимы двери:
;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
       SETPG32KLOW
       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