home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quake_src / d_sky68k.s < prev    next >
Text File  |  2000-06-17  |  13KB  |  448 lines

  1. * Copyright (C) 1996-1997 Id Software, Inc. 
  2. * This program is free software; you can redistribute it and/or 
  3. * modify it under the terms of the GNU General Public License 
  4. * as published by the Free Software Foundation; either version 2 
  5. * of the License, or (at your option) any later version. 
  6. * This program is distributed in the hope that it will be useful, 
  7. * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  8. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   
  9. * See the GNU General Public License for more details. 
  10. * You should have received a copy of the GNU General Public License 
  11. * along with this program; if not, write to the Free Software 
  12. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
  13.  
  14. **
  15. ** Quake for AMIGA
  16. ** d_sky.c assembler implementations by Frank Wille <frank@phoenix.owl.de>
  17. **
  18.  
  19.         XREF    _d_viewbuffer
  20.         XREF    _screenwidth
  21.         XREF    _r_refdef
  22.         XREF    _r_skysource
  23.         XREF    _vid
  24.         XREF    _vright
  25.         XREF    _vpn
  26.         XREF    _vup
  27.         XREF    _skytime
  28.         XREF    _skyspeed
  29.  
  30.         XDEF    _D_DrawSkyScans8
  31.  
  32. PSPAN_NEXT              =       $C
  33. REFDEF_VRECT_X          =       0
  34. REFDEF_VRECT_Y          =       4
  35. REFDEF_VRECT_WIDTH      =       8
  36. REFDEF_VRECT_HEIGHT     =       12
  37. VID_WIDTH               =       20
  38. VID_HEIGHT              =       24
  39.  
  40. SKYSHIFT                =       7
  41. SKYSIZE                 =       (1 << SKYSHIFT)
  42. SKYMASK                 =       (SKYSIZE - 1)
  43. SKY_SPAN_SHIFT          =       5
  44. SKY_SPAN_MAX            =       (1 << SKY_SPAN_SHIFT)
  45. R_SKY_SMASK             =       $007f
  46. R_SKY_TMASK             =       $007f
  47.  
  48.  
  49.  
  50.  
  51. ******************************************************************************
  52. *
  53. *       void D_DrawSkyScans8 (espan_t *pspan)
  54. *
  55. *       standard scan drawing function for the sky
  56. *
  57. *       D_Sky_uv_To_st is inlined.
  58. *
  59. *       IMPORTANT!! SKY_SPAN_SHIFT must *NOT* exceed 5 (The ReciprocTable
  60. *       has to be extended)
  61. *
  62. ******************************************************************************
  63.  
  64.         cnop    0,4
  65. _D_DrawSkyScans8
  66.  
  67.  
  68. *****   stackframe
  69.  
  70.         rsreset
  71. .savefp1        rs.x    1
  72. .saved4         rs.l    1
  73. .saved5         rs.l    1
  74. .vr0            rs.s    1
  75. .vr1            rs.s    1
  76. .vr2            rs.s    1
  77. .fpuregs        rs.x    6
  78. .intregs        rs.l    11
  79.         rs.l    1
  80. .pspan          rs.l    1
  81.  
  82.  
  83. ******  Prologue. Global variables are put into registers or onto the stackframe
  84.  
  85.         movem.l d2-d7/a2-a6,-(sp)
  86.         fmovem.x        fp2-fp7,-(sp)
  87.         sub.l   #.fpuregs,sp
  88.  
  89. ******  First loop. In every iteration one complete span is drawn
  90.  
  91.  
  92.         move.l  .pspan(sp),a6           ;get function parameter
  93.  
  94.         lea     _r_refdef,a1
  95.         move.l  REFDEF_VRECT_HEIGHT(a1),d0
  96.         move.l  REFDEF_VRECT_WIDTH(a1),d1
  97.         cmp.l   d0,d1                   ;if (r_refdef.vrect.width >= r_...)
  98.         blt.b   .height
  99.         fmove.l d1,fp0                  ;temp = (float)r_refdef.vrect.height
  100.         bra.b   .width
  101. .height
  102.         fmove.l d0,fp0                  ;temp = (float)r_refdef.vrect.width
  103. .width
  104.         fmove.s #8192,fp1
  105.         fdiv    fp0,fp1                 ;fp1 = 8192 / temp
  106.         move.l  _r_skysource,a5
  107. .loop
  108.         fmove.x fp1,.savefp1(sp)
  109.         move.l  _d_viewbuffer,a0
  110.         move.l  _screenwidth,d0
  111.         move.l  (a6)+,d3
  112.         move.l  (a6)+,d2
  113.         fmove.l d2,fp4
  114.         muls    d2,d0                   ;d0 = screenwidth * pspan->v
  115.         add.l   d3,d0
  116.         add.l   d0,a0                   ;pdest = d_viewbuffer + pspan->u + d0
  117.  
  118.         fmove.s #4096,fp7
  119.         lea     _vpn,a2
  120.         fmove.s (a2)+,fp5
  121.         fmul    fp7,fp5                 ;fp5 = 4096*vpn[0]
  122.         fmove.s (a2)+,fp6
  123.         fmul    fp7,fp6                 ;fp6 = 4096*vpn[1]
  124.         fmul.s  (a2)+,fp7               ;fp7 = 4096*vpn[2]
  125.         lea     _vid,a1
  126.         move.l  VID_WIDTH(a1),d0
  127.         move.l  VID_HEIGHT(a1),d1
  128.         asr.l   #1,d0
  129.         move.l  d0,a2                   ;a2 = vid.width>>1
  130.         asr.l   #1,d1
  131.         fmove.l d1,fp0
  132.         fsub    fp4,fp0                 ;fp0 = ((vid.height>>1)-v)
  133.         fmul    fp1,fp0                 ;wv = 8192 * fp0 / temp
  134.         lea     _vup,a1
  135.         fmove.s (a1)+,fp2
  136.         fmul    fp0,fp2                 ;fp2 = wv*vup[0]
  137.         fadd    fp2,fp5                 ;fp5 = 4096*vpn[0] + wv*vup[0]
  138.         fmove.s (a1)+,fp3
  139.         fmul    fp0,fp3                 ;fp3 = wv*vup[1]
  140.         fadd    fp3,fp6                 ;fp6 = 4096*vpn[1] + wv*vup[0]
  141.         fmul.s  (a1)+,fp0               ;fp0 = wv*vup[2]
  142.         fadd    fp0,fp7                 ;fp7 = 4096*vpn[2] + wv*vup[2]
  143.         lea     _vright,a1
  144.         fmove.s (a1)+,fp2
  145.         fmove.s (a1)+,fp3
  146.         fmove.s (a1)+,fp4
  147.         fmul    fp1,fp2                 ;fp2 = 8192 * vright[0] / temp
  148.         fmul    fp1,fp3                 ;fp3 = 8192 * vright[1] / temp
  149.         fmul    fp1,fp4                 ;fp4 = 8192 * vright[2] / temp
  150.         fmove.s fp2,.vr0(sp)
  151.         fmove.s fp3,.vr1(sp)
  152.         fmove.s #3,fp1
  153.         fmul    fp1,fp7                 ;multiply by 3
  154.         fmul    fp1,fp4
  155.         fmove.s fp4,.vr2(sp)
  156.         move.l  (a6)+,d1                ;count = pspan->count
  157.         fmove.s _skytime,fp0
  158.         fmul.s  _skyspeed,fp0
  159.         fmul.s  #65536,fp0
  160.         fmove.l fp0,d0                  ;d0 = skytime*skyspeed*$10000
  161.         move.l  d0,a4
  162.  
  163. ******  D_Sky_uv_To_st (inlined)
  164.  
  165.         move.l  d3,d0
  166.         sub.l   a2,d0
  167.         fmove.l d0,fp0                  ;fp0 = (float(u-(vid.width>>1)))
  168.         fmove   fp0,fp2
  169.         fmul.s  .vr0(sp),fp2            ;fp2 = wu*vright[0]
  170.         fadd    fp5,fp2                 ;fp2 = end[0]
  171.         fmove   fp2,fp1
  172.         fmul    fp2,fp2
  173.         fmove   fp0,fp3
  174.         fmul.s  .vr1(sp),fp3            ;fp3 = wu*vright[1]
  175.         fadd    fp6,fp3                 ;fp3 = end[1]
  176.         fmove   fp3,fp4
  177.         fmul    fp3,fp3
  178.         fadd    fp3,fp2
  179.         fmul.s  .vr2(sp),fp0            ;fp0 = wu*vright[2]
  180.         fadd    fp7,fp0                 ;fp0 = end[2]
  181.         fmul    fp0,fp0
  182.         fadd    fp0,fp2
  183.         fsqrt   fp2                     ;fp2 = length(end)
  184.         fmove.s #(65536*6*(SKYSIZE/2-1)),fp0
  185.         fdiv    fp2,fp0
  186.         fmul    fp0,fp1                 ;fp1 = 6*(SKYSIZE/2-1)*end[0]
  187.         fmul    fp0,fp4                 ;fp4 = 6*(SKYSIZE/2-1)*end[1]
  188.         fmove.l fp1,d6
  189.         add.l   a4,d6                   ;d6 = s
  190.         fmove.l fp4,d7
  191.         add.l   a4,d7                   ;d7 = t
  192.  
  193. ******  end of D_Sky_uv_To_st
  194.  
  195. ******  Second loop. In every iteration one part of the whole span is drawn
  196. ******  d2 gets the value (spancount-1)! [NOT spancount]
  197.  
  198. ******  d1 = count
  199.  
  200. *                do
  201. *                {
  202. *                        if (count >= SKY_SPAN_MAX)
  203. *                                spancount = SKY_SPAN_MAX;
  204. *                        else
  205. *                                spancount = count;
  206. *
  207. *                        count -= spancount;
  208. *
  209. *                        if (count)
  210. *                        {
  211.  
  212. .loop2
  213.         move.l  #SKY_SPAN_MAX-1,d2      ;spancount = SKY_SPAN_MAX
  214.         cmp.l   #SKY_SPAN_MAX,d1        ;if (count >= SKY_SPAN_MAX)
  215.         bgt.b   .cont
  216.         move.l  d1,d2                   ;spancount = count
  217.         subq.l  #1,d2
  218.         moveq   #0,d1                   ;count -= spancount
  219.         bra.w   .finalpart
  220. .cont
  221.         sub.l   #SKY_SPAN_MAX,d1        ;count -= spancount;
  222.  
  223.  
  224. ******  Evaluation of the values for the inner loop. This version is used for
  225. ******  span size = SKY_SPAN_MAX
  226.  
  227. *                        // calculate s and t at far end of span,
  228. *                        // calculate s and t steps across span by shifting
  229. *                                u += spancount;
  230. *
  231. *                                D_Sky_uv_To_st (u, v, &snext, &tnext);
  232. *
  233. *                                sstep = (snext - s) >> SKY_SPAN_SHIFT;
  234. *                                tstep = (tnext - t) >> SKY_SPAN_SHIFT;
  235. *                        }
  236.  
  237.  
  238.         add.l   d2,d3
  239.         addq.l  #1,d3
  240.  
  241. ******  D_Sky_uv_To_st (inlined)
  242.  
  243.         move.l  d3,d0
  244.         sub.l   a2,d0
  245.         fmove.l d0,fp0                  ;fp0 = (float(u-(vid.width>>1)))
  246.         fmove   fp0,fp2
  247.         fmul.s  .vr0(sp),fp2            ;fp2 = wu*vright[0]
  248.         fadd    fp5,fp2                 ;fp2 = end[0]
  249.         fmove   fp2,fp1
  250.         fmul    fp2,fp2
  251.         fmove   fp0,fp3
  252.         fmul.s  .vr1(sp),fp3            ;fp3 = wu*vright[1]
  253.         fadd    fp6,fp3                 ;fp3 = end[1]
  254.         fmove   fp3,fp4
  255.         fmul    fp3,fp3
  256.         fadd    fp3,fp2
  257.         fmul.s  .vr2(sp),fp0            ;fp0 = wu*vright[2]
  258.         fadd    fp7,fp0                 ;fp0 = end[2]
  259.         fmul    fp0,fp0
  260.         fadd    fp0,fp2
  261.         fsqrt   fp2                     ;fp2 = length(end)
  262.         fmove.s #(65536*6*(SKYSIZE/2-1)),fp0
  263.         fdiv    fp2,fp0
  264.         fmul    fp0,fp1                 ;fp1 = 6*(SKYSIZE/2-1)*end[0]
  265.         fmul    fp0,fp4                 ;fp4 = 6*(SKYSIZE/2-1)*end[1]
  266.         fmove.l fp1,d4
  267.         add.l   a4,d4                   ;d6 = snext
  268.         fmove.l fp4,d5
  269.         add.l   a4,d5                   ;d7 = tnext
  270.  
  271. ******  end of D_Sky_uv_To_st
  272.  
  273.         move.l  d4,.saved4(sp)          ;save snext
  274.         move.l  d5,.saved5(sp)          ;save tnext
  275.         sub.l   d6,d4                   ;d4 = snext - s
  276.         sub.l   d7,d5                   ;d5 = tnext - t
  277.         asr.l   #SKY_SPAN_SHIFT,d4      ;sstep = d4 >> SKY_SPAN_SHIFT
  278.         asr.l   #SKY_SPAN_SHIFT,d5      ;tstep = d5 >> SKY_SPAN_SHIFT
  279.         bra.w   .mainloop
  280.  
  281.  
  282. .finalpart
  283.         add.l   d2,d3
  284.  
  285. ******  D_Sky_uv_To_st (inlined)
  286.  
  287.         move.l  d3,d0
  288.         sub.l   a2,d0
  289.         fmove.l d0,fp0                  ;fp0 = (float(u-(vid.width>>1)))
  290.         fmove   fp0,fp2
  291.         fmul.s  .vr0(sp),fp2            ;fp2 = wu*vright[0]
  292.         fadd    fp5,fp2                 ;fp2 = end[0]
  293.         fmove   fp2,fp1
  294.         fmul    fp2,fp2
  295.         fmove   fp0,fp3
  296.         fmul.s  .vr1(sp),fp3            ;fp3 = wu*vright[1]
  297.         fadd    fp6,fp3                 ;fp3 = end[1]
  298.         fmove   fp3,fp4
  299.         fmul    fp3,fp3
  300.         fadd    fp3,fp2
  301.         fmul.s  .vr2(sp),fp0            ;fp0 = wu*vright[2]
  302.         fadd    fp7,fp0                 ;fp0 = end[2]
  303.         fmul    fp0,fp0
  304.         fadd    fp0,fp2
  305.         fsqrt   fp2                     ;fp2 = length(end)
  306.         fmove.s #(65536*6*(SKYSIZE/2-1)),fp0
  307.         fdiv    fp2,fp0
  308.         fmul    fp0,fp1                 ;fp1 = 6*(SKYSIZE/2-1)*end[0]
  309.         fmul    fp0,fp4                 ;fp4 = 6*(SKYSIZE/2-1)*end[1]
  310.         fmove.l fp1,d4
  311.         add.l   a4,d4                   ;d6 = snext
  312.         fmove.l fp4,d5
  313.         add.l   a4,d5                   ;d7 = tnext
  314.  
  315. ******  end of D_Sky_uv_To_st
  316.  
  317.         move.l  d4,.saved4(sp)          ;save snext
  318.         move.l  d5,.saved5(sp)          ;save tnext
  319.         sub.l   d6,d4                   ;d4 = snext - s
  320.         sub.l   d7,d5                   ;d5 = tnext - t
  321.         cmp     #5,d2                   ;(spancount-1) < 5?
  322.         blt.b   .special                ;yes -> special case
  323. .qdiv
  324.         asr.l   #7,d4                   ;d4 >> 7
  325.         asr.l   #7,d5                   ;d5 >> 7
  326.         lea     ReciprocTable,a3        ;a3 -> reciprocal table
  327.         move    0(a3,d2.w*2),d0         ;d0 = (1/(spancount-1))<<16
  328.         muls    d0,d4                   ;d4 = d4 / (spancount-1)
  329.         asr.l   #7,d4                   ;sstep = d4 >> 7
  330.         muls    d0,d5                   ;d5 = d5 / (spancount-1)
  331.         asr.l   #7,d5                   ;tstep = d5 >> 7
  332.         bra.b   .mainloop
  333. .special
  334.         cmp     #1,d2                   ;switch (spancount-1)
  335.         ble.b   .mainloop               ;0,1 -> no scaling needed
  336.         cmp     #3,d2                   ;3 -> standard qdiv
  337.         beq.b   .qdiv
  338.         blt.b   .spec_2
  339.         asr.l   #2,d4                   ;4 -> scale by shifting right
  340.         asr.l   #2,d5
  341.         bra.b   .mainloop
  342. .spec_2
  343.         asr.l   #1,d4                   ;2 -> scale by shifting right
  344.         asr.l   #1,d5
  345.  
  346.  
  347. ******  Main drawing loop.
  348.  
  349. ******  d2 : spancount
  350. ******  d4 : sstep
  351. ******  d5 : tstep
  352. ******  d6 : s
  353. ******  d7 : t
  354. ******  a0 : pdest
  355. ******  a5 : r_skysource
  356.  
  357. *                        do
  358. *                        {
  359. *                                *pdest++ = r_skysource[((t & R_SKY_TMASK) >> 8) +
  360. *                                                ((s & R_SKY_SMASK) >> 16)];
  361. *                                s += sstep;
  362. *                                t += tstep;
  363. *                        } while (--spancount > 0);
  364.  
  365.  
  366. .mainloop
  367.         move.l  d1,-(sp)
  368.         swap    d4
  369.         swap    d5
  370.         swap    d6
  371.         swap    d7
  372.         move    d5,d1                   ;d2 = tstep integer part
  373.         move    d4,d0                   ;d0 = sstep integer part
  374.         clr     d5                      ;d5 = tstep fractional part
  375.         clr     d4                      ;d4 = sstep fractional part
  376. .loop3
  377.         and     #R_SKY_TMASK,d7
  378.         asl     #8,d7
  379.         lea     0(a5,d7.w),a3
  380.         asr     #8,d7
  381.         and     #R_SKY_SMASK,d6
  382.         move.b  0(a3,d6.w),(a0)+
  383.         add.l   d4,d6
  384.         addx.w  d0,d6
  385.         add.l   d5,d7
  386.         addx.w  d1,d7
  387.         dbra    d2,.loop3
  388.         move.l  (sp)+,d1
  389.  
  390. ******  loop terminations
  391.  
  392.  
  393.         move.l   .saved5(sp),d7         ;t = tnext
  394.         move.l   .saved4(sp),d6         ;s = snext
  395.  
  396.         tst.l   d1                      ;while (count > 0)
  397.         bgt.w   .loop2
  398.         fmove.x .savefp1(sp),fp1
  399.  
  400.         move.l  (a6)+,a6
  401.         tst.l   a6
  402.         bne.w   .loop
  403.         add.l   #.fpuregs,sp
  404.         fmovem.x        (sp)+,fp2-fp7
  405.         movem.l (sp)+,d2-d7/a2-a6
  406.         rts
  407.  
  408. ReciprocTable
  409.         dc.w    0
  410.         dc.w    0
  411.         dc.w    0
  412.         dc.w    16384/3
  413.         dc.w    0
  414.         dc.w    16384/5
  415.         dc.w    16384/6
  416.         dc.w    16384/7
  417.         dc.w    16384/8
  418.         dc.w    16384/9
  419.         dc.w    16384/10
  420.         dc.w    16384/11
  421.         dc.w    16384/12
  422.         dc.w    16384/13
  423.         dc.w    16384/14
  424.         dc.w    16384/15
  425.         dc.w    16384/16
  426.         dc.w    16384/17
  427.         dc.w    16384/18
  428.         dc.w    16384/19
  429.         dc.w    16384/20
  430.         dc.w    16384/21
  431.         dc.w    16384/22
  432.         dc.w    16384/23
  433.         dc.w    16384/24
  434.         dc.w    16384/25
  435.         dc.w    16384/26
  436.         dc.w    16384/27
  437.         dc.w    16384/28
  438.         dc.w    16384/29
  439.         dc.w    16384/30
  440.         dc.w    16384/31
  441.  
  442.