changeset 25:13dda1c3ae88

As we launch from a browser now, include the HTML and necessary Javascript bits for that. Also added in "docompile.html" that can be used to pre-compile the Multipaint PSJS code to a multipaint.js. Also included is a patch for Processing.js v1.4.8 that removes use for data: blob URIs that may be against many sites content security policy (CSP).
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 04 Jul 2018 10:27:30 +0300
parents 6b6c92c66002
children 7087fa1b3995
files compiled/index.html docompile.html index.html mpui.js multipaint.pde processing.js-1.4.8.patch
diffstat 6 files changed, 316 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiled/index.html	Wed Jul 04 10:27:30 2018 +0300
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>Multipaint.JS</title>
+  <script src="processing.min.js"></script>
+  <script src="mpui.js"></script>
+  <script src="multipaint.js"></script>
+</head>
+<body>
+<canvas id="mpCanvas"></canvas>
+<div id="mpUI"></div>
+<div id="mpNote"><a href="http://multipaint.kameli.net/">Multipaint</a> (C)
+2016-2017 <b>Tero "Dr. TerrorZ" Heikkinen</b>,
+ProcessingJS port and modifications by <b>Matti "ccr" Hämäläinen</b> (2018)
+</div>
+<script>
+
+function mpRunSketch(canvas)
+{
+  new Processing(canvas, multipaintJS);
+}
+
+mpStart();
+
+</script>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docompile.html	Wed Jul 04 10:27:30 2018 +0300
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>Multipaint</title>
+  <script src="processing.min.js"></script>
+  <script src="mpui.js"></script>
+</head>
+<body>
+<canvas id="mpCanvas"></canvas>
+<div id="mpUI"></div>
+<script>
+var mpMachine = 0;
+var mpCanvas = document.getElementById("mpCanvas");
+new Processing.loadSketchFromSources(mpCanvas, mpSources);
+
+function mpWaitUntilSketchIsReady()
+{
+  var inst = Processing.getInstanceById("mpCanvas");
+  if (inst)
+  {
+    var code = "var multipaintJS =\n"+ inst.externals.sketch.sourceCode;
+    var uriContent = "data:application/octet-stream,"+ encodeURIComponent(code);
+    document.getElementById("mpUI").innerHTML = "<a href="+ uriContent +" download=\"multipaint.js\">Here is the download link</a>";
+  }
+  else
+    setTimeout(mpWaitUntilSketchIsReady, 250);
+}
+
+document.addEventListener('DOMContentLoaded', mpWaitUntilSketchIsReady, false);
+
+</script>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/index.html	Wed Jul 04 10:27:30 2018 +0300
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>Multipaint.JS</title>
+  <script src="processing.js"></script>
+  <script src="mpui.js"></script>
+</head>
+<body>
+<canvas id="mpCanvas"></canvas>
+<div id="mpUI"></div>
+<div id="mpNote"><a href="http://multipaint.kameli.net/">Multipaint</a> (C)
+2016-2017 <b>Tero "Dr. TerrorZ" Heikkinen</b>,
+ProcessingJS port and modifications by <b>Matti "ccr" Hämäläinen</b> (2018)
+</div>
+<script>
+
+function mpRunSketch(canvas)
+{
+  Processing.loadSketchFromSources(canvas, mpSources);
+}
+
+mpStart();
+
+</script>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mpui.js	Wed Jul 04 10:27:30 2018 +0300
@@ -0,0 +1,168 @@
+var mpMachine = 0;
+
+var mpMachines =
+{
+    0  : "C64 hires",
+    10 : "C64 multicolor",
+    6  : "ZX Spectrum",
+    5  : "MSX1 mode 2",
+    9  : "Plus4 hires",
+    19 : "Plus4 multicolor",
+    2  : "Amstrad CPC mode 0",
+};
+
+
+var mpSources =
+[
+  "draw_inputs.pde",
+  "draw_outputs.pde",
+  "draw_smart.pde",
+  "events.pde",
+  "exporters.pde",
+  "Interface.pde",
+  "multipaint.pde",
+  "prefread.pde",
+];
+
+
+function stGE(obname)
+{
+  return document.getElementById(obname);
+}
+
+
+function stCE(obname, obid)
+{
+  var mob = document.createElement(obname);
+  if (obid)
+    mob.id = obid;
+  return mob;
+}
+
+
+function stClearChildren(obnode)
+{
+  while (obnode.firstChild)
+    obnode.removeChild(obnode.firstChild);
+}
+
+
+function stPRE(mstr)
+{
+  return mstr.toLowerCase().replace(/[^a-z0-9]/g, "_");
+}
+
+
+function stAddEventOb(obname, evobj, evtype, evcallback, evparam)
+{
+  if (evobj == null || typeof(evobj) == 'undefined')
+  {
+    console.log("Event object '"+ obname +"' == null.");
+    return;
+  }
+
+  evobj.addEventListener(evtype, evcallback, false);
+  evobj.evparam = evparam;
+}
+
+
+function stAddEvent(obname, evtype, evcallback, evparam)
+{
+  stAddEventOb(obname, stGE(obname), evtype, evcallback, evparam);
+}
+
+
+function mpShowMachineSelector()
+{
+  var mpCanvas = stGE("mpCanvas");
+  mpCanvas.style.display = "none";
+
+  var mpUI = stGE("mpUI");
+  mobj = stCE("h2");
+  mobj.textContent = "Multipaint.JS"
+  mpUI.appendChild(mobj);
+
+  var mdiv = stCE("div");
+  mpUI.appendChild(mdiv);
+
+  mobj = stCE("p");
+  mobj.textContent = "Choose your target machine:";
+  mdiv.appendChild(mobj);
+
+  mobj = stCE("select", "machineID");
+  for (var key in mpMachines)
+  {
+    var opt = stCE("option");
+    opt.value = key;
+    opt.textContent = mpMachines[key];
+    mobj.appendChild(opt);
+  }
+  mdiv.appendChild(mobj);
+
+  mobj = stCE("button", "selectID");
+  mobj.textContent = "RUN";
+  stAddEventOb(mobj.name, mobj, "click", mpMachineSelected);
+  mdiv.appendChild(mobj);
+
+  mobj = stCE("div");
+  mobj.innerHTML = 
+  "<p><b>Things that are known NOT to work:</b></p>"+
+  "<ul>"+
+  "<li>Native Multipaint save/load</li>"+
+  "<li>Source / PRG import/export</li>"+
+  "<li>PNG/JPEG import/export</li>"+
+  "<li>Flood fill tool</li>"+
+  "<li> .. there may be bugs.</li>"+
+  "</ul>"+
+  "<p><b>NOTICE!</b> When loading/importing, you click on the load icon (or press key) and a HTML file selector button will appear "+
+  "ON THE BOTTOM. You need to click that, too. Sorry, that can't be automated because of pop-up blocking etc..</p>";
+  mpUI.appendChild(mobj);
+
+  mobj = stCE("hr");
+  mpUI.appendChild(mobj);
+}
+
+
+function mpMachineSelected()
+{
+  var mpUI = stGE("mpUI");
+  var id = stGE("machineID");
+  mpMachine = id.selectedIndex >= 0 ? id.options[id.selectedIndex].value : 0;
+  stClearChildren(mpUI);
+
+  var mpCanvas = stGE("mpCanvas");
+  mpCanvas.style.display = "block";
+
+  window.location.href = window.location.href +"?"+ mpMachine.toString();
+
+  mpRunSketch(mpCanvas);
+}
+
+
+function mpStart()
+{
+  var slink = window.location.href;
+  var spos, found = false;
+  if ((spos = slink.indexOf("?")) >= 0)
+  {
+    var tmp = parseInt(unescape(slink.substr(spos + 1)));
+    for (var key in mpMachines)
+    {
+      if (key == tmp)
+      {
+        mpMachine = key;
+        found = true;
+        break;
+      }
+    }
+  }
+
+  if (found)
+  {
+    mpRunSketch(stGE("mpCanvas"));
+  }
+  else
+  {
+    stAddEventOb("DOM", document, "DOMContentLoaded", mpShowMachineSelector);
+  }
+}
--- a/multipaint.pde	Wed Jul 04 10:12:16 2018 +0300
+++ b/multipaint.pde	Wed Jul 04 10:27:30 2018 +0300
@@ -79,8 +79,7 @@
 
 void setup() {
     int i, x, y;
-    g_uizoom = 2;
-    g_animspeed = 1;
+
     frameRate(40);
     g_magpix[0] = 3;
     g_magpix[1] = 8;
@@ -105,7 +104,16 @@
     g_omag = 1;
     g_bordh = 64;
     g_bordv = 32;
-    readprefs("prefs.txt");
+
+    g_uizoom = 2;
+    g_animspeed = 1;
+
+    if (mpMachine)
+        machine = mpMachine;
+    else
+        machine = C64;
+
+//    readprefs("prefs.txt");
 
     //processing 2
     switch (g_uizoom) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/processing.js-1.4.8.patch	Wed Jul 04 10:27:30 2018 +0300
@@ -0,0 +1,48 @@
+--- processing.js	2018-07-04 10:13:30.641931795 +0300
++++ ../processing.js	2018-07-03 05:00:43.852701268 +0300
+@@ -336,7 +336,8 @@
+     MOVE:     'move',
+     TEXT:     'text',
+     WAIT:     'wait',
+-    NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto",
++//    NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto",
++    NOCURSOR: "default",
+ 
+     // Hints
+     DISABLE_OPENGL_2X_SMOOTH:     1,
+@@ -1999,11 +2000,13 @@
+       };
+       var fontface = document.createElement("style");
+       fontface.setAttribute("type","text/css");
++/*
+       fontface.innerHTML =  "@font-face {\n" +
+                             '  font-family: "PjsEmptyFont";' + "\n" +
+                             "  src: url('data:application/x-font-ttf;base64,"+generateTinyFont()+"')\n" +
+                             "       format('truetype');\n" +
+                             "}";
++*/
+       document.head.appendChild(fontface);
+ 
+       // set up the template element
+--- processing.min.js	2018-07-04 10:13:25.045938081 +0300
++++ ../processing.min.js	2018-07-03 00:56:38.585452065 +0300
+@@ -4,7 +4,7 @@
+ VZ:23,VW:24,AR:25,AG:26,AB:27,DR:3,DG:4,DB:5,DA:6,SPR:28,SPG:29,SPB:30,SHINE:31,ER:32,EG:33,EB:34,BEEN_LIT:35,VERTEX_FIELD_COUNT:36,P2D:1,JAVA2D:1,WEBGL:2,P3D:2,OPENGL:2,PDF:0,DXF:0,OTHER:0,WINDOWS:1,MAXOSX:2,LINUX:3,EPSILON:1E-4,MAX_FLOAT:3.4028235E38,MIN_FLOAT:-3.4028235E38,MAX_INT:2147483647,MIN_INT:-2147483648,PI:Math.PI,TWO_PI:2*Math.PI,TAU:2*Math.PI,HALF_PI:Math.PI/2,THIRD_PI:Math.PI/3,QUARTER_PI:Math.PI/4,DEG_TO_RAD:Math.PI/180,RAD_TO_DEG:180/Math.PI,WHITESPACE:" \t\n\r\f\u00a0",RGB:1,ARGB:2,
+ HSB:3,ALPHA:4,CMYK:5,TIFF:0,TARGA:1,JPEG:2,GIF:3,BLUR:11,GRAY:12,INVERT:13,OPAQUE:14,POSTERIZE:15,THRESHOLD:16,ERODE:17,DILATE:18,REPLACE:0,BLEND:1,ADD:2,SUBTRACT:4,LIGHTEST:8,DARKEST:16,DIFFERENCE:32,EXCLUSION:64,MULTIPLY:128,SCREEN:256,OVERLAY:512,HARD_LIGHT:1024,SOFT_LIGHT:2048,DODGE:4096,BURN:8192,ALPHA_MASK:4278190080,RED_MASK:16711680,GREEN_MASK:65280,BLUE_MASK:255,CUSTOM:0,ORTHOGRAPHIC:2,PERSPECTIVE:3,POINT:2,POINTS:2,LINE:4,LINES:4,TRIANGLE:8,TRIANGLES:9,TRIANGLE_STRIP:10,TRIANGLE_FAN:11,
+ QUAD:16,QUADS:16,QUAD_STRIP:17,POLYGON:20,PATH:21,RECT:30,ELLIPSE:31,ARC:32,SPHERE:40,BOX:41,GROUP:0,PRIMITIVE:1,GEOMETRY:3,VERTEX:0,BEZIER_VERTEX:1,CURVE_VERTEX:2,BREAK:3,CLOSESHAPE:4,OPEN:1,CLOSE:2,CORNER:0,CORNERS:1,RADIUS:2,CENTER_RADIUS:2,CENTER:3,DIAMETER:3,CENTER_DIAMETER:3,BASELINE:0,TOP:101,BOTTOM:102,NORMAL:1,NORMALIZED:1,IMAGE:2,MODEL:4,SHAPE:5,SQUARE:"butt",ROUND:"round",PROJECT:"square",MITER:"miter",BEVEL:"bevel",AMBIENT:0,DIRECTIONAL:1,SPOT:3,BACKSPACE:8,TAB:9,ENTER:10,RETURN:13,ESC:27,
+-DELETE:127,CODED:65535,SHIFT:16,CONTROL:17,ALT:18,CAPSLK:20,PGUP:33,PGDN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,NUMLK:144,META:157,INSERT:155,ARROW:"default",CROSS:"crosshair",HAND:"pointer",MOVE:"move",TEXT:"text",WAIT:"wait",NOCURSOR:"url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto",DISABLE_OPENGL_2X_SMOOTH:1,ENABLE_OPENGL_2X_SMOOTH:-1,ENABLE_OPENGL_4X_SMOOTH:2,
++DELETE:127,CODED:65535,SHIFT:16,CONTROL:17,ALT:18,CAPSLK:20,PGUP:33,PGDN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,NUMLK:144,META:157,INSERT:155,ARROW:"default",CROSS:"crosshair",HAND:"pointer",MOVE:"move",TEXT:"text",WAIT:"wait",NOCURSOR:"default",DISABLE_OPENGL_2X_SMOOTH:1,ENABLE_OPENGL_2X_SMOOTH:-1,ENABLE_OPENGL_4X_SMOOTH:2,
+ ENABLE_NATIVE_FONTS:3,DISABLE_DEPTH_TEST:4,ENABLE_DEPTH_TEST:-4,ENABLE_DEPTH_SORT:5,DISABLE_DEPTH_SORT:-5,DISABLE_OPENGL_ERROR_REPORT:6,ENABLE_OPENGL_ERROR_REPORT:-6,ENABLE_ACCURATE_TEXTURES:7,DISABLE_ACCURATE_TEXTURES:-7,HINT_COUNT:10,SINCOS_LENGTH:720,PRECISIONB:15,PRECISIONF:32768,PREC_MAXVAL:32767,PREC_ALPHA_SHIFT:9,PREC_RED_SHIFT:1,NORMAL_MODE_AUTO:0,NORMAL_MODE_SHAPE:1,NORMAL_MODE_VERTEX:2,MAX_LIGHTS:8}},{}],5:[function(D,x,Q){x.exports=function(k){function h(){}function m(a,d,f){if(a.hasOwnProperty(d)&&
+ "function"===typeof a[d]){var l=a[d];if("$overloads"in l)l.$defaultOverload=f;else if("$overloads"in f||l.length!==f.length){var p;"$overloads"in f?(p=f.$overloads.slice(0),p[l.length]=l,l=f.$defaultOverload):(p=[],p[f.length]=f,p[l.length]=l);var r=function(){return(r.$overloads[arguments.length]||("$methodArgsIndex"in r&&arguments.length>r.$methodArgsIndex?r.$overloads[r.$methodArgsIndex]:null)||r.$defaultOverload).apply(this,arguments)};r.$overloads=p;"$methodArgsIndex"in f&&(r.$methodArgsIndex=
+ f.$methodArgsIndex);r.$defaultOverload=l;r.name=d;a[d]=r}}else a[d]=f}function n(b,d){function f(f){a.defineProperty(b,f,{get:function(){return d[f]},set:function(c){d[f]=c},enumerable:!0})}var l=[],p;for(p in d)"function"===typeof d[p]?m(b,p,d[p]):"$"===p.charAt(0)||p in b||l.push(p);for(;0<l.length;)f(l.shift());b.$super=d}h.prototype=k.PConstants;var a=new h;Object.keys(k).forEach(function(b){a[b]=k[b]});a.defineProperty=function(a,d,f){"defineProperty"in Object?Object.defineProperty(a,d,f):(f.hasOwnProperty("get")&&
+@@ -36,8 +36,8 @@
+ r.font=p;p=n.createElement("div");p.style.position="absolute";p.style.opacity=0;p.style.fontFamily='"'+this.name+'"';p.style.fontSize="250px";p.innerHTML="dbflkhyjqpg<br/>dbflkhyjqpg";n.body.appendChild(p);var c=l.width,k=l.height,l=k/2;r.fillStyle="white";r.fillRect(0,0,c,k);r.fillStyle="black";r.fillText("dbflkhyjqpg",0,l);for(var k=r.getImageData(0,0,c,k).data,m=0,G=4*c,A=k.length;++m<A&&255===k[m];)a();c=Math.round(m/G);for(m=A-1;0<--m&&255===k[m];)a();k=Math.round(m/G);this.ascent=f*(l-c);this.descent=
+ f*(k-l);n.defaultView.getComputedStyle&&(l=n.defaultView.getComputedStyle(p,null).getPropertyValue("height"),l=f*l.replace("px",""),l>=2*this.size&&(this.leading=Math.round(l/2)));n.body.removeChild(p);f=this.caching?r:void 0;this.context2d=f;this.css=this.getCSSDefinition();this.context2d&&(this.context2d.font=this.css)}var n=k.Browser.document,a=k.noop;m.prototype.caching=!0;m.prototype.getCSSDefinition=function(a,d){a===h&&(a=this.size+"px");d===h&&(d=this.leading+"px");return[this.style,"normal",
+ this.weight,a+"/"+d,this.family].join(" ")};m.prototype.measureTextWidth=function(a){return this.context2d.measureText(a).width};m.prototype.measureTextWidthFallback=function(a){var d=n.createElement("canvas").getContext("2d");d.font=this.css;return d.measureText(a).width};m.PFontCache={length:0};m.get=function(a,d){d=(10*d+0.5|0)/10;var f=m.PFontCache,l=a+"/"+d;if(!f[l]){f[l]=new m(a,d);f.length++;if(50===f.length){m.prototype.measureTextWidth=m.prototype.measureTextWidthFallback;m.prototype.caching=
+-!1;for(var p in f)"length"!==p&&(f[p].context2d=null);return new m(a,d)}if(400===f.length)return m.PFontCache={},m.get=m.getFallback,new m(a,d)}return f[l]};m.getFallback=function(a,d){return new m(a,d)};m.list=function(){return["sans-serif","serif","monospace","fantasy","cursive"]};m.preloading={template:{},initialized:!1,initialize:function(){var a=n.createElement("style");a.setAttribute("type","text/css");a.innerHTML='@font-face {\n  font-family: "PjsEmptyFont";\n  src: url(\'data:application/x-font-ttf;base64,'+
+-function(){return"#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3#yld0xg32QAB77#E777773B#E3C#I#Q77773E#Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#".replace(/[#237]/g,function(a){return"AAAAAAAA".substr(~~a?7-a:6)})}()+"')\n       format('truetype');\n}";n.head.appendChild(a);a=n.createElement("span");a.style.cssText='position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;';
++!1;for(var p in f)"length"!==p&&(f[p].context2d=null);return new m(a,d)}if(400===f.length)return m.PFontCache={},m.get=m.getFallback,new m(a,d)}return f[l]};m.getFallback=function(a,d){return new m(a,d)};m.list=function(){return["sans-serif","serif","monospace","fantasy","cursive"]};m.preloading={template:{},initialized:!1,initialize:function(){var a=n.createElement("style");a.setAttribute("type","text/css");
++n.head.appendChild(a);a=n.createElement("span");a.style.cssText='position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;';
+ a.innerHTML="AAAAAAAA";n.body.appendChild(a);this.template=a;this.initialized=!0},getElementWidth:function(a){return n.defaultView.getComputedStyle(a,"").getPropertyValue("width")},timeAttempted:0,pending:function(a){this.initialized||this.initialize();for(var d,f,l=this.getElementWidth(this.template),p=0;p<this.fontList.length;p++){d=this.fontList[p];f=this.getElementWidth(d);if(4E3>this.timeAttempted&&f===l)return this.timeAttempted+=a,!0;n.body.removeChild(d);this.fontList.splice(p--,1);this.timeAttempted=
+ 0}return 0===this.fontList.length?!1:!0},fontList:[],addedList:{},add:function(a){this.initialized||this.initialize();var d="object"===typeof a?a.fontFace:a;a="object"===typeof a?a.url:a;if(!this.addedList[d]){var f=n.createElement("style");f.setAttribute("type","text/css");f.innerHTML="@font-face{\n  font-family: '"+d+"';\n  src:  url('"+a+"');\n}\n";n.head.appendChild(f);this.addedList[d]=!0;a=n.createElement("span");a.style.cssText="position: absolute; top: 0; left: 0; opacity: 0;";a.style.fontFamily=
+ '"'+d+'", "PjsEmptyFont", fantasy';a.innerHTML="AAAAAAAA";n.body.appendChild(a);this.fontList.push(a)}}};return m}},{}],13:[function(D,x,Q){x.exports=function(k,h){var m=k.p,n=function(){0===arguments.length?this.reset():1===arguments.length&&arguments[0]instanceof n?this.set(arguments[0].array()):6===arguments.length&&this.set(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5])};n.prototype={set:function(){if(6===arguments.length){var a=arguments;this.set([a[0],a[1],a[2],