mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-10 11:59:58 -05:00
Quack 3
This commit is contained in:
committed by
GitHub
parent
e8bd66b89c
commit
0bf99969fd
1077
ref_soft/adivtab.h
Normal file
1077
ref_soft/adivtab.h
Normal file
File diff suppressed because it is too large
Load Diff
181
ref_soft/anorms.h
Normal file
181
ref_soft/anorms.h
Normal file
@ -0,0 +1,181 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 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.
|
||||
|
||||
*/
|
||||
{-0.525731, 0.000000, 0.850651},
|
||||
{-0.442863, 0.238856, 0.864188},
|
||||
{-0.295242, 0.000000, 0.955423},
|
||||
{-0.309017, 0.500000, 0.809017},
|
||||
{-0.162460, 0.262866, 0.951056},
|
||||
{0.000000, 0.000000, 1.000000},
|
||||
{0.000000, 0.850651, 0.525731},
|
||||
{-0.147621, 0.716567, 0.681718},
|
||||
{0.147621, 0.716567, 0.681718},
|
||||
{0.000000, 0.525731, 0.850651},
|
||||
{0.309017, 0.500000, 0.809017},
|
||||
{0.525731, 0.000000, 0.850651},
|
||||
{0.295242, 0.000000, 0.955423},
|
||||
{0.442863, 0.238856, 0.864188},
|
||||
{0.162460, 0.262866, 0.951056},
|
||||
{-0.681718, 0.147621, 0.716567},
|
||||
{-0.809017, 0.309017, 0.500000},
|
||||
{-0.587785, 0.425325, 0.688191},
|
||||
{-0.850651, 0.525731, 0.000000},
|
||||
{-0.864188, 0.442863, 0.238856},
|
||||
{-0.716567, 0.681718, 0.147621},
|
||||
{-0.688191, 0.587785, 0.425325},
|
||||
{-0.500000, 0.809017, 0.309017},
|
||||
{-0.238856, 0.864188, 0.442863},
|
||||
{-0.425325, 0.688191, 0.587785},
|
||||
{-0.716567, 0.681718, -0.147621},
|
||||
{-0.500000, 0.809017, -0.309017},
|
||||
{-0.525731, 0.850651, 0.000000},
|
||||
{0.000000, 0.850651, -0.525731},
|
||||
{-0.238856, 0.864188, -0.442863},
|
||||
{0.000000, 0.955423, -0.295242},
|
||||
{-0.262866, 0.951056, -0.162460},
|
||||
{0.000000, 1.000000, 0.000000},
|
||||
{0.000000, 0.955423, 0.295242},
|
||||
{-0.262866, 0.951056, 0.162460},
|
||||
{0.238856, 0.864188, 0.442863},
|
||||
{0.262866, 0.951056, 0.162460},
|
||||
{0.500000, 0.809017, 0.309017},
|
||||
{0.238856, 0.864188, -0.442863},
|
||||
{0.262866, 0.951056, -0.162460},
|
||||
{0.500000, 0.809017, -0.309017},
|
||||
{0.850651, 0.525731, 0.000000},
|
||||
{0.716567, 0.681718, 0.147621},
|
||||
{0.716567, 0.681718, -0.147621},
|
||||
{0.525731, 0.850651, 0.000000},
|
||||
{0.425325, 0.688191, 0.587785},
|
||||
{0.864188, 0.442863, 0.238856},
|
||||
{0.688191, 0.587785, 0.425325},
|
||||
{0.809017, 0.309017, 0.500000},
|
||||
{0.681718, 0.147621, 0.716567},
|
||||
{0.587785, 0.425325, 0.688191},
|
||||
{0.955423, 0.295242, 0.000000},
|
||||
{1.000000, 0.000000, 0.000000},
|
||||
{0.951056, 0.162460, 0.262866},
|
||||
{0.850651, -0.525731, 0.000000},
|
||||
{0.955423, -0.295242, 0.000000},
|
||||
{0.864188, -0.442863, 0.238856},
|
||||
{0.951056, -0.162460, 0.262866},
|
||||
{0.809017, -0.309017, 0.500000},
|
||||
{0.681718, -0.147621, 0.716567},
|
||||
{0.850651, 0.000000, 0.525731},
|
||||
{0.864188, 0.442863, -0.238856},
|
||||
{0.809017, 0.309017, -0.500000},
|
||||
{0.951056, 0.162460, -0.262866},
|
||||
{0.525731, 0.000000, -0.850651},
|
||||
{0.681718, 0.147621, -0.716567},
|
||||
{0.681718, -0.147621, -0.716567},
|
||||
{0.850651, 0.000000, -0.525731},
|
||||
{0.809017, -0.309017, -0.500000},
|
||||
{0.864188, -0.442863, -0.238856},
|
||||
{0.951056, -0.162460, -0.262866},
|
||||
{0.147621, 0.716567, -0.681718},
|
||||
{0.309017, 0.500000, -0.809017},
|
||||
{0.425325, 0.688191, -0.587785},
|
||||
{0.442863, 0.238856, -0.864188},
|
||||
{0.587785, 0.425325, -0.688191},
|
||||
{0.688191, 0.587785, -0.425325},
|
||||
{-0.147621, 0.716567, -0.681718},
|
||||
{-0.309017, 0.500000, -0.809017},
|
||||
{0.000000, 0.525731, -0.850651},
|
||||
{-0.525731, 0.000000, -0.850651},
|
||||
{-0.442863, 0.238856, -0.864188},
|
||||
{-0.295242, 0.000000, -0.955423},
|
||||
{-0.162460, 0.262866, -0.951056},
|
||||
{0.000000, 0.000000, -1.000000},
|
||||
{0.295242, 0.000000, -0.955423},
|
||||
{0.162460, 0.262866, -0.951056},
|
||||
{-0.442863, -0.238856, -0.864188},
|
||||
{-0.309017, -0.500000, -0.809017},
|
||||
{-0.162460, -0.262866, -0.951056},
|
||||
{0.000000, -0.850651, -0.525731},
|
||||
{-0.147621, -0.716567, -0.681718},
|
||||
{0.147621, -0.716567, -0.681718},
|
||||
{0.000000, -0.525731, -0.850651},
|
||||
{0.309017, -0.500000, -0.809017},
|
||||
{0.442863, -0.238856, -0.864188},
|
||||
{0.162460, -0.262866, -0.951056},
|
||||
{0.238856, -0.864188, -0.442863},
|
||||
{0.500000, -0.809017, -0.309017},
|
||||
{0.425325, -0.688191, -0.587785},
|
||||
{0.716567, -0.681718, -0.147621},
|
||||
{0.688191, -0.587785, -0.425325},
|
||||
{0.587785, -0.425325, -0.688191},
|
||||
{0.000000, -0.955423, -0.295242},
|
||||
{0.000000, -1.000000, 0.000000},
|
||||
{0.262866, -0.951056, -0.162460},
|
||||
{0.000000, -0.850651, 0.525731},
|
||||
{0.000000, -0.955423, 0.295242},
|
||||
{0.238856, -0.864188, 0.442863},
|
||||
{0.262866, -0.951056, 0.162460},
|
||||
{0.500000, -0.809017, 0.309017},
|
||||
{0.716567, -0.681718, 0.147621},
|
||||
{0.525731, -0.850651, 0.000000},
|
||||
{-0.238856, -0.864188, -0.442863},
|
||||
{-0.500000, -0.809017, -0.309017},
|
||||
{-0.262866, -0.951056, -0.162460},
|
||||
{-0.850651, -0.525731, 0.000000},
|
||||
{-0.716567, -0.681718, -0.147621},
|
||||
{-0.716567, -0.681718, 0.147621},
|
||||
{-0.525731, -0.850651, 0.000000},
|
||||
{-0.500000, -0.809017, 0.309017},
|
||||
{-0.238856, -0.864188, 0.442863},
|
||||
{-0.262866, -0.951056, 0.162460},
|
||||
{-0.864188, -0.442863, 0.238856},
|
||||
{-0.809017, -0.309017, 0.500000},
|
||||
{-0.688191, -0.587785, 0.425325},
|
||||
{-0.681718, -0.147621, 0.716567},
|
||||
{-0.442863, -0.238856, 0.864188},
|
||||
{-0.587785, -0.425325, 0.688191},
|
||||
{-0.309017, -0.500000, 0.809017},
|
||||
{-0.147621, -0.716567, 0.681718},
|
||||
{-0.425325, -0.688191, 0.587785},
|
||||
{-0.162460, -0.262866, 0.951056},
|
||||
{0.442863, -0.238856, 0.864188},
|
||||
{0.162460, -0.262866, 0.951056},
|
||||
{0.309017, -0.500000, 0.809017},
|
||||
{0.147621, -0.716567, 0.681718},
|
||||
{0.000000, -0.525731, 0.850651},
|
||||
{0.425325, -0.688191, 0.587785},
|
||||
{0.587785, -0.425325, 0.688191},
|
||||
{0.688191, -0.587785, 0.425325},
|
||||
{-0.955423, 0.295242, 0.000000},
|
||||
{-0.951056, 0.162460, 0.262866},
|
||||
{-1.000000, 0.000000, 0.000000},
|
||||
{-0.850651, 0.000000, 0.525731},
|
||||
{-0.955423, -0.295242, 0.000000},
|
||||
{-0.951056, -0.162460, 0.262866},
|
||||
{-0.864188, 0.442863, -0.238856},
|
||||
{-0.951056, 0.162460, -0.262866},
|
||||
{-0.809017, 0.309017, -0.500000},
|
||||
{-0.864188, -0.442863, -0.238856},
|
||||
{-0.951056, -0.162460, -0.262866},
|
||||
{-0.809017, -0.309017, -0.500000},
|
||||
{-0.681718, 0.147621, -0.716567},
|
||||
{-0.681718, -0.147621, -0.716567},
|
||||
{-0.850651, 0.000000, -0.525731},
|
||||
{-0.688191, 0.587785, -0.425325},
|
||||
{-0.587785, 0.425325, -0.688191},
|
||||
{-0.425325, 0.688191, -0.587785},
|
||||
{-0.425325, -0.688191, -0.587785},
|
||||
{-0.587785, -0.425325, -0.688191},
|
||||
{-0.688191, -0.587785, -0.425325},
|
121
ref_soft/asm_draw.h
Normal file
121
ref_soft/asm_draw.h
Normal file
@ -0,0 +1,121 @@
|
||||
//
|
||||
// asm_draw.h
|
||||
//
|
||||
// Include file for asm drawing routines.
|
||||
//
|
||||
|
||||
//
|
||||
// !!! note that this file must match the corresponding C structures at all
|
||||
// times !!!
|
||||
//
|
||||
|
||||
// !!! if this is changed, it must be changed in r_local.h too !!!
|
||||
#define NEAR_CLIP 0.01
|
||||
|
||||
// !!! if this is changed, it must be changed in r_local.h too !!!
|
||||
#define CYCLE 128
|
||||
|
||||
// espan_t structure
|
||||
// !!! if this is changed, it must be changed in r_shared.h too !!!
|
||||
#define espan_t_u 0
|
||||
#define espan_t_v 4
|
||||
#define espan_t_count 8
|
||||
#define espan_t_pnext 12
|
||||
#define espan_t_size 16
|
||||
|
||||
// sspan_t structure
|
||||
// !!! if this is changed, it must be changed in d_local.h too !!!
|
||||
#define sspan_t_u 0
|
||||
#define sspan_t_v 4
|
||||
#define sspan_t_count 8
|
||||
#define sspan_t_pnext 12
|
||||
#define sspan_t_size 16
|
||||
|
||||
// edge_t structure
|
||||
// !!! if this is changed, it must be changed in r_shared.h too !!!
|
||||
#define et_u 0
|
||||
#define et_u_step 4
|
||||
#define et_prev 8
|
||||
#define et_next 12
|
||||
#define et_surfs 16
|
||||
#define et_nextremove 20
|
||||
#define et_nearzi 24
|
||||
#define et_owner 28
|
||||
#define et_size 32
|
||||
|
||||
// surf_t structure
|
||||
// !!! if this is changed, it must be changed in r_shared.h too !!!
|
||||
#define SURF_T_SHIFT 6
|
||||
#define st_next 0
|
||||
#define st_prev 4
|
||||
#define st_spans 8
|
||||
#define st_key 12
|
||||
#define st_last_u 16
|
||||
#define st_spanstate 20
|
||||
#define st_flags 24
|
||||
#define st_data 28
|
||||
#define st_entity 32
|
||||
#define st_nearzi 36
|
||||
#define st_insubmodel 40
|
||||
#define st_d_ziorigin 44
|
||||
#define st_d_zistepu 48
|
||||
#define st_d_zistepv 52
|
||||
#define st_pad 56
|
||||
#define st_size 64
|
||||
|
||||
// clipplane_t structure
|
||||
// !!! if this is changed, it must be changed in r_local.h too !!!
|
||||
#define cp_normal 0
|
||||
#define cp_dist 12
|
||||
#define cp_next 16
|
||||
#define cp_leftedge 20
|
||||
#define cp_rightedge 21
|
||||
#define cp_reserved 22
|
||||
#define cp_size 24
|
||||
|
||||
// medge_t structure
|
||||
// !!! if this is changed, it must be changed in model.h too !!!
|
||||
#define me_v 0
|
||||
#define me_cachededgeoffset 4
|
||||
#define me_size 8
|
||||
|
||||
// mvertex_t structure
|
||||
// !!! if this is changed, it must be changed in model.h too !!!
|
||||
#define mv_position 0
|
||||
#define mv_size 12
|
||||
|
||||
// refdef_t structure
|
||||
// !!! if this is changed, it must be changed in render.h too !!!
|
||||
#define rd_vrect 0
|
||||
#define rd_aliasvrect 20
|
||||
#define rd_vrectright 40
|
||||
#define rd_vrectbottom 44
|
||||
#define rd_aliasvrectright 48
|
||||
#define rd_aliasvrectbottom 52
|
||||
#define rd_vrectrightedge 56
|
||||
#define rd_fvrectx 60
|
||||
#define rd_fvrecty 64
|
||||
#define rd_fvrectx_adj 68
|
||||
#define rd_fvrecty_adj 72
|
||||
#define rd_vrect_x_adj_shift20 76
|
||||
#define rd_vrectright_adj_shift20 80
|
||||
#define rd_fvrectright_adj 84
|
||||
#define rd_fvrectbottom_adj 88
|
||||
#define rd_fvrectright 92
|
||||
#define rd_fvrectbottom 96
|
||||
#define rd_horizontalFieldOfView 100
|
||||
#define rd_xOrigin 104
|
||||
#define rd_yOrigin 108
|
||||
#define rd_vieworg 112
|
||||
#define rd_viewangles 124
|
||||
#define rd_ambientlight 136
|
||||
#define rd_size 140
|
||||
|
||||
// mtriangle_t structure
|
||||
// !!! if this is changed, it must be changed in model.h too !!!
|
||||
#define mtri_facesfront 0
|
||||
#define mtri_vertindex 4
|
||||
#define mtri_size 16 // !!! if this changes, array indexing in !!!
|
||||
// !!! d_polysa.s must be changed to match !!!
|
||||
#define mtri_shift 4
|
||||
|
116
ref_soft/block16.inc
Normal file
116
ref_soft/block16.inc
Normal file
@ -0,0 +1,116 @@
|
||||
LEnter16_16:
|
||||
mov al,ds:byte ptr[esi]
|
||||
mov cl,ds:byte ptr[esi+ebx]
|
||||
mov ah,dh
|
||||
add edx,ebp
|
||||
mov ch,dh
|
||||
lea esi,ds:dword ptr[esi+ebx*2]
|
||||
mov ax,ds:word ptr[12345678h+eax*2]
|
||||
LBPatch0:
|
||||
add edx,ebp
|
||||
mov ds:word ptr[edi],ax
|
||||
mov cx,ds:word ptr[12345678h+ecx*2]
|
||||
LBPatch1:
|
||||
mov ds:word ptr[2+edi],cx
|
||||
add edi,04h
|
||||
mov al,ds:byte ptr[esi]
|
||||
mov cl,ds:byte ptr[esi+ebx]
|
||||
mov ah,dh
|
||||
add edx,ebp
|
||||
mov ch,dh
|
||||
lea esi,ds:dword ptr[esi+ebx*2]
|
||||
mov ax,ds:word ptr[12345678h+eax*2]
|
||||
LBPatch2:
|
||||
add edx,ebp
|
||||
mov ds:word ptr[edi],ax
|
||||
mov cx,ds:word ptr[12345678h+ecx*2]
|
||||
LBPatch3:
|
||||
mov ds:word ptr[2+edi],cx
|
||||
add edi,04h
|
||||
mov al,ds:byte ptr[esi]
|
||||
mov cl,ds:byte ptr[esi+ebx]
|
||||
mov ah,dh
|
||||
add edx,ebp
|
||||
mov ch,dh
|
||||
lea esi,ds:dword ptr[esi+ebx*2]
|
||||
mov ax,ds:word ptr[12345678h+eax*2]
|
||||
LBPatch4:
|
||||
add edx,ebp
|
||||
mov ds:word ptr[edi],ax
|
||||
mov cx,ds:word ptr[12345678h+ecx*2]
|
||||
LBPatch5:
|
||||
mov ds:word ptr[2+edi],cx
|
||||
add edi,04h
|
||||
mov al,ds:byte ptr[esi]
|
||||
mov cl,ds:byte ptr[esi+ebx]
|
||||
mov ah,dh
|
||||
add edx,ebp
|
||||
mov ch,dh
|
||||
lea esi,ds:dword ptr[esi+ebx*2]
|
||||
mov ax,ds:word ptr[12345678h+eax*2]
|
||||
LBPatch6:
|
||||
add edx,ebp
|
||||
mov ds:word ptr[edi],ax
|
||||
mov cx,ds:word ptr[12345678h+ecx*2]
|
||||
LBPatch7:
|
||||
mov ds:word ptr[2+edi],cx
|
||||
add edi,04h
|
||||
LEnter8_16:
|
||||
mov al,ds:byte ptr[esi]
|
||||
mov cl,ds:byte ptr[esi+ebx]
|
||||
mov ah,dh
|
||||
add edx,ebp
|
||||
mov ch,dh
|
||||
lea esi,ds:dword ptr[esi+ebx*2]
|
||||
mov ax,ds:word ptr[12345678h+eax*2]
|
||||
LBPatch8:
|
||||
add edx,ebp
|
||||
mov ds:word ptr[edi],ax
|
||||
mov cx,ds:word ptr[12345678h+ecx*2]
|
||||
LBPatch9:
|
||||
mov ds:word ptr[2+edi],cx
|
||||
add edi,04h
|
||||
mov al,ds:byte ptr[esi]
|
||||
mov cl,ds:byte ptr[esi+ebx]
|
||||
mov ah,dh
|
||||
add edx,ebp
|
||||
mov ch,dh
|
||||
lea esi,ds:dword ptr[esi+ebx*2]
|
||||
mov ax,ds:word ptr[12345678h+eax*2]
|
||||
LBPatch10:
|
||||
add edx,ebp
|
||||
mov ds:word ptr[edi],ax
|
||||
mov cx,ds:word ptr[12345678h+ecx*2]
|
||||
LBPatch11:
|
||||
mov ds:word ptr[2+edi],cx
|
||||
add edi,04h
|
||||
LEnter4_16:
|
||||
mov al,ds:byte ptr[esi]
|
||||
mov cl,ds:byte ptr[esi+ebx]
|
||||
mov ah,dh
|
||||
add edx,ebp
|
||||
mov ch,dh
|
||||
lea esi,ds:dword ptr[esi+ebx*2]
|
||||
mov ax,ds:word ptr[12345678h+eax*2]
|
||||
LBPatch12:
|
||||
add edx,ebp
|
||||
mov ds:word ptr[edi],ax
|
||||
mov cx,ds:word ptr[12345678h+ecx*2]
|
||||
LBPatch13:
|
||||
mov ds:word ptr[2+edi],cx
|
||||
add edi,04h
|
||||
LEnter2_16:
|
||||
mov al,ds:byte ptr[esi]
|
||||
mov cl,ds:byte ptr[esi+ebx]
|
||||
mov ah,dh
|
||||
add edx,ebp
|
||||
mov ch,dh
|
||||
lea esi,ds:dword ptr[esi+ebx*2]
|
||||
mov ax,ds:word ptr[12345678h+eax*2]
|
||||
LBPatch14:
|
||||
add edx,ebp
|
||||
mov ds:word ptr[edi],ax
|
||||
mov cx,ds:word ptr[12345678h+ecx*2]
|
||||
LBPatch15:
|
||||
mov ds:word ptr[2+edi],cx
|
||||
add edi,04h
|
116
ref_soft/block8.inc
Normal file
116
ref_soft/block8.inc
Normal file
@ -0,0 +1,116 @@
|
||||
LEnter16_16:
|
||||
mov al,ds:byte ptr[esi]
|
||||
mov cl,ds:byte ptr[esi+ebx]
|
||||
mov ah,dh
|
||||
add edx,ebp
|
||||
mov ch,dh
|
||||
lea esi,ds:dword ptr[esi+ebx*2]
|
||||
mov ax,ds:word ptr[12345678h+eax*2]
|
||||
LBPatch0:
|
||||
add edx,ebp
|
||||
mov ds:word ptr[edi],ax
|
||||
mov cx,ds:word ptr[12345678h+ecx*2]
|
||||
LBPatch1:
|
||||
mov ds:word ptr[2+edi],cx
|
||||
add edi,04h
|
||||
mov al,ds:byte ptr[esi]
|
||||
mov cl,ds:byte ptr[esi+ebx]
|
||||
mov ah,dh
|
||||
add edx,ebp
|
||||
mov ch,dh
|
||||
lea esi,ds:dword ptr[esi+ebx*2]
|
||||
mov ax,ds:word ptr[12345678h+eax*2]
|
||||
LBPatch2:
|
||||
add edx,ebp
|
||||
mov ds:word ptr[edi],ax
|
||||
mov cx,ds:word ptr[12345678h+ecx*2]
|
||||
LBPatch3:
|
||||
mov ds:word ptr[2+edi],cx
|
||||
add edi,04h
|
||||
mov al,ds:byte ptr[esi]
|
||||
mov cl,ds:byte ptr[esi+ebx]
|
||||
mov ah,dh
|
||||
add edx,ebp
|
||||
mov ch,dh
|
||||
lea esi,ds:dword ptr[esi+ebx*2]
|
||||
mov ax,ds:word ptr[12345678h+eax*2]
|
||||
LBPatch4:
|
||||
add edx,ebp
|
||||
mov ds:word ptr[edi],ax
|
||||
mov cx,ds:word ptr[12345678h+ecx*2]
|
||||
LBPatch5:
|
||||
mov ds:word ptr[2+edi],cx
|
||||
add edi,04h
|
||||
mov al,ds:byte ptr[esi]
|
||||
mov cl,ds:byte ptr[esi+ebx]
|
||||
mov ah,dh
|
||||
add edx,ebp
|
||||
mov ch,dh
|
||||
lea esi,ds:dword ptr[esi+ebx*2]
|
||||
mov ax,ds:word ptr[12345678h+eax*2]
|
||||
LBPatch6:
|
||||
add edx,ebp
|
||||
mov ds:word ptr[edi],ax
|
||||
mov cx,ds:word ptr[12345678h+ecx*2]
|
||||
LBPatch7:
|
||||
mov ds:word ptr[2+edi],cx
|
||||
add edi,04h
|
||||
LEnter8_16:
|
||||
mov al,ds:byte ptr[esi]
|
||||
mov cl,ds:byte ptr[esi+ebx]
|
||||
mov ah,dh
|
||||
add edx,ebp
|
||||
mov ch,dh
|
||||
lea esi,ds:dword ptr[esi+ebx*2]
|
||||
mov ax,ds:word ptr[12345678h+eax*2]
|
||||
LBPatch8:
|
||||
add edx,ebp
|
||||
mov ds:word ptr[edi],ax
|
||||
mov cx,ds:word ptr[12345678h+ecx*2]
|
||||
LBPatch9:
|
||||
mov ds:word ptr[2+edi],cx
|
||||
add edi,04h
|
||||
mov al,ds:byte ptr[esi]
|
||||
mov cl,ds:byte ptr[esi+ebx]
|
||||
mov ah,dh
|
||||
add edx,ebp
|
||||
mov ch,dh
|
||||
lea esi,ds:dword ptr[esi+ebx*2]
|
||||
mov ax,ds:word ptr[12345678h+eax*2]
|
||||
LBPatch10:
|
||||
add edx,ebp
|
||||
mov ds:word ptr[edi],ax
|
||||
mov cx,ds:word ptr[12345678h+ecx*2]
|
||||
LBPatch11:
|
||||
mov ds:word ptr[2+edi],cx
|
||||
add edi,04h
|
||||
LEnter4_16:
|
||||
mov al,ds:byte ptr[esi]
|
||||
mov cl,ds:byte ptr[esi+ebx]
|
||||
mov ah,dh
|
||||
add edx,ebp
|
||||
mov ch,dh
|
||||
lea esi,ds:dword ptr[esi+ebx*2]
|
||||
mov ax,ds:word ptr[12345678h+eax*2]
|
||||
LBPatch12:
|
||||
add edx,ebp
|
||||
mov ds:word ptr[edi],ax
|
||||
mov cx,ds:word ptr[12345678h+ecx*2]
|
||||
LBPatch13:
|
||||
mov ds:word ptr[2+edi],cx
|
||||
add edi,04h
|
||||
LEnter2_16:
|
||||
mov al,ds:byte ptr[esi]
|
||||
mov cl,ds:byte ptr[esi+ebx]
|
||||
mov ah,dh
|
||||
add edx,ebp
|
||||
mov ch,dh
|
||||
lea esi,ds:dword ptr[esi+ebx*2]
|
||||
mov ax,ds:word ptr[12345678h+eax*2]
|
||||
LBPatch14:
|
||||
add edx,ebp
|
||||
mov ds:word ptr[edi],ax
|
||||
mov cx,ds:word ptr[12345678h+ecx*2]
|
||||
LBPatch15:
|
||||
mov ds:word ptr[2+edi],cx
|
||||
add edi,04h
|
81
ref_soft/d_if.inc
Normal file
81
ref_soft/d_if.inc
Normal file
@ -0,0 +1,81 @@
|
||||
;
|
||||
; d_ifacea.h
|
||||
;
|
||||
; Include file for asm driver interface.
|
||||
;
|
||||
|
||||
;
|
||||
; !!! note that this file must match the corresponding C structures in
|
||||
; d_iface.h at all times !!!
|
||||
;
|
||||
|
||||
; !!! if this is changed, it must be changed in r_shared.h too !!!
|
||||
ALIAS_ONSEAM equ 00020h
|
||||
|
||||
; !!! if this is changed, it must be changed in d_iface.h too !!!
|
||||
TURB_TEX_SIZE equ 64
|
||||
|
||||
; !!! if this is changed, it must be changed in d_iface.h too !!!
|
||||
CYCLE equ 128
|
||||
|
||||
; !!! if this is changed, it must be changed in r_shared.h too !!!
|
||||
MAXHEIGHT equ 1024
|
||||
|
||||
; !!! if this is changed, it must be changed in quakedef.h too !!!
|
||||
CACHE_SIZE equ 32
|
||||
|
||||
; particle_t structure
|
||||
; !!! if this is changed, it must be changed in d_iface.h too !!!
|
||||
; driver-usable fields
|
||||
pt_org equ 0
|
||||
pt_color equ 12
|
||||
; drivers never touch the following fields
|
||||
pt_next equ 16
|
||||
pt_vel equ 20
|
||||
pt_ramp equ 32
|
||||
pt_die equ 36
|
||||
pt_type equ 40
|
||||
pt_size equ 44
|
||||
|
||||
PARTICLE_Z_CLIP equ 8.0
|
||||
|
||||
; finalvert_t structure
|
||||
; !!! if this is changed, it must be changed in d_iface.h too !!!
|
||||
fv_v equ 0 ; !!! if this is moved, cases where the !!!
|
||||
; !!! address of this field is pushed in !!!
|
||||
; !!! d_polysa.s must be changed !!!
|
||||
fv_flags equ 24
|
||||
fv_reserved equ 28
|
||||
fv_size equ 32
|
||||
fv_shift equ 5
|
||||
|
||||
|
||||
; stvert_t structure
|
||||
; !!! if this is changed, it must be changed in modelgen.h too !!!
|
||||
stv_onseam equ 0
|
||||
stv_s equ 4
|
||||
stv_t equ 8
|
||||
stv_size equ 12
|
||||
|
||||
|
||||
; trivertx_t structure
|
||||
; !!! if this is changed, it must be changed in modelgen.h too !!!
|
||||
tv_v equ 0
|
||||
tv_lightnormalindex equ 3
|
||||
tv_size equ 4
|
||||
|
||||
; affinetridesc_t structure
|
||||
; !!! if this is changed, it must be changed in d_iface.h too !!!
|
||||
atd_pskin equ 0
|
||||
atd_pskindesc equ 4
|
||||
atd_skinwidth equ 8
|
||||
atd_skinheight equ 12
|
||||
atd_ptriangles equ 16
|
||||
atd_pfinalverts equ 20
|
||||
atd_numtriangles equ 24
|
||||
atd_drawtype equ 28
|
||||
atd_seamfixupX16 equ 32
|
||||
atd_do_vis_thresh equ 36
|
||||
atd_vis_thresh equ 40
|
||||
atd_size equ 44
|
||||
|
76
ref_soft/d_ifacea.h
Normal file
76
ref_soft/d_ifacea.h
Normal file
@ -0,0 +1,76 @@
|
||||
//
|
||||
// d_ifacea.h
|
||||
//
|
||||
// Include file for asm driver interface.
|
||||
//
|
||||
|
||||
//
|
||||
// !!! note that this file must match the corresponding C structures in
|
||||
// d_iface.h at all times !!!
|
||||
//
|
||||
|
||||
// !!! if this is changed, it must be changed in d_iface.h too !!!
|
||||
#define TURB_TEX_SIZE 64 // base turbulent texture size
|
||||
|
||||
// !!! if this is changed, it must be changed in d_iface.h too !!!
|
||||
#define CYCLE 128
|
||||
|
||||
// !!! if this is changed, it must be changed in r_shared.h too !!!
|
||||
#define MAXHEIGHT 1200
|
||||
|
||||
// !!! if this is changed, it must be changed in qcommon.h too !!!
|
||||
#define CACHE_SIZE 32 // used to align key data structures
|
||||
|
||||
// particle_t structure
|
||||
// !!! if this is changed, it must be changed in d_iface.h too !!!
|
||||
// driver-usable fields
|
||||
#define pt_org 0
|
||||
#define pt_color 12
|
||||
// drivers never touch the following fields
|
||||
#define pt_next 16
|
||||
#define pt_vel 20
|
||||
#define pt_ramp 32
|
||||
#define pt_die 36
|
||||
#define pt_type 40
|
||||
#define pt_size 44
|
||||
|
||||
#define PARTICLE_Z_CLIP 8.0
|
||||
|
||||
// finalvert_t structure
|
||||
// !!! if this is changed, it must be changed in d_iface.h too !!!
|
||||
#define fv_v 0 // !!! if this is moved, cases where the !!!
|
||||
// !!! address of this field is pushed in !!!
|
||||
// !!! d_polysa.s must be changed !!!
|
||||
#define fv_flags 24
|
||||
#define fv_reserved 28
|
||||
#define fv_size 32
|
||||
#define fv_shift 5
|
||||
|
||||
|
||||
// stvert_t structure
|
||||
// !!! if this is changed, it must be changed in modelgen.h too !!!
|
||||
#define stv_onseam 0
|
||||
#define stv_s 4
|
||||
#define stv_t 8
|
||||
#define stv_size 12
|
||||
|
||||
|
||||
// trivertx_t structure
|
||||
// !!! if this is changed, it must be changed in modelgen.h too !!!
|
||||
#define tv_v 0
|
||||
#define tv_lightnormalindex 3
|
||||
#define tv_size 4
|
||||
|
||||
// affinetridesc_t structure
|
||||
// !!! if this is changed, it must be changed in d_iface.h too !!!
|
||||
#define atd_pskin 0
|
||||
#define atd_pskindesc 4
|
||||
#define atd_skinwidth 8
|
||||
#define atd_skinheight 12
|
||||
#define atd_ptriangles 16
|
||||
#define atd_pfinalverts 20
|
||||
#define atd_numtriangles 24
|
||||
#define atd_drawtype 28
|
||||
#define atd_seamfixupX16 32
|
||||
#define atd_size 36
|
||||
|
435
ref_soft/qasm.inc
Normal file
435
ref_soft/qasm.inc
Normal file
@ -0,0 +1,435 @@
|
||||
;
|
||||
; qasm.inc
|
||||
;
|
||||
; Include file for asm routines.
|
||||
;
|
||||
|
||||
;
|
||||
; !!! note that this file must match the corresponding C structures at all
|
||||
; times !!!
|
||||
;
|
||||
|
||||
; set to 0 to skip all asm code
|
||||
id386 equ 1
|
||||
|
||||
; !!! must be kept the same as in d_iface.h !!!
|
||||
TRANSPARENT_COLOR equ 255
|
||||
|
||||
ifndef GLQUAKE
|
||||
externdef _d_zistepu:dword
|
||||
externdef _d_pzbuffer:dword
|
||||
externdef _d_zistepv:dword
|
||||
externdef _d_zrowbytes:dword
|
||||
externdef _d_ziorigin:dword
|
||||
externdef _r_turb_s:dword
|
||||
externdef _r_turb_t:dword
|
||||
externdef _r_turb_pdest:dword
|
||||
externdef _r_turb_spancount:dword
|
||||
externdef _r_turb_turb:dword
|
||||
externdef _r_turb_pbase:dword
|
||||
externdef _r_turb_sstep:dword
|
||||
externdef _r_turb_tstep:dword
|
||||
externdef _r_bmodelactive:dword
|
||||
externdef _d_sdivzstepu:dword
|
||||
externdef _d_tdivzstepu:dword
|
||||
externdef _d_sdivzstepv:dword
|
||||
externdef _d_tdivzstepv:dword
|
||||
externdef _d_sdivzorigin:dword
|
||||
externdef _d_tdivzorigin:dword
|
||||
externdef _sadjust:dword
|
||||
externdef _tadjust:dword
|
||||
externdef _bbextents:dword
|
||||
externdef _bbextentt:dword
|
||||
externdef _cacheblock:dword
|
||||
externdef _d_viewbuffer:dword
|
||||
externdef _cachewidth:dword
|
||||
externdef _d_pzbuffer:dword
|
||||
externdef _d_zrowbytes:dword
|
||||
externdef _d_zwidth:dword
|
||||
externdef _d_scantable:dword
|
||||
externdef _r_lightptr:dword
|
||||
externdef _r_numvblocks:dword
|
||||
externdef _prowdestbase:dword
|
||||
externdef _pbasesource:dword
|
||||
externdef _r_lightwidth:dword
|
||||
externdef _lightright:dword
|
||||
externdef _lightrightstep:dword
|
||||
externdef _lightdeltastep:dword
|
||||
externdef _lightdelta:dword
|
||||
externdef _lightright:dword
|
||||
externdef _lightdelta:dword
|
||||
externdef _sourcetstep:dword
|
||||
externdef _surfrowbytes:dword
|
||||
externdef _lightrightstep:dword
|
||||
externdef _lightdeltastep:dword
|
||||
externdef _r_sourcemax:dword
|
||||
externdef _r_stepback:dword
|
||||
externdef _colormap:dword
|
||||
externdef _blocksize:dword
|
||||
externdef _sourcesstep:dword
|
||||
externdef _lightleft:dword
|
||||
externdef _blockdivshift:dword
|
||||
externdef _blockdivmask:dword
|
||||
externdef _lightleftstep:dword
|
||||
externdef _r_origin:dword
|
||||
externdef _r_ppn:dword
|
||||
externdef _r_pup:dword
|
||||
externdef _r_pright:dword
|
||||
externdef _ycenter:dword
|
||||
externdef _xcenter:dword
|
||||
externdef _d_vrectbottom_particle:dword
|
||||
externdef _d_vrectright_particle:dword
|
||||
externdef _d_vrecty:dword
|
||||
externdef _d_vrectx:dword
|
||||
externdef _d_pix_shift:dword
|
||||
externdef _d_pix_min:dword
|
||||
externdef _d_pix_max:dword
|
||||
externdef _d_y_aspect_shift:dword
|
||||
externdef _screenwidth:dword
|
||||
externdef _r_leftclipped:dword
|
||||
externdef _r_leftenter:dword
|
||||
externdef _r_rightclipped:dword
|
||||
externdef _r_rightenter:dword
|
||||
externdef _modelorg:dword
|
||||
externdef _xscale:dword
|
||||
externdef _r_refdef:dword
|
||||
externdef _yscale:dword
|
||||
externdef _r_leftexit:dword
|
||||
externdef _r_rightexit:dword
|
||||
externdef _r_lastvertvalid:dword
|
||||
externdef _cacheoffset:dword
|
||||
externdef _newedges:dword
|
||||
externdef _removeedges:dword
|
||||
externdef _r_pedge:dword
|
||||
externdef _r_framecount:dword
|
||||
externdef _r_u1:dword
|
||||
externdef _r_emitted:dword
|
||||
externdef _edge_p:dword
|
||||
externdef _surface_p:dword
|
||||
externdef _surfaces:dword
|
||||
externdef _r_lzi1:dword
|
||||
externdef _r_v1:dword
|
||||
externdef _r_ceilv1:dword
|
||||
externdef _r_nearzi:dword
|
||||
externdef _r_nearzionly:dword
|
||||
externdef _edge_aftertail:dword
|
||||
externdef _edge_tail:dword
|
||||
externdef _current_iv:dword
|
||||
externdef _edge_head_u_shift20:dword
|
||||
externdef _span_p:dword
|
||||
externdef _edge_head:dword
|
||||
externdef _fv:dword
|
||||
externdef _edge_tail_u_shift20:dword
|
||||
externdef _r_apverts:dword
|
||||
externdef _r_anumverts:dword
|
||||
externdef _aliastransform:dword
|
||||
externdef _r_avertexnormals:dword
|
||||
externdef _r_plightvec:dword
|
||||
externdef _r_ambientlight:dword
|
||||
externdef _r_shadelight:dword
|
||||
externdef _aliasxcenter:dword
|
||||
externdef _aliasycenter:dword
|
||||
externdef _a_sstepxfrac:dword
|
||||
externdef _r_affinetridesc:dword
|
||||
externdef _acolormap:dword
|
||||
externdef _d_pcolormap:dword
|
||||
externdef _r_affinetridesc:dword
|
||||
externdef _d_sfrac:dword
|
||||
externdef _d_ptex:dword
|
||||
externdef _d_pedgespanpackage:dword
|
||||
externdef _d_tfrac:dword
|
||||
externdef _d_light:dword
|
||||
externdef _d_zi:dword
|
||||
externdef _d_pdest:dword
|
||||
externdef _d_pz:dword
|
||||
externdef _d_aspancount:dword
|
||||
externdef _erroradjustup:dword
|
||||
externdef _errorterm:dword
|
||||
externdef _d_xdenom:dword
|
||||
externdef _r_p0:dword
|
||||
externdef _r_p1:dword
|
||||
externdef _r_p2:dword
|
||||
externdef _a_tstepxfrac:dword
|
||||
externdef _r_sstepx:dword
|
||||
externdef _r_tstepx:dword
|
||||
externdef _a_ststepxwhole:dword
|
||||
externdef _zspantable:dword
|
||||
externdef _skintable:dword
|
||||
externdef _r_zistepx:dword
|
||||
externdef _erroradjustdown:dword
|
||||
externdef _d_countextrastep:dword
|
||||
externdef _ubasestep:dword
|
||||
externdef _a_ststepxwhole:dword
|
||||
externdef _a_tstepxfrac:dword
|
||||
externdef _r_lstepx:dword
|
||||
externdef _a_spans:dword
|
||||
externdef _erroradjustdown:dword
|
||||
externdef _d_pdestextrastep:dword
|
||||
externdef _d_pzextrastep:dword
|
||||
externdef _d_sfracextrastep:dword
|
||||
externdef _d_ptexextrastep:dword
|
||||
externdef _d_countextrastep:dword
|
||||
externdef _d_tfracextrastep:dword
|
||||
externdef _d_lightextrastep:dword
|
||||
externdef _d_ziextrastep:dword
|
||||
externdef _d_pdestbasestep:dword
|
||||
externdef _d_pzbasestep:dword
|
||||
externdef _d_sfracbasestep:dword
|
||||
externdef _d_ptexbasestep:dword
|
||||
externdef _ubasestep:dword
|
||||
externdef _d_tfracbasestep:dword
|
||||
externdef _d_lightbasestep:dword
|
||||
externdef _d_zibasestep:dword
|
||||
externdef _zspantable:dword
|
||||
externdef _r_lstepy:dword
|
||||
externdef _r_sstepy:dword
|
||||
externdef _r_tstepy:dword
|
||||
externdef _r_zistepy:dword
|
||||
externdef _D_PolysetSetEdgeTable:dword
|
||||
externdef _D_RasterizeAliasPolySmooth:dword
|
||||
|
||||
externdef float_point5:dword
|
||||
externdef Float2ToThe31nd:dword
|
||||
externdef izistep:dword
|
||||
externdef izi:dword
|
||||
externdef FloatMinus2ToThe31nd:dword
|
||||
externdef float_1:dword
|
||||
externdef float_particle_z_clip:dword
|
||||
externdef float_minus_1:dword
|
||||
externdef float_0:dword
|
||||
externdef fp_16:dword
|
||||
externdef fp_64k:dword
|
||||
externdef fp_1m:dword
|
||||
externdef fp_1m_minus_1:dword
|
||||
externdef fp_8 :dword
|
||||
externdef entryvec_table:dword
|
||||
externdef advancetable:dword
|
||||
externdef sstep:dword
|
||||
externdef tstep:dword
|
||||
externdef pspantemp:dword
|
||||
externdef counttemp:dword
|
||||
externdef jumptemp:dword
|
||||
externdef reciprocal_table:dword
|
||||
externdef DP_Count:dword
|
||||
externdef DP_u:dword
|
||||
externdef DP_v:dword
|
||||
externdef DP_32768:dword
|
||||
externdef DP_Color:dword
|
||||
externdef DP_Pix:dword
|
||||
externdef DP_EntryTable:dword
|
||||
externdef pbase:dword
|
||||
externdef s:dword
|
||||
externdef t:dword
|
||||
externdef sfracf:dword
|
||||
externdef tfracf:dword
|
||||
externdef snext:dword
|
||||
externdef tnext:dword
|
||||
externdef spancountminus1:dword
|
||||
externdef zi16stepu:dword
|
||||
externdef sdivz16stepu:dword
|
||||
externdef tdivz16stepu:dword
|
||||
externdef zi8stepu:dword
|
||||
externdef sdivz8stepu:dword
|
||||
externdef tdivz8stepu:dword
|
||||
externdef reciprocal_table_16:dword
|
||||
externdef entryvec_table_16:dword
|
||||
externdef fp_64kx64k:dword
|
||||
externdef pz:dword
|
||||
externdef spr8entryvec_table:dword
|
||||
endif
|
||||
|
||||
externdef _fpu_ceil_cw:dword
|
||||
externdef _fpu_chop_cw:dword
|
||||
externdef _snd_scaletable:dword
|
||||
externdef _paintbuffer:dword
|
||||
externdef _snd_linear_count:dword
|
||||
externdef _snd_p:dword
|
||||
externdef _snd_vol:dword
|
||||
externdef _snd_out:dword
|
||||
externdef _vright:dword
|
||||
externdef _vup:dword
|
||||
externdef _vpn:dword
|
||||
externdef _BOPS_Error:dword
|
||||
|
||||
; plane_t structure
|
||||
; !!! if this is changed, it must be changed in model.h too !!!
|
||||
; !!! if the size of this is changed, the array lookup in SV_HullPointContents
|
||||
; must be changed too !!!
|
||||
pl_normal equ 0
|
||||
pl_dist equ 12
|
||||
pl_type equ 16
|
||||
pl_signbits equ 17
|
||||
pl_pad equ 18
|
||||
pl_size equ 20
|
||||
|
||||
; hull_t structure
|
||||
; !!! if this is changed, it must be changed in model.h too !!!
|
||||
hu_clipnodes equ 0
|
||||
hu_planes equ 4
|
||||
hu_firstclipnode equ 8
|
||||
hu_lastclipnode equ 12
|
||||
hu_clip_mins equ 16
|
||||
hu_clip_maxs equ 28
|
||||
hu_size equ 40
|
||||
|
||||
; dnode_t structure
|
||||
; !!! if this is changed, it must be changed in bspfile.h too !!!
|
||||
nd_planenum equ 0
|
||||
nd_children equ 4
|
||||
nd_mins equ 8
|
||||
nd_maxs equ 20
|
||||
nd_firstface equ 32
|
||||
nd_numfaces equ 36
|
||||
nd_size equ 40
|
||||
|
||||
; sfxcache_t structure
|
||||
; !!! if this is changed, it much be changed in sound.h too !!!
|
||||
sfxc_length equ 0
|
||||
sfxc_loopstart equ 4
|
||||
sfxc_speed equ 8
|
||||
sfxc_width equ 12
|
||||
sfxc_stereo equ 16
|
||||
sfxc_data equ 20
|
||||
|
||||
; channel_t structure
|
||||
; !!! if this is changed, it much be changed in sound.h too !!!
|
||||
ch_sfx equ 0
|
||||
ch_leftvol equ 4
|
||||
ch_rightvol equ 8
|
||||
ch_end equ 12
|
||||
ch_pos equ 16
|
||||
ch_looping equ 20
|
||||
ch_entnum equ 24
|
||||
ch_entchannel equ 28
|
||||
ch_origin equ 32
|
||||
ch_dist_mult equ 44
|
||||
ch_master_vol equ 48
|
||||
ch_size equ 52
|
||||
|
||||
; portable_samplepair_t structure
|
||||
; !!! if this is changed, it much be changed in sound.h too !!!
|
||||
psp_left equ 0
|
||||
psp_right equ 4
|
||||
psp_size equ 8
|
||||
|
||||
; !!! if this is changed, it must be changed in r_local.h too !!!
|
||||
NEAR_CLIP equ 0.01
|
||||
|
||||
; !!! if this is changed, it must be changed in r_local.h too !!!
|
||||
CYCLE equ 128
|
||||
|
||||
; espan_t structure
|
||||
; !!! if this is changed, it must be changed in r_shared.h too !!!
|
||||
espan_t_u equ 0
|
||||
espan_t_v equ 4
|
||||
espan_t_count equ 8
|
||||
espan_t_pnext equ 12
|
||||
espan_t_size equ 16
|
||||
|
||||
; sspan_t structure
|
||||
; !!! if this is changed, it must be changed in d_local.h too !!!
|
||||
sspan_t_u equ 0
|
||||
sspan_t_v equ 4
|
||||
sspan_t_count equ 8
|
||||
sspan_t_size equ 12
|
||||
|
||||
; spanpackage_t structure
|
||||
; !!! if this is changed, it must be changed in d_polyset.c too !!!
|
||||
spanpackage_t_pdest equ 0
|
||||
spanpackage_t_pz equ 4
|
||||
spanpackage_t_count equ 8
|
||||
spanpackage_t_ptex equ 12
|
||||
spanpackage_t_sfrac equ 16
|
||||
spanpackage_t_tfrac equ 20
|
||||
spanpackage_t_light equ 24
|
||||
spanpackage_t_zi equ 28
|
||||
spanpackage_t_size equ 32
|
||||
|
||||
; edge_t structure
|
||||
; !!! if this is changed, it must be changed in r_shared.h too !!!
|
||||
et_u equ 0
|
||||
et_u_step equ 4
|
||||
et_prev equ 8
|
||||
et_next equ 12
|
||||
et_surfs equ 16
|
||||
et_nextremove equ 20
|
||||
et_nearzi equ 24
|
||||
et_owner equ 28
|
||||
et_size equ 32
|
||||
|
||||
; surf_t structure
|
||||
; !!! if this is changed, it must be changed in r_shared.h too !!!
|
||||
SURF_T_SHIFT equ 6
|
||||
st_next equ 0
|
||||
st_prev equ 4
|
||||
st_spans equ 8
|
||||
st_key equ 12
|
||||
st_last_u equ 16
|
||||
st_spanstate equ 20
|
||||
st_flags equ 24
|
||||
st_data equ 28
|
||||
st_entity equ 32
|
||||
st_nearzi equ 36
|
||||
st_insubmodel equ 40
|
||||
st_d_ziorigin equ 44
|
||||
st_d_zistepu equ 48
|
||||
st_d_zistepv equ 52
|
||||
st_pad equ 56
|
||||
st_size equ 64
|
||||
|
||||
; clipplane_t structure
|
||||
; !!! if this is changed, it must be changed in r_local.h too !!!
|
||||
cp_normal equ 0
|
||||
cp_dist equ 12
|
||||
cp_next equ 16
|
||||
cp_leftedge equ 20
|
||||
cp_rightedge equ 21
|
||||
cp_reserved equ 22
|
||||
cp_size equ 24
|
||||
|
||||
; medge_t structure
|
||||
; !!! if this is changed, it must be changed in model.h too !!!
|
||||
me_v equ 0
|
||||
me_cachededgeoffset equ 4
|
||||
me_size equ 8
|
||||
|
||||
; mvertex_t structure
|
||||
; !!! if this is changed, it must be changed in model.h too !!!
|
||||
mv_position equ 0
|
||||
mv_size equ 12
|
||||
|
||||
; refdef_t structure
|
||||
; !!! if this is changed, it must be changed in render.h too !!!
|
||||
rd_vrect equ 0
|
||||
rd_aliasvrect equ 20
|
||||
rd_vrectright equ 40
|
||||
rd_vrectbottom equ 44
|
||||
rd_aliasvrectright equ 48
|
||||
rd_aliasvrectbottom equ 52
|
||||
rd_vrectrightedge equ 56
|
||||
rd_fvrectx equ 60
|
||||
rd_fvrecty equ 64
|
||||
rd_fvrectx_adj equ 68
|
||||
rd_fvrecty_adj equ 72
|
||||
rd_vrect_x_adj_shift20 equ 76
|
||||
rd_vrectright_adj_shift20 equ 80
|
||||
rd_fvrectright_adj equ 84
|
||||
rd_fvrectbottom_adj equ 88
|
||||
rd_fvrectright equ 92
|
||||
rd_fvrectbottom equ 96
|
||||
rd_horizontalFieldOfView equ 100
|
||||
rd_xOrigin equ 104
|
||||
rd_yOrigin equ 108
|
||||
rd_vieworg equ 112
|
||||
rd_viewangles equ 124
|
||||
rd_ambientlight equ 136
|
||||
rd_size equ 140
|
||||
|
||||
; mtriangle_t structure
|
||||
; !!! if this is changed, it must be changed in model.h too !!!
|
||||
mtri_facesfront equ 0
|
||||
mtri_vertindex equ 4
|
||||
mtri_size equ 16 ; !!! if this changes, array indexing in !!!
|
||||
; !!! d_polysa.s must be changed to match !!!
|
||||
mtri_shift equ 4
|
||||
|
323
ref_soft/r_aclip.c
Normal file
323
ref_soft/r_aclip.c
Normal file
@ -0,0 +1,323 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 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 "r_local.h"
|
||||
|
||||
static finalvert_t fv[2][8];
|
||||
|
||||
void R_AliasProjectAndClipTestFinalVert (finalvert_t *fv);
|
||||
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;
|
||||
|
||||
scale = (ALIAS_Z_CLIP_PLANE - pfv0->xyz[2]) /
|
||||
(pfv1->xyz[2] - pfv0->xyz[2]);
|
||||
|
||||
out->xyz[0] = pfv0->xyz[0] + (pfv1->xyz[0] - pfv0->xyz[0]) * scale;
|
||||
out->xyz[1] = pfv0->xyz[1] + (pfv1->xyz[1] - pfv0->xyz[1]) * scale;
|
||||
out->xyz[2] = ALIAS_Z_CLIP_PLANE;
|
||||
|
||||
out->s = pfv0->s + (pfv1->s - pfv0->s) * scale;
|
||||
out->t = pfv0->t + (pfv1->t - pfv0->t) * scale;
|
||||
out->l = pfv0->l + (pfv1->l - pfv0->l) * scale;
|
||||
|
||||
R_AliasProjectAndClipTestFinalVert (out);
|
||||
}
|
||||
|
||||
|
||||
#if !id386
|
||||
|
||||
void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
|
||||
if (pfv0->v >= pfv1->v )
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrect.x - pfv0->u) /
|
||||
(pfv1->u - pfv0->u);
|
||||
out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5;
|
||||
out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5;
|
||||
out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5;
|
||||
out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5;
|
||||
out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5;
|
||||
out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrect.x - pfv1->u) /
|
||||
(pfv0->u - pfv1->u);
|
||||
out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5;
|
||||
out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5;
|
||||
out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5;
|
||||
out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5;
|
||||
out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5;
|
||||
out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
|
||||
if ( pfv0->v >= pfv1->v )
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrectright - pfv0->u ) /
|
||||
(pfv1->u - pfv0->u );
|
||||
out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5;
|
||||
out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5;
|
||||
out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5;
|
||||
out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5;
|
||||
out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5;
|
||||
out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrectright - pfv1->u ) /
|
||||
(pfv0->u - pfv1->u );
|
||||
out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5;
|
||||
out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5;
|
||||
out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5;
|
||||
out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5;
|
||||
out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5;
|
||||
out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
|
||||
if (pfv0->v >= pfv1->v)
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrect.y - pfv0->v) /
|
||||
(pfv1->v - pfv0->v);
|
||||
out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5;
|
||||
out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5;
|
||||
out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5;
|
||||
out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5;
|
||||
out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5;
|
||||
out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrect.y - pfv1->v) /
|
||||
(pfv0->v - pfv1->v);
|
||||
out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5;
|
||||
out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5;
|
||||
out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5;
|
||||
out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5;
|
||||
out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5;
|
||||
out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1,
|
||||
finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
|
||||
if (pfv0->v >= pfv1->v)
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrectbottom - pfv0->v) /
|
||||
(pfv1->v - pfv0->v);
|
||||
|
||||
out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5;
|
||||
out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5;
|
||||
out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5;
|
||||
out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5;
|
||||
out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5;
|
||||
out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrectbottom - pfv1->v) /
|
||||
(pfv0->v - pfv1->v);
|
||||
|
||||
out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5;
|
||||
out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5;
|
||||
out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5;
|
||||
out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5;
|
||||
out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5;
|
||||
out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * 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].u < r_refdef.aliasvrect.x)
|
||||
out[k].flags |= ALIAS_LEFT_CLIP;
|
||||
if (out[k].v < r_refdef.aliasvrect.y)
|
||||
out[k].flags |= ALIAS_TOP_CLIP;
|
||||
if (out[k].u > r_refdef.aliasvrectright)
|
||||
out[k].flags |= ALIAS_RIGHT_CLIP;
|
||||
if (out[k].v > r_refdef.aliasvrectbottom)
|
||||
out[k].flags |= ALIAS_BOTTOM_CLIP;
|
||||
k++;
|
||||
}
|
||||
if (!flags)
|
||||
{
|
||||
out[k] = in[i];
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_AliasClipTriangle
|
||||
================
|
||||
*/
|
||||
void R_AliasClipTriangle (finalvert_t *index0, finalvert_t *index1, finalvert_t *index2)
|
||||
{
|
||||
int i, k, pingpong;
|
||||
unsigned clipflags;
|
||||
|
||||
// copy vertexes and fix seam texture coordinates
|
||||
fv[0][0] = *index0;
|
||||
fv[0][1] = *index1;
|
||||
fv[0][2] = *index2;
|
||||
|
||||
// clip
|
||||
clipflags = fv[0][0].flags | fv[0][1].flags | fv[0][2].flags;
|
||||
|
||||
if (clipflags & ALIAS_Z_CLIP)
|
||||
{
|
||||
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].u < r_refdef.aliasvrect.x)
|
||||
fv[pingpong][i].u = r_refdef.aliasvrect.x;
|
||||
else if (fv[pingpong][i].u > r_refdef.aliasvrectright)
|
||||
fv[pingpong][i].u = r_refdef.aliasvrectright;
|
||||
|
||||
if (fv[pingpong][i].v < r_refdef.aliasvrect.y)
|
||||
fv[pingpong][i].v = r_refdef.aliasvrect.y;
|
||||
else if (fv[pingpong][i].v > r_refdef.aliasvrectbottom)
|
||||
fv[pingpong][i].v = r_refdef.aliasvrectbottom;
|
||||
|
||||
fv[pingpong][i].flags = 0;
|
||||
}
|
||||
|
||||
// draw triangles
|
||||
for (i=1 ; i<k-1 ; i++)
|
||||
{
|
||||
aliastriangleparms.a = &fv[pingpong][0];
|
||||
aliastriangleparms.b = &fv[pingpong][i];
|
||||
aliastriangleparms.c = &fv[pingpong][i+1];
|
||||
R_DrawTriangle();
|
||||
}
|
||||
}
|
||||
|
200
ref_soft/r_aclipa.asm
Normal file
200
ref_soft/r_aclipa.asm
Normal file
@ -0,0 +1,200 @@
|
||||
.386P
|
||||
.model FLAT
|
||||
;
|
||||
; r_aliasa.s
|
||||
; x86 assembly-language Alias model transform and project code.
|
||||
;
|
||||
|
||||
include qasm.inc
|
||||
include d_if.inc
|
||||
|
||||
if id386
|
||||
|
||||
_DATA SEGMENT
|
||||
Ltemp0 dd 0
|
||||
Ltemp1 dd 0
|
||||
|
||||
_DATA ENDS
|
||||
_TEXT SEGMENT
|
||||
|
||||
pfv0 equ 8+4
|
||||
pfv1 equ 8+8
|
||||
outparm equ 8+12
|
||||
|
||||
public _R_Alias_clip_bottom
|
||||
_R_Alias_clip_bottom:
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov esi,ds:dword ptr[pfv0+esp]
|
||||
mov edi,ds:dword ptr[pfv1+esp]
|
||||
|
||||
mov eax,ds:dword ptr[_r_refdef+rd_aliasvrectbottom]
|
||||
|
||||
LDoForwardOrBackward:
|
||||
|
||||
mov edx,ds:dword ptr[fv_v+4+esi]
|
||||
mov ecx,ds:dword ptr[fv_v+4+edi]
|
||||
|
||||
cmp edx,ecx
|
||||
jl LDoForward
|
||||
|
||||
mov ecx,ds:dword ptr[fv_v+4+esi]
|
||||
mov edx,ds:dword ptr[fv_v+4+edi]
|
||||
mov edi,ds:dword ptr[pfv0+esp]
|
||||
mov esi,ds:dword ptr[pfv1+esp]
|
||||
|
||||
LDoForward:
|
||||
|
||||
sub ecx,edx
|
||||
sub eax,edx
|
||||
mov ds:dword ptr[Ltemp1],ecx
|
||||
mov ds:dword ptr[Ltemp0],eax
|
||||
fild ds:dword ptr[Ltemp1]
|
||||
fild ds:dword ptr[Ltemp0]
|
||||
mov edx,ds:dword ptr[outparm+esp]
|
||||
mov eax,2
|
||||
|
||||
fdivrp st(1),st(0) ; scale
|
||||
|
||||
LDo3Forward:
|
||||
fild ds:dword ptr[fv_v+0+esi] ; fv0v0 | scale
|
||||
fild ds:dword ptr[fv_v+0+edi] ; fv1v0 | fv0v0 | scale
|
||||
fild ds:dword ptr[fv_v+4+esi] ; fv0v1 | fv1v0 | fv0v0 | scale
|
||||
fild ds:dword ptr[fv_v+4+edi] ; fv1v1 | fv0v1 | fv1v0 | fv0v0 | scale
|
||||
fild ds:dword ptr[fv_v+8+esi] ; fv0v2 | fv1v1 | fv0v1 | fv1v0 | fv0v0 | scale
|
||||
fild ds:dword ptr[fv_v+8+edi] ; fv1v2 | fv0v2 | fv1v1 | fv0v1 | fv1v0 | fv0v0 |
|
||||
; scale
|
||||
fxch st(5) ; fv0v0 | fv0v2 | fv1v1 | fv0v1 | fv1v0 | fv1v2 |
|
||||
; scale
|
||||
fsub st(4),st(0) ; fv0v0 | fv0v2 | fv1v1 | fv0v1 | fv1v0-fv0v0 |
|
||||
; fv1v2 | scale
|
||||
fxch st(3) ; fv0v1 | fv0v2 | fv1v1 | fv0v0 | fv1v0-fv0v0 |
|
||||
; fv1v2 | scale
|
||||
fsub st(2),st(0) ; fv0v1 | fv0v2 | fv1v1-fv0v1 | fv0v0 |
|
||||
; fv1v0-fv0v0 | fv1v2 | scale
|
||||
fxch st(1) ; fv0v2 | fv0v1 | fv1v1-fv0v1 | fv0v0 |
|
||||
; fv1v0-fv0v0 | fv1v2 | scale
|
||||
fsub st(5),st(0) ; fv0v2 | fv0v1 | fv1v1-fv0v1 | fv0v0 |
|
||||
; fv1v0-fv0v0 | fv1v2-fv0v2 | scale
|
||||
fxch st(6) ; scale | fv0v1 | fv1v1-fv0v1 | fv0v0 |
|
||||
; fv1v0-fv0v0 | fv1v2-fv0v2 | fv0v2
|
||||
fmul st(4),st(0) ; scale | fv0v1 | fv1v1-fv0v1 | fv0v0 |
|
||||
; (fv1v0-fv0v0)*scale | fv1v2-fv0v2 | fv0v2
|
||||
add edi,12
|
||||
fmul st(2),st(0) ; scale | fv0v1 | (fv1v1-fv0v1)*scale | fv0v0 |
|
||||
; (fv1v0-fv0v0)*scale | fv1v2-fv0v2 | fv0v2
|
||||
add esi,12
|
||||
add edx,12
|
||||
fmul st(5),st(0) ; scale | fv0v1 | (fv1v1-fv0v1)*scale | fv0v0 |
|
||||
; (fv1v0-fv0v0)*scale | (fv1v2-fv0v2)*scale |
|
||||
; fv0v2
|
||||
fxch st(3) ; fv0v0 | fv0v1 | (fv1v1-fv0v1)*scale | scale |
|
||||
; (fv1v0-fv0v0)*scale | (fv1v2-fv0v2)*scale |
|
||||
; fv0v2
|
||||
faddp st(4),st(0) ; fv0v1 | (fv1v1-fv0v1)*scale | scale |
|
||||
; fv0v0+(fv1v0-fv0v0)*scale |
|
||||
; (fv1v2-fv0v2)*scale | fv0v2
|
||||
faddp st(1),st(0) ; fv0v1+(fv1v1-fv0v1)*scale | scale |
|
||||
; fv0v0+(fv1v0-fv0v0)*scale |
|
||||
; (fv1v2-fv0v2)*scale | fv0v2
|
||||
fxch st(4) ; fv0v2 | scale | fv0v0+(fv1v0-fv0v0)*scale |
|
||||
; (fv1v2-fv0v2)*scale | fv0v1+(fv1v1-fv0v1)*scale
|
||||
faddp st(3),st(0) ; scale | fv0v0+(fv1v0-fv0v0)*scale |
|
||||
; fv0v2+(fv1v2-fv0v2)*scale |
|
||||
; fv0v1+(fv1v1-fv0v1)*scale
|
||||
fxch st(1) ; fv0v0+(fv1v0-fv0v0)*scale | scale |
|
||||
; fv0v2+(fv1v2-fv0v2)*scale |
|
||||
; fv0v1+(fv1v1-fv0v1)*scale
|
||||
fadd ds:dword ptr[float_point5]
|
||||
fxch st(3) ; fv0v1+(fv1v1-fv0v1)*scale | scale |
|
||||
; fv0v2+(fv1v2-fv0v2)*scale |
|
||||
; fv0v0+(fv1v0-fv0v0)*scale
|
||||
fadd ds:dword ptr[float_point5]
|
||||
fxch st(2) ; fv0v2+(fv1v2-fv0v2)*scale | scale |
|
||||
; fv0v1+(fv1v1-fv0v1)*scale |
|
||||
; fv0v0+(fv1v0-fv0v0)*scale
|
||||
fadd ds:dword ptr[float_point5]
|
||||
fxch st(3) ; fv0v0+(fv1v0-fv0v0)*scale | scale |
|
||||
; fv0v1+(fv1v1-fv0v1)*scale |
|
||||
; fv0v2+(fv1v2-fv0v2)*scale
|
||||
fistp ds:dword ptr[fv_v+0-12+edx] ; scale | fv0v1+(fv1v1-fv0v1)*scale |
|
||||
; fv0v2+(fv1v2-fv0v2)*scale
|
||||
fxch st(1) ; fv0v1+(fv1v1-fv0v1)*scale | scale |
|
||||
; fv0v2+(fv1v2-fv0v2)*scale | scale
|
||||
fistp ds:dword ptr[fv_v+4-12+edx] ; scale | fv0v2+(fv1v2-fv0v2)*scale
|
||||
fxch st(1) ; fv0v2+(fv1v2-fv0v2)*sc | scale
|
||||
fistp ds:dword ptr[fv_v+8-12+edx] ; scale
|
||||
|
||||
dec eax
|
||||
jnz LDo3Forward
|
||||
|
||||
fstp st(0)
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
|
||||
ret
|
||||
|
||||
|
||||
public _R_Alias_clip_top
|
||||
_R_Alias_clip_top:
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov esi,ds:dword ptr[pfv0+esp]
|
||||
mov edi,ds:dword ptr[pfv1+esp]
|
||||
|
||||
mov eax,ds:dword ptr[_r_refdef+rd_aliasvrect+4]
|
||||
jmp LDoForwardOrBackward
|
||||
|
||||
|
||||
|
||||
public _R_Alias_clip_right
|
||||
_R_Alias_clip_right:
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov esi,ds:dword ptr[pfv0+esp]
|
||||
mov edi,ds:dword ptr[pfv1+esp]
|
||||
|
||||
mov eax,ds:dword ptr[_r_refdef+rd_aliasvrectright]
|
||||
|
||||
LRightLeftEntry:
|
||||
|
||||
|
||||
mov edx,ds:dword ptr[fv_v+4+esi]
|
||||
mov ecx,ds:dword ptr[fv_v+4+edi]
|
||||
|
||||
cmp edx,ecx
|
||||
mov edx,ds:dword ptr[fv_v+0+esi]
|
||||
|
||||
mov ecx,ds:dword ptr[fv_v+0+edi]
|
||||
jl LDoForward2
|
||||
|
||||
mov ecx,ds:dword ptr[fv_v+0+esi]
|
||||
mov edx,ds:dword ptr[fv_v+0+edi]
|
||||
mov edi,ds:dword ptr[pfv0+esp]
|
||||
mov esi,ds:dword ptr[pfv1+esp]
|
||||
|
||||
LDoForward2:
|
||||
|
||||
jmp LDoForward
|
||||
|
||||
|
||||
public _R_Alias_clip_left
|
||||
_R_Alias_clip_left:
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov esi,ds:dword ptr[pfv0+esp]
|
||||
mov edi,ds:dword ptr[pfv1+esp]
|
||||
|
||||
mov eax,ds:dword ptr[_r_refdef+rd_aliasvrect+0]
|
||||
jmp LRightLeftEntry
|
||||
|
||||
|
||||
|
||||
_TEXT ENDS
|
||||
endif ;id386
|
||||
END
|
1198
ref_soft/r_alias.c
Normal file
1198
ref_soft/r_alias.c
Normal file
File diff suppressed because it is too large
Load Diff
637
ref_soft/r_bsp.c
Normal file
637
ref_soft/r_bsp.c
Normal file
@ -0,0 +1,637 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 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_bsp.c
|
||||
|
||||
#include "r_local.h"
|
||||
|
||||
//
|
||||
// current entity info
|
||||
//
|
||||
qboolean insubmodel;
|
||||
entity_t *currententity;
|
||||
vec3_t modelorg; // modelorg is the viewpoint reletive to
|
||||
// the currently rendering entity
|
||||
vec3_t r_entorigin; // the currently rendering entity in world
|
||||
// coordinates
|
||||
|
||||
float entity_rotation[3][3];
|
||||
|
||||
int r_currentbkey;
|
||||
|
||||
typedef enum {touchessolid, drawnode, nodrawnode} solidstate_t;
|
||||
|
||||
#define MAX_BMODEL_VERTS 500 // 6K
|
||||
#define MAX_BMODEL_EDGES 1000 // 12K
|
||||
|
||||
static mvertex_t *pbverts;
|
||||
static bedge_t *pbedges;
|
||||
static int numbverts, numbedges;
|
||||
|
||||
static mvertex_t *pfrontenter, *pfrontexit;
|
||||
|
||||
static qboolean makeclippededge;
|
||||
|
||||
|
||||
//===========================================================================
|
||||
|
||||
/*
|
||||
================
|
||||
R_EntityRotate
|
||||
================
|
||||
*/
|
||||
void R_EntityRotate (vec3_t vec)
|
||||
{
|
||||
vec3_t tvec;
|
||||
|
||||
VectorCopy (vec, tvec);
|
||||
vec[0] = DotProduct (entity_rotation[0], tvec);
|
||||
vec[1] = DotProduct (entity_rotation[1], tvec);
|
||||
vec[2] = DotProduct (entity_rotation[2], tvec);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_RotateBmodel
|
||||
================
|
||||
*/
|
||||
void R_RotateBmodel (void)
|
||||
{
|
||||
float angle, s, c, temp1[3][3], temp2[3][3], temp3[3][3];
|
||||
|
||||
// TODO: should use a look-up table
|
||||
// TODO: should really be stored with the entity instead of being reconstructed
|
||||
// TODO: could cache lazily, stored in the entity
|
||||
// TODO: share work with R_SetUpAliasTransform
|
||||
|
||||
// yaw
|
||||
angle = currententity->angles[YAW];
|
||||
angle = angle * M_PI*2 / 360;
|
||||
s = sin(angle);
|
||||
c = cos(angle);
|
||||
|
||||
temp1[0][0] = c;
|
||||
temp1[0][1] = s;
|
||||
temp1[0][2] = 0;
|
||||
temp1[1][0] = -s;
|
||||
temp1[1][1] = c;
|
||||
temp1[1][2] = 0;
|
||||
temp1[2][0] = 0;
|
||||
temp1[2][1] = 0;
|
||||
temp1[2][2] = 1;
|
||||
|
||||
|
||||
// pitch
|
||||
angle = currententity->angles[PITCH];
|
||||
angle = angle * M_PI*2 / 360;
|
||||
s = sin(angle);
|
||||
c = cos(angle);
|
||||
|
||||
temp2[0][0] = c;
|
||||
temp2[0][1] = 0;
|
||||
temp2[0][2] = -s;
|
||||
temp2[1][0] = 0;
|
||||
temp2[1][1] = 1;
|
||||
temp2[1][2] = 0;
|
||||
temp2[2][0] = s;
|
||||
temp2[2][1] = 0;
|
||||
temp2[2][2] = c;
|
||||
|
||||
R_ConcatRotations (temp2, temp1, temp3);
|
||||
|
||||
// roll
|
||||
angle = currententity->angles[ROLL];
|
||||
angle = angle * M_PI*2 / 360;
|
||||
s = sin(angle);
|
||||
c = cos(angle);
|
||||
|
||||
temp1[0][0] = 1;
|
||||
temp1[0][1] = 0;
|
||||
temp1[0][2] = 0;
|
||||
temp1[1][0] = 0;
|
||||
temp1[1][1] = c;
|
||||
temp1[1][2] = s;
|
||||
temp1[2][0] = 0;
|
||||
temp1[2][1] = -s;
|
||||
temp1[2][2] = c;
|
||||
|
||||
R_ConcatRotations (temp1, temp3, entity_rotation);
|
||||
|
||||
//
|
||||
// rotate modelorg and the transformation matrix
|
||||
//
|
||||
R_EntityRotate (modelorg);
|
||||
R_EntityRotate (vpn);
|
||||
R_EntityRotate (vright);
|
||||
R_EntityRotate (vup);
|
||||
|
||||
R_TransformFrustum ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_RecursiveClipBPoly
|
||||
|
||||
Clip a bmodel poly down the world bsp tree
|
||||
================
|
||||
*/
|
||||
void R_RecursiveClipBPoly (bedge_t *pedges, mnode_t *pnode, msurface_t *psurf)
|
||||
{
|
||||
bedge_t *psideedges[2], *pnextedge, *ptedge;
|
||||
int i, side, lastside;
|
||||
float dist, frac, lastdist;
|
||||
mplane_t *splitplane, tplane;
|
||||
mvertex_t *pvert, *plastvert, *ptvert;
|
||||
mnode_t *pn;
|
||||
int area;
|
||||
|
||||
psideedges[0] = psideedges[1] = NULL;
|
||||
|
||||
makeclippededge = false;
|
||||
|
||||
// transform the BSP plane into model space
|
||||
// FIXME: cache these?
|
||||
splitplane = pnode->plane;
|
||||
tplane.dist = splitplane->dist -
|
||||
DotProduct(r_entorigin, splitplane->normal);
|
||||
tplane.normal[0] = DotProduct (entity_rotation[0], splitplane->normal);
|
||||
tplane.normal[1] = DotProduct (entity_rotation[1], splitplane->normal);
|
||||
tplane.normal[2] = DotProduct (entity_rotation[2], splitplane->normal);
|
||||
|
||||
// clip edges to BSP plane
|
||||
for ( ; pedges ; pedges = pnextedge)
|
||||
{
|
||||
pnextedge = pedges->pnext;
|
||||
|
||||
// set the status for the last point as the previous point
|
||||
// FIXME: cache this stuff somehow?
|
||||
plastvert = pedges->v[0];
|
||||
lastdist = DotProduct (plastvert->position, tplane.normal) -
|
||||
tplane.dist;
|
||||
|
||||
if (lastdist > 0)
|
||||
lastside = 0;
|
||||
else
|
||||
lastside = 1;
|
||||
|
||||
pvert = pedges->v[1];
|
||||
|
||||
dist = DotProduct (pvert->position, tplane.normal) - tplane.dist;
|
||||
|
||||
if (dist > 0)
|
||||
side = 0;
|
||||
else
|
||||
side = 1;
|
||||
|
||||
if (side != lastside)
|
||||
{
|
||||
// clipped
|
||||
if (numbverts >= MAX_BMODEL_VERTS)
|
||||
return;
|
||||
|
||||
// generate the clipped vertex
|
||||
frac = lastdist / (lastdist - dist);
|
||||
ptvert = &pbverts[numbverts++];
|
||||
ptvert->position[0] = plastvert->position[0] +
|
||||
frac * (pvert->position[0] -
|
||||
plastvert->position[0]);
|
||||
ptvert->position[1] = plastvert->position[1] +
|
||||
frac * (pvert->position[1] -
|
||||
plastvert->position[1]);
|
||||
ptvert->position[2] = plastvert->position[2] +
|
||||
frac * (pvert->position[2] -
|
||||
plastvert->position[2]);
|
||||
|
||||
// split into two edges, one on each side, and remember entering
|
||||
// and exiting points
|
||||
// FIXME: share the clip edge by having a winding direction flag?
|
||||
if (numbedges >= (MAX_BMODEL_EDGES - 1))
|
||||
{
|
||||
ri.Con_Printf (PRINT_ALL,"Out of edges for bmodel\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ptedge = &pbedges[numbedges];
|
||||
ptedge->pnext = psideedges[lastside];
|
||||
psideedges[lastside] = ptedge;
|
||||
ptedge->v[0] = plastvert;
|
||||
ptedge->v[1] = ptvert;
|
||||
|
||||
ptedge = &pbedges[numbedges + 1];
|
||||
ptedge->pnext = psideedges[side];
|
||||
psideedges[side] = ptedge;
|
||||
ptedge->v[0] = ptvert;
|
||||
ptedge->v[1] = pvert;
|
||||
|
||||
numbedges += 2;
|
||||
|
||||
if (side == 0)
|
||||
{
|
||||
// entering for front, exiting for back
|
||||
pfrontenter = ptvert;
|
||||
makeclippededge = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pfrontexit = ptvert;
|
||||
makeclippededge = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// add the edge to the appropriate side
|
||||
pedges->pnext = psideedges[side];
|
||||
psideedges[side] = pedges;
|
||||
}
|
||||
}
|
||||
|
||||
// if anything was clipped, reconstitute and add the edges along the clip
|
||||
// plane to both sides (but in opposite directions)
|
||||
if (makeclippededge)
|
||||
{
|
||||
if (numbedges >= (MAX_BMODEL_EDGES - 2))
|
||||
{
|
||||
ri.Con_Printf (PRINT_ALL,"Out of edges for bmodel\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ptedge = &pbedges[numbedges];
|
||||
ptedge->pnext = psideedges[0];
|
||||
psideedges[0] = ptedge;
|
||||
ptedge->v[0] = pfrontexit;
|
||||
ptedge->v[1] = pfrontenter;
|
||||
|
||||
ptedge = &pbedges[numbedges + 1];
|
||||
ptedge->pnext = psideedges[1];
|
||||
psideedges[1] = ptedge;
|
||||
ptedge->v[0] = pfrontenter;
|
||||
ptedge->v[1] = pfrontexit;
|
||||
|
||||
numbedges += 2;
|
||||
}
|
||||
|
||||
// draw or recurse further
|
||||
for (i=0 ; i<2 ; i++)
|
||||
{
|
||||
if (psideedges[i])
|
||||
{
|
||||
// draw if we've reached a non-solid leaf, done if all that's left is a
|
||||
// solid leaf, and continue down the tree if it's not a leaf
|
||||
pn = pnode->children[i];
|
||||
|
||||
// we're done with this branch if the node or leaf isn't in the PVS
|
||||
if (pn->visframe == r_visframecount)
|
||||
{
|
||||
if (pn->contents != CONTENTS_NODE)
|
||||
{
|
||||
if (pn->contents != CONTENTS_SOLID)
|
||||
{
|
||||
if (r_newrefdef.areabits)
|
||||
{
|
||||
area = ((mleaf_t *)pn)->area;
|
||||
if (! (r_newrefdef.areabits[area>>3] & (1<<(area&7)) ) )
|
||||
continue; // not visible
|
||||
}
|
||||
|
||||
r_currentbkey = ((mleaf_t *)pn)->key;
|
||||
R_RenderBmodelFace (psideedges[i], psurf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
R_RecursiveClipBPoly (psideedges[i], pnode->children[i],
|
||||
psurf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_DrawSolidClippedSubmodelPolygons
|
||||
|
||||
Bmodel crosses multiple leafs
|
||||
================
|
||||
*/
|
||||
void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel, mnode_t *topnode)
|
||||
{
|
||||
int i, j, lindex;
|
||||
vec_t dot;
|
||||
msurface_t *psurf;
|
||||
int numsurfaces;
|
||||
mplane_t *pplane;
|
||||
mvertex_t bverts[MAX_BMODEL_VERTS];
|
||||
bedge_t bedges[MAX_BMODEL_EDGES], *pbedge;
|
||||
medge_t *pedge, *pedges;
|
||||
|
||||
// FIXME: use bounding-box-based frustum clipping info?
|
||||
|
||||
psurf = &pmodel->surfaces[pmodel->firstmodelsurface];
|
||||
numsurfaces = pmodel->nummodelsurfaces;
|
||||
pedges = pmodel->edges;
|
||||
|
||||
for (i=0 ; i<numsurfaces ; i++, psurf++)
|
||||
{
|
||||
// find which side of the node we are on
|
||||
pplane = psurf->plane;
|
||||
|
||||
dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
|
||||
|
||||
// draw the polygon
|
||||
if (( !(psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
|
||||
((psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
|
||||
continue;
|
||||
|
||||
// FIXME: use bounding-box-based frustum clipping info?
|
||||
|
||||
// copy the edges to bedges, flipping if necessary so always
|
||||
// clockwise winding
|
||||
// FIXME: if edges and vertices get caches, these assignments must move
|
||||
// outside the loop, and overflow checking must be done here
|
||||
pbverts = bverts;
|
||||
pbedges = bedges;
|
||||
numbverts = numbedges = 0;
|
||||
pbedge = &bedges[numbedges];
|
||||
numbedges += psurf->numedges;
|
||||
|
||||
for (j=0 ; j<psurf->numedges ; j++)
|
||||
{
|
||||
lindex = pmodel->surfedges[psurf->firstedge+j];
|
||||
|
||||
if (lindex > 0)
|
||||
{
|
||||
pedge = &pedges[lindex];
|
||||
pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[0]];
|
||||
pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[1]];
|
||||
}
|
||||
else
|
||||
{
|
||||
lindex = -lindex;
|
||||
pedge = &pedges[lindex];
|
||||
pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[1]];
|
||||
pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[0]];
|
||||
}
|
||||
|
||||
pbedge[j].pnext = &pbedge[j+1];
|
||||
}
|
||||
|
||||
pbedge[j-1].pnext = NULL; // mark end of edges
|
||||
|
||||
if ( !( psurf->texinfo->flags & ( SURF_TRANS66 | SURF_TRANS33 ) ) )
|
||||
R_RecursiveClipBPoly (pbedge, topnode, psurf);
|
||||
else
|
||||
R_RenderBmodelFace( pbedge, psurf );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_DrawSubmodelPolygons
|
||||
|
||||
All in one leaf
|
||||
================
|
||||
*/
|
||||
void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags, mnode_t *topnode)
|
||||
{
|
||||
int i;
|
||||
vec_t dot;
|
||||
msurface_t *psurf;
|
||||
int numsurfaces;
|
||||
mplane_t *pplane;
|
||||
|
||||
// FIXME: use bounding-box-based frustum clipping info?
|
||||
|
||||
psurf = &pmodel->surfaces[pmodel->firstmodelsurface];
|
||||
numsurfaces = pmodel->nummodelsurfaces;
|
||||
|
||||
for (i=0 ; i<numsurfaces ; i++, psurf++)
|
||||
{
|
||||
// find which side of the node we are on
|
||||
pplane = psurf->plane;
|
||||
|
||||
dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
|
||||
|
||||
// draw the polygon
|
||||
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
|
||||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
|
||||
{
|
||||
r_currentkey = ((mleaf_t *)topnode)->key;
|
||||
|
||||
// FIXME: use bounding-box-based frustum clipping info?
|
||||
R_RenderFace (psurf, clipflags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int c_drawnode;
|
||||
|
||||
/*
|
||||
================
|
||||
R_RecursiveWorldNode
|
||||
================
|
||||
*/
|
||||
void R_RecursiveWorldNode (mnode_t *node, int clipflags)
|
||||
{
|
||||
int i, c, side, *pindex;
|
||||
vec3_t acceptpt, rejectpt;
|
||||
mplane_t *plane;
|
||||
msurface_t *surf, **mark;
|
||||
float d, dot;
|
||||
mleaf_t *pleaf;
|
||||
|
||||
if (node->contents == CONTENTS_SOLID)
|
||||
return; // solid
|
||||
|
||||
if (node->visframe != r_visframecount)
|
||||
return;
|
||||
|
||||
// cull the clipping planes if not trivial accept
|
||||
// FIXME: the compiler is doing a lousy job of optimizing here; it could be
|
||||
// twice as fast in ASM
|
||||
if (clipflags)
|
||||
{
|
||||
for (i=0 ; i<4 ; i++)
|
||||
{
|
||||
if (! (clipflags & (1<<i)) )
|
||||
continue; // don't need to clip against it
|
||||
|
||||
// generate accept and reject points
|
||||
// FIXME: do with fast look-ups or integer tests based on the sign bit
|
||||
// of the floating point values
|
||||
|
||||
pindex = pfrustum_indexes[i];
|
||||
|
||||
rejectpt[0] = (float)node->minmaxs[pindex[0]];
|
||||
rejectpt[1] = (float)node->minmaxs[pindex[1]];
|
||||
rejectpt[2] = (float)node->minmaxs[pindex[2]];
|
||||
|
||||
d = DotProduct (rejectpt, view_clipplanes[i].normal);
|
||||
d -= view_clipplanes[i].dist;
|
||||
if (d <= 0)
|
||||
return;
|
||||
acceptpt[0] = (float)node->minmaxs[pindex[3+0]];
|
||||
acceptpt[1] = (float)node->minmaxs[pindex[3+1]];
|
||||
acceptpt[2] = (float)node->minmaxs[pindex[3+2]];
|
||||
|
||||
d = DotProduct (acceptpt, view_clipplanes[i].normal);
|
||||
d -= view_clipplanes[i].dist;
|
||||
|
||||
if (d >= 0)
|
||||
clipflags &= ~(1<<i); // node is entirely on screen
|
||||
}
|
||||
}
|
||||
|
||||
c_drawnode++;
|
||||
|
||||
// if a leaf node, draw stuff
|
||||
if (node->contents != -1)
|
||||
{
|
||||
pleaf = (mleaf_t *)node;
|
||||
|
||||
// check for door connected areas
|
||||
if (r_newrefdef.areabits)
|
||||
{
|
||||
if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
|
||||
return; // not visible
|
||||
}
|
||||
|
||||
mark = pleaf->firstmarksurface;
|
||||
c = pleaf->nummarksurfaces;
|
||||
|
||||
if (c)
|
||||
{
|
||||
do
|
||||
{
|
||||
(*mark)->visframe = r_framecount;
|
||||
mark++;
|
||||
} while (--c);
|
||||
}
|
||||
|
||||
pleaf->key = r_currentkey;
|
||||
r_currentkey++; // all bmodels in a leaf share the same key
|
||||
}
|
||||
else
|
||||
{
|
||||
// node is just a decision point, so go down the apropriate sides
|
||||
|
||||
// find which side of the node we are on
|
||||
plane = node->plane;
|
||||
|
||||
switch (plane->type)
|
||||
{
|
||||
case PLANE_X:
|
||||
dot = modelorg[0] - plane->dist;
|
||||
break;
|
||||
case PLANE_Y:
|
||||
dot = modelorg[1] - plane->dist;
|
||||
break;
|
||||
case PLANE_Z:
|
||||
dot = modelorg[2] - plane->dist;
|
||||
break;
|
||||
default:
|
||||
dot = DotProduct (modelorg, plane->normal) - plane->dist;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dot >= 0)
|
||||
side = 0;
|
||||
else
|
||||
side = 1;
|
||||
|
||||
// recurse down the children, front side first
|
||||
R_RecursiveWorldNode (node->children[side], clipflags);
|
||||
|
||||
// draw stuff
|
||||
c = node->numsurfaces;
|
||||
|
||||
if (c)
|
||||
{
|
||||
surf = r_worldmodel->surfaces + node->firstsurface;
|
||||
|
||||
if (dot < -BACKFACE_EPSILON)
|
||||
{
|
||||
do
|
||||
{
|
||||
if ((surf->flags & SURF_PLANEBACK) &&
|
||||
(surf->visframe == r_framecount))
|
||||
{
|
||||
R_RenderFace (surf, clipflags);
|
||||
}
|
||||
|
||||
surf++;
|
||||
} while (--c);
|
||||
}
|
||||
else if (dot > BACKFACE_EPSILON)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (!(surf->flags & SURF_PLANEBACK) &&
|
||||
(surf->visframe == r_framecount))
|
||||
{
|
||||
R_RenderFace (surf, clipflags);
|
||||
}
|
||||
|
||||
surf++;
|
||||
} while (--c);
|
||||
}
|
||||
|
||||
// all surfaces on the same node share the same sequence number
|
||||
r_currentkey++;
|
||||
}
|
||||
|
||||
// recurse down the back side
|
||||
R_RecursiveWorldNode (node->children[!side], clipflags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_RenderWorld
|
||||
================
|
||||
*/
|
||||
void R_RenderWorld (void)
|
||||
{
|
||||
|
||||
if (!r_drawworld->value)
|
||||
return;
|
||||
if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
|
||||
return;
|
||||
|
||||
c_drawnode=0;
|
||||
|
||||
// auto cycle the world frame for texture animation
|
||||
r_worldentity.frame = (int)(r_newrefdef.time*2);
|
||||
currententity = &r_worldentity;
|
||||
|
||||
VectorCopy (r_origin, modelorg);
|
||||
currentmodel = r_worldmodel;
|
||||
r_pcurrentvertbase = currentmodel->vertexes;
|
||||
|
||||
R_RecursiveWorldNode (currentmodel->nodes, 15);
|
||||
}
|
||||
|
||||
|
445
ref_soft/r_draw.c
Normal file
445
ref_soft/r_draw.c
Normal file
@ -0,0 +1,445 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 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.
|
||||
|
||||
*/
|
||||
|
||||
// draw.c
|
||||
|
||||
#include "r_local.h"
|
||||
|
||||
|
||||
image_t *draw_chars; // 8*8 graphic characters
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
================
|
||||
Draw_FindPic
|
||||
================
|
||||
*/
|
||||
image_t *Draw_FindPic (char *name)
|
||||
{
|
||||
image_t *image;
|
||||
char fullname[MAX_QPATH];
|
||||
|
||||
if (name[0] != '/' && name[0] != '\\')
|
||||
{
|
||||
Com_sprintf (fullname, sizeof(fullname), "pics/%s.pcx", name);
|
||||
image = R_FindImage (fullname, it_pic);
|
||||
}
|
||||
else
|
||||
image = R_FindImage (name+1, it_pic);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
Draw_InitLocal
|
||||
===============
|
||||
*/
|
||||
void Draw_InitLocal (void)
|
||||
{
|
||||
draw_chars = Draw_FindPic ("conchars");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
Draw_Char
|
||||
|
||||
Draws one 8*8 graphics character
|
||||
It can be clipped to the top of the screen to allow the console to be
|
||||
smoothly scrolled off.
|
||||
================
|
||||
*/
|
||||
void Draw_Char (int x, int y, int num)
|
||||
{
|
||||
byte *dest;
|
||||
byte *source;
|
||||
int drawline;
|
||||
int row, col;
|
||||
|
||||
num &= 255;
|
||||
|
||||
if (num == 32 || num == 32+128)
|
||||
return;
|
||||
|
||||
if (y <= -8)
|
||||
return; // totally off screen
|
||||
|
||||
// if ( ( y + 8 ) >= vid.height )
|
||||
if ( ( y + 8 ) > vid.height ) // PGM - status text was missing in sw...
|
||||
return;
|
||||
|
||||
#ifdef PARANOID
|
||||
if (y > vid.height - 8 || x < 0 || x > vid.width - 8)
|
||||
ri.Sys_Error (ERR_FATAL,"Con_DrawCharacter: (%i, %i)", x, y);
|
||||
if (num < 0 || num > 255)
|
||||
ri.Sys_Error (ERR_FATAL,"Con_DrawCharacter: char %i", num);
|
||||
#endif
|
||||
|
||||
row = num>>4;
|
||||
col = num&15;
|
||||
source = draw_chars->pixels[0] + (row<<10) + (col<<3);
|
||||
|
||||
if (y < 0)
|
||||
{ // clipped
|
||||
drawline = 8 + y;
|
||||
source -= 128*y;
|
||||
y = 0;
|
||||
}
|
||||
else
|
||||
drawline = 8;
|
||||
|
||||
|
||||
dest = vid.buffer + y*vid.rowbytes + x;
|
||||
|
||||
while (drawline--)
|
||||
{
|
||||
if (source[0] != TRANSPARENT_COLOR)
|
||||
dest[0] = source[0];
|
||||
if (source[1] != TRANSPARENT_COLOR)
|
||||
dest[1] = source[1];
|
||||
if (source[2] != TRANSPARENT_COLOR)
|
||||
dest[2] = source[2];
|
||||
if (source[3] != TRANSPARENT_COLOR)
|
||||
dest[3] = source[3];
|
||||
if (source[4] != TRANSPARENT_COLOR)
|
||||
dest[4] = source[4];
|
||||
if (source[5] != TRANSPARENT_COLOR)
|
||||
dest[5] = source[5];
|
||||
if (source[6] != TRANSPARENT_COLOR)
|
||||
dest[6] = source[6];
|
||||
if (source[7] != TRANSPARENT_COLOR)
|
||||
dest[7] = source[7];
|
||||
source += 128;
|
||||
dest += vid.rowbytes;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Draw_GetPicSize
|
||||
=============
|
||||
*/
|
||||
void Draw_GetPicSize (int *w, int *h, char *pic)
|
||||
{
|
||||
image_t *gl;
|
||||
|
||||
gl = Draw_FindPic (pic);
|
||||
if (!gl)
|
||||
{
|
||||
*w = *h = -1;
|
||||
return;
|
||||
}
|
||||
*w = gl->width;
|
||||
*h = gl->height;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Draw_StretchPicImplementation
|
||||
=============
|
||||
*/
|
||||
void Draw_StretchPicImplementation (int x, int y, int w, int h, image_t *pic)
|
||||
{
|
||||
byte *dest, *source;
|
||||
int v, u, sv;
|
||||
int height;
|
||||
int f, fstep;
|
||||
int skip;
|
||||
|
||||
if ((x < 0) ||
|
||||
(x + w > vid.width) ||
|
||||
(y + h > vid.height))
|
||||
{
|
||||
ri.Sys_Error (ERR_FATAL,"Draw_Pic: bad coordinates");
|
||||
}
|
||||
|
||||
height = h;
|
||||
if (y < 0)
|
||||
{
|
||||
skip = -y;
|
||||
height += y;
|
||||
y = 0;
|
||||
}
|
||||
else
|
||||
skip = 0;
|
||||
|
||||
dest = vid.buffer + y * vid.rowbytes + x;
|
||||
|
||||
for (v=0 ; v<height ; v++, dest += vid.rowbytes)
|
||||
{
|
||||
sv = (skip + v)*pic->height/h;
|
||||
source = pic->pixels[0] + sv*pic->width;
|
||||
if (w == pic->width)
|
||||
memcpy (dest, source, w);
|
||||
else
|
||||
{
|
||||
f = 0;
|
||||
fstep = pic->width*0x10000/w;
|
||||
for (u=0 ; u<w ; u+=4)
|
||||
{
|
||||
dest[u] = source[f>>16];
|
||||
f += fstep;
|
||||
dest[u+1] = source[f>>16];
|
||||
f += fstep;
|
||||
dest[u+2] = source[f>>16];
|
||||
f += fstep;
|
||||
dest[u+3] = source[f>>16];
|
||||
f += fstep;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Draw_StretchPic
|
||||
=============
|
||||
*/
|
||||
void Draw_StretchPic (int x, int y, int w, int h, char *name)
|
||||
{
|
||||
image_t *pic;
|
||||
|
||||
pic = Draw_FindPic (name);
|
||||
if (!pic)
|
||||
{
|
||||
ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", name);
|
||||
return;
|
||||
}
|
||||
Draw_StretchPicImplementation (x, y, w, h, pic);
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Draw_StretchRaw
|
||||
=============
|
||||
*/
|
||||
void Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, byte *data)
|
||||
{
|
||||
image_t pic;
|
||||
|
||||
pic.pixels[0] = data;
|
||||
pic.width = cols;
|
||||
pic.height = rows;
|
||||
Draw_StretchPicImplementation (x, y, w, h, &pic);
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Draw_Pic
|
||||
=============
|
||||
*/
|
||||
void Draw_Pic (int x, int y, char *name)
|
||||
{
|
||||
image_t *pic;
|
||||
byte *dest, *source;
|
||||
int v, u;
|
||||
int tbyte;
|
||||
int height;
|
||||
|
||||
pic = Draw_FindPic (name);
|
||||
if (!pic)
|
||||
{
|
||||
ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((x < 0) ||
|
||||
(x + pic->width > vid.width) ||
|
||||
(y + pic->height > vid.height))
|
||||
return; // ri.Sys_Error (ERR_FATAL,"Draw_Pic: bad coordinates");
|
||||
|
||||
height = pic->height;
|
||||
source = pic->pixels[0];
|
||||
if (y < 0)
|
||||
{
|
||||
height += y;
|
||||
source += pic->width*-y;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
dest = vid.buffer + y * vid.rowbytes + x;
|
||||
|
||||
if (!pic->transparent)
|
||||
{
|
||||
for (v=0 ; v<height ; v++)
|
||||
{
|
||||
memcpy (dest, source, pic->width);
|
||||
dest += vid.rowbytes;
|
||||
source += pic->width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pic->width & 7)
|
||||
{ // general
|
||||
for (v=0 ; v<height ; v++)
|
||||
{
|
||||
for (u=0 ; u<pic->width ; u++)
|
||||
if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
|
||||
dest[u] = tbyte;
|
||||
|
||||
dest += vid.rowbytes;
|
||||
source += pic->width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // unwound
|
||||
for (v=0 ; v<height ; v++)
|
||||
{
|
||||
for (u=0 ; u<pic->width ; u+=8)
|
||||
{
|
||||
if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
|
||||
dest[u] = tbyte;
|
||||
if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR)
|
||||
dest[u+1] = tbyte;
|
||||
if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR)
|
||||
dest[u+2] = tbyte;
|
||||
if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR)
|
||||
dest[u+3] = tbyte;
|
||||
if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR)
|
||||
dest[u+4] = tbyte;
|
||||
if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR)
|
||||
dest[u+5] = tbyte;
|
||||
if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR)
|
||||
dest[u+6] = tbyte;
|
||||
if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR)
|
||||
dest[u+7] = tbyte;
|
||||
}
|
||||
dest += vid.rowbytes;
|
||||
source += pic->width;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Draw_TileClear
|
||||
|
||||
This repeats a 64*64 tile graphic to fill the screen around a sized down
|
||||
refresh window.
|
||||
=============
|
||||
*/
|
||||
void Draw_TileClear (int x, int y, int w, int h, char *name)
|
||||
{
|
||||
int i, j;
|
||||
byte *psrc;
|
||||
byte *pdest;
|
||||
image_t *pic;
|
||||
int x2;
|
||||
|
||||
if (x < 0)
|
||||
{
|
||||
w += x;
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0)
|
||||
{
|
||||
h += y;
|
||||
y = 0;
|
||||
}
|
||||
if (x + w > vid.width)
|
||||
w = vid.width - x;
|
||||
if (y + h > vid.height)
|
||||
h = vid.height - y;
|
||||
if (w <= 0 || h <= 0)
|
||||
return;
|
||||
|
||||
pic = Draw_FindPic (name);
|
||||
if (!pic)
|
||||
{
|
||||
ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", name);
|
||||
return;
|
||||
}
|
||||
x2 = x + w;
|
||||
pdest = vid.buffer + y*vid.rowbytes;
|
||||
for (i=0 ; i<h ; i++, pdest += vid.rowbytes)
|
||||
{
|
||||
psrc = pic->pixels[0] + pic->width * ((i+y)&63);
|
||||
for (j=x ; j<x2 ; j++)
|
||||
pdest[j] = psrc[j&63];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
Draw_Fill
|
||||
|
||||
Fills a box of pixels with a single color
|
||||
=============
|
||||
*/
|
||||
void Draw_Fill (int x, int y, int w, int h, int c)
|
||||
{
|
||||
byte *dest;
|
||||
int u, v;
|
||||
|
||||
if (x+w > vid.width)
|
||||
w = vid.width - x;
|
||||
if (y+h > vid.height)
|
||||
h = vid.height - y;
|
||||
if (x < 0)
|
||||
{
|
||||
w += x;
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0)
|
||||
{
|
||||
h += y;
|
||||
y = 0;
|
||||
}
|
||||
if (w < 0 || h < 0)
|
||||
return;
|
||||
dest = vid.buffer + y*vid.rowbytes + x;
|
||||
for (v=0 ; v<h ; v++, dest += vid.rowbytes)
|
||||
for (u=0 ; u<w ; u++)
|
||||
dest[u] = c;
|
||||
}
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
================
|
||||
Draw_FadeScreen
|
||||
|
||||
================
|
||||
*/
|
||||
void Draw_FadeScreen (void)
|
||||
{
|
||||
int x,y;
|
||||
byte *pbuf;
|
||||
int t;
|
||||
|
||||
for (y=0 ; y<vid.height ; y++)
|
||||
{
|
||||
pbuf = (byte *)(vid.buffer + vid.rowbytes*y);
|
||||
t = (y & 1) << 1;
|
||||
|
||||
for (x=0 ; x<vid.width ; x++)
|
||||
{
|
||||
if ((x & 3) != t)
|
||||
pbuf[x] = 0;
|
||||
}
|
||||
}
|
||||
}
|
1234
ref_soft/r_draw16.asm
Normal file
1234
ref_soft/r_draw16.asm
Normal file
File diff suppressed because it is too large
Load Diff
822
ref_soft/r_drawa.asm
Normal file
822
ref_soft/r_drawa.asm
Normal file
@ -0,0 +1,822 @@
|
||||
.386P
|
||||
.model FLAT
|
||||
;
|
||||
; r_drawa.s
|
||||
; x86 assembly-language edge clipping and emission code
|
||||
;
|
||||
|
||||
include qasm.inc
|
||||
include d_if.inc
|
||||
|
||||
if id386
|
||||
|
||||
; !!! if these are changed, they must be changed in r_draw.c too !!!
|
||||
FULLY_CLIPPED_CACHED equ 080000000h
|
||||
FRAMECOUNT_MASK equ 07FFFFFFFh
|
||||
|
||||
_DATA SEGMENT
|
||||
|
||||
Ld0 dd 0.0
|
||||
Ld1 dd 0.0
|
||||
Lstack dd 0
|
||||
Lfp_near_clip dd NEAR_CLIP
|
||||
Lceilv0 dd 0
|
||||
Lv dd 0
|
||||
Lu0 dd 0
|
||||
Lv0 dd 0
|
||||
Lzi0 dd 0
|
||||
|
||||
_DATA ENDS
|
||||
_TEXT SEGMENT
|
||||
|
||||
;----------------------------------------------------------------------
|
||||
; edge clipping code
|
||||
;----------------------------------------------------------------------
|
||||
|
||||
pv0 equ 4+12
|
||||
pv1 equ 8+12
|
||||
clip equ 12+12
|
||||
|
||||
align 4
|
||||
public _R_ClipEdge
|
||||
_R_ClipEdge:
|
||||
push esi ; preserve register variables
|
||||
push edi
|
||||
push ebx
|
||||
mov ds:dword ptr[Lstack],esp ; for clearing the stack later
|
||||
|
||||
; float d0, d1, f;
|
||||
; mvertex_t clipvert;
|
||||
|
||||
mov ebx,ds:dword ptr[clip+esp]
|
||||
mov esi,ds:dword ptr[pv0+esp]
|
||||
mov edx,ds:dword ptr[pv1+esp]
|
||||
|
||||
; if (clip)
|
||||
; {
|
||||
test ebx,ebx
|
||||
jz Lemit
|
||||
|
||||
; do
|
||||
; {
|
||||
|
||||
Lcliploop:
|
||||
|
||||
; d0 = DotProduct (pv0->position, clip->normal) - clip->dist;
|
||||
; d1 = DotProduct (pv1->position, clip->normal) - clip->dist;
|
||||
fld ds:dword ptr[mv_position+0+esi]
|
||||
fmul ds:dword ptr[cp_normal+0+ebx]
|
||||
fld ds:dword ptr[mv_position+4+esi]
|
||||
fmul ds:dword ptr[cp_normal+4+ebx]
|
||||
fld ds:dword ptr[mv_position+8+esi]
|
||||
fmul ds:dword ptr[cp_normal+8+ebx]
|
||||
fxch st(1)
|
||||
faddp st(2),st(0) ; d0mul2 | d0add0
|
||||
|
||||
fld ds:dword ptr[mv_position+0+edx]
|
||||
fmul ds:dword ptr[cp_normal+0+ebx]
|
||||
fld ds:dword ptr[mv_position+4+edx]
|
||||
fmul ds:dword ptr[cp_normal+4+ebx]
|
||||
fld ds:dword ptr[mv_position+8+edx]
|
||||
fmul ds:dword ptr[cp_normal+8+ebx]
|
||||
fxch st(1)
|
||||
faddp st(2),st(0) ; d1mul2 | d1add0 | d0mul2 | d0add0
|
||||
fxch st(3) ; d0add0 | d1add0 | d0mul2 | d1mul2
|
||||
|
||||
faddp st(2),st(0) ; d1add0 | dot0 | d1mul2
|
||||
faddp st(2),st(0) ; dot0 | dot1
|
||||
|
||||
fsub ds:dword ptr[cp_dist+ebx] ; d0 | dot1
|
||||
fxch st(1) ; dot1 | d0
|
||||
fsub ds:dword ptr[cp_dist+ebx] ; d1 | d0
|
||||
fxch st(1)
|
||||
fstp ds:dword ptr[Ld0]
|
||||
fstp ds:dword ptr[Ld1]
|
||||
|
||||
; if (d0 >= 0)
|
||||
; {
|
||||
mov eax,ds:dword ptr[Ld0]
|
||||
mov ecx,ds:dword ptr[Ld1]
|
||||
or ecx,eax
|
||||
js Lp2
|
||||
|
||||
; both points are unclipped
|
||||
|
||||
Lcontinue:
|
||||
|
||||
;
|
||||
; R_ClipEdge (&clipvert, pv1, clip->next);
|
||||
; return;
|
||||
; }
|
||||
; } while ((clip = clip->next) != NULL);
|
||||
mov ebx,ds:dword ptr[cp_next+ebx]
|
||||
test ebx,ebx
|
||||
jnz Lcliploop
|
||||
|
||||
; }
|
||||
|
||||
;// add the edge
|
||||
; R_EmitEdge (pv0, pv1);
|
||||
Lemit:
|
||||
|
||||
;
|
||||
; set integer rounding to ceil mode, set to single precision
|
||||
;
|
||||
; FIXME: do away with by manually extracting integers from floats?
|
||||
; FIXME: set less often
|
||||
fldcw ds:word ptr[_fpu_ceil_cw]
|
||||
|
||||
; edge_t *edge, *pcheck;
|
||||
; int u_check;
|
||||
; float u, u_step;
|
||||
; vec3_t local, transformed;
|
||||
; float *world;
|
||||
; int v, v2, ceilv0;
|
||||
; float scale, lzi0, u0, v0;
|
||||
; int side;
|
||||
|
||||
; if (r_lastvertvalid)
|
||||
; {
|
||||
cmp ds:dword ptr[_r_lastvertvalid],0
|
||||
jz LCalcFirst
|
||||
|
||||
; u0 = r_u1;
|
||||
; v0 = r_v1;
|
||||
; lzi0 = r_lzi1;
|
||||
; ceilv0 = r_ceilv1;
|
||||
mov eax,ds:dword ptr[_r_lzi1]
|
||||
mov ecx,ds:dword ptr[_r_u1]
|
||||
mov ds:dword ptr[Lzi0],eax
|
||||
mov ds:dword ptr[Lu0],ecx
|
||||
mov ecx,ds:dword ptr[_r_v1]
|
||||
mov eax,ds:dword ptr[_r_ceilv1]
|
||||
mov ds:dword ptr[Lv0],ecx
|
||||
mov ds:dword ptr[Lceilv0],eax
|
||||
jmp LCalcSecond
|
||||
|
||||
; }
|
||||
|
||||
LCalcFirst:
|
||||
|
||||
; else
|
||||
; {
|
||||
; world = &pv0->position[0];
|
||||
|
||||
call near ptr LTransformAndProject ; v0 | lzi0 | u0
|
||||
|
||||
fst ds:dword ptr[Lv0]
|
||||
fxch st(2) ; u0 | lzi0 | v0
|
||||
fstp ds:dword ptr[Lu0] ; lzi0 | v0
|
||||
fstp ds:dword ptr[Lzi0] ; v0
|
||||
|
||||
; ceilv0 = (int)(v0 - 2000) + 2000; // ceil(v0);
|
||||
fistp ds:dword ptr[Lceilv0]
|
||||
|
||||
; }
|
||||
|
||||
LCalcSecond:
|
||||
|
||||
; world = &pv1->position[0];
|
||||
mov esi,edx
|
||||
|
||||
call near ptr LTransformAndProject ; v1 | lzi1 | u1
|
||||
|
||||
fld ds:dword ptr[Lu0] ; u0 | v1 | lzi1 | u1
|
||||
fxch st(3) ; u1 | v1 | lzi1 | u0
|
||||
fld ds:dword ptr[Lzi0] ; lzi0 | u1 | v1 | lzi1 | u0
|
||||
fxch st(3) ; lzi1 | u1 | v1 | lzi0 | u0
|
||||
fld ds:dword ptr[Lv0] ; v0 | lzi1 | u1 | v1 | lzi0 | u0
|
||||
fxch st(3) ; v1 | lzi1 | u1 | v0 | lzi0 | u0
|
||||
|
||||
; r_ceilv1 = (int)(r_v1 - 2000) + 2000; // ceil(r_v1);
|
||||
fist ds:dword ptr[_r_ceilv1]
|
||||
|
||||
fldcw ds:word ptr[_fpu_chop_cw] ; put back normal floating-point state
|
||||
|
||||
fst ds:dword ptr[_r_v1]
|
||||
fxch st(4) ; lzi0 | lzi1 | u1 | v0 | v1 | u0
|
||||
|
||||
; if (r_lzi1 > lzi0)
|
||||
; lzi0 = r_lzi1;
|
||||
fcom st(1)
|
||||
fnstsw ax
|
||||
test ah,1
|
||||
jz LP0
|
||||
fstp st(0)
|
||||
fld st(0)
|
||||
LP0:
|
||||
|
||||
fxch st(1) ; lzi1 | lzi0 | u1 | v0 | v1 | u0
|
||||
fstp ds:dword ptr[_r_lzi1] ; lzi0 | u1 | v0 | v1 | u0
|
||||
fxch st(1)
|
||||
fst ds:dword ptr[_r_u1]
|
||||
fxch st(1)
|
||||
|
||||
; if (lzi0 > r_nearzi) // for mipmap finding
|
||||
; r_nearzi = lzi0;
|
||||
fcom ds:dword ptr[_r_nearzi]
|
||||
fnstsw ax
|
||||
test ah,045h
|
||||
jnz LP1
|
||||
fst ds:dword ptr[_r_nearzi]
|
||||
LP1:
|
||||
|
||||
; // for right edges, all we want is the effect on 1/z
|
||||
; if (r_nearzionly)
|
||||
; return;
|
||||
mov eax,ds:dword ptr[_r_nearzionly]
|
||||
test eax,eax
|
||||
jz LP2
|
||||
LPop5AndDone:
|
||||
mov eax,ds:dword ptr[_cacheoffset]
|
||||
mov edx,ds:dword ptr[_r_framecount]
|
||||
cmp eax,07FFFFFFFh
|
||||
jz LDoPop
|
||||
and edx,offset FRAMECOUNT_MASK
|
||||
or edx,offset FULLY_CLIPPED_CACHED
|
||||
mov ds:dword ptr[_cacheoffset],edx
|
||||
|
||||
LDoPop:
|
||||
fstp st(0) ; u1 | v0 | v1 | u0
|
||||
fstp st(0) ; v0 | v1 | u0
|
||||
fstp st(0) ; v1 | u0
|
||||
fstp st(0) ; u0
|
||||
fstp st(0)
|
||||
jmp Ldone
|
||||
|
||||
LP2:
|
||||
|
||||
; // create the edge
|
||||
; if (ceilv0 == r_ceilv1)
|
||||
; return; // horizontal edge
|
||||
mov ebx,ds:dword ptr[Lceilv0]
|
||||
mov edi,ds:dword ptr[_edge_p]
|
||||
mov ecx,ds:dword ptr[_r_ceilv1]
|
||||
mov edx,edi
|
||||
mov esi,ds:dword ptr[_r_pedge]
|
||||
add edx,offset et_size
|
||||
cmp ebx,ecx
|
||||
jz LPop5AndDone
|
||||
|
||||
mov eax,ds:dword ptr[_r_pedge]
|
||||
mov ds:dword ptr[et_owner+edi],eax
|
||||
|
||||
; side = ceilv0 > r_ceilv1;
|
||||
;
|
||||
; edge->nearzi = lzi0;
|
||||
fstp ds:dword ptr[et_nearzi+edi] ; u1 | v0 | v1 | u0
|
||||
|
||||
; if (side == 1)
|
||||
; {
|
||||
jc LSide0
|
||||
|
||||
LSide1:
|
||||
|
||||
; // leading edge (go from p2 to p1)
|
||||
|
||||
; u_step = ((u0 - r_u1) / (v0 - r_v1));
|
||||
fsubp st(3),st(0) ; v0 | v1 | u0-u1
|
||||
fsub st(0),st(1) ; v0-v1 | v1 | u0-u1
|
||||
fdivp st(2),st(0) ; v1 | ustep
|
||||
|
||||
; r_emitted = 1;
|
||||
mov ds:dword ptr[_r_emitted],1
|
||||
|
||||
; edge = edge_p++;
|
||||
mov ds:dword ptr[_edge_p],edx
|
||||
|
||||
; pretouch next edge
|
||||
mov eax,ds:dword ptr[edx]
|
||||
|
||||
; v2 = ceilv0 - 1;
|
||||
; v = r_ceilv1;
|
||||
mov eax,ecx
|
||||
lea ecx,ds:dword ptr[-1+ebx]
|
||||
mov ebx,eax
|
||||
|
||||
; edge->surfs[0] = 0;
|
||||
; edge->surfs[1] = surface_p - surfaces;
|
||||
mov eax,ds:dword ptr[_surface_p]
|
||||
mov esi,ds:dword ptr[_surfaces]
|
||||
sub edx,edx
|
||||
sub eax,esi
|
||||
shr eax,offset SURF_T_SHIFT
|
||||
mov ds:dword ptr[et_surfs+edi],edx
|
||||
mov ds:dword ptr[et_surfs+2+edi],eax
|
||||
|
||||
sub esi,esi
|
||||
|
||||
; u = r_u1 + ((float)v - r_v1) * u_step;
|
||||
mov ds:dword ptr[Lv],ebx
|
||||
fild ds:dword ptr[Lv] ; v | v1 | ustep
|
||||
fsubrp st(1),st(0) ; v-v1 | ustep
|
||||
fmul st(0),st(1) ; (v-v1)*ustep | ustep
|
||||
fadd ds:dword ptr[_r_u1] ; u | ustep
|
||||
|
||||
jmp LSideDone
|
||||
|
||||
; }
|
||||
|
||||
LSide0:
|
||||
|
||||
; else
|
||||
; {
|
||||
; // trailing edge (go from p1 to p2)
|
||||
|
||||
; u_step = ((r_u1 - u0) / (r_v1 - v0));
|
||||
fsub st(0),st(3) ; u1-u0 | v0 | v1 | u0
|
||||
fxch st(2) ; v1 | v0 | u1-u0 | u0
|
||||
fsub st(0),st(1) ; v1-v0 | v0 | u1-u0 | u0
|
||||
fdivp st(2),st(0) ; v0 | ustep | u0
|
||||
|
||||
; r_emitted = 1;
|
||||
mov ds:dword ptr[_r_emitted],1
|
||||
|
||||
; edge = edge_p++;
|
||||
mov ds:dword ptr[_edge_p],edx
|
||||
|
||||
; pretouch next edge
|
||||
mov eax,ds:dword ptr[edx]
|
||||
|
||||
; v = ceilv0;
|
||||
; v2 = r_ceilv1 - 1;
|
||||
dec ecx
|
||||
|
||||
; edge->surfs[0] = surface_p - surfaces;
|
||||
; edge->surfs[1] = 0;
|
||||
mov eax,ds:dword ptr[_surface_p]
|
||||
mov esi,ds:dword ptr[_surfaces]
|
||||
sub edx,edx
|
||||
sub eax,esi
|
||||
shr eax,offset SURF_T_SHIFT
|
||||
mov ds:dword ptr[et_surfs+2+edi],edx
|
||||
mov ds:dword ptr[et_surfs+edi],eax
|
||||
|
||||
mov esi,1
|
||||
|
||||
; u = u0 + ((float)v - v0) * u_step;
|
||||
mov ds:dword ptr[Lv],ebx
|
||||
fild ds:dword ptr[Lv] ; v | v0 | ustep | u0
|
||||
fsubrp st(1),st(0) ; v-v0 | ustep | u0
|
||||
fmul st(0),st(1) ; (v-v0)*ustep | ustep | u0
|
||||
faddp st(2),st(0) ; ustep | u
|
||||
fxch st(1) ; u | ustep
|
||||
|
||||
; }
|
||||
|
||||
LSideDone:
|
||||
|
||||
; edge->u_step = u_step*0x100000;
|
||||
; edge->u = u*0x100000 + 0xFFFFF;
|
||||
|
||||
fmul ds:dword ptr[fp_1m] ; u*0x100000 | ustep
|
||||
fxch st(1) ; ustep | u*0x100000
|
||||
fmul ds:dword ptr[fp_1m] ; ustep*0x100000 | u*0x100000
|
||||
fxch st(1) ; u*0x100000 | ustep*0x100000
|
||||
fadd ds:dword ptr[fp_1m_minus_1] ; u*0x100000 + 0xFFFFF | ustep*0x100000
|
||||
fxch st(1) ; ustep*0x100000 | u*0x100000 + 0xFFFFF
|
||||
fistp ds:dword ptr[et_u_step+edi] ; u*0x100000 + 0xFFFFF
|
||||
fistp ds:dword ptr[et_u+edi]
|
||||
|
||||
; // we need to do this to avoid stepping off the edges if a very nearly
|
||||
; // horizontal edge is less than epsilon above a scan, and numeric error
|
||||
; // causes it to incorrectly extend to the scan, and the extension of the
|
||||
; // line goes off the edge of the screen
|
||||
; // FIXME: is this actually needed?
|
||||
; if (edge->u < r_refdef.vrect_x_adj_shift20)
|
||||
; edge->u = r_refdef.vrect_x_adj_shift20;
|
||||
; if (edge->u > r_refdef.vrectright_adj_shift20)
|
||||
; edge->u = r_refdef.vrectright_adj_shift20;
|
||||
mov eax,ds:dword ptr[et_u+edi]
|
||||
mov edx,ds:dword ptr[_r_refdef+rd_vrect_x_adj_shift20]
|
||||
cmp eax,edx
|
||||
jl LP4
|
||||
mov edx,ds:dword ptr[_r_refdef+rd_vrectright_adj_shift20]
|
||||
cmp eax,edx
|
||||
jng LP5
|
||||
LP4:
|
||||
mov ds:dword ptr[et_u+edi],edx
|
||||
mov eax,edx
|
||||
LP5:
|
||||
|
||||
; // sort the edge in normally
|
||||
; u_check = edge->u;
|
||||
;
|
||||
; if (edge->surfs[0])
|
||||
; u_check++; // sort trailers after leaders
|
||||
add eax,esi
|
||||
|
||||
; if (!newedges[v] || newedges[v]->u >= u_check)
|
||||
; {
|
||||
mov esi,ds:dword ptr[_newedges+ebx*4]
|
||||
test esi,esi
|
||||
jz LDoFirst
|
||||
cmp ds:dword ptr[et_u+esi],eax
|
||||
jl LNotFirst
|
||||
LDoFirst:
|
||||
|
||||
; edge->next = newedges[v];
|
||||
; newedges[v] = edge;
|
||||
mov ds:dword ptr[et_next+edi],esi
|
||||
mov ds:dword ptr[_newedges+ebx*4],edi
|
||||
|
||||
jmp LSetRemove
|
||||
|
||||
; }
|
||||
|
||||
LNotFirst:
|
||||
|
||||
; else
|
||||
; {
|
||||
; pcheck = newedges[v];
|
||||
;
|
||||
; while (pcheck->next && pcheck->next->u < u_check)
|
||||
; pcheck = pcheck->next;
|
||||
LFindInsertLoop:
|
||||
mov edx,esi
|
||||
mov esi,ds:dword ptr[et_next+esi]
|
||||
test esi,esi
|
||||
jz LInsertFound
|
||||
cmp ds:dword ptr[et_u+esi],eax
|
||||
jl LFindInsertLoop
|
||||
|
||||
LInsertFound:
|
||||
|
||||
; edge->next = pcheck->next;
|
||||
; pcheck->next = edge;
|
||||
mov ds:dword ptr[et_next+edi],esi
|
||||
mov ds:dword ptr[et_next+edx],edi
|
||||
|
||||
; }
|
||||
|
||||
LSetRemove:
|
||||
|
||||
; edge->nextremove = removeedges[v2];
|
||||
; removeedges[v2] = edge;
|
||||
mov eax,ds:dword ptr[_removeedges+ecx*4]
|
||||
mov ds:dword ptr[_removeedges+ecx*4],edi
|
||||
mov ds:dword ptr[et_nextremove+edi],eax
|
||||
|
||||
Ldone:
|
||||
mov esp,ds:dword ptr[Lstack] ; clear temporary variables from stack
|
||||
|
||||
pop ebx ; restore register variables
|
||||
pop edi
|
||||
pop esi
|
||||
ret
|
||||
|
||||
; at least one point is clipped
|
||||
|
||||
Lp2:
|
||||
test eax,eax
|
||||
jns Lp1
|
||||
|
||||
; else
|
||||
; {
|
||||
; // point 0 is clipped
|
||||
|
||||
; if (d1 < 0)
|
||||
; {
|
||||
mov eax,ds:dword ptr[Ld1]
|
||||
test eax,eax
|
||||
jns Lp3
|
||||
|
||||
; // both points are clipped
|
||||
; // we do cache fully clipped edges
|
||||
; if (!leftclipped)
|
||||
mov eax,ds:dword ptr[_r_leftclipped]
|
||||
mov ecx,ds:dword ptr[_r_pedge]
|
||||
test eax,eax
|
||||
jnz Ldone
|
||||
|
||||
; r_pedge->framecount = r_framecount;
|
||||
mov eax,ds:dword ptr[_r_framecount]
|
||||
and eax,offset FRAMECOUNT_MASK
|
||||
or eax,offset FULLY_CLIPPED_CACHED
|
||||
mov ds:dword ptr[_cacheoffset],eax
|
||||
|
||||
; return;
|
||||
jmp Ldone
|
||||
|
||||
; }
|
||||
|
||||
Lp1:
|
||||
|
||||
; // point 0 is unclipped
|
||||
; if (d1 >= 0)
|
||||
; {
|
||||
; // both points are unclipped
|
||||
; continue;
|
||||
|
||||
; // only point 1 is clipped
|
||||
|
||||
; f = d0 / (d0 - d1);
|
||||
fld ds:dword ptr[Ld0]
|
||||
fld ds:dword ptr[Ld1]
|
||||
fsubr st(0),st(1)
|
||||
|
||||
; // we don't cache partially clipped edges
|
||||
mov ds:dword ptr[_cacheoffset],07FFFFFFFh
|
||||
|
||||
fdivp st(1),st(0)
|
||||
|
||||
sub esp,offset mv_size ; allocate space for clipvert
|
||||
|
||||
; clipvert.position[0] = pv0->position[0] +
|
||||
; f * (pv1->position[0] - pv0->position[0]);
|
||||
; clipvert.position[1] = pv0->position[1] +
|
||||
; f * (pv1->position[1] - pv0->position[1]);
|
||||
; clipvert.position[2] = pv0->position[2] +
|
||||
; f * (pv1->position[2] - pv0->position[2]);
|
||||
fld ds:dword ptr[mv_position+8+edx]
|
||||
fsub ds:dword ptr[mv_position+8+esi]
|
||||
fld ds:dword ptr[mv_position+4+edx]
|
||||
fsub ds:dword ptr[mv_position+4+esi]
|
||||
fld ds:dword ptr[mv_position+0+edx]
|
||||
fsub ds:dword ptr[mv_position+0+esi] ; 0 | 1 | 2
|
||||
|
||||
; replace pv1 with the clip point
|
||||
mov edx,esp
|
||||
mov eax,ds:dword ptr[cp_leftedge+ebx]
|
||||
test al,al
|
||||
|
||||
fmul st(0),st(3)
|
||||
fxch st(1) ; 1 | 0 | 2
|
||||
fmul st(0),st(3)
|
||||
fxch st(2) ; 2 | 0 | 1
|
||||
fmulp st(3),st(0) ; 0 | 1 | 2
|
||||
fadd ds:dword ptr[mv_position+0+esi]
|
||||
fxch st(1) ; 1 | 0 | 2
|
||||
fadd ds:dword ptr[mv_position+4+esi]
|
||||
fxch st(2) ; 2 | 0 | 1
|
||||
fadd ds:dword ptr[mv_position+8+esi]
|
||||
fxch st(1) ; 0 | 2 | 1
|
||||
fstp ds:dword ptr[mv_position+0+esp] ; 2 | 1
|
||||
fstp ds:dword ptr[mv_position+8+esp] ; 1
|
||||
fstp ds:dword ptr[mv_position+4+esp]
|
||||
|
||||
; if (clip->leftedge)
|
||||
; {
|
||||
jz Ltestright
|
||||
|
||||
; r_leftclipped = true;
|
||||
; r_leftexit = clipvert;
|
||||
mov ds:dword ptr[_r_leftclipped],1
|
||||
mov eax,ds:dword ptr[mv_position+0+esp]
|
||||
mov ds:dword ptr[_r_leftexit+mv_position+0],eax
|
||||
mov eax,ds:dword ptr[mv_position+4+esp]
|
||||
mov ds:dword ptr[_r_leftexit+mv_position+4],eax
|
||||
mov eax,ds:dword ptr[mv_position+8+esp]
|
||||
mov ds:dword ptr[_r_leftexit+mv_position+8],eax
|
||||
|
||||
jmp Lcontinue
|
||||
|
||||
; }
|
||||
|
||||
Ltestright:
|
||||
; else if (clip->rightedge)
|
||||
; {
|
||||
test ah,ah
|
||||
jz Lcontinue
|
||||
|
||||
; r_rightclipped = true;
|
||||
; r_rightexit = clipvert;
|
||||
mov ds:dword ptr[_r_rightclipped],1
|
||||
mov eax,ds:dword ptr[mv_position+0+esp]
|
||||
mov ds:dword ptr[_r_rightexit+mv_position+0],eax
|
||||
mov eax,ds:dword ptr[mv_position+4+esp]
|
||||
mov ds:dword ptr[_r_rightexit+mv_position+4],eax
|
||||
mov eax,ds:dword ptr[mv_position+8+esp]
|
||||
mov ds:dword ptr[_r_rightexit+mv_position+8],eax
|
||||
|
||||
; }
|
||||
;
|
||||
; R_ClipEdge (pv0, &clipvert, clip->next);
|
||||
; return;
|
||||
; }
|
||||
jmp Lcontinue
|
||||
|
||||
; }
|
||||
|
||||
Lp3:
|
||||
|
||||
; // only point 0 is clipped
|
||||
; r_lastvertvalid = false;
|
||||
|
||||
mov ds:dword ptr[_r_lastvertvalid],0
|
||||
|
||||
; f = d0 / (d0 - d1);
|
||||
fld ds:dword ptr[Ld0]
|
||||
fld ds:dword ptr[Ld1]
|
||||
fsubr st(0),st(1)
|
||||
|
||||
; // we don't cache partially clipped edges
|
||||
mov ds:dword ptr[_cacheoffset],07FFFFFFFh
|
||||
|
||||
fdivp st(1),st(0)
|
||||
|
||||
sub esp,offset mv_size ; allocate space for clipvert
|
||||
|
||||
; clipvert.position[0] = pv0->position[0] +
|
||||
; f * (pv1->position[0] - pv0->position[0]);
|
||||
; clipvert.position[1] = pv0->position[1] +
|
||||
; f * (pv1->position[1] - pv0->position[1]);
|
||||
; clipvert.position[2] = pv0->position[2] +
|
||||
; f * (pv1->position[2] - pv0->position[2]);
|
||||
fld ds:dword ptr[mv_position+8+edx]
|
||||
fsub ds:dword ptr[mv_position+8+esi]
|
||||
fld ds:dword ptr[mv_position+4+edx]
|
||||
fsub ds:dword ptr[mv_position+4+esi]
|
||||
fld ds:dword ptr[mv_position+0+edx]
|
||||
fsub ds:dword ptr[mv_position+0+esi] ; 0 | 1 | 2
|
||||
|
||||
mov eax,ds:dword ptr[cp_leftedge+ebx]
|
||||
test al,al
|
||||
|
||||
fmul st(0),st(3)
|
||||
fxch st(1) ; 1 | 0 | 2
|
||||
fmul st(0),st(3)
|
||||
fxch st(2) ; 2 | 0 | 1
|
||||
fmulp st(3),st(0) ; 0 | 1 | 2
|
||||
fadd ds:dword ptr[mv_position+0+esi]
|
||||
fxch st(1) ; 1 | 0 | 2
|
||||
fadd ds:dword ptr[mv_position+4+esi]
|
||||
fxch st(2) ; 2 | 0 | 1
|
||||
fadd ds:dword ptr[mv_position+8+esi]
|
||||
fxch st(1) ; 0 | 2 | 1
|
||||
fstp ds:dword ptr[mv_position+0+esp] ; 2 | 1
|
||||
fstp ds:dword ptr[mv_position+8+esp] ; 1
|
||||
fstp ds:dword ptr[mv_position+4+esp]
|
||||
|
||||
; replace pv0 with the clip point
|
||||
mov esi,esp
|
||||
|
||||
; if (clip->leftedge)
|
||||
; {
|
||||
jz Ltestright2
|
||||
|
||||
; r_leftclipped = true;
|
||||
; r_leftenter = clipvert;
|
||||
mov ds:dword ptr[_r_leftclipped],1
|
||||
mov eax,ds:dword ptr[mv_position+0+esp]
|
||||
mov ds:dword ptr[_r_leftenter+mv_position+0],eax
|
||||
mov eax,ds:dword ptr[mv_position+4+esp]
|
||||
mov ds:dword ptr[_r_leftenter+mv_position+4],eax
|
||||
mov eax,ds:dword ptr[mv_position+8+esp]
|
||||
mov ds:dword ptr[_r_leftenter+mv_position+8],eax
|
||||
|
||||
jmp Lcontinue
|
||||
|
||||
; }
|
||||
|
||||
Ltestright2:
|
||||
; else if (clip->rightedge)
|
||||
; {
|
||||
test ah,ah
|
||||
jz Lcontinue
|
||||
|
||||
; r_rightclipped = true;
|
||||
; r_rightenter = clipvert;
|
||||
mov ds:dword ptr[_r_rightclipped],1
|
||||
mov eax,ds:dword ptr[mv_position+0+esp]
|
||||
mov ds:dword ptr[_r_rightenter+mv_position+0],eax
|
||||
mov eax,ds:dword ptr[mv_position+4+esp]
|
||||
mov ds:dword ptr[_r_rightenter+mv_position+4],eax
|
||||
mov eax,ds:dword ptr[mv_position+8+esp]
|
||||
mov ds:dword ptr[_r_rightenter+mv_position+8],eax
|
||||
|
||||
; }
|
||||
jmp Lcontinue
|
||||
|
||||
; %esi = vec3_t point to transform and project
|
||||
; %edx preserved
|
||||
LTransformAndProject:
|
||||
|
||||
; // transform and project
|
||||
; VectorSubtract (world, modelorg, local);
|
||||
fld ds:dword ptr[mv_position+0+esi]
|
||||
fsub ds:dword ptr[_modelorg+0]
|
||||
fld ds:dword ptr[mv_position+4+esi]
|
||||
fsub ds:dword ptr[_modelorg+4]
|
||||
fld ds:dword ptr[mv_position+8+esi]
|
||||
fsub ds:dword ptr[_modelorg+8]
|
||||
fxch st(2) ; local[0] | local[1] | local[2]
|
||||
|
||||
; TransformVector (local, transformed);
|
||||
;
|
||||
; if (transformed[2] < NEAR_CLIP)
|
||||
; transformed[2] = NEAR_CLIP;
|
||||
;
|
||||
; lzi0 = 1.0 / transformed[2];
|
||||
fld st(0) ; local[0] | local[0] | local[1] | local[2]
|
||||
fmul ds:dword ptr[_vpn+0] ; zm0 | local[0] | local[1] | local[2]
|
||||
fld st(1) ; local[0] | zm0 | local[0] | local[1] |
|
||||
; local[2]
|
||||
fmul ds:dword ptr[_vright+0] ; xm0 | zm0 | local[0] | local[1] | local[2]
|
||||
fxch st(2) ; local[0] | zm0 | xm0 | local[1] | local[2]
|
||||
fmul ds:dword ptr[_vup+0] ; ym0 | zm0 | xm0 | local[1] | local[2]
|
||||
fld st(3) ; local[1] | ym0 | zm0 | xm0 | local[1] |
|
||||
; local[2]
|
||||
fmul ds:dword ptr[_vpn+4] ; zm1 | ym0 | zm0 | xm0 | local[1] |
|
||||
; local[2]
|
||||
fld st(4) ; local[1] | zm1 | ym0 | zm0 | xm0 |
|
||||
; local[1] | local[2]
|
||||
fmul ds:dword ptr[_vright+4] ; xm1 | zm1 | ym0 | zm0 | xm0 |
|
||||
; local[1] | local[2]
|
||||
fxch st(5) ; local[1] | zm1 | ym0 | zm0 | xm0 |
|
||||
; xm1 | local[2]
|
||||
fmul ds:dword ptr[_vup+4] ; ym1 | zm1 | ym0 | zm0 | xm0 |
|
||||
; xm1 | local[2]
|
||||
fxch st(1) ; zm1 | ym1 | ym0 | zm0 | xm0 |
|
||||
; xm1 | local[2]
|
||||
faddp st(3),st(0) ; ym1 | ym0 | zm2 | xm0 | xm1 | local[2]
|
||||
fxch st(3) ; xm0 | ym0 | zm2 | ym1 | xm1 | local[2]
|
||||
faddp st(4),st(0) ; ym0 | zm2 | ym1 | xm2 | local[2]
|
||||
faddp st(2),st(0) ; zm2 | ym2 | xm2 | local[2]
|
||||
fld st(3) ; local[2] | zm2 | ym2 | xm2 | local[2]
|
||||
fmul ds:dword ptr[_vpn+8] ; zm3 | zm2 | ym2 | xm2 | local[2]
|
||||
fld st(4) ; local[2] | zm3 | zm2 | ym2 | xm2 | local[2]
|
||||
fmul ds:dword ptr[_vright+8] ; xm3 | zm3 | zm2 | ym2 | xm2 | local[2]
|
||||
fxch st(5) ; local[2] | zm3 | zm2 | ym2 | xm2 | xm3
|
||||
fmul ds:dword ptr[_vup+8] ; ym3 | zm3 | zm2 | ym2 | xm2 | xm3
|
||||
fxch st(1) ; zm3 | ym3 | zm2 | ym2 | xm2 | xm3
|
||||
faddp st(2),st(0) ; ym3 | zm4 | ym2 | xm2 | xm3
|
||||
fxch st(4) ; xm3 | zm4 | ym2 | xm2 | ym3
|
||||
faddp st(3),st(0) ; zm4 | ym2 | xm4 | ym3
|
||||
fxch st(1) ; ym2 | zm4 | xm4 | ym3
|
||||
faddp st(3),st(0) ; zm4 | xm4 | ym4
|
||||
|
||||
fcom ds:dword ptr[Lfp_near_clip]
|
||||
fnstsw ax
|
||||
test ah,1
|
||||
jz LNoClip
|
||||
fstp st(0)
|
||||
fld ds:dword ptr[Lfp_near_clip]
|
||||
|
||||
LNoClip:
|
||||
|
||||
fdivr ds:dword ptr[float_1] ; lzi0 | x | y
|
||||
fxch st(1) ; x | lzi0 | y
|
||||
|
||||
; // FIXME: build x/yscale into transform?
|
||||
; scale = xscale * lzi0;
|
||||
; u0 = (xcenter + scale*transformed[0]);
|
||||
fld ds:dword ptr[_xscale] ; xscale | x | lzi0 | y
|
||||
fmul st(0),st(2) ; scale | x | lzi0 | y
|
||||
fmulp st(1),st(0) ; scale*x | lzi0 | y
|
||||
fadd ds:dword ptr[_xcenter] ; u0 | lzi0 | y
|
||||
|
||||
; if (u0 < r_refdef.fvrectx_adj)
|
||||
; u0 = r_refdef.fvrectx_adj;
|
||||
; if (u0 > r_refdef.fvrectright_adj)
|
||||
; u0 = r_refdef.fvrectright_adj;
|
||||
; FIXME: use integer compares of floats?
|
||||
fcom ds:dword ptr[_r_refdef+rd_fvrectx_adj]
|
||||
fnstsw ax
|
||||
test ah,1
|
||||
jz LClampP0
|
||||
fstp st(0)
|
||||
fld ds:dword ptr[_r_refdef+rd_fvrectx_adj]
|
||||
LClampP0:
|
||||
fcom ds:dword ptr[_r_refdef+rd_fvrectright_adj]
|
||||
fnstsw ax
|
||||
test ah,045h
|
||||
jnz LClampP1
|
||||
fstp st(0)
|
||||
fld ds:dword ptr[_r_refdef+rd_fvrectright_adj]
|
||||
LClampP1:
|
||||
|
||||
fld st(1) ; lzi0 | u0 | lzi0 | y
|
||||
|
||||
; scale = yscale * lzi0;
|
||||
; v0 = (ycenter - scale*transformed[1]);
|
||||
fmul ds:dword ptr[_yscale] ; scale | u0 | lzi0 | y
|
||||
fmulp st(3),st(0) ; u0 | lzi0 | scale*y
|
||||
fxch st(2) ; scale*y | lzi0 | u0
|
||||
fsubr ds:dword ptr[_ycenter] ; v0 | lzi0 | u0
|
||||
|
||||
; if (v0 < r_refdef.fvrecty_adj)
|
||||
; v0 = r_refdef.fvrecty_adj;
|
||||
; if (v0 > r_refdef.fvrectbottom_adj)
|
||||
; v0 = r_refdef.fvrectbottom_adj;
|
||||
; FIXME: use integer compares of floats?
|
||||
fcom ds:dword ptr[_r_refdef+rd_fvrecty_adj]
|
||||
fnstsw ax
|
||||
test ah,1
|
||||
jz LClampP2
|
||||
fstp st(0)
|
||||
fld ds:dword ptr[_r_refdef+rd_fvrecty_adj]
|
||||
LClampP2:
|
||||
fcom ds:dword ptr[_r_refdef+rd_fvrectbottom_adj]
|
||||
fnstsw ax
|
||||
test ah,045h
|
||||
jnz LClampP3
|
||||
fstp st(0)
|
||||
fld ds:dword ptr[_r_refdef+rd_fvrectbottom_adj]
|
||||
LClampP3:
|
||||
ret
|
||||
|
||||
|
||||
_TEXT ENDS
|
||||
endif ;id386
|
||||
END
|
1125
ref_soft/r_edge.c
Normal file
1125
ref_soft/r_edge.c
Normal file
File diff suppressed because it is too large
Load Diff
733
ref_soft/r_edgea.asm
Normal file
733
ref_soft/r_edgea.asm
Normal file
@ -0,0 +1,733 @@
|
||||
.386P
|
||||
.model FLAT
|
||||
;
|
||||
; r_edgea.s
|
||||
; x86 assembly-language edge-processing code.
|
||||
;
|
||||
|
||||
include qasm.inc
|
||||
|
||||
if id386
|
||||
|
||||
_DATA SEGMENT
|
||||
Ltemp dd 0
|
||||
float_1_div_0100000h dd 035800000h ; 1.0/(float)0x100000
|
||||
float_point_999 dd 0.999
|
||||
float_1_point_001 dd 1.001
|
||||
|
||||
_DATA ENDS
|
||||
_TEXT SEGMENT
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
|
||||
edgestoadd equ 4+8 ; note odd stack offsets because of interleaving
|
||||
edgelist equ 8+12 ; with pushes
|
||||
|
||||
public _R_EdgeCodeStart
|
||||
_R_EdgeCodeStart:
|
||||
|
||||
public _R_InsertNewEdges
|
||||
_R_InsertNewEdges:
|
||||
push edi
|
||||
push esi ; preserve register variables
|
||||
mov edx,ds:dword ptr[edgestoadd+esp]
|
||||
push ebx
|
||||
mov ecx,ds:dword ptr[edgelist+esp]
|
||||
|
||||
LDoNextEdge:
|
||||
mov eax,ds:dword ptr[et_u+edx]
|
||||
mov edi,edx
|
||||
|
||||
LContinueSearch:
|
||||
mov ebx,ds:dword ptr[et_u+ecx]
|
||||
mov esi,ds:dword ptr[et_next+ecx]
|
||||
cmp eax,ebx
|
||||
jle LAddedge
|
||||
mov ebx,ds:dword ptr[et_u+esi]
|
||||
mov ecx,ds:dword ptr[et_next+esi]
|
||||
cmp eax,ebx
|
||||
jle LAddedge2
|
||||
mov ebx,ds:dword ptr[et_u+ecx]
|
||||
mov esi,ds:dword ptr[et_next+ecx]
|
||||
cmp eax,ebx
|
||||
jle LAddedge
|
||||
mov ebx,ds:dword ptr[et_u+esi]
|
||||
mov ecx,ds:dword ptr[et_next+esi]
|
||||
cmp eax,ebx
|
||||
jg LContinueSearch
|
||||
|
||||
LAddedge2:
|
||||
mov edx,ds:dword ptr[et_next+edx]
|
||||
mov ebx,ds:dword ptr[et_prev+esi]
|
||||
mov ds:dword ptr[et_next+edi],esi
|
||||
mov ds:dword ptr[et_prev+edi],ebx
|
||||
mov ds:dword ptr[et_next+ebx],edi
|
||||
mov ds:dword ptr[et_prev+esi],edi
|
||||
mov ecx,esi
|
||||
|
||||
cmp edx,0
|
||||
jnz LDoNextEdge
|
||||
jmp LDone
|
||||
|
||||
align 4
|
||||
LAddedge:
|
||||
mov edx,ds:dword ptr[et_next+edx]
|
||||
mov ebx,ds:dword ptr[et_prev+ecx]
|
||||
mov ds:dword ptr[et_next+edi],ecx
|
||||
mov ds:dword ptr[et_prev+edi],ebx
|
||||
mov ds:dword ptr[et_next+ebx],edi
|
||||
mov ds:dword ptr[et_prev+ecx],edi
|
||||
|
||||
cmp edx,0
|
||||
jnz LDoNextEdge
|
||||
|
||||
LDone:
|
||||
pop ebx ; restore register variables
|
||||
pop esi
|
||||
pop edi
|
||||
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
|
||||
predge equ 4+4
|
||||
|
||||
public _R_RemoveEdges
|
||||
_R_RemoveEdges:
|
||||
push ebx
|
||||
mov eax,ds:dword ptr[predge+esp]
|
||||
|
||||
Lre_loop:
|
||||
mov ecx,ds:dword ptr[et_next+eax]
|
||||
mov ebx,ds:dword ptr[et_nextremove+eax]
|
||||
mov edx,ds:dword ptr[et_prev+eax]
|
||||
test ebx,ebx
|
||||
mov ds:dword ptr[et_prev+ecx],edx
|
||||
jz Lre_done
|
||||
mov ds:dword ptr[et_next+edx],ecx
|
||||
|
||||
mov ecx,ds:dword ptr[et_next+ebx]
|
||||
mov edx,ds:dword ptr[et_prev+ebx]
|
||||
mov eax,ds:dword ptr[et_nextremove+ebx]
|
||||
mov ds:dword ptr[et_prev+ecx],edx
|
||||
test eax,eax
|
||||
mov ds:dword ptr[et_next+edx],ecx
|
||||
jnz Lre_loop
|
||||
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
Lre_done:
|
||||
mov ds:dword ptr[et_next+edx],ecx
|
||||
pop ebx
|
||||
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
|
||||
pedgelist equ 4+4 ; note odd stack offset because of interleaving
|
||||
; with pushes
|
||||
|
||||
public _R_StepActiveU
|
||||
_R_StepActiveU:
|
||||
push edi
|
||||
mov edx,ds:dword ptr[pedgelist+esp]
|
||||
push esi ; preserve register variables
|
||||
push ebx
|
||||
|
||||
mov esi,ds:dword ptr[et_prev+edx]
|
||||
|
||||
LNewEdge:
|
||||
mov edi,ds:dword ptr[et_u+esi]
|
||||
|
||||
LNextEdge:
|
||||
mov eax,ds:dword ptr[et_u+edx]
|
||||
mov ebx,ds:dword ptr[et_u_step+edx]
|
||||
add eax,ebx
|
||||
mov esi,ds:dword ptr[et_next+edx]
|
||||
mov ds:dword ptr[et_u+edx],eax
|
||||
cmp eax,edi
|
||||
jl LPushBack
|
||||
|
||||
mov edi,ds:dword ptr[et_u+esi]
|
||||
mov ebx,ds:dword ptr[et_u_step+esi]
|
||||
add edi,ebx
|
||||
mov edx,ds:dword ptr[et_next+esi]
|
||||
mov ds:dword ptr[et_u+esi],edi
|
||||
cmp edi,eax
|
||||
jl LPushBack2
|
||||
|
||||
mov eax,ds:dword ptr[et_u+edx]
|
||||
mov ebx,ds:dword ptr[et_u_step+edx]
|
||||
add eax,ebx
|
||||
mov esi,ds:dword ptr[et_next+edx]
|
||||
mov ds:dword ptr[et_u+edx],eax
|
||||
cmp eax,edi
|
||||
jl LPushBack
|
||||
|
||||
mov edi,ds:dword ptr[et_u+esi]
|
||||
mov ebx,ds:dword ptr[et_u_step+esi]
|
||||
add edi,ebx
|
||||
mov edx,ds:dword ptr[et_next+esi]
|
||||
mov ds:dword ptr[et_u+esi],edi
|
||||
cmp edi,eax
|
||||
jnl LNextEdge
|
||||
|
||||
LPushBack2:
|
||||
mov ebx,edx
|
||||
mov eax,edi
|
||||
mov edx,esi
|
||||
mov esi,ebx
|
||||
|
||||
LPushBack:
|
||||
; push it back to keep it sorted
|
||||
mov ecx,ds:dword ptr[et_prev+edx]
|
||||
mov ebx,ds:dword ptr[et_next+edx]
|
||||
|
||||
; done if the -1 in edge_aftertail triggered this
|
||||
cmp edx,offset _edge_aftertail
|
||||
jz LUDone
|
||||
|
||||
; pull the edge out of the edge list
|
||||
mov edi,ds:dword ptr[et_prev+ecx]
|
||||
mov ds:dword ptr[et_prev+esi],ecx
|
||||
mov ds:dword ptr[et_next+ecx],ebx
|
||||
|
||||
; find out where the edge goes in the edge list
|
||||
LPushBackLoop:
|
||||
mov ecx,ds:dword ptr[et_prev+edi]
|
||||
mov ebx,ds:dword ptr[et_u+edi]
|
||||
cmp eax,ebx
|
||||
jnl LPushBackFound
|
||||
|
||||
mov edi,ds:dword ptr[et_prev+ecx]
|
||||
mov ebx,ds:dword ptr[et_u+ecx]
|
||||
cmp eax,ebx
|
||||
jl LPushBackLoop
|
||||
|
||||
mov edi,ecx
|
||||
|
||||
; put the edge back into the edge list
|
||||
LPushBackFound:
|
||||
mov ebx,ds:dword ptr[et_next+edi]
|
||||
mov ds:dword ptr[et_prev+edx],edi
|
||||
mov ds:dword ptr[et_next+edx],ebx
|
||||
mov ds:dword ptr[et_next+edi],edx
|
||||
mov ds:dword ptr[et_prev+ebx],edx
|
||||
|
||||
mov edx,esi
|
||||
mov esi,ds:dword ptr[et_prev+esi]
|
||||
|
||||
cmp edx,offset _edge_tail
|
||||
jnz LNewEdge
|
||||
|
||||
LUDone:
|
||||
pop ebx ; restore register variables
|
||||
pop esi
|
||||
pop edi
|
||||
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
|
||||
surf equ 4 ; note this is loaded before any pushes
|
||||
|
||||
align 4
|
||||
TrailingEdge:
|
||||
mov eax,ds:dword ptr[st_spanstate+esi] ; check for edge inversion
|
||||
dec eax
|
||||
jnz LInverted
|
||||
|
||||
mov ds:dword ptr[st_spanstate+esi],eax
|
||||
mov ecx,ds:dword ptr[st_insubmodel+esi]
|
||||
mov edx,ds:dword ptr[12345678h] ; surfaces[1].st_next
|
||||
LPatch0:
|
||||
mov eax,ds:dword ptr[_r_bmodelactive]
|
||||
sub eax,ecx
|
||||
cmp edx,esi
|
||||
mov ds:dword ptr[_r_bmodelactive],eax
|
||||
jnz LNoEmit ; surface isn't on top, just remove
|
||||
|
||||
; emit a span (current top going away)
|
||||
mov eax,ds:dword ptr[et_u+ebx]
|
||||
shr eax,20 ; iu = integral pixel u
|
||||
mov edx,ds:dword ptr[st_last_u+esi]
|
||||
mov ecx,ds:dword ptr[st_next+esi]
|
||||
cmp eax,edx
|
||||
jle LNoEmit2 ; iu <= surf->last_u, so nothing to emit
|
||||
|
||||
mov ds:dword ptr[st_last_u+ecx],eax ; surf->next->last_u = iu;
|
||||
sub eax,edx
|
||||
mov ds:dword ptr[espan_t_u+ebp],edx ; span->u = surf->last_u;
|
||||
|
||||
mov ds:dword ptr[espan_t_count+ebp],eax ; span->count = iu - span->u;
|
||||
mov eax,ds:dword ptr[_current_iv]
|
||||
mov ds:dword ptr[espan_t_v+ebp],eax ; span->v = current_iv;
|
||||
mov eax,ds:dword ptr[st_spans+esi]
|
||||
mov ds:dword ptr[espan_t_pnext+ebp],eax ; span->pnext = surf->spans;
|
||||
mov ds:dword ptr[st_spans+esi],ebp ; surf->spans = span;
|
||||
add ebp,offset espan_t_size
|
||||
|
||||
mov edx,ds:dword ptr[st_next+esi] ; remove the surface from the surface
|
||||
mov esi,ds:dword ptr[st_prev+esi] ; stack
|
||||
|
||||
mov ds:dword ptr[st_next+esi],edx
|
||||
mov ds:dword ptr[st_prev+edx],esi
|
||||
ret
|
||||
|
||||
LNoEmit2:
|
||||
mov ds:dword ptr[st_last_u+ecx],eax ; surf->next->last_u = iu;
|
||||
mov edx,ds:dword ptr[st_next+esi] ; remove the surface from the surface
|
||||
mov esi,ds:dword ptr[st_prev+esi] ; stack
|
||||
|
||||
mov ds:dword ptr[st_next+esi],edx
|
||||
mov ds:dword ptr[st_prev+edx],esi
|
||||
ret
|
||||
|
||||
LNoEmit:
|
||||
mov edx,ds:dword ptr[st_next+esi] ; remove the surface from the surface
|
||||
mov esi,ds:dword ptr[st_prev+esi] ; stack
|
||||
|
||||
mov ds:dword ptr[st_next+esi],edx
|
||||
mov ds:dword ptr[st_prev+edx],esi
|
||||
ret
|
||||
|
||||
LInverted:
|
||||
mov ds:dword ptr[st_spanstate+esi],eax
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
|
||||
; trailing edge only
|
||||
Lgs_trailing:
|
||||
push offset Lgs_nextedge
|
||||
jmp TrailingEdge
|
||||
|
||||
|
||||
public _R_GenerateSpans
|
||||
_R_GenerateSpans:
|
||||
push ebp ; preserve caller's stack frame
|
||||
push edi
|
||||
push esi ; preserve register variables
|
||||
push ebx
|
||||
|
||||
; clear active surfaces to just the background surface
|
||||
mov eax,ds:dword ptr[_surfaces]
|
||||
mov edx,ds:dword ptr[_edge_head_u_shift20]
|
||||
add eax,offset st_size
|
||||
; %ebp = span_p throughout
|
||||
mov ebp,ds:dword ptr[_span_p]
|
||||
|
||||
mov ds:dword ptr[_r_bmodelactive],0
|
||||
|
||||
mov ds:dword ptr[st_next+eax],eax
|
||||
mov ds:dword ptr[st_prev+eax],eax
|
||||
mov ds:dword ptr[st_last_u+eax],edx
|
||||
mov ebx,ds:dword ptr[_edge_head+et_next] ; edge=edge_head.next
|
||||
|
||||
; generate spans
|
||||
cmp ebx,offset _edge_tail ; done if empty list
|
||||
jz Lgs_lastspan
|
||||
|
||||
Lgs_edgeloop:
|
||||
|
||||
mov edi,ds:dword ptr[et_surfs+ebx]
|
||||
mov eax,ds:dword ptr[_surfaces]
|
||||
mov esi,edi
|
||||
and edi,0FFFF0000h
|
||||
and esi,0FFFFh
|
||||
jz Lgs_leading ; not a trailing edge
|
||||
|
||||
; it has a left surface, so a surface is going away for this span
|
||||
shl esi,offset SURF_T_SHIFT
|
||||
add esi,eax
|
||||
test edi,edi
|
||||
jz Lgs_trailing
|
||||
|
||||
; both leading and trailing
|
||||
call near ptr TrailingEdge
|
||||
mov eax,ds:dword ptr[_surfaces]
|
||||
|
||||
; ---------------------------------------------------------------
|
||||
; handle a leading edge
|
||||
; ---------------------------------------------------------------
|
||||
|
||||
Lgs_leading:
|
||||
shr edi,16-SURF_T_SHIFT
|
||||
mov eax,ds:dword ptr[_surfaces]
|
||||
add edi,eax
|
||||
mov esi,ds:dword ptr[12345678h] ; surf2 = surfaces[1].next;
|
||||
LPatch2:
|
||||
mov edx,ds:dword ptr[st_spanstate+edi]
|
||||
mov eax,ds:dword ptr[st_insubmodel+edi]
|
||||
test eax,eax
|
||||
jnz Lbmodel_leading
|
||||
|
||||
; handle a leading non-bmodel edge
|
||||
|
||||
; don't start a span if this is an inverted span, with the end edge preceding
|
||||
; the start edge (that is, we've already seen the end edge)
|
||||
test edx,edx
|
||||
jnz Lxl_done
|
||||
|
||||
|
||||
; if (surf->key < surf2->key)
|
||||
; goto newtop;
|
||||
inc edx
|
||||
mov eax,ds:dword ptr[st_key+edi]
|
||||
mov ds:dword ptr[st_spanstate+edi],edx
|
||||
mov ecx,ds:dword ptr[st_key+esi]
|
||||
cmp eax,ecx
|
||||
jl Lnewtop
|
||||
|
||||
; main sorting loop to search through surface stack until insertion point
|
||||
; found. Always terminates because background surface is sentinel
|
||||
; do
|
||||
; {
|
||||
; surf2 = surf2->next;
|
||||
; } while (surf->key >= surf2->key);
|
||||
Lsortloopnb:
|
||||
mov esi,ds:dword ptr[st_next+esi]
|
||||
mov ecx,ds:dword ptr[st_key+esi]
|
||||
cmp eax,ecx
|
||||
jge Lsortloopnb
|
||||
|
||||
jmp LInsertAndExit
|
||||
|
||||
|
||||
; handle a leading bmodel edge
|
||||
align 4
|
||||
Lbmodel_leading:
|
||||
|
||||
; don't start a span if this is an inverted span, with the end edge preceding
|
||||
; the start edge (that is, we've already seen the end edge)
|
||||
test edx,edx
|
||||
jnz Lxl_done
|
||||
|
||||
mov ecx,ds:dword ptr[_r_bmodelactive]
|
||||
inc edx
|
||||
inc ecx
|
||||
mov ds:dword ptr[st_spanstate+edi],edx
|
||||
mov ds:dword ptr[_r_bmodelactive],ecx
|
||||
|
||||
; if (surf->key < surf2->key)
|
||||
; goto newtop;
|
||||
mov eax,ds:dword ptr[st_key+edi]
|
||||
mov ecx,ds:dword ptr[st_key+esi]
|
||||
cmp eax,ecx
|
||||
jl Lnewtop
|
||||
|
||||
; if ((surf->key == surf2->key) && surf->insubmodel)
|
||||
; {
|
||||
jz Lzcheck_for_newtop
|
||||
|
||||
; main sorting loop to search through surface stack until insertion point
|
||||
; found. Always terminates because background surface is sentinel
|
||||
; do
|
||||
; {
|
||||
; surf2 = surf2->next;
|
||||
; } while (surf->key > surf2->key);
|
||||
Lsortloop:
|
||||
mov esi,ds:dword ptr[st_next+esi]
|
||||
mov ecx,ds:dword ptr[st_key+esi]
|
||||
cmp eax,ecx
|
||||
jg Lsortloop
|
||||
|
||||
jne LInsertAndExit
|
||||
|
||||
; Do 1/z sorting to see if we've arrived in the right position
|
||||
mov eax,ds:dword ptr[et_u+ebx]
|
||||
sub eax,0FFFFFh
|
||||
mov ds:dword ptr[Ltemp],eax
|
||||
fild ds:dword ptr[Ltemp]
|
||||
|
||||
fmul ds:dword ptr[float_1_div_0100000h] ; fu = (float)(edge->u - 0xFFFFF) *
|
||||
; (1.0 / 0x100000);
|
||||
|
||||
fld st(0) ; fu | fu
|
||||
fmul ds:dword ptr[st_d_zistepu+edi] ; fu*surf->d_zistepu | fu
|
||||
fld ds:dword ptr[_fv] ; fv | fu*surf->d_zistepu | fu
|
||||
fmul ds:dword ptr[st_d_zistepv+edi] ; fv*surf->d_zistepv | fu*surf->d_zistepu | fu
|
||||
fxch st(1) ; fu*surf->d_zistepu | fv*surf->d_zistepv | fu
|
||||
fadd ds:dword ptr[st_d_ziorigin+edi] ; fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
; fv*surf->d_zistepv | fu
|
||||
|
||||
fld ds:dword ptr[st_d_zistepu+esi] ; surf2->d_zistepu |
|
||||
; fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
; fv*surf->d_zistepv | fu
|
||||
fmul st(0),st(3) ; fu*surf2->d_zistepu |
|
||||
; fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
; fv*surf->d_zistepv | fu
|
||||
fxch st(1) ; fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
; fu*surf2->d_zistepu |
|
||||
; fv*surf->d_zistepv | fu
|
||||
faddp st(2),st(0) ; fu*surf2->d_zistepu | newzi | fu
|
||||
|
||||
fld ds:dword ptr[_fv] ; fv | fu*surf2->d_zistepu | newzi | fu
|
||||
fmul ds:dword ptr[st_d_zistepv+esi] ; fv*surf2->d_zistepv |
|
||||
; fu*surf2->d_zistepu | newzi | fu
|
||||
fld st(2) ; newzi | fv*surf2->d_zistepv |
|
||||
; fu*surf2->d_zistepu | newzi | fu
|
||||
fmul ds:dword ptr[float_point_999] ; newzibottom | fv*surf2->d_zistepv |
|
||||
; fu*surf2->d_zistepu | newzi | fu
|
||||
|
||||
fxch st(2) ; fu*surf2->d_zistepu | fv*surf2->d_zistepv |
|
||||
; newzibottom | newzi | fu
|
||||
fadd ds:dword ptr[st_d_ziorigin+esi] ; fu*surf2->d_zistepu + surf2->d_ziorigin |
|
||||
; fv*surf2->d_zistepv | newzibottom | newzi |
|
||||
; fu
|
||||
faddp st(1),st(0) ; testzi | newzibottom | newzi | fu
|
||||
fxch st(1) ; newzibottom | testzi | newzi | fu
|
||||
|
||||
; if (newzibottom >= testzi)
|
||||
; goto Lgotposition;
|
||||
|
||||
fcomp st(1) ; testzi | newzi | fu
|
||||
|
||||
fxch st(1) ; newzi | testzi | fu
|
||||
fmul ds:dword ptr[float_1_point_001] ; newzitop | testzi | fu
|
||||
fxch st(1) ; testzi | newzitop | fu
|
||||
|
||||
fnstsw ax
|
||||
test ah,001h
|
||||
jz Lgotposition_fpop3
|
||||
|
||||
; if (newzitop >= testzi)
|
||||
; {
|
||||
|
||||
fcomp st(1) ; newzitop | fu
|
||||
fnstsw ax
|
||||
test ah,045h
|
||||
jz Lsortloop_fpop2
|
||||
|
||||
; if (surf->d_zistepu >= surf2->d_zistepu)
|
||||
; goto newtop;
|
||||
|
||||
fld ds:dword ptr[st_d_zistepu+edi] ; surf->d_zistepu | newzitop| fu
|
||||
fcomp ds:dword ptr[st_d_zistepu+esi] ; newzitop | fu
|
||||
fnstsw ax
|
||||
test ah,001h
|
||||
jz Lgotposition_fpop2
|
||||
|
||||
fstp st(0) ; clear the FPstack
|
||||
fstp st(0)
|
||||
mov eax,ds:dword ptr[st_key+edi]
|
||||
jmp Lsortloop
|
||||
|
||||
|
||||
Lgotposition_fpop3:
|
||||
fstp st(0)
|
||||
Lgotposition_fpop2:
|
||||
fstp st(0)
|
||||
fstp st(0)
|
||||
jmp LInsertAndExit
|
||||
|
||||
|
||||
; emit a span (obscures current top)
|
||||
|
||||
Lnewtop_fpop3:
|
||||
fstp st(0)
|
||||
Lnewtop_fpop2:
|
||||
fstp st(0)
|
||||
fstp st(0)
|
||||
mov eax,ds:dword ptr[st_key+edi] ; reload the sorting key
|
||||
|
||||
Lnewtop:
|
||||
mov eax,ds:dword ptr[et_u+ebx]
|
||||
mov edx,ds:dword ptr[st_last_u+esi]
|
||||
shr eax,20 ; iu = integral pixel u
|
||||
mov ds:dword ptr[st_last_u+edi],eax ; surf->last_u = iu;
|
||||
cmp eax,edx
|
||||
jle LInsertAndExit ; iu <= surf->last_u, so nothing to emit
|
||||
|
||||
sub eax,edx
|
||||
mov ds:dword ptr[espan_t_u+ebp],edx ; span->u = surf->last_u;
|
||||
|
||||
mov ds:dword ptr[espan_t_count+ebp],eax ; span->count = iu - span->u;
|
||||
mov eax,ds:dword ptr[_current_iv]
|
||||
mov ds:dword ptr[espan_t_v+ebp],eax ; span->v = current_iv;
|
||||
mov eax,ds:dword ptr[st_spans+esi]
|
||||
mov ds:dword ptr[espan_t_pnext+ebp],eax ; span->pnext = surf->spans;
|
||||
mov ds:dword ptr[st_spans+esi],ebp ; surf->spans = span;
|
||||
add ebp,offset espan_t_size
|
||||
|
||||
LInsertAndExit:
|
||||
; insert before surf2
|
||||
mov ds:dword ptr[st_next+edi],esi ; surf->next = surf2;
|
||||
mov eax,ds:dword ptr[st_prev+esi]
|
||||
mov ds:dword ptr[st_prev+edi],eax ; surf->prev = surf2->prev;
|
||||
mov ds:dword ptr[st_prev+esi],edi ; surf2->prev = surf;
|
||||
mov ds:dword ptr[st_next+eax],edi ; surf2->prev->next = surf;
|
||||
|
||||
; ---------------------------------------------------------------
|
||||
; leading edge done
|
||||
; ---------------------------------------------------------------
|
||||
|
||||
; ---------------------------------------------------------------
|
||||
; see if there are any more edges
|
||||
; ---------------------------------------------------------------
|
||||
|
||||
Lgs_nextedge:
|
||||
mov ebx,ds:dword ptr[et_next+ebx]
|
||||
cmp ebx,offset _edge_tail
|
||||
jnz Lgs_edgeloop
|
||||
|
||||
; clean up at the right edge
|
||||
Lgs_lastspan:
|
||||
|
||||
; now that we've reached the right edge of the screen, we're done with any
|
||||
; unfinished surfaces, so emit a span for whatever's on top
|
||||
mov esi,ds:dword ptr[12345678h] ; surfaces[1].st_next
|
||||
LPatch3:
|
||||
mov eax,ds:dword ptr[_edge_tail_u_shift20]
|
||||
xor ecx,ecx
|
||||
mov edx,ds:dword ptr[st_last_u+esi]
|
||||
sub eax,edx
|
||||
jle Lgs_resetspanstate
|
||||
|
||||
mov ds:dword ptr[espan_t_u+ebp],edx
|
||||
mov ds:dword ptr[espan_t_count+ebp],eax
|
||||
mov eax,ds:dword ptr[_current_iv]
|
||||
mov ds:dword ptr[espan_t_v+ebp],eax
|
||||
mov eax,ds:dword ptr[st_spans+esi]
|
||||
mov ds:dword ptr[espan_t_pnext+ebp],eax
|
||||
mov ds:dword ptr[st_spans+esi],ebp
|
||||
add ebp,offset espan_t_size
|
||||
|
||||
; reset spanstate for all surfaces in the surface stack
|
||||
Lgs_resetspanstate:
|
||||
mov ds:dword ptr[st_spanstate+esi],ecx
|
||||
mov esi,ds:dword ptr[st_next+esi]
|
||||
cmp esi,012345678h ; &surfaces[1]
|
||||
LPatch4:
|
||||
jnz Lgs_resetspanstate
|
||||
|
||||
; store the final span_p
|
||||
mov ds:dword ptr[_span_p],ebp
|
||||
|
||||
pop ebx ; restore register variables
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebp ; restore the caller's stack frame
|
||||
ret
|
||||
|
||||
|
||||
; ---------------------------------------------------------------
|
||||
; 1/z sorting for bmodels in the same leaf
|
||||
; ---------------------------------------------------------------
|
||||
align 4
|
||||
Lxl_done:
|
||||
inc edx
|
||||
mov ds:dword ptr[st_spanstate+edi],edx
|
||||
|
||||
jmp Lgs_nextedge
|
||||
|
||||
|
||||
align 4
|
||||
Lzcheck_for_newtop:
|
||||
mov eax,ds:dword ptr[et_u+ebx]
|
||||
sub eax,0FFFFFh
|
||||
mov ds:dword ptr[Ltemp],eax
|
||||
fild ds:dword ptr[Ltemp]
|
||||
|
||||
fmul ds:dword ptr[float_1_div_0100000h] ; fu = (float)(edge->u - 0xFFFFF) *
|
||||
; (1.0 / 0x100000);
|
||||
|
||||
fld st(0) ; fu | fu
|
||||
fmul ds:dword ptr[st_d_zistepu+edi] ; fu*surf->d_zistepu | fu
|
||||
fld ds:dword ptr[_fv] ; fv | fu*surf->d_zistepu | fu
|
||||
fmul ds:dword ptr[st_d_zistepv+edi] ; fv*surf->d_zistepv | fu*surf->d_zistepu | fu
|
||||
fxch st(1) ; fu*surf->d_zistepu | fv*surf->d_zistepv | fu
|
||||
fadd ds:dword ptr[st_d_ziorigin+edi] ; fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
; fv*surf->d_zistepv | fu
|
||||
|
||||
fld ds:dword ptr[st_d_zistepu+esi] ; surf2->d_zistepu |
|
||||
; fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
; fv*surf->d_zistepv | fu
|
||||
fmul st(0),st(3) ; fu*surf2->d_zistepu |
|
||||
; fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
; fv*surf->d_zistepv | fu
|
||||
fxch st(1) ; fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
; fu*surf2->d_zistepu |
|
||||
; fv*surf->d_zistepv | fu
|
||||
faddp st(2),st(0) ; fu*surf2->d_zistepu | newzi | fu
|
||||
|
||||
fld ds:dword ptr[_fv] ; fv | fu*surf2->d_zistepu | newzi | fu
|
||||
fmul ds:dword ptr[st_d_zistepv+esi] ; fv*surf2->d_zistepv |
|
||||
; fu*surf2->d_zistepu | newzi | fu
|
||||
fld st(2) ; newzi | fv*surf2->d_zistepv |
|
||||
; fu*surf2->d_zistepu | newzi | fu
|
||||
fmul ds:dword ptr[float_point_999] ; newzibottom | fv*surf2->d_zistepv |
|
||||
; fu*surf2->d_zistepu | newzi | fu
|
||||
|
||||
fxch st(2) ; fu*surf2->d_zistepu | fv*surf2->d_zistepv |
|
||||
; newzibottom | newzi | fu
|
||||
fadd ds:dword ptr[st_d_ziorigin+esi] ; fu*surf2->d_zistepu + surf2->d_ziorigin |
|
||||
; fv*surf2->d_zistepv | newzibottom | newzi |
|
||||
; fu
|
||||
faddp st(1),st(0) ; testzi | newzibottom | newzi | fu
|
||||
fxch st(1) ; newzibottom | testzi | newzi | fu
|
||||
|
||||
; if (newzibottom >= testzi)
|
||||
; goto newtop;
|
||||
|
||||
fcomp st(1) ; testzi | newzi | fu
|
||||
|
||||
fxch st(1) ; newzi | testzi | fu
|
||||
fmul ds:dword ptr[float_1_point_001] ; newzitop | testzi | fu
|
||||
fxch st(1) ; testzi | newzitop | fu
|
||||
|
||||
fnstsw ax
|
||||
test ah,001h
|
||||
jz Lnewtop_fpop3
|
||||
|
||||
; if (newzitop >= testzi)
|
||||
; {
|
||||
|
||||
fcomp st(1) ; newzitop | fu
|
||||
fnstsw ax
|
||||
test ah,045h
|
||||
jz Lsortloop_fpop2
|
||||
|
||||
; if (surf->d_zistepu >= surf2->d_zistepu)
|
||||
; goto newtop;
|
||||
|
||||
fld ds:dword ptr[st_d_zistepu+edi] ; surf->d_zistepu | newzitop | fu
|
||||
fcomp ds:dword ptr[st_d_zistepu+esi] ; newzitop | fu
|
||||
fnstsw ax
|
||||
test ah,001h
|
||||
jz Lnewtop_fpop2
|
||||
|
||||
Lsortloop_fpop2:
|
||||
fstp st(0) ; clear the FP stack
|
||||
fstp st(0)
|
||||
mov eax,ds:dword ptr[st_key+edi]
|
||||
jmp Lsortloop
|
||||
|
||||
|
||||
public _R_EdgeCodeEnd
|
||||
_R_EdgeCodeEnd:
|
||||
|
||||
|
||||
;----------------------------------------------------------------------
|
||||
; Surface array address code patching routine
|
||||
;----------------------------------------------------------------------
|
||||
|
||||
align 4
|
||||
public _R_SurfacePatch
|
||||
_R_SurfacePatch:
|
||||
|
||||
mov eax,ds:dword ptr[_surfaces]
|
||||
add eax,offset st_size
|
||||
mov ds:dword ptr[LPatch4-4],eax
|
||||
|
||||
add eax,offset st_next
|
||||
mov ds:dword ptr[LPatch0-4],eax
|
||||
mov ds:dword ptr[LPatch2-4],eax
|
||||
mov ds:dword ptr[LPatch3-4],eax
|
||||
|
||||
ret
|
||||
|
||||
_TEXT ENDS
|
||||
endif ;id386
|
||||
END
|
617
ref_soft/r_image.c
Normal file
617
ref_soft/r_image.c
Normal file
@ -0,0 +1,617 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 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 "r_local.h"
|
||||
|
||||
|
||||
#define MAX_RIMAGES 1024
|
||||
image_t r_images[MAX_RIMAGES];
|
||||
int numr_images;
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
R_ImageList_f
|
||||
===============
|
||||
*/
|
||||
void R_ImageList_f (void)
|
||||
{
|
||||
int i;
|
||||
image_t *image;
|
||||
int texels;
|
||||
|
||||
ri.Con_Printf (PRINT_ALL, "------------------\n");
|
||||
texels = 0;
|
||||
|
||||
for (i=0, image=r_images ; i<numr_images ; i++, image++)
|
||||
{
|
||||
if (image->registration_sequence <= 0)
|
||||
continue;
|
||||
texels += image->width*image->height;
|
||||
switch (image->type)
|
||||
{
|
||||
case it_skin:
|
||||
ri.Con_Printf (PRINT_ALL, "M");
|
||||
break;
|
||||
case it_sprite:
|
||||
ri.Con_Printf (PRINT_ALL, "S");
|
||||
break;
|
||||
case it_wall:
|
||||
ri.Con_Printf (PRINT_ALL, "W");
|
||||
break;
|
||||
case it_pic:
|
||||
ri.Con_Printf (PRINT_ALL, "P");
|
||||
break;
|
||||
default:
|
||||
ri.Con_Printf (PRINT_ALL, " ");
|
||||
break;
|
||||
}
|
||||
|
||||
ri.Con_Printf (PRINT_ALL, " %3i %3i : %s\n",
|
||||
image->width, image->height, image->name);
|
||||
}
|
||||
ri.Con_Printf (PRINT_ALL, "Total texel count: %i\n", texels);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================================================================
|
||||
|
||||
PCX LOADING
|
||||
|
||||
=================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
==============
|
||||
LoadPCX
|
||||
==============
|
||||
*/
|
||||
void LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height)
|
||||
{
|
||||
byte *raw;
|
||||
pcx_t *pcx;
|
||||
int x, y;
|
||||
int len;
|
||||
int dataByte, runLength;
|
||||
byte *out, *pix;
|
||||
|
||||
*pic = NULL;
|
||||
|
||||
//
|
||||
// load the file
|
||||
//
|
||||
len = ri.FS_LoadFile (filename, (void **)&raw);
|
||||
if (!raw)
|
||||
{
|
||||
ri.Con_Printf (PRINT_DEVELOPER, "Bad pcx file %s\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// parse the PCX file
|
||||
//
|
||||
pcx = (pcx_t *)raw;
|
||||
|
||||
pcx->xmin = LittleShort(pcx->xmin);
|
||||
pcx->ymin = LittleShort(pcx->ymin);
|
||||
pcx->xmax = LittleShort(pcx->xmax);
|
||||
pcx->ymax = LittleShort(pcx->ymax);
|
||||
pcx->hres = LittleShort(pcx->hres);
|
||||
pcx->vres = LittleShort(pcx->vres);
|
||||
pcx->bytes_per_line = LittleShort(pcx->bytes_per_line);
|
||||
pcx->palette_type = LittleShort(pcx->palette_type);
|
||||
|
||||
raw = &pcx->data;
|
||||
|
||||
if (pcx->manufacturer != 0x0a
|
||||
|| pcx->version != 5
|
||||
|| pcx->encoding != 1
|
||||
|| pcx->bits_per_pixel != 8
|
||||
|| pcx->xmax >= 640
|
||||
|| pcx->ymax >= 480)
|
||||
{
|
||||
ri.Con_Printf (PRINT_ALL, "Bad pcx file %s\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
out = malloc ( (pcx->ymax+1) * (pcx->xmax+1) );
|
||||
|
||||
*pic = out;
|
||||
|
||||
pix = out;
|
||||
|
||||
if (palette)
|
||||
{
|
||||
*palette = malloc(768);
|
||||
memcpy (*palette, (byte *)pcx + len - 768, 768);
|
||||
}
|
||||
|
||||
if (width)
|
||||
*width = pcx->xmax+1;
|
||||
if (height)
|
||||
*height = pcx->ymax+1;
|
||||
|
||||
for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1)
|
||||
{
|
||||
for (x=0 ; x<=pcx->xmax ; )
|
||||
{
|
||||
dataByte = *raw++;
|
||||
|
||||
if((dataByte & 0xC0) == 0xC0)
|
||||
{
|
||||
runLength = dataByte & 0x3F;
|
||||
dataByte = *raw++;
|
||||
}
|
||||
else
|
||||
runLength = 1;
|
||||
|
||||
while(runLength-- > 0)
|
||||
pix[x++] = dataByte;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( raw - (byte *)pcx > len)
|
||||
{
|
||||
ri.Con_Printf (PRINT_DEVELOPER, "PCX file %s was malformed", filename);
|
||||
free (*pic);
|
||||
*pic = NULL;
|
||||
}
|
||||
|
||||
ri.FS_FreeFile (pcx);
|
||||
}
|
||||
|
||||
/*
|
||||
=========================================================
|
||||
|
||||
TARGA LOADING
|
||||
|
||||
=========================================================
|
||||
*/
|
||||
|
||||
typedef struct _TargaHeader {
|
||||
unsigned char id_length, colormap_type, image_type;
|
||||
unsigned short colormap_index, colormap_length;
|
||||
unsigned char colormap_size;
|
||||
unsigned short x_origin, y_origin, width, height;
|
||||
unsigned char pixel_size, attributes;
|
||||
} TargaHeader;
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
LoadTGA
|
||||
=============
|
||||
*/
|
||||
void LoadTGA (char *name, byte **pic, int *width, int *height)
|
||||
{
|
||||
int columns, rows, numPixels;
|
||||
byte *pixbuf;
|
||||
int row, column;
|
||||
byte *buf_p;
|
||||
byte *buffer;
|
||||
int length;
|
||||
TargaHeader targa_header;
|
||||
byte *targa_rgba;
|
||||
|
||||
*pic = NULL;
|
||||
|
||||
//
|
||||
// load the file
|
||||
//
|
||||
length = ri.FS_LoadFile (name, (void **)&buffer);
|
||||
if (!buffer)
|
||||
{
|
||||
ri.Con_Printf (PRINT_DEVELOPER, "Bad tga file %s\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
buf_p = buffer;
|
||||
|
||||
targa_header.id_length = *buf_p++;
|
||||
targa_header.colormap_type = *buf_p++;
|
||||
targa_header.image_type = *buf_p++;
|
||||
|
||||
targa_header.colormap_index = LittleShort ( *((short *)buf_p) );
|
||||
buf_p+=2;
|
||||
targa_header.colormap_length = LittleShort ( *((short *)buf_p) );
|
||||
buf_p+=2;
|
||||
targa_header.colormap_size = *buf_p++;
|
||||
targa_header.x_origin = LittleShort ( *((short *)buf_p) );
|
||||
buf_p+=2;
|
||||
targa_header.y_origin = LittleShort ( *((short *)buf_p) );
|
||||
buf_p+=2;
|
||||
targa_header.width = LittleShort ( *((short *)buf_p) );
|
||||
buf_p+=2;
|
||||
targa_header.height = LittleShort ( *((short *)buf_p) );
|
||||
buf_p+=2;
|
||||
targa_header.pixel_size = *buf_p++;
|
||||
targa_header.attributes = *buf_p++;
|
||||
|
||||
if (targa_header.image_type!=2
|
||||
&& targa_header.image_type!=10)
|
||||
ri.Sys_Error (ERR_DROP, "LoadTGA: Only type 2 and 10 targa RGB images supported\n");
|
||||
|
||||
if (targa_header.colormap_type !=0
|
||||
|| (targa_header.pixel_size!=32 && targa_header.pixel_size!=24))
|
||||
ri.Sys_Error (ERR_DROP, "LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
|
||||
|
||||
columns = targa_header.width;
|
||||
rows = targa_header.height;
|
||||
numPixels = columns * rows;
|
||||
|
||||
if (width)
|
||||
*width = columns;
|
||||
if (height)
|
||||
*height = rows;
|
||||
|
||||
targa_rgba = malloc (numPixels*4);
|
||||
*pic = targa_rgba;
|
||||
|
||||
if (targa_header.id_length != 0)
|
||||
buf_p += targa_header.id_length; // skip TARGA image comment
|
||||
|
||||
if (targa_header.image_type==2) { // Uncompressed, RGB images
|
||||
for(row=rows-1; row>=0; row--) {
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
for(column=0; column<columns; column++) {
|
||||
unsigned char red,green,blue,alphabyte;
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alphabyte = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alphabyte;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (targa_header.image_type==10) { // Runlength encoded RGB images
|
||||
unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
|
||||
for(row=rows-1; row>=0; row--) {
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
for(column=0; column<columns; ) {
|
||||
packetHeader= *buf_p++;
|
||||
packetSize = 1 + (packetHeader & 0x7f);
|
||||
if (packetHeader & 0x80) { // run-length packet
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alphabyte = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alphabyte = *buf_p++;
|
||||
break;
|
||||
}
|
||||
|
||||
for(j=0;j<packetSize;j++) {
|
||||
*pixbuf++=red;
|
||||
*pixbuf++=green;
|
||||
*pixbuf++=blue;
|
||||
*pixbuf++=alphabyte;
|
||||
column++;
|
||||
if (column==columns) { // run spans across rows
|
||||
column=0;
|
||||
if (row>0)
|
||||
row--;
|
||||
else
|
||||
goto breakOut;
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // non run-length packet
|
||||
for(j=0;j<packetSize;j++) {
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alphabyte = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alphabyte;
|
||||
break;
|
||||
}
|
||||
column++;
|
||||
if (column==columns) { // pixel packet run spans across rows
|
||||
column=0;
|
||||
if (row>0)
|
||||
row--;
|
||||
else
|
||||
goto breakOut;
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
breakOut:;
|
||||
}
|
||||
}
|
||||
|
||||
ri.FS_FreeFile (buffer);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================
|
||||
|
||||
image_t *R_FindFreeImage (void)
|
||||
{
|
||||
image_t *image;
|
||||
int i;
|
||||
|
||||
// find a free image_t
|
||||
for (i=0, image=r_images ; i<numr_images ; i++,image++)
|
||||
{
|
||||
if (!image->registration_sequence)
|
||||
break;
|
||||
}
|
||||
if (i == numr_images)
|
||||
{
|
||||
if (numr_images == MAX_RIMAGES)
|
||||
ri.Sys_Error (ERR_DROP, "MAX_RIMAGES");
|
||||
numr_images++;
|
||||
}
|
||||
image = &r_images[i];
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
GL_LoadPic
|
||||
|
||||
================
|
||||
*/
|
||||
image_t *GL_LoadPic (char *name, byte *pic, int width, int height, imagetype_t type)
|
||||
{
|
||||
image_t *image;
|
||||
int i, c, b;
|
||||
|
||||
image = R_FindFreeImage ();
|
||||
if (strlen(name) >= sizeof(image->name))
|
||||
ri.Sys_Error (ERR_DROP, "Draw_LoadPic: \"%s\" is too long", name);
|
||||
strcpy (image->name, name);
|
||||
image->registration_sequence = registration_sequence;
|
||||
|
||||
image->width = width;
|
||||
image->height = height;
|
||||
image->type = type;
|
||||
|
||||
c = width*height;
|
||||
image->pixels[0] = malloc (c);
|
||||
image->transparent = false;
|
||||
for (i=0 ; i<c ; i++)
|
||||
{
|
||||
b = pic[i];
|
||||
if (b == 255)
|
||||
image->transparent = true;
|
||||
image->pixels[0][i] = b;
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_LoadWal
|
||||
================
|
||||
*/
|
||||
image_t *R_LoadWal (char *name)
|
||||
{
|
||||
miptex_t *mt;
|
||||
int ofs;
|
||||
image_t *image;
|
||||
int size;
|
||||
|
||||
ri.FS_LoadFile (name, (void **)&mt);
|
||||
if (!mt)
|
||||
{
|
||||
ri.Con_Printf (PRINT_ALL, "R_LoadWal: can't load %s\n", name);
|
||||
return r_notexture_mip;
|
||||
}
|
||||
|
||||
image = R_FindFreeImage ();
|
||||
strcpy (image->name, name);
|
||||
image->width = LittleLong (mt->width);
|
||||
image->height = LittleLong (mt->height);
|
||||
image->type = it_wall;
|
||||
image->registration_sequence = registration_sequence;
|
||||
|
||||
size = image->width*image->height * (256+64+16+4)/256;
|
||||
image->pixels[0] = malloc (size);
|
||||
image->pixels[1] = image->pixels[0] + image->width*image->height;
|
||||
image->pixels[2] = image->pixels[1] + image->width*image->height/4;
|
||||
image->pixels[3] = image->pixels[2] + image->width*image->height/16;
|
||||
|
||||
ofs = LittleLong (mt->offsets[0]);
|
||||
memcpy ( image->pixels[0], (byte *)mt + ofs, size);
|
||||
|
||||
ri.FS_FreeFile ((void *)mt);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
R_FindImage
|
||||
|
||||
Finds or loads the given image
|
||||
===============
|
||||
*/
|
||||
image_t *R_FindImage (char *name, imagetype_t type)
|
||||
{
|
||||
image_t *image;
|
||||
int i, len;
|
||||
byte *pic, *palette;
|
||||
int width, height;
|
||||
|
||||
if (!name)
|
||||
return NULL; // ri.Sys_Error (ERR_DROP, "R_FindImage: NULL name");
|
||||
len = strlen(name);
|
||||
if (len<5)
|
||||
return NULL; // ri.Sys_Error (ERR_DROP, "R_FindImage: bad name: %s", name);
|
||||
|
||||
// look for it
|
||||
for (i=0, image=r_images ; i<numr_images ; i++,image++)
|
||||
{
|
||||
if (!strcmp(name, image->name))
|
||||
{
|
||||
image->registration_sequence = registration_sequence;
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// load the pic from disk
|
||||
//
|
||||
pic = NULL;
|
||||
palette = NULL;
|
||||
if (!strcmp(name+len-4, ".pcx"))
|
||||
{
|
||||
LoadPCX (name, &pic, &palette, &width, &height);
|
||||
if (!pic)
|
||||
return NULL; // ri.Sys_Error (ERR_DROP, "R_FindImage: can't load %s", name);
|
||||
image = GL_LoadPic (name, pic, width, height, type);
|
||||
}
|
||||
else if (!strcmp(name+len-4, ".wal"))
|
||||
{
|
||||
image = R_LoadWal (name);
|
||||
}
|
||||
else if (!strcmp(name+len-4, ".tga"))
|
||||
return NULL; // ri.Sys_Error (ERR_DROP, "R_FindImage: can't load %s in software renderer", name);
|
||||
else
|
||||
return NULL; // ri.Sys_Error (ERR_DROP, "R_FindImage: bad extension on: %s", name);
|
||||
|
||||
if (pic)
|
||||
free(pic);
|
||||
if (palette)
|
||||
free(palette);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
R_RegisterSkin
|
||||
===============
|
||||
*/
|
||||
struct image_s *R_RegisterSkin (char *name)
|
||||
{
|
||||
return R_FindImage (name, it_skin);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_FreeUnusedImages
|
||||
|
||||
Any image that was not touched on this registration sequence
|
||||
will be freed.
|
||||
================
|
||||
*/
|
||||
void R_FreeUnusedImages (void)
|
||||
{
|
||||
int i;
|
||||
image_t *image;
|
||||
|
||||
for (i=0, image=r_images ; i<numr_images ; i++, image++)
|
||||
{
|
||||
if (image->registration_sequence == registration_sequence)
|
||||
{
|
||||
Com_PageInMemory ((byte *)image->pixels[0], image->width*image->height);
|
||||
continue; // used this sequence
|
||||
}
|
||||
if (!image->registration_sequence)
|
||||
continue; // free texture
|
||||
if (image->type == it_pic)
|
||||
continue; // don't free pics
|
||||
// free it
|
||||
free (image->pixels[0]); // the other mip levels just follow
|
||||
memset (image, 0, sizeof(*image));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
R_InitImages
|
||||
===============
|
||||
*/
|
||||
void R_InitImages (void)
|
||||
{
|
||||
registration_sequence = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_ShutdownImages
|
||||
===============
|
||||
*/
|
||||
void R_ShutdownImages (void)
|
||||
{
|
||||
int i;
|
||||
image_t *image;
|
||||
|
||||
for (i=0, image=r_images ; i<numr_images ; i++, image++)
|
||||
{
|
||||
if (!image->registration_sequence)
|
||||
continue; // free texture
|
||||
// free it
|
||||
free (image->pixels[0]); // the other mip levels just follow
|
||||
memset (image, 0, sizeof(*image));
|
||||
}
|
||||
}
|
||||
|
442
ref_soft/r_light.c
Normal file
442
ref_soft/r_light.c
Normal file
@ -0,0 +1,442 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 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_light.c
|
||||
|
||||
#include "r_local.h"
|
||||
|
||||
int r_dlightframecount;
|
||||
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
DYNAMIC LIGHTS
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
=============
|
||||
R_MarkLights
|
||||
=============
|
||||
*/
|
||||
void R_MarkLights (dlight_t *light, int bit, mnode_t *node)
|
||||
{
|
||||
mplane_t *splitplane;
|
||||
float dist;
|
||||
msurface_t *surf;
|
||||
int i;
|
||||
|
||||
if (node->contents != -1)
|
||||
return;
|
||||
|
||||
splitplane = node->plane;
|
||||
dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist;
|
||||
|
||||
//=====
|
||||
//PGM
|
||||
i=light->intensity;
|
||||
if(i<0)
|
||||
i=-i;
|
||||
//PGM
|
||||
//=====
|
||||
|
||||
if (dist > i) // PGM (dist > light->intensity)
|
||||
{
|
||||
R_MarkLights (light, bit, node->children[0]);
|
||||
return;
|
||||
}
|
||||
if (dist < -i) // PGM (dist < -light->intensity)
|
||||
{
|
||||
R_MarkLights (light, bit, node->children[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
// mark the polygons
|
||||
surf = r_worldmodel->surfaces + node->firstsurface;
|
||||
for (i=0 ; i<node->numsurfaces ; i++, surf++)
|
||||
{
|
||||
if (surf->dlightframe != r_dlightframecount)
|
||||
{
|
||||
surf->dlightbits = 0;
|
||||
surf->dlightframe = r_dlightframecount;
|
||||
}
|
||||
surf->dlightbits |= bit;
|
||||
}
|
||||
|
||||
R_MarkLights (light, bit, node->children[0]);
|
||||
R_MarkLights (light, bit, node->children[1]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
R_PushDlights
|
||||
=============
|
||||
*/
|
||||
void R_PushDlights (model_t *model)
|
||||
{
|
||||
int i;
|
||||
dlight_t *l;
|
||||
|
||||
r_dlightframecount = r_framecount;
|
||||
for (i=0, l = r_newrefdef.dlights ; i<r_newrefdef.num_dlights ; i++, l++)
|
||||
{
|
||||
R_MarkLights ( l, 1<<i,
|
||||
model->nodes + model->firstnode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
LIGHT SAMPLING
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
vec3_t pointcolor;
|
||||
mplane_t *lightplane; // used as shadow plane
|
||||
vec3_t lightspot;
|
||||
|
||||
int RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
|
||||
{
|
||||
float front, back, frac;
|
||||
int side;
|
||||
mplane_t *plane;
|
||||
vec3_t mid;
|
||||
msurface_t *surf;
|
||||
int s, t, ds, dt;
|
||||
int i;
|
||||
mtexinfo_t *tex;
|
||||
byte *lightmap;
|
||||
float *scales;
|
||||
int maps;
|
||||
float samp;
|
||||
int r;
|
||||
|
||||
if (node->contents != -1)
|
||||
return -1; // didn't hit anything
|
||||
|
||||
// calculate mid point
|
||||
|
||||
// FIXME: optimize for axial
|
||||
plane = node->plane;
|
||||
front = DotProduct (start, plane->normal) - plane->dist;
|
||||
back = DotProduct (end, plane->normal) - plane->dist;
|
||||
side = front < 0;
|
||||
|
||||
if ( (back < 0) == side)
|
||||
return RecursiveLightPoint (node->children[side], start, end);
|
||||
|
||||
frac = front / (front-back);
|
||||
mid[0] = start[0] + (end[0] - start[0])*frac;
|
||||
mid[1] = start[1] + (end[1] - start[1])*frac;
|
||||
mid[2] = start[2] + (end[2] - start[2])*frac;
|
||||
if (plane->type < 3) // axial planes
|
||||
mid[plane->type] = plane->dist;
|
||||
|
||||
// go down front side
|
||||
r = RecursiveLightPoint (node->children[side], start, mid);
|
||||
if (r >= 0)
|
||||
return r; // hit something
|
||||
|
||||
if ( (back < 0) == side )
|
||||
return -1; // didn't hit anuthing
|
||||
|
||||
// check for impact on this node
|
||||
VectorCopy (mid, lightspot);
|
||||
lightplane = plane;
|
||||
|
||||
surf = r_worldmodel->surfaces + node->firstsurface;
|
||||
for (i=0 ; i<node->numsurfaces ; i++, surf++)
|
||||
{
|
||||
if (surf->flags&(SURF_DRAWTURB|SURF_DRAWSKY))
|
||||
continue; // no lightmaps
|
||||
|
||||
tex = surf->texinfo;
|
||||
|
||||
s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3];
|
||||
t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3];
|
||||
if (s < surf->texturemins[0] ||
|
||||
t < surf->texturemins[1])
|
||||
continue;
|
||||
|
||||
ds = s - surf->texturemins[0];
|
||||
dt = t - surf->texturemins[1];
|
||||
|
||||
if ( ds > surf->extents[0] || dt > surf->extents[1] )
|
||||
continue;
|
||||
|
||||
if (!surf->samples)
|
||||
return 0;
|
||||
|
||||
ds >>= 4;
|
||||
dt >>= 4;
|
||||
|
||||
lightmap = surf->samples;
|
||||
VectorCopy (vec3_origin, pointcolor);
|
||||
if (lightmap)
|
||||
{
|
||||
lightmap += dt * ((surf->extents[0]>>4)+1) + ds;
|
||||
|
||||
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
|
||||
maps++)
|
||||
{
|
||||
samp = *lightmap * /* 0.5 * */ (1.0/255); // adjust for gl scale
|
||||
scales = r_newrefdef.lightstyles[surf->styles[maps]].rgb;
|
||||
VectorMA (pointcolor, samp, scales, pointcolor);
|
||||
lightmap += ((surf->extents[0]>>4)+1) *
|
||||
((surf->extents[1]>>4)+1);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// go down back side
|
||||
return RecursiveLightPoint (node->children[!side], mid, end);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_LightPoint
|
||||
===============
|
||||
*/
|
||||
void R_LightPoint (vec3_t p, vec3_t color)
|
||||
{
|
||||
vec3_t end;
|
||||
float r;
|
||||
int lnum;
|
||||
dlight_t *dl;
|
||||
float light;
|
||||
vec3_t dist;
|
||||
float add;
|
||||
|
||||
if (!r_worldmodel->lightdata)
|
||||
{
|
||||
color[0] = color[1] = color[2] = 1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
end[0] = p[0];
|
||||
end[1] = p[1];
|
||||
end[2] = p[2] - 2048;
|
||||
|
||||
r = RecursiveLightPoint (r_worldmodel->nodes, p, end);
|
||||
|
||||
if (r == -1)
|
||||
{
|
||||
VectorCopy (vec3_origin, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy (pointcolor, color);
|
||||
}
|
||||
|
||||
//
|
||||
// add dynamic lights
|
||||
//
|
||||
light = 0;
|
||||
for (lnum=0 ; lnum<r_newrefdef.num_dlights ; lnum++)
|
||||
{
|
||||
dl = &r_newrefdef.dlights[lnum];
|
||||
VectorSubtract (currententity->origin,
|
||||
dl->origin,
|
||||
dist);
|
||||
add = dl->intensity - VectorLength(dist);
|
||||
add *= (1.0/256);
|
||||
if (add > 0)
|
||||
{
|
||||
VectorMA (color, add, dl->color, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
|
||||
|
||||
unsigned blocklights[1024]; // allow some very large lightmaps
|
||||
|
||||
/*
|
||||
===============
|
||||
R_AddDynamicLights
|
||||
===============
|
||||
*/
|
||||
void R_AddDynamicLights (void)
|
||||
{
|
||||
msurface_t *surf;
|
||||
int lnum;
|
||||
int sd, td;
|
||||
float dist, rad, minlight;
|
||||
vec3_t impact, local;
|
||||
int s, t;
|
||||
int i;
|
||||
int smax, tmax;
|
||||
mtexinfo_t *tex;
|
||||
dlight_t *dl;
|
||||
int negativeLight; //PGM
|
||||
|
||||
surf = r_drawsurf.surf;
|
||||
smax = (surf->extents[0]>>4)+1;
|
||||
tmax = (surf->extents[1]>>4)+1;
|
||||
tex = surf->texinfo;
|
||||
|
||||
for (lnum=0 ; lnum<r_newrefdef.num_dlights ; lnum++)
|
||||
{
|
||||
if ( !(surf->dlightbits & (1<<lnum) ) )
|
||||
continue; // not lit by this light
|
||||
|
||||
dl = &r_newrefdef.dlights[lnum];
|
||||
rad = dl->intensity;
|
||||
|
||||
//=====
|
||||
//PGM
|
||||
negativeLight = 0;
|
||||
if(rad < 0)
|
||||
{
|
||||
negativeLight = 1;
|
||||
rad = -rad;
|
||||
}
|
||||
//PGM
|
||||
//=====
|
||||
|
||||
dist = DotProduct (dl->origin, surf->plane->normal) -
|
||||
surf->plane->dist;
|
||||
rad -= fabs(dist);
|
||||
minlight = 32; // dl->minlight;
|
||||
if (rad < minlight)
|
||||
continue;
|
||||
minlight = rad - minlight;
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
impact[i] = dl->origin[i] -
|
||||
surf->plane->normal[i]*dist;
|
||||
}
|
||||
|
||||
local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3];
|
||||
local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3];
|
||||
|
||||
local[0] -= surf->texturemins[0];
|
||||
local[1] -= surf->texturemins[1];
|
||||
|
||||
for (t = 0 ; t<tmax ; t++)
|
||||
{
|
||||
td = local[1] - t*16;
|
||||
if (td < 0)
|
||||
td = -td;
|
||||
for (s=0 ; s<smax ; s++)
|
||||
{
|
||||
sd = local[0] - s*16;
|
||||
if (sd < 0)
|
||||
sd = -sd;
|
||||
if (sd > td)
|
||||
dist = sd + (td>>1);
|
||||
else
|
||||
dist = td + (sd>>1);
|
||||
//====
|
||||
//PGM
|
||||
if(!negativeLight)
|
||||
{
|
||||
if (dist < minlight)
|
||||
blocklights[t*smax + s] += (rad - dist)*256;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dist < minlight)
|
||||
blocklights[t*smax + s] -= (rad - dist)*256;
|
||||
if(blocklights[t*smax + s] < minlight)
|
||||
blocklights[t*smax + s] = minlight;
|
||||
}
|
||||
//PGM
|
||||
//====
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_BuildLightMap
|
||||
|
||||
Combine and scale multiple lightmaps into the 8.8 format in blocklights
|
||||
===============
|
||||
*/
|
||||
void R_BuildLightMap (void)
|
||||
{
|
||||
int smax, tmax;
|
||||
int t;
|
||||
int i, size;
|
||||
byte *lightmap;
|
||||
unsigned scale;
|
||||
int maps;
|
||||
msurface_t *surf;
|
||||
|
||||
surf = r_drawsurf.surf;
|
||||
|
||||
smax = (surf->extents[0]>>4)+1;
|
||||
tmax = (surf->extents[1]>>4)+1;
|
||||
size = smax*tmax;
|
||||
|
||||
if (r_fullbright->value || !r_worldmodel->lightdata)
|
||||
{
|
||||
for (i=0 ; i<size ; i++)
|
||||
blocklights[i] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// clear to no light
|
||||
for (i=0 ; i<size ; i++)
|
||||
blocklights[i] = 0;
|
||||
|
||||
|
||||
// add all the lightmaps
|
||||
lightmap = surf->samples;
|
||||
if (lightmap)
|
||||
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
|
||||
maps++)
|
||||
{
|
||||
scale = r_drawsurf.lightadj[maps]; // 8.8 fraction
|
||||
for (i=0 ; i<size ; i++)
|
||||
blocklights[i] += lightmap[i] * scale;
|
||||
lightmap += size; // skip to next lightmap
|
||||
}
|
||||
|
||||
// add all the dynamic lights
|
||||
if (surf->dlightframe == r_framecount)
|
||||
R_AddDynamicLights ();
|
||||
|
||||
// bound, invert, and shift
|
||||
for (i=0 ; i<size ; i++)
|
||||
{
|
||||
t = (int)blocklights[i];
|
||||
if (t < 0)
|
||||
t = 0;
|
||||
t = (255*256 - t) >> (8 - VID_CBITS);
|
||||
|
||||
if (t < (1 << 6))
|
||||
t = (1 << 6);
|
||||
|
||||
blocklights[i] = t;
|
||||
}
|
||||
}
|
||||
|
849
ref_soft/r_local.h
Normal file
849
ref_soft/r_local.h
Normal file
@ -0,0 +1,849 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "../client/ref.h"
|
||||
|
||||
#define REF_VERSION "SOFT 0.01"
|
||||
|
||||
// up / down
|
||||
#define PITCH 0
|
||||
|
||||
// left / right
|
||||
#define YAW 1
|
||||
|
||||
// fall over
|
||||
#define ROLL 2
|
||||
|
||||
|
||||
/*
|
||||
|
||||
skins will be outline flood filled and mip mapped
|
||||
pics and sprites with alpha will be outline flood filled
|
||||
pic won't be mip mapped
|
||||
|
||||
model skin
|
||||
sprite frame
|
||||
wall texture
|
||||
pic
|
||||
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
it_skin,
|
||||
it_sprite,
|
||||
it_wall,
|
||||
it_pic,
|
||||
it_sky
|
||||
} imagetype_t;
|
||||
|
||||
typedef struct image_s
|
||||
{
|
||||
char name[MAX_QPATH]; // game path, including extension
|
||||
imagetype_t type;
|
||||
int width, height;
|
||||
qboolean transparent; // true if any 255 pixels in image
|
||||
int registration_sequence; // 0 = free
|
||||
byte *pixels[4]; // mip levels
|
||||
} image_t;
|
||||
|
||||
|
||||
//===================================================================
|
||||
|
||||
typedef unsigned char pixel_t;
|
||||
|
||||
typedef struct vrect_s
|
||||
{
|
||||
int x,y,width,height;
|
||||
struct vrect_s *pnext;
|
||||
} vrect_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
pixel_t *buffer; // invisible buffer
|
||||
pixel_t *colormap; // 256 * VID_GRADES size
|
||||
pixel_t *alphamap; // 256 * 256 translucency map
|
||||
int rowbytes; // may be > width if displayed in a window
|
||||
// can be negative for stupid dibs
|
||||
int width;
|
||||
int height;
|
||||
} viddef_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
rserr_ok,
|
||||
|
||||
rserr_invalid_fullscreen,
|
||||
rserr_invalid_mode,
|
||||
|
||||
rserr_unknown
|
||||
} rserr_t;
|
||||
|
||||
extern viddef_t vid;
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
typedef struct
|
||||
{
|
||||
vrect_t vrect; // subwindow in video for refresh
|
||||
// FIXME: not need vrect next field here?
|
||||
vrect_t aliasvrect; // scaled Alias version
|
||||
int vrectright, vrectbottom; // right & bottom screen coords
|
||||
int aliasvrectright, aliasvrectbottom; // scaled Alias versions
|
||||
float vrectrightedge; // rightmost right edge we care about,
|
||||
// for use in edge list
|
||||
float fvrectx, fvrecty; // for floating-point compares
|
||||
float fvrectx_adj, fvrecty_adj; // left and top edges, for clamping
|
||||
int vrect_x_adj_shift20; // (vrect.x + 0.5 - epsilon) << 20
|
||||
int vrectright_adj_shift20; // (vrectright + 0.5 - epsilon) << 20
|
||||
float fvrectright_adj, fvrectbottom_adj;
|
||||
// right and bottom edges, for clamping
|
||||
float fvrectright; // rightmost edge, for Alias clamping
|
||||
float fvrectbottom; // bottommost edge, for Alias clamping
|
||||
float horizontalFieldOfView; // at Z = 1.0, this many X is visible
|
||||
// 2.0 = 90 degrees
|
||||
float xOrigin; // should probably always be 0.5
|
||||
float yOrigin; // between be around 0.3 to 0.5
|
||||
|
||||
vec3_t vieworg;
|
||||
vec3_t viewangles;
|
||||
|
||||
int ambientlight;
|
||||
} oldrefdef_t;
|
||||
|
||||
extern oldrefdef_t r_refdef;
|
||||
|
||||
#include "r_model.h"
|
||||
|
||||
#define CACHE_SIZE 32
|
||||
|
||||
/*
|
||||
====================================================
|
||||
|
||||
CONSTANTS
|
||||
|
||||
====================================================
|
||||
*/
|
||||
|
||||
#define VID_CBITS 6
|
||||
#define VID_GRADES (1 << VID_CBITS)
|
||||
|
||||
|
||||
// r_shared.h: general refresh-related stuff shared between the refresh and the
|
||||
// driver
|
||||
|
||||
|
||||
#define MAXVERTS 64 // max points in a surface polygon
|
||||
#define MAXWORKINGVERTS (MAXVERTS+4) // max points in an intermediate
|
||||
// polygon (while processing)
|
||||
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
|
||||
#define MAXHEIGHT 1200
|
||||
#define MAXWIDTH 1600
|
||||
|
||||
#define INFINITE_DISTANCE 0x10000 // distance that's always guaranteed to
|
||||
// be farther away than anything in
|
||||
// the scene
|
||||
|
||||
|
||||
// d_iface.h: interface header file for rasterization driver modules
|
||||
|
||||
#define WARP_WIDTH 320
|
||||
#define WARP_HEIGHT 240
|
||||
|
||||
#define MAX_LBM_HEIGHT 480
|
||||
|
||||
|
||||
#define PARTICLE_Z_CLIP 8.0
|
||||
|
||||
// !!! must be kept the same as in quakeasm.h !!!
|
||||
#define TRANSPARENT_COLOR 0xFF
|
||||
|
||||
|
||||
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
|
||||
#define TURB_TEX_SIZE 64 // base turbulent texture size
|
||||
|
||||
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
|
||||
#define CYCLE 128 // turbulent cycle size
|
||||
|
||||
#define SCANBUFFERPAD 0x1000
|
||||
|
||||
#define DS_SPAN_LIST_END -128
|
||||
|
||||
#define NUMSTACKEDGES 2000
|
||||
#define MINEDGES NUMSTACKEDGES
|
||||
#define NUMSTACKSURFACES 1000
|
||||
#define MINSURFACES NUMSTACKSURFACES
|
||||
#define MAXSPANS 3000
|
||||
|
||||
// flags in finalvert_t.flags
|
||||
#define ALIAS_LEFT_CLIP 0x0001
|
||||
#define ALIAS_TOP_CLIP 0x0002
|
||||
#define ALIAS_RIGHT_CLIP 0x0004
|
||||
#define ALIAS_BOTTOM_CLIP 0x0008
|
||||
#define ALIAS_Z_CLIP 0x0010
|
||||
#define ALIAS_XY_CLIP_MASK 0x000F
|
||||
|
||||
#define SURFCACHE_SIZE_AT_320X240 1024*768
|
||||
|
||||
#define BMODEL_FULLY_CLIPPED 0x10 // value returned by R_BmodelCheckBBox ()
|
||||
// if bbox is trivially rejected
|
||||
|
||||
#define XCENTERING (1.0 / 2.0)
|
||||
#define YCENTERING (1.0 / 2.0)
|
||||
|
||||
#define CLIP_EPSILON 0.001
|
||||
|
||||
#define BACKFACE_EPSILON 0.01
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
#define NEAR_CLIP 0.01
|
||||
|
||||
|
||||
#define MAXALIASVERTS 2000 // TODO: tune this
|
||||
#define ALIAS_Z_CLIP_PLANE 4
|
||||
|
||||
// turbulence stuff
|
||||
|
||||
#define AMP 8*0x10000
|
||||
#define AMP2 3
|
||||
#define SPEED 20
|
||||
|
||||
|
||||
/*
|
||||
====================================================
|
||||
|
||||
TYPES
|
||||
|
||||
====================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float u, v;
|
||||
float s, t;
|
||||
float zi;
|
||||
} emitpoint_t;
|
||||
|
||||
/*
|
||||
** if you change this structure be sure to change the #defines
|
||||
** listed after it!
|
||||
*/
|
||||
#define SMALL_FINALVERT 0
|
||||
|
||||
#if SMALL_FINALVERT
|
||||
|
||||
typedef struct finalvert_s {
|
||||
short u, v, s, t;
|
||||
int l;
|
||||
int zi;
|
||||
int flags;
|
||||
float xyz[3]; // eye space
|
||||
} finalvert_t;
|
||||
|
||||
#define FINALVERT_V0 0
|
||||
#define FINALVERT_V1 2
|
||||
#define FINALVERT_V2 4
|
||||
#define FINALVERT_V3 6
|
||||
#define FINALVERT_V4 8
|
||||
#define FINALVERT_V5 12
|
||||
#define FINALVERT_FLAGS 16
|
||||
#define FINALVERT_X 20
|
||||
#define FINALVERT_Y 24
|
||||
#define FINALVERT_Z 28
|
||||
#define FINALVERT_SIZE 32
|
||||
|
||||
#else
|
||||
|
||||
typedef struct finalvert_s {
|
||||
int u, v, s, t;
|
||||
int l;
|
||||
int zi;
|
||||
int flags;
|
||||
float xyz[3]; // eye space
|
||||
} finalvert_t;
|
||||
|
||||
#define FINALVERT_V0 0
|
||||
#define FINALVERT_V1 4
|
||||
#define FINALVERT_V2 8
|
||||
#define FINALVERT_V3 12
|
||||
#define FINALVERT_V4 16
|
||||
#define FINALVERT_V5 20
|
||||
#define FINALVERT_FLAGS 24
|
||||
#define FINALVERT_X 28
|
||||
#define FINALVERT_Y 32
|
||||
#define FINALVERT_Z 36
|
||||
#define FINALVERT_SIZE 40
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *pskin;
|
||||
int pskindesc;
|
||||
int skinwidth;
|
||||
int skinheight;
|
||||
dtriangle_t *ptriangles;
|
||||
finalvert_t *pfinalverts;
|
||||
int numtriangles;
|
||||
int drawtype;
|
||||
int seamfixupX16;
|
||||
qboolean do_vis_thresh;
|
||||
int vis_thresh;
|
||||
} affinetridesc_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
byte *surfdat; // destination for generated surface
|
||||
int rowbytes; // destination logical width in bytes
|
||||
msurface_t *surf; // description for surface to generate
|
||||
fixed8_t lightadj[MAXLIGHTMAPS];
|
||||
// adjust for lightmap levels for dynamic lighting
|
||||
image_t *image;
|
||||
int surfmip; // mipmapped ratio of surface texels / world pixels
|
||||
int surfwidth; // in mipmapped texels
|
||||
int surfheight; // in mipmapped texels
|
||||
} drawsurf_t;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
int ambientlight;
|
||||
int shadelight;
|
||||
float *plightvec;
|
||||
} alight_t;
|
||||
|
||||
// clipped bmodel edges
|
||||
|
||||
typedef struct bedge_s
|
||||
{
|
||||
mvertex_t *v[2];
|
||||
struct bedge_s *pnext;
|
||||
} bedge_t;
|
||||
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
typedef struct clipplane_s
|
||||
{
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
struct clipplane_s *next;
|
||||
byte leftedge;
|
||||
byte rightedge;
|
||||
byte reserved[2];
|
||||
} clipplane_t;
|
||||
|
||||
|
||||
typedef struct surfcache_s
|
||||
{
|
||||
struct surfcache_s *next;
|
||||
struct surfcache_s **owner; // NULL is an empty chunk of memory
|
||||
int lightadj[MAXLIGHTMAPS]; // checked for strobe flush
|
||||
int dlight;
|
||||
int size; // including header
|
||||
unsigned width;
|
||||
unsigned height; // DEBUG only needed for debug
|
||||
float mipscale;
|
||||
image_t *image;
|
||||
byte data[4]; // width*height elements
|
||||
} surfcache_t;
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
typedef struct espan_s
|
||||
{
|
||||
int u, v, count;
|
||||
struct espan_s *pnext;
|
||||
} espan_t;
|
||||
|
||||
// used by the polygon drawer (R_POLY.C) and sprite setup code (R_SPRITE.C)
|
||||
typedef struct
|
||||
{
|
||||
int nump;
|
||||
emitpoint_t *pverts;
|
||||
byte *pixels; // image
|
||||
int pixel_width; // image width
|
||||
int pixel_height; // image height
|
||||
vec3_t vup, vright, vpn; // in worldspace, for plane eq
|
||||
float dist;
|
||||
float s_offset, t_offset;
|
||||
float viewer_position[3];
|
||||
void (*drawspanlet)( void );
|
||||
int stipple_parity;
|
||||
} polydesc_t;
|
||||
|
||||
// FIXME: compress, make a union if that will help
|
||||
// insubmodel is only 1, flags is fewer than 32, spanstate could be a byte
|
||||
typedef struct surf_s
|
||||
{
|
||||
struct surf_s *next; // active surface stack in r_edge.c
|
||||
struct surf_s *prev; // used in r_edge.c for active surf stack
|
||||
struct espan_s *spans; // pointer to linked list of spans to draw
|
||||
int key; // sorting key (BSP order)
|
||||
int last_u; // set during tracing
|
||||
int spanstate; // 0 = not in span
|
||||
// 1 = in span
|
||||
// -1 = in inverted span (end before
|
||||
// start)
|
||||
int flags; // currentface flags
|
||||
msurface_t *msurf;
|
||||
entity_t *entity;
|
||||
float nearzi; // nearest 1/z on surface, for mipmapping
|
||||
qboolean insubmodel;
|
||||
float d_ziorigin, d_zistepu, d_zistepv;
|
||||
|
||||
int pad[2]; // to 64 bytes
|
||||
} surf_t;
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
typedef struct edge_s
|
||||
{
|
||||
fixed16_t u;
|
||||
fixed16_t u_step;
|
||||
struct edge_s *prev, *next;
|
||||
unsigned short surfs[2];
|
||||
struct edge_s *nextremove;
|
||||
float nearzi;
|
||||
medge_t *owner;
|
||||
} edge_t;
|
||||
|
||||
|
||||
/*
|
||||
====================================================
|
||||
|
||||
VARS
|
||||
|
||||
====================================================
|
||||
*/
|
||||
|
||||
extern int d_spanpixcount;
|
||||
extern int r_framecount; // sequence # of current frame since Quake
|
||||
// started
|
||||
extern float r_aliasuvscale; // scale-up factor for screen u and v
|
||||
// on Alias vertices passed to driver
|
||||
extern qboolean r_dowarp;
|
||||
|
||||
extern affinetridesc_t r_affinetridesc;
|
||||
|
||||
extern vec3_t r_pright, r_pup, r_ppn;
|
||||
|
||||
void D_DrawSurfaces (void);
|
||||
void R_DrawParticle( void );
|
||||
void D_ViewChanged (void);
|
||||
void D_WarpScreen (void);
|
||||
void R_PolysetUpdateTables (void);
|
||||
|
||||
extern void *acolormap; // FIXME: should go away
|
||||
|
||||
//=======================================================================//
|
||||
|
||||
// callbacks to Quake
|
||||
|
||||
extern drawsurf_t r_drawsurf;
|
||||
|
||||
void R_DrawSurface (void);
|
||||
|
||||
extern int c_surf;
|
||||
|
||||
extern byte r_warpbuffer[WARP_WIDTH * WARP_HEIGHT];
|
||||
|
||||
|
||||
|
||||
|
||||
extern float scale_for_mip;
|
||||
|
||||
extern qboolean d_roverwrapped;
|
||||
extern surfcache_t *sc_rover;
|
||||
extern surfcache_t *d_initial_rover;
|
||||
|
||||
extern float d_sdivzstepu, d_tdivzstepu, d_zistepu;
|
||||
extern float d_sdivzstepv, d_tdivzstepv, d_zistepv;
|
||||
extern float d_sdivzorigin, d_tdivzorigin, d_ziorigin;
|
||||
|
||||
extern fixed16_t sadjust, tadjust;
|
||||
extern fixed16_t bbextents, bbextentt;
|
||||
|
||||
|
||||
void D_DrawSpans16 (espan_t *pspans);
|
||||
void D_DrawZSpans (espan_t *pspans);
|
||||
void Turbulent8 (espan_t *pspan);
|
||||
void NonTurbulent8 (espan_t *pspan); //PGM
|
||||
|
||||
surfcache_t *D_CacheSurface (msurface_t *surface, int miplevel);
|
||||
|
||||
extern int d_vrectx, d_vrecty, d_vrectright_particle, d_vrectbottom_particle;
|
||||
|
||||
extern int d_pix_min, d_pix_max, d_pix_shift;
|
||||
|
||||
extern pixel_t *d_viewbuffer;
|
||||
extern short *d_pzbuffer;
|
||||
extern unsigned int d_zrowbytes, d_zwidth;
|
||||
extern short *zspantable[MAXHEIGHT];
|
||||
extern int d_scantable[MAXHEIGHT];
|
||||
|
||||
extern int d_minmip;
|
||||
extern float d_scalemip[3];
|
||||
|
||||
//===================================================================
|
||||
|
||||
extern int cachewidth;
|
||||
extern pixel_t *cacheblock;
|
||||
extern int r_screenwidth;
|
||||
|
||||
extern int r_drawnpolycount;
|
||||
|
||||
extern int sintable[1280];
|
||||
extern int intsintable[1280];
|
||||
extern int blanktable[1280]; // PGM
|
||||
|
||||
extern vec3_t vup, base_vup;
|
||||
extern vec3_t vpn, base_vpn;
|
||||
extern vec3_t vright, base_vright;
|
||||
|
||||
extern surf_t *surfaces, *surface_p, *surf_max;
|
||||
|
||||
// surfaces are generated in back to front order by the bsp, so if a surf
|
||||
// pointer is greater than another one, it should be drawn in front
|
||||
// surfaces[1] is the background, and is used as the active surface stack.
|
||||
// surfaces[0] is a dummy, because index 0 is used to indicate no surface
|
||||
// attached to an edge_t
|
||||
|
||||
//===================================================================
|
||||
|
||||
extern vec3_t sxformaxis[4]; // s axis transformed into viewspace
|
||||
extern vec3_t txformaxis[4]; // t axis transformed into viewspac
|
||||
|
||||
extern float xcenter, ycenter;
|
||||
extern float xscale, yscale;
|
||||
extern float xscaleinv, yscaleinv;
|
||||
extern float xscaleshrink, yscaleshrink;
|
||||
|
||||
extern void TransformVector (vec3_t in, vec3_t out);
|
||||
extern void SetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv,
|
||||
fixed8_t endvertu, fixed8_t endvertv);
|
||||
|
||||
extern int ubasestep, errorterm, erroradjustup, erroradjustdown;
|
||||
|
||||
//===========================================================================
|
||||
|
||||
extern cvar_t *sw_aliasstats;
|
||||
extern cvar_t *sw_clearcolor;
|
||||
extern cvar_t *sw_drawflat;
|
||||
extern cvar_t *sw_draworder;
|
||||
extern cvar_t *sw_maxedges;
|
||||
extern cvar_t *sw_maxsurfs;
|
||||
extern cvar_t *sw_mipcap;
|
||||
extern cvar_t *sw_mipscale;
|
||||
extern cvar_t *sw_mode;
|
||||
extern cvar_t *sw_reportsurfout;
|
||||
extern cvar_t *sw_reportedgeout;
|
||||
extern cvar_t *sw_stipplealpha;
|
||||
extern cvar_t *sw_surfcacheoverride;
|
||||
extern cvar_t *sw_waterwarp;
|
||||
|
||||
extern cvar_t *r_fullbright;
|
||||
extern cvar_t *r_lefthand;
|
||||
extern cvar_t *r_drawentities;
|
||||
extern cvar_t *r_drawworld;
|
||||
extern cvar_t *r_dspeeds;
|
||||
extern cvar_t *r_lerpmodels;
|
||||
|
||||
extern cvar_t *r_speeds;
|
||||
|
||||
extern cvar_t *r_lightlevel; //FIXME HACK
|
||||
|
||||
extern cvar_t *vid_fullscreen;
|
||||
extern cvar_t *vid_gamma;
|
||||
|
||||
|
||||
extern clipplane_t view_clipplanes[4];
|
||||
extern int *pfrustum_indexes[4];
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void R_RenderWorld (void);
|
||||
|
||||
//=============================================================================
|
||||
|
||||
extern mplane_t screenedge[4];
|
||||
|
||||
extern vec3_t r_origin;
|
||||
|
||||
extern entity_t r_worldentity;
|
||||
extern model_t *currentmodel;
|
||||
extern entity_t *currententity;
|
||||
extern vec3_t modelorg;
|
||||
extern vec3_t r_entorigin;
|
||||
|
||||
extern float verticalFieldOfView;
|
||||
extern float xOrigin, yOrigin;
|
||||
|
||||
extern int r_visframecount;
|
||||
|
||||
extern msurface_t *r_alpha_surfaces;
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void R_ClearPolyList (void);
|
||||
void R_DrawPolyList (void);
|
||||
|
||||
//
|
||||
// current entity info
|
||||
//
|
||||
extern qboolean insubmodel;
|
||||
|
||||
void R_DrawAlphaSurfaces( void );
|
||||
|
||||
void R_DrawSprite (void);
|
||||
void R_DrawBeam( entity_t *e );
|
||||
|
||||
void R_RenderFace (msurface_t *fa, int clipflags);
|
||||
void R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf);
|
||||
void R_TransformPlane (mplane_t *p, float *normal, float *dist);
|
||||
void R_TransformFrustum (void);
|
||||
void R_DrawSurfaceBlock16 (void);
|
||||
void R_DrawSurfaceBlock8 (void);
|
||||
|
||||
#if id386
|
||||
|
||||
void R_DrawSurfaceBlock8_mip0 (void);
|
||||
void R_DrawSurfaceBlock8_mip1 (void);
|
||||
void R_DrawSurfaceBlock8_mip2 (void);
|
||||
void R_DrawSurfaceBlock8_mip3 (void);
|
||||
|
||||
#endif
|
||||
|
||||
void R_GenSkyTile (void *pdest);
|
||||
void R_GenSkyTile16 (void *pdest);
|
||||
void R_Surf8Patch (void);
|
||||
void R_Surf16Patch (void);
|
||||
void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags, mnode_t *topnode);
|
||||
void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel, mnode_t *topnode);
|
||||
|
||||
void R_AddPolygonEdges (emitpoint_t *pverts, int numverts, int miplevel);
|
||||
surf_t *R_GetSurf (void);
|
||||
void R_AliasDrawModel (void);
|
||||
void R_BeginEdgeFrame (void);
|
||||
void R_ScanEdges (void);
|
||||
void D_DrawSurfaces (void);
|
||||
void R_InsertNewEdges (edge_t *edgestoadd, edge_t *edgelist);
|
||||
void R_StepActiveU (edge_t *pedge);
|
||||
void R_RemoveEdges (edge_t *pedge);
|
||||
void R_PushDlights (model_t *model);
|
||||
|
||||
extern void R_Surf8Start (void);
|
||||
extern void R_Surf8End (void);
|
||||
extern void R_Surf16Start (void);
|
||||
extern void R_Surf16End (void);
|
||||
extern void R_EdgeCodeStart (void);
|
||||
extern void R_EdgeCodeEnd (void);
|
||||
|
||||
extern void R_RotateBmodel (void);
|
||||
|
||||
extern int c_faceclip;
|
||||
extern int r_polycount;
|
||||
extern int r_wholepolycount;
|
||||
|
||||
extern int ubasestep, errorterm, erroradjustup, erroradjustdown;
|
||||
|
||||
extern fixed16_t sadjust, tadjust;
|
||||
extern fixed16_t bbextents, bbextentt;
|
||||
|
||||
extern mvertex_t *r_ptverts, *r_ptvertsmax;
|
||||
|
||||
extern float entity_rotation[3][3];
|
||||
|
||||
extern int r_currentkey;
|
||||
extern int r_currentbkey;
|
||||
|
||||
void R_InitTurb (void);
|
||||
|
||||
void R_DrawParticles (void);
|
||||
void R_SurfacePatch (void);
|
||||
|
||||
extern int r_amodels_drawn;
|
||||
extern edge_t *auxedges;
|
||||
extern int r_numallocatededges;
|
||||
extern edge_t *r_edges, *edge_p, *edge_max;
|
||||
|
||||
extern edge_t *newedges[MAXHEIGHT];
|
||||
extern edge_t *removeedges[MAXHEIGHT];
|
||||
|
||||
// FIXME: make stack vars when debugging done
|
||||
extern edge_t edge_head;
|
||||
extern edge_t edge_tail;
|
||||
extern edge_t edge_aftertail;
|
||||
|
||||
extern int r_aliasblendcolor;
|
||||
|
||||
extern float aliasxscale, aliasyscale, aliasxcenter, aliasycenter;
|
||||
|
||||
extern int r_outofsurfaces;
|
||||
extern int r_outofedges;
|
||||
|
||||
extern mvertex_t *r_pcurrentvertbase;
|
||||
extern int r_maxvalidedgeoffset;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
finalvert_t *a, *b, *c;
|
||||
} aliastriangleparms_t;
|
||||
|
||||
extern aliastriangleparms_t aliastriangleparms;
|
||||
|
||||
void R_DrawTriangle( void );
|
||||
//void R_DrawTriangle (finalvert_t *index0, finalvert_t *index1, finalvert_t *index2);
|
||||
void R_AliasClipTriangle (finalvert_t *index0, finalvert_t *index1, finalvert_t *index2);
|
||||
|
||||
|
||||
extern float r_time1;
|
||||
extern float da_time1, da_time2;
|
||||
extern float dp_time1, dp_time2, db_time1, db_time2, rw_time1, rw_time2;
|
||||
extern float se_time1, se_time2, de_time1, de_time2, dv_time1, dv_time2;
|
||||
extern int r_frustum_indexes[4*6];
|
||||
extern int r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs;
|
||||
extern qboolean r_surfsonstack;
|
||||
|
||||
extern mleaf_t *r_viewleaf;
|
||||
extern int r_viewcluster, r_oldviewcluster;
|
||||
|
||||
extern int r_clipflags;
|
||||
extern int r_dlightframecount;
|
||||
extern qboolean r_fov_greater_than_90;
|
||||
|
||||
extern image_t *r_notexture_mip;
|
||||
extern model_t *r_worldmodel;
|
||||
|
||||
void R_PrintAliasStats (void);
|
||||
void R_PrintTimes (void);
|
||||
void R_PrintDSpeeds (void);
|
||||
void R_AnimateLight (void);
|
||||
void R_LightPoint (vec3_t p, vec3_t color);
|
||||
void R_SetupFrame (void);
|
||||
void R_cshift_f (void);
|
||||
void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1);
|
||||
void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip);
|
||||
void R_SplitEntityOnNode2 (mnode_t *node);
|
||||
|
||||
extern refdef_t r_newrefdef;
|
||||
|
||||
extern surfcache_t *sc_rover, *sc_base;
|
||||
|
||||
extern void *colormap;
|
||||
|
||||
//====================================================================
|
||||
|
||||
float R_DLightPoint (vec3_t p);
|
||||
|
||||
void R_NewMap (void);
|
||||
void R_Register (void);
|
||||
void R_UnRegister (void);
|
||||
void Draw_InitLocal (void);
|
||||
qboolean R_Init( void *hInstance, void *wndProc );
|
||||
void R_Shutdown (void);
|
||||
void R_InitCaches (void);
|
||||
void D_FlushCaches (void);
|
||||
|
||||
void R_ScreenShot_f( void );
|
||||
void R_BeginRegistration (char *map);
|
||||
struct model_s *R_RegisterModel (char *name);
|
||||
void R_EndRegistration (void);
|
||||
|
||||
void R_RenderFrame (refdef_t *fd);
|
||||
|
||||
struct image_s *Draw_FindPic (char *name);
|
||||
|
||||
void Draw_GetPicSize (int *w, int *h, char *name);
|
||||
void Draw_Pic (int x, int y, char *name);
|
||||
void Draw_StretchPic (int x, int y, int w, int h, char *name);
|
||||
void Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, byte *data);
|
||||
void Draw_Char (int x, int y, int c);
|
||||
void Draw_TileClear (int x, int y, int w, int h, char *name);
|
||||
void Draw_Fill (int x, int y, int w, int h, int c);
|
||||
void Draw_FadeScreen (void);
|
||||
|
||||
void Draw_GetPalette (void);
|
||||
|
||||
void R_BeginFrame( float camera_separation );
|
||||
|
||||
void R_CinematicSetPalette( const unsigned char *palette );
|
||||
|
||||
extern unsigned d_8to24table[256]; // base
|
||||
|
||||
void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length);
|
||||
void Sys_SetFPCW (void);
|
||||
|
||||
void LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height);
|
||||
|
||||
void R_InitImages (void);
|
||||
void R_ShutdownImages (void);
|
||||
image_t *R_FindImage (char *name, imagetype_t type);
|
||||
void R_FreeUnusedImages (void);
|
||||
|
||||
void R_GammaCorrectAndSetPalette( const unsigned char *pal );
|
||||
|
||||
extern mtexinfo_t *sky_texinfo[6];
|
||||
|
||||
void R_InitSkyBox (void);
|
||||
|
||||
typedef struct swstate_s
|
||||
{
|
||||
qboolean fullscreen;
|
||||
int prev_mode; // last valid SW mode
|
||||
|
||||
byte gammatable[256];
|
||||
byte currentpalette[1024];
|
||||
|
||||
} swstate_t;
|
||||
|
||||
void R_IMFlatShadedQuad( vec3_t a, vec3_t b, vec3_t c, vec3_t d, int color, float alpha );
|
||||
|
||||
extern swstate_t sw_state;
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
|
||||
IMPORTED FUNCTIONS
|
||||
|
||||
====================================================================
|
||||
*/
|
||||
|
||||
extern refimport_t ri;
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
|
||||
IMPLEMENTATION FUNCTIONS
|
||||
|
||||
====================================================================
|
||||
*/
|
||||
|
||||
void SWimp_BeginFrame( float camera_separation );
|
||||
void SWimp_EndFrame (void);
|
||||
int SWimp_Init( void *hInstance, void *wndProc );
|
||||
void SWimp_SetPalette( const unsigned char *palette);
|
||||
void SWimp_Shutdown( void );
|
||||
rserr_t SWimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen );
|
||||
void SWimp_AppActivate( qboolean active );
|
||||
|
1422
ref_soft/r_main.c
Normal file
1422
ref_soft/r_main.c
Normal file
File diff suppressed because it is too large
Load Diff
670
ref_soft/r_misc.c
Normal file
670
ref_soft/r_misc.c
Normal file
@ -0,0 +1,670 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 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_misc.c
|
||||
|
||||
#include "r_local.h"
|
||||
|
||||
#define NUM_MIPS 4
|
||||
|
||||
cvar_t *sw_mipcap;
|
||||
cvar_t *sw_mipscale;
|
||||
|
||||
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;
|
||||
|
||||
int d_vrectx, d_vrecty, d_vrectright_particle, d_vrectbottom_particle;
|
||||
|
||||
int d_pix_min, d_pix_max, d_pix_shift;
|
||||
|
||||
int d_scantable[MAXHEIGHT];
|
||||
short *zspantable[MAXHEIGHT];
|
||||
|
||||
/*
|
||||
================
|
||||
D_Patch
|
||||
================
|
||||
*/
|
||||
void D_Patch (void)
|
||||
{
|
||||
#if id386
|
||||
extern void D_Aff8Patch( void );
|
||||
static qboolean protectset8 = false;
|
||||
extern void D_PolysetAff8Start( void );
|
||||
|
||||
if (!protectset8)
|
||||
{
|
||||
Sys_MakeCodeWriteable ((int)D_PolysetAff8Start,
|
||||
(int)D_Aff8Patch - (int)D_PolysetAff8Start);
|
||||
Sys_MakeCodeWriteable ((long)R_Surf8Start,
|
||||
(long)R_Surf8End - (long)R_Surf8Start);
|
||||
protectset8 = true;
|
||||
}
|
||||
colormap = vid.colormap;
|
||||
|
||||
R_Surf8Patch ();
|
||||
D_Aff8Patch();
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
================
|
||||
D_ViewChanged
|
||||
================
|
||||
*/
|
||||
unsigned char *alias_colormap;
|
||||
|
||||
void D_ViewChanged (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
for (i=0 ; i<vid.height; i++)
|
||||
{
|
||||
d_scantable[i] = i*r_screenwidth;
|
||||
zspantable[i] = d_pzbuffer + i*d_zwidth;
|
||||
}
|
||||
|
||||
/*
|
||||
** clear Z-buffer and color-buffers if we're doing the gallery
|
||||
*/
|
||||
if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
|
||||
{
|
||||
memset( d_pzbuffer, 0xff, vid.width * vid.height * sizeof( d_pzbuffer[0] ) );
|
||||
Draw_Fill( r_newrefdef.x, r_newrefdef.y, r_newrefdef.width, r_newrefdef.height,( int ) sw_clearcolor->value & 0xff );
|
||||
}
|
||||
|
||||
alias_colormap = vid.colormap;
|
||||
|
||||
D_Patch ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
R_PrintTimes
|
||||
=============
|
||||
*/
|
||||
void R_PrintTimes (void)
|
||||
{
|
||||
int r_time2;
|
||||
int ms;
|
||||
|
||||
r_time2 = Sys_Milliseconds ();
|
||||
|
||||
ms = r_time2 - r_time1;
|
||||
|
||||
ri.Con_Printf (PRINT_ALL,"%5i ms %3i/%3i/%3i poly %3i surf\n",
|
||||
ms, c_faceclip, r_polycount, r_drawnpolycount, c_surf);
|
||||
c_surf = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
R_PrintDSpeeds
|
||||
=============
|
||||
*/
|
||||
void R_PrintDSpeeds (void)
|
||||
{
|
||||
int ms, dp_time, r_time2, rw_time, db_time, se_time, de_time, da_time;
|
||||
|
||||
r_time2 = Sys_Milliseconds ();
|
||||
|
||||
da_time = (da_time2 - da_time1);
|
||||
dp_time = (dp_time2 - dp_time1);
|
||||
rw_time = (rw_time2 - rw_time1);
|
||||
db_time = (db_time2 - db_time1);
|
||||
se_time = (se_time2 - se_time1);
|
||||
de_time = (de_time2 - de_time1);
|
||||
ms = (r_time2 - r_time1);
|
||||
|
||||
ri.Con_Printf (PRINT_ALL,"%3i %2ip %2iw %2ib %2is %2ie %2ia\n",
|
||||
ms, dp_time, rw_time, db_time, se_time, de_time, da_time);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
R_PrintAliasStats
|
||||
=============
|
||||
*/
|
||||
void R_PrintAliasStats (void)
|
||||
{
|
||||
ri.Con_Printf (PRINT_ALL,"%3i polygon model drawn\n", r_amodels_drawn);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
R_TransformFrustum
|
||||
===================
|
||||
*/
|
||||
void R_TransformFrustum (void)
|
||||
{
|
||||
int i;
|
||||
vec3_t v, v2;
|
||||
|
||||
for (i=0 ; i<4 ; i++)
|
||||
{
|
||||
v[0] = screenedge[i].normal[2];
|
||||
v[1] = -screenedge[i].normal[0];
|
||||
v[2] = screenedge[i].normal[1];
|
||||
|
||||
v2[0] = v[1]*vright[0] + v[2]*vup[0] + v[0]*vpn[0];
|
||||
v2[1] = v[1]*vright[1] + v[2]*vup[1] + v[0]*vpn[1];
|
||||
v2[2] = v[1]*vright[2] + v[2]*vup[2] + v[0]*vpn[2];
|
||||
|
||||
VectorCopy (v2, view_clipplanes[i].normal);
|
||||
|
||||
view_clipplanes[i].dist = DotProduct (modelorg, v2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if !(defined __linux__ && defined __i386__)
|
||||
#if !id386
|
||||
|
||||
/*
|
||||
================
|
||||
TransformVector
|
||||
================
|
||||
*/
|
||||
void TransformVector (vec3_t in, vec3_t out)
|
||||
{
|
||||
out[0] = DotProduct(in,vright);
|
||||
out[1] = DotProduct(in,vup);
|
||||
out[2] = DotProduct(in,vpn);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
__declspec( naked ) void TransformVector( vec3_t vin, vec3_t vout )
|
||||
{
|
||||
__asm mov eax, dword ptr [esp+4]
|
||||
__asm mov edx, dword ptr [esp+8]
|
||||
|
||||
__asm fld dword ptr [eax+0]
|
||||
__asm fmul dword ptr [vright+0]
|
||||
__asm fld dword ptr [eax+0]
|
||||
__asm fmul dword ptr [vup+0]
|
||||
__asm fld dword ptr [eax+0]
|
||||
__asm fmul dword ptr [vpn+0]
|
||||
|
||||
__asm fld dword ptr [eax+4]
|
||||
__asm fmul dword ptr [vright+4]
|
||||
__asm fld dword ptr [eax+4]
|
||||
__asm fmul dword ptr [vup+4]
|
||||
__asm fld dword ptr [eax+4]
|
||||
__asm fmul dword ptr [vpn+4]
|
||||
|
||||
__asm fxch st(2)
|
||||
|
||||
__asm faddp st(5), st(0)
|
||||
__asm faddp st(3), st(0)
|
||||
__asm faddp st(1), st(0)
|
||||
|
||||
__asm fld dword ptr [eax+8]
|
||||
__asm fmul dword ptr [vright+8]
|
||||
__asm fld dword ptr [eax+8]
|
||||
__asm fmul dword ptr [vup+8]
|
||||
__asm fld dword ptr [eax+8]
|
||||
__asm fmul dword ptr [vpn+8]
|
||||
|
||||
__asm fxch st(2)
|
||||
|
||||
__asm faddp st(5), st(0)
|
||||
__asm faddp st(3), st(0)
|
||||
__asm faddp st(1), st(0)
|
||||
|
||||
__asm fstp dword ptr [edx+8]
|
||||
__asm fstp dword ptr [edx+4]
|
||||
__asm fstp dword ptr [edx+0]
|
||||
|
||||
__asm ret
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_TransformPlane
|
||||
================
|
||||
*/
|
||||
void R_TransformPlane (mplane_t *p, float *normal, float *dist)
|
||||
{
|
||||
float d;
|
||||
|
||||
d = DotProduct (r_origin, p->normal);
|
||||
*dist = p->dist - d;
|
||||
// TODO: when we have rotating entities, this will need to use the view matrix
|
||||
TransformVector (p->normal, normal);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
R_SetUpFrustumIndexes
|
||||
===============
|
||||
*/
|
||||
void R_SetUpFrustumIndexes (void)
|
||||
{
|
||||
int i, j, *pindex;
|
||||
|
||||
pindex = r_frustum_indexes;
|
||||
|
||||
for (i=0 ; i<4 ; i++)
|
||||
{
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
if (view_clipplanes[i].normal[j] < 0)
|
||||
{
|
||||
pindex[j] = j;
|
||||
pindex[j+3] = j+3;
|
||||
}
|
||||
else
|
||||
{
|
||||
pindex[j] = j+3;
|
||||
pindex[j+3] = j;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: do just once at start
|
||||
pfrustum_indexes[i] = pindex;
|
||||
pindex += 6;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_ViewChanged
|
||||
|
||||
Called every time the vid structure or r_refdef changes.
|
||||
Guaranteed to be called before the first refresh
|
||||
===============
|
||||
*/
|
||||
void R_ViewChanged (vrect_t *vr)
|
||||
{
|
||||
int i;
|
||||
|
||||
r_refdef.vrect = *vr;
|
||||
|
||||
r_refdef.horizontalFieldOfView = 2*tan((float)r_newrefdef.fov_x/360*M_PI);;
|
||||
verticalFieldOfView = 2*tan((float)r_newrefdef.fov_y/360*M_PI);
|
||||
|
||||
r_refdef.fvrectx = (float)r_refdef.vrect.x;
|
||||
r_refdef.fvrectx_adj = (float)r_refdef.vrect.x - 0.5;
|
||||
r_refdef.vrect_x_adj_shift20 = (r_refdef.vrect.x<<20) + (1<<19) - 1;
|
||||
r_refdef.fvrecty = (float)r_refdef.vrect.y;
|
||||
r_refdef.fvrecty_adj = (float)r_refdef.vrect.y - 0.5;
|
||||
r_refdef.vrectright = r_refdef.vrect.x + r_refdef.vrect.width;
|
||||
r_refdef.vrectright_adj_shift20 = (r_refdef.vrectright<<20) + (1<<19) - 1;
|
||||
r_refdef.fvrectright = (float)r_refdef.vrectright;
|
||||
r_refdef.fvrectright_adj = (float)r_refdef.vrectright - 0.5;
|
||||
r_refdef.vrectrightedge = (float)r_refdef.vrectright - 0.99;
|
||||
r_refdef.vrectbottom = r_refdef.vrect.y + r_refdef.vrect.height;
|
||||
r_refdef.fvrectbottom = (float)r_refdef.vrectbottom;
|
||||
r_refdef.fvrectbottom_adj = (float)r_refdef.vrectbottom - 0.5;
|
||||
|
||||
r_refdef.aliasvrect.x = (int)(r_refdef.vrect.x * r_aliasuvscale);
|
||||
r_refdef.aliasvrect.y = (int)(r_refdef.vrect.y * r_aliasuvscale);
|
||||
r_refdef.aliasvrect.width = (int)(r_refdef.vrect.width * r_aliasuvscale);
|
||||
r_refdef.aliasvrect.height = (int)(r_refdef.vrect.height * r_aliasuvscale);
|
||||
r_refdef.aliasvrectright = r_refdef.aliasvrect.x +
|
||||
r_refdef.aliasvrect.width;
|
||||
r_refdef.aliasvrectbottom = r_refdef.aliasvrect.y +
|
||||
r_refdef.aliasvrect.height;
|
||||
|
||||
xOrigin = r_refdef.xOrigin;
|
||||
yOrigin = r_refdef.yOrigin;
|
||||
|
||||
// values for perspective projection
|
||||
// if math were exact, the values would range from 0.5 to to range+0.5
|
||||
// hopefully they wll be in the 0.000001 to range+.999999 and truncate
|
||||
// the polygon rasterization will never render in the first row or column
|
||||
// but will definately render in the [range] row and column, so adjust the
|
||||
// buffer origin to get an exact edge to edge fill
|
||||
xcenter = ((float)r_refdef.vrect.width * XCENTERING) +
|
||||
r_refdef.vrect.x - 0.5;
|
||||
aliasxcenter = xcenter * r_aliasuvscale;
|
||||
ycenter = ((float)r_refdef.vrect.height * YCENTERING) +
|
||||
r_refdef.vrect.y - 0.5;
|
||||
aliasycenter = ycenter * r_aliasuvscale;
|
||||
|
||||
xscale = r_refdef.vrect.width / r_refdef.horizontalFieldOfView;
|
||||
aliasxscale = xscale * r_aliasuvscale;
|
||||
xscaleinv = 1.0 / xscale;
|
||||
|
||||
yscale = xscale;
|
||||
aliasyscale = yscale * r_aliasuvscale;
|
||||
yscaleinv = 1.0 / yscale;
|
||||
xscaleshrink = (r_refdef.vrect.width-6)/r_refdef.horizontalFieldOfView;
|
||||
yscaleshrink = xscaleshrink;
|
||||
|
||||
// left side clip
|
||||
screenedge[0].normal[0] = -1.0 / (xOrigin*r_refdef.horizontalFieldOfView);
|
||||
screenedge[0].normal[1] = 0;
|
||||
screenedge[0].normal[2] = 1;
|
||||
screenedge[0].type = PLANE_ANYZ;
|
||||
|
||||
// right side clip
|
||||
screenedge[1].normal[0] =
|
||||
1.0 / ((1.0-xOrigin)*r_refdef.horizontalFieldOfView);
|
||||
screenedge[1].normal[1] = 0;
|
||||
screenedge[1].normal[2] = 1;
|
||||
screenedge[1].type = PLANE_ANYZ;
|
||||
|
||||
// top side clip
|
||||
screenedge[2].normal[0] = 0;
|
||||
screenedge[2].normal[1] = -1.0 / (yOrigin*verticalFieldOfView);
|
||||
screenedge[2].normal[2] = 1;
|
||||
screenedge[2].type = PLANE_ANYZ;
|
||||
|
||||
// bottom side clip
|
||||
screenedge[3].normal[0] = 0;
|
||||
screenedge[3].normal[1] = 1.0 / ((1.0-yOrigin)*verticalFieldOfView);
|
||||
screenedge[3].normal[2] = 1;
|
||||
screenedge[3].type = PLANE_ANYZ;
|
||||
|
||||
for (i=0 ; i<4 ; i++)
|
||||
VectorNormalize (screenedge[i].normal);
|
||||
|
||||
D_ViewChanged ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
R_SetupFrame
|
||||
===============
|
||||
*/
|
||||
void R_SetupFrame (void)
|
||||
{
|
||||
int i;
|
||||
vrect_t vrect;
|
||||
|
||||
if (r_fullbright->modified)
|
||||
{
|
||||
r_fullbright->modified = false;
|
||||
D_FlushCaches (); // so all lighting changes
|
||||
}
|
||||
|
||||
r_framecount++;
|
||||
|
||||
|
||||
// build the transformation matrix for the given view angles
|
||||
VectorCopy (r_refdef.vieworg, modelorg);
|
||||
VectorCopy (r_refdef.vieworg, r_origin);
|
||||
|
||||
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
|
||||
|
||||
// current viewleaf
|
||||
if ( !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
|
||||
{
|
||||
r_viewleaf = Mod_PointInLeaf (r_origin, r_worldmodel);
|
||||
r_viewcluster = r_viewleaf->cluster;
|
||||
}
|
||||
|
||||
if (sw_waterwarp->value && (r_newrefdef.rdflags & RDF_UNDERWATER) )
|
||||
r_dowarp = true;
|
||||
else
|
||||
r_dowarp = false;
|
||||
|
||||
if (r_dowarp)
|
||||
{ // warp into off screen buffer
|
||||
vrect.x = 0;
|
||||
vrect.y = 0;
|
||||
vrect.width = r_newrefdef.width < WARP_WIDTH ? r_newrefdef.width : WARP_WIDTH;
|
||||
vrect.height = r_newrefdef.height < WARP_HEIGHT ? r_newrefdef.height : WARP_HEIGHT;
|
||||
|
||||
d_viewbuffer = r_warpbuffer;
|
||||
r_screenwidth = WARP_WIDTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
vrect.x = r_newrefdef.x;
|
||||
vrect.y = r_newrefdef.y;
|
||||
vrect.width = r_newrefdef.width;
|
||||
vrect.height = r_newrefdef.height;
|
||||
|
||||
d_viewbuffer = (void *)vid.buffer;
|
||||
r_screenwidth = vid.rowbytes;
|
||||
}
|
||||
|
||||
R_ViewChanged (&vrect);
|
||||
|
||||
// start off with just the four screen edge clip planes
|
||||
R_TransformFrustum ();
|
||||
R_SetUpFrustumIndexes ();
|
||||
|
||||
// save base values
|
||||
VectorCopy (vpn, base_vpn);
|
||||
VectorCopy (vright, base_vright);
|
||||
VectorCopy (vup, base_vup);
|
||||
|
||||
// clear frame counts
|
||||
c_faceclip = 0;
|
||||
d_spanpixcount = 0;
|
||||
r_polycount = 0;
|
||||
r_drawnpolycount = 0;
|
||||
r_wholepolycount = 0;
|
||||
r_amodels_drawn = 0;
|
||||
r_outofsurfaces = 0;
|
||||
r_outofedges = 0;
|
||||
|
||||
// d_setup
|
||||
d_roverwrapped = false;
|
||||
d_initial_rover = sc_rover;
|
||||
|
||||
d_minmip = sw_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] * sw_mipscale->value;
|
||||
|
||||
d_aflatcolor = 0;
|
||||
}
|
||||
|
||||
|
||||
#if !id386
|
||||
|
||||
/*
|
||||
================
|
||||
R_SurfacePatch
|
||||
================
|
||||
*/
|
||||
void R_SurfacePatch (void)
|
||||
{
|
||||
// we only patch code on Intel
|
||||
}
|
||||
|
||||
#endif // !id386
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
SCREEN SHOTS
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
WritePCXfile
|
||||
==============
|
||||
*/
|
||||
void WritePCXfile (char *filename, byte *data, int width, int height,
|
||||
int rowbytes, byte *palette)
|
||||
{
|
||||
int i, j, length;
|
||||
pcx_t *pcx;
|
||||
byte *pack;
|
||||
FILE *f;
|
||||
|
||||
pcx = (pcx_t *)malloc (width*height*2+1000);
|
||||
if (!pcx)
|
||||
return;
|
||||
|
||||
pcx->manufacturer = 0x0a; // PCX id
|
||||
pcx->version = 5; // 256 color
|
||||
pcx->encoding = 1; // uncompressed
|
||||
pcx->bits_per_pixel = 8; // 256 color
|
||||
pcx->xmin = 0;
|
||||
pcx->ymin = 0;
|
||||
pcx->xmax = LittleShort((short)(width-1));
|
||||
pcx->ymax = LittleShort((short)(height-1));
|
||||
pcx->hres = LittleShort((short)width);
|
||||
pcx->vres = LittleShort((short)height);
|
||||
memset (pcx->palette,0,sizeof(pcx->palette));
|
||||
pcx->color_planes = 1; // chunky image
|
||||
pcx->bytes_per_line = LittleShort((short)width);
|
||||
pcx->palette_type = LittleShort(2); // not a grey scale
|
||||
memset (pcx->filler,0,sizeof(pcx->filler));
|
||||
|
||||
// pack the image
|
||||
pack = &pcx->data;
|
||||
|
||||
for (i=0 ; i<height ; i++)
|
||||
{
|
||||
for (j=0 ; j<width ; j++)
|
||||
{
|
||||
if ( (*data & 0xc0) != 0xc0)
|
||||
*pack++ = *data++;
|
||||
else
|
||||
{
|
||||
*pack++ = 0xc1;
|
||||
*pack++ = *data++;
|
||||
}
|
||||
}
|
||||
|
||||
data += rowbytes - width;
|
||||
}
|
||||
|
||||
// write the palette
|
||||
*pack++ = 0x0c; // palette ID byte
|
||||
for (i=0 ; i<768 ; i++)
|
||||
*pack++ = *palette++;
|
||||
|
||||
// write output file
|
||||
length = pack - (byte *)pcx;
|
||||
f = fopen (filename, "wb");
|
||||
if (!f)
|
||||
ri.Con_Printf (PRINT_ALL, "Failed to open to %s\n", filename);
|
||||
else
|
||||
{
|
||||
fwrite ((void *)pcx, 1, length, f);
|
||||
fclose (f);
|
||||
}
|
||||
|
||||
free (pcx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
R_ScreenShot_f
|
||||
==================
|
||||
*/
|
||||
void R_ScreenShot_f (void)
|
||||
{
|
||||
int i;
|
||||
char pcxname[80];
|
||||
char checkname[MAX_OSPATH];
|
||||
FILE *f;
|
||||
byte palette[768];
|
||||
|
||||
// create the scrnshots directory if it doesn't exist
|
||||
Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot", ri.FS_Gamedir());
|
||||
Sys_Mkdir (checkname);
|
||||
|
||||
//
|
||||
// find a file name to save it to
|
||||
//
|
||||
strcpy(pcxname,"quake00.pcx");
|
||||
|
||||
for (i=0 ; i<=99 ; i++)
|
||||
{
|
||||
pcxname[5] = i/10 + '0';
|
||||
pcxname[6] = i%10 + '0';
|
||||
Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot/%s", ri.FS_Gamedir(), pcxname);
|
||||
f = fopen (checkname, "r");
|
||||
if (!f)
|
||||
break; // file doesn't exist
|
||||
fclose (f);
|
||||
}
|
||||
if (i==100)
|
||||
{
|
||||
ri.Con_Printf (PRINT_ALL, "R_ScreenShot_f: Couldn't create a PCX");
|
||||
return;
|
||||
}
|
||||
|
||||
// turn the current 32 bit palette into a 24 bit palette
|
||||
for (i=0 ; i<256 ; i++)
|
||||
{
|
||||
palette[i*3+0] = sw_state.currentpalette[i*4+0];
|
||||
palette[i*3+1] = sw_state.currentpalette[i*4+1];
|
||||
palette[i*3+2] = sw_state.currentpalette[i*4+2];
|
||||
}
|
||||
|
||||
//
|
||||
// save the pcx file
|
||||
//
|
||||
|
||||
WritePCXfile (checkname, vid.buffer, vid.width, vid.height, vid.rowbytes,
|
||||
palette);
|
||||
|
||||
ri.Con_Printf (PRINT_ALL, "Wrote %s\n", checkname);
|
||||
}
|
||||
|
1241
ref_soft/r_model.c
Normal file
1241
ref_soft/r_model.c
Normal file
File diff suppressed because it is too large
Load Diff
256
ref_soft/r_model.h
Normal file
256
ref_soft/r_model.h
Normal file
@ -0,0 +1,256 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 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.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __MODEL__
|
||||
#define __MODEL__
|
||||
|
||||
/*
|
||||
|
||||
d*_t structures are on-disk representations
|
||||
m*_t structures are in-memory
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
BRUSH MODELS
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// in memory representation
|
||||
//
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
typedef struct
|
||||
{
|
||||
vec3_t position;
|
||||
} mvertex_t;
|
||||
|
||||
#define SIDE_FRONT 0
|
||||
#define SIDE_BACK 1
|
||||
#define SIDE_ON 2
|
||||
|
||||
|
||||
// plane_t structure
|
||||
// !!! if this is changed, it must be changed in asm_i386.h too !!!
|
||||
typedef struct mplane_s
|
||||
{
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
byte type; // for texture axis selection and fast side tests
|
||||
byte signbits; // signx + signy<<1 + signz<<1
|
||||
byte pad[2];
|
||||
} mplane_t;
|
||||
|
||||
|
||||
// FIXME: differentiate from texinfo SURF_ flags
|
||||
#define SURF_PLANEBACK 2
|
||||
#define SURF_DRAWSKY 4 // sky brush face
|
||||
#define SURF_DRAWTURB 0x10
|
||||
#define SURF_DRAWBACKGROUND 0x40
|
||||
#define SURF_DRAWSKYBOX 0x80 // sky box
|
||||
|
||||
#define SURF_FLOW 0x100 //PGM
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
typedef struct
|
||||
{
|
||||
unsigned short v[2];
|
||||
unsigned int cachededgeoffset;
|
||||
} medge_t;
|
||||
|
||||
typedef struct mtexinfo_s
|
||||
{
|
||||
float vecs[2][4];
|
||||
float mipadjust;
|
||||
image_t *image;
|
||||
int flags;
|
||||
int numframes;
|
||||
struct mtexinfo_s *next; // animation chain
|
||||
} mtexinfo_t;
|
||||
|
||||
typedef struct msurface_s
|
||||
{
|
||||
int visframe; // should be drawn when node is crossed
|
||||
|
||||
int dlightframe;
|
||||
int dlightbits;
|
||||
|
||||
mplane_t *plane;
|
||||
int flags;
|
||||
|
||||
int firstedge; // look up in model->surfedges[], negative numbers
|
||||
int numedges; // are backwards edges
|
||||
|
||||
// surface generation data
|
||||
struct surfcache_s *cachespots[MIPLEVELS];
|
||||
|
||||
short texturemins[2];
|
||||
short extents[2];
|
||||
|
||||
mtexinfo_t *texinfo;
|
||||
|
||||
// lighting info
|
||||
byte styles[MAXLIGHTMAPS];
|
||||
byte *samples; // [numstyles*surfsize]
|
||||
|
||||
struct msurface_s *nextalphasurface;
|
||||
} msurface_t;
|
||||
|
||||
|
||||
#define CONTENTS_NODE -1
|
||||
typedef struct mnode_s
|
||||
{
|
||||
// common with leaf
|
||||
int contents; // CONTENTS_NODE, to differentiate from leafs
|
||||
int visframe; // node needs to be traversed if current
|
||||
|
||||
short minmaxs[6]; // for bounding box culling
|
||||
|
||||
struct mnode_s *parent;
|
||||
|
||||
// node specific
|
||||
mplane_t *plane;
|
||||
struct mnode_s *children[2];
|
||||
|
||||
unsigned short firstsurface;
|
||||
unsigned short numsurfaces;
|
||||
} mnode_t;
|
||||
|
||||
|
||||
|
||||
typedef struct mleaf_s
|
||||
{
|
||||
// common with node
|
||||
int contents; // wil be something other than CONTENTS_NODE
|
||||
int visframe; // node needs to be traversed if current
|
||||
|
||||
short minmaxs[6]; // for bounding box culling
|
||||
|
||||
struct mnode_s *parent;
|
||||
|
||||
// leaf specific
|
||||
int cluster;
|
||||
int area;
|
||||
|
||||
msurface_t **firstmarksurface;
|
||||
int nummarksurfaces;
|
||||
int key; // BSP sequence number for leaf's contents
|
||||
} mleaf_t;
|
||||
|
||||
|
||||
//===================================================================
|
||||
|
||||
//
|
||||
// Whole model
|
||||
//
|
||||
|
||||
typedef enum {mod_bad, mod_brush, mod_sprite, mod_alias } modtype_t;
|
||||
|
||||
typedef struct model_s
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
|
||||
int registration_sequence;
|
||||
|
||||
modtype_t type;
|
||||
int numframes;
|
||||
|
||||
int flags;
|
||||
|
||||
//
|
||||
// volume occupied by the model graphics
|
||||
//
|
||||
vec3_t mins, maxs;
|
||||
|
||||
//
|
||||
// solid volume for clipping (sent from server)
|
||||
//
|
||||
qboolean clipbox;
|
||||
vec3_t clipmins, clipmaxs;
|
||||
|
||||
//
|
||||
// brush model
|
||||
//
|
||||
int firstmodelsurface, nummodelsurfaces;
|
||||
|
||||
int numsubmodels;
|
||||
dmodel_t *submodels;
|
||||
|
||||
int numplanes;
|
||||
mplane_t *planes;
|
||||
|
||||
int numleafs; // number of visible leafs, not counting 0
|
||||
mleaf_t *leafs;
|
||||
|
||||
int numvertexes;
|
||||
mvertex_t *vertexes;
|
||||
|
||||
int numedges;
|
||||
medge_t *edges;
|
||||
|
||||
int numnodes;
|
||||
int firstnode;
|
||||
mnode_t *nodes;
|
||||
|
||||
int numtexinfo;
|
||||
mtexinfo_t *texinfo;
|
||||
|
||||
int numsurfaces;
|
||||
msurface_t *surfaces;
|
||||
|
||||
int numsurfedges;
|
||||
int *surfedges;
|
||||
|
||||
int nummarksurfaces;
|
||||
msurface_t **marksurfaces;
|
||||
|
||||
dvis_t *vis;
|
||||
|
||||
byte *lightdata;
|
||||
|
||||
// for alias models and sprites
|
||||
image_t *skins[MAX_MD2SKINS];
|
||||
void *extradata;
|
||||
int extradatasize;
|
||||
} model_t;
|
||||
|
||||
//============================================================================
|
||||
|
||||
void Mod_Init (void);
|
||||
void Mod_ClearAll (void);
|
||||
model_t *Mod_ForName (char *name, qboolean crash);
|
||||
void *Mod_Extradata (model_t *mod); // handles caching
|
||||
void Mod_TouchModel (char *name);
|
||||
|
||||
mleaf_t *Mod_PointInLeaf (float *p, model_t *model);
|
||||
byte *Mod_ClusterPVS (int cluster, model_t *model);
|
||||
|
||||
void Mod_Modellist_f (void);
|
||||
void Mod_FreeAll (void);
|
||||
void Mod_Free (model_t *mod);
|
||||
|
||||
extern int registration_sequence;
|
||||
|
||||
#endif // __MODEL__
|
638
ref_soft/r_part.c
Normal file
638
ref_soft/r_part.c
Normal file
@ -0,0 +1,638 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 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 "r_local.h"
|
||||
|
||||
vec3_t r_pright, r_pup, r_ppn;
|
||||
|
||||
#define PARTICLE_33 0
|
||||
#define PARTICLE_66 1
|
||||
#define PARTICLE_OPAQUE 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
particle_t *particle;
|
||||
int level;
|
||||
int color;
|
||||
} partparms_t;
|
||||
|
||||
static partparms_t partparms;
|
||||
|
||||
#if id386 && !defined __linux__
|
||||
|
||||
static unsigned s_prefetch_address;
|
||||
|
||||
/*
|
||||
** BlendParticleXX
|
||||
**
|
||||
** Inputs:
|
||||
** EAX = color
|
||||
** EDI = pdest
|
||||
**
|
||||
** Scratch:
|
||||
** EBX = scratch (dstcolor)
|
||||
** EBP = scratch
|
||||
**
|
||||
** Outputs:
|
||||
** none
|
||||
*/
|
||||
__declspec(naked) void BlendParticle33( void )
|
||||
{
|
||||
// return vid.alphamap[color + dstcolor*256];
|
||||
__asm mov ebp, vid.alphamap
|
||||
__asm xor ebx, ebx
|
||||
|
||||
__asm mov bl, byte ptr [edi]
|
||||
__asm shl ebx, 8
|
||||
|
||||
__asm add ebp, ebx
|
||||
__asm add ebp, eax
|
||||
|
||||
__asm mov al, byte ptr [ebp]
|
||||
|
||||
__asm mov byte ptr [edi], al
|
||||
|
||||
__asm ret
|
||||
}
|
||||
|
||||
__declspec(naked) void BlendParticle66( void )
|
||||
{
|
||||
// return vid.alphamap[pcolor*256 + dstcolor];
|
||||
__asm mov ebp, vid.alphamap
|
||||
__asm xor ebx, ebx
|
||||
|
||||
__asm shl eax, 8
|
||||
__asm mov bl, byte ptr [edi]
|
||||
|
||||
__asm add ebp, ebx
|
||||
__asm add ebp, eax
|
||||
|
||||
__asm mov al, byte ptr [ebp]
|
||||
|
||||
__asm mov byte ptr [edi], al
|
||||
|
||||
__asm ret
|
||||
}
|
||||
|
||||
__declspec(naked) void BlendParticle100( void )
|
||||
{
|
||||
__asm mov byte ptr [edi], al
|
||||
__asm ret
|
||||
}
|
||||
|
||||
/*
|
||||
** R_DrawParticle (asm version)
|
||||
**
|
||||
** Since we use __declspec( naked ) we don't have a stack frame
|
||||
** that we can use. Since I want to reserve EBP anyway, I tossed
|
||||
** all the important variables into statics. This routine isn't
|
||||
** meant to be re-entrant, so this shouldn't cause any problems
|
||||
** other than a slightly higher global memory footprint.
|
||||
**
|
||||
*/
|
||||
__declspec(naked) void R_DrawParticle( void )
|
||||
{
|
||||
static vec3_t local, transformed;
|
||||
static float zi;
|
||||
static int u, v, tmp;
|
||||
static short izi;
|
||||
static int ebpsave;
|
||||
|
||||
static byte (*blendfunc)(void);
|
||||
|
||||
/*
|
||||
** must be memvars since x86 can't load constants
|
||||
** directly. I guess I could use fld1, but that
|
||||
** actually costs one more clock than fld [one]!
|
||||
*/
|
||||
static float particle_z_clip = PARTICLE_Z_CLIP;
|
||||
static float one = 1.0F;
|
||||
static float point_five = 0.5F;
|
||||
static float eight_thousand_hex = 0x8000;
|
||||
|
||||
/*
|
||||
** save trashed variables
|
||||
*/
|
||||
__asm mov ebpsave, ebp
|
||||
__asm push esi
|
||||
__asm push edi
|
||||
|
||||
/*
|
||||
** transform the particle
|
||||
*/
|
||||
// VectorSubtract (pparticle->origin, r_origin, local);
|
||||
__asm mov esi, partparms.particle
|
||||
__asm fld dword ptr [esi+0] ; p_o.x
|
||||
__asm fsub dword ptr [r_origin+0] ; p_o.x-r_o.x
|
||||
__asm fld dword ptr [esi+4] ; p_o.y | p_o.x-r_o.x
|
||||
__asm fsub dword ptr [r_origin+4] ; p_o.y-r_o.y | p_o.x-r_o.x
|
||||
__asm fld dword ptr [esi+8] ; p_o.z | p_o.y-r_o.y | p_o.x-r_o.x
|
||||
__asm fsub dword ptr [r_origin+8] ; p_o.z-r_o.z | p_o.y-r_o.y | p_o.x-r_o.x
|
||||
__asm fxch st(2) ; p_o.x-r_o.x | p_o.y-r_o.y | p_o.z-r_o.z
|
||||
__asm fstp dword ptr [local+0] ; p_o.y-r_o.y | p_o.z-r_o.z
|
||||
__asm fstp dword ptr [local+4] ; p_o.z-r_o.z
|
||||
__asm fstp dword ptr [local+8] ; (empty)
|
||||
|
||||
// transformed[0] = DotProduct(local, r_pright);
|
||||
// transformed[1] = DotProduct(local, r_pup);
|
||||
// transformed[2] = DotProduct(local, r_ppn);
|
||||
__asm fld dword ptr [local+0] ; l.x
|
||||
__asm fmul dword ptr [r_pright+0] ; l.x*pr.x
|
||||
__asm fld dword ptr [local+4] ; l.y | l.x*pr.x
|
||||
__asm fmul dword ptr [r_pright+4] ; l.y*pr.y | l.x*pr.x
|
||||
__asm fld dword ptr [local+8] ; l.z | l.y*pr.y | l.x*pr.x
|
||||
__asm fmul dword ptr [r_pright+8] ; l.z*pr.z | l.y*pr.y | l.x*pr.x
|
||||
__asm fxch st(2) ; l.x*pr.x | l.y*pr.y | l.z*pr.z
|
||||
__asm faddp st(1), st ; l.x*pr.x + l.y*pr.y | l.z*pr.z
|
||||
__asm faddp st(1), st ; l.x*pr.x + l.y*pr.y + l.z*pr.z
|
||||
__asm fstp dword ptr [transformed+0] ; (empty)
|
||||
|
||||
__asm fld dword ptr [local+0] ; l.x
|
||||
__asm fmul dword ptr [r_pup+0] ; l.x*pr.x
|
||||
__asm fld dword ptr [local+4] ; l.y | l.x*pr.x
|
||||
__asm fmul dword ptr [r_pup+4] ; l.y*pr.y | l.x*pr.x
|
||||
__asm fld dword ptr [local+8] ; l.z | l.y*pr.y | l.x*pr.x
|
||||
__asm fmul dword ptr [r_pup+8] ; l.z*pr.z | l.y*pr.y | l.x*pr.x
|
||||
__asm fxch st(2) ; l.x*pr.x | l.y*pr.y | l.z*pr.z
|
||||
__asm faddp st(1), st ; l.x*pr.x + l.y*pr.y | l.z*pr.z
|
||||
__asm faddp st(1), st ; l.x*pr.x + l.y*pr.y + l.z*pr.z
|
||||
__asm fstp dword ptr [transformed+4] ; (empty)
|
||||
|
||||
__asm fld dword ptr [local+0] ; l.x
|
||||
__asm fmul dword ptr [r_ppn+0] ; l.x*pr.x
|
||||
__asm fld dword ptr [local+4] ; l.y | l.x*pr.x
|
||||
__asm fmul dword ptr [r_ppn+4] ; l.y*pr.y | l.x*pr.x
|
||||
__asm fld dword ptr [local+8] ; l.z | l.y*pr.y | l.x*pr.x
|
||||
__asm fmul dword ptr [r_ppn+8] ; l.z*pr.z | l.y*pr.y | l.x*pr.x
|
||||
__asm fxch st(2) ; l.x*pr.x | l.y*pr.y | l.z*pr.z
|
||||
__asm faddp st(1), st ; l.x*pr.x + l.y*pr.y | l.z*pr.z
|
||||
__asm faddp st(1), st ; l.x*pr.x + l.y*pr.y + l.z*pr.z
|
||||
__asm fstp dword ptr [transformed+8] ; (empty)
|
||||
|
||||
/*
|
||||
** make sure that the transformed particle is not in front of
|
||||
** the particle Z clip plane. We can do the comparison in
|
||||
** integer space since we know the sign of one of the inputs
|
||||
** and can figure out the sign of the other easily enough.
|
||||
*/
|
||||
// if (transformed[2] < PARTICLE_Z_CLIP)
|
||||
// return;
|
||||
|
||||
__asm mov eax, dword ptr [transformed+8]
|
||||
__asm and eax, eax
|
||||
__asm js end
|
||||
__asm cmp eax, particle_z_clip
|
||||
__asm jl end
|
||||
|
||||
/*
|
||||
** project the point by initiating the 1/z calc
|
||||
*/
|
||||
// zi = 1.0 / transformed[2];
|
||||
__asm fld one
|
||||
__asm fdiv dword ptr [transformed+8]
|
||||
|
||||
/*
|
||||
** bind the blend function pointer to the appropriate blender
|
||||
** while we're dividing
|
||||
*/
|
||||
//if ( level == PARTICLE_33 )
|
||||
// blendparticle = BlendParticle33;
|
||||
//else if ( level == PARTICLE_66 )
|
||||
// blendparticle = BlendParticle66;
|
||||
//else
|
||||
// blendparticle = BlendParticle100;
|
||||
|
||||
__asm cmp partparms.level, PARTICLE_66
|
||||
__asm je blendfunc_66
|
||||
__asm jl blendfunc_33
|
||||
__asm lea ebx, BlendParticle100
|
||||
__asm jmp done_selecting_blend_func
|
||||
blendfunc_33:
|
||||
__asm lea ebx, BlendParticle33
|
||||
__asm jmp done_selecting_blend_func
|
||||
blendfunc_66:
|
||||
__asm lea ebx, BlendParticle66
|
||||
done_selecting_blend_func:
|
||||
__asm mov blendfunc, ebx
|
||||
|
||||
// prefetch the next particle
|
||||
__asm mov ebp, s_prefetch_address
|
||||
__asm mov ebp, [ebp]
|
||||
|
||||
// finish the above divide
|
||||
__asm fstp zi
|
||||
|
||||
// u = (int)(xcenter + zi * transformed[0] + 0.5);
|
||||
// v = (int)(ycenter - zi * transformed[1] + 0.5);
|
||||
__asm fld zi ; zi
|
||||
__asm fmul dword ptr [transformed+0] ; zi * transformed[0]
|
||||
__asm fld zi ; zi | zi * transformed[0]
|
||||
__asm fmul dword ptr [transformed+4] ; zi * transformed[1] | zi * transformed[0]
|
||||
__asm fxch st(1) ; zi * transformed[0] | zi * transformed[1]
|
||||
__asm fadd xcenter ; xcenter + zi * transformed[0] | zi * transformed[1]
|
||||
__asm fxch st(1) ; zi * transformed[1] | xcenter + zi * transformed[0]
|
||||
__asm fld ycenter ; ycenter | zi * transformed[1] | xcenter + zi * transformed[0]
|
||||
__asm fsubrp st(1), st(0) ; ycenter - zi * transformed[1] | xcenter + zi * transformed[0]
|
||||
__asm fxch st(1) ; xcenter + zi * transformed[0] | ycenter + zi * transformed[1]
|
||||
__asm fadd point_five ; xcenter + zi * transformed[0] + 0.5 | ycenter - zi * transformed[1]
|
||||
__asm fxch st(1) ; ycenter - zi * transformed[1] | xcenter + zi * transformed[0] + 0.5
|
||||
__asm fadd point_five ; ycenter - zi * transformed[1] + 0.5 | xcenter + zi * transformed[0] + 0.5
|
||||
__asm fxch st(1) ; u | v
|
||||
__asm fistp dword ptr [u] ; v
|
||||
__asm fistp dword ptr [v] ; (empty)
|
||||
|
||||
/*
|
||||
** clip out the particle
|
||||
*/
|
||||
|
||||
// if ((v > d_vrectbottom_particle) ||
|
||||
// (u > d_vrectright_particle) ||
|
||||
// (v < d_vrecty) ||
|
||||
// (u < d_vrectx))
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
__asm mov ebx, u
|
||||
__asm mov ecx, v
|
||||
__asm cmp ecx, d_vrectbottom_particle
|
||||
__asm jg end
|
||||
__asm cmp ecx, d_vrecty
|
||||
__asm jl end
|
||||
__asm cmp ebx, d_vrectright_particle
|
||||
__asm jg end
|
||||
__asm cmp ebx, d_vrectx
|
||||
__asm jl end
|
||||
|
||||
/*
|
||||
** compute addresses of zbuffer, framebuffer, and
|
||||
** compute the Z-buffer reference value.
|
||||
**
|
||||
** EBX = U
|
||||
** ECX = V
|
||||
**
|
||||
** Outputs:
|
||||
** ESI = Z-buffer address
|
||||
** EDI = framebuffer address
|
||||
*/
|
||||
// ESI = d_pzbuffer + (d_zwidth * v) + u;
|
||||
__asm mov esi, d_pzbuffer ; esi = d_pzbuffer
|
||||
__asm mov eax, d_zwidth ; eax = d_zwidth
|
||||
__asm mul ecx ; eax = d_zwidth*v
|
||||
__asm add eax, ebx ; eax = d_zwidth*v+u
|
||||
__asm shl eax, 1 ; eax = 2*(d_zwidth*v+u)
|
||||
__asm add esi, eax ; esi = ( short * ) ( d_pzbuffer + ( d_zwidth * v ) + u )
|
||||
|
||||
// initiate
|
||||
// izi = (int)(zi * 0x8000);
|
||||
__asm fld zi
|
||||
__asm fmul eight_thousand_hex
|
||||
|
||||
// EDI = pdest = d_viewbuffer + d_scantable[v] + u;
|
||||
__asm lea edi, [d_scantable+ecx*4]
|
||||
__asm mov edi, [edi]
|
||||
__asm add edi, d_viewbuffer
|
||||
__asm add edi, ebx
|
||||
|
||||
// complete
|
||||
// izi = (int)(zi * 0x8000);
|
||||
__asm fistp tmp
|
||||
__asm mov eax, tmp
|
||||
__asm mov izi, ax
|
||||
|
||||
/*
|
||||
** determine the screen area covered by the particle,
|
||||
** which also means clamping to a min and max
|
||||
*/
|
||||
// pix = izi >> d_pix_shift;
|
||||
__asm xor edx, edx
|
||||
__asm mov dx, izi
|
||||
__asm mov ecx, d_pix_shift
|
||||
__asm shr dx, cl
|
||||
|
||||
// if (pix < d_pix_min)
|
||||
// pix = d_pix_min;
|
||||
__asm cmp edx, d_pix_min
|
||||
__asm jge check_pix_max
|
||||
__asm mov edx, d_pix_min
|
||||
__asm jmp skip_pix_clamp
|
||||
|
||||
// else if (pix > d_pix_max)
|
||||
// pix = d_pix_max;
|
||||
check_pix_max:
|
||||
__asm cmp edx, d_pix_max
|
||||
__asm jle skip_pix_clamp
|
||||
__asm mov edx, d_pix_max
|
||||
|
||||
skip_pix_clamp:
|
||||
|
||||
/*
|
||||
** render the appropriate pixels
|
||||
**
|
||||
** ECX = count (used for inner loop)
|
||||
** EDX = count (used for outer loop)
|
||||
** ESI = zbuffer
|
||||
** EDI = framebuffer
|
||||
*/
|
||||
__asm mov ecx, edx
|
||||
|
||||
__asm cmp ecx, 1
|
||||
__asm ja over
|
||||
|
||||
over:
|
||||
|
||||
/*
|
||||
** at this point:
|
||||
**
|
||||
** ECX = count
|
||||
*/
|
||||
__asm push ecx
|
||||
__asm push edi
|
||||
__asm push esi
|
||||
|
||||
top_of_pix_vert_loop:
|
||||
|
||||
top_of_pix_horiz_loop:
|
||||
|
||||
// for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
// {
|
||||
// for (i=0 ; i<pix ; i++)
|
||||
// {
|
||||
// if (pz[i] <= izi)
|
||||
// {
|
||||
// pdest[i] = blendparticle( color, pdest[i] );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
__asm xor eax, eax
|
||||
|
||||
__asm mov ax, word ptr [esi]
|
||||
|
||||
__asm cmp ax, izi
|
||||
__asm jg end_of_horiz_loop
|
||||
|
||||
#if ENABLE_ZWRITES_FOR_PARTICLES
|
||||
__asm mov bp, izi
|
||||
__asm mov word ptr [esi], bp
|
||||
#endif
|
||||
|
||||
__asm mov eax, partparms.color
|
||||
|
||||
__asm call [blendfunc]
|
||||
|
||||
__asm add edi, 1
|
||||
__asm add esi, 2
|
||||
|
||||
end_of_horiz_loop:
|
||||
|
||||
__asm dec ecx
|
||||
__asm jnz top_of_pix_horiz_loop
|
||||
|
||||
__asm pop esi
|
||||
__asm pop edi
|
||||
|
||||
__asm mov ebp, d_zwidth
|
||||
__asm shl ebp, 1
|
||||
|
||||
__asm add esi, ebp
|
||||
__asm add edi, [r_screenwidth]
|
||||
|
||||
__asm pop ecx
|
||||
__asm push ecx
|
||||
|
||||
__asm push edi
|
||||
__asm push esi
|
||||
|
||||
__asm dec edx
|
||||
__asm jnz top_of_pix_vert_loop
|
||||
|
||||
__asm pop ecx
|
||||
__asm pop ecx
|
||||
__asm pop ecx
|
||||
|
||||
end:
|
||||
__asm pop edi
|
||||
__asm pop esi
|
||||
__asm mov ebp, ebpsave
|
||||
__asm ret
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static byte BlendParticle33( int pcolor, int dstcolor )
|
||||
{
|
||||
return vid.alphamap[pcolor + dstcolor*256];
|
||||
}
|
||||
|
||||
static byte BlendParticle66( int pcolor, int dstcolor )
|
||||
{
|
||||
return vid.alphamap[pcolor*256+dstcolor];
|
||||
}
|
||||
|
||||
static byte BlendParticle100( int pcolor, int dstcolor )
|
||||
{
|
||||
dstcolor = dstcolor;
|
||||
return pcolor;
|
||||
}
|
||||
|
||||
/*
|
||||
** R_DrawParticle
|
||||
**
|
||||
** Yes, this is amazingly slow, but it's the C reference
|
||||
** implementation and should be both robust and vaguely
|
||||
** understandable. The only time this path should be
|
||||
** executed is if we're debugging on x86 or if we're
|
||||
** recompiling and deploying on a non-x86 platform.
|
||||
**
|
||||
** To minimize error and improve readability I went the
|
||||
** function pointer route. This exacts some overhead, but
|
||||
** it pays off in clean and easy to understand code.
|
||||
*/
|
||||
void R_DrawParticle( void )
|
||||
{
|
||||
particle_t *pparticle = partparms.particle;
|
||||
int level = partparms.level;
|
||||
vec3_t local, transformed;
|
||||
float zi;
|
||||
byte *pdest;
|
||||
short *pz;
|
||||
int color = pparticle->color;
|
||||
int i, izi, pix, count, u, v;
|
||||
byte (*blendparticle)( int, int );
|
||||
|
||||
/*
|
||||
** transform the particle
|
||||
*/
|
||||
VectorSubtract (pparticle->origin, 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;
|
||||
|
||||
/*
|
||||
** bind the blend function pointer to the appropriate blender
|
||||
*/
|
||||
if ( level == PARTICLE_33 )
|
||||
blendparticle = BlendParticle33;
|
||||
else if ( level == PARTICLE_66 )
|
||||
blendparticle = BlendParticle66;
|
||||
else
|
||||
blendparticle = BlendParticle100;
|
||||
|
||||
/*
|
||||
** 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;
|
||||
}
|
||||
|
||||
/*
|
||||
** compute addresses of zbuffer, framebuffer, and
|
||||
** compute the Z-buffer reference value.
|
||||
*/
|
||||
pz = d_pzbuffer + (d_zwidth * v) + u;
|
||||
pdest = d_viewbuffer + d_scantable[v] + u;
|
||||
izi = (int)(zi * 0x8000);
|
||||
|
||||
/*
|
||||
** determine the screen area covered by the particle,
|
||||
** which also means clamping to a min and max
|
||||
*/
|
||||
pix = izi >> d_pix_shift;
|
||||
if (pix < d_pix_min)
|
||||
pix = d_pix_min;
|
||||
else if (pix > d_pix_max)
|
||||
pix = d_pix_max;
|
||||
|
||||
/*
|
||||
** render the appropriate pixels
|
||||
*/
|
||||
count = pix;
|
||||
|
||||
switch (level) {
|
||||
case PARTICLE_33 :
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth)
|
||||
{
|
||||
//FIXME--do it in blocks of 8?
|
||||
for (i=0 ; i<pix ; i++)
|
||||
{
|
||||
if (pz[i] <= izi)
|
||||
{
|
||||
pz[i] = izi;
|
||||
pdest[i] = vid.alphamap[color + ((int)pdest[i]<<8)];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PARTICLE_66 :
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth)
|
||||
{
|
||||
for (i=0 ; i<pix ; i++)
|
||||
{
|
||||
if (pz[i] <= izi)
|
||||
{
|
||||
pz[i] = izi;
|
||||
pdest[i] = vid.alphamap[(color<<8) + (int)pdest[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: //100
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth)
|
||||
{
|
||||
for (i=0 ; i<pix ; i++)
|
||||
{
|
||||
if (pz[i] <= izi)
|
||||
{
|
||||
pz[i] = izi;
|
||||
pdest[i] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !id386
|
||||
|
||||
/*
|
||||
** R_DrawParticles
|
||||
**
|
||||
** Responsible for drawing all of the particles in the particle list
|
||||
** throughout the world. Doesn't care if we're using the C path or
|
||||
** if we're using the asm path, it simply assigns a function pointer
|
||||
** and goes.
|
||||
*/
|
||||
void R_DrawParticles (void)
|
||||
{
|
||||
particle_t *p;
|
||||
int i;
|
||||
extern unsigned long fpu_sp24_cw, fpu_chop_cw;
|
||||
|
||||
VectorScale( vright, xscaleshrink, r_pright );
|
||||
VectorScale( vup, yscaleshrink, r_pup );
|
||||
VectorCopy( vpn, r_ppn );
|
||||
|
||||
#if id386 && !defined __linux__
|
||||
__asm fldcw word ptr [fpu_sp24_cw]
|
||||
#endif
|
||||
|
||||
for (p=r_newrefdef.particles, i=0 ; i<r_newrefdef.num_particles ; i++,p++)
|
||||
{
|
||||
|
||||
if ( p->alpha > 0.66 )
|
||||
partparms.level = PARTICLE_OPAQUE;
|
||||
else if ( p->alpha > 0.33 )
|
||||
partparms.level = PARTICLE_66;
|
||||
else
|
||||
partparms.level = PARTICLE_33;
|
||||
|
||||
partparms.particle = p;
|
||||
partparms.color = p->color;
|
||||
|
||||
#if id386 && !defined __linux__
|
||||
if ( i < r_newrefdef.num_particles-1 )
|
||||
s_prefetch_address = ( unsigned int ) ( p + 1 );
|
||||
else
|
||||
s_prefetch_address = ( unsigned int ) r_newrefdef.particles;
|
||||
#endif
|
||||
|
||||
R_DrawParticle();
|
||||
}
|
||||
|
||||
#if id386 && !defined __linux__
|
||||
__asm fldcw word ptr [fpu_chop_cw]
|
||||
#endif
|
||||
|
||||
}
|
||||
|
1244
ref_soft/r_poly.c
Normal file
1244
ref_soft/r_poly.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user