?login_element?

Subversion Repositories NedoOS

Rev

Rev 772 | Rev 1907 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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