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:
Spoike 2013-04-04 08:08:49 +00:00
parent 0807d7a28d
commit 49197218bc
14 changed files with 386 additions and 111 deletions

View file

@ -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=

View file

@ -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
}

View file

@ -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");

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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)
{

View file

@ -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");

View file

@ -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;

View file

@ -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>

View file

@ -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)

View file

@ -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

View file

@ -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