📄 r_glide.c
字号:
SetWindowLong (lvid->WndParent, GWL_STYLE, WS_POPUP | WS_VISIBLE);
SetWindowPos(lvid->WndParent, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE |
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
//cleanup previous mode
if (grPreviousContext) {
// close the current graphics subsystem
DBG_Printf ("grSstWinClose()\n");
grSstWinClose (grPreviousContext);
}
// create Glide window
grPreviousContext = grSstWinOpen( (FxU32)lvid->WndParent,
iResolution,
GR_REFRESH_60Hz, //note: we could always use the higher refresh?
GR_COLORFORMAT_ABGR,
GR_ORIGIN_UPPER_LEFT,
2, 1 );
if ( !grPreviousContext ) {
DBG_Printf ("grSstWinOpen() FAILED\n");
return 0;
}
// for glide debug console
//tlSetScreen (pcurrentmode->width, pcurrentmode->height);
glide_initialized = true;
GR_ResetStates (lvid);
// force reload of patches because the memory is trashed while we change the screen
GR_InitMipmapCache();
lvid->buffer = NULL; //unless we use the software view
lvid->direct = NULL; //direct access to video memory, old DOS crap
currentmode_width = pcurrentmode->width;
currentmode_height = pcurrentmode->height;
// remember lvid here, to free the software buffer if we used it (software view)
viddef = lvid;
return 1;
}
// --------------------------------------------------------------------------
// Swap front and back buffers
// --------------------------------------------------------------------------
static int glide_console = 1;
EXPORT void HWRAPI( FinishUpdate ) ( int waitvbl )
{
if (!grPreviousContext) {
DBG_Printf ("HWRAPI FinishUpdate() : display not set\n");
return;
}
/*
static int frame=0;
static int lasttic=0;
int tic,fps;
// draw silly stuff here
if (glide_console & 1)
tlPrintNumber (frame++);
if (glide_console & 1)
{
tic = dl.I_GetTime();
fps = TICRATE - (tic - lasttic) + 1;
lasttic = tic;
tlPrintNumber (fps);
}
*/
//DBG_Printf ("HWRAPI FinishUpdate()\n");
// flip screen
grBufferSwap( waitvbl );
}
// --------------------------------------------------------------------------
//
// --------------------------------------------------------------------------
static unsigned long myPaletteData[256]; // 256 ARGB entries
//TODO: do the chroma key stuff out of here
EXPORT void HWRAPI( SetPalette ) (RGBA_t* pal, RGBA_t *gamma)
{
int i;
if (!grPreviousContext) {
DBG_Printf ("HWRAPI SetPalette() : display not set\n");
return;
}
// create the palette in the format used for downloading to 3Dfx card
for (i=0; i<256; i++)
myPaletteData[i] = (pal[i].s.alpha << 24) |
(pal[i].s.red<<16) |
(pal[i].s.green<<8) |
pal[i].s.blue;
// make sure the chromakey color is always the same value
myPaletteData[HWR_PATCHES_CHROMAKEY_COLORINDEX] = HWR_PATCHES_CHROMAKEY_COLORVALUE;
grTexDownloadTable (GR_TEXTABLE_PALETTE, (void*)myPaletteData);
guGammaCorrectionRGB(gamma->s.red/127.0f,gamma->s.green/127.0f,gamma->s.blue/127.0f);
}
// **************************************************************************
//
// **************************************************************************
// store min/max w depth buffer values here, used to clear buffer
static FxU32 gr_wrange[2];
// --------------------------------------------------------------------------
// Do a full buffer clear including color / alpha / and Z buffers
// --------------------------------------------------------------------------
static void BufferClear (void)
{
if (!grPreviousContext) {
DBG_Printf ("BufferClear() : display not set\n");
return;
}
grDepthMask (FXTRUE);
grColorMask (FXTRUE,FXFALSE);
grBufferClear(0x00000000, 0, gr_wrange[1]);
}
//
// set initial state of 3d card settings
//
static void GR_ResetStates (viddef_t *lvid)
{
DBG_Printf ("ResetStates()\n");
if (!grPreviousContext) {
DBG_Printf ("ResetStates() : display not set\n");
return;
}
//grSplash( 64, 64, SCREEN_WIDTH-64, SCREEN_HEIGHT-64, 0 ); //splash screen!
// get min/max w buffer range values
grGet (GR_WDEPTH_MIN_MAX, 8, gr_wrange);
grCoordinateSpace(GR_CLIP_COORDS);
grViewport((FxU32)0, (FxU32)0, (FxU32)lvid->width, (FxU32)lvid->height);
// don't work ! the only function that support this is drawpoly
// y=0 is in lower left corner, (not like in vga)
//grSstOrigin( GR_ORIGIN_LOWER_LEFT );
// initialize depth buffer type
grDepthRange( 0.0, 1.0 );
grDepthBufferMode(GR_DEPTHBUFFER_WBUFFER);
grDepthBufferFunction( GR_CMP_LEQUAL );
grDepthMask( FXTRUE );
grColorMask ( FXTRUE, FXFALSE);
// my vertex format
grVertexLayout(GR_PARAM_XY , FIELD_OFFSET(FOutVector,x) , GR_PARAM_ENABLE);
grVertexLayout(GR_PARAM_PARGB, FIELD_OFFSET(FOutVector,argb), GR_PARAM_ENABLE);
//grVertexLayout(GR_PARAM_Q, 12, GR_PARAM_ENABLE);
grVertexLayout(GR_PARAM_W , FIELD_OFFSET(FOutVector,oow) , GR_PARAM_ENABLE);
grVertexLayout(GR_PARAM_ST0 , FIELD_OFFSET(FOutVector,sow) , GR_PARAM_ENABLE); //s and t for tmu0
grTexCombine (GR_TMU0, GR_COMBINE_FUNCTION_LOCAL,
GR_COMBINE_FACTOR_NONE,
GR_COMBINE_FUNCTION_LOCAL,
GR_COMBINE_FACTOR_NONE,
FXFALSE, FXFALSE );
// no mipmaps based on depth
grTexMipMapMode (GR_TMU0, GR_MIPMAP_DISABLE, FXFALSE );
grConstantColorValue (0xffffffff);
grChromakeyValue(HWR_PATCHES_CHROMAKEY_COLORVALUE);
grAlphaTestReferenceValue( 0 );
// this set CurrentPolyFlags to the acctual configuration
CurrentPolyFlags = 0xffffffff;
SetBlend(0);
BufferClear();
MakeFogTable();
ReSetSpecialState();
}
// **************************************************************************
// 3DFX MEMORY CACHE MANAGEMENT
// **************************************************************************
#define TEXMEM_2MB_EDGE (1<<21)
static FxU32 gr_cachemin;
static FxU32 gr_cachemax;
static FxU32 gr_cachepos;
static GlideMipmap_t* gr_cachetail = NULL;
static GlideMipmap_t* gr_cachehead;
static GlideMipmap_t* lastmipmapset;
// --------------------------------------------------------------------------
// This must be done once only for all program execution
// --------------------------------------------------------------------------
GlideMipmap_t fakemipmap;
static void GR_ClearMipmapCache (void)
{
while (gr_cachetail)
{
gr_cachetail->downloaded = false;
gr_cachehead = gr_cachetail;
gr_cachetail = gr_cachetail->nextmipmap;
gr_cachehead->nextmipmap = NULL;
}
// make a dummy first just for easy cache handling
fakemipmap.cachepos = gr_cachemin;
fakemipmap.mipmapSize = grTexCalcMemRequired(GR_LOD_LOG2_1,GR_LOD_LOG2_1,GR_ASPECT_LOG2_1x1,GR_TEXFMT_P_8);
fakemipmap.downloaded = true;
fakemipmap.nextmipmap = NULL;
lastmipmapset = NULL;
gr_cachetail = &fakemipmap;
gr_cachehead = &fakemipmap;
gr_cachepos = gr_cachetail->cachepos+fakemipmap.mipmapSize;
DBG_Printf ("Cache cleared\n");
}
EXPORT void HWRAPI( ClearMipMapCache ) (void)
{
GR_ClearMipmapCache ();
}
static void GR_InitMipmapCache (void)
{
gr_cachemin = grTexMinAddress(GR_TMU0);
gr_cachemax = grTexMaxAddress(GR_TMU0);
//testing..
// reduise memory so there will use more the legacy heap
//gr_cachemax = gr_cachemin + (256<<10);
if( gr_cachemax-gr_cachemin < 64<<10 )
I_ErrorGr("R_Glide : Only %d memory available for texture !\n",gr_cachemax-gr_cachemin);
GR_ClearMipmapCache();
DBG_Printf ("HWR_InitMipmapCache() : %d kb, from %x to %x\n"
"tmu2 : from %x to %x\n", (gr_cachemax-gr_cachemin)>>10,gr_cachemin,gr_cachemax,grTexMinAddress(GR_TMU1),grTexMaxAddress(GR_TMU1));
}
static boolean possibleproblem=false;
static void GR_FlushMipmap ()
{
if( !gr_cachetail)
return;
if(!gr_cachetail->downloaded)
DBG_Printf ("flush not dowloaded !!\n");
gr_cachetail->downloaded = false;
// should never happen
if (!gr_cachetail->nextmipmap)
{
if( possibleproblem )
I_ErrorGr ("This just CAN'T HAPPEN!!! So you think you're different eh ?");
possibleproblem=true;
DBG_Printf ("Never happen happen !!\n");
GR_ClearMipmapCache ();
}
else
{
// DBG_Printf ("fluching mipmap at position %d (%d bytes) tailpos=%d (%d byte)\n",gr_cachetail->cachepos,gr_cachetail->mipmapSize,gr_cachetail->nextmipmap->cachepos,gr_cachetail->nextmipmap->mipmapSize);
gr_cachetail->cachepos = 0;
gr_cachetail->mipmapSize = -1;
gr_cachetail = gr_cachetail->nextmipmap;
}
}
// --------------------------------------------------------------------------
// Download a 'surface' into the graphics card memory
// --------------------------------------------------------------------------
static void GR_DownloadMipmap (GlideMipmap_t* grMipmap)
{
FxU32 mipmapSize;
if (!grPreviousContext) {
DBG_Printf ("HWRAPI DownloadMipmap() : display not set\n");
return;
}
if ( !grMipmap->grInfo.data ) {
DBG_Printf ("HWRAPI DownloadMipmap() : No DATA !!!\n");
return;
}
mipmapSize = grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &grMipmap->grInfo);
while (1)
{
// 3Dfx specs : a mipmap level can not straddle the 2MByte boundary
if (gr_cachetail->cachepos >= gr_cachepos)
{
if (gr_cachetail->cachepos >= gr_cachepos + mipmapSize)
if((gr_cachepos < TEXMEM_2MB_EDGE) && (gr_cachepos+mipmapSize > TEXMEM_2MB_EDGE))
{
if( gr_cachetail->cachepos >= TEXMEM_2MB_EDGE )
{
gr_cachepos = TEXMEM_2MB_EDGE;
continue;
}
// else FlushMipmap
}
else
break;
GR_FlushMipmap ();
}
else
{
if (gr_cachemax >= gr_cachepos + mipmapSize)
{
if((gr_cachepos < TEXMEM_2MB_EDGE) && (gr_cachepos+mipmapSize > TEXMEM_2MB_EDGE) && (gr_cachetail->cachepos < TEXMEM_2MB_EDGE))
gr_cachepos = TEXMEM_2MB_EDGE;
else
break;
}
else
// not enough space in the end of the buffer
gr_cachepos = gr_cachemin;
//dbg_printf (" cycle over\n");
}
//dbg_printf (" tailpos: %7d pos: %7d size: %7d free: %7d\n",
// gr_cachetail->cachepos, gr_cachepos, mipmapsize, freespace);
}
gr_cachehead->nextmipmap = grMipmap;
//DBG_Printf ("download %d byte at %d\n",mipmapSize,gr_cachepos);
grTexDownloadMipMap (GR_TMU0, gr_cachepos, GR_MIPMAPLEVELMASK_BOTH, &grMipmap->grInfo);
grMipmap->cachepos = gr_cachepos;
grMipmap->mipmapSize = mipmapSize;
grMipmap->downloaded = true;
grMipmap->nextmipmap = NULL; // the head don't have next
gr_cachepos += mipmapSize;
gr_cachehead = grMipmap; // the head is the last loaded texture (FIFO)
possibleproblem=false;
}
// ==========================================================================
// The mipmap becomes the current texture source
// ==========================================================================
EXPORT void HWRAPI( SetTexture ) (GlideMipmap_t* grMipmap)
{
FBITFIELD xor;
if (!grPreviousContext) {
DBG_Printf ("HWRAPI SetTexture() : display not set\n");
return;
}
// don't set exactely the same mipmap
if( lastmipmapset == grMipmap )
return;
if (!grMipmap->downloaded)
GR_DownloadMipmap (grMipmap);
xor = grMipmap->flags ^ CurrentTextureFlags;
if(xor)
{
if(xor&TF_WRAPXY)
{
switch(grMipmap->flags & TF_WRAPXY)
{
case 0 :
grTexClampMode (GR_TMU0, GR_TEXTURECLAMP_CLAMP, GR_TEXTURECLAMP_CLAMP);
break;
case TF_WRAPX :
grTexClampMode (GR_TMU0, GR_TEXTURECLAMP_WRAP , GR_TEXTURECLAMP_CLAMP);
break;
case TF_WRAPY :
grTexClampMode (GR_TMU0, GR_TEXTURECLAMP_CLAMP, GR_TEXTURECLAMP_WRAP);
break;
case TF_WRAPXY :
grTexClampMode (GR_TMU0, GR_TEXTURECLAMP_WRAP, GR_TEXTURECLAMP_WRAP);
break;
}
}
if( xor & TF_CHROMAKEYED )
{
if(grMipmap->flags & TF_CHROMAKEYED )
grChromakeyMode (GR_CHROMAKEY_ENABLE);
else
grChromakeyMode (GR_CHROMAKEY_DISABLE);
}
CurrentTextureFlags = grMipmap->flags;
}
grTexSource (GR_TMU0, grMipmap->cachepos, GR_MIPMAPLEVELMASK_BOTH, &grMipmap->grInfo);
lastmipmapset = grMipmap;
}
// -----------------+
// SetBlend : Set render mode
// -----------------+
// PF_Masked - we could use an ALPHA_TEST of GL_EQUAL, and alpha ref of 0,
// is it faster when pixels are discarded ?
EXPORT void HWRAPI( SetBlend ) ( FBITFIELD PolyFlags )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -