?login_element?

Subversion Repositories NedoOS

Rev

Rev 2089 | Blame | Compare with Previous | Last modification | View Log | Download

  1. tkeyangle=$-5
  2.               ;LRDU
  3.        ;DB -1 ;0000
  4.        ;DB 128;0001
  5.        ;DB 0  ;0010
  6.        ;DB -1 ;0011
  7.        ;DB 64 ;0100
  8.         DB 96 ;0101
  9.         DB 32 ;0110
  10.         DB 64 ;0111
  11.         DB 192;1000
  12.         DB 160;1001
  13.         DB 224;1010
  14.         DB 192;1011
  15.         DB -1 ;1100
  16.         DB 128;1101
  17.         DB 0  ;1110
  18.         DB -1 ;1111
  19. tkeyangleend
  20.  
  21. inctime
  22.         ld hl,leveltime
  23.         inc (hl) ;frames
  24.         ld a,(hl)
  25.         sub 25
  26.         ret nz
  27.         ld (hl),a
  28.         call invalidatehud
  29.         inc hl
  30.         inc (hl) ;sec
  31.         sub 60
  32.         ret nz
  33.         ld (hl),a
  34.         inc hl
  35.         inc (hl) ;min
  36.         ret
  37.  
  38. ;в 0x4000 включена pgmap
  39. my_logic
  40.         call inctime
  41.  
  42.         LD HL,(IMcurXx+1)
  43.         LD a,(IMcurYy+1)
  44.         ld h,a
  45.         ;корректировать адрес стены в зависимости от направления
  46.         ld a,(IMavision+1)
  47.         sub 32
  48.         cp 64
  49.         jr nc,$+3
  50.          inc h
  51.         bit 6,a
  52.         jr z,$+4
  53.          SET mapdifbit,L
  54.         cp -64
  55.         jr c,$+3
  56.          inc l
  57.         ld (touchedwalladdr),hl
  58.  
  59.        if EDITOR
  60.         ld a,0xf7
  61.         in a,(0xfe)
  62.         and 0x1f
  63. oldeditkeys=$+1
  64.         ld c,0
  65.         ld (oldeditkeys),a
  66.         cp c
  67.         jr z,noedit
  68.         ld c,a
  69.         bit 0,c
  70.         jr nz,noedit1
  71.         ld a,(hl)
  72.         or a
  73.         ld (hl),0xc0
  74.         jr z,edit1q
  75.          set 6,a
  76.         add a,2
  77.         cp 0xc0+(2*12)
  78.         jr c,$+4
  79.         ld a,0xc0
  80.          xor (hl)
  81.          and 0x3f
  82.          xor (hl)
  83.         ld (hl),a
  84. edit1q
  85. noedit1
  86.         bit 1,c
  87.         jr nz,noedit2
  88.         ld a,(hl)
  89.         or a
  90.         ld (hl),0xc0
  91.         jr z,edit2q
  92.          set 6,a
  93.         sub 2
  94.         cp 0xc0
  95.         jr nc,$+4
  96.         ld a,0xc0+(2*11)
  97.          xor (hl)
  98.          and 0x3f
  99.          xor (hl)
  100.         ld (hl),a
  101. edit2q
  102. noedit2
  103.         bit 2,c
  104.         jr nz,noedit3
  105.         ld a,(hl)
  106.         xor 1 ;mirror
  107.         ld (hl),a
  108. noedit3
  109.         bit 3,c
  110.         jr nz,noedit4
  111.         ld (hl),0
  112. noedit4
  113.         bit 4,c
  114.         jr nz,noedit5
  115.         ld a,(hl)
  116.         or a
  117.         jr z,noedit5
  118.         xor 64 ;page
  119.         ld (hl),a
  120. noedit5
  121. noedit
  122.        endif
  123.  
  124.        if music
  125.         ld a,0xfb
  126.         in a,(0xfe)
  127.         and 0x1f
  128. oldtunekeys=$+1
  129.         ld c,0
  130.         ld (oldtunekeys),a
  131.         cp c
  132.         jr z,notune
  133.         bit 4,a
  134.         jr nz,notune
  135.        if !atm ;TODO atm
  136.         halt
  137.         call SETPGmusic_silent
  138.         ld hl,playmusicflag
  139.         ld a,(hl)
  140.         xor 0xcd^0x21
  141.         ld (hl),a
  142.         call 0xc008;MUTE
  143.        endif
  144. notune
  145.        endif
  146.  
  147. ;режимы двери:
  148. ;0: дверь закрыта
  149. ;1: дверь открывается, doortimer увеличивается
  150. ;2: дверь открыта, dooropentimer уменьшается
  151. ;3: дверь закрывается, doortimer уменьшается
  152. doortimer=$+1
  153.         ld a,0
  154. doortimermode=$+1
  155.         ld b,0
  156.         djnz control_door_noopening
  157.         add a,2*LOGICSPEED
  158.         ld (doortimer),a
  159.         jr nz,control_doorq
  160.         dec a ;-1
  161.         ld (doortimer),a ;stay opened
  162.         ld a,50 ;a=door open time
  163.         ld (dooropentimer),a
  164.         ld a,2
  165.         ld (doortimermode),a
  166.         jr control_doorq
  167. control_door_noopening
  168.         djnz control_door_noopened
  169. dooropentimer=$+1
  170.         ld a,0
  171.         dec a
  172.         ld (dooropentimer),a
  173.         jr nz,control_doorq
  174.         ;call closecurrentdoor ;keeps hl
  175.         ld a,-2*LOGICSPEED
  176.         ld (doortimer),a ;stay opened
  177.         ld a,3
  178.         ld (doortimermode),a
  179.         jr control_doorq
  180. control_door_noopened
  181.         djnz control_door_noclosing
  182. ;если игрок стоит в дверях, то не закрываем, а открываем
  183.         LD HL,(IMcurXx+1)
  184.         LD a,(IMcurYy+1)
  185.         ld h,a
  186.         ld a,ID_DOOR
  187.         cp (hl)
  188.         jr z,control_door_setopened
  189.         inc h
  190.         cp (hl)
  191.         jr z,control_door_setopened
  192.         dec h
  193.         set mapdifbit,l
  194.         cp (hl)
  195.         jr z,control_door_setopened
  196.         inc l
  197.         cp (hl)
  198.         jr z,control_door_setopened
  199.         ld a,(doortimer)
  200.         sub 2*LOGICSPEED
  201.         ld (doortimer),a
  202.         jr nz,control_doorq
  203.         ;xor a
  204.         ld (doortimermode),a
  205.         call closecurrentdoor ;keeps hl
  206.         jr control_doorq
  207. control_door_setopened
  208.         ld a,1
  209.         ld (doortimermode),a
  210. control_door_noclosing
  211. control_doorq
  212.  
  213.        IF kempston
  214.         LD C,#FF
  215.         IN A,(#1F)
  216.         LD B,A
  217.         AND #E0
  218.         jr NZ,nKEMPSTON
  219.         LD A,B
  220.         RRA
  221.         jr NC,$+4
  222.         RES 1,C
  223.         RRA
  224.         jr NC,$+4
  225.         RES 0,C
  226.         RRA
  227.         jr NC,$+4
  228.         RES 3,C
  229.         RRA
  230.         jr NC,$+4
  231.         RES 2,C
  232.         RRA
  233.         jr NC,$+4
  234.         RES 6,C
  235. nKEMPSTON
  236. ;C=%1f11durl
  237.        ENDIF
  238. ;autostrafe было тут (только для кемпстона)
  239.  
  240.         LD B,#FF
  241.         ld a,#fe
  242.         in a,(#fe)
  243.         rra
  244.         rl b ;cs (open)
  245.         LD A,#7F
  246.         IN A,(#FE)
  247.         RRA
  248.         RL B ;space (fire)
  249.         LD A,#FD
  250.         IN A,(#FE)
  251.         RRA
  252.         RL B ;A
  253.         RRA
  254.         RRA
  255.         RL B ;D
  256.         RLA
  257.         RL B ;S (down)
  258.         LD A,#FB
  259.         IN A,(#FE)
  260.         RRA
  261.         RRA
  262.         RL B ;W (up)
  263.         LD A,#DF
  264.         IN A,(#FE)
  265.         RRA
  266.         RL B ;P (right)
  267.         RRA
  268.         LD A,B
  269.         RLA ;O (left)
  270.        IF kempston
  271.         AND C
  272.        ENDIF
  273.  
  274. ;A=%ofADdurl
  275.  
  276.        IF autostrafe
  277.         BIT 3,a ;down
  278.         jr NZ,nAUTOSTRAFE
  279.         ;LD A,C
  280.         BIT 1,A
  281.         jr NZ,$+6
  282.         AND %11101111 ;strafe
  283.         ;AND %01101111 ;strafe + rotate flag
  284.         OR %00001011 ;block down & rotate
  285.         BIT 0,A
  286.         jr NZ,$+6
  287.         AND %11011111 ;strafe
  288.         ;AND %01011111 ;strafe + rotate flag
  289.         OR %00001011 ;block down & rotate
  290.         ;LD C,A
  291. nAUTOSTRAFE
  292.  
  293.         ld hl,downtimer_time
  294. downtimer_oldkey=$+1
  295.         ld b,0xff
  296.         ld (downtimer_oldkey),a
  297.         cp b
  298.         jr z,downtimer_nevent
  299.         cp %11110111 ;down only
  300.         jr nz,downtimer_ndown
  301.         ld b,(hl) ;время от прошлого нажатия
  302.         ld (hl),16/LOGICSPEED
  303.         dec b ;если счётчик истёк, то не даблклик
  304.         jr z,downtimer_ndown ;счётчик истёк
  305.         ld a,%01111111 ;grenade only
  306. downtimer_ndown
  307. downtimer_nevent
  308.         dec (hl)
  309.         jr nz,$+3
  310.         inc (hl)
  311.  
  312.        ENDIF
  313.  
  314.        IF demoplay
  315. demoplayoff=$
  316.         OR A
  317.         jr C,demoplayQ
  318.        BIT 4,A ;"D"
  319.        jr NZ,demoplaynOFF
  320.         LD A,#37 ;scf
  321.         LD (demoplayoff),A
  322.         LD A,#91 ;sub c
  323.         LD (mouseon),A
  324.         LD A,#FF
  325. demoplaynOFF
  326. democursor=$+1
  327.         LD HL,demobegin
  328. demokey=$+1
  329.         LD A,%00111111
  330. demokeytime=$+1
  331.         LD C,1
  332.         DEC C
  333.         jr NZ,CnNEWKEY
  334.         LD A,(HL)
  335.         LD (demokey),A
  336.         INC HL
  337.         LD C,(HL)
  338.         INC HL
  339.         LD (democursor),HL
  340. CnNEWKEY
  341.         LD HL,demokeytime
  342.         LD (HL),C
  343. demoplayQ
  344.        ELSE
  345.        IF demorec
  346. democursor=$+1
  347.         LD HL,demobegin
  348. demokeytime=$+1
  349.         LD C,0
  350.         INC C
  351.         jr Z,CNEWKEY
  352.         CP (HL)
  353.         jr Z,CnNEWKEY
  354. CNEWKEY
  355.         INC HL
  356.         LD (HL),C
  357.         LD C,0
  358.         INC HL
  359. CnNEWKEY
  360.         LD (HL),A
  361.         LD (democursor),HL
  362.         LD HL,demokeytime
  363.         LD (HL),C
  364.        ENDIF
  365.        ENDIF
  366.  
  367. ;a=%ofADdurl
  368.        PUSH AF
  369.         ;bit 7,a
  370.         ;jr nz,noopendoor
  371.         ;call closecurrentdoor ;keeps hl
  372.  
  373.         ;LD HL,(IMcurXx+1)
  374.         ;LD a,(IMcurYy+1)
  375.         ;ld h,a
  376. touchedwalladdr=$+1
  377.         ld hl,0
  378.         ld c,ID_DOOR*2
  379.         ld a,(hl)
  380.         add a,a
  381.         cp c
  382.         jr nz,noopendoor
  383.         bit mapdifbit,l
  384.         jr z,opendoor_h
  385. opendoor_l
  386.         push hl
  387.         res 7,(hl)
  388.         inc l
  389.         ld a,(hl)
  390.         add a,a
  391.         cp c
  392.         jr z,opendoorok
  393.         dec l
  394.         dec l
  395.         ;ld a,(hl)
  396.         ;add a,a
  397.         ;cp c
  398.         jr opendoorok
  399. opendoor_h
  400.         push hl
  401.         res 7,(hl)
  402.         inc h
  403.         ld a,(hl)
  404.         add a,a
  405.         cp c
  406.         jr z,opendoorok
  407.         dec h
  408.         dec h
  409.         ;ld a,(hl)
  410.         ;add a,a
  411.         ;cp c
  412. opendoorok
  413.         res 7,(hl)
  414. ;ничего не делать, если hl==(oldopendooraddr2)
  415.        ld de,(oldopendooraddr2)
  416.        or a
  417.        sbc hl,de
  418.        add hl,de
  419.         pop de
  420.        jr z,noopendoor
  421.         call closecurrentdoor ;keeps hl,de
  422.         ld (oldopendooraddr2),hl
  423.         ld (oldopendooraddr),de
  424.         xor a
  425.         ld (doortimer),a
  426.         inc a
  427.         ld (doortimermode),a
  428.         ld a,5 ;open sfx
  429.         call sfxplay
  430. noopendoor
  431.        pop af
  432.  
  433. ;сколько фреймов прошло с прошлого fire? считать независимо от fire!
  434.         ld hl,firedelaycounter
  435.         dec (hl)
  436.         jp p,nofire
  437. ;a=%ofADdurl
  438.        bit 6,a
  439.        jp nz,nofire
  440.         ld hl,bullets
  441.         ld b,(hl)
  442.         inc b
  443.         dec b
  444.         jp z,nofire
  445.         dec (hl)
  446.  
  447.        push af
  448.  
  449.         ;push hl
  450.         ld a,1 ;shot sfx
  451.         call sfxplay
  452.         ;pop hl
  453.  
  454.        if sprites
  455.  
  456.         call RAYPREPXY
  457.         LD l,SCRWIDPIX/2;0x40;TODO связано с scrwid/2
  458.         ;ld a,l
  459.         ;LD (cura),A
  460.         CALL RAYCASTl
  461. ;C=dist(scale#)
  462. ;B=texx
  463.         ld a,c
  464.         ld (fire_walldist),a
  465.        if 1==0
  466.        call getuser_scr_high_cur
  467.        SETPG8000
  468.        ld a,(fire_walldist)
  469.        ld hl,0x8000
  470.        ld bc,40
  471.        dup 8
  472.        ld (hl),7
  473.        rla
  474.        rr (hl)
  475.        add hl,bc
  476.        edup
  477.        endif
  478.  
  479.         call SCANMONS
  480. ;в cursprites лежат данные о видимых спрайтах (от задних к передним)
  481. ;ID 8 (0=end)
  482. ;dist 16
  483. ;xscr 8
  484. ;monster index
  485.         ld hl,cursprites
  486. fire_scan0
  487.         ld a,(hl)
  488.         or a
  489.         jp z,fire_scan0q
  490.         inc l
  491.         ld c,(hl)
  492.         inc l
  493.         ld b,(hl) ;bc=dist
  494.         ld d,b
  495.         ld e,c
  496.         inc l
  497.         dup 4;3;4
  498.         srl d
  499.         rr e
  500.         edup
  501.         ld a,d
  502.         or a
  503.         jr z,$+4
  504.          ld e,255
  505.         or e
  506.         jr nz,$+3
  507.          inc e
  508.         ld d,t1x/256
  509.         ld a,(de) ;width*k (for typical sprite width)
  510.         ld e,a
  511.         ld a,(hl) ;xscr (центр = 0x40)
  512.         sub e
  513.         jr nc,$+3
  514.          xor a ;a=sprite left margin
  515.         cp SCRWIDPIX/2;0x40;TODO связано с scrwid/2
  516.         jp nc,fire_miss
  517.         ld a,(hl) ;xscr
  518.         add a,e
  519.         jr nc,$+3
  520.          sbc a,a ;a=sprite right margin
  521.         cp SCRWIDPIX/2;0x40;TODO связано с scrwid/2
  522.         jr c,fire_miss
  523.         push hl
  524. ;не убивать, если стена впереди закрывает монстра (т.е. стена ближе)
  525. ;bc=dist
  526. ;приводим к 128..255
  527.         LD DE,#000
  528.         INC B
  529.         DEC B
  530.         LD A,C
  531.         jr Z,fire_MOTOLOGRLQ
  532.        ;DUP 5;6
  533. MOTOLOGRLloop
  534.         INC D
  535.         SRL B
  536.         RRA
  537.         jr nz,MOTOLOGRLloop
  538.         ;jr Z,fire_MOTOLOGRLE
  539.        ;EDUP
  540. fire_MOTOLOGRLQ ;
  541. fire_MOTOLOGRLE ;
  542.         LD C,A ;128..255 ;D=0..5
  543.         LD B,tlogd/256
  544.         LD A,(BC) ;log(dist) = 128..255 for arg>=128
  545.        if atm==0
  546.        SUB 16;64                 ;0..127 for arg=64..127 ;???
  547.        endif
  548.         LD C,A                ;0 for arg<64
  549.         LD B,tlogd2sca/256
  550.          SRA D
  551.          RR E ;DE=+0,+#80,..+#300
  552.         ex de,hl
  553.         ADD HL,BC
  554.         LD a,(HL) ;scale#
  555.         pop hl
  556. fire_walldist=$+1
  557.         cp 0
  558.         jr c,fire_miss
  559.         push hl
  560.  
  561. ;найти этого монстра в таблице монстров
  562.         inc l
  563.         ld l,(hl) ;monster index
  564.         ld h,0
  565.         add hl,hl
  566.         add hl,hl
  567.         add hl,hl ;*8
  568.         ld bc,MONSTRS+5 ;Xx,Yy,TYPEphase_dir,TIMEenergy
  569.         add hl,bc ;TYPEphase
  570.  
  571.         ld b,30;20 ;energy loss
  572.         call fire_wound
  573.  
  574.         pop hl
  575. fire_miss
  576.        if CURSPRITES_RECSZ == 5
  577.        inc l
  578.        endif
  579.         inc l
  580.         jp fire_scan0
  581. fire_scan0q
  582.  
  583.        endif
  584.  
  585.        pop af
  586.  
  587.         ld hl,firedelaycounter
  588.         ld (hl),10
  589. nofire
  590.  
  591. ;GRENADE
  592. ;сколько фреймов прошло с прошлого fire? считать независимо от fire!
  593.         ld hl,grenadedelaycounter
  594.         dec (hl)
  595.         jp p,nogrenade
  596. ;a=%ofADdurl
  597.        bit 7,a
  598.        jp nz,nogrenade
  599.         ld hl,grenades
  600.         inc (hl)
  601.         dec (hl)
  602.         jp z,nogrenade
  603.         dec (hl)
  604.        push af
  605.         ;ld hl,grenades
  606.         ;ld b,1
  607.         ;call decvariable
  608.         ;jr c,nogrenade ;error
  609.         call findfreemonster
  610.         jr c,popnogrenade ;error
  611.  
  612.         LD de,(IMcurXx)
  613.         ld (hl),e
  614.         inc l
  615.         ld (hl),d
  616.         inc l
  617.         LD de,(IMcurYy)
  618.         ld (hl),e
  619.         inc l
  620.         ld (hl),d
  621.         inc l
  622.         ld a,(IMavision+1)
  623.         ld (hl),a ;dir
  624.         inc l
  625.         ld (hl),7*8+0 ;grenade
  626.         inc l
  627.         ld (hl),10 ;energy (определяет время горения)
  628.         ;inc l
  629.         ;ld (hl),0 ;TIME
  630. popnogrenade
  631.        pop af
  632.  
  633.         ld hl,grenadedelaycounter
  634.         ld (hl),20
  635. nogrenade
  636.  
  637.        push af
  638.  
  639. IMavision=$+1
  640.         LD HL,32*256
  641. IMdavision=$+1
  642.         LD DE,100
  643.         AND %10110011
  644.         CP 0
  645.         LD ($-1),A
  646.         jr Z,$+4
  647.         LD E,50 ;key just pressed/released
  648.        IF 0;autostrafe;&kempston
  649.         BIT 7,A
  650.         jr NZ,nAUTOROTATE
  651.         BIT 4,A
  652.         jr NZ,AUTOROTATEnr
  653.         dup (1+doublerotate)*LOGICSPEED
  654.         ADD HL,DE
  655.         edup
  656. AUTOROTATEnr
  657.         BIT 5,A
  658.         jr NZ,AUTOROTATEnl
  659.         dup (1+doublerotate)*LOGICSPEED
  660.         SBC HL,DE
  661.         edup
  662. AUTOROTATEnl
  663. nAUTOROTATE
  664.        ENDIF
  665.         RRA
  666.         jr C,rotatenr
  667.         dup (1+doublerotate)*LOGICSPEED
  668.         ADD HL,DE
  669.         edup
  670. rotatenr
  671.         RRA
  672.         jr C,rotatenl
  673.         dup (1+doublerotate)*LOGICSPEED
  674.         SBC HL,DE
  675.         edup
  676. rotatenl
  677.  
  678.         LD A,E
  679.         ADD A,20;12;10
  680.         jr C,$+3
  681.          LD E,A ;key held: increase rotspd
  682.         LD (IMdavision),DE
  683.        IF mouse
  684.         LD BC,#FBDF
  685.         IN A,(C)
  686. mouseoldx=$+1
  687.         LD C,0
  688.         LD ($-1),A
  689. mouseon=$
  690.        IF demoplay
  691.         XOR A
  692.        ELSE
  693.         SUB C
  694.        ENDIF
  695.         NEG
  696.         LD E,A
  697.         RLA
  698.         SBC A,A
  699.         LD D,A
  700.         ex de,hl
  701.         DUP 6
  702.         ADD HL,HL
  703.         EDUP
  704.         ADD HL,DE
  705.        ENDIF
  706.         LD (IMavision),HL
  707.  
  708. ;делим вектор на коэфф замедления
  709. IMcurDX=$+1
  710.         LD HL,0
  711.         LD B,H
  712.         ld A,L
  713.         SRA B
  714.         RRA
  715.        IF doublespeed
  716.         SRA B
  717.         RRA
  718.        ENDIF
  719.         LD C,A
  720.         CP B
  721.        jr NZ,$+3
  722.        LD C,L
  723.         SBC HL,BC
  724.         LD B,H
  725.         ld C,L
  726. CSLOWXQ
  727. IMcurDY=$+1
  728.         LD HL,0
  729.         LD D,H
  730.         ld A,L
  731.         SRA D
  732.         RRA
  733.        IF doublespeed
  734.         SRA D
  735.         RRA
  736.        ENDIF
  737.         LD E,A
  738.         CP D
  739.        jr NZ,$+3
  740.        LD E,L
  741.         SBC HL,DE
  742.         LD D,H
  743.         ld E,L
  744. CSLOWYQ
  745.        POP AF ;%00ADSWPO
  746.        RRCA
  747.        RRCA
  748.        AND 15
  749.         LD HL,tkeyangle
  750.         ADD A,L
  751.         LD L,A
  752.        IF (tkeyangle^tkeyangleend)&256
  753.         ADC A,H
  754.         SUB L
  755.         LD H,A
  756.        ENDIF
  757.         LD A,(HL)
  758. ;прибавляем вектор направления
  759. ;sin и cos (IMavision+32*N), где N=0..7 в зав. от клавиш
  760. ;0=forth
  761. ;64=left
  762.        CP -1
  763.        JP Z,CTRLnspeed
  764.         LD HL,IMavision+1
  765.         ADD A,(HL)
  766.         LD L,A
  767.      if 1
  768.        ld h,tsin/256
  769.        ld a,(hl)
  770.        ld e,a
  771.        rla
  772.        sbc a,a
  773.        ld d,a
  774.         LD A,64
  775.         SUB L
  776.         LD L,A
  777.        ld a,(hl)
  778.        ld c,a
  779.        rla
  780.        sbc a,a
  781.        ld b,a
  782.      else
  783.         LD H,tcos/256 ;-pi/4..+pi/4
  784.         LD A,(HL)
  785.        ADD A,C
  786.        LD C,A
  787.        BIT 7,(HL)
  788.        jr NZ,$+3
  789.        INC B
  790.        jr C,$+3
  791.        DEC B
  792.         LD A,64
  793.         SUB L
  794.         LD L,A
  795.         LD A,(HL)
  796.        ADD A,E
  797.        LD E,A
  798.        BIT 7,(HL)
  799.        jr NZ,$+3
  800.        INC D
  801.        jr C,$+3
  802.        DEC D
  803.      endif
  804. CTRLnspeed
  805.         LD (IMcurDX),BC
  806.         LD (IMcurDY),DE
  807.        DUP 2
  808.         SRA D
  809.         RR E
  810.         SRA B
  811.         RR C
  812.        EDUP
  813.         ld b,e
  814.         LD HL,(IMcurXx)
  815.         LD de,(IMcurYy)
  816. ;hl=x
  817. ;de=y
  818. ;c=dx/4
  819. ;b=dy/4
  820.         call moveandcollideX
  821.         ex de,hl
  822.         call moveandcollideY
  823. ;hl=y
  824. ;de=x
  825.         LD (IMcurYy),HL
  826.         LD (IMcurXx),de
  827.  
  828. ;TODO загнать 2 цикла в один?
  829.         ;call collideobjects
  830.         call movemonsters
  831.         ;ret
  832.  
  833. collideobjects
  834. ;collide with objects
  835. ;все объекты - в центре своей клетки
  836.         LD HL,MONSTRS+1 ;1+начало табл.монстров/предметов
  837.         ;ld hx,-1 ;monster index
  838.        jp logCOLLIDE0 ;цикл скан-я видимых монстров/предметов
  839. logCOLLIDENx
  840.         LD A,L
  841.         ADD A,8
  842.         LD L,A
  843.         JR C,logCOLLIDExIH
  844. logCOLLIDE0
  845.        ;inc hx ;monster index
  846.         LD A,(HL) ;X
  847.         INC A
  848.        RET Z
  849.         ld a,(IMcurXx+1)
  850.         cp (hl)
  851.         jr nz,logCOLLIDENx
  852.         inc l
  853.         inc l
  854.         ld a,(IMcurYy+1)
  855.         cp (hl)
  856.         jr z,logCOLLIDEY
  857.         LD A,L
  858.         ADD A,6
  859.         LD L,A
  860.         JP NC,logCOLLIDE0
  861. logCOLLIDExIH
  862.         INC H
  863.         JP logCOLLIDE0
  864. logCOLLIDEY
  865.         inc l
  866.         ;ld a,(hl) ;dir
  867.         inc l
  868.         ld a,(hl) ;TYPE*8+phase
  869.         cp 4*8
  870.         jr c,logCOLLIDEnobj
  871.         cp 6*8
  872.         jr nc,logCOLLIDEnobj
  873.         and 0xf8 ;иначе фаза шевелится 0..1
  874.         push hl
  875.         ;ld a,l
  876.         ;and 0xf8
  877.         ;ld l,a
  878.         ;inc l ;X
  879.         res 1,l
  880.         res 2,l
  881.         ld (hl),0xc0 ;impossible X
  882.         ;cp 4*8
  883.         ;jr nz,logCOLLIDEnammo
  884.         ld hl,bullets
  885.         ld bc,40*256+50 ;ADDmax
  886. logCOLLIDEnammo
  887.         cp 5*8
  888.         jr nz,logCOLLIDEnhealth
  889.         ld hl,health
  890.         ld bc,40*256+100 ;ADDmax
  891. logCOLLIDEnhealth
  892.         call addmax
  893.  
  894.         ld a,3 ;get obj
  895.         call sfxplay
  896.         pop hl
  897. logCOLLIDEnobj
  898.         inc l
  899.         ;ld a,(hl) ;energy
  900.         inc l
  901.         ;ld a,(hl) ;time
  902.         inc hl
  903.        INC L ;skip x
  904.         jp logCOLLIDE0
  905.  
  906. ;bc=y
  907. ;de=x
  908. woundneighbours
  909.         ld a,d
  910.         SUB woundrange
  911.         LD (woundXbase),A
  912.         ld a,b
  913.         SUB woundrange
  914.         LD (woundYbase),A
  915.         LD HL,MONSTRS+1 ;1+начало табл.монстров/предметов
  916.  
  917.         ;ld hx,-1 ;monster index
  918.        jp wound0 ;цикл скан-я видимых монстров/предметов
  919. woundNx
  920.         LD A,L
  921.         ADD A,8
  922.         LD L,A
  923.         JR C,woundxIH
  924. wound0
  925.        ;inc hx ;monster index
  926.         LD A,(HL) ;X
  927.         INC A
  928.        RET Z
  929. woundXbase=$+1
  930.         SUB 0
  931.         CP woundrange*2+1
  932.         JP NC,woundNx
  933.         INC L
  934.         inc L
  935.         LD A,(HL)
  936. woundYbase=$+1
  937.         SUB 0
  938.         CP woundrange*2+1
  939.         JR C,woundY
  940.         LD A,L
  941.         ADD A,6
  942.         LD L,A
  943.         JP NC,wound0
  944. woundxIH
  945.         INC H
  946.         JP wound0
  947. woundY
  948.         DEC L
  949.         dec L
  950.         dec L
  951.         LD C,(HL)
  952.         INC L
  953.         LD B,(HL) ;Xx
  954.         INC L
  955.         LD E,(HL)
  956.         INC L
  957.         LD D,(HL) ;Yy
  958.         INC L
  959.  
  960.         inc l ;skip dir
  961.  
  962.         push hl
  963.         ld b,100
  964. ;hl=@TYPEphase
  965. ;b=energy loss
  966.         call fire_wound
  967.         pop hl
  968.         inc l ;skip TYPEphase
  969.         inc l ;skip energy
  970.         inc hl ;skip TIME
  971.        INC L ;skip x
  972.         jp wound0
  973.  
  974.  
  975. movemonsters
  976. ;move monsters
  977.         LD A,(IMcurXx+1);d;(curX)
  978.         SUB viewrange
  979.         LD (logscmonX),A
  980.         LD A,(IMcurYy+1);h;(curY)
  981.         SUB viewrange
  982.         LD (logscmonY),A
  983.         LD HL,MONSTRS+1 ;1+начало табл.монстров/предметов
  984.         ;ld hx,-1 ;monster index
  985.        jp logSCMONS0 ;цикл скан-я видимых монстров/предметов
  986. logSCMONNx
  987.         LD A,L
  988.         ADD A,8
  989.         LD L,A
  990.         JR C,logSCMxIH
  991. logSCMONS0
  992.        ;inc hx ;monster index
  993.         LD A,(HL) ;X
  994.         INC A
  995.        RET Z
  996. logscmonX=$+1
  997.         SUB 0
  998.         CP viewrange*2+1
  999.         JP NC,logSCMONNx
  1000.         INC L
  1001.         inc L
  1002.         LD A,(HL)
  1003. logscmonY=$+1
  1004.         SUB 0
  1005.         CP viewrange*2+1
  1006.         JR C,logSCMONY
  1007.         LD A,L
  1008.         ADD A,6
  1009.         LD L,A
  1010.         JP NC,logSCMONS0
  1011. logSCMxIH
  1012.         INC H
  1013.         JP logSCMONS0
  1014. logSCMONY
  1015.         DEC L
  1016.         dec L
  1017.         dec L
  1018.        push hl ;objaddr
  1019.         LD C,(HL)
  1020.         INC L
  1021.         LD B,(HL) ;Xx
  1022.         INC L
  1023.         LD E,(HL)
  1024.         INC L
  1025.         LD D,(HL) ;Yy
  1026.         INC L
  1027.         ld a,(hl) ;dir
  1028.        inc l
  1029.        ex af,af' ;'
  1030.        ld a,(hl) ;TYPEphase
  1031.        ex af,af' ;'
  1032.         or a
  1033.         jr z,logSCMONS_nomove
  1034.        push af ;dir
  1035.         push bc ;x
  1036.         ld l,a
  1037.      if 1
  1038.        ld h,tsin/256
  1039.        ld b,(hl)
  1040.         LD A,64
  1041.         SUB L
  1042.         LD L,A
  1043.        ld c,(hl)
  1044.        dup 2
  1045.        sra b
  1046.        sra c
  1047.        edup
  1048.      else
  1049.         LD H,tcos/256 ;-pi/4..+pi/4
  1050.         LD c,(HL)
  1051.         LD A,64
  1052.         SUB L
  1053.         LD L,A
  1054.        ;ld a,b ;TYPEphase
  1055.         LD b,(HL)
  1056.      endif
  1057.         pop hl ;x
  1058.        ex af,af' ;'
  1059.        cp 7*8 ;grenade
  1060.        jr nc,movemons_noslow
  1061.         dup 2;3
  1062.         sra b
  1063.         sra c
  1064.         edup
  1065. movemons_noslow
  1066.        ex af,af' ;'
  1067. ;hl=x
  1068. ;de=y
  1069. ;c=dx/4
  1070. ;b=dy/4
  1071.         call moveandcollideX
  1072.         ex de,hl
  1073.         call nc,moveandcollideY
  1074. ;hl=y
  1075. ;de=x
  1076.        pop bc ;b=dir
  1077.        ld a,b
  1078.        jr nc,movemons_nochagedir
  1079.        ld a,r ;TODO rnd
  1080.        add a,a
  1081.        inc a
  1082.        ex af,af' ;'
  1083.        cp 7*8 ;grenade
  1084.        jr c,movemons_chagedir_ngrenade
  1085.        ex (sp),hl ;pop objaddr
  1086.        push hl ;objaddr
  1087.        ;jr $
  1088.        set 2,l
  1089.        ;ld (hl),0 ;dir=no move
  1090.        inc l
  1091.        ld (hl),7*8+4 ;ammo wounded ;explode
  1092.         inc l
  1093.         ;ld (hl),a ;energy
  1094.         inc l
  1095.         ld (hl),TIME_WOUNDED ;time
  1096. ;TODO ранить себя
  1097.         push bc ;b=dir
  1098.         push de
  1099.         ;jr $
  1100.        res 2,l
  1101.        ld b,(hl)
  1102.        dec l
  1103.        ld c,(hl)
  1104. ;bc=y
  1105. ;de=x
  1106.         call woundneighbours
  1107.  
  1108.         ld a,6 ;explode
  1109.         call sfxplay
  1110.         pop de
  1111.         pop bc ;b=dir
  1112.        pop hl ;objaddr
  1113.        ex (sp),hl ;push objaddr
  1114.        ;ex af,af' ;'
  1115.        xor a ;dir=no move
  1116.        ex af,af' ;'
  1117. movemons_chagedir_ngrenade
  1118.        ex af,af' ;'
  1119. movemons_nochagedir
  1120.         ld b,d
  1121.         ld c,e ;x
  1122.         ex de,hl ;y
  1123. logSCMONS_nomove
  1124.        pop hl ;objaddr
  1125.         ld (hl),c
  1126.        ld lx,c
  1127.         inc l
  1128.         ld (hl),b ;Xx
  1129.         inc l
  1130.         ld (hl),e
  1131.        ld hx,e
  1132.         inc l
  1133.         ld (hl),d ;Yy
  1134.         inc l
  1135.         ld (hl),a ;dir
  1136.         inc l ;skip dir
  1137.  
  1138.       if 1
  1139.       ;ld a,0xfe
  1140.       ;in a,(0xfe)
  1141.       ;rra
  1142.       ;jr c,logSCMONS_noattack
  1143. ;если (1..3)*8+(0..1) и близко, то wantattack:
  1144.         ld a,(hl) ;TYPE*8+phase
  1145.         and (30*8)+6
  1146.         cp 0*8+0 ;стоит спиной
  1147.         ld e,MONSTERBACKviewrange
  1148.         jr z,logSCMONS_startattack
  1149.         cp 2*8+0 ;стоит лицом или идёт
  1150.         ld e,MONSTERviewrange
  1151.         jr nz,logSCMONS_noattack
  1152. logSCMONS_startattack
  1153.         ld a,(IMcurYy+1)
  1154.         sub d ;Y
  1155.         jr nc,$+4
  1156.         neg
  1157.         cp e;MONSTERviewrange
  1158.         jr nc,logSCMONS_noattack
  1159.         ld a,(IMcurXx+1)
  1160.         sub b ;X
  1161.         jr nc,$+4
  1162.         neg
  1163.         cp e;MONSTERviewrange
  1164.         jr nc,logSCMONS_noattack
  1165.        ;ld a,(hl) ;TYPE*8+phase
  1166.         ld (hl),3*8+2 ;wantattack
  1167.         inc l
  1168.         inc l
  1169.         ld (hl),TIME_WANTATTACK
  1170.         dec l
  1171.         dec l
  1172.         push hl
  1173. ;чтобы кричать только первый раз:
  1174.        ;cp 0*8+0
  1175.        ;jr z,doshout ;если стоял спиной, то всё-таки крикнуть
  1176.        dec l
  1177.        ld a,(hl) ;dir
  1178.        or a
  1179.        jr z,doshout;noshout ;если стоял, то кричать
  1180.        and 0x3f
  1181.        dec a ;квадратно-гнездовое направление (изначальное) - кричать, иначе нет
  1182. doshout
  1183.         ld a,4 ;shout
  1184.         call z,sfxplay
  1185. noshout
  1186.         pop hl
  1187. logSCMONS_noattack
  1188.       endif
  1189.         ld c,(hl) ;TYPE*8+phase
  1190.         INC L ;skip TYPE*8+phase
  1191.         inc L ;skip energy
  1192.         dec (hl) ;time
  1193.         jp nz,logSCMONS_notime
  1194.         ;ld (hl),TIME_STEP ;time
  1195.         ;dec l
  1196.         ;dec l ;hl points to TYPE*8+phase
  1197.         ld a,c
  1198.         and 7
  1199.         jr z,logSCMONS_step
  1200.         dec a
  1201.         jr z,logSCMONS_step
  1202.         dec a
  1203.         jr z,logSCMONS_wantattack
  1204.         dec a ;attack
  1205.         jr z,logSCMONS_attack
  1206.         dec a
  1207.         jr z,logSCMONS_wounded
  1208.         dec a
  1209.         jr z,logSCMONS_explode2
  1210.         jr logSCMONS_nosetphase
  1211. logSCMONS_wantattack
  1212.         ;inc l
  1213.         ;inc l
  1214.         ld (hl),TIME_ATTACK
  1215.         dec l
  1216.         dec l
  1217.         dec l
  1218.         ld (hl),0 ;dir (no move)
  1219.         inc l
  1220.         ld a,3*8+3 ;moving attack
  1221.         jr logSCMONS_setphase
  1222. logSCMONS_explode2
  1223.         ;inc l
  1224.         ;inc l
  1225.         ld (hl),TIME_EXPLODE
  1226.         dec l
  1227.         dec l
  1228.        ld a,8*8 ;fire
  1229.        jr logSCMONS_setphase
  1230. ;logSCMONS_wounded_ammo
  1231. ;       ld a,7*8+6 ;explode2
  1232. ;       jr logSCMONS_setphase
  1233. ;дальше продолжаем движение
  1234. logSCMONS_wounded
  1235.         ;inc l
  1236.         ;inc l
  1237.         ld (hl),TIME_WOUNDED
  1238.         dec l
  1239.         dec l
  1240.        ld a,(hl)
  1241.        cp 4*8 ;ammo?
  1242.        ld a,7*8+5 ;explode2
  1243.        jr nc,logSCMONS_setphase;logSCMONS_wounded_ammo
  1244. logSCMONS_setmoving
  1245.         ld a,r ;TODO rnd
  1246.         add a,a ;dir
  1247.         dec l
  1248.         ld (hl),a ;dir
  1249.         inc l
  1250.         ld a,3*8+0 ;moving
  1251.         jr logSCMONS_setphase ;not ammo
  1252. logSCMONS_step
  1253.         ;inc l
  1254.         ;inc l
  1255.         ld (hl),TIME_STEP
  1256.         dec l
  1257.         dec l
  1258.         ld a,c
  1259.         and 0xf8
  1260.         cp 8*8
  1261.         jr nz,logSCMONS_noendfire
  1262. ;огонь гасим постепенным уменьшением энергии
  1263.         inc l
  1264.         dec (hl)
  1265.         dec hl
  1266.         jr nz,logSCMONS_noendfire
  1267.         res 2,l
  1268.         ld (hl),0xc0 ;impossible X
  1269.         set 2,l
  1270. logSCMONS_noendfire
  1271.         ld a,c
  1272.         xor 1
  1273. logSCMONS_setphase
  1274.         ld (hl),a
  1275. logSCMONS_nosetphase
  1276.         inc l
  1277.         inc l
  1278. logSCMONS_notime
  1279.         inc hl ;skip TIME
  1280.        INC L ;skip x
  1281.         jp logSCMONS0
  1282. ;;;;attack!!!!
  1283. logSCMONS_attack
  1284.         ;inc l
  1285.         ;inc l
  1286.         ld (hl),TIME_SHOT
  1287.         dec l
  1288.         dec l
  1289. ;TODO узнать расстояние, чтобы определить, сколько отнять здоровья
  1290. ;todo проверить, что враг нас видит
  1291. ;для этого найти угол, под которым мы видим врага
  1292. ;потом найти евклидово расстояние (OBJMUL, но без коррекции!)
  1293. ;и сравнить его с расстоянием в RAYCAST (для этого угла) без коррекции!
  1294. ;[или повернуть виртуальную камеру (на угол, под которым мы видим врага) и делать с коррекцией, обычными процедурами?]
  1295.        push hl
  1296.  
  1297.        ld c,lx ;было запорото
  1298.        ld e,hx ;было запорото
  1299.  
  1300.        push bc ;monsterXx
  1301.        push de ;monsterYy
  1302.  
  1303.         LD HL,(curYy)
  1304.         ex de,hl
  1305.         SBC HL,DE ;dYy со стороны монстра
  1306.         ld (logSCMONS_dYy),hl
  1307.         ex de,hl;EXD
  1308.         ld h,b
  1309.         ld l,c
  1310.         LD bc,(curXx)
  1311.         SBC HL,BC ;dXx со стороны монстра
  1312.         ld (logSCMONS_dXx),hl
  1313.  
  1314.        ;push de ;dYy
  1315.        ;push hl ;dXx
  1316.  
  1317. normvec0
  1318.         sra d
  1319.         rr e
  1320.         sra h
  1321.         rr l
  1322.         ld a,e
  1323.         rla
  1324.         sbc a,a
  1325.         cp d
  1326.         jr nz,normvec0
  1327.         ld a,l
  1328.         rla
  1329.         sbc a,a
  1330.         cp h
  1331.         jr nz,normvec0
  1332.         ;ld a,l
  1333.         ;cpl
  1334.         ;ld b,a ;-x
  1335.         ld b,l ;x
  1336.         ;ld a,e
  1337.         ;cpl
  1338.         ;ld c,a ;-y
  1339.         ld c,e ;y
  1340. ;B = x, C = y in -128,127
  1341.         call atan2
  1342. ;out: A = angle in 0-255
  1343. ;монстр с востока:
  1344. ;de=fffc, hl=00fa [de=0x0039(y), hl=0xfec2(x)]
  1345. ;de=fffe, hl=007d [de=0x000e(y), hl=0xffb0(x)] после уменьшения
  1346. ;a=[81]00 (с юго-востока [9c]e8)
  1347. ;в рендере: 0x40 смотрим на север, 0x20 на северо-восток, 0x00 на восток, 0xc0 на юг, 0x80 на запад
  1348.         add a,0x80
  1349.  
  1350.        pop de ;monsterYy
  1351.        pop hl ;monsterXx
  1352. ;hl=monsterXx
  1353. ;de=monsterYy
  1354. ;a=monster angle
  1355.  
  1356.         call RAYPREPXY_hldea ;между делом заполняет curangle
  1357.  
  1358. logSCMONS_dXx=$+1
  1359.         ld hl,0
  1360. logSCMONS_dYy=$+1
  1361.         ld de,0
  1362. ;calculate sprite position
  1363.         CALL OBJMUL
  1364.        ;BC=dist
  1365.        ;DE=xscr
  1366. ;BC=dist ;017a с востока ;0058..00ad с юго-востока - ошибка,занижено!!!
  1367.         call disttoscale
  1368. ;de=dist, c=scale# (0x1a впритык с востока) (3a..2d с юго-востока - ошибка,занижено!!!)
  1369.        ld a,c
  1370.        ld (logSCMONS_sprscale),a ;scale#(spr)
  1371.      
  1372.         LD l,SCRWIDPIX/2;0x40;TODO связано с scrwid/2
  1373.         ;ld a,l
  1374.         ;LD (cura),A
  1375.         CALL RAYCASTl
  1376. ;C=dist(scale#) (0x09 впритык с востока) (30 с юго-востока)
  1377. ;B=texx
  1378. ;сравнить dist(raycast) > dist(spr), то есть scale#(raycast) < scale#(spr)
  1379.         ld a,c ;scale#(raycast)
  1380.         ;jr $
  1381. logSCMONS_sprscale=$+1
  1382.         cp 0;lx ;scale#(spr)
  1383.         jr nc,logSCMONS_failfire
  1384.  
  1385.         ld a,7 ;enemy shoot
  1386.         call sfxplay
  1387.         ld hl,health
  1388.         ld b,5;3
  1389.         call decvariable ;out: z=0, c=error
  1390. logSCMONS_failfire
  1391.        pop hl
  1392.         jp logSCMONS_setmoving
  1393.         ;ld a,3*8+0 ;moving
  1394.         ;jr logSCMONS_setphase ;not ammo
  1395.  
  1396. moveandcollideX
  1397. ;hl=x
  1398. ;de=y
  1399. ;c=dx/4
  1400. ;b=dy/4
  1401.         ;ADD HL,BC
  1402.        PUSH HL
  1403. ;|..............|
  1404. ;.....<---*--->..
  1405.         ;or a:sbc hl,bc;LD HL,(IMcurXx)
  1406.          ld a,l
  1407.          sub mindist ;dx<0
  1408.          ;dec h
  1409.         BIT 7,c;B
  1410.         jr nz,$+6
  1411.          ld a,l
  1412.          add a,mindist ;dx>0
  1413.          inc h
  1414.         jr nc,CTRLXpass ;проходимо (CY=0)
  1415.         ;LD A,H
  1416.         ;LD HL,(IMcurYy)
  1417.         ;LD L,A
  1418.         ld l,h
  1419.         ld h,d ;Y
  1420.         SET mapdifbit,L
  1421.         LD A,(HL)
  1422.         RLA ;проходимо?
  1423. CTRLXpass
  1424.        POP HL
  1425.         jr nc,CTRLnXq ;проходимо (CY=0)
  1426. CTRLnX
  1427. ;непроходимо
  1428.         ;LD HL,(IMcurXx)
  1429.         BIT 7,c;B
  1430.         LD l,256-mindist ;dx>0
  1431.         ret z ;C
  1432.         LD l,mindist ;dx<0
  1433.         ret ;C
  1434. CTRLnXq
  1435.         ;add hl,bc
  1436.         ld a,c
  1437.         add a,l
  1438.         ld l,a
  1439.         adc a,h
  1440.         sub l
  1441.         ld h,a
  1442.          or a ;NC
  1443.         bit 7,c
  1444.         ret z ;NC
  1445.         dec h
  1446.         ret ;NC
  1447. moveandcollideY
  1448. ;hl=y
  1449. ;b=dy/4
  1450.         ;ADD HL,DE
  1451.        PUSH HL
  1452.         ;or a:sbc hl,de;LD HL,(IMcurYy)
  1453.          ld a,l
  1454.          sub mindist ;dx<0
  1455.          ;dec h
  1456.         BIT 7,b;D
  1457.         jr nz,$+6
  1458.          ld a,l
  1459.          add a,mindist ;dx>0
  1460.          inc h
  1461.         jr nc,CTRLYpass ;проходимо (CY=0)
  1462.         ;LD A,H
  1463.         ;LD HL,(IMcurXx)
  1464.         ;LD L,H
  1465.         ;LD H,A
  1466.         ld l,d ;X
  1467.         LD A,(HL)
  1468.         RLA ;проходимо?
  1469. CTRLYpass
  1470.        POP HL
  1471.        jr nc,CTRLnYq ;проходимо (CY=0)
  1472. ;непроходимо
  1473.         ;LD HL,(IMcurYy)
  1474.         BIT 7,b;d
  1475.         LD l,256-mindist ;dy>0
  1476.         ret z ;C
  1477.         LD l,mindist ;dy<0
  1478.         ret ;C
  1479. CTRLnYq
  1480.         ;add hl,de
  1481.         ld a,b
  1482.         add a,l
  1483.         ld l,a
  1484.         adc a,h
  1485.         sub l
  1486.         ld h,a
  1487.          or a ;NC
  1488.         bit 7,b
  1489.         ret z ;NC
  1490.         dec h
  1491.         RET ;NC
  1492.  
  1493. closecurrentdoor
  1494. ;keeps hl,de
  1495.         ld a,128+ID_DOOR;(hl)
  1496. oldopendooraddr=$+1
  1497.         ld (killablebyte),a
  1498. oldopendooraddr2=$+1
  1499.         ld (killablebyte),a
  1500.        ld bc,killablebyte
  1501.        ld (oldopendooraddr),bc
  1502.        ld (oldopendooraddr2),bc
  1503.         ret
  1504. killablebyte
  1505.         db 0
  1506.  
  1507. addmax
  1508. ;add b, max c
  1509.         ld a,(hl)
  1510.         cp c;100
  1511.         ret nc
  1512.         add a,b;40
  1513.         ld (hl),a
  1514.         cp c;100
  1515.         ret c
  1516.         ld (hl),c;100
  1517.         ret
  1518.  
  1519. decvariable
  1520. ;sub b
  1521. ;out: z=0, c=error
  1522.         ld a,(hl)
  1523.         or a
  1524.         ccf
  1525.         ret z ;error
  1526.         sub b
  1527.         jr nc,$+3
  1528.         xor a
  1529.         ld (hl),a
  1530.         ret
  1531.  
  1532. fire_wound
  1533. ;hl=@TYPEphase
  1534. ;b=energy loss
  1535.         ld a,(hl)
  1536.         cp 5*8;4*8
  1537.         ret nc;jr nc,fire_skip ;not a monster/ammo
  1538.         and 7
  1539.         cp 6
  1540.         ret z;jr z,fire_skip ;dead monster
  1541.         dec l
  1542.         ld (hl),0 ;dir = no move
  1543.         inc l
  1544.        ld a,(hl)
  1545.        cp 4*8 ;ammo?
  1546.         ld (hl),3*8+4 ;wounded, go
  1547.        jr c,$+4 ;not ammo
  1548.        ld (hl),7*8+4 ;ammo wounded
  1549.         inc l
  1550.         ld a,(hl) ;energy
  1551.         sub b;20
  1552.         ld (hl),a ;energy
  1553.         jr c,fire_kill
  1554.         inc l
  1555.         ld (hl),TIME_WOUNDED ;time
  1556.         ld a,2 ;wound sfx
  1557.         jr fire_killq
  1558. fire_kill
  1559.         dec l
  1560.         ld (hl),3*8+6 ;dead
  1561.         ;ld a,l
  1562.         ;and 0xf8
  1563.         ;ld l,a
  1564.         ;inc l ;X
  1565.         ;ld (hl),0xc0 ;impossible X
  1566.         ld a,0 ;kill sfx
  1567. fire_killq
  1568.         jp sfxplay
  1569. ;fire_skip
  1570. ;        ret
  1571.  
  1572. findfreemonster
  1573. ;out: CY=error, hl=addr
  1574.         ld hl,MONSTRS ;Xx,Yy,TYPEphase_dir,TIMEenergy ;TYPEphase=TYPE*8+phase
  1575. ;перебрать объекты, вставить на место дохлого (impossible X = 0xc0) или в конец
  1576. findfreemonster0
  1577.         inc l
  1578.         ld a,(hl)
  1579.         INC A
  1580.         jr z,findfreemonsterEND
  1581.         cp 0xc0+1
  1582.         jr z,findfreemonsterOK
  1583.         set 1,l
  1584.         set 2,l
  1585.         inc hl
  1586.         jr findfreemonster0
  1587. findfreemonsterEND
  1588.         ld bc,-(ENDMONS-8)
  1589.         add hl,bc
  1590.         ret c
  1591.         sbc hl,bc
  1592.         ld bc,8
  1593.         add hl,bc
  1594.         ld (hl),-1 ;new end marker
  1595.         sbc hl,bc
  1596. findfreemonsterOK
  1597.         dec l
  1598.         ret ;NC
  1599.  
  1600.        if 1
  1601. ; 8-bit atan2
  1602.  
  1603. ; Calculate the angle, in a 256-degree circle.
  1604. ; The trick is to use logarithmic division to get the y/x ratio and
  1605. ; integrate the power function into the atan table.
  1606.  
  1607. ;       input
  1608. ;       B = x, C = y    in -128,127
  1609. ;
  1610. ;       output
  1611. ;       A = angle               in 0-255
  1612.  
  1613. ;      |
  1614. ;  q1  |  q0
  1615. ;------+-------
  1616. ;  q3  |  q2
  1617. ;      |
  1618.  
  1619. atan2:
  1620.                 ld      de,0x8000
  1621.  
  1622.                 ld      a,c
  1623.                 add     a,d
  1624.                 rl      e                               ; y-
  1625.  
  1626.                 ld      a,b
  1627.                 add     a,d
  1628.                 rl      e                               ; x-
  1629.  
  1630.                 dec     e
  1631.                 jr      z,q1
  1632.                 dec     e
  1633.                 jr      z,q2
  1634.                 dec     e
  1635.                 jr      z,q3
  1636.  
  1637. q0:
  1638.                 ld      h,log2_tab / 256
  1639.                 ld      l,b
  1640.  
  1641.                 ld      a,(hl)                  ; 32*log2(x)
  1642.                 ld      l,c
  1643.  
  1644.                 sub     (hl)                    ; 32*log2(x/y)
  1645.  
  1646.                 jr      nc,1f                   ; |x|>|y|
  1647.                 neg                             ; |x|<|y|       A = 32*log2(y/x)
  1648. 1:              ld      l,a
  1649.  
  1650.                 ld      h,atan_tab / 256
  1651.                 ld      a,(hl)
  1652.                 ret     c                       ; |x|<|y|
  1653.  
  1654.                 neg
  1655.                 and     0x3F                    ; |x|>|y|
  1656.                 ret
  1657.  
  1658. q1:             xor a;ld        a,b
  1659.                 sub b;neg
  1660.                 ld      b,a
  1661.                 call    q0
  1662.                 neg
  1663.                 and     0x7F
  1664.                 ret
  1665.  
  1666. q2:             xor a;ld        a,c
  1667.                 sub c;neg
  1668.                 ld      c,a
  1669.                 call    q0
  1670.                 neg
  1671.                 ret
  1672.  
  1673. q3:             xor a;ld        a,b
  1674.                 sub b;neg
  1675.                 ld      b,a
  1676.                 xor a;ld        a,c
  1677.                 sub c;neg
  1678.                 ld      c,a
  1679.                 call    q0
  1680.                 add     a,128
  1681.                 ret
  1682.  
  1683.  
  1684.        endif
  1685.