Subversion Repositories NedoOS

Rev

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

  1.        IF corr_coord
  2. CORR_COORD
  3.        LD A,L
  4.        OR A
  5.        jr NZ,$+3
  6.        INC L
  7.        INC A
  8.        jr NZ,$+3
  9.        DEC L
  10.        LD A,H
  11.        OR A
  12.        jr NZ,$+3
  13.        INC H
  14.        INC A
  15.        RET NZ
  16.        DEC H
  17.         RET
  18.        ENDIF
  19.  
  20. RAYPREPXY
  21. ;TODO брать координаты не из прерывания!!!
  22.        IF !atm && optfast
  23.         LD HL,(IMcurDX)
  24.         LD A,H
  25.         OR L
  26.         LD HL,(IMcurDY)
  27.         OR H
  28.         OR L
  29.         LD A,lowmaxscale
  30.         jr Z,$+4
  31.         LD A,0;-1
  32.         LD (foptfast),A
  33.        ENDIF
  34. IMcurXx=$+1
  35.         LD HL,#0F80 ;#0580
  36. IMcurYy=$+1
  37.         LD de,#0180+(map&#FF00) ;#A580
  38.         LD A,(IMavision+1)
  39. RAYPREPXY_hldea
  40.         ex af,af' ;'
  41.        IF corr_coord
  42.         CALL CORR_COORD
  43.        ENDIF
  44.         LD (curXx),HL
  45.         ex de,hl
  46.        IF corr_coord
  47.         CALL CORR_COORD
  48.        ENDIF
  49.         LD (curYy),HL
  50.         ex af,af' ;'
  51.        LD (curangle),A
  52.         SUB 32
  53.         LD L,A
  54.         LD H,0
  55.         ADD HL,HL
  56.         ADD HL,HL
  57.         LD A,L
  58.         LD (avision4L),A
  59.         LD A,H
  60.         LD (avision4H),A
  61.         LD HL,(cury-1)
  62.         LD A,(curx)
  63.         LD L,A
  64.         LD (cur00yx),HL
  65.         LD (cur01yx),HL
  66.       ;LD A,L ;основное направление
  67.        CPL ;1-основное направление
  68.        LD L,A
  69.         LD (cur10yx),HL
  70.         LD (cur11yx),HL
  71.        CPL ;основное направление
  72.         LD L,H
  73.         ld H,A
  74.         LD (cur00xy),HL
  75.         LD (cur01xy),HL
  76.        LD A,L ;1-основное направление
  77.        CPL ;основное направление
  78.        LD L,A
  79.         LD (cur10xy),HL
  80.         LD (cur11xy),HL
  81.         LD HL,(curX)
  82.         LD A,(curY)
  83.         LD H,A
  84.        ;LD (curYX),HL
  85.         LD (ray00yx_YX),HL
  86.         LD (ray01yx_YX),HL
  87.         LD (ray10yx_YX),HL
  88.         LD (ray11yx_YX),HL
  89.         LD (ray00xy_YX),HL
  90.         LD (ray01xy_YX),HL
  91.         LD (ray10xy_YX),HL
  92.         LD (ray11xy_YX),HL
  93.         SET mapdifbit,L
  94.         LD (ray00xy_YX2),HL
  95.         LD (ray01xy_YX2),HL
  96.         LD (ray10xy_YX2),HL
  97.         LD (ray11xy_YX2),HL
  98.         ret
  99. SCAN
  100.         call RAYPREPXY
  101.  
  102.         ;TODO чтобы узнать, какая дверь открывается, надо её отметить на самой карте (с обеих сторон)
  103.  
  104.       IF interpolate == 0
  105.  
  106.        IF lores
  107.         LD L,0;2*(32-scrwid)
  108.         LD HY,SCRWIDPIX;scrwid*4
  109.        ELSE
  110.         LD L,0;4*(32-scrwid)
  111.         LD HY,SCRWIDPIX;scrwid*8
  112.        ENDIF
  113. RAY0
  114.         ;LD A,L
  115.         ;LD (cura),A
  116.         CALL RAYCASTl
  117.        LD HL,(cura)
  118.         LD H,distbuf/256+2
  119.         LD (HL),C ;dist (scale#)
  120.         DEC H
  121.         LD (HL),B ;texx
  122.         DEC H
  123.         RRCA ;CY=0
  124.         LD A,(DE) ;ID(YX)
  125.          ;ld a,0xc0
  126.         LD (HL),A ;ID
  127.         INC L
  128.         DEC HY
  129.         JP NZ,RAY0
  130.  
  131.       ELSE ;interpolate
  132. main_step=interpolate;16
  133.          ;oldscan=RAYCAST(0)
  134.         XOR A
  135.         LD L,A
  136.         ;LD (cura),A
  137.         CALL RAYCASTl
  138.         EXX
  139.          ;main_a=main_step-1
  140.         LD L,main_step-1
  141.        ;IF lores
  142.        ; LD HY,scrwid*4/main_step
  143.        ;ELSE
  144.        ; LD HY,scrwid*8/main_step
  145.        ;ENDIF
  146.        ld hy,SCRWIDPIX/main_step
  147.          ;repeat {
  148. ;L=main_a
  149. ;BCDE'=oldscan
  150. ;BCDE=newscan
  151. RAY0
  152.          ;newscan=RAYCAST(main_a)
  153.         ;LD A,L
  154.         ;LD (cura),A
  155.         CALL RAYCASTl
  156.        LD HL,(cura)
  157.          ;INTERPOLATE_SUB(main_a, main_step, oldscan, newscan)
  158.         LD A,main_step
  159.         LD H,distbuf/256+2
  160.         LD (HL),C ;dist (scale#)
  161.         DEC H
  162.         LD (HL),B ;texx
  163.         DEC H
  164.         RRCA ;CY=0
  165.         CALL INTERPOLATE_SUB
  166.         LD A,(DE) ;ID(YX)
  167.          ;ld a,0xc0
  168.         LD (HL),A ;ID
  169.          ;oldscan=newscan
  170.         LD A,L
  171.         EXX
  172.          ;main_a+=main_step
  173.         ADD A,main_step
  174.         LD L,A
  175.          ;} until(main_a>255)
  176.         DEC HY
  177.         JP NZ,RAY0
  178.       ENDIF ;interpolate
  179.         RET
  180.  
  181. ;((b+f)/2)^2-b^2/4-f^2/4
  182. ;a=e
  183.        MACRO MULPOS
  184.         LD H,tsqr2/256
  185.         ADD A,C
  186.         RRA
  187.         LD L,A
  188.         LD A,(HL)
  189.         INC H
  190.         LD L,C
  191.         SUB (HL)
  192.         LD L,E
  193.         SUB (HL)
  194.        ENDM
  195.  
  196.        MACRO DIVPOS
  197.         SRL C
  198.        DUP 7
  199.         ADD A,C
  200.         jr NC,$+3
  201.         SUB C
  202.         RL B
  203.         ADD A,A
  204.        EDUP
  205.         ADD A,C
  206.         LD A,B
  207.         RLA
  208.        ENDM
  209.  
  210.        MACRO DIVNEG
  211.         SRL C
  212.        DUP 7
  213.         SUB C
  214.         jr NC,$+3
  215.         ADD A,C
  216.         RL B
  217.         ADD A,A
  218.        EDUP
  219.         SUB C
  220.         LD A,B
  221.         RLA
  222.        ENDM
  223.  
  224.  
  225. ;Y растёт вверх
  226. RAYCASTl
  227.         ld a,l
  228.         ld (cura),a
  229. ;L=(cura)=угол на экране
  230. ;портит ABCDEHLIX
  231.         ld a,(doortimer)
  232.         ld ly,a
  233.         LD H,tda/256
  234.         LD A,(HL)
  235. avision4L=$+1
  236.         ADD A,0
  237.         LD (rayrealangle),A
  238.         LD L,A
  239. avision4H=$+1
  240.         ADC A,0
  241.         SUB L ;a1..0 = 0..3 ~ sector 1..4
  242.        ;LD H,tctg/256 ;-pi/4..+pi/4
  243.        INC H
  244.         LD C,(HL) ;ystep or xstep
  245.         LD HX,-1 ;IX=dist*cos
  246.         RRA
  247.         jr NC,ray13
  248.         RRA
  249.         JP NC,ray2
  250.         JP ray4
  251. ray13   RRA
  252.         JP NC,ray1
  253.         JP ray3
  254.  
  255.         macro INCR num ;0..5 = bcdehl
  256.         db 0x04+(8*(num))
  257.         endm
  258.  
  259.         macro DECR num ;0..5 = bcdehl
  260.         db 0x05+(8*(num))
  261.         endm
  262.  
  263. ;RAY 1,1,H,D,y,x
  264.        MACRO RAY mainplus,secplus,maindirhlreg,maindirdereg,maindir,secdir
  265. ;mainplus=\0 ;основное направление положительно
  266. ;secplus=\1 ;побочное направление положительно
  267. ;\2=основное направление для hl (YX)
  268. ;\4=основное направление для de (yx)
  269. ;\6=основное направление (0=x, 1=y)
  270. ;\7=побочное направление (0=x, 1=y)
  271. ;c=побочный шаг
  272.         LD A,E ;основное направление
  273.         LD LX,A ;IX=dist*cos
  274.         MULPOS ;a = a*c
  275.       IF secplus ;побочное направление положительно
  276.         ADD A,D ;побочное направление
  277.         LD B,A ;texx
  278. ray0176_YX=$+1
  279.         LD HL,0 ;hl = основная стенка
  280.        IF maindir != 0 ;"\6\6"-"xx"
  281. ray0176_YX2=$+1
  282.         LD DE,0 ;set mapdifbit ;осн.напр. y, побочное x
  283.        ELSE
  284.         LD D,H ;осн.напр. x, побочное y
  285.         ld E,L
  286.        ENDIF ;de = побочная стенка
  287.         jr NC,2f;raynshort\0\1\7\6 ;точно не пересечение по побоч.напр.
  288.         INCR maindirdereg^1 ;secdirdereg;INC \5 ;e/d
  289.         LD A,(DE)
  290.          add a,a
  291.          cp ID_DOOR*2;128+(22*2)
  292.          jr z,9f
  293.          ld a,(de)
  294.         RLA
  295.         jp C,1f;raysec\0\1\7\6 ;выход по побочной стене
  296. 9
  297.         INCR maindirhlreg^1 ;secdirhlreg;INC \3 ;l/h
  298. 2;raynshort\0\1\7\6
  299.        IF maindir != 1 ;"\6\6"-"yy"
  300.         SET mapdifbit,L
  301.        ENDIF
  302.       ELSE ;побочное направление отрицательно
  303.         LD L,A
  304.         LD A,D ;побочное направление
  305.         SUB L
  306.         LD B,A ;texx
  307. ray0176_YX=$+1
  308.         LD HL,0 ;hl = основная стенка
  309.        IF maindir != 0 ;"\6\6"-"xx"
  310. ray0176_YX2=$+1
  311.         LD DE,0 ;set mapdifbit ;осн.напр. y, побочное x
  312.        ELSE
  313.         LD D,H ;осн.напр. x, побочное y
  314.         ld E,L
  315.        ENDIF ;de = побочная стенка
  316.         jr NC,2f;raynshort\0\1\7\6 ;точно не пересечение по побоч.напр.
  317.         LD A,(DE)
  318.          add a,a
  319.          cp ID_DOOR*2;128+(22*2)
  320.          jr z,9f
  321.          ld a,(de)
  322.         RLA
  323.         jp C,1f;raysec\0\1\7\6 ;выход по побочной стене
  324. 9
  325. ;продолжение по основному направлению
  326.         DECR maindirhlreg^1 ;secdirhlreg
  327.         DECR maindirdereg^1 ;secdirdereg
  328. 2;raynshort\0\1\7\6
  329.        IF maindir != 1 ;"\6\6"-"yy"
  330.         SET mapdifbit,L
  331.        ENDIF
  332.       ENDIF
  333. ;первый (короткий) шаг закончен, теперь идём полными шагами в цикле
  334. 3;raynsec=$;\0\1\7\6
  335.         INC HX
  336.        IF mainplus ;основное направление положительно
  337.         INCR maindirhlreg;INC \2 ;h/l
  338.        ENDIF
  339.         LD A,(HL)
  340.          add a,a
  341.          cp ID_DOOR*2;128+(22*2)
  342.          jp z,4f;doorhlq ;куб двери
  343.          ld a,(hl)
  344.         RLA
  345.         JP C,rayhlq ;b=texx ;выход по основной стене
  346. 13
  347.        IF mainplus ;основное направление положительно
  348.         INCR maindirdereg;INC \4 ;d/e
  349.        ELSE
  350.         DECR maindirhlreg
  351.         DECR maindirdereg
  352.        ENDIF
  353.         LD A,B ;texx
  354.        IF secplus ;побочное направление положительно
  355.         ADD A,C ;побочный шаг
  356.        ELSE
  357.         SUB C ;побочный шаг
  358.        ENDIF
  359.         LD B,A ;texx
  360.         jr NC,3b;raynsec;\0\1\7\6 ;точно не пересечение по побоч.напр.
  361. 12
  362.        IF secplus ;побочное направление положительно
  363.         INCR maindirdereg^1 ;secdirdereg;INC \5 ;e/d
  364.        ENDIF
  365.         LD A,(DE)
  366.          add a,a
  367.          cp ID_DOOR*2;128+(22*2)
  368.          jr z,5f
  369.          ld a,(de)
  370.         RLA
  371.         jp C,1f;raysec\0\1\7\6 ;выход по побочной стене
  372. 9
  373.        IF secplus ;побочное направление положительно
  374.         INCR maindirhlreg^1 ;secdirhlreg;INC \3 ;l/h
  375.        ELSE        ;побочное направление отрицательно
  376.         DECR maindirhlreg^1 ;secdirhlreg
  377.         DECR maindirdereg^1 ;secdirdereg
  378.        ENDIF
  379.         JP 3b;raynsec;\0\1\7\6
  380.  
  381. 7 ;возврат из куба двери, если дверь открыта (в следующей стене игнорить дверь!!!)
  382.         LD A,B ;texx
  383.        IF secplus ;побочное направление положительно
  384.         ADD A,C ;побочный шаг
  385.        ELSE
  386.         SUB C ;побочный шаг
  387.        ENDIF
  388.         LD B,A ;texx
  389.         jr C,12b;raynsec;\0\1\7\6 ;точно не пересечение по побоч.напр.
  390. ;3;raynsec=$;\0\1\7\6
  391.         INC HX
  392.        IF mainplus ;основное направление положительно
  393.         INCR maindirhlreg;INC \2 ;h/l
  394.        ENDIF
  395.         jr 13b ;считаем, что стены впереди нет, продолжаем как обычно
  396.  
  397. ;куб двери по побочному шагу
  398. 5
  399.         ld a,(de)
  400.         rla
  401.         jr nc,$+5 ;закрытая дверь
  402.         ld ly,0
  403.        IF secplus ;побочное направление положительно
  404.         INCR maindirhlreg^1 ;secdirhlreg;INC \3 ;l/h
  405.        ELSE        ;побочное направление отрицательно
  406.         DECR maindirhlreg^1 ;secdirhlreg
  407.         DECR maindirdereg^1 ;secdirdereg
  408.        ENDIF
  409.         INC HX
  410.         bit 7,B ;texx
  411.        IF secplus ;побочное направление положительно
  412.         jp z,rayhlq ;видим основную стену до двери
  413.        ELSE
  414.         jp nz,rayhlq ;видим основную стену до двери
  415.        ENDIF
  416.         ;ld b,10 ;сплошной голубой (0=сплошной серый)
  417.         ;jp z,rayhlq
  418.  
  419.        IF secplus ;побочное направление положительно
  420.         INCR maindirdereg^1 ;secdirdereg;INC \5 ;e/d
  421.        ENDIF
  422.         ;jp rayhlq ;дверь открыта, выход по основной стене
  423.          ;dec hx
  424.          ld a,b ;texx
  425.          add a,128
  426.          ;ld b,a
  427.         ;jr 1f ;jr C,8f;raysec\0\1\7\6 ;выход по побочной стене
  428.         ;LD A,B
  429.        IF secplus ;побочное направление положительно
  430.         SUB C
  431.        else
  432.         ADD A,C
  433.        endif
  434. ;a=texx как был
  435.         ex de,hl;EXD
  436.         ;ex de,hl
  437.         ;jp rayhlq ;дверь открыта, выход по основной стене
  438.         push bc
  439.        IF secplus ;побочное направление положительно
  440.         DIVPOS ;texx(a)/step(c), портит b,c
  441.        ELSE
  442.         DIVNEG ;texx(a)/step(c), портит b,c
  443.        ENDIF
  444.         pop bc
  445.        IF mainplus ;основное направление положительно
  446.         CPL
  447.          ;push hl
  448.          ;ld hl,timer
  449.          add a,ly;(hl)
  450.          jr c,6f ;b=texx, выход по осн. стене (полуоткрытая дверь)
  451.         LD B,A ;b=texx
  452.         sub ly;(hl)
  453.          ;pop hl
  454.        ELSE
  455.          ;push hl
  456.          ;ld hl,timer
  457.          add a,ly;(hl)
  458.          jr c,6f ;выход по осн. стене (полуоткрытая дверь)
  459.         LD B,A ;b=texx
  460.         sub ly;(hl)
  461.         CPL
  462.          ;pop hl
  463.        ENDIF
  464.          dec hx
  465.         JP raydeq ;c,de не важны
  466. 6 ;выход по осн. стене (полуоткрытая дверь)
  467.         ;pop hl
  468.         ex de,hl
  469.         jp rayhlq ;b=texx
  470.  
  471. ;куб двери по основному шагу
  472. 4
  473.         bit 7,(HL)
  474.         jr z,$+5 ;закрытая дверь
  475.         ld ly,0
  476. ;проверить, что позади дверь, тогда выход в 13b (т.е. впереди пусто)
  477.        IF mainplus ;основное направление положительно
  478.         DECR maindirhlreg;INC \4 ;d/e
  479.        ELSE
  480.         INCR maindirhlreg
  481.        ENDIF
  482.         ld a,(hl)
  483.        IF mainplus ;основное направление положительно
  484.         INCR maindirhlreg;INC \4 ;d/e
  485.        ELSE
  486.         DECR maindirhlreg
  487.        ENDIF
  488.          add a,a
  489.          cp ID_DOOR*2;128+(22*2)
  490.         jp z,13b ;позади дверь, значит, впереди пусто
  491. ;
  492.         srl c ;побочный шаг
  493.        IF mainplus ;основное направление положительно
  494.         INCR maindirdereg;INC \4 ;d/e
  495.        ELSE
  496.         DECR maindirhlreg
  497.         DECR maindirdereg
  498.        ENDIF
  499.         LD A,B ;texx
  500.        IF secplus ;побочное направление положительно
  501.         ADD A,C ;побочный шаг
  502.         LD B,A ;texx
  503.         SUB C ;побочный шаг
  504.        ELSE
  505.         SUB C ;побочный шаг
  506.         LD B,A ;texx
  507.         ADD A,C ;побочный шаг
  508.        ENDIF
  509.         jr c,2f
  510.         ex af,af' ;'
  511.         ld a,ly;(timer)
  512.         add a,b
  513.         ld b,a
  514.         jr nc,11f ;дверь по основному направлению
  515.         ex af,af' ;'
  516.         ld b,a ;texx как был
  517.         sla c ;побочный шаг как был
  518.         jp 7b ;нет двери
  519. 11      
  520.         jp doorhlq;3b;raynsec;\0\1\7\6 ;точно не пересечение по побоч.напр.
  521. 2;куб двери по основному шагу - выход по побочной стене
  522.        IF secplus ;побочное направление положительно
  523.         INCR maindirdereg^1 ;secdirdereg;INC \5 ;e/d
  524.        ENDIF
  525.  
  526. ;побочная стена при шаге половинками
  527.         sla c ;побочный шаг как был
  528.         jr 8f
  529.        
  530. ;побочная стена
  531. 1;raysec\0\1\7\6
  532.         LD A,B
  533.        IF secplus ;побочное направление положительно
  534.         SUB C
  535.        else
  536.         ADD A,C
  537.        endif
  538. 8
  539. ;a=texx как был
  540.         ex de,hl;EXD
  541.        IF secplus ;побочное направление положительно
  542.         DIVPOS ;texx(a)/step(c)
  543.        ELSE
  544.         DIVNEG ;texx(a)/step(c)
  545.        ENDIF
  546.        IF mainplus ;основное направление положительно
  547.         CPL
  548.         LD B,A ;b=texx
  549.        ELSE
  550.         LD B,A ;b=texx
  551.         CPL
  552.        ENDIF
  553.         JP raydeq
  554.        ENDM
  555.  
  556. ;mainplus=\0 ;основное направление положительно
  557. ;secplus=\1 ;побочное направление положительно
  558. ;\2=основное направление для hl = 4..5
  559. ;\4=основное направление для de = 2..3
  560. ;\6=основное направление
  561. ;\7=побочное направление
  562. ;c = ystep or xstep (шаг по побочному направлению) всегда положительный
  563. ;HX=-1 ;IX=dist*cos
  564. ;сейчас l=angle
  565. ray1
  566.         BIT 7,L
  567.         JP NZ,ray1b
  568.         ;RAY 1,1,L,E,x,y ;1a
  569. cur11yx=$+1
  570.         LD DE,0
  571.         RAY 1,1,5,3,0,1;x,y ;1a
  572. ;cur11yx=cur0176
  573. ray11yx_YX=ray0176_YX
  574. ;ray11yx_YX2=ray0176_YX2
  575. ray1b
  576.         ;RAY 1,1,H,D,y,x ;1b
  577. cur11xy=$+1
  578.         LD DE,0
  579.         RAY 1,1,4,2,1,0;y,x ;1b
  580. ;cur11xy=cur0176
  581. ray11xy_YX=ray0176_YX
  582. ray11xy_YX2=ray0176_YX2
  583. ray2
  584.         BIT 7,L
  585.         JP NZ,ray2b
  586.         ;RAY 1,0,H,D,y,x ;2a
  587. cur10xy=$+1
  588.         LD DE,0
  589.         RAY 1,0,4,2,1,0;y,x ;2a
  590. ;cur10xy=cur0176
  591. ray10xy_YX=ray0176_YX
  592. ray10xy_YX2=ray0176_YX2
  593. ray2b
  594.         ;RAY 0,1,L,E,x,y ;2b
  595. cur01yx=$+1
  596.         LD DE,0
  597.         RAY 0,1,5,3,0,1;x,y ;2b
  598. ;cur01yx=cur0176
  599. ray01yx_YX=ray0176_YX
  600. ;ray01yx_YX2=ray0176_YX2
  601. ray3
  602.         BIT 7,L
  603.         JP NZ,ray3b
  604.         ;RAY 0,0,L,E,x,y ;3a
  605. cur00yx=$+1
  606.         LD DE,0
  607.         RAY 0,0,5,3,0,1;x,y ;3a
  608. ;cur00yx=cur0176
  609. ray00yx_YX=ray0176_YX
  610. ;ray00yx_YX2=ray0176_YX2
  611. ray3b
  612.         ;RAY 0,0,H,D,y,x ;3b
  613. cur00xy=$+1
  614.         LD DE,0
  615.         RAY 0,0,4,2,1,0;y,x ;3b
  616. ;cur00xy=cur0176
  617. ray00xy_YX=ray0176_YX
  618. ray00xy_YX2=ray0176_YX2
  619. ray4
  620.         BIT 7,L
  621.         JP NZ,ray4b
  622.         ;RAY 0,1,H,D,y,x ;4a
  623. cur01xy=$+1
  624.         LD DE,0
  625.         RAY 0,1,4,2,1,0;y,x ;4a
  626. ;cur01xy=cur0176
  627. ray01xy_YX=ray0176_YX
  628. ray01xy_YX2=ray0176_YX2
  629. ray4b
  630.         ;RAY 1,0,L,E,x,y ;4b
  631. cur10yx=$+1
  632.         LD DE,0
  633.         RAY 1,0,5,3,0,1;x,y ;4b
  634. ;cur10yx=cur0176
  635. ray10yx_YX=ray0176_YX
  636. ;ray10yx_YX2=ray0176_YX2
  637.  
  638. doorhlq
  639.         ld a,128
  640.         jr raydeq
  641. rayhlq_texxaxorb
  642.         xor b
  643.         ld b,a
  644. rayhlq
  645.         XOR A
  646. raydeq
  647. ;b=texx
  648. ;hl=YX
  649. ;dist*cos=ix+a
  650.  
  651.        PUSH HL
  652.         ADD A,LX
  653.         LD L,A
  654.         ADC A,HX
  655.         SUB L
  656.         LD H,A
  657. ;HL=dist*cos=128..#3fff
  658. ;приводим к 128..255
  659.         LD DE,#000
  660.         LD A,L
  661.         jr Z,TOLOGRLQ
  662.        DUP 5;6
  663.         INC D
  664.         SRL H
  665.         RRA
  666.         jr Z,TOLOGRLE
  667.        EDUP
  668. TOLOGRLQ ;
  669.        if antizalom;debug
  670.        cp 64
  671.        jr nc,$+4
  672.        ld a,64
  673.        else
  674.         OR A
  675.         JP M,$+5 ;>=128
  676.         LD A,128 ;<128
  677.        endif
  678. TOLOGRLE ;
  679.         LD L,A ;128..255
  680.        ;D=0..5
  681.         LD H,tlogd/256
  682. ;2.делим на cos
  683. rayrealangle=$+1
  684.         LD A,(tlogcos) ;0..63
  685.         ADD A,(HL) ;log(dist/2^N) = 128..255 for arg>=128
  686.        IF antizalom;debug
  687.        jr NC,$+3
  688.        INC D
  689.        ENDIF
  690.  
  691. ;3.умножение на corrdist(scrX) - получаем k/масштаб
  692. ;(сокращаем расстояние по краям в sqrt(2) раз)
  693. ;corrdist(scrX)=1/sqrt(1+scrX^2), где scrX=-1..+1
  694. ;из него номер таблицы масштабирования
  695. cura=$+1
  696.         LD HL,tcorrlogd ;L=scrX=0..255="-127.5..127.5"
  697.         SUB (HL) ;64..128
  698.        IF antizalom;debug
  699.        jr NC,DEBBP
  700.        DEC D
  701.        JP P,DEBBP
  702.        INC D
  703.        XOR A
  704. DEBBP ;
  705.        ENDIF
  706.         LD L,A
  707.         LD H,tlogd2sca/256
  708.          SRA D
  709.          RR E ;DE=+0,+#80,..+#300
  710.         ADD HL,DE
  711.        IF 0;debug
  712.         BIT 7,(HL)
  713.         jr NZ,$
  714.        ENDIF
  715.         LD C,(HL) ;dist(scale#)=63..1;127..1
  716.                   ;todo linear scale, recalc in DRAWWALLS
  717.          SCF
  718.          RR B ;texx=0x80..0xFF
  719.        IF scale64
  720.         SRL B ;texx=0x40..0x7F
  721.        ENDIF
  722.        POP DE
  723.         RET
  724.  
  725.        IF interpolate
  726.        IF 0
  727. I_SUB_INTERt ;
  728.         POP HL  ;
  729.         PUSH HL ;de
  730.         LD A,D
  731.         SUB H
  732.         jr NZ,holeny
  733.         LD A,E
  734.         SUB L
  735.         JP Z,I_SUB_INTER ;продолжение стены
  736.         DEC A
  737.         CP 3
  738.         jr C,nhole
  739.         JP isubneq
  740. holeny ;
  741.         DEC A
  742.         CP 3
  743.         jr NC,isubneq
  744.         LD A,E
  745.         CP L
  746.         jr NZ,isubneq
  747. nhole ;
  748.        ENDIF
  749. I_SUB_INTER
  750.          ; rightscan=Middlescan
  751.         LD A,C
  752.         EXX
  753.         ADD A,C
  754.         RRA
  755.         LD C,A ;dist
  756.         EXX
  757.         LD A,B
  758.         EXX
  759.         ADD A,B
  760.         RRA
  761.         LD B,A ;texx
  762. I_SUB_SCANQ ;
  763.          ;INTERPOLATE_SUB(a-step, step, leftscan, rightscan);r=M
  764.        PUSH HL ;step,a
  765.         LD A,L
  766.         SUB H
  767.         LD L,A ;a-step
  768.         LD A,H
  769.         LD H,distbuf/256+2
  770.         LD (HL),C ;dist
  771.         DEC H
  772.         LD (HL),B ;texx
  773.         DEC H
  774.         RRCA
  775.         CALL NC,INTERPOLATE_SUB
  776.         LD A,(DE) ;ID
  777.          ;ld a,0xc0
  778.         LD (HL),A ;ID
  779.          ;leftscan=rightscan ;=Middlescan
  780.         EXX
  781.        POP HL ;step,a
  782.          ;pop(rightscan)
  783.         POP DE
  784.         pop BC
  785.          ;INTERPOLATE_SUB(a, step, leftscan, rightscan) ;l=M,r=R
  786.          ;scan[a]=rightscan
  787.          ;if (step==1) exit
  788.         LD A,H
  789.         LD H,distbuf/256+2
  790.         LD (HL),C ;dist
  791.         DEC H
  792.         LD (HL),B ;texx
  793.         DEC H
  794.         RRCA
  795.         RET C
  796. INTERPOLATE_SUB
  797. ;L=a
  798. ;A=step/2                 ;not preserved
  799. ;BCDE'=leftscan ;(a-step) ;not preserved
  800. ;BCDE=rightscan ;(a)
  801. ;CY=0
  802.        EXA
  803.         LD A,(DE) ;ID
  804.         LD (HL),A ;ID ;texx,dist are written already
  805.        EXA
  806.          ;step=step/2
  807.         LD H,A
  808.          ;push(rightscan)
  809.         PUSH BC
  810.         push DE
  811.          ;if(rightscan.yx==leftscan.yx)
  812.      ;LD A,(DE)
  813.         EXX
  814.      ;EXD
  815.      ;XOR (HL)
  816.      ;EXD
  817.      ;JP Z,I_SUB_INTERt
  818.         POP HL  ;
  819.         PUSH HL ;de
  820.         ;OR A
  821.         SBC HL,DE ;CY=0
  822.         JP Z,I_SUB_INTER
  823. isubneq
  824.          ; rightscan=RAYCAST(a-step)
  825.         EXX
  826.         PUSH HL
  827.         LD A,L
  828.         SUB H
  829.         LD L,A ;a-step
  830.         ;LD (cura),A
  831.         CALL RAYCASTl
  832.         POP HL
  833.         JP I_SUB_SCANQ
  834.          ;else - see above
  835.        ENDIF ;interpolate
  836.  
  837.  
  838. ;============================
  839.        IF sprites
  840. DOSORTSPRITES=1
  841. ;CURSPRITES_RECSZ=5;4
  842.  
  843. SCANMONS
  844.         LD A,(curX)
  845.         SUB viewrange
  846.         LD (scmonX),A
  847.         LD A,(curY)
  848.         SUB viewrange
  849.         LD (scmonY),A
  850.        LD HL,cursprites
  851.       if DOSORTSPRITES
  852.        LD (HL),0 ;end of sprites
  853.       endif
  854.        LD (scaneof),HL
  855.         LD HL,MONSTRS+1 ;1+начало табл.монстров/предметов
  856.         ld hx,-1 ;monster index
  857.        jp SCMONS0 ;цикл скан-я видимых монстров/предметов
  858. SCMONNx
  859.         LD A,L
  860.         ADD A,8
  861.         LD L,A
  862.         JR C,SCMxIH
  863. SCMONS0
  864.        inc hx ;monster index
  865.         LD A,(HL) ;X
  866.         INC A
  867.        RET Z
  868. scmonX=$+1
  869.         SUB 0
  870.         CP viewrange*2+1
  871.         JP NC,SCMONNx
  872.         INC L
  873.         inc L
  874.         LD A,(HL)
  875. scmonY=$+1
  876.         SUB 0
  877.         CP viewrange*2+1
  878.         JR C,SCMONY
  879.         LD A,L
  880.         ADD A,6
  881.         LD L,A
  882.         JP NC,SCMONS0
  883. SCMxIH  INC H
  884.         JP SCMONS0
  885. SCMONY  DEC L
  886.         dec L
  887.         dec L
  888.         LD C,(HL)
  889.         INC L
  890.         LD B,(HL) ;Xx
  891.         INC L
  892.         LD E,(HL)
  893.         INC L
  894.         LD D,(HL) ;Yy
  895.         INC L
  896.    PUSH HL
  897.         PUSH BC
  898.        ld a,(IMavision+1)
  899.        sub (hl) ;DIR
  900.        inc l ;skip DIR (TODO use)
  901.        LD L,(HL) ;TYPE*8+phase
  902.        ld H,0
  903.         LD BC,MONSTAB-8
  904.         ADD HL,BC
  905.       if doublescr
  906.        ;a=mydir-objdir. если около 128, смотрит на нас. около 0 - от нас. около 64 - влево?
  907.         sub 32
  908.         rlca
  909.         rlca
  910.         rlca
  911.         and 6
  912.         add a,ZOMBIEMANrotate-ZOMBIEMANgo
  913.        ld c,a ;mydir-objdir
  914.       endif
  915.        LD A,(HL) ;ID текстуры (в зависимости от фазы)
  916.        ld lx,a ;!=0
  917.       if doublescr
  918.        ld a,l
  919.        cp 0xff&(3*8+0 + (MONSTAB-8))
  920.        jr z,goside_phase1
  921.        cp 0xff&(3*8+1 + (MONSTAB-8))
  922.        ;jr z,goside_phase2
  923.        jr nz,nogoside
  924. goside_phase2
  925. goside_phase1
  926.         ld b,0
  927.         add hl,bc
  928.         ld a,(hl)
  929.         ld lx,a
  930. nogoside
  931.       endif
  932.         POP BC
  933. ;calculate sprite position
  934.         LD HL,(curYy)
  935.         SBC HL,DE ;dYy со стороны игрока
  936.         ex de,hl;EXD
  937.         LD HL,(curXx)
  938.         SBC HL,BC ;dXx со стороны игрока
  939.        ;ld a,(curangle)
  940.         CALL OBJMUL
  941.        ;BC=dist
  942.        ;DE=xscr
  943.        IF lores
  944.         SRA D
  945.         RR E
  946.        ENDIF
  947.         LD HL,pixperchr*scrwid/2-256
  948.         SBC HL,DE
  949.         INC H
  950.        jr NZ,SCANnSPR ;X out of screen
  951.        IF lores
  952.         BIT 7,L
  953.        jr NZ,SCANnSPR ;X out of screen
  954.        ENDIF
  955. ;write data to cursprites
  956. ;ID 8 (0=end)
  957. ;dist 16
  958. ;xscr 8
  959. ;monster index
  960.        if DOSORTSPRITES == 0
  961.         LD A,L ;xscr
  962. scaneof=$+1
  963.         ld hl,0
  964.         ld e,lx
  965.         ld (hl),e ;id
  966.         inc l
  967.         ld (hl),c
  968.         inc l
  969.         ld (hl),b ;bc=dist
  970.         inc l
  971.         ld (hl),a ;xscr
  972.         inc l
  973.        if CURSPRITES_RECSZ == 5
  974.        ld a,hx
  975.        ld (hl),a ;monster index
  976.        inc l
  977.        endif
  978.         ld (hl),0
  979.         ld (scaneof),hl
  980.        else
  981.  
  982.        PUSH BC
  983.         EXX
  984.        POP BC
  985.         LD HL,cursprites+((-(CURSPRITES_RECSZ-2))&0xff)
  986. SCANsort0
  987.        if CURSPRITES_RECSZ == 5
  988.         INC L
  989.        endif
  990.         INC L
  991.         inc L
  992.         LD A,(HL)
  993.         OR A
  994.         jr Z,SCANins
  995.         INC L
  996.         LD E,(HL)
  997.         INC L
  998.         LD D,(HL) ;de=dist
  999.         ex de,hl;EXD
  1000.         SBC HL,BC
  1001.         ex de,hl;EXD
  1002.         jr NC,SCANsort0
  1003.         DEC L
  1004.         dec L
  1005. SCANins
  1006.        PUSH BC
  1007. scaneof=$+1
  1008.         LD DE,0
  1009.         LD A,E
  1010.         SUB L
  1011.         INC A ;bytes to move
  1012.         LD C,A
  1013.         LD B,0
  1014.         LD H,D
  1015.         ld L,E
  1016.         LD A,E
  1017.         ADD A,CURSPRITES_RECSZ;4
  1018.         LD E,A
  1019.         LD (scaneof),A
  1020.         LDDR
  1021.         INC HL
  1022.        POP BC
  1023.        LD A,lx;1
  1024. ;A=ID текстуры
  1025. ;BC'=dist
  1026. ;L'=xscr
  1027.         LD (HL),A
  1028.         INC L
  1029.         LD (HL),C
  1030.         INC L
  1031.         LD (HL),B
  1032.         INC L
  1033.         EXX
  1034.         LD A,L
  1035.         EXX
  1036.         LD (HL),A ;xscr
  1037.         INC L
  1038.        if CURSPRITES_RECSZ == 5
  1039.        ld a,hx
  1040.        ld (hl),a ;monster index
  1041.        inc l
  1042.        endif
  1043.         EXX
  1044.        endif
  1045. SCANnSPR ;
  1046.  
  1047.    POP HL
  1048.         INC L
  1049.         inc L
  1050.         inc L
  1051.         inc HL
  1052.        INC L
  1053.         JP SCMONS0
  1054.  
  1055. DRAWSPRITES
  1056. ;ID 8 (0=end)
  1057. ;dist 16
  1058. ;xscr 8
  1059. ;monster index
  1060.         LD IY,cursprites
  1061. DRAWSPRITES0 ;
  1062.         LD A,(IY) ;id
  1063.         OR A
  1064.         RET Z
  1065.         INC IY
  1066.         LD C,(IY)
  1067.         INC IY
  1068.         LD B,(IY) ;bc=dist
  1069.         INC IY
  1070. ;A=ID
  1071.         EXX
  1072.          LD D,a ;ID (не адрес)
  1073.         EXX
  1074.  
  1075.         LD L,(IY) ;xscr
  1076.         INC IY
  1077.        if CURSPRITES_RECSZ == 5
  1078.         INC IY
  1079.        endif
  1080. ;L=xscr
  1081. ;BC=dist
  1082.         call disttoscale
  1083. ;de=dist, c=scale#
  1084.        if atm
  1085.         ld a,l ;xscr
  1086.         ld h,d
  1087.         ld l,e
  1088.         srl h
  1089.         rr l
  1090.         add hl,de
  1091.         ex de,hl ;de = de * 1.5
  1092.         ld l,a ;xscr
  1093.        else
  1094.        IF loresspr
  1095.         SLA E
  1096.         RL D
  1097.        ENDIF
  1098.         SLA E
  1099.         RL D ;DE=texx step = de * 4
  1100.        endif
  1101.  
  1102.        IF loresspr_hires|optresspr
  1103.        RES 0,L
  1104.        ENDIF
  1105.         LD H,distbuf/256+2 ;ID,texx,dist
  1106.         LD A,C ;scale#
  1107.         CP (HL)
  1108.          if !atm
  1109.          ld hx,0xc0 ;TODO
  1110.          endif
  1111.         CALL NC,DRAWSPRITE ;object center is visible ;TODO независимо от видимости центра
  1112.         JP DRAWSPRITES0
  1113.  
  1114. disttoscale
  1115. ;bc=dist
  1116. ;out: de=dist, c=scale#
  1117. ;keep l=xscr
  1118.         INC B
  1119.         DJNZ gFILLNCLOSE
  1120.         LD A,108;64 ;от этого числа зависит только ширина спрайта при максимальном приближении, но не максимальная высота (она ограничена этим числом и сравнением дальше, закомментированным) ;108 чуть ниже ATM экрана, 128 запас около 8 пикс снизу
  1121.         CP C
  1122.          ;jr nc,DRAWSPRITES0 ;лампы не уменьшаем ;TODO уметь отличать врагов от ламп
  1123.         jr C,$+3
  1124.         LD C,A ;спрайт слишком близко!!! уменьшим
  1125. gFILLNCLOSE
  1126.        PUSH BC ;dist
  1127. ;приводим к 128..255
  1128.         LD DE,#000
  1129.         INC B
  1130.         DEC B
  1131.         LD A,C
  1132.         jr Z,MOTOLOGRLQ
  1133.        DUP 5;6
  1134.         INC D
  1135.         SRL B
  1136.         RRA
  1137.         jr Z,MOTOLOGRLE
  1138.        EDUP
  1139. MOTOLOGRLQ ;
  1140.         ;OR A
  1141.         ;JP M,$+5 ;>=128
  1142.         ;LD A,128 ;<128
  1143.         ;;cp 96
  1144.         ;;jr nc,$+4
  1145.         ;;ld a,96 ;спрайт слишком близко!!! увеличим dist для уменьшения высоты
  1146. MOTOLOGRLE ;
  1147.         LD C,A ;128..255 ;D=0..5
  1148.         LD B,tlogd/256
  1149.         LD A,(BC) ;log(dist) = 128..255 for arg>=128
  1150.        if atm==0
  1151.        SUB 16;64                 ;0..127 for arg=64..127 ;???
  1152.        endif
  1153.         LD C,A                ;0 for arg<64
  1154.         LD B,tlogd2sca/256
  1155.          SRA D
  1156.          RR E ;DE=+0,+#80,..+#300
  1157.         ex de,hl;EXD
  1158.         ADD HL,BC
  1159.         LD C,(HL) ;scale#
  1160.         ex de,hl;EXD
  1161.       ;
  1162.        POP DE ;dist
  1163.         ret
  1164.  
  1165. ;умножение
  1166. ;A=+-0.7
  1167. ;HL=A*DE
  1168.     ;A сохраняется!!!
  1169. MULT
  1170.         LD HL,0
  1171. MULTADD
  1172.         RLCA
  1173.         JR NC,MULTPLU
  1174.         DUP 6
  1175.         SRA D
  1176.         RR E
  1177.         RLCA
  1178.         JR C,$+4
  1179.         SBC HL,DE
  1180.         EDUP
  1181.         RLCA
  1182.         RET C
  1183.         SRA D
  1184.         RR E
  1185.          OR A
  1186.         SBC HL,DE
  1187.         RET
  1188. MULTPLU DUP 6
  1189.         SRA D
  1190.         RR E
  1191.         RLCA
  1192.         JR NC,$+3
  1193.         ADD HL,DE
  1194.         EDUP
  1195.         RLCA
  1196.         RET NC
  1197.         SRA D
  1198.         RR E
  1199.         ADD HL,DE
  1200.         RET
  1201.  
  1202. OBJMULQ
  1203.         POP AF ;X
  1204.        LD D,#40 ;X out of screen
  1205.         RET
  1206. ;пересчет относительных координат объекта (dXx=HL, dYy=DE)
  1207. ;в координаты на экране (DE=xscr, BC=расстояние)
  1208. OBJMUL
  1209.         PUSH HL ;X
  1210.        PUSH DE ;Y
  1211.        PUSH HL ;X
  1212.         LD HL,(curangle) ;L=центр взгляда (рассчитан в RAYPREPXY_hldea)
  1213.        ;ld l,a
  1214.         LD C,(HL) ;sin=шаг по Y
  1215.         LD A,-64
  1216.         SUB L
  1217.         LD L,A
  1218.         LD B,(HL) ;-COS=шаг по X
  1219.    ;Bc=DXdy=COSsin
  1220.         LD A,C
  1221.         CPL
  1222.         CALL MULT ;HL=A*DE=-sin*Y
  1223.        POP DE ;X
  1224.         LD A,B
  1225.         CALL MULTADD ;HL=-COS*X-sin*Y=d(расстояние по объекта)
  1226.        POP DE ;Y
  1227.         BIT 7,H
  1228.         jr NZ,OBJMULQ ;если расстояние<0,то объект за спиной=>exit
  1229.         LD (_OBJd1),HL
  1230.         CALL MULT;A=B=-COS, HL=-COS*Y
  1231.        POP DE ;X
  1232.         LD A,C
  1233.         CALL MULTADD ;HL=-COS*Y+sin*X=xscr*d
  1234.         ex de,hl;EXD
  1235. _OBJd1=$+1
  1236.         LD BC,0 ;BC=d ;после MONDIV получим DE=xscr
  1237.         ;jp MONDIV
  1238.        ENDIF ;sprites
  1239. ;деление
  1240. ;DE=+-7.8;BC=+7.8
  1241. ;DE=DE/BC=+-8.7/2
  1242.     ;BC сохраняется!!!
  1243. MONDIV
  1244.         LD H,0
  1245.         LD A,D
  1246.         SLA E
  1247.         RLA
  1248.         JP C,MONDIVNEG ;если делимое<0
  1249.         LD L,A
  1250.         INC E
  1251.         LD A,E
  1252.        DUP 7
  1253.         SBC HL,BC
  1254.         JR NC,$+3
  1255.         ADD HL,BC
  1256.         RLA
  1257.         ADC HL,HL
  1258.        EDUP
  1259.         CPL
  1260.         LD D,A
  1261.        DUP 7
  1262.         SBC HL,BC
  1263.         JR NC,$+3
  1264.         ADD HL,BC
  1265.         RLA
  1266.         ADD HL,HL
  1267.        EDUP
  1268.         SBC HL,BC
  1269.         JR NC,$+3
  1270.         ADD HL,BC
  1271.         RLA
  1272.         CPL
  1273.         LD E,A
  1274.         RET
  1275. ;если делимое<0
  1276. MONDIVNEG
  1277.         CPL
  1278.         LD L,A
  1279.         SBC A,A
  1280.         XOR E
  1281.        DUP 7
  1282.         SBC HL,BC
  1283.         JR NC,$+3
  1284.         ADD HL,BC
  1285.         RLA
  1286.         ADC HL,HL
  1287.        EDUP
  1288.         LD D,A
  1289.        DUP 7
  1290.         SBC HL,BC
  1291.         JR NC,$+3
  1292.         ADD HL,BC
  1293.         RLA
  1294.         ADD HL,HL
  1295.        EDUP
  1296.         SBC HL,BC
  1297.         JR NC,$+3
  1298.         ADD HL,BC
  1299.         RLA
  1300.         LD E,A
  1301.         RET
  1302.