revamped fog to use glsl. shouldn't harm framerate quite so much.

tweeked d3d renderer. certain shader constructs might be broken now so don't try q3 with it, but framerates are up when playing quake.
tweeked gl rendering too, timedemo results seem a little higher also.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3933 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2011-12-23 03:12:29 +00:00
parent dd006b6edd
commit 1693ba6c58
72 changed files with 2744 additions and 2413 deletions

View file

@ -327,7 +327,6 @@ CLIENT_OBJS = \
cl_cg.o \
clq3_parse.o \
pr_csqc.o \
pr_skelobj.o \
console.o \
image.o \
keys.o \

View file

@ -1925,7 +1925,7 @@ void CL_TransitionEntities (void)
/*and transition players too*/
{
float frac, a1, a2;
int i,j, p;
int i, p;
vec3_t move;
lerpents_t *le;
player_state_t *pnew, *pold;
@ -1935,12 +1935,17 @@ void CL_TransitionEntities (void)
frac = (servertime-packold->servertime)/(packnew->servertime-packold->servertime);
pnew = &cl.frames[newf].playerstate[0];
pold = &cl.frames[oldf].playerstate[0];
for (p = 0; p < MAX_CLIENTS; p++, pnew++, pold++)
for (p = 0; p < cl.allocated_client_slots; p++, pnew++, pold++)
{
if (pnew->messagenum != cl.parsecount)
continue;
le = &cl.lerpplayers[p];
VectorSubtract(pnew->origin, pold->origin, move);
if (DotProduct(move, move) > 120*120)
frac = 1;
//lerp based purely on the packet times,
for (i = 0; i < 3; i++)
{
@ -3105,26 +3110,7 @@ void CL_LinkPlayers (void)
// only predict half the move to minimize overruns
msec = 500*(playertime - state->state_time);
/*
if (1)
{
float f;
int i;
f = (cl.gametime-cl.servertime)/(cl.gametime-cl.oldgametime);
if (f<0)
f=0;
if (f>1)
f=1;
for (i=0 ; i<3 ; i++)
{
ent->origin[i] = state->origin[i] +
f * (fromf->playerstate[j].origin[i] - state->origin[i]);
}
}
else
*/
if (pnum < cl.splitclients)
{ //this is a local player
}

View file

@ -654,6 +654,7 @@ void CL_CheckForResend (void)
netadr_t adr;
char data[2048];
double t1, t2;
int contype = 0;
#ifndef CLIENTONLY
if (!cls.state && sv.state)
@ -799,8 +800,19 @@ void CL_CheckForResend (void)
Con_TPrintf (TLC_CONNECTINGTO, cls.servername);
contype |= 1; /*always try qw type connections*/
// if ((connect_tries&3)==3) || (connect_defaultport==26000))
contype |= 2; /*try nq connections periodically (or if its the default nq port)*/
/*DP, QW, Q2, Q3*/
if (contype & 1)
{
Q_snprintfz (data, sizeof(data), "%c%c%c%cgetchallenge\n", 255, 255, 255, 255);
NET_SendPacket (NS_CLIENT, strlen(data), data, adr);
}
/*NQ*/
#ifdef NQPROT
if (((connect_tries&3)==3) != (connect_defaultport==26000))
if (contype & 2)
{
sizebuf_t sb;
memset(&sb, 0, sizeof(sb));
@ -823,18 +835,13 @@ void CL_CheckForResend (void)
MSG_WriteByte(&sb, 0); /*flags*/
MSG_WriteLong(&sb, strtoul(password.string, NULL, 0)); /*password*/
/*so dual-protocol servers can send a more useful reply*/
/*FTE servers will detect this string and treat it as a qw challenge instead (if it allows qw clients), so protocol choice is deterministic*/
MSG_WriteString(&sb, "getchallenge");
*(int*)sb.data = LongSwap(NETFLAG_CTL | sb.cursize);
NET_SendPacket (NS_CLIENT, sb.cursize, sb.data, adr);
}
else
#endif
{
Q_snprintfz (data, sizeof(data), "%c%c%c%cgetchallenge\n", 255, 255, 255, 255);
NET_SendPacket (NS_CLIENT, strlen(data), data, adr);
}
connect_tries++;
}
@ -1602,6 +1609,9 @@ void CL_CheckServerInfo(void)
cls.allow_lightmapgamma=true;
s = Info_ValueForKey(cl.serverinfo, "allow_fish");
if (cl.spectator || cls.demoplayback || !*s || atoi(s))
cls.allow_postproc=true;
s = Info_ValueForKey(cl.serverinfo, "allow_postproc");
if (cl.spectator || cls.demoplayback || !*s || atoi(s))
cls.allow_postproc=true;
@ -2280,6 +2290,8 @@ void CL_ConnectionlessPacket (void)
if (c == S2C_CHALLENGE)
{
static unsigned int lasttime = 0xdeadbeef;
unsigned int curtime = Sys_Milliseconds();
unsigned long pext = 0, pext2 = 0, huffcrc=0;
Con_TPrintf (TLC_S2C_CHALLENGE);
@ -2287,9 +2299,15 @@ void CL_ConnectionlessPacket (void)
COM_Parse(s);
if (!strcmp(com_token, "hallengeResponse"))
{
/*Quake3*/
#ifdef Q3CLIENT
if (cls.protocol == CP_QUAKE3 || cls.protocol == CP_UNKNOWN)
{
/*throttle*/
if (curtime - lasttime < 500)
return;
lasttime = curtime;
cls.protocol = CP_QUAKE3;
cls.challenge = atoi(s+17);
CL_SendConnectPacket (0, 0, 0/*, ...*/);
@ -2307,7 +2325,13 @@ void CL_ConnectionlessPacket (void)
}
else if (!strcmp(com_token, "hallenge"))
{
/*Quake2 or Darkplaces*/
char *s2;
/*throttle*/
if (curtime - lasttime < 500)
return;
lasttime = curtime;
for (s2 = s+9; *s2; s2++)
{
if ((*s2 < '0' || *s2 > '9') && *s2 != '-')
@ -2354,6 +2378,9 @@ void CL_ConnectionlessPacket (void)
goto client_connect;
}
#endif
/*no idea, assume a QuakeWorld challenge response ('c' packet)*/
else if (cls.protocol == CP_QUAKEWORLD || cls.protocol == CP_UNKNOWN)
cls.protocol = CP_QUAKEWORLD;
else
@ -2361,6 +2388,12 @@ void CL_ConnectionlessPacket (void)
Con_Printf("\nChallenge from another protocol, ignoring QW challenge\n");
return;
}
/*throttle*/
if (curtime - lasttime < 500)
return;
lasttime = curtime;
cls.challenge = atoi(s);
for(;;)
@ -2778,7 +2811,7 @@ void CL_ReadPackets (void)
if (cls.netchan.incoming_sequence > cls.netchan.outgoing_sequence)
{ //server should not be responding to packets we have not sent yet
Con_Printf("Server is from the future! (%i packets)\n", cls.netchan.incoming_sequence - cls.netchan.outgoing_sequence);
Con_DPrintf("Server is from the future! (%i packets)\n", cls.netchan.incoming_sequence - cls.netchan.outgoing_sequence);
cls.netchan.outgoing_sequence = cls.netchan.incoming_sequence;
}
MSG_ChangePrimitives(cls.netchan.netprim);
@ -3484,7 +3517,9 @@ double Host_Frame (double time)
RSpeedLocals();
if (setjmp (host_abort) )
{
return 0; // something bad happened, or the server disconnected
}
realframetime = time = Media_TweekCaptureFrameTime(time);

View file

@ -15,6 +15,7 @@ enum {
MT_BAD, //this would be an error
MT_MASTERHTTPNQ, //an http/ftp based master server with NQ servers
MT_MASTERHTTPQW,//an http/ftp based master server with QW servers
MT_MASTERHTTPJSON,//quakeone's server listing
MT_BCASTQW, //-1status
MT_BCASTQ2, //-1status
MT_BCASTQ3,

View file

@ -1962,6 +1962,7 @@ void CLDP_ParseDownloadFinished(char *s)
Cmd_TokenizeString(s+1, false, false);
VFS_CLOSE (cls.downloadqw);
FS_FlushFSHash();
cls.downloadqw = FS_OpenVFS (cls.downloadtempname, "rb", FS_GAME);
if (cls.downloadqw)
@ -4408,10 +4409,13 @@ char *CL_ParseChat(char *text, player_info_t **player)
S_LocalSound (cl_enemychatsound.string);
}
if (cl_nofake.value == 1 || (cl_nofake.value == 2 && flags != 2)) {
for (p = s; *p; p++)
if (*p == 13 || (*p == 10 && p[1]))
*p = ' ';
if (flags)
{
if (cl_nofake.value == 1 || (cl_nofake.value == 2 && flags != 2)) {
for (p = s; *p; p++)
if (*p == 13 || (*p == 10 && p[1]))
*p = ' ';
}
}
msgflags = flags;
@ -4436,6 +4440,7 @@ void CL_ParsePrint(char *msg, int level)
Stats_ParsePrintLine(printtext);
TP_SearchForMsgTriggers(printtext, level);
*msg = '\n';
msg++;
memmove(printtext, msg, strlen(msg)+1);

View file

@ -853,6 +853,13 @@ void CL_PredictMovePNum (int pnum)
if (((cl_nopred.value && cls.demoplayback!=DPB_MVD && cls.demoplayback != DPB_EZTV)|| cl.fixangle[pnum] || cl.paused))
{
if (cl_lerp_players.ival && !cls.demoplayback)
{
lerpents_t *le = &cl.lerpplayers[spec_track[pnum]];
org = le->origin;
vel = vec3_origin;
}
fixedorg:
VectorCopy (vel, cl.simvel[pnum]);
VectorCopy (org, cl.simorg[pnum]);

View file

@ -1246,7 +1246,10 @@ int CIN_RunCinematic (struct cinematics_s *cin, qbyte **outdata, int *outwidth,
typedef struct cin_s cin_t;
#ifdef NOMEDIA
#define Media_Playing false
#define Media_Playing() false
#define Media_Init() 0
#define Media_PlayingFullScreen() false
#define Media_PlayFilm(n) false
#else
/*media playing system*/
qboolean Media_PlayingFullScreen(void);

File diff suppressed because it is too large Load diff

View file

@ -2464,11 +2464,9 @@ void Media_Init(void)
#else
void Media_Init(void){}
void M_Media_Draw (void){}
void M_Media_Key (int key) {}
qboolean Media_ShowFilm(void){return false;}
qboolean Media_PlayFilm(char *name) {return false;}
double Media_TweekCaptureFrameTime(double time) { return time ; }
void Media_RecordFrame (void) {}
@ -2481,7 +2479,6 @@ void M_Menu_Media_f (void) {}
char *Media_NextTrack(int musicchannelnum) {return NULL;}
qboolean Media_PausedDemo(void) {return false;}
qboolean Media_PlayingFullScreen(void) {return false;}
int filmtexture;
#endif

View file

@ -44,7 +44,7 @@ void M_Menu_MultiPlayer_f (void)
mgt=64;
menu->selecteditem = (menuoption_t*)
MC_AddConsoleCommandHexen2BigFont (menu, 80, mgt, "Join A Game ", "menu_slist\n");mgt+=20;
MC_AddConsoleCommandHexen2BigFont (menu, 80, mgt, "Server List ", "menu_slist\n");mgt+=20;
MC_AddConsoleCommandHexen2BigFont (menu, 80, mgt, "New Server ", "menu_newmulti\n");mgt+=20;
MC_AddConsoleCommandHexen2BigFont (menu, 80, mgt, "Player Setup", "menu_setup\n");mgt+=20;
MC_AddConsoleCommandHexen2BigFont (menu, 80, mgt, "Demos ", "menu_demo\n");mgt+=20;
@ -59,7 +59,7 @@ void M_Menu_MultiPlayer_f (void)
mgt=32;
menu->selecteditem = (menuoption_t*)
MC_AddConsoleCommandQBigFont (menu, 72, mgt, "Join A Game ", "menu_slist\n");mgt+=20;
MC_AddConsoleCommandQBigFont (menu, 72, mgt, "Server List ", "menu_slist\n");mgt+=20;
MC_AddConsoleCommandQBigFont (menu, 72, mgt, "Quick Connect", "quickconnect qw\n");mgt+=20;
MC_AddConsoleCommandQBigFont (menu, 72, mgt, "New Server ", "menu_newmulti\n");mgt+=20;
MC_AddConsoleCommandQBigFont (menu, 72, mgt, "Player Setup", "menu_setup\n");mgt+=20;
@ -444,33 +444,6 @@ void M_Menu_Setup_f (void)
#ifdef CL_MASTER
void M_Menu_ServerList_f (void)
{
key_dest = key_menu;
m_state = m_slist;
MasterInfo_Refresh();
}
#endif
void M_ServerList_Draw (void)
{
#ifdef CL_MASTER
M_DrawServers();
#endif
}
void M_ServerList_Key (int k)
{
#ifdef CL_MASTER
M_SListKey(k);
#endif
}
#ifdef CLIENTONLY
void M_Menu_GameOptions_f (void)

View file

@ -341,6 +341,7 @@ void M_Menu_Particles_f (void)
static const char *pdescopts[] =
{
"Classic",
"Faithful",
"High FPS",
"Fancy",
@ -351,6 +352,7 @@ void M_Menu_Particles_f (void)
};
static const char *pdescvals[] =
{
"classic",
"faithful",
"highfps",
"spikeset",
@ -380,8 +382,8 @@ void M_Menu_Particles_f (void)
menubulk_t bulk[] = {
MB_REDTEXT("Particle Options", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_COMBOCVAR("Particle System", r_particlesystem, psystemopts, psystemvals, "Selects particle system to use. Classic is standard Quake particles, script is FTE style scripted particles, and none disables particles entirely."),
MB_COMBOCVAR("Script Set", r_particledesc, pdescopts, pdescvals, "Selects particle set to use with script system."),
// MB_COMBOCVAR("Particle System", r_particlesystem, psystemopts, psystemvals, "Selects particle system to use. Classic is standard Quake particles, script is FTE style scripted particles, and none disables particles entirely."),
MB_COMBOCVAR("Particle Set", r_particledesc, pdescopts, pdescvals, "Selects particle set to use with the scripted particle system."),
MB_SPACING(4),
MB_COMBOCVAR("Rocket Trail", r_rockettrail, trailopts, trailvals, "Chooses effect to replace rocket trails."),
MB_COMBOCVAR("Grenade Trail", r_grenadetrail, trailopts, trailvals, "Chooses effect to replace grenade trails."),

View file

@ -823,7 +823,6 @@ void M_Init_Internal (void)
#ifdef CL_MASTER
Cmd_AddRemCommand ("menu_servers", M_Menu_ServerList2_f);
Cmd_AddRemCommand ("menu_serversold", M_Menu_ServerList_f);
Cmd_AddRemCommand ("menu_slist", M_Menu_ServerList2_f);
#endif
Cmd_AddRemCommand ("menu_setup", M_Menu_Setup_f);
@ -889,7 +888,6 @@ void M_DeInit_Internal (void)
#ifdef CL_MASTER
Cmd_RemoveCommand ("menu_servers");
Cmd_RemoveCommand ("menu_serversold");
Cmd_RemoveCommand ("menu_slist");
#endif
Cmd_RemoveCommand ("menu_setup");
@ -1007,10 +1005,6 @@ void M_Draw (int uimenu)
M_Help_Draw ();
break;
case m_slist:
M_ServerList_Draw ();
break;
case m_media:
M_Media_Draw ();
break;
@ -1044,10 +1038,6 @@ void M_Keydown (int key, int unicode)
M_Help_Key (key);
return;
case m_slist:
M_ServerList_Key (key);
return;
case m_media:
M_Media_Key (key);
return;

View file

@ -115,7 +115,7 @@ void M_Menu_Quit_f (void);
struct menu_s;
typedef enum {m_none, m_complex, m_help, m_slist, m_media, m_plugin, m_menu_dat} m_state_t;
typedef enum {m_none, m_complex, m_help, m_media, m_plugin, m_menu_dat} m_state_t;
extern m_state_t m_state;
typedef enum {

View file

@ -133,6 +133,11 @@ void Master_HideServer(serverinfo_t *server)
void Master_InsertAt(serverinfo_t *server, int pos)
{
int i;
if (numvisibleservers >= maxvisibleservers)
{
maxvisibleservers = maxvisibleservers+10;
visibleservers = BZ_Realloc(visibleservers, maxvisibleservers*sizeof(serverinfo_t*));
}
for (i = numvisibleservers; i > pos; i--)
{
visibleservers[i] = visibleservers[i-1];
@ -714,6 +719,8 @@ qboolean Master_LoadMasterList (char *filename, int defaulttype, int depth)
servertype = MT_MASTERQ2;
else if (!strcmp(com_token, "master:q3"))
servertype = MT_MASTERQ3;
else if (!strcmp(com_token, "master:httpjson"))
servertype = MT_MASTERHTTPJSON;
else if (!strcmp(com_token, "master:httpnq"))
servertype = MT_MASTERHTTPNQ;
else if (!strcmp(com_token, "master:httpqw"))
@ -776,12 +783,14 @@ qboolean Master_LoadMasterList (char *filename, int defaulttype, int depth)
{
switch (servertype)
{
case MT_MASTERHTTPJSON:
case MT_MASTERHTTPNQ:
case MT_MASTERHTTPQW:
Master_AddMasterHTTP(line, servertype, name);
break;
default:
Master_AddMaster(line, servertype, name);
break;
}
}
@ -1138,6 +1147,7 @@ void MasterInfo_ProcessHTTP(vfsfile_t *file, int type)
info->sends = 1;
info->special = type;
info->refreshtime = 0;
info->ping = 0xffff;
snprintf(info->name, sizeof(info->name), "%s", NET_AdrToString(adrbuf, sizeof(adrbuf), info->adr));
@ -1149,6 +1159,118 @@ void MasterInfo_ProcessHTTP(vfsfile_t *file, int type)
}
}
char *jsonnode(int level, char *node)
{
netadr_t adr = {NA_INVALID};
char servername[256] = {0};
char key[256];
int flags = 0;
int port = 0;
int cp = 0, mp = 0;
if (*node != '{')
return node;
do
{
node++;
node = COM_ParseToken(node, ",:{}[]");
if (*node != ':')
continue;
node++;
if (*node == '[')
{
do
{
node++;
node = jsonnode(level+1, node);
if (!node)
return NULL;
if (*node == ']')
{
break;
}
} while(*node == ',');
if (*node != ']')
return NULL;
node++;
}
else
{
Q_strncpyz(key, com_token, sizeof(key));
node = COM_ParseToken(node, ",:{}[]");
if (level == 1)
{
if (!strcmp(key, "IPAddress"))
NET_StringToAdr(com_token, &adr);
if (!strcmp(key, "Port"))
port = atoi(com_token);
if (!strcmp(key, "DNS"))
Q_strncpyz(servername, com_token, sizeof(servername));
if (!strcmp(key, "CurrentPlayerCount"))
cp = atoi(com_token);
if (!strcmp(key, "MaxPlayers"))
mp = atoi(com_token);
if (!strcmp(key, "Game"))
{
if (!strcmp(com_token, "NetQuake"))
flags |= SS_NETQUAKE;
if (!strcmp(com_token, "Quake2"))
flags |= SS_QUAKE2;
if (!strcmp(com_token, "Quake3"))
flags |= SS_QUAKE3;
}
}
}
} while(*node == ',');
if (*node == '}')
node++;
if (adr.type != NA_INVALID)
{
serverinfo_t *info;
if (port)
adr.port = htons(port);
if ((info = Master_InfoForServer(adr))) //remove if the server already exists.
{
info->sends = 1; //reset.
}
else
{
info = Z_Malloc(sizeof(serverinfo_t));
info->adr = adr;
info->sends = 1;
info->special = flags;
info->refreshtime = 0;
info->players = cp;
info->maxplayers = mp;
snprintf(info->name, sizeof(info->name), "%s", *servername?servername:NET_AdrToString(servername, sizeof(servername), info->adr));
info->next = firstserver;
firstserver = info;
Master_ResortServer(info);
}
}
return node;
}
void MasterInfo_ProcessHTTPJSON(struct dl_download *dl)
{
int len;
char *buf;
len = VFS_GETLEN(dl->file);
buf = malloc(len + 1);
VFS_READ(dl->file, buf, len);
buf[len] = 0;
jsonnode(0, buf);
free(buf);
}
// wrapper functions for the different server types
void MasterInfo_ProcessHTTPNQ(struct dl_download *dl)
{
@ -1234,6 +1356,9 @@ void MasterInfo_Request(master_t *mast, qboolean evenifwedonthavethefiles)
break;
#endif
#ifdef WEBCLIENT
case MT_MASTERHTTPJSON:
HTTP_CL_Get(mast->address, NULL, MasterInfo_ProcessHTTPJSON);
break;
case MT_MASTERHTTPNQ:
HTTP_CL_Get(mast->address, NULL, MasterInfo_ProcessHTTPNQ);
break;
@ -1387,6 +1512,7 @@ void MasterInfo_Refresh(void)
{
//Master_AddMaster("12.166.196.192:27950", MT_MASTERDP, "DarkPlaces Master 3");
Master_AddMasterHTTP("http://www.gameaholic.com/servers/qspy-quake", MT_MASTERHTTPNQ, "gameaholic's NQ master");
Master_AddMasterHTTP("http://servers.quakeone.com/index.php?format=json", MT_MASTERHTTPJSON, "quakeone's server listing");
Master_AddMaster("ghdigital.com:27950", MT_MASTERDP, "DarkPlaces Master 1"); // LordHavoc
Master_AddMaster("dpmaster.deathmask.net:27950", MT_MASTERDP, "DarkPlaces Master 2"); // Willis
Master_AddMaster("dpmaster.tchr.no:27950", MT_MASTERDP, "DarkPlaces Master 3"); // tChr
@ -1957,6 +2083,8 @@ void CL_MasterListParse(netadrtype_t adrtype, int type, qboolean slashpad)
}
if ((old = Master_InfoForServer(info->adr))) //remove if the server already exists.
{
if ((info->special & (SS_DARKPLACES | SS_NETQUAKE | SS_QUAKE2 | SS_QUAKE3)) && !(type & (SS_DARKPLACES | SS_NETQUAKE | SS_QUAKE2 | SS_QUAKE3)))
old->special = type | (old->special & SS_FAVORITE);
old->sends = 1; //reset.
Z_Free(info);
}

View file

@ -217,6 +217,7 @@ static qboolean PClassic_InitParticles (void)
#endif
classicshader = R_RegisterShader("particles_classic",
"{\n"
"program defaultsprite\n"
"nomipmaps\n"
"{\n"
"map $diffuse\n"
@ -384,9 +385,9 @@ static void PClassic_DrawParticles(void)
cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(*cl_strisvertc)*cl_maxstrisvert);
}
Vector4Set(cl_strisvertc[cl_numstrisvert+0],1,1,1,1);
Vector4Set(cl_strisvertc[cl_numstrisvert+1],1,1,1,1);
Vector4Set(cl_strisvertc[cl_numstrisvert+2],1,1,1,1);
// Vector4Set(cl_strisvertc[cl_numstrisvert+0],1,1,1,1);
// Vector4Set(cl_strisvertc[cl_numstrisvert+1],1,1,1,1);
// Vector4Set(cl_strisvertc[cl_numstrisvert+2],1,1,1,1);
Vector4Set(cl_strisvertc[cl_numstrisvert+0], ((p->rgb&0xff)>>0)/256.0, ((p->rgb&0xff00)>>8)/256.0, ((p->rgb&0xff0000)>>16)/256.0, ((p->type == pt_fire)?((6 - p->ramp) *0.166666):1.0));
Vector4Copy(cl_strisvertc[cl_numstrisvert+0], cl_strisvertc[cl_numstrisvert+1]);

View file

@ -527,6 +527,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
namepostfix = "_blend";
defaultshader =
"{\n"
"program defaultsprite\n"
"nomipmaps\n"
"{\n"
"map $diffuse\n"
@ -542,6 +543,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
namepostfix = "_bc";
defaultshader =
"{\n"
"program defaultsprite\n"
"nomipmaps\n"
"{\n"
"map $diffuse\n"
@ -557,6 +559,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
namepostfix = "_add";
defaultshader =
"{\n"
"program defaultsprite\n"
"nomipmaps\n"
"{\n"
"map $diffuse\n"
@ -572,6 +575,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
namepostfix = "_invmod";
defaultshader =
"{\n"
"program defaultsprite\n"
"nomipmaps\n"
"{\n"
"map $diffuse\n"
@ -587,6 +591,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
namepostfix = "_sub";
defaultshader =
"{\n"
"program defaultsprite\n"
"nomipmaps\n"
"{\n"
"map $diffuse\n"
@ -825,7 +830,7 @@ static void P_ParticleEffect_f(void)
if (*buf == '{')
{
int nest = 1;
char *str = BZ_Malloc(2);
char *str = BZ_Malloc(3);
int slen = 2;
str[0] = '{';
str[1] = '\n';
@ -4267,6 +4272,7 @@ static void PScript_DrawParticleTypes (void)
int traces=r_particle_tracelimit.ival;
int rampind;
static float oldtime;
RSpeedMark();
if (r_plooksdirty)
@ -4288,11 +4294,16 @@ static void PScript_DrawParticleTypes (void)
r_plooksdirty = false;
CL_RegisterParticles();
}
#if 1
pframetime = cl.time - oldtime;
if (pframetime < 0)
pframetime = 0;
oldtime = cl.time;
#else
pframetime = host_frametime;
if (cl.paused || r_secondaryview || r_refdef.recurse)
pframetime = 0;
#endif
VectorScale (vup, 1.5, pup);
VectorScale (vright, 1.5, pright);

View file

@ -619,7 +619,8 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
else
{
VectorCopy(in->v->angles, out->angles);
out->angles[0]*=-1;
if (model->type == mod_alias)
out->angles[0]*=-1;
AngleVectors(out->angles, out->axis[0], out->axis[1], out->axis[2]);
VectorInverse(out->axis[1]);
@ -3235,62 +3236,6 @@ static void QCBUILTIN PF_rotatevectorsbytag (progfuncs_t *prinst, struct globalv
VectorCopy(srcorg, retorg);
}
static void EdictToTransform(csqcedict_t *ed, float *trans)
{
AngleVectors(ed->v->angles, trans+0, trans+4, trans+8);
VectorInverse(trans+4);
trans[3] = ed->v->origin[0];
trans[7] = ed->v->origin[1];
trans[11] = ed->v->origin[2];
}
static void QCBUILTIN PF_cs_gettaginfo (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
csqcedict_t *ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM0);
int tagnum = G_FLOAT(OFS_PARM1);
float *origin = G_VECTOR(OFS_RETURN);
int modelindex = ent->v->modelindex;
model_t *mod = CSQC_GetModelForIndex(modelindex);
float transent[12];
float transforms[12];
float result[12];
framestate_t fstate;
cs_getframestate(ent, ent->xv->renderflags, &fstate);
#ifdef warningmsg
#pragma warningmsg("PF_cs_gettaginfo: This function doesn't honour attachments (but setattachment isn't implemented yet anyway)")
#endif
if (!Mod_GetTag(mod, tagnum, &fstate, transforms))
{
memset(transforms, 0, sizeof(transforms));
}
EdictToTransform(ent, transent);
R_ConcatTransforms((void*)transent, (void*)transforms, (void*)result);
origin[0] = result[3];
origin[1] = result[7];
origin[2] = result[11];
VectorCopy((result+0), csqcg.forward);
VectorCopy((result+4), csqcg.right);
VectorCopy((result+8), csqcg.up);
}
static void QCBUILTIN PF_cs_gettagindex (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
csqcedict_t *ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM0);
char *tagname = PR_GetStringOfs(prinst, OFS_PARM1);
model_t *mod = CSQC_GetModelForIndex(ent->v->modelindex);
G_FLOAT(OFS_RETURN) = Mod_TagNumForName(mod, tagname);
}
static void QCBUILTIN PF_rotatevectorsbyangles (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float *ang = G_VECTOR(OFS_PARM0);
@ -3439,12 +3384,6 @@ static void QCBUILTIN PF_cs_walkmove (progfuncs_t *prinst, struct globalvars_s *
*csqcg.self = oldself;
}
void PF_cs_touchtriggers(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
wedict_t *ent = (wedict_t*)PROG_TO_EDICT(prinst, *csqcg.self);
World_LinkEdict (&csqc_world, ent, true);
}
static void QCBUILTIN PF_cs_movetogoal (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
wedict_t *ent;
@ -3990,19 +3929,6 @@ static void QCBUILTIN PF_ReadServerEntityState(progfuncs_t *prinst, struct globa
}
#endif
static void QCBUILTIN PF_cs_terrain_edit(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int action = G_FLOAT(OFS_PARM0);
float *pos = G_VECTOR(OFS_PARM1);
float radius = G_FLOAT(OFS_PARM2);
float quant = G_FLOAT(OFS_PARM3);
#if defined(TERRAIN)
G_FLOAT(OFS_RETURN) = Heightmap_Edit(csqc_world.worldmodel, action, pos, radius, quant);
#else
G_FLOAT(OFS_RETURN) = false;
#endif
}
#define PF_FixTen PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme
//prefixes:
@ -4238,8 +4164,8 @@ static struct {
{"frameforname", PF_frameforname, 276},//void(float modidx, string framename) frameforname = #276 (FTE_CSQC_SKELETONOBJECTS)
{"frameduration", PF_frameduration, 277},//void(float modidx, float framenum) frameduration = #277 (FTE_CSQC_SKELETONOBJECTS)
{"terrain_edit", PF_cs_terrain_edit, 278},//void(float action, vector pos, float radius, float quant) terrain_edit = #278 (??FTE_TERRAIN_EDIT??)
{"touchtriggers", PF_cs_touchtriggers, 279},//void() touchtriggers = #279;
{"terrain_edit", PF_terrain_edit, 278},//void(float action, vector pos, float radius, float quant) terrain_edit = #278 (??FTE_TERRAIN_EDIT??)
{"touchtriggers", PF_touchtriggers, 279},//void() touchtriggers = #279;
{"skel_ragupdate", PF_skel_ragedit, 281},// (FTE_QC_RAGDOLL)
{"skel_mmap", PF_skel_mmap, 282},// (FTE_QC_RAGDOLL)
//300
@ -4386,17 +4312,17 @@ static struct {
{"te_lightning1", PF_cl_te_lightning1, 428}, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
{"te_lightning2", PF_cl_te_lightning2,429}, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
{"te_lightning3", PF_cl_te_lightning3,430}, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
{"te_beam", PF_cl_te_beam, 431}, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
{"vectorvectors", PF_cs_vectorvectors,432}, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
{"te_plasmaburn", PF_cl_te_plasmaburn,433}, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
// {"getsurfacenumpoints", PF_Fixme, 434}, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
{"te_lightning3", PF_cl_te_lightning3, 430}, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
{"te_beam", PF_cl_te_beam, 431}, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
{"vectorvectors", PF_cs_vectorvectors, 432}, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
{"te_plasmaburn", PF_cl_te_plasmaburn, 433}, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
{"getsurfacenumpoints", PF_getsurfacenumpoints, 434}, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
// {"getsurfacepoint", PF_Fixme, 435}, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
// {"getsurfacenormal", PF_Fixme, 436}, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
// {"getsurfacetexture", PF_Fixme, 437}, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
// {"getsurfacenearpoint", PF_Fixme, 438}, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
// {"getsurfaceclippedpoint", PF_Fixme, 439}, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
{"getsurfacepoint", PF_getsurfacepoint, 435}, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
{"getsurfacenormal", PF_getsurfacenormal, 436}, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
{"getsurfacetexture", PF_getsurfacetexture, 437}, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
{"getsurfacenearpoint", PF_getsurfacenearpoint, 438}, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
{"getsurfaceclippedpoint", PF_getsurfaceclippedpoint, 439}, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
{"clientcommand", PF_NoCSQC, 440}, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND) (don't implement)
{"tokenize", PF_Tokenize, 441}, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
@ -4411,8 +4337,8 @@ static struct {
{"findflags", PF_FindFlags, 449}, // #449 entity(entity start, .entity fld, float match) findflags (DP_QC_FINDFLAGS)
{"findchainflags", PF_cs_findchainflags, 450}, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
{"gettagindex", PF_cs_gettagindex, 451}, // #451 float(entity ent, string tagname) gettagindex (DP_MD3_TAGSINFO)
{"gettaginfo", PF_cs_gettaginfo, 452}, // #452 vector(entity ent, float tagindex) gettaginfo (DP_MD3_TAGSINFO)
{"gettagindex", PF_gettagindex, 451}, // #451 float(entity ent, string tagname) gettagindex (DP_MD3_TAGSINFO)
{"gettaginfo", PF_gettaginfo, 452}, // #452 vector(entity ent, float tagindex) gettaginfo (DP_MD3_TAGSINFO)
{"dropclient", PF_NoCSQC, 453}, // #453 void(entity player) dropclient (DP_SV_BOTCLIENT) (don't implement)
{"spawnclient", PF_NoCSQC, 454}, // #454 entity() spawnclient (DP_SV_BOTCLIENT) (don't implement)
@ -5608,8 +5534,10 @@ void CSQC_ParseEntities(void)
if (!csqcprogs)
Host_EndGame("CSQC needs to be initialized for this server.\n");
if (!csqcg.ent_update || !csqcg.self || !csqc_world.worldmodel || csqc_world.worldmodel->needload)
if (!csqcg.ent_update || !csqcg.self)
Host_EndGame("CSQC is unable to parse entities\n");
if (!csqc_world.worldmodel || csqc_world.worldmodel->needload)
Host_EndGame("world is not yet initialised\n");
pr_globals = PR_globals(csqcprogs, PR_CURRENT);

View file

@ -23,7 +23,7 @@ this file deals with qc builtins to apply custom skeletal blending (skeletal obj
#include "quakedef.h"
#ifdef CSQC_DAT
#if defined(CSQC_DAT) || !defined(CLIENTONLY)
#define RAGDOLL
#include "pr_common.h"
@ -94,6 +94,23 @@ static doll_t *dolllist;
static skelobject_t skelobjects[MAX_SKEL_OBJECTS];
static int numskelobjectsused;
static void bonemat_fromidentity(float *out)
{
out[0] = 1;
out[1] = 0;
out[2] = 0;
out[3] = 0;
out[4] = 0;
out[5] = 1;
out[6] = 0;
out[7] = 0;
out[8] = 0;
out[9] = 0;
out[10] = 1;
out[11] = 0;
}
static void bonemat_fromqcvectors(float *out, const float vx[3], const float vy[3], const float vz[3], const float t[3])
{
out[0] = vx[0];
@ -109,6 +126,20 @@ static void bonemat_fromqcvectors(float *out, const float vx[3], const float vy[
out[10] = vz[2];
out[11] = t[2];
}
static void bonemat_fromentity(world_t *w, wedict_t *ed, float *trans)
{
vec3_t d[3], a;
model_t *mod;
mod = w->Get_CModel(w, ed->v->modelindex);
if (!mod || mod->type == mod_alias)
a[0] = -ed->v->angles[0];
else
a[0] = ed->v->angles[0];
a[1] = ed->v->angles[1];
a[2] = ed->v->angles[2];
AngleVectors(a, d[0], d[1], d[2]);
bonemat_fromqcvectors(trans, d[0], d[1], d[2], ed->v->origin);
}
static void bonemat_toqcvectors(const float *in, float vx[3], float vy[3], float vz[3], float t[3])
{
vx[0] = in[0];
@ -742,6 +773,71 @@ void QCBUILTIN PF_skel_get_boneabs (progfuncs_t *prinst, struct globalvars_s *pr
}
}
//void(entity ent, float bonenum, vector org, optional fwd, right, up) skel_set_bone_world (FTE_CSQC_SKELETONOBJECTS2) (reads v_forward etc)
void QCBUILTIN PF_skel_set_bone_world (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *w = prinst->parms->user;
wedict_t *ent = G_WEDICT(prinst, OFS_PARM0);
unsigned int boneidx = G_FLOAT(OFS_PARM1)-1;
float *matrix[3];
skelobject_t *skelobj;
float *bone;
float childworld[12], parentinv[12];
/*sort out the parameters*/
if (*prinst->callargc == 4)
{
vec3_t d[3], a;
a[0] = G_VECTOR(OFS_PARM2)[0] * -1; /*mod_alias bug*/
a[1] = G_VECTOR(OFS_PARM2)[1];
a[2] = G_VECTOR(OFS_PARM2)[2];
AngleVectors(a, d[0], d[1], d[2]);
bonemat_fromqcvectors(childworld, d[0], d[1], d[2], G_VECTOR(OFS_PARM2));
}
else
{
if (*prinst->callargc > 5)
{
matrix[0] = G_VECTOR(OFS_PARM3);
matrix[1] = G_VECTOR(OFS_PARM4);
matrix[2] = G_VECTOR(OFS_PARM5);
}
else
{
matrix[0] = w->g.v_forward;
matrix[1] = w->g.v_right;
matrix[2] = w->g.v_up;
}
bonemat_fromqcvectors(childworld, matrix[0], matrix[1], matrix[2], G_VECTOR(OFS_PARM2));
}
/*make sure the skeletal object is correct*/
skelobj = skel_get(prinst, ent->xv->skeletonindex, 0);
if (!skelobj || boneidx >= skelobj->numbones)
return;
/*get the inverse of the parent matrix*/
{
float parentabs[12];
float parentw[12];
float parentent[12];
framestate_t fstate;
w->Get_FrameState(w, ent, &fstate);
if (!Mod_GetTag(skelobj->model, boneidx+1, &fstate, parentabs))
{
bonemat_fromidentity(parentabs);
}
bonemat_fromentity(w, ent, parentent);
Matrix3x4_Multiply(parentent, parentabs, parentw);
Matrix3x4_Invert_Simple(parentw, parentinv);
}
/*calc the result*/
bone = skelobj->bonematrix+12*boneidx;
Matrix3x4_Multiply(parentinv, childworld, bone);
}
//void(float skel, float bonenum, vector org) skel_set_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
void QCBUILTIN PF_skel_set_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
@ -770,7 +866,7 @@ void QCBUILTIN PF_skel_set_bone (progfuncs_t *prinst, struct globalvars_s *pr_gl
return;
bone = skelobj->bonematrix+12*boneidx;
bonemat_fromqcvectors(skelobj->bonematrix+12*boneidx, matrix[0], matrix[1], matrix[2], G_VECTOR(OFS_PARM2));
bonemat_fromqcvectors(bone, matrix[0], matrix[1], matrix[2], G_VECTOR(OFS_PARM2));
}
//void(float skel, float bonenum, vector org [, vector fwd, vector right, vector up]) skel_mul_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
@ -908,5 +1004,56 @@ void QCBUILTIN PF_skel_delete (progfuncs_t *prinst, struct globalvars_s *pr_glob
pendingkill = true;
}
}
//vector(entity ent, float tag) gettaginfo (DP_MD3_TAGSINFO)
void QCBUILTIN PF_gettaginfo (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *w = prinst->parms->user;
wedict_t *ent = G_WEDICT(prinst, OFS_PARM0);
int tagnum = G_FLOAT(OFS_PARM1);
int modelindex = ent->v->modelindex;
model_t *mod = w->Get_CModel(w, modelindex);
float transent[12];
float transforms[12];
float result[12];
framestate_t fstate;
w->Get_FrameState(w, ent, &fstate);
if (!Mod_GetTag(mod, tagnum, &fstate, transforms))
{
bonemat_fromidentity(transforms);
}
if (ent->xv->tag_entity)
{
#ifdef warningmsg
#pragma warningmsg("PF_gettaginfo: This function doesn't honour attachments")
#endif
Con_Printf("bug: PF_gettaginfo doesn't support attachments\n");
}
bonemat_fromentity(w, ent, transent);
R_ConcatTransforms((void*)transent, (void*)transforms, (void*)result);
bonemat_toqcvectors(result, w->g.v_forward, w->g.v_right, w->g.v_up, G_VECTOR(OFS_RETURN));
}
//vector(entity ent, string tagname) gettagindex (DP_MD3_TAGSINFO)
void QCBUILTIN PF_gettagindex (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *w = prinst->parms->user;
wedict_t *ent = G_WEDICT(prinst, OFS_PARM0);
char *tagname = PR_GetStringOfs(prinst, OFS_PARM1);
model_t *mod = *tagname?w->Get_CModel(w, ent->v->modelindex):NULL;
if (mod)
G_FLOAT(OFS_RETURN) = Mod_TagNumForName(mod, tagname);
else
G_FLOAT(OFS_RETURN) = 0;
}
#endif

View file

@ -158,8 +158,8 @@ typedef struct
float m_view[16];
vec3_t gfog_rgb;
float gfog_alpha;
float gfog_density;
float gfog_alpha;
vrect_t pxrect; /*vrect, but in pixels rather than virtual coords*/
qboolean externalview; /*draw external models and not viewmodels*/
@ -204,8 +204,8 @@ void Surf_RenderDynamicLightmaps (struct msurface_s *fa);
void Surf_RenderAmbientLightmaps (struct msurface_s *fa, int ambient);
int Surf_LightmapShift (struct model_s *model);
#ifndef LMBLOCK_WIDTH
#define LMBLOCK_WIDTH 256
#define LMBLOCK_HEIGHT 256
#define LMBLOCK_WIDTH 128
#define LMBLOCK_HEIGHT 128
typedef struct glRect_s {
unsigned char l,t,w,h;
} glRect_t;
@ -272,6 +272,8 @@ enum imageflags
IF_NOALPHA = 1<<3,
IF_NOGAMMA = 1<<4,
IF_NEAREST = 1<<5,
IF_CUBEMAP = 1<<6,
IF_3DMAP = 1<<7,
IF_SUBDIRONLY = 1<<31
};

View file

@ -92,8 +92,8 @@ cvar_t r_flashblend = SCVARF ("gl_flashblend", "0",
CVAR_ARCHIVE);
cvar_t r_flashblendscale = SCVARF ("gl_flashblendscale", "0.35",
CVAR_ARCHIVE);
cvar_t r_floorcolour = SCVARF ("r_floorcolour", "255 255 255",
CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);
cvar_t r_floorcolour = CVARAF ("r_floorcolour", "255 255 255",
"r_floorcolor", CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);
cvar_t r_floortexture = SCVARF ("r_floortexture", "",
CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);
cvar_t r_fullbright = SCVARF ("r_fullbright", "0",
@ -122,8 +122,8 @@ cvar_t r_stainfadetime = SCVAR ("r_stainfadetime", "1");
cvar_t r_stains = CVARFC("r_stains", IFMINIMAL("0","0.75"),
CVAR_ARCHIVE,
Cvar_Limiter_ZeroToOne_Callback);
cvar_t r_wallcolour = CVARF ("r_wallcolour", "255 255 255",
CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);//FIXME: broken
cvar_t r_wallcolour = CVARAF ("r_wallcolour", "255 255 255",
"r_wallcolor", CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);//FIXME: broken
cvar_t r_walltexture = CVARF ("r_walltexture", "",
CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM); //FIXME: broken
cvar_t r_wateralpha = CVARF ("r_wateralpha", "1",

View file

@ -2031,9 +2031,9 @@ void Sbar_Hexen2DrawExtra (int pnum)
Sbar_DrawTinyString (11, 79, va("abilities"));
if (cl.stats[pnum][STAT_H2_FLAGS] & (1<<22))
Sbar_DrawTinyString (8, 89, va("ability 1"));
Sbar_DrawTinyString (8, 89, T_GetString(400 + 2*(pclass-1) + 0));
if (cl.stats[pnum][STAT_H2_FLAGS] & (1<<23))
Sbar_DrawTinyString (8, 96, va("ability 2"));
Sbar_DrawTinyString (8, 96, T_GetString(400 + 2*(pclass-1) + 1));
for (i = 0; i < 4; i++)
{
@ -2404,14 +2404,14 @@ void Sbar_Draw (void)
if (sbar_hexen2)
{
if (sb_lines > 0)
if (sb_lines > 24 || sb_hexen2_extra_info[pnum])
{
Sbar_Hexen2DrawExtra(pnum);
Sbar_Hexen2DrawBasic(pnum);
Sbar_Hexen2DrawInventory(pnum);
}
else
else if (sb_lines > 0)
Sbar_Hexen2DrawMinimal(pnum);
Sbar_Hexen2DrawInventory(pnum);
if (cl.deathmatch)
Sbar_MiniDeathmatchOverlay ();

View file

@ -51,7 +51,6 @@ unsigned int sys_parenttop;
unsigned int sys_parentwidth; //valid if sys_parentwindow is set
unsigned int sys_parentheight;
/*
================
Sys_RandomBytes
@ -813,7 +812,7 @@ void Sys_Quit (void)
longjmp (host_abort, 1);
}
#else
exit (0);
exit(1);
#endif
}

View file

@ -366,7 +366,7 @@ void GLV_Gamma_Callback(struct cvar_s *var, char *oldvalue)
{
BuildGammaTable (v_gamma.value, v_contrast.value);
vid.recalc_refdef = 1; // force a surface cache flush
GLV_UpdatePalette (true, 0);
V_UpdatePalette (true);
}
#endif
@ -625,9 +625,7 @@ void V_CalcPowerupCshift (void)
V_CalcBlend
=============
*/
#if defined(GLQUAKE) || defined(D3DQUAKE)
void GLV_CalcBlend (float *hw_blend)
void V_CalcBlend (float *hw_blend)
{
float a2;
int j;
@ -689,14 +687,20 @@ void GLV_CalcBlend (float *hw_blend)
V_UpdatePalette
=============
*/
void GLV_UpdatePalette (qboolean force, double ftime)
void V_UpdatePalette (qboolean force)
{
int i;
float newhw_blend[4];
int ir, ig, ib;
float ftime;
static float oldtime;
RSpeedMark();
ftime = cl.time - oldtime;
oldtime = cl.time;
if (ftime < 0)
ftime = 0;
V_CalcPowerupCshift ();
// drop the damage value
@ -709,7 +713,7 @@ void GLV_UpdatePalette (qboolean force, double ftime)
if (cl.cshifts[CSHIFT_BONUS].percent <= 0)
cl.cshifts[CSHIFT_BONUS].percent = 0;
GLV_CalcBlend(newhw_blend);
V_CalcBlend(newhw_blend);
if (hw_blend[0] != newhw_blend[0] || hw_blend[1] != newhw_blend[1] || hw_blend[2] != newhw_blend[2] || hw_blend[3] != newhw_blend[3] || force)
{
@ -744,7 +748,7 @@ void GLV_UpdatePalette (qboolean force, double ftime)
RSpeedEnd(RSPEED_PALETTEFLASHES);
}
#endif
/*
=============
V_UpdatePalette
@ -1468,8 +1472,6 @@ void V_RenderView (void)
//work out which packet entities are solid
CL_SetSolidEntities ();
// CL_EmitEntities();
// Set up prediction for other players
CL_SetUpPlayerPrediction(false);

View file

@ -29,8 +29,7 @@ extern qboolean r_secondaryview;
void V_Init (void);
void V_RenderView (void);
float V_CalcRoll (vec3_t angles, vec3_t velocity);
void GLV_UpdatePalette (qboolean force, double ftime);
void SWV_UpdatePalette (qboolean force, double ftime);
void V_UpdatePalette (qboolean force);
void V_ClearCShifts (void);
entity_t *V_AddEntity(entity_t *in);
void VQ2_AddLerpEntity(entity_t *in);

View file

@ -245,6 +245,18 @@ static void GenMatrixPosQuat4Scale(vec3_t pos, vec4_t quat, vec3_t scale, float
result[1*4+3] = pos[1];
result[2*4+3] = pos[2];
}
/*like above, but guess the quat.w*/
static void GenMatrixPosQuat3Scale(vec3_t pos, vec3_t quat3, vec3_t scale, float result[12])
{
vec4_t quat4;
float term = 1 - DotProduct(quat3, quat3);
if (term < 0)
quat4[3] = 0;
else
quat4[3] = - (float) sqrt(term);
VectorCopy(quat3, quat4);
GenMatrixPosQuat4Scale(pos, quat4, scale, result);
}
static void GenMatrix(float x, float y, float z, float qx, float qy, float qz, float result[12])
{
@ -777,7 +789,7 @@ static int Alias_BuildLerps(float plerp[4], float *pose[4], int numbones, galias
return l;
}
//
//ignores any skeletal objects
int Alias_GetBoneRelations(galiasinfo_t *inf, framestate_t *fstate, float *result, int firstbone, int lastbones)
{
#ifdef SKELETALMODELS
@ -894,7 +906,7 @@ int Alias_GetBoneRelations(galiasinfo_t *inf, framestate_t *fstate, float *resul
}
//_may_ write into bonepose, return value is the real result. obtains absolute values
float *Alias_GetBonePositions(galiasinfo_t *inf, framestate_t *fstate, float *buffer, int buffersize)
float *Alias_GetBonePositions(galiasinfo_t *inf, framestate_t *fstate, float *buffer, int buffersize, qboolean renderable)
{
#ifdef SKELETALMODELS
float relationsbuf[MAX_BONES][12];
@ -909,7 +921,19 @@ float *Alias_GetBonePositions(galiasinfo_t *inf, framestate_t *fstate, float *bu
relations = fstate->bonestate;
numbones = inf->numbones;
if (fstate->boneabs)
{
/*we may need to invert by the inverse of the base pose to get the bones into the proper positions*/
if (!inf->numswtransforms && renderable)
{
int i;
for (i = 0; i < inf->numbones; i++)
{
R_ConcatTransforms((void*)(relations + i*12), (void*)(bones[i].inverse), (void*)(buffer + i*12));
}
return buffer;
}
return relations;
}
}
else
{
@ -921,13 +945,30 @@ float *Alias_GetBonePositions(galiasinfo_t *inf, framestate_t *fstate, float *bu
{
int i, k;
for (i = 0; i < numbones; i++)
if (!inf->numswtransforms && renderable)
{
if (bones[i].parent >= 0)
R_ConcatTransforms((void*)(buffer + bones[i].parent*12), (void*)((float*)relations+i*12), (void*)(buffer+i*12));
else
for (k = 0;k < 12;k++) //parentless
buffer[i*12+k] = ((float*)relations)[i*12+k];
float tmp[12];
for (i = 0; i < numbones; i++)
{
if (bones[i].parent >= 0)
R_ConcatTransforms((void*)(buffer + bones[i].parent*12), (void*)((float*)relations+i*12), (void*)tmp);
else
for (k = 0;k < 12;k++) //parentless
tmp[k] = ((float*)relations)[i*12+k];
R_ConcatTransforms((void*)tmp, (void*)bones[i].inverse, (void*)(buffer+i*12));
}
}
else
{
for (i = 0; i < numbones; i++)
{
if (bones[i].parent >= 0)
R_ConcatTransforms((void*)(buffer + bones[i].parent*12), (void*)((float*)relations+i*12), (void*)(buffer+i*12));
else
for (k = 0;k < 12;k++) //parentless
buffer[i*12+k] = ((float*)relations)[i*12+k];
}
}
return buffer;
}
@ -995,7 +1036,7 @@ float *Alias_GetBonePositions(galiasinfo_t *inf, framestate_t *fstate, float *bu
return buffer;
}
#endif
return 0;
return NULL;
}
@ -1480,7 +1521,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int surfnum, ent
meshcache.usebonepose = NULL;
if (inf->numbones)
{
meshcache.usebonepose = Alias_GetBonePositions(inf, &e->framestate, meshcache.bonepose, MAX_BONES);
meshcache.usebonepose = Alias_GetBonePositions(inf, &e->framestate, meshcache.bonepose, MAX_BONES, true);
if (e->fatness || !inf->ofs_skel_idx || !usebones)
{
@ -3420,56 +3461,79 @@ qboolean Mod_GetTag(model_t *model, int tagnum, framestate_t *fstate, float *res
#ifdef warningmsg
#pragma warningmsg("fixme: no base info")
#endif
frame1 = fstate->g[FS_REG].frame[0];
frame2 = fstate->g[FS_REG].frame[1];
f1time = fstate->g[FS_REG].frametime[0];
f2time = fstate->g[FS_REG].frametime[1];
f2ness = fstate->g[FS_REG].lerpfrac;
if (tagnum <= 0 || tagnum > inf->numbones)
return false;
tagnum--; //tagnum 0 is 'use my angles/org'
if (frame1 < 0 || frame1 >= inf->groups)
return false;
if (frame2 < 0 || frame2 >= inf->groups)
{
f2ness = 0;
frame2 = frame1;
}
bone = (galiasbone_t*)((char*)inf + inf->ofsbones);
//the higher level merges old/new anims, but we still need to blend between automated frame-groups.
g1 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame1);
g2 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame2);
f1time *= g1->rate;
frame1 = (int)f1time%g1->numposes;
frame2 = ((int)f1time+1)%g1->numposes;
f1time = f1time - (int)f1time;
pose[numposes] = (float *)((char *)g1 + g1->poseofs + sizeof(float)*inf->numbones*12*frame1);
plerp[numposes] = (1-f1time) * (1-f2ness);
numposes++;
if (frame1 != frame2)
if (fstate->bonestate)
{
pose[numposes] = (float *)((char *)g1 + g1->poseofs + sizeof(float)*inf->numbones*12*frame2);
plerp[numposes] = f1time * (1-f2ness);
numposes++;
}
if (f2ness)
{
f2time *= g2->rate;
frame1 = (int)f2time%g2->numposes;
frame2 = ((int)f2time+1)%g2->numposes;
f2time = f2time - (int)f2time;
pose[numposes] = (float *)((char *)g2 + g2->poseofs + sizeof(float)*inf->numbones*12*frame1);
plerp[numposes] = (1-f2time) * f2ness;
numposes++;
if (frame1 != frame2)
if (tagnum >= fstate->bonecount)
return false;
if (fstate->boneabs)
{
pose[numposes] = (float *)((char *)g2 + g2->poseofs + sizeof(float)*inf->numbones*12*frame2);
plerp[numposes] = f2time * f2ness;
memcpy(result, fstate->bonestate + 12 * tagnum, 12*sizeof(*result));
return true;
}
pose[0] = fstate->bonestate;
plerp[0] = 1;
numposes = 1;
}
else
{
frame1 = fstate->g[FS_REG].frame[0];
frame2 = fstate->g[FS_REG].frame[1];
f1time = fstate->g[FS_REG].frametime[0];
f2time = fstate->g[FS_REG].frametime[1];
f2ness = fstate->g[FS_REG].lerpfrac;
if (frame1 < 0 || frame1 >= inf->groups)
return false;
if (frame2 < 0 || frame2 >= inf->groups)
{
f2ness = 0;
frame2 = frame1;
}
//the higher level merges old/new anims, but we still need to blend between automated frame-groups.
g1 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame1);
g2 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame2);
if (f2ness != 1)
{
f1time *= g1->rate;
frame1 = (int)f1time%g1->numposes;
frame2 = ((int)f1time+1)%g1->numposes;
f1time = f1time - (int)f1time;
pose[numposes] = (float *)((char *)g1 + g1->poseofs + sizeof(float)*inf->numbones*12*frame1);
plerp[numposes] = (1-f1time) * (1-f2ness);
numposes++;
if (frame1 != frame2)
{
pose[numposes] = (float *)((char *)g1 + g1->poseofs + sizeof(float)*inf->numbones*12*frame2);
plerp[numposes] = f1time * (1-f2ness);
numposes++;
}
}
if (f2ness)
{
f2time *= g2->rate;
frame1 = (int)f2time%g2->numposes;
frame2 = ((int)f2time+1)%g2->numposes;
f2time = f2time - (int)f2time;
pose[numposes] = (float *)((char *)g2 + g2->poseofs + sizeof(float)*inf->numbones*12*frame1);
plerp[numposes] = (1-f2time) * f2ness;
numposes++;
if (frame1 != frame2)
{
pose[numposes] = (float *)((char *)g2 + g2->poseofs + sizeof(float)*inf->numbones*12*frame2);
plerp[numposes] = f2time * f2ness;
numposes++;
}
}
}
@ -5596,7 +5660,8 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
texnums_t *texnum;
index_t *idx;
float basepose[12 * MAX_BONES];
float invbasepose[12 * MAX_BONES];
qboolean baseposeonly;
qboolean noweights;
if (memcmp(h->magic, IQM_MAGIC, sizeof(h->magic)))
{
@ -5613,17 +5678,6 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
Con_Printf("%s: size (%u != %u)\n", mod->name, h->filesize, com_filesize);
return NULL;
}
/*
struct iqmjoint
unsigned int name;
int parent;
float translate[3], rotate[3], scale[3];
unsigned int num_meshes, ofs_meshes;
unsigned int num_vertexarrays, num_vertexes, ofs_vertexarrays;
unsigned int num_triangles, ofs_triangles, ofs_adjacency;
unsigned int num_joints, ofs_joints;
*/
varray = (struct iqmvertexarray*)(buffer + h->ofs_vertexarrays);
for (i = 0; i < h->num_vertexarrays; i++)
@ -5651,6 +5705,20 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
if (!h->num_meshes)
return NULL;
if (h->num_vertexes > 0 && (!vpos || !tcoord))
{
Con_Printf("%s is missing vertex array data\n", loadmodel->name);
return NULL;
}
noweights = !vbone || !vweight;
if (noweights)
{
if (h->num_frames || h->num_anims || h->num_joints)
return NULL;
}
baseposeonly = !h->num_anims;
strings = buffer + h->ofs_text;
mesh = (struct iqmmesh*)(buffer + h->ofs_meshes);
@ -5660,18 +5728,27 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
#ifndef SERVERONLY
sizeof(*skin)*h->num_meshes + sizeof(*texnum)*h->num_meshes +
#endif
sizeof(*fgroup)*h->num_anims + sizeof(float)*12*h->num_poses*h->num_frames + sizeof(*bones)*h->num_joints +
(sizeof(*opos) + sizeof(*onorm) + sizeof(*oweight) + sizeof(*otcoords) + sizeof(*oindex)) * h->num_vertexes);
sizeof(*fgroup)*(baseposeonly?1:h->num_anims) + sizeof(float)*12*(baseposeonly?h->num_joints:(h->num_poses*h->num_frames)) + sizeof(*bones)*h->num_joints +
(sizeof(*opos) + sizeof(*onorm) + sizeof(*otcoords) + (noweights?0:(sizeof(*oindex)+sizeof(*oweight)))) * h->num_vertexes);
bones = (galiasbone_t*)(gai + h->num_meshes);
opos = (vecV_t*)(bones + h->num_joints);
onorm = (vec3_t*)(opos + h->num_vertexes);
oindex = (byte_vec4_t*)(onorm + h->num_vertexes);
oweight = (vec4_t*)(oindex + h->num_vertexes);
otcoords = (vec2_t*)(oweight + h->num_vertexes);
if (noweights)
{
oindex = NULL;
oweight = NULL;
otcoords = (vec2_t*)(onorm + h->num_vertexes);
}
else
{
oindex = (byte_vec4_t*)(onorm + h->num_vertexes);
oweight = (vec4_t*)(oindex + h->num_vertexes);
otcoords = (vec2_t*)(oweight + h->num_vertexes);
}
fgroup = (galiasgroup_t*)(otcoords + h->num_vertexes);
opose = (float*)(fgroup + h->num_anims);
opose = (float*)(fgroup + (baseposeonly?1:h->num_anims));
#ifndef SERVERONLY
skin = (galiasskin_t*)(opose + 12*h->num_poses*h->num_frames);
skin = (galiasskin_t*)(opose + 12*(baseposeonly?h->num_joints:h->num_poses*h->num_frames));
texnum = (texnums_t*)(skin + h->num_meshes);
#endif
@ -5686,23 +5763,20 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
vec3_t pos;
vec4_t quat;
vec3_t scale;
float mat[12], mat2[12];
float mat[12];
for (i = 0; i < h->num_joints; i++)
{
Q_strncpyz(bones[i].name, strings+ijoint[i].name, sizeof(ijoint[i].name));
bones[i].parent = ijoint[i].parent;
GenMatrixPosQuat4Scale(ijoint[i].translate, ijoint[i].rotate, ijoint[i].scale, &basepose[i*12]);
GenMatrixPosQuat3Scale(ijoint[i].translate, ijoint[i].rotate, ijoint[i].scale, &basepose[i*12]);
Matrix3x4_Invert(&basepose[i*12], &invbasepose[12*i]);
if (ijoint[i].parent >= 0)
{
Matrix3x4_Multiply(&basepose[i*12], &basepose[ijoint[i].parent*12], mat);
Matrix3x4_Multiply(mat, &basepose[ijoint[i].parent*12], &basepose[i*12]);
else
memcpy(&basepose[i*12], mat, sizeof(mat));
Matrix3x4_Multiply(&invbasepose[ijoint[i].parent*12], &invbasepose[i*12], mat);
memcpy(&invbasepose[i*12], mat, sizeof(mat));
}
Matrix3x4_Invert_Simple(&basepose[i*12], bones[i].inverse);
}
for (i = 0; i < h->num_frames; i++)
@ -5721,15 +5795,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
quat[3] = -sqrt(max(1.0 - pow(VectorLength(quat),2), 0.0));
GenMatrixPosQuat4Scale(pos, quat, scale, opose + (i*h->num_poses+j)*12);
if (ijoint[j].parent >= 0)
{
Matrix3x4_Multiply(mat, &basepose[ijoint[j].parent*12], mat2);
Matrix3x4_Multiply(&invbasepose[j*12], mat2, &opose[(i*h->num_poses+j)*12]);
}
else
Matrix3x4_Multiply(&invbasepose[j*12], mat, &opose[(i*h->num_poses+j)*12]);
GenMatrixPosQuat3Scale(pos, quat, scale, &opose[(i*h->num_poses+j)*12]);
}
}
}
@ -5740,23 +5806,20 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
vec3_t pos;
vec4_t quat;
vec3_t scale;
float mat[12], mat2[12];
float mat[12];
for (i = 0; i < h->num_joints; i++)
{
Q_strncpyz(bones[i].name, strings+ijoint[i].name, sizeof(bones[i].name));
bones[i].parent = ijoint[i].parent;
GenMatrixPosQuat4Scale(ijoint[i].translate, ijoint[i].rotate, ijoint[i].scale, &basepose[i*12]);
GenMatrixPosQuat4Scale(ijoint[i].translate, ijoint[i].rotate, ijoint[i].scale, mat);
Matrix3x4_Invert(&basepose[i*12], &invbasepose[12*i]);
if (ijoint[i].parent >= 0)
{
Matrix3x4_Multiply(&basepose[i*12], &basepose[ijoint[i].parent*12], mat);
Matrix3x4_Multiply(mat, &basepose[ijoint[i].parent*12], &basepose[i*12]);
else
memcpy(&basepose[i*12], mat, sizeof(mat));
Matrix3x4_Multiply(&invbasepose[ijoint[i].parent*12], &invbasepose[i*12], mat);
memcpy(&invbasepose[i*12], mat, sizeof(mat));
}
Matrix3x4_Invert_Simple(&basepose[i*12], bones[i].inverse);
}
for (i = 0; i < h->num_frames; i++)
@ -5774,29 +5837,35 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
scale[1] = p->channeloffset[8]; if (p->mask & 256) scale[1] += *framedata++ * p->channelscale[8];
scale[2] = p->channeloffset[9]; if (p->mask & 512) scale[2] += *framedata++ * p->channelscale[9];
GenMatrixPosQuat4Scale(pos, quat, scale, mat);
if (ijoint[j].parent >= 0)
{
Matrix3x4_Multiply(mat, &basepose[ijoint[j].parent*12], mat2);
Matrix3x4_Multiply(&invbasepose[j*12], mat2, &opose[(i*h->num_poses+j)*12]);
}
else
Matrix3x4_Multiply(&invbasepose[j*12], mat, &opose[(i*h->num_poses+j)*12]);
GenMatrixPosQuat4Scale(pos, quat, scale, &opose[(i*h->num_poses+j)*12]);
}
}
}
/*load the framegroup info*/
anim = (struct iqmanim*)(buffer + h->ofs_anims);
for (i = 0; i < h->num_anims; i++)
if (baseposeonly)
{
fgroup[i].isheirachical = true;
fgroup[i].loop = LittleLong(anim[i].flags) & IQM_LOOP;
Q_strncpyz(fgroup[i].name, strings+anim[i].name, sizeof(fgroup[i].name));
fgroup[i].numposes = LittleLong(anim[i].num_frames);
fgroup[i].poseofs = (char*)(opose+LittleLong(anim[i].first_frame)*12*h->num_poses) - (char*)&fgroup[i];
fgroup[i].rate = LittleFloat(anim[i].framerate);
fgroup->isheirachical = false;
fgroup->loop = true;
Q_strncpyz(fgroup->name, "base", sizeof(fgroup->name));
fgroup->numposes = 1;
fgroup->poseofs = (char*)opose - (char*)fgroup;
fgroup->rate = 10;
memcpy(opose, basepose, sizeof(float)*12 * h->num_joints);
}
else
{
/*load the framegroup info*/
anim = (struct iqmanim*)(buffer + h->ofs_anims);
for (i = 0; i < h->num_anims; i++)
{
fgroup[i].isheirachical = true;
fgroup[i].loop = LittleLong(anim[i].flags) & IQM_LOOP;
Q_strncpyz(fgroup[i].name, strings+anim[i].name, sizeof(fgroup[i].name));
fgroup[i].numposes = LittleLong(anim[i].num_frames);
fgroup[i].poseofs = (char*)(opose+LittleLong(anim[i].first_frame)*12*h->num_poses) - (char*)&fgroup[i];
fgroup[i].rate = LittleFloat(anim[i].framerate);
}
}
for (i = 0; i < h->num_meshes; i++)
@ -5807,7 +5876,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
gai[i].shares_bones = 0;
gai[i].numbones = h->num_joints;
gai[i].ofsbones = (char*)bones - (char*)&gai[i];
gai[i].groups = h->num_anims;
gai[i].groups = baseposeonly?1:h->num_anims;
gai[i].groupofs = (char*)fgroup - (char*)&gai[i];
offset = LittleLong(mesh[i].first_vertex);
@ -5850,16 +5919,22 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
gai[i].ofs_skel_norm = (char*)(onorm+offset) - (char*)&gai[i];
gai[i].ofs_skel_svect = 0;
gai[i].ofs_skel_tvect = 0;
gai[i].ofs_skel_idx = (char*)(oindex+offset) - (char*)&gai[i];
gai[i].ofs_skel_weight = (char*)(oweight+offset) - (char*)&gai[i];
gai[i].ofs_skel_idx = oindex?(char*)(oindex+offset) - (char*)&gai[i]:0;
gai[i].ofs_skel_weight = oweight?(char*)(oweight+offset) - (char*)&gai[i]:0;
}
if (!noweights)
{
for (i = 0; i < h->num_vertexes; i++)
{
Vector4Copy(vbone+i*4, oindex[i]);
Vector4Scale(vweight+i*4, 1/255.0, oweight[i]);
}
}
for (i = 0; i < h->num_vertexes; i++)
{
Vector2Copy(tcoord+i*2, otcoords[i]);
VectorCopy(vpos+i*3, opos[i]);
VectorCopy(vnorm+i*4, onorm[i]);
Vector4Copy(vbone+i*4, oindex[i]);
Vector4Scale(vweight+i*4, 1/255.0, oweight[i]);
}
return gai;
}

View file

@ -81,11 +81,13 @@ typedef struct {
vec3_t scale_origin;
} galiaspose_t;
typedef struct galiasbone_s galiasbone_t;
#ifdef SKELETALMODELS
typedef struct galiasbone_s {
struct galiasbone_s {
char name[32];
int parent;
} galiasbone_t;
float inverse[12];
};
typedef struct {
//skeletal poses refer to this.
@ -123,7 +125,7 @@ typedef struct {
} galiascolourmapped_t;
#endif
float *Alias_GetBonePositions(galiasinfo_t *inf, framestate_t *fstate, float *buffer, int buffersize);
float *Alias_GetBonePositions(galiasinfo_t *inf, framestate_t *fstate, float *buffer, int buffersize, qboolean renderable);
#ifdef SKELETALMODELS
void Alias_TransformVerticies(float *bonepose, galisskeletaltransforms_t *weights, int numweights, vecV_t *xyzout, vec3_t *normout);
#endif

View file

@ -47,13 +47,22 @@ cvar_t physics_ode_worldquickstep_iterations = CVARDP4(0, "physics_ode_worldquic
cvar_t physics_ode_contact_mu = CVARDP4(0, "physics_ode_contact_mu", "1", "contact solver mu parameter - friction pyramid approximation 1 (see ODE User Guide)");
cvar_t physics_ode_contact_erp = CVARDP4(0, "physics_ode_contact_erp", "0.96", "contact solver erp parameter - Error Restitution Percent (see ODE User Guide)");
cvar_t physics_ode_contact_cfm = CVARDP4(0, "physics_ode_contact_cfm", "0", "contact solver cfm parameter - Constraint Force Mixing (see ODE User Guide)");
cvar_t physics_ode_world_damping_angle = CVARDP4(0, "physics_ode_world_damping_angle", "0", "damping");
cvar_t physics_ode_world_damping_linear = CVARDP4(0, "physics_ode_world_damping_linear", "0", "damping");
cvar_t physics_ode_world_damping = CVARDP4(0, "physics_ode_world_damping", "1", "enabled damping scale (see ODE User Guide), this scales all damping values, be aware that behavior depends of step type");
cvar_t physics_ode_world_damping_linear = CVARDP4(0, "physics_ode_world_damping_linear", "0.005", "world linear damping scale (see ODE User Guide); use defaults when set to -1");
cvar_t physics_ode_world_damping_linear_threshold = CVARDP4(0, "physics_ode_world_damping_linear_threshold", "0.01", "world linear damping threshold (see ODE User Guide); use defaults when set to -1");
cvar_t physics_ode_world_damping_angular = CVARDP4(0, "physics_ode_world_damping_angular", "0.005", "world angular damping scale (see ODE User Guide); use defaults when set to -1");
cvar_t physics_ode_world_damping_angular_threshold = CVARDP4(0, "physics_ode_world_damping_angular_threshold", "0.01", "world angular damping threshold (see ODE User Guide); use defaults when set to -1");
cvar_t physics_ode_world_erp = CVARDP4(0, "physics_ode_world_erp", "-1", "world solver erp parameter - Error Restitution Percent (see ODE User Guide); use defaults when set to -1");
cvar_t physics_ode_world_cfm = CVARDP4(0, "physics_ode_world_cfm", "-1", "world solver cfm parameter - Constraint Force Mixing (see ODE User Guide); not touched when -1");
cvar_t physics_ode_iterationsperframe = CVARDP4(0, "physics_ode_iterationsperframe", "4", "divisor for time step, runs multiple physics steps per frame");
cvar_t physics_ode_movelimit = CVARDP4(0, "physics_ode_movelimit", "0.5", "clamp velocity if a single move would exceed this percentage of object thickness, to prevent flying through walls");
cvar_t physics_ode_spinlimit = CVARDP4(0, "physics_ode_spinlimit", "10000", "reset spin velocity if it gets too large");
cvar_t physics_ode_autodisable = CVARDP4(0, "physics_ode_autodisable", "1", "automatic disabling of objects which dont move for long period of time, makes object stacking a lot faster");
cvar_t physics_ode_autodisable_steps = CVARDP4(0, "physics_ode_autodisable_steps", "10", "how many steps object should be dormant to be autodisabled");
cvar_t physics_ode_autodisable_time = CVARDP4(0, "physics_ode_autodisable_time", "0", "how many seconds object should be dormant to be autodisabled");
cvar_t physics_ode_autodisable_threshold_linear = CVARDP4(0, "physics_ode_autodisable_threshold_linear", "0.2", "body will be disabled if it's linear move below this value");
cvar_t physics_ode_autodisable_threshold_angular = CVARDP4(0, "physics_ode_autodisable_threshold_angular", "0.3", "body will be disabled if it's angular move below this value");
cvar_t physics_ode_autodisable_threshold_samples = CVARDP4(0, "physics_ode_autodisable_threshold_samples", "5", "average threshold with this number of samples");
// LordHavoc: this large chunk of definitions comes from the ODE library
// include files.
@ -294,30 +303,30 @@ void (ODE_API *dWorldSetContactSurfaceLayer)(dWorldID, dReal depth);
//void (ODE_API *dWorldSetAutoEnableDepthSF1)(dWorldID, int autoEnableDepth);
//int (ODE_API *dWorldGetAutoEnableDepthSF1)(dWorldID);
//dReal (ODE_API *dWorldGetAutoDisableLinearThreshold)(dWorldID);
//void (ODE_API *dWorldSetAutoDisableLinearThreshold)(dWorldID, dReal linear_threshold);
void (ODE_API *dWorldSetAutoDisableLinearThreshold)(dWorldID, dReal linear_threshold);
//dReal (ODE_API *dWorldGetAutoDisableAngularThreshold)(dWorldID);
//void (ODE_API *dWorldSetAutoDisableAngularThreshold)(dWorldID, dReal angular_threshold);
void (ODE_API *dWorldSetAutoDisableAngularThreshold)(dWorldID, dReal angular_threshold);
//dReal (ODE_API *dWorldGetAutoDisableLinearAverageThreshold)(dWorldID);
//void (ODE_API *dWorldSetAutoDisableLinearAverageThreshold)(dWorldID, dReal linear_average_threshold);
//dReal (ODE_API *dWorldGetAutoDisableAngularAverageThreshold)(dWorldID);
//void (ODE_API *dWorldSetAutoDisableAngularAverageThreshold)(dWorldID, dReal angular_average_threshold);
//int (ODE_API *dWorldGetAutoDisableAverageSamplesCount)(dWorldID);
//void (ODE_API *dWorldSetAutoDisableAverageSamplesCount)(dWorldID, unsigned int average_samples_count );
void (ODE_API *dWorldSetAutoDisableAverageSamplesCount)(dWorldID, unsigned int average_samples_count );
//int (ODE_API *dWorldGetAutoDisableSteps)(dWorldID);
//void (ODE_API *dWorldSetAutoDisableSteps)(dWorldID, int steps);
void (ODE_API *dWorldSetAutoDisableSteps)(dWorldID, int steps);
//dReal (ODE_API *dWorldGetAutoDisableTime)(dWorldID);
//void (ODE_API *dWorldSetAutoDisableTime)(dWorldID, dReal time);
void (ODE_API *dWorldSetAutoDisableTime)(dWorldID, dReal time);
//int (ODE_API *dWorldGetAutoDisableFlag)(dWorldID);
void (ODE_API *dWorldSetAutoDisableFlag)(dWorldID, int do_auto_disable);
//dReal (ODE_API *dWorldGetLinearDampingThreshold)(dWorldID w);
//void (ODE_API *dWorldSetLinearDampingThreshold)(dWorldID w, dReal threshold);
void (ODE_API *dWorldSetLinearDampingThreshold)(dWorldID w, dReal threshold);
//dReal (ODE_API *dWorldGetAngularDampingThreshold)(dWorldID w);
//void (ODE_API *dWorldSetAngularDampingThreshold)(dWorldID w, dReal threshold);
void (ODE_API *dWorldSetAngularDampingThreshold)(dWorldID w, dReal threshold);
//dReal (ODE_API *dWorldGetLinearDamping)(dWorldID w);
//void (ODE_API *dWorldSetLinearDamping)(dWorldID w, dReal scale);
void (ODE_API *dWorldSetLinearDamping)(dWorldID w, dReal scale);
//dReal (ODE_API *dWorldGetAngularDamping)(dWorldID w);
//void (ODE_API *dWorldSetAngularDamping)(dWorldID w, dReal scale);
void (ODE_API *dWorldSetDamping)(dWorldID w, dReal linear_scale, dReal angular_scale);
void (ODE_API *dWorldSetAngularDamping)(dWorldID w, dReal scale);
//void (ODE_API *dWorldSetDamping)(dWorldID w, dReal linear_scale, dReal angular_scale);
//dReal (ODE_API *dWorldGetMaxAngularSpeed)(dWorldID w);
//void (ODE_API *dWorldSetMaxAngularSpeed)(dWorldID w, dReal max_speed);
//dReal (ODE_API *dBodyGetAutoDisableLinearThreshold)(dBodyID);
@ -759,30 +768,30 @@ static dllfunction_t odefuncs[] =
// {"dWorldSetAutoEnableDepthSF1", (void **) &dWorldSetAutoEnableDepthSF1},
// {"dWorldGetAutoEnableDepthSF1", (void **) &dWorldGetAutoEnableDepthSF1},
// {"dWorldGetAutoDisableLinearThreshold", (void **) &dWorldGetAutoDisableLinearThreshold},
// {"dWorldSetAutoDisableLinearThreshold", (void **) &dWorldSetAutoDisableLinearThreshold},
{(void **) &dWorldSetAutoDisableLinearThreshold,"dWorldSetAutoDisableLinearThreshold"},
// {"dWorldGetAutoDisableAngularThreshold", (void **) &dWorldGetAutoDisableAngularThreshold},
// {"dWorldSetAutoDisableAngularThreshold", (void **) &dWorldSetAutoDisableAngularThreshold},
{(void **) &dWorldSetAutoDisableAngularThreshold,"dWorldSetAutoDisableAngularThreshold"},
// {"dWorldGetAutoDisableLinearAverageThreshold", (void **) &dWorldGetAutoDisableLinearAverageThreshold},
// {"dWorldSetAutoDisableLinearAverageThreshold", (void **) &dWorldSetAutoDisableLinearAverageThreshold},
// {"dWorldGetAutoDisableAngularAverageThreshold", (void **) &dWorldGetAutoDisableAngularAverageThreshold},
// {"dWorldSetAutoDisableAngularAverageThreshold", (void **) &dWorldSetAutoDisableAngularAverageThreshold},
// {"dWorldGetAutoDisableAverageSamplesCount", (void **) &dWorldGetAutoDisableAverageSamplesCount},
// {"dWorldSetAutoDisableAverageSamplesCount", (void **) &dWorldSetAutoDisableAverageSamplesCount},
{(void **)&dWorldSetAutoDisableAverageSamplesCount, "dWorldSetAutoDisableAverageSamplesCount"},
// {"dWorldGetAutoDisableSteps", (void **) &dWorldGetAutoDisableSteps},
// {"dWorldSetAutoDisableSteps", (void **) &dWorldSetAutoDisableSteps},
{(void **) &dWorldSetAutoDisableSteps, "dWorldSetAutoDisableSteps"},
// {"dWorldGetAutoDisableTime", (void **) &dWorldGetAutoDisableTime},
// {"dWorldSetAutoDisableTime", (void **) &dWorldSetAutoDisableTime},
{(void **) &dWorldSetAutoDisableTime, "dWorldSetAutoDisableTime"},
// {"dWorldGetAutoDisableFlag", (void **) &dWorldGetAutoDisableFlag},
{(void **) &dWorldSetAutoDisableFlag, "dWorldSetAutoDisableFlag"},
// {"dWorldGetLinearDampingThreshold", (void **) &dWorldGetLinearDampingThreshold},
// {"dWorldSetLinearDampingThreshold", (void **) &dWorldSetLinearDampingThreshold},
{(void **) &dWorldSetLinearDampingThreshold, "dWorldSetLinearDampingThreshold"},
// {"dWorldGetAngularDampingThreshold", (void **) &dWorldGetAngularDampingThreshold},
// {"dWorldSetAngularDampingThreshold", (void **) &dWorldSetAngularDampingThreshold},
{(void **) &dWorldSetAngularDampingThreshold, "dWorldSetAngularDampingThreshold"},
// {"dWorldGetLinearDamping", (void **) &dWorldGetLinearDamping},
// {"dWorldSetLinearDamping", (void **) &dWorldSetLinearDamping},
{(void **) &dWorldSetLinearDamping, "dWorldSetLinearDamping"},
// {"dWorldGetAngularDamping", (void **) &dWorldGetAngularDamping},
// {"dWorldSetAngularDamping", (void **) &dWorldSetAngularDamping},
{(void **) &dWorldSetDamping, "dWorldSetDamping"},
{(void **) &dWorldSetAngularDamping, "dWorldSetAngularDamping"},
// {(void **) &dWorldSetDamping, "dWorldSetDamping"},
// {"dWorldGetMaxAngularSpeed", (void **) &dWorldGetMaxAngularSpeed},
// {"dWorldSetMaxAngularSpeed", (void **) &dWorldSetMaxAngularSpeed},
// {"dBodyGetAutoDisableLinearThreshold", (void **) &dBodyGetAutoDisableLinearThreshold},
@ -1187,13 +1196,22 @@ void World_ODE_Init(void)
Cvar_Register(&physics_ode_contact_mu, "ODE Physics Library");
Cvar_Register(&physics_ode_contact_erp, "ODE Physics Library");
Cvar_Register(&physics_ode_contact_cfm, "ODE Physics Library");
Cvar_Register(&physics_ode_world_damping_angle, "ODE Physics Library");
Cvar_Register(&physics_ode_world_damping, "ODE Physics Library");
Cvar_Register(&physics_ode_world_damping_linear, "ODE Physics Library");
Cvar_Register(&physics_ode_world_damping_linear_threshold, "ODE Physics Library");
Cvar_Register(&physics_ode_world_damping_angular, "ODE Physics Library");
Cvar_Register(&physics_ode_world_damping_angular_threshold, "ODE Physics Library");
Cvar_Register(&physics_ode_world_erp, "ODE Physics Library");
Cvar_Register(&physics_ode_world_cfm, "ODE Physics Library");
Cvar_Register(&physics_ode_iterationsperframe, "ODE Physics Library");
Cvar_Register(&physics_ode_movelimit, "ODE Physics Library");
Cvar_Register(&physics_ode_spinlimit, "ODE Physics Library");
Cvar_Register(&physics_ode_autodisable, "ODE Physics Library");
Cvar_Register(&physics_ode_autodisable_steps, "ODE Physics Library");
Cvar_Register(&physics_ode_autodisable_time, "ODE Physics Library");
Cvar_Register(&physics_ode_autodisable_threshold_linear, "ODE Physics Library");
Cvar_Register(&physics_ode_autodisable_threshold_angular, "ODE Physics Library");
Cvar_Register(&physics_ode_autodisable_threshold_samples, "ODE Physics Library");
#ifdef ODE_DYNAMIC
// Load the DLL
@ -1263,12 +1281,37 @@ static void World_ODE_Enable(world_t *world)
world->ode.ode_world = dWorldCreate();
world->ode.ode_space = dQuadTreeSpaceCreate(NULL, center, extents, bound(1, physics_ode_quadtree_depth.ival, 10));
world->ode.ode_contactgroup = dJointGroupCreate(0);
if(physics_ode_world_erp.value >= 0)
dWorldSetERP(world->ode.ode_world, physics_ode_world_erp.value);
if(physics_ode_world_cfm.value >= 0)
dWorldSetCFM(world->ode.ode_world, physics_ode_world_cfm.value);
dWorldSetDamping(world->ode.ode_world, physics_ode_world_damping_linear.value, physics_ode_world_damping_angle.value);
// dWorldSetAutoDisableFlag (world->ode.ode_world, true);
if (physics_ode_world_damping.ival)
{
dWorldSetLinearDamping(world->ode.ode_world, (physics_ode_world_damping_linear.value >= 0) ? (physics_ode_world_damping_linear.value * physics_ode_world_damping.value) : 0);
dWorldSetLinearDampingThreshold(world->ode.ode_world, (physics_ode_world_damping_linear_threshold.value >= 0) ? (physics_ode_world_damping_linear_threshold.value * physics_ode_world_damping.value) : 0);
dWorldSetAngularDamping(world->ode.ode_world, (physics_ode_world_damping_angular.value >= 0) ? (physics_ode_world_damping_angular.value * physics_ode_world_damping.value) : 0);
dWorldSetAngularDampingThreshold(world->ode.ode_world, (physics_ode_world_damping_angular_threshold.value >= 0) ? (physics_ode_world_damping_angular_threshold.value * physics_ode_world_damping.value) : 0);
}
else
{
dWorldSetLinearDamping(world->ode.ode_world, 0);
dWorldSetLinearDampingThreshold(world->ode.ode_world, 0);
dWorldSetAngularDamping(world->ode.ode_world, 0);
dWorldSetAngularDampingThreshold(world->ode.ode_world, 0);
}
if (physics_ode_autodisable.ival)
{
dWorldSetAutoDisableSteps(world->ode.ode_world, bound(1, physics_ode_autodisable_steps.ival, 100));
dWorldSetAutoDisableTime(world->ode.ode_world, physics_ode_autodisable_time.value);
dWorldSetAutoDisableAverageSamplesCount(world->ode.ode_world, bound(1, physics_ode_autodisable_threshold_samples.ival, 100));
dWorldSetAutoDisableLinearThreshold(world->ode.ode_world, physics_ode_autodisable_threshold_linear.value);
dWorldSetAutoDisableAngularThreshold(world->ode.ode_world, physics_ode_autodisable_threshold_angular.value);
dWorldSetAutoDisableFlag (world->ode.ode_world, true);
}
else
dWorldSetAutoDisableFlag (world->ode.ode_world, false);
}
void World_ODE_Start(world_t *world)
@ -1967,7 +2010,7 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
gravity = false;
// compatibility for legacy entities
//if (!VectorLength2(forward) || solid == SOLID_BSP)
// if (!DotProduct(forward,forward) || solid == SOLID_BSP)
{
vec3_t qangles, qavelocity;
VectorCopy(angles, qangles);
@ -2270,6 +2313,21 @@ void World_ODE_Frame(world_t *world, double frametime, double gravity)
int i;
wedict_t *ed;
if (!world->ode.hasodeents)
{
for (i = 0; i < world->num_edicts; i++)
{
ed = (wedict_t*)EDICT_NUM(world->progs, i);
if (ed->v->movetype >= SOLID_PHYSICS_BOX)
{
world->ode.hasodeents = true;
break;
}
}
if (!world->ode.hasodeents)
return;
}
world->ode.ode_iterations = bound(1, physics_ode_iterationsperframe.ival, 1000);
world->ode.ode_step = frametime / world->ode.ode_iterations;
world->ode.ode_movelimit = physics_ode_movelimit.value / world->ode.ode_step;

View file

@ -1956,14 +1956,14 @@ qboolean CModQ3_LoadSubmodels (lump_t *l)
out->maxs[j] = LittleFloat (in->maxs[j]) + 1;
out->origin[j] = (out->maxs[j] + out->mins[j])/2;
}
out->firstsurface = LittleLong (in->firstsurface);
out->numsurfaces = LittleLong (in->num_surfaces);
if (!i)
out->headnode = 0;
else
{
//create a new leaf to hold the bruses and be directly clipped
out->headnode = -1 - numleafs;
out->firstsurface = LittleLong (in->firstsurface);
out->numsurfaces = LittleLong (in->num_surfaces);
// out->firstbrush = LittleLong(in->firstbrush);
// out->num_brushes = LittleLong(in->num_brushes);
@ -3937,6 +3937,8 @@ cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned *c
mod->hulls[j].available = false;
}
mod->nummodelsurfaces = map_cmodels[0].numsurfaces;
for (i=1 ; i< loadmodel->numsubmodels ; i++)
{
cmodel_t *bm;

View file

@ -321,12 +321,12 @@ void VectorAngles(float *forward, float *up, float *result) //up may be NULL
{
if (forward[2] > 0)
{
pitch = 90;
pitch = -M_PI * 0.5;
yaw = up ? atan2(-up[1], -up[0]) : 0;
}
else
{
pitch = 270;
pitch = M_PI * 0.5;
yaw = up ? atan2(up[1], up[0]) : 0;
}
roll = 0;

View file

@ -1275,7 +1275,7 @@ qboolean NET_IsClientLegal(netadr_t *adr)
NetadrToSockadr (adr, &sadr);
if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
Sys_Error ("NET_IsClientLegal: socket:", strerror(qerrno));
sadr.sin_port = 0;
@ -1785,7 +1785,7 @@ ftenet_generic_connection_t *FTENET_Generic_EstablishConnection(int adrfamily, i
ftenet_generic_connection_t *newcon;
unsigned long _true = true;
int newsocket = INVALID_SOCKET;
SOCKET newsocket = INVALID_SOCKET;
int temp;
netadr_t adr;
struct sockaddr_qstorage qs;
@ -1848,8 +1848,10 @@ ftenet_generic_connection_t *FTENET_Generic_EstablishConnection(int adrfamily, i
return NULL;
}
if (family == AF_INET6 && !net_hybriddualstack.ival)
#ifdef IPV6_V6ONLY
if (family == AF_INET6)
setsockopt(newsocket, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&_true, sizeof(_true));
#endif
bufsz = 1<<18;
setsockopt(newsocket, SOL_SOCKET, SO_RCVBUF, (void*)&bufsz, sizeof(bufsz));
@ -3071,7 +3073,7 @@ int maxport = port + 100;
int UDP_OpenSocket (int port, qboolean bcast)
{
int newsocket;
SOCKET newsocket;
struct sockaddr_in address;
unsigned long _true = true;
int i;
@ -3128,7 +3130,7 @@ int maxport = port + 100;
int UDP6_OpenSocket (int port, qboolean bcast)
{
int err;
int newsocket;
SOCKET newsocket;
struct sockaddr_in6 address;
unsigned long _true = true;
// int i;
@ -3136,7 +3138,7 @@ int maxport = port + 100;
memset(&address, 0, sizeof(address));
if ((newsocket = socket (PF_INET6, SOCK_DGRAM, 0)) == -1)
if ((newsocket = socket (PF_INET6, SOCK_DGRAM, 0)) == INVALID_SOCKET)
{
Con_Printf("IPV6 is not supported: %s\n", strerror(qerrno));
return INVALID_SOCKET;
@ -3213,11 +3215,11 @@ int IPX_OpenSocket (int port, qboolean bcast)
#ifndef USEIPX
return 0;
#else
int newsocket;
SOCKET newsocket;
struct sockaddr_ipx address;
u_long _true = 1;
if ((newsocket = socket (PF_IPX, SOCK_DGRAM, NSPROTO_IPX)) == -1)
if ((newsocket = socket (PF_IPX, SOCK_DGRAM, NSPROTO_IPX)) == INVALID_SOCKET)
{
if (qerrno != EAFNOSUPPORT)
Con_Printf ("WARNING: IPX_Socket: socket: %i\n", qerrno);
@ -3347,7 +3349,7 @@ void NET_GetLocalAddress (int socket, netadr_t *out)
}
#ifndef CLIENTONLY
void SVNET_AddPort(void)
void SVNET_AddPort_f(void)
{
netadr_t adr;
char *s = Cmd_Argv(1);
@ -3441,6 +3443,10 @@ void NET_Init (void)
#endif
Cvar_Register(&net_hybriddualstack, "networking");
#ifndef CLIENTONLY
Cmd_AddCommand("sv_addport", SVNET_AddPort_f);
#endif
}
#ifndef SERVERONLY
void NET_InitClient(void)

View file

@ -178,6 +178,228 @@ void VARGS PR_CB_Free(void *mem)
BZ_Free(mem);
}
////////////////////////////////////////////////////
//model functions
//DP_QC_GETSURFACE
// #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
void QCBUILTIN PF_getsurfacenumpoints(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
unsigned int surfnum;
model_t *model;
wedict_t *ent;
world_t *w = prinst->parms->user;
ent = G_WEDICT(prinst, OFS_PARM0);
surfnum = G_FLOAT(OFS_PARM1);
model = w->Get_CModel(w, ent->v->modelindex);
if (!model || model->type != mod_brush || surfnum >= model->nummodelsurfaces)
G_FLOAT(OFS_RETURN) = 0;
else
{
surfnum += model->firstmodelsurface;
G_FLOAT(OFS_RETURN) = model->surfaces[surfnum].mesh->numvertexes;
}
}
// #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
void QCBUILTIN PF_getsurfacepoint(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
unsigned int surfnum, pointnum;
model_t *model;
wedict_t *ent;
world_t *w = prinst->parms->user;
ent = G_WEDICT(prinst, OFS_PARM0);
surfnum = G_FLOAT(OFS_PARM1);
pointnum = G_FLOAT(OFS_PARM2);
model = w->Get_CModel(w, ent->v->modelindex);
if (!model || model->type != mod_brush || surfnum >= model->nummodelsurfaces)
{
G_FLOAT(OFS_RETURN+0) = 0;
G_FLOAT(OFS_RETURN+1) = 0;
G_FLOAT(OFS_RETURN+2) = 0;
}
else
{
surfnum += model->firstmodelsurface;
G_FLOAT(OFS_RETURN+0) = model->surfaces[surfnum].mesh->xyz_array[pointnum][0];
G_FLOAT(OFS_RETURN+1) = model->surfaces[surfnum].mesh->xyz_array[pointnum][1];
G_FLOAT(OFS_RETURN+2) = model->surfaces[surfnum].mesh->xyz_array[pointnum][2];
}
}
// #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
void QCBUILTIN PF_getsurfacenormal(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
unsigned int surfnum, pointnum;
model_t *model;
wedict_t *ent;
world_t *w = prinst->parms->user;
ent = G_WEDICT(prinst, OFS_PARM0);
surfnum = G_FLOAT(OFS_PARM1);
pointnum = G_FLOAT(OFS_PARM2);
model = w->Get_CModel(w, ent->v->modelindex);
if (!model || model->type != mod_brush || surfnum >= model->nummodelsurfaces)
{
G_FLOAT(OFS_RETURN+0) = 0;
G_FLOAT(OFS_RETURN+1) = 0;
G_FLOAT(OFS_RETURN+2) = 0;
}
else
{
surfnum += model->firstmodelsurface;
G_FLOAT(OFS_RETURN+0) = model->surfaces[surfnum].plane->normal[0];
G_FLOAT(OFS_RETURN+1) = model->surfaces[surfnum].plane->normal[1];
G_FLOAT(OFS_RETURN+2) = model->surfaces[surfnum].plane->normal[2];
if (model->surfaces[surfnum].flags & SURF_PLANEBACK)
VectorInverse(G_VECTOR(OFS_RETURN));
}
}
// #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
void QCBUILTIN PF_getsurfacetexture(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
model_t *model;
wedict_t *ent;
msurface_t *surf;
int surfnum;
world_t *w = prinst->parms->user;
ent = G_WEDICT(prinst, OFS_PARM0);
surfnum = G_FLOAT(OFS_PARM1);
model = w->Get_CModel(w, ent->v->modelindex);
G_INT(OFS_RETURN) = 0;
if (!model || model->type != mod_brush)
return;
if (surfnum < 0 || surfnum > model->nummodelsurfaces)
return;
surfnum += model->firstmodelsurface;
surf = &model->surfaces[surfnum];
G_INT(OFS_RETURN) = PR_TempString(prinst, surf->texinfo->texture->name);
}
// #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
void QCBUILTIN PF_getsurfacenearpoint(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
model_t *model;
wedict_t *ent;
msurface_t *surf;
int i;
float planedist;
float *point;
vec3_t edgedir;
vec3_t edgenormal;
vec3_t cpoint, temp;
mvertex_t *v1, *v2;
int edge;
int e;
float bestdist = 10000000000000, dist;
int bestsurf = -1;
world_t *w = prinst->parms->user;
ent = G_WEDICT(prinst, OFS_PARM0);
point = G_VECTOR(OFS_PARM1);
G_FLOAT(OFS_RETURN) = -1;
model = w->Get_CModel(w, ent->v->modelindex);
if (!model || model->type != mod_brush)
return;
if (model->fromgame != fg_quake)
return;
surf = model->surfaces + model->firstmodelsurface;
for (i = 0; i < model->nummodelsurfaces; i++, surf++)
{
planedist = DotProduct(point, surf->plane->normal) - surf->plane->dist;
//don't care about SURF_PLANEBACK, the maths works out the same.
if (planedist*planedist < bestdist)
{ //within a specific range
//make sure it's within the poly
VectorMA(point, planedist, surf->plane->normal, cpoint);
for (e = surf->firstedge+surf->numedges; e > surf->firstedge; edge++)
{
edge = model->surfedges[--e];
if (edge < 0)
{
v1 = &model->vertexes[model->edges[-edge].v[0]];
v2 = &model->vertexes[model->edges[-edge].v[1]];
}
else
{
v2 = &model->vertexes[model->edges[edge].v[0]];
v1 = &model->vertexes[model->edges[edge].v[1]];
}
VectorSubtract(v1->position, v2->position, edgedir);
CrossProduct(edgedir, surf->plane->normal, edgenormal);
if (!(surf->flags & SURF_PLANEBACK))
{
VectorNegate(edgenormal, edgenormal);
}
VectorNormalize(edgenormal);
dist = DotProduct(v1->position, edgenormal) - DotProduct(cpoint, edgenormal);
if (dist < 0)
VectorMA(cpoint, dist, edgenormal, cpoint);
}
VectorSubtract(cpoint, point, temp);
dist = DotProduct(temp, temp);
if (dist < bestdist)
{
bestsurf = i;
bestdist = dist;
}
}
}
G_FLOAT(OFS_RETURN) = bestsurf;
}
// #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
void QCBUILTIN PF_getsurfaceclippedpoint(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
}
void QCBUILTIN PF_terrain_edit(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *w = prinst->parms->user;
int action = G_FLOAT(OFS_PARM0);
float *pos = G_VECTOR(OFS_PARM1);
float radius = G_FLOAT(OFS_PARM2);
float quant = G_FLOAT(OFS_PARM3);
#if defined(TERRAIN)
G_FLOAT(OFS_RETURN) = Heightmap_Edit(w->worldmodel, action, pos, radius, quant);
#else
G_FLOAT(OFS_RETURN) = false;
#endif
}
//end model functions
////////////////////////////////////////////////////
void PF_touchtriggers(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *w = prinst->parms->user;
wedict_t *ent = (wedict_t*)PROG_TO_EDICT(prinst, *w->g.self);
World_LinkEdict (w, ent, true);
}
////////////////////////////////////////////////////
//Finding
@ -280,7 +502,7 @@ void QCBUILTIN PF_FindFlags (progfuncs_t *prinst, struct globalvars_s *pr_global
{
int e, f;
int s;
edict_t *ed;
wedict_t *ed;
e = G_EDICTNUM(prinst, OFS_PARM0);
f = G_INT(OFS_PARM1)+prinst->fieldadjust;
@ -288,7 +510,7 @@ void QCBUILTIN PF_FindFlags (progfuncs_t *prinst, struct globalvars_s *pr_global
for (e++; e < *prinst->parms->sv_num_edicts; e++)
{
ed = EDICT_NUM(prinst, e);
ed = WEDICT_NUM(prinst, e);
if (ed->isfree)
continue;
if ((int)((float *)ed->v)[f] & s)
@ -306,7 +528,7 @@ void QCBUILTIN PF_FindFloat (progfuncs_t *prinst, struct globalvars_s *pr_global
{
int e, f;
int s;
edict_t *ed;
wedict_t *ed;
if (*prinst->callargc != 3) //I can hate mvdsv if I want to.
{
@ -320,7 +542,7 @@ void QCBUILTIN PF_FindFloat (progfuncs_t *prinst, struct globalvars_s *pr_global
for (e++; e < *prinst->parms->sv_num_edicts; e++)
{
ed = EDICT_NUM(prinst, e);
ed = WEDICT_NUM(prinst, e);
if (ed->isfree)
continue;
if (((int *)ed->v)[f] == s)
@ -340,7 +562,7 @@ void QCBUILTIN PF_FindString (progfuncs_t *prinst, struct globalvars_s *pr_globa
int f;
char *s;
string_t t;
edict_t *ed;
wedict_t *ed;
e = G_EDICTNUM(prinst, OFS_PARM0);
f = G_INT(OFS_PARM1)+prinst->fieldadjust;
@ -353,7 +575,7 @@ void QCBUILTIN PF_FindString (progfuncs_t *prinst, struct globalvars_s *pr_globa
for (e++ ; e < *prinst->parms->sv_num_edicts ; e++)
{
ed = EDICT_NUM(prinst, e);
ed = WEDICT_NUM(prinst, e);
if (ed->isfree)
continue;
t = ((string_t *)ed->v)[f];
@ -436,6 +658,20 @@ void QCBUILTIN PF_cvar_set (progfuncs_t *prinst, struct globalvars_s *pr_globals
Cvar_Set (var, val);
}
void QCBUILTIN PF_cvar_setlatch (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *var_name, *val;
cvar_t *var;
var_name = PR_GetStringOfs(prinst, OFS_PARM0);
val = PR_GetStringOfs(prinst, OFS_PARM1);
var = Cvar_Get(var_name, val, 0, "QC variables");
if (!var)
return;
Cvar_LockFromServer(var, val);
}
void QCBUILTIN PF_cvar_setf (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *var_name;
@ -1003,15 +1239,15 @@ void PR_fclose_progs (progfuncs_t *prinst)
void QCBUILTIN PF_WasFreed (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
edict_t *ent;
ent = (edict_t*)G_EDICT(prinst, OFS_PARM0);
wedict_t *ent;
ent = G_WEDICT(prinst, OFS_PARM0);
G_FLOAT(OFS_RETURN) = ent->isfree;
}
void QCBUILTIN PF_num_for_edict (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
edict_t *ent;
ent = (edict_t*)G_EDICT(prinst, OFS_PARM0);
wedict_t *ent;
ent = G_WEDICT(prinst, OFS_PARM0);
G_FLOAT(OFS_RETURN) = ent->entnum;
}
@ -1027,7 +1263,7 @@ void QCBUILTIN PF_edict_for_num(progfuncs_t *prinst, struct globalvars_s *pr_glo
void QCBUILTIN PF_nextent (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int i;
edict_t *ent;
wedict_t *ent;
i = G_EDICTNUM(prinst, OFS_PARM0);
while (1)
@ -1038,7 +1274,7 @@ void QCBUILTIN PF_nextent (progfuncs_t *prinst, struct globalvars_s *pr_globals)
RETURN_EDICT(prinst, *prinst->parms->sv_edicts);
return;
}
ent = EDICT_NUM(prinst, i);
ent = WEDICT_NUM(prinst, i);
if (!ent->isfree)
{
RETURN_EDICT(prinst, ent);
@ -2545,7 +2781,7 @@ void QCBUILTIN PF_eprint (progfuncs_t *prinst, struct globalvars_s *pr_globals)
int size = 1024*1024;
char *buffer = BZ_Malloc(size);
char *buf;
buf = prinst->saveent(prinst, buffer, &size, G_EDICT(prinst, OFS_PARM0));
buf = prinst->saveent(prinst, buffer, &size, (struct edict_s*)G_WEDICT(prinst, OFS_PARM0));
Con_Printf("Entity %i:\n%s\n", G_EDICTNUM(prinst, OFS_PARM0), buf);
BZ_Free(buffer);
}
@ -2981,7 +3217,10 @@ static void PR_AutoCvarApply(progfuncs_t *prinst, eval_t *val, etype_t type, cva
break;
case ev_string:
PR_RemoveProgsString(prinst, val->_int);
val->_int = PR_SetString(prinst, var->string);
if (*var->string)
val->_int = PR_SetString(prinst, var->string);
else
val->_int = 0;
break;
case ev_vector:
{

View file

@ -174,6 +174,13 @@ void PR_AutoCvarSetup(progfuncs_t *prinst);
void PR_AutoCvar(progfuncs_t *prinst, cvar_t *var);
void QCBUILTIN PF_getsurfacenumpoints(progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_getsurfacepoint(progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_getsurfacenormal(progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_getsurfacetexture(progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_getsurfacenearpoint(progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_getsurfaceclippedpoint(progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_skel_set_bone_world (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_skel_mmap(progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_skel_ragedit(progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_skel_create (progfuncs_t *prinst, struct globalvars_s *pr_globals);
@ -192,6 +199,10 @@ void QCBUILTIN PF_skel_delete (progfuncs_t *prinst, struct globalvars_s *pr_glob
void skel_lookup(progfuncs_t *prinst, int skelidx, framestate_t *out);
void skel_dodelete(progfuncs_t *prinst);
void skel_reset(progfuncs_t *prinst);
void QCBUILTIN PF_gettaginfo (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_gettagindex (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_terrain_edit(progfuncs_t *prinst, struct globalvars_s *pr_globals);
void PF_touchtriggers(progfuncs_t *prinst, struct globalvars_s *pr_globals);
//pr_cmds.c builtins that need to be moved to a common.
void VARGS PR_BIError(progfuncs_t *progfuncs, char *format, ...) LIKEPRINTF(2);
@ -366,33 +377,6 @@ pbool ED_CanFree (edict_t *ed);
#define DAMAGE_YES 1
#define DAMAGE_AIM 2
// edict->flags
#define FL_FLY (1<<0)
#define FL_SWIM (1<<1)
#define FL_GLIMPSE (1<<2)
#define FL_CLIENT (1<<3)
#define FL_INWATER (1<<4)
#define FL_MONSTER (1<<5)
#define FL_GODMODE (1<<6)
#define FL_NOTARGET (1<<7)
#define FL_ITEM (1<<8)
#define FL_ONGROUND (1<<9)
#define FL_PARTIALGROUND (1<<10) // not all corners are valid
#define FL_WATERJUMP (1<<11) // player jumping out of water
//12
//13
#define FL_FINDABLE_NONSOLID (1<<14) //a cpqwsv feature
#define FL_MOVECHAIN_ANGLE (1<<15) // when in a move chain, will update the angle
#define FL_LAGGEDMOVE (1<<16)
//17
//18
//19
//20
#define FL_CLASS_DEPENDENT (1<<21)
//shared constants
typedef enum
{

View file

@ -762,7 +762,7 @@ void TL_InitLanguages(void)
#ifndef CLIENTONLY
//#ifndef CLIENTONLY
//this stuff is for hexen2 translation strings.
//(hexen2 is uuuuggllyyyy...)
static char *strings_list;
@ -828,7 +828,7 @@ char *T_GetString(int num)
return strings_table[num];
}
#endif
//#endif
#ifndef SERVERONLY
static char *info_strings_list;

View file

@ -85,6 +85,33 @@ typedef struct q2trace_s
void *ent; // not set by CM_*() functions
} q2trace_t;
// edict->flags
#define FL_FLY (1<<0)
#define FL_SWIM (1<<1)
//#define FL_GLIMPSE (1<<2)
#define FL_CLIENT (1<<3)
#define FL_INWATER (1<<4)
#define FL_MONSTER (1<<5)
#define FL_GODMODE (1<<6)
#define FL_NOTARGET (1<<7)
#define FL_ITEM (1<<8)
#define FL_ONGROUND (1<<9)
#define FL_PARTIALGROUND (1<<10) // not all corners are valid
#define FL_WATERJUMP (1<<11) // player jumping out of water
// FL_JUMPRELEASED //12
//13
#define FL_FINDABLE_NONSOLID (1<<14) //a cpqwsv feature
#define FL_MOVECHAIN_ANGLE (1<<15) // hexen2 - when in a move chain, will update the angle
#define FL_LAGGEDMOVE (1<<16)
//17
//18
//19
//20
#define FL_CLASS_DEPENDENT (1<<21) //hexen2
#define MOVE_NORMAL 0
#define MOVE_NOMONSTERS 1
#define MOVE_MISSILE 2
@ -110,6 +137,7 @@ typedef struct areanode_s
typedef struct wedict_s wedict_t;
#define PROG_TO_WEDICT (wedict_t*)PROG_TO_EDICT
#define WEDICT_NUM (wedict_t *)EDICT_NUM
#define G_WEDICT (wedict_t *)G_EDICT
typedef struct
{
@ -130,20 +158,22 @@ struct world_s
/*FTE_DEPRECATED*/ unsigned int edict_size; //still used in copyentity
wedict_t *edicts; // can NOT be array indexed.
struct progfuncs_s *progs;
qboolean usesolidcorpse;
qboolean usesolidcorpse; //to disable SOLID_CORPSE when running hexen2 due to conflict.
model_t *worldmodel;
areanode_t areanodes[AREA_NODES];
int numareanodes;
double physicstime;
double physicstime; // the last time global physics were run
unsigned int framenum;
int lastcheck; // used by PF_checkclient
double lastchecktime; // for monster ai
/*antilag*/
float lagentsfrac;
laggedentinfo_t *lagents;
unsigned int maxlagents;
/*qc globals*/
struct {
int *self;
int *other;

View file

@ -131,6 +131,7 @@ typedef struct
float depthfactor;
float m_model[16];
unsigned int lastpasscount;
vbo_t *batchvbo;
texid_t curtex[MAX_TMUS];
unsigned int tmuflags[MAX_TMUS];
@ -179,7 +180,8 @@ enum
D3D_VDEC_ST3 = 1<<4,
D3D_VDEC_NORM = 1<<5,
D3D_VDEC_SKEL = 1<<6,
D3D_VDEC_MAX = 1<<7
D3D_VDEC_MAX = 1<<7,
};
#define STRM_VERT 0
#define STRM_COL 1
@ -193,7 +195,7 @@ enum
#define STRM_BONENUM 9
#define STRM_BONEWEIGHT 10
#define STRM_MAX 11
IDirect3DVertexDeclaration9 *vertexdecls[D3D_VDEC_MAX];
static IDirect3DVertexDeclaration9 *vertexdecls[D3D_VDEC_MAX];
static void BE_ApplyTMUState(unsigned int tu, unsigned int flags)
{
@ -575,6 +577,8 @@ static void BindTexture(unsigned int tu, void *id)
static void SelectPassTexture(unsigned int tu, shaderpass_t *pass)
{
int last;
switch(pass->texgen)
{
default:
@ -619,58 +623,74 @@ static void SelectPassTexture(unsigned int tu, shaderpass_t *pass)
BE_ApplyTMUState(tu, pass->flags);
if (tu == 0)
{
if (shaderstate.passsinglecolour)
{
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_CONSTANT, shaderstate.passcolour);
last = D3DTA_CONSTANT;
}
else
{
last = D3DTA_DIFFUSE;
}
}
else
last = D3DTA_CURRENT;
switch (pass->blendmode)
{
case PBM_DOTPRODUCT:
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_CURRENT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, last);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
// IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
// IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, last);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
break;
case PBM_REPLACE:
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, last);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
if (shaderstate.flags & (BEF_FORCETRANSPARENT | BEF_FORCEADDITIVE))
{
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, last);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
}
else
{
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
// IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
// IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, last);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
}
break;
case PBM_ADD:
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_CURRENT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
shaderstate.passcolour &= 0xff000000;
if (tu == 0)
goto forcemod;
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, last);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_ADD);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, last);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
break;
case PBM_DECAL:
if (!tu)
goto forcemod;
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_CURRENT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, last);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
// IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
// IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, last);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
break;
case PBM_OVERBRIGHT:
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_CURRENT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, last);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_TEXTURE);
{
extern cvar_t gl_overbright;
switch (gl_overbright.ival)
@ -687,48 +707,25 @@ static void SelectPassTexture(unsigned int tu, shaderpass_t *pass)
break;
}
}
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, last);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
break;
default:
case PBM_MODULATE:
forcemod:
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_CURRENT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, last);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_MODULATE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, last);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
break;
}
if (tu == 0)
{
if (shaderstate.passsinglecolour)
{
if (shaderstate.passcolour == D3DCOLOR_RGBA(255,255,255,255))
{
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
}
else
{
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_CONSTANT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_CONSTANT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_CONSTANT, shaderstate.passcolour);
}
}
else
{
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
}
}
}
static void colourgenbyte(const shaderpass_t *pass, int cnt, byte_vec4_t *src, byte_vec4_t *dst, const mesh_t *mesh)
static void colourgenbyte(const shaderpass_t *pass, int cnt, byte_vec4_t *srcb, vec4_t *srcf, byte_vec4_t *dst, const mesh_t *mesh)
{
D3DCOLOR block;
switch (pass->rgbgen)
@ -749,40 +746,64 @@ static void colourgenbyte(const shaderpass_t *pass, int cnt, byte_vec4_t *src, b
break;
case RGB_GEN_VERTEX_LIGHTING:
case RGB_GEN_VERTEX_EXACT:
if (!src)
{
while((cnt)--)
{
dst[cnt][0] = 255;
dst[cnt][1] = 255;
dst[cnt][2] = 255;
}
}
else
if (srcb)
{
while((cnt)--)
{
qbyte r, g, b;
r=src[cnt][0];
g=src[cnt][1];
b=src[cnt][2];
r=srcb[cnt][0];
g=srcb[cnt][1];
b=srcb[cnt][2];
dst[cnt][0] = b;
dst[cnt][1] = g;
dst[cnt][2] = r;
}
}
else if (srcf)
{
while((cnt)--)
{
int r, g, b;
r=srcf[cnt][0]*255;
g=srcf[cnt][1]*255;
b=srcf[cnt][2]*255;
dst[cnt][0] = bound(0, b, 255);
dst[cnt][1] = bound(0, g, 255);
dst[cnt][2] = bound(0, r, 255);
}
}
else
goto identity;
break;
case RGB_GEN_ONE_MINUS_VERTEX:
while((cnt)--)
if (srcb)
{
qbyte r, g, b;
r=255-src[cnt][0];
g=255-src[cnt][1];
b=255-src[cnt][2];
dst[cnt][0] = b;
dst[cnt][1] = g;
dst[cnt][2] = r;
while((cnt)--)
{
qbyte r, g, b;
r=255-srcb[cnt][0];
g=255-srcb[cnt][1];
b=255-srcb[cnt][2];
dst[cnt][0] = b;
dst[cnt][1] = g;
dst[cnt][2] = r;
}
}
else if (srcf)
{
while((cnt)--)
{
int r, g, b;
r=255-srcf[cnt][0]*255;
g=255-srcf[cnt][1]*255;
b=255-srcf[cnt][2]*255;
dst[cnt][0] = bound(0, b, 255);
dst[cnt][1] = bound(0, g, 255);
dst[cnt][2] = bound(0, r, 255);
}
}
else
goto identity;
break;
case RGB_GEN_IDENTITY_LIGHTING:
//compensate for overbrights
@ -793,6 +814,7 @@ static void colourgenbyte(const shaderpass_t *pass, int cnt, byte_vec4_t *src, b
}
break;
default:
identity:
case RGB_GEN_IDENTITY:
block = D3DCOLOR_RGBA(255, 255, 255, 255);
while((cnt)--)
@ -855,7 +877,7 @@ static void colourgenbyte(const shaderpass_t *pass, int cnt, byte_vec4_t *src, b
}
}
static void alphagenbyte(const shaderpass_t *pass, int cnt, byte_vec4_t *src, byte_vec4_t *dst, const mesh_t *mesh)
static void alphagenbyte(const shaderpass_t *pass, int cnt, byte_vec4_t *srcb, vec4_t *srcf, byte_vec4_t *dst, const mesh_t *mesh)
{
/*FIXME: Skip this if the rgbgen did it*/
float *table;
@ -913,18 +935,26 @@ static void alphagenbyte(const shaderpass_t *pass, int cnt, byte_vec4_t *src, by
break;
case ALPHA_GEN_VERTEX:
if (!src)
if (srcb)
{
while(cnt--)
{
dst[cnt][3] = srcb[cnt][3];
}
}
else if (srcf)
{
while(cnt--)
{
dst[cnt][3] = bound(0, srcf[cnt][3]*255, 255);
}
}
else
{
while(cnt--)
{
dst[cnt][3] = 255;
}
break;
}
while(cnt--)
{
dst[cnt][3] = src[cnt][3];
}
break;
@ -975,75 +1005,38 @@ static unsigned int BE_GenerateColourMods(unsigned int vertcount, const shaderpa
{
shaderstate.passsinglecolour = true;
shaderstate.passcolour = D3DCOLOR_RGBA(255,255,255,255);
colourgenbyte(pass, 1, (byte_vec4_t*)&shaderstate.passcolour, (byte_vec4_t*)&shaderstate.passcolour, m);
alphagenbyte(pass, 1, (byte_vec4_t*)&shaderstate.passcolour, (byte_vec4_t*)&shaderstate.passcolour, m);
colourgenbyte(pass, 1, (byte_vec4_t*)&shaderstate.passcolour, NULL, (byte_vec4_t*)&shaderstate.passcolour, m);
alphagenbyte(pass, 1, (byte_vec4_t*)&shaderstate.passcolour, NULL, (byte_vec4_t*)&shaderstate.passcolour, m);
/*FIXME: just because there's no rgba set, there's no reason to assume it should be a single colour (unshaded ents)*/
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_COL, NULL, 0, 0));
}
else
{
unsigned int v;
int c;
float *src;
shaderstate.passsinglecolour = false;
ret |= D3D_VDEC_COL4B;
allocvertexbuffer(shaderstate.dyncol_buff, shaderstate.dyncol_size, &shaderstate.dyncol_offs, (void**)&map, vertcount*sizeof(D3DCOLOR));
if (m->colors4b_array)
{
for (vertcount = 0, mno = 0; mno < shaderstate.nummeshes; mno++)
{
m = shaderstate.meshlist[mno];
colourgenbyte(pass, m->numvertexes, (byte_vec4_t*)m->colors4b_array, (byte_vec4_t*)map, m);
alphagenbyte(pass, m->numvertexes, (byte_vec4_t*)m->colors4b_array, (byte_vec4_t*)map, m);
map += m->numvertexes*4;
vertcount += m->numvertexes;
}
}
else if (m->colors4f_array &&
if (shaderstate.batchvbo && (m->colors4f_array &&
((pass->rgbgen == RGB_GEN_VERTEX_LIGHTING) ||
(pass->rgbgen == RGB_GEN_VERTEX_EXACT) ||
(pass->rgbgen == RGB_GEN_ONE_MINUS_VERTEX) ||
(pass->rgbgen == RGB_GEN_ONE_MINUS_VERTEX)) &&
(pass->alphagen == ALPHA_GEN_VERTEX)))
{
for (vertcount = 0, mno = 0; mno < shaderstate.nummeshes; mno++)
{
m = shaderstate.meshlist[mno];
src = m->colors4f_array[0];
for (v = 0; v < m->numvertexes; v++)
{
c = src[0]*255;
map[0] = bound(0, c, 255);
c = src[1]*255;
map[1] = bound(0, c, 255);
c = src[2]*255;
map[2] = bound(0, c, 255);
c = src[3]*255;
map[3] = bound(0, c, 255);
map += 4;
src += 4;
}
vertcount += m->numvertexes;
}
map -= vertcount*4;
/*FIXME: m is wrong. its the last ent only*/
colourgenbyte(pass, vertcount, (byte_vec4_t*)map, (byte_vec4_t*)map, m);
alphagenbyte(pass, vertcount, (byte_vec4_t*)map, (byte_vec4_t*)map, m);
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_COL, shaderstate.batchvbo->colours.d3d.buff, shaderstate.batchvbo->colours.d3d.offs, sizeof(byte_vec4_t)));
}
else
{
allocvertexbuffer(shaderstate.dyncol_buff, shaderstate.dyncol_size, &shaderstate.dyncol_offs, (void**)&map, vertcount*sizeof(D3DCOLOR));
for (vertcount = 0, mno = 0; mno < shaderstate.nummeshes; mno++)
{
m = shaderstate.meshlist[mno];
colourgenbyte(pass, m->numvertexes, NULL, (byte_vec4_t*)map, m);
alphagenbyte(pass, m->numvertexes, NULL, (byte_vec4_t*)map, m);
colourgenbyte(pass, m->numvertexes, m->colors4b_array, m->colors4f_array, (byte_vec4_t*)map, m);
alphagenbyte(pass, m->numvertexes, m->colors4b_array, m->colors4f_array, (byte_vec4_t*)map, m);
map += m->numvertexes*4;
vertcount += m->numvertexes;
}
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dyncol_buff));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_COL, shaderstate.dyncol_buff, shaderstate.dyncol_offs - vertcount*sizeof(D3DCOLOR), sizeof(D3DCOLOR)));
}
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dyncol_buff));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_COL, shaderstate.dyncol_buff, shaderstate.dyncol_offs - vertcount*sizeof(D3DCOLOR), sizeof(D3DCOLOR)));
}
return ret;
}
@ -1220,7 +1213,7 @@ static void GenerateTCMods(const shaderpass_t *pass, float *dest)
}
else if (src != dest)
{
memcpy(dest, src, 8*mesh->numvertexes);
memcpy(dest, src, sizeof(vec2_t)*mesh->numvertexes);
}
dest += mesh->numvertexes*2;
}
@ -1493,7 +1486,6 @@ static qboolean BE_DrawMeshChain_SetupPass(shaderpass_t *pass, unsigned int vert
return false;
/*all meshes in a chain must have the same features*/
vdec = 0;
/*we only use one colour, generated from the first pass*/
@ -1513,10 +1505,17 @@ static qboolean BE_DrawMeshChain_SetupPass(shaderpass_t *pass, unsigned int vert
SelectPassTexture(tmu, pass+passno);
vdec |= D3D_VDEC_ST0<<tmu;
allocvertexbuffer(shaderstate.dynst_buff[tmu], shaderstate.dynst_size, &shaderstate.dynst_offs[tmu], &map, vertcount*sizeof(vec2_t));
GenerateTCMods(pass+passno, map);
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynst_buff[tmu]));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, shaderstate.dynst_buff[tmu], shaderstate.dynst_offs[tmu] - vertcount*sizeof(vec2_t), sizeof(vec2_t)));
if (shaderstate.batchvbo && pass[passno].tcgen == TC_GEN_BASE && !pass[passno].numtcmods)
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, shaderstate.batchvbo->texcoord.d3d.buff, shaderstate.batchvbo->texcoord.d3d.offs, sizeof(vec2_t)));
else if (shaderstate.batchvbo && pass[passno].tcgen == TC_GEN_LIGHTMAP && !pass[passno].numtcmods)
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, shaderstate.batchvbo->lmcoord.d3d.buff, shaderstate.batchvbo->lmcoord.d3d.offs, sizeof(vec2_t)));
else
{
allocvertexbuffer(shaderstate.dynst_buff[tmu], shaderstate.dynst_size, &shaderstate.dynst_offs[tmu], &map, vertcount*sizeof(vec2_t));
GenerateTCMods(pass+passno, map);
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynst_buff[tmu]));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, shaderstate.dynst_buff[tmu], shaderstate.dynst_offs[tmu] - vertcount*sizeof(vec2_t), sizeof(vec2_t)));
}
tmu++;
}
/*deactivate any extras*/
@ -1544,6 +1543,43 @@ static qboolean BE_DrawMeshChain_SetupPass(shaderpass_t *pass, unsigned int vert
return true;
}
static void BE_SubmitMeshChain(int idxfirst)
{
int startv, starti, endv, endi;
int m;
mesh_t *mesh;
// if (shaderstate.batchvbo)
// IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_TRIANGLELIST, 0, 0, shaderstate.batchvbo->vertcount, idxfirst, shaderstate.batchvbo->indexcount/3);
for (m = 0, mesh = shaderstate.meshlist[0]; m < shaderstate.nummeshes; )
{
startv = mesh->vbofirstvert;
starti = mesh->vbofirstelement;
endv = startv+mesh->numvertexes;
endi = starti+mesh->numindexes;
//find consecutive surfaces
for (++m; m < shaderstate.nummeshes; m++)
{
mesh = shaderstate.meshlist[m];
/* if (endi == mesh->vbofirstelement)
{
endv = mesh->vbofirstvert+mesh->numvertexes;
endi = mesh->vbofirstelement+mesh->numindexes;
}
else
*/ {
break;
}
}
IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_TRIANGLELIST, 0, startv, endv - startv, idxfirst + starti, (endi-starti)/3);
RQuantAdd(RQUANT_DRAWS, 1);
}
}
static void BE_ApplyUniforms(program_t *prog, int permu)
{
int i;
@ -1649,67 +1685,82 @@ static void BE_RenderMeshProgram(unsigned int vertcount, unsigned int idxfirst,
/*colours*/
if (vdec & D3D_VDEC_COL4B)
{
int mno,v;
void *map;
mesh_t *m;
allocvertexbuffer(shaderstate.dynst_buff[0], shaderstate.dynst_size, &shaderstate.dynst_offs[0], &map, vertcount*sizeof(byte_vec4_t));
for (mno = 0, vertcount = 0; mno < shaderstate.nummeshes; mno++)
if (shaderstate.batchvbo)
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_COL, shaderstate.batchvbo->colours.d3d.buff, shaderstate.batchvbo->colours.d3d.offs, sizeof(byte_vec4_t)));
else
{
byte_vec4_t *dest = (byte_vec4_t*)((char*)map+vertcount*sizeof(byte_vec4_t));
m = shaderstate.meshlist[mno];
if (m->colors4f_array)
int mno,v;
void *map;
mesh_t *m;
allocvertexbuffer(shaderstate.dynst_buff[0], shaderstate.dynst_size, &shaderstate.dynst_offs[0], &map, vertcount*sizeof(byte_vec4_t));
for (mno = 0, vertcount = 0; mno < shaderstate.nummeshes; mno++)
{
for (v = 0; v < m->numvertexes; v++)
byte_vec4_t *dest = (byte_vec4_t*)((char*)map+vertcount*sizeof(byte_vec4_t));
m = shaderstate.meshlist[mno];
if (m->colors4f_array)
{
dest[v][0] = bound(0, m->colors4f_array[v][0] * 255, 255);
dest[v][1] = bound(0, m->colors4f_array[v][1] * 255, 255);
dest[v][2] = bound(0, m->colors4f_array[v][2] * 255, 255);
dest[v][3] = bound(0, m->colors4f_array[v][3] * 255, 255);
for (v = 0; v < m->numvertexes; v++)
{
dest[v][0] = bound(0, m->colors4f_array[v][0] * 255, 255);
dest[v][1] = bound(0, m->colors4f_array[v][1] * 255, 255);
dest[v][2] = bound(0, m->colors4f_array[v][2] * 255, 255);
dest[v][3] = bound(0, m->colors4f_array[v][3] * 255, 255);
}
}
else if (m->colors4b_array)
memcpy(dest, m->colors4b_array, m->numvertexes*sizeof(byte_vec4_t));
else
memset(dest, 0, m->numvertexes*sizeof(byte_vec4_t));
vertcount += m->numvertexes;
}
else if (m->colors4b_array)
memcpy(dest, m->colors4b_array, m->numvertexes*sizeof(byte_vec4_t));
else
memset(dest, 0, m->numvertexes*sizeof(byte_vec4_t));
vertcount += m->numvertexes;
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynst_buff[0]));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0, shaderstate.dynst_buff[0], shaderstate.dynst_offs[0] - vertcount*sizeof(byte_vec4_t), sizeof(byte_vec4_t)));
}
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynst_buff[0]));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0, shaderstate.dynst_buff[0], shaderstate.dynst_offs[0] - vertcount*sizeof(byte_vec4_t), sizeof(byte_vec4_t)));
}
/*texture coords*/
if (vdec & D3D_VDEC_ST0)
{
int mno;
void *map;
mesh_t *m;
allocvertexbuffer(shaderstate.dynst_buff[0], shaderstate.dynst_size, &shaderstate.dynst_offs[0], &map, vertcount*sizeof(vec2_t));
for (mno = 0, vertcount = 0; mno < shaderstate.nummeshes; mno++)
if (shaderstate.batchvbo)
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0, shaderstate.batchvbo->texcoord.d3d.buff, shaderstate.batchvbo->texcoord.d3d.offs, sizeof(vec2_t)));
else
{
vec2_t *dest = (vec2_t*)((char*)map+vertcount*sizeof(vec2_t));
m = shaderstate.meshlist[mno];
memcpy(dest, m->st_array, m->numvertexes*sizeof(vec2_t));
vertcount += m->numvertexes;
int mno;
void *map;
mesh_t *m;
allocvertexbuffer(shaderstate.dynst_buff[0], shaderstate.dynst_size, &shaderstate.dynst_offs[0], &map, vertcount*sizeof(vec2_t));
for (mno = 0, vertcount = 0; mno < shaderstate.nummeshes; mno++)
{
vec2_t *dest = (vec2_t*)((char*)map+vertcount*sizeof(vec2_t));
m = shaderstate.meshlist[mno];
memcpy(dest, m->st_array, m->numvertexes*sizeof(vec2_t));
vertcount += m->numvertexes;
}
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynst_buff[0]));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0, shaderstate.dynst_buff[0], shaderstate.dynst_offs[0] - vertcount*sizeof(vec2_t), sizeof(vec2_t)));
}
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynst_buff[0]));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0, shaderstate.dynst_buff[0], shaderstate.dynst_offs[0] - vertcount*sizeof(vec2_t), sizeof(vec2_t)));
}
/*lm coords*/
if (vdec & D3D_VDEC_ST1)
{
int mno;
void *map;
mesh_t *m;
allocvertexbuffer(shaderstate.dynst_buff[1], shaderstate.dynst_size, &shaderstate.dynst_offs[1], &map, vertcount*sizeof(vec2_t));
for (mno = 0, vertcount = 0; mno < shaderstate.nummeshes; mno++)
if (shaderstate.batchvbo)
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC1, shaderstate.batchvbo->lmcoord.d3d.buff, shaderstate.batchvbo->lmcoord.d3d.offs, sizeof(vec2_t)));
else
{
vec2_t *dest = (vec2_t*)((char*)map+vertcount*sizeof(vec2_t));
m = shaderstate.meshlist[mno];
memcpy(dest, m->lmst_array, m->numvertexes*sizeof(vec2_t));
vertcount += m->numvertexes;
int mno;
void *map;
mesh_t *m;
allocvertexbuffer(shaderstate.dynst_buff[1], shaderstate.dynst_size, &shaderstate.dynst_offs[1], &map, vertcount*sizeof(vec2_t));
for (mno = 0, vertcount = 0; mno < shaderstate.nummeshes; mno++)
{
vec2_t *dest = (vec2_t*)((char*)map+vertcount*sizeof(vec2_t));
m = shaderstate.meshlist[mno];
memcpy(dest, m->lmst_array, m->numvertexes*sizeof(vec2_t));
vertcount += m->numvertexes;
}
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynst_buff[1]));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC1, shaderstate.dynst_buff[1], shaderstate.dynst_offs[1] - vertcount*sizeof(vec2_t), sizeof(vec2_t)));
}
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynst_buff[1]));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0, shaderstate.dynst_buff[1], shaderstate.dynst_offs[1] - vertcount*sizeof(vec2_t), sizeof(vec2_t)));
}
/*normals/tangents/bitangents*/
@ -1733,7 +1784,7 @@ static void BE_RenderMeshProgram(unsigned int vertcount, unsigned int idxfirst,
}
// IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9,
d3dcheck(IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_TRIANGLELIST, 0, 0, vertcount, idxfirst, idxcount/3));
BE_SubmitMeshChain(idxfirst);
IDirect3DDevice9_SetVertexShader(pD3DDev9, NULL);
IDirect3DDevice9_SetPixelShader(pD3DDev9, NULL);
@ -1794,41 +1845,64 @@ static void BE_DrawMeshChain_Internal(void)
// IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SLOPESCALEDEPTHBIAS, *(DWORD*)&shaderstate.depthfactor);
// }
for (mno = 0, vertcount = 0, idxcount = 0; mno < shaderstate.nummeshes; mno++)
if (shaderstate.batchvbo)
{
m = shaderstate.meshlist[mno];
vertcount += m->numvertexes;
idxcount += m->numindexes;
vertcount = shaderstate.batchvbo->vertcount;
idxcount = shaderstate.batchvbo->indexcount;
}
else
{
for (mno = 0, vertcount = 0, idxcount = 0; mno < shaderstate.nummeshes; mno++)
{
m = shaderstate.meshlist[mno];
vertcount += m->numvertexes;
idxcount += m->numindexes;
}
}
/*vertex buffers are common to all passes*/
allocvertexbuffer(shaderstate.dynxyz_buff, shaderstate.dynxyz_size, &shaderstate.dynxyz_offs, &map, vertcount*sizeof(vecV_t));
for (mno = 0, vertcount = 0; mno < shaderstate.nummeshes; mno++)
if (shaderstate.batchvbo && !shaderstate.curshader->numdeforms)
{
vecV_t *dest = (vecV_t*)((char*)map+vertcount*sizeof(vecV_t));
m = shaderstate.meshlist[mno];
deformgen(&shaderstate.curshader->deforms[0], m->numvertexes, m->xyz_array, dest, m);
for (i = 1; i < shaderstate.curshader->numdeforms; i++)
{
deformgen(&shaderstate.curshader->deforms[i], m->numvertexes, dest, dest, m);
}
vertcount += m->numvertexes;
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_VERT, shaderstate.batchvbo->coord.d3d.buff, shaderstate.batchvbo->coord.d3d.offs, sizeof(vecV_t)));
}
else
{
allocvertexbuffer(shaderstate.dynxyz_buff, shaderstate.dynxyz_size, &shaderstate.dynxyz_offs, &map, vertcount*sizeof(vecV_t));
for (mno = 0, vertcount = 0; mno < shaderstate.nummeshes; mno++)
{
vecV_t *dest = (vecV_t*)((char*)map+vertcount*sizeof(vecV_t));
m = shaderstate.meshlist[mno];
deformgen(&shaderstate.curshader->deforms[0], m->numvertexes, m->xyz_array, dest, m);
for (i = 1; i < shaderstate.curshader->numdeforms; i++)
{
deformgen(&shaderstate.curshader->deforms[i], m->numvertexes, dest, dest, m);
}
vertcount += m->numvertexes;
}
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynxyz_buff));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_VERT, shaderstate.dynxyz_buff, shaderstate.dynxyz_offs - vertcount*sizeof(vecV_t), sizeof(vecV_t)));
}
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynxyz_buff));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_VERT, shaderstate.dynxyz_buff, shaderstate.dynxyz_offs - vertcount*sizeof(vecV_t), sizeof(vecV_t)));
/*so are index buffers*/
idxfirst = allocindexbuffer(&map, idxcount);
for (mno = 0, vertcount = 0; mno < shaderstate.nummeshes; mno++)
if (shaderstate.batchvbo)
{
m = shaderstate.meshlist[mno];
for (i = 0; i < m->numindexes; i++)
((index_t*)map)[i] = m->indexes[i]+vertcount;
map = (char*)map + m->numindexes*sizeof(index_t);
vertcount += m->numvertexes;
d3dcheck(IDirect3DDevice9_SetIndices(pD3DDev9, shaderstate.batchvbo->indicies.d3d.buff));
idxfirst = 0;
}
else
{
idxfirst = allocindexbuffer(&map, idxcount);
for (mno = 0, vertcount = 0; mno < shaderstate.nummeshes; mno++)
{
m = shaderstate.meshlist[mno];
for (i = 0; i < m->numindexes; i++)
((index_t*)map)[i] = m->indexes[i]+vertcount;
map = (char*)map + m->numindexes*sizeof(index_t);
vertcount += m->numvertexes;
}
d3dcheck(IDirect3DIndexBuffer9_Unlock(shaderstate.dynidx_buff));
d3dcheck(IDirect3DDevice9_SetIndices(pD3DDev9, shaderstate.dynidx_buff));
}
d3dcheck(IDirect3DIndexBuffer9_Unlock(shaderstate.dynidx_buff));
d3dcheck(IDirect3DDevice9_SetIndices(pD3DDev9, shaderstate.dynidx_buff));
switch (shaderstate.mode)
{
@ -1850,7 +1924,7 @@ static void BE_DrawMeshChain_Internal(void)
passno++;
}
shaderstate.lastpasscount = 0;
d3dcheck(IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_TRIANGLELIST, 0, 0, vertcount, idxfirst, idxcount/3));
BE_SubmitMeshChain(idxfirst);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_ALPHA);
break;
default:
@ -1871,7 +1945,8 @@ static void BE_DrawMeshChain_Internal(void)
if (shaderstate.bench.clamp && shaderstate.bench.clamp < shaderstate.bench.draws)
continue;
#endif
d3dcheck(IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_TRIANGLELIST, 0, 0, vertcount, idxfirst, idxcount/3));
BE_SubmitMeshChain(idxfirst);
// d3dcheck(IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_TRIANGLELIST, 0, 0, vertcount, idxfirst, idxcount/3));
}
}
break;
@ -1897,9 +1972,19 @@ void D3DBE_GenBrushModelVBO(model_t *mod)
unsigned int meshes;
vbo_t *vbo;
char *vboedata;
index_t *vboedata;
mesh_t *m;
char *vbovdata;
IDirect3DVertexBuffer9 *vbuff;
IDirect3DIndexBuffer9 *ebuff;
vecV_t *coord;
vec2_t *texcoord;
vec2_t *lmcoord;
vec3_t *normals;
vec3_t *svector;
vec3_t *tvector;
byte_vec4_t *colours;
if (!mod->numsurfaces)
return;
@ -1945,17 +2030,40 @@ void D3DBE_GenBrushModelVBO(model_t *mod)
sizeof(vec3_t)+ //tdir
sizeof(vec4_t); //colours
vbovdata = BZ_Malloc(maxvboverts*pervertsize);
vboedata = BZ_Malloc(maxvboelements*sizeof(index_t));
IDirect3DDevice9_CreateIndexBuffer(pD3DDev9, sizeof(index_t) * maxvboelements, 0, D3DFMT_QINDEX, D3DPOOL_MANAGED, &ebuff, NULL);
IDirect3DDevice9_CreateVertexBuffer(pD3DDev9, pervertsize * maxvboverts, D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &vbuff, NULL);
vbo->coord = (vecV_t*)(vbovdata);
vbo->texcoord = (vec2_t*)((char*)vbo->coord+maxvboverts*sizeof(*vbo->coord));
vbo->lmcoord = (vec2_t*)((char*)vbo->texcoord+maxvboverts*sizeof(*vbo->texcoord));
vbo->normals = (vec3_t*)((char*)vbo->lmcoord+maxvboverts*sizeof(*vbo->lmcoord));
vbo->svector = (vec3_t*)((char*)vbo->normals+maxvboverts*sizeof(*vbo->normals));
vbo->tvector = (vec3_t*)((char*)vbo->svector+maxvboverts*sizeof(*vbo->svector));
vbo->colours4f = (vec4_t*)((char*)vbo->tvector+maxvboverts*sizeof(*vbo->tvector));
vbo->indicies = (index_t*)vboedata;
IDirect3DIndexBuffer9_Lock(ebuff, 0, sizeof(index_t) * maxvboelements, &vboedata, D3DLOCK_DISCARD);
IDirect3DVertexBuffer9_Lock(vbuff, 0, pervertsize * maxvboverts, &vbovdata, D3DLOCK_DISCARD);
vbo->vertdata = vbuff;
vbo->indexcount = maxvboelements;
vbo->vertcount = maxvboverts;
vbo->coord.d3d.buff = vbuff;
vbo->coord.d3d.offs = 0;
vbo->texcoord.d3d.buff = vbuff;
vbo->texcoord.d3d.offs = vbo->coord.d3d.offs+maxvboverts*sizeof(vecV_t);
vbo->lmcoord.d3d.buff = vbuff;
vbo->lmcoord.d3d.offs = vbo->texcoord.d3d.offs+maxvboverts*sizeof(vec2_t);
vbo->normals.d3d.buff = vbuff;
vbo->normals.d3d.offs = vbo->lmcoord.d3d.offs+maxvboverts*sizeof(vec2_t);
vbo->svector.d3d.buff = vbuff;
vbo->svector.d3d.offs = vbo->normals.d3d.offs+maxvboverts*sizeof(vec3_t);
vbo->tvector.d3d.buff = vbuff;
vbo->tvector.d3d.offs = vbo->svector.d3d.offs+maxvboverts*sizeof(vec3_t);
vbo->colours.d3d.buff = vbuff;
vbo->colours.d3d.offs = vbo->tvector.d3d.offs+maxvboverts*sizeof(vec3_t);
vbo->indicies.d3d.buff = ebuff;
vbo->indicies.d3d.offs = 0;
coord = (void*)(vbovdata + vbo->coord.d3d.offs);
texcoord = (void*)(vbovdata + vbo->texcoord.d3d.offs);
lmcoord = (void*)(vbovdata + vbo->lmcoord.d3d.offs);
normals = (void*)(vbovdata + vbo->normals.d3d.offs);
svector = (void*)(vbovdata + vbo->svector.d3d.offs);
tvector = (void*)(vbovdata + vbo->tvector.d3d.offs);
colours = (void*)(vbovdata + vbo->colours.d3d.offs);
vbo->meshcount = meshes;
vbo->meshlist = BZ_Malloc(meshes*sizeof(*vbo->meshlist));
@ -1976,66 +2084,74 @@ void D3DBE_GenBrushModelVBO(model_t *mod)
m->vbofirstvert = vcount;
m->vbofirstelement = ecount;
for (v = 0; v < m->numindexes; v++)
vbo->indicies[ecount++] = vcount + m->indexes[v];
vboedata[ecount++] = vcount + m->indexes[v];
for (v = 0; v < m->numvertexes; v++)
{
vbo->coord[vcount+v][0] = m->xyz_array[v][0];
vbo->coord[vcount+v][1] = m->xyz_array[v][1];
vbo->coord[vcount+v][2] = m->xyz_array[v][2];
coord[vcount+v][0] = m->xyz_array[v][0];
coord[vcount+v][1] = m->xyz_array[v][1];
coord[vcount+v][2] = m->xyz_array[v][2];
coord[vcount+v][3] = 1;
if (m->st_array)
{
vbo->texcoord[vcount+v][0] = m->st_array[v][0];
vbo->texcoord[vcount+v][1] = m->st_array[v][1];
texcoord[vcount+v][0] = m->st_array[v][0];
texcoord[vcount+v][1] = m->st_array[v][1];
}
if (m->lmst_array)
{
vbo->lmcoord[vcount+v][0] = m->lmst_array[v][0];
vbo->lmcoord[vcount+v][1] = m->lmst_array[v][1];
lmcoord[vcount+v][0] = m->lmst_array[v][0];
lmcoord[vcount+v][1] = m->lmst_array[v][1];
}
if (m->normals_array)
{
vbo->normals[vcount+v][0] = m->normals_array[v][0];
vbo->normals[vcount+v][1] = m->normals_array[v][1];
vbo->normals[vcount+v][2] = m->normals_array[v][2];
normals[vcount+v][0] = m->normals_array[v][0];
normals[vcount+v][1] = m->normals_array[v][1];
normals[vcount+v][2] = m->normals_array[v][2];
}
if (m->snormals_array)
{
vbo->svector[vcount+v][0] = m->snormals_array[v][0];
vbo->svector[vcount+v][1] = m->snormals_array[v][1];
vbo->svector[vcount+v][2] = m->snormals_array[v][2];
svector[vcount+v][0] = m->snormals_array[v][0];
svector[vcount+v][1] = m->snormals_array[v][1];
svector[vcount+v][2] = m->snormals_array[v][2];
}
if (m->tnormals_array)
{
vbo->tvector[vcount+v][0] = m->tnormals_array[v][0];
vbo->tvector[vcount+v][1] = m->tnormals_array[v][1];
vbo->tvector[vcount+v][2] = m->tnormals_array[v][2];
tvector[vcount+v][0] = m->tnormals_array[v][0];
tvector[vcount+v][1] = m->tnormals_array[v][1];
tvector[vcount+v][2] = m->tnormals_array[v][2];
}
if (m->colors4b_array)
{
colours[vcount+v][0] = m->colors4b_array[v][0];
colours[vcount+v][1] = m->colors4b_array[v][1];
colours[vcount+v][2] = m->colors4b_array[v][2];
colours[vcount+v][3] = m->colors4b_array[v][3];
}
if (m->colors4f_array)
{
vbo->colours4f[vcount+v][0] = m->colors4f_array[v][0];
vbo->colours4f[vcount+v][1] = m->colors4f_array[v][1];
vbo->colours4f[vcount+v][2] = m->colors4f_array[v][2];
vbo->colours4f[vcount+v][3] = m->colors4f_array[v][3];
colours[vcount+v][0] = m->colors4f_array[v][0] * 255;
colours[vcount+v][1] = m->colors4f_array[v][1] * 255;
colours[vcount+v][2] = m->colors4f_array[v][2] * 255;
colours[vcount+v][3] = m->colors4f_array[v][3] * 255;
}
}
vcount += v;
}
// if (GL_BuildVBO(vbo, vbovdata, vcount*pervertsize, vboedata, ecount*sizeof(index_t)))
{
BZ_Free(vbovdata);
BZ_Free(vboedata);
}
IDirect3DIndexBuffer9_Unlock(ebuff);
IDirect3DVertexBuffer9_Unlock(vbuff);
}
//for (i=0 ; i<mod->numsurfaces ; i++)
//{
// if (!mod->surfaces[i].mark)
// Host_EndGame("Surfaces with bad textures detected\n");
//}
}
/*Wipes a vbo*/
void D3DBE_ClearVBO(vbo_t *vbo)
{
IDirect3DVertexBuffer9 *vbuff = vbo->vertdata;
IDirect3DIndexBuffer9 *ebuff = vbo->indicies.d3d.buff;
if (vbuff)
IDirect3DVertexBuffer9_Release(vbuff);
if (ebuff)
IDirect3DIndexBuffer9_Release(ebuff);
vbo->vertdata = NULL;
vbo->indicies.d3d.buff = NULL;
}
/*upload all lightmaps at the start to reduce lags*/
@ -2234,6 +2350,10 @@ void D3DBE_SubmitBatch(batch_t *batch)
BE_RotateForEntity(batch->ent, batch->ent->model);
shaderstate.curtime = r_refdef.time - shaderstate.curentity->shaderTime;
}
if (batch->texture)
shaderstate.batchvbo = &batch->texture->vbo;
else
shaderstate.batchvbo = batch->vbo;
shaderstate.meshlist = batch->mesh + batch->firstmesh;
shaderstate.curshader = batch->shader;
shaderstate.curtexnums = batch->skin;
@ -2248,6 +2368,7 @@ void D3DBE_SubmitBatch(batch_t *batch)
void D3DBE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **meshlist, vbo_t *vbo, texnums_t *texnums, unsigned int beflags)
{
shaderstate.batchvbo = vbo;
shaderstate.curshader = shader;
shaderstate.curtexnums = texnums;
shaderstate.curlightmap = r_nulltex;
@ -2260,6 +2381,7 @@ void D3DBE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **meshlist, vbo
void D3DBE_DrawMesh_Single(shader_t *shader, mesh_t *meshchain, vbo_t *vbo, texnums_t *texnums, unsigned int beflags)
{
shaderstate.batchvbo = vbo;
shaderstate.curtime = realtime;
shaderstate.curshader = shader;
shaderstate.curtexnums = texnums?texnums:&shader->defaulttextures;
@ -2597,7 +2719,7 @@ static void BE_SubmitMeshesPortals(batch_t **worldlist, batch_t *dynamiclist)
}
}
void BE_SubmitMeshes (qboolean drawworld, batch_t **blist)
void D3DBE_SubmitMeshes (qboolean drawworld, batch_t **blist)
{
model_t *model = cl.worldmodel;
int i;
@ -2652,13 +2774,13 @@ void D3DBE_DrawWorld (qbyte *vis)
BE_SelectMode(BEM_STANDARD);
RSpeedRemark();
BE_SubmitMeshes(true, batches);
D3DBE_SubmitMeshes(true, batches);
RSpeedEnd(RSPEED_WORLD);
}
else
{
RSpeedRemark();
BE_SubmitMeshes(false, batches);
D3DBE_SubmitMeshes(false, batches);
RSpeedEnd(RSPEED_DRAWENTITIES);
}

View file

@ -34,9 +34,12 @@ static d3dtexture_t *d3d_lookup_texture(char *ident)
{
d3dtexture_t *tex;
for (tex = d3dtextures; tex; tex = tex->next)
if (!strcmp(tex->name, ident))
return tex;
if (*ident)
{
for (tex = d3dtextures; tex; tex = tex->next)
if (!strcmp(tex->name, ident))
return tex;
}
tex = calloc(1, sizeof(*tex)+strlen(ident));
strcpy(tex->name, ident);
@ -256,7 +259,7 @@ static void D3D9_LoadTexture_8(d3dtexture_t *tex, unsigned char *data, unsigned
else
{
noalpha = false;
trans[i] = pal32[p] & 0x00ffffff;
trans[i] = 0;
}
}
}

View file

@ -157,13 +157,8 @@ void D3DShader_Init(void)
void D3DShader_CreateProgram (program_t *prog, int permu, char **precompilerconstants, char *vert, char *frag)
{
int i, j, k;
D3DXMACRO defines[64];
LPD3DXBUFFER code = NULL, errors = NULL;
D3DXCONSTANTTABLE_DESC ctd;
D3DXHANDLE ch;
D3DXCONSTANT_DESC d;
UINT dc;
prog->handle[permu].hlsl.vert = NULL;
prog->handle[permu].hlsl.frag = NULL;

View file

@ -57,7 +57,7 @@ LPDIRECT3DDEVICE9 pD3DDev9;
static D3DPRESENT_PARAMETERS d3dpp;
float d3d_trueprojection[16];
static qboolean vid_initializing;
qboolean vid_initializing;
extern qboolean scr_initialized; // ready to draw
extern qboolean scr_drawloading;
@ -368,7 +368,7 @@ static LRESULT WINAPI D3D9_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
if (MessageBox (mainwindow, "Are you sure you want to quit?", "Confirm Exit",
MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES)
{
Sys_Quit ();
Cbuf_AddText("\nquit\n", RESTRICT_LOCAL);
}
break;
@ -741,8 +741,6 @@ static qboolean D3D9_VID_Init(rendererstate_t *info, unsigned char *palette)
static void (D3D9_R_NewMap) (void)
{
r_worldentity.model = cl.worldmodel;
R_AnimateLight();
Surf_BuildLightmaps();
#ifdef MAP_PROC
if (cl.worldmodel && cl.worldmodel->fromgame == fg_doom3)
@ -751,6 +749,12 @@ static void (D3D9_R_NewMap) (void)
/*wipe any lingering particles*/
P_ClearParticles();
CL_RegisterParticles();
R_AnimateLight();
Surf_DeInit();
Surf_WipeStains();
Surf_BuildLightmaps();
}
extern mleaf_t *r_viewleaf, *r_oldviewleaf;
@ -987,7 +991,7 @@ static void (D3D9_SCR_UpdateScreen) (void)
if (editormodal)
{
Editor_Draw();
GLV_UpdatePalette (false, host_frametime);
V_UpdatePalette (false);
#if defined(_WIN32) && defined(GLQUAKE)
Media_RecordFrame();
#endif
@ -1005,7 +1009,7 @@ static void (D3D9_SCR_UpdateScreen) (void)
if (Media_ShowFilm())
{
M_Draw(0);
// GLV_UpdatePalette (false, host_frametime);
// V_UpdatePalette (false);
#if defined(_WIN32)
Media_RecordFrame();
#endif
@ -1072,7 +1076,7 @@ static void (D3D9_SCR_UpdateScreen) (void)
SCR_DrawTwoDimensional(uimenu, nohud);
GLV_UpdatePalette (false, host_frametime);
V_UpdatePalette (false);
#if defined(_WIN32) && defined(GLQUAKE)
Media_RecordFrame();
#endif
@ -1195,12 +1199,12 @@ static void (D3D9_R_RenderView) (void)
d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1, 0));
R_SetFrustum (r_refdef.m_projection, r_refdef.m_view);
RQ_BeginFrame();
Surf_DrawWorld();
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL))
{
if (cl.worldmodel)
P_DrawParticles ();
}
Surf_DrawWorld();
RQ_RenderBatchClear();
}

View file

@ -20,7 +20,7 @@
<Configuration
Name="MinGLDebug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
IntermediateDirectory="fteqw_$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
@ -56,11 +56,8 @@
FloatingPointModel="2"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="quakedef.h"
PrecompiledHeaderFile=".\GLDebug/qwcl.pch"
AssemblerListingLocation=".\ftequake___Win32_MinGLDebug/"
ObjectFile=".\GLDebug/"
ProgramDataBaseFileName=".\GLDebug/"
BrowseInformation="1"
BrowseInformationFile="$(IntDir)\"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
@ -102,7 +99,7 @@
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\ftequake___Win32_MinGLDebug/ftequake.bsc"
OutputFile="$(IntDir)\"
/>
<Tool
Name="VCFxCopTool"
@ -221,7 +218,7 @@
<Configuration
Name="D3DDebug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
IntermediateDirectory="fteqw_$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
@ -257,10 +254,8 @@
FloatingPointModel="2"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="quakedef.h"
AssemblerListingLocation=".\D3DDebug/"
ObjectFile=".\D3DDebug/"
ProgramDataBaseFileName=".\D3DDebug/"
BrowseInformation="1"
BrowseInformationFile="$(IntDir)\"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
@ -303,6 +298,7 @@
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile="$(IntDir)\"
/>
<Tool
Name="VCFxCopTool"
@ -422,7 +418,7 @@
<Configuration
Name="MinGLRelease|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
IntermediateDirectory="fteqw_$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
@ -467,11 +463,8 @@
FloatingPointModel="2"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="quakedef.h"
PrecompiledHeaderFile=".\ftequake___Win32_MinGLRelease/ftequake.pch"
AssemblerListingLocation=".\ftequake___Win32_MinGLRelease/"
ObjectFile=".\ftequake___Win32_MinGLRelease/"
ProgramDataBaseFileName=".\ftequake___Win32_MinGLRelease/"
BrowseInformation="1"
BrowseInformationFile="$(IntDir)\"
WarningLevel="3"
SuppressStartupBanner="true"
CallingConvention="1"
@ -514,7 +507,7 @@
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\ftequake___Win32_MinGLRelease/ftequake.bsc"
OutputFile="$(IntDir)\"
/>
<Tool
Name="VCFxCopTool"
@ -636,7 +629,7 @@
<Configuration
Name="GLDebug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
IntermediateDirectory="fteqw_$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
@ -675,6 +668,7 @@
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="quakedef.h"
BrowseInformation="1"
BrowseInformationFile="$(IntDir)\"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
@ -720,7 +714,7 @@
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\GLDebug/ftequake.bsc"
OutputFile="$(IntDir)\"
/>
<Tool
Name="VCFxCopTool"
@ -837,7 +831,7 @@
<Configuration
Name="Release Dedicated Server|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
IntermediateDirectory="fteqw_$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
@ -879,6 +873,7 @@
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="quakedef.h"
BrowseInformation="1"
BrowseInformationFile="$(IntDir)\"
WarningLevel="3"
SuppressStartupBanner="true"
DisableSpecificWarnings="4996"
@ -919,7 +914,7 @@
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\ftequake___Win32_Release_Dedicated_Server/ftequake.bsc"
OutputFile="$(IntDir)\"
/>
<Tool
Name="VCFxCopTool"
@ -1039,7 +1034,7 @@
<Configuration
Name="MRelease|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
IntermediateDirectory="fteqw_$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
@ -1082,11 +1077,7 @@
FloatingPointModel="2"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="quakedef.h"
PrecompiledHeaderFile=".\MRelease/ftequake.pch"
AssemblerListingLocation=".\MRelease/"
ObjectFile=".\MRelease/"
ProgramDataBaseFileName=".\MRelease/"
BrowseInformationFile=".\MRelease/"
BrowseInformationFile="$(IntDir)\"
SuppressStartupBanner="true"
DisableSpecificWarnings="4996"
/>
@ -1128,7 +1119,7 @@
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\MRelease/ftequake.bsc"
OutputFile="$(IntDir)\"
/>
<Tool
Name="VCFxCopTool"
@ -1249,7 +1240,7 @@
<Configuration
Name="Debug Dedicated Server|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
IntermediateDirectory="fteqw_$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
@ -1286,11 +1277,8 @@
FloatingPointModel="2"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="quakedef.h"
PrecompiledHeaderFile=".\DebugServer/qwcl.pch"
AssemblerListingLocation=".\DebugServer/"
ObjectFile=".\DebugServer/"
ProgramDataBaseFileName=".\DebugServer/"
BrowseInformation="1"
BrowseInformationFile="$(IntDir)\"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
@ -1332,7 +1320,7 @@
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\DebugServer/ftequake.bsc"
OutputFile="$(IntDir)\"
/>
<Tool
Name="VCFxCopTool"
@ -1453,7 +1441,7 @@
<Configuration
Name="MDebug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
IntermediateDirectory="fteqw_$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
@ -1489,12 +1477,8 @@
FloatingPointModel="2"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="quakedef.h"
PrecompiledHeaderFile=".\MDebug/qwcl.pch"
AssemblerListingLocation=".\MDebug/"
ObjectFile=".\MDebug/"
ProgramDataBaseFileName=".\MDebug/"
BrowseInformation="1"
BrowseInformationFile=".\MDebug/"
BrowseInformationFile="$(IntDir)\"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
@ -1537,7 +1521,7 @@
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\MDebug/ftequake.bsc"
OutputFile="$(IntDir)\"
/>
<Tool
Name="VCFxCopTool"
@ -1659,12 +1643,12 @@
<Configuration
Name="GLRelease|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
IntermediateDirectory="fteqw_$(ConfigurationName)"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
WholeProgramOptimization="1"
WholeProgramOptimization="2"
>
<Tool
Name="VCPreBuildEventTool"
@ -1694,20 +1678,16 @@
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="true"
AdditionalIncludeDirectories="../libs/speex,..\client,../libs/freetype2/include,../common,../server,../gl,../sw,../qclib,../libs,../libs/dxsdk7/include"
PreprocessorDefinitions="NDEBUG;GLQUAKE;WIN32;_WINDOWS"
StringPooling="true"
ExceptionHandling="0"
BufferSecurityCheck="false"
EnableEnhancedInstructionSet="0"
FloatingPointModel="2"
RuntimeTypeInfo="false"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="quakedef.h"
PrecompiledHeaderFile=".\ftequake___Win32_GLRelease/ftequake.pch"
AssemblerListingLocation=".\ftequake___Win32_GLRelease/"
ObjectFile=".\ftequake___Win32_GLRelease/"
ProgramDataBaseFileName=".\ftequake___Win32_GLRelease/"
BrowseInformationFile="$(IntDir)\"
WarningLevel="3"
SuppressStartupBanner="true"
CallingConvention="1"
@ -1729,14 +1709,12 @@
Name="VCLinkerTool"
AdditionalDependencies="comctl32.lib wsock32.lib winmm.lib odbc32.lib odbccp32.lib"
OutputFile="../../fteglqw.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="../libs/dxsdk7/lib"
GenerateManifest="false"
GenerateManifest="true"
IgnoreDefaultLibraryNames="libc.lib;msvcrt.lib"
GenerateDebugInformation="true"
GenerateMapFile="true"
SubSystem="2"
LargeAddressAware="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
OptimizeForWindows98="1"
@ -1753,8 +1731,7 @@
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\ftequake___Win32_GLRelease/ftequake.bsc"
OutputFile="$(IntDir)\"
/>
<Tool
Name="VCFxCopTool"
@ -1876,7 +1853,7 @@
<Configuration
Name="D3DRelease|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
IntermediateDirectory="fteqw_$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
@ -1912,15 +1889,15 @@
OmitFramePointers="true"
AdditionalIncludeDirectories="../libs/speex;..\client;../libs/freetype2/include;../common;../server;../gl;../sw;../qclib;../libs;../d3d9;../libs/dxsdk9/include;../libs/dxsdk7/include"
PreprocessorDefinitions="NDEBUG;D3DQUAKE;WIN32;_WINDOWS"
StringPooling="true"
ExceptionHandling="0"
RuntimeLibrary="0"
BufferSecurityCheck="false"
FloatingPointModel="2"
RuntimeTypeInfo="false"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="quakedef.h"
AssemblerListingLocation=".\D3DRelease/"
ObjectFile=".\D3DRelease/"
ProgramDataBaseFileName=".\D3DRelease/vc80.pdb"
BrowseInformationFile="$(IntDir)\"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="0"
@ -1949,6 +1926,8 @@
GenerateMapFile="true"
MapFileName=".\D3DRelease/fted3dqw_dbg.map"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
@ -1963,7 +1942,7 @@
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\D3DRelease/ftequake.bsc"
OutputFile="$(IntDir)\"
/>
<Tool
Name="VCFxCopTool"
@ -12580,10 +12559,6 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\client\pr_skelobj.c"
>
</File>
<File
RelativePath="..\client\r_part.c"
>
@ -23817,6 +23792,7 @@
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
@ -32006,6 +31982,10 @@
RelativePath="..\common\pr_bgcmd.c"
>
</File>
<File
RelativePath="..\client\pr_skelobj.c"
>
</File>
<File
RelativePath="..\common\q1bsp.c"
>

View file

@ -89,6 +89,7 @@
GenerateDebugInformation="true"
GenerateMapFile="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@ -312,7 +313,7 @@
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\npfte___Win32_GLRelease/npfte.bsc"
OutputFile="$(IntDir)\"
/>
<Tool
Name="VCFxCopTool"
@ -459,6 +460,14 @@
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\client\sys_npfte.c"

View file

@ -1039,7 +1039,7 @@ void R_GAlias_GenerateBatches(entity_t *e, batch_t **batches)
}
if (e->flags & RF_NOSHADOW)
b->flags |= BEF_NOSHADOWS;
b->vbo = 0;
b->vbo = NULL;
b->next = batches[sort];
batches[sort] = b;
}
@ -1115,7 +1115,7 @@ void R_Sprite_GenerateBatches(entity_t *e, batch_t **batches)
b->lightmap = -1;
b->surf_first = surfnum;
b->flags = 0;
b->vbo = 0;
b->vbo = NULL;
b->next = batches[shader->sort];
batches[shader->sort] = b;
}

View file

@ -137,6 +137,7 @@ void main ()\n\
#define LIGHTPASS_GLSL_FRAGMENT "\
#ifdef FRAGMENT_SHADER\n\
#include \"sys/fog.h\"\n\
uniform sampler2D s_t0;\n"/*base texture*/"\
#if defined(BUMP) || defined(SPECULAR) || defined(OFFSETMAPPING)\n\
uniform sampler2D s_t1;\n"/*normalmap/height texture*/"\
@ -230,7 +231,7 @@ vec2 spot = ((shadowcoord.st)/shadowcoord.w - 0.5)*2.0;colorscale*=1.0-(dot(spot
l_lightcolour *= texture2d(s_t3, shadowcoord);\n\
#endif\n\
\n\
gl_FragColor.rgb = diff*colorscale*l_lightcolour;\n\
gl_FragColor.rgb = fog3additive(diff*colorscale*l_lightcolour);\n\
}\n\
\
#endif\n\
@ -252,6 +253,7 @@ static const char LIGHTPASS_SHADER[] = "\
!!permu FULLBRIGHT\n\
!!permu OFFSETMAPPING\n\
!!permu SKELETAL\n\
!!permu FOG\n\
#define LIGHTPASS\n\
%s\n\
}\n\
@ -352,6 +354,7 @@ struct {
int currentprogram;
vbo_t dummyvbo;
int colourarraytype;
int currentvbo;
int currentebo;
@ -949,7 +952,7 @@ static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass, qboolea
t = shaderstate.curshadowmap;
break;
case T_GEN_SKYBOX:
case T_GEN_CUBEMAP:
t = pass->anim_frames[0];
GL_LazyBind(tmu, GL_TEXTURE_CUBE_MAP_ARB, t, useclientarray);
return;
@ -958,6 +961,13 @@ static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass, qboolea
GL_LazyBind(tmu, GL_TEXTURE_CUBE_MAP_ARB, t, useclientarray);
return;
case T_GEN_3DMAP:
t = pass->anim_frames[0];
checkglerror();
GL_LazyBind(tmu, GL_TEXTURE_3D, t, useclientarray);
checkglerror();
return;
case T_GEN_VIDEOMAP:
#ifdef NOMEDIA
t = shaderstate.curtexnums?shaderstate.curtexnums->base:r_nulltex;
@ -1976,15 +1986,15 @@ static void GenerateColourMods(const shaderpass_t *pass)
mesh_t *meshlist;
meshlist = shaderstate.meshes[0];
if (shaderstate.sourcevbo->colours4ub)
/*if (shaderstate.sourcevbo->colours4ub)
{
//hack...
GL_SelectVBO(shaderstate.sourcevbo->vbocolours);
GL_SelectVBO(shaderstate.sourcevbo->colours.gl.vbo);
qglEnableClientState(GL_COLOR_ARRAY);
qglColorPointer(4, GL_UNSIGNED_BYTE, 0, shaderstate.sourcevbo->colours4ub);
qglColorPointer(4, GL_UNSIGNED_BYTE, 0, shaderstate.sourcevbo->colours4ub.gl.addr);
qglShadeModel(GL_SMOOTH);
return;
}
}*/
if (pass->flags & SHADER_PASS_NOCOLORARRAY && qglColor4fv)
{
avec4_t scol;
@ -2037,8 +2047,8 @@ static void GenerateColourMods(const shaderpass_t *pass)
//if its vetex lighting, just use the vbo
if (((pass->rgbgen == RGB_GEN_VERTEX_LIGHTING && shaderstate.identitylighting == 1) || pass->rgbgen == RGB_GEN_VERTEX_EXACT) && pass->alphagen == ALPHA_GEN_VERTEX)
{
GL_SelectVBO(shaderstate.sourcevbo->vbocolours);
qglColorPointer(4, GL_FLOAT, 0, shaderstate.sourcevbo->colours4f);
GL_SelectVBO(shaderstate.sourcevbo->colours.gl.vbo);
qglColorPointer(4, shaderstate.colourarraytype, 0, shaderstate.sourcevbo->colours.gl.addr);
qglEnableClientState(GL_COLOR_ARRAY);
return;
}
@ -2065,36 +2075,36 @@ static void BE_GeneratePassTC(const shaderpass_t *pass, int passno)
//if there are no tcmods, pass through here as fast as possible
if (pass->tcgen == TC_GEN_BASE)
{
GL_SelectVBO(shaderstate.sourcevbo->vbotexcoord);
qglTexCoordPointer(2, GL_FLOAT, 0, shaderstate.sourcevbo->texcoord);
GL_SelectVBO(shaderstate.sourcevbo->texcoord.gl.vbo);
qglTexCoordPointer(2, GL_FLOAT, 0, shaderstate.sourcevbo->texcoord.gl.addr);
}
else if (pass->tcgen == TC_GEN_LIGHTMAP)
{
if (!shaderstate.sourcevbo->lmcoord)
if (!shaderstate.sourcevbo->lmcoord.gl.addr)
{
GL_SelectVBO(shaderstate.sourcevbo->vbotexcoord);
qglTexCoordPointer(2, GL_FLOAT, 0, shaderstate.sourcevbo->texcoord);
GL_SelectVBO(shaderstate.sourcevbo->texcoord.gl.vbo);
qglTexCoordPointer(2, GL_FLOAT, 0, shaderstate.sourcevbo->texcoord.gl.addr);
}
else
{
GL_SelectVBO(shaderstate.sourcevbo->vbolmcoord);
qglTexCoordPointer(2, GL_FLOAT, 0, shaderstate.sourcevbo->lmcoord);
GL_SelectVBO(shaderstate.sourcevbo->lmcoord.gl.vbo);
qglTexCoordPointer(2, GL_FLOAT, 0, shaderstate.sourcevbo->lmcoord.gl.addr);
}
}
else if (pass->tcgen == TC_GEN_NORMAL)
{
GL_SelectVBO(shaderstate.sourcevbo->vbonormals);
qglTexCoordPointer(3, GL_FLOAT, 0, shaderstate.sourcevbo->normals);
GL_SelectVBO(shaderstate.sourcevbo->normals.gl.vbo);
qglTexCoordPointer(3, GL_FLOAT, 0, shaderstate.sourcevbo->normals.gl.addr);
}
else if (pass->tcgen == TC_GEN_SVECTOR)
{
GL_SelectVBO(shaderstate.sourcevbo->vbosvector);
qglTexCoordPointer(3, GL_FLOAT, 0, shaderstate.sourcevbo->svector);
GL_SelectVBO(shaderstate.sourcevbo->svector.gl.vbo);
qglTexCoordPointer(3, GL_FLOAT, 0, shaderstate.sourcevbo->svector.gl.addr);
}
else if (pass->tcgen == TC_GEN_TVECTOR)
{
GL_SelectVBO(shaderstate.sourcevbo->vbotvector);
qglTexCoordPointer(3, GL_FLOAT, 0, shaderstate.sourcevbo->tvector);
GL_SelectVBO(shaderstate.sourcevbo->tvector.gl.vbo);
qglTexCoordPointer(3, GL_FLOAT, 0, shaderstate.sourcevbo->tvector.gl.addr);
}
else
{
@ -2351,7 +2361,7 @@ static void BE_SubmitMeshChain(void)
}
}
qglDrawRangeElements(GL_TRIANGLES, startv, endv, endi-starti, GL_INDEX_TYPE, shaderstate.sourcevbo->indicies + starti);
qglDrawRangeElements(GL_TRIANGLES, startv, endv, endi-starti, GL_INDEX_TYPE, (index_t*)shaderstate.sourcevbo->indicies.gl.addr + starti);
RQuantAdd(RQUANT_DRAWS, 1);
}
/*
@ -2420,52 +2430,52 @@ static unsigned int BE_Program_Set_Attribute(const shaderprogparm_t *p, unsigned
qglVertexAttribPointer(p->handle[perm], 3, GL_FLOAT, GL_FALSE, sizeof(vecV_t), shaderstate.pendingvertexpointer);
return 1u<<p->handle[perm];
case SP_ATTR_COLOUR:
if (shaderstate.sourcevbo->colours4f)
if (shaderstate.sourcevbo->colours.gl.addr)
{
GL_SelectVBO(shaderstate.sourcevbo->vbocolours);
qglVertexAttribPointer(p->handle[perm], 4, GL_FLOAT, GL_FALSE, sizeof(vec4_t), shaderstate.sourcevbo->colours4f);
GL_SelectVBO(shaderstate.sourcevbo->colours.gl.vbo);
qglVertexAttribPointer(p->handle[perm], 4, shaderstate.colourarraytype, GL_FALSE, 0, shaderstate.sourcevbo->colours.gl.addr);
return 1u<<p->handle[perm];
}
else if (shaderstate.sourcevbo->colours4ub)
/* else if (shaderstate.sourcevbo->colours4ub)
{
GL_SelectVBO(shaderstate.sourcevbo->vbocolours);
qglVertexAttribPointer(p->handle[perm], 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(byte_vec4_t), shaderstate.sourcevbo->colours4ub);
GL_SelectVBO(shaderstate.sourcevbo->colours.gl.vbo);
qglVertexAttribPointer(p->handle[perm], 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(byte_vec4_t), shaderstate.sourcevbo->colours.gl.addr);
return 1u<<p->handle[perm];
}
}*/
break;
case SP_ATTR_TEXCOORD:
GL_SelectVBO(shaderstate.sourcevbo->vbotexcoord);
qglVertexAttribPointer(p->handle[perm], 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->texcoord);
GL_SelectVBO(shaderstate.sourcevbo->texcoord.gl.vbo);
qglVertexAttribPointer(p->handle[perm], 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->texcoord.gl.addr);
return 1u<<p->handle[perm];
case SP_ATTR_LMCOORD:
GL_SelectVBO(shaderstate.sourcevbo->vbolmcoord);
qglVertexAttribPointer(p->handle[perm], 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->lmcoord);
GL_SelectVBO(shaderstate.sourcevbo->lmcoord.gl.vbo);
qglVertexAttribPointer(p->handle[perm], 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->lmcoord.gl.addr);
return 1u<<p->handle[perm];
case SP_ATTR_NORMALS:
if (!shaderstate.sourcevbo->normals)
if (!shaderstate.sourcevbo->normals.gl.addr)
return 0;
GL_SelectVBO(shaderstate.sourcevbo->vbonormals);
qglVertexAttribPointer(p->handle[perm], 3, GL_FLOAT, GL_FALSE, sizeof(vec3_t), shaderstate.sourcevbo->normals);
GL_SelectVBO(shaderstate.sourcevbo->normals.gl.vbo);
qglVertexAttribPointer(p->handle[perm], 3, GL_FLOAT, GL_FALSE, sizeof(vec3_t), shaderstate.sourcevbo->normals.gl.addr);
return 1u<<p->handle[perm];
case SP_ATTR_SNORMALS:
if (!shaderstate.sourcevbo->normals)
if (!shaderstate.sourcevbo->svector.gl.addr)
return 0;
GL_SelectVBO(shaderstate.sourcevbo->vbosvector);
qglVertexAttribPointer(p->handle[perm], 3, GL_FLOAT, GL_FALSE, sizeof(vec3_t), shaderstate.sourcevbo->svector);
GL_SelectVBO(shaderstate.sourcevbo->svector.gl.vbo);
qglVertexAttribPointer(p->handle[perm], 3, GL_FLOAT, GL_FALSE, sizeof(vec3_t), shaderstate.sourcevbo->svector.gl.addr);
return 1u<<p->handle[perm];
case SP_ATTR_TNORMALS:
if (!shaderstate.sourcevbo->normals)
if (!shaderstate.sourcevbo->tvector.gl.addr)
return 0;
GL_SelectVBO(shaderstate.sourcevbo->vbotvector);
qglVertexAttribPointer(p->handle[perm], 3, GL_FLOAT, GL_FALSE, sizeof(vec3_t), shaderstate.sourcevbo->tvector);
GL_SelectVBO(shaderstate.sourcevbo->tvector.gl.vbo);
qglVertexAttribPointer(p->handle[perm], 3, GL_FLOAT, GL_FALSE, sizeof(vec3_t), shaderstate.sourcevbo->tvector.gl.addr);
return 1u<<p->handle[perm];
case SP_ATTR_BONENUMS:
GL_SelectVBO(shaderstate.sourcevbo->vbobonenums);
qglVertexAttribPointer(p->handle[perm], 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(byte_vec4_t), shaderstate.sourcevbo->bonenums);
GL_SelectVBO(shaderstate.sourcevbo->bonenums.gl.vbo);
qglVertexAttribPointer(p->handle[perm], 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(byte_vec4_t), shaderstate.sourcevbo->bonenums.gl.addr);
return 1u<<p->handle[perm];
case SP_ATTR_BONEWEIGHTS:
GL_SelectVBO(shaderstate.sourcevbo->vboboneweights);
qglVertexAttribPointer(p->handle[perm], 4, GL_FLOAT, GL_FALSE, sizeof(vec4_t), shaderstate.sourcevbo->boneweights);
GL_SelectVBO(shaderstate.sourcevbo->boneweights.gl.vbo);
qglVertexAttribPointer(p->handle[perm], 4, GL_FLOAT, GL_FALSE, sizeof(vec4_t), shaderstate.sourcevbo->boneweights.gl.addr);
return 1u<<p->handle[perm];
case SP_M_VIEW:
@ -2563,7 +2573,6 @@ static unsigned int BE_Program_Set_Attribute(const shaderprogparm_t *p, unsigned
case SP_LIGHTSCREEN:
{
float v[4], tempv[4];
float out[3];
v[0] = shaderstate.lightorg[0];
v[1] = shaderstate.lightorg[1];
@ -2587,6 +2596,9 @@ static unsigned int BE_Program_Set_Attribute(const shaderprogparm_t *p, unsigned
case SP_LIGHTCOLOUR:
qglUniform3fvARB(p->handle[perm], 1, shaderstate.lightcolours);
break;
case SP_W_FOG:
qglUniform4fvARB(p->handle[perm], 1, r_refdef.gfog_rgb);
break;
case SP_V_EYEPOS:
qglUniform3fvARB(p->handle[perm], 1, r_origin);
break;
@ -2683,6 +2695,8 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
perm |= PERMUTATION_LOWER;
if (TEXVALID(shaderstate.curtexnums->upperoverlay) && p->handle[perm|PERMUTATION_UPPER].glsl)
perm |= PERMUTATION_UPPER;
if (r_refdef.gfog_alpha && p->handle[perm|PERMUTATION_FOG].glsl)
perm |= PERMUTATION_FOG;
if (r_glsl_offsetmapping.ival && TEXVALID(shaderstate.curtexnums->bump) && p->handle[perm|PERMUTATION_OFFSET].glsl)
perm |= PERMUTATION_OFFSET;
GL_SelectProgram(p->handle[perm].glsl);
@ -2786,7 +2800,8 @@ void GLBE_SelectMode(backendmode_t mode)
{
GL_LazyBind(--shaderstate.lastpasstmus, 0, r_nulltex, false);
}
qglShadeModel(GL_FLAT);
if (qglShadeModel)
qglShadeModel(GL_FLAT);
//we don't write or blend anything (maybe alpha test... but mneh)
BE_SendPassBlendDepthMask(SBITS_MISC_DEPTHWRITE | SBITS_MASK_BITS);
@ -2991,13 +3006,13 @@ static void DrawMeshes(void)
RQuantAdd(RQUANT_ENTBATCHES, 1);
}
GL_SelectEBO(shaderstate.sourcevbo->vboe);
GL_SelectEBO(shaderstate.sourcevbo->indicies.gl.vbo);
if (shaderstate.curshader->numdeforms)
GenerateVertexDeforms(shaderstate.curshader);
else
{
shaderstate.pendingvertexpointer = shaderstate.sourcevbo->coord;
shaderstate.pendingvertexvbo = shaderstate.sourcevbo->vbocoord;
shaderstate.pendingvertexpointer = shaderstate.sourcevbo->coord.gl.addr;
shaderstate.pendingvertexvbo = shaderstate.sourcevbo->coord.gl.vbo;
}
#ifndef FORCESTATE
@ -3127,18 +3142,26 @@ void GLBE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **meshlist, vbo_
{
m = *meshlist++;
shaderstate.dummyvbo.coord = m->xyz_array;
shaderstate.dummyvbo.texcoord = m->st_array;
shaderstate.dummyvbo.indicies = m->indexes;
shaderstate.dummyvbo.normals = m->normals_array;
shaderstate.dummyvbo.svector = m->snormals_array;
shaderstate.dummyvbo.tvector = m->tnormals_array;
shaderstate.dummyvbo.colours4f = m->colors4f_array;
shaderstate.dummyvbo.colours4ub = m->colors4b_array;
shaderstate.dummyvbo.coord.gl.addr = m->xyz_array;
shaderstate.dummyvbo.texcoord.gl.addr = m->st_array;
shaderstate.dummyvbo.indicies.gl.addr = m->indexes;
shaderstate.dummyvbo.normals.gl.addr = m->normals_array;
shaderstate.dummyvbo.svector.gl.addr = m->snormals_array;
shaderstate.dummyvbo.tvector.gl.addr = m->tnormals_array;
if (m->colors4f_array)
{
shaderstate.colourarraytype = GL_FLOAT;
shaderstate.dummyvbo.colours.gl.addr = m->colors4f_array;
}
else
{
shaderstate.colourarraytype = GL_UNSIGNED_BYTE;
shaderstate.dummyvbo.colours.gl.addr = m->colors4b_array;
}
shaderstate.dummyvbo.bones = m->bones;
shaderstate.dummyvbo.numbones = m->numbones;
shaderstate.dummyvbo.bonenums = m->bonenums;
shaderstate.dummyvbo.boneweights = m->boneweights;
shaderstate.dummyvbo.bonenums.gl.addr = m->bonenums;
shaderstate.dummyvbo.boneweights.gl.addr = m->boneweights;
shaderstate.meshcount = 1;
shaderstate.meshes = &m;
@ -3148,6 +3171,7 @@ void GLBE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **meshlist, vbo_
else
{
shaderstate.sourcevbo = vbo;
shaderstate.colourarraytype = GL_FLOAT;
shaderstate.curshader = shader;
shaderstate.flags = beflags;
if (shaderstate.curentity != &r_worldentity)
@ -3177,22 +3201,31 @@ void GLBE_SubmitBatch(batch_t *batch)
if (batch->texture)
{
shaderstate.sourcevbo = &batch->texture->vbo;
shaderstate.colourarraytype = GL_FLOAT;
lm = batch->lightmap;
}
else
{
shaderstate.dummyvbo.coord = batch->mesh[0]->xyz_array;
shaderstate.dummyvbo.texcoord = batch->mesh[0]->st_array;
shaderstate.dummyvbo.indicies = batch->mesh[0]->indexes;
shaderstate.dummyvbo.normals = batch->mesh[0]->normals_array;
shaderstate.dummyvbo.svector = batch->mesh[0]->snormals_array;
shaderstate.dummyvbo.tvector = batch->mesh[0]->tnormals_array;
shaderstate.dummyvbo.colours4f = batch->mesh[0]->colors4f_array;
shaderstate.dummyvbo.colours4ub = batch->mesh[0]->colors4b_array;
shaderstate.dummyvbo.coord.gl.addr = batch->mesh[0]->xyz_array;
shaderstate.dummyvbo.texcoord.gl.addr = batch->mesh[0]->st_array;
shaderstate.dummyvbo.indicies.gl.addr = batch->mesh[0]->indexes;
shaderstate.dummyvbo.normals.gl.addr = batch->mesh[0]->normals_array;
shaderstate.dummyvbo.svector.gl.addr = batch->mesh[0]->snormals_array;
shaderstate.dummyvbo.tvector.gl.addr = batch->mesh[0]->tnormals_array;
if (batch->mesh[0]->colors4f_array)
{
shaderstate.colourarraytype = GL_FLOAT;
shaderstate.dummyvbo.colours.gl.addr = batch->mesh[0]->colors4f_array;
}
else
{
shaderstate.colourarraytype = GL_UNSIGNED_BYTE;
shaderstate.dummyvbo.colours.gl.addr = batch->mesh[0]->colors4b_array;
}
shaderstate.dummyvbo.bones = batch->mesh[0]->bones;
shaderstate.dummyvbo.numbones = batch->mesh[0]->numbones;
shaderstate.dummyvbo.bonenums = batch->mesh[0]->bonenums;
shaderstate.dummyvbo.boneweights = batch->mesh[0]->boneweights;
shaderstate.dummyvbo.bonenums.gl.addr = batch->mesh[0]->bonenums;
shaderstate.dummyvbo.boneweights.gl.addr = batch->mesh[0]->boneweights;
shaderstate.sourcevbo = &shaderstate.dummyvbo;
lm = -1;
}
@ -3637,12 +3670,13 @@ void GLBE_DrawWorld (qbyte *vis)
GLBE_SubmitMeshes(true, batches, SHADER_SORT_DECAL, SHADER_SORT_NEAREST);
if (r_refdef.gfog_alpha)
/* if (r_refdef.gfog_alpha)
{
BE_SelectMode(BEM_FOG);
BE_SelectFog(r_refdef.gfog_rgb, r_refdef.gfog_alpha, r_refdef.gfog_density);
GLBE_SubmitMeshes(true, batches, SHADER_SORT_PORTAL, SHADER_SORT_NEAREST);
}
*/
}
else
{

View file

@ -1153,6 +1153,43 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigne
if (gl_config.arb_texture_compression && gl_compress.value && name && !(flags&IF_NOMIPMAP))
samples = (flags&IF_NOALPHA) ? GL_COMPRESSED_RGB_ARB : GL_COMPRESSED_RGBA_ARB;
if (flags & IF_3DMAP)
{
int r,d;
if (scaled_height * scaled_height != scaled_width)
return;
qglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
if (flags & IF_NEAREST)
qglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
else
qglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (flags&IF_CLAMP)
{
qglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
}
else
{
qglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
qglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
qglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
}
for (d = 0; d < scaled_height; d++)
{
/*each 'layer' is sequential, which means we need to de-interlace the layers*/
for (r = 0; r < scaled_height; r++)
{
memcpy(scaled + (r + d*scaled_height) * scaled_height, data + (r*scaled_height + d) * scaled_height, scaled_height*sizeof(*data));
}
}
qglTexImage3D (GL_TEXTURE_3D, 0, samples, scaled_height, scaled_height, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, scaled);
return;
}
if (gl_config.sgis_generate_mipmap && !(flags&IF_NOMIPMAP))
{
TRACE(("dbg: GL_Upload32: GL_SGIS_generate_mipmap\n"));
@ -2191,7 +2228,10 @@ texid_t GL_LoadTexture32 (char *identifier, int width, int height, void *data, u
glt->bpp = 32;
glt->flags = flags;
GL_MTBind(0, GL_TEXTURE_2D, glt->texnum);
if (flags & IF_3DMAP)
GL_MTBind(0, GL_TEXTURE_3D, glt->texnum);
else
GL_MTBind(0, GL_TEXTURE_2D, glt->texnum);
GL_Upload32 (identifier, data, width, height, flags);

View file

@ -1201,7 +1201,7 @@ TRACE(("dbg: RMod_LoadTextures: inittexturedescs\n"));
snprintf(altname, sizeof(altname)-1, "%s_bump", mt->name);
}
if (!TEXVALID(tn.bump) && loadmodel->fromgame != fg_halflife)
/* if (!TEXVALID(tn.bump) && loadmodel->fromgame != fg_halflife)
{
//no mip levels here, would be absurd.
base = (qbyte *)(mt+1); //convert to greyscale.
@ -1210,7 +1210,7 @@ TRACE(("dbg: RMod_LoadTextures: inittexturedescs\n"));
tn.bump = R_LoadTexture8BumpPal(altname, tx->width, tx->height, base, true); //normalise it and then bump it.
}
*/
//don't do any complex quake 8bit -> glossmap. It would likly look a little ugly...
if (gl_specular.value && gl_load24bit.value)
{
@ -1373,7 +1373,7 @@ void RMod_NowLoadExternal(void)
tn.bump = R_LoadBumpmapTexture(va("%s_bump", tx->name), loadname);
if (!TEXVALID(tn.bump))
tn.bump = R_LoadBumpmapTexture(va("%s_bump", tx->name), "bmodels");
if (!TEXVALID(tn.bump))
/* if (!TEXVALID(tn.bump))
{
qbyte *data;
qbyte *heightmap;
@ -1392,7 +1392,7 @@ void RMod_NowLoadExternal(void)
tn.bump = R_LoadTexture8BumpPal (va("%s_bump", tx->name), width, height, heightmap-j, true);
}
}
}
*/ }
if (!TEXVALID(tn.base))
{
tn.base = R_LoadTexture8("notexture", 16, 16, r_notexture_mip+1, IF_NOALPHA, 0);

View file

@ -234,45 +234,60 @@ typedef struct texnums_s {
struct shader_s *shader; //fixme: remove...
} texnums_t;
typedef struct vboarray_s
{
union
{
int dummy;
#ifdef GLQUAKE
struct
{
int vbo;
void *addr;
} gl;
#endif
#ifdef D3DQUAKE
struct
{
void *buff;
unsigned int offs;
} d3d;
#endif
};
} vboarray_t;
typedef struct vbo_s
{
int numvisible;
unsigned int numvisible;
struct msurface_s **vislist;
int meshcount;
unsigned int indexcount;
unsigned int vertcount;
unsigned int meshcount;
struct msurface_s **meshlist;
int vboe;
index_t *indicies;
vboarray_t indicies;
void *vertdata; /*internal use*/
int vbocoord;
vecV_t *coord;
int vbotexcoord;
vec2_t *texcoord;
int vbolmcoord;
vec2_t *lmcoord;
vboarray_t coord;
vboarray_t texcoord;
vboarray_t lmcoord;
int vbonormals;
vec3_t *normals;
int vbosvector;
vec3_t *svector;
int vbotvector;
vec3_t *tvector;
vboarray_t normals;
vboarray_t svector;
vboarray_t tvector;
int vbocolours;
vec4_t *colours4f;
byte_vec4_t *colours4ub;
vboarray_t colours;
int vbobonenums;
byte_vec4_t *bonenums;
vboarray_t bonenums;
int vboboneweights;
vec4_t *boneweights;
vboarray_t boneweights;
int vbobones;
unsigned int vbobones;
float *bones;
int numbones;
unsigned int numbones;
} vbo_t;
void GL_SelectVBO(int vbo);
void GL_SelectEBO(int vbo);

View file

@ -169,7 +169,7 @@ void GLR_FrameTimeGraph (int frametime)
void R_NetgraphInit(void)
{
TEXASSIGN(netgraphtexture, GL_AllocNewTexture("***netgraph***", NET_TIMINGS, NET_GRAPHHEIGHT));
TEXASSIGN(netgraphtexture, R_AllocNewTexture("***netgraph***", NET_TIMINGS, NET_GRAPHHEIGHT));
netgraphshader = R_RegisterShader("netgraph",
"{\n"
"{\n"

View file

@ -99,7 +99,8 @@ void AddLightBlend (float r, float g, float b, float a2)
//Con_Printf("AddLightBlend(): %4.2f %4.2f %4.2f %4.6f\n", v_blend[0], v_blend[1], v_blend[2], v_blend[3]);
}
static float bubble_sintable[17], bubble_costable[17];
#define FLASHBLEND_VERTS 16
static float bubble_sintable[FLASHBLEND_VERTS+1], bubble_costable[FLASHBLEND_VERTS+1];
static void R_InitBubble(void)
{
@ -110,15 +111,14 @@ static void R_InitBubble(void)
bub_sin = bubble_sintable;
bub_cos = bubble_costable;
for (i=16 ; i>=0 ; i--)
for (i=FLASHBLEND_VERTS ; i>=0 ; i--)
{
a = i/16.0 * M_PI*2;
a = i/(float)FLASHBLEND_VERTS * M_PI*2;
*bub_sin++ = sin(a);
*bub_cos++ = cos(a);
}
}
#define FLASHBLEND_VERTS 16
avec4_t flashblend_colours[FLASHBLEND_VERTS+1];
vecV_t flashblend_vcoords[FLASHBLEND_VERTS+1];
vec2_t flashblend_tccoords[FLASHBLEND_VERTS+1];
@ -128,9 +128,32 @@ mesh_t flashblend_mesh;
mesh_t flashblend_fsmesh;
shader_t *flashblend_shader;
shader_t *lpplight_shader;
void R_GenerateFlashblendTexture(void)
{
float dx, dy;
int x, y, a;
unsigned char pixels[32][32][4];
for (y = 0;y < 32;y++)
{
dy = (y - 15.5f) * (1.0f / 16.0f);
for (x = 0;x < 32;x++)
{
dx = (x - 15.5f) * (1.0f / 16.0f);
a = (int)(((1.0f / (dx * dx + dy * dy + 0.2f)) - (1.0f / (1.0f + 0.2))) * 32.0f / (1.0f / (1.0f + 0.2)));
a = bound(0, a, 255);
pixels[y][x][0] = a;
pixels[y][x][1] = a;
pixels[y][x][2] = a;
pixels[y][x][3] = 255;
}
}
R_LoadTexture32("***flashblend***", 32, 32, pixels, 0);
}
void R_InitFlashblends(void)
{
int i;
R_InitBubble();
for (i = 0; i < FLASHBLEND_VERTS; i++)
{
flashblend_indexes[i*3+0] = 0;
@ -139,7 +162,12 @@ void R_InitFlashblends(void)
else
flashblend_indexes[i*3+1] = i+2;
flashblend_indexes[i*3+2] = i+1;
flashblend_tccoords[i+1][0] = 0.5 + bubble_sintable[i]*0.5;
flashblend_tccoords[i+1][1] = 0.5 + bubble_costable[i]*0.5;
}
flashblend_tccoords[0][0] = 0.5;
flashblend_tccoords[0][1] = 0.5;
flashblend_mesh.numvertexes = FLASHBLEND_VERTS+1;
flashblend_mesh.xyz_array = flashblend_vcoords;
flashblend_mesh.st_array = flashblend_tccoords;
@ -156,10 +184,13 @@ void R_InitFlashblends(void)
flashblend_fsmesh.numindexes = 6;
flashblend_fsmesh.istrifan = true;
R_GenerateFlashblendTexture();
flashblend_shader = R_RegisterShader("flashblend",
"{\n"
"program defaultadditivesprite\n"
"{\n"
"map %whiteimage\n"
"map ***flashblend***\n"
"blendfunc gl_one gl_one\n"
"rgbgen vertex\n"
"alphagen vertex\n"
@ -167,8 +198,6 @@ void R_InitFlashblends(void)
"}\n"
);
lpplight_shader = NULL;
R_InitBubble();
}
static qboolean R_BuildDlightMesh(dlight_t *light, float radscale, qboolean expand)
@ -353,7 +382,7 @@ void R_GenDlightBatches(batch_t *batches[])
b->lightmap = -1;
b->surf_first = i;
b->flags |= BEF_NOSHADOWS;
b->vbo = 0;
b->vbo = NULL;
b->next = batches[sort];
batches[sort] = b;
}

View file

@ -78,6 +78,7 @@ cvar_t gl_affinemodels = SCVAR("gl_affinemodels","0");
cvar_t gl_reporttjunctions = SCVAR("gl_reporttjunctions","0");
cvar_t gl_finish = SCVAR("gl_finish","0");
cvar_t gl_dither = SCVAR("gl_dither", "1");
cvar_t r_postprocshader = CVARD("r_postprocshader", "", "Specifies a shader to use as a post-processing shader");
extern cvar_t gl_screenangle;
@ -921,6 +922,8 @@ qboolean R_RenderScene_Cubemap(void)
return false;
if (!ffov.value)
return false;
if (!cls.allow_postproc)
return false;
facemask = 0;
if (ffov.value < 0)
@ -1032,6 +1035,7 @@ qboolean R_RenderScene_Cubemap(void)
R_RenderScene ();
GL_MTBind(0, GL_TEXTURE_CUBE_MAP_ARB, scenepp_postproc_cube);
//FIXME: use a render target instead.
qglCopyTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i, 0, 0, 0, 0, vid.pixelheight - (prect.y + cmapsize), cmapsize, cmapsize);
}
@ -1160,9 +1164,11 @@ void GLR_RenderView (void)
// we check if we need to use any shaders - currently it's just waterwarp
if ((r_waterwarp.value>0 && r_viewleaf && r_viewleaf->contents <= Q1CONTENTS_WATER))
{
GL_Set2D();
if (scenepp_waterwarp)
{
GL_Set2D();
R2D_ScalePic(0, 0, vid.width, vid.height, scenepp_waterwarp);
}
}
@ -1170,6 +1176,16 @@ void GLR_RenderView (void)
if (gl_motionblur.value>0 && gl_motionblur.value < 1 && qglCopyTexImage2D)
R_RenderMotionBlur();
if (*r_postprocshader.string)
{
shader_t *postproc = R_RegisterCustom(r_postprocshader.string, NULL, NULL);
if (postproc)
{
GL_Set2D();
R2D_ScalePic(0, 0, vid.width, vid.height, postproc);
}
}
if (qglGetError())
Con_Printf("GL Error drawing post processing\n");
}

View file

@ -996,6 +996,7 @@ TRACE(("dbg: GLR_NewMap: tp\n"));
if (rtlights_first == rtlights_max)
R_ImportRTLights(cl.worldmodel->entities);
}
Sh_PreGenerateLights();
#endif
}

View file

@ -30,13 +30,13 @@ void GLBE_ClearVBO(vbo_t *vbo)
{
int vboh[7];
int i, j;
vboh[0] = vbo->vboe;
vboh[1] = vbo->vbocoord;
vboh[2] = vbo->vbotexcoord;
vboh[3] = vbo->vbolmcoord;
vboh[4] = vbo->vbonormals;
vboh[5] = vbo->vbosvector;
vboh[6] = vbo->vbotvector;
vboh[0] = vbo->indicies.gl.vbo;
vboh[1] = vbo->coord.gl.vbo;
vboh[2] = vbo->texcoord.gl.vbo;
vboh[3] = vbo->lmcoord.gl.vbo;
vboh[4] = vbo->normals.gl.vbo;
vboh[5] = vbo->svector.gl.vbo;
vboh[6] = vbo->tvector.gl.vbo;
for (i = 0; i < 7; i++)
{
@ -82,45 +82,45 @@ static qboolean GL_BuildVBO(vbo_t *vbo, void *vdata, int vsize, void *edata, int
//opengl ate our data, fixup the vbo arrays to point to the vbo instead of the raw data
if (vbo->indicies && elementsize)
if (vbo->indicies.gl.addr && elementsize)
{
vbo->vboe = vbos[1];
vbo->indicies = (index_t*)((char*)vbo->indicies - (char*)edata);
vbo->indicies.gl.vbo = vbos[1];
vbo->indicies.gl.addr = (index_t*)((char*)vbo->indicies.gl.addr - (char*)edata);
}
if (vbo->coord)
if (vbo->coord.gl.addr)
{
vbo->vbocoord = vbos[0];
vbo->coord = (vecV_t*)((char*)vbo->coord - (char*)vdata);
vbo->coord.gl.vbo = vbos[0];
vbo->coord.gl.addr = (vecV_t*)((char*)vbo->coord.gl.addr - (char*)vdata);
}
if (vbo->texcoord)
if (vbo->texcoord.gl.addr)
{
vbo->vbotexcoord = vbos[0];
vbo->texcoord = (vec2_t*)((char*)vbo->texcoord - (char*)vdata);
vbo->texcoord.gl.vbo = vbos[0];
vbo->texcoord.gl.addr = (vec2_t*)((char*)vbo->texcoord.gl.addr - (char*)vdata);
}
if (vbo->lmcoord)
if (vbo->lmcoord.gl.addr)
{
vbo->vbolmcoord = vbos[0];
vbo->lmcoord = (vec2_t*)((char*)vbo->lmcoord - (char*)vdata);
vbo->lmcoord.gl.vbo = vbos[0];
vbo->lmcoord.gl.addr = (vec2_t*)((char*)vbo->lmcoord.gl.addr - (char*)vdata);
}
if (vbo->normals)
if (vbo->normals.gl.addr)
{
vbo->vbonormals = vbos[0];
vbo->normals = (vec3_t*)((char*)vbo->normals - (char*)vdata);
vbo->normals.gl.vbo = vbos[0];
vbo->normals.gl.addr = (vec3_t*)((char*)vbo->normals.gl.addr - (char*)vdata);
}
if (vbo->svector)
if (vbo->svector.gl.addr)
{
vbo->vbosvector = vbos[0];
vbo->svector = (vec3_t*)((char*)vbo->svector - (char*)vdata);
vbo->svector.gl.vbo = vbos[0];
vbo->svector.gl.addr = (vec3_t*)((char*)vbo->svector.gl.addr - (char*)vdata);
}
if (vbo->tvector)
if (vbo->tvector.gl.addr)
{
vbo->vbotvector = vbos[0];
vbo->tvector = (vec3_t*)((char*)vbo->tvector - (char*)vdata);
vbo->tvector.gl.vbo = vbos[0];
vbo->tvector.gl.addr = (vec3_t*)((char*)vbo->tvector.gl.addr - (char*)vdata);
}
if (vbo->colours4f)
if (vbo->colours.gl.addr)
{
vbo->vbocolours = vbos[0];
vbo->colours4f = (vec4_t*)((char*)vbo->colours4f - (char*)vdata);
vbo->colours.gl.vbo = vbos[0];
vbo->colours.gl.addr = (vec4_t*)((char*)vbo->colours.gl.addr - (char*)vdata);
}
return true;
@ -152,6 +152,15 @@ void GLBE_GenBrushModelVBO(model_t *mod)
mesh_t *m;
char *p;
vecV_t *coord;
vec2_t *texcoord;
vec2_t *lmcoord;
vec3_t *normals;
vec3_t *svector;
vec3_t *tvector;
vec4_t *colours;
index_t *indicies;
if (!mod->numsurfaces)
return;
@ -200,14 +209,23 @@ void GLBE_GenBrushModelVBO(model_t *mod)
p = vbo->vertdata;
vbo->coord = allocbuf(&p, maxvboverts, sizeof(*vbo->coord));
vbo->texcoord = allocbuf(&p, maxvboverts, sizeof(*vbo->texcoord));
vbo->lmcoord = allocbuf(&p, maxvboverts, sizeof(*vbo->lmcoord));
vbo->normals = allocbuf(&p, maxvboverts, sizeof(*vbo->normals));
vbo->svector = allocbuf(&p, maxvboverts, sizeof(*vbo->svector));
vbo->tvector = allocbuf(&p, maxvboverts, sizeof(*vbo->tvector));
vbo->colours4f = allocbuf(&p, maxvboverts, sizeof(*vbo->colours4f));
vbo->indicies = allocbuf(&p, maxvboelements, sizeof(index_t));
vbo->coord.gl.addr = allocbuf(&p, maxvboverts, sizeof(vecV_t));
vbo->texcoord.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec2_t));
vbo->lmcoord.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec2_t));
vbo->normals.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec3_t));
vbo->svector.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec3_t));
vbo->tvector.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec3_t));
vbo->colours.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec4_t));
vbo->indicies.gl.addr = allocbuf(&p, maxvboelements, sizeof(index_t));
coord = vbo->coord.gl.addr;
texcoord = vbo->texcoord.gl.addr;
lmcoord = vbo->lmcoord.gl.addr;
normals = vbo->normals.gl.addr;
svector = vbo->svector.gl.addr;
tvector = vbo->tvector.gl.addr;
colours = vbo->colours.gl.addr;
indicies = vbo->indicies.gl.addr;
vbo->meshcount = meshes;
vbo->meshlist = BZ_Malloc(meshes*sizeof(*vbo->meshlist));
@ -228,62 +246,57 @@ void GLBE_GenBrushModelVBO(model_t *mod)
m->vbofirstvert = vcount;
m->vbofirstelement = ecount;
for (v = 0; v < m->numindexes; v++)
vbo->indicies[ecount++] = vcount + m->indexes[v];
indicies[ecount++] = vcount + m->indexes[v];
for (v = 0; v < m->numvertexes; v++)
{
vbo->coord[vcount+v][0] = m->xyz_array[v][0];
vbo->coord[vcount+v][1] = m->xyz_array[v][1];
vbo->coord[vcount+v][2] = m->xyz_array[v][2];
coord[vcount+v][0] = m->xyz_array[v][0];
coord[vcount+v][1] = m->xyz_array[v][1];
coord[vcount+v][2] = m->xyz_array[v][2];
if (m->st_array)
{
vbo->texcoord[vcount+v][0] = m->st_array[v][0];
vbo->texcoord[vcount+v][1] = m->st_array[v][1];
texcoord[vcount+v][0] = m->st_array[v][0];
texcoord[vcount+v][1] = m->st_array[v][1];
}
if (m->lmst_array)
{
vbo->lmcoord[vcount+v][0] = m->lmst_array[v][0];
vbo->lmcoord[vcount+v][1] = m->lmst_array[v][1];
lmcoord[vcount+v][0] = m->lmst_array[v][0];
lmcoord[vcount+v][1] = m->lmst_array[v][1];
}
if (m->normals_array)
{
vbo->normals[vcount+v][0] = m->normals_array[v][0];
vbo->normals[vcount+v][1] = m->normals_array[v][1];
vbo->normals[vcount+v][2] = m->normals_array[v][2];
normals[vcount+v][0] = m->normals_array[v][0];
normals[vcount+v][1] = m->normals_array[v][1];
normals[vcount+v][2] = m->normals_array[v][2];
}
if (m->snormals_array)
{
vbo->svector[vcount+v][0] = m->snormals_array[v][0];
vbo->svector[vcount+v][1] = m->snormals_array[v][1];
vbo->svector[vcount+v][2] = m->snormals_array[v][2];
svector[vcount+v][0] = m->snormals_array[v][0];
svector[vcount+v][1] = m->snormals_array[v][1];
svector[vcount+v][2] = m->snormals_array[v][2];
}
if (m->tnormals_array)
{
vbo->tvector[vcount+v][0] = m->tnormals_array[v][0];
vbo->tvector[vcount+v][1] = m->tnormals_array[v][1];
vbo->tvector[vcount+v][2] = m->tnormals_array[v][2];
tvector[vcount+v][0] = m->tnormals_array[v][0];
tvector[vcount+v][1] = m->tnormals_array[v][1];
tvector[vcount+v][2] = m->tnormals_array[v][2];
}
if (m->colors4f_array)
{
vbo->colours4f[vcount+v][0] = m->colors4f_array[v][0];
vbo->colours4f[vcount+v][1] = m->colors4f_array[v][1];
vbo->colours4f[vcount+v][2] = m->colors4f_array[v][2];
vbo->colours4f[vcount+v][3] = m->colors4f_array[v][3];
colours[vcount+v][0] = m->colors4f_array[v][0];
colours[vcount+v][1] = m->colors4f_array[v][1];
colours[vcount+v][2] = m->colors4f_array[v][2];
colours[vcount+v][3] = m->colors4f_array[v][3];
}
}
vcount += v;
}
if (GL_BuildVBO(vbo, vbo->coord, vcount*pervertsize, vbo->indicies, ecount*sizeof(index_t)))
if (GL_BuildVBO(vbo, vbo->vertdata, vcount*pervertsize, indicies, ecount*sizeof(index_t)))
{
BZ_Free(vbo->vertdata);
vbo->vertdata = NULL;
}
}
/* for (i=0 ; i<mod->numsurfaces ; i++)
{
if (!mod->surfaces[i].mark)
Host_EndGame("Surfaces with bad textures detected\n");
}*/
}
void GLBE_UploadAllLightmaps(void)

View file

@ -110,7 +110,7 @@ void GLSCR_UpdateScreen (void)
if (editormodal)
{
Editor_Draw();
GLV_UpdatePalette (false, host_frametime);
V_UpdatePalette (false);
#if defined(_WIN32) && defined(GLQUAKE)
Media_RecordFrame();
#endif
@ -127,7 +127,7 @@ void GLSCR_UpdateScreen (void)
if (Media_ShowFilm())
{
M_Draw(0);
GLV_UpdatePalette (false, host_frametime);
V_UpdatePalette (false);
#if defined(_WIN32) && defined(GLQUAKE)
Media_RecordFrame();
#endif
@ -205,7 +205,7 @@ void GLSCR_UpdateScreen (void)
SCR_DrawTwoDimensional(uimenu, nohud);
GLV_UpdatePalette (false, host_frametime);
V_UpdatePalette (false);
#if defined(_WIN32) && defined(GLQUAKE)
Media_RecordFrame();
#endif

View file

@ -52,6 +52,7 @@ int be_maxpasses;
#define Q_stricmp stricmp
#define Q_strnicmp strnicmp
#define Com_sprintf snprintf
#define clamp(v,min, max) (v) = (((v)<(min))?(min):(((v)>(max))?(max):(v)));
@ -229,7 +230,7 @@ static qboolean Shader_EvaluateCondition(char **ptr)
{
token++;
if (!Q_stricmp(token, "lpp"))
conditiontrue = conditiontrue == !r_lightprepass.ival;
conditiontrue = conditiontrue == r_lightprepass.ival;
else if (!Q_stricmp(token, "lightmap"))
conditiontrue = conditiontrue == !r_fullbright.value;
else if (!Q_stricmp(token, "deluxmap") )
@ -537,10 +538,21 @@ static void Shader_ParseFunc ( char **ptr, shaderfunc_t *func )
//===========================================================================
static int Shader_SetImageFlags ( shader_t *shader )
static int Shader_SetImageFlags(shader_t *shader, char **name)
{
int flags = 0;
while (name)
{
if (!Q_strnicmp(*name, "$3d:", 4))
{
*name+=4;
flags|= IF_3DMAP;
}
else
name = NULL;
}
// if (shader->flags & SHADER_SKY)
// flags |= IF_SKY;
if (shader->flags & SHADER_NOMIPMAPS)
@ -562,7 +574,7 @@ static texid_t Shader_FindImage ( char *name, int flags )
if (!Q_stricmp (name, "_black"))
{
int wibuf[16] = {0};
return R_LoadTexture("$blackimage", 4, 4, TF_RGBA32, wibuf, IF_NOMIPMAP|IF_NOPICMIP|IF_NEAREST|IF_NOGAMMA);;
return R_LoadTexture("$blackimage", 4, 4, TF_RGBA32, wibuf, IF_NOMIPMAP|IF_NOPICMIP|IF_NEAREST|IF_NOGAMMA);
}
}
else
@ -776,7 +788,7 @@ static void Shader_EntityMergable ( shader_t *shader, shaderpass_t *pass, char *
shader->flags |= SHADER_ENTITY_MERGABLE;
}
static void Shader_ProgAutoFields(program_t *prog, char **cvarfnames);
static void Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cvartypes);
/*program text is already loaded, this function parses the 'header' of it to see which permutations it provides, and how many times we need to recompile it*/
static void Shader_LoadPermutations(char *name, program_t *prog, char *script, int qrtype, int ver)
{
@ -789,6 +801,7 @@ static void Shader_LoadPermutations(char *name, program_t *prog, char *script, i
"#define UPPER\n",
"#define OFFSETMAPPING\n",
"#define SKELETAL\n",
"#define FOG\n",
NULL
};
char *permutationdefines[sizeof(permutationname)/sizeof(permutationname[0])];
@ -796,10 +809,11 @@ static void Shader_LoadPermutations(char *name, program_t *prog, char *script, i
int p, n, pn;
char *end;
char *cvarfnames[64];
int cvarfcount = 0;
char *cvarnames[64];
int cvartypes[64];
int cvarcount = 0;
cvarfnames[cvarfcount] = NULL;
cvarnames[cvarcount] = NULL;
for(;;)
{
@ -813,9 +827,28 @@ static void Shader_LoadPermutations(char *name, program_t *prog, char *script, i
end = script;
while ((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') || *end == '_')
end++;
if (cvarfcount+1 != sizeof(cvarfnames)/sizeof(cvarfnames[0]))
cvarfnames[cvarfcount++] = script;
cvarfnames[cvarfcount] = NULL;
if (cvarcount+1 != sizeof(cvarnames)/sizeof(cvarnames[0]))
{
cvartypes[cvarcount] = SP_CVARF;
cvarnames[cvarcount++] = script;
cvarnames[cvarcount] = NULL;
}
script = end;
}
else if (!strncmp(script, "!!cvarv", 7))
{
script += 7;
while (*script == ' ' || *script == '\t')
script++;
end = script;
while ((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') || *end == '_')
end++;
if (cvarcount+1 != sizeof(cvarnames)/sizeof(cvarnames[0]))
{
cvartypes[cvarcount] = SP_CVAR3F;
cvarnames[cvarcount++] = script;
cvarnames[cvarcount] = NULL;
}
script = end;
}
else if (!strncmp(script, "!!permu", 7))
@ -890,7 +923,7 @@ static void Shader_LoadPermutations(char *name, program_t *prog, char *script, i
#endif
}
Shader_ProgAutoFields(prog, cvarfnames);
Shader_ProgAutoFields(prog, cvarnames, cvartypes);
}
typedef struct sgeneric_s
{
@ -991,6 +1024,63 @@ struct sbuiltin_s
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "defaultsprite",
"!!permu FOG\n"
"#include \"sys/fog.h\"\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"attribute vec4 v_colour;\n"
"varying vec2 tc;\n"
"varying vec4 vc;\n"
"void main ()\n"
"{\n"
" tc = v_texcoord;\n"
" vc = v_colour;\n"
" gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"in vec2 tc;\n"
"varying vec4 vc;\n"
"void main ()\n"
"{\n"
" gl_FragColor = fog4blend(texture2D(s_t0, tc) * vc);\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "defaultadditivesprite",
"!!permu FOG\n"
"#include \"sys/fog.h\"\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"attribute vec4 v_colour;\n"
"varying vec2 tc;\n"
"varying vec4 vc;\n"
"void main ()\n"
"{\n"
" tc = v_texcoord;\n"
" vc = v_colour;\n"
" gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"in vec2 tc;\n"
"varying vec4 vc;\n"
"void main ()\n"
"{\n"
" gl_FragColor = fog4additive(texture2D(s_t0, tc) * vc);\n"
"}\n"
"#endif\n"
},
/*draws a wall, with lightmap.*/
{QR_OPENGL/*ES*/, 100, "defaultwall",
"!!cvarf gl_overbright\n"
@ -1025,6 +1115,8 @@ struct sbuiltin_s
},
{QR_OPENGL, 110, "defaultwall",
"!!cvarf gl_overbright\n"
"!!permu FOG\n"
"#include \"sys/fog.h\"\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"attribute vec2 v_lmcoord;\n"
@ -1050,7 +1142,41 @@ struct sbuiltin_s
"void main ()\n"
"{\n"
" float scale = exp2(floor(clamp(cvar_gl_overbright, 0.0, 2.0)));\n"
" gl_FragColor = texture2D(s_t0, tc) * texture2D(s_t1, lm) * vec4(scale, scale, scale, 1);\n"
" gl_FragColor = fog4(texture2D(s_t0, tc) * texture2D(s_t1, lm) * vec4(scale, scale, scale, 1));\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "drawflat_wall",
"!!cvarf gl_overbright\n"
"!!cvarv r_floorcolor\n"
"!!cvarv r_wallcolor\n"
"!!permu FOG\n"
"#include \"sys/fog.h\"\n"
"varying vec4 col;\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec3 v_normal;\n"
"attribute vec2 v_lmcoord;\n"
"varying vec2 lm;\n"
"uniform vec3 cvar_r_wallcolor;\n"
"uniform vec3 cvar_r_floorcolor;\n"
"uniform float cvar_gl_overbright;\n"
"void main ()\n"
"{\n"
" float scale = exp2(floor(clamp(cvar_gl_overbright, 0.0, 2.0))) / 255.0;\n"
" col = scale * vec4((v_normal.z < 0.73)?cvar_r_wallcolor:cvar_r_floorcolor, 1.0);\n"
" lm = v_lmcoord;\n"
" gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n" /*tex_lightmap*/
"varying vec2 lm;\n"
"void main ()\n"
"{\n"
" gl_FragColor = fog4(col * texture2D(s_t0, lm));\n"
"}\n"
"#endif\n"
},
@ -1085,6 +1211,8 @@ struct sbuiltin_s
},
{QR_OPENGL, 110, "defaultwarp",
"!!cvarf r_wateralpha\n"
"!!permu FOG\n"
"#include \"sys/fog.h\"\n"
"varying vec2 tc;\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
@ -1107,7 +1235,7 @@ struct sbuiltin_s
" ntc.t = tc.t + sin(tc.s+e_time)*0.125;\n"
" vec3 ts = vec3(texture2D(s_t0, ntc));\n"
" gl_FragColor = vec4(ts, cvar_r_wateralpha);\n"
" gl_FragColor = fog4(vec4(ts, cvar_r_wateralpha));\n"
"}\n"
"#endif\n"
},
@ -1366,6 +1494,7 @@ struct sbuiltin_s
"!!permu LOWER\n"
"!!permu UPPER\n"
"!!permu SKELETAL\n"
"!!permu FOG\n"
"varying vec2 tc;\n"
"varying vec3 light;\n"
"#ifdef VERTEX_SHADER\n"
@ -1385,6 +1514,7 @@ struct sbuiltin_s
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"#include \"sys/fog.h\"\n"
"uniform sampler2D s_t0;\n" /*tex_diffuse*/
"#ifdef LOWER\n"
"uniform sampler2D s_t1;\n" /*tex_lower*/
@ -1416,14 +1546,13 @@ struct sbuiltin_s
" vec4 fb = texture2D(s_t3, tc);\n"
" col.rgb = mix(col.rgb, fb.rgb, fb.a);\n"
"#endif\n"
" gl_FragColor = col * e_colourident;\n"
" gl_FragColor = fog4(col * e_colourident);\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "lpp_depthnorm",
"!!permu BUMP\n"
"!!permu SKELETAL\n"
"varying vec2 pos;\n"
"varying vec3 norm, tang, bitang;\n"
"#if defined(BUMP)\n"
"varying vec2 tc;\n"
@ -1439,7 +1568,6 @@ struct sbuiltin_s
"#else\n"
"gl_Position = skeletaltransform_n(norm);\n"
"#endif\n"
"pos = gl_Position.zw;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
@ -1456,7 +1584,7 @@ struct sbuiltin_s
"#else\n"
"onorm = norm;\n"
"#endif\n"
"gl_FragColor = vec4(onorm.xyz, pos.x/pos.y);\n"
"gl_FragColor = vec4(onorm.xyz, gl_FragCoord.z / gl_FragCoord.w);\n"
"}\n"
"#endif\n"
},
@ -1569,6 +1697,35 @@ struct sbuiltin_s
"#endif\n"
},
{QR_OPENGL, 110, "colourtint",
"varying vec4 tf;\n"
"#ifdef VERTEX_SHADER\n"
"void main ()\n"
"{\n"
"gl_Position = tf = vec4(v_position.xy,-1.0, 1.0);\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"uniform sampler3D s_t1;\n"
"void main()\n"
"{\n"
"vec2 fc;\n"
"fc = tf.xy / tf.w;\n"
"vec3 raw = texture2D(s_t0, (1.0 + fc) / 2.0).rgb;\n"
//scale+bias the sample to not clamp out at the edges
"#define LUTSIZE 16.0\n"
"vec3 scale = vec3((LUTSIZE-1.0)/LUTSIZE);\n"
"vec3 bias = vec3(1.0/(2.0*LUTSIZE));\n"
"gl_FragColor = texture3D(s_t1, raw * scale + bias);\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "crepuscular_rays",
/*yoinked from http://fabiensanglard.net/lightScattering/index.php*/
"!!cvarf crep_decay\n"
@ -1586,10 +1743,10 @@ struct sbuiltin_s
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform float cvar_crep_decay;\n"
"uniform float cvar_crep_density;\n"
"uniform float cvar_crep_weight;\n"
"uniform float l_lightcolour;\n"
"const float crep_decay = 0.94;\n"
"const float crep_density = 0.5;\n"
"const float crep_weight = 0.2;\n"
"uniform vec3 l_lightcolour;\n"
"uniform vec3 l_lightscreen;\n"
"uniform sampler2D s_t0;\n"
"const int NUM_SAMPLES = 100;\n"
@ -1599,18 +1756,18 @@ struct sbuiltin_s
// "gl_FragColor = texture2D(s_t0, tc.st);\n"
"vec2 deltaTextCoord = vec2( tc.st - l_lightscreen.xy );\n"
"vec2 textCoo = tc.st;\n"
"deltaTextCoord *= 1.0 / float(NUM_SAMPLES) * cvar_crep_density;\n"
"deltaTextCoord *= 1.0 / float(NUM_SAMPLES) * crep_density;\n"
"float illuminationDecay = 1.0;\n"
"for(int i=0; i < NUM_SAMPLES ; i++)\n"
"{\n"
"textCoo -= deltaTextCoord;\n"
"vec4 sample = texture2D(s_t0, textCoo);\n"
"sample *= illuminationDecay * cvar_crep_weight;\n"
"sample *= illuminationDecay * crep_weight;\n"
"gl_FragColor += sample;\n"
"illuminationDecay *= cvar_crep_decay;\n"
"illuminationDecay *= crep_decay;\n"
"}\n"
"gl_FragColor *= l_lightcolour;\n"
"gl_FragColor *= vec4(l_lightcolour, 1.0);\n"
"}\n"
"#endif\n"
},
@ -1761,18 +1918,29 @@ struct sbuiltin_s
static sgeneric_t *sgenerics;
void Shader_UnloadGeneric(program_t *prog)
{
int p;
if (prog->refs == 1)
{
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL)
{
int p;
for (p = 0; p < PERMUTATIONS; p++)
{
if (prog->handle[p].glsl)
qglDeleteProgramObject_(prog->handle[p].glsl);
}
}
#endif
#ifdef D3DQUAKE
if (qrenderer == QR_DIRECT3D)
{
int p;
for (p = 0; p < PERMUTATIONS; p++)
{
// if (prog->handle[p].hlsl.vert || prog->handle[p].hlsl.frag)
// D3DShader_DeleteProgram(&prog->handle[p].hlsl);
}
}
#endif
free(prog);
}
@ -1938,6 +2106,7 @@ struct shader_field_names_s shader_field_names[] =
/*viewer properties*/
{"v_eyepos", SP_V_EYEPOS},
{"w_fog", SP_W_FOG},
/*ent properties*/
{"e_origin", SP_E_ORIGIN},
@ -1962,7 +2131,7 @@ struct shader_field_names_s shader_field_names[] =
{NULL}
};
static void Shader_ProgAutoFields(program_t *prog, char **cvarfnames)
static void Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cvartypes)
{
unsigned int i, p;
qboolean found;
@ -1978,15 +2147,18 @@ static void Shader_ProgAutoFields(program_t *prog, char **cvarfnames)
prog->nofixedcompat = true;
/*set cvar unirforms*/
for (i = 0; cvarfnames[i]; i++)
for (i = 0; cvarnames[i]; i++)
{
for (p = 0; cvarfnames[i][p] && (unsigned char)cvarfnames[i][p] > 32 && p < sizeof(tmpname)-1; p++)
tmpname[p] = cvarfnames[i][p];
for (p = 0; cvarnames[i][p] && (unsigned char)cvarnames[i][p] > 32 && p < sizeof(tmpname)-1; p++)
tmpname[p] = cvarnames[i][p];
tmpname[p] = 0;
cvar = Cvar_Get(tmpname, "0", CVAR_SHADERSYSTEM, "glsl cvars");
if (!cvar)
continue;
cvar->flags |= CVAR_SHADERSYSTEM;
prog->parm[prog->numparams].type = cvartypes[i];
prog->parm[prog->numparams].pval = cvar;
found = false;
for (p = 0; p < PERMUTATIONS; p++)
{
if (!prog->handle[p].glsl)
@ -1994,8 +2166,14 @@ static void Shader_ProgAutoFields(program_t *prog, char **cvarfnames)
GL_SelectProgram(prog->handle[p].glsl);
uniformloc = qglGetUniformLocationARB(prog->handle[p].glsl, va("cvar_%s", tmpname));
if (uniformloc != -1)
{
qglUniform1fARB(uniformloc, cvar->value);
found = true;
}
prog->parm[prog->numparams].handle[p] = uniformloc;
}
if (found)
prog->numparams++;
}
for (i = 0; shader_field_names[i].name; i++)
{
@ -2044,10 +2222,10 @@ static void Shader_ProgAutoFields(program_t *prog, char **cvarfnames)
prog->nofixedcompat = true;
/*set cvar uniforms*/
for (i = 0; cvarfnames[i]; i++)
for (i = 0; cvarnames[i]; i++)
{
for (p = 0; cvarfnames[i][p] && (unsigned char)cvarfnames[i][p] > 32 && p < sizeof(tmpname)-1; p++)
tmpname[p] = cvarfnames[i][p];
for (p = 0; cvarnames[i][p] && (unsigned char)cvarnames[i][p] > 32 && p < sizeof(tmpname)-1; p++)
tmpname[p] = cvarnames[i][p];
tmpname[p] = 0;
cvar = Cvar_FindVar(tmpname);
if (!cvar)
@ -2486,8 +2664,11 @@ static void Shaderpass_Map (shader_t *shader, shaderpass_t *pass, char **ptr)
token = Shader_ParseString (ptr);
if (!ShaderPass_MapGen(shader, pass, token))
{
pass->texgen = T_GEN_SINGLEMAP;
flags = Shader_SetImageFlags (shader);
flags = Shader_SetImageFlags (shader, &token);
if (flags & IF_3DMAP)
pass->texgen = T_GEN_3DMAP;
else
pass->texgen = T_GEN_SINGLEMAP;
pass->tcgen = TC_GEN_BASE;
pass->anim_frames[0] = Shader_FindImage (token, flags);
@ -2500,7 +2681,7 @@ static void Shaderpass_AnimMap (shader_t *shader, shaderpass_t *pass, char **ptr
char *token;
texid_t image;
flags = Shader_SetImageFlags (shader);
flags = Shader_SetImageFlags (shader, NULL);
pass->tcgen = TC_GEN_BASE;
pass->flags |= SHADER_PASS_ANIMMAP;
@ -2542,15 +2723,21 @@ static void Shaderpass_ClampMap (shader_t *shader, shaderpass_t *pass, char **pt
if (!ShaderPass_MapGen(shader, pass, token))
{
flags = Shader_SetImageFlags (shader);
flags = Shader_SetImageFlags (shader, &token);
pass->tcgen = TC_GEN_BASE;
pass->anim_frames[0] = Shader_FindImage (token, flags | IF_CLAMP);
pass->texgen = T_GEN_SINGLEMAP;
if (flags & IF_3DMAP)
pass->texgen = T_GEN_3DMAP;
else
pass->texgen = T_GEN_SINGLEMAP;
if (!TEXVALID(pass->anim_frames[0]))
{
pass->anim_frames[0] = missing_texture;
if (flags & (IF_3DMAP | IF_CUBEMAP))
pass->anim_frames[0] = r_nulltex;
else
pass->anim_frames[0] = missing_texture;
Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", shader->name, token);
}
}
@ -3096,10 +3283,12 @@ static void Shaderpass_TexGen(shader_t *shader, shaderpass_t *pass, char **ptr)
}
static void Shaderpass_CubeMap(shader_t *shader, shaderpass_t *pass, char **ptr)
{
char *token = Shader_ParseString(ptr);
if (pass->tcgen == TC_GEN_BASE)
pass->tcgen = TC_GEN_SKYBOX;
pass->texgen = T_GEN_SKYBOX;
pass->anim_frames[0] = r_nulltex;//Shader_FindImage(token, flags);
pass->texgen = T_GEN_CUBEMAP;
pass->anim_frames[0] = Shader_FindImage(token, IF_CUBEMAP);
if (!TEXVALID(pass->anim_frames[0]))
{
@ -3794,7 +3983,7 @@ void Shader_Finish (shader_t *s)
if (TEXVALID(s->defaulttextures.base))
s->flags &= ~SHADER_NOIMAGE;
if (!s->numpasses && s->sort != SHADER_SORT_PORTAL && !(s->flags & (SHADER_NODRAW|SHADER_SKY)) && !s->fog_dist)
if (!s->numpasses && s->sort != SHADER_SORT_PORTAL && !(s->flags & (SHADER_NODRAW|SHADER_SKY)) && !s->fog_dist && !s->prog)
{
pass = &s->passes[s->numpasses++];
pass = &s->passes[0];
@ -4143,6 +4332,7 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args)
if (!builtin && r_drawflat.value)
builtin = (
"{\n"
"program drawflat_wall\n"
"{\n"
"map $lightmap\n"
"tcgen lightmap\n"
@ -4151,59 +4341,62 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args)
"}\n"
);
#ifdef GLQUAKE
if (!builtin && r_lightprepass.ival)
if (qrenderer == QR_OPENGL)
{
builtin = (
"{\n"
"program lpp_wall\n"
if (!builtin && r_lightprepass.ival)
{
builtin = (
"{\n"
"map $sourcecolour\n"
"program lpp_wall\n"
"{\n"
"map $sourcecolour\n"
"}\n"
"{\n"
"map $diffuse\n"
"}\n"
"{\n"
"map $lightmap\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $deluxmap\n"
"}\n"
"{\n"
"map $fullbright\n"
"}\n"
"}\n"
);
}
if (!builtin && gl_config.arb_shader_objects)
{
builtin = (
"{\n"
"map $diffuse\n"
"program defaultwall\n"
/*"param texture 0 tex_diffuse\n"
"param texture 1 tex_lightmap\n"
"param texture 2 tex_normalmap\n"
"param texture 3 tex_deluxmap\n"
"param texture 4 tex_fullbright\n"*/
"{\n"
"map $diffuse\n"
"}\n"
"{\n"
"map $lightmap\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $deluxmap\n"
"}\n"
"{\n"
"map $fullbright\n"
"}\n"
"}\n"
"{\n"
"map $lightmap\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $deluxmap\n"
"}\n"
"{\n"
"map $fullbright\n"
"}\n"
"}\n"
);
}
if (!builtin && gl_config.arb_shader_objects && gl_config.nofixedfunc)
{
builtin = (
"{\n"
"program defaultwall\n"
/*"param texture 0 tex_diffuse\n"
"param texture 1 tex_lightmap\n"
"param texture 2 tex_normalmap\n"
"param texture 3 tex_deluxmap\n"
"param texture 4 tex_fullbright\n"*/
"{\n"
"map $diffuse\n"
"}\n"
"{\n"
"map $lightmap\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $deluxmap\n"
"}\n"
"{\n"
"map $fullbright\n"
"}\n"
"}\n"
);
);
}
}
#endif
if (!builtin)
@ -4619,9 +4812,9 @@ void Shader_DefaultSkin(char *shortname, shader_t *s, const void *args)
"{\n"
"if $lpp\n"
"[\n"
"program defaultskin\n"
"][\n"
"program lpp_skin\n"
"][\n"
"program defaultskin\n"
"]\n"
"{\n"
"map $diffuse\n"

View file

@ -882,7 +882,7 @@ static void SHM_ComposeVolume_Fan(vecV_t *points, int numpoints)
int i;
#define MAX_ARRAY_VERTS 65535
static int pointidx[MAX_ARRAY_VERTS];
static index_t pointidx[MAX_ARRAY_VERTS];
/*make sure there's space*/
newmax = (cv.numpoints+numpoints + inc)&~(inc-1);
@ -913,19 +913,19 @@ static void SHM_ComposeVolume_Fan(vecV_t *points, int numpoints)
{
cv.tris[cv.numtris].edge[0] = lastedge;
cv.tris[cv.numtris].edge[1] = SHM_ComposeVolume_FindEdge(pointidx[i-1], pointidx[i]);
lastedge = SHM_ComposeVolume_FindEdge(pointidx[i], pointidx[i-2]);
lastedge = SHM_ComposeVolume_FindEdge(pointidx[i], pointidx[0]);
cv.tris[cv.numtris].edge[2] = lastedge;
lastedge = -(lastedge+1);
cv.numtris++;
}
}
static void SHM_ComposeVolume_Soup(vecV_t *points, int numpoints, int *idx, int numidx)
static void SHM_ComposeVolume_Soup(vecV_t *points, int numpoints, index_t *idx, int numidx)
{
int newmax;
int i;
#define MAX_ARRAY_VERTS 65535
static int pointidx[MAX_ARRAY_VERTS];
static index_t pointidx[MAX_ARRAY_VERTS];
/*make sure there's space*/
newmax = (cv.numpoints+numpoints + inc)&~(inc-1);
@ -1024,9 +1024,9 @@ static void SHM_ComposeVolume_BruteForce(dlight_t *dl)
VectorNormalize(ext);
/*back face*/
sh_shmesh->verts[(i * 2) + 1][0] = cv.points[i][0] + ext[0] * dl->radius*2;
sh_shmesh->verts[(i * 2) + 1][1] = cv.points[i][1] + ext[1] * dl->radius*2;
sh_shmesh->verts[(i * 2) + 1][2] = cv.points[i][2] + ext[2] * dl->radius*2;
sh_shmesh->verts[(i * 2) + 1][0] = cv.points[i][0] + ext[0] * dl->radius;
sh_shmesh->verts[(i * 2) + 1][1] = cv.points[i][1] + ext[1] * dl->radius;
sh_shmesh->verts[(i * 2) + 1][2] = cv.points[i][2] + ext[2] * dl->radius;
}
sh_shmesh->numverts = i*2;
@ -1100,9 +1100,20 @@ static struct shadowmesh_s *SHM_BuildShadowMesh(dlight_t *dl, unsigned char *lvi
{
case fg_quake:
case fg_halflife:
SHM_BeginShadowMesh(dl, surfonly);
SHM_MarkLeavesQ1(dl, lvis);
SHM_RecursiveWorldNodeQ1_r(dl, cl.worldmodel->nodes);
if (!dl->die)
{
SHM_BeginShadowMesh(dl, true);
SHM_MarkLeavesQ1(dl, lvis);
SHM_RecursiveWorldNodeQ1_r(dl, cl.worldmodel->nodes);
if (!surfonly)
SHM_ComposeVolume_BruteForce(dl);
}
else
{
SHM_BeginShadowMesh(dl, surfonly);
SHM_MarkLeavesQ1(dl, lvis);
SHM_RecursiveWorldNodeQ1_r(dl, cl.worldmodel->nodes);
}
break;
#ifdef Q2BSPS
case fg_quake2:
@ -2111,13 +2122,17 @@ static void Sh_DrawBrushModelShadow(dlight_t *dl, entity_t *e)
v2 = surf->mesh->xyz_array[( v+1 )%surf->mesh->numvertexes];
//get positions of v3 and v4 based on the light position
v3[0] = ( v1[0]-lightorg[0] )*PROJECTION_DISTANCE;
v3[1] = ( v1[1]-lightorg[1] )*PROJECTION_DISTANCE;
v3[2] = ( v1[2]-lightorg[2] )*PROJECTION_DISTANCE;
v3[0] = ( v1[0]-lightorg[0] );
v3[1] = ( v1[1]-lightorg[1] );
v3[2] = ( v1[2]-lightorg[2] );
VectorNormalizeFast(v3);
VectorScale(v3, PROJECTION_DISTANCE, v3);
v4[0] = ( v2[0]-lightorg[0] )*PROJECTION_DISTANCE;
v4[1] = ( v2[1]-lightorg[1] )*PROJECTION_DISTANCE;
v4[2] = ( v2[2]-lightorg[2] )*PROJECTION_DISTANCE;
v4[0] = ( v2[0]-lightorg[0] );
v4[1] = ( v2[1]-lightorg[1] );
v4[2] = ( v2[2]-lightorg[2] );
VectorNormalizeFast(v4);
VectorScale(v4, PROJECTION_DISTANCE, v4);
//Now draw the quad from the two verts to the projected light
//verts
@ -2135,9 +2150,11 @@ static void Sh_DrawBrushModelShadow(dlight_t *dl, entity_t *e)
for (v = surf->mesh->numvertexes-1; v >=0; v--)
{
v1 = surf->mesh->xyz_array[v];
v3[0] = (v1[0]-lightorg[0])*PROJECTION_DISTANCE;
v3[1] = (v1[1]-lightorg[1])*PROJECTION_DISTANCE;
v3[2] = (v1[2]-lightorg[2])*PROJECTION_DISTANCE;
v3[0] = (v1[0]-lightorg[0]);
v3[1] = (v1[1]-lightorg[1]);
v3[2] = (v1[2]-lightorg[2]);
VectorNormalizeFast(v3);
VectorScale(v3, PROJECTION_DISTANCE, v3);
qglVertex3f(v1[0]+v3[0], v1[1]+v3[1], v1[2]+v3[2]);
}
@ -2472,7 +2489,7 @@ static void Sh_DrawShadowlessLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
leaf = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, dl->origin);
lvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, leaf, lvisb, sizeof(lvisb));
SHM_BuildShadowMesh(dl, lvis, vvis, false);
SHM_BuildShadowMesh(dl, lvis, vvis, true);
if (!Sh_VisOverlaps(lvis, vvis)) //The two viewing areas do not intersect.
{
@ -2595,6 +2612,42 @@ void Sh_DrawCrepuscularLight(dlight_t *dl, float *colours, batch_t **batches)
#endif
}
void Sh_PreGenerateLights(void)
{
unsigned int ignoreflags;
dlight_t *dl;
qboolean shadow;
int leaf;
qbyte *lvis;
qbyte lvisb[MAX_MAP_LEAFS/8];
int i;
ignoreflags = (r_shadow_realtime_world.value?LFLAG_REALTIMEMODE:LFLAG_NORMALMODE);
for (dl = cl_dlights+rtlights_first, i=rtlights_first; i<rtlights_max; i++, dl++)
{
if (!dl->radius)
continue; //dead
if (!(dl->flags & ignoreflags))
continue;
if (dl->flags & LFLAG_CREPUSCULAR)
continue;
else if (((!dl->die)?!r_shadow_realtime_world_shadows.ival:!r_shadow_realtime_dlight_shadows.ival) || dl->flags & LFLAG_NOSHADOWS)
shadow = false;
else if (dl->flags & LFLAG_SHADOWMAP)
shadow = false;
else
shadow = true;
leaf = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, dl->origin);
lvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, leaf, lvisb, sizeof(lvisb));
SHM_BuildShadowMesh(dl, lvis, NULL, !shadow);
}
}
void Sh_DrawLights(qbyte *vis, batch_t **mbatches)
{
vec3_t colour;

View file

@ -69,6 +69,7 @@ void (APIENTRY *qglTexEnvi) (GLenum target, GLenum pname, GLint param);
void (APIENTRY *qglTexGeni) (GLenum coord, GLenum pname, GLint param);
void (APIENTRY *qglTexGenfv) (GLenum coord, GLenum pname, const GLfloat *param);
void (APIENTRY *qglTexImage2D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void (APIENTRY *qglTexImage3D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void (APIENTRY *qglTexParameteri) (GLenum target, GLenum pname, GLint param);
void (APIENTRY *qglTexParameterf) (GLenum target, GLenum pname, GLfloat param);
void (APIENTRY *qglTexParameteriv) (GLenum target, GLenum pname, const GLint *params);
@ -757,6 +758,64 @@ static const char *glsl_hdrs[] =
"}\n"
"#endif\n"
,
"sys/fog.h",
"#ifdef FRAGMENT_SHADER\n"
"#ifdef FOG\n"
"uniform vec4 w_fog;\n"
"vec3 fog3(in vec3 regularcolour)"
"{"
"float z = gl_FragCoord.z / gl_FragCoord.w;\n"
"float fac = exp2(-("
"w_fog.w * w_fog.w * "
"z * z * "
"1.442695));\n"
"fac = clamp(fac, 0.0, 1.0);\n"
"return mix(w_fog.rgb, regularcolour, fac);\n"
"}\n"
"vec3 fog3additive(in vec3 regularcolour)"
"{"
"float z = gl_FragCoord.z / gl_FragCoord.w;\n"
"float fac = exp2(-("
"w_fog.w * w_fog.w * "
"z * z * "
"1.442695));\n"
"fac = clamp(fac, 0.0, 1.0);\n"
"return regularcolour * fac;\n"
"}\n"
"vec4 fog4(in vec4 regularcolour)"
"{"
"return vec4(fog3(regularcolour.rgb), 1.0) * regularcolour.a;\n"
"}\n"
"vec4 fog4additive(in vec4 regularcolour)"
"{"
"float z = gl_FragCoord.z / gl_FragCoord.w;\n"
"float fac = exp2(-("
"w_fog.w * w_fog.w * "
"z * z * "
"1.442695));\n"
"fac = clamp(fac, 0.0, 1.0);\n"
"return regularcolour * vec4(fac, fac, fac, 1.0);\n"
"}\n"
"vec4 fog4blend(in vec4 regularcolour)"
"{"
"float z = gl_FragCoord.z / gl_FragCoord.w;\n"
"float fac = exp2(-("
"w_fog.w * w_fog.w * "
"z * z * "
"1.442695));\n"
"fac = clamp(fac, 0.0, 1.0);\n"
"return regularcolour * vec4(1.0, 1.0, 1.0, fac);\n"
"}\n"
"#else\n"
/*don't use macros for this - mesa bugs out*/
"vec3 fog3(in vec3 regularcolour) { return regularcolour; }\n"
"vec3 fog3additive(in vec3 regularcolour) { return regularcolour; }\n"
"vec4 fog4(in vec4 regularcolour) { return regularcolour; }\n"
"vec4 fog4additive(in vec4 regularcolour) { return regularcolour; }\n"
"vec4 fog4blend(in vec4 regularcolour) { return regularcolour; }\n"
"#endif\n"
"#endif\n"
,
NULL
};
@ -1100,6 +1159,7 @@ void GL_Init(void *(*getglfunction) (char *name))
qglTexGeni = (void *)getglcore("glTexGeni");
qglTexGenfv = (void *)getglcore("glTexGenfv");
qglTexImage2D = (void *)getglcore("glTexImage2D");
qglTexImage3D = (void *)getglext("glTexImage3D");
qglTexParameteri = (void *)getglcore("glTexParameteri");
qglTexParameterf = (void *)getglcore("glTexParameterf");
qglTexParameteriv = (void *)getglcore("glTexParameteriv");

View file

@ -274,6 +274,7 @@ FTE_DEPRECATED void PPL_RevertToKnownState(void);
qboolean R_CullBox (vec3_t mins, vec3_t maxs);
qboolean R_CullEntityBox(entity_t *e, vec3_t modmins, vec3_t modmaxs);
qboolean R_CullSphere (vec3_t origin, float radius);
void Sh_PreGenerateLights(void);
#ifdef GLQUAKE
void R_TranslatePlayerSkin (int playernum);
@ -716,6 +717,7 @@ extern void (APIENTRY *qglTexGeni) (GLenum coord, GLenum pname, GLint param);
extern void (APIENTRY *qglTexGeniv) (GLenum coord, GLenum pname, const GLint *params);
extern void (APIENTRY *qglTexImage1D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
extern void (APIENTRY *qglTexImage2D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
extern void (APIENTRY *qglTexImage3D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
extern void (APIENTRY *qglTexParameterf) (GLenum target, GLenum pname, GLfloat param);
extern void (APIENTRY *qglTexParameterfv) (GLenum target, GLenum pname, const GLfloat *params);
extern void (APIENTRY *qglTexParameteri) (GLenum target, GLenum pname, GLint param);

View file

@ -226,7 +226,8 @@ typedef struct shaderpass_s {
T_GEN_SOURCECUBE, //used for render-to-texture targets
T_GEN_VIDEOMAP, //use the media playback as an image source, updating each frame for which it is visible
T_GEN_SKYBOX, //use a skybox instead, otherwise T_GEN_SINGLEMAP
T_GEN_CUBEMAP, //use a cubemap instead, otherwise like T_GEN_SINGLEMAP
T_GEN_3DMAP, //use a 3d texture instead, otherwise T_GEN_SINGLEMAP.
} texgen;
enum {
@ -258,8 +259,9 @@ enum{
PERMUTATION_UPPER = 16,
PERMUTATION_OFFSET = 32,
PERMUTATION_SKELETAL = 64,
PERMUTATION_FOG = 128,
PERMUTATIONS = 128
PERMUTATIONS = 256
};
typedef struct {
@ -291,6 +293,7 @@ typedef struct {
SP_E_L_AMBIENT,
SP_E_EYEPOS, /*viewer's eyepos, in model space*/
SP_V_EYEPOS, /*viewer's eyepos, in world space*/
SP_W_FOG,
SP_M_ENTBONES,
SP_M_VIEW,
@ -393,6 +396,7 @@ struct shader_s
SHADER_NODLIGHT = 1 << 15, //from surfaceflags
SHADER_HASLIGHTMAP = 1 << 16,
SHADER_HASTOPBOTTOM = 1 << 17,
SHADER_STATICDATA = 1 << 18 //set if true: no deforms, no tcgen, rgbgen=identitylighting, alphagen=identity, tmu0=st + tmu1=lm(if available) for every pass, no norms
} flags;
program_t *prog;
@ -502,6 +506,8 @@ void BE_PushOffsetShadow(qboolean foobar);
void BE_SetupForShadowMap(void);
//Called from shadowmapping code into backend
void BE_BaseEntTextures(void);
//prebuilds shadow volumes
void Sh_PreGenerateLights(void);
//Draws lights, called from the backend
void Sh_DrawLights(qbyte *vis, batch_t **mbatches);
void Sh_Shutdown(void);

View file

@ -146,7 +146,8 @@ void PRAddressableFlush(progfuncs_t *progfuncs, int totalammount)
VirtualFree(addressablehunk, 0, MEM_RELEASE); //doesn't this look complicated? :p
addressablehunk = NULL;
}
addressablehunk = VirtualAlloc (addressablehunk, totalammount, MEM_RESERVE, PAGE_NOACCESS);
if (!addressablehunk)
addressablehunk = VirtualAlloc (addressablehunk, totalammount, MEM_RESERVE, PAGE_NOACCESS);
#else
if (addressablehunk)
free(addressablehunk);

View file

@ -243,8 +243,15 @@ int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, s
{
if (field[i].type != type)
{
printf("Field type mismatch on \"%s\". %i != %i\n", name, field[i].type, type);
continue;
/*Hexen2/DP compat hack: if the new type is a float and the original type is a vector, make the new def alias to the engine's _x field
this 'works around' the unused .vector color field used for rtlight colours vs the .float color used for particle colours (the float initialisers in map files will expand into the x slot safely).
qc/hc can work around this by just using .vector color/color_x instead, which is the same as this hack, but would resolve defs to allow rtlight colours.
*/
if (field[i].type != ev_vector || type != ev_float)
{
printf("Field type mismatch on \"%s\". %i != %i\n", name, field[i].type, type);
continue;
}
}
if (!progfuncs->fieldadjust && engineofs>=0)
if ((unsigned)engineofs/4 != field[i].ofs)

View file

@ -26,7 +26,7 @@ const unsigned int type_size[12] = {1, //void
sizeof(func_t)/4,//function
1, //pointer (its an int index)
1, //integer
1, //fixme: how big should a variant be?
3, //fixme: how big should a variant be?
0, //ev_struct. variable sized.
0 //ev_union. variable sized.
};

View file

@ -3545,7 +3545,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
{
if (!strncmp(func->name,"precache_file", 13))
{
if (pr_token_type == tt_immediate && pr_immediate_type->type == ev_string)
if (pr_token_type == tt_immediate && pr_immediate_type->type == ev_string && pr_scope && !strcmp(pr_scope->name, "main"))
{
optres_precache_file += strlen(pr_immediate_string);
QCC_PR_Lex();

View file

@ -649,8 +649,8 @@ pbool QCC_WriteData (int crc)
if (compressoutput) progs.blockscompressed |=64; //line numbers
if (compressoutput) progs.blockscompressed |=128; //types
//include a type block?
types = debugtarget;//!!QCC_PR_CheckCompConstDefined("TYPES"); //useful for debugging and saving (maybe, anyway...).
if (sizeof(char *) != sizeof(string_t))
types = debugtarget;
if (types && sizeof(char *) != sizeof(string_t))
{
//qcc_typeinfo_t has a char* inside it, which changes size
printf("AMD64 builds cannot write typeinfo structures\n");

View file

@ -654,24 +654,41 @@ void NPP_NQFlush(void)
{
if (cl->state == cs_spawned && ISQWCLIENT(cl))
{
char *h2finale = NULL;
if (cl->zquake_extensions & Z_EXT_SERVERTIME)
{
ClientReliableCheckBlock(cl, 6);
ClientReliableWrite_Byte(cl, svc_updatestatlong);
ClientReliableWrite_Byte(cl, STAT_TIME);
ClientReliableWrite_Long(cl, (int)(sv.time * 1000));
cl->nextservertimeupdate = sv.time+10;
ClientReliableWrite_Long(cl, (int)(sv.world.physicstime * 1000));
cl->nextservertimeupdate = sv.world.physicstime+10;
}
ClientReliableCheckBlock(cl, 16);
ClientReliableWrite_Byte(cl, svc_intermission);
ClientReliableWrite_Coord(cl, cl->edict->v->origin[0]);
ClientReliableWrite_Coord(cl, cl->edict->v->origin[1]);
ClientReliableWrite_Coord(cl, cl->edict->v->origin[2]+cl->edict->v->view_ofs[2]);
ClientReliableWrite_Angle(cl, cl->edict->v->angles[0]);
ClientReliableWrite_Angle(cl, cl->edict->v->angles[1]);
ClientReliableWrite_Angle(cl, cl->edict->v->angles[2]);
if (progstype == PROG_H2)
{
/*hexen2 does something like this in the client, but we don't support those protocols, so translate to something usable*/
int lookup[13] = {394, 395, 356, 357, 358, 411, 386+6, 386+7, 386+8, 391, 538, 545, 561};
if (buffer[1] < 13)
h2finale = T_GetString(lookup[buffer[1]]);
}
if (h2finale)
{
ClientReliableCheckBlock(cl, 16);
ClientReliableWrite_Byte(cl, svc_finale);
ClientReliableWrite_String(cl, h2finale);
}
else
{
ClientReliableCheckBlock(cl, 16);
ClientReliableWrite_Byte(cl, svc_intermission);
ClientReliableWrite_Coord(cl, cl->edict->v->origin[0]);
ClientReliableWrite_Coord(cl, cl->edict->v->origin[1]);
ClientReliableWrite_Coord(cl, cl->edict->v->origin[2]+cl->edict->v->view_ofs[2]);
ClientReliableWrite_Angle(cl, cl->edict->v->angles[0]);
ClientReliableWrite_Angle(cl, cl->edict->v->angles[1]);
ClientReliableWrite_Angle(cl, cl->edict->v->angles[2]);
}
}
}
bufferlen = 0;
@ -1064,9 +1081,16 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
default:
protocollen = sizeof(buffer);
te_515sevilhackworkaround = true;
Con_Printf("NQWriteByte: bad tempentity %i\n", data);
PR_StackTrace(svprogfuncs);
if (dest == MSG_MULTICAST)
{
Con_DPrintf("NQWriteByte: unknown tempentity %i\n", data);
}
else
{
te_515sevilhackworkaround = true;
Con_Printf("NQWriteByte: unknown tempentity %i\n", data);
PR_StackTrace(svprogfuncs);
}
break;
}
break;
@ -1395,8 +1419,8 @@ void NPP_QWFlush(void)
ClientReliableCheckBlock(cl, 6);
ClientReliableWrite_Byte(cl, svc_updatestatlong);
ClientReliableWrite_Byte(cl, STAT_TIME);
ClientReliableWrite_Long(cl, (int)(sv.time * 1000));
cl->nextservertimeupdate = sv.time+10;
ClientReliableWrite_Long(cl, (int)(sv.world.physicstime * 1000));
cl->nextservertimeupdate = sv.world.physicstime+10;
}
ClientReliableCheckBlock(cl, 1);

View file

@ -66,6 +66,7 @@ cvar_t pr_no_parsecommand = CVARF("pr_no_parsecommand", "0", 0);
cvar_t pr_ssqc_progs = CVARAF("progs", "", "sv_progs", CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_NOTFROMSERVER);
cvar_t qc_nonetaccess = CVAR("qc_nonetaccess", "0"); //prevent write_... builtins from doing anything. This means we can run any mod, specific to any engine, on the condition that it also has a qw or nq crc.
cvar_t qc_netpreparse = CVAR("qc_netpreparse", "1"); //server-side writebyte protocol translation
cvar_t pr_overridebuiltins = CVAR("pr_overridebuiltins", "1");
@ -77,6 +78,8 @@ cvar_t pr_droptofloorunits = CVAR("pr_droptofloorunits", "");
cvar_t sv_gameplayfix_honest_tracelines = CVAR("sv_gameplayfix_honest_tracelines", "1");
cvar_t sv_gameplayfix_blowupfallenzombies = CVAR("sv_gameplayfix_blowupfallenzombies", "0");
cvar_t sv_gameplayfix_setmodelrealbox = CVAR("sv_gameplayfix_setmodelrealbox", "0");
cvar_t sv_gameplayfix_setmodelsize_qw = CVAR("sv_gameplayfix_setmodelsize_qw", "0");
cvar_t sv_addon[MAXADDONS];
char cvargroup_progs[] = "Progs variables";
@ -348,6 +351,9 @@ void PR_SV_FillWorldGlobals(world_t *w)
w->g.frametime = pr_global_ptrs->frametime;
w->g.newmis = pr_global_ptrs->newmis;
w->g.time = pr_global_ptrs->time;
w->g.v_forward = *pr_global_ptrs->v_forward;
w->g.v_right = *pr_global_ptrs->v_right;
w->g.v_up = *pr_global_ptrs->v_up;
}
void PR_SSQC_Relocated(progfuncs_t *pr, char *oldb, char *newb, int oldlen)
@ -454,10 +460,19 @@ int QCEditor (progfuncs_t *prinst, char *filename, int line, int nump, char **pa
model_t *SVPR_GetCModel(world_t *w, int modelindex)
{
if ((unsigned int)modelindex < MAX_MODELS)
{
if (!sv.models[modelindex] && sv.strings.model_precache[modelindex])
sv.models[modelindex] = Mod_ForName(sv.strings.model_precache[modelindex], false);
return sv.models[modelindex];
}
else
return NULL;
}
void SVPR_Get_FrameState(world_t *w, wedict_t *ent, framestate_t *fstate)
{
memset(fstate, 0, sizeof(*fstate));
fstate->g[FS_REG].frame[0] = ent->v->frame;
}
void SVPR_Event_Touch(world_t *w, wedict_t *s, wedict_t *o)
{
@ -524,6 +539,7 @@ void Q_SetProgsParms(qboolean forcompiler)
if (pr_ssqc_memsize.ival == -2)
svprogparms.addressablerelocated = PR_SSQC_Relocated;
svprogparms.user = &sv.world;
if (!svprogfuncs)
{
sv.world.progs = svprogfuncs = InitProgs(&svprogparms);
@ -532,6 +548,7 @@ void Q_SetProgsParms(qboolean forcompiler)
sv.world.Event_Think = SVPR_Event_Think;
sv.world.Event_Sound = SVQ1_StartSound;
sv.world.Get_CModel = SVPR_GetCModel;
sv.world.Get_FrameState = SVPR_Get_FrameState;
PRSV_ClearThreads();
PR_fclose_progs(svprogfuncs);
@ -1181,6 +1198,8 @@ void PR_Init(void)
Cvar_Register (&sv_gameplayfix_honest_tracelines, cvargroup_progs);
Cvar_Register (&sv_gameplayfix_blowupfallenzombies, cvargroup_progs);
Cvar_Register (&sv_gameplayfix_setmodelrealbox, cvargroup_progs);
Cvar_Register (&sv_gameplayfix_setmodelsize_qw, cvargroup_progs);
#ifdef SQL
SQL_Init();
@ -2192,7 +2211,7 @@ void PF_setmodel_Internal (progfuncs_t *prinst, edict_t *e, char *m)
else
#endif
m = sv.strings.model_precache[i] = PR_AddString(prinst, m, 0);
if (!strcmp(m + strlen(m) - 4, ".bsp"))
if (!strcmp(m + strlen(m) - 4, ".bsp")) //always precache bsps
sv.models[i] = Mod_FindName(m);
Con_Printf("WARNING: SV_ModelIndex: model %s not precached\n", m);
@ -2235,7 +2254,7 @@ void PF_setmodel_Internal (progfuncs_t *prinst, edict_t *e, char *m)
return;
}
if (progstype == PROG_H2)
/*if (progstype == PROG_H2)
{
e->v->mins[0] = 0;
e->v->mins[1] = 0;
@ -2247,15 +2266,18 @@ void PF_setmodel_Internal (progfuncs_t *prinst, edict_t *e, char *m)
VectorSubtract (e->v->maxs, e->v->mins, e->v->size);
}
else
else*/
{
if (progstype != PROG_QW)
if (sv_gameplayfix_setmodelrealbox.ival)
mod = SVPR_GetCModel(&sv.world, i);
else
mod = sv.models[i];
if (progstype != PROG_QW || sv_gameplayfix_setmodelsize_qw.ival)
{ //also sets size.
//nq dedicated servers load bsps and mdls
//qw dedicated servers only load bsps (better)
mod = sv.models[i];
if (mod)
{
mod = Mod_ForName (m, false);
@ -2285,16 +2307,12 @@ void PF_setmodel_Internal (progfuncs_t *prinst, edict_t *e, char *m)
}
else
{
if (sv.models[i])
if (mod && mod->type != mod_alias)
{
mod = Mod_ForName (m, false);
if (mod)
{
VectorCopy (mod->mins, e->v->mins);
VectorCopy (mod->maxs, e->v->maxs);
VectorSubtract (mod->maxs, mod->mins, e->v->size);
World_LinkEdict (&sv.world, (wedict_t*)e, false);
}
VectorCopy (mod->mins, e->v->mins);
VectorCopy (mod->maxs, e->v->maxs);
VectorSubtract (mod->maxs, mod->mins, e->v->size);
World_LinkEdict (&sv.world, (wedict_t*)e, false);
}
//qw was fixed - it never sets the size of an alias model, mostly because it doesn't know it.
}
@ -2328,7 +2346,7 @@ static void QCBUILTIN PF_frameforname (progfuncs_t *prinst, struct globalvars_s
{
unsigned int modelindex = G_FLOAT(OFS_PARM0);
char *str = PF_VarString(prinst, 1, pr_globals);
model_t *mod = (modelindex>= MAX_MODELS)?NULL:sv.models[modelindex];
model_t *mod = SVPR_GetCModel(&sv.world, modelindex);
if (mod && Mod_FrameForName)
G_FLOAT(OFS_RETURN) = Mod_FrameForName(mod, str);
@ -2345,9 +2363,7 @@ static void QCBUILTIN PF_frameduration (progfuncs_t *prinst, struct globalvars_s
G_FLOAT(OFS_RETURN) = 0;
else
{
mod = sv.models[modelindex];
if (!mod)
mod = sv.models[modelindex] = Mod_ForName(sv.strings.model_precache[modelindex], false);
mod = SVPR_GetCModel(&sv.world, modelindex);
if (mod && Mod_GetFrameDuration)
G_FLOAT(OFS_RETURN) = Mod_GetFrameDuration(mod, framenum);
@ -2360,7 +2376,7 @@ static void QCBUILTIN PF_skinforname (progfuncs_t *prinst, struct globalvars_s *
#ifndef SERVERONLY
unsigned int modelindex = G_FLOAT(OFS_PARM0);
char *str = PF_VarString(prinst, 1, pr_globals);
model_t *mod = (modelindex>= MAX_MODELS)?NULL:sv.models[modelindex];
model_t *mod = SVPR_GetCModel(&sv.world, modelindex);
if (mod && Mod_SkinForName)
@ -3523,7 +3539,12 @@ void PR_CheckEmptyString (char *s)
*/
static void QCBUILTIN PF_precache_file (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ // precache_file is only used to copy files with qcc, it does nothing
char *s = PR_GetStringOfs(prinst, OFS_PARM0);
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
/*touch the file, so any packs will be referenced. this is fte behaviour.*/
FS_FLocateFile(s, FSLFRT_IFFOUND, NULL);
}
void PF_precache_sound_Internal (progfuncs_t *prinst, char *s)
@ -3542,6 +3563,8 @@ void PF_precache_sound_Internal (progfuncs_t *prinst, char *s)
{
strcpy(sv.strings.sound_precache[i], s);
/*touch the file, so any packs will be referenced*/
FS_FLocateFile(s, FSLFRT_IFFOUND, NULL);
if (sv.state != ss_loading)
{
@ -3601,8 +3624,13 @@ int PF_precache_model_Internal (progfuncs_t *prinst, char *s, qboolean queryonly
#endif
sv.strings.model_precache[i] = PR_AddString(prinst, s, 0);
s = sv.strings.model_precache[i];
if (!strcmp(s + strlen(s) - 4, ".bsp"))
if (!strcmp(s + strlen(s) - 4, ".bsp") || sv_gameplayfix_setmodelrealbox.ival)
sv.models[i] = Mod_FindName(s);
else
{
/*touch the file, so any packs will be referenced*/
FS_FLocateFile(s, FSLFRT_IFFOUND, NULL);
}
if (sv.state != ss_loading)
{
@ -3775,12 +3803,6 @@ static void QCBUILTIN PF_walkmove (progfuncs_t *prinst, struct globalvars_s *pr_
pr_global_struct->self = oldself;
}
void PF_sv_touchtriggers(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
wedict_t *ent = (wedict_t*)PROG_TO_EDICT(prinst, pr_global_struct->self);
World_LinkEdict (&sv.world, ent, true);
}
/*
===============
PF_droptofloor
@ -4309,7 +4331,8 @@ client_t *Write_GetClient(void)
extern sizebuf_t csqcmsgbuffer;
void QCBUILTIN PF_WriteByte (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
if (G_FLOAT(OFS_PARM0) == MSG_CSQC)
int dest = G_FLOAT(OFS_PARM0);
if (dest == MSG_CSQC)
{ //csqc buffers are always written.
MSG_WriteByte(&csqcmsgbuffer, G_FLOAT(OFS_PARM1));
return;
@ -4325,17 +4348,18 @@ void QCBUILTIN PF_WriteByte (progfuncs_t *prinst, struct globalvars_s *pr_global
if (progstype == PROG_NQ || progstype == PROG_H2)
{
NPP_NQWriteByte(G_FLOAT(OFS_PARM0), (qbyte)G_FLOAT(OFS_PARM1));
NPP_NQWriteByte(dest, (qbyte)G_FLOAT(OFS_PARM1));
return;
}
#ifdef NQPROT
else
{
NPP_QWWriteByte(G_FLOAT(OFS_PARM0), (qbyte)G_FLOAT(OFS_PARM1));
NPP_QWWriteByte(dest, (qbyte)G_FLOAT(OFS_PARM1));
return;
}
#else
else if (G_FLOAT(OFS_PARM0) == MSG_ONE)
#endif
if (dest == MSG_ONE)
{
client_t *cl = Write_GetClient();
if (!cl)
@ -4345,7 +4369,6 @@ void QCBUILTIN PF_WriteByte (progfuncs_t *prinst, struct globalvars_s *pr_global
}
else
MSG_WriteByte (QWWriteDest(G_FLOAT(OFS_PARM0)), G_FLOAT(OFS_PARM1));
#endif
}
void QCBUILTIN PF_WriteChar (progfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -6477,12 +6500,13 @@ static void QCBUILTIN PF_h2matchAngleToSlope(progfuncs_t *prinst, struct globalv
vec3_t v_forward, old_forward, old_right, new_angles2 = { 0, 0, 0 };
float pitch, mod, dot;
// OFS_PARM0 is used by PF_vectoangles below
actor = G_EDICT(prinst, OFS_PARM1);
AngleVectors(actor->v->angles, old_forward, old_right, P_VEC(v_up));
PF_vectoangles(prinst, pr_globals);
VectorAngles(G_VECTOR(OFS_PARM0), NULL, G_VECTOR(OFS_RETURN));
pitch = G_FLOAT(OFS_RETURN) - 90;
@ -8095,9 +8119,7 @@ static void QCBUILTIN PF_ChangePic(progfuncs_t *prinst, struct globalvars_s *pr_
int SV_TagForName(int modelindex, char *tagname)
{
model_t *model = sv.models[modelindex];
if (!model)
model = Mod_ForName(sv.strings.model_precache[modelindex], false);
model_t *model = SVPR_GetCModel(&sv.world, modelindex);
if (!model)
return 0;
@ -8110,7 +8132,7 @@ static void QCBUILTIN PF_setattachment(progfuncs_t *prinst, struct globalvars_s
edict_t *tagentity = G_EDICT(prinst, OFS_PARM1);
char *tagname = PR_GetStringOfs(prinst, OFS_PARM2);
int modelindex;
model_t *model;
int tagidx;
@ -8118,115 +8140,21 @@ static void QCBUILTIN PF_setattachment(progfuncs_t *prinst, struct globalvars_s
if (tagentity != (edict_t*)sv.world.edicts && tagname && tagname[0])
{
modelindex = (int)tagentity->v->modelindex;
if (modelindex > 0 && modelindex < MAX_MODELS)
model = SVPR_GetCModel(&sv.world, tagentity->v->modelindex);
if (model)
{
if (!sv.models[modelindex])
sv.models[modelindex] = Mod_ForName(sv.strings.model_precache[modelindex], false);
if (sv.models[modelindex])
{
tagidx = SV_TagForName(modelindex, tagname);
if (tagidx == 0)
Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, tagentity), tagname, tagname, NUM_FOR_EDICT(prinst, tagentity), sv.models[modelindex]->name);
}
else
Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): Couldn't load model %s\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, tagentity), tagname, sv.strings.model_precache[modelindex]);
tagidx = Mod_TagNumForName(model, tagname);
if (tagidx == 0)
Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, tagentity), tagname, tagname, NUM_FOR_EDICT(prinst, tagentity), model->name);
}
else
Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, tagentity), tagname, tagname, NUM_FOR_EDICT(prinst, tagentity));
Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): Couldn't load model\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, tagentity), tagname);
}
e->xv->tag_entity = EDICT_TO_PROG(prinst,tagentity);
e->xv->tag_index = tagidx;
}
// #451 float(entity ent, string tagname) gettagindex (DP_MD3_TAGSINFO)
static void QCBUILTIN PF_gettagindex(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
edict_t *e = G_EDICT(prinst, OFS_PARM0);
char *tagname = PR_GetStringOfs(prinst, OFS_PARM1);
int modelindex;
int tagidx;
tagidx = 0;
if (tagname && tagname[0])
{
modelindex = (int)e->v->modelindex;
if (modelindex > 0 && modelindex < MAX_MODELS && sv.strings.model_precache[modelindex])
{
tagidx = SV_TagForName(modelindex, tagname);
if (tagidx == 0)
Con_DPrintf("PF_gettagindex(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, e), tagname, tagname, NUM_FOR_EDICT(prinst, e), sv.models[modelindex]->name);
}
else
Con_DPrintf("PF_gettagindex(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, e), tagname, tagname, NUM_FOR_EDICT(prinst, e));
}
G_FLOAT(OFS_RETURN) = tagidx;
}
static void EdictToTransform(edict_t *ed, float *trans)
{
AngleVectors(ed->v->angles, trans+0, trans+4, trans+8);
VectorInverse(trans+4);
trans[3] = ed->v->origin[0];
trans[7] = ed->v->origin[1];
trans[11] = ed->v->origin[2];
}
// #452 vector(entity ent, float tagindex) gettaginfo (DP_MD3_TAGSINFO)
static void QCBUILTIN PF_sv_gettaginfo(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
framestate_t fstate;
float transtag[12];
float transent[12];
float result[12];
edict_t *ent = G_EDICT(prinst, OFS_PARM0);
int tagnum = G_FLOAT(OFS_PARM1);
model_t *model = sv.models[(int)ent->v->modelindex];
float *origin = G_VECTOR(OFS_RETURN);
float *axis[3];
axis[0] = P_VEC(v_forward);
axis[1] = P_VEC(v_up);
axis[2] = P_VEC(v_right);
if (!model)
model = Mod_FindName(sv.strings.model_precache[(int)ent->v->modelindex]);
memset(&fstate, 0, sizeof(fstate));
fstate.g[FS_REG].frame[0] = fstate.g[FS_REG].frame[0] = ent->v->frame;
if (!Mod_GetTag(model, tagnum, &fstate, transtag))
{
return;
}
if (ent->xv->tag_entity)
{
#ifdef warningmsg
#pragma warningmsg("PF_sv_gettaginfo: This function doesn't honour attachments")
#endif
Con_Printf("PF_sv_gettaginfo doesn't support attachments\n");
}
EdictToTransform(ent, transent);
R_ConcatTransforms((void*)transent, (void*)transtag, (void*)result);
origin[0] = result[3];
origin[1] = result[7];
origin[2] = result[11];
VectorCopy((result+0), axis[0]);
VectorCopy((result+4), axis[1]);
VectorCopy((result+8), axis[2]);
}
//the first implementation of this function was (float type, float num, string name)
//it is now float num, float type, .field
//EXT_CSQC_1
@ -8474,219 +8402,6 @@ qboolean SV_RunFullQCMovement(client_t *client, usercmd_t *ucmd)
return false;
}
//DP_QC_GETSURFACE
// #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
static void QCBUILTIN PF_getsurfacenumpoints(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
unsigned int surfnum;
model_t *model;
int modelindex;
edict_t *ent;
ent = G_EDICT(prinst, OFS_PARM0);
surfnum = G_FLOAT(OFS_PARM1);
modelindex = ent->v->modelindex;
if (modelindex > 0 && modelindex < MAX_MODELS)
model = sv.models[(int)ent->v->modelindex];
else
model = NULL;
if (!model || model->type != mod_brush || surfnum >= model->nummodelsurfaces)
G_FLOAT(OFS_RETURN) = 0;
else
{
surfnum += model->firstmodelsurface;
G_FLOAT(OFS_RETURN) = model->surfaces[surfnum].mesh->numvertexes;
}
}
// #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
static void QCBUILTIN PF_getsurfacepoint(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
unsigned int surfnum, pointnum;
model_t *model;
int modelindex;
edict_t *ent;
ent = G_EDICT(prinst, OFS_PARM0);
surfnum = G_FLOAT(OFS_PARM1);
pointnum = G_FLOAT(OFS_PARM2);
modelindex = ent->v->modelindex;
if (modelindex > 0 && modelindex < MAX_MODELS)
model = sv.models[(int)ent->v->modelindex];
else
model = NULL;
if (!model || model->type != mod_brush || surfnum >= model->nummodelsurfaces)
{
G_FLOAT(OFS_RETURN+0) = 0;
G_FLOAT(OFS_RETURN+1) = 0;
G_FLOAT(OFS_RETURN+2) = 0;
}
else
{
surfnum += model->firstmodelsurface;
G_FLOAT(OFS_RETURN+0) = model->surfaces[surfnum].mesh->xyz_array[pointnum][0];
G_FLOAT(OFS_RETURN+1) = model->surfaces[surfnum].mesh->xyz_array[pointnum][1];
G_FLOAT(OFS_RETURN+2) = model->surfaces[surfnum].mesh->xyz_array[pointnum][2];
}
}
// #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
static void QCBUILTIN PF_getsurfacenormal(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
unsigned int surfnum, pointnum;
model_t *model;
int modelindex;
edict_t *ent;
ent = G_EDICT(prinst, OFS_PARM0);
surfnum = G_FLOAT(OFS_PARM1);
pointnum = G_FLOAT(OFS_PARM2);
modelindex = ent->v->modelindex;
if (modelindex > 0 && modelindex < MAX_MODELS)
model = sv.models[(int)ent->v->modelindex];
else
model = NULL;
if (!model || model->type != mod_brush || surfnum >= model->nummodelsurfaces)
{
G_FLOAT(OFS_RETURN+0) = 0;
G_FLOAT(OFS_RETURN+1) = 0;
G_FLOAT(OFS_RETURN+2) = 0;
}
else
{
surfnum += model->firstmodelsurface;
G_FLOAT(OFS_RETURN+0) = model->surfaces[surfnum].plane->normal[0];
G_FLOAT(OFS_RETURN+1) = model->surfaces[surfnum].plane->normal[1];
G_FLOAT(OFS_RETURN+2) = model->surfaces[surfnum].plane->normal[2];
if (model->surfaces[surfnum].flags & SURF_PLANEBACK)
VectorInverse(G_VECTOR(OFS_RETURN));
}
}
// #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
void PF_getsurfacetexture(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
model_t *model;
edict_t *ent;
msurface_t *surf;
int modelindex;
int surfnum;
ent = G_EDICT(prinst, OFS_PARM0);
surfnum = G_FLOAT(OFS_PARM1);
modelindex = ent->v->modelindex;
if (modelindex > 0 && modelindex < MAX_MODELS)
model = sv.models[(int)ent->v->modelindex];
else
model = NULL;
G_INT(OFS_RETURN) = 0;
if (!model || model->type != mod_brush)
return;
if (surfnum < 0 || surfnum > model->nummodelsurfaces)
return;
surfnum += model->firstmodelsurface;
surf = &model->surfaces[surfnum];
G_INT(OFS_RETURN) = PR_TempString(prinst, surf->texinfo->texture->name);
}
// #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
static void QCBUILTIN PF_getsurfacenearpoint(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
model_t *model;
edict_t *ent;
msurface_t *surf;
int i;
float planedist;
float *point;
int modelindex;
vec3_t edgedir;
vec3_t edgenormal;
vec3_t cpoint, temp;
mvertex_t *v1, *v2;
int edge;
int e;
float bestdist = 10000000000000, dist;
int bestsurf = -1;
ent = G_EDICT(prinst, OFS_PARM0);
point = G_VECTOR(OFS_PARM1);
G_FLOAT(OFS_RETURN) = -1;
modelindex = ent->v->modelindex;
if (modelindex > 0 && modelindex < MAX_MODELS)
model = sv.models[(int)ent->v->modelindex];
else
model = NULL;
if (!model || model->type != mod_brush)
return;
if (model->fromgame != fg_quake)
return;
surf = model->surfaces + model->firstmodelsurface;
for (i = 0; i < model->nummodelsurfaces; i++, surf++)
{
planedist = DotProduct(point, surf->plane->normal) - surf->plane->dist;
//don't care about SURF_PLANEBACK, the maths works out the same.
if (planedist*planedist < bestdist)
{ //within a specific range
//make sure it's within the poly
VectorMA(point, planedist, surf->plane->normal, cpoint);
for (e = surf->firstedge+surf->numedges; e > surf->firstedge; edge++)
{
edge = model->surfedges[--e];
if (edge < 0)
{
v1 = &model->vertexes[model->edges[-edge].v[0]];
v2 = &model->vertexes[model->edges[-edge].v[1]];
}
else
{
v2 = &model->vertexes[model->edges[edge].v[0]];
v1 = &model->vertexes[model->edges[edge].v[1]];
}
VectorSubtract(v1->position, v2->position, edgedir);
CrossProduct(edgedir, surf->plane->normal, edgenormal);
if (!(surf->flags & SURF_PLANEBACK))
{
VectorNegate(edgenormal, edgenormal);
}
VectorNormalize(edgenormal);
dist = DotProduct(v1->position, edgenormal) - DotProduct(cpoint, edgenormal);
if (dist < 0)
VectorMA(cpoint, dist, edgenormal, cpoint);
}
VectorSubtract(cpoint, point, temp);
dist = DotProduct(temp, temp);
if (dist < bestdist)
{
bestsurf = i;
bestdist = dist;
}
}
}
G_FLOAT(OFS_RETURN) = bestsurf;
}
// #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
static void QCBUILTIN PF_getsurfaceclippedpoint(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
}
qbyte qcpvs[(MAX_MAP_LEAFS+7)/8];
//#240 float(vector viewpos, entity viewee) checkpvs (FTE_QC_CHECKPVS)
//note: this requires a correctly setorigined entity.
@ -8746,24 +8461,13 @@ static void QCBUILTIN PF_SendPacket(progfuncs_t *prinst, struct globalvars_s *pr
NET_SendPacket(NS_SERVER, strlen(contents), contents, to);
}
static void QCBUILTIN PF_sv_terrain_edit(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int action = G_FLOAT(OFS_PARM0);
float *pos = G_VECTOR(OFS_PARM1);
float radius = G_FLOAT(OFS_PARM2);
float quant = G_FLOAT(OFS_PARM3);
#if defined(TERRAIN)
G_FLOAT(OFS_RETURN) = Heightmap_Edit(sv.world.worldmodel, action, pos, radius, quant);
#else
G_FLOAT(OFS_RETURN) = false;
#endif
}
#define STUB ,true
#ifdef DEBUG
#define NYI ,true
#else
#define NYI ,false
#else
#define NYI ,true
#endif
BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"fixme", PF_Fixme, 0, 0, 0, 0, "void()"},
@ -8825,7 +8529,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"changeyaw", PF_changeyaw, 49, 49, 49, 0, "#define ChangeYaw changeyaw\nvoid()"},
// {"qtest_precacheitem", NULL, 50}, // defined QTest builtin that is never called
{"vhlen", PF_vhlen, 0, 0, 50, 0, "float(vector)"},
{"vectoangles", PF_vectoangles, 51, 51, 51, 0, "vector(vector fwd)"},
{"vectoangles", PF_vectoangles, 51, 51, 51, 0, "vector(vector fwd, optional vector up)"},
{"WriteByte", PF_WriteByte, 52, 52, 52, 0, "void(float to, float val)"}, //52
{"WriteChar", PF_WriteChar, 53, 53, 53, 0, "void(float to, float val)"}, //53
@ -8915,7 +8619,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"infokey", PF_infokey, 0, 80, 0, 80, "string(entity e, string key)"}, //80
{"stof", PF_stof, 0, 81, 0, 81, "float(string)"}, //81
{"multicast", PF_multicast, 0, 82, 0, 0, "void(vector where, float set)"}, //82
{"multicast", PF_multicast, 0, 82, 0, 82, "void(vector where, float set)"}, //82
@ -9078,7 +8782,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"rotatevectorsbyangle", PF_Fixme, 0, 0, 0, 235, "void(vector angle)"}, // #235
{"rotatevectorsbyvectors", PF_Fixme, 0, 0, 0, 236, "void(vector fwd, vector right, vector up)"}, // #236
{"skinforname", PF_skinforname, 0, 0, 0, 237, "float(float mdlindex, string skinname)"}, // #237
{"shaderforname", PF_Fixme, 0, 0, 0, 238, "float(string shadername, optional string defaultshader)"},
{"shaderforname", PF_Fixme, 0, 0, 0, 238, "float(string shadername, optional string defaultshader, ...)"},
{"te_bloodqw", PF_te_bloodqw, 0, 0, 0, 239, "void(vector org, optional float count)"},
{"checkpvs", PF_checkpvs, 0, 0, 0, 240, "float(vector viewpos, entity entity)"},
@ -9121,11 +8825,14 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"frameforname", PF_frameforname, 0, 0, 0, 276, "void(float modidx, string framename)"},// (FTE_CSQC_SKELETONOBJECTS)
{"frameduration", PF_frameduration, 0, 0, 0, 277, "float(float modidx, float framenum)"},// (FTE_CSQC_SKELETONOBJECTS)
{"terrain_edit", PF_sv_terrain_edit, 0, 0, 0, 278, "void(float action, vector pos, float radius, float quant)"},// (??FTE_TERRAIN_EDIT??
{"touchtriggers", PF_sv_touchtriggers,0, 0, 0, 279, "void()"},//
{"terrain_edit", PF_terrain_edit, 0, 0, 0, 278, "void(float action, vector pos, float radius, float quant)"},// (??FTE_TERRAIN_EDIT??
{"touchtriggers", PF_touchtriggers, 0, 0, 0, 279, "void()"},//
{"writefloat", PF_WriteFloat, 0, 0, 0, 280, "void(float buf, float fl)"},//
{"skel_ragupdate", PF_skel_ragedit, 0, 0, 0, 281, "float(float skel, string dollname, float parentskel, vector trans, vector fwd, vector rt, vector up)" NYI}, // (FTE_CSQC_RAGDOLL)
{"skel_mmap", PF_skel_mmap, 0, 0, 0, 282, "float*(float skel)"},// (FTE_QC_RAGDOLL)
{"skel_set_bone_world",PF_skel_set_bone_world,0,0, 0, 283, "void(entity ent, float bonenum, vector org, optional vector angorfwd, optional vector right, optional vector up)"},
// {"cvar_setlatch", PF_cvar_setlatch, 0, 0, 0, 284, "void(string cvarname, optional string value)"}, //72
{"clearscene", PF_Fixme, 0, 0, 0, 300, "void()"},// (EXT_CSQC)
@ -9186,7 +8893,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"stringtokeynum", PF_Fixme, 0, 0, 0, 341, "float(string keyname)"},// (EXT_CSQC)
{"getkeybind", PF_Fixme, 0, 0, 0, 342, "string(float keynum)"},// (EXT_CSQC)
{"getmousepos", PF_Fixme, 0, 0, 0, 344, "", true}, // #344 This is a DP extension
{"getmousepos", PF_Fixme, 0, 0, 0, 344, "vector()"}, // #344 This is a DP extension
{"getinputstate", PF_Fixme, 0, 0, 0, 345, "float(float framenum)"},// (EXT_CSQC)
{"setsensitivityscaler",PF_Fixme,0, 0, 0, 346, "void(float sens)"},// (EXT_CSQC)
@ -9286,7 +8993,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"getsurfacenormal",PF_getsurfacenormal,0, 0, 0, 436, "vector(entity e, float s)"},// (DP_QC_GETSURFACE)
{"getsurfacetexture",PF_getsurfacetexture,0, 0, 0, 437, "string(entity e, float s)"},// (DP_QC_GETSURFACE)
{"getsurfacenearpoint",PF_getsurfacenearpoint,0,0, 0, 438, "float(entity e, vector p)"},// (DP_QC_GETSURFACE)
{"getsurfaceclippedpoint",PF_getsurfaceclippedpoint,0,0,0, 439, "vector(entity e, float s, vector p)"},// (DP_QC_GETSURFACE)
{"getsurfaceclippedpoint",PF_getsurfaceclippedpoint,0,0,0, 439, "vector(entity e, float s, vector p)" STUB},// (DP_QC_GETSURFACE)
//KRIMZON_SV_PARSECLIENTCOMMAND
{"clientcommand", PF_clientcommand, 0, 0, 0, 440, "void(entity e, string s)"},// (KRIMZON_SV_PARSECLIENTCOMMAND)
@ -9309,7 +9016,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"findchainflags", PF_sv_findchainflags,0, 0, 0, 450, "entity(.float fld, float match)"},//
//DP_MD3_TAGSINFO
{"gettagindex", PF_gettagindex, 0, 0, 0, 451, "float(entity ent, string tagname)"},// (DP_MD3_TAGSINFO)
{"gettaginfo", PF_sv_gettaginfo, 0, 0, 0, 452, "vector(entity ent, float tagindex)"},// (DP_MD3_TAGSINFO)
{"gettaginfo", PF_gettaginfo, 0, 0, 0, 452, "vector(entity ent, float tagindex)"},// (DP_MD3_TAGSINFO)
//DP_SV_BOTCLIENT
{"dropclient", PF_dropclient, 0, 0, 0, 453, "void(entity player)"},//DP_SV_BOTCLIENT
@ -9423,12 +9130,39 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"buf_cvarlist", PF_buf_cvarlist, 0, 0, 0, 517, "void(float strbuf)" STUB},
{"cvar_description",PF_cvar_description,0, 0, 0, 518, "string(string cvarname)"},
{"gettime", PF_Fixme, 0, 0, 0, 519, "float(optional float timetype)"},
//end dp extras
// {"loadfromdata", VM_loadfromdata, 0, 0, 0, 529, "??" STUB},
// {"loadfromfile", VM_loadfromfile, 0, 0, 0, 530, "??" STUB},
// {"setpause", VM_SV_setpause, 0, 0, 0, 531, "void(float pause)" STUB},
//end dp extras
{"precache_vwep_model",PF_precache_vwep_model,0,0, 0, 532, "float(string mname)"},
//restart dp extras
// {"log", VM_Fixme, 0, 0, 0, 532, "float(string mname)", true},
// {"getsoundtime", VM_getsoundtime, 0, 0, 0, 533, "float(entity e, float channel)" STUB},
// {"soundlength", VM_soundlength, 0, 0, 0, 534, "float(string sample)" STUB},
{"physics_enable", PF_Ignore, 0, 0, 0, 540, "void(entity e, float physics_enabled)" STUB},
{"physics_addforce",PF_Ignore, 0, 0, 0, 541, "void(entity e, vector force, vector relative_ofs)" STUB},
{"physics_addtorque",PF_Ignore, 0, 0, 0, 542, "void(entity e, vector torque)" STUB},
//VM_callfunction, // #605
//VM_writetofile, // #606
//VM_isfunction, // #607
//VM_parseentitydata, // #613
//VM_SV_getextresponse, // #624 string getextresponse(void)
{"sprintf", PF_sprintf, 0, 0, 0, 627, "string(...)" STUB},
// {"getsurfacenumpoints",VM_getsurfacenumtriangles,0,0, 0, 628, "float(entity e, float s)" STUB},
// {"getsurfacepoint",VM_getsurfacenumtriangles,0,0, 0, 629, "vector(entity e, float s, float n)" STUB},
//VM_digest_hex, // #639
//end dp extras
{"getrmqeffectsversion", PF_Ignore, 0, 0, 0, 666, "float()" STUB},
//don't exceed sizeof(pr_builtin)/sizeof(pr_builtin[0]) (currently 1024) without modifing the size of pr_builtin
{NULL}
@ -9702,7 +9436,7 @@ void PR_RegisterFields(void) //it's just easier to do it this way.
#define comfieldfloat(name) PR_RegisterFieldVar(svprogfuncs, ev_float, #name, (size_t)&((stdentvars_t*)0)->name, -1);
#define comfieldvector(name) PR_RegisterFieldVar(svprogfuncs, ev_vector, #name, (size_t)&((stdentvars_t*)0)->name, -1);
#define comfieldentity(name) PR_RegisterFieldVar(svprogfuncs, ev_entity, #name, (size_t)&((stdentvars_t*)0)->name, -1);
#define comfieldstring(name) PR_RegisterFieldVar(svprogfuncs, ev_string, #name, (size_t)&((stdentvars_t*)0)->name, -1);
#define comfieldstring(name) PR_RegisterFieldVar(svprogfuncs, ev_string, (((size_t)&((stdentvars_t*)0)->name==(size_t)&((stdentvars_t*)0)->message)?"_"#name:#name), (size_t)&((stdentvars_t*)0)->name, -1);
#define comfieldfunction(name, typestr) PR_RegisterFieldVar(svprogfuncs, ev_function, #name, (size_t)&((stdentvars_t*)0)->name, -1);
comqcfields
#undef comfieldfloat
@ -9767,6 +9501,7 @@ void PR_DumpPlatform_f(void)
int d = 0, nd;
vfsfile_t *f;
char *fname = "";
char dbgfname[MAX_OSPATH];
unsigned int targ = 0;
qboolean defines = false;
@ -9941,6 +9676,41 @@ void PR_DumpPlatform_f(void)
{"TRUE", "const float", QW|NQ|CS, 1},
{"FALSE", "const float", QW|NQ|CS, 0},
{"MOVETYPE_NONE", "const float", QW|NQ|CS, MOVETYPE_NONE},
{"MOVETYPE_WALK", "const float", QW|NQ|CS, MOVETYPE_WALK},
{"MOVETYPE_STEP", "const float", QW|NQ|CS, MOVETYPE_STEP},
{"MOVETYPE_FLY", "const float", QW|NQ|CS, MOVETYPE_FLY},
{"MOVETYPE_TOSS", "const float", QW|NQ|CS, MOVETYPE_TOSS},
{"MOVETYPE_PUSH", "const float", QW|NQ|CS, MOVETYPE_PUSH},
{"MOVETYPE_NOCLIP", "const float", QW|NQ|CS, MOVETYPE_NOCLIP},
{"MOVETYPE_FLYMISSILE", "const float", QW|NQ|CS, MOVETYPE_FLYMISSILE},
{"MOVETYPE_BOUNCE", "const float", QW|NQ|CS, MOVETYPE_BOUNCE},
{"MOVETYPE_BOUNCEMISSILE", "const float", QW|NQ|CS, MOVETYPE_BOUNCEMISSILE},
{"MOVETYPE_FOLLOW", "const float", QW|NQ|CS, MOVETYPE_FOLLOW},
{"MOVETYPE_PHYSICS", "const float", QW|NQ|CS, MOVETYPE_PHYSICS},
{"SOLID_NOT", "const float", QW|NQ|CS, SOLID_NOT},
{"SOLID_TRIGGER", "const float", QW|NQ|CS, SOLID_TRIGGER},
{"SOLID_BBOX", "const float", QW|NQ|CS, SOLID_BBOX},
{"SOLID_SLIDEBOX", "const float", QW|NQ|CS, SOLID_SLIDEBOX},
{"SOLID_BSP", "const float", QW|NQ|CS, SOLID_BSP},
{"SOLID_CORPSE", "const float", QW|NQ|CS, SOLID_CORPSE},
{"SOLID_LADDER", "const float", QW|NQ|CS, SOLID_LADDER},
{"SOLID_PHYSICS_BOX", "const float", QW|NQ|CS, SOLID_PHYSICS_BOX},
{"SOLID_PHYSICS_SPHERE", "const float", QW|NQ|CS, SOLID_PHYSICS_SPHERE},
{"SOLID_PHYSICS_CAPSULE", "const float", QW|NQ|CS, SOLID_PHYSICS_CAPSULE},
{"JOINTTYPE_FIXED", "const float", QW|NQ|CS, JOINTTYPE_FIXED},
{"JOINTTYPE_POINT", "const float", QW|NQ|CS, JOINTTYPE_POINT},
{"JOINTTYPE_HINGE", "const float", QW|NQ|CS, JOINTTYPE_HINGE},
{"JOINTTYPE_SLIDER", "const float", QW|NQ|CS, JOINTTYPE_SLIDER},
{"JOINTTYPE_UNIVERSAL", "const float", QW|NQ|CS, JOINTTYPE_UNIVERSAL},
{"JOINTTYPE_HINGE2", "const float", QW|NQ|CS, JOINTTYPE_HINGE2},
{"DAMAGE_NO", "const float", QW|NQ, DAMAGE_NO},
{"DAMAGE_YES", "const float", QW|NQ, DAMAGE_YES},
{"DAMAGE_AIM", "const float", QW|NQ, DAMAGE_AIM},
{"CONTENT_EMPTY", "const float", QW|NQ|CS, Q1CONTENTS_EMPTY},
{"CONTENT_SOLID", "const float", QW|NQ|CS, Q1CONTENTS_SOLID},
{"CONTENT_WATER", "const float", QW|NQ|CS, Q1CONTENTS_WATER},
@ -9959,6 +9729,51 @@ void PR_DumpPlatform_f(void)
// {"ATTN_IDLE", "const float", QW|NQ|CS, ATTN_IDLE},
// {"ATTN_STATIC", "const float", QW|NQ|CS, ATTN_STATIC},
{"MSG_BROADCAST", "const float", QW|NQ, MSG_BROADCAST},
{"MSG_ONE", "const float", QW|NQ, MSG_ONE},
{"MSG_ALL", "const float", QW|NQ, MSG_ALL},
{"MSG_INIT", "const float", QW|NQ, MSG_INIT},
{"MSG_MULTICAST", "const float", QW|NQ, MSG_MULTICAST},
{"MSG_ENTITY", "const float", QW|NQ, MSG_CSQC},
{"MULTICAST_ALL", "const float", QW|NQ, MULTICAST_ALL},
{"MULTICAST_PHS", "const float", QW|NQ, MULTICAST_PHS},
{"MULTICAST_PVS", "const float", QW|NQ, MULTICAST_PVS},
{"MULTICAST_ONE", "const float", QW|NQ, MULTICAST_ONE},
{"MULTICAST_ALL_R", "const float", QW|NQ, MULTICAST_ALL_R},
{"MULTICAST_PHS_R", "const float", QW|NQ, MULTICAST_PHS_R},
{"MULTICAST_PVS_R", "const float", QW|NQ, MULTICAST_PVS_R},
{"MULTICAST_ONE_R", "const float", QW|NQ, MULTICAST_ONE_R},
{"PRINT_LOW", "const float", QW, PRINT_LOW},
{"PRINT_MEDIUM", "const float", QW, PRINT_MEDIUM},
{"PRINT_HIGH", "const float", QW, PRINT_HIGH},
{"PRINT_CHAT", "const float", QW, PRINT_CHAT},
// edict.flags
{"FL_FLY", "const float", QW|NQ|CS, FL_FLY},
{"FL_SWIM", "const float", QW|NQ|CS, FL_SWIM},
{"FL_CLIENT", "const float", QW|NQ|CS, FL_CLIENT},
{"FL_INWATER", "const float", QW|NQ|CS, FL_INWATER},
{"FL_MONSTER", "const float", QW|NQ|CS, FL_MONSTER},
{"FL_GODMODE", "const float", QW|NQ, FL_GODMODE},
{"FL_NOTARGET", "const float", QW|NQ, FL_NOTARGET},
{"FL_ITEM", "const float", QW|NQ|CS, FL_ITEM},
{"FL_ONGROUND", "const float", QW|NQ|CS, FL_ONGROUND},
{"FL_PARTIALGROUND", "const float", QW|NQ|CS, FL_PARTIALGROUND},
{"FL_WATERJUMP", "const float", QW|NQ|CS, FL_WATERJUMP},
// {"FL_MOVECHAIN_ANGLE", "const float", QW|NQ, FL_MOVECHAIN_ANGLE},
{"FL_LAGGEDMOVE", "const float", QW|NQ, FL_LAGGEDMOVE},
// {"FL_CLASS_DEPENDENT", "const float", QW|NQ, FL_CLASS_DEPENDENT},
{"MOVE_NORMAL", "const float", QW|NQ|CS, MOVE_NORMAL},
{"MOVE_NOMONSTERS", "const float", QW|NQ|CS, MOVE_NOMONSTERS},
{"MOVE_MISSILE", "const float", QW|NQ|CS, MOVE_MISSILE},
{"MOVE_HITMODEL", "const float", QW|NQ|CS, MOVE_HITMODEL},
{"MOVE_TRIGGERS", "const float", QW|NQ|CS, MOVE_TRIGGERS},
{"MOVE_EVERYTHING", "const float", QW|NQ|CS, MOVE_EVERYTHING},
{"MOVE_LAGGED", "const float", QW|NQ, MOVE_LAGGED},
{"MOVE_ENTCHAIN", "const float", QW|NQ|CS, MOVE_ENTCHAIN},
{"EF_BRIGHTFIELD", "const float", QW|NQ|CS, EF_BRIGHTFIELD},
{"EF_MUZZLEFLASH", "const float", NQ|CS, EF_MUZZLEFLASH},
@ -10080,7 +9895,15 @@ void PR_DumpPlatform_f(void)
if (!*fname)
fname = "fteextensions";
f = FS_OpenVFS(va("src/%s.qc", fname), "wb", FS_GAMEONLY);
fname = va("src/%s.qc", fname);
FS_NativePath(fname, FS_GAMEONLY, dbgfname, sizeof(dbgfname));
FS_CreatePath(fname, FS_GAMEONLY);
f = FS_OpenVFS(fname, "wb", FS_GAMEONLY);
if (!f)
{
Con_Printf("Unable to create \"%s\"\n", dbgfname);
return;
}
VFS_PRINTF(f, "/*\n"
"This file was automatically generated by %s v%i.%02i\n"
@ -10203,7 +10026,11 @@ void PR_DumpPlatform_f(void)
else
{
if (BuiltinList[i].bifunc == PF_Fixme || BuiltinList[i].bifunc == PF_Ignore)
continue; /*neither*/
{
/*neither*/
BuiltinList[i].obsolete = true;
nd = d; /*don't switch ifdefs*/
}
else
nd = 1; /*ssqc only*/
}
@ -10217,7 +10044,7 @@ void PR_DumpPlatform_f(void)
VFS_PRINTF(f, "#ifdef CSQC\n");
d = nd;
}
VFS_PRINTF(f, "%s %s = #%u;\n", BuiltinList[i].prototype, BuiltinList[i].name, idx);
VFS_PRINTF(f, "%s%s %s = #%u;\n", BuiltinList[i].obsolete?"//":"", BuiltinList[i].prototype, BuiltinList[i].name, idx);
}
}
if (d)
@ -10227,6 +10054,7 @@ void PR_DumpPlatform_f(void)
VFS_CLOSE(f);
FS_FlushFSHash();
Con_Printf("Written \"%s\"\n", dbgfname);
#endif
}

View file

@ -177,7 +177,7 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldentity(dmg_inflictor)\
comfieldentity(owner)\
comfieldvector(movedir)\
comfieldstring(message) /*not used directly, hexen2 uses floats, so we go via qclib for message*/\
comfieldstring(message) /*don't use directly, hexen2 uses floats, so we go via qclib for message*/\
comfieldfloat(sounds)\
comfieldstring(noise)\
comfieldstring(noise1)\
@ -196,6 +196,8 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldfloat(scale)/*DP_ENT_SCALE*/\
comfieldfloat(fatness)/*FTE_PEXT_FATNESS*/\
comfieldfloat(alpha)/*DP_ENT_ALPHA*/\
comfieldentity(tag_entity)\
comfieldfloat(skeletonindex) /*FTE_CSQC_SKELETONOBJECTS*/\
comfieldvector(colormod)\
comfieldfloat(pmove_flags)/*EXT_CSQC_1*/\
comfieldfloat(jointtype)/*DP_...PHYSICS*/\
@ -220,7 +222,6 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldfloat(button7)\
comfieldfloat(button8)\
comfieldfloat(viewzoom)/*DP_VIEWZOOM*/\
comfieldentity(tag_entity)\
comfieldfloat(tag_index)\
comfieldfloat(glow_size)\
comfieldfloat(glow_color)\
@ -272,8 +273,6 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldfloat(subblendfrac) /*FTE_CSQC_HALFLIFE_MODELS*/\
comfieldfloat(basesubblendfrac) /*FTE_CSQC_HALFLIFE_MODELS+FTE_CSQC_BASEFRAME*/\
\
comfieldfloat(skeletonindex) /*FTE_CSQC_SKELETONOBJECTS*/\
\
comfieldfloat(drawmask) /*So that the qc can specify all rockets at once or all bannanas at once*/ \
comfieldfunction(predraw, ".void()") /*If present, is called just before it's drawn.*/ \
comfieldvector(glowmod) \
@ -409,6 +408,7 @@ typedef struct
{
// for ODE physics engine
qboolean ode; // if true then ode is activated
qboolean hasodeents; // if true then we have some ode body somewhere, and we consume more cycles processing full physics, instead of trying to skip as much as we can
void *ode_world;
void *ode_space;
void *ode_contactgroup;

View file

@ -27,7 +27,10 @@ typedef enum multicast_e
MULTICAST_PVS,
MULTICAST_ALL_R,
MULTICAST_PHS_R,
MULTICAST_PVS_R
MULTICAST_PVS_R,
MULTICAST_ONE,
MULTICAST_ONE_R
} multicast_t;
extern float pm_q2stepheight;

View file

@ -809,30 +809,6 @@ typedef struct
#define DAMAGE_YES 1
#define DAMAGE_AIM 2
// edict->flags
#define FL_FLY (1<<0)
#define FL_SWIM (1<<1)
#define FL_GLIMPSE (1<<2)
#define FL_CLIENT (1<<3)
#define FL_INWATER (1<<4)
#define FL_MONSTER (1<<5)
#define FL_GODMODE (1<<6)
#define FL_NOTARGET (1<<7)
#define FL_ITEM (1<<8)
#define FL_ONGROUND (1<<9)
#define FL_PARTIALGROUND (1<<10) // not all corners are valid
#define FL_WATERJUMP (1<<11) // player jumping out of water
//12
//13
#define FL_FINDABLE_NONSOLID (1<<14) //a cpqwsv feature
#define FL_MOVECHAIN_ANGLE (1<<15) // when in a move chain, will update the angle
#define FL_LAGGEDMOVE (1<<16)
//17
//18
//19
//20
#define FL_CLASS_DEPENDENT (1<<21)
#define PVSF_NORMALPVS 0x0
#define PVSF_NOTRACECHECK 0x1
#define PVSF_USEPHS 0x2

View file

@ -514,7 +514,10 @@ void SV_Map_f (void)
COM_FlushFSCache();
if (strlen(level) > 4 && !strcmp(level + strlen(level)-4, ".cin"))
if (strlen(level) > 4 &&
(!strcmp(level + strlen(level)-4, ".cin") ||
!strcmp(level + strlen(level)-4, ".roq") ||
!strcmp(level + strlen(level)-4, ".avi")))
{
cinematic = true;
}
@ -627,7 +630,7 @@ void SV_Map_f (void)
}
SV_SendMessagesToAll ();
if (newunit || !startspot || !SV_LoadLevelCache(NULL, level, startspot, false))
if (newunit || !startspot || cinematic || !SV_LoadLevelCache(NULL, level, startspot, false))
{
if (waschangelevel && !startspot)
startspot = "";

View file

@ -596,6 +596,7 @@ void SV_UnspawnServer (void) //terminate the running server.
if (svs.clients[i].state)
SV_DropClient(svs.clients+i);
}
PR_Deinit();
#ifdef Q2SERVER
SVQ2_ShutdownGameProgs();
#endif

View file

@ -320,9 +320,6 @@ void VARGS SV_Error (char *error, ...)
#ifndef SERVERONLY
if (cls.state)
{
if (sv.state)
SV_UnspawnServer();
inerror = false;
Host_EndGame("SV_Error: %s\n",string);
}

View file

@ -505,6 +505,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
int leafnum;
int j;
qboolean reliable;
int pnum = 0;
// to = MULTICAST_ALL;
#ifdef Q2BSPS
@ -642,8 +643,6 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
else
#endif
{
leafnum = sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, origin);
reliable = false;
switch (to)
@ -660,15 +659,30 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
if (!sv.phs) /*broadcast if no pvs*/
mask = sv.pvs;
else
{
leafnum = sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, origin);
mask = sv.phs + leafnum * 4*((sv.world.worldmodel->numleafs+31)>>5);
}
break;
case MULTICAST_PVS_R:
reliable = true; // intentional fallthrough
case MULTICAST_PVS:
leafnum = sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, origin);
mask = sv.pvs + leafnum * 4*((sv.world.worldmodel->numleafs+31)>>5);
break;
case MULTICAST_ONE_R:
reliable = true;
case MULTICAST_ONE:
if (svprogfuncs)
{
edict_t *ent = PROG_TO_EDICT(svprogfuncs, pr_global_struct->msg_entity);
pnum = NUM_FOR_EDICT(svprogfuncs, ent) - 1;
}
mask = NULL;
break;
default:
mask = NULL;
SV_Error ("SV_Multicast: bad to:%i", to);
@ -697,7 +711,12 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
}
}
if (svprogfuncs)
if (!mask)
{
if (pnum != j)
continue;
}
else if (svprogfuncs)
{
if (!((int)client->edict->xv->dimension_see & dimension_mask))
continue;
@ -777,12 +796,22 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
if (sv.mvdrecording && !with) //mvds don't get the pext stuff
{
if (reliable)
if (!mask)
{
MVDWrite_Begin(dem_all, 0, sv.multicast.cursize);
/*no distinction between reliable or not*/
MVDWrite_Begin(dem_single, pnum, sv.multicast.cursize);
SZ_Write(&demo.dbuf->sb, sv.multicast.data, sv.multicast.cursize);
} else
SZ_Write(&demo.datagram, sv.multicast.data, sv.multicast.cursize);
}
else
{
if (reliable)
{
MVDWrite_Begin(dem_all, 0, sv.multicast.cursize);
SZ_Write(&demo.dbuf->sb, sv.multicast.data, sv.multicast.cursize);
}
else
SZ_Write(&demo.datagram, sv.multicast.data, sv.multicast.cursize);
}
}
#ifdef NQPROT

View file

@ -5226,6 +5226,8 @@ void AddLinksToPmove ( edict_t *player, areanode_t *node )
pe->notouch = !((int)player->xv->dimension_solid & (int)check->xv->dimension_hit);
if (!((int)player->xv->dimension_hit & (int)check->xv->dimension_solid))
continue;
if (!check->v->size[0]) //points are not meant to be solid
continue;
pmove.numphysent++;
VectorCopy (check->v->origin, pe->origin);
@ -5625,7 +5627,6 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
pmove.waterjumptime = sv_player->v->teleport_time;
if (pmove.waterjumptime > sv.time)
sv_player->v->flags = (int)sv_player->v->flags | FL_WATERJUMP;
sv_player->v->teleport_time = sv.time + pmove.waterjumptime;
}
else
jumpable = false;
@ -5729,7 +5730,10 @@ if (sv_player->v->health > 0 && before && !after )
host_client->jump_held = pmove.jump_held;
if (progstype != PROG_QW) //this is just annoying.
sv_player->v->teleport_time = pmove.waterjumptime + sv.time;
{
if (pmove.waterjumptime)
sv_player->v->teleport_time = pmove.waterjumptime + sv.time;
}
else
sv_player->v->teleport_time = pmove.waterjumptime;
sv_player->v->waterlevel = pmove.waterlevel;

View file

@ -882,7 +882,23 @@ qboolean Mod_LoadEdges (lump_t *l, qboolean lm)
if (lm)
{
#pragma warningmsg("bsp2 todo")
dledge_t *in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
Con_Printf ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
return false;
}
count = l->filelen / sizeof(*in);
out = Hunk_AllocName ( (count + 1) * sizeof(*out), loadname);
loadmodel->edges = out;
loadmodel->numedges = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
out->v[0] = (unsigned int)LittleLong(in->v[0]);
out->v[1] = (unsigned int)LittleLong(in->v[1]);
}
}
else
{
@ -1038,66 +1054,85 @@ Mod_LoadFaces
*/
qboolean Mod_LoadFaces (lump_t *l, qboolean lm)
{
dsface_t *in;
dsface_t *ins;
dlface_t *inl;
msurface_t *out;
int i, count, surfnum;
int planenum, side;
int tn, lofs;
if (lm)
{
in = NULL;
#pragma warningmsg("bsp2 fixme")
}
else
{
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
ins = NULL;
inl = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*inl))
{
Con_Printf ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
return false;
}
count = l->filelen / sizeof(*in);
count = l->filelen / sizeof(*inl);
}
else
{
inl = NULL;
ins = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*ins))
{
Con_Printf ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
return false;
}
count = l->filelen / sizeof(*ins);
}
out = Hunk_AllocName ( count*sizeof(*out), loadname);
loadmodel->surfaces = out;
loadmodel->numsurfaces = count;
for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++)
for ( surfnum=0 ; surfnum<count ; surfnum++, out++)
{
if (lm)
{
#pragma warningmsg("bsp2 fixme")
planenum = LittleLong(inl->planenum);
side = LittleLong(inl->side);
out->firstedge = LittleLong(inl->firstedge);
out->numedges = LittleLong(inl->numedges);
tn = LittleLong (inl->texinfo);
for (i=0 ; i<MAXLIGHTMAPS ; i++)
out->styles[i] = inl->styles[i];
lofs = LittleLong(inl->lightofs);
inl++;
}
else
{
out->firstedge = LittleLong(in->firstedge);
out->numedges = LittleShort(in->numedges);
planenum = LittleShort(ins->planenum);
side = LittleShort(ins->side);
out->firstedge = LittleLong(ins->firstedge);
out->numedges = LittleShort(ins->numedges);
tn = LittleShort (ins->texinfo);
for (i=0 ; i<MAXLIGHTMAPS ; i++)
out->styles[i] = ins->styles[i];
lofs = LittleLong(ins->lightofs);
ins++;
}
out->flags = 0;
planenum = LittleShort(in->planenum);
side = LittleShort(in->side);
if (side)
out->flags |= SURF_PLANEBACK;
out->plane = loadmodel->planes + planenum;
out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo);
out->texinfo = loadmodel->texinfo + tn;
CalcSurfaceExtents (out);
// lighting info
for (i=0 ; i<MAXLIGHTMAPS ; i++)
out->styles[i] = in->styles[i];
i = LittleLong(in->lightofs);
if (i == -1)
if (lofs == -1)
out->samples = NULL;
else if (loadmodel->fromgame == fg_halflife)
out->samples = loadmodel->lightdata + i;
out->samples = loadmodel->lightdata + lofs;
else
out->samples = loadmodel->lightdata + i*3;
out->samples = loadmodel->lightdata + lofs*3;
// set the drawing flags flag
@ -1145,15 +1180,50 @@ Mod_LoadNodes
qboolean Mod_LoadNodes (lump_t *l, qboolean lm)
{
int i, j, count, p;
dsnode_t *in;
mnode_t *out;
if (lm)
{
#pragma warningmsg("bsp2 fixme")
dlnode_t *in;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
Con_Printf (CON_ERROR "MOD_LoadBmodel: funny lump size in %s\n",loadmodel->name);
return false;
}
count = l->filelen / sizeof(*in);
out = Hunk_AllocName ( count*sizeof(*out), loadname);
loadmodel->nodes = out;
loadmodel->numnodes = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
for (j=0 ; j<3 ; j++)
{
out->minmaxs[j] = LittleShort (in->mins[j]);
out->minmaxs[3+j] = LittleShort (in->maxs[j]);
}
p = LittleLong(in->planenum);
out->plane = loadmodel->planes + p;
out->firstsurface = LittleLong (in->firstface);
out->numsurfaces = LittleLong (in->numfaces);
for (j=0 ; j<2 ; j++)
{
p = LittleLong (in->children[j]);
if (p >= 0)
out->children[j] = loadmodel->nodes + p;
else
out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p));
}
}
}
else
{
dsnode_t *in;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
@ -1202,16 +1272,52 @@ Mod_LoadLeafs
*/
qboolean Mod_LoadLeafs (lump_t *l, qboolean lm)
{
dsleaf_t *in;
mleaf_t *out;
int i, j, count, p;
if (lm)
{
#pragma warningmsg("bsp2 fixme")
dlleaf_t *in;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
Con_Printf (CON_ERROR "MOD_LoadBmodel: funny lump size in %s\n",loadmodel->name);
return false;
}
count = l->filelen / sizeof(*in);
out = Hunk_AllocName ( count*sizeof(*out), loadname);
loadmodel->leafs = out;
loadmodel->numleafs = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
for (j=0 ; j<3 ; j++)
{
out->minmaxs[j] = LittleShort (in->mins[j]);
out->minmaxs[3+j] = LittleShort (in->maxs[j]);
}
p = LittleLong(in->contents);
out->contents = p;
out->firstmarksurface = loadmodel->marksurfaces +
(unsigned int)LittleLong(in->firstmarksurface);
out->nummarksurfaces = (unsigned int)LittleLong(in->nummarksurfaces);
p = LittleLong(in->visofs);
if (p == -1)
out->compressed_vis = NULL;
else
out->compressed_vis = loadmodel->visdata + p;
for (j=0 ; j<4 ; j++)
out->ambient_sound_level[j] = in->ambient_level[j];
}
}
else
{
dsleaf_t *in;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
@ -1260,18 +1366,13 @@ Mod_LoadClipnodes
*/
qboolean Mod_LoadClipnodes (lump_t *l, qboolean lm)
{
dsclipnode_t *in;
mclipnode_t *out;
int i, count;
hull_t *hull;
if (lm)
{
#pragma warningmsg("bsp2 fixme")
in = NULL;
}
else
{
dlclipnode_t *in;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
@ -1279,8 +1380,34 @@ qboolean Mod_LoadClipnodes (lump_t *l, qboolean lm)
return false;
}
count = l->filelen / sizeof(*in);
out = Hunk_AllocName ( count*sizeof(*out), loadname);
for (i=0 ; i<count ; i++, in++)
{
out[i].planenum = LittleLong(in->planenum);
out[i].children[0] = LittleLong(in->children[0]);
out[i].children[1] = LittleLong(in->children[1]);
}
}
else
{
dsclipnode_t *in;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
Con_Printf (CON_ERROR "MOD_LoadBmodel: funny lump size in %s\n",loadmodel->name);
return false;
}
count = l->filelen / sizeof(*in);
out = Hunk_AllocName ( count*sizeof(*out), loadname);
for (i=0 ; i<count ; i++, in++)
{
out[i].planenum = LittleLong(in->planenum);
out[i].children[0] = LittleShort(in->children[0]);
out[i].children[1] = LittleShort(in->children[1]);
}
}
out = Hunk_AllocName ( count*sizeof(*out), loadname);
loadmodel->clipnodes = out;
loadmodel->numclipnodes = count;
@ -1444,20 +1571,6 @@ qboolean Mod_LoadClipnodes (lump_t *l, qboolean lm)
hull->available = false;
}
if (lm)
{
#pragma warningmsg("bsp2 fixme")
}
else
{
for (i=0 ; i<count ; i++, out++, in++)
{
out->planenum = LittleLong(in->planenum);
out->children[0] = LittleShort(in->children[0]);
out->children[1] = LittleShort(in->children[1]);
}
}
return true;
}