?login_element?

Subversion Repositories NedoOS

Rev

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

  1.         DEVICE ZXSPECTRUM128
  2.         include "../../_sdk/sys_h.asm"
  3.  
  4. EGA=1;0
  5.  
  6. COLOR_SKY=0b11101101
  7. COLOR_SKYDARK=0b00101101
  8. COLOR_SHADOW=0
  9. COLOR_SQUARE0=0b00001001
  10. COLOR_SQUARE1=0b11110110
  11.  
  12. ;GO=0x6001;0x8001
  13.  
  14. SCRHGT=176
  15. YMID88=88
  16.  
  17. SQUAREMUL=1
  18. SQUARESQR=1
  19. showtime=0;1
  20. fastest=1
  21. original_coords=1
  22.  
  23. ;IMVEC=0x7d00;0xae00;0xbe00
  24. ;IMER=(IMVEC/256+1)*257
  25.        
  26. SQRTFIXK=256
  27. FIXK=(SQRTFIXK*SQRTFIXK)
  28. FIXKDIV2=(FIXK/2)
  29.  
  30. spheres=0x02
  31.  
  32. cx0=-(30*FIXK/100>>8) ;-30
  33. cy0=-(80*FIXK/100>>8) ;-80
  34. cz0=(300*FIXK/100>>8) ;300
  35. r0=(60*FIXK/100>>8) ;60
  36.  
  37.         if original_coords
  38. cx1=(83*FIXK/100>>8) ;90 ;88
  39. cy1=-(120*FIXK/100>>8) ;-110 ;-114
  40. cz1=(200*FIXK/100>>8)
  41. r1=(20*FIXK/100>>8)
  42.         else
  43. cx1=(87*FIXK/100>>8) ;90
  44. cy1=-(100*FIXK/100>>8) ;-110 (100 оптимизируется MegaLZ)
  45. cz1=(200*FIXK/100>>8) ;200 (200 оптимизируется MegaLZ)
  46. r1=(20*FIXK/100>>8) ;20
  47.         endif
  48.  
  49. q0=(r0*r0>>8)
  50. q1=(r1*r1>>8)
  51.        
  52. GROUND=0x3e;0x7f ;код команды ld a,N
  53. SKY=0xff
  54. EYEX=(30*FIXK/100)
  55. EYEY=-(50*FIXK/100)
  56. EYEZ=(0*FIXK/100)
  57. KVECTOR=64
  58. ;EYEDZ=(300*FIXK/KVECTOR)
  59. EYEDZ=(256*FIXK/KVECTOR)
  60. EYEDZDIVFIXK=(EYEDZ/SQRTFIXK)
  61. SQEYEDZ=(EYEDZDIVFIXK*EYEDZDIVFIXK)
  62.  
  63.         include "math.asm"
  64.  
  65. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;        
  66.         org PROGSTART
  67. begin
  68.         ld sp,0x4000 ;не должен опускаться ниже 0x3b00! иначе возможна порча OS
  69.         OS_HIDEFROMPARENT
  70.        if EGA
  71.         ld e,0+0x80 ;EGA + keep gfx pages
  72.        else
  73.         ld e,3+0x80 ;6912 + keep gfx pages
  74.        endif
  75.         OS_SETGFX ;e=0:EGA, e=2:MC, e=3:6912, e=6:text ;+SET FOCUS ;e=-1: disable gfx (out: e=old gfxmode)
  76.  
  77.         ld e,0
  78.         OS_CLS
  79.  
  80.         if EGA == 0
  81.         ld a,(user_scr0_high) ;ok
  82.         SETPG16K
  83.         xor a
  84.         ;out (0xfe),a
  85.         ld de,0x5801
  86.         ld h,d
  87.         ld l,a
  88.         ld bc,767
  89.         ld (hl),7
  90.         ldir
  91.         endif
  92.  
  93.         if SQUAREMUL
  94. ;d.e * b.c = 0.5*(d.e+b.c)^2 - 0.5*d.e^2 - 0.5*b.c^2
  95. ;адрес в таблице: %1hhhhhhh.lllllll0
  96. ;максимум = 127^2/2 = #1f80
  97.         ;ex de,hl ;hl=0 after dehrum
  98.         ld de,#8000
  99.         ;ld sp,hl
  100.         xor a ;сумма мл
  101.         ld h,a
  102.         ld l,a
  103.         ;ld d,a
  104.         ;ld e,a
  105.         ;ld b,a
  106.         ;ld c,a
  107.         ;ld de,0 ;сумма
  108.         ld bc,0 ;счётчик
  109.         ld lx,a ;счётчик мл
  110. mksquare
  111.         ex de,hl
  112.         ld (hl),e
  113.         inc l
  114.         ld (hl),d
  115.         inc lx
  116.         inc lx
  117.         inc lx
  118.         inc lx
  119.         jr nz,$+3
  120.         inc bc
  121.         add a,lx
  122.         ex de,hl ;тут лучше
  123.         adc hl,bc
  124.         ;ex de,hl
  125.        
  126.         ;inc hl
  127.         ;inc h
  128.         ;dec h
  129.         inc de
  130.         inc d
  131.         dec d
  132.         jr nz,mksquare
  133.         endif
  134.  
  135.         if !SQUARESQR
  136.         ld bc,1
  137.         ld de,tsqr
  138.         ;ld hl,0 ;выгоднее на MegaLZ и Hrum (после dehrum уже hl=0, de=rnd, bc=#1010)
  139. mksqr0
  140.         ex de,hl
  141.         ld (hl),e
  142.         inc h
  143.         ld (hl),d
  144.         dec h
  145.         ex de,hl
  146.         add hl,bc
  147.         inc bc
  148.         inc bc
  149.         inc e
  150.         jr nz,mksqr0
  151. ;e=0
  152. ;hl=0
  153. ;bc=0x201
  154.         endif
  155.  
  156.         if showtime
  157.         ld de,IMVEC;0xbe00 ;выгоднее на MegaLZ
  158.         ld a,d
  159.         ld i,a
  160.         inc a
  161.         ;ld a,IMER/256
  162.         ld (de),a
  163.         inc e
  164.         jr nz,$-2
  165.         inc d
  166.         ld (de),a
  167.         ld e,d
  168.         ld hl,on_int.
  169.          ld b,1
  170.         ldir
  171.         im 2
  172.         ei
  173.         else
  174.         ;di
  175. raytrace_begin
  176.         ;ld a,0xaf
  177.         endif
  178.  
  179.         if 1==1
  180.         ld l,2*(spheres-1)+1
  181. mkbounding0
  182.         push hl
  183.          dec l
  184.         ld h,cz/256
  185.         ld c,(hl)
  186.         inc l
  187.         ld b,(hl)
  188. ;de=cz
  189.         ;ld hl,-EYEZ ;0
  190.         ;add hl,de
  191.         ;ld b,h
  192.         ;ld c,l
  193. ;bc=sub(cz[k],EYEZ) >= 0
  194.         ;pop hl
  195.         ;push hl
  196.         inc h ;ld h,rad/256
  197.         ld d,(hl)
  198.         dec l
  199.         ld e,(hl)
  200.         ld a,d
  201.         or a
  202.         ex af,af' ;'
  203.         DIVDEBC_AXSIGN_NONEGBC ;(keep bc)
  204.         pop hl
  205.         ld h,projr/256
  206.         push hl
  207.         ld (hl),e
  208.        
  209.         ld h,cx/256
  210.         ld d,(hl)
  211.         dec l
  212.         ld e,(hl)
  213.         ld hl,-((EYEX>>8)&0xffff)&0xffff
  214.         add hl,de
  215.         ex de,hl
  216.         ld a,d
  217.         or a
  218.         ex af,af' ;'
  219.         DIVDEBC_AXSIGN_NONEGBC ;(keep bc)
  220.         pop hl
  221.         inc h
  222.         push hl
  223.         ;ld h,projx/256
  224.         ld (hl),e
  225.        
  226.         ld h,cy/256
  227.         ld d,(hl)
  228.         dec l
  229.         ld e,(hl)
  230.         ld hl,-((EYEY>>8)&0xffff)&0xffff
  231.         add hl,de
  232.         ex de,hl
  233.         ld a,d
  234.         or a
  235.         ex af,af' ;'
  236.         DIVDEBC_AXSIGN_NONEGBC ;(keep bc)
  237.         pop hl
  238.         ;inc h
  239.         ;ld h,projy/256
  240.          dec l
  241.         ld (hl),e
  242.  
  243.         dec l
  244.         jp p,mkbounding0
  245.        
  246.         endif
  247.        
  248. ;  i = 0x00;
  249. ;  REPEAT {
  250. ;    //eyedy = ((FLOAT)(88)-(FLOAT)(i))<<10L;
  251. ;    //eyedy = mul(((FLOAT)(88)-(FLOAT)(i))*FIXK, MULVECTOR);
  252. ;    //sqeyedy = sq(eyedy);
  253. ;    count_eyedy();
  254. ;    j = 0x00;
  255. ;    REPEAT {
  256. ;      tracepixel(i,j);
  257. ;      INC j;
  258. ;    }UNTIL (j == 0x00);
  259. ;    INC i;
  260. ;  }UNTIL (i == 0xb0);
  261.         ld a,SCRHGT-1;0xaf
  262. raytrace_lines0        
  263. ;//eyedy = ((FLOAT)(88)-(FLOAT)(i))<<10L;
  264. ;//eyedy = mul(((FLOAT)(88)-(FLOAT)(i))*FIXK, MULVECTOR);
  265.         ld (tracepixel.i),a
  266.         sub YMID88
  267.          ld (scryHSB),a
  268.         ld l,a
  269.         SBC A,a
  270.         ld h,a
  271.         add hl,hl
  272.         add hl,hl
  273.         LD [eyedyUINT],hl
  274.         SQHL
  275.         LD hl,+(SQEYEDZ>>8)&0xffff
  276.         add hl,de
  277.         LD [sqeyedyUINT],HL
  278.        
  279.        if EGA
  280.         xor a ;X
  281. raytrace_pixels0
  282.        push af ;X
  283.         and 2
  284.         ld a,(user_scr0_high) ;ok
  285.         jr nz,$+5
  286.         ld a,(user_scr0_low) ;ok
  287.         SETPG16K
  288.        pop af
  289.        push af
  290.         call tracepixel ;A=pixel color
  291.         ex af,af' ;'
  292.         ld hl,(tracepixel.i) ;Y
  293.         ld h,0x40/32
  294.         ld b,0
  295.         ld c,l
  296.         add hl,hl
  297.         add hl,hl
  298.         add hl,bc ;*5
  299.         add hl,hl
  300.         add hl,hl
  301.         add hl,hl ;Y*40
  302.        pop af ;X
  303.         ld c,a
  304.         ex af,af' ;'
  305.         srl c ;X0 TODO
  306.         jr c,raytrace_pixel_right
  307.         and 0b01000111
  308.         jr raytrace_pixel_leftq
  309. raytrace_pixel_right
  310.         and 0b10111000
  311. raytrace_pixel_leftq
  312.         srl c
  313.         srl c
  314.         jr nc,$+4
  315.          set 5,h
  316.         inc c
  317.         inc c
  318.         inc c
  319.         inc c
  320.         ld b,0
  321.         add hl,bc
  322.         or (hl)
  323.         ld (hl),a
  324.         ex af,af' ;'
  325.  
  326.         inc a
  327.         jr nz,raytrace_pixels0
  328.        
  329.        else
  330.         ld a,(tracepixel.i) ;Y
  331.         ld c,0
  332.         ;call 8880
  333.         ld b,a
  334.         and a
  335.         rra
  336.         scf
  337.         rra
  338.         and a
  339.         rra
  340.         xor b
  341.         and 0xf8
  342.         xor b
  343.         ld h,a
  344.         ld a,c
  345.         rlca
  346.         rlca
  347.         rlca
  348.         xor b
  349.         and 0xc7
  350.         xor b
  351.         rlca
  352.         rlca
  353.         ld l,a
  354.         xor a ;X
  355. raytrace_pixels0
  356.         push af
  357.          push hl
  358.         call tracepixel ;CY=pixel color
  359.          pop hl
  360.         rl (hl)
  361.         pop af
  362.         inc a
  363.         push af
  364.         and 7
  365.         jr nz,nonextbyte
  366.         inc l
  367. nonextbyte
  368.         pop af
  369.         jr nz,raytrace_pixels0
  370.        endif
  371. tracepixel.i=$+1
  372.         ld a,0
  373.         dec a;sub 1
  374.         jp nz,raytrace_lines0
  375.        
  376.         YIELDGETKEYLOOP
  377.         QUIT
  378.        
  379.         if showtime
  380.         ld iy,23610
  381.         ld hl,10072
  382.         exx
  383.         im 1
  384. _TIMER=$+1
  385.         ld bc,0
  386.         sla c
  387.         rl b
  388.         ld sp,0x5fe8
  389.         ;ret
  390.  
  391. on_int.
  392.         push hl
  393. ;_TIMER=$+1+IMER-on_int.
  394.         ld hl,(_TIMER);0
  395.         inc hl
  396.         ld (_TIMER),hl
  397.         pop hl
  398.         ei
  399.         ret
  400.         else
  401.         if 1==1
  402.         halt
  403.         else
  404.         ;ld hl,cz
  405.         ;ld a,(hl)
  406.         ;sub 5
  407.         ;ld (hl),a
  408.         ;ld hl,cz+2
  409.         ;ld a,(hl)
  410.         ;add a,5
  411.         ;ld (hl),a
  412.        
  413.         ld hl,cy
  414.         inc (hl)
  415.         ;inc hl
  416.         ;inc hl
  417.         ;dec (hl)
  418.         jp raytrace_begin
  419.         endif
  420.         endif
  421.  
  422. tracepixel
  423. ;//x = EYEX;
  424. ;//y = EYEY;
  425. ;//z = EYEZ;
  426. ;//dx = ((FLOAT)(j)-(FLOAT)(128))<<10L; //dx = mul(((FLOAT)(j)-(FLOAT)(128))*FIX
  427. ;//dy = eyedy;
  428. ;//dz = EYEDZ; //mul((FLOAT)(300)*FIXK, MULVECTOR);
  429. ;//dd = sq(dx) + sqeyedy + SQEYEDZ; //sq(dz); //dx*dx+dy*dy+dz*dz;
  430. ;a = j
  431. eyedyUINT=$+1
  432.         LD hl,0 ;+(EYEDZ>>8)&0xffff и т.п. невыгодно
  433.         LD [tracepixel.dyUINT],HL
  434.         LD HL,+(EYEDZ>>8)&0xffff
  435.         LD [tracepixel.dzUINT],HL
  436.         LD hl,+(EYEX>>8)&0xffff
  437.         LD [tracepixel.xUINT],hl
  438.         LD hl,+(EYEZ>>8)&0xffff ;ld l,h проигрывает 2 байта в MegaLZ, 1 байт в Hrum
  439.         LD [tracepixel.zUINT],hl
  440.         LD hl,+(EYEY>>8)&0xffff
  441.         LD [tracepixel.yUINT],hl
  442.         sub l;128
  443.          ld (scrxHSB),a
  444.         ld l,a
  445.         SBC A,a
  446.         ld h,a
  447.         add hl,hl
  448.         add hl,hl
  449.         ld (tracepixel.dxUINT),hl
  450.         SQHL ;out: de
  451. sqeyedyUINT=$+1
  452.         LD hl,+(SQEYEDZ>>8)&0xffff;0
  453.         add hl,de
  454.         LD [tracepixel.ddUINT],HL
  455. tracepixel.L100
  456. ;//IF (positive(y) || negative(dy)) { n = SKY; s = 0x7fffffffL; }ELSE { n = GROUND; s = neg(idiv(y, dy)); };
  457.  
  458.         LD BC,[tracepixel.dyUINT] ;лучшая перестановка
  459.        ld hl,[tracepixel.yUINT]
  460.        ld a,h
  461.        cpl
  462.        or b
  463.         LD [tracepixel.sUINT+1],a
  464.         JP M,skyorground_count_s.q
  465. ;P
  466.          ex de,hl ;de=y
  467.        DIVDEBC_ASIGN ;de / bc
  468.         LD [tracepixel.sUINT],de
  469.         LD A,GROUND
  470. skyorground_count_s.q
  471.         LD [tracepixel.n],A
  472.        
  473.         ld l,2*(spheres-1)+1
  474. checkbounding0
  475.         ld h,projr/256
  476.         ld e,(hl) ;projr
  477.         inc h;ld h,projx/256
  478. scrxHSB=$+1
  479.         ld a,GROUND;0
  480.         sub (hl) ;a = SCRX - projx
  481.         dec l
  482.         add a,e ;a = SCRX - (projx-projr)
  483.         jp m,tracepixel.NOTFOUNDb
  484.         srl a
  485.         cp e
  486.         jp nc,tracepixel.NOTFOUNDb
  487.         ;inc h;ld h,projy/256
  488. scryHSB=$+1
  489.         ld a,GROUND;0
  490.         sub (hl) ;a = SCRY - projy
  491.         add a,e ;a = SCRY - (projy-projr)
  492.         jp m,tracepixel.NOTFOUNDb
  493.         srl a
  494.         cp e
  495.         ;jr nc,tracepixel.NOTFOUNDb
  496.         jr c,checkspheres
  497.          ;ld a,(scrxHSB)
  498.          ;ld hl,scryHSB
  499.          ;xor (hl)
  500.          ;rra
  501.          ;ret c
  502. tracepixel.NOTFOUNDb
  503.         dec l
  504.         jp p,checkbounding0
  505.         jp checkspheresq
  506.        
  507. checkspheres
  508.          ;jp tracepixel.NOTFOUND
  509.         ld a,2*(spheres-1)
  510. tracepixel.checkspheres0
  511.         LD [tracepixel.k],A
  512. ;//ищем сферу, на которую смотрим (если есть)
  513. ;//px = cx[k] - x;
  514. ;//py = cy[k] - y;
  515. ;//pz = cz[k] - z;
  516. ;//pp = sq(px) + sq(py) + sq(pz);
  517. ;//sc = mul(px,dx) + mul(py,dy) + mul(pz,dz);
  518.        ld (count_pxpypzppsc_cxaddr),a
  519.        ld (count_pxpypzppsc_cyaddr),a
  520.        ld (count_pxpypzppsc_czaddr),a
  521.        
  522. ;центр проекции сферы: cx[k]/pz, cy[k]/pz
  523. ;радиус проекции сферы: r[k]/pz
  524. ;    IF (!(
  525. ;        (SCRX >= sub(projx[k],projr[k]))
  526. ;      &&(SCRX < add(projx[k],projr[k]))
  527. ;      &&(SCRY >= sub(projy[k],projr[k]))
  528. ;      &&(SCRY < add(projy[k],projr[k]))
  529. ;       )) {
  530. ;      goto L200; //не та сфера
  531. ;    };
  532.        
  533. count_pxpypzppsc_czaddr=$+1
  534.         ld hl,(cz)
  535. tracepixel.zUINT=$+1
  536.         LD bc,0;x0101
  537.         ;or a
  538.         SBC HL,bc
  539.         push hl ;pz=cz[k]-z
  540.         SQHL ;out: de
  541.         ld hy,d
  542.         ld ly,e ;sq(pz)
  543. count_pxpypzppsc_cyaddr=$+1
  544.         ld hl,(cy)
  545. tracepixel.yUINT=$+1
  546.         LD bc,0;x0101
  547.         ;or a
  548.         SBC HL,bc
  549.         push hl ;py=cy[k]-y
  550.         SQHL ;out: de
  551.         add iy,de ;sq(pz) + sq(py)
  552. count_pxpypzppsc_cxaddr=$+1
  553.         ld hl,(cx)
  554. tracepixel.xUINT=$+1
  555.         LD bc,0;x0101
  556.         SBC HL,bc
  557.         push hl ;px=cx[k]-x
  558.         SQHL ;out: de
  559.         add iy,de
  560.         LD [tracepixel.ppUINT],iy ;pp = sq(px) + sq(py) + sq(pz)
  561.        
  562.         pop bc ;px=cx[k]-x
  563. tracepixel.dxUINT=$+1
  564.         LD de,0;x1111
  565.         MULDEBC_TOIY
  566.         pop bc ;py=cy[k]-y
  567. tracepixel.dyUINT=$+1
  568.         LD de,0;x1111
  569.         MULDEBC
  570.         add iy,de
  571.         pop bc ;pz=cz[k]-z
  572. tracepixel.dzUINT=$+1
  573.         LD de,0;x1111
  574.         MULDEBC
  575.         add iy,de ;sc = mul(px,dx) + mul(py,dy) + mul(pz,dz)
  576. ;//IF (negative(sc)) { goto L200; }; //не та сфера
  577. ;//bb = idiv(sq(sc),dd); //sc*sc/dd;
  578. ;//aa = q[k]-pp+bb; //add(sub(q[k],pp),bb); //q[k]-pp+bb;
  579. ;//IF (negative(aa)) { goto L200; }; //не та сфера
  580. ;//s = idiv(root(bb)-root(aa), root(dd)); //(sqrt(bb)-sqrt(aa))/sqrt(dd);
  581. ;//n = k;
  582. ;//goto LFOUND;
  583. ;//L200:
  584.        ld d,hy
  585.        ld e,ly ;de = sc = mul(px,dx) + mul(py,dy) + mul(pz,dz) ;ниже невыгодно в MegaLZ (2 байта)
  586.         LD a,d
  587.         or a;rla
  588.         JP M,tracepixel.NOTFOUND ;выгоднее в MegaLZ
  589.         if SQUARESQR
  590.         set 7,d
  591.         res 0,e
  592.         ex de,hl
  593.         ld e,(hl)
  594.         inc l
  595.         ld d,(hl)
  596.         ;ld a,l
  597.         ;cp 8 ;костыль для младшего бита
  598.         rl e;sla e
  599.         rl d
  600.         else
  601.         SQDE
  602.         endif
  603. tracepixel.ddUINT=$+1
  604.         LD bc,0
  605.         DIVDEBC_POSITIVE ;de = bb
  606.         ld hl,(q)
  607. tracepixel.k=$-2
  608. checksphereradius_qaddr=$-2
  609.         add hl,de ;q[k]+bb ;CY=0, т.к. q[k] (>=0) + bb (>=0)
  610. tracepixel.ppUINT=$+1
  611.         LD bc,0;x0101
  612.         ;or a
  613.         sbc hl,bc ;q[k]+bb-pp
  614.         JP M,tracepixel.NOTFOUND
  615.          push de ;bb
  616.         ROOTHL
  617.          ex (sp),hl ;push sqrt(aa), pop bb
  618.         ROOTHL;call root0hl0
  619.          pop bc ;sqrt(aa)
  620.         ;or a
  621.         SBC HL,bc ;hl = sqrt(bb)-sqrt(aa)
  622.          push hl
  623.         LD hl,[tracepixel.ddUINT]
  624.         ROOTHL
  625.         ld b,h
  626.         ld c,l ;bc = sqrt(dd)
  627.          pop de ;de = sqrt(bb)-sqrt(aa)
  628.         DIVDEBC_POSITIVE ;sqrt(bb)-sqrt(aa) >= 0
  629.         LD [tracepixel.sUINT],de ;s = (sqrt(bb)-sqrt(aa))/sqrt(dd)
  630.         LD A,(tracepixel.k);0x3e
  631.         LD [tracepixel.n],A
  632.         ;de = s
  633.         jr tracepixel.FOUND
  634. tracepixel.NOTFOUND ;не та сфера
  635.         ld a,(tracepixel.k)
  636.         sub 2
  637.         JP nc,tracepixel.checkspheres0
  638. checkspheresq
  639.  
  640.         LD A,[tracepixel.n]
  641.         or a ;SUB 0x80
  642.        if EGA
  643. tracepixel.sUINT=$+1
  644.         LD de,0
  645.         jp M,tracepixel.sky ;//небо
  646.        else
  647.         ret M ;nc ;//небо
  648. tracepixel.sUINT=$+1
  649.         LD de,0
  650.        endif
  651. tracepixel.FOUND
  652. ;de = s
  653. ;//dx = mul(dx,s); //dx*s;
  654. ;//dy = mul(dy,s); //dy*s;
  655. ;//dz = mul(dz,s); //dz*s;
  656. ;//dd = mul(sq(s),dd); //dd*s*s;
  657. ;//x = x + dx;  //x+dx;
  658. ;//y = y + dy; //y+dy;
  659. ;//z = z + dz; //z+dz;
  660.         if SQUAREMUL
  661.         set 7,d
  662.         res 0,e
  663.         endif
  664.         LD bc,(tracepixel.dxUINT)
  665.         MULDEBC_TOHL_DEPOSITIVE
  666.         if SQUAREMUL
  667.         dec e
  668.         endif
  669.         LD [tracepixel.dxUINT],hl ;dx = dx*s
  670.         LD bc,[tracepixel.xUINT]
  671.         add hl,bc
  672.         LD [tracepixel.xUINT],hl ;x = x+dx
  673.         LD bc,[tracepixel.dyUINT]
  674.         MULDEBC_TOHL_DEPOSITIVE
  675.         if SQUAREMUL
  676.         dec e
  677.         endif
  678.         LD [tracepixel.dyUINT],hl ;dy = dy*s
  679.         LD bc,[tracepixel.yUINT]
  680.         add hl,bc
  681.         LD [tracepixel.yUINT],hl ;y = y+dy
  682.         LD bc,[tracepixel.dzUINT]
  683.         MULDEBC_TOHL_DEPOSITIVE
  684.         if SQUARESQR&SQUAREMUL
  685.         dec e ;выигрыш 1 байт по сравнению с dec l
  686.         endif
  687.         LD [tracepixel.dzUINT],hl ;dz = dz*s
  688.         LD bc,[tracepixel.zUINT]
  689.         add hl,bc
  690.         LD [tracepixel.zUINT],hl ;z = z+dz
  691.  
  692.         if SQUARESQR&SQUAREMUL
  693.         ex de,hl
  694.         ld e,(hl)
  695.         inc l
  696.         ld d,(hl)
  697.         ld a,l
  698.         cp 8 ;костыль для младшего бита
  699.         rl e;sla e
  700.         rl d
  701.         else
  702.         LD HL,[tracepixel.sUINT]
  703.         SQHL ;out: de
  704.         endif
  705.         LD bc,[tracepixel.ddUINT]
  706.         MULDEBC_TOHL_POSITIVE
  707.         LD [tracepixel.ddUINT],hl ;dd = dd*s*s
  708.  
  709. tracepixel.n=$+1
  710.         LD A,0x3e
  711.         cp GROUND
  712.         JP z,tracepixel.ground ;//земля
  713. ;//nx = x - cx[n];
  714. ;//ny = y - cy[n];
  715. ;//nz = z - cz[n];
  716. ;//l = idiv(mul2( mul(dx,nx) + mul(dy,ny) + mul(dz,nz)), /**nn*/sq(nx) + sq(ny)
  717. ;//dx = dx - mul(nx,l); //dx-nx*l;
  718. ;//dy = dy - mul(ny,l); //dy-ny*l;
  719. ;//dz = dz - mul(nz,l);  //dz-nz*l;
  720.         ld (count_reflection_cxaddr),a
  721.         ld (count_reflection_cyaddr),a
  722.         ld l,a
  723.         LD h,cz/256
  724.         ld c,(hl)
  725.         inc l
  726.         ld b,(hl)
  727.         LD HL,[tracepixel.zUINT]
  728.         SBC HL,BC
  729.         LD [tracepixel.nz],HL ;z-cz[n]
  730.         SQHL ;out: de
  731.         ld hy,d
  732.         ld ly,e
  733. count_reflection_cyaddr=$+2
  734.         LD bc,(cy)
  735.         LD HL,[tracepixel.yUINT]
  736.         SBC HL,BC
  737.         LD [tracepixel.ny],HL ;y-cy[n]
  738.         SQHL ;out: de
  739.         add iy,de
  740. count_reflection_cxaddr=$+2
  741.         LD bc,(cx)
  742.         LD HL,[tracepixel.xUINT]
  743.         SBC HL,BC
  744.         LD [tracepixel.nx],HL ;x-cx[n]
  745.         SQHL ;out: de
  746.         add iy,de
  747.          push iy ;делитель = sq(nx)+sq(ny)+sq(nz)
  748.  
  749. tracepixel.nx=$+1
  750.         LD bc,0;x0101
  751.         LD de,[tracepixel.dxUINT]
  752.         MULDEBC_TOIY
  753. tracepixel.ny=$+1
  754.         LD bc,0;x0101
  755.         LD de,[tracepixel.dyUINT]
  756.         MULDEBC
  757.         add iy,de
  758. tracepixel.nz=$+1
  759.         LD bc,0;x0101
  760.         LD de,[tracepixel.dzUINT]
  761.         MULDEBC
  762.         add iy,de
  763.         ld d,hy
  764.         ld e,ly
  765.         rl e
  766.         rl d ;for sign ;de = делимое = 2*(dx*nx+dy*ny+dz*nz)
  767.          pop bc ;bc = делитель = sq(nx)+sq(ny)+sq(nz)
  768.         ;ld a,d
  769.         ;xor b
  770.         ex af,af' ;'
  771.         DIVDEBC_AXSIGN_NONEGBC ;de / bc
  772.          push de ;tracepixel.l = 2*(dx*nx+dy*ny+dz*nz)/(sq(nx)+sq(ny)+sq(nz)) ;со знаком
  773.  
  774.         LD bc,[tracepixel.nx] ;со знаком
  775.         MULDEBC
  776.         ld hl,(tracepixel.dxUINT)
  777.         ;or a
  778.         sbc hl,de;bc
  779.         ld (tracepixel.dxUINT),hl ;dx-nx*l
  780.          pop de
  781.          push de ;tracepixel.l
  782.         LD bc,[tracepixel.ny] ;со знаком
  783.         MULDEBC
  784.         ld hl,(tracepixel.dyUINT)
  785.         ;or a
  786.         sbc hl,de;bc
  787.         ld (tracepixel.dyUINT),hl ;dy-ny*l
  788.          pop de ;tracepixel.l
  789.         LD bc,[tracepixel.nz] ;со знаком
  790.         MULDEBC
  791.         ld hl,(tracepixel.dzUINT)
  792.         ;or a
  793.         sbc hl,de;bc
  794.         ld (tracepixel.dzUINT),hl ;dz-nz*l
  795.         JP tracepixel.L100 ;//отражение
  796.        
  797.         if EGA
  798. tracepixel.sky
  799.         if SQUAREMUL
  800.         set 7,d
  801.         res 0,e
  802.         endif
  803.         LD bc,[tracepixel.dyUINT] ;<0
  804.         ;MULDEBC_TOHL_DEPOSITIVE
  805.         ;if SQUAREMUL
  806.         ;dec e
  807.         ;endif
  808.         ;LD [tracepixel.dyUINT],hl ;dy = dy*s
  809.          srl b
  810.          rr c
  811.          srl b
  812.          rr c
  813.         ;c=яркость
  814.  
  815.          ld a,(scrxHSB)
  816.          and 3
  817.          ld b,a
  818.          ld a,(tracepixel.i)
  819.          and 3
  820.          add a,a
  821.          add a,a
  822.          add a,b
  823.          ld hl,tchunk
  824.          add a,l
  825.          ld l,a
  826.          jr nc,$+3
  827.          inc h
  828.         ld a,(hl)
  829.         cp c
  830.  
  831.        ld a,COLOR_SKY
  832.         ret c
  833.        ld a,COLOR_SKYDARK
  834.         ret
  835.  
  836. tchunk
  837.         db 0x08, 0x88, 0x28, 0xa8
  838.         db 0xc8, 0x48, 0xe8, 0x68
  839.         db 0x38, 0xb8, 0x18, 0x98
  840.         db 0xf8, 0x58, 0xd8, 0x58
  841.         endif
  842.        
  843.        
  844. tracepixel.ground
  845. ;//земля
  846. ;//k = 0x00;
  847. ;//REPEAT {
  848. ;//  IF (less((sq(/**u*/cx[k]-x) + sq(/**v*/cz[k]-z)), q[k])) {goto RETURNME;};
  849. ;//  INC k;
  850. ;//}UNTIL (k == spheres);
  851. ;//IF (fract(x) != fract(z)) {
  852. ;//  invpix(j,i)
  853. ;//};   //((x+100)-(int)(x+100))  //(z-(int)(z))
  854.         ld a,2*(spheres-1)
  855. drawground_findshadow0
  856.         LD [tracepixel.k],A
  857.         ld (drawground_findshadow_qaddr),a
  858.         ld (drawground_findshadow_cxaddr),a
  859.         LD l,A
  860.         LD h,cz/256
  861.         LD E,[HL]
  862.         INC L
  863.         LD D,[HL]
  864.         LD hl,[tracepixel.zUINT]
  865.         sbc hl,de
  866.         SQHL ;out: de
  867.         ld hy,d
  868.         ld ly,e
  869. drawground_findshadow_cxaddr=$+2
  870.         ld de,(cx)
  871.         LD HL,[tracepixel.xUINT]
  872.         sbc hl,de
  873.         SQHL ;out: de
  874.         add iy,de
  875.          ld d,hy
  876.          ld e,ly
  877. drawground_findshadow_qaddr=$+1
  878.         ld hl,(q)
  879.         sbc hl,de
  880.        if EGA
  881.        ld a,COLOR_SHADOW
  882.        endif
  883.         ret nc ;shadow
  884.         LD a,[tracepixel.k]
  885.         sub 2
  886.         JP nc,drawground_findshadow0
  887.  
  888.         ld a,(tracepixel.xUINT) ;дробная часть
  889.         ld hl,tracepixel.zUINT
  890.         xor (hl)
  891.         rla
  892.        if EGA
  893.        ld a,COLOR_SQUARE0
  894.        ret nc
  895.        ld a,COLOR_SQUARE1
  896.        endif
  897.         ret
  898.        
  899.         if !fastest
  900. muldebc
  901. ;+de0 * +bc0 -> .de.
  902.         ld a,d
  903.         xor b
  904.         ex af,af' ;M=разные знаки '
  905.         ld a,d
  906.         rla
  907.         jr nc,mul_noneghld0
  908.         xor a
  909.         sub e
  910.         ld e,a
  911.         sbc a,d
  912.         sub e
  913.         ld d,a
  914. mul_noneghld0
  915.         ld a,b
  916.         rla
  917.         jr nc,mul_nonegbcx0
  918.         xor a
  919.         sub c
  920.         ld c,a
  921.         sbc a,b
  922.         sub c
  923.         ld b,a
  924. mul_nonegbcx0
  925.         if SQUAREMUL
  926.         set 7,d
  927.         res 0,e
  928.         endif
  929.         MULDEBC_POSITIVE
  930.         ex af,af' ;M=разные знаки '
  931.         ret p
  932.         xor a
  933.         sub e
  934.         ld e,a
  935.         sbc a,d
  936.         sub e
  937.         ld d,a
  938.         ret
  939.         endif
  940.        
  941.         if !SQUARESQR
  942.         ;ds (-$)&255
  943. tsqr=0x7b00;0x7a00 ;код команды ld a,d (не помогает)
  944.         ;ds 512 ;incbin "tsqr"
  945.         endif
  946.  
  947.         align 256
  948. q ;такой порядок выгоднее в MegaLZ
  949.         DW q1
  950.         DW q0
  951.         align 256
  952. cx
  953.         DW cx1
  954.         DW cx0
  955.         align 256
  956. cy
  957.         DW cy1
  958.         DW cy0
  959.         align 256
  960. cz
  961.         DW cz1
  962.         DW cz0
  963.         align 256 ;сразу после cz
  964. rad
  965.         DW r1*17/16 ; //больше, потому что бок сферы торчит за проекцию
  966.         DW r0*17/16
  967. end
  968.         align 256
  969. projr
  970.         dw 0 ;используется только старший байт
  971.         dw 0
  972.         align 256 ;projx и projy сразу после rad
  973. projx
  974.         dw 0 ;используется только старший байт
  975.         dw 0
  976. ;        align 256
  977. ;projy
  978. ;        dw 0 ;используется только младший байт
  979. ;        dw 0
  980.  
  981. ;end
  982.  
  983.         display "End=",end
  984.         display "Free after end=",/d,#c000-end
  985.         display "Size ",/d,end-begin," bytes"
  986.        
  987.         savebin "raytrace.com",begin,end-begin
  988.        
  989.         LABELSLIST "../../../us/user.l"
  990.