?login_element?

Subversion Repositories NedoOS

Rev

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

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