view mpui.js @ 212:b3579297e04e

Implement rest of the stuff needed for selecting external palettes in the launcher and actual Multipaint code.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 03 Sep 2018 14:22:20 +0300
parents 13aed87e472a
children ddb36f1c515f
line wrap: on
line source

/*
 * Multipaint.JS - Javascript launcher
 * (C) Copyright 2018 Matti 'ccr' Hämäläinen <ccr@tnsp.org>
 */
var mpMachine = 0, mpUIScale,
  mpUIForcedWidth, mpUIForcedHeight, mpURL,
  mpUIPalette;

// Machine ID, Name/desc, Alt.palette array index (-1 if none)
var mpMachines =
[
  [   0, "C64 hires"           , 0 ],
  [  10, "C64 multicolor"      , 0 ],
  [   6, "ZX Spectrum"         , -1 ],
  [   5, "MSX1 mode 2"         , -1 ],
  [   9, "Plus4 hires"         , -1 ],
  [  19, "Plus4 multicolor"    , -1 ],
  [   2, "Amstrad CPC mode 0"  , -1 ],

  [  -1, "Experimental/unsupported modes below" , -1 ],

  [  32, "C64 no limit (buggy)", 0 ],
  [  20, "C64 FLI hires"       , 0 ],
  [  21, "C64 FLI multicolor"  , 0 ],
  [   7, "Timex"               , -1 ],
  [   8, "JR200"               , -1 ],
  [  99, "BK-0010"             , -1 ],
//  [  , "" , -1 ],
];


// Alternative palettes array
var mpPalettes =
[
  [ "pepto.act", "colodore.act", ],
];


// UI dimensions list (first is always "default")
var mpUIDimensions =
[
  [ -1, -1 ],
  [ 1200, 800 ],
  [ 1600, 800 ],
  [ 1600, 1000 ],
];


// UI scaling factors, 2 is default and thus first
var mpUIScales =
[
  2, 3, 1
];


var mpSources =
[
  "buffers.pde",
  "files.pde",
  "preview.pde",
  "draw_inputs.pde",
  "draw_outputs.pde",
  "draw_smart.pde",
  "events.pde",
  "exporters.pde",
  "interface.pde",
  "multipaint.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 stGetSelIndex(vname)
{
  var velem = stGE(vname);
  return velem ? velem.selectedIndex : 0;
}


function stGetSelValue(velem, vdef)
{
  if (velem)
    return velem.selectedIndex >= 0 ? velem.options[velem.selectedIndex].value : vdef;
  else
    return vdef;
}


function stCreateSelect(vid, vlist, vcallback)
{
  var vobj = stCE("select", vid);

  for (var n = 0; n < vlist.length; n++)
  {
    var mp = vlist[n];
    var opt = stCE("option");
    vcallback(n, opt, mp);
    vobj.appendChild(opt);
  }

  return vobj;
}


function stCleanFilename(vstr)
{
  return vstr.replace(/[^a-z0-9_\.]/ig, "");
}


function mpMachineChanged()
{
  var tmp = stGetSelIndex("machineID");
  var velem = stGE("paletteID");
  var palID = mpMachines[tmp][2];
  velem.style.display = (palID >= 0) ? "block" : "none";
  stClearChildren(velem);
  if (palID >= 0)
  {
    var vlist = mpPalettes[palID];
    for (var n = 0; n < vlist.length; n++)
    {
      var mp = vlist[n];
      var opt = stCE("option");
      opt.value = n;
      opt.textContent = mp;
      velem.appendChild(opt);
    }
  }
}


function mpShowLauncher()
{
  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", "mmachine");
  mpUI.appendChild(mdiv);

  mobj = stCE("p");
  mobj.textContent = "Target machine / mode:";
  mdiv.appendChild(mobj);

  mobj = stCreateSelect("machineID", mpMachines,
    function (vn, vopt, val)
    {
      if (val[0] < 0)
        vopt.disabled = true;
      else
        vopt.value = val[0];

      vopt.textContent = val[1];
    });

  mdiv.appendChild(mobj);
  stAddEventOb(mobj.name, mobj, "change", mpMachineChanged);

  mobj = stCE("button", "selectID");
  mobj.textContent = "RUN";
  stAddEventOb(mobj.name, mobj, "click", mpLauncherDone);
  mdiv.appendChild(mobj);

  mobj = stCE("div");
  mdiv.appendChild(mobj);
  mobj.appendChild(stCE("select", "paletteID"));

  mdiv = stCE("div", "mdimensions");
  mpUI.appendChild(mdiv);

  mobj = stCE("p");
  mobj.textContent = "Choose UI size / scale:";
  mdiv.appendChild(mobj);

  mdiv.appendChild(stCreateSelect("dimensionsID", mpUIDimensions,
    function (vn, vopt, val) { vopt.value = vn; vopt.textContent = (vn == 0) ? "DEFAULT" : val[0] +" x "+ val[1]; }));

  mdiv.appendChild(stCreateSelect("scalesID", mpUIScales,
    function (vn, vopt, val) { vopt.value = val; vopt.textContent = " x "+ val; }));

  mpMachineChanged();

  mobj = stCE("div");
  mobj.innerHTML =
    "<p><b>Things of note:</b></p>"+
    "<ul>"+
    "<li>Save ('S') and Load ('L') save to/load from <a href=\"https://en.wikipedia.org/wiki/Web_storage\">browser local storage</a> "+
    "(there can be only one \"save\" per machine type, so be careful.)</li>"+
    "<li>Each machine type has its own local storage save space.</li>"+
    "<li>Save as ('s') and Load from ('l') export and import Multipaint workfiles.</li>"+
    "<li>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.</li>"+
    "</ul>"+
    "<p><b>Existing problems:</b></p>"+
    "<ul>"+
    "<li>All of Multipaint v1.8.2018 changes have been integrated, "+
    "but there are no UI widgets for changing some settings, "+
    "loading of alternate palettes, etc. (yet.. might take time to implement these.)</li>"+
    "<li>Source code export is not guaranteed to work (it is enabled now, though.)</li>"+
    "<li>PNG/JPEG <b>import</b> does not work. <b>PNG export works now (alt+shift+W or alt+click on format export icon.)</b></li>"+
    "<li>The 'magnify' tool works oddly, though I think this issue may exist in the original as well.</li>"+
    "<li>The preview window seems to be buggy for multicolor bitmaps.</li>"+
    "<li>There may be other bugs .. though I've also fixed few bugs that exist in original Multipaint.</li>"+
    "</ul>"+
    "<p>You can also view the <a href=\"https://tnsp.org/hg/forks/multipaint-js/\">Mercurial repository for this project</a>.</p>";

  mpUI.appendChild(mobj);
}


function mpLauncherDone()
{
  // Get selected values from DOM elements
  var mpUI = stGE("mpUI");
  mpMachine = stGetSelValue(stGE("machineID"), 0);

  var index = stGetSelValue(stGE("dimensionsID"), -1);
  if (index > 0)
  {
    mpUIForcedWidth = mpUIDimensions[index][0];
    mpUIForcedHeight = mpUIDimensions[index][1];
  }
  else
    mpUIForcedWidth = mpUIForcedHeight = 0;

  mpUIScale = stGetSelValue(stGE("scalesID"), -1);
  index = stGetSelValue(stGE("paletteID"), -1);
  if (index >= 0)
    mpUIPalette = mpPalettes[mpMachine][index];

  stClearChildren(mpUI);

  // Initialize the canvas etc.
  var mpCanvas = stGE("mpCanvas");
  mpCanvas.style.display = "block";

  window.location.href = mpURL +"?"+
    mpMachine.toString() +":"+
    mpUIForcedWidth +":"+ mpUIForcedHeight +":"+ mpUIScale +":"+ mpUIPalette;

  mpRunSketch(mpCanvas);
}


function mpStart()
{
  stGE("mpNote").innerHTML =
    "<a href=\"http://multipaint.kameli.net/\">Multipaint</a> (C) 2016-2018 <b>Tero 'Dr. TerrorZ' Heikkinen</b>, "+
    "ProcessingJS port and modifications by <b>Matti 'ccr' Hämäläinen</b> (2018)";

  // Check for URL parameters
  var slink = window.location.href;
  var spos, found = false;
  if ((spos = slink.indexOf("?")) >= 0)
  {
    var sargs = unescape(slink.substr(spos + 1)).split(":");
    mpURL = slink.substr(0, spos);
    mpMachine = parseInt(sargs[0]);
    found = true;

    if (sargs.length >= 3)
    {
      mpUIForcedWidth = parseInt(sargs[1]);
      mpUIForcedHeight = parseInt(sargs[2]);
    }
    if (sargs.length >= 4)
      mpUIScale = parseInt(sargs[3]);

    if (sargs.length >= 5)
      mpUIPalette = stCleanFilename(sargs[4]);
  }
  else
    mpURL = slink;

  // Either run sketch or show the launcher
  if (found)
  {
    mpRunSketch(stGE("mpCanvas"));
  }
  else
  {
    stAddEventOb("DOM", document, "DOMContentLoaded", mpShowLauncher);
  }
}