16 Jan 2008

This commit is contained in:
g-cont 2008-01-16 00:00:00 +03:00 committed by Alibek Omarov
parent 3935504d65
commit c8c30eb43b
49 changed files with 929 additions and 825 deletions

View File

@ -11,18 +11,15 @@ fopen
возвращал.
// замеченные баги
1. SC_ParseToken вылетает при парсинге сейв-файла
2. viewer ничего не пишет в лог (сцуко)
3. По прежнему глюк с загрузкой спрайтов
4. скриншотам гамму вывернуть
1. viewer ничего не пишет в лог (сцуко)
2. Модели не рисуются для неотвизеных карт (даже самых мелких)
// из неоконченного
0. Приделать бы всем утилитам разные иконки
1. bounds checker для prvm_edict.c
2. snd encoder для roqlib
3. doom snd decoder для snddec
1. snd encoder для roqlib
2. doom snd decoder для snddec
Полная отладка network messaging, физики встроенной, физики на ньютоне
physic.dll
{
1. Вернуть квантизацию пространства в 0.125 юнита OK
2. поля в вирт машине для сохранения матрицы OK
@ -34,14 +31,25 @@ fopen
8. Придумать как развернуть меш на 90 грд OK
9. Пофиксить утечку памяти в cmodel OK
10.Найти все кластеры для карт без виза (рендер\сервер) OK
11.Перенести cmodel и pmove.c в physic.dll
11.Перенести cmodel в physic.dll OK
12.Подключить его к серверу и клиенту OK
13.Билдер коллижн мешей для бсп-моделей OK
14.Переписать трасинг
}
Создание sdk_main
{
0. переименовать папку в !sdk_main OK
1. подключить пользовательскую дллку к движку
2. иконки для всех экзешников
3. перенести qc код в sdk_main
}
//==================================================
// то, что уже готово
//==================================================
+скриншоты теперь учитывают текущую гамму
+освещение влияет на спрайты (кроме additive и glow)
+базовые форматы текстур - tga и dds. Другие типы не поддерживаются
+Запущены в строй lmpdec, mdldec, mipdec, snddec, sprdec

View File

@ -23,13 +23,8 @@ vec3_t illumination[MAX_PATCHES]; // light arriving at a patch
vec3_t face_offset[MAX_MAP_FACES]; // for rotating bmodels
dplane_t backplanes[MAX_MAP_PLANES];
char inbase[32], outbase[32];
int fakeplanes; // created planes for origin offset
int numbounce;
bool extrasamples;
float subdiv = 64;
void BuildLightmaps (void);
@ -37,6 +32,7 @@ int TestLine (vec3_t start, vec3_t stop);
int junk;
int numbounce = 3;
float ambient = 0;
float maxlight = 196;
float lightscale = 1.0;
@ -455,6 +451,7 @@ void RadWorld (void)
void WradMain ( bool option )
{
string cmdparm;
extrasamples = option;
if(!LoadBSPFile())
@ -468,13 +465,16 @@ void WradMain ( bool option )
if( extrasamples )
{
numbounce = 8;
ambient = 125; //FIXME: check result
if(FS_GetParmFromCmdLine("-ambient", cmdparm ))
ambient = com.atoi( cmdparm );
ambient = bound( 0, ambient, 512 );
}
else numbounce = 3;
if(FS_GetParmFromCmdLine("-bounce", cmdparm ))
numbounce = com.atoi( cmdparm );
numbounce = bound( 0, numbounce, 32 );
ParseEntities ();
CalcTextureReflectivity ();
ParseEntities();
CalcTextureReflectivity();
if (!visdatasize)
{

View File

@ -1196,7 +1196,7 @@ void CL_RequestNextDownload (void)
{
precache_check = ENV_CNT + 1;
CM_BeginRegistration( cl.configstrings[CS_MODELS+1], true, &map_checksum );
pe->BeginRegistration( cl.configstrings[CS_MODELS+1], true, &map_checksum );
if( map_checksum != com.atoi(cl.configstrings[CS_MAPCHECKSUM]))
{
Host_Error("Local map version differs from server: %i != '%s'\n", map_checksum, cl.configstrings[CS_MAPCHECKSUM]);
@ -1229,16 +1229,13 @@ void CL_RequestNextDownload (void)
// confirm existance of textures, download any that don't exist
if (precache_check == TEXTURE_CNT+1)
{
// from common/cmodel.c
extern mapsurface_t map_surfaces[];
if (allow_download->value && allow_download_maps->value)
{
while( precache_tex < CM_NumTexinfo())
while( precache_tex < pe->NumTextures())
{
char fn[MAX_OSPATH];
sprintf(fn, "textures/%s.tga", CM_TexName( precache_tex++ ));
sprintf(fn, "textures/%s.tga", pe->GetTextureName( precache_tex++ ));
if(!CL_CheckOrDownloadFile(fn)) return; // started a download
}
}
@ -1267,7 +1264,7 @@ void CL_Precache_f (void)
if(Cmd_Argc() < 2)
{
uint map_checksum; // for detecting cheater maps
CM_BeginRegistration( cl.configstrings[CS_MODELS+1], true, &map_checksum );
pe->BeginRegistration( cl.configstrings[CS_MODELS+1], true, &map_checksum );
CL_RegisterSounds();
CL_PrepRefresh();
return;

View File

@ -493,7 +493,7 @@ void CL_ParseConfigString (void)
{
cl.model_draw[i-CS_MODELS] = re->RegisterModel (cl.configstrings[i]);
if (cl.configstrings[i][0] == '*')
cl.model_clip[i-CS_MODELS] = CM_RegisterModel(cl.configstrings[i] );
cl.model_clip[i-CS_MODELS] = pe->RegisterModel(cl.configstrings[i] );
else cl.model_clip[i-CS_MODELS] = NULL;
}
}

View File

@ -105,14 +105,14 @@ void CL_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
bmins[2] = -zd;
bmaxs[2] = zu;
headnode = CM_HeadnodeForBox (bmins, bmaxs);
headnode = pe->HeadnodeForBox (bmins, bmaxs);
angles = vec3_origin; // boxes don't rotate
}
if (tr->allsolid)
return;
trace = CM_TransformedBoxTrace (start, end, mins, maxs, headnode, MASK_PLAYERSOLID, ent->origin, angles);
trace = pe->TransformedBoxTrace (start, end, mins, maxs, headnode, MASK_PLAYERSOLID, ent->origin, angles);
if (trace.allsolid || trace.startsolid ||
trace.fraction < tr->fraction)
@ -141,7 +141,7 @@ trace_t CL_PMTrace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
trace_t t;
// check against world
t = CM_BoxTrace (start, end, mins, maxs, 0, MASK_PLAYERSOLID);
t = pe->BoxTrace (start, end, mins, maxs, 0, MASK_PLAYERSOLID);
if (t.fraction < 1.0) t.ent = (edict_t *)1;
// check all other solid models
@ -158,7 +158,7 @@ int CL_PMpointcontents (vec3_t point)
cmodel_t *cmodel;
int contents;
contents = CM_PointContents (point, 0);
contents = pe->PointContents (point, 0);
for (i=0 ; i<cl.frame.num_entities ; i++)
{
@ -172,7 +172,7 @@ int CL_PMpointcontents (vec3_t point)
if (!cmodel)
continue;
contents |= CM_TransformedPointContents (point, cmodel->headnode, ent->origin, ent->angles);
contents |= pe->TransformedPointContents (point, cmodel->headnode, ent->origin, ent->angles);
}
return contents;

View File

@ -335,7 +335,7 @@ void CL_PrepRefresh( void )
Sys_SendKeyEvents(); // pump message loop
cl.model_draw[i] = re->RegisterModel( name );
if (name[0] == '*') cl.model_clip[i] = CM_RegisterModel( name );
if (name[0] == '*') cl.model_clip[i] = pe->RegisterModel( name );
else cl.model_clip[i] = NULL;//get studio models here?
Cvar_SetValue("scr_loading", scr_loading->value + 50.0f/mdlcount );
SCR_UpdateScreen();

View File

@ -193,7 +193,7 @@ typedef struct
// locally derived information from server state
//
model_t *model_draw[MAX_MODELS];
struct cmodel_s *model_clip[MAX_MODELS];
cmodel_t *model_clip[MAX_MODELS];
sound_t sound_precache[MAX_SOUNDS];
image_t *image_precache[MAX_IMAGES];
@ -288,6 +288,19 @@ extern client_static_t cls;
//=============================================================================
// console color typeing
static vec4_t g_color_table[8] =
{
{0.0, 0.0, 0.0, 1.0},
{1.0, 0.0, 0.0, 1.0},
{0.0, 1.0, 0.0, 1.0},
{1.0, 1.0, 0.0, 1.0},
{0.0, 0.0, 1.0, 1.0},
{0.0, 1.0, 1.0, 1.0},
{1.0, 0.0, 1.0, 1.0},
{1.0, 1.0, 1.0, 1.0},
};
//
// cvars
//

View File

@ -27,37 +27,6 @@
#define PMF_TIME_TELEPORT 32 // pm_time is non-moving time
#define PMF_NO_PREDICTION 64 // temporarily disables prediction (used for grappling hook)
cmodel_t *CM_BeginRegistration( const char *name, bool clientload, uint *checksum );
cmodel_t *CM_RegisterModel( const char *name );
void CM_EndRegistration( void );
void CM_FreeModels( void );
void CM_FreeWorld( void );
int CM_NumClusters (void);
int CM_NumTexinfo( void );
int CM_NumInlineModels (void);
char *CM_EntityString (void);
char *CM_TexName( int index );
int CM_HeadnodeForBox (vec3_t mins, vec3_t maxs);
int CM_PointContents (vec3_t p, int headnode);
const char *CM_GetStringFromTable( int index );
int CM_TransformedPointContents (vec3_t p, int headnode, vec3_t origin, vec3_t angles);
trace_t CM_BoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int headnode, int brushmask);
trace_t CM_TransformedBoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int headnode, int brushmask, vec3_t origin, vec3_t angles);
byte *CM_ClusterPVS (int cluster);
byte *CM_ClusterPHS (int cluster);
int CM_PointLeafnum (vec3_t p);
int CM_BoxLeafnums (vec3_t mins, vec3_t maxs, int *list, int listsize, int *topnode);
int CM_LeafContents (int leafnum);
int CM_LeafCluster (int leafnum);
int CM_LeafArea (int leafnum);
void CM_SetAreaPortalState (int portalnum, bool open);
bool CM_AreasConnected (int area1, int area2);
int CM_WriteAreaBits (byte *buffer, int area);
bool CM_HeadnodeVisible (int headnode, byte *visbits);
void CM_InitBoxHull (void);
void CM_FloodAreaConnections (void);
extern byte portalopen[MAX_MAP_AREAPORTALS];
/*
==============================================================

View File

@ -57,8 +57,8 @@ LINK32=link.exe
# ADD LINK32 winmm.lib user32.lib msvcrt.lib ole32.lib /nologo /subsystem:windows /dll /pdb:none /machine:I386 /nodefaultlib:"libc.lib" /opt:nowin98
# SUBTRACT LINK32 /debug /nodefaultlib
# Begin Custom Build
TargetDir=\XASH3D\src_main\!source\temp\engine\!release
InputPath=\XASH3D\src_main\!source\temp\engine\!release\engine.dll
TargetDir=\XASH3D\src_main\temp\engine\!release
InputPath=\XASH3D\src_main\temp\engine\!release\engine.dll
SOURCE="$(InputPath)"
"D:\Xash3D\bin\engine.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
@ -94,8 +94,8 @@ LINK32=link.exe
# ADD LINK32 winmm.lib user32.lib msvcrt.lib ole32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"msvcrtd.lib" /pdbtype:sept
# SUBTRACT LINK32 /incremental:no /map /nodefaultlib
# Begin Custom Build
TargetDir=\XASH3D\src_main\!source\temp\engine\!debug
InputPath=\XASH3D\src_main\!source\temp\engine\!debug\engine.dll
TargetDir=\XASH3D\src_main\temp\engine\!debug
InputPath=\XASH3D\src_main\temp\engine\!debug\engine.dll
SOURCE="$(InputPath)"
"D:\Xash3D\bin\engine.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
@ -178,10 +178,6 @@ SOURCE=.\client\cl_view.c
# End Source File
# Begin Source File
SOURCE=.\cmodel.c
# End Source File
# Begin Source File
SOURCE=.\common.c
# End Source File
# Begin Source File

View File

@ -18,8 +18,6 @@ stdlib_api_t com, newcom;
byte *zonepool;
char *buildstring = __TIME__ " " __DATE__;
//void Key_Init (void);
dll_info_t physic_dll = { "physic.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(physic_exp_t) };
dll_info_t render_dll = { "render.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(render_exp_t) };

View File

@ -188,7 +188,6 @@ typedef struct
char mapcmd[MAX_TOKEN_CHARS]; // ie: *intro.cin+base
char comment[MAX_TOKEN_CHARS]; // map name, e.t.c.
byte portalopen[MAX_MAP_AREAPORTALS];
int spawncount; // incremented each server start
// used to check late spawns
@ -328,7 +327,7 @@ void SV_SetMassCentre( edict_t *ent);
//
// sv_studio.c
//
byte *SV_GetModelPtr( edict_t *ent );
cmodel_t *SV_GetModelPtr( edict_t *ent );
float *SV_GetModelVerts( sv_edict_t *ent, int *numvertices );
int SV_StudioExtractBbox( studiohdr_t *phdr, int sequence, float *mins, float *maxs );
bool SV_CreateMeshBuffer( edict_t *in, cmodel_t *out );
@ -336,7 +335,7 @@ bool SV_CreateMeshBuffer( edict_t *in, cmodel_t *out );
//
// sv_spawn.c
//
void SV_SpawnEntities (char *mapname, char *entities);
void SV_SpawnEntities( const char *mapname, const char *entities );
void SV_StartParticle (vec3_t org, vec3_t dir, int color, int count);
void SV_Transform( sv_edict_t *ed, matrix4x3 transform );
void SV_FreeEdict (edict_t *ed);

View File

@ -365,14 +365,14 @@ void SV_FatPVS (vec3_t org)
maxs[i] = org[i] + SV_COORD_FRAC;
}
count = CM_BoxLeafnums (mins, maxs, leafs, 64, NULL);
count = pe->BoxLeafnums (mins, maxs, leafs, 64, NULL);
if (count < 1) Host_Error("SV_FatPVS: count < 1\n");
longs = (CM_NumClusters()+31)>>5;
longs = (pe->NumClusters()+31)>>5;
// convert leafs to clusters
for (i = 0; i < count; i++) leafs[i] = CM_LeafCluster(leafs[i]);
for (i = 0; i < count; i++) leafs[i] = pe->LeafCluster(leafs[i]);
Mem_Copy(fatpvs, CM_ClusterPVS(leafs[0]), longs<<2);
Mem_Copy(fatpvs, pe->ClusterPVS(leafs[0]), longs<<2);
// or in all the other leaf bits
for (i = 1; i < count; i++)
@ -383,7 +383,7 @@ void SV_FatPVS (vec3_t org)
break;
}
if (j != i) continue; // already have the cluster we want
src = CM_ClusterPVS(leafs[i]);
src = pe->ClusterPVS(leafs[i]);
for (j = 0; j < longs; j++) ((long *)fatpvs)[j] |= ((long *)src)[j];
}
}
@ -424,18 +424,18 @@ void SV_BuildClientFrame (client_state_t *client)
VectorScale( clent->priv.sv->client->ps.pmove.origin, CL_COORD_FRAC, org );
VectorAdd( org, clent->priv.sv->client->ps.viewoffset, org );
leafnum = CM_PointLeafnum (org);
clientarea = CM_LeafArea (leafnum);
clientcluster = CM_LeafCluster (leafnum);
leafnum = pe->PointLeafnum (org);
clientarea = pe->LeafArea (leafnum);
clientcluster = pe->LeafCluster (leafnum);
// calculate the visible areas
frame->areabytes = CM_WriteAreaBits (frame->areabits, clientarea);
frame->areabytes = pe->WriteAreaBits (frame->areabits, clientarea);
// grab the current player_state_t
frame->ps = clent->priv.sv->client->ps;
SV_FatPVS (org);
clientphs = CM_ClusterPHS (clientcluster);
clientphs = pe->ClusterPHS (clientcluster);
// build up the list of visible entities
frame->num_entities = 0;
@ -455,11 +455,11 @@ void SV_BuildClientFrame (client_state_t *client)
if (ent != clent)
{
// check area
if (!CM_AreasConnected (clientarea, ent->priv.sv->areanum))
if (!pe->AreasConnected (clientarea, ent->priv.sv->areanum))
{
// doors can legally straddle two areas, so
// we may need to check another one
if (!ent->priv.sv->areanum2 || !CM_AreasConnected (clientarea, ent->priv.sv->areanum2))
if (!ent->priv.sv->areanum2 || !pe->AreasConnected (clientarea, ent->priv.sv->areanum2))
continue; // blocked by a door
}
@ -483,7 +483,7 @@ void SV_BuildClientFrame (client_state_t *client)
if (ent->priv.sv->num_clusters == -1)
{
// too many leafs for individual check, go by headnode
if (!CM_HeadnodeVisible (ent->priv.sv->headnode, bitvector))
if (!pe->HeadnodeVisible (ent->priv.sv->headnode, bitvector))
continue;
c_fullsend++;
}

View File

@ -194,22 +194,22 @@ void SV_SpawnServer (char *server, char *savename, sv_state_t serverstate )
if (serverstate != ss_game)
{
sv.models[1] = CM_BeginRegistration("", false, &checksum); // no real map
sv.models[1] = pe->BeginRegistration("", false, &checksum); // no real map
}
else
{
sprintf(sv.configstrings[CS_MODELS+1], "maps/%s", server);
sv.models[1] = CM_BeginRegistration(sv.configstrings[CS_MODELS+1], false, &checksum);
sv.models[1] = pe->BeginRegistration(sv.configstrings[CS_MODELS+1], false, &checksum);
}
sprintf(sv.configstrings[CS_MAPCHECKSUM], "%i", checksum);
// clear physics interaction links
SV_ClearWorld();
for (i = 1; i < CM_NumInlineModels(); i++)
for (i = 1; i < pe->NumBmodels(); i++)
{
sprintf( sv.configstrings[CS_MODELS+1+i], "*%i", i );
sv.models[i+1] = CM_RegisterModel(sv.configstrings[CS_MODELS+1+i] );
sv.models[i+1] = pe->RegisterModel(sv.configstrings[CS_MODELS+1+i] );
}
//
@ -225,7 +225,7 @@ void SV_SpawnServer (char *server, char *savename, sv_state_t serverstate )
SV_CheckForSavegame( savename );
if(sv.loadgame) SV_ReadLevelFile( savename );
else SV_SpawnEntities ( sv.name, CM_EntityString());
else SV_SpawnEntities ( sv.name, pe->GetEntityString());
// run two frames to allow everything to settle
SV_RunFrame();
@ -240,7 +240,7 @@ void SV_SpawnServer (char *server, char *savename, sv_state_t serverstate )
// set serverinfo variable
Cvar_FullSet("mapname", sv.name, CVAR_SERVERINFO | CVAR_INIT);
CM_EndRegistration(); // free unused models
pe->EndRegistration(); // free unused models
SV_VM_End();
}

View File

@ -110,6 +110,8 @@ void SV_WriteSaveFile( char *name )
dsavehdr_t *header;
file_t *savfile;
bool autosave = false;
byte *portalopen = Z_Malloc( MAX_MAP_AREAPORTALS );
int portalsize;
if(sv.state != ss_game) return;
if(Cvar_VariableValue("deathmatch"))
@ -122,7 +124,7 @@ void SV_WriteSaveFile( char *name )
MsgDev(D_ERROR, "SV_WriteSaveFile: can't savegame while dead!\n");
return;
}
if(!com.strcmp(name, "save0.bin")) autosave = true;
sprintf (path, "save/%s", name );
savfile = FS_Open( path, "wb");
@ -142,9 +144,10 @@ void SV_WriteSaveFile( char *name )
FS_Write( savfile, header, sizeof(dsavehdr_t));
// write lumps
pe->GetAreaPortals( &portalopen, &portalsize );
SV_AddSaveLump( header, savfile, LUMP_COMMENTS, comment, sizeof(comment));
SV_AddCStrLump( header, savfile );
SV_AddSaveLump( header, savfile, LUMP_AREASTATE, svs.portalopen, sizeof(svs.portalopen));
SV_AddCStrLump( header, savfile );
SV_AddSaveLump( header, savfile, LUMP_AREASTATE, portalopen, portalsize );
SV_WriteGlobal( header, savfile );
SV_AddSaveLump( header, savfile, LUMP_MAPNAME, svs.mapcmd, sizeof(svs.mapcmd));
SV_AddCvarLump( header, savfile );
@ -154,6 +157,7 @@ void SV_WriteSaveFile( char *name )
FS_Seek( savfile, 0, SEEK_SET );
FS_Write( savfile, header, sizeof(dsavehdr_t));
FS_Close( savfile );
Z_Free( portalopen);
Z_Free( header );
MsgDev(D_INFO, "done.\n");
}
@ -225,8 +229,7 @@ void Sav_LoadAreaPortals( lump_t *l )
if (l->filelen % sizeof(*in)) Host_Error("Sav_LoadAreaPortals: funny lump size\n" );
size = l->filelen / sizeof(*in);
Mem_Copy(svs.portalopen, in, size);
CM_FloodAreaConnections();
pe->SetAreaPortals( in, size );
}
void Sav_LoadGlobal( lump_t *l )

View File

@ -189,19 +189,19 @@ void _MSG_Send (msgtype_t to, vec3_t origin, edict_t *ent, const char *filename,
reliable = true; // intentional fallthrough
case MSG_PHS:
if(origin == NULL) return;
leafnum = CM_PointLeafnum (origin);
cluster = CM_LeafCluster (leafnum);
mask = CM_ClusterPHS (cluster);
area1 = CM_LeafArea (leafnum);
leafnum = pe->PointLeafnum (origin);
cluster = pe->LeafCluster (leafnum);
mask = pe->ClusterPHS (cluster);
area1 = pe->LeafArea (leafnum);
break;
case MSG_PVS_R:
reliable = true; // intentional fallthrough
case MSG_PVS:
if(origin == NULL) return;
leafnum = CM_PointLeafnum (origin);
cluster = CM_LeafCluster (leafnum);
mask = CM_ClusterPVS (cluster);
area1 = CM_LeafArea (leafnum);
leafnum = pe->PointLeafnum (origin);
cluster = pe->LeafCluster (leafnum);
mask = pe->ClusterPVS (cluster);
area1 = pe->LeafArea (leafnum);
break;
case MSG_ONE_R:
reliable = true; // intentional fallthrough
@ -225,10 +225,10 @@ void _MSG_Send (msgtype_t to, vec3_t origin, edict_t *ent, const char *filename,
if (mask)
{
area2 = CM_LeafArea (leafnum);
cluster = CM_LeafCluster (leafnum);
leafnum = CM_PointLeafnum (client->edict->progs.sv->origin);
if (!CM_AreasConnected (area1, area2)) continue;
area2 = pe->LeafArea (leafnum);
cluster = pe->LeafCluster (leafnum);
leafnum = pe->PointLeafnum (client->edict->progs.sv->origin);
if (!pe->AreasConnected (area1, area2)) continue;
if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7))))) continue;
}

View File

@ -89,7 +89,7 @@ Creates a server's entity / program execution context by
parsing textual entity definitions out of an ent file.
==============
*/
void SV_SpawnEntities (char *mapname, char *entities)
void SV_SpawnEntities( const char *mapname, const char *entities )
{
edict_t *ent;
int i;

View File

@ -6,31 +6,28 @@
#include "engine.h"
#include "server.h"
byte *SV_GetModelPtr( edict_t *ent )
cmodel_t *SV_GetModelPtr( edict_t *ent )
{
cmodel_t *cmod;
cmod = CM_RegisterModel( sv.configstrings[CS_MODELS + (int)ent->progs.sv->modelindex] );
if(!cmod || !cmod->extradata)
return NULL;
return cmod->extradata;
return pe->RegisterModel( sv.configstrings[CS_MODELS + (int)ent->progs.sv->modelindex] );
}
float *SV_GetModelVerts( sv_edict_t *ed, int *numvertices )
{
cmodel_t *cmod;
edict_t *ent;
int i;
ent = PRVM_EDICT_NUM(ed->serialnumber);
i = (int)ent->progs.sv->body;
cmod = CM_RegisterModel( sv.configstrings[CS_MODELS + (int)ent->progs.sv->modelindex] );
if( cmod && cmod->physmesh[i].verts )
cmod = pe->RegisterModel( sv.configstrings[CS_MODELS + (int)ent->progs.sv->modelindex] );
if( cmod )
{
*numvertices = cmod->physmesh[i].numverts;
return (float *)cmod->physmesh[i].verts;
int i = (int)ent->progs.sv->body;
i = bound( 0, i, cmod->numbodies ); // make sure what body exist
if( cmod->physmesh[i].verts )
{
*numvertices = cmod->physmesh[i].numverts;
return (float *)cmod->physmesh[i].verts;
}
}
return NULL;
}

View File

@ -127,7 +127,7 @@ void SV_SetModel (edict_t *ent, const char *name)
ent->progs.sv->model = PRVM_SetEngineString( sv.configstrings[CS_MODELS+i] );
ent->progs.sv->modelindex = i;
mod = CM_RegisterModel( name );
mod = pe->RegisterModel( name );
if( mod ) SV_SetMinMaxSize( ent, mod->mins, mod->maxs, false );
// FIXME: translate angles correctly
@ -310,20 +310,20 @@ void PF_inpvs ( void )
p1 = PRVM_G_VECTOR(OFS_PARM0);
p2 = PRVM_G_VECTOR(OFS_PARM1);
leafnum = CM_PointLeafnum (p1);
cluster = CM_LeafCluster (leafnum);
area1 = CM_LeafArea (leafnum);
mask = CM_ClusterPVS (cluster);
leafnum = pe->PointLeafnum (p1);
cluster = pe->LeafCluster (leafnum);
area1 = pe->LeafArea (leafnum);
mask = pe->ClusterPVS (cluster);
leafnum = CM_PointLeafnum (p2);
cluster = CM_LeafCluster (leafnum);
area2 = CM_LeafArea (leafnum);
leafnum = pe->PointLeafnum (p2);
cluster = pe->LeafCluster (leafnum);
area2 = pe->LeafArea (leafnum);
if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)))))
{
PRVM_G_FLOAT(OFS_RETURN) = 0;
}
else if (!CM_AreasConnected (area1, area2))
else if (!pe->AreasConnected (area1, area2))
{
PRVM_G_FLOAT(OFS_RETURN) = 0; // a door blocks sight
}
@ -347,20 +347,20 @@ void PF_inphs (void)
p1 = PRVM_G_VECTOR(OFS_PARM0);
p2 = PRVM_G_VECTOR(OFS_PARM1);
leafnum = CM_PointLeafnum (p1);
cluster = CM_LeafCluster (leafnum);
area1 = CM_LeafArea (leafnum);
mask = CM_ClusterPHS (cluster);
leafnum = pe->PointLeafnum (p1);
cluster = pe->LeafCluster (leafnum);
area1 = pe->LeafArea (leafnum);
mask = pe->ClusterPHS (cluster);
leafnum = CM_PointLeafnum (p2);
cluster = CM_LeafCluster (leafnum);
area2 = CM_LeafArea (leafnum);
leafnum = pe->PointLeafnum (p2);
cluster = pe->LeafCluster (leafnum);
area2 = pe->LeafArea (leafnum);
if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)))))
{
PRVM_G_FLOAT(OFS_RETURN) = 0; // more than one bounce away
}
else if (!CM_AreasConnected (area1, area2))
else if (!pe->AreasConnected (area1, area2))
{
PRVM_G_FLOAT(OFS_RETURN) = 0; // a door blocks hearing
}
@ -878,7 +878,7 @@ void PF_configstring( void )
void PF_areaportalstate( void )
{
CM_SetAreaPortalState((int)PRVM_G_FLOAT(OFS_PARM0), (bool)PRVM_G_FLOAT(OFS_PARM1));
pe->SetAreaPortalState((int)PRVM_G_FLOAT(OFS_PARM0), (bool)PRVM_G_FLOAT(OFS_PARM1));
}
/*

View File

@ -238,13 +238,13 @@ void SV_LinkEdict (edict_t *ent)
ent->priv.sv->areanum2 = 0;
//get all leafs, including solids
num_leafs = CM_BoxLeafnums (ent->progs.sv->absmin, ent->progs.sv->absmax, leafs, MAX_TOTAL_ENT_LEAFS, &topnode);
num_leafs = pe->BoxLeafnums (ent->progs.sv->absmin, ent->progs.sv->absmax, leafs, MAX_TOTAL_ENT_LEAFS, &topnode);
// set areas
for (i = 0; i < num_leafs; i++)
{
clusters[i] = CM_LeafCluster (leafs[i]);
area = CM_LeafArea (leafs[i]);
clusters[i] = pe->LeafCluster (leafs[i]);
area = pe->LeafArea (leafs[i]);
if (area)
{ // doors may legally straggle two areas,
// but nothing should evern need more than that
@ -399,7 +399,7 @@ int SV_PointContents (vec3_t p)
float *angles;
// get base contents from world
contents = CM_PointContents (p, sv.models[1]->headnode);
contents = pe->PointContents (p, sv.models[1]->headnode);
// or in contents from all the other entities
num = SV_AreaEdicts (p, p, touch, MAX_EDICTS, AREA_SOLID);
@ -412,7 +412,7 @@ int SV_PointContents (vec3_t p)
headnode = SV_HullForEntity (hit);
angles = hit->progs.sv->angles;
if (hit->progs.sv->solid != SOLID_BSP) angles = vec3_origin; // boxes don't rotate
c2 = CM_TransformedPointContents (p, headnode, hit->progs.sv->origin, hit->progs.sv->angles);
c2 = pe->TransformedPointContents (p, headnode, hit->progs.sv->origin, hit->progs.sv->angles);
contents |= c2;
}
return contents;
@ -463,7 +463,7 @@ int SV_HullForEntity (edict_t *ent)
}
// create a temp hull from bounding box sizes
return CM_HeadnodeForBox (ent->progs.sv->mins, ent->progs.sv->maxs);
return pe->HeadnodeForBox (ent->progs.sv->mins, ent->progs.sv->maxs);
}
/*
@ -508,11 +508,11 @@ void SV_ClipMoveToEntities ( moveclip_t *clip )
if ((int)touch->progs.sv->flags & FL_MONSTER)
{
trace = CM_TransformedBoxTrace (clip->start, clip->end, clip->mins2, clip->maxs2, headnode, clip->contentmask, touch->progs.sv->origin, angles);
trace = pe->TransformedBoxTrace (clip->start, clip->end, clip->mins2, clip->maxs2, headnode, clip->contentmask, touch->progs.sv->origin, angles);
}
else
{
trace = CM_TransformedBoxTrace (clip->start, clip->end, clip->mins, clip->maxs, headnode, clip->contentmask, touch->progs.sv->origin, angles);
trace = pe->TransformedBoxTrace (clip->start, clip->end, clip->mins, clip->maxs, headnode, clip->contentmask, touch->progs.sv->origin, angles);
}
if (trace.allsolid || trace.startsolid || trace.fraction < clip->trace.fraction)
{
@ -573,7 +573,7 @@ trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *p
memset ( &clip, 0, sizeof ( moveclip_t ) );
// clip to world
clip.trace = CM_BoxTrace (start, end, mins, maxs, 0, contentmask);
clip.trace = pe->BoxTrace (start, end, mins, maxs, 0, contentmask);
clip.trace.ent = prog->edicts;
if (clip.trace.fraction == 0) return clip.trace; // blocked by the world
@ -636,5 +636,5 @@ trace_t SV_TraceToss (edict_t *tossent, edict_t *ignore)
trace_t SV_ClipMoveToEntity(edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int contentsmask)
{
return CM_BoxTrace(start, end, mins, maxs, ent->priv.sv->headnode, contentsmask);
return pe->BoxTrace(start, end, mins, maxs, ent->priv.sv->headnode, contentsmask);
}

View File

@ -16,7 +16,7 @@ default: $(MAINTARGET).exe
$(MAINTARGET).exe: $(MAINTARGET).obj bsplib.res
$(link) $(OBJS) bsplib.res /out:"bsplib.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp $(MAINTARGET).res > nul
@copy $(MAINTARGET).exe D:\Xash3D\bin\$(MAINTARGET).exe
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
@del $(MAINTARGET).exe
@echo ‘Ş®Ż¨ŕ®˘ ­® ä ©«®˘: 1.
clean:

View File

@ -13,8 +13,9 @@ FILE *logfile;
dll_info_t common_dll = { "common.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(launch_exp_t) };
dll_info_t engine_dll = { "engine.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(launch_exp_t) };
dll_info_t editor_dll = { "viewer.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(launch_exp_t) };
dll_info_t viewer_dll = { "viewer.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(launch_exp_t) };
dll_info_t ripper_dll = { "ripper.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(launch_exp_t) };
dll_info_t custom_dll = { "custom.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(launch_exp_t) };
static const char *show_credits = "\n\n\n\n\tCopyright XashXT Group 2007 ©\n\t\
All Rights Reserved\n\n\t Visit www.xash.ru\n";
@ -248,8 +249,8 @@ void Sys_LookupInstance( void )
Sys.con_readonly = true;
//don't show console as default
if(!Sys.debug) Sys.con_showalways = false;
Sys.linked_dll = &editor_dll; // pointer to editor.dll info
com_strcpy(Sys.log_path, "viewer.log" ); // xash3d root directory
Sys.linked_dll = &viewer_dll; // pointer to viewer.dll info
Sys.log_active = Sys.developer = Sys.debug = 0; // clear all dbg states
com_strcpy(Sys.caption, va("Xash3D Resource Viewer ver.%g", XASH_VERSION ));
}
else if(!com_strcmp(Sys.progname, "splash"))
@ -365,6 +366,19 @@ void Sys_LookupInstance( void )
com_sprintf(Sys.log_path, "%s/source.log", sys_rootdir ); // default
com_strcpy(Sys.caption, va("QuakeC Decompiler ver.%g", XASH_VERSION ));
}
else if(!com_strcmp(Sys.progname, "sdklib"))
{
string szTemp;
// extract caption from exe-name
if(GetModuleFileName( NULL, szTemp, MAX_STRING ))
FS_FileBase( szTemp, Sys.caption );
else com_strcpy( Sys.caption, "Xash Generic Compiler" );
Sys.app_name = COMP_SDKLIB;
Sys.con_readonly = true;
Sys.linked_dll = &custom_dll; // pointer to custom.dll info
com_sprintf(Sys.log_path, "%s/result.log", sys_rootdir ); // default
}
}
/*
@ -391,6 +405,7 @@ void Sys_CreateInstance( void )
case COMP_SPRITE:
case COMP_STUDIO:
case COMP_WADLIB:
case COMP_SDKLIB:
case RIPP_MIPDEC:
case RIPP_SPRDEC:
case RIPP_MDLDEC:
@ -441,6 +456,7 @@ void Sys_CreateInstance( void )
case COMP_SPRITE:
case COMP_STUDIO:
case COMP_WADLIB:
case COMP_SDKLIB:
case RIPP_MIPDEC:
case RIPP_SPRDEC:
case RIPP_MDLDEC:

View File

@ -16,7 +16,7 @@ default: $(MAINTARGET).exe
$(MAINTARGET).exe: $(MAINTARGET).obj xash.res
$(link) $(OBJS) xash.res /out:"xash.exe" /subsystem:windows /opt:nowin98 /nodefaultlib:"libc.lib"
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp $(MAINTARGET).res > nul
@copy $(MAINTARGET).exe D:\Xash3D\#xash.exe
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\#xash.exe
@del $(MAINTARGET).exe
@echo ‘Ş®Ż¨ŕ®˘ ­® ä ©«®˘: 1.
clean:

View File

@ -16,7 +16,7 @@ default: $(MAINTARGET).exe
$(MAINTARGET).exe: $(MAINTARGET).obj lmpdec.res
$(link) $(OBJS) lmpdec.res /out:"lmpdec.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp $(MAINTARGET).res > nul
@copy $(MAINTARGET).exe D:\Xash3D\bin\$(MAINTARGET).exe
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
@del $(MAINTARGET).exe
@echo ‘Ş®Ż¨ŕ®˘ ­® ä ©«®˘: 1.
clean:

View File

@ -16,7 +16,7 @@ default: $(MAINTARGET).exe
$(MAINTARGET).exe: $(MAINTARGET).obj mdldec.res
$(link) $(OBJS) mdldec.res /out:"mdldec.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp $(MAINTARGET).res > nul
@copy $(MAINTARGET).exe D:\Xash3D\bin\$(MAINTARGET).exe
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
@del $(MAINTARGET).exe
@echo ‘Ş®Ż¨ŕ®˘ ­® ä ©«®˘: 1.
clean:

View File

@ -15,7 +15,7 @@ default: $(MAINTARGET).exe
$(MAINTARGET).exe: $(MAINTARGET).obj
$(link) $(OBJS) /out:"mipdec.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp > nul
@copy $(MAINTARGET).exe D:\Xash3D\bin\$(MAINTARGET).exe
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
@del $(MAINTARGET).exe
@echo ‘Ş®Ż¨ŕ®˘ ­® ä ©«®˘: 1.
clean:

View File

@ -16,7 +16,7 @@ default: $(MAINTARGET).exe
$(MAINTARGET).exe: $(MAINTARGET).obj qccdec.res
$(link) $(OBJS) qccdec.res /out:"qccdec.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp $(MAINTARGET).res > nul
@copy $(MAINTARGET).exe D:\Xash3D\bin\$(MAINTARGET).exe
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
@del $(MAINTARGET).exe
@echo ‘Ş®Ż¨ŕ®˘ ­® ä ©«®˘: 1.
clean:

View File

@ -16,7 +16,7 @@ default: $(MAINTARGET).exe
$(MAINTARGET).exe: $(MAINTARGET).obj qcclib.res
$(link) $(OBJS) qcclib.res /out:"qcclib.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp $(MAINTARGET).res > nul
@copy $(MAINTARGET).exe D:\Xash3D\bin\$(MAINTARGET).exe
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
@del $(MAINTARGET).exe
@echo ‘Ş®Ż¨ŕ®˘ ­® ä ©«®˘: 1.
clean:

View File

@ -15,7 +15,7 @@ default: $(MAINTARGET).exe
$(MAINTARGET).exe: $(MAINTARGET).obj
$(link) $(OBJS) /out:"roqlib.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp > nul
@copy $(MAINTARGET).exe D:\Xash3D\bin\$(MAINTARGET).exe
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
@del $(MAINTARGET).exe
@echo ‘Ş®Ż¨ŕ®˘ ­® ä ©«®˘: 1.
clean:

View File

@ -16,7 +16,7 @@ default: $(MAINTARGET).exe
$(MAINTARGET).exe: $(MAINTARGET).obj snddec.res
$(link) $(OBJS) snddec.res /out:"snddec.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp $(MAINTARGET).res > nul
@copy $(MAINTARGET).exe D:\Xash3D\bin\$(MAINTARGET).exe
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
@del $(MAINTARGET).exe
@echo ‘Ş®Ż¨ŕ®˘ ­® ä ©«®˘: 1.
clean:

View File

@ -16,7 +16,7 @@ default: $(MAINTARGET).exe
$(MAINTARGET).exe: $(MAINTARGET).obj sprdec.res
$(link) $(OBJS) sprdec.res /out:"sprdec.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp $(MAINTARGET).res > nul
@copy $(MAINTARGET).exe D:\Xash3D\bin\$(MAINTARGET).exe
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
@del $(MAINTARGET).exe
@echo ‘Ş®Ż¨ŕ®˘ ­® ä ©«®˘: 1.
clean:

View File

@ -15,7 +15,7 @@ default: $(MAINTARGET).exe
$(MAINTARGET).exe: $(MAINTARGET).obj
$(link) $(OBJS) /out:"spritegen.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp > nul
@copy $(MAINTARGET).exe D:\Xash3D\bin\$(MAINTARGET).exe
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
@del $(MAINTARGET).exe
@echo ‘Ş®Ż¨ŕ®˘ ­® ä ©«®˘: 1.
clean:

View File

@ -15,7 +15,7 @@ default: $(MAINTARGET).exe
$(MAINTARGET).exe: $(MAINTARGET).obj
$(link) $(OBJS) /out:"studiomdl.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp > nul
@copy $(MAINTARGET).exe D:\Xash3D\bin\$(MAINTARGET).exe
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
@del $(MAINTARGET).exe
@echo ‘Ş®Ż¨ŕ®˘ ­® ä ©«®˘: 1.
clean:

View File

@ -16,7 +16,7 @@ default: $(MAINTARGET).exe
$(MAINTARGET).exe: $(MAINTARGET).obj viewer.res
$(link) $(OBJS) viewer.res /out:"viewer.exe" /subsystem:windows /opt:nowin98 /nodefaultlib:"libc.lib"
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp $(MAINTARGET).res > nul
@copy $(MAINTARGET).exe D:\Xash3D\$(MAINTARGET).exe
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
@del $(MAINTARGET).exe
@echo ‘Ş®Ż¨ŕ®˘ ­® ä ©«®˘: 1.
clean:

View File

@ -15,7 +15,7 @@ default: $(MAINTARGET).exe
$(MAINTARGET).exe: $(MAINTARGET).obj
$(link) $(OBJS) /out:"wadlib.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp > nul
@copy $(MAINTARGET).exe D:\Xash3D\bin\$(MAINTARGET).exe
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
@del $(MAINTARGET).exe
@echo ‘Ş®Ż¨ŕ®˘ ­® ä ©«®˘: 1.
clean:

View File

@ -1,355 +0,0 @@
//=======================================================================
// Copyright XashXT Group 2007 ©
// cm_bsptree.c - collision tree
//=======================================================================
#include "physic.h"
typedef struct cfacedesc_s
{
int flags; // surface description
} cfacedesc_t;
struct collision_tree_s
{
byte *pmod_base; // start of buffer
dvertex_t *vertices;
int *surfedges;
dface_t *surfaces;
dedge_t *edges;
dmodel_t *models;
cfacedesc_t *surfdesc;
int num_models;
int num_faces; // for bounds checking
vfile_t *world_tree; // pre-calcualated collision tree (worldmodel only)
NewtonCollision *collision;
NewtonBody *body;
bool loaded; // map is loaded?
bool tree_build; // phys tree is created ?
bool use_thread; // bsplib use thread
} map;
/*
=================
BSP_LoadVerts
=================
*/
void BSP_LoadVerts( lump_t *l )
{
dvertex_t *in, *out;
int i, count;
in = (void *)(map.pmod_base + l->fileofs);
if (l->filelen % sizeof(*in)) Host_Error("BSP_LoadVerts: funny lump size\n");
count = l->filelen / sizeof(*in);
map.vertices = out = Mem_Alloc( physpool, count * sizeof(*out));
for ( i = 0; i < count; i++, in++, out++)
{
out->point[0] = LittleFloat(in->point[0]);
out->point[1] = LittleFloat(in->point[1]);
out->point[2] = LittleFloat(in->point[2]);
}
}
/*
=================
BSP_LoadEdges
=================
*/
void BSP_LoadEdges( lump_t *l )
{
dedge_t *in, *out;
int i, count;
in = (void *)(map.pmod_base + l->fileofs);
if (l->filelen % sizeof(*in)) Host_Error("BSP_LoadEdges: funny lump size\n");
count = l->filelen / sizeof(*in);
map.edges = out = Mem_Alloc( physpool, count * sizeof(*out));
for ( i = 0; i < count; i++, in++, out++)
{
out->v[0] = LittleLong(in->v[0]);
out->v[1] = LittleLong(in->v[1]);
}
}
/*
=================
BSP_LoadSurfedges
=================
*/
void BSP_LoadSurfedges( lump_t *l )
{
int *in, *out;
int i, count;
in = (void *)(map.pmod_base + l->fileofs);
if (l->filelen % sizeof(*in)) Host_Error("BSP_LoadSurfedges: funny lump size\n");
count = l->filelen / sizeof(*in);
if (count < 1 || count >= MAX_MAP_SURFEDGES) Host_Error("BSP_LoadSurfedges: funny lump size\n");
map.surfedges = out = Mem_Alloc( physpool, count * sizeof(*out));
for ( i = 0; i < count; i++) out[i] = LittleLong(in[i]);
}
/*
=================
BSP_LoadFaces
=================
*/
void BSP_LoadFaces( lump_t *l )
{
dface_t *in, *out;
int i;
in = (void *)(map.pmod_base + l->fileofs);
if (l->filelen % sizeof(*in)) Host_Error("BSP_LoadFaces: funny lump size\n");
map.num_faces = l->filelen / sizeof(*in);
map.surfaces = out = Mem_Alloc( physpool, map.num_faces * sizeof(*out));
for( i = 0; i < map.num_faces; i++, in++, out++)
{
out->firstedge = LittleLong(in->firstedge);
out->numedges = LittleLong(in->numedges);
out->desc = LittleLong(in->desc);
}
}
/*
=================
BSP_LoadModels
=================
*/
void BSP_LoadModels( lump_t *l )
{
dmodel_t *in, *out;
int i;
in = (void *)(map.pmod_base + l->fileofs);
if (l->filelen % sizeof(*in)) Host_Error("BSP_LoadModels: funny lump size\n");
map.num_models = l->filelen / sizeof(*in);
map.models = out = Mem_Alloc( physpool, map.num_models * sizeof(*out));
if(map.num_models < 1) Host_Error("Map with no models\n");
if(map.num_models > MAX_MAP_MODELS) Host_Error("Map has too many models\n");
for ( i = 0; i < map.num_models; i++, in++, out++)
{
CM_ConvertDimensionToMeters( out->mins, in->mins );
CM_ConvertDimensionToMeters( out->maxs, in->maxs );
out->headnode = LittleLong( in->headnode );
out->firstface = LittleLong( in->firstface );
out->numfaces = LittleLong( in->numfaces );
out->firstbrush = LittleLong( in->firstbrush );
out->numbrushes = LittleLong( in->numbrushes );
}
}
/*
=================
BSP_LoadSurfDesc
=================
*/
void BSP_LoadSurfDesc( lump_t *l )
{
dsurfdesc_t *in;
cfacedesc_t *out;
int i, count;
in = (void *)(map.pmod_base + l->fileofs);
if (l->filelen % sizeof(*in)) Host_Error("BSP_LoadSurfDesc: funny lump size\n" );
count = l->filelen / sizeof(*in);
map.surfdesc = out = Mem_Alloc( physpool, count * sizeof(*out));
for ( i = 0; i < count; i++, in++, out++) out->flags = LittleLong (in->flags);
}
/*
=================
BSP_LoadModels
=================
*/
void BSP_LoadCollision( lump_t *l )
{
byte *in;
int count;
in = (void *)(map.pmod_base + l->fileofs);
if (l->filelen % sizeof(*in)) Host_Error("BSP_LoadCollision: funny lump size\n");
count = l->filelen / sizeof(*in);
map.world_tree = VFS_Create( in, count );
}
void CM_GetPoint( int index, vec3_t out )
{
int vert_index;
int edge_index = map.surfedges[index];
if(edge_index > 0) vert_index = map.edges[edge_index].v[0];
else vert_index = map.edges[-edge_index].v[1];
CM_ConvertPositionToMeters( out, map.vertices[vert_index].point );
}
void BSP_BeginBuildTree( void )
{
// create tree collision
map.collision = NewtonCreateTreeCollision( gWorld, NULL );
NewtonTreeCollisionBeginBuild( map.collision );
}
void BSP_AddCollisionFace( int facenum )
{
dface_t *m_face;
int j, k;
int flags;
if(facenum < 0 || facenum >= map.num_faces)
{
MsgDev(D_ERROR, "invalid face number %d, must be in range [0 == %d]\n", facenum, map.num_faces - 1);
return;
}
m_face = map.surfaces + facenum;
flags = map.surfdesc[m_face->desc].flags;
k = m_face->firstedge;
// sky is noclip for all physobjects
if(flags & SURF_SKY) return;
if( cm_use_triangles->integer )
{
// convert polygon to triangles
for(j = 0; j < m_face->numedges - 2; j++)
{
vec3_t face[3]; // triangle
CM_GetPoint( k, face[0] );
CM_GetPoint( k+j+1, face[1] );
CM_GetPoint( k+j+2, face[2] );
NewtonTreeCollisionAddFace( map.collision, 3, (float *)face[0], sizeof(vec3_t), 1 );
}
}
else
{
vec3_t *face = Mem_Alloc( physpool, m_face->numedges * sizeof(vec3_t));
for(j = 0; j < m_face->numedges; j++ ) CM_GetPoint( k+j, face[j] );
NewtonTreeCollisionAddFace( map.collision, m_face->numedges, (float *)face[0], sizeof(vec3_t), 1);
if( face ) Mem_Free( face ); // polygons with 0 edges ?
}
}
void BSP_EndBuildTree( void )
{
if( map.use_thread ) Msg("Optimize collision tree..." );
NewtonTreeCollisionEndBuild( map.collision, true );
if( map.use_thread ) Msg(" done\n");
}
static void BSP_LoadTree( vfile_t* handle, void* buffer, size_t size )
{
VFS_Read( handle, buffer, size );
}
void CM_LoadBSP( const void *buffer )
{
dheader_t header;
header = *(dheader_t *)buffer;
map.pmod_base = (byte *)buffer;
// loading level
BSP_LoadVerts(&header.lumps[LUMP_VERTEXES]);
BSP_LoadEdges(&header.lumps[LUMP_EDGES]);
BSP_LoadSurfedges(&header.lumps[LUMP_SURFEDGES]);
BSP_LoadFaces(&header.lumps[LUMP_FACES]);
BSP_LoadModels(&header.lumps[LUMP_MODELS]);
BSP_LoadSurfDesc(&header.lumps[LUMP_SURFDESC]);
BSP_LoadCollision(&header.lumps[LUMP_COLLISION]);
map.loaded = true;
map.use_thread = true;
// keep bspdata because we want create bsp models
// as kinematic objects: doors, fans, pendulums etc
}
void CM_FreeBSP( void )
{
if(!map.loaded) return;
Mem_Free( map.surfedges );
Mem_Free( map.edges );
Mem_Free( map.surfaces );
Mem_Free( map.vertices );
Mem_Free( map.models );
map.num_models = 0;
map.num_faces = 0;
map.loaded = false;
}
void CM_MakeCollisionTree( void )
{
int i, world = 0; // world index
if(!map.loaded) Host_Error("CM_MakeCollisionTree: map not loaded\n");
if(map.collision) return; // already generated
if(map.use_thread) Msg("Building collision tree...\n" );
BSP_BeginBuildTree();
// world firstface index always equal 0
if(map.use_thread) RunThreadsOnIndividual( map.models[world].numfaces, true, BSP_AddCollisionFace );
else for( i = 0; i < map.models[world].numfaces; i++ ) BSP_AddCollisionFace( i );
BSP_EndBuildTree();
}
void CM_SaveCollisionTree( file_t *f, cmsave_t callback )
{
CM_MakeCollisionTree(); // create if needed
NewtonTreeCollisionSerialize( map.collision, callback, f );
}
void CM_LoadCollisionTree( void )
{
map.collision = NewtonCreateTreeCollisionFromSerialization( gWorld, NULL, BSP_LoadTree, map.world_tree );
VFS_Close( map.world_tree );
map.world_tree = NULL;
}
void CM_LoadWorld( const void *buffer )
{
matrix4x4 m_matrix;
vec3_t boxP0, boxP1;
vec3_t extra = { 10.0f, 10.0f, 10.0f };
CM_LoadBSP( buffer ); // loading bspdata
map.use_thread = false;
if(map.world_tree) CM_LoadCollisionTree();
else CM_MakeCollisionTree(); // can be used for old maps
map.body = NewtonCreateBody( gWorld, map.collision );
NewtonBodyGetMatrix( map.body, &m_matrix[0][0] ); // set the global position of this body
NewtonCollisionCalculateAABB( map.collision, &m_matrix[0][0], &boxP0[0], &boxP1[0] );
NewtonReleaseCollision( gWorld, map.collision );
VectorSubtract( boxP0, extra, boxP0 );
VectorAdd( boxP1, extra, boxP1 );
NewtonSetWorldSize( gWorld, &boxP0[0], &boxP1[0] );
NewtonSetSolverModel( gWorld, cm_solver_model->integer );
NewtonSetFrictionModel( gWorld, cm_friction_model->integer );
}
void CM_FreeWorld( void )
{
CM_FreeBSP();
if(!map.body) return;
// and physical body release too
NewtonDestroyBody( gWorld, map.body );
map.body = NULL;
map.collision = NULL;
}

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@
#include "physic.h"
#include "mathlib.h"
physbody_t *Phys_CreateBody( sv_edict_t *ed, void *buffer, matrix4x3 transform, int solid )
physbody_t *Phys_CreateBody( sv_edict_t *ed, cmodel_t *mod, matrix4x3 transform, int solid )
{
NewtonCollision *col;
NewtonBody *body;
@ -14,19 +14,15 @@ physbody_t *Phys_CreateBody( sv_edict_t *ed, void *buffer, matrix4x3 transform,
float *vertices;
int numvertices;
vec3_t size, center, mins, maxs;
studiohdr_t *phdr = (studiohdr_t *)buffer;
mstudioseqdesc_t *pseqdesc;
// identity matrixes
// setup matrixes
MatrixLoadIdentity( trans );
MatrixLoadIdentity( offset );
if( phdr )
if( mod )
{
// custom convex hull
pseqdesc = (mstudioseqdesc_t *)((byte *)phdr + phdr->seqindex);
VectorCopy( pseqdesc[0].bbmin, mins );
VectorCopy( pseqdesc[0].bbmax, maxs );
VectorCopy( mod->mins, mins );
VectorCopy( mod->maxs, maxs );
if( solid == SOLID_BOX )
{

View File

@ -28,5 +28,36 @@ void CM_FreeWorld( void );
void CM_MakeCollisionTree( void );
void CM_LoadCollisionTree( void );
void CM_SaveCollisionTree( file_t *f, cmsave_t callback );
void CM_InitBoxHull( void );
void CM_FloodAreaConnections( void );
cmodel_t *CM_BeginRegistration ( const char *name, bool clientload, uint *checksum );
cmodel_t *CM_RegisterModel ( const char *name );
void CM_EndRegistration ( void );
void CM_SetAreaPortals ( byte *portals, size_t size );
void CM_GetAreaPortals ( byte **portals, size_t *size );
void CM_SetAreaPortalState ( int portalnum, bool open );
int CM_NumClusters( void );
int CM_NumTexinfo( void );
int CM_NumInlineModels( void );
const char *CM_EntityString( void );
const char *CM_TexName( int index );
int CM_HeadnodeForBox( vec3_t mins, vec3_t maxs );
int CM_PointContents( vec3_t p, int headnode );
int CM_TransformedPointContents( vec3_t p, int headnode, vec3_t origin, vec3_t angles );
trace_t CM_BoxTrace( vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int headnode, int brushmask);
trace_t CM_TransformedBoxTrace( vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int headnode, int brushmask, vec3_t origin, vec3_t angles );
byte *CM_ClusterPVS( int cluster );
byte *CM_ClusterPHS( int cluster );
int CM_PointLeafnum( vec3_t p );
int CM_BoxLeafnums( vec3_t mins, vec3_t maxs, int *list, int listsize, int *topnode );
int CM_LeafContents( int leafnum ); // probably unused
int CM_LeafCluster( int leafnum );
int CM_LeafArea( int leafnum );
bool CM_AreasConnected( int area1, int area2 );
int CM_WriteAreaBits( byte *buffer, int area );
bool CM_HeadnodeVisible( int headnode, byte *visbits );
#endif//CM_UTILS_H

View File

@ -9,6 +9,7 @@ physic_imp_t pi;
stdlib_api_t com;
physic_t ph; // physic globalstate
byte *physpool;
byte *cmappool;
NewtonWorld *gWorld;
cvar_t *cm_use_triangles;
@ -18,6 +19,7 @@ cvar_t *cm_friction_model;
bool InitPhysics( void )
{
physpool = Mem_AllocPool("Physics Pool");
cmappool = Mem_AllocPool("CM Zone");
gWorld = NewtonCreate (Palloc, Pfree); // alloc world
cm_use_triangles = Cvar_Get("cm_convert_polygons", "1", CVAR_INIT|CVAR_SYSTEMINFO );//, "convert bsp polygons to triangles, slowly but more safety way" );
@ -27,6 +29,11 @@ bool InitPhysics( void )
return true;
}
void PhysFrame( float time )
{
NewtonUpdate( gWorld, time );
}
void FreePhysics( void )
{
NewtonDestroy( gWorld );
@ -49,13 +56,42 @@ physic_exp_t DLLEXPORT *CreateAPI ( stdlib_api_t *input, physic_imp_t *engfuncs
Phys.Init = InitPhysics;
Phys.Shutdown = FreePhysics;
Phys.LoadBSP = CM_LoadBSP;
Phys.FreeBSP = CM_FreeBSP;
Phys.WriteCollisionLump = CM_SaveCollisionTree;
Phys.DrawCollision = DebugShowCollision;
Phys.LoadWorld = CM_LoadWorld;
Phys.FreeWorld = CM_FreeWorld;
Phys.Frame = Phys_Frame;
Phys.LoadBSP = CM_LoadBSP;
Phys.FreeBSP = CM_FreeBSP;
Phys.BeginRegistration = CM_BeginRegistration;
Phys.RegisterModel = CM_RegisterModel;
Phys.EndRegistration = CM_EndRegistration;
Phys.SetAreaPortals = CM_SetAreaPortals;
Phys.GetAreaPortals = CM_GetAreaPortals;
Phys.SetAreaPortalState = CM_SetAreaPortalState;
Phys.NumClusters = CM_NumClusters;
Phys.NumTextures = CM_NumTexinfo;
Phys.NumBmodels = CM_NumInlineModels;
Phys.GetEntityString = CM_EntityString;
Phys.GetTextureName = CM_TexName;
Phys.HeadnodeForBox = CM_HeadnodeForBox;
Phys.PointContents = CM_PointContents;
Phys.TransformedPointContents = CM_TransformedPointContents;
Phys.BoxTrace = CM_BoxTrace;
Phys.TransformedBoxTrace = CM_TransformedBoxTrace;
Phys.ClusterPVS = CM_ClusterPVS;
Phys.ClusterPHS = CM_ClusterPHS;
Phys.PointLeafnum = CM_PointLeafnum;
Phys.BoxLeafnums = CM_BoxLeafnums;
Phys.LeafContents = CM_LeafContents;
Phys.LeafCluster = CM_LeafCluster;
Phys.LeafArea = CM_LeafArea;
Phys.AreasConnected = CM_AreasConnected;
Phys.WriteAreaBits = CM_WriteAreaBits;
Phys.HeadnodeVisible = CM_HeadnodeVisible;
Phys.Frame = PhysFrame;
Phys.CreateBody = Phys_CreateBody;
Phys.GetForce = Phys_GetForce;
Phys.SetForce = Phys_SetForce;

View File

@ -113,7 +113,7 @@ SOURCE="$(InputPath)"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\cm_bsptree.c
SOURCE=.\cm_model.c
# End Source File
# Begin Source File

View File

@ -23,6 +23,7 @@ typedef struct physragbone_s NewtonRagDollBone;
extern physic_imp_t pi;
extern stdlib_api_t com;
extern byte *physpool;
extern byte *cmappool;
extern NewtonWorld *gWorld;
// cvars
@ -39,7 +40,7 @@ void Phys_Frame( float time );
//
// cm_rigidbody.c
//
physbody_t *Phys_CreateBody( sv_edict_t *ed, void *buffer, matrix4x3 transform, int solid );
physbody_t *Phys_CreateBody( sv_edict_t *ed, cmodel_t *mod, matrix4x3 transform, int solid );
bool Phys_GetForce( physbody_t *body, vec3_t velocity, vec3_t avelocity, vec3_t force, vec3_t torque );
void Phys_SetForce( physbody_t *body, vec3_t velocity, vec3_t avelocity, vec3_t force, vec3_t torque );
bool Phys_GetMassCentre( physbody_t *body, matrix3x3 mass );

View File

@ -19,9 +19,4 @@ void* Palloc (int size )
void Pfree (void *ptr, int size )
{
if( ptr ) Mem_Free( ptr );
}
void Phys_Frame( float time )
{
NewtonUpdate(gWorld, time );
}

View File

@ -216,4 +216,12 @@ void env_monster( void )
pev->nextthink = time;
pev->think = walk_sprite;
pev->frame = 0;
}
void func_physbox( void )
{
pev->owner = pev;
pev->solid = SOLID_MESH;
pev->movetype = MOVETYPE_PHYSIC;
setmodel (pev, pev->model );
}

View File

@ -23,7 +23,7 @@
#define MAX_NUM_ARGVS 128
#define MAX_STRING 256
#define MAX_SYSPATH 1024
#define MAX_INPUTLINE 16384 // many buffers use this size
#define MAX_INPUTLINE 16384 // console buffer
#define MAX_INFO_KEY 64
#define MAX_INFO_VALUE 64
#define MAX_INFO_STRING 512
@ -125,6 +125,7 @@ typedef struct { byte r; byte g; byte b; byte a; } color32;
typedef struct { const char *name; void **func; } dllfunc_t; // Sys_LoadLibrary stuff
typedef struct { int ofs; int type; const char *name; } fields_t; // prvm custom fields
typedef void (*cmread_t) (void* handle, void* buffer, size_t size);
typedef enum { mod_bad, mod_brush, mod_studio, mod_sprite } modtype_t;
typedef void (*cmsave_t) (void* handle, const void* buffer, size_t size);
typedef void (*cmdraw_t)( int color, int numpoints, const float *points );
typedef struct { int numfilenames; char **filenames; char *filenamesbuffer; } search_t;
@ -144,6 +145,7 @@ enum host_state
COMP_SPRITE, // "sprite"
COMP_STUDIO, // "studio"
COMP_WADLIB, // "wadlib"
COMP_SDKLIB, // "sdklib"
RIPP_MIPDEC, // "mipdec"
RIPP_SPRDEC, // "sprdec"
RIPP_MDLDEC, // "mdldec"
@ -164,19 +166,6 @@ enum dev_level
D_MEMORY, // "-dev 6", show memory allocation
};
static vec4_t g_color_table[8] =
{
{0.0, 0.0, 0.0, 1.0},
{1.0, 0.0, 0.0, 1.0},
{0.0, 1.0, 0.0, 1.0},
{1.0, 1.0, 0.0, 1.0},
{0.0, 0.0, 1.0, 1.0},
{0.0, 1.0, 1.0, 1.0},
{1.0, 0.0, 1.0, 1.0},
{1.0, 1.0, 1.0, 1.0},
};
#include "byteorder.h" // byte ordering swap functions
#include "stdref.h" // reference xash formats
#include "stdapi.h" // reference xash stdlib api

View File

@ -229,14 +229,40 @@ typedef struct physic_exp_s
void (*FreeBSP)( void ); // free bspdata
void (*WriteCollisionLump)( file_t *f, cmsave_t callback ); // write collision data into LUMP_COLLISION
void (*LoadWorld)( const void *buf ); // loading collision tree or generated if not present ( engine )
void (*FreeWorld)( void ); // free world collision
void (*DrawCollision)( cmdraw_t callback ); // debug draw world
void (*Frame)( float time ); // physics frame
cmodel_t *(*BeginRegistration)( const char *name, bool clientload, uint *checksum );
cmodel_t *(*RegisterModel)( const char *name );
void (*EndRegistration)( void );
void (*SetAreaPortals)( byte *portals, size_t size );
void (*GetAreaPortals)( byte **portals, size_t *size );
void (*SetAreaPortalState)( int portalnum, bool open );
int (*NumClusters)( void );
int (*NumTextures)( void );
int (*NumBmodels )( void );
const char *(*GetEntityString)( void );
const char *(*GetTextureName)( int index );
int (*HeadnodeForBox)( vec3_t mins, vec3_t maxs );
int (*PointContents)( vec3_t p, int headnode );
int (*TransformedPointContents)( vec3_t p, int headnode, vec3_t origin, vec3_t angles );
trace_t (*BoxTrace)( vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int headnode, int brushmask);
trace_t (*TransformedBoxTrace)( vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int headnode, int brushmask, vec3_t origin, vec3_t angles );
byte *(*ClusterPVS)( int cluster );
byte *(*ClusterPHS)( int cluster );
int (*PointLeafnum)( vec3_t p );
int (*BoxLeafnums)( vec3_t mins, vec3_t maxs, int *list, int listsize, int *topnode );
int (*LeafContents)( int leafnum ); // probably unused
int (*LeafCluster)( int leafnum );
int (*LeafArea)( int leafnum );
bool (*AreasConnected)( int area1, int area2 );
int (*WriteAreaBits)( byte *buffer, int area );
bool (*HeadnodeVisible)( int headnode, byte *visbits );
// simple objects
physbody_t *(*CreateBody)( sv_edict_t *ed, void *buffer, matrix4x3 transform, int solid );
physbody_t *(*CreateBody)( sv_edict_t *ed, cmodel_t *mod, matrix4x3 transform, int solid );
bool (*GetForce)(physbody_t *body, vec3_t vel, vec3_t avel, vec3_t force, vec3_t torque );
void (*SetForce)(physbody_t *body, vec3_t vel, vec3_t avel, vec3_t force, vec3_t torque );
bool (*GetMassCentre)( physbody_t *body, matrix3x3 mass );

View File

@ -1378,16 +1378,19 @@ typedef struct cmodel_s
vec3_t mins, maxs; // boundbox
int headnode; // bsp info
int type; // model type
int firstface; // used to create collision tree
int numfaces;
int firstbrush; // used to create collision brush
int numbrushes;
int numframes; // sprite framecount
int numbodies; // physmesh numbody
cmesh_t physmesh[MAXSTUDIOMODELS]; // max bodies
void *extradata; // get rid of this
} cmodel_t;
typedef struct csurface_s
{
char name[16];
string name;
int flags;
int value;
@ -1396,12 +1399,6 @@ typedef struct csurface_s
int numedges; // are backwards edges
} csurface_t;
typedef struct mapsurface_s
{
csurface_t c;
char rname[32];
} mapsurface_t;
typedef struct trace_s
{
bool allsolid; // if true, plane is not valid

View File

@ -180,9 +180,6 @@ typedef struct mleaf_s
//
// Whole model
//
typedef enum {mod_bad, mod_brush, mod_studio, mod_sprite } modtype_t;
typedef struct model_s
{
string name;

View File

@ -794,8 +794,9 @@ void R_DrawInlineBModel (void)
if ( currententity->flags & RF_TRANSLUCENT )
{
qglEnable (GL_BLEND);
qglColor4f (1,1,1,0.25);
GL_EnableBlend();
qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
qglColor4f( 1.0f, 1.0f, 1.0f, 0.9f );
GL_TexEnv( GL_MODULATE );
}
@ -830,15 +831,15 @@ void R_DrawInlineBModel (void)
}
}
if ( !(currententity->flags & RF_TRANSLUCENT) )
if(!(currententity->flags & RF_TRANSLUCENT) )
{
if ( !qglMTexCoord2fSGIS )
R_BlendLightmaps ();
if( !qglMTexCoord2fSGIS )
R_BlendLightmaps();
}
else
{
qglDisable (GL_BLEND);
qglColor4f (1,1,1,1);
GL_DisableBlend();
qglColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
GL_TexEnv( GL_REPLACE );
}
}

View File

@ -14,6 +14,7 @@ int gl_tex_solid_format = 3;
int gl_tex_alpha_format = 4;
int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST;
int gl_filter_max = GL_LINEAR;
byte gammatable[256];
typedef struct
{
@ -532,6 +533,31 @@ void qglPerspective( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zF
qglFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
}
/*
================
VID_ImageAdjustGamma
================
*/
void VID_ImageAdjustGamma( byte *in, uint width, uint height )
{
int i, c = width * height;
float g = vid_gamma->value;
byte *p = in;
// screenshots gamma
for ( i = 0; i < 256; i++ )
{
if ( g == 1 ) gammatable[i] = i;
else gammatable[i] = bound(0, 255 * pow ( (i + 0.5)/255.5 , g ) + 0.5, 255);
}
for (i = 0; i < c; i++, p += 3 )
{
p[0] = gammatable[p[0]];
p[1] = gammatable[p[1]];
p[2] = gammatable[p[2]];
}
}
bool VID_ScreenShot( const char *filename, bool levelshot )
{
rgbdata_t *r_shot;
@ -550,8 +576,8 @@ bool VID_ScreenShot( const char *filename, bool levelshot )
r_shot->palette = NULL;
r_shot->buffer = r_framebuffer;
// levelshot always have const size
if( levelshot ) Image_Processing( filename, &r_shot, 512, 384 );
if( levelshot ) Image_Processing( filename, &r_shot, 512, 384 ); // resample to 512x384
else VID_ImageAdjustGamma( r_shot->buffer, r_shot->width, r_shot->height ); // adjust brightness
// write image
FS_SaveImage( filename, r_shot );