04 Sep 2011
This commit is contained in:
parent
6ad79ff451
commit
de17869a55
14
change.log
14
change.log
|
@ -1,8 +1,20 @@
|
|||
build ????
|
||||
build 1662
|
||||
|
||||
Client: implement StudioRemapColors function
|
||||
Client: add simple shadows for stduiomodels (disabled like in GoldSrc)
|
||||
Client: fix some Paranoia bugs when custom renderer is disabled
|
||||
Client: implement overview tool (dev_overview)
|
||||
Client: add debug commands linefile and pointfile
|
||||
Client: get support for full-color external textures (tga format) - world, studiomodels and decals
|
||||
Client: fixed some HLFX 0.6 bugs
|
||||
Client: fixed follow studiomodels (like flags in CTF)
|
||||
Server: add pfnGetApproxWavePlayLen
|
||||
Sound: get support for mp3's with wav header
|
||||
Server: fixed FIND_CLIENT_IN_PVS
|
||||
Server: fixed PlaybackEvent, use camera PVS point when client see in
|
||||
Render: enable lightmaps on a transparent surfaces like windows (r_lighting_extended 2)
|
||||
Server: func_pushable can push players which standing on (sv_fix_pushstep)
|
||||
Render: partially fix for underwater fog (temporary solution)
|
||||
|
||||
build 1613
|
||||
|
||||
|
|
|
@ -6,6 +6,116 @@
|
|||
--------------------Configuration: cl_dll - Win32 Release--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP266.tmp" with contents
|
||||
[
|
||||
/nologo /MT /W3 /GX /O2 /I "..\utils\vgui\include" /I "..\engine" /I "..\common" /I "..\pm_shared" /I "..\dlls" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "CLIENT_DLL" /D "CLIENT_WEAPONS" /Fp"..\temp\cl_dll\!release/cl_dll.pch" /YX /Fo"..\temp\cl_dll\!release/" /Fd"..\temp\cl_dll\!release/" /FD /c
|
||||
"D:\Xash3D\src_main\cl_dll\ev_hldm.cpp"
|
||||
"D:\Xash3D\src_main\cl_dll\cdll_int.cpp"
|
||||
"D:\Xash3D\src_main\cl_dll\ev_common.cpp"
|
||||
"D:\Xash3D\src_main\pm_shared\pm_shared.c"
|
||||
]
|
||||
Creating command line "cl.exe @"C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP266.tmp""
|
||||
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP267.tmp" with contents
|
||||
[
|
||||
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib winmm.lib ../utils/vgui/lib/win32_vc6/vgui.lib wsock32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"..\temp\cl_dll\!release/client.pdb" /machine:I386 /out:"..\temp\cl_dll\!release/client.dll" /implib:"..\temp\cl_dll\!release/client.lib"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\crossbow.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\crowbar.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\egon.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\ev_hldm.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\gauss.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\handgrenade.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\hl_baseentity.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\hl_events.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\hl_objects.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\hl_weapons.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\hl_wpn_glock.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\hornetgun.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\mp5.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\python.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\rpg.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\satchel.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\shotgun.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\squeakgrenade.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\tripmine.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_scrollbar2.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_slider2.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\voice_banmgr.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\voice_status.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\ammo.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\ammo_secondary.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\ammohistory.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\battery.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\cdll_int.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\com_weapons.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\death.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\demo.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\entity.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\ev_common.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\events.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\flashlight.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\GameStudioModelRenderer.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\geiger.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\health.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\hud.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\hud_msg.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\hud_redraw.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\hud_servers.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\hud_spectator.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\hud_update.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\in_camera.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\input.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\inputw32.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\menu.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\message.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\parsemsg.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\pm_debug.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\pm_math.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\pm_shared.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\saytext.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\status_icons.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\statusbar.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\studio_util.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\StudioModelRenderer.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\text_message.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\train.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\tri.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\util.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_checkbutton2.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_ClassMenu.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_ConsolePanel.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_ControlConfigPanel.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_CustomObjects.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_grid.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_helpers.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_int.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_listbox.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_loadtga.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_MOTDWindow.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_SchemeManager.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_ScorePanel.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_ServerBrowser.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_SpectatorPanel.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_TeamFortressViewport.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\vgui_teammenu.obj"
|
||||
"\Xash3D\src_main\temp\cl_dll\!release\view.obj"
|
||||
]
|
||||
Creating command line "link.exe @"C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP267.tmp""
|
||||
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP268.bat" with contents
|
||||
[
|
||||
@echo off
|
||||
copy \Xash3D\src_main\temp\cl_dll\!release\client.dll "D:\Xash3D\valve\cl_dlls\client.dll"
|
||||
]
|
||||
Creating command line ""C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP268.bat""
|
||||
Compiling...
|
||||
ev_hldm.cpp
|
||||
cdll_int.cpp
|
||||
ev_common.cpp
|
||||
pm_shared.c
|
||||
Linking...
|
||||
Creating library ..\temp\cl_dll\!release/client.lib and object ..\temp\cl_dll\!release/client.exp
|
||||
<h3>Output Window</h3>
|
||||
Performing Custom Build Step on \Xash3D\src_main\temp\cl_dll\!release\client.dll
|
||||
‘ª®¯¨à®¢ ® ä ©«®¢: 1.
|
||||
|
||||
|
||||
|
||||
|
|
16
dlls/hl.plg
16
dlls/hl.plg
|
@ -6,13 +6,13 @@
|
|||
--------------------Configuration: hl - Win32 Release--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1B70.tmp" with contents
|
||||
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1931.tmp" with contents
|
||||
[
|
||||
/nologo /G5 /MT /W3 /O2 /I "..\dlls" /I "..\engine" /I "..\common" /I "..\pm_shared" /I "..\game_shared" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "QUIVER" /D "VOXEL" /D "QUAKE2" /D "VALVE_DLL" /D "CLIENT_WEAPONS" /Fr"..\temp\dlls\!release/" /Fp"..\temp\dlls\!release/hl.pch" /YX /Fo"..\temp\dlls\!release/" /Fd"..\temp\dlls\!release/" /FD /c
|
||||
"D:\Xash3D\src_main\dlls\client.cpp"
|
||||
"D:\Xash3D\src_main\dlls\nodes.cpp"
|
||||
]
|
||||
Creating command line "cl.exe @"C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1B70.tmp""
|
||||
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1B71.tmp" with contents
|
||||
Creating command line "cl.exe @"C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1931.tmp""
|
||||
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1932.tmp" with contents
|
||||
[
|
||||
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"..\temp\dlls\!release/hl.pdb" /debug /machine:I386 /def:".\hl.def" /out:"..\temp\dlls\!release/hl.dll" /implib:"..\temp\dlls\!release/hl.lib"
|
||||
"\Xash3D\src_main\temp\dlls\!release\aflock.obj"
|
||||
|
@ -117,15 +117,15 @@ kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32
|
|||
"\Xash3D\src_main\temp\dlls\!release\xen.obj"
|
||||
"\Xash3D\src_main\temp\dlls\!release\zombie.obj"
|
||||
]
|
||||
Creating command line "link.exe @"C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1B71.tmp""
|
||||
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1B72.bat" with contents
|
||||
Creating command line "link.exe @"C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1932.tmp""
|
||||
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1933.bat" with contents
|
||||
[
|
||||
@echo off
|
||||
copy \Xash3D\src_main\temp\dlls\!release\hl.dll "D:\Xash3D\valve\dlls\hl.dll"
|
||||
]
|
||||
Creating command line ""C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1B72.bat""
|
||||
Creating command line ""C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1933.bat""
|
||||
Compiling...
|
||||
client.cpp
|
||||
nodes.cpp
|
||||
Linking...
|
||||
Creating library ..\temp\dlls\!release/hl.lib and object ..\temp\dlls\!release/hl.exp
|
||||
<h3>Output Window</h3>
|
||||
|
|
|
@ -407,7 +407,7 @@ int CTripmine::GetItemInfo(ItemInfo *p)
|
|||
|
||||
BOOL CTripmine::Deploy( )
|
||||
{
|
||||
//pev->body = 0;
|
||||
pev->body = 0;
|
||||
return DefaultDeploy( "models/v_tripmine.mdl", "models/p_tripmine.mdl", TRIPMINE_DRAW, "trip" );
|
||||
}
|
||||
|
||||
|
|
|
@ -65,10 +65,13 @@ void CL_PlayCDTrack_f( void )
|
|||
static int track = 0;
|
||||
static qboolean paused = false;
|
||||
static qboolean looped = false;
|
||||
static qboolean enabled = true;
|
||||
|
||||
if( Cmd_Argc() < 2 ) return;
|
||||
command = Cmd_Argv( 1 );
|
||||
|
||||
if( !enabled && Q_stricmp( command, "on" )) return; // CD-player is disabled
|
||||
|
||||
if( !Q_stricmp( command, "play" ))
|
||||
{
|
||||
track = bound( 1, Q_atoi( Cmd_Argv( 2 )), MAX_CDTRACKS );
|
||||
|
@ -100,6 +103,14 @@ void CL_PlayCDTrack_f( void )
|
|||
looped = false;
|
||||
track = 0;
|
||||
}
|
||||
else if( !Q_stricmp( command, "on" ))
|
||||
{
|
||||
enabled = true;
|
||||
}
|
||||
else if( !Q_stricmp( command, "off" ))
|
||||
{
|
||||
enabled = false;
|
||||
}
|
||||
else if( !Q_stricmp( command, "info" ))
|
||||
{
|
||||
int i, maxTrack;
|
||||
|
@ -128,7 +139,6 @@ void CL_ScreenshotGetName( int lastnum, char *filename )
|
|||
{
|
||||
int a, b, c, d;
|
||||
|
||||
if( !filename ) return;
|
||||
if( lastnum < 0 || lastnum > 9999 )
|
||||
{
|
||||
// bound
|
||||
|
@ -147,6 +157,35 @@ void CL_ScreenshotGetName( int lastnum, char *filename )
|
|||
Q_sprintf( filename, "scrshots/%s/shot%i%i%i%i.bmp", clgame.mapname, a, b, c, d );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_SnapshotGetName
|
||||
==================
|
||||
*/
|
||||
qboolean CL_SnapshotGetName( int lastnum, char *filename )
|
||||
{
|
||||
int a, b, c, d;
|
||||
|
||||
if( lastnum < 0 || lastnum > 9999 )
|
||||
{
|
||||
MsgDev( D_ERROR, "unable to write snapshot\n" );
|
||||
FS_AllowDirectPaths( false );
|
||||
return false;
|
||||
}
|
||||
|
||||
a = lastnum / 1000;
|
||||
lastnum -= a * 1000;
|
||||
b = lastnum / 100;
|
||||
lastnum -= b * 100;
|
||||
c = lastnum / 10;
|
||||
lastnum -= c * 10;
|
||||
d = lastnum;
|
||||
|
||||
Q_sprintf( filename, "../%s%i%i%i%i.bmp", clgame.mapname, a, b, c, d );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
|
@ -189,6 +228,46 @@ void CL_ScreenShot_f( void )
|
|||
cls.envshot_vieworg = NULL; // no custom view
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_SnapShot_f
|
||||
|
||||
save screenshots into root dir
|
||||
==================
|
||||
*/
|
||||
void CL_SnapShot_f( void )
|
||||
{
|
||||
int i;
|
||||
string checkname;
|
||||
|
||||
if( gl_overview->integer == 1 )
|
||||
{
|
||||
// special case for write overview image and script file
|
||||
Q_snprintf( cls.shotname, sizeof( cls.shotname ), "overviews/%s.bmp", clgame.mapname );
|
||||
cls.scrshot_action = scrshot_mapshot; // build new frame for mapshot
|
||||
}
|
||||
else
|
||||
{
|
||||
FS_AllowDirectPaths( true );
|
||||
|
||||
// scan for a free filename
|
||||
for( i = 0; i < 9999; i++ )
|
||||
{
|
||||
if( !CL_SnapshotGetName( i, checkname ))
|
||||
return; // no namespace
|
||||
|
||||
if( !FS_FileExists( checkname, false ))
|
||||
break;
|
||||
}
|
||||
|
||||
FS_AllowDirectPaths( false );
|
||||
Q_strncpy( cls.shotname, checkname, sizeof( cls.shotname ));
|
||||
cls.scrshot_action = scrshot_snapshot; // build new frame for screenshot
|
||||
}
|
||||
|
||||
cls.envshot_vieworg = NULL; // no custom view
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_EnvShot_f
|
||||
|
|
|
@ -256,6 +256,38 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
|
|||
dl->radius = 430;
|
||||
else dl->radius = Com_RandomLong( 400, 430 );
|
||||
}
|
||||
|
||||
if( ent->model->type == mod_studio )
|
||||
{
|
||||
if (ent->model->flags & STUDIO_ROTATE)
|
||||
ent->angles[1] = anglemod(100 * cl.time);
|
||||
|
||||
if (ent->model->flags & STUDIO_GIB)
|
||||
CL_RocketTrail (ent->prevstate.origin, ent->curstate.origin, 2);
|
||||
else if (ent->model->flags & STUDIO_ZOMGIB)
|
||||
CL_RocketTrail (ent->prevstate.origin, ent->curstate.origin, 4);
|
||||
else if (ent->model->flags & STUDIO_TRACER)
|
||||
CL_RocketTrail (ent->prevstate.origin, ent->curstate.origin, 3);
|
||||
else if (ent->model->flags & STUDIO_TRACER2)
|
||||
CL_RocketTrail (ent->prevstate.origin, ent->curstate.origin, 5);
|
||||
else if (ent->model->flags & STUDIO_ROCKET)
|
||||
{
|
||||
dlight_t *dl = CL_AllocDlight (ent->curstate.number);
|
||||
VectorCopy (ent->origin, dl->origin);
|
||||
dl->color.r = 255;
|
||||
dl->color.g = 255;
|
||||
dl->color.b = 255;
|
||||
dl->radius = 200;
|
||||
dl->die = cl.time + 0.01;
|
||||
|
||||
CL_RocketTrail (ent->prevstate.origin, ent->curstate.origin, 0);
|
||||
}
|
||||
else if (ent->model->flags & STUDIO_GRENADE)
|
||||
CL_RocketTrail (ent->prevstate.origin, ent->curstate.origin, 1);
|
||||
else if (ent->model->flags & STUDIO_TRACER3)
|
||||
CL_RocketTrail (ent->prevstate.origin, ent->curstate.origin, 6);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -276,40 +276,6 @@ void CL_StudioEvent( struct mstudioevent_s *event, cl_entity_t *pEdict )
|
|||
clgame.dllFuncs.pfnStudioEvent( event, pEdict );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_FadeAlpha
|
||||
================
|
||||
*/
|
||||
void CL_FadeAlpha( int starttime, int endtime, byte *alpha )
|
||||
{
|
||||
int time, fade_time;
|
||||
|
||||
if( !starttime )
|
||||
{
|
||||
*alpha = 255;
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: rewrite this code with float values
|
||||
time = (cl.time * 1000) - starttime;
|
||||
|
||||
if( time >= endtime )
|
||||
{
|
||||
*alpha = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// fade time is 1/4 of endtime
|
||||
fade_time = endtime / 4;
|
||||
fade_time = bound( 300, fade_time, 10000 );
|
||||
|
||||
// fade out
|
||||
if(( endtime - time ) < fade_time )
|
||||
*alpha = bound( 0, (( endtime - time ) * ( 1.0f / fade_time )) * 255, 255 );
|
||||
else *alpha = 255;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CL_AdjustXPos
|
||||
|
@ -388,7 +354,7 @@ void CL_CenterPrint( const char *text, float y )
|
|||
|
||||
clgame.centerPrint.lines = 1;
|
||||
clgame.centerPrint.totalWidth = 0;
|
||||
clgame.centerPrint.time = cl.mtime[0] * 1000; // allow pause for centerprint
|
||||
clgame.centerPrint.time = cl.mtime[0]; // allow pause for centerprint
|
||||
Q_strncpy( clgame.centerPrint.message, text, sizeof( clgame.centerPrint.message ));
|
||||
s = clgame.centerPrint.message;
|
||||
|
||||
|
@ -554,23 +520,23 @@ static void CL_DrawCenterPrint( void )
|
|||
char *pText;
|
||||
int i, j, x, y;
|
||||
int width, lineLength;
|
||||
byte line[80];
|
||||
byte alpha;
|
||||
byte *colorDefault, line[80];
|
||||
int charWidth, charHeight;
|
||||
|
||||
if( !clgame.centerPrint.time )
|
||||
return;
|
||||
|
||||
CL_FadeAlpha( clgame.centerPrint.time, scr_centertime->value * 1000, &alpha );
|
||||
|
||||
if( !alpha )
|
||||
if(( cl.time - clgame.centerPrint.time ) >= scr_centertime->value )
|
||||
{
|
||||
// faded out
|
||||
clgame.centerPrint.time = 0;
|
||||
// time expired
|
||||
clgame.centerPrint.time = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
pText = clgame.centerPrint.message;
|
||||
y = clgame.centerPrint.y; // start y
|
||||
colorDefault = g_color_table[7];
|
||||
pText = clgame.centerPrint.message;
|
||||
Con_DrawCharacterLen( 0, NULL, &charHeight );
|
||||
|
||||
for( i = 0; i < clgame.centerPrint.lines; i++ )
|
||||
{
|
||||
|
@ -581,10 +547,12 @@ static void CL_DrawCenterPrint( void )
|
|||
{
|
||||
byte c = *pText;
|
||||
line[lineLength] = c;
|
||||
width += clgame.scrInfo.charWidths[c];
|
||||
Con_DrawCharacterLen( c, &charWidth, NULL );
|
||||
width += charWidth;
|
||||
lineLength++;
|
||||
pText++;
|
||||
}
|
||||
|
||||
pText++; // Skip LineFeed
|
||||
line[lineLength] = 0;
|
||||
|
||||
|
@ -592,17 +560,10 @@ static void CL_DrawCenterPrint( void )
|
|||
|
||||
for( j = 0; j < lineLength; j++ )
|
||||
{
|
||||
int ch = line[j];
|
||||
int next = x + clgame.scrInfo.charWidths[ch];
|
||||
|
||||
if( x >= 0 && y >= 0 && next <= clgame.scrInfo.iWidth )
|
||||
{
|
||||
pfnPIC_Set( cls.creditsFont.hFontTexture, 255, 255, 255, alpha );
|
||||
pfnPIC_DrawAdditive( x, y, -1, -1, &cls.creditsFont.fontRc[ch] );
|
||||
}
|
||||
x = next;
|
||||
if( x >= 0 && y >= 0 && x <= clgame.scrInfo.iWidth )
|
||||
x += Con_DrawCharacter( x, y, line[j], colorDefault );
|
||||
}
|
||||
y += clgame.scrInfo.iCharHeight;
|
||||
y += charHeight;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -900,19 +861,28 @@ static void CL_DrawLoading( float percent )
|
|||
width *= xscale;
|
||||
height *= yscale;
|
||||
|
||||
pglColor4ub( 128, 128, 128, 255 );
|
||||
GL_SetRenderMode( kRenderTransTexture );
|
||||
R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, cls.loadingBar );
|
||||
if( cl_allow_levelshots->integer )
|
||||
{
|
||||
pglColor4ub( 128, 128, 128, 255 );
|
||||
GL_SetRenderMode( kRenderTransTexture );
|
||||
R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, cls.loadingBar );
|
||||
|
||||
step = (float)width / 100.0f;
|
||||
right = (int)ceil( percent * step );
|
||||
s2 = (float)right / width;
|
||||
width = right;
|
||||
step = (float)width / 100.0f;
|
||||
right = (int)ceil( percent * step );
|
||||
s2 = (float)right / width;
|
||||
width = right;
|
||||
|
||||
pglColor4ub( 208, 152, 0, 255 );
|
||||
GL_SetRenderMode( kRenderTransTexture );
|
||||
R_DrawStretchPic( x, y, width, height, 0, 0, s2, 1, cls.loadingBar );
|
||||
pglColor4ub( 255, 255, 255, 255 );
|
||||
pglColor4ub( 208, 152, 0, 255 );
|
||||
GL_SetRenderMode( kRenderTransTexture );
|
||||
R_DrawStretchPic( x, y, width, height, 0, 0, s2, 1, cls.loadingBar );
|
||||
pglColor4ub( 255, 255, 255, 255 );
|
||||
}
|
||||
else
|
||||
{
|
||||
pglColor4ub( 255, 255, 255, 255 );
|
||||
GL_SetRenderMode( kRenderTransTexture );
|
||||
R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, cls.loadingBar );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1972,7 +1942,7 @@ like trigger_multiple message in q1
|
|||
static void pfnCenterPrint( const char *string )
|
||||
{
|
||||
if( !string || !*string ) return; // someone stupid joke
|
||||
CL_CenterPrint( string, -1 );
|
||||
CL_CenterPrint( string, 0.25f );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1547,11 +1547,14 @@ void CL_InitLocal( void )
|
|||
Cmd_AddCommand ("stop", CL_Stop_f, "stop playing or recording a demo" );
|
||||
Cmd_AddCommand ("info", NULL, "collect info about local servers with specified protocol" );
|
||||
Cmd_AddCommand ("escape", CL_Escape_f, "escape from game to menu" );
|
||||
Cmd_AddCommand ("pointfile", CL_ReadPointFile_f, "show leaks on a map (if present of course)" );
|
||||
Cmd_AddCommand ("linefile", CL_ReadLineFile_f, "show leaks on a map (if present of course)" );
|
||||
|
||||
Cmd_AddCommand ("quit", CL_Quit_f, "quit from game" );
|
||||
Cmd_AddCommand ("exit", CL_Quit_f, "quit from game" );
|
||||
|
||||
Cmd_AddCommand ("screenshot", CL_ScreenShot_f, "takes a screenshot of the next rendered frame" );
|
||||
Cmd_AddCommand ("snapshot", CL_SnapShot_f, "takes a snapshot of the next rendered frame" );
|
||||
Cmd_AddCommand ("envshot", CL_EnvShot_f, "takes a six-sides cubemap shot with specified name" );
|
||||
Cmd_AddCommand ("skyshot", CL_SkyShot_f, "takes a six-sides envmap (skybox) shot with specified name" );
|
||||
Cmd_AddCommand ("levelshot", CL_LevelShot_f, "same as \"screenshot\", used for create plaque images" );
|
||||
|
|
|
@ -405,12 +405,7 @@ void CL_ParseStaticDecal( sizebuf_t *msg )
|
|||
else modelIndex = 0;
|
||||
flags = BF_ReadByte( msg );
|
||||
|
||||
host.decal_loading = true;
|
||||
if( !cl.decal_index[decalIndex] )
|
||||
cl.decal_index[decalIndex] = GL_LoadTexture( host.draw_decals[decalIndex], NULL, 0, TF_DECAL );
|
||||
host.decal_loading = false;
|
||||
|
||||
CL_DecalShoot( cl.decal_index[decalIndex], entityIndex, modelIndex, origin, flags );
|
||||
CL_DecalShoot( CL_DecalIndex( decalIndex ), entityIndex, modelIndex, origin, flags );
|
||||
}
|
||||
|
||||
void CL_ParseSoundFade( sizebuf_t *msg )
|
||||
|
@ -1326,7 +1321,7 @@ void CL_ParseServerMessage( sizebuf_t *msg )
|
|||
CL_ParseCustomization( msg );
|
||||
break;
|
||||
case svc_centerprint:
|
||||
CL_CenterPrint( BF_ReadString( msg ), 0.35f );
|
||||
CL_CenterPrint( BF_ReadString( msg ), 0.25f );
|
||||
break;
|
||||
case svc_event:
|
||||
CL_ParseEvent( msg );
|
||||
|
|
|
@ -294,22 +294,19 @@ int CL_WaterEntity( const float *rgflPos )
|
|||
|
||||
/*
|
||||
=============
|
||||
CL_GetWaterModel
|
||||
CL_GetWaterEntity
|
||||
|
||||
returns water brush where inside pos
|
||||
=============
|
||||
*/
|
||||
model_t *CL_GetWaterModel( const float *rgflPos )
|
||||
cl_entity_t *CL_GetWaterEntity( const float *rgflPos )
|
||||
{
|
||||
int entnum;
|
||||
cl_entity_t *clent;
|
||||
int entnum;
|
||||
|
||||
entnum = CL_WaterEntity( rgflPos );
|
||||
if( entnum <= 0 ) return NULL; // world or not water
|
||||
|
||||
if(( clent = CL_GetEntityByIndex( entnum )) != NULL )
|
||||
return clent->model;
|
||||
return NULL;
|
||||
return CL_GetEntityByIndex( entnum );
|
||||
}
|
||||
|
||||
static void pfnParticle( float *origin, int color, float life, int zpos, int zvel )
|
||||
|
|
|
@ -217,7 +217,7 @@ void CL_UpdateTexture( mstudiotexture_t *ptexture, int topcolor, int bottomcolor
|
|||
gltexture_t *glt;
|
||||
rgbdata_t *pic;
|
||||
texture_t *tx = NULL;
|
||||
char texname[128], name[128];
|
||||
char texname[128], name[128], mdlname[128];
|
||||
int i, size, index;
|
||||
byte paletteBackup[768];
|
||||
byte *raw, *pal;
|
||||
|
@ -226,8 +226,11 @@ void CL_UpdateTexture( mstudiotexture_t *ptexture, int topcolor, int bottomcolor
|
|||
glt = R_GetTexture( ptexture->index );
|
||||
|
||||
// build name of original texture
|
||||
Q_strncpy( mdlname, RI.currentmodel->name, sizeof( mdlname ));
|
||||
FS_FileBase( ptexture->name, name );
|
||||
Q_snprintf( texname, sizeof( texname ), "#%s/%s.mdl", RI.currentmodel->name, name );
|
||||
FS_StripExtension( mdlname );
|
||||
|
||||
Q_snprintf( texname, sizeof( texname ), "#%s/%s.mdl", mdlname, name );
|
||||
index = GL_FindTexture( texname );
|
||||
if( !index ) return; // couldn't find texture
|
||||
|
||||
|
|
|
@ -203,6 +203,9 @@ void SCR_MakeScreenShot( void )
|
|||
case scrshot_normal:
|
||||
iRet = VID_ScreenShot( cls.shotname, VID_SCREENSHOT );
|
||||
break;
|
||||
case scrshot_snapshot:
|
||||
iRet = VID_ScreenShot( cls.shotname, VID_SNAPSHOT );
|
||||
break;
|
||||
case scrshot_plaque:
|
||||
iRet = VID_ScreenShot( cls.shotname, VID_LEVELSHOT );
|
||||
break;
|
||||
|
@ -224,7 +227,12 @@ void SCR_MakeScreenShot( void )
|
|||
}
|
||||
|
||||
// report
|
||||
if( iRet ) MsgDev( D_INFO, "Write %s\n", cls.shotname );
|
||||
if( iRet )
|
||||
{
|
||||
// snapshots don't writes message about image
|
||||
if( cls.scrshot_action != scrshot_snapshot )
|
||||
MsgDev( D_INFO, "Write %s\n", cls.shotname );
|
||||
}
|
||||
else MsgDev( D_ERROR, "Unable to write %s\n", cls.shotname );
|
||||
|
||||
cls.envshot_vieworg = NULL;
|
||||
|
@ -390,7 +398,9 @@ void SCR_RegisterShaders( void )
|
|||
|
||||
// register gfx.wad images
|
||||
cls.pauseIcon = GL_LoadTexture( "gfx.wad/paused.lmp", NULL, 0, TF_IMAGE );
|
||||
cls.loadingBar = GL_LoadTexture( "gfx.wad/lambda.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE );
|
||||
if( cl_allow_levelshots->integer )
|
||||
cls.loadingBar = GL_LoadTexture( "gfx.wad/lambda.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE );
|
||||
else cls.loadingBar = GL_LoadTexture( "gfx.wad/lambda.lmp", NULL, 0, TF_IMAGE );
|
||||
cls.creditsFont.hFontTexture = GL_LoadTexture( "gfx.wad/creditsfont.fnt", NULL, 0, TF_IMAGE );
|
||||
cls.hChromeSprite = pfnSPR_Load( "sprites/shellchrome.spr" );
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ GNU General Public License for more details.
|
|||
#include "pm_local.h"
|
||||
#include "gl_local.h"
|
||||
#include "studio.h"
|
||||
#include "wadfile.h" // acess decal size
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
|
@ -824,6 +825,8 @@ void CL_BloodSprite( const vec3_t org, int colorIndex, int modelIndex, int model
|
|||
VectorSet( forward, 0.0f, 0.0f, 1.0f ); // up-vector
|
||||
VectorVectors( forward, right, up );
|
||||
|
||||
Mod_GetFrames( modelIndex2, &frameCount );
|
||||
|
||||
// create blood drops
|
||||
for( i = 0; i < 14; i++ )
|
||||
{
|
||||
|
@ -835,7 +838,7 @@ void CL_BloodSprite( const vec3_t org, int colorIndex, int modelIndex, int model
|
|||
pTemp = CL_TempEntAlloc( org, Mod_Handle( modelIndex2 ));
|
||||
if( !pTemp ) return;
|
||||
|
||||
pTemp->flags = FTENT_SPRANIMATELOOP|FTENT_COLLIDEWORLD|FTENT_SLOWGRAVITY;
|
||||
pTemp->flags = FTENT_COLLIDEWORLD|FTENT_SLOWGRAVITY;
|
||||
|
||||
pTemp->entity.curstate.rendermode = kRenderTransTexture;
|
||||
pTemp->entity.curstate.renderfx = kRenderFxClampMinScale;
|
||||
|
@ -843,17 +846,17 @@ void CL_BloodSprite( const vec3_t org, int colorIndex, int modelIndex, int model
|
|||
pTemp->entity.curstate.rendercolor.r = clgame.palette[colorIndex][0];
|
||||
pTemp->entity.curstate.rendercolor.g = clgame.palette[colorIndex][1];
|
||||
pTemp->entity.curstate.rendercolor.b = clgame.palette[colorIndex][2];
|
||||
pTemp->entity.curstate.framerate = frameCount * 4; // Finish in 0.250 seconds
|
||||
pTemp->entity.curstate.frame = Com_RandomLong( 0, frameCount - 1 );
|
||||
pTemp->die = cl.time + Com_RandomFloat( 1.0f, 3.0f );
|
||||
|
||||
pTemp->entity.angles[2] = Com_RandomLong( 0, 360 );
|
||||
pTemp->bounceFactor = 0;
|
||||
|
||||
dir[0] = forward[0] + Com_RandomFloat( -0.3f, 0.3f );
|
||||
dir[1] = forward[1] + Com_RandomFloat( -0.3f, 0.3f );
|
||||
dir[2] = forward[2] + Com_RandomFloat( -0.3f, 0.3f );
|
||||
dir[0] = forward[0] + Com_RandomFloat( -0.8f, 0.8f );
|
||||
dir[1] = forward[1] + Com_RandomFloat( -0.8f, 0.8f );
|
||||
dir[2] = forward[2];
|
||||
|
||||
VectorScale( dir, Com_RandomFloat( 4.0f * size, 16.0f * size ), pTemp->entity.baseline.origin );
|
||||
VectorScale( dir, Com_RandomFloat( 8.0f * size, 20.0f * size ), pTemp->entity.baseline.origin );
|
||||
pTemp->entity.baseline.origin[2] += Com_RandomFloat( 4.0f, 16.0f ) * size;
|
||||
}
|
||||
}
|
||||
|
@ -2384,12 +2387,12 @@ update client flashlight
|
|||
*/
|
||||
void CL_UpdateFlashlight( cl_entity_t *pEnt )
|
||||
{
|
||||
int key, traceFlags;
|
||||
vec3_t vecSrc, vecEnd;
|
||||
vec3_t forward, view_ofs;
|
||||
float falloff;
|
||||
pmtrace_t trace;
|
||||
dlight_t *dl;
|
||||
int key;
|
||||
|
||||
if(( pEnt->index - 1 ) == cl.playernum )
|
||||
{
|
||||
|
@ -2416,7 +2419,12 @@ void CL_UpdateFlashlight( cl_entity_t *pEnt )
|
|||
VectorAdd( pEnt->origin, view_ofs, vecSrc );
|
||||
VectorMA( vecSrc, FLASHLIGHT_DISTANCE, forward, vecEnd );
|
||||
|
||||
trace = PM_PlayerTrace( clgame.pmove, vecSrc, vecEnd, PM_GLASS_IGNORE|PM_STUDIO_BOX, 2, -1, NULL );
|
||||
traceFlags = PM_STUDIO_BOX;
|
||||
|
||||
if( r_lighting_extended->integer < 2 )
|
||||
traceFlags |= PM_GLASS_IGNORE;
|
||||
|
||||
trace = PM_PlayerTrace( clgame.pmove, vecSrc, vecEnd, traceFlags, 2, -1, NULL );
|
||||
falloff = trace.fraction * FLASHLIGHT_DISTANCE;
|
||||
|
||||
if( falloff < 250.0f ) falloff = 1.0f;
|
||||
|
@ -2538,7 +2546,40 @@ int CL_DecalIndex( int id )
|
|||
|
||||
host.decal_loading = true;
|
||||
if( !cl.decal_index[id] )
|
||||
cl.decal_index[id] = GL_LoadTexture( host.draw_decals[id], NULL, 0, TF_DECAL );
|
||||
{
|
||||
qboolean load_external = false;
|
||||
|
||||
if( host_allow_materials->integer )
|
||||
{
|
||||
char decalname[64];
|
||||
int gl_texturenum = 0;
|
||||
|
||||
Q_snprintf( decalname, sizeof( decalname ), "materials/decals/%s.tga", host.draw_decals[id] );
|
||||
|
||||
if( FS_FileExists( decalname, false ))
|
||||
gl_texturenum = GL_LoadTexture( decalname, NULL, 0, TF_DECAL );
|
||||
|
||||
if( gl_texturenum )
|
||||
{
|
||||
byte *fin;
|
||||
mip_t *mip;
|
||||
|
||||
// find real decal dimensions and store it into texture srcWidth\srcHeight
|
||||
if(( fin = FS_LoadFile( va( "decals.wad/%s", host.draw_decals[id] ), NULL, false )) != NULL )
|
||||
{
|
||||
mip = (mip_t *)fin;
|
||||
R_GetTexture( gl_texturenum )->srcWidth = mip->width;
|
||||
R_GetTexture( gl_texturenum )->srcHeight = mip->height;
|
||||
Mem_Free( fin ); // release low-quality decal
|
||||
}
|
||||
|
||||
cl.decal_index[id] = gl_texturenum;
|
||||
load_external = true; // sucessfully loaded
|
||||
}
|
||||
}
|
||||
|
||||
if( !load_external ) cl.decal_index[id] = GL_LoadTexture( host.draw_decals[id], NULL, 0, TF_DECAL );
|
||||
}
|
||||
host.decal_loading = false;
|
||||
|
||||
return cl.decal_index[id];
|
||||
|
|
|
@ -327,6 +327,8 @@ V_PostRender
|
|||
*/
|
||||
void V_PostRender( void )
|
||||
{
|
||||
qboolean draw_2d = false;
|
||||
|
||||
R_Set2DMode( true );
|
||||
|
||||
if( cls.state == ca_active )
|
||||
|
@ -335,7 +337,16 @@ void V_PostRender( void )
|
|||
VGui_Paint();
|
||||
}
|
||||
|
||||
if( cls.scrshot_action == scrshot_inactive || cls.scrshot_action == scrshot_normal )
|
||||
switch( cls.scrshot_action )
|
||||
{
|
||||
case scrshot_inactive:
|
||||
case scrshot_normal:
|
||||
case scrshot_snapshot:
|
||||
draw_2d = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if( draw_2d )
|
||||
{
|
||||
SCR_RSpeeds();
|
||||
SCR_NetSpeeds();
|
||||
|
|
|
@ -40,6 +40,7 @@ GNU General Public License for more details.
|
|||
#define VID_LEVELSHOT 1
|
||||
#define VID_MINISHOT 2
|
||||
#define VID_MAPSHOT 3 // special case for overview layer
|
||||
#define VID_SNAPSHOT 4 // save screenshot into root dir and no gamma correction
|
||||
|
||||
typedef int sound_t;
|
||||
|
||||
|
@ -171,6 +172,7 @@ typedef enum
|
|||
{
|
||||
scrshot_inactive,
|
||||
scrshot_normal, // in-game screenshot
|
||||
scrshot_snapshot, // in-game snapshot
|
||||
scrshot_plaque, // levelshot
|
||||
scrshot_savegame, // saveshot
|
||||
scrshot_demoshot, // for demos preview
|
||||
|
@ -256,8 +258,8 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
// centerprint stuff
|
||||
int lines;
|
||||
int y, time;
|
||||
float time;
|
||||
int y, lines;
|
||||
char message[2048];
|
||||
int totalWidth;
|
||||
int totalHeight;
|
||||
|
@ -550,6 +552,7 @@ void CL_PrepSound( void );
|
|||
//
|
||||
void CL_Quit_f( void );
|
||||
void CL_ScreenShot_f( void );
|
||||
void CL_SnapShot_f( void );
|
||||
void CL_PlayCDTrack_f( void );
|
||||
void CL_EnvShot_f( void );
|
||||
void CL_SkyShot_f( void );
|
||||
|
@ -664,7 +667,7 @@ qboolean CL_IsPredicted( void );
|
|||
int CL_TruePointContents( const vec3_t p );
|
||||
int CL_PointContents( const vec3_t p );
|
||||
int CL_WaterEntity( const float *rgflPos );
|
||||
model_t *CL_GetWaterModel( const float *rgflPos );
|
||||
cl_entity_t *CL_GetWaterEntity( const float *rgflPos );
|
||||
void CL_SetupPMove( playermove_t *pmove, clientdata_t *cd, entity_state_t *state, usercmd_t *ucmd );
|
||||
void CL_ClearPhysEnts( void );
|
||||
|
||||
|
@ -722,6 +725,8 @@ void CL_AddCustomBeam( cl_entity_t *pEnvBeam );
|
|||
void CL_KillDeadBeams( cl_entity_t *pDeadEntity );
|
||||
void CL_ParseViewBeam( sizebuf_t *msg, int beamType );
|
||||
void CL_RegisterMuzzleFlashes( void );
|
||||
void CL_ReadPointFile_f( void );
|
||||
void CL_ReadLineFile_f( void );
|
||||
|
||||
//
|
||||
// console.c
|
||||
|
@ -737,6 +742,8 @@ void Con_DrawConsole( void );
|
|||
void Con_DrawVersion( void );
|
||||
void Con_DrawStringLen( const char *pText, int *length, int *height );
|
||||
int Con_DrawString( int x, int y, const char *string, rgba_t setColor );
|
||||
int Con_DrawCharacter( int x, int y, int number, rgba_t color );
|
||||
void Con_DrawCharacterLen( int number, int *width, int *height );
|
||||
void Con_DefaultColor( int r, int g, int b );
|
||||
void Con_CharEvent( int key );
|
||||
void Key_Console( int key );
|
||||
|
|
|
@ -430,7 +430,11 @@ qboolean VID_ScreenShot( const char *filename, int shot_type )
|
|||
switch( shot_type )
|
||||
{
|
||||
case VID_SCREENSHOT:
|
||||
VID_ImageAdjustGamma( r_shot->buffer, r_shot->width, r_shot->height ); // adjust brightness
|
||||
if( !gl_overview->integer )
|
||||
VID_ImageAdjustGamma( r_shot->buffer, r_shot->width, r_shot->height ); // scrshot gamma
|
||||
break;
|
||||
case VID_SNAPSHOT:
|
||||
FS_AllowDirectPaths( true );
|
||||
break;
|
||||
case VID_LEVELSHOT:
|
||||
flags |= IMAGE_RESAMPLE;
|
||||
|
@ -454,6 +458,7 @@ qboolean VID_ScreenShot( const char *filename, int shot_type )
|
|||
|
||||
// write image
|
||||
result = FS_SaveImage( filename, r_shot );
|
||||
FS_AllowDirectPaths( false ); // always reset after store screenshot
|
||||
FS_FreeImage( r_shot );
|
||||
|
||||
return result;
|
||||
|
|
|
@ -162,6 +162,19 @@ static void ComputeNormal( const vec3_t vStartPos, const vec3_t vNextPos, vec3_t
|
|||
VectorNormalizeFast( pNormal );
|
||||
}
|
||||
|
||||
static void SetBeamRenderMode( int rendermode )
|
||||
{
|
||||
if( rendermode == kRenderTransAdd )
|
||||
{
|
||||
pglEnable( GL_BLEND );
|
||||
pglBlendFunc( GL_SRC_ALPHA, GL_ONE );
|
||||
}
|
||||
else pglDisable( GL_BLEND ); // solid mode
|
||||
|
||||
pglDisable( GL_ALPHA_TEST );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_DrawSegs
|
||||
|
@ -250,7 +263,7 @@ static void CL_DrawSegs( int modelIndex, float frame, int rendermode, const vec3
|
|||
segs_drawn = 0;
|
||||
total_segs = segments;
|
||||
|
||||
GL_SetRenderMode( rendermode );
|
||||
SetBeamRenderMode( rendermode );
|
||||
GL_Bind( GL_TEXTURE0, m_hSprite );
|
||||
pglBegin( GL_TRIANGLE_STRIP );
|
||||
|
||||
|
@ -421,7 +434,7 @@ static void CL_DrawDisk( int modelIndex, float frame, int rendermode, const vec3
|
|||
|
||||
w = freq * delta[2];
|
||||
|
||||
GL_SetRenderMode( rendermode );
|
||||
SetBeamRenderMode( rendermode );
|
||||
GL_Bind( GL_TEXTURE0, m_hSprite );
|
||||
|
||||
pglBegin( GL_TRIANGLE_STRIP );
|
||||
|
@ -491,7 +504,7 @@ static void CL_DrawCylinder( int modelIndex, float frame, int rendermode, const
|
|||
scale = scale * length;
|
||||
|
||||
GL_Cull( GL_NONE ); // draw both sides
|
||||
GL_SetRenderMode( rendermode );
|
||||
SetBeamRenderMode( rendermode );
|
||||
GL_Bind( GL_TEXTURE0, m_hSprite );
|
||||
|
||||
pglBegin( GL_TRIANGLE_STRIP );
|
||||
|
@ -606,7 +619,7 @@ void CL_DrawRing( int modelIndex, float frame, int rendermode, const vec3_t sour
|
|||
|
||||
j = segments / 8;
|
||||
|
||||
GL_SetRenderMode( rendermode );
|
||||
SetBeamRenderMode( rendermode );
|
||||
GL_Bind( GL_TEXTURE0, m_hSprite );
|
||||
|
||||
pglBegin( GL_TRIANGLE_STRIP );
|
||||
|
@ -780,7 +793,7 @@ static void DrawBeamFollow( int modelIndex, particle_t *pHead, int frame, int re
|
|||
nColor[1] = (byte)bound( 0, (int)(scaledColor[1] * 255.0f), 255 );
|
||||
nColor[2] = (byte)bound( 0, (int)(scaledColor[2] * 255.0f), 255 );
|
||||
|
||||
GL_SetRenderMode( rendermode );
|
||||
SetBeamRenderMode( rendermode );
|
||||
GL_Bind( GL_TEXTURE0, m_hSprite );
|
||||
|
||||
pglBegin( GL_QUADS );
|
||||
|
@ -1412,7 +1425,7 @@ void CL_DrawBeam( BEAM *pbeam )
|
|||
}
|
||||
|
||||
frame = ((int)( pbeam->frame + cl.time * pbeam->frameRate ) % pbeam->frameCount );
|
||||
rendermode = ( pbeam->flags & FBEAM_SOLID ) ? kRenderTransColor : kRenderTransAdd;
|
||||
rendermode = ( pbeam->flags & FBEAM_SOLID ) ? kRenderNormal : kRenderTransAdd;
|
||||
|
||||
// set color
|
||||
VectorSet( srcColor, pbeam->r, pbeam->g, pbeam->b );
|
||||
|
@ -1632,8 +1645,6 @@ void CL_BeamKill( int deadEntity )
|
|||
CL_KillDeadBeams( pDeadEntity );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
CL_BeamEnts
|
||||
|
@ -2114,4 +2125,85 @@ void CL_ParseViewBeam( sizebuf_t *msg, int beamType )
|
|||
CL_BeamKill( startEnt );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CL_ReadLineFile_f
|
||||
|
||||
Optimized version of pointfile - use beams instead of particles
|
||||
===============
|
||||
*/
|
||||
void CL_ReadLineFile_f( void )
|
||||
{
|
||||
char *afile, *pfile;
|
||||
vec3_t p1, p2;
|
||||
int count, modelIndex;
|
||||
char filename[64];
|
||||
string token;
|
||||
|
||||
Q_snprintf( filename, sizeof( filename ), "maps/%s.lin", clgame.mapname );
|
||||
afile = FS_LoadFile( filename, NULL, false );
|
||||
|
||||
if( !afile )
|
||||
{
|
||||
MsgDev( D_ERROR, "couldn't open %s\n", filename );
|
||||
return;
|
||||
}
|
||||
|
||||
Msg( "Reading %s...\n", filename );
|
||||
|
||||
count = 0;
|
||||
pfile = afile;
|
||||
modelIndex = CL_FindModelIndex( "sprites/laserbeam.spr" );
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
if( !pfile ) break;
|
||||
p1[0] = Q_atof( token );
|
||||
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
if( !pfile ) break;
|
||||
p1[1] = Q_atof( token );
|
||||
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
if( !pfile ) break;
|
||||
p1[2] = Q_atof( token );
|
||||
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
if( !pfile ) break;
|
||||
|
||||
if( token[0] != '-' )
|
||||
{
|
||||
MsgDev( D_ERROR, "%s is corrupted\n" );
|
||||
break;
|
||||
}
|
||||
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
if( !pfile ) break;
|
||||
p2[0] = Q_atof( token );
|
||||
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
if( !pfile ) break;
|
||||
p2[1] = Q_atof( token );
|
||||
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
if( !pfile ) break;
|
||||
p2[2] = Q_atof( token );
|
||||
|
||||
count++;
|
||||
|
||||
if( !CL_BeamPoints( p1, p2, modelIndex, 99999, 2, 0, 255, 0, 0, 0, 255.0f, 0.0f, 0.0f ))
|
||||
{
|
||||
if( !modelIndex ) MsgDev( D_ERROR, "CL_ReadLineFile: no beam sprite!\n" );
|
||||
else MsgDev( D_ERROR, "CL_ReadLineFile: not enough free beams!\n" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Mem_Free( afile );
|
||||
|
||||
if( count ) Msg( "%i lines read\n", count );
|
||||
else Msg( "map %s has no leaks!\n", clgame.mapname );
|
||||
}
|
|
@ -168,6 +168,7 @@ typedef struct
|
|||
float fogDensity;
|
||||
float fogStart;
|
||||
float fogEnd;
|
||||
int cached_contents; // in water
|
||||
|
||||
float waveHeight; // global waveHeight
|
||||
float currentWaveHeight; // current entity waveHeight
|
||||
|
@ -626,7 +627,6 @@ extern convar_t *r_novis;
|
|||
extern convar_t *r_nocull;
|
||||
extern convar_t *r_lockpvs;
|
||||
extern convar_t *r_lockcull;
|
||||
extern convar_t *r_wateralpha;
|
||||
extern convar_t *r_dynamic;
|
||||
extern convar_t *r_lightmap;
|
||||
extern convar_t *r_fastsky;
|
||||
|
|
|
@ -18,6 +18,8 @@ GNU General Public License for more details.
|
|||
#include "gl_local.h"
|
||||
#include "mathlib.h"
|
||||
|
||||
#define IsLiquidContents( cnt ) ( cnt == CONTENTS_WATER || cnt == CONTENTS_SLIME || cnt == CONTENTS_LAVA )
|
||||
|
||||
msurface_t *r_debug_surface;
|
||||
const char *r_debug_hitbox;
|
||||
float gldepthmin, gldepthmax;
|
||||
|
@ -840,65 +842,89 @@ static void R_EndGL( void )
|
|||
R_CheckFog
|
||||
|
||||
check for underwater fog
|
||||
FIXME: this code is wrong, we need to compute fog volumes (as water volumes)
|
||||
and get fog params from texture water on a surface.
|
||||
=============
|
||||
*/
|
||||
static void R_CheckFog( void )
|
||||
{
|
||||
model_t *model;
|
||||
cl_entity_t *ent;
|
||||
gltexture_t *tex;
|
||||
int i, count;
|
||||
int i, cnt, count;
|
||||
|
||||
RI.fogEnabled = false;
|
||||
|
||||
if( RI.refdef.waterlevel < 3 || !RI.drawWorld || !r_viewleaf )
|
||||
if( RI.refdef.waterlevel < 2 || !RI.drawWorld || !r_viewleaf )
|
||||
return;
|
||||
|
||||
model = CL_GetWaterModel( cl.refdef.vieworg );
|
||||
tex = NULL;
|
||||
ent = CL_GetWaterEntity( cl.refdef.vieworg );
|
||||
if( ent && ent->model && ent->model->type == mod_brush && ent->curstate.skin < 0 )
|
||||
cnt = ent->curstate.skin;
|
||||
else cnt = r_viewleaf->contents;
|
||||
|
||||
// check for water texture
|
||||
if( model && model->type == mod_brush )
|
||||
if( IsLiquidContents( RI.cached_contents ) && !IsLiquidContents( cnt ))
|
||||
{
|
||||
msurface_t *surf;
|
||||
|
||||
count = model->nummodelsurfaces;
|
||||
RI.cached_contents = CONTENTS_EMPTY;
|
||||
return;
|
||||
}
|
||||
|
||||
for( i = 0, surf = &model->surfaces[model->firstmodelsurface]; i < count; i++, surf++ )
|
||||
if( RI.refdef.waterlevel < 3 ) return;
|
||||
|
||||
if( !IsLiquidContents( RI.cached_contents ) && IsLiquidContents( cnt ))
|
||||
{
|
||||
tex = NULL;
|
||||
|
||||
// check for water texture
|
||||
if( ent && ent->model && ent->model->type == mod_brush )
|
||||
{
|
||||
if( surf->flags & SURF_DRAWTURB && surf->texinfo && surf->texinfo->texture )
|
||||
msurface_t *surf;
|
||||
|
||||
count = ent->model->nummodelsurfaces;
|
||||
|
||||
for( i = 0, surf = &ent->model->surfaces[ent->model->firstmodelsurface]; i < count; i++, surf++ )
|
||||
{
|
||||
tex = R_GetTexture( surf->texinfo->texture->gl_texturenum );
|
||||
break;
|
||||
if( surf->flags & SURF_DRAWTURB && surf->texinfo && surf->texinfo->texture )
|
||||
{
|
||||
tex = R_GetTexture( surf->texinfo->texture->gl_texturenum );
|
||||
RI.cached_contents = ent->curstate.skin;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
msurface_t **surf;
|
||||
|
||||
count = r_viewleaf->nummarksurfaces;
|
||||
|
||||
for( i = 0, surf = r_viewleaf->firstmarksurface; i < count; i++, surf++ )
|
||||
{
|
||||
if((*surf)->flags & SURF_DRAWTURB && (*surf)->texinfo && (*surf)->texinfo->texture )
|
||||
{
|
||||
tex = R_GetTexture( (*surf)->texinfo->texture->gl_texturenum );
|
||||
RI.cached_contents = r_viewleaf->contents;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( i == count || !tex )
|
||||
return; // no valid fogs
|
||||
|
||||
// copy fog params
|
||||
RI.fogColor[0] = tex->fogParams[0] / 255.0f;
|
||||
RI.fogColor[1] = tex->fogParams[1] / 255.0f;
|
||||
RI.fogColor[2] = tex->fogParams[2] / 255.0f;
|
||||
RI.fogDensity = tex->fogParams[3] * 0.000025f;
|
||||
RI.fogStart = RI.fogEnd = 0.0f;
|
||||
RI.fogCustom = false;
|
||||
RI.fogEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
msurface_t **surf;
|
||||
|
||||
count = r_viewleaf->nummarksurfaces;
|
||||
|
||||
for( i = 0, surf = r_viewleaf->firstmarksurface; i < count; i++, surf++ )
|
||||
{
|
||||
if((*surf)->flags & SURF_DRAWTURB && (*surf)->texinfo && (*surf)->texinfo->texture )
|
||||
{
|
||||
tex = R_GetTexture( (*surf)->texinfo->texture->gl_texturenum );
|
||||
break;
|
||||
}
|
||||
}
|
||||
RI.fogCustom = false;
|
||||
RI.fogEnabled = true;
|
||||
}
|
||||
|
||||
if( i == count || !tex )
|
||||
return; // no valid fogs
|
||||
|
||||
// copy fog params
|
||||
RI.fogColor[0] = tex->fogParams[0] / 255.0f;
|
||||
RI.fogColor[1] = tex->fogParams[1] / 255.0f;
|
||||
RI.fogColor[2] = tex->fogParams[2] / 255.0f;
|
||||
RI.fogDensity = tex->fogParams[3] * 0.000025f;
|
||||
RI.fogStart = RI.fogEnd = 0.0f;
|
||||
RI.fogCustom = false;
|
||||
RI.fogEnabled = true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -264,6 +264,7 @@ void R_ParseDetailTextures( const char *filename )
|
|||
|
||||
void R_NewMap( void )
|
||||
{
|
||||
texture_t *tx;
|
||||
int i;
|
||||
|
||||
R_ClearDecals(); // clear all level decals
|
||||
|
@ -284,10 +285,12 @@ void R_NewMap( void )
|
|||
if( !cl.worldmodel->textures[i] )
|
||||
continue;
|
||||
|
||||
if( world.version == Q1BSP_VERSION && !Q_strncmp( cl.worldmodel->textures[i]->name, "sky", 3 ))
|
||||
tx = cl.worldmodel->textures[i];
|
||||
|
||||
if( !Q_strncmp( tx->name, "sky", 3 ) && tx->width == 256 && tx->height == 128)
|
||||
tr.skytexturenum = i;
|
||||
|
||||
cl.worldmodel->textures[i]->texturechain = NULL;
|
||||
tx->texturechain = NULL;
|
||||
}
|
||||
|
||||
// upload detailtextures
|
||||
|
|
|
@ -1602,4 +1602,75 @@ void CL_Implosion( const vec3_t end, float radius, int count, float life )
|
|||
// die right when you get there
|
||||
p->die += ( life != 0.0f ) ? life : ( radius / vel );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CL_ReadPointFile_f
|
||||
|
||||
===============
|
||||
*/
|
||||
void CL_ReadPointFile_f( void )
|
||||
{
|
||||
char *afile, *pfile;
|
||||
vec3_t org;
|
||||
int count;
|
||||
particle_t *p;
|
||||
char filename[64];
|
||||
string token;
|
||||
|
||||
Q_snprintf( filename, sizeof( filename ), "maps/%s.pts", clgame.mapname );
|
||||
afile = FS_LoadFile( filename, NULL, false );
|
||||
|
||||
if( !afile )
|
||||
{
|
||||
MsgDev( D_ERROR, "couldn't open %s\n", filename );
|
||||
return;
|
||||
}
|
||||
|
||||
Msg( "Reading %s...\n", filename );
|
||||
|
||||
count = 0;
|
||||
pfile = afile;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
if( !pfile ) break;
|
||||
org[0] = Q_atof( token );
|
||||
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
if( !pfile ) break;
|
||||
org[1] = Q_atof( token );
|
||||
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
if( !pfile ) break;
|
||||
org[2] = Q_atof( token );
|
||||
|
||||
count++;
|
||||
|
||||
if( !cl_free_particles )
|
||||
{
|
||||
MsgDev( D_ERROR, "CL_ReadPointFile: not enough free particles!\n" );
|
||||
break;
|
||||
}
|
||||
|
||||
// NOTE: can't use CL_AllocateParticles because running from the console
|
||||
p = cl_free_particles;
|
||||
cl_free_particles = p->next;
|
||||
p->next = cl_active_particles;
|
||||
cl_active_particles = p;
|
||||
|
||||
p->ramp = 0;
|
||||
p->die = 99999;
|
||||
p->color = (-count) & 15;
|
||||
p->type = pt_static;
|
||||
VectorClear( p->vel );
|
||||
VectorCopy( org, p->org );
|
||||
}
|
||||
|
||||
Mem_Free( afile );
|
||||
|
||||
if( count ) Msg( "%i points read\n", count );
|
||||
else Msg( "map %s has no leaks!\n", clgame.mapname );
|
||||
}
|
|
@ -357,7 +357,7 @@ texture_t *R_TextureAnimation( texture_t *base, int surfacenum )
|
|||
return base;
|
||||
|
||||
// GoldSrc and Quake1 has different animating speed
|
||||
if( world.version == Q1BSP_VERSION )
|
||||
if( world.sky_sphere || world.version == Q1BSP_VERSION )
|
||||
speed = 10;
|
||||
else speed = 20;
|
||||
|
||||
|
@ -733,6 +733,8 @@ void R_BlendLightmaps( void )
|
|||
switch( RI.currententity->curstate.rendermode )
|
||||
{
|
||||
case kRenderTransTexture:
|
||||
if( r_lighting_extended->integer == 2 )
|
||||
break;
|
||||
case kRenderTransColor:
|
||||
case kRenderTransAdd:
|
||||
case kRenderGlow:
|
||||
|
@ -746,8 +748,14 @@ void R_BlendLightmaps( void )
|
|||
if( !r_lightmap->integer )
|
||||
{
|
||||
pglEnable( GL_BLEND );
|
||||
pglDepthMask( GL_FALSE );
|
||||
pglDepthFunc( GL_EQUAL );
|
||||
|
||||
if( !glState.drawTrans )
|
||||
{
|
||||
// lightmapped solid surfaces
|
||||
pglDepthMask( GL_FALSE );
|
||||
pglDepthFunc( GL_EQUAL );
|
||||
}
|
||||
|
||||
pglDisable( GL_ALPHA_TEST );
|
||||
pglBlendFunc( GL_ZERO, GL_SRC_COLOR );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||
|
@ -849,8 +857,14 @@ void R_BlendLightmaps( void )
|
|||
if( !r_lightmap->integer )
|
||||
{
|
||||
pglDisable( GL_BLEND );
|
||||
pglDepthMask( GL_TRUE );
|
||||
pglDepthFunc( GL_LEQUAL );
|
||||
|
||||
if( !glState.drawTrans )
|
||||
{
|
||||
// restore depth state
|
||||
pglDepthMask( GL_TRUE );
|
||||
pglDepthFunc( GL_LEQUAL );
|
||||
}
|
||||
|
||||
pglDisable( GL_ALPHA_TEST );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
|
||||
}
|
||||
|
@ -960,7 +974,7 @@ void R_RenderBrushPoly( msurface_t *fa )
|
|||
|
||||
if( fa->flags & SURF_DRAWSKY )
|
||||
{
|
||||
if( world.version == Q1BSP_VERSION )
|
||||
if( world.sky_sphere )
|
||||
{
|
||||
// warp texture, no lightmaps
|
||||
EmitSkyLayers( fa );
|
||||
|
@ -1086,11 +1100,14 @@ void R_DrawTextureChains( void )
|
|||
|
||||
if( i == tr.skytexturenum )
|
||||
{
|
||||
if( world.version == Q1BSP_VERSION )
|
||||
if( world.sky_sphere )
|
||||
R_DrawSkyChain( s );
|
||||
}
|
||||
else
|
||||
{
|
||||
if(( s->flags & SURF_DRAWTURB ) && RI.refdef.movevars->wateralpha < 1.0f )
|
||||
continue; // draw translucent water later
|
||||
|
||||
for( ; s != NULL; s = s->texturechain )
|
||||
R_RenderBrushPoly( s );
|
||||
}
|
||||
|
@ -1113,7 +1130,7 @@ void R_DrawWaterSurfaces( void )
|
|||
return;
|
||||
|
||||
// non-transparent water is already drawed
|
||||
if( r_wateralpha->value >= 1.0f )
|
||||
if( RI.refdef.movevars->wateralpha >= 1.0f )
|
||||
return;
|
||||
|
||||
// go back to the world matrix
|
||||
|
@ -1125,7 +1142,7 @@ void R_DrawWaterSurfaces( void )
|
|||
pglDisable( GL_ALPHA_TEST );
|
||||
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||
pglColor4f( 1.0f, 1.0f, 1.0f, r_wateralpha->value );
|
||||
pglColor4f( 1.0f, 1.0f, 1.0f, RI.refdef.movevars->wateralpha );
|
||||
|
||||
for( i = 0; i < cl.worldmodel->numtextures; i++ )
|
||||
{
|
||||
|
@ -1684,7 +1701,7 @@ void R_RecursiveWorldNode( mnode_t *node, uint clipflags )
|
|||
if( R_CullSurface( surf, clipflags ))
|
||||
continue;
|
||||
|
||||
if( surf->flags & SURF_DRAWSKY && world.version == HLBSP_VERSION )
|
||||
if( surf->flags & SURF_DRAWSKY && !world.sky_sphere )
|
||||
{
|
||||
// make sky chain to right clip the skybox
|
||||
surf->texturechain = skychain;
|
||||
|
@ -1958,41 +1975,50 @@ void R_MarkLeaves( void )
|
|||
int i;
|
||||
|
||||
if( !RI.drawWorld ) return;
|
||||
|
||||
if( r_novis->modified )
|
||||
{
|
||||
// force recalc viewleaf
|
||||
r_novis->modified = false;
|
||||
r_viewleaf = NULL;
|
||||
}
|
||||
|
||||
if( r_viewleaf == r_oldviewleaf && r_viewleaf2 == r_oldviewleaf2 && !r_novis->integer && r_viewleaf != NULL )
|
||||
return;
|
||||
|
||||
// development aid to let you run around
|
||||
// and see exactly where the pvs ends
|
||||
if( r_lockpvs->integer )
|
||||
return;
|
||||
if( r_lockpvs->integer ) return;
|
||||
|
||||
tr.visframecount++;
|
||||
r_oldviewleaf = r_viewleaf;
|
||||
r_oldviewleaf2 = r_viewleaf2;
|
||||
|
||||
|
||||
if( r_novis->integer || RI.drawOrtho || !r_viewleaf || !cl.worldmodel->visdata )
|
||||
{
|
||||
// force to get full visibility
|
||||
vis = Mod_LeafPVS( NULL, NULL );
|
||||
// mark everything
|
||||
for( i = 0; i < cl.worldmodel->numleafs; i++ )
|
||||
cl.worldmodel->leafs[i+1].visframe = tr.visframecount;
|
||||
for( i = 0; i < cl.worldmodel->numnodes; i++ )
|
||||
cl.worldmodel->nodes[i].visframe = tr.visframecount;
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
// may have to combine two clusters
|
||||
// because of solid water boundaries
|
||||
vis = Mod_LeafPVS( r_viewleaf, cl.worldmodel );
|
||||
|
||||
if( r_viewleaf != r_viewleaf2 )
|
||||
{
|
||||
// may have to combine two clusters
|
||||
// because of solid water boundaries
|
||||
vis = Mod_LeafPVS( r_viewleaf, cl.worldmodel );
|
||||
int longs = ( cl.worldmodel->numleafs + 31 ) >> 5;
|
||||
|
||||
if( r_viewleaf != r_viewleaf2 )
|
||||
{
|
||||
int longs = ( cl.worldmodel->numleafs + 31 ) >> 5;
|
||||
Q_memcpy( visbytes, vis, longs << 2 );
|
||||
vis = Mod_LeafPVS( r_viewleaf2, cl.worldmodel );
|
||||
|
||||
Q_memcpy( visbytes, vis, longs << 2 );
|
||||
vis = Mod_LeafPVS( r_viewleaf2, cl.worldmodel );
|
||||
for( i = 0; i < longs; i++ )
|
||||
((int *)visbytes)[i] |= ((int *)vis)[i];
|
||||
|
||||
for( i = 0; i < longs; i++ )
|
||||
((int *)visbytes)[i] |= ((int *)vis)[i];
|
||||
|
||||
vis = visbytes;
|
||||
}
|
||||
vis = visbytes;
|
||||
}
|
||||
|
||||
for( i = 0; i < cl.worldmodel->numleafs; i++ )
|
||||
|
@ -2098,14 +2124,20 @@ void GL_BuildLightmaps( void )
|
|||
|
||||
GL_CreateSurfaceLightmap( m->surfaces + j );
|
||||
|
||||
if( m->surfaces[i].flags & SURF_DRAWTURB )
|
||||
if( m->surfaces[j].flags & SURF_DRAWTURB )
|
||||
continue;
|
||||
|
||||
if( m->surfaces[i].flags & SURF_DRAWSKY && world.version == Q1BSP_VERSION )
|
||||
if( m->surfaces[j].flags & SURF_DRAWSKY && world.sky_sphere )
|
||||
continue;
|
||||
|
||||
GL_BuildPolygonFromSurface( m->surfaces + j );
|
||||
}
|
||||
|
||||
// clearing visframe
|
||||
for( j = 0; j < m->numleafs; j++ )
|
||||
m->leafs[j+1].visframe = 0;
|
||||
for( j = 0; j < m->numnodes; j++ )
|
||||
m->nodes[j].visframe = 0;
|
||||
}
|
||||
|
||||
loadmodel = NULL;
|
||||
|
|
|
@ -830,7 +830,7 @@ static _inline qboolean R_SpriteHasLightmap( cl_entity_t *e, int texFormat )
|
|||
if( e->curstate.effects & EF_FULLBRIGHT )
|
||||
return false;
|
||||
|
||||
if( e->curstate.renderamt != 255 )
|
||||
if( e->curstate.renderamt <= 127 )
|
||||
return false;
|
||||
|
||||
switch( e->curstate.rendermode )
|
||||
|
@ -856,10 +856,10 @@ void R_DrawSpriteModel( cl_entity_t *e )
|
|||
mspriteframe_t *frame, *oldframe;
|
||||
msprite_t *psprite;
|
||||
model_t *model;
|
||||
int i, alpha;
|
||||
int i, alpha, type;
|
||||
float angle, dot, sr, cr, flAlpha;
|
||||
float lerp = 1.0f, ilerp, scale;
|
||||
vec3_t v_forward, v_right, v_up;
|
||||
vec3_t v_forward, v_right, v_up, tmp;
|
||||
vec3_t origin, color, color2;
|
||||
|
||||
if( RI.params & RP_ENVVIEW )
|
||||
|
@ -959,16 +959,27 @@ void R_DrawSpriteModel( cl_entity_t *e )
|
|||
frame = oldframe = R_GetSpriteFrame( model, e->curstate.frame, e->angles[YAW] );
|
||||
else lerp = R_GetSpriteFrameInterpolant( e, &oldframe, &frame );
|
||||
|
||||
switch( psprite->type )
|
||||
type = psprite->type;
|
||||
|
||||
// automatically roll parallel sprites if requested
|
||||
if( e->angles[ROLL] != 0.0f && type == SPR_FWD_PARALLEL )
|
||||
type = SPR_FWD_PARALLEL_ORIENTED;
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case SPR_ORIENTED:
|
||||
AngleVectors( e->angles, v_forward, v_right, v_up );
|
||||
VectorScale( v_forward, 0.01f, v_forward ); // to avoid z-fighting
|
||||
VectorScale( v_forward, 0.01f, v_forward ); // to avoid z-fighting
|
||||
VectorSubtract( origin, v_forward, origin );
|
||||
break;
|
||||
case SPR_FACING_UPRIGHT:
|
||||
VectorSet( v_right, origin[1] - RI.vieworg[1], -(origin[0] - RI.vieworg[0]), 0.0f );
|
||||
VectorSet( v_up, 0.0f, 0.0f, 1.0f );
|
||||
VectorNegate( e->origin, tmp );
|
||||
VectorNormalize( tmp );
|
||||
dot = tmp[2];
|
||||
if(( dot > 0.999848 ) || ( dot < -0.999848 )) // cos(1 degree) = 0.999848
|
||||
return; // invisible
|
||||
VectorSet( v_up, 0.0f, 0.0f, 1.0f );
|
||||
VectorSet( v_right, tmp[1], -tmp[0], 0.0f );
|
||||
VectorNormalize( v_right );
|
||||
break;
|
||||
case SPR_FWD_PARALLEL_UPRIGHT:
|
||||
|
@ -989,19 +1000,9 @@ void R_DrawSpriteModel( cl_entity_t *e )
|
|||
}
|
||||
break;
|
||||
case SPR_FWD_PARALLEL: // normal sprite
|
||||
default: // gold src support rotating sprites
|
||||
angle = e->angles[ROLL];
|
||||
|
||||
if( angle != 0.0f )
|
||||
{
|
||||
RotatePointAroundVector( v_up, RI.vforward, RI.vright, angle-90.0f ); // make up
|
||||
CrossProduct( RI.vforward, v_up, v_right ); // make right
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy( RI.vright, v_right );
|
||||
VectorCopy( RI.vup, v_up );
|
||||
}
|
||||
default:
|
||||
VectorCopy( RI.vright, v_right );
|
||||
VectorCopy( RI.vup, v_up );
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -3108,7 +3108,8 @@ static void R_StudioLoadTexture( model_t *mod, studiohdr_t *phdr, mstudiotexture
|
|||
{
|
||||
size_t size;
|
||||
int flags = 0;
|
||||
char texname[128], name[128];
|
||||
qboolean load_external = false;
|
||||
char texname[128], name[128], mdlname[128];
|
||||
texture_t *tx = NULL;
|
||||
|
||||
if( ptexture->flags & STUDIO_NF_TRANSPARENT )
|
||||
|
@ -3165,15 +3166,38 @@ static void R_StudioLoadTexture( model_t *mod, studiohdr_t *phdr, mstudiotexture
|
|||
mod->numtextures++; // done
|
||||
}
|
||||
|
||||
// NOTE: replace index with pointer to start of imagebuffer, ImageLib expected it
|
||||
ptexture->index = (int)((byte *)phdr) + ptexture->index;
|
||||
size = sizeof( mstudiotexture_t ) + ptexture->width * ptexture->height + 768;
|
||||
Q_strncpy( mdlname, mod->name, sizeof( mdlname ));
|
||||
FS_FileBase( ptexture->name, name );
|
||||
FS_StripExtension( mdlname );
|
||||
|
||||
// build the texname
|
||||
Q_snprintf( texname, sizeof( texname ), "#%s/%s.mdl", mod->name, name );
|
||||
ptexture->index = GL_LoadTexture( texname, (byte *)ptexture, size, flags );
|
||||
// NOTE: colormaps must have the palette for properly work. Ignore it.
|
||||
if( host_allow_materials->integer && !( ptexture->flags & STUDIO_NF_COLORMAP ))
|
||||
{
|
||||
int gl_texturenum = 0;
|
||||
|
||||
Q_snprintf( texname, sizeof( texname ), "materials/%s/%s.tga", mdlname, name );
|
||||
|
||||
if( FS_FileExists( texname, false ))
|
||||
gl_texturenum = GL_LoadTexture( texname, NULL, 0, flags );
|
||||
|
||||
if( gl_texturenum )
|
||||
{
|
||||
ptexture->index = gl_texturenum;
|
||||
load_external = true; // sucessfully loaded
|
||||
}
|
||||
}
|
||||
|
||||
if( !load_external )
|
||||
{
|
||||
// NOTE: replace index with pointer to start of imagebuffer, ImageLib expected it
|
||||
ptexture->index = (int)((byte *)phdr) + ptexture->index;
|
||||
size = sizeof( mstudiotexture_t ) + ptexture->width * ptexture->height + 768;
|
||||
|
||||
// build the texname
|
||||
Q_snprintf( texname, sizeof( texname ), "#%s/%s.mdl", mdlname, name );
|
||||
ptexture->index = GL_LoadTexture( texname, (byte *)ptexture, size, flags );
|
||||
}
|
||||
|
||||
if( !ptexture->index )
|
||||
{
|
||||
MsgDev( D_WARN, "%s has null texture %s\n", mod->name, ptexture->name );
|
||||
|
|
|
@ -73,7 +73,6 @@ convar_t *r_novis;
|
|||
convar_t *r_nocull;
|
||||
convar_t *r_lockpvs;
|
||||
convar_t *r_lockcull;
|
||||
convar_t *r_wateralpha;
|
||||
convar_t *r_dynamic;
|
||||
convar_t *r_lightmap;
|
||||
convar_t *r_fastsky;
|
||||
|
@ -1254,6 +1253,13 @@ check vid modes and fullscreen
|
|||
*/
|
||||
void VID_CheckChanges( void )
|
||||
{
|
||||
if( cl_allow_levelshots->modified )
|
||||
{
|
||||
GL_FreeTexture( cls.loadingBar );
|
||||
SCR_RegisterShaders(); // reload 'lambda' image
|
||||
cl_allow_levelshots->modified = false;
|
||||
}
|
||||
|
||||
if( renderinfo->modified )
|
||||
{
|
||||
if( !VID_SetMode())
|
||||
|
@ -1424,7 +1430,6 @@ void GL_InitCommands( void )
|
|||
r_detailtextures = Cvar_Get( "r_detailtextures", "1", CVAR_ARCHIVE, "enable detail textures support, use \"2\" for auto-generate mapname_detail.txt" );
|
||||
r_lockpvs = Cvar_Get( "r_lockpvs", "0", CVAR_CHEAT, "lockpvs area at current point (pvs test)" );
|
||||
r_lockcull = Cvar_Get( "r_lockcull", "0", CVAR_CHEAT, "lock frustrum area at current point (cull test)" );
|
||||
r_wateralpha = Cvar_Get( "r_wateralpha", "1", CVAR_ARCHIVE, "world water transparency factor" );
|
||||
r_dynamic = Cvar_Get( "r_dynamic", "1", CVAR_ARCHIVE, "allow dynamic lighting (dlights, lightstyles)" );
|
||||
r_lightmap = Cvar_Get( "r_lightmap", "0", CVAR_CHEAT, "lightmap debugging tool" );
|
||||
r_fastsky = Cvar_Get( "r_fastsky", "0", CVAR_ARCHIVE, "enable algorhytm fo fast sky rendering (for old machines)" );
|
||||
|
|
|
@ -121,17 +121,32 @@ S_LoadSound
|
|||
*/
|
||||
wavdata_t *S_LoadSound( sfx_t *sfx )
|
||||
{
|
||||
wavdata_t *sc;
|
||||
wavdata_t *sc = NULL;
|
||||
|
||||
if( !sfx ) return NULL;
|
||||
if( sfx->cache ) return sfx->cache; // see if still in memory
|
||||
|
||||
// load it from disk
|
||||
if( sfx->name[0] == '*' )
|
||||
sc = FS_LoadSound( sfx->name + 1, NULL, 0 );
|
||||
else sc = FS_LoadSound( sfx->name, NULL, 0 );
|
||||
if( Q_stricmp( sfx->name, "*default" ))
|
||||
{
|
||||
// load it from disk
|
||||
if( sfx->name[0] == '*' )
|
||||
sc = FS_LoadSound( sfx->name + 1, NULL, 0 );
|
||||
else sc = FS_LoadSound( sfx->name, NULL, 0 );
|
||||
}
|
||||
|
||||
if( !sc ) sc = S_CreateDefaultSound();
|
||||
|
||||
if( sc->rate < SOUND_11k ) // some bad sounds
|
||||
Sound_Process( &sc, SOUND_11k, sc->width, SOUND_RESAMPLE );
|
||||
#if SOUND_DMA_SPEED > SOUND_11k
|
||||
else if( sc->rate > SOUND_11k && sc->rate < SOUND_22k ) // some bad sounds
|
||||
Sound_Process( &sc, SOUND_22k, sc->width, SOUND_RESAMPLE );
|
||||
#endif
|
||||
|
||||
#if SOUND_DMA_SPEED > SOUND_32k
|
||||
else if( sc->rate > SOUND_22k && sc->rate <= SOUND_32k ) // some bad sounds
|
||||
Sound_Process( &sc, SOUND_44k, sc->width, SOUND_RESAMPLE );
|
||||
#endif
|
||||
sfx->cache = sc;
|
||||
|
||||
return sfx->cache;
|
||||
|
@ -247,8 +262,27 @@ S_BeginRegistration
|
|||
*/
|
||||
void S_BeginRegistration( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
s_registration_sequence++;
|
||||
s_registering = true;
|
||||
|
||||
// create unused 0-entry
|
||||
S_RegisterSound( "*default" );
|
||||
|
||||
snd_ambient = false;
|
||||
|
||||
// check for automatic ambient sounds
|
||||
for( i = 0; i < NUM_AMBIENTS; i++ )
|
||||
{
|
||||
if( !GI->ambientsound[i][0] )
|
||||
continue; // empty slot
|
||||
|
||||
if( !ambient_sfx[i] )
|
||||
MsgDev( D_NOTE, "Loading ambient[%i]: ^2%s^7\n", i, GI->ambientsound[i] );
|
||||
ambient_sfx[i] = S_RegisterSound( GI->ambientsound[i] );
|
||||
if( ambient_sfx[i] ) snd_ambient = true; // allow auto-ambients
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -26,18 +26,23 @@ dma_t dma;
|
|||
byte *sndpool;
|
||||
static soundfade_t soundfade;
|
||||
channel_t channels[MAX_CHANNELS];
|
||||
sound_t ambient_sfx[NUM_AMBIENTS];
|
||||
qboolean snd_ambient = false;
|
||||
listener_t s_listener;
|
||||
int total_channels;
|
||||
int soundtime; // sample PAIRS
|
||||
int paintedtime; // sample PAIRS
|
||||
|
||||
convar_t *s_check_errors;
|
||||
convar_t *s_volume;
|
||||
convar_t *s_musicvolume;
|
||||
convar_t *s_show;
|
||||
convar_t *s_mixahead;
|
||||
convar_t *s_primary;
|
||||
convar_t *s_lerping;
|
||||
convar_t *s_ambient_level;
|
||||
convar_t *s_ambient_fade;
|
||||
convar_t *s_combine_sounds;
|
||||
convar_t *s_test; // cvar for testing new effects
|
||||
convar_t *dsp_off; // set to 1 to disable all dsp processing
|
||||
|
||||
/*
|
||||
|
@ -176,7 +181,7 @@ channel_t *SND_PickDynamicChannel( int entnum, int channel, sfx_t *sfx )
|
|||
first_to_die = -1;
|
||||
life_left = 0x7fffffff;
|
||||
|
||||
for( ch_idx = 0; ch_idx < MAX_DYNAMIC_CHANNELS; ch_idx++ )
|
||||
for( ch_idx = NUM_AMBIENTS; ch_idx < MAX_DYNAMIC_CHANNELS; ch_idx++ )
|
||||
{
|
||||
channel_t *ch = &channels[ch_idx];
|
||||
|
||||
|
@ -315,7 +320,7 @@ int S_AlterChannel( int entnum, int channel, sfx_t *sfx, int vol, int pitch, int
|
|||
// at a time, so we can just shut off
|
||||
// any channel that has ch->isSentence >= 0 and matches the entnum.
|
||||
|
||||
for( i = 0, ch = channels; i < total_channels; i++, ch++ )
|
||||
for( i = NUM_AMBIENTS, ch = channels + NUM_AMBIENTS; i < total_channels; i++, ch++ )
|
||||
{
|
||||
if( ch->entnum == entnum && ch->entchannel == channel && ch->sfx && ch->isSentence )
|
||||
{
|
||||
|
@ -337,7 +342,7 @@ int S_AlterChannel( int entnum, int channel, sfx_t *sfx, int vol, int pitch, int
|
|||
}
|
||||
|
||||
// regular sound or streaming sound
|
||||
for( i = 0, ch = channels; i < total_channels; i++, ch++ )
|
||||
for( i = NUM_AMBIENTS, ch = channels + NUM_AMBIENTS; i < total_channels; i++, ch++ )
|
||||
{
|
||||
if( ch->entnum == entnum && ch->entchannel == channel && ch->sfx == sfx )
|
||||
{
|
||||
|
@ -428,13 +433,12 @@ void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fv
|
|||
channel_t *target_chan, *check;
|
||||
int vol, ch_idx;
|
||||
|
||||
if( pitch <= 1 ) pitch = PITCH_NORM; // Invasion issues
|
||||
|
||||
if( !dma.initialized ) return;
|
||||
sfx = S_GetSfxByHandle( handle );
|
||||
if( !sfx ) return;
|
||||
|
||||
vol = bound( 0, fvol * 255, 255 );
|
||||
if( pitch <= 1 ) pitch = PITCH_NORM; // Invasion issues
|
||||
|
||||
if( flags & ( SND_STOP|SND_CHANGE_VOL|SND_CHANGE_PITCH ))
|
||||
{
|
||||
|
@ -527,7 +531,7 @@ void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fv
|
|||
// Init client entity mouth movement vars
|
||||
SND_InitMouth( ent, chan );
|
||||
|
||||
for( ch_idx = 0, check = channels; ch_idx < MAX_DYNAMIC_CHANNELS; ch_idx++, check++ )
|
||||
for( ch_idx = NUM_AMBIENTS, check = channels + NUM_AMBIENTS; ch_idx < MAX_DYNAMIC_CHANNELS; ch_idx++, check++)
|
||||
{
|
||||
if( check == target_chan ) continue;
|
||||
|
||||
|
@ -570,6 +574,7 @@ void S_AmbientSound( const vec3_t pos, int ent, sound_t handle, float fvol, floa
|
|||
if( !sfx ) return;
|
||||
|
||||
vol = bound( 0, fvol * 255, 255 );
|
||||
if( pitch <= 1 ) pitch = PITCH_NORM; // Invasion issues
|
||||
|
||||
if( flags & (SND_STOP|SND_CHANGE_VOL|SND_CHANGE_PITCH))
|
||||
{
|
||||
|
@ -684,6 +689,79 @@ int S_GetCurrentStaticSounds( soundlist_t *pout, int size )
|
|||
return ( size - sounds_left );
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
S_InitAmbientChannels
|
||||
===================
|
||||
*/
|
||||
void S_InitAmbientChannels( void )
|
||||
{
|
||||
int ambient_channel;
|
||||
channel_t *chan;
|
||||
|
||||
for( ambient_channel = 0; ambient_channel < NUM_AMBIENTS; ambient_channel++ )
|
||||
{
|
||||
chan = &channels[ambient_channel];
|
||||
|
||||
chan->staticsound = true;
|
||||
chan->use_loop = true;
|
||||
chan->dist_mult = (ATTN_NONE / SND_CLIP_DISTANCE);
|
||||
chan->basePitch = PITCH_NORM;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
S_UpdateAmbientSounds
|
||||
===================
|
||||
*/
|
||||
void S_UpdateAmbientSounds( void )
|
||||
{
|
||||
mleaf_t *leaf;
|
||||
float vol;
|
||||
int ambient_channel;
|
||||
channel_t *chan;
|
||||
|
||||
if( !snd_ambient ) return;
|
||||
|
||||
// calc ambient sound levels
|
||||
if( !cl.worldmodel ) return;
|
||||
|
||||
leaf = Mod_PointInLeaf( s_listener.origin, cl.worldmodel->nodes );
|
||||
|
||||
if( !leaf || !s_ambient_level->value )
|
||||
{
|
||||
for( ambient_channel = 0; ambient_channel < NUM_AMBIENTS; ambient_channel++ )
|
||||
channels[ambient_channel].sfx = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
for( ambient_channel = 0; ambient_channel < NUM_AMBIENTS; ambient_channel++ )
|
||||
{
|
||||
chan = &channels[ambient_channel];
|
||||
chan->sfx = S_GetSfxByHandle( ambient_sfx[ambient_channel] );
|
||||
|
||||
if( !chan->sfx ) continue;
|
||||
|
||||
vol = s_ambient_level->value * leaf->ambient_sound_level[ambient_channel];
|
||||
if( vol < 8 ) vol = 0;
|
||||
|
||||
// don't adjust volume too fast
|
||||
if( chan->master_vol < vol )
|
||||
{
|
||||
chan->master_vol += s_listener.frametime * s_ambient_fade->value;
|
||||
if( chan->master_vol > vol ) chan->master_vol = vol;
|
||||
}
|
||||
else if( chan->master_vol > vol )
|
||||
{
|
||||
chan->master_vol -= s_listener.frametime * s_ambient_fade->value;
|
||||
if( chan->master_vol < vol ) chan->master_vol = vol;
|
||||
}
|
||||
|
||||
chan->leftvol = chan->rightvol = chan->master_vol;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
S_ClearBuffer
|
||||
|
@ -739,6 +817,9 @@ void S_StopAllSounds( void )
|
|||
// clear all the channels
|
||||
Q_memset( channels, 0, sizeof( channels ));
|
||||
|
||||
// restart the ambient sounds
|
||||
S_InitAmbientChannels ();
|
||||
|
||||
S_ClearBuffer ();
|
||||
|
||||
// clear any remaining soundfade
|
||||
|
@ -769,8 +850,8 @@ void S_UpdateChannels( void )
|
|||
|
||||
if(( endtime - paintedtime ) & 0x3 )
|
||||
{
|
||||
// The difference between endtime and painted time should align on
|
||||
// boundaries of 4 samples. This is important when upsampling from 11khz -> 44khz.
|
||||
// the difference between endtime and painted time should align on
|
||||
// boundaries of 4 samples. this is important when upsampling from 11khz -> 44khz.
|
||||
endtime -= ( endtime - paintedtime ) & 0x3;
|
||||
}
|
||||
|
||||
|
@ -801,9 +882,9 @@ Called once each time through the main loop
|
|||
*/
|
||||
void S_RenderFrame( ref_params_t *fd )
|
||||
{
|
||||
int i, total;
|
||||
int i, j, total;
|
||||
con_nprint_t info;
|
||||
channel_t *ch;
|
||||
channel_t *ch, *combine;
|
||||
|
||||
if( !dma.initialized ) return;
|
||||
if( !fd ) return; // too early
|
||||
|
@ -825,11 +906,58 @@ void S_RenderFrame( ref_params_t *fd )
|
|||
VectorCopy( fd->simvel, s_listener.velocity );
|
||||
AngleVectors( fd->viewangles, s_listener.forward, s_listener.right, s_listener.up );
|
||||
|
||||
// update general area ambient sound sources
|
||||
S_UpdateAmbientSounds();
|
||||
|
||||
combine = NULL;
|
||||
|
||||
// update spatialization for static and dynamic sounds
|
||||
for( i = 0, ch = channels; i < total_channels; i++, ch++ )
|
||||
for( i = NUM_AMBIENTS, ch = channels + NUM_AMBIENTS; i < total_channels; i++, ch++ )
|
||||
{
|
||||
if( !ch->sfx ) continue;
|
||||
SND_Spatialize( ch ); // respatialize channel
|
||||
|
||||
if( !ch->leftvol && !ch->rightvol )
|
||||
continue;
|
||||
|
||||
// try to combine static sounds with a previous channel of the same
|
||||
// sound effect so we don't mix five torches every frame
|
||||
// g-cont: perfomance option, probably kill stereo effect in most cases
|
||||
if( i >= MAX_DYNAMIC_CHANNELS && s_combine_sounds->integer )
|
||||
{
|
||||
// see if it can just use the last one
|
||||
if( combine && combine->sfx == ch->sfx )
|
||||
{
|
||||
combine->leftvol += ch->leftvol;
|
||||
combine->rightvol += ch->rightvol;
|
||||
ch->leftvol = ch->rightvol = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// search for one
|
||||
combine = channels + MAX_DYNAMIC_CHANNELS;
|
||||
|
||||
for( j = MAX_DYNAMIC_CHANNELS; j < i; j++, combine++ )
|
||||
{
|
||||
if( combine->sfx == ch->sfx )
|
||||
break;
|
||||
}
|
||||
|
||||
if( j == total_channels )
|
||||
{
|
||||
combine = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( combine != ch )
|
||||
{
|
||||
combine->leftvol += ch->leftvol;
|
||||
combine->rightvol += ch->rightvol;
|
||||
ch->leftvol = ch->rightvol = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// debugging output
|
||||
|
@ -845,7 +973,8 @@ void S_RenderFrame( ref_params_t *fd )
|
|||
if( ch->sfx && ( ch->leftvol || ch->rightvol ))
|
||||
{
|
||||
info.index = total;
|
||||
Con_NXPrintf( &info, "%3i %3i %s\n", ch->leftvol, ch->rightvol, ch->sfx->name );
|
||||
Con_NXPrintf( &info, "chan %i, lv%3i rv%3i %s\n",
|
||||
i, ch->leftvol, ch->rightvol, ch->sfx->name );
|
||||
total++;
|
||||
}
|
||||
}
|
||||
|
@ -870,9 +999,10 @@ void S_Play_f( void )
|
|||
{
|
||||
if( Cmd_Argc() == 1 )
|
||||
{
|
||||
Msg( "Usage: playsound <soundfile>\n" );
|
||||
Msg( "Usage: play <soundfile>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
S_StartLocalSound( Cmd_Argv( 1 ));
|
||||
}
|
||||
|
||||
|
@ -969,9 +1099,12 @@ qboolean S_Init( void )
|
|||
s_musicvolume = Cvar_Get( "musicvolume", "1.0", CVAR_ARCHIVE, "background music volume" );
|
||||
s_mixahead = Cvar_Get( "_snd_mixahead", "0.1", CVAR_ARCHIVE, "how much sound to mix ahead of time" );
|
||||
s_show = Cvar_Get( "s_show", "0", CVAR_ARCHIVE, "show playing sounds" );
|
||||
s_check_errors = Cvar_Get( "s_check_errors", "1", CVAR_ARCHIVE, "ignore audio engine errors" );
|
||||
s_lerping = Cvar_Get( "s_lerping", "0", CVAR_ARCHIVE, "apply interpolation to sound output" );
|
||||
dsp_off = Cvar_Get( "dsp_off", "0", CVAR_ARCHIVE, "set to 1 to disable all dsp processing" );
|
||||
s_ambient_level = Cvar_Get( "ambient_level", "0.3", 0, "volume of environment noises (water and wind)" );
|
||||
s_ambient_fade = Cvar_Get( "ambient_fade", "100", 0, "rate of volume fading when client is moving" );
|
||||
s_combine_sounds = Cvar_Get( "s_combine", "0", CVAR_ARCHIVE, "combine the channels with same sounds" );
|
||||
s_test = Cvar_Get( "s_test", "0", 0, "engine developer cvar for quick testing new features" );
|
||||
|
||||
Cmd_AddCommand( "play", S_Play_f, "playing a specified sound file" );
|
||||
Cmd_AddCommand( "stopsound", S_StopSound_f, "stop all sounds" );
|
||||
|
@ -989,6 +1122,9 @@ qboolean S_Init( void )
|
|||
soundtime = 0;
|
||||
paintedtime = 0;
|
||||
|
||||
// clear ambient sounds
|
||||
Q_memset( ambient_sfx, 0, sizeof( ambient_sfx ));
|
||||
|
||||
MIX_InitAllPaintbuffers ();
|
||||
|
||||
S_InitScaletable ();
|
||||
|
|
|
@ -601,7 +601,6 @@ void MIX_MixChannelsToPaintbuffer( int endtime, int rate, int outputRate )
|
|||
{
|
||||
case SOUND_11k:
|
||||
case SOUND_22k:
|
||||
case SOUND_32k:
|
||||
case SOUND_44k:
|
||||
if( rate != pSource->rate )
|
||||
continue;
|
||||
|
@ -1005,11 +1004,6 @@ void MIX_UpsampleAllPaintbuffers( int end, int count )
|
|||
MIX_SetCurrentPaintbuffer( IROOMBUFFER );
|
||||
S_MixUpsample( count / ( SOUND_DMA_SPEED / SOUND_22k ), FILTERTYPE_LINEAR );
|
||||
#endif
|
||||
|
||||
#if (SOUND_DMA_SPEED >= SOUND_32k)
|
||||
// mix 32khz sounds:
|
||||
MIX_MixChannelsToPaintbuffer( end, SOUND_32k, SOUND_DMA_SPEED );
|
||||
#endif
|
||||
// mix all 44khz sounds to all active paintbuffers
|
||||
MIX_MixChannelsToPaintbuffer( end, SOUND_44k, SOUND_DMA_SPEED );
|
||||
|
||||
|
|
|
@ -114,7 +114,6 @@ char *VOX_LookupString( const char *pSentenceName, int *psentencenum )
|
|||
return (g_Sentences[i].pName + Q_strlen( g_Sentences[i].pName ) + 1 );
|
||||
}
|
||||
|
||||
|
||||
for( i = 0; i < g_numSentences; i++ )
|
||||
{
|
||||
if( !Q_stricmp( pSentenceName, g_Sentences[i].pName ))
|
||||
|
|
|
@ -27,6 +27,7 @@ extern byte *sndpool;
|
|||
// sound engine rate defines
|
||||
#define SOUND_DMA_SPEED 44100 // hardware playback rate
|
||||
#define SOUND_11k 11025 // 11khz sample rate
|
||||
#define SOUND_16k 16000 // 16khz sample rate
|
||||
#define SOUND_22k 22050 // 22khz sample rate
|
||||
#define SOUND_32k 32000 // 32khz sample rate
|
||||
#define SOUND_44k 44100 // 44khz sample rate
|
||||
|
@ -135,7 +136,6 @@ typedef struct
|
|||
qboolean use_loop; // don't loop default and local sounds
|
||||
qboolean staticsound; // use origin instead of fetching entnum's origin
|
||||
qboolean localsound; // it's a local menu sound (not looped, not paused)
|
||||
qboolean bdry; // if true, bypass all dsp processing for this sound (ie: music)
|
||||
mixer_t pMixer;
|
||||
|
||||
// sentence mixer
|
||||
|
@ -186,10 +186,12 @@ void SNDDMA_Submit( void );
|
|||
|
||||
//====================================================================
|
||||
|
||||
#define MAX_DYNAMIC_CHANNELS 28
|
||||
#define MAX_DYNAMIC_CHANNELS (28 + NUM_AMBIENTS)
|
||||
#define MAX_CHANNELS 128
|
||||
#define MAX_RAW_SAMPLES 8192
|
||||
|
||||
extern sound_t ambient_sfx[NUM_AMBIENTS];
|
||||
extern qboolean snd_ambient;
|
||||
extern channel_t channels[MAX_CHANNELS];
|
||||
extern int total_channels;
|
||||
extern int paintedtime;
|
||||
|
@ -199,13 +201,13 @@ extern dma_t dma;
|
|||
extern listener_t s_listener;
|
||||
extern int idsp_room;
|
||||
|
||||
extern convar_t *s_check_errors;
|
||||
extern convar_t *s_volume;
|
||||
extern convar_t *s_musicvolume;
|
||||
extern convar_t *s_show;
|
||||
extern convar_t *s_mixahead;
|
||||
extern convar_t *s_lerping;
|
||||
extern convar_t *dsp_off;
|
||||
extern convar_t *s_test;
|
||||
|
||||
extern portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
|
||||
|
||||
|
@ -232,6 +234,7 @@ void MIX_PaintChannels( int endtime );
|
|||
qboolean S_TestSoundChar( const char *pch, char c );
|
||||
char *S_SkipSoundChar( const char *pch );
|
||||
sfx_t *S_FindName( const char *name, int *pfInCache );
|
||||
sound_t S_RegisterSound( const char *name );
|
||||
void S_FreeSound( sfx_t *sfx );
|
||||
|
||||
// s_dsp.c
|
||||
|
|
|
@ -18,6 +18,7 @@ GNU General Public License for more details.
|
|||
#include "const.h"
|
||||
#include "vgui_draw.h"
|
||||
#include "vgui_main.h"
|
||||
#include <tlhelp32.h>
|
||||
|
||||
CEnginePanel *rootpanel = NULL;
|
||||
CEngineSurface *surface = NULL;
|
||||
|
@ -59,6 +60,32 @@ void CEngineApp :: getCursorPos( int &x,int &y )
|
|||
|
||||
void VGui_RunFrame( void )
|
||||
{
|
||||
PROCESSENTRY32 pe32;
|
||||
HANDLE hSnapshot;
|
||||
|
||||
host.force_draw_version = false;
|
||||
|
||||
if(( hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 )) == INVALID_HANDLE_VALUE )
|
||||
return;
|
||||
|
||||
pe32.dwSize = sizeof( PROCESSENTRY32 );
|
||||
|
||||
if( !Process32First( hSnapshot, &pe32 ))
|
||||
{
|
||||
CloseHandle( hSnapshot );
|
||||
return;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if( Q_stristr( pe32.szExeFile, "fraps.exe" ))
|
||||
{
|
||||
host.force_draw_version = true;
|
||||
break;
|
||||
}
|
||||
} while( Process32Next( hSnapshot, &pe32 ));
|
||||
|
||||
CloseHandle( hSnapshot );
|
||||
}
|
||||
|
||||
void VGui_Startup( void )
|
||||
|
|
|
@ -124,6 +124,7 @@ extern convar_t *scr_height;
|
|||
extern convar_t *scr_loading;
|
||||
extern convar_t *scr_download;
|
||||
extern convar_t *cl_allow_levelshots;
|
||||
extern convar_t *host_allow_materials;
|
||||
extern convar_t *host_limitlocal;
|
||||
extern convar_t *host_maxfps;
|
||||
|
||||
|
@ -173,6 +174,8 @@ typedef struct gameinfo_s
|
|||
float client_mins[4][3]; // 4 hulls allowed
|
||||
float client_maxs[4][3]; // 4 hulls allowed
|
||||
|
||||
char ambientsound[NUM_AMBIENTS][64];// quake ambient sounds
|
||||
|
||||
int max_edicts; // min edicts is 600, max edicts is 4096
|
||||
int max_tents; // min temp ents is 300, max is 2048
|
||||
int max_beams; // min beams is 64, max beams is 512
|
||||
|
@ -304,6 +307,7 @@ typedef struct host_parm_s
|
|||
qboolean shutdown_issued; // engine is shutting down
|
||||
qboolean decal_loading; // nasty hack to tell imagelib about decal
|
||||
qboolean overview_loading; // another nasty hackk to tell imagelib about ovierview
|
||||
qboolean force_draw_version; // used when fraps is loaded
|
||||
|
||||
char rootdir[256]; // member root directory
|
||||
char gamefolder[64]; // it's a default gamefolder
|
||||
|
@ -539,6 +543,7 @@ wavdata_t *FS_StreamInfo( stream_t *stream );
|
|||
long FS_ReadStream( stream_t *stream, int bytes, void *buffer );
|
||||
void FS_FreeStream( stream_t *stream );
|
||||
qboolean Sound_Process( wavdata_t **wav, int rate, int width, uint flags );
|
||||
uint Sound_GetApproxWavePlayLen( const char *filepath );
|
||||
|
||||
//
|
||||
// build.c
|
||||
|
|
|
@ -309,7 +309,7 @@ void Con_CheckResize( void )
|
|||
|
||||
width = ( scr_width->integer / charWidth ) - 2;
|
||||
|
||||
// FIXME: Con_CheckResize is totally wrong :-(
|
||||
// NOTE: Con_CheckResize is totally wrong :-(
|
||||
// g-cont. i've just used fixed width on all resolutions
|
||||
width = 90;
|
||||
|
||||
|
@ -346,7 +346,6 @@ void Con_CheckResize( void )
|
|||
for( i = 0; i < CON_TEXTSIZE; i++ )
|
||||
con.text[i] = ( ColorIndex( COLOR_DEFAULT ) << 8 ) | ' ';
|
||||
|
||||
// FIXME: should we consider '\n' when counting the actual lines?
|
||||
for( i = 0; i < numlines; i++ )
|
||||
{
|
||||
for( j = 0; j < numchars; j++ )
|
||||
|
@ -517,12 +516,18 @@ static int Con_DrawGenericChar( int x, int y, int number, rgba_t color )
|
|||
return con.charWidths[number];
|
||||
}
|
||||
|
||||
static int Con_DrawCharacter( int x, int y, int number, rgba_t color )
|
||||
int Con_DrawCharacter( int x, int y, int number, rgba_t color )
|
||||
{
|
||||
GL_SetRenderMode( kRenderTransTexture );
|
||||
return Con_DrawGenericChar( x, y, number, color );
|
||||
}
|
||||
|
||||
void Con_DrawCharacterLen( int number, int *width, int *height )
|
||||
{
|
||||
if( width ) *width = con.charWidths[number];
|
||||
if( height ) *height = con.charHeight;
|
||||
}
|
||||
|
||||
void Con_DrawStringLen( const char *pText, int *length, int *height )
|
||||
{
|
||||
int curLength = 0;
|
||||
|
@ -1799,11 +1804,24 @@ void Con_DrawVersion( void )
|
|||
byte *color = g_color_table[7];
|
||||
int i, stringLen, width = 0, charH;
|
||||
int start, height = scr_height->integer;
|
||||
qboolean draw_version = false;
|
||||
string curbuild;
|
||||
|
||||
if( cls.key_dest != key_menu && cls.scrshot_action != scrshot_normal ) return;
|
||||
switch( cls.scrshot_action )
|
||||
{
|
||||
case scrshot_normal:
|
||||
case scrshot_snapshot:
|
||||
draw_version = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if( cls.scrshot_action == scrshot_normal )
|
||||
if( !host.force_draw_version )
|
||||
{
|
||||
if(( cls.key_dest != key_menu && !draw_version ) || gl_overview->integer == 2 )
|
||||
return;
|
||||
}
|
||||
|
||||
if( host.force_draw_version || draw_version )
|
||||
Q_snprintf( curbuild, MAX_STRING, "Xash3D v%i/%g (build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildnum( ));
|
||||
else Q_snprintf( curbuild, MAX_STRING, "v%i/%g (build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildnum( ));
|
||||
Con_DrawStringLen( curbuild, &stringLen, &charH );
|
||||
|
|
|
@ -1355,7 +1355,7 @@ static qboolean FS_ParseGameInfo( const char *gamedir, gameinfo_t *GameInfo )
|
|||
else if( !Q_stricmp( token, "max_particles" ))
|
||||
{
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
GameInfo->max_particles = bound( 1024, Q_atoi( token ), 32768 );
|
||||
GameInfo->max_particles = bound( 1024, Q_atoi( token ), 131072 );
|
||||
}
|
||||
else if( !Q_stricmp( token, "gamemode" ))
|
||||
{
|
||||
|
@ -1379,6 +1379,19 @@ static qboolean FS_ParseGameInfo( const char *gamedir, gameinfo_t *GameInfo )
|
|||
FS_ParseVector( &pfile, GameInfo->client_maxs[hullNum], 3 );
|
||||
}
|
||||
}
|
||||
else if( !Q_strnicmp( token, "ambient", 7 ))
|
||||
{
|
||||
int ambientNum = Q_atoi( token + 7 );
|
||||
|
||||
if( ambientNum < 0 || ambientNum > ( NUM_AMBIENTS - 1 ))
|
||||
{
|
||||
MsgDev( D_ERROR, "FS_ParseGameInfo: Invalid ambient number %i. Ignored.\n", ambientNum );
|
||||
}
|
||||
else
|
||||
{
|
||||
pfile = COM_ParseFile( pfile, GameInfo->ambientsound[ambientNum] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Mem_Free( afile );
|
||||
|
|
|
@ -33,6 +33,7 @@ sysinfo_t SI;
|
|||
convar_t *host_serverstate;
|
||||
convar_t *host_gameloaded;
|
||||
convar_t *host_clientloaded;
|
||||
convar_t *host_allow_materials;
|
||||
convar_t *host_limitlocal;
|
||||
convar_t *host_cheats;
|
||||
convar_t *host_maxfps;
|
||||
|
@ -691,6 +692,7 @@ int EXPORT Host_Main( const char *progname, int bChangeGame, pfnChangeGame func
|
|||
host_gameloaded = Cvar_Get( "host_gameloaded", "0", CVAR_INIT, "inidcates a loaded game.dll" );
|
||||
host_clientloaded = Cvar_Get( "host_clientloaded", "0", CVAR_INIT, "inidcates a loaded client.dll" );
|
||||
host_limitlocal = Cvar_Get( "host_limitlocal", "0", 0, "apply cl_cmdrate and rate to loopback connection" );
|
||||
host_allow_materials = Cvar_Get( "host_allow_materials", "1", CVAR_LATCH|CVAR_ARCHIVE, "allow HD textures" );
|
||||
con_gamemaps = Cvar_Get( "con_gamemaps", "1", CVAR_ARCHIVE, "when true show only maps in game folder" );
|
||||
|
||||
// content control
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
img_quant.c - image quantizer. based on hl2 beta original code
|
||||
img_quant.c - image quantizer. based on Antony Dekker original code
|
||||
Copyright (C) 2011 Uncle Mike
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
|
|
@ -0,0 +1,363 @@
|
|||
/*
|
||||
img_quant.c - image quantizer. based on hl2 beta original code
|
||||
Copyright (C) 2011 Uncle Mike
|
||||
|
||||
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 3 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.
|
||||
*/
|
||||
|
||||
#include "imagelib.h"
|
||||
|
||||
#define MAX_PAL_SIZE 256
|
||||
#define MAX_NUM_NODES ( MAX_PAL_SIZE * 8 + 1 )
|
||||
|
||||
typedef struct quantnode_s
|
||||
{
|
||||
qboolean isLeaf;
|
||||
int timesUsed;
|
||||
vec3_t cumulativeColor;
|
||||
int paletteIndex;
|
||||
struct quantnode_s *children[8];
|
||||
struct quantnode_s *parent;
|
||||
struct quantnode_s *next; // next in the priority list for this level of the tree.
|
||||
// also next for the free list.
|
||||
} quantnode_t;
|
||||
|
||||
static quantnode_t nodePool[MAX_NUM_NODES];
|
||||
static int nextFreeID;
|
||||
static quantnode_t *freeList;
|
||||
static quantnode_t *root;
|
||||
static int numColorsUsed;
|
||||
static int desiredNumColors;
|
||||
static byte insertColor[3];
|
||||
static int currNumPalIndices;
|
||||
static byte *pal;
|
||||
static int debugNumNodes = 0;
|
||||
static quantnode_t *priorityQueues[9]; // not prioritized for now.
|
||||
|
||||
static quantnode_t *AllocNode()
|
||||
{
|
||||
quantnode_t *node;
|
||||
|
||||
debugNumNodes++;
|
||||
|
||||
if( nextFreeID < MAX_NUM_NODES )
|
||||
{
|
||||
node = &nodePool[nextFreeID];
|
||||
nextFreeID++;
|
||||
}
|
||||
else
|
||||
{
|
||||
node = freeList;
|
||||
if( !node )
|
||||
{
|
||||
ASSERT( node );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
freeList = freeList->next;
|
||||
}
|
||||
|
||||
Q_memset( node, 0, sizeof( quantnode_t ));
|
||||
return node;
|
||||
}
|
||||
|
||||
static void FreeNode( quantnode_t *node )
|
||||
{
|
||||
debugNumNodes--;
|
||||
node->next = freeList;
|
||||
freeList = node;
|
||||
}
|
||||
|
||||
static void InitNodeAllocation( void )
|
||||
{
|
||||
freeList = NULL;
|
||||
nextFreeID = 0;
|
||||
}
|
||||
|
||||
static void RemoveFromPriorityQueue( int level, quantnode_t *node )
|
||||
{
|
||||
quantnode_t *searchNode, *prev;
|
||||
quantnode_t dummy;
|
||||
|
||||
dummy.next = priorityQueues[level];
|
||||
prev = &dummy;
|
||||
|
||||
for( searchNode = dummy.next; searchNode; searchNode = searchNode->next )
|
||||
{
|
||||
if( searchNode == node )
|
||||
{
|
||||
prev->next = node->next;
|
||||
FreeNode( node );
|
||||
priorityQueues[level] = dummy.next;
|
||||
return;
|
||||
}
|
||||
|
||||
prev = searchNode;
|
||||
}
|
||||
|
||||
ASSERT( 0 );
|
||||
}
|
||||
|
||||
static void ReduceNode( quantnode_t *node, int nodeLevel )
|
||||
{
|
||||
int childNum;
|
||||
|
||||
if( node->timesUsed == 0 )
|
||||
{
|
||||
numColorsUsed++;
|
||||
}
|
||||
|
||||
for( childNum = 0; childNum < 8; childNum++ )
|
||||
{
|
||||
quantnode_t *child;
|
||||
|
||||
child = node->children[childNum];
|
||||
|
||||
if( child )
|
||||
{
|
||||
node->cumulativeColor[0] += child->cumulativeColor[0];
|
||||
node->cumulativeColor[1] += child->cumulativeColor[1];
|
||||
node->cumulativeColor[2] += child->cumulativeColor[2];
|
||||
node->timesUsed += child->timesUsed;
|
||||
|
||||
RemoveFromPriorityQueue( nodeLevel + 1, child );
|
||||
numColorsUsed--;
|
||||
node->children[childNum] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if( !node->isLeaf )
|
||||
{
|
||||
node->next = priorityQueues[nodeLevel];
|
||||
priorityQueues[nodeLevel] = node;
|
||||
}
|
||||
|
||||
node->isLeaf = true;
|
||||
}
|
||||
|
||||
static void ReduceTree( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 8; i > 0; i-- )
|
||||
{
|
||||
if( priorityQueues[i] )
|
||||
{
|
||||
ReduceNode( priorityQueues[i]->parent, i - 1 );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT( 0 );
|
||||
}
|
||||
|
||||
static void AddToNode( quantnode_t *node, int depth, byte *color )
|
||||
{
|
||||
node->timesUsed++;
|
||||
node->cumulativeColor[0] += ( 1.0f / 255.0f ) * color[0];
|
||||
node->cumulativeColor[1] += ( 1.0f / 255.0f ) * color[1];
|
||||
node->cumulativeColor[2] += ( 1.0f / 255.0f ) * color[2];
|
||||
node->isLeaf = true;
|
||||
|
||||
// insert into priority queue if not already there.
|
||||
if( node->timesUsed == 1 )
|
||||
{
|
||||
node->next = priorityQueues[depth];
|
||||
priorityQueues[depth] = node;
|
||||
numColorsUsed++;
|
||||
}
|
||||
}
|
||||
|
||||
static void Insert( quantnode_t *node, quantnode_t *parent, int depth, uint r, uint g, uint b )
|
||||
{
|
||||
int childNum;
|
||||
|
||||
if( depth == 8 || node->isLeaf )
|
||||
{
|
||||
if( numColorsUsed < desiredNumColors )
|
||||
{
|
||||
// just add it and go since we have pal entries to use.
|
||||
AddToNode( node, depth, insertColor );
|
||||
}
|
||||
else
|
||||
{
|
||||
// make space and try again.
|
||||
while( numColorsUsed >= desiredNumColors )
|
||||
{
|
||||
ReduceTree();
|
||||
}
|
||||
Insert( root, NULL, 0, insertColor[0], insertColor[1], insertColor[2] );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// figure out which child to go to.
|
||||
childNum = (( r & ( 1 << 7 )) >> 5 ) | (( g & ( 1 << 7 )) >> 6 ) | (( b & ( 1 << 7 )) >> 7 );
|
||||
|
||||
ASSERT( childNum >= 0 && childNum < 8 );
|
||||
|
||||
// does the child already exist?
|
||||
if( !node->children[childNum] )
|
||||
{
|
||||
// before allocating anything new, make sure we have
|
||||
// space for something new and start over
|
||||
if( numColorsUsed >= desiredNumColors )
|
||||
{
|
||||
do
|
||||
{
|
||||
ReduceTree();
|
||||
} while( numColorsUsed >= desiredNumColors );
|
||||
Insert( root, NULL, 0, insertColor[0], insertColor[1], insertColor[2] );
|
||||
return;
|
||||
}
|
||||
|
||||
node->children[childNum] = AllocNode();
|
||||
node->children[childNum]->parent = node;
|
||||
}
|
||||
|
||||
Insert( node->children[childNum], node, depth + 1, ( r << 1 ) & 0xff, ( g << 1 ) & 0xff, ( b << 1 ) & 0xff );
|
||||
}
|
||||
|
||||
void Quantize( byte *image, int numPixels, int bytesPerPixel, int numPalEntries, byte *palette )
|
||||
{
|
||||
int i;
|
||||
|
||||
pal = palette;
|
||||
desiredNumColors = numPalEntries;
|
||||
root = AllocNode();
|
||||
|
||||
ASSERT( root );
|
||||
|
||||
numColorsUsed = 0;
|
||||
desiredNumColors = numPalEntries;
|
||||
|
||||
for( i = 0; i < 9; i++ )
|
||||
{
|
||||
priorityQueues[i] = NULL;
|
||||
}
|
||||
|
||||
for( i = 0; i < numPixels; i++ )
|
||||
{
|
||||
Q_memcpy( insertColor, &image[i*bytesPerPixel], 3 );
|
||||
Insert( root, NULL, 0, (uint)insertColor[0], (uint)insertColor[1], (uint)insertColor[2] );
|
||||
}
|
||||
}
|
||||
|
||||
static void AverageColorsAndBuildPalette( quantnode_t *node )
|
||||
{
|
||||
vec3_t fColor;
|
||||
float ooTimesUsed;
|
||||
int i;
|
||||
|
||||
if( !node ) return;
|
||||
|
||||
if( node->isLeaf )
|
||||
{
|
||||
ooTimesUsed = 1.0f / node->timesUsed;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
fColor[i] = node->cumulativeColor[i] * ooTimesUsed;
|
||||
if( fColor[i] > 1.0f ) fColor[i] = 1.0f;
|
||||
pal[currNumPalIndices*3+i] = (byte)( fColor[i] * 255 );
|
||||
}
|
||||
|
||||
node->paletteIndex = currNumPalIndices;
|
||||
currNumPalIndices++;
|
||||
return;
|
||||
}
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
AverageColorsAndBuildPalette( node->children[i] );
|
||||
}
|
||||
}
|
||||
|
||||
static void RemapPixel( quantnode_t *node, int depth, int pixel, uint r, uint g, uint b )
|
||||
{
|
||||
int childNum;
|
||||
|
||||
if( !node ) return;
|
||||
|
||||
if( node->isLeaf )
|
||||
{
|
||||
image.tempbuffer[pixel] = node->paletteIndex;
|
||||
return;
|
||||
}
|
||||
|
||||
// figure out which child to go to.
|
||||
childNum = (( r & ( 1 << 7 )) >> 5 ) | (( g & ( 1 << 7 )) >> 6 ) | (( b & ( 1 << 7 )) >> 7 );
|
||||
|
||||
ASSERT( childNum >= 0 && childNum < 8 );
|
||||
|
||||
RemapPixel( node->children[childNum], depth + 1, pixel, ( r << 1 ) & 0xff, ( g << 1 ) & 0xff, ( b << 1 ) & 0xff );
|
||||
}
|
||||
|
||||
static void MapImageToPalette( byte *in, int numPixels, int bpp )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < numPixels; i++ )
|
||||
{
|
||||
RemapPixel( root, 0, i, (uint)in[i*bpp+0], (uint)in[i*bpp+1], (uint)in[i*bpp+2] );
|
||||
}
|
||||
}
|
||||
|
||||
// returns the actual number of palette entries.
|
||||
rgbdata_t *Image_Quantize( rgbdata_t *pic )
|
||||
{
|
||||
byte palette[768];
|
||||
int bpp;
|
||||
|
||||
// quick case to reject unneeded conversions
|
||||
if( pic->type == PF_INDEXED_24 || pic->type == PF_INDEXED_32 )
|
||||
return pic;
|
||||
|
||||
// get image description
|
||||
switch( pic->type )
|
||||
{
|
||||
case PF_RGB_24:
|
||||
case PF_BGR_24:
|
||||
bpp = 3;
|
||||
break;
|
||||
case PF_RGBA_32:
|
||||
case PF_BGRA_32:
|
||||
bpp = 4;
|
||||
break;
|
||||
default:
|
||||
MsgDev( D_ERROR, "Image_Quantize: unsupported image type %s\n", PFDesc[pic->type].name );
|
||||
return pic;
|
||||
}
|
||||
|
||||
Image_CopyParms( pic );
|
||||
image.size = image.width * image.height;
|
||||
image.palette = palette;
|
||||
image.ptr = 0;
|
||||
|
||||
// allocate 8-bit buffer
|
||||
image.tempbuffer = Mem_Realloc( host.imagepool, image.tempbuffer, image.size );
|
||||
|
||||
InitNodeAllocation();
|
||||
Quantize( pic->buffer, image.size, bpp, 256, palette );
|
||||
currNumPalIndices = 0;
|
||||
AverageColorsAndBuildPalette( root );
|
||||
MapImageToPalette( pic->buffer, image.size, bpp );
|
||||
|
||||
pic->buffer = Mem_Realloc( host.imagepool, pic->buffer, image.size );
|
||||
Q_memcpy( pic->buffer, image.tempbuffer, image.size );
|
||||
pic->palette = Mem_Alloc( host.imagepool, sizeof( palette ));
|
||||
Q_memcpy( pic->palette, palette, sizeof( palette ));
|
||||
pic->type = PF_INDEXED_24;
|
||||
pic->size = image.size;
|
||||
image.palette = NULL;
|
||||
|
||||
return pic;
|
||||
}
|
|
@ -116,6 +116,9 @@ qboolean Image_LoadTGA( const char *name, const byte *buffer, size_t filesize )
|
|||
}
|
||||
}
|
||||
|
||||
// HACKHACK: detect luma textures by name
|
||||
if( Q_stristr( name, "_luma" )) image.flags |= IMAGE_HAS_LUMA;
|
||||
|
||||
columns = targa_header.width;
|
||||
rows = targa_header.height;
|
||||
|
||||
|
|
|
@ -1035,7 +1035,7 @@ byte *Image_FlipInternal( const byte *in, word *srcwidth, word *srcheight, int t
|
|||
return image.tempbuffer;
|
||||
}
|
||||
|
||||
byte *Image_CreateLumaInternal( const byte *fin, int width, int height, int type, int flags )
|
||||
byte *Image_CreateLumaInternal( byte *fin, int width, int height, int type, int flags )
|
||||
{
|
||||
byte *out;
|
||||
int i;
|
||||
|
@ -1054,6 +1054,26 @@ byte *Image_CreateLumaInternal( const byte *fin, int width, int height, int type
|
|||
for( i = 0; i < width * height; i++ )
|
||||
*out++ = fin[i] >= 224 ? fin[i] : 0;
|
||||
break;
|
||||
case PF_RGB_24:
|
||||
case PF_BGR_24:
|
||||
// clearing any gray pixels
|
||||
for( i = 0; i < width * height; i++ )
|
||||
{
|
||||
if( fin[i*3+0] < 32 ) fin[i*3+0] = 0;
|
||||
if( fin[i*3+1] < 32 ) fin[i*3+1] = 0;
|
||||
if( fin[i*3+2] < 32 ) fin[i*3+2] = 0;
|
||||
}
|
||||
return (byte *)fin;
|
||||
case PF_RGBA_32:
|
||||
case PF_BGRA_32:
|
||||
// clearing any gray pixels
|
||||
for( i = 0; i < width * height; i++ )
|
||||
{
|
||||
if( fin[i*4+0] < 32 ) fin[i*4+0] = 0;
|
||||
if( fin[i*4+1] < 32 ) fin[i*4+1] = 0;
|
||||
if( fin[i*4+2] < 32 ) fin[i*4+2] = 0;
|
||||
}
|
||||
return (byte *)fin;
|
||||
default:
|
||||
// another formats does ugly result :(
|
||||
MsgDev( D_WARN, "Image_MakeLuma: unsupported format %s\n", PFDesc[type].name );
|
||||
|
|
|
@ -404,8 +404,8 @@ qboolean Image_LoadMIP( const char *name, const byte *buffer, size_t filesize )
|
|||
// this is a good reason for using fullbright pixels
|
||||
pal_type = Image_ComparePalette( pal );
|
||||
|
||||
// check for luma pixels
|
||||
if( pal_type == PAL_QUAKE1 )
|
||||
// check for luma pixels (but ignore liquid textures, this a Xash3D limitation)
|
||||
if( mip.name[0] != '!' && pal_type == PAL_QUAKE1 )
|
||||
{
|
||||
for( i = 0; i < image.width * image.height; i++ )
|
||||
{
|
||||
|
|
|
@ -587,6 +587,13 @@ void Key_Event( int key, qboolean down )
|
|||
// distribute the key down event to the apropriate handler
|
||||
if( cls.key_dest == key_game )
|
||||
{
|
||||
if( cls.state == ca_cinematic && ( key != K_ESCAPE || !down ))
|
||||
{
|
||||
// only escape passed when cinematic is playing
|
||||
// HLFX 0.6 bug: crash in vgui3.dll while press +attack during movie playback
|
||||
return;
|
||||
}
|
||||
|
||||
// send the bound action
|
||||
kb = keys[key].binding;
|
||||
if( !kb )
|
||||
|
|
|
@ -63,6 +63,7 @@ typedef struct
|
|||
int max_surfaces; // max surfaces per submodel (for all models)
|
||||
size_t visdatasize; // actual size of the visdata
|
||||
qboolean loading; // true if worldmodel is loading
|
||||
qboolean sky_sphere; // true when quake sky-sphere is used
|
||||
|
||||
vec3_t mins; // real accuracy world bounds
|
||||
vec3_t maxs;
|
||||
|
|
|
@ -30,7 +30,8 @@ static model_t cm_models[MAX_MODELS];
|
|||
static int cm_nummodels = 0;
|
||||
static byte visdata[MAX_MAP_LEAFS/8]; // intermediate buffer
|
||||
int bmodel_version; // global stuff to detect bsp version
|
||||
|
||||
char modelname[64]; // short model name (without path and ext)
|
||||
|
||||
model_t *loadmodel;
|
||||
model_t *worldmodel;
|
||||
|
||||
|
@ -326,7 +327,7 @@ qboolean Mod_BoxVisible( const vec3_t mins, const vec3_t maxs, const byte *visbi
|
|||
{
|
||||
int leafnum = leafList[i];
|
||||
|
||||
if( visbits[leafnum>>3] & (1<<( leafnum & 7 )))
|
||||
if( leafnum != -1 && visbits[leafnum>>3] & (1<<( leafnum & 7 )))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -456,7 +457,7 @@ static void Mod_LoadSubmodels( const dlump_t *l )
|
|||
if( VectorIsNull( out->origin ))
|
||||
{
|
||||
// NOTE: zero origin after recalculating is indicated included origin brush
|
||||
VectorAverage( out->mins, out->maxs, out->origin );
|
||||
// VectorAverage( out->mins, out->maxs, out->origin );
|
||||
}
|
||||
|
||||
if( i == 0 || !world.loading )
|
||||
|
@ -481,7 +482,7 @@ static void Mod_LoadTextures( const dlump_t *l )
|
|||
texture_t *anims[10];
|
||||
texture_t *altanims[10];
|
||||
int num, max, altmax;
|
||||
char texname[32];
|
||||
char texname[64];
|
||||
mip_t *mt;
|
||||
int i, j;
|
||||
|
||||
|
@ -491,6 +492,7 @@ static void Mod_LoadTextures( const dlump_t *l )
|
|||
GL_FreeTexture( tr.solidskyTexture );
|
||||
GL_FreeTexture( tr.alphaskyTexture );
|
||||
tr.solidskyTexture = tr.alphaskyTexture = 0;
|
||||
world.sky_sphere = false;
|
||||
}
|
||||
|
||||
if( !l->filelen )
|
||||
|
@ -507,6 +509,9 @@ static void Mod_LoadTextures( const dlump_t *l )
|
|||
|
||||
for( i = 0; i < loadmodel->numtextures; i++ )
|
||||
{
|
||||
qboolean load_external = false;
|
||||
qboolean load_external_luma = false;
|
||||
|
||||
if( in->dataofs[i] == -1 )
|
||||
{
|
||||
// create default texture (some mods requires this)
|
||||
|
@ -533,51 +538,166 @@ static void Mod_LoadTextures( const dlump_t *l )
|
|||
// convert to lowercase
|
||||
Q_strnlwr( mt->name, mt->name, sizeof( mt->name ));
|
||||
Q_strncpy( tx->name, mt->name, sizeof( tx->name ));
|
||||
Q_snprintf( texname, sizeof( texname ), "%s%s.mip", ( mt->offsets[0] > 0 ) ? "#" : "", mt->name );
|
||||
|
||||
tx->width = mt->width;
|
||||
tx->height = mt->height;
|
||||
|
||||
// check for sky texture (quake1 only!)
|
||||
if( world.loading && world.version == Q1BSP_VERSION && !Q_strncmp( mt->name, "sky", 3 ))
|
||||
// check for multi-layered sky texture
|
||||
if( world.loading && !Q_strncmp( mt->name, "sky", 3 ) && mt->width == 256 && mt->height == 128 )
|
||||
{
|
||||
R_InitSky( mt, tx );
|
||||
}
|
||||
else if( mt->offsets[0] > 0 )
|
||||
{
|
||||
// NOTE: imagelib detect miptex version by size
|
||||
// 770 additional bytes is indicated custom palette
|
||||
int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6);
|
||||
if( bmodel_version == HLBSP_VERSION ) size += sizeof( short ) + 768;
|
||||
if( host_allow_materials->integer )
|
||||
{
|
||||
// build standard path: "materials/mapname/texname_solid.tga"
|
||||
Q_snprintf( texname, sizeof( texname ), "materials/%s/%s_solid.tga", modelname, mt->name );
|
||||
|
||||
tx->gl_texturenum = GL_LoadTexture( texname, (byte *)mt, size, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// okay, loading it from wad
|
||||
tx->gl_texturenum = GL_LoadTexture( texname, NULL, 0, 0 );
|
||||
}
|
||||
if( !FS_FileExists( texname, false ))
|
||||
{
|
||||
// build common path: "materials/mapname/texname_solid.tga"
|
||||
Q_snprintf( texname, sizeof( texname ), "materials/common/%s_solid.tga", mt->name );
|
||||
|
||||
// set the emo-texture for missed
|
||||
if( !tx->gl_texturenum ) tx->gl_texturenum = tr.defaultTexture;
|
||||
if( FS_FileExists( texname, false ))
|
||||
load_external = true;
|
||||
}
|
||||
else load_external = true;
|
||||
|
||||
// check for luma texture
|
||||
if( R_GetTexture( tx->gl_texturenum )->flags & TF_HAS_LUMA )
|
||||
if( load_external )
|
||||
{
|
||||
tr.solidskyTexture = GL_LoadTexture( texname, NULL, 0, TF_UNCOMPRESSED|TF_NOMIPMAP );
|
||||
GL_SetTextureType( tr.solidskyTexture, TEX_BRUSH );
|
||||
load_external = false;
|
||||
}
|
||||
|
||||
if( tr.solidskyTexture )
|
||||
{
|
||||
// build standard path: "materials/mapname/texname_alpha.tga"
|
||||
Q_snprintf( texname, sizeof( texname ), "materials/%s/%s_alpha.tga", modelname, mt->name );
|
||||
|
||||
if( !FS_FileExists( texname, false ))
|
||||
{
|
||||
// build common path: "materials/mapname/texname_alpha.tga"
|
||||
Q_snprintf( texname, sizeof( texname ), "materials/common/%s_alpha.tga", mt->name );
|
||||
|
||||
if( FS_FileExists( texname, false ))
|
||||
load_external = true;
|
||||
}
|
||||
else load_external = true;
|
||||
|
||||
if( load_external )
|
||||
{
|
||||
tr.alphaskyTexture = GL_LoadTexture( texname, NULL, 0, TF_UNCOMPRESSED|TF_NOMIPMAP );
|
||||
GL_SetTextureType( tr.alphaskyTexture, TEX_BRUSH );
|
||||
load_external = false;
|
||||
}
|
||||
}
|
||||
|
||||
if( !tr.solidskyTexture || !tr.alphaskyTexture )
|
||||
{
|
||||
// couldn't find one of layer
|
||||
GL_FreeTexture( tr.solidskyTexture );
|
||||
GL_FreeTexture( tr.alphaskyTexture );
|
||||
tr.solidskyTexture = tr.alphaskyTexture = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( !tr.solidskyTexture && !tr.alphaskyTexture )
|
||||
R_InitSky( mt, tx ); // fallback to standard sky
|
||||
|
||||
if( tr.solidskyTexture && tr.alphaskyTexture )
|
||||
world.sky_sphere = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( texname, sizeof( texname ), "%s%s_luma.mip", mt->offsets[0] > 0 ? "#" : "", mt->name );
|
||||
if( mt->offsets[0] > 0 )
|
||||
if( host_allow_materials->integer )
|
||||
{
|
||||
if( mt->name[0] == '*' ) mt->name[0] = '!'; // replace unexpected symbol
|
||||
|
||||
// build standard path: "materials/mapname/texname.tga"
|
||||
Q_snprintf( texname, sizeof( texname ), "materials/%s/%s.tga", modelname, mt->name );
|
||||
|
||||
if( !FS_FileExists( texname, false ))
|
||||
{
|
||||
// build common path: "materials/mapname/texname.tga"
|
||||
Q_snprintf( texname, sizeof( texname ), "materials/common/%s.tga", mt->name );
|
||||
|
||||
if( FS_FileExists( texname, false ))
|
||||
load_external = true;
|
||||
}
|
||||
else load_external = true;
|
||||
}
|
||||
load_wad_textures:
|
||||
if( !load_external )
|
||||
Q_snprintf( texname, sizeof( texname ), "%s%s.mip", ( mt->offsets[0] > 0 ) ? "#" : "", mt->name );
|
||||
else MsgDev( D_NOTE, "loading HQ: %s\n", texname );
|
||||
|
||||
if( mt->offsets[0] > 0 && !load_external )
|
||||
{
|
||||
// NOTE: imagelib detect miptex version by size
|
||||
// 770 additional bytes is indicated custom palette
|
||||
int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6);
|
||||
if( bmodel_version == HLBSP_VERSION ) size += sizeof( short ) + 768;
|
||||
|
||||
tx->fb_texturenum = GL_LoadTexture( texname, (byte *)mt, size, TF_MAKELUMA|TF_NOMIPMAP );
|
||||
tx->gl_texturenum = GL_LoadTexture( texname, (byte *)mt, size, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// okay, loading it from wad
|
||||
tx->fb_texturenum = GL_LoadTexture( texname, NULL, 0, TF_MAKELUMA|TF_NOMIPMAP );
|
||||
tx->gl_texturenum = GL_LoadTexture( texname, NULL, 0, 0 );
|
||||
|
||||
if( !tx->gl_texturenum && load_external )
|
||||
{
|
||||
// in case we failed to loading 32-bit texture
|
||||
MsgDev( D_ERROR, "Couldn't load %s\n", texname );
|
||||
load_external = false;
|
||||
goto load_wad_textures;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set the emo-texture for missed
|
||||
if( !tx->gl_texturenum ) tx->gl_texturenum = tr.defaultTexture;
|
||||
|
||||
if( load_external )
|
||||
{
|
||||
// build standard luma path: "materials/mapname/texname_luma.tga"
|
||||
Q_snprintf( texname, sizeof( texname ), "materials/%s/%s_luma.tga", modelname, mt->name );
|
||||
|
||||
if( !FS_FileExists( texname, false ))
|
||||
{
|
||||
// build common path: "materials/mapname/texname_luma.tga"
|
||||
Q_snprintf( texname, sizeof( texname ), "materials/common/%s_luma.tga", mt->name );
|
||||
|
||||
if( FS_FileExists( texname, false ))
|
||||
load_external_luma = true;
|
||||
}
|
||||
else load_external_luma = true;
|
||||
}
|
||||
|
||||
// check for luma texture
|
||||
if( R_GetTexture( tx->gl_texturenum )->flags & TF_HAS_LUMA || load_external_luma )
|
||||
{
|
||||
if( !load_external_luma )
|
||||
Q_snprintf( texname, sizeof( texname ), "%s%s_luma.mip", mt->offsets[0] > 0 ? "#" : "", mt->name );
|
||||
else MsgDev( D_NOTE, "loading luma HQ: %s\n", texname );
|
||||
|
||||
if( mt->offsets[0] > 0 && !load_external_luma )
|
||||
{
|
||||
// NOTE: imagelib detect miptex version by size
|
||||
// 770 additional bytes is indicated custom palette
|
||||
int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6);
|
||||
if( bmodel_version == HLBSP_VERSION ) size += sizeof( short ) + 768;
|
||||
|
||||
tx->fb_texturenum = GL_LoadTexture( texname, (byte *)mt, size, TF_NOMIPMAP|TF_MAKELUMA );
|
||||
}
|
||||
else
|
||||
{
|
||||
// okay, loading it from wad
|
||||
tx->fb_texturenum = GL_LoadTexture( texname, NULL, 0, TF_NOMIPMAP|TF_MAKELUMA );
|
||||
|
||||
if( !tx->fb_texturenum && load_external_luma )
|
||||
{
|
||||
// in case we failed to loading 32-bit luma texture
|
||||
MsgDev( D_ERROR, "Couldn't load %s\n", texname );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -937,13 +1057,13 @@ static void Mod_LoadSurfaces( const dlump_t *l )
|
|||
if(( tex->name[0] == '*' && Q_stricmp( tex->name, "*default" )) || tex->name[0] == '!' )
|
||||
out->flags |= (SURF_DRAWTURB|SURF_DRAWTILED);
|
||||
|
||||
if( !Q_strnicmp( tex->name, "water", 5 ) || !Q_strnicmp( tex->name, "laser", 5 ))
|
||||
if( !Q_strncmp( tex->name, "water", 5 ) || !Q_strnicmp( tex->name, "laser", 5 ))
|
||||
out->flags |= (SURF_DRAWTURB|SURF_DRAWTILED|SURF_NOCULL);
|
||||
|
||||
if( !Q_strnicmp( tex->name, "scroll", 6 ))
|
||||
if( !Q_strncmp( tex->name, "scroll", 6 ))
|
||||
out->flags |= SURF_CONVEYOR;
|
||||
#ifdef MIRROR_TEST
|
||||
if( !Q_strnicmp( tex->name, "glassblue1", 10 ))
|
||||
if( !Q_strncmp( tex->name, "glassblue1", 10 ))
|
||||
out->flags |= SURF_MIRROR;
|
||||
#endif
|
||||
if( tex->name[0] == '{' )
|
||||
|
@ -965,7 +1085,7 @@ static void Mod_LoadSurfaces( const dlump_t *l )
|
|||
for( j = 0; j < MAXLIGHTMAPS; j++ )
|
||||
out->styles[j] = in->styles[j];
|
||||
|
||||
if( world.loading && out->flags & SURF_DRAWSKY && world.version == Q1BSP_VERSION )
|
||||
if( out->flags & SURF_DRAWSKY && world.loading && world.sky_sphere )
|
||||
GL_SubdivideSurface( out ); // cut up polygon for warps
|
||||
|
||||
if( out->flags & SURF_DRAWTURB )
|
||||
|
@ -1759,6 +1879,8 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
FS_FileBase( mod->name, modelname );
|
||||
|
||||
MsgDev( D_NOTE, "Mod_LoadModel: %s\n", mod->name );
|
||||
mod->needload = world.load_sequence; // register mod
|
||||
mod->type = mod_bad;
|
||||
|
|
|
@ -80,6 +80,7 @@ static const delta_field_t pm_fields[] =
|
|||
{ PHYS_DEF( skyvec_z ) },
|
||||
{ PHYS_DEF( studio_scale ) },
|
||||
{ PHYS_DEF( clienttrace ) },
|
||||
{ PHYS_DEF( wateralpha ) },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
@ -818,7 +819,7 @@ void Delta_Init( void )
|
|||
Delta_AddField( "movevars_t", "skyvec_z", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
|
||||
Delta_AddField( "movevars_t", "studio_scale", DT_INTEGER, 1, 1.0f, 1.0f );
|
||||
Delta_AddField( "movevars_t", "clienttrace", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
|
||||
|
||||
Delta_AddField( "movevars_t", "wateralpha", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
|
||||
// now done
|
||||
dt->bInitialized = true;
|
||||
}
|
||||
|
|
|
@ -131,9 +131,9 @@ hull_t *PM_HullForEntity( physent_t *pe, vec3_t mins, vec3_t maxs, vec3_t offset
|
|||
}
|
||||
else
|
||||
{
|
||||
if( size[0] <= 36.0f )
|
||||
if( size[0] <= world.hull_sizes[1][0] )
|
||||
{
|
||||
if( size[2] <= 36.0f )
|
||||
if( size[2] <= world.hull_sizes[3][2] )
|
||||
hull = &pe->model->hulls[3];
|
||||
else hull = &pe->model->hulls[1];
|
||||
}
|
||||
|
@ -460,7 +460,7 @@ pmtrace_t PM_PlayerTrace( playermove_t *pmove, vec3_t start, vec3_t end, int fla
|
|||
if( pmFilter && pmFilter( pe ))
|
||||
continue;
|
||||
|
||||
if(( i > 0 ) && !VectorIsNull( mins ) && VectorIsNull( pe->mins ))
|
||||
if(( i > 0 ) && usehull != 2 && VectorIsNull( pe->mins ) && VectorIsNull( pe->maxs ))
|
||||
continue; // points never interact
|
||||
|
||||
// might intersect, so do an exact clip
|
||||
|
|
|
@ -113,10 +113,7 @@ qboolean Sound_LoadMPG( const char *name, const byte *buffer, size_t filesize )
|
|||
}
|
||||
|
||||
if( bytesWrite + mpeg.outsize > sound.size )
|
||||
{
|
||||
outsize = ( sound.size - bytesWrite );
|
||||
Msg( "merge size from %i, to %i\n", mpeg.outsize, outsize );
|
||||
}
|
||||
else outsize = mpeg.outsize;
|
||||
|
||||
Q_memcpy( &sound.wav[bytesWrite], mpeg.out, outsize );
|
||||
|
|
|
@ -92,6 +92,49 @@ byte *Sound_Copy( size_t size )
|
|||
return out;
|
||||
}
|
||||
|
||||
uint Sound_GetApproxWavePlayLen( const char *filepath )
|
||||
{
|
||||
file_t *f;
|
||||
wavehdr_t wav;
|
||||
size_t filesize;
|
||||
float seconds;
|
||||
uint samples;
|
||||
|
||||
f = FS_Open( filepath, "rb", false );
|
||||
if( !f ) return 0;
|
||||
|
||||
if( FS_Read( f, &wav, sizeof( wav )) != sizeof( wav ))
|
||||
{
|
||||
FS_Close( f );
|
||||
return 0;
|
||||
}
|
||||
|
||||
filesize = FS_FileLength( f );
|
||||
filesize -= ( sizeof( wavehdr_t ) + sizeof( chunkhdr_t ));
|
||||
|
||||
FS_Close( f );
|
||||
|
||||
// is real wav file ?
|
||||
if( wav.riff_id != RIFFHEADER || wav.wave_id != WAVEHEADER || wav.fmt_id != FORMHEADER )
|
||||
return 0;
|
||||
|
||||
if( wav.wFormatTag != 1 )
|
||||
return 0;
|
||||
|
||||
if( wav.nChannels != 1 && wav.nChannels != 2 )
|
||||
return 0;
|
||||
|
||||
if( wav.nBitsPerSample != 8 && wav.nBitsPerSample != 16 )
|
||||
return 0;
|
||||
|
||||
// calc samplecount
|
||||
seconds = (float)filesize / wav.nAvgBytesPerSec / wav.nChannels;
|
||||
samples = (uint)(( wav.nSamplesPerSec * wav.nChannels ) * seconds );
|
||||
|
||||
// g-cont. this function returns samplecount or time in milliseconds ???
|
||||
return (uint)(seconds * 1000);
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Sound_ConvertToSigned
|
||||
|
|
|
@ -139,7 +139,8 @@ Sound_LoadWAV
|
|||
*/
|
||||
qboolean Sound_LoadWAV( const char *name, const byte *buffer, size_t filesize )
|
||||
{
|
||||
int samples;
|
||||
int samples, fmt;
|
||||
qboolean mpeg_stream = false;
|
||||
|
||||
if( !buffer || filesize <= 0 ) return false;
|
||||
|
||||
|
@ -164,10 +165,15 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, size_t filesize )
|
|||
}
|
||||
|
||||
iff_dataPtr += 8;
|
||||
if( GetLittleShort() != 1 )
|
||||
fmt = GetLittleShort();
|
||||
if( fmt != 1 )
|
||||
{
|
||||
MsgDev( D_ERROR, "Sound_LoadWAV: %s not a microsoft PCM format\n", name );
|
||||
return false;
|
||||
if( fmt != 85 )
|
||||
{
|
||||
MsgDev( D_ERROR, "Sound_LoadWAV: %s not a microsoft PCM format\n", name );
|
||||
return false;
|
||||
}
|
||||
else mpeg_stream = true;
|
||||
}
|
||||
|
||||
sound.channels = GetLittleShort();
|
||||
|
@ -181,6 +187,8 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, size_t filesize )
|
|||
iff_dataPtr += 6;
|
||||
|
||||
sound.width = GetLittleShort() / 8;
|
||||
if( mpeg_stream ) sound.width = 2; // mp3 always 16bit
|
||||
|
||||
if( sound.width != 1 && sound.width != 2 )
|
||||
{
|
||||
MsgDev( D_WARN, "Sound_LoadWAV: only 8 and 16 bit WAV files supported (%s)\n", name );
|
||||
|
@ -242,6 +250,22 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, size_t filesize )
|
|||
sound.type = WF_PCMDATA;
|
||||
sound.samples /= sound.channels;
|
||||
|
||||
// g-cont. get support for mp3 streams packed in wav container
|
||||
// e.g. CAd menu sounds
|
||||
if( mpeg_stream )
|
||||
{
|
||||
int hdr_size = (iff_dataPtr - buffer);
|
||||
|
||||
if(( filesize - hdr_size ) < 16384 )
|
||||
{
|
||||
sound.tempbuffer = (byte *)Mem_Realloc( host.soundpool, sound.tempbuffer, 16384 );
|
||||
Q_memcpy( sound.tempbuffer, buffer + (iff_dataPtr - buffer), filesize - hdr_size );
|
||||
return Sound_LoadMPG( name, sound.tempbuffer, 16384 );
|
||||
}
|
||||
|
||||
return Sound_LoadMPG( name, buffer + hdr_size, filesize - hdr_size );
|
||||
}
|
||||
|
||||
// Load the data
|
||||
sound.size = sound.samples * sound.width * sound.channels;
|
||||
sound.wav = Mem_Alloc( host.soundpool, sound.size );
|
||||
|
|
|
@ -70,6 +70,40 @@ typedef struct stream_s
|
|||
void *ptr;
|
||||
};
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.WAV sound format
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
#define RIFFHEADER (('F'<<24)+('F'<<16)+('I'<<8)+'R') // little-endian "RIFF"
|
||||
#define WAVEHEADER (('E'<<24)+('V'<<16)+('A'<<8)+'W') // little-endian "WAVE"
|
||||
#define FORMHEADER ((' '<<24)+('t'<<16)+('m'<<8)+'f') // little-endian "fmt "
|
||||
#define DATAHEADER (('a'<<24)+('t'<<16)+('a'<<8)+'d') // little-endian "data"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int riff_id; // 'RIFF'
|
||||
long rLen;
|
||||
int wave_id; // 'WAVE'
|
||||
int fmt_id; // 'fmt '
|
||||
long pcm_header_len; // varies...
|
||||
short wFormatTag;
|
||||
short nChannels; // 1,2 for stereo data is (l,r) pairs
|
||||
long nSamplesPerSec;
|
||||
long nAvgBytesPerSec;
|
||||
short nBlockAlign;
|
||||
short nBitsPerSample;
|
||||
} wavehdr_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int data_id; // 'data' or 'fact'
|
||||
long dLen;
|
||||
} chunkhdr_t;
|
||||
|
||||
extern sndlib_t sound;
|
||||
//
|
||||
// formats load
|
||||
|
|
|
@ -61,9 +61,16 @@ TargetDir=\Xash3D\src_main\temp\engine\!release
|
|||
InputPath=\Xash3D\src_main\temp\engine\!release\xash.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"D:\Xash3D\xash.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\xash.dll "D:\Xash3D\xash.dll"
|
||||
BuildCmds= \
|
||||
copy $(TargetDir)\xash.dll "D:\Xash3D\xash.dll" \
|
||||
copy $(TargetDir)\xash.dll "D:\Area51\xash.dll" \
|
||||
|
||||
|
||||
"D:\Xash3D\xash.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"D:\Area51\xash.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "engine - Win32 Debug"
|
||||
|
@ -98,9 +105,16 @@ TargetDir=\Xash3D\src_main\temp\engine\!debug
|
|||
InputPath=\Xash3D\src_main\temp\engine\!debug\xash.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"D:\Xash3D\xash.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\xash.dll "D:\Xash3D\xash.dll"
|
||||
BuildCmds= \
|
||||
copy $(TargetDir)\xash.dll "D:\Xash3D\xash.dll" \
|
||||
copy $(TargetDir)\xash.dll "D:\Area51\xash.dll" \
|
||||
|
||||
|
||||
"D:\Xash3D\xash.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"D:\Area51\xash.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
|
|
|
@ -395,6 +395,7 @@ extern convar_t *sv_allow_download;
|
|||
extern convar_t *sv_allow_studio_scaling;
|
||||
extern convar_t *sv_allow_studio_attachment_angles;
|
||||
extern convar_t *sv_allow_rotate_pushables;
|
||||
extern convar_t *sv_fix_pushstep;
|
||||
extern convar_t *sv_clienttrace;
|
||||
extern convar_t *sv_send_resources;
|
||||
extern convar_t *sv_send_logos;
|
||||
|
|
|
@ -215,10 +215,10 @@ gotnewcl:
|
|||
newcl->frames = (client_frame_t *)Z_Malloc( sizeof( client_frame_t ) * SV_UPDATE_BACKUP );
|
||||
newcl->userid = g_userid++; // create unique userid
|
||||
newcl->authentication_method = 2;
|
||||
|
||||
// FIXME: g-cont. i'm don't know how spectators interact with server
|
||||
// newcl->spectator = spectator;
|
||||
|
||||
#if 0
|
||||
// g-cont. i'm don't know how spectators interact with server. disabled
|
||||
newcl->spectator = spectator;
|
||||
#endif
|
||||
// get the game a chance to reject this connection or modify the userinfo
|
||||
if( !( SV_ClientConnect( ent, userinfo )))
|
||||
{
|
||||
|
@ -1056,7 +1056,8 @@ void SV_New_f( sv_client_t *cl )
|
|||
ent = EDICT_NUM( playernum + 1 );
|
||||
cl->edict = ent;
|
||||
|
||||
if( sv_maxclients->integer == 1 )
|
||||
// NOTE: custom resources download is disabled until is done
|
||||
if( /*sv_maxclients->integer ==*/ 1 )
|
||||
{
|
||||
Q_memset( &cl->lastcmd, 0, sizeof( cl->lastcmd ));
|
||||
|
||||
|
|
|
@ -319,7 +319,7 @@ qboolean SV_Send( int dest, const vec3_t origin, const edict_t *ent )
|
|||
|
||||
// -1 is because pvs rows are 1 based, not 0 based like leafs
|
||||
leafnum = Mod_PointLeafnum( viewOrg ) - 1;
|
||||
if( mask && (!(mask[leafnum>>3] & (1<<( leafnum & 7 )))))
|
||||
if( leafnum != -1 && (!(mask[leafnum>>3] & (1<<( leafnum & 7 )))))
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -385,7 +385,7 @@ static qboolean SV_OriginIn( int mode, const vec3_t v1, const vec3_t v2 )
|
|||
// -1 is because pvs rows are 1 based, not 0 based like leafs
|
||||
leafnum = Mod_PointLeafnum( v2 ) - 1;
|
||||
|
||||
if( mask && (!( mask[leafnum>>3] & (1<<( leafnum & 7 )))))
|
||||
if( mask && leafnum != -1 && (!( mask[leafnum>>3] & (1<<( leafnum & 7 )))))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -805,7 +805,7 @@ void SV_PlaybackEvent( sizebuf_t *msg, event_info_t *info )
|
|||
|
||||
BF_WriteWord( msg, info->index ); // send event index
|
||||
BF_WriteWord( msg, (int)( info->fire_time * 100.0f )); // send event delay
|
||||
MSG_WriteDeltaEvent( msg, &nullargs, &info->args ); // FIXME: use delta-compressing
|
||||
MSG_WriteDeltaEvent( msg, &nullargs, &info->args ); // TODO: use delta-compressing
|
||||
}
|
||||
|
||||
const char *SV_ClassName( const edict_t *e )
|
||||
|
@ -1309,15 +1309,17 @@ pfnFindClientInPVS
|
|||
edict_t* pfnFindClientInPVS( edict_t *pEdict )
|
||||
{
|
||||
edict_t *pClient;
|
||||
mleaf_t *leaf;
|
||||
vec3_t view;
|
||||
float delta;
|
||||
int i;
|
||||
|
||||
if( !SV_IsValidEdict( pEdict ))
|
||||
return svgame.edicts;
|
||||
|
||||
delta = ( sv.time - sv.lastchecktime );
|
||||
|
||||
// find a new check if on a new frame
|
||||
if(( sv.time - sv.lastchecktime ) >= 0.1 )
|
||||
if( delta < 0.0f || delta >= 0.1f )
|
||||
{
|
||||
sv.lastcheck = SV_CheckClientPVS( sv.lastcheck );
|
||||
sv.lastchecktime = sv.time;
|
||||
|
@ -1329,8 +1331,11 @@ edict_t* pfnFindClientInPVS( edict_t *pEdict )
|
|||
return svgame.edicts;
|
||||
|
||||
VectorAdd( pEdict->v.origin, pEdict->v.view_ofs, view );
|
||||
leaf = Mod_PointInLeaf( view, sv.worldmodel->nodes );
|
||||
i = (leaf - sv.worldmodel->leafs) - 1;
|
||||
|
||||
if( pEdict->v.effects & EF_INVLIGHT )
|
||||
view[2] -= 1.0f; // HACK for barnacle
|
||||
|
||||
i = Mod_PointLeafnum( view ) - 1;
|
||||
|
||||
if( i < 0 || !((clientpvs[i>>3]) & (1 << (i & 7))))
|
||||
return svgame.edicts;
|
||||
|
@ -3562,7 +3567,7 @@ void SV_PlaybackEventFull( int flags, const edict_t *pInvoker, word eventindex,
|
|||
continue;
|
||||
}
|
||||
|
||||
if(!( flags & FEV_GLOBAL ))
|
||||
if( mask && !( flags & FEV_GLOBAL ))
|
||||
{
|
||||
int clientnum;
|
||||
|
||||
|
@ -3575,7 +3580,7 @@ void SV_PlaybackEventFull( int flags, const edict_t *pInvoker, word eventindex,
|
|||
|
||||
// -1 is because pvs rows are 1 based, not 0 based like leafs
|
||||
leafnum = Mod_PointLeafnum( viewOrg ) - 1;
|
||||
if( mask && (!( mask[leafnum>>3] & (1<<( leafnum & 7 )))))
|
||||
if( leafnum != -1 && (!( mask[leafnum>>3] & (1<<( leafnum & 7 )))))
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -4032,18 +4037,6 @@ int pfnGetFileSize( char *filename )
|
|||
return FS_FileSize( filename, false );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
pfnGetApproxWavePlayLen
|
||||
|
||||
returns the wave length in samples
|
||||
=============
|
||||
*/
|
||||
uint pfnGetApproxWavePlayLen( const char *filepath )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
pfnIsCareerMatch
|
||||
|
@ -4290,7 +4283,7 @@ static enginefuncs_t gEngfuncs =
|
|||
pfnSequenceGet,
|
||||
pfnSequencePickSentence,
|
||||
pfnGetFileSize,
|
||||
pfnGetApproxWavePlayLen,
|
||||
Sound_GetApproxWavePlayLen,
|
||||
pfnIsCareerMatch,
|
||||
pfnGetLocalizedStringLength,
|
||||
pfnRegisterTutorMessageShown,
|
||||
|
@ -4428,10 +4421,7 @@ parsing textual entity definitions out of an ent file.
|
|||
void SV_LoadFromFile( char *entities )
|
||||
{
|
||||
string token;
|
||||
int inhibited, spawned, died;
|
||||
int current_skill = Cvar_VariableInteger( "skill" ); // lock skill level
|
||||
qboolean inhibits_ents = (world.version == Q1BSP_VERSION) ? true : false;
|
||||
qboolean deathmatch = Cvar_VariableInteger( "deathmatch" );
|
||||
int inhibited, spawned;
|
||||
qboolean create_world = true;
|
||||
edict_t *ent;
|
||||
|
||||
|
@ -4439,7 +4429,6 @@ void SV_LoadFromFile( char *entities )
|
|||
|
||||
inhibited = 0;
|
||||
spawned = 0;
|
||||
died = 0;
|
||||
|
||||
// parse ents
|
||||
while(( entities = COM_ParseFile( entities, token )) != NULL )
|
||||
|
@ -4457,41 +4446,23 @@ void SV_LoadFromFile( char *entities )
|
|||
if( !SV_ParseEdict( &entities, ent ))
|
||||
continue;
|
||||
|
||||
// remove things from different skill levels or deathmatch
|
||||
if( inhibits_ents && deathmatch )
|
||||
if( svgame.dllFuncs.pfnSpawn( ent ) == -1 )
|
||||
{
|
||||
if( ent->v.spawnflags & (1<<11))
|
||||
// game rejected the spawn
|
||||
if( !( ent->v.flags & FL_KILLME ))
|
||||
{
|
||||
SV_FreeEdict( ent );
|
||||
inhibited++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if( inhibits_ents && current_skill == 0 && ent->v.spawnflags & (1<<8))
|
||||
{
|
||||
SV_FreeEdict( ent );
|
||||
inhibited++;
|
||||
continue;
|
||||
}
|
||||
else if( inhibits_ents && current_skill == 1 && ent->v.spawnflags & (1<<9))
|
||||
{
|
||||
SV_FreeEdict( ent );
|
||||
inhibited++;
|
||||
continue;
|
||||
}
|
||||
else if( inhibits_ents && current_skill >= 2 && ent->v.spawnflags & (1<<10))
|
||||
{
|
||||
SV_FreeEdict( ent );
|
||||
inhibited++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( svgame.dllFuncs.pfnSpawn( ent ) == -1 )
|
||||
died++;
|
||||
else spawned++;
|
||||
}
|
||||
|
||||
MsgDev( D_INFO, "\n%i entities inhibited\n", inhibited );
|
||||
|
||||
// reset world origin and angles
|
||||
VectorClear( svgame.edicts->v.origin );
|
||||
VectorClear( svgame.edicts->v.angles );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4511,6 +4482,7 @@ void SV_SpawnEntities( const char *mapname, char *entities )
|
|||
// reset misc parms
|
||||
Cvar_Reset( "sv_zmax" );
|
||||
Cvar_Reset( "sv_wateramp" );
|
||||
Cvar_Reset( "sv_wateralpha" );
|
||||
|
||||
// reset sky parms
|
||||
Cvar_Reset( "sv_skycolor_r" );
|
||||
|
|
|
@ -65,6 +65,7 @@ convar_t *sv_send_resources;
|
|||
convar_t *sv_send_logos;
|
||||
convar_t *sv_sendvelocity;
|
||||
convar_t *sv_airmove;
|
||||
convar_t *sv_fix_pushstep;
|
||||
convar_t *mp_consistency;
|
||||
convar_t *serverinfo;
|
||||
convar_t *physinfo;
|
||||
|
@ -78,6 +79,7 @@ convar_t *sv_skyvec_x;
|
|||
convar_t *sv_skyvec_y;
|
||||
convar_t *sv_skyvec_z;
|
||||
convar_t *sv_skyname;
|
||||
convar_t *sv_wateralpha;
|
||||
|
||||
void Master_Shutdown( void );
|
||||
|
||||
|
@ -225,6 +227,7 @@ void SV_UpdateMovevars( void )
|
|||
svgame.movevars.skyvec_z = sv_skyvec_z->value;
|
||||
svgame.movevars.studio_scale = sv_allow_studio_scaling->integer;
|
||||
svgame.movevars.clienttrace = sv_clienttrace->value;
|
||||
svgame.movevars.wateralpha = sv_wateralpha->value;
|
||||
|
||||
if( MSG_WriteDeltaMovevars( &sv.reliable_datagram, &svgame.oldmovevars, &svgame.movevars ))
|
||||
Q_memcpy( &svgame.oldmovevars, &svgame.movevars, sizeof( movevars_t )); // oldstate changed
|
||||
|
@ -650,6 +653,7 @@ void SV_Init( void )
|
|||
sv_skyvec_z = Cvar_Get ("sv_skyvec_z", "0", CVAR_PHYSICINFO, "sky direction z (hl1 compatibility)" );
|
||||
sv_skyname = Cvar_Get ("sv_skyname", "desert", CVAR_PHYSICINFO, "skybox name (can be dynamically changed in-game)" );
|
||||
sv_footsteps = Cvar_Get ("mp_footsteps", "1", CVAR_PHYSICINFO, "can hear footsteps from other players" );
|
||||
sv_wateralpha = Cvar_Get ("sv_wateralpha", "1", CVAR_PHYSICINFO, "world surfaces water transparency factor. 1.0 - solid, 0.0 - fully transparent" );
|
||||
|
||||
rcon_password = Cvar_Get( "rcon_password", "", 0, "remote connect password" );
|
||||
sv_stepsize = Cvar_Get( "sv_stepsize", "18", CVAR_ARCHIVE|CVAR_PHYSICINFO, "how high you can step up" );
|
||||
|
@ -693,6 +697,7 @@ void SV_Init( void )
|
|||
sv_send_logos = Cvar_Get( "sv_send_logos", "1", 0, "send custom player decals to other clients" );
|
||||
sv_send_resources = Cvar_Get( "sv_send_resources", "1", 0, "send generic resources that specified in 'mapname.res'" );
|
||||
sv_sendvelocity = Cvar_Get( "sv_sendvelocity", "1", CVAR_ARCHIVE, "force to send velocity for event_t structure across network" );
|
||||
sv_fix_pushstep = Cvar_Get( "sv_fix_pushstep", "0", CVAR_ARCHIVE, "allow the 'func_pushable' push the clients which standing on when the entity is floating in water" );
|
||||
mp_consistency = Cvar_Get( "mp_consistency", "1", CVAR_SERVERNOTIFY, "enbale consistency check in multiplayer" );
|
||||
clockwindow = Cvar_Get( "clockwindow", "0.5", 0, "timewindow to execute client moves" );
|
||||
sv_novis = Cvar_Get( "sv_novis", "0", 0, "force to ignore server visibility" );
|
||||
|
|
|
@ -1119,11 +1119,10 @@ void SV_Physics_Follow( edict_t *ent )
|
|||
parent = ent->v.aiment;
|
||||
if( !SV_IsValidEdict( parent )) return;
|
||||
|
||||
VectorAdd( parent->v.origin, parent->v.view_ofs, ent->v.origin );
|
||||
VectorAdd( parent->v.origin, parent->v.view_ofs, ent->v.v_angle );
|
||||
VectorCopy( parent->v.angles, ent->v.angles );
|
||||
|
||||
// noclip ents never touch triggers
|
||||
SV_LinkEdict( ent, false );
|
||||
SV_LinkEdict( ent, true );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1145,7 +1144,9 @@ void SV_Physics_Compound( edict_t *ent )
|
|||
|
||||
parent = ent->v.aiment;
|
||||
if( !SV_IsValidEdict( parent )) return;
|
||||
ent->v.solid = SOLID_NOT;
|
||||
|
||||
if( ent->v.solid != SOLID_TRIGGER )
|
||||
ent->v.solid = SOLID_NOT;
|
||||
|
||||
switch( parent->v.movetype )
|
||||
{
|
||||
|
@ -1185,8 +1186,8 @@ void SV_Physics_Compound( edict_t *ent )
|
|||
VectorAdd( ent->v.angles, amove, ent->v.angles );
|
||||
VectorAdd( ent->v.origin, lmove, ent->v.origin );
|
||||
|
||||
// noclip ents never touch triggers
|
||||
SV_LinkEdict( ent, false );
|
||||
// notsolid ents never touch triggers
|
||||
SV_LinkEdict( ent, (ent->v.solid == SOLID_NOT) ? false : true );
|
||||
|
||||
// shuffle states
|
||||
VectorCopy( parent->v.origin, ent->v.oldorigin );
|
||||
|
@ -1430,7 +1431,12 @@ void SV_Physics_Step( edict_t *ent )
|
|||
|
||||
if( inwater && ( ent->v.flags & FL_FLOAT ))
|
||||
{
|
||||
vec3_t lmove;
|
||||
int e, block;
|
||||
edict_t *check;
|
||||
|
||||
ent->v.flags |= FL_INWATER;
|
||||
VectorClear( lmove );
|
||||
|
||||
// floating pushables
|
||||
if( ent->v.waterlevel >= 2 )
|
||||
|
@ -1445,6 +1451,25 @@ void SV_Physics_Step( edict_t *ent )
|
|||
{
|
||||
ent->v.velocity[2] -= (ent->v.skin * host.frametime);
|
||||
}
|
||||
|
||||
if( sv_fix_pushstep->integer )
|
||||
{
|
||||
lmove[2] = (ent->v.skin * host.frametime);
|
||||
|
||||
// push the clients to avoid sticking in float items
|
||||
for( e = 1; e < svgame.globals->maxClients + 1; e++ )
|
||||
{
|
||||
check = EDICT_NUM( e );
|
||||
if( !SV_IsValidEdict( check )) continue;
|
||||
|
||||
if(( check->v.flags & FL_ONGROUND ) && check->v.groundentity == ent )
|
||||
{
|
||||
SV_PushEntity( check, lmove, vec3_origin, &block );
|
||||
check->v.groundentity = NULL;
|
||||
check->v.flags &= ~FL_ONGROUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( !wasonground )
|
||||
{
|
||||
|
|
|
@ -73,6 +73,8 @@ typedef struct
|
|||
float skyVec_y;
|
||||
float skyVec_z;
|
||||
int viewentity; // Xash3D added
|
||||
int serverflags; // converted to float and back
|
||||
float wateralpha;
|
||||
} SAVE_HEADER;
|
||||
|
||||
typedef struct
|
||||
|
@ -104,6 +106,8 @@ static TYPEDESCRIPTION gSaveHeader[] =
|
|||
DEFINE_FIELD( SAVE_HEADER, skyVec_y, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( SAVE_HEADER, skyVec_z, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( SAVE_HEADER, viewentity, FIELD_SHORT ),
|
||||
DEFINE_FIELD( SAVE_HEADER, serverflags, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( SAVE_HEADER, wateralpha, FIELD_FLOAT ),
|
||||
};
|
||||
|
||||
static TYPEDESCRIPTION gAdjacency[] =
|
||||
|
@ -703,6 +707,9 @@ void SV_SaveGameStateGlobals( SAVERESTOREDATA *pSaveData )
|
|||
}
|
||||
else header.viewentity = 1;
|
||||
|
||||
header.serverflags = (int)svgame.globals->serverflags;
|
||||
header.wateralpha = Cvar_VariableValue( "sv_wateralpha" );
|
||||
|
||||
pSaveData->time = 0; // prohibits rebase of header.time (why not just save time as a field_float and ditch this hack?)
|
||||
svgame.dllFuncs.pfnSaveWriteFields( pSaveData, "Save Header", &header, gSaveHeader, ARRAYSIZE( gSaveHeader ));
|
||||
pSaveData->time = header.time;
|
||||
|
@ -1175,6 +1182,11 @@ int SV_LoadGameState( char const *level, qboolean createPlayers )
|
|||
Cvar_SetFloat( "sv_skyvec_y", header.skyVec_y );
|
||||
Cvar_SetFloat( "sv_skyvec_z", header.skyVec_z );
|
||||
|
||||
// restore serverflags
|
||||
svgame.globals->serverflags = header.serverflags;
|
||||
|
||||
Cvar_SetFloat( "sv_wateralpha", header.wateralpha );
|
||||
|
||||
// re-base the savedata since we re-ordered the entity/table / restore fields
|
||||
SaveRestore_Rebase( pSaveData );
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ void SV_InitBoxHull( void )
|
|||
|
||||
box_planes[i].type = i>>1;
|
||||
box_planes[i].normal[i>>1] = 1;
|
||||
box_planes[i].signbits = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -176,9 +177,9 @@ hull_t *SV_HullForEntity( edict_t *ent, int hullNumber, vec3_t mins, vec3_t maxs
|
|||
}
|
||||
else
|
||||
{
|
||||
if( size[0] <= 36.0f )
|
||||
if( size[0] <= world.hull_sizes[1][0] )
|
||||
{
|
||||
if( size[2] <= 36.0f )
|
||||
if( size[2] <= world.hull_sizes[3][2] )
|
||||
hull = &model->hulls[3];
|
||||
else hull = &model->hulls[1];
|
||||
}
|
||||
|
@ -920,8 +921,7 @@ trace_t SV_TraceHull( edict_t *ent, int hullNum, const vec3_t start, vec3_t mins
|
|||
VectorLerp( start, trace.fraction, end, trace.endpos );
|
||||
|
||||
VectorCopy( trace.plane.normal, temp );
|
||||
Matrix4x4_TransformPositivePlane( matrix, temp, trace.plane.dist,
|
||||
trace.plane.normal, &trace.plane.dist );
|
||||
Matrix4x4_TransformPositivePlane( matrix, temp, trace.plane.dist, trace.plane.normal, &trace.plane.dist );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -48,11 +48,15 @@ Studio models are position independent, so the cache manager can move them.
|
|||
#define MAXSTUDIOCONTROLLERS 8 // max controllers per model
|
||||
#define MAXSTUDIOATTACHMENTS 4 // max attachments per model
|
||||
|
||||
// model global flags
|
||||
#define STUDIO_STATIC 0x0001 // model without anims
|
||||
#define STUDIO_RAGDOLL 0x0002 // ragdoll animation pose
|
||||
#define STUDIO_HAS_CHROME 0x0008 // if any of the textures have chrome on them
|
||||
|
||||
// client-side model flags
|
||||
#define STUDIO_ROCKET 0x0001 // leave a trail
|
||||
#define STUDIO_GRENADE 0x0002 // leave a trail
|
||||
#define STUDIO_GIB 0x0004 // leave a trail
|
||||
#define STUDIO_ROTATE 0x0008 // rotate (bonus items)
|
||||
#define STUDIO_TRACER 0x0010 // green split trail
|
||||
#define STUDIO_ZOMGIB 0x0020 // small blood trail
|
||||
#define STUDIO_TRACER2 0x0040 // orange split trail + rotate
|
||||
#define STUDIO_TRACER3 0x0080 // purple trail
|
||||
#define STUDIO_DYNAMIC_LIGHT 0x0100 // dynamically get lighting from floor or ceil (flying monsters)
|
||||
#define STUDIO_TRACE_HITBOX 0x0200 // always use hitbox trace instead of bbox
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ static void UI_CreateGame_Begin( void )
|
|||
if( CVAR_GET_FLOAT( "host_serverstate" ) && CVAR_GET_FLOAT( "maxplayers" ) == 1 )
|
||||
HOST_ENDGAME( "end of the game" );
|
||||
|
||||
CVAR_SET_FLOAT( "deathmatch", 1.0f ); // FIXME
|
||||
CVAR_SET_FLOAT( "deathmatch", 1.0f ); // start deathmatch as default
|
||||
CVAR_SET_FLOAT( "maxplayers", atoi( uiCreateGame.maxClients.buffer ));
|
||||
CVAR_SET_STRING( "hostname", uiCreateGame.hostName.buffer );
|
||||
CVAR_SET_STRING( "defaultmap", uiCreateGame.mapName[uiCreateGame.mapsList.curItem] );
|
||||
|
|
|
@ -235,7 +235,7 @@ int UI_FadeAlpha( int starttime, int endtime )
|
|||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
time = ( gpGlobals->time * 1000 ) - starttime; // FIXME; convert it to float properly
|
||||
time = ( gpGlobals->time * 1000 ) - starttime;
|
||||
|
||||
if( time >= endtime )
|
||||
{
|
||||
|
|
|
@ -42,6 +42,7 @@ struct movevars_s
|
|||
float skyvec_z; //
|
||||
qboolean studio_scale; // Allow engine to scale visible and physic hull of studiomodels
|
||||
float clienttrace; // Studiomodels scale that applied for the clients (visual effect only)
|
||||
float wateralpha; // World water alpha 1.0 - solid 0.0 - transparent
|
||||
};
|
||||
|
||||
extern movevars_t movevars;
|
||||
|
|
Reference in New Issue