diff --git a/engine/web/ftejslib.js b/engine/web/ftejslib.js index 3071af50c..281fe3851 100644 --- a/engine/web/ftejslib.js +++ b/engine/web/ftejslib.js @@ -1,411 +1,410 @@ - -mergeInto(LibraryManager.library, -{ - //generic handles array - //yeah, I hope you don't use-after-free. hopefully that sort of thing will be detected on systems with easier non-mangled debuggers. - $FTEH__deps: [], - $FTEH: { - h: [], - f: {} - }, - - $FTEC: - { - w: -1, - h: -1, - donecb:0, - evcb: { - resize:0, - mouse:0, - key:0, - }, - - handleevent : function(event) - { - switch(event.type) - { - case 'resize': - if (FTEC.evcb.resize != 0) - Runtime.dynCall('vii', FTEC.evcb.resize, [Module['canvas'].width, Module['canvas'].height]); - break; - case 'mousemove': - if (FTEC.evcb.mouse != 0) - { - if (Browser.pointerLock) - { - if (typeof event.movementX === 'undefined') - { - event.movementX = event.mozMovementX; - event.movementY = event.mozMovementY; - } - if (typeof event.movementX === 'undefined') - { - event.movementX = event.webkitMovementX; - event.movementY = event.webkitMovementY; - } - Runtime.dynCall('viiffff', FTEC.evcb.mouse, [0, false, event.movementX, event.movementY, 0, 0]); - } - else - Runtime.dynCall('viiffff', FTEC.evcb.mouse, [0, true, event.pageX, event.pageY, 0, 0]); - } - break; - case 'mousedown': - case 'mouseup': - Browser.requestFullScreen(true, true); - Module['canvas'].requestPointerLock(); - if (FTEC.evcb.button != 0) - { - Runtime.dynCall('viii', FTEC.evcb.button, [0, event.type=='mousedown', event.button]); - event.preventDefault(); - } - break; - case 'mousewheel': - case 'wheel': - if (FTEC.evcb.button != 0) - { - Runtime.dynCall('viii', FTEC.evcb.button, [0, 3, event.deltaY]); - event.preventDefault(); - } - break; - case 'mouseout': - if (FTEC.evcb.button != 0) - { - for (var i = 0; i < 8; i++) - Runtime.dynCall('viii', FTEC.evcb.button, [0, false, i]); - } - break; - case 'keypress': - if (FTEC.evcb.key != 0) - { - Runtime.dynCall('viiii', FTEC.evcb.key, [0, 1, 0, event.charCode]); - Runtime.dynCall('viiii', FTEC.evcb.key, [0, 0, 0, event.charCode]); - event.preventDefault(); - } - break; - case 'keydown': - case 'keyup': - //122 is 'toggle fullscreen'. - //we don't steal that because its impossible to leave it again once used. - if (FTEC.evcb.key != 0 && event.keyCode != 122) - { - Runtime.dynCall('viiii', FTEC.evcb.key, [0, event.type=='keydown', event.keyCode, 0]); - event.preventDefault(); - } - break; - case 'keydown': - default: - console.log(event); - } - } - }, - emscriptenfte_setupcanvas__deps: ['$FTEC', '$Browser'], - emscriptenfte_setupcanvas : function(nw,nh,evresz,evm,evb,evk) - { - FTEC.evcb.resize = evresz; - FTEC.evcb.mouse = evm; - FTEC.evcb.button = evb; - FTEC.evcb.key = evk; - if (!FTEC.donecb) - { - FTEC.donecb = 1; - ['mousedown', 'mouseup', 'mousemove', 'wheel', 'mousewheel', 'mouseout', 'keydown', 'keyup'].forEach(function(event) - { - Module['canvas'].addEventListener(event, FTEC.handleevent, true); - }); - ['keydown', 'keyup', 'keypress'].forEach(function(event) - { - document.addEventListener(event, FTEC.handleevent, true); - }); - - Browser.resizeListeners.push(function(w, h) { - FTEC.handleevent({ - type: 'resize', - }); - }); - } - var ctx = Browser.createContext(Module['canvas'], true, true); - if (!ctx) - return 0; - Browser.setCanvasSize(nw, nh, false); - - window.onresize = function() - { - //emscripten's browser library will revert sizes wrongly or something when we're fullscreen, so make sure that doesn't happen. - if (Browser.isFullScreen) - { - Browser.windowedWidth = window.innerWidth; - Browser.windowedHeight = window.innerHeight; - } - else - Browser.setCanvasSize(window.innerWidth, window.innerHeight, false); - }; - window.onresize(); - - return 1; - }, - - emscriptenfte_abortmainloop : function(msg) - { - msg = Pointer_stringify(msg); - throw 'oh noes! something bad happened in ' + msg + '!'; - }, - emscriptenfte_alert : function(msg) - { - msg = Pointer_stringify(msg); - console.log(msg); - alert(msg); - }, - - //FIXME: split+merge by \n - emscriptenfte_print : function(msg) - { - console.log(Pointer_stringify(msg)); - }, - emscriptenfte_ticks_ms : function() - { - return Date.now(); - }, - - emscriptenfte_handle_alloc__deps : ['$FTEH'], - emscriptenfte_handle_alloc : function(h) - { - for (var i = 0; FTEH.h.length; i+=1) - { - if (FTEH.h[i] == null) - { - FTEH.h[i] = h; - return i; - } - } - i = FTEH.h.length; - FTEH.h[i] = h; - return i; - }, - - //temp files - emscriptenfte_buf_create__deps : ['emscriptenfte_handle_alloc'], - emscriptenfte_buf_create : function() - { - var b = {h:-1, r:1, l:0,m:4096,d:new Uint8Array(4096), n:null}; - b.h = _emscriptenfte_handle_alloc(b); - return b.h; - }, - //temp files - emscriptenfte_buf_open__deps : ['emscriptenfte_buf_create'], - emscriptenfte_buf_open : function(name, createifneeded) - { - name = Pointer_stringify(name); - var f = FTEH.f[name]; - var r = -1; - if (f == null) - { - if (createifneeded) - r = _emscriptenfte_buf_create(); - if (r != -1) - { - f = FTEH.h[r]; - f.r+=1; - f.n = name; - FTEH.f[name] = f; - if (FTEH.f[name] != f || f.n != name) - console.log('error creating file '+name); - } - } - else - { - f.r+=1; - r = f.h; - } - return r; - }, - emscriptenfte_buf_rename : function(oldname, newname) - { - oldname = Pointer_stringify(oldname); - newname = Pointer_stringify(newname); - var f = FTEH.f[oldname]; - if (f == null) - return 0; - if (FTEH.f[newname] != null) - return 0; - FTEH.f[newname] = f; - delete FTEH.f[oldname]; - f.n = newname; - return 1; - }, - emscriptenfte_buf_delete : function(name) - { - name = Pointer_stringify(name); - var f = FTEH.f[name]; - if (f) - { - delete FTEH.f[name]; - f.n = null; - emscriptenfte_buf_release(f.h); -console.log('deleted '+name); - return 1; - } - return 0; - }, - emscriptenfte_buf_release : function(handle) - { - var b = FTEH.h[handle]; - if (b == null) - { - Module.printError('emscriptenfte_buf_release with invalid handle'); - return; - } - b.r -= 1; - if (b.r == 0) - { - if (b.n != null) - delete FTEH.f[b.n]; - delete FTEH.h[handle]; - b.d = null; - } - }, - emscriptenfte_buf_getsize : function(handle) - { - var b = FTEH.h[handle]; - return b.l; - }, - emscriptenfte_buf_read : function(handle, offset, data, len) - { - var b = FTEH.h[handle]; - if (offset+len > b.l) //clamp the read - len = b.l - offset; - if (len < 0) - { - len = 0; - if (offset+len >= b.l) - return -1; - } - HEAPU8.set(b.d.subarray(offset, offset+len), data); - return len; - }, - emscriptenfte_buf_write : function(handle, offset, data, len) - { - var b = FTEH.h[handle]; - if (offset+len > b.m) - { //extend it if needed. - b.m = offset + len + 4095; - b.m = b.m & ~4095; - var nd = new Uint8Array(b.m); - nd.set(b.d, 0); - b.d = nd; - } - if (len < 0) - len = 0; -console.log('deleted '+name); - b.d.set(HEAPU8.subarray(data, data+len), offset); - if (offset + len > b.l) - b.l = offset + len; - return len; - }, - - emscriptenfte_ws_connect__deps: ['emscriptenfte_handle_alloc'], - emscriptenfte_ws_connect : function(url) - { - var _url = Pointer_stringify(url); - var s = {ws:null, inq:[], err:0}; - s.ws = new WebSocket(_url, 'binary'); - if (!s.ws) - return -1; - 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 _emscriptenfte_handle_alloc(s); - }, - emscriptenfte_ws_close : function(sockid) - { - var s = FTEH.h[sockid]; - if (!s) - return -1; - s.ws.close(); - s.ws = null; //make sure to avoid circular references - delete FTEH.h[sockid]; //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 = FTEH.h[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 = FTEH.h[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 = FTEH.h[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); - console.log("Attempting download of " + _url); - var http = new XMLHttpRequest(); - http.open('GET', _url, true); - http.responseType = 'arraybuffer'; - - http.onload = function(e) - { - console.log("onload: " + _url + " status " + http.status); - 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) - { - console.log("onerror: " + _url + " status " + http.status); - 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); - } -}); + +mergeInto(LibraryManager.library, +{ + //generic handles array + //yeah, I hope you don't use-after-free. hopefully that sort of thing will be detected on systems with easier non-mangled debuggers. + $FTEH__deps: [], + $FTEH: { + h: [], + f: {} + }, + + $FTEC: + { + w: -1, + h: -1, + donecb:0, + evcb: { + resize:0, + mouse:0, + key:0, + }, + + handleevent : function(event) + { + switch(event.type) + { + case 'resize': + if (FTEC.evcb.resize != 0) + Runtime.dynCall('vii', FTEC.evcb.resize, [Module['canvas'].width, Module['canvas'].height]); + break; + case 'mousemove': + if (FTEC.evcb.mouse != 0) + { + if (Browser.pointerLock) + { + if (typeof event.movementX === 'undefined') + { + event.movementX = event.mozMovementX; + event.movementY = event.mozMovementY; + } + if (typeof event.movementX === 'undefined') + { + event.movementX = event.webkitMovementX; + event.movementY = event.webkitMovementY; + } + Runtime.dynCall('viiffff', FTEC.evcb.mouse, [0, false, event.movementX, event.movementY, 0, 0]); + } + else + Runtime.dynCall('viiffff', FTEC.evcb.mouse, [0, true, event.pageX, event.pageY, 0, 0]); + } + break; + case 'mousedown': + case 'mouseup': + Browser.requestFullScreen(true, true); + Module['canvas'].requestPointerLock(); + if (FTEC.evcb.button != 0) + { + Runtime.dynCall('viii', FTEC.evcb.button, [0, event.type=='mousedown', event.button]); + event.preventDefault(); + } + break; + case 'mousewheel': + case 'wheel': + if (FTEC.evcb.button != 0) + { + Runtime.dynCall('viii', FTEC.evcb.button, [0, 3, event.deltaY]); + event.preventDefault(); + } + break; + case 'mouseout': + if (FTEC.evcb.button != 0) + { + for (var i = 0; i < 8; i++) + Runtime.dynCall('viii', FTEC.evcb.button, [0, false, i]); + } + break; + case 'keypress': + if (FTEC.evcb.key != 0) + { + Runtime.dynCall('viiii', FTEC.evcb.key, [0, 1, 0, event.charCode]); + Runtime.dynCall('viiii', FTEC.evcb.key, [0, 0, 0, event.charCode]); + event.preventDefault(); + } + break; + case 'keydown': + case 'keyup': + //122 is 'toggle fullscreen'. + //we don't steal that because its impossible to leave it again once used. + if (FTEC.evcb.key != 0 && event.keyCode != 122) + { + if (Runtime.dynCall('iiiii', FTEC.evcb.key, [0, event.type=='keydown', event.keyCode, 0])) + event.preventDefault(); + } + break; + default: + console.log(event); + } + } + }, + emscriptenfte_setupcanvas__deps: ['$FTEC', '$Browser'], + emscriptenfte_setupcanvas : function(nw,nh,evresz,evm,evb,evk) + { + FTEC.evcb.resize = evresz; + FTEC.evcb.mouse = evm; + FTEC.evcb.button = evb; + FTEC.evcb.key = evk; + if (!FTEC.donecb) + { + FTEC.donecb = 1; + ['mousedown', 'mouseup', 'mousemove', 'wheel', 'mousewheel', 'mouseout', 'keypress', 'keydown', 'keyup'].forEach(function(event) + { + Module['canvas'].addEventListener(event, FTEC.handleevent, true); + }); + ['keydown', 'keyup', 'keypress'].forEach(function(event) + { + document.addEventListener(event, FTEC.handleevent, true); + }); + + Browser.resizeListeners.push(function(w, h) { + FTEC.handleevent({ + type: 'resize', + }); + }); + } + var ctx = Browser.createContext(Module['canvas'], true, true); + if (!ctx) + return 0; + Browser.setCanvasSize(nw, nh, false); + + window.onresize = function() + { + //emscripten's browser library will revert sizes wrongly or something when we're fullscreen, so make sure that doesn't happen. + if (Browser.isFullScreen) + { + Browser.windowedWidth = window.innerWidth; + Browser.windowedHeight = window.innerHeight; + } + else + Browser.setCanvasSize(window.innerWidth, window.innerHeight, false); + }; + window.onresize(); + + return 1; + }, + + emscriptenfte_abortmainloop : function(msg) + { + msg = Pointer_stringify(msg); + throw 'oh noes! something bad happened in ' + msg + '!'; + }, + emscriptenfte_alert : function(msg) + { + msg = Pointer_stringify(msg); + console.log(msg); + alert(msg); + }, + + //FIXME: split+merge by \n + emscriptenfte_print : function(msg) + { + console.log(Pointer_stringify(msg)); + }, + emscriptenfte_ticks_ms : function() + { + return Date.now(); + }, + + emscriptenfte_handle_alloc__deps : ['$FTEH'], + emscriptenfte_handle_alloc : function(h) + { + for (var i = 0; FTEH.h.length; i+=1) + { + if (FTEH.h[i] == null) + { + FTEH.h[i] = h; + return i; + } + } + i = FTEH.h.length; + FTEH.h[i] = h; + return i; + }, + + //temp files + emscriptenfte_buf_create__deps : ['emscriptenfte_handle_alloc'], + emscriptenfte_buf_create : function() + { + var b = {h:-1, r:1, l:0,m:4096,d:new Uint8Array(4096), n:null}; + b.h = _emscriptenfte_handle_alloc(b); + return b.h; + }, + //temp files + emscriptenfte_buf_open__deps : ['emscriptenfte_buf_create'], + emscriptenfte_buf_open : function(name, createifneeded) + { + name = Pointer_stringify(name); + var f = FTEH.f[name]; + var r = -1; + if (f == null) + { + if (createifneeded) + r = _emscriptenfte_buf_create(); + if (r != -1) + { + f = FTEH.h[r]; + f.r+=1; + f.n = name; + FTEH.f[name] = f; + if (FTEH.f[name] != f || f.n != name) + console.log('error creating file '+name); + } + } + else + { + f.r+=1; + r = f.h; + } + return r; + }, + emscriptenfte_buf_rename : function(oldname, newname) + { + oldname = Pointer_stringify(oldname); + newname = Pointer_stringify(newname); + var f = FTEH.f[oldname]; + if (f == null) + return 0; + if (FTEH.f[newname] != null) + return 0; + FTEH.f[newname] = f; + delete FTEH.f[oldname]; + f.n = newname; + return 1; + }, + emscriptenfte_buf_delete : function(name) + { + name = Pointer_stringify(name); + var f = FTEH.f[name]; + if (f) + { + delete FTEH.f[name]; + f.n = null; + emscriptenfte_buf_release(f.h); +console.log('deleted '+name); + return 1; + } + return 0; + }, + emscriptenfte_buf_release : function(handle) + { + var b = FTEH.h[handle]; + if (b == null) + { + Module.printError('emscriptenfte_buf_release with invalid handle'); + return; + } + b.r -= 1; + if (b.r == 0) + { + if (b.n != null) + delete FTEH.f[b.n]; + delete FTEH.h[handle]; + b.d = null; + } + }, + emscriptenfte_buf_getsize : function(handle) + { + var b = FTEH.h[handle]; + return b.l; + }, + emscriptenfte_buf_read : function(handle, offset, data, len) + { + var b = FTEH.h[handle]; + if (offset+len > b.l) //clamp the read + len = b.l - offset; + if (len < 0) + { + len = 0; + if (offset+len >= b.l) + return -1; + } + HEAPU8.set(b.d.subarray(offset, offset+len), data); + return len; + }, + emscriptenfte_buf_write : function(handle, offset, data, len) + { + var b = FTEH.h[handle]; + if (offset+len > b.m) + { //extend it if needed. + b.m = offset + len + 4095; + b.m = b.m & ~4095; + var nd = new Uint8Array(b.m); + nd.set(b.d, 0); + b.d = nd; + } + if (len < 0) + len = 0; +console.log('deleted '+name); + b.d.set(HEAPU8.subarray(data, data+len), offset); + if (offset + len > b.l) + b.l = offset + len; + return len; + }, + + emscriptenfte_ws_connect__deps: ['emscriptenfte_handle_alloc'], + emscriptenfte_ws_connect : function(url) + { + var _url = Pointer_stringify(url); + var s = {ws:null, inq:[], err:0}; + s.ws = new WebSocket(_url, 'binary'); + if (!s.ws) + return -1; + 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 _emscriptenfte_handle_alloc(s); + }, + emscriptenfte_ws_close : function(sockid) + { + var s = FTEH.h[sockid]; + if (!s) + return -1; + s.ws.close(); + s.ws = null; //make sure to avoid circular references + delete FTEH.h[sockid]; //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 = FTEH.h[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 = FTEH.h[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 = FTEH.h[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); + console.log("Attempting download of " + _url); + var http = new XMLHttpRequest(); + http.open('GET', _url, true); + http.responseType = 'arraybuffer'; + + http.onload = function(e) + { + console.log("onload: " + _url + " status " + http.status); + 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) + { + console.log("onerror: " + _url + " status " + http.status); + 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); + } +}); diff --git a/engine/web/gl_vidweb.c b/engine/web/gl_vidweb.c index bf116ab88..9c901fd0b 100644 --- a/engine/web/gl_vidweb.c +++ b/engine/web/gl_vidweb.c @@ -1,214 +1,223 @@ -#include "quakedef.h" -#include "glquake.h" -#include "web/ftejslib.h" - -extern cvar_t vid_hardwaregamma; -extern cvar_t gl_lateswap; -extern int gammaworks; - -extern qboolean vid_isfullscreen; - -qboolean ActiveApp; -qboolean mouseactive; -extern qboolean mouseusedforgui; - - -static void *GLVID_getsdlglfunction(char *functionname) -{ - return NULL; -} - -static void VID_Resized(int width, int height) -{ - extern cvar_t vid_conautoscale, vid_conwidth; - vid.pixelwidth = width; - vid.pixelheight = height; -//Con_Printf("Resized: %i %i\n", vid.pixelwidth, vid.pixelheight); - - Cvar_ForceCallback(&vid_conautoscale); - Cvar_ForceCallback(&vid_conwidth); -} -static unsigned int domkeytoquake(unsigned int code) -{ - unsigned int tab[256] = - { - /* 0*/ 0,0,0,0,0,0,0,0, K_BACKSPACE,K_TAB,0,0,0,K_ENTER,0,0, - /* 16*/ K_SHIFT,K_CTRL,K_ALT,K_PAUSE,K_CAPSLOCK,0,0,0,0,0,0,K_ESCAPE,0,0,0,0, - /* 32*/ ' ',K_PGUP,K_PGDN,K_END,K_HOME,K_LEFTARROW,K_UPARROW,K_RIGHTARROW, K_DOWNARROW,0,0,0,K_PRINTSCREEN,K_INS,K_DEL,0, - /* 48*/ '0','1','2','3','4','5','6','7', '8','9',0,0,0,0,0,0, - - /* 64*/ 0,'a','b','c','d','e','f','g', 'h','i','j','k','l','m','n','o', - /* 80*/ 'p','q','r','s','t','u','v','w', 'x','y','z',K_LWIN,K_RWIN,K_APP,0,0, - /* 96*/ K_KP_INS,K_KP_END,K_KP_DOWNARROW,K_KP_PGDN,K_KP_LEFTARROW,K_KP_5,K_KP_RIGHTARROW,K_KP_HOME, K_KP_UPARROW,K_KP_PGDN,K_KP_STAR,K_KP_PLUS,0,K_KP_MINUS,K_KP_DEL,K_KP_SLASH, - /*112*/ K_F1,K_F2,K_F3,K_F4,K_F5,K_F6,K_F7,K_F8,K_F9,K_F10,K_F11,K_F12,0,0,0,0, - /*128*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, - /*144*/ K_KP_NUMLOCK,K_SCRLCK,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, - /*160*/ 0,0,0,'#',0,0,0,0, 0,0,0,0,0,0,0,0, - /*176*/ 0,0,0,0,0,0,0,0, 0,0,';','=',',','-','.','/', - /*192*/ '`',0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, - /*208*/ 0,0,0,0,0,0,0,0, 0,0,0,'[','\\',']','\'','`', - /*224*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, - /*240*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, - }; - if (!code) - return 0; - if (code >= sizeof(tab)/sizeof(tab[0])) - { - Con_DPrintf("You just pressed key %u, but I don't know what its meant to be\n", code); - return 0; - } - if (!tab[code]) - Con_DPrintf("You just pressed key %u, but I don't know what its meant to be\n", code); - - Con_DPrintf("You just pressed dom key %u, which is quake key %u\n", code, tab[code]); - return tab[code]; -} -static void DOM_KeyEvent(int devid, int down, int scan, int uni) -{ - IN_KeyEvent(0, down, domkeytoquake(scan), uni); -} -static void DOM_ButtonEvent(int devid, int down, int button) -{ - if (down == 2) - { - //fixme: the event is a float. we ignore that. - while(button < 0) - { - IN_KeyEvent(0, true, K_MWHEELUP, 0); - button += 1; - } - while(button > 0) - { - IN_KeyEvent(0, true, K_MWHEELDOWN, 0); - button -= 1; - } - } - else - { - //swap buttons 2 and 3, so rmb is still +forward by default and not +mlook. - if (button == 2) - button = 1; - else if (button == 1) - button = 2; - - IN_KeyEvent(0, down, K_MOUSE1+button, 0); - } -} - -qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) -{ - int flags; - - vid_isfullscreen = true; - - if (!emscriptenfte_setupcanvas( - info->width, - info->height, - VID_Resized, - IN_MouseMove, - DOM_ButtonEvent, - DOM_KeyEvent - )) - { - Con_Printf("Couldn't set up canvas\n"); - return false; - } - - ActiveApp = true; - - GL_Init(GLVID_getsdlglfunction); - - qglViewport (0, 0, vid.pixelwidth, vid.pixelheight); - - mouseactive = false; - - return true; -} - -void GLVID_DeInit (void) -{ - ActiveApp = false; - - emscriptenfte_setupcanvas(-1, -1, NULL, NULL, NULL, NULL); -} - - -void GL_BeginRendering (void) -{ -} - -qboolean screenflush; -void GL_DoSwap (void) -{ - if (!screenflush) - return; - screenflush = 0; - - //webgl doesn't support swapbuffers. - //you can't use it for loading screens. - //such things must result in waiting until the following frame. - //although there IS a swapped-buffers event, which we should probably use in preference to requestanimationframe or whatever the call is. - -/* - if (!vid_isfullscreen) - { - if (!_windowed_mouse.value) - { - if (mouseactive) - { - IN_DeactivateMouse (); - } - } - else - { - if ((key_dest == key_game||mouseusedforgui) && ActiveApp) - IN_ActivateMouse (); - else if (!(key_dest == key_game || mouseusedforgui) || !ActiveApp) - IN_DeactivateMouse (); - } - } -*/ -} - -void GL_EndRendering (void) -{ - screenflush = true; - if (!gl_lateswap.value) - GL_DoSwap(); -} - -qboolean GLVID_ApplyGammaRamps (unsigned short *ramps) -{ - gammaworks = false; - return gammaworks; -} - -void GLVID_SetCaption(char *text) -{ -// SDL_WM_SetCaption( text, NULL ); -} - -void Sys_SendKeyEvents(void) -{ - /*callbacks happen outside our code, we don't need to poll for events*/ -} -/*various stuff for joysticks, which we don't support in this port*/ -void INS_Shutdown (void) -{ -} -void INS_ReInit (void) -{ -} -void INS_Move(float *movements, int pnum) -{ -} -void INS_Init (void) -{ -} -void INS_Accumulate(void) -{ -} -void INS_Commands (void) -{ -} - +#include "quakedef.h" +#include "glquake.h" +#include "web/ftejslib.h" + +extern cvar_t vid_hardwaregamma; +extern cvar_t gl_lateswap; +extern int gammaworks; + +extern qboolean vid_isfullscreen; + +qboolean ActiveApp; +qboolean mouseactive; +extern qboolean mouseusedforgui; + + +static void *GLVID_getsdlglfunction(char *functionname) +{ + return NULL; +} + +static void VID_Resized(int width, int height) +{ + extern cvar_t vid_conautoscale, vid_conwidth; + vid.pixelwidth = width; + vid.pixelheight = height; +//Con_Printf("Resized: %i %i\n", vid.pixelwidth, vid.pixelheight); + + Cvar_ForceCallback(&vid_conautoscale); + Cvar_ForceCallback(&vid_conwidth); +} +static unsigned int domkeytoquake(unsigned int code) +{ + unsigned int tab[256] = + { + /* 0*/ 0,0,0,0,0,0,0,0, K_BACKSPACE,K_TAB,0,0,0,K_ENTER,0,0, + /* 16*/ K_SHIFT,K_CTRL,K_ALT,K_PAUSE,K_CAPSLOCK,0,0,0,0,0,0,K_ESCAPE,0,0,0,0, + /* 32*/ ' ',K_PGUP,K_PGDN,K_END,K_HOME,K_LEFTARROW,K_UPARROW,K_RIGHTARROW, K_DOWNARROW,0,0,0,K_PRINTSCREEN,K_INS,K_DEL,0, + /* 48*/ '0','1','2','3','4','5','6','7', '8','9',0,0,0,0,0,0, + + /* 64*/ 0,'a','b','c','d','e','f','g', 'h','i','j','k','l','m','n','o', + /* 80*/ 'p','q','r','s','t','u','v','w', 'x','y','z',K_LWIN,K_RWIN,K_APP,0,0, + /* 96*/ K_KP_INS,K_KP_END,K_KP_DOWNARROW,K_KP_PGDN,K_KP_LEFTARROW,K_KP_5,K_KP_RIGHTARROW,K_KP_HOME, K_KP_UPARROW,K_KP_PGDN,K_KP_STAR,K_KP_PLUS,0,K_KP_MINUS,K_KP_DEL,K_KP_SLASH, + /*112*/ K_F1,K_F2,K_F3,K_F4,K_F5,K_F6,K_F7,K_F8,K_F9,K_F10,K_F11,K_F12,0,0,0,0, + /*128*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + /*144*/ K_KP_NUMLOCK,K_SCRLCK,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + /*160*/ 0,0,0,'#',0,0,0,0, 0,0,0,0,0,0,0,0, + /*176*/ 0,0,0,0,0,0,0,0, 0,0,';','=',',','-','.','/', + /*192*/ '`',0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + /*208*/ 0,0,0,0,0,0,0,0, 0,0,0,'[','\\',']','\'','`', + /*224*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + /*240*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }; + if (!code) + return 0; + if (code >= sizeof(tab)/sizeof(tab[0])) + { + Con_DPrintf("You just pressed key %u, but I don't know what its meant to be\n", code); + return 0; + } + if (!tab[code]) + Con_DPrintf("You just pressed key %u, but I don't know what its meant to be\n", code); + + Con_DPrintf("You just pressed dom key %u, which is quake key %u\n", code, tab[code]); + return tab[code]; +} +static int DOM_KeyEvent(int devid, int down, int scan, int uni) +{ + IN_KeyEvent(0, down, domkeytoquake(scan), uni); + //Chars which don't map to some printable ascii value get preventDefaulted. + //This is to stop fucking annoying fucking things like backspace randomly destroying the page and thus game. + //And it has to be conditional, or we don't get any unicode chars at all. + //The behaviour browsers seem to give is retardedly unhelpful, and just results in hacks to detect keys that appear to map to ascii... + //Preventing the browser from leaving the page etc should NOT mean I can no longer get ascii/unicode values, only that the browser stops trying to do something random due to the event. + //If you are the person that decreed that this is the holy way, then please castrate yourself now. + if (scan < ' ' || scan >= 127) + return TRUE; + return FALSE; +} +static void DOM_ButtonEvent(int devid, int down, int button) +{ + if (down == 2) + { + //fixme: the event is a float. we ignore that. + while(button < 0) + { + IN_KeyEvent(0, true, K_MWHEELUP, 0); + button += 1; + } + while(button > 0) + { + IN_KeyEvent(0, true, K_MWHEELDOWN, 0); + button -= 1; + } + } + else + { + //swap buttons 2 and 3, so rmb is still +forward by default and not +mlook. + if (button == 2) + button = 1; + else if (button == 1) + button = 2; + + IN_KeyEvent(0, down, K_MOUSE1+button, 0); + } +} + +qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) +{ + int flags; + + vid_isfullscreen = true; + + if (!emscriptenfte_setupcanvas( + info->width, + info->height, + VID_Resized, + IN_MouseMove, + DOM_ButtonEvent, + DOM_KeyEvent + )) + { + Con_Printf("Couldn't set up canvas\n"); + return false; + } + + ActiveApp = true; + + GL_Init(GLVID_getsdlglfunction); + + qglViewport (0, 0, vid.pixelwidth, vid.pixelheight); + + mouseactive = false; + + return true; +} + +void GLVID_DeInit (void) +{ + ActiveApp = false; + + emscriptenfte_setupcanvas(-1, -1, NULL, NULL, NULL, NULL); +} + + +void GL_BeginRendering (void) +{ +} + +qboolean screenflush; +void GL_DoSwap (void) +{ + if (!screenflush) + return; + screenflush = 0; + + //webgl doesn't support swapbuffers. + //you can't use it for loading screens. + //such things must result in waiting until the following frame. + //although there IS a swapped-buffers event, which we should probably use in preference to requestanimationframe or whatever the call is. + +/* + if (!vid_isfullscreen) + { + if (!_windowed_mouse.value) + { + if (mouseactive) + { + IN_DeactivateMouse (); + } + } + else + { + if ((key_dest == key_game||mouseusedforgui) && ActiveApp) + IN_ActivateMouse (); + else if (!(key_dest == key_game || mouseusedforgui) || !ActiveApp) + IN_DeactivateMouse (); + } + } +*/ +} + +void GL_EndRendering (void) +{ + screenflush = true; + if (!gl_lateswap.value) + GL_DoSwap(); +} + +qboolean GLVID_ApplyGammaRamps (unsigned short *ramps) +{ + gammaworks = false; + return gammaworks; +} + +void GLVID_SetCaption(char *text) +{ +// SDL_WM_SetCaption( text, NULL ); +} + +void Sys_SendKeyEvents(void) +{ + /*callbacks happen outside our code, we don't need to poll for events*/ +} +/*various stuff for joysticks, which we don't support in this port*/ +void INS_Shutdown (void) +{ +} +void INS_ReInit (void) +{ +} +void INS_Move(float *movements, int pnum) +{ +} +void INS_Init (void) +{ +} +void INS_Accumulate(void) +{ +} +void INS_Commands (void) +{ +} +