?? r_main.c
字號:
/*
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_main.c
#include "r_local.h"
viddef_t vid;
refimport_t ri;
unsigned d_8to24table[256];
entity_t r_worldentity;
char skyname[MAX_QPATH];
float skyrotate;
vec3_t skyaxis;
image_t *sky_images[6];
refdef_t r_newrefdef;
model_t *currentmodel;
model_t *r_worldmodel;
byte r_warpbuffer[WARP_WIDTH * WARP_HEIGHT];
swstate_t sw_state;
void *colormap;
vec3_t viewlightvec;
alight_t r_viewlighting = {128, 192, viewlightvec};
float r_time1;
int r_numallocatededges;
float r_aliasuvscale = 1.0;
int r_outofsurfaces;
int r_outofedges;
qboolean r_dowarp;
mvertex_t *r_pcurrentvertbase;
int c_surf;
int r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs;
qboolean r_surfsonstack;
int r_clipflags;
//
// view origin
//
vec3_t vup, base_vup;
vec3_t vpn, base_vpn;
vec3_t vright, base_vright;
vec3_t r_origin;
//
// screen size info
//
oldrefdef_t r_refdef;
float xcenter, ycenter;
float xscale, yscale;
float xscaleinv, yscaleinv;
float xscaleshrink, yscaleshrink;
float aliasxscale, aliasyscale, aliasxcenter, aliasycenter;
int r_screenwidth;
float verticalFieldOfView;
float xOrigin, yOrigin;
mplane_t screenedge[4];
//
// refresh flags
//
int r_framecount = 1; // so frame counts initialized to 0 don't match
int r_visframecount;
int d_spanpixcount;
int r_polycount;
int r_drawnpolycount;
int r_wholepolycount;
int *pfrustum_indexes[4];
int r_frustum_indexes[4*6];
mleaf_t *r_viewleaf;
int r_viewcluster, r_oldviewcluster;
image_t *r_notexture_mip;
float da_time1, da_time2, dp_time1, dp_time2, db_time1, db_time2, rw_time1, rw_time2;
float se_time1, se_time2, de_time1, de_time2;
void R_MarkLeaves (void);
cvar_t *r_lefthand;
cvar_t *sw_aliasstats;
cvar_t *sw_allow_modex;
cvar_t *sw_clearcolor;
cvar_t *sw_drawflat;
cvar_t *sw_draworder;
cvar_t *sw_maxedges;
cvar_t *sw_maxsurfs;
cvar_t *sw_mode;
cvar_t *sw_reportedgeout;
cvar_t *sw_reportsurfout;
cvar_t *sw_stipplealpha;
cvar_t *sw_surfcacheoverride;
cvar_t *sw_waterwarp;
cvar_t *r_drawworld;
cvar_t *r_drawentities;
cvar_t *r_dspeeds;
cvar_t *r_fullbright;
cvar_t *r_lerpmodels;
cvar_t *r_novis;
cvar_t *r_speeds;
cvar_t *r_lightlevel; //FIXME HACK
cvar_t *vid_fullscreen;
cvar_t *vid_gamma;
//PGM
cvar_t *sw_lockpvs;
//PGM
#define STRINGER(x) "x"
#if !id386
// r_vars.c
// all global and static refresh variables are collected in a contiguous block
// to avoid cache conflicts.
//-------------------------------------------------------
// global refresh variables
//-------------------------------------------------------
// FIXME: make into one big structure, like cl or sv
// FIXME: do separately for refresh engine and driver
// d_vars.c
// all global and static refresh variables are collected in a contiguous block
// to avoid cache conflicts.
//-------------------------------------------------------
// global refresh variables
//-------------------------------------------------------
// FIXME: make into one big structure, like cl or sv
// FIXME: do separately for refresh engine and driver
float d_sdivzstepu, d_tdivzstepu, d_zistepu;
float d_sdivzstepv, d_tdivzstepv, d_zistepv;
float d_sdivzorigin, d_tdivzorigin, d_ziorigin;
fixed16_t sadjust, tadjust, bbextents, bbextentt;
pixel_t *cacheblock;
int cachewidth;
pixel_t *d_viewbuffer;
short *d_pzbuffer;
unsigned int d_zrowbytes;
unsigned int d_zwidth;
#endif // !id386
byte r_notexture_buffer[1024];
/*
==================
R_InitTextures
==================
*/
void R_InitTextures (void)
{
int x,y, m;
byte *dest;
// create a simple checkerboard texture for the default
r_notexture_mip = (image_t *)&r_notexture_buffer;
r_notexture_mip->width = r_notexture_mip->height = 16;
r_notexture_mip->pixels[0] = &r_notexture_buffer[sizeof(image_t)];
r_notexture_mip->pixels[1] = r_notexture_mip->pixels[0] + 16*16;
r_notexture_mip->pixels[2] = r_notexture_mip->pixels[1] + 8*8;
r_notexture_mip->pixels[3] = r_notexture_mip->pixels[2] + 4*4;
for (m=0 ; m<4 ; m++)
{
dest = r_notexture_mip->pixels[m];
for (y=0 ; y< (16>>m) ; y++)
for (x=0 ; x< (16>>m) ; x++)
{
if ( (y< (8>>m) ) ^ (x< (8>>m) ) )
*dest++ = 0;
else
*dest++ = 0xff;
}
}
}
/*
================
R_InitTurb
================
*/
void R_InitTurb (void)
{
int i;
for (i=0 ; i<1280 ; i++)
{
sintable[i] = AMP + sin(i*3.14159*2/CYCLE)*AMP;
intsintable[i] = AMP2 + sin(i*3.14159*2/CYCLE)*AMP2; // AMP2, not 20
blanktable[i] = 0; //PGM
}
}
void R_ImageList_f( void );
void R_Register (void)
{
sw_aliasstats = ri.Cvar_Get ("sw_polymodelstats", "0", 0);
sw_allow_modex = ri.Cvar_Get( "sw_allow_modex", "1", CVAR_ARCHIVE );
sw_clearcolor = ri.Cvar_Get ("sw_clearcolor", "2", 0);
sw_drawflat = ri.Cvar_Get ("sw_drawflat", "0", 0);
sw_draworder = ri.Cvar_Get ("sw_draworder", "0", 0);
sw_maxedges = ri.Cvar_Get ("sw_maxedges", STRINGER(MAXSTACKSURFACES), 0);
sw_maxsurfs = ri.Cvar_Get ("sw_maxsurfs", "0", 0);
sw_mipcap = ri.Cvar_Get ("sw_mipcap", "0", 0);
sw_mipscale = ri.Cvar_Get ("sw_mipscale", "1", 0);
sw_reportedgeout = ri.Cvar_Get ("sw_reportedgeout", "0", 0);
sw_reportsurfout = ri.Cvar_Get ("sw_reportsurfout", "0", 0);
sw_stipplealpha = ri.Cvar_Get( "sw_stipplealpha", "0", CVAR_ARCHIVE );
sw_surfcacheoverride = ri.Cvar_Get ("sw_surfcacheoverride", "0", 0);
sw_waterwarp = ri.Cvar_Get ("sw_waterwarp", "1", 0);
sw_mode = ri.Cvar_Get( "sw_mode", "0", CVAR_ARCHIVE );
r_lefthand = ri.Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE );
r_speeds = ri.Cvar_Get ("r_speeds", "0", 0);
r_fullbright = ri.Cvar_Get ("r_fullbright", "0", 0);
r_drawentities = ri.Cvar_Get ("r_drawentities", "1", 0);
r_drawworld = ri.Cvar_Get ("r_drawworld", "1", 0);
r_dspeeds = ri.Cvar_Get ("r_dspeeds", "0", 0);
r_lightlevel = ri.Cvar_Get ("r_lightlevel", "0", 0);
r_lerpmodels = ri.Cvar_Get( "r_lerpmodels", "1", 0 );
r_novis = ri.Cvar_Get( "r_novis", "0", 0 );
vid_fullscreen = ri.Cvar_Get( "vid_fullscreen", "0", CVAR_ARCHIVE );
vid_gamma = ri.Cvar_Get( "vid_gamma", "1.0", CVAR_ARCHIVE );
ri.Cmd_AddCommand ("modellist", Mod_Modellist_f);
ri.Cmd_AddCommand( "screenshot", R_ScreenShot_f );
ri.Cmd_AddCommand( "imagelist", R_ImageList_f );
sw_mode->modified = true; // force us to do mode specific stuff later
vid_gamma->modified = true; // force us to rebuild the gamma table later
//PGM
sw_lockpvs = ri.Cvar_Get ("sw_lockpvs", "0", 0);
//PGM
}
void R_UnRegister (void)
{
ri.Cmd_RemoveCommand( "screenshot" );
ri.Cmd_RemoveCommand ("modellist");
ri.Cmd_RemoveCommand( "imagelist" );
}
/*
===============
R_Init
===============
*/
qboolean R_Init( void *hInstance, void *wndProc )
{
R_InitImages ();
Mod_Init ();
Draw_InitLocal ();
R_InitTextures ();
R_InitTurb ();
view_clipplanes[0].leftedge = true;
view_clipplanes[1].rightedge = true;
view_clipplanes[1].leftedge = view_clipplanes[2].leftedge =
view_clipplanes[3].leftedge = false;
view_clipplanes[0].rightedge = view_clipplanes[2].rightedge =
view_clipplanes[3].rightedge = false;
r_refdef.xOrigin = XCENTERING;
r_refdef.yOrigin = YCENTERING;
// TODO: collect 386-specific code in one place
#if id386
Sys_MakeCodeWriteable ((long)R_EdgeCodeStart,
(long)R_EdgeCodeEnd - (long)R_EdgeCodeStart);
Sys_SetFPCW (); // get bit masks for FPCW (FIXME: is this id386?)
#endif // id386
r_aliasuvscale = 1.0;
R_Register ();
Draw_GetPalette ();
SWimp_Init( hInstance, wndProc );
// create the window
R_BeginFrame( 0 );
ri.Con_Printf (PRINT_ALL, "ref_soft version: "REF_VERSION"\n");
return true;
}
/*
===============
R_Shutdown
===============
*/
void R_Shutdown (void)
{
// free z buffer
if (d_pzbuffer)
{
free (d_pzbuffer);
d_pzbuffer = NULL;
}
// free surface cache
if (sc_base)
{
D_FlushCaches ();
free (sc_base);
sc_base = NULL;
}
// free colormap
if (vid.colormap)
{
free (vid.colormap);
vid.colormap = NULL;
}
R_UnRegister ();
Mod_FreeAll ();
R_ShutdownImages ();
SWimp_Shutdown();
}
/*
===============
R_NewMap
===============
*/
void R_NewMap (void)
{
r_viewcluster = -1;
r_cnumsurfs = sw_maxsurfs->value;
if (r_cnumsurfs <= MINSURFACES)
r_cnumsurfs = MINSURFACES;
if (r_cnumsurfs > NUMSTACKSURFACES)
{
surfaces = malloc (r_cnumsurfs * sizeof(surf_t));
surface_p = surfaces;
surf_max = &surfaces[r_cnumsurfs];
r_surfsonstack = false;
// surface 0 doesn't really exist; it's just a dummy because index 0
// is used to indicate no edge attached to surface
surfaces--;
R_SurfacePatch ();
}
else
{
r_surfsonstack = true;
}
r_maxedgesseen = 0;
r_maxsurfsseen = 0;
r_numallocatededges = sw_maxedges->value;
if (r_numallocatededges < MINEDGES)
r_numallocatededges = MINEDGES;
if (r_numallocatededges <= NUMSTACKEDGES)
{
auxedges = NULL;
}
else
{
auxedges = malloc (r_numallocatededges * sizeof(edge_t));
}
}
/*
===============
R_MarkLeaves
Mark the leaves and nodes that are in the PVS for the current
cluster
===============
*/
void R_MarkLeaves (void)
{
byte *vis;
mnode_t *node;
int i;
mleaf_t *leaf;
int cluster;
if (r_oldviewcluster == r_viewcluster && !r_novis->value && r_viewcluster != -1)
return;
// development aid to let you run around and see exactly where
// the pvs ends
if (sw_lockpvs->value)
return;
r_visframecount++;
r_oldviewcluster = r_viewcluster;
if (r_novis->value || r_viewcluster == -1 || !r_worldmodel->vis)
{
// mark everything
for (i=0 ; i<r_worldmodel->numleafs ; i++)
r_worldmodel->leafs[i].visframe = r_visframecount;
for (i=0 ; i<r_worldmodel->numnodes ; i++)
r_worldmodel->nodes[i].visframe = r_visframecount;
return;
}
vis = Mod_ClusterPVS (r_viewcluster, r_worldmodel);
for (i=0,leaf=r_worldmodel->leafs ; i<r_worldmodel->numleafs ; i++, leaf++)
{
cluster = leaf->cluster;
if (cluster == -1)
continue;
if (vis[cluster>>3] & (1<<(cluster&7)))
{
node = (mnode_t *)leaf;
do
{
if (node->visframe == r_visframecount)
break;
node->visframe = r_visframecount;
node = node->parent;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -