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:
Spoike 2013-05-14 18:38:42 +00:00
parent 594a297ffa
commit d97a163011
8 changed files with 165 additions and 20 deletions

View File

@ -1105,8 +1105,8 @@ ifeq ($(FTE_TARGET),web)
WEB_MEMORY?=402653184
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)
DEBUG_LDLAGS=-O0 $(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) --js-library web/ftejslib.js
CC=emcc
#-s ASM_JS=1
#BASELDFLAGS=

View File

@ -28,6 +28,7 @@ void (APIENTRY *qglGetFloatv) (GLenum pname, GLfloat *params);
void (APIENTRY *qglGetIntegerv) (GLenum pname, GLint *params);
const GLubyte * (APIENTRY *qglGetString) (GLenum name);
void (APIENTRY *qglHint) (GLenum target, GLenum mode);
GLboolean (APIENTRY *qglIsEnabled) (GLenum cap);
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 *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 *qglFrustum) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
GLuint (APIENTRY *qglGenLists) (GLsizei range);
GLboolean (APIENTRY *qglIsEnabled) (GLenum cap);
void (APIENTRY *qglLoadIdentity) (void);
void (APIENTRY *qglLoadMatrixf) (const GLfloat *m);
void (APIENTRY *qglNormal3f) (GLfloat nx, GLfloat ny, GLfloat nz);
@ -1507,6 +1507,7 @@ void GL_Init(void *(*getglfunction) (char *name))
qglGetIntegerv = (void *)getglcore("glGetIntegerv");
qglGetString = (void *)getglcore("glGetString");
qglHint = (void *)getglcore("glHint");
qglIsEnabled = (void *)getglext("glIsEnabled");
qglReadPixels = (void *)getglcore("glReadPixels");
qglTexImage2D = (void *)getglcore("glTexImage2D");
qglTexSubImage2D = (void *)getglcore("glTexSubImage2D");
@ -1596,7 +1597,6 @@ void GL_Init(void *(*getglfunction) (char *name))
qglGetTexEnviv = (void *)getglext("glGetTexEnviv");
qglGetPointerv = (void *)getglext("glGetPointerv");
qglIsEnabled = (void *)getglext("glIsEnabled");
qglGetStringi = (void *)getglext("glGetStringi");

View File

@ -31,8 +31,6 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
{
int flags;
Con_Printf("SDL GLVID_Init\n");
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);
#ifndef FTE_TARGET_WEB
SDL_SetVideoMode( 0, 0, 0, 0 ); //to get around some SDL bugs
@ -89,7 +87,6 @@ void GLVID_DeInit (void)
ActiveApp = false;
IN_DeactivateMouse();
Con_Printf("Restoring gamma\n");
SDL_SetGammaRamp (intitialgammaramps[0], intitialgammaramps[1], intitialgammaramps[2]);
SDL_QuitSubSystem(SDL_INIT_VIDEO);
@ -149,7 +146,7 @@ qboolean GLVID_ApplyGammaRamps (unsigned short *ramps)
if (gammaworks)
{ //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]);
return;
return true;
}
gammaworks = !SDL_SetGammaRamp (&ramps[0], &ramps[256], &ramps[512]);
}

View File

@ -7,7 +7,14 @@
#if defined(WEBCLIENT)
#if defined(FTE_TARGET_WEB)
#define MYJS 1
#if MYJS
#include "web/ftejslib.h"
#else
#include <emscripten/emscripten.h>
#endif
typedef struct
{
@ -56,11 +63,11 @@ 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;
/*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;
@ -82,43 +89,55 @@ static void DL_Abort(struct dl_download *dl)
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;
#if !MYJS
dl->completed += datasize;
#endif
dl->status = DL_FINISHED;
}
#if MYJS
static void DL_OnError(void *c, int ecode)
#else
static void DL_OnError(void *c)
#endif
{
struct dl_download *dl = c;
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?
#endif
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.
qboolean HTTPDL_Decide(struct dl_download *dl)
@ -141,8 +160,13 @@ qboolean HTTPDL_Decide(struct dl_download *dl)
dl->abort = DL_Abort;
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);
#endif
}
return true;

2
engine/web/ftejslib.h Normal file
View File

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

43
engine/web/ftejslib.js Normal file
View File

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

79
engine/web/fteshell.html Normal file
View File

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

View File

@ -12,9 +12,9 @@ Module['preRun'] = function()
//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
if (!document.referrer) {
qstring = decodeURIComponent(window.location.search.substring(1)).split(" ");
Module['arguments'] = Module['arguments'].concat(qstring);
}
}