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