From 6dfb76b6690edf04dc869af7abfc02cd4d0dfa09 Mon Sep 17 00:00:00 2001 From: Rob Loach <robloach@gmail.com> Date: Tue, 16 Aug 2016 23:32:45 -0400 Subject: [PATCH 1/2] Move emscripten JS/CSS to split files --- emscripten/webplayer.css | 6 + emscripten/webplayer.html | 269 +------------------------------------- emscripten/webplayer.js | 242 ++++++++++++++++++++++++++++++++++ 3 files changed, 255 insertions(+), 262 deletions(-) create mode 100644 emscripten/webplayer.css create mode 100644 emscripten/webplayer.js diff --git a/emscripten/webplayer.css b/emscripten/webplayer.css new file mode 100644 index 0000000000..ec7cb08e42 --- /dev/null +++ b/emscripten/webplayer.css @@ -0,0 +1,6 @@ + +.webplayer { padding-right: 0; margin-left: auto; margin-right: auto; display: block; } +textarea.webplayer { border: 0px; font-family: 'Share Tech Mono'; font-size: 12px; width: 100%; overflow:hide; resize:none; color:black; } +div.webplayer, h1 { text-align: left; } +div.canvas_border { background-color:gray; width:800px; height:600px; margin-left: auto; margin-right: auto; } +canvas.webplayer { border: 0px none; } \ No newline at end of file diff --git a/emscripten/webplayer.html b/emscripten/webplayer.html index 5e80686aeb..179080e02d 100644 --- a/emscripten/webplayer.html +++ b/emscripten/webplayer.html @@ -1,22 +1,10 @@ <!doctype html> -<script src="//cdnjs.cloudflare.com/ajax/libs/dropbox.js/0.10.2/dropbox.min.js"> -</script> - - - <html lang="en"> <head> <meta charset="utf-8"> <title>RetroArch Web Player</title> - <script type="text/javascript" src="browserfs.js"></script> - - <style> - .webplayer { padding-right: 0; margin-left: auto; margin-right: auto; display: block; } - textarea.webplayer { border: 0px; font-family: 'Share Tech Mono'; font-size: 12px; width: 100%; overflow:hide; resize:none; color:black; } - div.webplayer, h1 { text-align: left; } - div.canvas_border { background-color:gray; width:800px; height:600px; margin-left: auto; margin-right: auto; } - canvas.webplayer { border: 0px none; } - </style> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link href="webplayer.css" rel="stylesheet" type="text/css"> </head> <body> <hr/> @@ -43,253 +31,10 @@ <hr/> <textarea class="webplayer" id="output" rows="15"></textarea> <hr> + + <script src="//cdnjs.cloudflare.com/ajax/libs/dropbox.js/0.10.2/dropbox.min.js"></script> + <script src="browserfs.js"></script> + <script src="webplayer.js"></script> + <script src="gambatte.js"></script> </body> </html> - -<script type='text/javascript'> - var dropbox = false; - var client = new Dropbox.Client({ key: "il6e10mfd7pgf8r" }); - - var showError = function(error) { - switch (error.status) { - case Dropbox.ApiError.INVALID_TOKEN: - // If you're using dropbox.js, the only cause behind this error is that - // the user token expired. - // Get the user through the authentication flow again. - break; - - case Dropbox.ApiError.NOT_FOUND: - // The file or folder you tried to access is not in the user's Dropbox. - // Handling this error is specific to your application. - break; - - case Dropbox.ApiError.OVER_QUOTA: - // The user is over their Dropbox quota. - // Tell them their Dropbox is full. Refreshing the page won't help. - break; - - case Dropbox.ApiError.RATE_LIMITED: - // Too many API requests. Tell the user to try again later. - // Long-term, optimize your code to use fewer API calls. - break; - - case Dropbox.ApiError.NETWORK_ERROR: - // An error occurred at the XMLHttpRequest layer. - // Most likely, the user's network connection is down. - // API calls will not succeed until the user gets back online. - break; - - case Dropbox.ApiError.INVALID_PARAM: - case Dropbox.ApiError.OAUTH_ERROR: - case Dropbox.ApiError.INVALID_METHOD: - default: - // Caused by a bug in dropbox.js, in your application, or in Dropbox. - // Tell the user an error occurred, ask them to refresh the page. - } - }; - - function dropboxInit() - { - document.getElementById('btnStart').disabled = true; - document.getElementById('btnAuth').disabled = true; - client.authDriver(new Dropbox.AuthDriver.Redirect()); - client.authenticate({ rememberUser: true }, function(error, client) - { - if (error) - { - return showError(error); - } - dropboxSync(client, success); - }); - } - function success() - { - document.getElementById('btnStart').disabled = false; - console.log("WEBPLAYER: Sync successful"); - } - function dropboxSync(dropboxClient, cb) - { - var dbfs = new BrowserFS.FileSystem.Dropbox(dropboxClient); - // Wrap in AsyncMirrorFS. - var asyncMirror = new BrowserFS.FileSystem.AsyncMirror( - new BrowserFS.FileSystem.InMemory(), dbfs); - - asyncMirror.initialize(function(err) - { - // Initialize it as the root file system. - BrowserFS.initialize(asyncMirror); - - cb(); - }); - } - - var count = 0; - function setupFileSystem() - { - console.log("WEBPLAYER: Initializing Filesystem"); - if(!client.isAuthenticated()) - { - console.log("WEBPLAYER: Initializing LocalStorage"); - if(localStorage.getItem("fs_inited")!="true") - { - var lsfs = new BrowserFS.FileSystem.LocalStorage(); - - BrowserFS.initialize(lsfs); - var BFS = new BrowserFS.EmscriptenFS(); - FS.mount(BFS, {root: '/'}, '/home'); - console.log('WEBPLAYER: Filesystem initialized'); - } - else - { - console.log('WEBPLAYER: Filesystem already initialized'); - } - } - else - { - console.log("WEBPLAYER: Initializing DropBoxFS"); - // Grab the BrowserFS Emscripten FS plugin. - var BFS = new BrowserFS.EmscriptenFS(); - // Create the folder that we'll turn into a mount point. - FS.createPath(FS.root, 'home', true, true); - // Mount BFS's root folder into the '/data' folder. - console.log('WEBPLAYER: Mounting'); - FS.mount(BFS, {root: '/'}, '/home'); - console.log('WEBPLAYER: DropBox initialized'); - } - } - - - function setupFolderStructure() - { - FS.createPath('/', '/home/web_user', true, true); - FS.createPath('/', '/home/web_user/.config', true, true); - FS.createPath('/', '/home/web_user/.config/retroarch', true, true); - FS.createPath('/', '/home/web_user/content', true, true); - FS.createPath('/', '/home/web_user/saves', true, true); - FS.createPath('/', '/home/web_user/states', true, true); - FS.createPath('/', '/home/web_user/system', true, true); - } - - function stat(path) - { - try{ - FS.stat(path); - } - catch(err) - { - console.log("WEBPLAYER: file " + path + " doesn't exist"); - return false; - } - return true; - } - - function startRetroArch() - { - document.getElementById('canvas_div').style.display = 'block'; - document.getElementById('vsync').disabled = true; - document.getElementById('vsync-label').style.color = 'gray'; - document.getElementById('latency').disabled = true; - document.getElementById('latency-label').style.color = 'gray'; - - setupFileSystem(); - setupFolderStructure(); - cfgFile = '/home/web_user/.config/retroarch/retroarch.cfg' - - if (!stat(cfgFile)) - { - console.log ("WEBPLAYER: first run, setting defaults"); - var config = 'input_player1_select = shift\n'; - var latency = parseInt(document.getElementById('latency').value, 10); - if (isNaN(latency)) latency = 96; - config += 'audio_latency = ' + latency + '\n' - if (document.getElementById('vsync').checked) - config += 'video_vsync = true\n'; - else - config += 'video_vsync = false\n'; - config += 'system_directory = /home/web_user/system/\n'; - config += 'savefile_directory = /home/web_user/saves/\n'; - config += 'savestate_directory = /home/web_user/states/\n'; - config += 'rgui_browser_directory = /home/web_user/content/\n'; - - FS.writeFile(cfgFile, config); - } - else - { - console.log ("WEBPLAYER: loading config from " + cfgFile); - } - Module['callMain'](Module['arguments']); - } - - function selectFiles(files) - { - count = files.length; - - for (var i = 0; i < files.length; i++) - { - filereader = new FileReader(); - filereader.file_name = files[i].name; - filereader.readAsArrayBuffer(files[i]); - filereader.onload = function(){uploadData(this.result, this.file_name)}; - } - } - - function uploadData(data,name) - { - var dataView = new Uint8Array(data); - FS.createDataFile('/', name, dataView, true, false); - - var data = FS.readFile(name,{ encoding: 'binary' }); - FS.writeFile('/home/web_user/content/' + name, data ,{ encoding: 'binary' }); - FS.unlink(name); - - } - - function dropboxCopy() - { - var data = FS.readFile('/home/web_user/.config/retroarch/retroarch.cfg',{ encoding: 'utf8' }); - console.log(data); - var dbfs = new BrowserFS.FileSystem.Dropbox(client); - BrowserFS.initialize(dbfs); - var BFS = new BrowserFS.EmscriptenFS(); - - var fs = BrowserFS.BFSRequire('fs'); - fs.writeFile('retroarch.cfg', data ,{ encoding: 'utf8' }); - } - - var Module = - { - noInitialRun: true, - arguments: ["-v", "--menu"], - preRun: [], - postRun: [], - print: (function() - { - var element = document.getElementById('output'); - element.value = ''; // clear browser cache - return function(text) - { - text = Array.prototype.slice.call(arguments).join(' '); - element.value += text + "\n"; - element.scrollTop = 99999; // focus on bottom - }; - })(), - - printErr: function(text) - { - var text = Array.prototype.slice.call(arguments).join(' '); - var element = document.getElementById('output'); - element.value += text + "\n"; - element.scrollTop = 99999; // focus on bottom - }, - canvas: document.getElementById('canvas'), - - totalDependencies: 0, - monitorRunDependencies: function(left) - { - this.totalDependencies = Math.max(this.totalDependencies, left); - } - }; - -</script> -<script type="text/javascript" src="browserfs.js"></script> -<script type="text/javascript" src="gambatte.js"></script> \ No newline at end of file diff --git a/emscripten/webplayer.js b/emscripten/webplayer.js new file mode 100644 index 0000000000..463a3f232d --- /dev/null +++ b/emscripten/webplayer.js @@ -0,0 +1,242 @@ +var dropbox = false; +var client = new Dropbox.Client({ key: "il6e10mfd7pgf8r" }); + +var showError = function(error) { + switch (error.status) { + case Dropbox.ApiError.INVALID_TOKEN: + // If you're using dropbox.js, the only cause behind this error is that + // the user token expired. + // Get the user through the authentication flow again. + break; + + case Dropbox.ApiError.NOT_FOUND: + // The file or folder you tried to access is not in the user's Dropbox. + // Handling this error is specific to your application. + break; + + case Dropbox.ApiError.OVER_QUOTA: + // The user is over their Dropbox quota. + // Tell them their Dropbox is full. Refreshing the page won't help. + break; + + case Dropbox.ApiError.RATE_LIMITED: + // Too many API requests. Tell the user to try again later. + // Long-term, optimize your code to use fewer API calls. + break; + + case Dropbox.ApiError.NETWORK_ERROR: + // An error occurred at the XMLHttpRequest layer. + // Most likely, the user's network connection is down. + // API calls will not succeed until the user gets back online. + break; + + case Dropbox.ApiError.INVALID_PARAM: + case Dropbox.ApiError.OAUTH_ERROR: + case Dropbox.ApiError.INVALID_METHOD: + default: + // Caused by a bug in dropbox.js, in your application, or in Dropbox. + // Tell the user an error occurred, ask them to refresh the page. + } +}; + +function dropboxInit() +{ + document.getElementById('btnStart').disabled = true; + document.getElementById('btnAuth').disabled = true; + client.authDriver(new Dropbox.AuthDriver.Redirect()); + client.authenticate({ rememberUser: true }, function(error, client) + { + if (error) + { + return showError(error); + } + dropboxSync(client, success); + }); +} +function success() +{ + document.getElementById('btnStart').disabled = false; + console.log("WEBPLAYER: Sync successful"); +} +function dropboxSync(dropboxClient, cb) +{ + var dbfs = new BrowserFS.FileSystem.Dropbox(dropboxClient); + // Wrap in AsyncMirrorFS. + var asyncMirror = new BrowserFS.FileSystem.AsyncMirror( + new BrowserFS.FileSystem.InMemory(), dbfs); + + asyncMirror.initialize(function(err) + { + // Initialize it as the root file system. + BrowserFS.initialize(asyncMirror); + + cb(); + }); +} + +var count = 0; +function setupFileSystem() +{ + console.log("WEBPLAYER: Initializing Filesystem"); + if(!client.isAuthenticated()) + { + console.log("WEBPLAYER: Initializing LocalStorage"); + if(localStorage.getItem("fs_inited")!="true") + { + var lsfs = new BrowserFS.FileSystem.LocalStorage(); + + BrowserFS.initialize(lsfs); + var BFS = new BrowserFS.EmscriptenFS(); + FS.mount(BFS, {root: '/'}, '/home'); + console.log('WEBPLAYER: Filesystem initialized'); + } + else + { + console.log('WEBPLAYER: Filesystem already initialized'); + } + } + else + { + console.log("WEBPLAYER: Initializing DropBoxFS"); + // Grab the BrowserFS Emscripten FS plugin. + var BFS = new BrowserFS.EmscriptenFS(); + // Create the folder that we'll turn into a mount point. + FS.createPath(FS.root, 'home', true, true); + // Mount BFS's root folder into the '/data' folder. + console.log('WEBPLAYER: Mounting'); + FS.mount(BFS, {root: '/'}, '/home'); + console.log('WEBPLAYER: DropBox initialized'); + } +} + + +function setupFolderStructure() +{ + FS.createPath('/', '/home/web_user', true, true); + FS.createPath('/', '/home/web_user/.config', true, true); + FS.createPath('/', '/home/web_user/.config/retroarch', true, true); + FS.createPath('/', '/home/web_user/content', true, true); + FS.createPath('/', '/home/web_user/saves', true, true); + FS.createPath('/', '/home/web_user/states', true, true); + FS.createPath('/', '/home/web_user/system', true, true); +} + +function stat(path) +{ + try{ + FS.stat(path); + } + catch(err) + { + console.log("WEBPLAYER: file " + path + " doesn't exist"); + return false; + } + return true; +} + +function startRetroArch() +{ + document.getElementById('canvas_div').style.display = 'block'; + document.getElementById('vsync').disabled = true; + document.getElementById('vsync-label').style.color = 'gray'; + document.getElementById('latency').disabled = true; + document.getElementById('latency-label').style.color = 'gray'; + + setupFileSystem(); + setupFolderStructure(); + cfgFile = '/home/web_user/.config/retroarch/retroarch.cfg' + + if (!stat(cfgFile)) + { + console.log ("WEBPLAYER: first run, setting defaults"); + var config = 'input_player1_select = shift\n'; + var latency = parseInt(document.getElementById('latency').value, 10); + if (isNaN(latency)) latency = 96; + config += 'audio_latency = ' + latency + '\n' + if (document.getElementById('vsync').checked) + config += 'video_vsync = true\n'; + else + config += 'video_vsync = false\n'; + config += 'system_directory = /home/web_user/system/\n'; + config += 'savefile_directory = /home/web_user/saves/\n'; + config += 'savestate_directory = /home/web_user/states/\n'; + config += 'rgui_browser_directory = /home/web_user/content/\n'; + + FS.writeFile(cfgFile, config); + } + else + { + console.log ("WEBPLAYER: loading config from " + cfgFile); + } + Module['callMain'](Module['arguments']); +} + +function selectFiles(files) +{ + count = files.length; + + for (var i = 0; i < files.length; i++) + { + filereader = new FileReader(); + filereader.file_name = files[i].name; + filereader.readAsArrayBuffer(files[i]); + filereader.onload = function(){uploadData(this.result, this.file_name)}; + } +} + +function uploadData(data,name) +{ + var dataView = new Uint8Array(data); + FS.createDataFile('/', name, dataView, true, false); + + var data = FS.readFile(name,{ encoding: 'binary' }); + FS.writeFile('/home/web_user/content/' + name, data ,{ encoding: 'binary' }); + FS.unlink(name); + +} + +function dropboxCopy() +{ + var data = FS.readFile('/home/web_user/.config/retroarch/retroarch.cfg',{ encoding: 'utf8' }); + console.log(data); + var dbfs = new BrowserFS.FileSystem.Dropbox(client); + BrowserFS.initialize(dbfs); + var BFS = new BrowserFS.EmscriptenFS(); + + var fs = BrowserFS.BFSRequire('fs'); + fs.writeFile('retroarch.cfg', data ,{ encoding: 'utf8' }); +} + +var Module = +{ + noInitialRun: true, + arguments: ["-v", "--menu"], + preRun: [], + postRun: [], + print: (function() + { + var element = document.getElementById('output'); + element.value = ''; // clear browser cache + return function(text) + { + text = Array.prototype.slice.call(arguments).join(' '); + element.value += text + "\n"; + element.scrollTop = 99999; // focus on bottom + }; + })(), + + printErr: function(text) + { + var text = Array.prototype.slice.call(arguments).join(' '); + var element = document.getElementById('output'); + element.value += text + "\n"; + element.scrollTop = 99999; // focus on bottom + }, + canvas: document.getElementById('canvas'), + + totalDependencies: 0, + monitorRunDependencies: function(left) + { + this.totalDependencies = Math.max(this.totalDependencies, left); + } +}; \ No newline at end of file From 361949e89a8fe94ec45421e1de4c05c86a3f0493 Mon Sep 17 00:00:00 2001 From: Rob Loach <robloach@gmail.com> Date: Tue, 16 Aug 2016 23:35:25 -0400 Subject: [PATCH 2/2] Add JS/CSS documentation --- emscripten/webplayer.css | 39 +++++++++++++++++++++++++++++++++------ emscripten/webplayer.js | 5 +++++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/emscripten/webplayer.css b/emscripten/webplayer.css index ec7cb08e42..7d24e4e63e 100644 --- a/emscripten/webplayer.css +++ b/emscripten/webplayer.css @@ -1,6 +1,33 @@ - -.webplayer { padding-right: 0; margin-left: auto; margin-right: auto; display: block; } -textarea.webplayer { border: 0px; font-family: 'Share Tech Mono'; font-size: 12px; width: 100%; overflow:hide; resize:none; color:black; } -div.webplayer, h1 { text-align: left; } -div.canvas_border { background-color:gray; width:800px; height:600px; margin-left: auto; margin-right: auto; } -canvas.webplayer { border: 0px none; } \ No newline at end of file +/** + * RetroArch Web Player + * + * This provides the basic styling for the RetroArch web player. + */ +.webplayer { + padding-right: 0; + margin-left: auto; + margin-right: auto; + display: block; +} +textarea.webplayer { + border: 0px; + font-family: 'Share Tech Mono'; + font-size: 12px; + width: 100%; + overflow:hide; + resize:none; + color:black; +} +div.webplayer, +h1 { + text-align: left; +} +div.canvas_border { + background-color:gray; + width:800px; height:600px; + margin-left: auto; + margin-right: auto; +} +canvas.webplayer { + border: 0px none; +} diff --git a/emscripten/webplayer.js b/emscripten/webplayer.js index 463a3f232d..062968c97d 100644 --- a/emscripten/webplayer.js +++ b/emscripten/webplayer.js @@ -1,3 +1,8 @@ +/** + * RetroArch Web Player + * + * This provides the basic JavaScript for the RetroArch web player. + */ var dropbox = false; var client = new Dropbox.Client({ key: "il6e10mfd7pgf8r" });