home *** CD-ROM | disk | FTP | other *** search
- *
- * Copyright (C) 1996-1997 Id Software, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
-
- **
- ** Quake for AMIGA
- ** d_sky.c assembler implementations by Frank Wille <frank@phoenix.owl.de>
- **
-
- XREF _d_viewbuffer
- XREF _screenwidth
- XREF _r_refdef
- XREF _r_skysource
- XREF _vid
- XREF _vright
- XREF _vpn
- XREF _vup
- XREF _skytime
- XREF _skyspeed
-
- XDEF _D_DrawSkyScans8
-
- PSPAN_NEXT = $C
- REFDEF_VRECT_X = 0
- REFDEF_VRECT_Y = 4
- REFDEF_VRECT_WIDTH = 8
- REFDEF_VRECT_HEIGHT = 12
- VID_WIDTH = 20
- VID_HEIGHT = 24
-
- SKYSHIFT = 7
- SKYSIZE = (1 << SKYSHIFT)
- SKYMASK = (SKYSIZE - 1)
- SKY_SPAN_SHIFT = 5
- SKY_SPAN_MAX = (1 << SKY_SPAN_SHIFT)
- R_SKY_SMASK = $007f
- R_SKY_TMASK = $007f
-
-
-
-
- ******************************************************************************
- *
- * void D_DrawSkyScans8 (espan_t *pspan)
- *
- * standard scan drawing function for the sky
- *
- * D_Sky_uv_To_st is inlined.
- *
- * IMPORTANT!! SKY_SPAN_SHIFT must *NOT* exceed 5 (The ReciprocTable
- * has to be extended)
- *
- ******************************************************************************
-
- cnop 0,4
- _D_DrawSkyScans8
-
-
- ***** stackframe
-
- rsreset
- .savefp1 rs.x 1
- .saved4 rs.l 1
- .saved5 rs.l 1
- .vr0 rs.s 1
- .vr1 rs.s 1
- .vr2 rs.s 1
- .fpuregs rs.x 6
- .intregs rs.l 11
- rs.l 1
- .pspan rs.l 1
-
-
- ****** Prologue. Global variables are put into registers or onto the stackframe
-
- movem.l d2-d7/a2-a6,-(sp)
- fmovem.x fp2-fp7,-(sp)
- sub.l #.fpuregs,sp
-
- ****** First loop. In every iteration one complete span is drawn
-
-
- move.l .pspan(sp),a6 ;get function parameter
-
- lea _r_refdef,a1
- move.l REFDEF_VRECT_HEIGHT(a1),d0
- move.l REFDEF_VRECT_WIDTH(a1),d1
- cmp.l d0,d1 ;if (r_refdef.vrect.width >= r_...)
- blt.b .height
- fmove.l d1,fp0 ;temp = (float)r_refdef.vrect.height
- bra.b .width
- .height
- fmove.l d0,fp0 ;temp = (float)r_refdef.vrect.width
- .width
- fmove.s #8192,fp1
- fdiv fp0,fp1 ;fp1 = 8192 / temp
- move.l _r_skysource,a5
- .loop
- fmove.x fp1,.savefp1(sp)
- move.l _d_viewbuffer,a0
- move.l _screenwidth,d0
- move.l (a6)+,d3
- move.l (a6)+,d2
- fmove.l d2,fp4
- muls d2,d0 ;d0 = screenwidth * pspan->v
- add.l d3,d0
- add.l d0,a0 ;pdest = d_viewbuffer + pspan->u + d0
-
- fmove.s #4096,fp7
- lea _vpn,a2
- fmove.s (a2)+,fp5
- fmul fp7,fp5 ;fp5 = 4096*vpn[0]
- fmove.s (a2)+,fp6
- fmul fp7,fp6 ;fp6 = 4096*vpn[1]
- fmul.s (a2)+,fp7 ;fp7 = 4096*vpn[2]
- lea _vid,a1
- move.l VID_WIDTH(a1),d0
- move.l VID_HEIGHT(a1),d1
- asr.l #1,d0
- move.l d0,a2 ;a2 = vid.width>>1
- asr.l #1,d1
- fmove.l d1,fp0
- fsub fp4,fp0 ;fp0 = ((vid.height>>1)-v)
- fmul fp1,fp0 ;wv = 8192 * fp0 / temp
- lea _vup,a1
- fmove.s (a1)+,fp2
- fmul fp0,fp2 ;fp2 = wv*vup[0]
- fadd fp2,fp5 ;fp5 = 4096*vpn[0] + wv*vup[0]
- fmove.s (a1)+,fp3
- fmul fp0,fp3 ;fp3 = wv*vup[1]
- fadd fp3,fp6 ;fp6 = 4096*vpn[1] + wv*vup[0]
- fmul.s (a1)+,fp0 ;fp0 = wv*vup[2]
- fadd fp0,fp7 ;fp7 = 4096*vpn[2] + wv*vup[2]
- lea _vright,a1
- fmove.s (a1)+,fp2
- fmove.s (a1)+,fp3
- fmove.s (a1)+,fp4
- fmul fp1,fp2 ;fp2 = 8192 * vright[0] / temp
- fmul fp1,fp3 ;fp3 = 8192 * vright[1] / temp
- fmul fp1,fp4 ;fp4 = 8192 * vright[2] / temp
- fmove.s fp2,.vr0(sp)
- fmove.s fp3,.vr1(sp)
- fmove.s #3,fp1
- fmul fp1,fp7 ;multiply by 3
- fmul fp1,fp4
- fmove.s fp4,.vr2(sp)
- move.l (a6)+,d1 ;count = pspan->count
- fmove.s _skytime,fp0
- fmul.s _skyspeed,fp0
- fmul.s #65536,fp0
- fmove.l fp0,d0 ;d0 = skytime*skyspeed*$10000
- move.l d0,a4
-
- ****** D_Sky_uv_To_st (inlined)
-
- move.l d3,d0
- sub.l a2,d0
- fmove.l d0,fp0 ;fp0 = (float(u-(vid.width>>1)))
- fmove fp0,fp2
- fmul.s .vr0(sp),fp2 ;fp2 = wu*vright[0]
- fadd fp5,fp2 ;fp2 = end[0]
- fmove fp2,fp1
- fmul fp2,fp2
- fmove fp0,fp3
- fmul.s .vr1(sp),fp3 ;fp3 = wu*vright[1]
- fadd fp6,fp3 ;fp3 = end[1]
- fmove fp3,fp4
- fmul fp3,fp3
- fadd fp3,fp2
- fmul.s .vr2(sp),fp0 ;fp0 = wu*vright[2]
- fadd fp7,fp0 ;fp0 = end[2]
- fmul fp0,fp0
- fadd fp0,fp2
- fsqrt fp2 ;fp2 = length(end)
- fmove.s #(65536*6*(SKYSIZE/2-1)),fp0
- fdiv fp2,fp0
- fmul fp0,fp1 ;fp1 = 6*(SKYSIZE/2-1)*end[0]
- fmul fp0,fp4 ;fp4 = 6*(SKYSIZE/2-1)*end[1]
- fmove.l fp1,d6
- add.l a4,d6 ;d6 = s
- fmove.l fp4,d7
- add.l a4,d7 ;d7 = t
-
- ****** end of D_Sky_uv_To_st
-
- ****** Second loop. In every iteration one part of the whole span is drawn
- ****** d2 gets the value (spancount-1)! [NOT spancount]
-
- ****** d1 = count
-
- * do
- * {
- * if (count >= SKY_SPAN_MAX)
- * spancount = SKY_SPAN_MAX;
- * else
- * spancount = count;
- *
- * count -= spancount;
- *
- * if (count)
- * {
-
- .loop2
- move.l #SKY_SPAN_MAX-1,d2 ;spancount = SKY_SPAN_MAX
- cmp.l #SKY_SPAN_MAX,d1 ;if (count >= SKY_SPAN_MAX)
- bgt.b .cont
- move.l d1,d2 ;spancount = count
- subq.l #1,d2
- moveq #0,d1 ;count -= spancount
- bra.w .finalpart
- .cont
- sub.l #SKY_SPAN_MAX,d1 ;count -= spancount;
-
-
- ****** Evaluation of the values for the inner loop. This version is used for
- ****** span size = SKY_SPAN_MAX
-
- * // calculate s and t at far end of span,
- * // calculate s and t steps across span by shifting
- * u += spancount;
- *
- * D_Sky_uv_To_st (u, v, &snext, &tnext);
- *
- * sstep = (snext - s) >> SKY_SPAN_SHIFT;
- * tstep = (tnext - t) >> SKY_SPAN_SHIFT;
- * }
-
-
- add.l d2,d3
- addq.l #1,d3
-
- ****** D_Sky_uv_To_st (inlined)
-
- move.l d3,d0
- sub.l a2,d0
- fmove.l d0,fp0 ;fp0 = (float(u-(vid.width>>1)))
- fmove fp0,fp2
- fmul.s .vr0(sp),fp2 ;fp2 = wu*vright[0]
- fadd fp5,fp2 ;fp2 = end[0]
- fmove fp2,fp1
- fmul fp2,fp2
- fmove fp0,fp3
- fmul.s .vr1(sp),fp3 ;fp3 = wu*vright[1]
- fadd fp6,fp3 ;fp3 = end[1]
- fmove fp3,fp4
- fmul fp3,fp3
- fadd fp3,fp2
- fmul.s .vr2(sp),fp0 ;fp0 = wu*vright[2]
- fadd fp7,fp0 ;fp0 = end[2]
- fmul fp0,fp0
- fadd fp0,fp2
- fsqrt fp2 ;fp2 = length(end)
- fmove.s #(65536*6*(SKYSIZE/2-1)),fp0
- fdiv fp2,fp0
- fmul fp0,fp1 ;fp1 = 6*(SKYSIZE/2-1)*end[0]
- fmul fp0,fp4 ;fp4 = 6*(SKYSIZE/2-1)*end[1]
- fmove.l fp1,d4
- add.l a4,d4 ;d6 = snext
- fmove.l fp4,d5
- add.l a4,d5 ;d7 = tnext
-
- ****** end of D_Sky_uv_To_st
-
- move.l d4,.saved4(sp) ;save snext
- move.l d5,.saved5(sp) ;save tnext
- sub.l d6,d4 ;d4 = snext - s
- sub.l d7,d5 ;d5 = tnext - t
- asr.l #SKY_SPAN_SHIFT,d4 ;sstep = d4 >> SKY_SPAN_SHIFT
- asr.l #SKY_SPAN_SHIFT,d5 ;tstep = d5 >> SKY_SPAN_SHIFT
- bra.w .mainloop
-
-
- .finalpart
- add.l d2,d3
-
- ****** D_Sky_uv_To_st (inlined)
-
- move.l d3,d0
- sub.l a2,d0
- fmove.l d0,fp0 ;fp0 = (float(u-(vid.width>>1)))
- fmove fp0,fp2
- fmul.s .vr0(sp),fp2 ;fp2 = wu*vright[0]
- fadd fp5,fp2 ;fp2 = end[0]
- fmove fp2,fp1
- fmul fp2,fp2
- fmove fp0,fp3
- fmul.s .vr1(sp),fp3 ;fp3 = wu*vright[1]
- fadd fp6,fp3 ;fp3 = end[1]
- fmove fp3,fp4
- fmul fp3,fp3
- fadd fp3,fp2
- fmul.s .vr2(sp),fp0 ;fp0 = wu*vright[2]
- fadd fp7,fp0 ;fp0 = end[2]
- fmul fp0,fp0
- fadd fp0,fp2
- fsqrt fp2 ;fp2 = length(end)
- fmove.s #(65536*6*(SKYSIZE/2-1)),fp0
- fdiv fp2,fp0
- fmul fp0,fp1 ;fp1 = 6*(SKYSIZE/2-1)*end[0]
- fmul fp0,fp4 ;fp4 = 6*(SKYSIZE/2-1)*end[1]
- fmove.l fp1,d4
- add.l a4,d4 ;d6 = snext
- fmove.l fp4,d5
- add.l a4,d5 ;d7 = tnext
-
- ****** end of D_Sky_uv_To_st
-
- move.l d4,.saved4(sp) ;save snext
- move.l d5,.saved5(sp) ;save tnext
- sub.l d6,d4 ;d4 = snext - s
- sub.l d7,d5 ;d5 = tnext - t
- cmp #5,d2 ;(spancount-1) < 5?
- blt.b .special ;yes -> special case
- .qdiv
- asr.l #7,d4 ;d4 >> 7
- asr.l #7,d5 ;d5 >> 7
- lea ReciprocTable,a3 ;a3 -> reciprocal table
- move 0(a3,d2.w*2),d0 ;d0 = (1/(spancount-1))<<16
- muls d0,d4 ;d4 = d4 / (spancount-1)
- asr.l #7,d4 ;sstep = d4 >> 7
- muls d0,d5 ;d5 = d5 / (spancount-1)
- asr.l #7,d5 ;tstep = d5 >> 7
- bra.b .mainloop
- .special
- cmp #1,d2 ;switch (spancount-1)
- ble.b .mainloop ;0,1 -> no scaling needed
- cmp #3,d2 ;3 -> standard qdiv
- beq.b .qdiv
- blt.b .spec_2
- asr.l #2,d4 ;4 -> scale by shifting right
- asr.l #2,d5
- bra.b .mainloop
- .spec_2
- asr.l #1,d4 ;2 -> scale by shifting right
- asr.l #1,d5
-
-
- ****** Main drawing loop.
-
- ****** d2 : spancount
- ****** d4 : sstep
- ****** d5 : tstep
- ****** d6 : s
- ****** d7 : t
- ****** a0 : pdest
- ****** a5 : r_skysource
-
- * do
- * {
- * *pdest++ = r_skysource[((t & R_SKY_TMASK) >> 8) +
- * ((s & R_SKY_SMASK) >> 16)];
- * s += sstep;
- * t += tstep;
- * } while (--spancount > 0);
-
-
- .mainloop
- move.l d1,-(sp)
- swap d4
- swap d5
- swap d6
- swap d7
- move d5,d1 ;d2 = tstep integer part
- move d4,d0 ;d0 = sstep integer part
- clr d5 ;d5 = tstep fractional part
- clr d4 ;d4 = sstep fractional part
- .loop3
- and #R_SKY_TMASK,d7
- asl #8,d7
- lea 0(a5,d7.w),a3
- asr #8,d7
- and #R_SKY_SMASK,d6
- move.b 0(a3,d6.w),(a0)+
- add.l d4,d6
- addx.w d0,d6
- add.l d5,d7
- addx.w d1,d7
- dbra d2,.loop3
- move.l (sp)+,d1
-
- ****** loop terminations
-
-
- move.l .saved5(sp),d7 ;t = tnext
- move.l .saved4(sp),d6 ;s = snext
-
- tst.l d1 ;while (count > 0)
- bgt.w .loop2
- fmove.x .savefp1(sp),fp1
-
- move.l (a6)+,a6
- tst.l a6
- bne.w .loop
- add.l #.fpuregs,sp
- fmovem.x (sp)+,fp2-fp7
- movem.l (sp)+,d2-d7/a2-a6
- rts
-
- ReciprocTable
- dc.w 0
- dc.w 0
- dc.w 0
- dc.w 16384/3
- dc.w 0
- dc.w 16384/5
- dc.w 16384/6
- dc.w 16384/7
- dc.w 16384/8
- dc.w 16384/9
- dc.w 16384/10
- dc.w 16384/11
- dc.w 16384/12
- dc.w 16384/13
- dc.w 16384/14
- dc.w 16384/15
- dc.w 16384/16
- dc.w 16384/17
- dc.w 16384/18
- dc.w 16384/19
- dc.w 16384/20
- dc.w 16384/21
- dc.w 16384/22
- dc.w 16384/23
- dc.w 16384/24
- dc.w 16384/25
- dc.w 16384/26
- dc.w 16384/27
- dc.w 16384/28
- dc.w 16384/29
- dc.w 16384/30
- dc.w 16384/31
-
-