Code cleanup
This commit is contained in:
parent
7913ef2a0a
commit
b6cf972131
36 changed files with 561 additions and 227 deletions
451
modules/build/lib/build.js
Normal file
451
modules/build/lib/build.js
Normal file
|
|
@ -0,0 +1,451 @@
|
|||
/**
|
||||
* @fileoverview PCjs Build Options
|
||||
* @author <a href="mailto:Jeff@pcjs.org">Jeff Parsons</a>
|
||||
* @version 1.0
|
||||
* Created 2016-Feb-10
|
||||
*
|
||||
* Copyright © 2012-2016 Jeff Parsons <Jeff@pcjs.org>
|
||||
*
|
||||
* This file is part of the JavaScript Machines Project (aka JSMachines) at <http://jsmachines.net/>
|
||||
* and <http://pcjs.org/>.
|
||||
*
|
||||
* JSMachines is free software: you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation, either version 3
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* JSMachines is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with JSMachines.
|
||||
* If not, see <http://www.gnu.org/licenses/gpl.html>.
|
||||
*
|
||||
* You are required to include the above copyright notice in every source code file of every
|
||||
* copy or modified version of this work, and to display that copyright notice on every screen
|
||||
* that loads or runs any version of this software (see Computer.COPYRIGHT).
|
||||
*
|
||||
* Some JSMachines files also attempt to load external resource files, such as character-image files,
|
||||
* ROM files, and disk image files. Those external resource files are not considered part of the
|
||||
* JSMachines Project for purposes of the GNU General Public License, and the author does not claim
|
||||
* any copyright as to their contents.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
* This file provides all the UI options for building a functional PCjs PC.
|
||||
*/
|
||||
|
||||
var typeAddress = {
|
||||
type: "address"
|
||||
};
|
||||
|
||||
var typeBoolean = {
|
||||
type: "boolean"
|
||||
};
|
||||
|
||||
var typeNumber = {
|
||||
type: "number"
|
||||
};
|
||||
|
||||
var typePath = {
|
||||
type: "string"
|
||||
};
|
||||
|
||||
var typeString = {
|
||||
type: "string"
|
||||
};
|
||||
|
||||
var typeElement = {
|
||||
type: "element"
|
||||
};
|
||||
|
||||
var machineOptions = {
|
||||
'ibm5150': "IBM PC (Model 5150)",
|
||||
'ibm5160': "IBM PC XT (Model 5160)",
|
||||
'ibm5170': "IBM PC AT (Model 5170)",
|
||||
'deskpro386': "COMPAQ DeskPro 386"
|
||||
};
|
||||
|
||||
var videoLEDCapsLock = {
|
||||
'control': {
|
||||
_type: typeElement,
|
||||
'type': {
|
||||
_type: typeString,
|
||||
_value: "led"
|
||||
},
|
||||
'label': {
|
||||
_type: typeString,
|
||||
_value: "Caps"
|
||||
},
|
||||
'binding': {
|
||||
_type: typeString,
|
||||
_value: "caps-lock"
|
||||
},
|
||||
'pad-left': {
|
||||
_type: typeString,
|
||||
_value: "8px"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var videoLEDNumLock = {
|
||||
'control': {
|
||||
_type: typeElement,
|
||||
'type': {
|
||||
_type: typeString,
|
||||
_value: "led"
|
||||
},
|
||||
'label': {
|
||||
_type: typeString,
|
||||
_value: "Num"
|
||||
},
|
||||
'binding': {
|
||||
_type: typeString,
|
||||
_value: "num-lock"
|
||||
},
|
||||
'pad-left': {
|
||||
_type: typeString,
|
||||
_value: "8px"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var videoLEDScrollLock = {
|
||||
'control': {
|
||||
_type: typeElement,
|
||||
'type': {
|
||||
_type: typeString,
|
||||
_value: "led"
|
||||
},
|
||||
'label': {
|
||||
_type: typeString,
|
||||
_value: "Scroll"
|
||||
},
|
||||
'binding': {
|
||||
_type: typeString,
|
||||
_value: "scroll-lock"
|
||||
},
|
||||
'pad-left': {
|
||||
_type: typeString,
|
||||
_value: "8px"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var videoLEDContainer = {
|
||||
_type: typeElement,
|
||||
_value: [videoLEDCapsLock, videoLEDNumLock, videoLEDScrollLock],
|
||||
'type': {
|
||||
_type: typeString,
|
||||
_value: "container"
|
||||
},
|
||||
'pos': {
|
||||
_type: typeString,
|
||||
_value: "right"
|
||||
}
|
||||
};
|
||||
|
||||
var videoCGALEDContainer = {
|
||||
'title': {
|
||||
_type: typeElement,
|
||||
_value: "Color Display"
|
||||
},
|
||||
'control': videoLEDContainer
|
||||
};
|
||||
|
||||
var videoCGALEDMenu = {
|
||||
'menu': {
|
||||
_type: typeElement,
|
||||
_value: videoCGALEDContainer
|
||||
}
|
||||
};
|
||||
|
||||
var machineElements = {
|
||||
'name': {
|
||||
_type: typeElement,
|
||||
_desc: "Machine Description",
|
||||
_value: "IBM PC"
|
||||
},
|
||||
'computer': {
|
||||
_type: typeElement,
|
||||
_desc: "General Computer Features",
|
||||
_value: null,
|
||||
'buswidth': {
|
||||
_type: typeNumber,
|
||||
_desc: "Bus width",
|
||||
_opts: {
|
||||
20: "20-bit bus",
|
||||
24: "24-bit bus",
|
||||
32: "32-bit bus"
|
||||
}
|
||||
},
|
||||
'resume': {
|
||||
_type: typeNumber,
|
||||
_desc: "Resume option",
|
||||
_opts: {
|
||||
0: "Resume Disabled",
|
||||
1: "Resume Enabled",
|
||||
2: "Resume with Prompt"
|
||||
}
|
||||
}
|
||||
},
|
||||
'ram': {
|
||||
_type: typeElement,
|
||||
_desc: "Read-Write Memory (Conventional or Extended)",
|
||||
_multi: true,
|
||||
_value: [
|
||||
{
|
||||
'id': "ramLow",
|
||||
'addr': "0x00000"
|
||||
}
|
||||
],
|
||||
'id': {
|
||||
_type: typeString
|
||||
},
|
||||
'addr': {
|
||||
_type: typeAddress
|
||||
},
|
||||
'size': {
|
||||
_type: typeNumber
|
||||
}
|
||||
},
|
||||
'rom': {
|
||||
_type: typeElement,
|
||||
_desc: "Read-Only Memory",
|
||||
_multi: true,
|
||||
_value: [
|
||||
{
|
||||
'id': "romBASIC",
|
||||
'addr': "0xf6000",
|
||||
'size': "0x8000",
|
||||
'file': "/devices/pc/rom/5150/basic/BASIC100.json"
|
||||
},
|
||||
{
|
||||
'id': "romBIOS",
|
||||
'addr': "0xfe000",
|
||||
'size': "0x2000",
|
||||
'file': "/devices/pc/rom/5150/bios/1981-04-24/PCBIOS-REV1.json"
|
||||
}
|
||||
],
|
||||
'addr': {
|
||||
_type: typeAddress
|
||||
},
|
||||
'size': {
|
||||
_type: typeNumber
|
||||
},
|
||||
'file': {
|
||||
_type: typePath
|
||||
}
|
||||
},
|
||||
'video': {
|
||||
_type: typeElement,
|
||||
_desc: "Video Adapter",
|
||||
_multi: false,
|
||||
_opts: {
|
||||
'cga': {
|
||||
'screenwidth': {
|
||||
_type: typeNumber,
|
||||
_opts: [960]
|
||||
},
|
||||
'screenheight': {
|
||||
_type: typeNumber,
|
||||
_opts: [480]
|
||||
},
|
||||
'scale': {
|
||||
_type: typeBoolean,
|
||||
_opts: [true]
|
||||
},
|
||||
'charset': {
|
||||
_type: typePath,
|
||||
_opts: ["/devices/pc/video/ibm/cga/ibm-cga.json"]
|
||||
},
|
||||
'pos': {
|
||||
_type: typeString,
|
||||
_opts: ["center"]
|
||||
},
|
||||
'padding': {
|
||||
_type: typeString,
|
||||
_opts: ["8px"]
|
||||
},
|
||||
'controls': videoCGALEDMenu
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var pcElements = {
|
||||
'machine': {
|
||||
_desc: "Machine",
|
||||
_type: typeElement,
|
||||
_opts: machineOptions,
|
||||
_value: machineElements,
|
||||
'id': {
|
||||
_type: typeString
|
||||
},
|
||||
'class': {
|
||||
_type: typeString,
|
||||
_value: "pc"
|
||||
},
|
||||
'border': {
|
||||
_type: typeNumber,
|
||||
_value: "1"
|
||||
},
|
||||
'pos': {
|
||||
_type: typeString,
|
||||
_value: "center"
|
||||
},
|
||||
'background': {
|
||||
_type: typeString,
|
||||
_value: "#FAEBD7"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* As we build a PC, elements will be added to pcState that mirror the template structures above. Also,
|
||||
* as choices are made, the identifier of that choice will be added as the 'id' of the corresponding element.
|
||||
*
|
||||
* 'machine': {
|
||||
* 'id': "ibm5150",
|
||||
* 'class': "pc",
|
||||
* 'border': "1",
|
||||
* 'pos': "center"
|
||||
* 'background': "#FAEBD7"
|
||||
* 'name': {
|
||||
* },
|
||||
* 'computer': {
|
||||
* },
|
||||
* 'ram': {
|
||||
* }
|
||||
* // ...
|
||||
* }
|
||||
*/
|
||||
var pcState = {};
|
||||
|
||||
/**
|
||||
* findNewItem(state, template)
|
||||
*
|
||||
* @param {Object} state (eg, pcState)
|
||||
* @param {Object} template (eg, pcElements)
|
||||
* @return {Object|null} (eg, state['machine'])
|
||||
*/
|
||||
function findNewItem(state, template)
|
||||
{
|
||||
for (var item in template) {
|
||||
|
||||
if (item.charAt(0) == '_') continue;
|
||||
|
||||
if (state[item] === undefined) {
|
||||
state[item] = {
|
||||
_template: template[item]
|
||||
};
|
||||
return state[item];
|
||||
}
|
||||
|
||||
if (typeof template[item] == "object") {
|
||||
var itemNext = findNewItem(state[item], template[item]);
|
||||
if (itemNext) return itemNext;
|
||||
}
|
||||
}
|
||||
|
||||
if (template._type == typeElement && template._value && typeof template._value == "object") {
|
||||
return findNewItem(state, template._value);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* setNewItem(idHTML, eHTML, item)
|
||||
*
|
||||
* @param {string} idHTML
|
||||
* @param {Object} eHTML
|
||||
* @param {Object} item (ie, a node in pcState with a _template that contains _opts)
|
||||
*/
|
||||
function setNewItem(idHTML, eHTML, item)
|
||||
{
|
||||
/*
|
||||
* First, remove any old options...
|
||||
*
|
||||
while (eHTML.firstChild) {
|
||||
eHTML.removeChild(eHTML.firstChild);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
* Next, add a new set of options....
|
||||
*/
|
||||
var value;
|
||||
var opts = item._template._opts;
|
||||
if (!opts) {
|
||||
value = item._template._value;
|
||||
if (value) {
|
||||
populateItem(item, null);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Add an input field to prompt for the value...
|
||||
*/
|
||||
}
|
||||
setTimeout(function() { buildPC(idHTML) }, 0);
|
||||
}
|
||||
else {
|
||||
var eSelect = document.createElement("select");
|
||||
var eOption = document.createElement("option");
|
||||
eOption['value'] = "none";
|
||||
eOption.textContent = "Select a " + item._template._desc + "...";
|
||||
eSelect.appendChild(eOption);
|
||||
for (value in opts) {
|
||||
eOption = document.createElement("option");
|
||||
eOption['value'] = value;
|
||||
eOption.textContent = opts[value];
|
||||
eSelect.appendChild(eOption);
|
||||
}
|
||||
eSelect.onchange = function(event) {
|
||||
var id = eSelect.value;
|
||||
if (id != "none" && id != item.id) {
|
||||
populateItem(item, id);
|
||||
setTimeout(function() { buildPC(idHTML) }, 0);
|
||||
}
|
||||
};
|
||||
eHTML.appendChild(eSelect);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* populateItem(item, id)
|
||||
*
|
||||
* @param {Object} item (eg, state['machine'])
|
||||
* @param {string|null} id for item
|
||||
*/
|
||||
function populateItem(item, id)
|
||||
{
|
||||
if (id) item.id = id;
|
||||
for (var prop in item._template) {
|
||||
if (prop == '_value' && !id) {
|
||||
item[prop] = item._template[prop];
|
||||
}
|
||||
if (prop.charAt(0) != '_') {
|
||||
var attr = item._template[prop];
|
||||
if (item[prop] === undefined && typeof attr._value == "string") {
|
||||
item[prop] = attr._value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* buildPC(idHTML)
|
||||
*
|
||||
* @param {string} idHTML (the ID of the DIV where build UI options should be presented)
|
||||
*/
|
||||
function buildPC(idHTML)
|
||||
{
|
||||
var eHTML = document.getElementById(idHTML);
|
||||
if (eHTML) {
|
||||
var item = findNewItem(pcState, pcElements);
|
||||
if (item) {
|
||||
setNewItem(idHTML, eHTML, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue