Playing around trying to make the emscriptem port more usable/nicer.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4371 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
594a297ffa
commit
d97a163011
|
@ -1105,8 +1105,8 @@ ifeq ($(FTE_TARGET),web)
|
||||||
WEB_MEMORY?=402653184
|
WEB_MEMORY?=402653184
|
||||||
RELEASE_CFLAGS=-DOMIT_QCC -DGL_STATIC -DFTE_TARGET_WEB
|
RELEASE_CFLAGS=-DOMIT_QCC -DGL_STATIC -DFTE_TARGET_WEB
|
||||||
DEBUG_CFLAGS=-g --jcache -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)
|
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)
|
DEBUG_LDLAGS=-O0 $(WEB_PREJS) -s TOTAL_MEMORY=$(WEB_MEMORY) --js-library web/ftejslib.js
|
||||||
CC=emcc
|
CC=emcc
|
||||||
#-s ASM_JS=1
|
#-s ASM_JS=1
|
||||||
#BASELDFLAGS=
|
#BASELDFLAGS=
|
||||||
|
|
|
@ -28,6 +28,7 @@ void (APIENTRY *qglGetFloatv) (GLenum pname, GLfloat *params);
|
||||||
void (APIENTRY *qglGetIntegerv) (GLenum pname, GLint *params);
|
void (APIENTRY *qglGetIntegerv) (GLenum pname, GLint *params);
|
||||||
const GLubyte * (APIENTRY *qglGetString) (GLenum name);
|
const GLubyte * (APIENTRY *qglGetString) (GLenum name);
|
||||||
void (APIENTRY *qglHint) (GLenum target, GLenum mode);
|
void (APIENTRY *qglHint) (GLenum target, GLenum mode);
|
||||||
|
GLboolean (APIENTRY *qglIsEnabled) (GLenum cap);
|
||||||
void (APIENTRY *qglPolygonOffset) (GLfloat factor, GLfloat units);
|
void (APIENTRY *qglPolygonOffset) (GLfloat factor, GLfloat units);
|
||||||
void (APIENTRY *qglReadPixels) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
|
void (APIENTRY *qglReadPixels) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
|
||||||
void (APIENTRY *qglTexImage2D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
void (APIENTRY *qglTexImage2D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
||||||
|
@ -110,7 +111,6 @@ void (APIENTRY *qglEnd) (void);
|
||||||
void (APIENTRY *qglEndList) (void);
|
void (APIENTRY *qglEndList) (void);
|
||||||
void (APIENTRY *qglFrustum) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
|
void (APIENTRY *qglFrustum) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
|
||||||
GLuint (APIENTRY *qglGenLists) (GLsizei range);
|
GLuint (APIENTRY *qglGenLists) (GLsizei range);
|
||||||
GLboolean (APIENTRY *qglIsEnabled) (GLenum cap);
|
|
||||||
void (APIENTRY *qglLoadIdentity) (void);
|
void (APIENTRY *qglLoadIdentity) (void);
|
||||||
void (APIENTRY *qglLoadMatrixf) (const GLfloat *m);
|
void (APIENTRY *qglLoadMatrixf) (const GLfloat *m);
|
||||||
void (APIENTRY *qglNormal3f) (GLfloat nx, GLfloat ny, GLfloat nz);
|
void (APIENTRY *qglNormal3f) (GLfloat nx, GLfloat ny, GLfloat nz);
|
||||||
|
@ -1507,6 +1507,7 @@ void GL_Init(void *(*getglfunction) (char *name))
|
||||||
qglGetIntegerv = (void *)getglcore("glGetIntegerv");
|
qglGetIntegerv = (void *)getglcore("glGetIntegerv");
|
||||||
qglGetString = (void *)getglcore("glGetString");
|
qglGetString = (void *)getglcore("glGetString");
|
||||||
qglHint = (void *)getglcore("glHint");
|
qglHint = (void *)getglcore("glHint");
|
||||||
|
qglIsEnabled = (void *)getglext("glIsEnabled");
|
||||||
qglReadPixels = (void *)getglcore("glReadPixels");
|
qglReadPixels = (void *)getglcore("glReadPixels");
|
||||||
qglTexImage2D = (void *)getglcore("glTexImage2D");
|
qglTexImage2D = (void *)getglcore("glTexImage2D");
|
||||||
qglTexSubImage2D = (void *)getglcore("glTexSubImage2D");
|
qglTexSubImage2D = (void *)getglcore("glTexSubImage2D");
|
||||||
|
@ -1596,7 +1597,6 @@ void GL_Init(void *(*getglfunction) (char *name))
|
||||||
|
|
||||||
qglGetTexEnviv = (void *)getglext("glGetTexEnviv");
|
qglGetTexEnviv = (void *)getglext("glGetTexEnviv");
|
||||||
qglGetPointerv = (void *)getglext("glGetPointerv");
|
qglGetPointerv = (void *)getglext("glGetPointerv");
|
||||||
qglIsEnabled = (void *)getglext("glIsEnabled");
|
|
||||||
|
|
||||||
qglGetStringi = (void *)getglext("glGetStringi");
|
qglGetStringi = (void *)getglext("glGetStringi");
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,6 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
|
||||||
{
|
{
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
Con_Printf("SDL GLVID_Init\n");
|
|
||||||
|
|
||||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);
|
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);
|
||||||
#ifndef FTE_TARGET_WEB
|
#ifndef FTE_TARGET_WEB
|
||||||
SDL_SetVideoMode( 0, 0, 0, 0 ); //to get around some SDL bugs
|
SDL_SetVideoMode( 0, 0, 0, 0 ); //to get around some SDL bugs
|
||||||
|
@ -89,7 +87,6 @@ void GLVID_DeInit (void)
|
||||||
ActiveApp = false;
|
ActiveApp = false;
|
||||||
|
|
||||||
IN_DeactivateMouse();
|
IN_DeactivateMouse();
|
||||||
Con_Printf("Restoring gamma\n");
|
|
||||||
SDL_SetGammaRamp (intitialgammaramps[0], intitialgammaramps[1], intitialgammaramps[2]);
|
SDL_SetGammaRamp (intitialgammaramps[0], intitialgammaramps[1], intitialgammaramps[2]);
|
||||||
|
|
||||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||||
|
@ -149,7 +146,7 @@ qboolean GLVID_ApplyGammaRamps (unsigned short *ramps)
|
||||||
if (gammaworks)
|
if (gammaworks)
|
||||||
{ //we have hardware gamma applied - if we're doing a BF, we don't want to reset to the default gamma (yuck)
|
{ //we have hardware gamma applied - if we're doing a BF, we don't want to reset to the default gamma (yuck)
|
||||||
SDL_SetGammaRamp (&ramps[0], &ramps[256], &ramps[512]);
|
SDL_SetGammaRamp (&ramps[0], &ramps[256], &ramps[512]);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
gammaworks = !SDL_SetGammaRamp (&ramps[0], &ramps[256], &ramps[512]);
|
gammaworks = !SDL_SetGammaRamp (&ramps[0], &ramps[256], &ramps[512]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,14 @@
|
||||||
#if defined(WEBCLIENT)
|
#if defined(WEBCLIENT)
|
||||||
|
|
||||||
#if defined(FTE_TARGET_WEB)
|
#if defined(FTE_TARGET_WEB)
|
||||||
|
|
||||||
|
|
||||||
|
#define MYJS 1
|
||||||
|
#if MYJS
|
||||||
|
#include "web/ftejslib.h"
|
||||||
|
#else
|
||||||
#include <emscripten/emscripten.h>
|
#include <emscripten/emscripten.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -82,43 +89,55 @@ static void DL_Abort(struct dl_download *dl)
|
||||||
static void DL_OnLoad(void *c, void *data, int datasize)
|
static void DL_OnLoad(void *c, void *data, int datasize)
|
||||||
{
|
{
|
||||||
struct dl_download *dl = c;
|
struct dl_download *dl = c;
|
||||||
Con_Printf("download %p: success\n", dl);
|
|
||||||
|
|
||||||
//make sure the file is 'open'.
|
//make sure the file is 'open'.
|
||||||
if (!dl->file)
|
if (!dl->file)
|
||||||
{
|
{
|
||||||
if (*dl->localname)
|
if (*dl->localname)
|
||||||
{
|
{
|
||||||
Con_Printf("create file\n");
|
|
||||||
FS_CreatePath(dl->localname, FS_GAME);
|
FS_CreatePath(dl->localname, FS_GAME);
|
||||||
dl->file = FS_OpenVFS(dl->localname, "w+b", FS_GAME);
|
dl->file = FS_OpenVFS(dl->localname, "w+b", FS_GAME);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//emscripten does not close the file. plus we seem to end up with infinite loops.
|
//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);
|
dl->file = VFSMEM_File(data, datasize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dl->file)
|
if (dl->file)
|
||||||
{
|
{
|
||||||
Con_Printf("writing to file\n");
|
|
||||||
VFS_WRITE(dl->file, data, datasize);
|
VFS_WRITE(dl->file, data, datasize);
|
||||||
}
|
}
|
||||||
|
|
||||||
dl->replycode = 200;
|
dl->replycode = 200;
|
||||||
|
#if !MYJS
|
||||||
dl->completed += datasize;
|
dl->completed += datasize;
|
||||||
|
#endif
|
||||||
dl->status = DL_FINISHED;
|
dl->status = DL_FINISHED;
|
||||||
}
|
}
|
||||||
|
#if MYJS
|
||||||
|
static void DL_OnError(void *c, int ecode)
|
||||||
|
#else
|
||||||
static void DL_OnError(void *c)
|
static void DL_OnError(void *c)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
struct dl_download *dl = c;
|
struct dl_download *dl = c;
|
||||||
Con_Printf("download %p: error\n", dl);
|
Con_Printf("download %p: error\n", dl);
|
||||||
|
|
||||||
|
#if MYJS
|
||||||
|
dl->replycode = ecode;
|
||||||
|
#else
|
||||||
dl->replycode = 404; //we don't actually know. should we not do this?
|
dl->replycode = 404; //we don't actually know. should we not do this?
|
||||||
|
#endif
|
||||||
dl->status = DL_FAILED;
|
dl->status = DL_FAILED;
|
||||||
}
|
}
|
||||||
|
static void DL_OnProgress(void *c, int position, int totalsize)
|
||||||
|
{
|
||||||
|
struct dl_download *dl = c;
|
||||||
|
dl->completed = position;
|
||||||
|
dl->totalsize = totalsize;
|
||||||
|
}
|
||||||
|
|
||||||
//this becomes a poll function. the main thread will call this once a frame or so.
|
//this becomes a poll function. the main thread will call this once a frame or so.
|
||||||
qboolean HTTPDL_Decide(struct dl_download *dl)
|
qboolean HTTPDL_Decide(struct dl_download *dl)
|
||||||
|
@ -141,8 +160,13 @@ qboolean HTTPDL_Decide(struct dl_download *dl)
|
||||||
dl->abort = DL_Abort;
|
dl->abort = DL_Abort;
|
||||||
dl->ctx = dl;
|
dl->ctx = dl;
|
||||||
|
|
||||||
Con_Printf("Sending %p request for %s\n", dl, url);
|
#if MYJS
|
||||||
|
emscriptenfte_async_wget_data2(url, dl, DL_OnLoad, DL_OnError, DL_OnProgress);
|
||||||
|
#else
|
||||||
|
//annoyingly, emscripten doesn't provide an onprogress callback, unlike firefox etc, so we can't actually tell how far its got.
|
||||||
|
//we'd need to provide our own js library to fix this. it can be done, I'm just lazy.
|
||||||
emscripten_async_wget_data(url, dl, DL_OnLoad, DL_OnError);
|
emscripten_async_wget_data(url, dl, DL_OnLoad, DL_OnError);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
void emscriptenfte_async_wget_data2(const char *url, void *ctx, void (*onload)(void*ctx,void*buf,int sz), void (*onerror)(void*ctx,int code), void (*onprogress)(void*ctx,int prog,int total));
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
|
||||||
|
mergeInto(LibraryManager.library,
|
||||||
|
{
|
||||||
|
emscriptenfte_async_wget_data2 : function(url, ctx, onload, onerror, onprogress)
|
||||||
|
{
|
||||||
|
var _url = Pointer_stringify(url);
|
||||||
|
|
||||||
|
var http = new XMLHttpRequest();
|
||||||
|
http.open('GET', _url, true);
|
||||||
|
http.responseType = 'arraybuffer';
|
||||||
|
|
||||||
|
http.onload = function(e)
|
||||||
|
{
|
||||||
|
if (http.status == 200)
|
||||||
|
{
|
||||||
|
var bar = new Uint8Array(http.response);
|
||||||
|
var buf = _malloc(bar.length);
|
||||||
|
HEAPU8.set(bar, buf);
|
||||||
|
if (onload)
|
||||||
|
Runtime.dynCall('viii', onload, [ctx, buf, bar.length]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (onerror)
|
||||||
|
Runtime.dynCall('vii', onerror, [ctx, http.status]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
http.onerror = function(e)
|
||||||
|
{
|
||||||
|
if (onerror)
|
||||||
|
Runtime.dynCall('vii', onerror, [ctx, http.status]);
|
||||||
|
};
|
||||||
|
|
||||||
|
http.onprogress = function(e)
|
||||||
|
{
|
||||||
|
if (onprogress)
|
||||||
|
Runtime.dynCall('viii', onprogress, [ctx, e.loaded, e.total]);
|
||||||
|
};
|
||||||
|
|
||||||
|
http.send(null);
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,79 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en-us">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<title>FTE QuakeWorld</title>
|
||||||
|
<style>
|
||||||
|
body { background-color:#000000; color:#808080; }
|
||||||
|
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
|
||||||
|
div.emscripten { text-align: center; }
|
||||||
|
div.emscripten_border { border: 1px solid black; }
|
||||||
|
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
|
||||||
|
canvas.emscripten { border: 0px none; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="emscripten" id="status">Is javascript enabled?</div>
|
||||||
|
<div class="emscripten">
|
||||||
|
<progress value="0" max="100" id="progress" hidden=1></progress>
|
||||||
|
</div>
|
||||||
|
<div class="emscripten_border">
|
||||||
|
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
|
||||||
|
</div>
|
||||||
|
<div class="emscripten">
|
||||||
|
<input type="checkbox" id="resize">Resize canvas
|
||||||
|
<input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer
|
||||||
|
|
||||||
|
<input type="button" value="Fullscreen" onclick="Module.requestFullScreen(document.getElementById('pointerLock').checked,
|
||||||
|
document.getElementById('resize').checked)">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type='text/javascript'>
|
||||||
|
// connect to canvas
|
||||||
|
var Module = {
|
||||||
|
preRun: [],
|
||||||
|
postRun: [],
|
||||||
|
print: (function() {
|
||||||
|
})(),
|
||||||
|
printErr: function(text) {
|
||||||
|
text = Array.prototype.slice.call(arguments).join(' ');
|
||||||
|
if (0) { // XXX disabled for safety typeof dump == 'function') {
|
||||||
|
dump(text + '\n'); // fast, straight to the real console
|
||||||
|
} else {
|
||||||
|
console.log(text);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
canvas: document.getElementById('canvas'),
|
||||||
|
setStatus: function(text) {
|
||||||
|
if (Module.setStatus.interval) clearInterval(Module.setStatus.interval);
|
||||||
|
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
|
||||||
|
var statusElement = document.getElementById('status');
|
||||||
|
var progressElement = document.getElementById('progress');
|
||||||
|
if (m) {
|
||||||
|
text = m[1];
|
||||||
|
progressElement.value = parseInt(m[2])*100;
|
||||||
|
progressElement.max = parseInt(m[4])*100;
|
||||||
|
progressElement.hidden = false;
|
||||||
|
} else {
|
||||||
|
progressElement.value = null;
|
||||||
|
progressElement.max = null;
|
||||||
|
progressElement.hidden = true;
|
||||||
|
}
|
||||||
|
statusElement.innerHTML = text;
|
||||||
|
},
|
||||||
|
totalDependencies: 0,
|
||||||
|
monitorRunDependencies: function(left) {
|
||||||
|
this.totalDependencies = Math.max(this.totalDependencies, left);
|
||||||
|
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Module.setStatus('Downloading...');
|
||||||
|
</script>
|
||||||
|
<script type='text/javascript'>
|
||||||
|
|
||||||
|
{{{ SCRIPT_CODE }}}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -12,7 +12,7 @@ Module['preRun'] = function()
|
||||||
//FS.createPreloadedFile('/id1/', 'pak3.pak', '/pak3.pak', true, false);
|
//FS.createPreloadedFile('/id1/', 'pak3.pak', '/pak3.pak', true, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
Module['arguments'] = ['-nohome'];//, '+connect', 'tcp://127.0.0.1:80'];//, '-manifest', document.location + '.fmf'];
|
Module['arguments'] = ['-nohome', '-manifest', document.location + '.fmf'];
|
||||||
// use query string in URL as command line
|
// use query string in URL as command line
|
||||||
if (!document.referrer) {
|
if (!document.referrer) {
|
||||||
qstring = decodeURIComponent(window.location.search.substring(1)).split(" ");
|
qstring = decodeURIComponent(window.location.search.substring(1)).split(" ");
|
||||||
|
|
Loading…
Reference in New Issue