Support for vertical text labels in graphical control panel
This commit is contained in:
parent
5477c1ae3e
commit
66bd2f2da0
5 changed files with 48 additions and 20 deletions
|
|
@ -11,7 +11,7 @@
|
|||
<video ref="/devices/pc/video/video-ega-128kb-lock.xml"/>
|
||||
<keyboard ref="/devices/pc/keyboard/keyboard-minimal-functions.xml"/>
|
||||
<debugger id="debugger" messages="fault" commands=""/>
|
||||
<fdc ref="/disks/pc/library.xml" padding="8px" automount='{A: {name: "PC-DOS 3.20 (Disk 1)", path: "/disks/pc/dos/ibm/3.20/PCDOS320-DISK1.json"}, B: {name: "PC-DOS 3.20 (Disk 2)", path: "/disks/pc/dos/ibm/3.20/PCDOS320-DISK2.json"}}'/>
|
||||
<fdc ref="/disks/pc/library.xml" automount='{A: {name: "PC-DOS 3.20 (Disk 1)", path: "/disks/pc/dos/ibm/3.20/PCDOS320-DISK1.json"}, B: {name: "PC-DOS 3.20 (Disk 2)", path: "/disks/pc/dos/ibm/3.20/PCDOS320-DISK2.json"}}'/>
|
||||
<panel ref="/devices/pc/panel/btpanel.xml"/>
|
||||
<hdc id="hdcAT" type="at" drives='[{name:"20Mb Hard Disk",type:2}]'/>
|
||||
<chipset id="chipset" model="5170" floppies="[1440,1200]" monitor="ega"/>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<fdc id="fdcNEC" pos="left" padleft="8px" padbottom="8px" automount='{A:{name:"PC-DOS 2.00 (Disk 1)",path:"/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json"}, B:{name:"PC-DOS 2.00 (Disk 2)",path:"/disks/pc/dos/ibm/2.00/PCDOS200-DISK2.json"}}'>
|
||||
<fdc id="fdcNEC" automount='{A:{name:"PC-DOS 2.00 (Disk 1)",path:"/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json"}, B:{name:"PC-DOS 2.00 (Disk 2)",path:"/disks/pc/dos/ibm/2.00/PCDOS200-DISK2.json"}}' pos="left" padleft="8px" padbottom="8px">
|
||||
<control type="list" binding="listDrives"/>
|
||||
<control type="list" binding="listDisks">
|
||||
<disk path="">None</disk>
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ So it's best to refer to these files generically as "modules", and more specific
|
|||
whenever they implement a specific device (or set of devices, in the case of [*ChipSet*](/docs/pcjs/chipset/)).
|
||||
|
||||
Examples of non-device modules include UI modules like [panel.js](panel.js) and [debugger.js](debugger.js),
|
||||
and sub-modules like [x86opxx.js](x86opxx.js), [x86mods.js](x86mods.js) and [x86help.js](x86help.js)
|
||||
that separate the CPU functionality of [x86.js](x86.js) into more manageable pieces.
|
||||
and sub-modules like [x86opxx.js](x86opxx.js) and [x86help.js](x86help.js) that separate the CPU functionality
|
||||
of [x86.js](x86.js) into more manageable pieces.
|
||||
|
||||
These modules should always be loaded or compiled in the order listed by the *pcJSFiles* property in
|
||||
[package.json](../../../package.json), which includes all the necessary *shared* modules as well.
|
||||
|
|
@ -39,7 +39,13 @@ At the time of this writing, the order is:
|
|||
* [pcjs/x86cpu.js](x86cpu.js)
|
||||
* [pcjs/x86grps.js](x86grps.js)
|
||||
* [pcjs/x86help.js](x86help.js)
|
||||
* [pcjs/x86mods.js](x86mods.js)
|
||||
* [pcjs/x86modb.js](x86modb.js)
|
||||
* [pcjs/x86modw.js](x86modw.js)
|
||||
* [pcjs/x86modb16.js](x86modb16.js)
|
||||
* [pcjs/x86modw16.js](x86modw16.js)
|
||||
* [pcjs/x86modb32.js](x86modb32.js)
|
||||
* [pcjs/x86modw32.js](x86modw32.js)
|
||||
* [pcjs/x86modsib.js](x86modsib.js)
|
||||
* [pcjs/x86opxx.js](x86opxx.js)
|
||||
* [pcjs/x86op0f.js](x86op0f.js)
|
||||
* [pcjs/chipset.js](chipset.js)
|
||||
|
|
@ -87,14 +93,14 @@ would make the feature dramatically more expensive, both in terms of size and sp
|
|||
|
||||
A BackTrack index is encoded as a 32-bit value with three parts:
|
||||
|
||||
- 15-bit BackTrack object index
|
||||
- 9-bit source object offset (0-511)
|
||||
- 6-bit generation number (1-63)
|
||||
- Bits 0-8: 9-bit BackTrack object offset (0-511)
|
||||
- Bits 9-15: 7-bit type and access info
|
||||
- Bits 16-30: 15-bit BackTrack object number (1-32767, 0 reserved for dynamic data)
|
||||
|
||||
This represents a total of 30 bits, with 2 bits reserved.
|
||||
This represents a total of 31 bits, with bit 31 reserved.
|
||||
|
||||
Let's look at one of the last things a ROM does during boot: load a disk sector into RAM. It will be up to the disk
|
||||
controller (or DMA controller if one is used) to create a BackTrack object representing the sector that was read,
|
||||
For example, look at one of the last things a ROM does during boot: load a disk sector into RAM. It will be up to the
|
||||
disk controller (or DMA controller if one is used) to create a BackTrack object representing the sector that was read,
|
||||
adding that object to the global BackTrack object array, and then associating the corresponding BackTrack index with
|
||||
the first byte of RAM where the sector was loaded. Subsequent bytes of RAM containing the rest of the sector will refer
|
||||
to the same BackTrack object, using BackTrack indexes containing offsets 1-511.
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ if (typeof module !== 'undefined') {
|
|||
global.TYPEDARRAYS = TYPEDARRAYS;
|
||||
global.BACKTRACK = BACKTRACK;
|
||||
global.SAMPLER = SAMPLER;
|
||||
global.BUGS_8086 = BUGS_8086;
|
||||
global.I386 = I386;
|
||||
/*
|
||||
* TODO: When we're "required" by Node, should we return anything via module.exports?
|
||||
|
|
|
|||
|
|
@ -198,7 +198,10 @@ Rectangle.prototype.contains = function(x, y)
|
|||
Rectangle.prototype.subDivide = function(units, unitsTotal, fHorizontal)
|
||||
{
|
||||
var rect;
|
||||
if (fHorizontal || units >= (unitsTotal >> 2)) {
|
||||
if (fHorizontal === undefined) {
|
||||
fHorizontal = units >= (unitsTotal >> 2);
|
||||
}
|
||||
if (fHorizontal) {
|
||||
rect = new Rectangle(this.x, this.y, this.cx, ((this.cy * units) / unitsTotal) | 0);
|
||||
this.y += rect.cy;
|
||||
this.cy -= rect.cy;
|
||||
|
|
@ -221,6 +224,8 @@ Rectangle.prototype.subDivide = function(units, unitsTotal, fHorizontal)
|
|||
Rectangle.prototype.drawWith = function(context, color)
|
||||
{
|
||||
if (!color) color = new Color();
|
||||
context.strokeStyle = "black";
|
||||
context.strokeRect(this.x, this.y, this.cx, this.cy);
|
||||
context.fillStyle = (typeof color == "string"? color : color.toString());
|
||||
context.fillRect(this.x, this.y, this.cx, this.cy);
|
||||
};
|
||||
|
|
@ -412,7 +417,7 @@ Panel.prototype.moveMouse = function(event)
|
|||
*
|
||||
* @this {Panel}
|
||||
* @param {Object} event object from a mouse event (specifically, a MouseEvent object)
|
||||
* @param {boolean} [fDown]
|
||||
* @param {boolean} [fDown] is true or false if this was a click event, otherwise it's just a move event
|
||||
*/
|
||||
Panel.prototype.updateMouse = function(event, fDown)
|
||||
{
|
||||
|
|
@ -443,6 +448,7 @@ Panel.prototype.updateMouse = function(event, fDown)
|
|||
|
||||
if (MAXDEBUG) this.log("Panel.moveMouse(" + x + "," + y + ")");
|
||||
this.assert(x >= 0 && x < Panel.LIVECANVAS.CX && y >= 0 && y < Panel.LIVECANVAS.CY);
|
||||
|
||||
/*
|
||||
* Convert the mouse position into the corresponding memory address, assuming it's over the live memory area
|
||||
*/
|
||||
|
|
@ -481,7 +487,7 @@ Panel.prototype.findAddress = function(x, y)
|
|||
var addrLimit = (iBlock + cBlocks) * this.bus.blockSize - 1;
|
||||
|
||||
/*
|
||||
* If you want memory to be displayed "vertically" instead of "horizontally", do this instead:
|
||||
* If you want memory to be arranged "vertically" instead of "horizontally", do this:
|
||||
*
|
||||
* if (x > 0) addr += rect.cy * (x - 1) * this.ratioMemoryToPixels;
|
||||
* addr += (y * this.ratioMemoryToPixels);
|
||||
|
|
@ -538,7 +544,7 @@ Panel.prototype.updateAnimation = function()
|
|||
var cBlocksRemaining = this.stats.cBlocks;
|
||||
for (i = 0; i < this.stats.cRegions; i++) {
|
||||
var cBlocksRegion = (this.stats.aRegions[i] >> Bus.BLOCK.COUNT_SHIFT) & Bus.BLOCK.COUNT_MASK;
|
||||
this.stats.aRects.push(rect = rectAvail.subDivide(cBlocksRegion, cBlocksRemaining, true));
|
||||
this.stats.aRects.push(rect = rectAvail.subDivide(cBlocksRegion, cBlocksRemaining, i == 0));
|
||||
if (MAXDEBUG) this.log("region " + i + " rectangle: (" + rect.x + "," + rect.y + " " + rect.cx + "," + rect.cy + ")");
|
||||
cBlocksRemaining -= cBlocksRegion;
|
||||
}
|
||||
|
|
@ -789,11 +795,22 @@ Panel.prototype.centerPen = function(rect)
|
|||
{
|
||||
this.fontText = this.fontDefault;
|
||||
this.heightText = this.heightDefault;
|
||||
if (rect.cy < this.heightText) {
|
||||
this.heightText = rect.cy;
|
||||
var x = rect.x + (rect.cx >> 1);
|
||||
var y = rect.y + (rect.cy >> 1);
|
||||
var maxText = rect.cy;
|
||||
if (rect.cx < rect.cy) {
|
||||
maxText = rect.cx;
|
||||
this.fVerticalText = true;
|
||||
this.contextText.save();
|
||||
this.contextText.translate(x, y);
|
||||
this.contextText.rotate(-Math.PI/2);
|
||||
x = y = 0;
|
||||
}
|
||||
if (maxText < this.heightText) {
|
||||
this.heightText = maxText;
|
||||
this.fontText = this.heightText + "px " + Panel.LIVECANVAS.FONT.FACE;
|
||||
}
|
||||
this.setPen(rect.x + (rect.cx >> 1), rect.y + (rect.cy >> 1));
|
||||
this.setPen(x, y);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -880,7 +897,7 @@ Panel.prototype.drawText = function(sText, nValue, nColsSkip, nLinesSkip)
|
|||
*
|
||||
* centerPen() sets xLeft and yTop to the center of the specified rectangle, and centerText() calculates
|
||||
* the width of the text, adjusting the horizontal centering by its width and the vertical centering by the
|
||||
* default font height. Then it call drawText().
|
||||
* default font height. Then it calls drawText().
|
||||
*
|
||||
* @this {Panel}
|
||||
* @param {string} sText
|
||||
|
|
@ -890,8 +907,12 @@ Panel.prototype.centerText = function(sText)
|
|||
this.contextText.font = this.fontText;
|
||||
var tm = this.contextText.measureText(sText);
|
||||
this.xText -= tm.width >> 1;
|
||||
this.yText += (this.heightText >> 1) - 1;
|
||||
this.yText += (this.heightText >> 1) - 2;
|
||||
this.drawText(sText);
|
||||
if (this.fVerticalText) {
|
||||
this.contextText.restore();
|
||||
this.fVerticalText = false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue