mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-10 14:42:13 +00:00
Slow progress. Most of what I am fighting is emscripten's javascript-based libc. Its networking is laughable at best, trust me you don't want to see it. Whereas its GL emulation seems to break things rather than anything else so for now I'm just disabling everything that isn't vbo+es2 and I still get warnings about emulation being enabled. No idea how to get rid of those. Still, bsp objects should now render correctly, but not models+particles+2d+text stuff.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4283 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
0807d7a28d
commit
49197218bc
14 changed files with 386 additions and 111 deletions
|
@ -1108,8 +1108,9 @@ ifeq ($(FTE_TARGET),droid)
|
|||
endif
|
||||
|
||||
ifeq ($(FTE_TARGET),web)
|
||||
RELEASE_CFLAGS=-O1 -DOMIT_QCC -DGL_STATIC
|
||||
CC=emcc -DFTE_TARGET_WEB -s TOTAL_MEMORY=268435456 -s FULL_ES2=1
|
||||
RELEASE_CFLAGS=-O1 -DOMIT_QCC -DGL_STATIC -DFTE_TARGET_WEB --pre-js web/prejs.js
|
||||
DEBUG_CFLAGS=-O0 -g --jcache -DOMIT_QCC -DGL_STATIC -DFTE_TARGET_WEB --pre-js web/prejs.js
|
||||
CC=emcc -s TOTAL_MEMORY=268435456
|
||||
#-s ASM_JS=1
|
||||
#BASELDFLAGS=
|
||||
|
||||
|
@ -1132,6 +1133,9 @@ ifeq ($(FTE_TARGET),web)
|
|||
GLB_DIR=gl_web
|
||||
GL_EXE_NAME=../ftewebgl.html
|
||||
|
||||
GL_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) $(OGGVORBISLDFLAGS)
|
||||
GL_CFLAGS=$(GLCFLAGS)
|
||||
|
||||
IMAGELDFLAGS=
|
||||
OGGVORBISLDFLAGS=
|
||||
|
||||
|
|
|
@ -397,6 +397,12 @@ void Sys_SendKeyEvents(void)
|
|||
case QR_OPENGL:
|
||||
vid.pixelwidth = event.resize.w;
|
||||
vid.pixelheight = event.resize.h;
|
||||
{
|
||||
extern cvar_t vid_conautoscale, vid_conwidth; //make sure the screen is updated properly.
|
||||
Cvar_ForceCallback(&vid_conautoscale);
|
||||
Cvar_ForceCallback(&vid_conwidth);
|
||||
}
|
||||
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -350,7 +350,11 @@ cvar_t r_glsl_turbscale = CVARF ("r_glsl_turbscale", "1", CVAR_ARCHIVE);
|
|||
cvar_t r_shadow_realtime_world = SCVARF ("r_shadow_realtime_world", "0", CVAR_ARCHIVE);
|
||||
cvar_t r_shadow_realtime_world_shadows = SCVARF ("r_shadow_realtime_world_shadows", "1", CVAR_ARCHIVE);
|
||||
cvar_t r_shadow_realtime_world_lightmaps = SCVARF ("r_shadow_realtime_world_lightmaps", "0", 0);
|
||||
#ifdef FTE_TARGET_WEB
|
||||
cvar_t r_shadow_realtime_dlight = SCVARF ("r_shadow_realtime_dlight", "0", CVAR_ARCHIVE);
|
||||
#else
|
||||
cvar_t r_shadow_realtime_dlight = SCVARF ("r_shadow_realtime_dlight", "1", CVAR_ARCHIVE);
|
||||
#endif
|
||||
cvar_t r_shadow_realtime_dlight_shadows = SCVARF ("r_shadow_realtime_dlight_shadows", "1", CVAR_ARCHIVE);
|
||||
cvar_t r_shadow_realtime_dlight_ambient = SCVAR ("r_shadow_realtime_dlight_ambient", "0");
|
||||
cvar_t r_shadow_realtime_dlight_diffuse = SCVAR ("r_shadow_realtime_dlight_diffuse", "1");
|
||||
|
|
|
@ -74,7 +74,7 @@ unsigned int Sys_Milliseconds(void)
|
|||
if (newtime < oldtime)
|
||||
Con_Printf("Sys_Milliseconds stepped backwards!\n");
|
||||
else
|
||||
curtime += oldtime - newtime;
|
||||
curtime += newtime - oldtime;
|
||||
oldtime = newtime;
|
||||
return curtime;
|
||||
}
|
||||
|
@ -82,6 +82,8 @@ unsigned int Sys_Milliseconds(void)
|
|||
//return the current time, in the form of a double
|
||||
double Sys_DoubleTime (void)
|
||||
{
|
||||
return Sys_Milliseconds() / 1000.0;
|
||||
/*
|
||||
static int first = true;
|
||||
static double oldtime = 0.0, curtime = 0.0;
|
||||
double newtime;
|
||||
|
@ -106,6 +108,7 @@ double Sys_DoubleTime (void)
|
|||
oldtime = newtime;
|
||||
|
||||
return curtime;
|
||||
*/
|
||||
}
|
||||
|
||||
//create a directory
|
||||
|
@ -500,12 +503,15 @@ int QDECL main(int argc, char **argv)
|
|||
|
||||
memset(&parms, 0, sizeof(parms));
|
||||
|
||||
parms.argv = argv;
|
||||
|
||||
#ifdef FTE_TARGET_WEB
|
||||
parms.basedir = "";
|
||||
#else
|
||||
parms.basedir = ".";
|
||||
#endif
|
||||
|
||||
parms.argc = argc;
|
||||
parms.argv = argv;
|
||||
parms.argv = (const char**)argv;
|
||||
|
||||
#ifndef WIN32
|
||||
fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
|
||||
|
|
|
@ -42,7 +42,16 @@ typedef vec4_t avec4_t;
|
|||
typedef qbyte byte_vec4_t[4];
|
||||
#endif
|
||||
|
||||
#define vecV_t avec4_t
|
||||
//VECV_STRIDE is used only as an argument for opengl.
|
||||
#ifdef FTE_TARGET_WEB
|
||||
//emscripten is alergic to explicit strides without packed attributes, at least in emulated code.
|
||||
//so we need to keep everything packed. screw sse-friendly packing.
|
||||
#define vecV_t vec3_t
|
||||
#define VECV_STRIDE 0
|
||||
#else
|
||||
#define vecV_t avec4_t
|
||||
#define VECV_STRIDE sizeof(vecV_t)
|
||||
#endif
|
||||
|
||||
typedef int fixed4_t;
|
||||
typedef int fixed8_t;
|
||||
|
|
|
@ -1797,6 +1797,9 @@ static void FTENET_NATPMP_Refresh(pmpcon_t *pmp, short oldport, ftenet_connectio
|
|||
else
|
||||
pmp->pmpaddr = pmp->reqpmpaddr;
|
||||
|
||||
if (*(int*)pmp->pmpaddr.address.ip == INADDR_ANY)
|
||||
continue;
|
||||
|
||||
//get the public ip.
|
||||
pmpreqmsg.op = 0;
|
||||
NET_SendPacket(NS_SERVER, 2, &pmpreqmsg, pmp->pmpaddr);
|
||||
|
@ -1804,6 +1807,8 @@ static void FTENET_NATPMP_Refresh(pmpcon_t *pmp, short oldport, ftenet_connectio
|
|||
//open the firewall/nat.
|
||||
pmpreqmsg.op = 1;
|
||||
NET_SendPacket(NS_SERVER, sizeof(pmpreqmsg), &pmpreqmsg, pmp->pmpaddr);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1824,6 +1829,7 @@ qboolean FTENET_NATPMP_GetPacket(struct ftenet_generic_connection_s *con)
|
|||
unsigned int now = Sys_Milliseconds();
|
||||
if (now - pmp->refreshtime > PMP_POLL_TIME) //weird logic to cope with wrapping
|
||||
{
|
||||
Con_Printf("nat-pmp refresh (%u - %u > %u)\n", now, pmp->refreshtime, PMP_POLL_TIME);
|
||||
pmp->refreshtime = now;
|
||||
FTENET_NATPMP_Refresh(pmp, pmp->natadr.port, pmp->col);
|
||||
}
|
||||
|
@ -1833,11 +1839,10 @@ qboolean FTENET_NATPMP_SendPacket(struct ftenet_generic_connection_s *con, int l
|
|||
{
|
||||
return false;
|
||||
}
|
||||
qboolean FTENET_NATPMP_Close(struct ftenet_generic_connection_s *con)
|
||||
void FTENET_NATPMP_Close(struct ftenet_generic_connection_s *con)
|
||||
{
|
||||
//FIXME: we should send a packet to close the port
|
||||
Z_Free(con);
|
||||
return true;
|
||||
}
|
||||
ftenet_generic_connection_t *FTENET_NATPMP_EstablishConnection(qboolean isserver, const char *address)
|
||||
{
|
||||
|
@ -2479,6 +2484,7 @@ typedef struct ftenet_tcpconnect_stream_s {
|
|||
enum
|
||||
{
|
||||
TCPC_UNKNOWN,
|
||||
TCPC_UNFRAMED, //something else is doing the framing (ie: we're running in emscripten and over some hidden websocket connection)
|
||||
TCPC_QIZMO,
|
||||
TCPC_WEBSOCKET
|
||||
} clienttype;
|
||||
|
@ -2869,6 +2875,17 @@ handshakeerror:
|
|||
net_message.currentbit = 0;
|
||||
net_from = st->remoteaddr;
|
||||
|
||||
return true;
|
||||
case TCPC_UNFRAMED:
|
||||
if (!st->inlen)
|
||||
continue;
|
||||
net_message.cursize = st->inlen;
|
||||
memcpy(net_message_buffer, st->inbuffer, net_message.cursize);
|
||||
st->inlen = 0;
|
||||
|
||||
net_message.packing = SZ_RAWBYTES;
|
||||
net_message.currentbit = 0;
|
||||
net_from = st->remoteaddr;
|
||||
return true;
|
||||
case TCPC_WEBSOCKET:
|
||||
while (st->inlen >= 2)
|
||||
|
@ -3094,6 +3111,14 @@ qboolean FTENET_TCPConnect_SendPacket(ftenet_generic_connection_t *gcon, int len
|
|||
}
|
||||
}
|
||||
break;
|
||||
case TCPC_UNFRAMED:
|
||||
if (length > sizeof(st->outbuffer))
|
||||
{
|
||||
Con_DPrintf("FTENET_TCPConnect_SendPacket: outgoing overflow\n");
|
||||
}
|
||||
memcpy(st->outbuffer, data, length);
|
||||
st->outlen = length;
|
||||
break;
|
||||
case TCPC_WEBSOCKET:
|
||||
{
|
||||
/*as a server, we don't need the mask stuff*/
|
||||
|
@ -3185,6 +3210,7 @@ void FTENET_TCPConnect_Close(ftenet_generic_connection_t *gcon)
|
|||
FTENET_Generic_Close(gcon);
|
||||
}
|
||||
|
||||
#ifdef HAVE_PACKET
|
||||
int FTENET_TCPConnect_SetReceiveFDSet(ftenet_generic_connection_t *gcon, fd_set *fdset)
|
||||
{
|
||||
int maxfd = 0;
|
||||
|
@ -3207,6 +3233,7 @@ int FTENET_TCPConnect_SetReceiveFDSet(ftenet_generic_connection_t *gcon, fd_set
|
|||
}
|
||||
return maxfd;
|
||||
}
|
||||
#endif
|
||||
|
||||
ftenet_generic_connection_t *FTENET_TCPConnect_EstablishConnection(int affamily, qboolean isserver, const char *address)
|
||||
{
|
||||
|
@ -3221,9 +3248,17 @@ ftenet_generic_connection_t *FTENET_TCPConnect_EstablishConnection(int affamily,
|
|||
int family;
|
||||
if (!strncmp(address, "tcp://", 6))
|
||||
address += 6;
|
||||
if (!strncmp(address, "ws://", 5))
|
||||
address += 5;
|
||||
if (!strncmp(address, "wss://", 6))
|
||||
address += 6;
|
||||
|
||||
if (isserver)
|
||||
{
|
||||
#ifndef HAVE_PACKET
|
||||
//unable to listen on tcp if we have no packet interface
|
||||
return NULL;
|
||||
#else
|
||||
if (!NET_PortToAdr(affamily, address, &adr))
|
||||
return NULL; //couldn't resolve the name
|
||||
if (adr.type == NA_IP)
|
||||
|
@ -3250,10 +3285,11 @@ ftenet_generic_connection_t *FTENET_TCPConnect_EstablishConnection(int affamily,
|
|||
|
||||
if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
|
||||
Sys_Error ("UDP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!NET_PortToAdr(affamily, address, &adr))
|
||||
if (!NET_StringToAdr(address, 0, &adr))
|
||||
return NULL; //couldn't resolve the name
|
||||
|
||||
if (adr.type == NA_IP)
|
||||
|
@ -3274,7 +3310,9 @@ ftenet_generic_connection_t *FTENET_TCPConnect_EstablishConnection(int affamily,
|
|||
newcon->generic.GetPacket = FTENET_TCPConnect_GetPacket;
|
||||
newcon->generic.SendPacket = FTENET_TCPConnect_SendPacket;
|
||||
newcon->generic.Close = FTENET_TCPConnect_Close;
|
||||
#ifdef HAVE_PACKET
|
||||
newcon->generic.SetReceiveFDSet = FTENET_TCPConnect_SetReceiveFDSet;
|
||||
#endif
|
||||
|
||||
newcon->generic.islisten = isserver;
|
||||
newcon->generic.addrtype[0] = adr.type;
|
||||
|
@ -3288,15 +3326,19 @@ ftenet_generic_connection_t *FTENET_TCPConnect_EstablishConnection(int affamily,
|
|||
|
||||
newcon->active++;
|
||||
newcon->tcpstreams = Z_Malloc(sizeof(*newcon->tcpstreams));
|
||||
newcon->tcpstreams->clienttype = TCPC_UNKNOWN;
|
||||
newcon->tcpstreams->next = NULL;
|
||||
newcon->tcpstreams->socketnum = newsocket;
|
||||
newcon->tcpstreams->inlen = 0;
|
||||
|
||||
newcon->tcpstreams->remoteaddr = adr;
|
||||
|
||||
#ifdef FTE_TARGET_WEB
|
||||
newcon->tcpstreams->clienttype = TCPC_UNFRAMED;
|
||||
#else
|
||||
//send the qizmo greeting.
|
||||
newcon->tcpstreams->clienttype = TCPC_UNKNOWN;
|
||||
send(newsocket, "qizmo\n", 6, 0);
|
||||
#endif
|
||||
|
||||
newcon->tcpstreams->timeouttime = Sys_DoubleTime() + 30;
|
||||
}
|
||||
|
@ -5054,7 +5096,7 @@ void NET_InitServer(void)
|
|||
#ifdef USEIPX
|
||||
Cvar_ForceCallback(&sv_port_ipx);
|
||||
#endif
|
||||
#ifdef TCPCONNECT
|
||||
#if defined(TCPCONNECT) && defined(HAVE_TCP)
|
||||
Cvar_ForceCallback(&sv_port_tcp);
|
||||
#ifdef IPPROTO_IPV6
|
||||
Cvar_ForceCallback(&sv_port_tcp6);
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
#define HAVE_PACKET //if we have the socket api at all...
|
||||
#endif
|
||||
|
||||
#ifdef FTE_TARGET_WEB
|
||||
#undef HAVE_PACKET //no udp packet interface.
|
||||
#endif
|
||||
|
||||
#ifdef NACL
|
||||
|
||||
struct sockaddr
|
||||
|
|
|
@ -386,10 +386,13 @@ void GL_MTBind(int tmu, int target, texid_t texnum)
|
|||
if (target)
|
||||
qglBindTexture (target, texnum.num);
|
||||
|
||||
if (
|
||||
#ifndef FORCESTATE
|
||||
if (shaderstate.curtexturetype[tmu] != target && !gl_config.nofixedfunc)
|
||||
shaderstate.curtexturetype[tmu] != target &&
|
||||
#endif
|
||||
!gl_config.nofixedfunc)
|
||||
{
|
||||
|
||||
if (shaderstate.curtexturetype[tmu])
|
||||
qglDisable(shaderstate.curtexturetype[tmu]);
|
||||
shaderstate.curtexturetype[tmu] = target;
|
||||
|
@ -520,7 +523,7 @@ static void BE_ApplyAttributes(unsigned int bitstochange, unsigned int bitstoend
|
|||
shaderstate.curvertexpointer = shaderstate.pendingvertexpointer;
|
||||
shaderstate.curvertexvbo = shaderstate.pendingvertexvbo;
|
||||
GL_SelectVBO(shaderstate.curvertexvbo);
|
||||
qglVertexPointer(3, GL_FLOAT, sizeof(vecV_t), shaderstate.curvertexpointer);
|
||||
qglVertexPointer(3, GL_FLOAT, VECV_STRIDE, shaderstate.curvertexpointer);
|
||||
}
|
||||
if ((bitstoendisable) & (1u<<VATTR_LEG_VERTEX))
|
||||
{
|
||||
|
@ -547,18 +550,18 @@ static void BE_ApplyAttributes(unsigned int bitstochange, unsigned int bitstoend
|
|||
case VATTR_VERTEX1:
|
||||
/*we still do vertex transforms for billboards and shadows and such*/
|
||||
GL_SelectVBO(shaderstate.pendingvertexvbo);
|
||||
qglVertexAttribPointer(i, 3, GL_FLOAT, GL_FALSE, sizeof(vecV_t), shaderstate.pendingvertexpointer);
|
||||
qglVertexAttribPointer(i, 3, GL_FLOAT, GL_FALSE, VECV_STRIDE, shaderstate.pendingvertexpointer);
|
||||
break;
|
||||
case VATTR_VERTEX2:
|
||||
if (!shaderstate.sourcevbo->coord2.gl.vbo && !shaderstate.sourcevbo->coord2.gl.addr)
|
||||
{
|
||||
GL_SelectVBO(shaderstate.pendingvertexvbo);
|
||||
qglVertexAttribPointer(i, 3, GL_FLOAT, GL_FALSE, sizeof(vecV_t), shaderstate.pendingvertexpointer);
|
||||
qglVertexAttribPointer(i, 3, GL_FLOAT, GL_FALSE, VECV_STRIDE, shaderstate.pendingvertexpointer);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_SelectVBO(shaderstate.sourcevbo->coord2.gl.vbo);
|
||||
qglVertexAttribPointer(VATTR_VERTEX2, 3, GL_FLOAT, GL_FALSE, sizeof(vecV_t), shaderstate.sourcevbo->coord2.gl.addr);
|
||||
qglVertexAttribPointer(VATTR_VERTEX2, 3, GL_FLOAT, GL_FALSE, VECV_STRIDE, shaderstate.sourcevbo->coord2.gl.addr);
|
||||
}
|
||||
break;
|
||||
case VATTR_COLOUR:
|
||||
|
@ -571,31 +574,31 @@ static void BE_ApplyAttributes(unsigned int bitstochange, unsigned int bitstoend
|
|||
break;
|
||||
case VATTR_TEXCOORD:
|
||||
GL_SelectVBO(shaderstate.sourcevbo->texcoord.gl.vbo);
|
||||
qglVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->texcoord.gl.addr);
|
||||
qglVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, shaderstate.sourcevbo->texcoord.gl.addr);
|
||||
break;
|
||||
case VATTR_LMCOORD:
|
||||
if (!shaderstate.sourcevbo->lmcoord[0].gl.vbo && !shaderstate.sourcevbo->lmcoord[0].gl.addr)
|
||||
{
|
||||
GL_SelectVBO(shaderstate.sourcevbo->texcoord.gl.vbo);
|
||||
qglVertexAttribPointer(VATTR_LMCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->texcoord.gl.addr);
|
||||
qglVertexAttribPointer(VATTR_LMCOORD, 2, GL_FLOAT, GL_FALSE, 0, shaderstate.sourcevbo->texcoord.gl.addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_SelectVBO(shaderstate.sourcevbo->lmcoord[0].gl.vbo);
|
||||
qglVertexAttribPointer(VATTR_LMCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->lmcoord[0].gl.addr);
|
||||
qglVertexAttribPointer(VATTR_LMCOORD, 2, GL_FLOAT, GL_FALSE, 0, shaderstate.sourcevbo->lmcoord[0].gl.addr);
|
||||
}
|
||||
break;
|
||||
case VATTR_LMCOORD2:
|
||||
GL_SelectVBO(shaderstate.sourcevbo->lmcoord[1].gl.vbo);
|
||||
qglVertexAttribPointer(VATTR_LMCOORD2, 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->lmcoord[1].gl.addr);
|
||||
qglVertexAttribPointer(VATTR_LMCOORD2, 2, GL_FLOAT, GL_FALSE, 0, shaderstate.sourcevbo->lmcoord[1].gl.addr);
|
||||
break;
|
||||
case VATTR_LMCOORD3:
|
||||
GL_SelectVBO(shaderstate.sourcevbo->lmcoord[2].gl.vbo);
|
||||
qglVertexAttribPointer(VATTR_LMCOORD3, 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->lmcoord[2].gl.addr);
|
||||
qglVertexAttribPointer(VATTR_LMCOORD3, 2, GL_FLOAT, GL_FALSE, 0, shaderstate.sourcevbo->lmcoord[2].gl.addr);
|
||||
break;
|
||||
case VATTR_LMCOORD4:
|
||||
GL_SelectVBO(shaderstate.sourcevbo->lmcoord[3].gl.vbo);
|
||||
qglVertexAttribPointer(VATTR_LMCOORD4, 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->lmcoord[3].gl.addr);
|
||||
qglVertexAttribPointer(VATTR_LMCOORD4, 2, GL_FLOAT, GL_FALSE, 0, shaderstate.sourcevbo->lmcoord[3].gl.addr);
|
||||
break;
|
||||
case VATTR_NORMALS:
|
||||
if (!shaderstate.sourcevbo->normals.gl.addr)
|
||||
|
@ -605,7 +608,7 @@ static void BE_ApplyAttributes(unsigned int bitstochange, unsigned int bitstoend
|
|||
continue;
|
||||
}
|
||||
GL_SelectVBO(shaderstate.sourcevbo->normals.gl.vbo);
|
||||
qglVertexAttribPointer(VATTR_NORMALS, 3, GL_FLOAT, GL_FALSE, sizeof(vec3_t), shaderstate.sourcevbo->normals.gl.addr);
|
||||
qglVertexAttribPointer(VATTR_NORMALS, 3, GL_FLOAT, GL_FALSE, 0, shaderstate.sourcevbo->normals.gl.addr);
|
||||
break;
|
||||
case VATTR_SNORMALS:
|
||||
if (!shaderstate.sourcevbo->svector.gl.addr)
|
||||
|
@ -615,7 +618,7 @@ static void BE_ApplyAttributes(unsigned int bitstochange, unsigned int bitstoend
|
|||
continue;
|
||||
}
|
||||
GL_SelectVBO(shaderstate.sourcevbo->svector.gl.vbo);
|
||||
qglVertexAttribPointer(VATTR_SNORMALS, 3, GL_FLOAT, GL_FALSE, sizeof(vec3_t), shaderstate.sourcevbo->svector.gl.addr);
|
||||
qglVertexAttribPointer(VATTR_SNORMALS, 3, GL_FLOAT, GL_FALSE, 0, shaderstate.sourcevbo->svector.gl.addr);
|
||||
break;
|
||||
case VATTR_TNORMALS:
|
||||
if (!shaderstate.sourcevbo->tvector.gl.addr)
|
||||
|
@ -625,15 +628,15 @@ static void BE_ApplyAttributes(unsigned int bitstochange, unsigned int bitstoend
|
|||
continue;
|
||||
}
|
||||
GL_SelectVBO(shaderstate.sourcevbo->tvector.gl.vbo);
|
||||
qglVertexAttribPointer(VATTR_TNORMALS, 3, GL_FLOAT, GL_FALSE, sizeof(vec3_t), shaderstate.sourcevbo->tvector.gl.addr);
|
||||
qglVertexAttribPointer(VATTR_TNORMALS, 3, GL_FLOAT, GL_FALSE, 0, shaderstate.sourcevbo->tvector.gl.addr);
|
||||
break;
|
||||
case VATTR_BONENUMS:
|
||||
GL_SelectVBO(shaderstate.sourcevbo->bonenums.gl.vbo);
|
||||
qglVertexAttribPointer(VATTR_BONENUMS, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(byte_vec4_t), shaderstate.sourcevbo->bonenums.gl.addr);
|
||||
qglVertexAttribPointer(VATTR_BONENUMS, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, shaderstate.sourcevbo->bonenums.gl.addr);
|
||||
break;
|
||||
case VATTR_BONEWEIGHTS:
|
||||
GL_SelectVBO(shaderstate.sourcevbo->boneweights.gl.vbo);
|
||||
qglVertexAttribPointer(VATTR_BONEWEIGHTS, 4, GL_FLOAT, GL_FALSE, sizeof(vec4_t), shaderstate.sourcevbo->boneweights.gl.addr);
|
||||
qglVertexAttribPointer(VATTR_BONEWEIGHTS, 4, GL_FLOAT, GL_FALSE, 0, shaderstate.sourcevbo->boneweights.gl.addr);
|
||||
break;
|
||||
}
|
||||
if ((bitstoendisable) & (1u<<i))
|
||||
|
@ -3498,6 +3501,13 @@ static void DrawMeshes(void)
|
|||
shaderstate.pendingvertexvbo = shaderstate.sourcevbo->coord.gl.vbo;
|
||||
}
|
||||
|
||||
#ifdef FTE_TARGET_WEB
|
||||
if (!shaderstate.pendingvertexvbo)
|
||||
return;
|
||||
if (!shaderstate.sourcevbo->indicies.gl.vbo)
|
||||
return;
|
||||
#endif
|
||||
|
||||
BE_PolyOffset(shaderstate.flags & BEF_PUSHDEPTH);
|
||||
switch(shaderstate.mode)
|
||||
{
|
||||
|
|
|
@ -57,6 +57,37 @@ void (APIENTRY *qglStencilOpSeparateATI) (GLenum face, GLenum fail, GLenum zfail
|
|||
|
||||
//quick hack that made quake work on both 1+ext and 1.1 gl implementations.
|
||||
BINDTEXFUNCPTR qglBindTexture;
|
||||
|
||||
|
||||
/*glslang - arb_shader_objects
|
||||
gl core uses different names/distinctions from the extension
|
||||
*/
|
||||
FTEPFNGLCREATEPROGRAMOBJECTARBPROC qglCreateProgramObjectARB;
|
||||
FTEPFNGLDELETEOBJECTARBPROC qglDeleteProgramObject_;
|
||||
FTEPFNGLDELETEOBJECTARBPROC qglDeleteShaderObject_;
|
||||
FTEPFNGLUSEPROGRAMOBJECTARBPROC qglUseProgramObjectARB;
|
||||
FTEPFNGLCREATESHADEROBJECTARBPROC qglCreateShaderObjectARB;
|
||||
FTEPFNGLSHADERSOURCEARBPROC qglShaderSourceARB;
|
||||
FTEPFNGLCOMPILESHADERARBPROC qglCompileShaderARB;
|
||||
FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetShaderParameteriv_;
|
||||
FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetProgramParameteriv_;
|
||||
FTEPFNGLATTACHOBJECTARBPROC qglAttachObjectARB;
|
||||
FTEPFNGLGETINFOLOGARBPROC qglGetShaderInfoLog_;
|
||||
FTEPFNGLGETINFOLOGARBPROC qglGetProgramInfoLog_;
|
||||
FTEPFNGLLINKPROGRAMARBPROC qglLinkProgramARB;
|
||||
FTEPFNGLBINDATTRIBLOCATIONARBPROC qglBindAttribLocationARB;
|
||||
FTEPFNGLGETATTRIBLOCATIONARBPROC qglGetAttribLocationARB;
|
||||
FTEPFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB;
|
||||
FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix4fvARB;
|
||||
FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix3x4fv;
|
||||
FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix4x3fv;
|
||||
FTEPFNGLUNIFORM4FARBPROC qglUniform4fARB;
|
||||
FTEPFNGLUNIFORM4FVARBPROC qglUniform4fvARB;
|
||||
FTEPFNGLUNIFORM3FARBPROC qglUniform3fARB;
|
||||
FTEPFNGLUNIFORM3FVARBPROC qglUniform3fvARB;
|
||||
FTEPFNGLUNIFORM4FVARBPROC qglUniform2fvARB;
|
||||
FTEPFNGLUNIFORM1IARBPROC qglUniform1iARB;
|
||||
FTEPFNGLUNIFORM1FARBPROC qglUniform1fARB;
|
||||
#endif
|
||||
//standard 1.1 opengl calls
|
||||
void (APIENTRY *qglAlphaFunc) (GLenum func, GLclampf ref);
|
||||
|
@ -152,35 +183,6 @@ PFNGLGENPROGRAMSARBPROC qglGenProgramsARB;
|
|||
FTEPFNGLLOCKARRAYSEXTPROC qglLockArraysEXT;
|
||||
FTEPFNGLUNLOCKARRAYSEXTPROC qglUnlockArraysEXT;
|
||||
|
||||
/*glslang - arb_shader_objects
|
||||
gl core uses different names/distinctions from the extension
|
||||
*/
|
||||
FTEPFNGLCREATEPROGRAMOBJECTARBPROC qglCreateProgramObjectARB;
|
||||
FTEPFNGLDELETEOBJECTARBPROC qglDeleteProgramObject_;
|
||||
FTEPFNGLDELETEOBJECTARBPROC qglDeleteShaderObject_;
|
||||
FTEPFNGLUSEPROGRAMOBJECTARBPROC qglUseProgramObjectARB;
|
||||
FTEPFNGLCREATESHADEROBJECTARBPROC qglCreateShaderObjectARB;
|
||||
FTEPFNGLSHADERSOURCEARBPROC qglShaderSourceARB;
|
||||
FTEPFNGLCOMPILESHADERARBPROC qglCompileShaderARB;
|
||||
FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetShaderParameteriv_;
|
||||
FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetProgramParameteriv_;
|
||||
FTEPFNGLATTACHOBJECTARBPROC qglAttachObjectARB;
|
||||
FTEPFNGLGETINFOLOGARBPROC qglGetShaderInfoLog_;
|
||||
FTEPFNGLGETINFOLOGARBPROC qglGetProgramInfoLog_;
|
||||
FTEPFNGLLINKPROGRAMARBPROC qglLinkProgramARB;
|
||||
FTEPFNGLBINDATTRIBLOCATIONARBPROC qglBindAttribLocationARB;
|
||||
FTEPFNGLGETATTRIBLOCATIONARBPROC qglGetAttribLocationARB;
|
||||
FTEPFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB;
|
||||
FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix4fvARB;
|
||||
FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix3x4fv;
|
||||
FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix4x3fv;
|
||||
FTEPFNGLUNIFORM4FARBPROC qglUniform4fARB;
|
||||
FTEPFNGLUNIFORM4FVARBPROC qglUniform4fvARB;
|
||||
FTEPFNGLUNIFORM3FARBPROC qglUniform3fARB;
|
||||
FTEPFNGLUNIFORM3FVARBPROC qglUniform3fvARB;
|
||||
FTEPFNGLUNIFORM4FVARBPROC qglUniform2fvARB;
|
||||
FTEPFNGLUNIFORM1IARBPROC qglUniform1iARB;
|
||||
FTEPFNGLUNIFORM1FARBPROC qglUniform1fARB;
|
||||
|
||||
//extensions
|
||||
//arb multitexture
|
||||
|
@ -395,11 +397,6 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
|
|||
else
|
||||
gl_config.gles = false;
|
||||
|
||||
if (webgl)
|
||||
{
|
||||
gl_major_version = 2;
|
||||
gl_minor_version = 0;
|
||||
}
|
||||
if (!gl_config.gles)
|
||||
{
|
||||
if (qglGetError())
|
||||
|
@ -420,6 +417,8 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
|
|||
s++;
|
||||
gl_minor_version = atoi(s);
|
||||
}
|
||||
if (webgl)
|
||||
gl_major_version+=1;
|
||||
//yes, I know, this can't cope with minor versions of 10+... I don't care yet.
|
||||
gl_config.glversion += gl_major_version + (gl_minor_version/10.f);
|
||||
|
||||
|
@ -720,7 +719,9 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
|
|||
qglUnmapBufferARB = (void *)getglext("glUnmapBufferARB");
|
||||
}
|
||||
|
||||
#ifndef GL_STATIC
|
||||
#ifdef GL_STATIC
|
||||
gl_config.arb_shader_objects = true;
|
||||
#else
|
||||
if (Cvar_Get("gl_blacklist_debug_glsl", "0", CVAR_RENDERERLATCH, "gl blacklists")->ival && !gl_config.nofixedfunc)
|
||||
{
|
||||
Con_Printf(CON_NOTICE "GLSL disabled\n");
|
||||
|
@ -788,10 +789,6 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
|
|||
qglLinkProgramARB = (void *)getglext("glLinkProgram");
|
||||
qglBindAttribLocationARB = (void *)getglext("glBindAttribLocation");
|
||||
qglGetAttribLocationARB = (void *)getglext("glGetAttribLocation");
|
||||
qglVertexAttribPointer = (void *)getglext("glVertexAttribPointer");
|
||||
qglGetVertexAttribiv = (void *)getglext("glGetVertexAttribiv");
|
||||
qglEnableVertexAttribArray = (void *)getglext("glEnableVertexAttribArray");
|
||||
qglDisableVertexAttribArray = (void *)getglext("glDisableVertexAttribArray");
|
||||
qglGetUniformLocationARB = (void *)getglext("glGetUniformLocation");
|
||||
qglUniformMatrix4fvARB = (void *)getglext("glUniformMatrix4fv");
|
||||
qglUniformMatrix3x4fv = (void *)getglext("glUniformMatrix3x4fv");
|
||||
|
@ -803,6 +800,10 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
|
|||
qglUniform2fvARB = (void *)getglext("glUniform2fv");
|
||||
qglUniform1iARB = (void *)getglext("glUniform1i");
|
||||
qglUniform1fARB = (void *)getglext("glUniform1f");
|
||||
qglVertexAttribPointer = (void *)getglext("glVertexAttribPointer");
|
||||
qglGetVertexAttribiv = (void *)getglext("glGetVertexAttribiv");
|
||||
qglEnableVertexAttribArray = (void *)getglext("glEnableVertexAttribArray");
|
||||
qglDisableVertexAttribArray = (void *)getglext("glDisableVertexAttribArray");
|
||||
Con_DPrintf("GLSL available\n");
|
||||
}
|
||||
else if (GL_CheckExtension("GL_ARB_fragment_shader")
|
||||
|
@ -1181,10 +1182,15 @@ GLhandleARB GLSlang_CreateShader (char *name, int ver, char **precompilerconstan
|
|||
/*required version not supported, don't even try*/
|
||||
if (ver > gl_config.maxglslversion)
|
||||
return 0;
|
||||
|
||||
prstrings[strings] = va("#version %u\n", ver);
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
#ifdef FTE_TARGET_WEB
|
||||
//emscripten prefixes our shader with a precision specifier, and then the browser bitches as the (otherwise valid) #version, so don't say anything at all if its ver 100, and the browser won't complain
|
||||
if (ver != 100)
|
||||
#endif
|
||||
{
|
||||
prstrings[strings] = va("#version %u\n", ver);
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
}
|
||||
}
|
||||
|
||||
while(*precompilerconstants)
|
||||
|
@ -1484,6 +1490,7 @@ void GL_Init(void *(*getglfunction) (char *name))
|
|||
qglScissor = (void *)getglcore("glScissor");
|
||||
qglPolygonOffset = (void *)getglext("glPolygonOffset");
|
||||
#endif
|
||||
#ifndef FTE_TARGET_WEB
|
||||
qglAlphaFunc = (void *)getglcore("glAlphaFunc");
|
||||
qglBegin = (void *)getglcore("glBegin");
|
||||
qglClearDepth = (void *)getglcore("glClearDepth");
|
||||
|
@ -1527,7 +1534,7 @@ void GL_Init(void *(*getglfunction) (char *name))
|
|||
qglVertex2f = (void *)getglcore("glVertex2f");
|
||||
qglVertex3f = (void *)getglcore("glVertex3f");
|
||||
qglVertex3fv = (void *)getglcore("glVertex3fv");
|
||||
|
||||
#endif
|
||||
|
||||
//various vertex array stuff.
|
||||
qglArrayElement = (void *)getglcore("glArrayElement");
|
||||
|
|
|
@ -114,6 +114,10 @@ extern r_config_t r_config;
|
|||
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#ifdef GL_STATIC
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <GL/glext.h>
|
||||
#endif
|
||||
#endif
|
||||
//#include <GL/glu.h>
|
||||
#include "glsupp.h"
|
||||
|
@ -585,6 +589,32 @@ void R_NetGraph (void);
|
|||
#define qglFramebufferTexture2DEXT qglFramebufferTexture2D
|
||||
#define qglDeleteRenderbuffersEXT qglDeleteRenderbuffers
|
||||
//#define qglCompressedTexImage2DARB qglCompressedTexImage2D
|
||||
|
||||
#define qglCreateProgramObjectARB glCreateProgram
|
||||
#define qglDeleteProgramObject_ glDeleteProgram
|
||||
#define qglDeleteShaderObject_ glDeleteShader
|
||||
#define qglUseProgramObjectARB glUseProgram
|
||||
#define qglCreateShaderObjectARB glCreateShader
|
||||
#define qglShaderSourceARB glShaderSource
|
||||
#define qglCompileShaderARB glCompileShader
|
||||
#define qglGetProgramParameteriv_ glGetProgramiv
|
||||
#define qglGetShaderParameteriv_ glGetShaderiv
|
||||
#define qglAttachObjectARB glAttachShader
|
||||
#define qglGetProgramInfoLog_ glGetProgramInfoLog
|
||||
#define qglGetShaderInfoLog_ glGetShaderInfoLog
|
||||
#define qglLinkProgramARB glLinkProgram
|
||||
#define qglBindAttribLocationARB glBindAttribLocation
|
||||
#define qglGetAttribLocationARB glGetAttribLocation
|
||||
#define qglGetUniformLocationARB glGetUniformLocation
|
||||
#define qglUniformMatrix4fvARB glUniformMatrix4fv
|
||||
#define qglUniform4fARB glUniform4f
|
||||
#define qglUniform4fvARB glUniform4fv
|
||||
#define qglUniform3fARB glUniform3f
|
||||
#define qglUniform3fvARB glUniform3fv
|
||||
#define qglUniform2fvARB glUniform2fv
|
||||
#define qglUniform1iARB glUniform1i
|
||||
#define qglUniform1fARB glUniform1f
|
||||
|
||||
#else
|
||||
extern void (APIENTRY *qglBindTexture) (GLenum target, GLuint texture);
|
||||
extern void (APIENTRY *qglBlendFunc) (GLenum sfactor, GLenum dfactor);
|
||||
|
@ -645,6 +675,32 @@ extern void (APIENTRY *qglFramebufferTexture2DEXT)(GLenum target, GLenum attachm
|
|||
extern void (APIENTRY *qglFramebufferRenderbufferEXT)(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint textureId);
|
||||
extern GLenum (APIENTRY *qglCheckFramebufferStatusEXT)(GLenum target);
|
||||
|
||||
|
||||
//glslang - arb_shader_objects
|
||||
extern FTEPFNGLCREATEPROGRAMOBJECTARBPROC qglCreateProgramObjectARB;
|
||||
extern FTEPFNGLDELETEOBJECTARBPROC qglDeleteProgramObject_;
|
||||
extern FTEPFNGLDELETEOBJECTARBPROC qglDeleteShaderObject_;
|
||||
extern FTEPFNGLUSEPROGRAMOBJECTARBPROC qglUseProgramObjectARB;
|
||||
extern FTEPFNGLCREATESHADEROBJECTARBPROC qglCreateShaderObjectARB;
|
||||
extern FTEPFNGLSHADERSOURCEARBPROC qglShaderSourceARB;
|
||||
extern FTEPFNGLCOMPILESHADERARBPROC qglCompileShaderARB;
|
||||
extern FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetProgramParameteriv_;
|
||||
extern FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetShaderParameteriv_;
|
||||
extern FTEPFNGLATTACHOBJECTARBPROC qglAttachObjectARB;
|
||||
extern FTEPFNGLGETINFOLOGARBPROC qglGetProgramInfoLog_;
|
||||
extern FTEPFNGLGETINFOLOGARBPROC qglGetShaderInfoLog_;
|
||||
extern FTEPFNGLLINKPROGRAMARBPROC qglLinkProgramARB;
|
||||
extern FTEPFNGLBINDATTRIBLOCATIONARBPROC qglBindAttribLocationARB;
|
||||
extern FTEPFNGLGETATTRIBLOCATIONARBPROC qglGetAttribLocationARB;
|
||||
extern FTEPFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB;
|
||||
extern FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix4fvARB;
|
||||
extern FTEPFNGLUNIFORM4FARBPROC qglUniform4fARB;
|
||||
extern FTEPFNGLUNIFORM4FVARBPROC qglUniform4fvARB;
|
||||
extern FTEPFNGLUNIFORM3FARBPROC qglUniform3fARB;
|
||||
extern FTEPFNGLUNIFORM3FVARBPROC qglUniform3fvARB;
|
||||
extern FTEPFNGLUNIFORM2FVARBPROC qglUniform2fvARB;
|
||||
extern FTEPFNGLUNIFORM1IARBPROC qglUniform1iARB;
|
||||
extern FTEPFNGLUNIFORM1FARBPROC qglUniform1fARB;
|
||||
extern FTEPFNGLVERTEXATTRIBPOINTER qglVertexAttribPointer;
|
||||
extern FTEPFNGLGETVERTEXATTRIBIV qglGetVertexAttribiv;
|
||||
extern FTEPFNGLENABLEVERTEXATTRIBARRAY qglEnableVertexAttribArray;
|
||||
|
@ -917,6 +973,9 @@ extern void (APIENTRY *qglTexSubImage1D) (GLenum target, GLint level, GLint xoff
|
|||
extern void (APIENTRY *qglTranslated) (GLdouble x, GLdouble y, GLdouble z);
|
||||
extern void (APIENTRY *qglTranslatef) (GLfloat x, GLfloat y, GLfloat z);
|
||||
|
||||
extern FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix4x3fv;
|
||||
extern FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix3x4fv;
|
||||
|
||||
#ifdef _WIN32
|
||||
extern BOOL (WINAPI *qwglCopyContext)(HGLRC, HGLRC, UINT);
|
||||
extern HGLRC (WINAPI *qwglCreateContext)(HDC);
|
||||
|
@ -939,34 +998,6 @@ extern PFNGLBINDPROGRAMARBPROC qglBindProgramARB;
|
|||
extern PFNGLGENPROGRAMSARBPROC qglGenProgramsARB;
|
||||
*/
|
||||
|
||||
//glslang - arb_shader_objects
|
||||
extern FTEPFNGLCREATEPROGRAMOBJECTARBPROC qglCreateProgramObjectARB;
|
||||
extern FTEPFNGLDELETEOBJECTARBPROC qglDeleteProgramObject_;
|
||||
extern FTEPFNGLDELETEOBJECTARBPROC qglDeleteShaderObject_;
|
||||
extern FTEPFNGLUSEPROGRAMOBJECTARBPROC qglUseProgramObjectARB;
|
||||
extern FTEPFNGLCREATESHADEROBJECTARBPROC qglCreateShaderObjectARB;
|
||||
extern FTEPFNGLSHADERSOURCEARBPROC qglShaderSourceARB;
|
||||
extern FTEPFNGLCOMPILESHADERARBPROC qglCompileShaderARB;
|
||||
extern FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetProgramParameteriv_;
|
||||
extern FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetShaderParameteriv_;
|
||||
extern FTEPFNGLATTACHOBJECTARBPROC qglAttachObjectARB;
|
||||
extern FTEPFNGLGETINFOLOGARBPROC qglGetProgramInfoLog_;
|
||||
extern FTEPFNGLGETINFOLOGARBPROC qglGetShaderInfoLog_;
|
||||
extern FTEPFNGLLINKPROGRAMARBPROC qglLinkProgramARB;
|
||||
extern FTEPFNGLBINDATTRIBLOCATIONARBPROC qglBindAttribLocationARB;
|
||||
extern FTEPFNGLGETATTRIBLOCATIONARBPROC qglGetAttribLocationARB;
|
||||
extern FTEPFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB;
|
||||
extern FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix4fvARB;
|
||||
extern FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix4x3fv;
|
||||
extern FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix3x4fv;
|
||||
extern FTEPFNGLUNIFORM4FARBPROC qglUniform4fARB;
|
||||
extern FTEPFNGLUNIFORM4FVARBPROC qglUniform4fvARB;
|
||||
extern FTEPFNGLUNIFORM3FARBPROC qglUniform3fARB;
|
||||
extern FTEPFNGLUNIFORM3FVARBPROC qglUniform3fvARB;
|
||||
extern FTEPFNGLUNIFORM2FVARBPROC qglUniform2fvARB;
|
||||
extern FTEPFNGLUNIFORM1IARBPROC qglUniform1iARB;
|
||||
extern FTEPFNGLUNIFORM1FARBPROC qglUniform1fARB;
|
||||
|
||||
extern FTEPFNGLLOCKARRAYSEXTPROC qglLockArraysEXT;
|
||||
extern FTEPFNGLUNLOCKARRAYSEXTPROC qglUnlockArraysEXT;
|
||||
|
||||
|
|
|
@ -5,7 +5,149 @@
|
|||
#include "netinc.h"
|
||||
|
||||
#if defined(WEBCLIENT)
|
||||
#if defined(NACL)
|
||||
|
||||
#if defined(FTE_TARGET_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vfsfile_t funcs;
|
||||
unsigned long offset;
|
||||
unsigned long length;
|
||||
char data[];
|
||||
} mfile_t;
|
||||
static int VFSMEM_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestoread)
|
||||
{
|
||||
mfile_t *f = (mfile_t*)file;
|
||||
if (f->offset >= f->length)
|
||||
return -1; //eof!
|
||||
if (bytestoread > f->length - f->offset)
|
||||
bytestoread = f->length - f->offset; //eof!
|
||||
memcpy(buffer, &f->data[f->offset], bytestoread);
|
||||
f->offset += bytestoread;
|
||||
return bytestoread;
|
||||
}
|
||||
static int VFSMEM_WriteBytes (struct vfsfile_s *file, const void *buffer, int bytestoread)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static qboolean VFSMEM_Seek (struct vfsfile_s *file, unsigned long pos)
|
||||
{
|
||||
mfile_t *f = (mfile_t*)file;
|
||||
f->offset = pos;
|
||||
return true;
|
||||
}
|
||||
static unsigned long VFSMEM_Tell (struct vfsfile_s *file)
|
||||
{
|
||||
mfile_t *f = (mfile_t*)file;
|
||||
return f->offset;
|
||||
}
|
||||
static unsigned long VFSMEM_GetSize (struct vfsfile_s *file)
|
||||
{
|
||||
mfile_t *f = (mfile_t*)file;
|
||||
return f->length;
|
||||
}
|
||||
static void VFSMEM_Close(vfsfile_t *file)
|
||||
{
|
||||
free(file);
|
||||
}
|
||||
static void VFSMEM_Flush(struct vfsfile_s *file)
|
||||
{
|
||||
}
|
||||
static vfsfile_t *VFSMEM_File(void *data, unsigned int datasize)
|
||||
{
|
||||
/*create a file which is already unlinked*/
|
||||
mfile_t *f;
|
||||
f = malloc(sizeof(*f) + datasize);
|
||||
if (!f)
|
||||
return NULL;
|
||||
f->funcs.ReadBytes = VFSMEM_ReadBytes;
|
||||
f->funcs.WriteBytes = VFSMEM_WriteBytes;
|
||||
f->funcs.Seek = VFSMEM_Seek;
|
||||
f->funcs.Tell = VFSMEM_Tell;
|
||||
f->funcs.GetLen = VFSMEM_GetSize;
|
||||
f->funcs.Close = VFSMEM_Close;
|
||||
f->funcs.Flush = VFSMEM_Flush;
|
||||
f->offset = 0;
|
||||
f->length = datasize;
|
||||
memcpy(f->data, data, datasize);
|
||||
|
||||
return &f->funcs;
|
||||
}
|
||||
|
||||
static void DL_Abort(struct dl_download *dl)
|
||||
{
|
||||
dl->ctx = NULL;
|
||||
}
|
||||
static void DL_OnLoad(void *c, void *data, int datasize)
|
||||
{
|
||||
struct dl_download *dl = c;
|
||||
Con_Printf("download %p: success\n", dl);
|
||||
|
||||
//make sure the file is 'open'.
|
||||
if (!dl->file)
|
||||
{
|
||||
if (*dl->localname)
|
||||
{
|
||||
Con_Printf("create file\n");
|
||||
FS_CreatePath(dl->localname, FS_GAME);
|
||||
dl->file = FS_OpenVFS(dl->localname, "w+b", FS_GAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
//emscripten does not close the file. plus we seem to end up with infinite loops.
|
||||
Con_Printf("temp file\n");
|
||||
dl->file = VFSMEM_File(data, datasize);
|
||||
}
|
||||
}
|
||||
|
||||
if (dl->file)
|
||||
{
|
||||
Con_Printf("writing to file\n");
|
||||
VFS_WRITE(dl->file, data, datasize);
|
||||
}
|
||||
|
||||
dl->replycode = 200;
|
||||
dl->completed += datasize;
|
||||
dl->status = DL_FINISHED;
|
||||
}
|
||||
static void DL_OnError(void *c)
|
||||
{
|
||||
struct dl_download *dl = c;
|
||||
Con_Printf("download %p: error\n", dl);
|
||||
|
||||
dl->replycode = 404; //we don't actually know. should we not do this?
|
||||
dl->status = DL_FAILED;
|
||||
}
|
||||
|
||||
//this becomes a poll function. the main thread will call this once a frame or so.
|
||||
qboolean HTTPDL_Decide(struct dl_download *dl)
|
||||
{
|
||||
const char *url = dl->redir;
|
||||
if (!*url)
|
||||
url = dl->url;
|
||||
|
||||
if (dl->ctx)
|
||||
{
|
||||
if (dl->status == DL_FAILED || dl->status == DL_FINISHED)
|
||||
{
|
||||
DL_Abort(dl);
|
||||
return false; //safe to destroy it now
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dl->status = DL_ACTIVE;
|
||||
dl->abort = DL_Abort;
|
||||
dl->ctx = dl;
|
||||
|
||||
Con_Printf("Sending %p request for %s\n", dl, url);
|
||||
emscripten_async_wget_data(url, dl, DL_OnLoad, DL_OnError);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#elif defined(NACL)
|
||||
#include <ppapi/c/pp_errors.h>
|
||||
#include <ppapi/c/ppb_core.h>
|
||||
#include <ppapi/c/pp_file_info.h>
|
||||
|
|
|
@ -1684,9 +1684,6 @@ void Q_InitProgs(void)
|
|||
// svprogfuncs->ToggleBreak(svprogfuncs, "", 0, 2);
|
||||
// svprogfuncs->SetWatchPoint(svprogfuncs, "");
|
||||
|
||||
sv.world.max_edicts = pr_maxedicts.value;
|
||||
if (sv.world.max_edicts > MAX_EDICTS)
|
||||
sv.world.max_edicts = MAX_EDICTS;
|
||||
sv.world.edict_size = PR_InitEnts(svprogfuncs, sv.world.max_edicts);
|
||||
|
||||
if (progstype == PROG_QW)
|
||||
|
|
|
@ -269,7 +269,7 @@ typedef struct
|
|||
|
||||
svcustomtents_t customtents[255];
|
||||
|
||||
int csqcentversion[MAX_EDICTS];//prevents ent versions from going backwards
|
||||
int *csqcentversion;//prevents ent versions from going backwards
|
||||
} server_t;
|
||||
|
||||
typedef enum
|
||||
|
|
|
@ -537,6 +537,11 @@ void SV_UnspawnServer (void) //terminate the running server.
|
|||
sv.world.worldmodel = NULL;
|
||||
sv.state = ss_dead;
|
||||
*sv.name = '\0';
|
||||
if (sv.csqcentversion)
|
||||
{
|
||||
BZ_Free(sv.csqcentversion);
|
||||
sv.csqcentversion = NULL;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
|
@ -565,6 +570,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
|
|||
{
|
||||
func_t f;
|
||||
char *file;
|
||||
extern cvar_t pr_maxedicts;
|
||||
|
||||
gametype_e newgametype;
|
||||
|
||||
|
@ -678,6 +684,9 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
|
|||
|
||||
PR_Deinit();
|
||||
|
||||
if (sv.csqcentversion)
|
||||
BZ_Free(sv.csqcentversion);
|
||||
|
||||
// wipe the entire per-level structure
|
||||
memset (&sv, 0, sizeof(sv));
|
||||
|
||||
|
@ -888,6 +897,15 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
|
|||
|
||||
sv.state = ss_loading;
|
||||
|
||||
sv.world.max_edicts = pr_maxedicts.value;
|
||||
if (sv.world.max_edicts > MAX_EDICTS)
|
||||
sv.world.max_edicts = MAX_EDICTS;
|
||||
#ifdef PEXT_CSQC
|
||||
sv.csqcentversion = BZ_Malloc(sizeof(*sv.csqcentversion) * sv.world.max_edicts);
|
||||
for (i=0 ; i<sv.world.max_edicts ; i++)
|
||||
sv.csqcentversion[i] = 1; //force all csqc edicts to start off as version 1
|
||||
#endif
|
||||
|
||||
newgametype = svs.gametype;
|
||||
#ifdef HLSERVER
|
||||
if (SVHL_InitGame())
|
||||
|
@ -1080,9 +1098,9 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
|
|||
|
||||
#ifdef PEXT_CSQC
|
||||
if (svs.clients[i].csqcentsequence)
|
||||
memset(svs.clients[i].csqcentsequence, 0, sizeof(svs.clients[i].csqcentsequence));
|
||||
memset(svs.clients[i].csqcentsequence, 0, sizeof(*svs.clients[i].csqcentsequence) * svs.clients[i].max_net_ents);
|
||||
if (svs.clients[i].csqcentversions)
|
||||
memset(svs.clients[i].csqcentversions, 0, sizeof(svs.clients[i].csqcentversions));
|
||||
memset(svs.clients[i].csqcentversions, 0, sizeof(*svs.clients[i].csqcentversions) * svs.clients[i].max_net_ents);
|
||||
#endif
|
||||
}
|
||||
for (; i < MAX_CLIENTS; i++)
|
||||
|
@ -1091,11 +1109,6 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
|
|||
SV_DropClient(&svs.clients[i]);
|
||||
svs.clients[i].namebuf[0] = '\0'; //kill all bots
|
||||
}
|
||||
#ifdef PEXT_CSQC
|
||||
for (i=0 ; i<MAX_EDICTS ; i++)
|
||||
sv.csqcentversion[i] = 1; //force all csqc edicts to start off as version 1
|
||||
#endif
|
||||
|
||||
break;
|
||||
case GT_QUAKE2:
|
||||
#ifdef Q2SERVER
|
||||
|
|
Loading…
Reference in a new issue