mirror of
https://git.code.sf.net/p/quake/quakeforge-old
synced 2024-11-25 21:31:18 +00:00
Missed a few..
This commit is contained in:
parent
f5c91c88af
commit
1def055dcb
20 changed files with 0 additions and 9181 deletions
|
@ -1,149 +0,0 @@
|
|||
//
|
||||
// d_copy.s
|
||||
// x86 assembly-language screen copying code.
|
||||
//
|
||||
|
||||
#include "asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
|
||||
.data
|
||||
|
||||
LCopyWidth: .long 0
|
||||
LBlockSrcStep: .long 0
|
||||
LBlockDestStep: .long 0
|
||||
LSrcDelta: .long 0
|
||||
LDestDelta: .long 0
|
||||
|
||||
#define bufptr 4+16
|
||||
|
||||
// copies 16 rows per plane at a pop; idea is that 16*512 = 8k, and since
|
||||
// no Mode X mode is wider than 360, all the data should fit in the cache for
|
||||
// the passes for the next 3 planes
|
||||
|
||||
.text
|
||||
|
||||
.globl C(VGA_UpdatePlanarScreen)
|
||||
C(VGA_UpdatePlanarScreen):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
movl C(VGA_bufferrowbytes),%eax
|
||||
shll $1,%eax
|
||||
movl %eax,LBlockSrcStep
|
||||
movl C(VGA_rowbytes),%eax
|
||||
shll $1,%eax
|
||||
movl %eax,LBlockDestStep
|
||||
|
||||
movl $0x3C4,%edx
|
||||
movb $2,%al
|
||||
outb %al,%dx // point the SC to the Map Mask
|
||||
incl %edx
|
||||
|
||||
movl bufptr(%esp),%esi
|
||||
movl C(VGA_pagebase),%edi
|
||||
movl C(VGA_height),%ebp
|
||||
shrl $1,%ebp
|
||||
|
||||
movl C(VGA_width),%ecx
|
||||
movl C(VGA_bufferrowbytes),%eax
|
||||
subl %ecx,%eax
|
||||
movl %eax,LSrcDelta
|
||||
movl C(VGA_rowbytes),%eax
|
||||
shll $2,%eax
|
||||
subl %ecx,%eax
|
||||
movl %eax,LDestDelta
|
||||
shrl $4,%ecx
|
||||
movl %ecx,LCopyWidth
|
||||
|
||||
LRowLoop:
|
||||
movb $1,%al
|
||||
|
||||
LPlaneLoop:
|
||||
outb %al,%dx
|
||||
movb $2,%ah
|
||||
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
LRowSetLoop:
|
||||
movl LCopyWidth,%ecx
|
||||
LColumnLoop:
|
||||
movb 12(%esi),%bh
|
||||
movb 8(%esi),%bl
|
||||
shll $16,%ebx
|
||||
movb 4(%esi),%bh
|
||||
movb (%esi),%bl
|
||||
movl %ebx,(%edi)
|
||||
addl $16,%esi
|
||||
addl $4,%edi
|
||||
decl %ecx
|
||||
jnz LColumnLoop
|
||||
|
||||
addl LDestDelta,%edi
|
||||
addl LSrcDelta,%esi
|
||||
decb %ah
|
||||
jnz LRowSetLoop
|
||||
|
||||
popl %edi
|
||||
popl %esi
|
||||
incl %esi
|
||||
|
||||
shlb $1,%al
|
||||
cmpb $16,%al
|
||||
jnz LPlaneLoop
|
||||
|
||||
subl $4,%esi
|
||||
addl LBlockSrcStep,%esi
|
||||
addl LBlockDestStep,%edi
|
||||
decl %ebp
|
||||
jnz LRowLoop
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
|
||||
ret
|
||||
|
||||
|
||||
#define srcptr 4+16
|
||||
#define destptr 8+16
|
||||
#define width 12+16
|
||||
#define height 16+16
|
||||
#define srcrowbytes 20+16
|
||||
#define destrowbytes 24+16
|
||||
|
||||
.globl C(VGA_UpdateLinearScreen)
|
||||
C(VGA_UpdateLinearScreen):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
cld
|
||||
movl srcptr(%esp),%esi
|
||||
movl destptr(%esp),%edi
|
||||
movl width(%esp),%ebx
|
||||
movl srcrowbytes(%esp),%eax
|
||||
subl %ebx,%eax
|
||||
movl destrowbytes(%esp),%edx
|
||||
subl %ebx,%edx
|
||||
shrl $2,%ebx
|
||||
movl height(%esp),%ebp
|
||||
LLRowLoop:
|
||||
movl %ebx,%ecx
|
||||
rep/movsl (%esi),(%edi)
|
||||
addl %eax,%esi
|
||||
addl %edx,%edi
|
||||
decl %ebp
|
||||
jnz LLRowLoop
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
|
||||
ret
|
||||
|
1037
qw_client/d_draw.s
1037
qw_client/d_draw.s
File diff suppressed because it is too large
Load diff
|
@ -1,974 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
//
|
||||
// d_draw16.s
|
||||
// x86 assembly-language horizontal 8-bpp span-drawing code, with 16-pixel
|
||||
// subdivision.
|
||||
//
|
||||
|
||||
#include "asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
#include "d_ifacea.h"
|
||||
|
||||
#if id386
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 8-bpp horizontal span drawing code for polygons, with no transparency and
|
||||
// 16-pixel subdivision.
|
||||
//
|
||||
// Assumes there is at least one span in pspans, and that every span
|
||||
// contains at least one pixel
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.data
|
||||
|
||||
.text
|
||||
|
||||
// out-of-line, rarely-needed clamping code
|
||||
|
||||
LClampHigh0:
|
||||
movl C(bbextents),%esi
|
||||
jmp LClampReentry0
|
||||
LClampHighOrLow0:
|
||||
jg LClampHigh0
|
||||
xorl %esi,%esi
|
||||
jmp LClampReentry0
|
||||
|
||||
LClampHigh1:
|
||||
movl C(bbextentt),%edx
|
||||
jmp LClampReentry1
|
||||
LClampHighOrLow1:
|
||||
jg LClampHigh1
|
||||
xorl %edx,%edx
|
||||
jmp LClampReentry1
|
||||
|
||||
LClampLow2:
|
||||
movl $4096,%ebp
|
||||
jmp LClampReentry2
|
||||
LClampHigh2:
|
||||
movl C(bbextents),%ebp
|
||||
jmp LClampReentry2
|
||||
|
||||
LClampLow3:
|
||||
movl $4096,%ecx
|
||||
jmp LClampReentry3
|
||||
LClampHigh3:
|
||||
movl C(bbextentt),%ecx
|
||||
jmp LClampReentry3
|
||||
|
||||
LClampLow4:
|
||||
movl $4096,%eax
|
||||
jmp LClampReentry4
|
||||
LClampHigh4:
|
||||
movl C(bbextents),%eax
|
||||
jmp LClampReentry4
|
||||
|
||||
LClampLow5:
|
||||
movl $4096,%ebx
|
||||
jmp LClampReentry5
|
||||
LClampHigh5:
|
||||
movl C(bbextentt),%ebx
|
||||
jmp LClampReentry5
|
||||
|
||||
|
||||
#define pspans 4+16
|
||||
|
||||
.align 4
|
||||
.globl C(D_DrawSpans16)
|
||||
C(D_DrawSpans16):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
//
|
||||
// set up scaled-by-16 steps, for 16-long segments; also set up cacheblock
|
||||
// and span list pointers
|
||||
//
|
||||
// TODO: any overlap from rearranging?
|
||||
flds C(d_sdivzstepu)
|
||||
fmuls fp_16
|
||||
movl C(cacheblock),%edx
|
||||
flds C(d_tdivzstepu)
|
||||
fmuls fp_16
|
||||
movl pspans(%esp),%ebx // point to the first span descriptor
|
||||
flds C(d_zistepu)
|
||||
fmuls fp_16
|
||||
movl %edx,pbase // pbase = cacheblock
|
||||
fstps zi16stepu
|
||||
fstps tdivz16stepu
|
||||
fstps sdivz16stepu
|
||||
|
||||
LSpanLoop:
|
||||
//
|
||||
// set up the initial s/z, t/z, and 1/z on the FP stack, and generate the
|
||||
// initial s and t values
|
||||
//
|
||||
// FIXME: pipeline FILD?
|
||||
fildl espan_t_v(%ebx)
|
||||
fildl espan_t_u(%ebx)
|
||||
|
||||
fld %st(1) // dv | du | dv
|
||||
fmuls C(d_sdivzstepv) // dv*d_sdivzstepv | du | dv
|
||||
fld %st(1) // du | dv*d_sdivzstepv | du | dv
|
||||
fmuls C(d_sdivzstepu) // du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
|
||||
fld %st(2) // du | du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
|
||||
fmuls C(d_tdivzstepu) // du*d_tdivzstepu | du*d_sdivzstepu |
|
||||
// dv*d_sdivzstepv | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu | du*d_tdivzstepu |
|
||||
// dv*d_sdivzstepv | du | dv
|
||||
faddp %st(0),%st(2) // du*d_tdivzstepu |
|
||||
// du*d_sdivzstepu + dv*d_sdivzstepv | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fld %st(3) // dv | du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fmuls C(d_tdivzstepv) // dv*d_tdivzstepv |
|
||||
// du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// dv*d_tdivzstepv | du*d_tdivzstepu | du | dv
|
||||
fadds C(d_sdivzorigin) // sdivz = d_sdivzorigin + dv*d_sdivzstepv +
|
||||
// du*d_sdivzstepu; stays in %st(2) at end
|
||||
fxch %st(4) // dv | dv*d_tdivzstepv | du*d_tdivzstepu | du |
|
||||
// s/z
|
||||
fmuls C(d_zistepv) // dv*d_zistepv | dv*d_tdivzstepv |
|
||||
// du*d_tdivzstepu | du | s/z
|
||||
fxch %st(1) // dv*d_tdivzstepv | dv*d_zistepv |
|
||||
// du*d_tdivzstepu | du | s/z
|
||||
faddp %st(0),%st(2) // dv*d_zistepv |
|
||||
// dv*d_tdivzstepv + du*d_tdivzstepu | du | s/z
|
||||
fxch %st(2) // du | dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// dv*d_zistepv | s/z
|
||||
fmuls C(d_zistepu) // du*d_zistepu |
|
||||
// dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// dv*d_zistepv | s/z
|
||||
fxch %st(1) // dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// du*d_zistepu | dv*d_zistepv | s/z
|
||||
fadds C(d_tdivzorigin) // tdivz = d_tdivzorigin + dv*d_tdivzstepv +
|
||||
// du*d_tdivzstepu; stays in %st(1) at end
|
||||
fxch %st(2) // dv*d_zistepv | du*d_zistepu | t/z | s/z
|
||||
faddp %st(0),%st(1) // dv*d_zistepv + du*d_zistepu | t/z | s/z
|
||||
|
||||
flds fp_64k // fp_64k | dv*d_zistepv + du*d_zistepu | t/z | s/z
|
||||
fxch %st(1) // dv*d_zistepv + du*d_zistepu | fp_64k | t/z | s/z
|
||||
fadds C(d_ziorigin) // zi = d_ziorigin + dv*d_zistepv +
|
||||
// du*d_zistepu; stays in %st(0) at end
|
||||
// 1/z | fp_64k | t/z | s/z
|
||||
//
|
||||
// calculate and clamp s & t
|
||||
//
|
||||
fdivr %st(0),%st(1) // 1/z | z*64k | t/z | s/z
|
||||
|
||||
//
|
||||
// point %edi to the first pixel in the span
|
||||
//
|
||||
movl C(d_viewbuffer),%ecx
|
||||
movl espan_t_v(%ebx),%eax
|
||||
movl %ebx,pspantemp // preserve spans pointer
|
||||
|
||||
movl C(tadjust),%edx
|
||||
movl C(sadjust),%esi
|
||||
movl C(d_scantable)(,%eax,4),%edi // v * screenwidth
|
||||
addl %ecx,%edi
|
||||
movl espan_t_u(%ebx),%ecx
|
||||
addl %ecx,%edi // pdest = &pdestspan[scans->u];
|
||||
movl espan_t_count(%ebx),%ecx
|
||||
|
||||
//
|
||||
// now start the FDIV for the end of the span
|
||||
//
|
||||
cmpl $16,%ecx
|
||||
ja LSetupNotLast1
|
||||
|
||||
decl %ecx
|
||||
jz LCleanup1 // if only one pixel, no need to start an FDIV
|
||||
movl %ecx,spancountminus1
|
||||
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
|
||||
fildl spancountminus1
|
||||
|
||||
flds C(d_tdivzstepu) // C(d_tdivzstepu) | spancountminus1
|
||||
flds C(d_zistepu) // C(d_zistepu) | C(d_tdivzstepu) | spancountminus1
|
||||
fmul %st(2),%st(0) // C(d_zistepu)*scm1 | C(d_tdivzstepu) | scm1
|
||||
fxch %st(1) // C(d_tdivzstepu) | C(d_zistepu)*scm1 | scm1
|
||||
fmul %st(2),%st(0) // C(d_tdivzstepu)*scm1 | C(d_zistepu)*scm1 | scm1
|
||||
fxch %st(2) // scm1 | C(d_zistepu)*scm1 | C(d_tdivzstepu)*scm1
|
||||
fmuls C(d_sdivzstepu) // C(d_sdivzstepu)*scm1 | C(d_zistepu)*scm1 |
|
||||
// C(d_tdivzstepu)*scm1
|
||||
fxch %st(1) // C(d_zistepu)*scm1 | C(d_sdivzstepu)*scm1 |
|
||||
// C(d_tdivzstepu)*scm1
|
||||
faddp %st(0),%st(3) // C(d_sdivzstepu)*scm1 | C(d_tdivzstepu)*scm1
|
||||
fxch %st(1) // C(d_tdivzstepu)*scm1 | C(d_sdivzstepu)*scm1
|
||||
faddp %st(0),%st(3) // C(d_sdivzstepu)*scm1
|
||||
faddp %st(0),%st(3)
|
||||
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
jmp LFDIVInFlight1
|
||||
|
||||
LCleanup1:
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
jmp LFDIVInFlight1
|
||||
|
||||
.align 4
|
||||
LSetupNotLast1:
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
|
||||
fadds zi16stepu
|
||||
fxch %st(2)
|
||||
fadds sdivz16stepu
|
||||
fxch %st(2)
|
||||
flds tdivz16stepu
|
||||
faddp %st(0),%st(2)
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // z = 1/1/z
|
||||
// this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
LFDIVInFlight1:
|
||||
|
||||
addl s,%esi
|
||||
addl t,%edx
|
||||
movl C(bbextents),%ebx
|
||||
movl C(bbextentt),%ebp
|
||||
cmpl %ebx,%esi
|
||||
ja LClampHighOrLow0
|
||||
LClampReentry0:
|
||||
movl %esi,s
|
||||
movl pbase,%ebx
|
||||
shll $16,%esi
|
||||
cmpl %ebp,%edx
|
||||
movl %esi,sfracf
|
||||
ja LClampHighOrLow1
|
||||
LClampReentry1:
|
||||
movl %edx,t
|
||||
movl s,%esi // sfrac = scans->sfrac;
|
||||
shll $16,%edx
|
||||
movl t,%eax // tfrac = scans->tfrac;
|
||||
sarl $16,%esi
|
||||
movl %edx,tfracf
|
||||
|
||||
//
|
||||
// calculate the texture starting address
|
||||
//
|
||||
sarl $16,%eax
|
||||
movl C(cachewidth),%edx
|
||||
imull %edx,%eax // (tfrac >> 16) * cachewidth
|
||||
addl %ebx,%esi
|
||||
addl %eax,%esi // psource = pbase + (sfrac >> 16) +
|
||||
// ((tfrac >> 16) * cachewidth);
|
||||
//
|
||||
// determine whether last span or not
|
||||
//
|
||||
cmpl $16,%ecx
|
||||
jna LLastSegment
|
||||
|
||||
//
|
||||
// not the last segment; do full 16-wide segment
|
||||
//
|
||||
LNotLastSegment:
|
||||
|
||||
//
|
||||
// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
|
||||
// get there
|
||||
//
|
||||
|
||||
// pick up after the FDIV that was left in flight previously
|
||||
|
||||
fld %st(0) // duplicate it
|
||||
fmul %st(4),%st(0) // s = s/z * z
|
||||
fxch %st(1)
|
||||
fmul %st(3),%st(0) // t = t/z * z
|
||||
fxch %st(1)
|
||||
fistpl snext
|
||||
fistpl tnext
|
||||
movl snext,%eax
|
||||
movl tnext,%edx
|
||||
|
||||
movb (%esi),%bl // get first source texel
|
||||
subl $16,%ecx // count off this segments' pixels
|
||||
movl C(sadjust),%ebp
|
||||
movl %ecx,counttemp // remember count of remaining pixels
|
||||
|
||||
movl C(tadjust),%ecx
|
||||
movb %bl,(%edi) // store first dest pixel
|
||||
|
||||
addl %eax,%ebp
|
||||
addl %edx,%ecx
|
||||
|
||||
movl C(bbextents),%eax
|
||||
movl C(bbextentt),%edx
|
||||
|
||||
cmpl $4096,%ebp
|
||||
jl LClampLow2
|
||||
cmpl %eax,%ebp
|
||||
ja LClampHigh2
|
||||
LClampReentry2:
|
||||
|
||||
cmpl $4096,%ecx
|
||||
jl LClampLow3
|
||||
cmpl %edx,%ecx
|
||||
ja LClampHigh3
|
||||
LClampReentry3:
|
||||
|
||||
movl %ebp,snext
|
||||
movl %ecx,tnext
|
||||
|
||||
subl s,%ebp
|
||||
subl t,%ecx
|
||||
|
||||
//
|
||||
// set up advancetable
|
||||
//
|
||||
movl %ecx,%eax
|
||||
movl %ebp,%edx
|
||||
sarl $20,%eax // tstep >>= 16;
|
||||
jz LZero
|
||||
sarl $20,%edx // sstep >>= 16;
|
||||
movl C(cachewidth),%ebx
|
||||
imull %ebx,%eax
|
||||
jmp LSetUp1
|
||||
|
||||
LZero:
|
||||
sarl $20,%edx // sstep >>= 16;
|
||||
movl C(cachewidth),%ebx
|
||||
|
||||
LSetUp1:
|
||||
|
||||
addl %edx,%eax // add in sstep
|
||||
// (tstep >> 16) * cachewidth + (sstep >> 16);
|
||||
movl tfracf,%edx
|
||||
movl %eax,advancetable+4 // advance base in t
|
||||
addl %ebx,%eax // ((tstep >> 16) + 1) * cachewidth +
|
||||
// (sstep >> 16);
|
||||
shll $12,%ebp // left-justify sstep fractional part
|
||||
movl sfracf,%ebx
|
||||
shll $12,%ecx // left-justify tstep fractional part
|
||||
movl %eax,advancetable // advance extra in t
|
||||
|
||||
movl %ecx,tstep
|
||||
addl %ecx,%edx // advance tfrac fractional part by tstep frac
|
||||
|
||||
sbbl %ecx,%ecx // turn tstep carry into -1 (0 if none)
|
||||
addl %ebp,%ebx // advance sfrac fractional part by sstep frac
|
||||
adcl advancetable+4(,%ecx,4),%esi // point to next source texel
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb (%esi),%al
|
||||
addl %ebp,%ebx
|
||||
movb %al,1(%edi)
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,2(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,3(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,4(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,5(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,6(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,7(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
|
||||
//
|
||||
// start FDIV for end of next segment in flight, so it can overlap
|
||||
//
|
||||
movl counttemp,%ecx
|
||||
cmpl $16,%ecx // more than one segment after this?
|
||||
ja LSetupNotLast2 // yes
|
||||
|
||||
decl %ecx
|
||||
jz LFDIVInFlight2 // if only one pixel, no need to start an FDIV
|
||||
movl %ecx,spancountminus1
|
||||
fildl spancountminus1
|
||||
|
||||
flds C(d_zistepu) // C(d_zistepu) | spancountminus1
|
||||
fmul %st(1),%st(0) // C(d_zistepu)*scm1 | scm1
|
||||
flds C(d_tdivzstepu) // C(d_tdivzstepu) | C(d_zistepu)*scm1 | scm1
|
||||
fmul %st(2),%st(0) // C(d_tdivzstepu)*scm1 | C(d_zistepu)*scm1 | scm1
|
||||
fxch %st(1) // C(d_zistepu)*scm1 | C(d_tdivzstepu)*scm1 | scm1
|
||||
faddp %st(0),%st(3) // C(d_tdivzstepu)*scm1 | scm1
|
||||
fxch %st(1) // scm1 | C(d_tdivzstepu)*scm1
|
||||
fmuls C(d_sdivzstepu) // C(d_sdivzstepu)*scm1 | C(d_tdivzstepu)*scm1
|
||||
fxch %st(1) // C(d_tdivzstepu)*scm1 | C(d_sdivzstepu)*scm1
|
||||
faddp %st(0),%st(3) // C(d_sdivzstepu)*scm1
|
||||
flds fp_64k // 64k | C(d_sdivzstepu)*scm1
|
||||
fxch %st(1) // C(d_sdivzstepu)*scm1 | 64k
|
||||
faddp %st(0),%st(4) // 64k
|
||||
|
||||
fdiv %st(1),%st(0) // this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
jmp LFDIVInFlight2
|
||||
|
||||
.align 4
|
||||
LSetupNotLast2:
|
||||
fadds zi16stepu
|
||||
fxch %st(2)
|
||||
fadds sdivz16stepu
|
||||
fxch %st(2)
|
||||
flds tdivz16stepu
|
||||
faddp %st(0),%st(2)
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // z = 1/1/z
|
||||
// this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
LFDIVInFlight2:
|
||||
movl %ecx,counttemp
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,8(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,9(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,10(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,11(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,12(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,13(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,14(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl $16,%edi
|
||||
movl %edx,tfracf
|
||||
movl snext,%edx
|
||||
movl %ebx,sfracf
|
||||
movl tnext,%ebx
|
||||
movl %edx,s
|
||||
movl %ebx,t
|
||||
|
||||
movl counttemp,%ecx // retrieve count
|
||||
|
||||
//
|
||||
// determine whether last span or not
|
||||
//
|
||||
cmpl $16,%ecx // are there multiple segments remaining?
|
||||
movb %al,-1(%edi)
|
||||
ja LNotLastSegment // yes
|
||||
|
||||
//
|
||||
// last segment of scan
|
||||
//
|
||||
LLastSegment:
|
||||
|
||||
//
|
||||
// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
|
||||
// get there. The number of pixels left is variable, and we want to land on the
|
||||
// last pixel, not step one past it, so we can't run into arithmetic problems
|
||||
//
|
||||
testl %ecx,%ecx
|
||||
jz LNoSteps // just draw the last pixel and we're done
|
||||
|
||||
// pick up after the FDIV that was left in flight previously
|
||||
|
||||
|
||||
fld %st(0) // duplicate it
|
||||
fmul %st(4),%st(0) // s = s/z * z
|
||||
fxch %st(1)
|
||||
fmul %st(3),%st(0) // t = t/z * z
|
||||
fxch %st(1)
|
||||
fistpl snext
|
||||
fistpl tnext
|
||||
|
||||
movb (%esi),%al // load first texel in segment
|
||||
movl C(tadjust),%ebx
|
||||
movb %al,(%edi) // store first pixel in segment
|
||||
movl C(sadjust),%eax
|
||||
|
||||
addl snext,%eax
|
||||
addl tnext,%ebx
|
||||
|
||||
movl C(bbextents),%ebp
|
||||
movl C(bbextentt),%edx
|
||||
|
||||
cmpl $4096,%eax
|
||||
jl LClampLow4
|
||||
cmpl %ebp,%eax
|
||||
ja LClampHigh4
|
||||
LClampReentry4:
|
||||
movl %eax,snext
|
||||
|
||||
cmpl $4096,%ebx
|
||||
jl LClampLow5
|
||||
cmpl %edx,%ebx
|
||||
ja LClampHigh5
|
||||
LClampReentry5:
|
||||
|
||||
cmpl $1,%ecx // don't bother
|
||||
je LOnlyOneStep // if two pixels in segment, there's only one step,
|
||||
// of the segment length
|
||||
subl s,%eax
|
||||
subl t,%ebx
|
||||
|
||||
addl %eax,%eax // convert to 15.17 format so multiply by 1.31
|
||||
addl %ebx,%ebx // reciprocal yields 16.48
|
||||
|
||||
imull reciprocal_table_16-8(,%ecx,4) // sstep = (snext - s) /
|
||||
// (spancount-1)
|
||||
movl %edx,%ebp
|
||||
|
||||
movl %ebx,%eax
|
||||
imull reciprocal_table_16-8(,%ecx,4) // tstep = (tnext - t) /
|
||||
// (spancount-1)
|
||||
LSetEntryvec:
|
||||
//
|
||||
// set up advancetable
|
||||
//
|
||||
movl entryvec_table_16(,%ecx,4),%ebx
|
||||
movl %edx,%eax
|
||||
movl %ebx,jumptemp // entry point into code for RET later
|
||||
movl %ebp,%ecx
|
||||
sarl $16,%edx // tstep >>= 16;
|
||||
movl C(cachewidth),%ebx
|
||||
sarl $16,%ecx // sstep >>= 16;
|
||||
imull %ebx,%edx
|
||||
|
||||
addl %ecx,%edx // add in sstep
|
||||
// (tstep >> 16) * cachewidth + (sstep >> 16);
|
||||
movl tfracf,%ecx
|
||||
movl %edx,advancetable+4 // advance base in t
|
||||
addl %ebx,%edx // ((tstep >> 16) + 1) * cachewidth +
|
||||
// (sstep >> 16);
|
||||
shll $16,%ebp // left-justify sstep fractional part
|
||||
movl sfracf,%ebx
|
||||
shll $16,%eax // left-justify tstep fractional part
|
||||
movl %edx,advancetable // advance extra in t
|
||||
|
||||
movl %eax,tstep
|
||||
movl %ecx,%edx
|
||||
addl %eax,%edx
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
jmp *jumptemp // jump to the number-of-pixels handler
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
LNoSteps:
|
||||
movb (%esi),%al // load first texel in segment
|
||||
subl $15,%edi // adjust for hardwired offset
|
||||
jmp LEndSpan
|
||||
|
||||
|
||||
LOnlyOneStep:
|
||||
subl s,%eax
|
||||
subl t,%ebx
|
||||
movl %eax,%ebp
|
||||
movl %ebx,%edx
|
||||
jmp LSetEntryvec
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Entry2_16, Entry3_16, Entry4_16, Entry5_16
|
||||
.globl Entry6_16, Entry7_16, Entry8_16, Entry9_16
|
||||
.globl Entry10_16, Entry11_16, Entry12_16, Entry13_16
|
||||
.globl Entry14_16, Entry15_16, Entry16_16
|
||||
|
||||
Entry2_16:
|
||||
subl $14,%edi // adjust for hardwired offsets
|
||||
movb (%esi),%al
|
||||
jmp LEntry2_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry3_16:
|
||||
subl $13,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
jmp LEntry3_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry4_16:
|
||||
subl $12,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry4_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry5_16:
|
||||
subl $11,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry5_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry6_16:
|
||||
subl $10,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry6_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry7_16:
|
||||
subl $9,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry7_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry8_16:
|
||||
subl $8,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry8_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry9_16:
|
||||
subl $7,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry9_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry10_16:
|
||||
subl $6,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry10_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry11_16:
|
||||
subl $5,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry11_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry12_16:
|
||||
subl $4,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry12_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry13_16:
|
||||
subl $3,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry13_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry14_16:
|
||||
subl $2,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry14_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry15_16:
|
||||
decl %edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry15_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry16_16:
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,1(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry15_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,2(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry14_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,3(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry13_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,4(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry12_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,5(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry11_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,6(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry10_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,7(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry9_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,8(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry8_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,9(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry7_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,10(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry6_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,11(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry5_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,12(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry4_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,13(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
LEntry3_16:
|
||||
movb %al,14(%edi)
|
||||
movb (%esi),%al
|
||||
LEntry2_16:
|
||||
|
||||
LEndSpan:
|
||||
|
||||
//
|
||||
// clear s/z, t/z, 1/z from FP stack
|
||||
//
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
|
||||
movl pspantemp,%ebx // restore spans pointer
|
||||
movl espan_t_pnext(%ebx),%ebx // point to next span
|
||||
testl %ebx,%ebx // any more spans?
|
||||
movb %al,15(%edi)
|
||||
jnz LSpanLoop // more spans
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
#endif // id386
|
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
// d_clear: clears a specified rectangle to the specified color
|
||||
|
||||
#include "quakedef.h"
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
D_FillRect
|
||||
================
|
||||
*/
|
||||
void D_FillRect (vrect_t *rect, int color)
|
||||
{
|
||||
int rx, ry, rwidth, rheight;
|
||||
unsigned char *dest;
|
||||
unsigned *ldest;
|
||||
|
||||
rx = rect->x;
|
||||
ry = rect->y;
|
||||
rwidth = rect->width;
|
||||
rheight = rect->height;
|
||||
|
||||
if (rx < 0)
|
||||
{
|
||||
rwidth += rx;
|
||||
rx = 0;
|
||||
}
|
||||
if (ry < 0)
|
||||
{
|
||||
rheight += ry;
|
||||
ry = 0;
|
||||
}
|
||||
if (rx+rwidth > vid.width)
|
||||
rwidth = vid.width - rx;
|
||||
if (ry+rheight > vid.height)
|
||||
rheight = vid.height - rx;
|
||||
|
||||
if (rwidth < 1 || rheight < 1)
|
||||
return;
|
||||
|
||||
dest = ((byte *)vid.buffer + ry*vid.rowbytes + rx);
|
||||
|
||||
if (((rwidth & 0x03) == 0) && (((long)dest & 0x03) == 0))
|
||||
{
|
||||
// faster aligned dword clear
|
||||
ldest = (unsigned *)dest;
|
||||
color += color << 16;
|
||||
|
||||
rwidth >>= 2;
|
||||
color += color << 8;
|
||||
|
||||
for (ry=0 ; ry<rheight ; ry++)
|
||||
{
|
||||
for (rx=0 ; rx<rwidth ; rx++)
|
||||
ldest[rx] = color;
|
||||
ldest = (unsigned *)((byte*)ldest + vid.rowbytes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// slower byte-by-byte clear for unaligned cases
|
||||
for (ry=0 ; ry<rheight ; ry++)
|
||||
{
|
||||
for (rx=0 ; rx<rwidth ; rx++)
|
||||
dest[rx] = color;
|
||||
dest += vid.rowbytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,174 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
// d_init.c: rasterization driver initialization
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "d_local.h"
|
||||
|
||||
#define NUM_MIPS 4
|
||||
|
||||
cvar_t d_subdiv16 = {"d_subdiv16", "1"};
|
||||
cvar_t d_mipcap = {"d_mipcap", "0"};
|
||||
cvar_t d_mipscale = {"d_mipscale", "1"};
|
||||
|
||||
surfcache_t *d_initial_rover;
|
||||
qboolean d_roverwrapped;
|
||||
int d_minmip;
|
||||
float d_scalemip[NUM_MIPS-1];
|
||||
|
||||
static float basemip[NUM_MIPS-1] = {1.0, 0.5*0.8, 0.25*0.8};
|
||||
|
||||
extern int d_aflatcolor;
|
||||
|
||||
void (*d_drawspans) (espan_t *pspan);
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
D_Init
|
||||
===============
|
||||
*/
|
||||
void D_Init (void)
|
||||
{
|
||||
|
||||
r_skydirect = 1;
|
||||
|
||||
Cvar_RegisterVariable (&d_subdiv16);
|
||||
Cvar_RegisterVariable (&d_mipcap);
|
||||
Cvar_RegisterVariable (&d_mipscale);
|
||||
|
||||
r_drawpolys = false;
|
||||
r_worldpolysbacktofront = false;
|
||||
r_recursiveaffinetriangles = true;
|
||||
r_pixbytes = 1;
|
||||
r_aliasuvscale = 1.0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
D_CopyRects
|
||||
===============
|
||||
*/
|
||||
void D_CopyRects (vrect_t *prects, int transparent)
|
||||
{
|
||||
|
||||
// this function is only required if the CPU doesn't have direct access to the
|
||||
// back buffer, and there's some driver interface function that the driver
|
||||
// doesn't support and requires Quake to do in software (such as drawing the
|
||||
// console); Quake will then draw into wherever the driver points vid.buffer
|
||||
// and will call this function before swapping buffers
|
||||
|
||||
UNUSED(prects);
|
||||
UNUSED(transparent);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
D_EnableBackBufferAccess
|
||||
===============
|
||||
*/
|
||||
void D_EnableBackBufferAccess (void)
|
||||
{
|
||||
|
||||
VID_LockBuffer ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
D_TurnZOn
|
||||
===============
|
||||
*/
|
||||
void D_TurnZOn (void)
|
||||
{
|
||||
// not needed for software version
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
D_DisableBackBufferAccess
|
||||
===============
|
||||
*/
|
||||
void D_DisableBackBufferAccess (void)
|
||||
{
|
||||
VID_UnlockBuffer ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
D_SetupFrame
|
||||
===============
|
||||
*/
|
||||
void D_SetupFrame (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (r_dowarp)
|
||||
d_viewbuffer = r_warpbuffer;
|
||||
else
|
||||
d_viewbuffer = (void *)(byte *)vid.buffer;
|
||||
|
||||
if (r_dowarp)
|
||||
screenwidth = WARP_WIDTH;
|
||||
else
|
||||
screenwidth = vid.rowbytes;
|
||||
|
||||
d_roverwrapped = false;
|
||||
d_initial_rover = sc_rover;
|
||||
|
||||
d_minmip = d_mipcap.value;
|
||||
if (d_minmip > 3)
|
||||
d_minmip = 3;
|
||||
else if (d_minmip < 0)
|
||||
d_minmip = 0;
|
||||
|
||||
for (i=0 ; i<(NUM_MIPS-1) ; i++)
|
||||
d_scalemip[i] = basemip[i] * d_mipscale.value;
|
||||
|
||||
#if id386
|
||||
if (d_subdiv16.value)
|
||||
d_drawspans = D_DrawSpans16;
|
||||
else
|
||||
d_drawspans = D_DrawSpans8;
|
||||
#else
|
||||
d_drawspans = D_DrawSpans8;
|
||||
#endif
|
||||
|
||||
d_aflatcolor = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
D_UpdateRects
|
||||
===============
|
||||
*/
|
||||
void D_UpdateRects (vrect_t *prect)
|
||||
{
|
||||
|
||||
// the software driver draws these directly to the vid buffer
|
||||
|
||||
UNUSED(prect);
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
// d_modech.c: called when mode has just changed
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "d_local.h"
|
||||
|
||||
int d_vrectx, d_vrecty, d_vrectright_particle, d_vrectbottom_particle;
|
||||
|
||||
int d_y_aspect_shift, d_pix_min, d_pix_max, d_pix_shift;
|
||||
|
||||
int d_scantable[MAXHEIGHT];
|
||||
short *zspantable[MAXHEIGHT];
|
||||
|
||||
/*
|
||||
================
|
||||
D_Patch
|
||||
================
|
||||
*/
|
||||
void D_Patch (void)
|
||||
{
|
||||
#if id386
|
||||
|
||||
static qboolean protectset8 = false;
|
||||
|
||||
if (!protectset8)
|
||||
{
|
||||
Sys_MakeCodeWriteable ((int)D_PolysetAff8Start,
|
||||
(int)D_PolysetAff8End - (int)D_PolysetAff8Start);
|
||||
protectset8 = true;
|
||||
}
|
||||
|
||||
#endif // id386
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
D_ViewChanged
|
||||
================
|
||||
*/
|
||||
void D_ViewChanged (void)
|
||||
{
|
||||
int rowbytes;
|
||||
|
||||
if (r_dowarp)
|
||||
rowbytes = WARP_WIDTH;
|
||||
else
|
||||
rowbytes = vid.rowbytes;
|
||||
|
||||
scale_for_mip = xscale;
|
||||
if (yscale > xscale)
|
||||
scale_for_mip = yscale;
|
||||
|
||||
d_zrowbytes = vid.width * 2;
|
||||
d_zwidth = vid.width;
|
||||
|
||||
d_pix_min = r_refdef.vrect.width / 320;
|
||||
if (d_pix_min < 1)
|
||||
d_pix_min = 1;
|
||||
|
||||
d_pix_max = (int)((float)r_refdef.vrect.width / (320.0 / 4.0) + 0.5);
|
||||
d_pix_shift = 8 - (int)((float)r_refdef.vrect.width / 320.0 + 0.5);
|
||||
if (d_pix_max < 1)
|
||||
d_pix_max = 1;
|
||||
|
||||
if (pixelAspect > 1.4)
|
||||
d_y_aspect_shift = 1;
|
||||
else
|
||||
d_y_aspect_shift = 0;
|
||||
|
||||
d_vrectx = r_refdef.vrect.x;
|
||||
d_vrecty = r_refdef.vrect.y;
|
||||
d_vrectright_particle = r_refdef.vrectright - d_pix_max;
|
||||
d_vrectbottom_particle =
|
||||
r_refdef.vrectbottom - (d_pix_max << d_y_aspect_shift);
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0 ; i<vid.height; i++)
|
||||
{
|
||||
d_scantable[i] = i*rowbytes;
|
||||
zspantable[i] = d_pzbuffer + i*d_zwidth;
|
||||
}
|
||||
}
|
||||
|
||||
D_Patch ();
|
||||
}
|
||||
|
|
@ -1,207 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
// d_part.c: software driver module for drawing particles
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "d_local.h"
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
D_EndParticles
|
||||
==============
|
||||
*/
|
||||
void D_EndParticles (void)
|
||||
{
|
||||
// not used by software driver
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
D_StartParticles
|
||||
==============
|
||||
*/
|
||||
void D_StartParticles (void)
|
||||
{
|
||||
// not used by software driver
|
||||
}
|
||||
|
||||
|
||||
#if !id386
|
||||
|
||||
/*
|
||||
==============
|
||||
D_DrawParticle
|
||||
==============
|
||||
*/
|
||||
void D_DrawParticle (particle_t *pparticle)
|
||||
{
|
||||
vec3_t local, transformed;
|
||||
float zi;
|
||||
byte *pdest;
|
||||
short *pz;
|
||||
int i, izi, pix, count, u, v;
|
||||
|
||||
// transform point
|
||||
VectorSubtract (pparticle->org, r_origin, local);
|
||||
|
||||
transformed[0] = DotProduct(local, r_pright);
|
||||
transformed[1] = DotProduct(local, r_pup);
|
||||
transformed[2] = DotProduct(local, r_ppn);
|
||||
|
||||
if (transformed[2] < PARTICLE_Z_CLIP)
|
||||
return;
|
||||
|
||||
// project the point
|
||||
// FIXME: preadjust xcenter and ycenter
|
||||
zi = 1.0 / transformed[2];
|
||||
u = (int)(xcenter + zi * transformed[0] + 0.5);
|
||||
v = (int)(ycenter - zi * transformed[1] + 0.5);
|
||||
|
||||
if ((v > d_vrectbottom_particle) ||
|
||||
(u > d_vrectright_particle) ||
|
||||
(v < d_vrecty) ||
|
||||
(u < d_vrectx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pz = d_pzbuffer + (d_zwidth * v) + u;
|
||||
pdest = d_viewbuffer + d_scantable[v] + u;
|
||||
izi = (int)(zi * 0x8000);
|
||||
|
||||
pix = izi >> d_pix_shift;
|
||||
|
||||
if (pix < d_pix_min)
|
||||
pix = d_pix_min;
|
||||
else if (pix > d_pix_max)
|
||||
pix = d_pix_max;
|
||||
|
||||
switch (pix)
|
||||
{
|
||||
case 1:
|
||||
count = 1 << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
if (pz[0] <= izi)
|
||||
{
|
||||
pz[0] = izi;
|
||||
pdest[0] = pparticle->color;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
count = 2 << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
if (pz[0] <= izi)
|
||||
{
|
||||
pz[0] = izi;
|
||||
pdest[0] = pparticle->color;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi)
|
||||
{
|
||||
pz[1] = izi;
|
||||
pdest[1] = pparticle->color;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
count = 3 << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
if (pz[0] <= izi)
|
||||
{
|
||||
pz[0] = izi;
|
||||
pdest[0] = pparticle->color;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi)
|
||||
{
|
||||
pz[1] = izi;
|
||||
pdest[1] = pparticle->color;
|
||||
}
|
||||
|
||||
if (pz[2] <= izi)
|
||||
{
|
||||
pz[2] = izi;
|
||||
pdest[2] = pparticle->color;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
count = 4 << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
if (pz[0] <= izi)
|
||||
{
|
||||
pz[0] = izi;
|
||||
pdest[0] = pparticle->color;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi)
|
||||
{
|
||||
pz[1] = izi;
|
||||
pdest[1] = pparticle->color;
|
||||
}
|
||||
|
||||
if (pz[2] <= izi)
|
||||
{
|
||||
pz[2] = izi;
|
||||
pdest[2] = pparticle->color;
|
||||
}
|
||||
|
||||
if (pz[3] <= izi)
|
||||
{
|
||||
pz[3] = izi;
|
||||
pdest[3] = pparticle->color;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
count = pix << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
for (i=0 ; i<pix ; i++)
|
||||
{
|
||||
if (pz[i] <= izi)
|
||||
{
|
||||
pz[i] = izi;
|
||||
pdest[i] = pparticle->color;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !id386
|
||||
|
|
@ -1,477 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
//
|
||||
// d_parta.s
|
||||
// x86 assembly-language 8-bpp particle-drawing code.
|
||||
//
|
||||
|
||||
#include "asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "d_ifacea.h"
|
||||
#include "asm_draw.h"
|
||||
|
||||
#if id386
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 8-bpp particle drawing code.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//FIXME: comments, full optimization
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 8-bpp particle queueing code.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.text
|
||||
|
||||
#define P 12+4
|
||||
|
||||
.align 4
|
||||
.globl C(D_DrawParticle)
|
||||
C(D_DrawParticle):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
movl P(%esp),%edi
|
||||
|
||||
// FIXME: better FP overlap in general here
|
||||
|
||||
// transform point
|
||||
// VectorSubtract (p->org, r_origin, local);
|
||||
flds C(r_origin)
|
||||
fsubrs pt_org(%edi)
|
||||
flds pt_org+4(%edi)
|
||||
fsubs C(r_origin)+4
|
||||
flds pt_org+8(%edi)
|
||||
fsubs C(r_origin)+8
|
||||
fxch %st(2) // local[0] | local[1] | local[2]
|
||||
|
||||
// transformed[2] = DotProduct(local, r_ppn);
|
||||
flds C(r_ppn) // r_ppn[0] | local[0] | local[1] | local[2]
|
||||
fmul %st(1),%st(0) // dot0 | local[0] | local[1] | local[2]
|
||||
flds C(r_ppn)+4 // r_ppn[1] | dot0 | local[0] | local[1] | local[2]
|
||||
fmul %st(3),%st(0) // dot1 | dot0 | local[0] | local[1] | local[2]
|
||||
flds C(r_ppn)+8 // r_ppn[2] | dot1 | dot0 | local[0] |
|
||||
// local[1] | local[2]
|
||||
fmul %st(5),%st(0) // dot2 | dot1 | dot0 | local[0] | local[1] | local[2]
|
||||
fxch %st(2) // dot0 | dot1 | dot2 | local[0] | local[1] | local[2]
|
||||
faddp %st(0),%st(1) // dot0 + dot1 | dot2 | local[0] | local[1] |
|
||||
// local[2]
|
||||
faddp %st(0),%st(1) // z | local[0] | local[1] | local[2]
|
||||
fld %st(0) // z | z | local[0] | local[1] |
|
||||
// local[2]
|
||||
fdivrs float_1 // 1/z | z | local[0] | local[1] | local[2]
|
||||
fxch %st(1) // z | 1/z | local[0] | local[1] | local[2]
|
||||
|
||||
// if (transformed[2] < PARTICLE_Z_CLIP)
|
||||
// return;
|
||||
fcomps float_particle_z_clip // 1/z | local[0] | local[1] | local[2]
|
||||
fxch %st(3) // local[2] | local[0] | local[1] | 1/z
|
||||
|
||||
flds C(r_pup) // r_pup[0] | local[2] | local[0] | local[1] | 1/z
|
||||
fmul %st(2),%st(0) // dot0 | local[2] | local[0] | local[1] | 1/z
|
||||
flds C(r_pup)+4 // r_pup[1] | dot0 | local[2] | local[0] |
|
||||
// local[1] | 1/z
|
||||
|
||||
fnstsw %ax
|
||||
testb $1,%ah
|
||||
jnz LPop6AndDone
|
||||
|
||||
// transformed[1] = DotProduct(local, r_pup);
|
||||
fmul %st(4),%st(0) // dot1 | dot0 | local[2] | local[0] | local[1] | 1/z
|
||||
flds C(r_pup)+8 // r_pup[2] | dot1 | dot0 | local[2] |
|
||||
// local[0] | local[1] | 1/z
|
||||
fmul %st(3),%st(0) // dot2 | dot1 | dot0 | local[2] | local[0] |
|
||||
// local[1] | 1/z
|
||||
fxch %st(2) // dot0 | dot1 | dot2 | local[2] | local[0] |
|
||||
// local[1] | 1/z
|
||||
faddp %st(0),%st(1) // dot0 + dot1 | dot2 | local[2] | local[0] |
|
||||
// local[1] | 1/z
|
||||
faddp %st(0),%st(1) // y | local[2] | local[0] | local[1] | 1/z
|
||||
fxch %st(3) // local[1] | local[2] | local[0] | y | 1/z
|
||||
|
||||
// transformed[0] = DotProduct(local, r_pright);
|
||||
fmuls C(r_pright)+4 // dot1 | local[2] | local[0] | y | 1/z
|
||||
fxch %st(2) // local[0] | local[2] | dot1 | y | 1/z
|
||||
fmuls C(r_pright) // dot0 | local[2] | dot1 | y | 1/z
|
||||
fxch %st(1) // local[2] | dot0 | dot1 | y | 1/z
|
||||
fmuls C(r_pright)+8 // dot2 | dot0 | dot1 | y | 1/z
|
||||
fxch %st(2) // dot1 | dot0 | dot2 | y | 1/z
|
||||
faddp %st(0),%st(1) // dot1 + dot0 | dot2 | y | 1/z
|
||||
|
||||
faddp %st(0),%st(1) // x | y | 1/z
|
||||
fxch %st(1) // y | x | 1/z
|
||||
|
||||
// project the point
|
||||
fmul %st(2),%st(0) // y/z | x | 1/z
|
||||
fxch %st(1) // x | y/z | 1/z
|
||||
fmul %st(2),%st(0) // x/z | y/z | 1/z
|
||||
fxch %st(1) // y/z | x/z | 1/z
|
||||
fsubrs C(ycenter) // v | x/z | 1/z
|
||||
fxch %st(1) // x/z | v | 1/z
|
||||
fadds C(xcenter) // u | v | 1/z
|
||||
// FIXME: preadjust xcenter and ycenter
|
||||
fxch %st(1) // v | u | 1/z
|
||||
fadds float_point5 // v | u | 1/z
|
||||
fxch %st(1) // u | v | 1/z
|
||||
fadds float_point5 // u | v | 1/z
|
||||
fxch %st(2) // 1/z | v | u
|
||||
fmuls DP_32768 // 1/z * 0x8000 | v | u
|
||||
fxch %st(2) // u | v | 1/z * 0x8000
|
||||
|
||||
// FIXME: use Terje's fp->int trick here?
|
||||
// FIXME: check we're getting proper rounding here
|
||||
fistpl DP_u // v | 1/z * 0x8000
|
||||
fistpl DP_v // 1/z * 0x8000
|
||||
|
||||
movl DP_u,%eax
|
||||
movl DP_v,%edx
|
||||
|
||||
// if ((v > d_vrectbottom_particle) ||
|
||||
// (u > d_vrectright_particle) ||
|
||||
// (v < d_vrecty) ||
|
||||
// (u < d_vrectx))
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
movl C(d_vrectbottom_particle),%ebx
|
||||
movl C(d_vrectright_particle),%ecx
|
||||
cmpl %ebx,%edx
|
||||
jg LPop1AndDone
|
||||
cmpl %ecx,%eax
|
||||
jg LPop1AndDone
|
||||
movl C(d_vrecty),%ebx
|
||||
movl C(d_vrectx),%ecx
|
||||
cmpl %ebx,%edx
|
||||
jl LPop1AndDone
|
||||
|
||||
cmpl %ecx,%eax
|
||||
jl LPop1AndDone
|
||||
|
||||
flds pt_color(%edi) // color | 1/z * 0x8000
|
||||
// FIXME: use Terje's fast fp->int trick?
|
||||
fistpl DP_Color // 1/z * 0x8000
|
||||
|
||||
movl C(d_viewbuffer),%ebx
|
||||
|
||||
addl %eax,%ebx
|
||||
movl C(d_scantable)(,%edx,4),%edi // point to the pixel
|
||||
|
||||
imull C(d_zrowbytes),%edx // point to the z pixel
|
||||
|
||||
leal (%edx,%eax,2),%edx
|
||||
movl C(d_pzbuffer),%eax
|
||||
|
||||
fistpl izi
|
||||
|
||||
addl %ebx,%edi
|
||||
addl %eax,%edx
|
||||
|
||||
// pix = izi >> d_pix_shift;
|
||||
|
||||
movl izi,%eax
|
||||
movl C(d_pix_shift),%ecx
|
||||
shrl %cl,%eax
|
||||
movl izi,%ebp
|
||||
|
||||
// if (pix < d_pix_min)
|
||||
// pix = d_pix_min;
|
||||
// else if (pix > d_pix_max)
|
||||
// pix = d_pix_max;
|
||||
|
||||
movl C(d_pix_min),%ebx
|
||||
movl C(d_pix_max),%ecx
|
||||
cmpl %ebx,%eax
|
||||
jnl LTestPixMax
|
||||
movl %ebx,%eax
|
||||
jmp LTestDone
|
||||
|
||||
LTestPixMax:
|
||||
cmpl %ecx,%eax
|
||||
jng LTestDone
|
||||
movl %ecx,%eax
|
||||
LTestDone:
|
||||
|
||||
movb DP_Color,%ch
|
||||
|
||||
movl C(d_y_aspect_shift),%ebx
|
||||
testl %ebx,%ebx
|
||||
jnz LDefault
|
||||
|
||||
cmpl $4,%eax
|
||||
ja LDefault
|
||||
|
||||
jmp *DP_EntryTable-4(,%eax,4)
|
||||
|
||||
// 1x1
|
||||
.globl DP_1x1
|
||||
DP_1x1:
|
||||
cmpw %bp,(%edx) // just one pixel to do
|
||||
jg LDone
|
||||
movw %bp,(%edx)
|
||||
movb %ch,(%edi)
|
||||
jmp LDone
|
||||
|
||||
// 2x2
|
||||
.globl DP_2x2
|
||||
DP_2x2:
|
||||
pushl %esi
|
||||
movl C(screenwidth),%ebx
|
||||
movl C(d_zrowbytes),%esi
|
||||
|
||||
cmpw %bp,(%edx)
|
||||
jg L2x2_1
|
||||
movw %bp,(%edx)
|
||||
movb %ch,(%edi)
|
||||
L2x2_1:
|
||||
cmpw %bp,2(%edx)
|
||||
jg L2x2_2
|
||||
movw %bp,2(%edx)
|
||||
movb %ch,1(%edi)
|
||||
L2x2_2:
|
||||
cmpw %bp,(%edx,%esi,1)
|
||||
jg L2x2_3
|
||||
movw %bp,(%edx,%esi,1)
|
||||
movb %ch,(%edi,%ebx,1)
|
||||
L2x2_3:
|
||||
cmpw %bp,2(%edx,%esi,1)
|
||||
jg L2x2_4
|
||||
movw %bp,2(%edx,%esi,1)
|
||||
movb %ch,1(%edi,%ebx,1)
|
||||
L2x2_4:
|
||||
|
||||
popl %esi
|
||||
jmp LDone
|
||||
|
||||
// 3x3
|
||||
.globl DP_3x3
|
||||
DP_3x3:
|
||||
pushl %esi
|
||||
movl C(screenwidth),%ebx
|
||||
movl C(d_zrowbytes),%esi
|
||||
|
||||
cmpw %bp,(%edx)
|
||||
jg L3x3_1
|
||||
movw %bp,(%edx)
|
||||
movb %ch,(%edi)
|
||||
L3x3_1:
|
||||
cmpw %bp,2(%edx)
|
||||
jg L3x3_2
|
||||
movw %bp,2(%edx)
|
||||
movb %ch,1(%edi)
|
||||
L3x3_2:
|
||||
cmpw %bp,4(%edx)
|
||||
jg L3x3_3
|
||||
movw %bp,4(%edx)
|
||||
movb %ch,2(%edi)
|
||||
L3x3_3:
|
||||
|
||||
cmpw %bp,(%edx,%esi,1)
|
||||
jg L3x3_4
|
||||
movw %bp,(%edx,%esi,1)
|
||||
movb %ch,(%edi,%ebx,1)
|
||||
L3x3_4:
|
||||
cmpw %bp,2(%edx,%esi,1)
|
||||
jg L3x3_5
|
||||
movw %bp,2(%edx,%esi,1)
|
||||
movb %ch,1(%edi,%ebx,1)
|
||||
L3x3_5:
|
||||
cmpw %bp,4(%edx,%esi,1)
|
||||
jg L3x3_6
|
||||
movw %bp,4(%edx,%esi,1)
|
||||
movb %ch,2(%edi,%ebx,1)
|
||||
L3x3_6:
|
||||
|
||||
cmpw %bp,(%edx,%esi,2)
|
||||
jg L3x3_7
|
||||
movw %bp,(%edx,%esi,2)
|
||||
movb %ch,(%edi,%ebx,2)
|
||||
L3x3_7:
|
||||
cmpw %bp,2(%edx,%esi,2)
|
||||
jg L3x3_8
|
||||
movw %bp,2(%edx,%esi,2)
|
||||
movb %ch,1(%edi,%ebx,2)
|
||||
L3x3_8:
|
||||
cmpw %bp,4(%edx,%esi,2)
|
||||
jg L3x3_9
|
||||
movw %bp,4(%edx,%esi,2)
|
||||
movb %ch,2(%edi,%ebx,2)
|
||||
L3x3_9:
|
||||
|
||||
popl %esi
|
||||
jmp LDone
|
||||
|
||||
|
||||
// 4x4
|
||||
.globl DP_4x4
|
||||
DP_4x4:
|
||||
pushl %esi
|
||||
movl C(screenwidth),%ebx
|
||||
movl C(d_zrowbytes),%esi
|
||||
|
||||
cmpw %bp,(%edx)
|
||||
jg L4x4_1
|
||||
movw %bp,(%edx)
|
||||
movb %ch,(%edi)
|
||||
L4x4_1:
|
||||
cmpw %bp,2(%edx)
|
||||
jg L4x4_2
|
||||
movw %bp,2(%edx)
|
||||
movb %ch,1(%edi)
|
||||
L4x4_2:
|
||||
cmpw %bp,4(%edx)
|
||||
jg L4x4_3
|
||||
movw %bp,4(%edx)
|
||||
movb %ch,2(%edi)
|
||||
L4x4_3:
|
||||
cmpw %bp,6(%edx)
|
||||
jg L4x4_4
|
||||
movw %bp,6(%edx)
|
||||
movb %ch,3(%edi)
|
||||
L4x4_4:
|
||||
|
||||
cmpw %bp,(%edx,%esi,1)
|
||||
jg L4x4_5
|
||||
movw %bp,(%edx,%esi,1)
|
||||
movb %ch,(%edi,%ebx,1)
|
||||
L4x4_5:
|
||||
cmpw %bp,2(%edx,%esi,1)
|
||||
jg L4x4_6
|
||||
movw %bp,2(%edx,%esi,1)
|
||||
movb %ch,1(%edi,%ebx,1)
|
||||
L4x4_6:
|
||||
cmpw %bp,4(%edx,%esi,1)
|
||||
jg L4x4_7
|
||||
movw %bp,4(%edx,%esi,1)
|
||||
movb %ch,2(%edi,%ebx,1)
|
||||
L4x4_7:
|
||||
cmpw %bp,6(%edx,%esi,1)
|
||||
jg L4x4_8
|
||||
movw %bp,6(%edx,%esi,1)
|
||||
movb %ch,3(%edi,%ebx,1)
|
||||
L4x4_8:
|
||||
|
||||
leal (%edx,%esi,2),%edx
|
||||
leal (%edi,%ebx,2),%edi
|
||||
|
||||
cmpw %bp,(%edx)
|
||||
jg L4x4_9
|
||||
movw %bp,(%edx)
|
||||
movb %ch,(%edi)
|
||||
L4x4_9:
|
||||
cmpw %bp,2(%edx)
|
||||
jg L4x4_10
|
||||
movw %bp,2(%edx)
|
||||
movb %ch,1(%edi)
|
||||
L4x4_10:
|
||||
cmpw %bp,4(%edx)
|
||||
jg L4x4_11
|
||||
movw %bp,4(%edx)
|
||||
movb %ch,2(%edi)
|
||||
L4x4_11:
|
||||
cmpw %bp,6(%edx)
|
||||
jg L4x4_12
|
||||
movw %bp,6(%edx)
|
||||
movb %ch,3(%edi)
|
||||
L4x4_12:
|
||||
|
||||
cmpw %bp,(%edx,%esi,1)
|
||||
jg L4x4_13
|
||||
movw %bp,(%edx,%esi,1)
|
||||
movb %ch,(%edi,%ebx,1)
|
||||
L4x4_13:
|
||||
cmpw %bp,2(%edx,%esi,1)
|
||||
jg L4x4_14
|
||||
movw %bp,2(%edx,%esi,1)
|
||||
movb %ch,1(%edi,%ebx,1)
|
||||
L4x4_14:
|
||||
cmpw %bp,4(%edx,%esi,1)
|
||||
jg L4x4_15
|
||||
movw %bp,4(%edx,%esi,1)
|
||||
movb %ch,2(%edi,%ebx,1)
|
||||
L4x4_15:
|
||||
cmpw %bp,6(%edx,%esi,1)
|
||||
jg L4x4_16
|
||||
movw %bp,6(%edx,%esi,1)
|
||||
movb %ch,3(%edi,%ebx,1)
|
||||
L4x4_16:
|
||||
|
||||
popl %esi
|
||||
jmp LDone
|
||||
|
||||
// default case, handling any size particle
|
||||
LDefault:
|
||||
|
||||
// count = pix << d_y_aspect_shift;
|
||||
|
||||
movl %eax,%ebx
|
||||
movl %eax,DP_Pix
|
||||
movb C(d_y_aspect_shift),%cl
|
||||
shll %cl,%ebx
|
||||
|
||||
// for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
// {
|
||||
// for (i=0 ; i<pix ; i++)
|
||||
// {
|
||||
// if (pz[i] <= izi)
|
||||
// {
|
||||
// pz[i] = izi;
|
||||
// pdest[i] = color;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
LGenRowLoop:
|
||||
movl DP_Pix,%eax
|
||||
|
||||
LGenColLoop:
|
||||
cmpw %bp,-2(%edx,%eax,2)
|
||||
jg LGSkip
|
||||
movw %bp,-2(%edx,%eax,2)
|
||||
movb %ch,-1(%edi,%eax,1)
|
||||
LGSkip:
|
||||
decl %eax // --pix
|
||||
jnz LGenColLoop
|
||||
|
||||
addl C(d_zrowbytes),%edx
|
||||
addl C(screenwidth),%edi
|
||||
|
||||
decl %ebx // --count
|
||||
jnz LGenRowLoop
|
||||
|
||||
LDone:
|
||||
popl %ebx // restore register variables
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
LPop6AndDone:
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
LPop1AndDone:
|
||||
fstp %st(0)
|
||||
jmp LDone
|
||||
|
||||
#endif // id386
|
1744
qw_client/d_polysa.s
1744
qw_client/d_polysa.s
File diff suppressed because it is too large
Load diff
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
//
|
||||
// d_scana.s
|
||||
// x86 assembly-language turbulent texture mapping code
|
||||
//
|
||||
|
||||
#include "asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
#include "d_ifacea.h"
|
||||
|
||||
#if id386
|
||||
|
||||
.data
|
||||
|
||||
.text
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// turbulent texture mapping code
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(D_DrawTurbulent8Span)
|
||||
C(D_DrawTurbulent8Span):
|
||||
pushl %ebp // preserve caller's stack frame pointer
|
||||
pushl %esi // preserve register variables
|
||||
pushl %edi
|
||||
pushl %ebx
|
||||
|
||||
movl C(r_turb_s),%esi
|
||||
movl C(r_turb_t),%ecx
|
||||
movl C(r_turb_pdest),%edi
|
||||
movl C(r_turb_spancount),%ebx
|
||||
|
||||
Llp:
|
||||
movl %ecx,%eax
|
||||
movl %esi,%edx
|
||||
sarl $16,%eax
|
||||
movl C(r_turb_turb),%ebp
|
||||
sarl $16,%edx
|
||||
andl $(CYCLE-1),%eax
|
||||
andl $(CYCLE-1),%edx
|
||||
movl (%ebp,%eax,4),%eax
|
||||
movl (%ebp,%edx,4),%edx
|
||||
addl %esi,%eax
|
||||
sarl $16,%eax
|
||||
addl %ecx,%edx
|
||||
sarl $16,%edx
|
||||
andl $(TURB_TEX_SIZE-1),%eax
|
||||
andl $(TURB_TEX_SIZE-1),%edx
|
||||
shll $6,%edx
|
||||
movl C(r_turb_pbase),%ebp
|
||||
addl %eax,%edx
|
||||
incl %edi
|
||||
addl C(r_turb_sstep),%esi
|
||||
addl C(r_turb_tstep),%ecx
|
||||
movb (%ebp,%edx,1),%dl
|
||||
decl %ebx
|
||||
movb %dl,-1(%edi)
|
||||
jnz Llp
|
||||
|
||||
movl %edi,C(r_turb_pdest)
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %edi
|
||||
popl %esi
|
||||
popl %ebp // restore caller's stack frame pointer
|
||||
ret
|
||||
|
||||
#endif // id386
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
// d_sky.c
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "r_local.h"
|
||||
#include "d_local.h"
|
||||
|
||||
#define SKY_SPAN_SHIFT 5
|
||||
#define SKY_SPAN_MAX (1 << SKY_SPAN_SHIFT)
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
D_Sky_uv_To_st
|
||||
=================
|
||||
*/
|
||||
void D_Sky_uv_To_st (int u, int v, fixed16_t *s, fixed16_t *t)
|
||||
{
|
||||
float wu, wv, temp;
|
||||
vec3_t end;
|
||||
|
||||
if (r_refdef.vrect.width >= r_refdef.vrect.height)
|
||||
temp = (float)r_refdef.vrect.width;
|
||||
else
|
||||
temp = (float)r_refdef.vrect.height;
|
||||
|
||||
wu = 8192.0 * (float)(u-((int)vid.width>>1)) / temp;
|
||||
wv = 8192.0 * (float)(((int)vid.height>>1)-v) / temp;
|
||||
|
||||
end[0] = 4096*vpn[0] + wu*vright[0] + wv*vup[0];
|
||||
end[1] = 4096*vpn[1] + wu*vright[1] + wv*vup[1];
|
||||
end[2] = 4096*vpn[2] + wu*vright[2] + wv*vup[2];
|
||||
end[2] *= 3;
|
||||
VectorNormalize (end);
|
||||
|
||||
temp = skytime*skyspeed; // TODO: add D_SetupFrame & set this there
|
||||
*s = (int)((temp + 6*(SKYSIZE/2-1)*end[0]) * 0x10000);
|
||||
*t = (int)((temp + 6*(SKYSIZE/2-1)*end[1]) * 0x10000);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
D_DrawSkyScans8
|
||||
=================
|
||||
*/
|
||||
void D_DrawSkyScans8 (espan_t *pspan)
|
||||
{
|
||||
int count, spancount, u, v;
|
||||
unsigned char *pdest;
|
||||
fixed16_t s, t, snext, tnext, sstep, tstep;
|
||||
int spancountminus1;
|
||||
|
||||
sstep = 0; // keep compiler happy
|
||||
tstep = 0; // ditto
|
||||
|
||||
do
|
||||
{
|
||||
pdest = (unsigned char *)((byte *)d_viewbuffer +
|
||||
(screenwidth * pspan->v) + pspan->u);
|
||||
|
||||
count = pspan->count;
|
||||
|
||||
// calculate the initial s & t
|
||||
u = pspan->u;
|
||||
v = pspan->v;
|
||||
D_Sky_uv_To_st (u, v, &s, &t);
|
||||
|
||||
do
|
||||
{
|
||||
if (count >= SKY_SPAN_MAX)
|
||||
spancount = SKY_SPAN_MAX;
|
||||
else
|
||||
spancount = count;
|
||||
|
||||
count -= spancount;
|
||||
|
||||
if (count)
|
||||
{
|
||||
u += spancount;
|
||||
|
||||
// calculate s and t at far end of span,
|
||||
// calculate s and t steps across span by shifting
|
||||
D_Sky_uv_To_st (u, v, &snext, &tnext);
|
||||
|
||||
sstep = (snext - s) >> SKY_SPAN_SHIFT;
|
||||
tstep = (tnext - t) >> SKY_SPAN_SHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// calculate s and t at last pixel in span,
|
||||
// calculate s and t steps across span by division
|
||||
spancountminus1 = (float)(spancount - 1);
|
||||
|
||||
if (spancountminus1 > 0)
|
||||
{
|
||||
u += spancountminus1;
|
||||
D_Sky_uv_To_st (u, v, &snext, &tnext);
|
||||
|
||||
sstep = (snext - s) / spancountminus1;
|
||||
tstep = (tnext - t) / spancountminus1;
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
*pdest++ = r_skysource[((t & R_SKY_TMASK) >> 8) +
|
||||
((s & R_SKY_SMASK) >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
} while (--spancount > 0);
|
||||
|
||||
s = snext;
|
||||
t = tnext;
|
||||
|
||||
} while (count > 0);
|
||||
|
||||
} while ((pspan = pspan->pnext) != NULL);
|
||||
}
|
||||
|
|
@ -1,900 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
//
|
||||
// d_spr8.s
|
||||
// x86 assembly-language horizontal 8-bpp transparent span-drawing code.
|
||||
//
|
||||
|
||||
#include "asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
|
||||
#if id386
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 8-bpp horizontal span drawing code for polygons, with transparency.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.text
|
||||
|
||||
// out-of-line, rarely-needed clamping code
|
||||
|
||||
LClampHigh0:
|
||||
movl C(bbextents),%esi
|
||||
jmp LClampReentry0
|
||||
LClampHighOrLow0:
|
||||
jg LClampHigh0
|
||||
xorl %esi,%esi
|
||||
jmp LClampReentry0
|
||||
|
||||
LClampHigh1:
|
||||
movl C(bbextentt),%edx
|
||||
jmp LClampReentry1
|
||||
LClampHighOrLow1:
|
||||
jg LClampHigh1
|
||||
xorl %edx,%edx
|
||||
jmp LClampReentry1
|
||||
|
||||
LClampLow2:
|
||||
movl $2048,%ebp
|
||||
jmp LClampReentry2
|
||||
LClampHigh2:
|
||||
movl C(bbextents),%ebp
|
||||
jmp LClampReentry2
|
||||
|
||||
LClampLow3:
|
||||
movl $2048,%ecx
|
||||
jmp LClampReentry3
|
||||
LClampHigh3:
|
||||
movl C(bbextentt),%ecx
|
||||
jmp LClampReentry3
|
||||
|
||||
LClampLow4:
|
||||
movl $2048,%eax
|
||||
jmp LClampReentry4
|
||||
LClampHigh4:
|
||||
movl C(bbextents),%eax
|
||||
jmp LClampReentry4
|
||||
|
||||
LClampLow5:
|
||||
movl $2048,%ebx
|
||||
jmp LClampReentry5
|
||||
LClampHigh5:
|
||||
movl C(bbextentt),%ebx
|
||||
jmp LClampReentry5
|
||||
|
||||
|
||||
#define pspans 4+16
|
||||
|
||||
.align 4
|
||||
.globl C(D_SpriteDrawSpans)
|
||||
C(D_SpriteDrawSpans):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
//
|
||||
// set up scaled-by-8 steps, for 8-long segments; also set up cacheblock
|
||||
// and span list pointers, and 1/z step in 0.32 fixed-point
|
||||
//
|
||||
// FIXME: any overlap from rearranging?
|
||||
flds C(d_sdivzstepu)
|
||||
fmuls fp_8
|
||||
movl C(cacheblock),%edx
|
||||
flds C(d_tdivzstepu)
|
||||
fmuls fp_8
|
||||
movl pspans(%esp),%ebx // point to the first span descriptor
|
||||
flds C(d_zistepu)
|
||||
fmuls fp_8
|
||||
movl %edx,pbase // pbase = cacheblock
|
||||
flds C(d_zistepu)
|
||||
fmuls fp_64kx64k
|
||||
fxch %st(3)
|
||||
fstps sdivz8stepu
|
||||
fstps zi8stepu
|
||||
fstps tdivz8stepu
|
||||
fistpl izistep
|
||||
movl izistep,%eax
|
||||
rorl $16,%eax // put upper 16 bits in low word
|
||||
movl sspan_t_count(%ebx),%ecx
|
||||
movl %eax,izistep
|
||||
|
||||
cmpl $0,%ecx
|
||||
jle LNextSpan
|
||||
|
||||
LSpanLoop:
|
||||
|
||||
//
|
||||
// set up the initial s/z, t/z, and 1/z on the FP stack, and generate the
|
||||
// initial s and t values
|
||||
//
|
||||
// FIXME: pipeline FILD?
|
||||
fildl sspan_t_v(%ebx)
|
||||
fildl sspan_t_u(%ebx)
|
||||
|
||||
fld %st(1) // dv | du | dv
|
||||
fmuls C(d_sdivzstepv) // dv*d_sdivzstepv | du | dv
|
||||
fld %st(1) // du | dv*d_sdivzstepv | du | dv
|
||||
fmuls C(d_sdivzstepu) // du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
|
||||
fld %st(2) // du | du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
|
||||
fmuls C(d_tdivzstepu) // du*d_tdivzstepu | du*d_sdivzstepu |
|
||||
// dv*d_sdivzstepv | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu | du*d_tdivzstepu |
|
||||
// dv*d_sdivzstepv | du | dv
|
||||
faddp %st(0),%st(2) // du*d_tdivzstepu |
|
||||
// du*d_sdivzstepu + dv*d_sdivzstepv | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fld %st(3) // dv | du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fmuls C(d_tdivzstepv) // dv*d_tdivzstepv |
|
||||
// du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// dv*d_tdivzstepv | du*d_tdivzstepu | du | dv
|
||||
fadds C(d_sdivzorigin) // sdivz = d_sdivzorigin + dv*d_sdivzstepv +
|
||||
// du*d_sdivzstepu; stays in %st(2) at end
|
||||
fxch %st(4) // dv | dv*d_tdivzstepv | du*d_tdivzstepu | du |
|
||||
// s/z
|
||||
fmuls C(d_zistepv) // dv*d_zistepv | dv*d_tdivzstepv |
|
||||
// du*d_tdivzstepu | du | s/z
|
||||
fxch %st(1) // dv*d_tdivzstepv | dv*d_zistepv |
|
||||
// du*d_tdivzstepu | du | s/z
|
||||
faddp %st(0),%st(2) // dv*d_zistepv |
|
||||
// dv*d_tdivzstepv + du*d_tdivzstepu | du | s/z
|
||||
fxch %st(2) // du | dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// dv*d_zistepv | s/z
|
||||
fmuls C(d_zistepu) // du*d_zistepu |
|
||||
// dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// dv*d_zistepv | s/z
|
||||
fxch %st(1) // dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// du*d_zistepu | dv*d_zistepv | s/z
|
||||
fadds C(d_tdivzorigin) // tdivz = d_tdivzorigin + dv*d_tdivzstepv +
|
||||
// du*d_tdivzstepu; stays in %st(1) at end
|
||||
fxch %st(2) // dv*d_zistepv | du*d_zistepu | t/z | s/z
|
||||
faddp %st(0),%st(1) // dv*d_zistepv + du*d_zistepu | t/z | s/z
|
||||
|
||||
flds fp_64k // fp_64k | dv*d_zistepv + du*d_zistepu | t/z | s/z
|
||||
fxch %st(1) // dv*d_zistepv + du*d_zistepu | fp_64k | t/z | s/z
|
||||
fadds C(d_ziorigin) // zi = d_ziorigin + dv*d_zistepv +
|
||||
// du*d_zistepu; stays in %st(0) at end
|
||||
// 1/z | fp_64k | t/z | s/z
|
||||
|
||||
fld %st(0) // FIXME: get rid of stall on FMUL?
|
||||
fmuls fp_64kx64k
|
||||
fxch %st(1)
|
||||
|
||||
//
|
||||
// calculate and clamp s & t
|
||||
//
|
||||
fdivr %st(0),%st(2) // 1/z | z*64k | t/z | s/z
|
||||
fxch %st(1)
|
||||
|
||||
fistpl izi // 0.32 fixed-point 1/z
|
||||
movl izi,%ebp
|
||||
|
||||
//
|
||||
// set pz to point to the first z-buffer pixel in the span
|
||||
//
|
||||
rorl $16,%ebp // put upper 16 bits in low word
|
||||
movl sspan_t_v(%ebx),%eax
|
||||
movl %ebp,izi
|
||||
movl sspan_t_u(%ebx),%ebp
|
||||
imull C(d_zrowbytes)
|
||||
shll $1,%ebp // a word per pixel
|
||||
addl C(d_pzbuffer),%eax
|
||||
addl %ebp,%eax
|
||||
movl %eax,pz
|
||||
|
||||
//
|
||||
// point %edi to the first pixel in the span
|
||||
//
|
||||
movl C(d_viewbuffer),%ebp
|
||||
movl sspan_t_v(%ebx),%eax
|
||||
pushl %ebx // preserve spans pointer
|
||||
movl C(tadjust),%edx
|
||||
movl C(sadjust),%esi
|
||||
movl C(d_scantable)(,%eax,4),%edi // v * screenwidth
|
||||
addl %ebp,%edi
|
||||
movl sspan_t_u(%ebx),%ebp
|
||||
addl %ebp,%edi // pdest = &pdestspan[scans->u];
|
||||
|
||||
//
|
||||
// now start the FDIV for the end of the span
|
||||
//
|
||||
cmpl $8,%ecx
|
||||
ja LSetupNotLast1
|
||||
|
||||
decl %ecx
|
||||
jz LCleanup1 // if only one pixel, no need to start an FDIV
|
||||
movl %ecx,spancountminus1
|
||||
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
|
||||
fildl spancountminus1
|
||||
|
||||
flds C(d_tdivzstepu) // _d_tdivzstepu | spancountminus1
|
||||
flds C(d_zistepu) // _d_zistepu | _d_tdivzstepu | spancountminus1
|
||||
fmul %st(2),%st(0) // _d_zistepu*scm1 | _d_tdivzstepu | scm1
|
||||
fxch %st(1) // _d_tdivzstepu | _d_zistepu*scm1 | scm1
|
||||
fmul %st(2),%st(0) // _d_tdivzstepu*scm1 | _d_zistepu*scm1 | scm1
|
||||
fxch %st(2) // scm1 | _d_zistepu*scm1 | _d_tdivzstepu*scm1
|
||||
fmuls C(d_sdivzstepu) // _d_sdivzstepu*scm1 | _d_zistepu*scm1 |
|
||||
// _d_tdivzstepu*scm1
|
||||
fxch %st(1) // _d_zistepu*scm1 | _d_sdivzstepu*scm1 |
|
||||
// _d_tdivzstepu*scm1
|
||||
faddp %st(0),%st(3) // _d_sdivzstepu*scm1 | _d_tdivzstepu*scm1
|
||||
fxch %st(1) // _d_tdivzstepu*scm1 | _d_sdivzstepu*scm1
|
||||
faddp %st(0),%st(3) // _d_sdivzstepu*scm1
|
||||
faddp %st(0),%st(3)
|
||||
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
jmp LFDIVInFlight1
|
||||
|
||||
LCleanup1:
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
jmp LFDIVInFlight1
|
||||
|
||||
.align 4
|
||||
LSetupNotLast1:
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
|
||||
fadds zi8stepu
|
||||
fxch %st(2)
|
||||
fadds sdivz8stepu
|
||||
fxch %st(2)
|
||||
flds tdivz8stepu
|
||||
faddp %st(0),%st(2)
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // z = 1/1/z
|
||||
// this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
LFDIVInFlight1:
|
||||
|
||||
addl s,%esi
|
||||
addl t,%edx
|
||||
movl C(bbextents),%ebx
|
||||
movl C(bbextentt),%ebp
|
||||
cmpl %ebx,%esi
|
||||
ja LClampHighOrLow0
|
||||
LClampReentry0:
|
||||
movl %esi,s
|
||||
movl pbase,%ebx
|
||||
shll $16,%esi
|
||||
cmpl %ebp,%edx
|
||||
movl %esi,sfracf
|
||||
ja LClampHighOrLow1
|
||||
LClampReentry1:
|
||||
movl %edx,t
|
||||
movl s,%esi // sfrac = scans->sfrac;
|
||||
shll $16,%edx
|
||||
movl t,%eax // tfrac = scans->tfrac;
|
||||
sarl $16,%esi
|
||||
movl %edx,tfracf
|
||||
|
||||
//
|
||||
// calculate the texture starting address
|
||||
//
|
||||
sarl $16,%eax
|
||||
addl %ebx,%esi
|
||||
imull C(cachewidth),%eax // (tfrac >> 16) * cachewidth
|
||||
addl %eax,%esi // psource = pbase + (sfrac >> 16) +
|
||||
// ((tfrac >> 16) * cachewidth);
|
||||
|
||||
//
|
||||
// determine whether last span or not
|
||||
//
|
||||
cmpl $8,%ecx
|
||||
jna LLastSegment
|
||||
|
||||
//
|
||||
// not the last segment; do full 8-wide segment
|
||||
//
|
||||
LNotLastSegment:
|
||||
|
||||
//
|
||||
// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
|
||||
// get there
|
||||
//
|
||||
|
||||
// pick up after the FDIV that was left in flight previously
|
||||
|
||||
fld %st(0) // duplicate it
|
||||
fmul %st(4),%st(0) // s = s/z * z
|
||||
fxch %st(1)
|
||||
fmul %st(3),%st(0) // t = t/z * z
|
||||
fxch %st(1)
|
||||
fistpl snext
|
||||
fistpl tnext
|
||||
movl snext,%eax
|
||||
movl tnext,%edx
|
||||
|
||||
subl $8,%ecx // count off this segments' pixels
|
||||
movl C(sadjust),%ebp
|
||||
pushl %ecx // remember count of remaining pixels
|
||||
movl C(tadjust),%ecx
|
||||
|
||||
addl %eax,%ebp
|
||||
addl %edx,%ecx
|
||||
|
||||
movl C(bbextents),%eax
|
||||
movl C(bbextentt),%edx
|
||||
|
||||
cmpl $2048,%ebp
|
||||
jl LClampLow2
|
||||
cmpl %eax,%ebp
|
||||
ja LClampHigh2
|
||||
LClampReentry2:
|
||||
|
||||
cmpl $2048,%ecx
|
||||
jl LClampLow3
|
||||
cmpl %edx,%ecx
|
||||
ja LClampHigh3
|
||||
LClampReentry3:
|
||||
|
||||
movl %ebp,snext
|
||||
movl %ecx,tnext
|
||||
|
||||
subl s,%ebp
|
||||
subl t,%ecx
|
||||
|
||||
//
|
||||
// set up advancetable
|
||||
//
|
||||
movl %ecx,%eax
|
||||
movl %ebp,%edx
|
||||
sarl $19,%edx // sstep >>= 16;
|
||||
movl C(cachewidth),%ebx
|
||||
sarl $19,%eax // tstep >>= 16;
|
||||
jz LIsZero
|
||||
imull %ebx,%eax // (tstep >> 16) * cachewidth;
|
||||
LIsZero:
|
||||
addl %edx,%eax // add in sstep
|
||||
// (tstep >> 16) * cachewidth + (sstep >> 16);
|
||||
movl tfracf,%edx
|
||||
movl %eax,advancetable+4 // advance base in t
|
||||
addl %ebx,%eax // ((tstep >> 16) + 1) * cachewidth +
|
||||
// (sstep >> 16);
|
||||
shll $13,%ebp // left-justify sstep fractional part
|
||||
movl %ebp,sstep
|
||||
movl sfracf,%ebx
|
||||
shll $13,%ecx // left-justify tstep fractional part
|
||||
movl %eax,advancetable // advance extra in t
|
||||
movl %ecx,tstep
|
||||
|
||||
movl pz,%ecx
|
||||
movl izi,%ebp
|
||||
|
||||
cmpw (%ecx),%bp
|
||||
jl Lp1
|
||||
movb (%esi),%al // get first source texel
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp1
|
||||
movw %bp,(%ecx)
|
||||
movb %al,(%edi) // store first dest pixel
|
||||
Lp1:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx // advance tfrac fractional part by tstep frac
|
||||
|
||||
sbbl %eax,%eax // turn tstep carry into -1 (0 if none)
|
||||
addl sstep,%ebx // advance sfrac fractional part by sstep frac
|
||||
adcl advancetable+4(,%eax,4),%esi // point to next source texel
|
||||
|
||||
cmpw 2(%ecx),%bp
|
||||
jl Lp2
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp2
|
||||
movw %bp,2(%ecx)
|
||||
movb %al,1(%edi)
|
||||
Lp2:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 4(%ecx),%bp
|
||||
jl Lp3
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp3
|
||||
movw %bp,4(%ecx)
|
||||
movb %al,2(%edi)
|
||||
Lp3:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 6(%ecx),%bp
|
||||
jl Lp4
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp4
|
||||
movw %bp,6(%ecx)
|
||||
movb %al,3(%edi)
|
||||
Lp4:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 8(%ecx),%bp
|
||||
jl Lp5
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp5
|
||||
movw %bp,8(%ecx)
|
||||
movb %al,4(%edi)
|
||||
Lp5:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
//
|
||||
// start FDIV for end of next segment in flight, so it can overlap
|
||||
//
|
||||
popl %eax
|
||||
cmpl $8,%eax // more than one segment after this?
|
||||
ja LSetupNotLast2 // yes
|
||||
|
||||
decl %eax
|
||||
jz LFDIVInFlight2 // if only one pixel, no need to start an FDIV
|
||||
movl %eax,spancountminus1
|
||||
fildl spancountminus1
|
||||
|
||||
flds C(d_zistepu) // _d_zistepu | spancountminus1
|
||||
fmul %st(1),%st(0) // _d_zistepu*scm1 | scm1
|
||||
flds C(d_tdivzstepu) // _d_tdivzstepu | _d_zistepu*scm1 | scm1
|
||||
fmul %st(2),%st(0) // _d_tdivzstepu*scm1 | _d_zistepu*scm1 | scm1
|
||||
fxch %st(1) // _d_zistepu*scm1 | _d_tdivzstepu*scm1 | scm1
|
||||
faddp %st(0),%st(3) // _d_tdivzstepu*scm1 | scm1
|
||||
fxch %st(1) // scm1 | _d_tdivzstepu*scm1
|
||||
fmuls C(d_sdivzstepu) // _d_sdivzstepu*scm1 | _d_tdivzstepu*scm1
|
||||
fxch %st(1) // _d_tdivzstepu*scm1 | _d_sdivzstepu*scm1
|
||||
faddp %st(0),%st(3) // _d_sdivzstepu*scm1
|
||||
flds fp_64k // 64k | _d_sdivzstepu*scm1
|
||||
fxch %st(1) // _d_sdivzstepu*scm1 | 64k
|
||||
faddp %st(0),%st(4) // 64k
|
||||
|
||||
fdiv %st(1),%st(0) // this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
jmp LFDIVInFlight2
|
||||
|
||||
.align 4
|
||||
LSetupNotLast2:
|
||||
fadds zi8stepu
|
||||
fxch %st(2)
|
||||
fadds sdivz8stepu
|
||||
fxch %st(2)
|
||||
flds tdivz8stepu
|
||||
faddp %st(0),%st(2)
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // z = 1/1/z
|
||||
// this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
LFDIVInFlight2:
|
||||
pushl %eax
|
||||
|
||||
cmpw 10(%ecx),%bp
|
||||
jl Lp6
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp6
|
||||
movw %bp,10(%ecx)
|
||||
movb %al,5(%edi)
|
||||
Lp6:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 12(%ecx),%bp
|
||||
jl Lp7
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp7
|
||||
movw %bp,12(%ecx)
|
||||
movb %al,6(%edi)
|
||||
Lp7:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 14(%ecx),%bp
|
||||
jl Lp8
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp8
|
||||
movw %bp,14(%ecx)
|
||||
movb %al,7(%edi)
|
||||
Lp8:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
addl $8,%edi
|
||||
addl $16,%ecx
|
||||
movl %edx,tfracf
|
||||
movl snext,%edx
|
||||
movl %ebx,sfracf
|
||||
movl tnext,%ebx
|
||||
movl %edx,s
|
||||
movl %ebx,t
|
||||
|
||||
movl %ecx,pz
|
||||
movl %ebp,izi
|
||||
|
||||
popl %ecx // retrieve count
|
||||
|
||||
//
|
||||
// determine whether last span or not
|
||||
//
|
||||
cmpl $8,%ecx // are there multiple segments remaining?
|
||||
ja LNotLastSegment // yes
|
||||
|
||||
//
|
||||
// last segment of scan
|
||||
//
|
||||
LLastSegment:
|
||||
|
||||
//
|
||||
// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
|
||||
// get there. The number of pixels left is variable, and we want to land on the
|
||||
// last pixel, not step one past it, so we can't run into arithmetic problems
|
||||
//
|
||||
testl %ecx,%ecx
|
||||
jz LNoSteps // just draw the last pixel and we're done
|
||||
|
||||
// pick up after the FDIV that was left in flight previously
|
||||
|
||||
|
||||
fld %st(0) // duplicate it
|
||||
fmul %st(4),%st(0) // s = s/z * z
|
||||
fxch %st(1)
|
||||
fmul %st(3),%st(0) // t = t/z * z
|
||||
fxch %st(1)
|
||||
fistpl snext
|
||||
fistpl tnext
|
||||
|
||||
movl C(tadjust),%ebx
|
||||
movl C(sadjust),%eax
|
||||
|
||||
addl snext,%eax
|
||||
addl tnext,%ebx
|
||||
|
||||
movl C(bbextents),%ebp
|
||||
movl C(bbextentt),%edx
|
||||
|
||||
cmpl $2048,%eax
|
||||
jl LClampLow4
|
||||
cmpl %ebp,%eax
|
||||
ja LClampHigh4
|
||||
LClampReentry4:
|
||||
movl %eax,snext
|
||||
|
||||
cmpl $2048,%ebx
|
||||
jl LClampLow5
|
||||
cmpl %edx,%ebx
|
||||
ja LClampHigh5
|
||||
LClampReentry5:
|
||||
|
||||
cmpl $1,%ecx // don't bother
|
||||
je LOnlyOneStep // if two pixels in segment, there's only one step,
|
||||
// of the segment length
|
||||
subl s,%eax
|
||||
subl t,%ebx
|
||||
|
||||
addl %eax,%eax // convert to 15.17 format so multiply by 1.31
|
||||
addl %ebx,%ebx // reciprocal yields 16.48
|
||||
imull reciprocal_table-8(,%ecx,4) // sstep = (snext - s) / (spancount-1)
|
||||
movl %edx,%ebp
|
||||
|
||||
movl %ebx,%eax
|
||||
imull reciprocal_table-8(,%ecx,4) // tstep = (tnext - t) / (spancount-1)
|
||||
|
||||
LSetEntryvec:
|
||||
//
|
||||
// set up advancetable
|
||||
//
|
||||
movl spr8entryvec_table(,%ecx,4),%ebx
|
||||
movl %edx,%eax
|
||||
pushl %ebx // entry point into code for RET later
|
||||
movl %ebp,%ecx
|
||||
sarl $16,%ecx // sstep >>= 16;
|
||||
movl C(cachewidth),%ebx
|
||||
sarl $16,%edx // tstep >>= 16;
|
||||
jz LIsZeroLast
|
||||
imull %ebx,%edx // (tstep >> 16) * cachewidth;
|
||||
LIsZeroLast:
|
||||
addl %ecx,%edx // add in sstep
|
||||
// (tstep >> 16) * cachewidth + (sstep >> 16);
|
||||
movl tfracf,%ecx
|
||||
movl %edx,advancetable+4 // advance base in t
|
||||
addl %ebx,%edx // ((tstep >> 16) + 1) * cachewidth +
|
||||
// (sstep >> 16);
|
||||
shll $16,%ebp // left-justify sstep fractional part
|
||||
movl sfracf,%ebx
|
||||
shll $16,%eax // left-justify tstep fractional part
|
||||
movl %edx,advancetable // advance extra in t
|
||||
|
||||
movl %eax,tstep
|
||||
movl %ebp,sstep
|
||||
movl %ecx,%edx
|
||||
|
||||
movl pz,%ecx
|
||||
movl izi,%ebp
|
||||
|
||||
ret // jump to the number-of-pixels handler
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
LNoSteps:
|
||||
movl pz,%ecx
|
||||
subl $7,%edi // adjust for hardwired offset
|
||||
subl $14,%ecx
|
||||
jmp LEndSpan
|
||||
|
||||
|
||||
LOnlyOneStep:
|
||||
subl s,%eax
|
||||
subl t,%ebx
|
||||
movl %eax,%ebp
|
||||
movl %ebx,%edx
|
||||
jmp LSetEntryvec
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry2_8
|
||||
Spr8Entry2_8:
|
||||
subl $6,%edi // adjust for hardwired offsets
|
||||
subl $12,%ecx
|
||||
movb (%esi),%al
|
||||
jmp LLEntry2_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry3_8
|
||||
Spr8Entry3_8:
|
||||
subl $5,%edi // adjust for hardwired offsets
|
||||
subl $10,%ecx
|
||||
jmp LLEntry3_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry4_8
|
||||
Spr8Entry4_8:
|
||||
subl $4,%edi // adjust for hardwired offsets
|
||||
subl $8,%ecx
|
||||
jmp LLEntry4_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry5_8
|
||||
Spr8Entry5_8:
|
||||
subl $3,%edi // adjust for hardwired offsets
|
||||
subl $6,%ecx
|
||||
jmp LLEntry5_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry6_8
|
||||
Spr8Entry6_8:
|
||||
subl $2,%edi // adjust for hardwired offsets
|
||||
subl $4,%ecx
|
||||
jmp LLEntry6_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry7_8
|
||||
Spr8Entry7_8:
|
||||
decl %edi // adjust for hardwired offsets
|
||||
subl $2,%ecx
|
||||
jmp LLEntry7_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry8_8
|
||||
Spr8Entry8_8:
|
||||
cmpw (%ecx),%bp
|
||||
jl Lp9
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp9
|
||||
movw %bp,(%ecx)
|
||||
movb %al,(%edi)
|
||||
Lp9:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry7_8:
|
||||
cmpw 2(%ecx),%bp
|
||||
jl Lp10
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp10
|
||||
movw %bp,2(%ecx)
|
||||
movb %al,1(%edi)
|
||||
Lp10:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry6_8:
|
||||
cmpw 4(%ecx),%bp
|
||||
jl Lp11
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp11
|
||||
movw %bp,4(%ecx)
|
||||
movb %al,2(%edi)
|
||||
Lp11:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry5_8:
|
||||
cmpw 6(%ecx),%bp
|
||||
jl Lp12
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp12
|
||||
movw %bp,6(%ecx)
|
||||
movb %al,3(%edi)
|
||||
Lp12:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry4_8:
|
||||
cmpw 8(%ecx),%bp
|
||||
jl Lp13
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp13
|
||||
movw %bp,8(%ecx)
|
||||
movb %al,4(%edi)
|
||||
Lp13:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry3_8:
|
||||
cmpw 10(%ecx),%bp
|
||||
jl Lp14
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp14
|
||||
movw %bp,10(%ecx)
|
||||
movb %al,5(%edi)
|
||||
Lp14:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry2_8:
|
||||
cmpw 12(%ecx),%bp
|
||||
jl Lp15
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp15
|
||||
movw %bp,12(%ecx)
|
||||
movb %al,6(%edi)
|
||||
Lp15:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
LEndSpan:
|
||||
cmpw 14(%ecx),%bp
|
||||
jl Lp16
|
||||
movb (%esi),%al // load first texel in segment
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp16
|
||||
movw %bp,14(%ecx)
|
||||
movb %al,7(%edi)
|
||||
Lp16:
|
||||
|
||||
//
|
||||
// clear s/z, t/z, 1/z from FP stack
|
||||
//
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
|
||||
popl %ebx // restore spans pointer
|
||||
LNextSpan:
|
||||
addl $(sspan_t_size),%ebx // point to next span
|
||||
movl sspan_t_count(%ebx),%ecx
|
||||
cmpl $0,%ecx // any more spans?
|
||||
jg LSpanLoop // yes
|
||||
jz LNextSpan // yes, but this one's empty
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
#endif // id386
|
|
@ -1,442 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
// d_sprite.c: software top-level rasterization driver module for drawing
|
||||
// sprites
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "d_local.h"
|
||||
|
||||
static int sprite_height;
|
||||
static int minindex, maxindex;
|
||||
static sspan_t *sprite_spans;
|
||||
|
||||
#if !id386
|
||||
|
||||
/*
|
||||
=====================
|
||||
D_SpriteDrawSpans
|
||||
=====================
|
||||
*/
|
||||
void D_SpriteDrawSpans (sspan_t *pspan)
|
||||
{
|
||||
int count, spancount, izistep;
|
||||
int izi;
|
||||
byte *pbase, *pdest;
|
||||
fixed16_t s, t, snext, tnext, sstep, tstep;
|
||||
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
|
||||
float sdivz8stepu, tdivz8stepu, zi8stepu;
|
||||
byte btemp;
|
||||
short *pz;
|
||||
|
||||
sstep = 0; // keep compiler happy
|
||||
tstep = 0; // ditto
|
||||
|
||||
pbase = cacheblock;
|
||||
|
||||
sdivz8stepu = d_sdivzstepu * 8;
|
||||
tdivz8stepu = d_tdivzstepu * 8;
|
||||
zi8stepu = d_zistepu * 8;
|
||||
|
||||
// we count on FP exceptions being turned off to avoid range problems
|
||||
izistep = (int)(d_zistepu * 0x8000 * 0x10000);
|
||||
|
||||
do
|
||||
{
|
||||
pdest = (byte *)d_viewbuffer + (screenwidth * pspan->v) + pspan->u;
|
||||
pz = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
|
||||
|
||||
count = pspan->count;
|
||||
|
||||
if (count <= 0)
|
||||
goto NextSpan;
|
||||
|
||||
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
|
||||
du = (float)pspan->u;
|
||||
dv = (float)pspan->v;
|
||||
|
||||
sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
|
||||
tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
|
||||
zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
|
||||
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
|
||||
// we count on FP exceptions being turned off to avoid range problems
|
||||
izi = (int)(zi * 0x8000 * 0x10000);
|
||||
|
||||
s = (int)(sdivz * z) + sadjust;
|
||||
if (s > bbextents)
|
||||
s = bbextents;
|
||||
else if (s < 0)
|
||||
s = 0;
|
||||
|
||||
t = (int)(tdivz * z) + tadjust;
|
||||
if (t > bbextentt)
|
||||
t = bbextentt;
|
||||
else if (t < 0)
|
||||
t = 0;
|
||||
|
||||
do
|
||||
{
|
||||
// calculate s and t at the far end of the span
|
||||
if (count >= 8)
|
||||
spancount = 8;
|
||||
else
|
||||
spancount = count;
|
||||
|
||||
count -= spancount;
|
||||
|
||||
if (count)
|
||||
{
|
||||
// calculate s/z, t/z, zi->fixed s and t at far end of span,
|
||||
// calculate s and t steps across span by shifting
|
||||
sdivz += sdivz8stepu;
|
||||
tdivz += tdivz8stepu;
|
||||
zi += zi8stepu;
|
||||
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
|
||||
|
||||
snext = (int)(sdivz * z) + sadjust;
|
||||
if (snext > bbextents)
|
||||
snext = bbextents;
|
||||
else if (snext < 8)
|
||||
snext = 8; // prevent round-off error on <0 steps from
|
||||
// from causing overstepping & running off the
|
||||
// edge of the texture
|
||||
|
||||
tnext = (int)(tdivz * z) + tadjust;
|
||||
if (tnext > bbextentt)
|
||||
tnext = bbextentt;
|
||||
else if (tnext < 8)
|
||||
tnext = 8; // guard against round-off error on <0 steps
|
||||
|
||||
sstep = (snext - s) >> 3;
|
||||
tstep = (tnext - t) >> 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
|
||||
// can't step off polygon), clamp, calculate s and t steps across
|
||||
// span by division, biasing steps low so we don't run off the
|
||||
// texture
|
||||
spancountminus1 = (float)(spancount - 1);
|
||||
sdivz += d_sdivzstepu * spancountminus1;
|
||||
tdivz += d_tdivzstepu * spancountminus1;
|
||||
zi += d_zistepu * spancountminus1;
|
||||
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
|
||||
snext = (int)(sdivz * z) + sadjust;
|
||||
if (snext > bbextents)
|
||||
snext = bbextents;
|
||||
else if (snext < 8)
|
||||
snext = 8; // prevent round-off error on <0 steps from
|
||||
// from causing overstepping & running off the
|
||||
// edge of the texture
|
||||
|
||||
tnext = (int)(tdivz * z) + tadjust;
|
||||
if (tnext > bbextentt)
|
||||
tnext = bbextentt;
|
||||
else if (tnext < 8)
|
||||
tnext = 8; // guard against round-off error on <0 steps
|
||||
|
||||
if (spancount > 1)
|
||||
{
|
||||
sstep = (snext - s) / (spancount - 1);
|
||||
tstep = (tnext - t) / (spancount - 1);
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
btemp = *(pbase + (s >> 16) + (t >> 16) * cachewidth);
|
||||
if (btemp != 255)
|
||||
{
|
||||
if (*pz <= (izi >> 16))
|
||||
{
|
||||
*pz = izi >> 16;
|
||||
*pdest = btemp;
|
||||
}
|
||||
}
|
||||
|
||||
izi += izistep;
|
||||
pdest++;
|
||||
pz++;
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
} while (--spancount > 0);
|
||||
|
||||
s = snext;
|
||||
t = tnext;
|
||||
|
||||
} while (count > 0);
|
||||
|
||||
NextSpan:
|
||||
pspan++;
|
||||
|
||||
} while (pspan->count != DS_SPAN_LIST_END);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
D_SpriteScanLeftEdge
|
||||
=====================
|
||||
*/
|
||||
void D_SpriteScanLeftEdge (void)
|
||||
{
|
||||
int i, v, itop, ibottom, lmaxindex;
|
||||
emitpoint_t *pvert, *pnext;
|
||||
sspan_t *pspan;
|
||||
float du, dv, vtop, vbottom, slope;
|
||||
fixed16_t u, u_step;
|
||||
|
||||
pspan = sprite_spans;
|
||||
i = minindex;
|
||||
if (i == 0)
|
||||
i = r_spritedesc.nump;
|
||||
|
||||
lmaxindex = maxindex;
|
||||
if (lmaxindex == 0)
|
||||
lmaxindex = r_spritedesc.nump;
|
||||
|
||||
vtop = ceil (r_spritedesc.pverts[i].v);
|
||||
|
||||
do
|
||||
{
|
||||
pvert = &r_spritedesc.pverts[i];
|
||||
pnext = pvert - 1;
|
||||
|
||||
vbottom = ceil (pnext->v);
|
||||
|
||||
if (vtop < vbottom)
|
||||
{
|
||||
du = pnext->u - pvert->u;
|
||||
dv = pnext->v - pvert->v;
|
||||
slope = du / dv;
|
||||
u_step = (int)(slope * 0x10000);
|
||||
// adjust u to ceil the integer portion
|
||||
u = (int)((pvert->u + (slope * (vtop - pvert->v))) * 0x10000) +
|
||||
(0x10000 - 1);
|
||||
itop = (int)vtop;
|
||||
ibottom = (int)vbottom;
|
||||
|
||||
for (v=itop ; v<ibottom ; v++)
|
||||
{
|
||||
pspan->u = u >> 16;
|
||||
pspan->v = v;
|
||||
u += u_step;
|
||||
pspan++;
|
||||
}
|
||||
}
|
||||
|
||||
vtop = vbottom;
|
||||
|
||||
i--;
|
||||
if (i == 0)
|
||||
i = r_spritedesc.nump;
|
||||
|
||||
} while (i != lmaxindex);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
D_SpriteScanRightEdge
|
||||
=====================
|
||||
*/
|
||||
void D_SpriteScanRightEdge (void)
|
||||
{
|
||||
int i, v, itop, ibottom;
|
||||
emitpoint_t *pvert, *pnext;
|
||||
sspan_t *pspan;
|
||||
float du, dv, vtop, vbottom, slope, uvert, unext, vvert, vnext;
|
||||
fixed16_t u, u_step;
|
||||
|
||||
pspan = sprite_spans;
|
||||
i = minindex;
|
||||
|
||||
vvert = r_spritedesc.pverts[i].v;
|
||||
if (vvert < r_refdef.fvrecty_adj)
|
||||
vvert = r_refdef.fvrecty_adj;
|
||||
if (vvert > r_refdef.fvrectbottom_adj)
|
||||
vvert = r_refdef.fvrectbottom_adj;
|
||||
|
||||
vtop = ceil (vvert);
|
||||
|
||||
do
|
||||
{
|
||||
pvert = &r_spritedesc.pverts[i];
|
||||
pnext = pvert + 1;
|
||||
|
||||
vnext = pnext->v;
|
||||
if (vnext < r_refdef.fvrecty_adj)
|
||||
vnext = r_refdef.fvrecty_adj;
|
||||
if (vnext > r_refdef.fvrectbottom_adj)
|
||||
vnext = r_refdef.fvrectbottom_adj;
|
||||
|
||||
vbottom = ceil (vnext);
|
||||
|
||||
if (vtop < vbottom)
|
||||
{
|
||||
uvert = pvert->u;
|
||||
if (uvert < r_refdef.fvrectx_adj)
|
||||
uvert = r_refdef.fvrectx_adj;
|
||||
if (uvert > r_refdef.fvrectright_adj)
|
||||
uvert = r_refdef.fvrectright_adj;
|
||||
|
||||
unext = pnext->u;
|
||||
if (unext < r_refdef.fvrectx_adj)
|
||||
unext = r_refdef.fvrectx_adj;
|
||||
if (unext > r_refdef.fvrectright_adj)
|
||||
unext = r_refdef.fvrectright_adj;
|
||||
|
||||
du = unext - uvert;
|
||||
dv = vnext - vvert;
|
||||
slope = du / dv;
|
||||
u_step = (int)(slope * 0x10000);
|
||||
// adjust u to ceil the integer portion
|
||||
u = (int)((uvert + (slope * (vtop - vvert))) * 0x10000) +
|
||||
(0x10000 - 1);
|
||||
itop = (int)vtop;
|
||||
ibottom = (int)vbottom;
|
||||
|
||||
for (v=itop ; v<ibottom ; v++)
|
||||
{
|
||||
pspan->count = (u >> 16) - pspan->u;
|
||||
u += u_step;
|
||||
pspan++;
|
||||
}
|
||||
}
|
||||
|
||||
vtop = vbottom;
|
||||
vvert = vnext;
|
||||
|
||||
i++;
|
||||
if (i == r_spritedesc.nump)
|
||||
i = 0;
|
||||
|
||||
} while (i != maxindex);
|
||||
|
||||
pspan->count = DS_SPAN_LIST_END; // mark the end of the span list
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
D_SpriteCalculateGradients
|
||||
=====================
|
||||
*/
|
||||
void D_SpriteCalculateGradients (void)
|
||||
{
|
||||
vec3_t p_normal, p_saxis, p_taxis, p_temp1;
|
||||
float distinv;
|
||||
|
||||
TransformVector (r_spritedesc.vpn, p_normal);
|
||||
TransformVector (r_spritedesc.vright, p_saxis);
|
||||
TransformVector (r_spritedesc.vup, p_taxis);
|
||||
VectorInverse (p_taxis);
|
||||
|
||||
distinv = 1.0 / (-DotProduct (modelorg, r_spritedesc.vpn));
|
||||
|
||||
d_sdivzstepu = p_saxis[0] * xscaleinv;
|
||||
d_tdivzstepu = p_taxis[0] * xscaleinv;
|
||||
|
||||
d_sdivzstepv = -p_saxis[1] * yscaleinv;
|
||||
d_tdivzstepv = -p_taxis[1] * yscaleinv;
|
||||
|
||||
d_zistepu = p_normal[0] * xscaleinv * distinv;
|
||||
d_zistepv = -p_normal[1] * yscaleinv * distinv;
|
||||
|
||||
d_sdivzorigin = p_saxis[2] - xcenter * d_sdivzstepu -
|
||||
ycenter * d_sdivzstepv;
|
||||
d_tdivzorigin = p_taxis[2] - xcenter * d_tdivzstepu -
|
||||
ycenter * d_tdivzstepv;
|
||||
d_ziorigin = p_normal[2] * distinv - xcenter * d_zistepu -
|
||||
ycenter * d_zistepv;
|
||||
|
||||
TransformVector (modelorg, p_temp1);
|
||||
|
||||
sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) -
|
||||
(-(cachewidth >> 1) << 16);
|
||||
tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) -
|
||||
(-(sprite_height >> 1) << 16);
|
||||
|
||||
// -1 (-epsilon) so we never wander off the edge of the texture
|
||||
bbextents = (cachewidth << 16) - 1;
|
||||
bbextentt = (sprite_height << 16) - 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
D_DrawSprite
|
||||
=====================
|
||||
*/
|
||||
void D_DrawSprite (void)
|
||||
{
|
||||
int i, nump;
|
||||
float ymin, ymax;
|
||||
emitpoint_t *pverts;
|
||||
sspan_t spans[MAXHEIGHT+1];
|
||||
|
||||
sprite_spans = spans;
|
||||
|
||||
// find the top and bottom vertices, and make sure there's at least one scan to
|
||||
// draw
|
||||
ymin = 999999.9;
|
||||
ymax = -999999.9;
|
||||
pverts = r_spritedesc.pverts;
|
||||
|
||||
for (i=0 ; i<r_spritedesc.nump ; i++)
|
||||
{
|
||||
if (pverts->v < ymin)
|
||||
{
|
||||
ymin = pverts->v;
|
||||
minindex = i;
|
||||
}
|
||||
|
||||
if (pverts->v > ymax)
|
||||
{
|
||||
ymax = pverts->v;
|
||||
maxindex = i;
|
||||
}
|
||||
|
||||
pverts++;
|
||||
}
|
||||
|
||||
ymin = ceil (ymin);
|
||||
ymax = ceil (ymax);
|
||||
|
||||
if (ymin >= ymax)
|
||||
return; // doesn't cross any scans at all
|
||||
|
||||
cachewidth = r_spritedesc.pspriteframe->width;
|
||||
sprite_height = r_spritedesc.pspriteframe->height;
|
||||
cacheblock = (byte *)&r_spritedesc.pspriteframe->pixels[0];
|
||||
|
||||
// copy the first vertex to the last vertex, so we don't have to deal with
|
||||
// wrapping
|
||||
nump = r_spritedesc.nump;
|
||||
pverts = r_spritedesc.pverts;
|
||||
pverts[nump] = pverts[0];
|
||||
|
||||
D_SpriteCalculateGradients ();
|
||||
D_SpriteScanLeftEdge ();
|
||||
D_SpriteScanRightEdge ();
|
||||
D_SpriteDrawSpans (sprite_spans);
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
// r_vars.c: global refresh variables
|
||||
|
||||
#if !id386
|
||||
|
||||
#include "quakedef.h"
|
||||
|
||||
// all global and static refresh variables are collected in a contiguous block
|
||||
// to avoid cache conflicts.
|
||||
|
||||
//-------------------------------------------------------
|
||||
// global refresh variables
|
||||
//-------------------------------------------------------
|
||||
|
||||
// FIXME: make into one big structure, like cl or sv
|
||||
// FIXME: do separately for refresh engine and driver
|
||||
|
||||
float d_sdivzstepu, d_tdivzstepu, d_zistepu;
|
||||
float d_sdivzstepv, d_tdivzstepv, d_zistepv;
|
||||
float d_sdivzorigin, d_tdivzorigin, d_ziorigin;
|
||||
|
||||
fixed16_t sadjust, tadjust, bbextents, bbextentt;
|
||||
|
||||
pixel_t *cacheblock;
|
||||
int cachewidth;
|
||||
pixel_t *d_viewbuffer;
|
||||
short *d_pzbuffer;
|
||||
unsigned int d_zrowbytes;
|
||||
unsigned int d_zwidth;
|
||||
|
||||
#endif // !id386
|
||||
|
|
@ -1,213 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
//
|
||||
// d_varsa.s
|
||||
//
|
||||
|
||||
#include "asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
#include "d_ifacea.h"
|
||||
|
||||
#if id386
|
||||
|
||||
.data
|
||||
|
||||
//-------------------------------------------------------
|
||||
// global refresh variables
|
||||
//-------------------------------------------------------
|
||||
|
||||
// FIXME: put all refresh variables into one contiguous block. Make into one
|
||||
// big structure, like cl or sv?
|
||||
|
||||
.align 4
|
||||
.globl C(d_sdivzstepu)
|
||||
.globl C(d_tdivzstepu)
|
||||
.globl C(d_zistepu)
|
||||
.globl C(d_sdivzstepv)
|
||||
.globl C(d_tdivzstepv)
|
||||
.globl C(d_zistepv)
|
||||
.globl C(d_sdivzorigin)
|
||||
.globl C(d_tdivzorigin)
|
||||
.globl C(d_ziorigin)
|
||||
C(d_sdivzstepu): .single 0
|
||||
C(d_tdivzstepu): .single 0
|
||||
C(d_zistepu): .single 0
|
||||
C(d_sdivzstepv): .single 0
|
||||
C(d_tdivzstepv): .single 0
|
||||
C(d_zistepv): .single 0
|
||||
C(d_sdivzorigin): .single 0
|
||||
C(d_tdivzorigin): .single 0
|
||||
C(d_ziorigin): .single 0
|
||||
|
||||
.globl C(sadjust)
|
||||
.globl C(tadjust)
|
||||
.globl C(bbextents)
|
||||
.globl C(bbextentt)
|
||||
C(sadjust): .long 0
|
||||
C(tadjust): .long 0
|
||||
C(bbextents): .long 0
|
||||
C(bbextentt): .long 0
|
||||
|
||||
.globl C(cacheblock)
|
||||
.globl C(d_viewbuffer)
|
||||
.globl C(cachewidth)
|
||||
.globl C(d_pzbuffer)
|
||||
.globl C(d_zrowbytes)
|
||||
.globl C(d_zwidth)
|
||||
C(cacheblock): .long 0
|
||||
C(cachewidth): .long 0
|
||||
C(d_viewbuffer): .long 0
|
||||
C(d_pzbuffer): .long 0
|
||||
C(d_zrowbytes): .long 0
|
||||
C(d_zwidth): .long 0
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// ASM-only variables
|
||||
//-------------------------------------------------------
|
||||
.globl izi
|
||||
izi: .long 0
|
||||
|
||||
.globl pbase, s, t, sfracf, tfracf, snext, tnext
|
||||
.globl spancountminus1, zi16stepu, sdivz16stepu, tdivz16stepu
|
||||
.globl zi8stepu, sdivz8stepu, tdivz8stepu, pz
|
||||
s: .long 0
|
||||
t: .long 0
|
||||
snext: .long 0
|
||||
tnext: .long 0
|
||||
sfracf: .long 0
|
||||
tfracf: .long 0
|
||||
pbase: .long 0
|
||||
zi8stepu: .long 0
|
||||
sdivz8stepu: .long 0
|
||||
tdivz8stepu: .long 0
|
||||
zi16stepu: .long 0
|
||||
sdivz16stepu: .long 0
|
||||
tdivz16stepu: .long 0
|
||||
spancountminus1: .long 0
|
||||
pz: .long 0
|
||||
|
||||
.globl izistep
|
||||
izistep: .long 0
|
||||
|
||||
//-------------------------------------------------------
|
||||
// local variables for d_draw16.s
|
||||
//-------------------------------------------------------
|
||||
|
||||
.globl reciprocal_table_16, entryvec_table_16
|
||||
// 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9, 1/10, 1/11, 1/12, 1/13,
|
||||
// 1/14, and 1/15 in 0.32 form
|
||||
reciprocal_table_16: .long 0x40000000, 0x2aaaaaaa, 0x20000000
|
||||
.long 0x19999999, 0x15555555, 0x12492492
|
||||
.long 0x10000000, 0xe38e38e, 0xccccccc, 0xba2e8ba
|
||||
.long 0xaaaaaaa, 0x9d89d89, 0x9249249, 0x8888888
|
||||
|
||||
#ifndef NeXT
|
||||
.extern Entry2_16
|
||||
.extern Entry3_16
|
||||
.extern Entry4_16
|
||||
.extern Entry5_16
|
||||
.extern Entry6_16
|
||||
.extern Entry7_16
|
||||
.extern Entry8_16
|
||||
.extern Entry9_16
|
||||
.extern Entry10_16
|
||||
.extern Entry11_16
|
||||
.extern Entry12_16
|
||||
.extern Entry13_16
|
||||
.extern Entry14_16
|
||||
.extern Entry15_16
|
||||
.extern Entry16_16
|
||||
#endif
|
||||
|
||||
entryvec_table_16: .long 0, Entry2_16, Entry3_16, Entry4_16
|
||||
.long Entry5_16, Entry6_16, Entry7_16, Entry8_16
|
||||
.long Entry9_16, Entry10_16, Entry11_16, Entry12_16
|
||||
.long Entry13_16, Entry14_16, Entry15_16, Entry16_16
|
||||
|
||||
//-------------------------------------------------------
|
||||
// local variables for d_parta.s
|
||||
//-------------------------------------------------------
|
||||
.globl DP_Count, DP_u, DP_v, DP_32768, DP_Color, DP_Pix, DP_EntryTable
|
||||
DP_Count: .long 0
|
||||
DP_u: .long 0
|
||||
DP_v: .long 0
|
||||
DP_32768: .single 32768.0
|
||||
DP_Color: .long 0
|
||||
DP_Pix: .long 0
|
||||
|
||||
|
||||
#ifndef NeXT
|
||||
.extern DP_1x1
|
||||
.extern DP_2x2
|
||||
.extern DP_3x3
|
||||
.extern DP_4x4
|
||||
#endif
|
||||
|
||||
DP_EntryTable: .long DP_1x1, DP_2x2, DP_3x3, DP_4x4
|
||||
|
||||
//
|
||||
// advancetable is 8 bytes, but points to the middle of that range so negative
|
||||
// offsets will work
|
||||
//
|
||||
.globl advancetable, sstep, tstep, pspantemp, counttemp, jumptemp
|
||||
advancetable: .long 0, 0
|
||||
sstep: .long 0
|
||||
tstep: .long 0
|
||||
|
||||
pspantemp: .long 0
|
||||
counttemp: .long 0
|
||||
jumptemp: .long 0
|
||||
|
||||
// 1/2, 1/3, 1/4, 1/5, 1/6, and 1/7 in 0.32 form
|
||||
.globl reciprocal_table, entryvec_table
|
||||
reciprocal_table: .long 0x40000000, 0x2aaaaaaa, 0x20000000
|
||||
.long 0x19999999, 0x15555555, 0x12492492
|
||||
|
||||
#ifndef NeXT
|
||||
.extern Entry2_8
|
||||
.extern Entry3_8
|
||||
.extern Entry4_8
|
||||
.extern Entry5_8
|
||||
.extern Entry6_8
|
||||
.extern Entry7_8
|
||||
.extern Entry8_8
|
||||
#endif
|
||||
|
||||
entryvec_table: .long 0, Entry2_8, Entry3_8, Entry4_8
|
||||
.long Entry5_8, Entry6_8, Entry7_8, Entry8_8
|
||||
|
||||
#ifndef NeXT
|
||||
.extern Spr8Entry2_8
|
||||
.extern Spr8Entry3_8
|
||||
.extern Spr8Entry4_8
|
||||
.extern Spr8Entry5_8
|
||||
.extern Spr8Entry6_8
|
||||
.extern Spr8Entry7_8
|
||||
.extern Spr8Entry8_8
|
||||
#endif
|
||||
|
||||
.globl spr8entryvec_table
|
||||
spr8entryvec_table: .long 0, Spr8Entry2_8, Spr8Entry3_8, Spr8Entry4_8
|
||||
.long Spr8Entry5_8, Spr8Entry6_8, Spr8Entry7_8, Spr8Entry8_8
|
||||
|
||||
#endif // id386
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
// d_zpoint.c: software driver module for drawing z-buffered points
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "d_local.h"
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
D_DrawZPoint
|
||||
=====================
|
||||
*/
|
||||
void D_DrawZPoint (void)
|
||||
{
|
||||
byte *pdest;
|
||||
short *pz;
|
||||
int izi;
|
||||
|
||||
pz = d_pzbuffer + (d_zwidth * r_zpointdesc.v) + r_zpointdesc.u;
|
||||
pdest = d_viewbuffer + d_scantable[r_zpointdesc.v] + r_zpointdesc.u;
|
||||
izi = (int)(r_zpointdesc.zi * 0x8000);
|
||||
|
||||
if (*pz <= izi)
|
||||
{
|
||||
*pz = izi;
|
||||
*pdest = r_zpointdesc.color;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,182 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
#include "quakedef.h"
|
||||
|
||||
#ifdef GLTEST
|
||||
|
||||
typedef struct
|
||||
{
|
||||
plane_t *plane;
|
||||
vec3_t origin;
|
||||
vec3_t normal;
|
||||
vec3_t up;
|
||||
vec3_t right;
|
||||
vec3_t reflect;
|
||||
float length;
|
||||
} puff_t;
|
||||
|
||||
#define MAX_PUFFS 64
|
||||
|
||||
puff_t puffs[MAX_PUFFS];
|
||||
|
||||
|
||||
void Test_Init (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
plane_t junk;
|
||||
plane_t *HitPlane (vec3_t start, vec3_t end)
|
||||
{
|
||||
trace_t trace;
|
||||
|
||||
// fill in a default trace
|
||||
memset (&trace, 0, sizeof(trace_t));
|
||||
trace.fraction = 1;
|
||||
trace.allsolid = true;
|
||||
VectorCopy (end, trace.endpos);
|
||||
|
||||
SV_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, start, end, &trace);
|
||||
|
||||
junk = trace.plane;
|
||||
return &junk;
|
||||
}
|
||||
|
||||
void Test_Spawn (vec3_t origin)
|
||||
{
|
||||
int i;
|
||||
puff_t *p;
|
||||
vec3_t temp;
|
||||
vec3_t normal;
|
||||
vec3_t incoming;
|
||||
plane_t *plane;
|
||||
float d;
|
||||
|
||||
for (i=0,p=puffs ; i<MAX_PUFFS ; i++,p++)
|
||||
{
|
||||
if (p->length <= 0)
|
||||
break;
|
||||
}
|
||||
if (i == MAX_PUFFS)
|
||||
return;
|
||||
|
||||
VectorSubtract (r_refdef.vieworg, origin, incoming);
|
||||
VectorSubtract (origin, incoming, temp);
|
||||
plane = HitPlane (r_refdef.vieworg, temp);
|
||||
|
||||
VectorNormalize (incoming);
|
||||
d = DotProduct (incoming, plane->normal);
|
||||
VectorSubtract (vec3_origin, incoming, p->reflect);
|
||||
VectorMA (p->reflect, d*2, plane->normal, p->reflect);
|
||||
|
||||
VectorCopy (origin, p->origin);
|
||||
VectorCopy (plane->normal, p->normal);
|
||||
|
||||
CrossProduct (incoming, p->normal, p->up);
|
||||
|
||||
CrossProduct (p->up, p->normal, p->right);
|
||||
|
||||
p->length = 8;
|
||||
}
|
||||
|
||||
void DrawPuff (puff_t *p)
|
||||
{
|
||||
vec3_t pts[2][3];
|
||||
int i, j;
|
||||
float s, d;
|
||||
|
||||
for (i=0 ; i<2 ; i++)
|
||||
{
|
||||
if (i == 1)
|
||||
{
|
||||
s = 6;
|
||||
d = p->length;
|
||||
}
|
||||
else
|
||||
{
|
||||
s = 2;
|
||||
d = 0;
|
||||
}
|
||||
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
pts[i][0][j] = p->origin[j] + p->up[j]*s + p->reflect[j]*d;
|
||||
pts[i][1][j] = p->origin[j] + p->right[j]*s + p->reflect[j]*d;
|
||||
pts[i][2][j] = p->origin[j] + -p->right[j]*s + p->reflect[j]*d;
|
||||
}
|
||||
}
|
||||
|
||||
glColor3f (1, 0, 0);
|
||||
|
||||
#if 0
|
||||
glBegin (GL_LINES);
|
||||
glVertex3fv (p->origin);
|
||||
glVertex3f (p->origin[0] + p->length*p->reflect[0],
|
||||
p->origin[1] + p->length*p->reflect[1],
|
||||
p->origin[2] + p->length*p->reflect[2]);
|
||||
|
||||
glVertex3fv (pts[0][0]);
|
||||
glVertex3fv (pts[1][0]);
|
||||
|
||||
glVertex3fv (pts[0][1]);
|
||||
glVertex3fv (pts[1][1]);
|
||||
|
||||
glVertex3fv (pts[0][2]);
|
||||
glVertex3fv (pts[1][2]);
|
||||
|
||||
glEnd ();
|
||||
#endif
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
j = (i+1)%3;
|
||||
glVertex3fv (pts[0][j]);
|
||||
glVertex3fv (pts[1][j]);
|
||||
glVertex3fv (pts[1][i]);
|
||||
glVertex3fv (pts[0][i]);
|
||||
}
|
||||
glEnd ();
|
||||
|
||||
glBegin (GL_TRIANGLES);
|
||||
glVertex3fv (pts[1][0]);
|
||||
glVertex3fv (pts[1][1]);
|
||||
glVertex3fv (pts[1][2]);
|
||||
glEnd ();
|
||||
|
||||
p->length -= host_frametime*2;
|
||||
}
|
||||
|
||||
|
||||
void Test_Draw (void)
|
||||
{
|
||||
int i;
|
||||
puff_t *p;
|
||||
|
||||
for (i=0, p=puffs ; i<MAX_PUFFS ; i++,p++)
|
||||
{
|
||||
if (p->length > 0)
|
||||
DrawPuff (p);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
1086
qw_client/gl_warp.c
1086
qw_client/gl_warp.c
File diff suppressed because it is too large
Load diff
|
@ -1,350 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
// r_aclip.c: clip routines for drawing Alias models directly to the screen
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "r_local.h"
|
||||
#include "d_local.h"
|
||||
|
||||
static finalvert_t fv[2][8];
|
||||
static auxvert_t av[8];
|
||||
|
||||
void R_AliasProjectFinalVert (finalvert_t *fv, auxvert_t *av);
|
||||
void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1,
|
||||
finalvert_t *out);
|
||||
void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1,
|
||||
finalvert_t *out);
|
||||
void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1,
|
||||
finalvert_t *out);
|
||||
void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1,
|
||||
finalvert_t *out);
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_Alias_clip_z
|
||||
|
||||
pfv0 is the unclipped vertex, pfv1 is the z-clipped vertex
|
||||
================
|
||||
*/
|
||||
void R_Alias_clip_z (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
auxvert_t *pav0, *pav1, avout;
|
||||
|
||||
pav0 = &av[pfv0 - &fv[0][0]];
|
||||
pav1 = &av[pfv1 - &fv[0][0]];
|
||||
|
||||
if (pfv0->v[1] >= pfv1->v[1])
|
||||
{
|
||||
scale = (ALIAS_Z_CLIP_PLANE - pav0->fv[2]) /
|
||||
(pav1->fv[2] - pav0->fv[2]);
|
||||
|
||||
avout.fv[0] = pav0->fv[0] + (pav1->fv[0] - pav0->fv[0]) * scale;
|
||||
avout.fv[1] = pav0->fv[1] + (pav1->fv[1] - pav0->fv[1]) * scale;
|
||||
avout.fv[2] = ALIAS_Z_CLIP_PLANE;
|
||||
|
||||
out->v[2] = pfv0->v[2] + (pfv1->v[2] - pfv0->v[2]) * scale;
|
||||
out->v[3] = pfv0->v[3] + (pfv1->v[3] - pfv0->v[3]) * scale;
|
||||
out->v[4] = pfv0->v[4] + (pfv1->v[4] - pfv0->v[4]) * scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = (ALIAS_Z_CLIP_PLANE - pav1->fv[2]) /
|
||||
(pav0->fv[2] - pav1->fv[2]);
|
||||
|
||||
avout.fv[0] = pav1->fv[0] + (pav0->fv[0] - pav1->fv[0]) * scale;
|
||||
avout.fv[1] = pav1->fv[1] + (pav0->fv[1] - pav1->fv[1]) * scale;
|
||||
avout.fv[2] = ALIAS_Z_CLIP_PLANE;
|
||||
|
||||
out->v[2] = pfv1->v[2] + (pfv0->v[2] - pfv1->v[2]) * scale;
|
||||
out->v[3] = pfv1->v[3] + (pfv0->v[3] - pfv1->v[3]) * scale;
|
||||
out->v[4] = pfv1->v[4] + (pfv0->v[4] - pfv1->v[4]) * scale;
|
||||
}
|
||||
|
||||
R_AliasProjectFinalVert (out, &avout);
|
||||
|
||||
if (out->v[0] < r_refdef.aliasvrect.x)
|
||||
out->flags |= ALIAS_LEFT_CLIP;
|
||||
if (out->v[1] < r_refdef.aliasvrect.y)
|
||||
out->flags |= ALIAS_TOP_CLIP;
|
||||
if (out->v[0] > r_refdef.aliasvrectright)
|
||||
out->flags |= ALIAS_RIGHT_CLIP;
|
||||
if (out->v[1] > r_refdef.aliasvrectbottom)
|
||||
out->flags |= ALIAS_BOTTOM_CLIP;
|
||||
}
|
||||
|
||||
|
||||
#if !id386
|
||||
|
||||
void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
int i;
|
||||
|
||||
if (pfv0->v[1] >= pfv1->v[1])
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrect.x - pfv0->v[0]) /
|
||||
(pfv1->v[0] - pfv0->v[0]);
|
||||
for (i=0 ; i<6 ; i++)
|
||||
out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrect.x - pfv1->v[0]) /
|
||||
(pfv0->v[0] - pfv1->v[0]);
|
||||
for (i=0 ; i<6 ; i++)
|
||||
out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1,
|
||||
finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
int i;
|
||||
|
||||
if (pfv0->v[1] >= pfv1->v[1])
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrectright - pfv0->v[0]) /
|
||||
(pfv1->v[0] - pfv0->v[0]);
|
||||
for (i=0 ; i<6 ; i++)
|
||||
out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrectright - pfv1->v[0]) /
|
||||
(pfv0->v[0] - pfv1->v[0]);
|
||||
for (i=0 ; i<6 ; i++)
|
||||
out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
int i;
|
||||
|
||||
if (pfv0->v[1] >= pfv1->v[1])
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrect.y - pfv0->v[1]) /
|
||||
(pfv1->v[1] - pfv0->v[1]);
|
||||
for (i=0 ; i<6 ; i++)
|
||||
out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrect.y - pfv1->v[1]) /
|
||||
(pfv0->v[1] - pfv1->v[1]);
|
||||
for (i=0 ; i<6 ; i++)
|
||||
out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1,
|
||||
finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
int i;
|
||||
|
||||
if (pfv0->v[1] >= pfv1->v[1])
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrectbottom - pfv0->v[1]) /
|
||||
(pfv1->v[1] - pfv0->v[1]);
|
||||
|
||||
for (i=0 ; i<6 ; i++)
|
||||
out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrectbottom - pfv1->v[1]) /
|
||||
(pfv0->v[1] - pfv1->v[1]);
|
||||
|
||||
for (i=0 ; i<6 ; i++)
|
||||
out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int R_AliasClip (finalvert_t *in, finalvert_t *out, int flag, int count,
|
||||
void(*clip)(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) )
|
||||
{
|
||||
int i,j,k;
|
||||
int flags, oldflags;
|
||||
|
||||
j = count-1;
|
||||
k = 0;
|
||||
for (i=0 ; i<count ; j = i, i++)
|
||||
{
|
||||
oldflags = in[j].flags & flag;
|
||||
flags = in[i].flags & flag;
|
||||
|
||||
if (flags && oldflags)
|
||||
continue;
|
||||
if (oldflags ^ flags)
|
||||
{
|
||||
clip (&in[j], &in[i], &out[k]);
|
||||
out[k].flags = 0;
|
||||
if (out[k].v[0] < r_refdef.aliasvrect.x)
|
||||
out[k].flags |= ALIAS_LEFT_CLIP;
|
||||
if (out[k].v[1] < r_refdef.aliasvrect.y)
|
||||
out[k].flags |= ALIAS_TOP_CLIP;
|
||||
if (out[k].v[0] > r_refdef.aliasvrectright)
|
||||
out[k].flags |= ALIAS_RIGHT_CLIP;
|
||||
if (out[k].v[1] > r_refdef.aliasvrectbottom)
|
||||
out[k].flags |= ALIAS_BOTTOM_CLIP;
|
||||
k++;
|
||||
}
|
||||
if (!flags)
|
||||
{
|
||||
out[k] = in[i];
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_AliasClipTriangle
|
||||
================
|
||||
*/
|
||||
void R_AliasClipTriangle (mtriangle_t *ptri)
|
||||
{
|
||||
int i, k, pingpong;
|
||||
mtriangle_t mtri;
|
||||
unsigned clipflags;
|
||||
|
||||
// copy vertexes and fix seam texture coordinates
|
||||
if (ptri->facesfront)
|
||||
{
|
||||
fv[0][0] = pfinalverts[ptri->vertindex[0]];
|
||||
fv[0][1] = pfinalverts[ptri->vertindex[1]];
|
||||
fv[0][2] = pfinalverts[ptri->vertindex[2]];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
fv[0][i] = pfinalverts[ptri->vertindex[i]];
|
||||
|
||||
if (!ptri->facesfront && (fv[0][i].flags & ALIAS_ONSEAM) )
|
||||
fv[0][i].v[2] += r_affinetridesc.seamfixupX16;
|
||||
}
|
||||
}
|
||||
|
||||
// clip
|
||||
clipflags = fv[0][0].flags | fv[0][1].flags | fv[0][2].flags;
|
||||
|
||||
if (clipflags & ALIAS_Z_CLIP)
|
||||
{
|
||||
for (i=0 ; i<3 ; i++)
|
||||
av[i] = pauxverts[ptri->vertindex[i]];
|
||||
|
||||
k = R_AliasClip (fv[0], fv[1], ALIAS_Z_CLIP, 3, R_Alias_clip_z);
|
||||
if (k == 0)
|
||||
return;
|
||||
|
||||
pingpong = 1;
|
||||
clipflags = fv[1][0].flags | fv[1][1].flags | fv[1][2].flags;
|
||||
}
|
||||
else
|
||||
{
|
||||
pingpong = 0;
|
||||
k = 3;
|
||||
}
|
||||
|
||||
if (clipflags & ALIAS_LEFT_CLIP)
|
||||
{
|
||||
k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
|
||||
ALIAS_LEFT_CLIP, k, R_Alias_clip_left);
|
||||
if (k == 0)
|
||||
return;
|
||||
|
||||
pingpong ^= 1;
|
||||
}
|
||||
|
||||
if (clipflags & ALIAS_RIGHT_CLIP)
|
||||
{
|
||||
k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
|
||||
ALIAS_RIGHT_CLIP, k, R_Alias_clip_right);
|
||||
if (k == 0)
|
||||
return;
|
||||
|
||||
pingpong ^= 1;
|
||||
}
|
||||
|
||||
if (clipflags & ALIAS_BOTTOM_CLIP)
|
||||
{
|
||||
k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
|
||||
ALIAS_BOTTOM_CLIP, k, R_Alias_clip_bottom);
|
||||
if (k == 0)
|
||||
return;
|
||||
|
||||
pingpong ^= 1;
|
||||
}
|
||||
|
||||
if (clipflags & ALIAS_TOP_CLIP)
|
||||
{
|
||||
k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
|
||||
ALIAS_TOP_CLIP, k, R_Alias_clip_top);
|
||||
if (k == 0)
|
||||
return;
|
||||
|
||||
pingpong ^= 1;
|
||||
}
|
||||
|
||||
for (i=0 ; i<k ; i++)
|
||||
{
|
||||
if (fv[pingpong][i].v[0] < r_refdef.aliasvrect.x)
|
||||
fv[pingpong][i].v[0] = r_refdef.aliasvrect.x;
|
||||
else if (fv[pingpong][i].v[0] > r_refdef.aliasvrectright)
|
||||
fv[pingpong][i].v[0] = r_refdef.aliasvrectright;
|
||||
|
||||
if (fv[pingpong][i].v[1] < r_refdef.aliasvrect.y)
|
||||
fv[pingpong][i].v[1] = r_refdef.aliasvrect.y;
|
||||
else if (fv[pingpong][i].v[1] > r_refdef.aliasvrectbottom)
|
||||
fv[pingpong][i].v[1] = r_refdef.aliasvrectbottom;
|
||||
|
||||
fv[pingpong][i].flags = 0;
|
||||
}
|
||||
|
||||
// draw triangles
|
||||
mtri.facesfront = ptri->facesfront;
|
||||
r_affinetridesc.ptriangles = &mtri;
|
||||
r_affinetridesc.pfinalverts = fv[pingpong];
|
||||
|
||||
// FIXME: do all at once as trifan?
|
||||
mtri.vertindex[0] = 0;
|
||||
for (i=1 ; i<k-1 ; i++)
|
||||
{
|
||||
mtri.vertindex[1] = i;
|
||||
mtri.vertindex[2] = i+1;
|
||||
D_PolysetDraw ();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,727 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
#include "quakedef.h"
|
||||
#include "winquake.h"
|
||||
|
||||
#define iDirectSoundCreate(a,b,c) pDirectSoundCreate(a,b,c)
|
||||
|
||||
HRESULT (WINAPI *pDirectSoundCreate)(GUID FAR *lpGUID, LPDIRECTSOUND FAR *lplpDS, IUnknown FAR *pUnkOuter);
|
||||
|
||||
// 64K is > 1 second at 16-bit, 22050 Hz
|
||||
#define WAV_BUFFERS 64
|
||||
#define WAV_MASK 0x3F
|
||||
#define WAV_BUFFER_SIZE 0x0400
|
||||
#define SECONDARY_BUFFER_SIZE 0x10000
|
||||
|
||||
typedef enum {SIS_SUCCESS, SIS_FAILURE, SIS_NOTAVAIL} sndinitstat;
|
||||
|
||||
static qboolean wavonly;
|
||||
static qboolean dsound_init;
|
||||
static qboolean wav_init;
|
||||
static qboolean snd_firsttime = true, snd_isdirect, snd_iswave;
|
||||
static qboolean primary_format_set;
|
||||
|
||||
static int sample16;
|
||||
static int snd_sent, snd_completed;
|
||||
|
||||
|
||||
/*
|
||||
* Global variables. Must be visible to window-procedure function
|
||||
* so it can unlock and free the data block after it has been played.
|
||||
*/
|
||||
|
||||
HANDLE hData;
|
||||
HPSTR lpData, lpData2;
|
||||
|
||||
HGLOBAL hWaveHdr;
|
||||
LPWAVEHDR lpWaveHdr;
|
||||
|
||||
HWAVEOUT hWaveOut;
|
||||
|
||||
WAVEOUTCAPS wavecaps;
|
||||
|
||||
DWORD gSndBufSize;
|
||||
|
||||
MMTIME mmstarttime;
|
||||
|
||||
LPDIRECTSOUND pDS;
|
||||
LPDIRECTSOUNDBUFFER pDSBuf, pDSPBuf;
|
||||
|
||||
HINSTANCE hInstDS;
|
||||
|
||||
qboolean SNDDMA_InitDirect (void);
|
||||
qboolean SNDDMA_InitWav (void);
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
S_BlockSound
|
||||
==================
|
||||
*/
|
||||
void S_BlockSound (void)
|
||||
{
|
||||
|
||||
// DirectSound takes care of blocking itself
|
||||
if (snd_iswave)
|
||||
{
|
||||
snd_blocked++;
|
||||
|
||||
if (snd_blocked == 1)
|
||||
waveOutReset (hWaveOut);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
S_UnblockSound
|
||||
==================
|
||||
*/
|
||||
void S_UnblockSound (void)
|
||||
{
|
||||
|
||||
// DirectSound takes care of blocking itself
|
||||
if (snd_iswave)
|
||||
{
|
||||
snd_blocked--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
FreeSound
|
||||
==================
|
||||
*/
|
||||
void FreeSound (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (pDSBuf)
|
||||
{
|
||||
pDSBuf->lpVtbl->Stop(pDSBuf);
|
||||
pDSBuf->lpVtbl->Release(pDSBuf);
|
||||
}
|
||||
|
||||
// only release primary buffer if it's not also the mixing buffer we just released
|
||||
if (pDSPBuf && (pDSBuf != pDSPBuf))
|
||||
{
|
||||
pDSPBuf->lpVtbl->Release(pDSPBuf);
|
||||
}
|
||||
|
||||
if (pDS)
|
||||
{
|
||||
pDS->lpVtbl->SetCooperativeLevel (pDS, mainwindow, DSSCL_NORMAL);
|
||||
pDS->lpVtbl->Release(pDS);
|
||||
}
|
||||
|
||||
if (hWaveOut)
|
||||
{
|
||||
waveOutReset (hWaveOut);
|
||||
|
||||
if (lpWaveHdr)
|
||||
{
|
||||
for (i=0 ; i< WAV_BUFFERS ; i++)
|
||||
waveOutUnprepareHeader (hWaveOut, lpWaveHdr+i, sizeof(WAVEHDR));
|
||||
}
|
||||
|
||||
waveOutClose (hWaveOut);
|
||||
|
||||
if (hWaveHdr)
|
||||
{
|
||||
GlobalUnlock(hWaveHdr);
|
||||
GlobalFree(hWaveHdr);
|
||||
}
|
||||
|
||||
if (hData)
|
||||
{
|
||||
GlobalUnlock(hData);
|
||||
GlobalFree(hData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pDS = NULL;
|
||||
pDSBuf = NULL;
|
||||
pDSPBuf = NULL;
|
||||
hWaveOut = 0;
|
||||
hData = 0;
|
||||
hWaveHdr = 0;
|
||||
lpData = NULL;
|
||||
lpWaveHdr = NULL;
|
||||
dsound_init = false;
|
||||
wav_init = false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
SNDDMA_InitDirect
|
||||
|
||||
Direct-Sound support
|
||||
==================
|
||||
*/
|
||||
sndinitstat SNDDMA_InitDirect (void)
|
||||
{
|
||||
DSBUFFERDESC dsbuf;
|
||||
DSBCAPS dsbcaps;
|
||||
DWORD dwSize, dwWrite;
|
||||
DSCAPS dscaps;
|
||||
WAVEFORMATEX format, pformat;
|
||||
HRESULT hresult;
|
||||
int reps;
|
||||
|
||||
memset ((void *)&sn, 0, sizeof (sn));
|
||||
|
||||
shm = &sn;
|
||||
|
||||
shm->channels = 2;
|
||||
shm->samplebits = 16;
|
||||
shm->speed = 11025;
|
||||
|
||||
memset (&format, 0, sizeof(format));
|
||||
format.wFormatTag = WAVE_FORMAT_PCM;
|
||||
format.nChannels = shm->channels;
|
||||
format.wBitsPerSample = shm->samplebits;
|
||||
format.nSamplesPerSec = shm->speed;
|
||||
format.nBlockAlign = format.nChannels
|
||||
*format.wBitsPerSample / 8;
|
||||
format.cbSize = 0;
|
||||
format.nAvgBytesPerSec = format.nSamplesPerSec
|
||||
*format.nBlockAlign;
|
||||
|
||||
if (!hInstDS)
|
||||
{
|
||||
hInstDS = LoadLibrary("dsound.dll");
|
||||
|
||||
if (hInstDS == NULL)
|
||||
{
|
||||
Con_SafePrintf ("Couldn't load dsound.dll\n");
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
pDirectSoundCreate = (void *)GetProcAddress(hInstDS,"DirectSoundCreate");
|
||||
|
||||
if (!pDirectSoundCreate)
|
||||
{
|
||||
Con_SafePrintf ("Couldn't get DS proc addr\n");
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
while ((hresult = iDirectSoundCreate(NULL, &pDS, NULL)) != DS_OK)
|
||||
{
|
||||
if (hresult != DSERR_ALLOCATED)
|
||||
{
|
||||
Con_SafePrintf ("DirectSound create failed\n");
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
if (MessageBox (NULL,
|
||||
"The sound hardware is in use by another app.\n\n"
|
||||
"Select Retry to try to start sound again or Cancel to run Quake with no sound.",
|
||||
"Sound not available",
|
||||
MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY)
|
||||
{
|
||||
Con_SafePrintf ("DirectSoundCreate failure\n"
|
||||
" hardware already in use\n");
|
||||
return SIS_NOTAVAIL;
|
||||
}
|
||||
}
|
||||
|
||||
dscaps.dwSize = sizeof(dscaps);
|
||||
|
||||
if (DS_OK != pDS->lpVtbl->GetCaps (pDS, &dscaps))
|
||||
{
|
||||
Con_SafePrintf ("Couldn't get DS caps\n");
|
||||
}
|
||||
|
||||
if (dscaps.dwFlags & DSCAPS_EMULDRIVER)
|
||||
{
|
||||
Con_SafePrintf ("No DirectSound driver installed\n");
|
||||
FreeSound ();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
if (DS_OK != pDS->lpVtbl->SetCooperativeLevel (pDS, mainwindow, DSSCL_EXCLUSIVE))
|
||||
{
|
||||
Con_SafePrintf ("Set coop level failed\n");
|
||||
FreeSound ();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
// get access to the primary buffer, if possible, so we can set the
|
||||
// sound hardware format
|
||||
memset (&dsbuf, 0, sizeof(dsbuf));
|
||||
dsbuf.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
||||
dsbuf.dwBufferBytes = 0;
|
||||
dsbuf.lpwfxFormat = NULL;
|
||||
|
||||
memset(&dsbcaps, 0, sizeof(dsbcaps));
|
||||
dsbcaps.dwSize = sizeof(dsbcaps);
|
||||
primary_format_set = false;
|
||||
|
||||
if (!COM_CheckParm ("-snoforceformat"))
|
||||
{
|
||||
if (DS_OK == pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSPBuf, NULL))
|
||||
{
|
||||
pformat = format;
|
||||
|
||||
if (DS_OK != pDSPBuf->lpVtbl->SetFormat (pDSPBuf, &pformat))
|
||||
{
|
||||
// if (snd_firsttime)
|
||||
// Con_SafePrintf ("Set primary sound buffer format: no\n");
|
||||
}
|
||||
else
|
||||
// {
|
||||
// if (snd_firsttime)
|
||||
// Con_SafePrintf ("Set primary sound buffer format: yes\n");
|
||||
|
||||
primary_format_set = true;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
if (!primary_format_set || !COM_CheckParm ("-primarysound"))
|
||||
{
|
||||
// create the secondary buffer we'll actually work with
|
||||
memset (&dsbuf, 0, sizeof(dsbuf));
|
||||
dsbuf.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE;
|
||||
dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE;
|
||||
dsbuf.lpwfxFormat = &format;
|
||||
|
||||
memset(&dsbcaps, 0, sizeof(dsbcaps));
|
||||
dsbcaps.dwSize = sizeof(dsbcaps);
|
||||
|
||||
if (DS_OK != pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL))
|
||||
{
|
||||
Con_SafePrintf ("DS:CreateSoundBuffer Failed");
|
||||
FreeSound ();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
shm->channels = format.nChannels;
|
||||
shm->samplebits = format.wBitsPerSample;
|
||||
shm->speed = format.nSamplesPerSec;
|
||||
|
||||
if (DS_OK != pDSBuf->lpVtbl->GetCaps (pDSBuf, &dsbcaps))
|
||||
{
|
||||
Con_SafePrintf ("DS:GetCaps failed\n");
|
||||
FreeSound ();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
// if (snd_firsttime)
|
||||
// Con_SafePrintf ("Using secondary sound buffer\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DS_OK != pDS->lpVtbl->SetCooperativeLevel (pDS, mainwindow, DSSCL_WRITEPRIMARY))
|
||||
{
|
||||
Con_SafePrintf ("Set coop level failed\n");
|
||||
FreeSound ();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
if (DS_OK != pDSPBuf->lpVtbl->GetCaps (pDSPBuf, &dsbcaps))
|
||||
{
|
||||
Con_Printf ("DS:GetCaps failed\n");
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
pDSBuf = pDSPBuf;
|
||||
// Con_SafePrintf ("Using primary sound buffer\n");
|
||||
}
|
||||
|
||||
// Make sure mixer is active
|
||||
pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);
|
||||
|
||||
/* if (snd_firsttime)
|
||||
Con_SafePrintf(" %d channel(s)\n"
|
||||
" %d bits/sample\n"
|
||||
" %d bytes/sec\n",
|
||||
shm->channels, shm->samplebits, shm->speed);*/
|
||||
|
||||
gSndBufSize = dsbcaps.dwBufferBytes;
|
||||
|
||||
// initialize the buffer
|
||||
reps = 0;
|
||||
|
||||
while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &lpData, &dwSize, NULL, NULL, 0)) != DS_OK)
|
||||
{
|
||||
if (hresult != DSERR_BUFFERLOST)
|
||||
{
|
||||
Con_SafePrintf ("SNDDMA_InitDirect: DS::Lock Sound Buffer Failed\n");
|
||||
FreeSound ();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
if (++reps > 10000)
|
||||
{
|
||||
Con_SafePrintf ("SNDDMA_InitDirect: DS: couldn't restore buffer\n");
|
||||
FreeSound ();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
memset(lpData, 0, dwSize);
|
||||
// lpData[4] = lpData[5] = 0x7f; // force a pop for debugging
|
||||
|
||||
pDSBuf->lpVtbl->Unlock(pDSBuf, lpData, dwSize, NULL, 0);
|
||||
|
||||
/* we don't want anyone to access the buffer directly w/o locking it first. */
|
||||
lpData = NULL;
|
||||
|
||||
pDSBuf->lpVtbl->Stop(pDSBuf);
|
||||
pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &mmstarttime.u.sample, &dwWrite);
|
||||
pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);
|
||||
|
||||
shm->soundalive = true;
|
||||
shm->splitbuffer = false;
|
||||
shm->samples = gSndBufSize/(shm->samplebits/8);
|
||||
shm->samplepos = 0;
|
||||
shm->submission_chunk = 1;
|
||||
shm->buffer = (unsigned char *) lpData;
|
||||
sample16 = (shm->samplebits/8) - 1;
|
||||
|
||||
dsound_init = true;
|
||||
|
||||
return SIS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
SNDDM_InitWav
|
||||
|
||||
Crappy windows multimedia base
|
||||
==================
|
||||
*/
|
||||
qboolean SNDDMA_InitWav (void)
|
||||
{
|
||||
WAVEFORMATEX format;
|
||||
int i;
|
||||
HRESULT hr;
|
||||
|
||||
snd_sent = 0;
|
||||
snd_completed = 0;
|
||||
|
||||
shm = &sn;
|
||||
|
||||
shm->channels = 2;
|
||||
shm->samplebits = 16;
|
||||
shm->speed = 11025;
|
||||
|
||||
memset (&format, 0, sizeof(format));
|
||||
format.wFormatTag = WAVE_FORMAT_PCM;
|
||||
format.nChannels = shm->channels;
|
||||
format.wBitsPerSample = shm->samplebits;
|
||||
format.nSamplesPerSec = shm->speed;
|
||||
format.nBlockAlign = format.nChannels
|
||||
*format.wBitsPerSample / 8;
|
||||
format.cbSize = 0;
|
||||
format.nAvgBytesPerSec = format.nSamplesPerSec
|
||||
*format.nBlockAlign;
|
||||
|
||||
/* Open a waveform device for output using window callback. */
|
||||
while ((hr = waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER,
|
||||
&format,
|
||||
0, 0L, CALLBACK_NULL)) != MMSYSERR_NOERROR)
|
||||
{
|
||||
if (hr != MMSYSERR_ALLOCATED)
|
||||
{
|
||||
Con_SafePrintf ("waveOutOpen failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MessageBox (NULL,
|
||||
"The sound hardware is in use by another app.\n\n"
|
||||
"Select Retry to try to start sound again or Cancel to run Quake with no sound.",
|
||||
"Sound not available",
|
||||
MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY)
|
||||
{
|
||||
Con_SafePrintf ("waveOutOpen failure;\n"
|
||||
" hardware already in use\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and lock memory for the waveform data. The memory
|
||||
* for waveform data must be globally allocated with
|
||||
* GMEM_MOVEABLE and GMEM_SHARE flags.
|
||||
|
||||
*/
|
||||
gSndBufSize = WAV_BUFFERS*WAV_BUFFER_SIZE;
|
||||
hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, gSndBufSize);
|
||||
if (!hData)
|
||||
{
|
||||
Con_SafePrintf ("Sound: Out of memory.\n");
|
||||
FreeSound ();
|
||||
return false;
|
||||
}
|
||||
lpData = GlobalLock(hData);
|
||||
if (!lpData)
|
||||
{
|
||||
Con_SafePrintf ("Sound: Failed to lock.\n");
|
||||
FreeSound ();
|
||||
return false;
|
||||
}
|
||||
memset (lpData, 0, gSndBufSize);
|
||||
|
||||
/*
|
||||
* Allocate and lock memory for the header. This memory must
|
||||
* also be globally allocated with GMEM_MOVEABLE and
|
||||
* GMEM_SHARE flags.
|
||||
*/
|
||||
hWaveHdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
|
||||
(DWORD) sizeof(WAVEHDR) * WAV_BUFFERS);
|
||||
|
||||
if (hWaveHdr == NULL)
|
||||
{
|
||||
Con_SafePrintf ("Sound: Failed to Alloc header.\n");
|
||||
FreeSound ();
|
||||
return false;
|
||||
}
|
||||
|
||||
lpWaveHdr = (LPWAVEHDR) GlobalLock(hWaveHdr);
|
||||
|
||||
if (lpWaveHdr == NULL)
|
||||
{
|
||||
Con_SafePrintf ("Sound: Failed to lock header.\n");
|
||||
FreeSound ();
|
||||
return false;
|
||||
}
|
||||
|
||||
memset (lpWaveHdr, 0, sizeof(WAVEHDR) * WAV_BUFFERS);
|
||||
|
||||
/* After allocation, set up and prepare headers. */
|
||||
for (i=0 ; i<WAV_BUFFERS ; i++)
|
||||
{
|
||||
lpWaveHdr[i].dwBufferLength = WAV_BUFFER_SIZE;
|
||||
lpWaveHdr[i].lpData = lpData + i*WAV_BUFFER_SIZE;
|
||||
|
||||
if (waveOutPrepareHeader(hWaveOut, lpWaveHdr+i, sizeof(WAVEHDR)) !=
|
||||
MMSYSERR_NOERROR)
|
||||
{
|
||||
Con_SafePrintf ("Sound: failed to prepare wave headers\n");
|
||||
FreeSound ();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
shm->soundalive = true;
|
||||
shm->splitbuffer = false;
|
||||
shm->samples = gSndBufSize/(shm->samplebits/8);
|
||||
shm->samplepos = 0;
|
||||
shm->submission_chunk = 1;
|
||||
shm->buffer = (unsigned char *) lpData;
|
||||
sample16 = (shm->samplebits/8) - 1;
|
||||
|
||||
wav_init = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SNDDMA_Init
|
||||
|
||||
Try to find a sound device to mix for.
|
||||
Returns false if nothing is found.
|
||||
==================
|
||||
*/
|
||||
|
||||
int SNDDMA_Init(void)
|
||||
{
|
||||
sndinitstat stat;
|
||||
|
||||
if (COM_CheckParm ("-wavonly"))
|
||||
wavonly = true;
|
||||
|
||||
dsound_init = wav_init = 0;
|
||||
|
||||
stat = SIS_FAILURE; // assume DirectSound won't initialize
|
||||
|
||||
/* Init DirectSound */
|
||||
if (!wavonly)
|
||||
{
|
||||
if (snd_firsttime || snd_isdirect)
|
||||
{
|
||||
stat = SNDDMA_InitDirect ();;
|
||||
|
||||
if (stat == SIS_SUCCESS)
|
||||
{
|
||||
snd_isdirect = true;
|
||||
|
||||
if (snd_firsttime)
|
||||
Con_SafePrintf ("DirectSound initialized\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
snd_isdirect = false;
|
||||
Con_SafePrintf ("DirectSound failed to init\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if DirectSound didn't succeed in initializing, try to initialize
|
||||
// waveOut sound, unless DirectSound failed because the hardware is
|
||||
// already allocated (in which case the user has already chosen not
|
||||
// to have sound)
|
||||
if (!dsound_init && (stat != SIS_NOTAVAIL))
|
||||
{
|
||||
if (snd_firsttime || snd_iswave)
|
||||
{
|
||||
|
||||
snd_iswave = SNDDMA_InitWav ();
|
||||
|
||||
if (snd_iswave)
|
||||
{
|
||||
if (snd_firsttime)
|
||||
Con_SafePrintf ("Wave sound initialized\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_SafePrintf ("Wave sound failed to init\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snd_firsttime = false;
|
||||
|
||||
if (!dsound_init && !wav_init)
|
||||
{
|
||||
if (snd_firsttime)
|
||||
Con_SafePrintf ("No sound device initialized\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SNDDMA_GetDMAPos
|
||||
|
||||
return the current sample position (in mono samples read)
|
||||
inside the recirculating dma buffer, so the mixing code will know
|
||||
how many sample are required to fill it up.
|
||||
===============
|
||||
*/
|
||||
int SNDDMA_GetDMAPos(void)
|
||||
{
|
||||
MMTIME mmtime;
|
||||
int s;
|
||||
DWORD dwWrite;
|
||||
|
||||
if (dsound_init)
|
||||
{
|
||||
mmtime.wType = TIME_SAMPLES;
|
||||
pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &mmtime.u.sample, &dwWrite);
|
||||
s = mmtime.u.sample - mmstarttime.u.sample;
|
||||
}
|
||||
else if (wav_init)
|
||||
{
|
||||
s = snd_sent * WAV_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
|
||||
s >>= sample16;
|
||||
|
||||
s &= (shm->samples-1);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SNDDMA_Submit
|
||||
|
||||
Send sound to device if buffer isn't really the dma buffer
|
||||
===============
|
||||
*/
|
||||
void SNDDMA_Submit(void)
|
||||
{
|
||||
LPWAVEHDR h;
|
||||
int wResult;
|
||||
|
||||
if (!wav_init)
|
||||
return;
|
||||
|
||||
//
|
||||
// find which sound blocks have completed
|
||||
//
|
||||
while (1)
|
||||
{
|
||||
if ( snd_completed == snd_sent )
|
||||
{
|
||||
Con_DPrintf ("Sound overrun\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! (lpWaveHdr[ snd_completed & WAV_MASK].dwFlags & WHDR_DONE) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
snd_completed++; // this buffer has been played
|
||||
}
|
||||
|
||||
//
|
||||
// submit two new sound blocks
|
||||
//
|
||||
while (((snd_sent - snd_completed) >> sample16) < 4)
|
||||
{
|
||||
h = lpWaveHdr + ( snd_sent&WAV_MASK );
|
||||
|
||||
snd_sent++;
|
||||
/*
|
||||
* Now the data block can be sent to the output device. The
|
||||
* waveOutWrite function returns immediately and waveform
|
||||
* data is sent to the output device in the background.
|
||||
*/
|
||||
wResult = waveOutWrite(hWaveOut, h, sizeof(WAVEHDR));
|
||||
|
||||
if (wResult != MMSYSERR_NOERROR)
|
||||
{
|
||||
Con_SafePrintf ("Failed to write block to device\n");
|
||||
FreeSound ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SNDDMA_Shutdown
|
||||
|
||||
Reset the sound device for exiting
|
||||
===============
|
||||
*/
|
||||
void SNDDMA_Shutdown(void)
|
||||
{
|
||||
FreeSound ();
|
||||
}
|
||||
|
Loading…
Reference in a new issue