Reduce webgl dependancies (no more q2/q3/plugins which wouldn't work anyway). Use websockets via our own javascript thunk to avoid issues/weirdness with emscripten's bsdsockets emulation.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4444 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
ab2351a18f
commit
a343d8d843
10 changed files with 252 additions and 53 deletions
|
@ -1119,13 +1119,14 @@ endif
|
|||
|
||||
ifeq ($(FTE_TARGET),web)
|
||||
WEB_PREJS ?= --pre-js web/prejs.js
|
||||
WEB_MEMORY?=402653184
|
||||
WEB_MEMORY?=402653184 #384mb
|
||||
ASMJS_MEMORY?=536870912 #512mb (required for asm.js)
|
||||
RELEASE_CFLAGS=-DOMIT_QCC -DGL_STATIC -DFTE_TARGET_WEB
|
||||
DEBUG_CFLAGS=-g --jcache -DOMIT_QCC -DGL_STATIC -DFTE_TARGET_WEB
|
||||
RELEASE_LDFLAGS=-O1 $(WEB_PREJS) -s TOTAL_MEMORY=$(WEB_MEMORY) --js-library web/ftejslib.js --shell-file web/fteshell.html
|
||||
RELEASE_LDFLAGS=-s ASM_JS=1 -O2 $(WEB_PREJS) -s TOTAL_MEMORY=$(ASMJS_MEMORY) --js-library web/ftejslib.js --shell-file web/fteshell.html
|
||||
# RELEASE_LDFLAGS=-O1 $(WEB_PREJS) -s TOTAL_MEMORY=$(WEB_MEMORY) --js-library web/ftejslib.js --shell-file web/fteshell.html
|
||||
DEBUG_LDLAGS=-O0 $(WEB_PREJS) -s TOTAL_MEMORY=$(WEB_MEMORY) --js-library web/ftejslib.js
|
||||
CC=emcc
|
||||
#-s ASM_JS=1
|
||||
#BASELDFLAGS=
|
||||
|
||||
#mostly we inherit the sdl defaults. because we can, however emscripten does not support sdl cd code.
|
||||
|
|
|
@ -4578,7 +4578,9 @@ void Host_Shutdown(void)
|
|||
}
|
||||
host_initialized = false;
|
||||
|
||||
#ifdef PLUGINS
|
||||
Plug_Shutdown(false);
|
||||
#endif
|
||||
|
||||
//disconnect server/client/etc
|
||||
CL_Disconnect_f();
|
||||
|
@ -4617,7 +4619,9 @@ void Host_Shutdown(void)
|
|||
|
||||
FS_Shutdown();
|
||||
|
||||
#ifdef PLUGINS
|
||||
Plug_Shutdown(true);
|
||||
#endif
|
||||
|
||||
Con_Shutdown();
|
||||
Memory_DeInit();
|
||||
|
|
|
@ -1313,12 +1313,6 @@ cin_t *Media_WinAvi_TryLoad(char *name)
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
cin_t *Media_WinAvi_TryLoad(char *name)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
//AVI Support (windows)
|
||||
|
@ -2106,11 +2100,6 @@ cin_t *Media_Gecko_TryLoad(char *name)
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
cin_t *Media_Gecko_TryLoad(char *name)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
//Gecko Support
|
||||
|
@ -2784,10 +2773,8 @@ static media_encoder_funcs_t capture_avi =
|
|||
};
|
||||
#endif
|
||||
|
||||
|
||||
static media_encoder_funcs_t *pluginencodersfunc[8];
|
||||
static struct plugin_s *pluginencodersplugin[8];
|
||||
|
||||
qboolean Media_RegisterEncoder(struct plugin_s *plug, media_encoder_funcs_t *funcs)
|
||||
{
|
||||
int i;
|
||||
|
@ -2806,7 +2793,7 @@ void Media_StopRecordFilm_f(void);
|
|||
/*funcs==null closes ALL decoders from this plugin*/
|
||||
qboolean Media_UnregisterEncoder(struct plugin_s *plug, media_encoder_funcs_t *funcs)
|
||||
{
|
||||
qboolean success = true;
|
||||
qboolean success = false;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(pluginencodersfunc)/sizeof(pluginencodersfunc[0]); i++)
|
||||
|
@ -2815,9 +2802,9 @@ qboolean Media_UnregisterEncoder(struct plugin_s *plug, media_encoder_funcs_t *f
|
|||
{
|
||||
if (currentcapture_funcs == funcs)
|
||||
Media_StopRecordFilm_f();
|
||||
|
||||
plugindecodersfunc[i] = NULL;
|
||||
plugindecodersplugin[i] = NULL;
|
||||
success = true;
|
||||
pluginencodersfunc[i] = NULL;
|
||||
pluginencodersplugin[i] = NULL;
|
||||
if (funcs)
|
||||
return success;
|
||||
}
|
||||
|
@ -3131,7 +3118,6 @@ void Media_RecordFilm_f (void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (capturesound.ival)
|
||||
{
|
||||
sndkhz = snd_speed?snd_speed:48000;
|
||||
|
|
|
@ -1656,7 +1656,15 @@ void V_RenderView (void)
|
|||
SCR_VRectForPlayer(&r_refdef.grect, viewnum);
|
||||
V_RenderPlayerViews(r_refdef.playerview);
|
||||
|
||||
Plug_SBar(r_refdef.playerview);
|
||||
#ifdef PLUGINS
|
||||
Plug_SBar (r_refdef.playerview);
|
||||
#else
|
||||
if (Sbar_ShouldDraw())
|
||||
{
|
||||
Sbar_Draw (r_refdef.playerview);
|
||||
Sbar_DrawScoreboard ();
|
||||
}
|
||||
#endif
|
||||
SCR_TileClear ();
|
||||
}
|
||||
r_refdef.playerview = NULL;
|
||||
|
|
|
@ -271,22 +271,43 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#endif
|
||||
|
||||
#ifdef FTE_TARGET_WEB
|
||||
#undef VOICECHAT
|
||||
#endif
|
||||
//try to trim the fat
|
||||
#undef VOICECHAT //too lazy to compile speex
|
||||
#undef HLCLIENT //dlls...
|
||||
#undef HLSERVER //dlls...
|
||||
#undef CL_MASTER //bah. use the site to specify the servers.
|
||||
#undef SV_MASTER //yeah, because that makes sense in a browser
|
||||
#undef RAGDOLL //no ode
|
||||
#undef TCPCONNECT //err...
|
||||
#undef IRCCONNECT //not happening
|
||||
#undef RUNTIMELIGHTING //too slow
|
||||
#undef PLUGINS //pointless
|
||||
#undef SUPPORT_ICE //utterly pointless
|
||||
#undef VM_Q1 //no dlls
|
||||
#undef MAP_PROC //meh
|
||||
#undef HALFLIFEMODELS //blurgh
|
||||
#undef WEBSERVER //hah, yeah, right
|
||||
#undef SUPPORT_ICE //kinda requires udp, but whatever
|
||||
|
||||
//extra features stripped to try to reduce memory footprints
|
||||
#undef Q2CLIENT
|
||||
#undef Q2SERVER //requires a dll anyway.
|
||||
#undef Q3CLIENT
|
||||
#undef Q3SERVER //trying to trim memory use
|
||||
#endif
|
||||
#ifdef ANDROID
|
||||
#undef RTLIGHTS
|
||||
#ifndef SPEEX_STATIC
|
||||
#undef VOICECHAT
|
||||
#undef RTLIGHTS
|
||||
#ifndef SPEEX_STATIC
|
||||
#undef VOICECHAT
|
||||
#endif
|
||||
#undef TEXTEDITOR
|
||||
#endif
|
||||
#undef TEXTEDITOR
|
||||
#endif
|
||||
#ifdef NACL
|
||||
#undef CL_MASTER //no sockets support
|
||||
#undef SV_MASTER //noone uses this anyway
|
||||
#undef WEBSERVER //no sockets support (certainly no servers)
|
||||
#undef TCPCONNECT
|
||||
#undef IRCCONNECT
|
||||
#if defined(NACL)
|
||||
#undef CL_MASTER //no sockets support
|
||||
#undef SV_MASTER //noone uses this anyway
|
||||
#undef WEBSERVER //no sockets support (certainly no servers)
|
||||
#undef TCPCONNECT
|
||||
#undef IRCCONNECT
|
||||
#endif
|
||||
|
||||
#ifndef MULTITHREAD
|
||||
|
|
|
@ -2332,6 +2332,24 @@ unsigned int unicode_charofsfrombyteofs(char *str, unsigned int byteofs)
|
|||
return chars;
|
||||
}
|
||||
|
||||
#ifdef FTE_TARGET_WEB
|
||||
//targets that don't support towupper/towlower...
|
||||
#define towupper Q_towupper
|
||||
#define towlower Q_towlower
|
||||
int towupper(int c)
|
||||
{
|
||||
if (c < 128)
|
||||
return toupper(c);
|
||||
return c;
|
||||
}
|
||||
int towlower(int c)
|
||||
{
|
||||
if (c < 128)
|
||||
return tolower(c);
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t unicode_strtoupper(char *in, char *out, size_t outsize)
|
||||
{
|
||||
//warning: towupper is locale-specific (eg: turkish has both I and dotted-I and thus i should transform to dotted-I rather than to I).
|
||||
|
|
|
@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#define PORT_ANY -1
|
||||
|
||||
#ifdef NACL
|
||||
#if defined(NACL) || defined(FTE_TARGET_WEB)
|
||||
#define HAVE_WEBSOCKCL
|
||||
#endif
|
||||
|
||||
|
|
|
@ -98,7 +98,11 @@ typedef struct ftenet_generic_connection_s {
|
|||
|
||||
netadrtype_t addrtype[FTENET_ADDRTYPES];
|
||||
qboolean islisten;
|
||||
#ifdef HAVE_PACKET
|
||||
SOCKET thesocket;
|
||||
#else
|
||||
int thesocket;
|
||||
#endif
|
||||
} ftenet_generic_connection_t;
|
||||
|
||||
|
||||
|
@ -4061,7 +4065,92 @@ struct ftenet_generic_connection_s *FTENET_IRCConnect_EstablishConnection(qboole
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WEBSOCKCL
|
||||
#ifdef FTE_TARGET_WEB
|
||||
int emscriptenfte_ws_connect(char *url);
|
||||
int emscriptenfte_ws_close(int sock);
|
||||
int emscriptenfte_ws_cansend(int sock, int extra, int maxpending);
|
||||
int emscriptenfte_ws_send(int sock, void *data, int len);
|
||||
int emscriptenfte_ws_recv(int sock, void *data, int len);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ftenet_generic_connection_t generic;
|
||||
int sock;
|
||||
netadr_t remoteadr;
|
||||
qboolean failed;
|
||||
} ftenet_websocket_connection_t;
|
||||
|
||||
static void FTENET_WebSocket_Close(ftenet_generic_connection_t *gcon)
|
||||
{
|
||||
ftenet_websocket_connection_t *wsc = (void*)gcon;
|
||||
emscriptenfte_ws_close(wsc->sock);
|
||||
}
|
||||
static qboolean FTENET_WebSocket_GetPacket(ftenet_generic_connection_t *gcon)
|
||||
{
|
||||
ftenet_websocket_connection_t *wsc = (void*)gcon;
|
||||
net_message.cursize = emscriptenfte_ws_recv(wsc->sock, net_message_buffer, sizeof(net_message_buffer));
|
||||
if (net_message.cursize > 0)
|
||||
{
|
||||
net_from = wsc->remoteadr;
|
||||
return true;
|
||||
}
|
||||
net_message.cursize = 0;//just incase
|
||||
return false;
|
||||
}
|
||||
static qboolean FTENET_WebSocket_SendPacket(ftenet_generic_connection_t *gcon, int length, void *data, netadr_t *to)
|
||||
{
|
||||
ftenet_websocket_connection_t *wsc = (void*)gcon;
|
||||
if (NET_CompareAdr(to, &wsc->remoteadr))
|
||||
{
|
||||
emscriptenfte_ws_send(wsc->sock, data, length);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static ftenet_generic_connection_t *FTENET_WebSocket_EstablishConnection(qboolean isserver, const char *address)
|
||||
{
|
||||
ftenet_websocket_connection_t *newcon;
|
||||
|
||||
netadr_t adr;
|
||||
int newsocket;
|
||||
|
||||
if (isserver)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (!NET_StringToAdr(address, 80, &adr))
|
||||
return NULL; //couldn't resolve the name
|
||||
newsocket = emscriptenfte_ws_connect(address);
|
||||
if (newsocket < 0)
|
||||
return NULL;
|
||||
newcon = Z_Malloc(sizeof(*newcon));
|
||||
if (newcon)
|
||||
{
|
||||
Q_strncpyz(newcon->generic.name, "WebSocket", sizeof(newcon->generic.name));
|
||||
newcon->generic.GetPacket = FTENET_WebSocket_GetPacket;
|
||||
newcon->generic.SendPacket = FTENET_WebSocket_SendPacket;
|
||||
newcon->generic.Close = FTENET_WebSocket_Close;
|
||||
|
||||
newcon->generic.islisten = isserver;
|
||||
newcon->generic.addrtype[0] = NA_WEBSOCKET;
|
||||
newcon->generic.addrtype[1] = NA_INVALID;
|
||||
|
||||
newcon->generic.thesocket = INVALID_SOCKET;
|
||||
newcon->sock = newsocket;
|
||||
|
||||
newcon->remoteadr = adr;
|
||||
|
||||
return &newcon->generic;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef NACL
|
||||
#include <ppapi/c/pp_errors.h>
|
||||
#include <ppapi/c/pp_resource.h>
|
||||
#include <ppapi/c/ppb_core.h>
|
||||
|
@ -4080,8 +4169,8 @@ typedef struct
|
|||
PP_Resource sock;
|
||||
netadr_t remoteadr;
|
||||
|
||||
qboolean havepacket;
|
||||
struct PP_Var incomingpacket;
|
||||
qboolean havepacket;
|
||||
|
||||
qboolean failed;
|
||||
} ftenet_websocket_connection_t;
|
||||
|
@ -4130,7 +4219,7 @@ static void websocketclosed(void *user_data, int32_t result)
|
|||
// Z_Free(wsc);
|
||||
}
|
||||
|
||||
static void FTENET_WebSocket_Close(ftenet_generic_connection_t *gcon)
|
||||
static void FTENET_NaClWebSocket_Close(ftenet_generic_connection_t *gcon)
|
||||
{
|
||||
int res;
|
||||
/*meant to free the memory too, in this case we get the callback to do it*/
|
||||
|
@ -4140,7 +4229,7 @@ static void FTENET_WebSocket_Close(ftenet_generic_connection_t *gcon)
|
|||
ppb_websocket_interface->Close(wsc->sock, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeUndefined(), ccb);
|
||||
}
|
||||
|
||||
static qboolean FTENET_WebSocket_GetPacket(ftenet_generic_connection_t *gcon)
|
||||
static qboolean FTENET_NaClWebSocket_GetPacket(ftenet_generic_connection_t *gcon)
|
||||
{
|
||||
ftenet_websocket_connection_t *wsc = (void*)gcon;
|
||||
int res;
|
||||
|
@ -4198,7 +4287,7 @@ static qboolean FTENET_WebSocket_GetPacket(ftenet_generic_connection_t *gcon)
|
|||
}
|
||||
return false;
|
||||
}
|
||||
static qboolean FTENET_WebSocket_SendPacket(ftenet_generic_connection_t *gcon, int length, void *data, netadr_t *to)
|
||||
static qboolean FTENET_NaClWebSocket_SendPacket(ftenet_generic_connection_t *gcon, int length, void *data, netadr_t *to)
|
||||
{
|
||||
ftenet_websocket_connection_t *wsc = (void*)gcon;
|
||||
int res;
|
||||
|
@ -4257,9 +4346,9 @@ static ftenet_generic_connection_t *FTENET_WebSocket_EstablishConnection(qboolea
|
|||
ppb_websocket_interface->Connect(newsocket, str, NULL, 0, ccb);
|
||||
ppb_var_interface->Release(str);
|
||||
Q_strncpyz(newcon->generic.name, "WebSocket", sizeof(newcon->generic.name));
|
||||
newcon->generic.GetPacket = FTENET_WebSocket_GetPacket;
|
||||
newcon->generic.SendPacket = FTENET_WebSocket_SendPacket;
|
||||
newcon->generic.Close = FTENET_WebSocket_Close;
|
||||
newcon->generic.GetPacket = FTENET_NaClWebSocket_GetPacket;
|
||||
newcon->generic.SendPacket = FTENET_NaClWebSocket_SendPacket;
|
||||
newcon->generic.Close = FTENET_NaClWebSocket_Close;
|
||||
|
||||
newcon->generic.islisten = isserver;
|
||||
newcon->generic.addrtype[0] = NA_WEBSOCKET;
|
||||
|
@ -4884,7 +4973,6 @@ typedef struct
|
|||
unsigned short attrtype;
|
||||
unsigned short attrlen;
|
||||
} stunattr_t;
|
||||
#define SUPPORT_ICE
|
||||
#ifdef SUPPORT_ICE
|
||||
/*
|
||||
Interactive Connectivity Establishment (rfc 5245)
|
||||
|
@ -6129,8 +6217,10 @@ qboolean NET_WasSpecialPacket(netsrc_t netsrc)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_ICE
|
||||
if (NET_WasStun(netsrc))
|
||||
return true;
|
||||
#endif
|
||||
#ifdef HAVE_NATPMP
|
||||
if (NET_Was_NATPMP(collection))
|
||||
return true;
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
|
||||
#ifndef NACL
|
||||
#if !defined(NACL) && !defined(FTE_TARGET_WEB)
|
||||
#define HAVE_IPV4 //says we can send and receive AF_INET ipv4 udp packets.
|
||||
#define HAVE_TCP //says we can use tcp too (either ipv4 or ipv6)
|
||||
#define HAVE_PACKET //if we have the socket api at all...
|
||||
#endif
|
||||
|
||||
#ifdef FTE_TARGET_WEB
|
||||
#undef HAVE_PACKET //no udp packet interface.
|
||||
#undef HAVE_TCP //we should probably use websockets instead.
|
||||
#endif
|
||||
|
||||
#ifdef NACL
|
||||
#if defined(NACL) || defined(FTE_TARGET_WEB)
|
||||
|
||||
struct sockaddr
|
||||
{
|
||||
|
@ -252,4 +247,4 @@ typedef struct
|
|||
void (QDECL *ICE_CloseModule)(void *module); //closes all unclosed connections, with warning.
|
||||
} icefuncs_t;
|
||||
extern icefuncs_t iceapi;
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,82 @@
|
|||
|
||||
mergeInto(LibraryManager.library,
|
||||
{
|
||||
$FTESockets__deps: [],
|
||||
$FTESockets: {
|
||||
socks: []
|
||||
},
|
||||
emscriptenfte_ws_connect__deps: ['$FTESockets'],
|
||||
emscriptenfte_ws_connect : function(url)
|
||||
{
|
||||
var _url = Pointer_stringify(url);
|
||||
var s = {ws:null, inq:[], err:0};
|
||||
for (var i = 0; ; i+=1)
|
||||
{
|
||||
if (!FTESockets.socks[i])
|
||||
{
|
||||
s.ws = new WebSocket(_url, 'binary');
|
||||
if (!s.ws)
|
||||
return -1;
|
||||
FTESockets.socks[i] = s;
|
||||
s.ws.onerror = function(event) {s.err = 1;};
|
||||
s.ws.onclose = function(event) {s.err = 1;};
|
||||
// s.ws.onopen = function(event) {};
|
||||
s.ws.onmessage = function(event)
|
||||
{
|
||||
assert(typeof event.data !== 'string' && event.data.byteLength);
|
||||
s.inq.push(new Uint8Array(event.data));
|
||||
};
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
emscriptenfte_ws_close : function(sockid)
|
||||
{
|
||||
var s = FTESockets.socks[sockid];
|
||||
if (!s)
|
||||
return -1;
|
||||
s.ws.close();
|
||||
s.ws = null; //make sure to avoid circular references
|
||||
FTESockets.socks[sockid] = null; //socked is no longer accessible.
|
||||
return 0;
|
||||
},
|
||||
//separate call allows for more sane flood control when fragmentation is involved.
|
||||
emscriptenfte_ws_cansend : function(sockid, extra, maxpending)
|
||||
{
|
||||
var s = FTESockets.socks[sockid];
|
||||
if (!s)
|
||||
return 1; //go on punk, make my day.
|
||||
return ((s.ws.bufferedAmount+extra) < maxpending);
|
||||
},
|
||||
emscriptenfte_ws_send : function(sockid, data, len)
|
||||
{
|
||||
var s = FTESockets.socks[sockid];
|
||||
if (!s)
|
||||
return -1;
|
||||
s.s.send(HEAPU8.subarray(data, data+len).buffer);
|
||||
return len;
|
||||
},
|
||||
emscriptenfte_ws_recv : function(sockid, data, len)
|
||||
{
|
||||
var s = FTESockets.socks[sockid];
|
||||
if (!s)
|
||||
return -1;
|
||||
var inp = s.inq.shift();
|
||||
if (inp)
|
||||
{
|
||||
if (inp.length > len)
|
||||
inp.length = len;
|
||||
HEAPU8.set(inp, data);
|
||||
return inp.length;
|
||||
}
|
||||
if (s.err)
|
||||
return 0;
|
||||
return -1;
|
||||
},
|
||||
|
||||
|
||||
|
||||
emscriptenfte_async_wget_data2 : function(url, ctx, onload, onerror, onprogress)
|
||||
{
|
||||
var _url = Pointer_stringify(url);
|
||||
|
|
Loading…
Reference in a new issue