1
0
Fork 0
forked from fte/fteqw

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:
Spoike 2013-07-31 00:20:16 +00:00
parent ab2351a18f
commit a343d8d843
10 changed files with 252 additions and 53 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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