Some fixes for the emscripten port

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5404 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2019-02-23 09:29:20 +00:00
parent 519630045c
commit d65d4f6ff1
12 changed files with 162 additions and 86 deletions

View File

@ -27,6 +27,7 @@ THREADS="-j 4"
TARGETS_LINUX="qcc-rel rel dbg vk-rel plugins-rel plugins-dbg" TARGETS_LINUX="qcc-rel rel dbg vk-rel plugins-rel plugins-dbg"
TARGETS_WINDOWS="sv-rel gl-rel vk-rel mingl-rel m-rel d3d-rel qcc-rel qccgui-scintilla qccgui-dbg gl-dbg sv-dbg plugins-dbg plugins-rel" TARGETS_WINDOWS="sv-rel gl-rel vk-rel mingl-rel m-rel d3d-rel qcc-rel qccgui-scintilla qccgui-dbg gl-dbg sv-dbg plugins-dbg plugins-rel"
TARGETS_WEB="gl-rel"
########### NaCL stuff ########### NaCL stuff
NACL_SDK_ROOT=/opt/nacl_sdk/pepper_31/ NACL_SDK_ROOT=/opt/nacl_sdk/pepper_31/
@ -169,7 +170,7 @@ if [ "$BUILD_DOS" == "y" ]; then
fi fi
if [ "$BUILD_WEB" != "n" ]; then if [ "$BUILD_WEB" != "n" ]; then
source $EMSDK/emsdk_env.sh >> /dev/null source $EMSDK/emsdk_env.sh >> /dev/null
build "Emscripten" web FTE_TARGET=web gl-rel CC=emcc build "Emscripten" web FTE_TARGET=web $TARGETS_WEB CC=emcc
fi fi
if [ "$BUILD_LINUX" != "n" ] && [ "$BUILD_SDL" != "n" ] && [ "$(uname -m)" != "x86_64" ]; then if [ "$BUILD_LINUX" != "n" ] && [ "$BUILD_SDL" != "n" ] && [ "$(uname -m)" != "x86_64" ]; then
build "Linux 32-bit (SDL)" linux_x86_sdl FTE_TARGET=SDL BITS=32 LTO=1 build "Linux 32-bit (SDL)" linux_x86_sdl FTE_TARGET=SDL BITS=32 LTO=1

View File

@ -569,7 +569,7 @@ ifeq ($(FTE_TARGET),vc)
WARNINGFLAGS=-W3 -D_CRT_SECURE_NO_WARNINGS WARNINGFLAGS=-W3 -D_CRT_SECURE_NO_WARNINGS
GNUC_FUNCS= GNUC_FUNCS=
else else
WARNINGFLAGS=-Wall -Wno-pointer-sign -Wno-unknown-pragmas -Wno-format-zero-length -Wno-strict-aliasing -Wcast-align WARNINGFLAGS=-Wall -Wno-pointer-sign -Wno-unknown-pragmas -Wno-format-zero-length -Wno-strict-aliasing #-Wcast-align
GNUC_FUNCS= -Dstrnicmp=strncasecmp -Dstricmp=strcasecmp GNUC_FUNCS= -Dstrnicmp=strncasecmp -Dstricmp=strcasecmp
endif endif
@ -1610,10 +1610,10 @@ ifeq ($(FTE_TARGET),web)
JSLIBS=--js-library web/ftejslib.js -s LEGACY_GL_EMULATION=0 JSLIBS=--js-library web/ftejslib.js -s LEGACY_GL_EMULATION=0
EMCC_ARGS=$(JSLIBS) $(WEB_PREJS) -s ERROR_ON_UNDEFINED_SYMBOLS=1 EMCC_ARGS=$(JSLIBS) $(WEB_PREJS) -s ERROR_ON_UNDEFINED_SYMBOLS=1
RELEASE_CFLAGS=-DOMIT_QCC -DGL_STATIC -DFTE_TARGET_WEB RELEASE_CFLAGS=-DOMIT_QCC -DGL_STATIC -DFTE_TARGET_WEB
DEBUG_CFLAGS=-g -DOMIT_QCC -DGL_STATIC -DFTE_TARGET_WEB DEBUG_CFLAGS=-g4 -DOMIT_QCC -DGL_STATIC -DFTE_TARGET_WEB
RELEASE_LDFLAGS=-s ASM_JS=1 -O3 -s TOTAL_MEMORY=$(ASMJS_MEMORY) $(EMCC_ARGS) RELEASE_LDFLAGS=-O3 -s TOTAL_MEMORY=$(ASMJS_MEMORY) $(EMCC_ARGS) -s NO_FILESYSTEM=1
# RELEASE_LDFLAGS=-s ASM_JS=0 -O1 -s TOTAL_MEMORY=$(WEB_MEMORY) $(EMCC_ARGS) # RELEASE_LDFLAGS=-O1 -s TOTAL_MEMORY=$(WEB_MEMORY) $(EMCC_ARGS)
DEBUG_LDFLAGS=-O0 -g4 -s TOTAL_MEMORY=$(WEB_MEMORY) $(EMCC_ARGS) -s SAFE_HEAP=1 -s ALIASING_FUNCTION_POINTERS=0 -s ASSERTIONS=2 DEBUG_LDFLAGS=-O0 -g4 -s TOTAL_MEMORY=$(WEB_MEMORY) $(EMCC_ARGS) -s SAFE_HEAP=1 -s ALIASING_FUNCTION_POINTERS=0 -s ASSERTIONS=2 -s NO_FILESYSTEM=1
CC?=emcc CC?=emcc
CXX?=emcc CXX?=emcc
#BASELDFLAGS= #BASELDFLAGS=
@ -2072,14 +2072,14 @@ web-rel:
cp $(BASE_DIR)/web/fteshell.html $(RELEASE_DIR)/ftewebgl.html cp $(BASE_DIR)/web/fteshell.html $(RELEASE_DIR)/ftewebgl.html
@gzip -f $(RELEASE_DIR)/ftewebgl.html @gzip -f $(RELEASE_DIR)/ftewebgl.html
@gzip -f $(RELEASE_DIR)/ftewebgl.js @gzip -f $(RELEASE_DIR)/ftewebgl.js
@gzip -f $(RELEASE_DIR)/ftewebgl.js.mem @gzip -f $(RELEASE_DIR)/ftewebgl.wasm
web-dbg: web-dbg:
@PATH="$(EMSCRIPTENPATH)" $(MAKE) gl-dbg FTE_TARGET=web CC="$(EMCC)" @PATH="$(EMSCRIPTENPATH)" $(MAKE) gl-dbg FTE_TARGET=web CC="$(EMCC)"
cp $(BASE_DIR)/web/fteshell.html $(DEBUG_DIR)/ftewebgl.html cp $(BASE_DIR)/web/fteshell.html $(DEBUG_DIR)/ftewebgl.html
@gzip -f $(DEBUG_DIR)/ftewebgl.html @gzip -f $(DEBUG_DIR)/ftewebgl.html
@gzip -f $(DEBUG_DIR)/ftewebgl.js @gzip -f $(DEBUG_DIR)/ftewebgl.js
@gzip -f $(DEBUG_DIR)/ftewebgl.js.map @gzip -f $(DEBUG_DIR)/ftewebgl.wasm
################################################# #################################################
#android #android

View File

@ -274,10 +274,10 @@ qbyte *ReadTargaFile(qbyte *buf, int length, int *width, int *height, uploadfmt_
tgaheader.cm_idx = MISSHORT(buf+3); tgaheader.cm_idx = MISSHORT(buf+3);
tgaheader.cm_len = MISSHORT(buf+5); tgaheader.cm_len = MISSHORT(buf+5);
tgaheader.cm_size = buf[7]; tgaheader.cm_size = buf[7];
tgaheader.originx = LittleShort(*(short *)&buf[8]); tgaheader.originx = MISSHORT(buf+8);
tgaheader.originy = LittleShort(*(short *)&buf[10]); tgaheader.originy = MISSHORT(buf+10);
tgaheader.width = LittleShort(*(short *)&buf[12]); tgaheader.width = MISSHORT(buf+12);
tgaheader.height = LittleShort(*(short *)&buf[14]); tgaheader.height = MISSHORT(buf+14);
tgaheader.bpp = buf[16]; tgaheader.bpp = buf[16];
tgaheader.attribs = buf[17]; tgaheader.attribs = buf[17];
@ -2347,7 +2347,7 @@ static qbyte *ReadRawBMPFile(qbyte *buf, int length, int *width, int *height, si
bmpheader_t h; bmpheader_t h;
qbyte *data; qbyte *data;
memcpy(&h, (bmpheader_t *)buf, sizeof(h)); memcpy(&h, buf, sizeof(h));
h.SizeofBITMAPINFOHEADER = LittleLong(h.SizeofBITMAPINFOHEADER); h.SizeofBITMAPINFOHEADER = LittleLong(h.SizeofBITMAPINFOHEADER);
h.Width = LittleLong(h.Width); h.Width = LittleLong(h.Width);
h.Height = LittleLong(h.Height); h.Height = LittleLong(h.Height);
@ -4735,7 +4735,7 @@ qbyte *ReadRawImageFile(qbyte *buf, int len, int *width, int *height, uploadfmt_
if (w >= 3 && h >= 4 && w*h+sizeof(int)*2 == len) if (w >= 3 && h >= 4 && w*h+sizeof(int)*2 == len)
{ //quake lmp { //quake lmp
qboolean foundalpha = false; qboolean foundalpha = false;
qbyte *in = (qbyte*)((int*)buf+2); qbyte *in = buf+sizeof(int)*2;
data = BZ_Malloc(w * h * sizeof(int)); data = BZ_Malloc(w * h * sizeof(int));
for (i = 0; i < w * h; i++) for (i = 0; i < w * h; i++)
{ {
@ -4751,7 +4751,7 @@ qbyte *ReadRawImageFile(qbyte *buf, int len, int *width, int *height, uploadfmt_
else if (w >= 3 && h >= 4 && w*h+sizeof(int)*2+768+2 == len) else if (w >= 3 && h >= 4 && w*h+sizeof(int)*2+768+2 == len)
{ //halflife. should probably verify that those 2 extra bytes read as 256. { //halflife. should probably verify that those 2 extra bytes read as 256.
qboolean foundalpha = false; qboolean foundalpha = false;
qbyte *in = (qbyte*)((int*)buf+2); qbyte *in = buf+sizeof(int)*2;
qbyte *palette = in + w*h+2, *p; qbyte *palette = in + w*h+2, *p;
data = BZ_Malloc(w * h * sizeof(int)); data = BZ_Malloc(w * h * sizeof(int));
for (i = 0; i < w * h; i++) for (i = 0; i < w * h; i++)

View File

@ -2551,7 +2551,11 @@ static void *PDECL MP_PRReadFile (const char *path, qbyte *(PDECL *buf_get)(void
return buffer; return buffer;
} }
else else
{
if (FS_FLocateFile(path, FSLF_IFFOUND, &loc))
Con_Printf("Not loading %s because it comes from an untrusted source\n", path);
return NULL; return NULL;
}
} }
static int PDECL MP_PRFileSize (const char *path) static int PDECL MP_PRFileSize (const char *path)
{ {

View File

@ -143,6 +143,22 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <alloca.h> #include <alloca.h>
#endif #endif
#ifdef FTE_TARGET_WEB //emscripten's filesystem is throwing all sorts of exceptions and making it hard to debug real bugs.
#define NOSTDIO
#endif
#ifdef NOSTDIO
#define stat stat_nolink
#define fopen fopen_nolink
#define fread fread_nolink
#define fwrite fwrite_nolink
#define fclose fclose_nolink
#define fseek fseek_nolink
#define open open_nolink
#define read read_nolink
#define write write_nolink
#define close close_nolink
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -4219,6 +4219,7 @@ Cmd_Init
*/ */
void Cmd_Init (void) void Cmd_Init (void)
{ {
macro_count = 0;
// //
// register our commands // register our commands
// //

View File

@ -1086,6 +1086,7 @@ static void QDECL FS_AddFileHash(int depth, const char *fname, fsbucket_t *fileh
fs_hash_files++; fs_hash_files++;
} }
#ifndef FTE_TARGET_WEB
static void FS_RebuildFSHash(qboolean domutex) static void FS_RebuildFSHash(qboolean domutex)
{ {
int depth = 1; int depth = 1;
@ -1134,6 +1135,7 @@ static void FS_RebuildFSHash(qboolean domutex)
Con_DPrintf("%i unique files, %i duplicates\n", fs_hash_files, fs_hash_dups); Con_DPrintf("%i unique files, %i duplicates\n", fs_hash_files, fs_hash_dups);
} }
#endif
static void FS_RebuildFSHash_Update(const char *fname) static void FS_RebuildFSHash_Update(const char *fname)
{ {
@ -2538,7 +2540,13 @@ static void FS_AddManifestPackages(searchpath_t **oldpaths, const char *purepath
if (palen > ptlen && (fs_manifest->package[i].path[ptlen] == '/' || fs_manifest->package[i].path[ptlen] == '\\' )&& !strncmp(purepath, fs_manifest->package[i].path, ptlen)) if (palen > ptlen && (fs_manifest->package[i].path[ptlen] == '/' || fs_manifest->package[i].path[ptlen] == '\\' )&& !strncmp(purepath, fs_manifest->package[i].path, ptlen))
{ {
Q_snprintfz(qhash, sizeof(qhash), "%#x", fs_manifest->package[i].crc); Q_snprintfz(qhash, sizeof(qhash), "%#x", fs_manifest->package[i].crc);
FS_AddHashedPackage(oldpaths,purepath,logicalpaths,search,loadstuff, fs_manifest->package[i].path,fs_manifest->package[i].crcknown?qhash:NULL,fs_manifest->package[i].prefix, SPF_COPYPROTECTED|(fs_manifest->security==MANIFEST_SECURITY_NOT?SPF_UNTRUSTED:0)); FS_AddHashedPackage(oldpaths,purepath,logicalpaths,search,loadstuff, fs_manifest->package[i].path,fs_manifest->package[i].crcknown?qhash:NULL,fs_manifest->package[i].prefix, SPF_COPYPROTECTED|
#ifdef FTE_TARGET_WEB
0 //web targets consider manifest packages as trusted, because they're about as trusted as the engine/html that goes with it.
#else
(fs_manifest->security==MANIFEST_SECURITY_NOT?SPF_UNTRUSTED:0)
#endif
);
} }
} }
} }
@ -4067,7 +4075,16 @@ static void FS_ReloadPackFiles_f(void)
FS_BeginManifestUpdates(); FS_BeginManifestUpdates();
} }
#if defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT) && !defined(_XBOX) #ifdef NOSTDIO
qboolean Sys_DoDirectoryPrompt(char *basepath, size_t basepathsize, const char *poshname, const char *savedname)
{
return false;
}
qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *basepath, int basepathlen, qboolean allowprompts)
{
return false;
}
#elif defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT) && !defined(_XBOX)
#include "winquake.h" #include "winquake.h"
#ifdef MINGW #ifdef MINGW
#define byte BYTE //some versions of mingw headers are broken slightly. this lets it compile. #define byte BYTE //some versions of mingw headers are broken slightly. this lets it compile.
@ -6189,7 +6206,6 @@ void FS_ArbitraryFile_c(int argn, const char *partial, struct xcommandargcomplet
static void COM_InitHomedir(ftemanifest_t *man) static void COM_InitHomedir(ftemanifest_t *man)
{ {
int i; int i;
char *ev;
qboolean usehome; qboolean usehome;
//FIXME: this should come from the manifest, as fte_GAME or something //FIXME: this should come from the manifest, as fte_GAME or something
@ -6235,7 +6251,7 @@ static void COM_InitHomedir(ftemanifest_t *man)
if (!*com_homepath) if (!*com_homepath)
{ {
ev = getenv("USERPROFILE"); char *ev = getenv("USERPROFILE");
if (ev) if (ev)
Q_snprintfz(com_homepath, sizeof(com_homepath), "%s/My Documents/My Games/%s/", ev, HOMESUBDIR); Q_snprintfz(com_homepath, sizeof(com_homepath), "%s/My Documents/My Games/%s/", ev, HOMESUBDIR);
} }
@ -6299,60 +6315,62 @@ static void COM_InitHomedir(ftemanifest_t *man)
} }
#endif #endif
} }
#else #elif !defined(NOSTDIO)
//on unix, we use environment settings.
//if $HOME/.fte/ exists then we use that because of legacy reasons.
//but if it doesn't exist then we use $XDG_DATA_HOME/.fte instead
//we used to use $HOME/.#HOMESUBDIR/ but this is now only used if it actually exists AND the new path doesn't.
//new installs use $XDG_DATA_HOME/#HOMESUBDIR/ instead
ev = getenv("FTEHOME");
if (ev && *ev)
{ {
if (ev[strlen(ev)-1] == '/') //on unix, we use environment settings.
Q_strncpyz(com_homepath, ev, sizeof(com_homepath)); //if $HOME/.fte/ exists then we use that because of legacy reasons.
else //but if it doesn't exist then we use $XDG_DATA_HOME/.fte instead
Q_snprintfz(com_homepath, sizeof(com_homepath), "%s/", ev); //we used to use $HOME/.#HOMESUBDIR/ but this is now only used if it actually exists AND the new path doesn't.
usehome = true; // always use home on unix unless told not to //new installs use $XDG_DATA_HOME/#HOMESUBDIR/ instead
ev = NULL;
}
else
ev = getenv("HOME");
if (ev && *ev)
{
const char *xdghome;
char oldhome[MAX_OSPATH];
char newhome[MAX_OSPATH];
struct stat s;
xdghome = getenv("XDG_DATA_HOME"); char *ev = getenv("FTEHOME");
if (!xdghome || !*xdghome) if (ev && *ev)
xdghome = va("%s/.local/share", ev);
if (man && man->installation)
{ {
if (xdghome[strlen(xdghome)-1] == '/')
Q_snprintfz(com_homepath, sizeof(com_homepath), "%s%s/", xdghome, *man->installation?man->installation:HOMESUBDIR);
else
Q_snprintfz(com_homepath, sizeof(com_homepath), "%s/%s/", xdghome, *man->installation?man->installation:HOMESUBDIR);
}
else
{
if (xdghome[strlen(xdghome)-1] == '/')
Q_snprintfz(newhome, sizeof(newhome), "%s%s/", xdghome, HOMESUBDIR);
else
Q_snprintfz(newhome, sizeof(newhome), "%s/%s/", xdghome, HOMESUBDIR);
if (ev[strlen(ev)-1] == '/') if (ev[strlen(ev)-1] == '/')
Q_snprintfz(oldhome, sizeof(oldhome), "%s.%s/", ev, HOMESUBDIR); Q_strncpyz(com_homepath, ev, sizeof(com_homepath));
else else
Q_snprintfz(oldhome, sizeof(oldhome), "%s/.%s/", ev, HOMESUBDIR); Q_snprintfz(com_homepath, sizeof(com_homepath), "%s/", ev);
usehome = true; // always use home on unix unless told not to
if (stat(newhome, &s) == -1 && stat(oldhome, &s) != -1) ev = NULL;
Q_strncpyz(com_homepath, oldhome, sizeof(com_homepath)); }
else else
Q_strncpyz(com_homepath, newhome, sizeof(com_homepath)); ev = getenv("HOME");
if (ev && *ev)
{
const char *xdghome;
char oldhome[MAX_OSPATH];
char newhome[MAX_OSPATH];
struct stat s;
xdghome = getenv("XDG_DATA_HOME");
if (!xdghome || !*xdghome)
xdghome = va("%s/.local/share", ev);
if (man && man->installation)
{
if (xdghome[strlen(xdghome)-1] == '/')
Q_snprintfz(com_homepath, sizeof(com_homepath), "%s%s/", xdghome, *man->installation?man->installation:HOMESUBDIR);
else
Q_snprintfz(com_homepath, sizeof(com_homepath), "%s/%s/", xdghome, *man->installation?man->installation:HOMESUBDIR);
}
else
{
if (xdghome[strlen(xdghome)-1] == '/')
Q_snprintfz(newhome, sizeof(newhome), "%s%s/", xdghome, HOMESUBDIR);
else
Q_snprintfz(newhome, sizeof(newhome), "%s/%s/", xdghome, HOMESUBDIR);
if (ev[strlen(ev)-1] == '/')
Q_snprintfz(oldhome, sizeof(oldhome), "%s.%s/", ev, HOMESUBDIR);
else
Q_snprintfz(oldhome, sizeof(oldhome), "%s/.%s/", ev, HOMESUBDIR);
if (stat(newhome, &s) == -1 && stat(oldhome, &s) != -1)
Q_strncpyz(com_homepath, oldhome, sizeof(com_homepath));
else
Q_strncpyz(com_homepath, newhome, sizeof(com_homepath));
}
usehome = true; // always use home on unix unless told not to
} }
usehome = true; // always use home on unix unless told not to
} }
#endif #endif

View File

@ -47,7 +47,7 @@ extern cvar_t r_shadow_bumpscale_basetexture;
//these are in model.c (or gl_model.c) //these are in model.c (or gl_model.c)
qboolean Mod_LoadVertexes (model_t *loadmodel, qbyte *mod_base, lump_t *l); qboolean Mod_LoadVertexes (model_t *loadmodel, qbyte *mod_base, lump_t *l);
qboolean Mod_LoadVertexNormals (model_t *loadmodel, qbyte *mod_base, lump_t *l); qboolean Mod_LoadVertexNormals (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base, lump_t *l);
qboolean Mod_LoadEdges (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm); qboolean Mod_LoadEdges (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm);
qboolean Mod_LoadMarksurfaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm); qboolean Mod_LoadMarksurfaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm);
qboolean Mod_LoadSurfedges (model_t *loadmodel, qbyte *mod_base, lump_t *l); qboolean Mod_LoadSurfedges (model_t *loadmodel, qbyte *mod_base, lump_t *l);
@ -4439,7 +4439,7 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
// load into heap // load into heap
noerrors = noerrors && Mod_LoadVertexes (mod, mod_base, &header.lumps[Q2LUMP_VERTEXES]); noerrors = noerrors && Mod_LoadVertexes (mod, mod_base, &header.lumps[Q2LUMP_VERTEXES]);
if (header.version == BSPVERSION_Q2W) if (header.version == BSPVERSION_Q2W)
/*noerrors = noerrors &&*/ Mod_LoadVertexNormals(mod, mod_base, &header.lumps[19]); /*noerrors = noerrors &&*/ Mod_LoadVertexNormals(mod, bspx, mod_base, &header.lumps[19]);
noerrors = noerrors && Mod_LoadEdges (mod, mod_base, &header.lumps[Q2LUMP_EDGES], false); noerrors = noerrors && Mod_LoadEdges (mod, mod_base, &header.lumps[Q2LUMP_EDGES], false);
noerrors = noerrors && Mod_LoadSurfedges (mod, mod_base, &header.lumps[Q2LUMP_SURFEDGES]); noerrors = noerrors && Mod_LoadSurfedges (mod, mod_base, &header.lumps[Q2LUMP_SURFEDGES]);
if (noerrors) if (noerrors)

View File

@ -3171,14 +3171,45 @@ static void BE_SubmitMeshChain(qboolean usetesselation)
if (drawcount == countof(counts)) if (drawcount == countof(counts))
{ {
qglMultiDrawElements(batchtype, counts, GL_INDEX_TYPE, indicies, drawcount); qglMultiDrawElements(batchtype, counts, GL_INDEX_TYPE, indicies, drawcount);
RQuantAdd(RQUANT_DRAWS, drawcount);
drawcount = 0; drawcount = 0;
} }
counts[drawcount] = endi-starti; counts[drawcount] = endi-starti;
indicies[drawcount] = (index_t*)shaderstate.sourcevbo->indicies.gl.addr + starti; indicies[drawcount] = (index_t*)shaderstate.sourcevbo->indicies.gl.addr + starti;
drawcount++; drawcount++;
RQuantAdd(RQUANT_PRIMITIVEINDICIES, endi-starti);
} }
qglMultiDrawElements(batchtype, counts, GL_INDEX_TYPE, indicies, drawcount); qglMultiDrawElements(batchtype, counts, GL_INDEX_TYPE, indicies, drawcount);
RQuantAdd(RQUANT_DRAWS, drawcount);
} }
#if 0 //def FTE_TARGET_WEB
else if (shaderstate.meshcount > 1)
{ //FIXME: not really needed if index lists are consecutive
index_t *tmp;
int ebo;
for (endi = 0, m = 0; m < shaderstate.meshcount; m++)
{
mesh = shaderstate.meshes[m];
endi += mesh->numindexes;
}
tmp = alloca(endi * sizeof(*tmp));
for (endi = 0, m = 0; m < shaderstate.meshcount; m++)
{
mesh = shaderstate.meshes[m];
for (starti = 0; starti < mesh->numindexes; starti++)
tmp[endi++] = mesh->vbofirstvert + mesh->indexes[starti];
}
shaderstate.streamid = (shaderstate.streamid + 1) & (sizeof(shaderstate.streamvbo)/sizeof(shaderstate.streamvbo[0]) - 1);
ebo = shaderstate.streamebo[shaderstate.streamid];
GL_SelectEBO(ebo);
qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(*tmp) * endi, tmp, GL_STREAM_DRAW_ARB);
qglDrawElements(batchtype, endi, GL_INDEX_TYPE, NULL);
RQuantAdd(RQUANT_DRAWS, 1);
RQuantAdd(RQUANT_PRIMITIVEINDICIES, endi);
}
#endif
else else
{ {
GL_SelectEBO(shaderstate.sourcevbo->indicies.gl.vbo); GL_SelectEBO(shaderstate.sourcevbo->indicies.gl.vbo);
@ -4122,7 +4153,7 @@ void GLBE_SelectEntity(entity_t *ent)
shaderstate.lastuniform = 0; shaderstate.lastuniform = 0;
} }
#if 1 #ifndef GLSLONLY
static void BE_SelectFog(vec3_t colour, float alpha, float density) static void BE_SelectFog(vec3_t colour, float alpha, float density)
{ {
float zscale; float zscale;

View File

@ -762,7 +762,7 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
#ifdef FTE_TARGET_WEB #ifdef FTE_TARGET_WEB
if (encoding == PTI_WHOLEFILE) if (encoding == PTI_WHOLEFILE)
{ {
emscriptenfte_gl_loadtexturefile(tex->num, &tex->width, &tex->height, mips->mip[i].data, mips->mip[i].datasize); emscriptenfte_gl_loadtexturefile(tex->num, &tex->width, &tex->height, mips->mip[0].data, mips->mip[0].datasize, tex->ident);
return true; return true;
} }
#endif #endif

View File

@ -36,7 +36,7 @@ NORETURN void emscriptenfte_abortmainloop(const char *caller);
//we're trying to avoid including libpng+libjpeg+libogg in javascript due to it being redundant bloat. //we're trying to avoid including libpng+libjpeg+libogg in javascript due to it being redundant bloat.
//to use such textures/sounds, we can just 'directly' load them via webgl //to use such textures/sounds, we can just 'directly' load them via webgl
void emscriptenfte_gl_loadtexturefile(int gltexid, int *width, int *height, void *data, int datasize); void emscriptenfte_gl_loadtexturefile(int gltexid, int *width, int *height, void *data, int datasize, const char *fname);
void emscriptenfte_al_loadaudiofile(int al_buf, void *data, int datasize); void emscriptenfte_al_loadaudiofile(int al_buf, void *data, int datasize);
//avoid all of emscripten's sdl emulation. //avoid all of emscripten's sdl emulation.

View File

@ -133,12 +133,12 @@ mergeInto(LibraryManager.library,
event.movementX = event.webkitMovementX; event.movementX = event.webkitMovementX;
event.movementY = event.webkitMovementY; event.movementY = event.webkitMovementY;
} }
Runtime.dynCall('viidddd', FTEC.evcb.mouse, [0, false, event.movementX, event.movementY, 0, 0]); Runtime.dynCall('viiffff', FTEC.evcb.mouse, [0, false, event.movementX, event.movementY, 0, 0]);
} }
else else
{ {
var rect = Module['canvas'].getBoundingClientRect(); var rect = Module['canvas'].getBoundingClientRect();
Runtime.dynCall('viidddd', FTEC.evcb.mouse, [0, true, (event.clientX - rect.left)*(Module['canvas'].width/rect.width), (event.clientY - rect.top)*(Module['canvas'].height/rect.height), 0, 0]); Runtime.dynCall('viiffff', FTEC.evcb.mouse, [0, true, (event.clientX - rect.left)*(Module['canvas'].width/rect.width), (event.clientY - rect.top)*(Module['canvas'].height/rect.height), 0, 0]);
} }
} }
break; break;
@ -228,7 +228,7 @@ mergeInto(LibraryManager.library,
{ {
var t = touches[i]; var t = touches[i];
if (FTEC.evcb.mouse) if (FTEC.evcb.mouse)
Runtime.dynCall('viidddd', FTEC.evcb.mouse, [t.identifier+1, true, t.pageX, t.pageY, 0, Math.sqrt(t.radiusX*t.radiusX+t.radiusY*t.radiusY)]); Runtime.dynCall('viiffff', FTEC.evcb.mouse, [t.identifier+1, true, t.pageX, t.pageY, 0, Math.sqrt(t.radiusX*t.radiusX+t.radiusY*t.radiusY)]);
if (FTEC.evcb.button) if (FTEC.evcb.button)
{ {
if (event.type == 'touchstart') if (event.type == 'touchstart')
@ -271,7 +271,7 @@ mergeInto(LibraryManager.library,
delete FTEH.gamepads[gp.index]; delete FTEH.gamepads[gp.index];
if (FTEC.evcb.jaxis) //try and clear out the axis when released. if (FTEC.evcb.jaxis) //try and clear out the axis when released.
for (var j = 0; j < 6; j+=1) for (var j = 0; j < 6; j+=1)
Runtime.dynCall('viidi', FTEC.evcb.jaxis, [gp.index, j, 0, true]); Runtime.dynCall('viifi', FTEC.evcb.jaxis, [gp.index, j, 0, true]);
if (FTEC.evcb.jbutton) //try and clear out the axis when released. if (FTEC.evcb.jbutton) //try and clear out the axis when released.
for (var j = 0; j < 32+4; j+=1) for (var j = 0; j < 32+4; j+=1)
Runtime.dynCall('viiii', FTEC.evcb.jbutton, [gp.index, j, 0, true]); Runtime.dynCall('viiii', FTEC.evcb.jbutton, [gp.index, j, 0, true]);
@ -396,7 +396,7 @@ mergeInto(LibraryManager.library,
} }
} }
for (var j = 0; j < gp.axes.length; j+=1) for (var j = 0; j < gp.axes.length; j+=1)
Runtime.dynCall('viidi', FTEC.evcb.jaxis, [gp.index, j, gp.axes[j], gp.mapping=="standard"]); Runtime.dynCall('viifi', FTEC.evcb.jaxis, [gp.index, j, gp.axes[j], gp.mapping=="standard"]);
} }
}, },
emscriptenfte_setupcanvas__deps: ['$FTEC', '$Browser', 'emscriptenfte_buf_createfromarraybuf'], emscriptenfte_setupcanvas__deps: ['$FTEC', '$Browser', 'emscriptenfte_buf_createfromarraybuf'],
@ -541,14 +541,14 @@ mergeInto(LibraryManager.library,
FTEC.vrDisplay.getFrameData(FTEC.vrframeData); FTEC.vrDisplay.getFrameData(FTEC.vrframeData);
} }
try // try
{ // {
dovsync = Runtime.dynCall('i', fnc, []); dovsync = Runtime.dynCall('i', fnc, []);
} // }
catch(err) // catch(err)
{ // {
console.log(err); // console.log(err);
} // }
if (vr) if (vr)
FTEC.vrDisplay.submitFrame(); FTEC.vrDisplay.submitFrame();
if (dovsync) if (dovsync)
@ -1109,7 +1109,7 @@ console.log("onerror: " + _url);
} }
}, },
emscriptenfte_gl_loadtexturefile : function(texid, widthptr, heightptr, dataptr, datasize) emscriptenfte_gl_loadtexturefile : function(texid, widthptr, heightptr, dataptr, datasize, fname)
{ {
function encode64(data) { function encode64(data) {
var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
@ -1141,8 +1141,14 @@ console.log("onerror: " + _url);
var img = new Image(); var img = new Image();
var gltex = GL.textures[texid]; var gltex = GL.textures[texid];
img.name = Pointer_stringify(fname);
img.onload = function() img.onload = function()
{ {
if (img.width < 1 || img.height < 1)
{
console.log("emscriptenfte_gl_loadtexturefile("+img.name+"): bad image size\n");
return;
}
var oldtex = GLctx.getParameter(GLctx.TEXTURE_BINDING_2D); //blurgh, try to avoid breaking anything in this unexpected event. var oldtex = GLctx.getParameter(GLctx.TEXTURE_BINDING_2D); //blurgh, try to avoid breaking anything in this unexpected event.
GLctx.bindTexture(GLctx.TEXTURE_2D, gltex); GLctx.bindTexture(GLctx.TEXTURE_2D, gltex);
GLctx.texImage2D(GLctx.TEXTURE_2D, 0, GLctx.RGBA, GLctx.RGBA, GLctx.UNSIGNED_BYTE, img); GLctx.texImage2D(GLctx.TEXTURE_2D, 0, GLctx.RGBA, GLctx.RGBA, GLctx.UNSIGNED_BYTE, img);
@ -1151,6 +1157,5 @@ console.log("onerror: " + _url);
}; };
img.crossorigin = true; img.crossorigin = true;
img.src = "data:image/png;base64," + encode64(HEAPU8.subarray(dataptr, dataptr+datasize)); img.src = "data:image/png;base64," + encode64(HEAPU8.subarray(dataptr, dataptr+datasize));
img.onload();
} }
}); });