1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-06-03 04:29:33 +00:00

fixed b/w vector graphics

This commit is contained in:
Steven Hugg 2018-08-18 09:52:17 -04:00
parent 9688e801b8
commit 6b1e09a835
2 changed files with 51 additions and 104 deletions

View File

@ -15,7 +15,9 @@ export function noise() {
return (Math.random() * 256) & 0xff; return (Math.random() * 256) & 0xff;
} }
function __createCanvas(mainElement:HTMLElement, width:number, height:number) { type KeyboardCallback = (which:number, charCode:number, flags:number) => void;
function __createCanvas(mainElement:HTMLElement, width:number, height:number) : HTMLElement {
// TODO // TODO
var fsElement = document.createElement('div'); var fsElement = document.createElement('div');
fsElement.classList.add("emubevel"); fsElement.classList.add("emubevel");
@ -31,8 +33,19 @@ function __createCanvas(mainElement:HTMLElement, width:number, height:number) {
return canvas; return canvas;
} }
function _setKeyboardEvents(canvas:HTMLElement, callback:KeyboardCallback) {
canvas.onkeydown = function(e) {
callback(e.which, 0, 1|_metakeyflags(e));
};
canvas.onkeyup = function(e) {
callback(e.which, 0, 0|_metakeyflags(e));
};
canvas.onkeypress = function(e) {
callback(e.which, e.charCode, 1|_metakeyflags(e));
};
};
export var RasterVideo = function(mainElement:HTMLElement, width:number, height:number, options?) { export var RasterVideo = function(mainElement:HTMLElement, width:number, height:number, options?) {
var self = this;
var canvas, ctx; var canvas, ctx;
var imageData, arraybuf, buf8, datau32; var imageData, arraybuf, buf8, datau32;
@ -49,9 +62,9 @@ export var RasterVideo = function(mainElement:HTMLElement, width:number, height:
} }
this.create = function() { this.create = function() {
self.canvas = canvas = __createCanvas(mainElement, width, height); this.canvas = canvas = __createCanvas(mainElement, width, height);
if (options && options.rotate) { if (options && options.rotate) {
self.setRotate(options.rotate); this.setRotate(options.rotate);
} }
ctx = canvas.getContext('2d'); ctx = canvas.getContext('2d');
imageData = ctx.createImageData(width, height); imageData = ctx.createImageData(width, height);
@ -64,24 +77,15 @@ export var RasterVideo = function(mainElement:HTMLElement, width:number, height:
datau32 = new Uint32Array(imageData.data.buffer); datau32 = new Uint32Array(imageData.data.buffer);
} }
// TODO: common function (canvas)
this.setKeyboardEvents = function(callback) { this.setKeyboardEvents = function(callback) {
canvas.onkeydown = function(e) { _setKeyboardEvents(canvas, callback);
callback(e.which, 0, 1|_metakeyflags(e)); }
};
canvas.onkeyup = function(e) {
callback(e.which, 0, 0|_metakeyflags(e));
};
canvas.onkeypress = function(e) {
callback(e.which, e.charCode, 1|_metakeyflags(e));
};
};
this.getFrameData = function() { return datau32; } this.getFrameData = function() { return datau32; }
this.getContext = function() { return ctx; } this.getContext = function() { return ctx; }
this.updateFrame = function(sx, sy, dx, dy, width, height) { this.updateFrame = function(sx:number, sy:number, dx:number, dy:number, width?:number, height?:number) {
//imageData.data.set(buf8); // TODO: slow w/ partial updates //imageData.data.set(buf8); // TODO: slow w/ partial updates
if (width && height) if (width && height)
ctx.putImageData(imageData, sx, sy, dx, dy, width, height); ctx.putImageData(imageData, sx, sy, dx, dy, width, height);
@ -89,51 +93,6 @@ export var RasterVideo = function(mainElement:HTMLElement, width:number, height:
ctx.putImageData(imageData, 0, 0); ctx.putImageData(imageData, 0, 0);
if (frameUpdateFunction) frameUpdateFunction(canvas); if (frameUpdateFunction) frameUpdateFunction(canvas);
} }
/*
mainElement.style.position = "relative";
mainElement.style.overflow = "hidden";
mainElement.style.outline = "none";
mainElement.tabIndex = "-1"; // Make it focusable
borderElement = document.createElement('div');
borderElement.style.position = "relative";
borderElement.style.overflow = "hidden";
borderElement.style.background = "black";
borderElement.style.border = "0 solid black";
borderElement.style.borderWidth = "" + borderTop + "px " + borderLateral + "px " + borderBottom + "px";
if (Javatari.SCREEN_CONTROL_BAR === 2) {
borderElement.style.borderImage = "url(" + IMAGE_PATH + "screenborder.png) " +
borderTop + " " + borderLateral + " " + borderBottom + " repeat stretch";
}
fsElement = document.createElement('div');
fsElement.style.position = "relative";
fsElement.style.width = "100%";
fsElement.style.height = "100%";
fsElement.style.overflow = "hidden";
fsElement.style.background = "black";
document.addEventListener("fullscreenchange", fullScreenChanged);
document.addEventListener("webkitfullscreenchange", fullScreenChanged);
document.addEventListener("mozfullscreenchange", fullScreenChanged);
document.addEventListener("msfullscreenchange", fullScreenChanged);
borderElement.appendChild(fsElement);
canvas.style.position = "absolute";
canvas.style.display = "block";
canvas.style.left = canvas.style.right = 0;
canvas.style.top = canvas.style.bottom = 0;
canvas.style.margin = "auto";
canvas.tabIndex = "-1"; // Make it focusable
canvas.style.outline = "none";
fsElement.appendChild(canvas);
setElementsSizes(jt.CanvasDisplay.DEFAULT_STARTING_WIDTH, jt.CanvasDisplay.DEFAULT_STARTING_HEIGHT);
mainElement.appendChild(borderElement);
*/
} }
export var VectorVideo = function(mainElement:HTMLElement, width:number, height:number) { export var VectorVideo = function(mainElement:HTMLElement, width:number, height:number) {
@ -146,22 +105,13 @@ export var VectorVideo = function(mainElement:HTMLElement, width:number, height:
var sy = height/1024.0; var sy = height/1024.0;
this.create = function() { this.create = function() {
canvas = __createCanvas(mainElement, width, height); this.canvas = canvas = __createCanvas(mainElement, width, height);
ctx = canvas.getContext('2d'); ctx = canvas.getContext('2d');
} }
// TODO: common function (canvas)
this.setKeyboardEvents = function(callback) { this.setKeyboardEvents = function(callback) {
canvas.onkeydown = function(e) { _setKeyboardEvents(canvas, callback);
callback(e.which, 0, 1|_metakeyflags(e)); }
};
canvas.onkeyup = function(e) {
callback(e.which, 0, 0|_metakeyflags(e));
};
canvas.onkeypress = function(e) {
callback(e.which, e.charCode, 1|_metakeyflags(e));
};
};
this.clear = function() { this.clear = function() {
ctx.globalCompositeOperation = 'source-over'; ctx.globalCompositeOperation = 'source-over';
@ -184,8 +134,8 @@ export var VectorVideo = function(mainElement:HTMLElement, width:number, height:
'#ffffff' '#ffffff'
]; ];
this.drawLine = function(x1, y1, x2, y2, intensity, color) { this.drawLine = function(x1:number, y1:number, x2:number, y2:number, intensity:number, color:number) {
//console.log(x1, y1, x2, y2, intensity); //console.log(x1,y1,x2,y2,intensity,color);
if (intensity > 0) { if (intensity > 0) {
// TODO: landscape vs portrait // TODO: landscape vs portrait
var alpha = Math.pow(intensity / 255.0, gamma); var alpha = Math.pow(intensity / 255.0, gamma);
@ -476,14 +426,17 @@ declare var addr2symbol; // address to symbol name map (TODO: import)
function lookupSymbol(addr) { function lookupSymbol(addr) {
var start = addr; var start = addr;
var foundsym;
while (addr >= 0) { while (addr >= 0) {
var sym = addr2symbol[addr]; var sym = addr2symbol[addr];
// TODO: what about asm? if (sym && sym.startsWith('_')) { // return first C symbol we find
if (sym && sym.startsWith('_')) {
return addr2symbol[addr] + " + " + (start-addr); return addr2symbol[addr] + " + " + (start-addr);
} else if (sym && !foundsym) { // cache first non-C symbol found
foundsym = sym;
} }
addr--; addr--;
} }
return foundsym || "";
} }
export function dumpStackToString(mem:number[], start:number, end:number, sp:number) : string { export function dumpStackToString(mem:number[], start:number, end:number, sp:number) : string {
@ -492,8 +445,10 @@ export function dumpStackToString(mem:number[], start:number, end:number, sp:num
//s = dumpRAM(mem.slice(start,start+end+1), start, end-start+1); //s = dumpRAM(mem.slice(start,start+end+1), start, end-start+1);
while (sp < end) { while (sp < end) {
sp++; sp++;
// see if there's a JSR on the stack here
// TODO: make work with roms and memory maps
var addr = mem[sp] + mem[sp+1]*256; var addr = mem[sp] + mem[sp+1]*256;
var opcode = mem[addr-2]; var opcode = mem[addr-2]; // might be out of bounds
if (opcode == 0x20) { // JSR if (opcode == 0x20) { // JSR
s += "\n$" + hex(sp) + ": "; s += "\n$" + hex(sp) + ": ";
s += hex(addr,4) + " " + lookupSymbol(addr); s += hex(addr,4) + " " + lookupSymbol(addr);

View File

@ -53,12 +53,15 @@ function newPOKEYAudio() {
var AtariVectorPlatform = function(mainElement) { var AtariVectorPlatform = function(mainElement) {
var self = this; var self = this;
var cpuFrequency = 1500000.0; var XTAL = 12096000;
var cpuCyclesPerNMI = 6000; var cpuFrequency = XTAL/8;
var cpuCyclesPer3khz = Math.round(cpuFrequency/(XTAL/4096)); // ~3 Khz
var cpuCyclesPerNMI = Math.round(cpuFrequency*12/(XTAL/4096)); // ~250 Hz
var cpuCyclesPerFrame = Math.round(cpuFrequency/60); var cpuCyclesPerFrame = Math.round(cpuFrequency/60);
var cpu, cpuram, dvgram, rom, vecrom, bus, dvg; var cpu, cpuram, dvgram, rom, vecrom, bus, dvg;
var video, audio, timer; var video, audio, timer;
var clock; var clock;
var watchdog = 0;
var switches = new RAM(16).mem; var switches = new RAM(16).mem;
var nmicount = cpuCyclesPerNMI; var nmicount = cpuCyclesPerNMI;
@ -71,14 +74,14 @@ var AtariVectorPlatform = function(mainElement) {
this.start = function() { this.start = function() {
cpuram = new RAM(0x400); cpuram = new RAM(0x400);
dvgram = new RAM(0x2000); dvgram = new RAM(0x2000);
switches[5] = 0xff; //switches[5] = 0xff;
switches[7] = 0xff; //switches[7] = 0xff;
// bus // bus
bus = { bus = {
read: newAddressDecoder([ read: newAddressDecoder([
[0x0, 0x3ff, 0x3ff, function(a) { return cpuram.mem[a]; }], [0x0, 0x3ff, 0x3ff, function(a) { return cpuram.mem[a]; }],
[0x2001, 0x2001, 0, function(a) { return ((clock/500) & 1) ? 0xff : 0x00; }], [0x2001, 0x2001, 0, function(a) { return ((clock / cpuCyclesPer3khz) & 1) ? 0xff : 0x00; }],
[0x2000, 0x2007, 0x7, function(a) { return switches[a]; }], [0x2000, 0x2007, 0x7, function(a) { return switches[a]; }],
[0x2400, 0x2407, 0x7, function(a) { return switches[a+8]; }], [0x2400, 0x2407, 0x7, function(a) { return switches[a+8]; }],
[0x4000, 0x4fff, 0xfff, function(a) { return dvgram.mem[a]; }], [0x4000, 0x4fff, 0xfff, function(a) { return dvgram.mem[a]; }],
@ -89,6 +92,7 @@ var AtariVectorPlatform = function(mainElement) {
write: newAddressDecoder([ write: newAddressDecoder([
[0x0, 0x3ff, 0x3ff, function(a,v) { cpuram.mem[a] = v; }], [0x0, 0x3ff, 0x3ff, function(a,v) { cpuram.mem[a] = v; }],
[0x3000, 0x3000, 0, function(a,v) { dvg.runUntilHalt(0); }], [0x3000, 0x3000, 0, function(a,v) { dvg.runUntilHalt(0); }],
[0x3400, 0x3400, 0, function(a,v) { watchdog = 0; }],
// TODO: draw asynchronous or allow poll of HALT ($2002) // TODO: draw asynchronous or allow poll of HALT ($2002)
[0x4000, 0x5fff, 0x1fff, function(a,v) { dvgram.mem[a] = v; }], [0x4000, 0x5fff, 0x1fff, function(a,v) { dvgram.mem[a] = v; }],
], {gmask:0x7fff}) ], {gmask:0x7fff})
@ -113,11 +117,11 @@ var AtariVectorPlatform = function(mainElement) {
var n = cpu.setNMIAndWait(); var n = cpu.setNMIAndWait();
clock += n; clock += n;
nmicount = cpuCyclesPerNMI - n; nmicount = cpuCyclesPerNMI - n;
//console.log(n, clock, nmicount);
} }
cpu.clockPulse(); cpu.clockPulse();
//cpu.executeInstruction(); //cpu.executeInstruction();
} }
//if (++watchdog == 256) { watchdog = 0; cpu.reset(); }
self.restartDebugState(); self.restartDebugState();
}); });
setKeyboardFromMap(video, switches, ASTEROIDS_KEYCODE_MAP); setKeyboardFromMap(video, switches, ASTEROIDS_KEYCODE_MAP);
@ -132,10 +136,6 @@ var AtariVectorPlatform = function(mainElement) {
this.reset(); this.reset();
} }
this.getRasterPosition = function() {
return {x:0, y:0}; // TODO
}
this.isRunning = function() { this.isRunning = function() {
return timer && timer.isRunning(); return timer && timer.isRunning();
} }
@ -154,7 +154,7 @@ var AtariVectorPlatform = function(mainElement) {
this.loadState = function(state) { this.loadState = function(state) {
cpu.loadState(state.c); cpu.loadState(state.c);
cpuram.mem.set(state.cb); cpuram.mem.set(state.b);
dvgram.mem.set(state.db); dvgram.mem.set(state.db);
switches.set(state.sw); switches.set(state.sw);
nmicount = state.nmic; nmicount = state.nmic;
@ -162,7 +162,7 @@ var AtariVectorPlatform = function(mainElement) {
this.saveState = function() { this.saveState = function() {
return { return {
c:cpu.saveState(), c:cpu.saveState(),
cb:cpuram.mem.slice(0), b:cpuram.mem.slice(0),
db:dvgram.mem.slice(0), db:dvgram.mem.slice(0),
sw:switches.slice(0), sw:switches.slice(0),
nmic:nmicount nmic:nmicount
@ -275,10 +275,6 @@ var AtariColorVectorPlatform = function(mainElement) {
this.reset(); this.reset();
} }
this.getRasterPosition = function() {
return {x:0, y:0}; // TODO
}
this.isRunning = function() { this.isRunning = function() {
return timer && timer.isRunning(); return timer && timer.isRunning();
} }
@ -297,7 +293,7 @@ var AtariColorVectorPlatform = function(mainElement) {
this.loadState = function(state) { this.loadState = function(state) {
cpu.loadState(state.c); cpu.loadState(state.c);
cpuram.mem.set(state.cb); cpuram.mem.set(state.b);
dvgram.mem.set(state.db); dvgram.mem.set(state.db);
switches.set(state.sw); switches.set(state.sw);
nmicount = state.nmic; nmicount = state.nmic;
@ -305,7 +301,7 @@ var AtariColorVectorPlatform = function(mainElement) {
this.saveState = function() { this.saveState = function() {
return { return {
c:cpu.saveState(), c:cpu.saveState(),
cb:cpuram.mem.slice(0), b:cpuram.mem.slice(0),
db:dvgram.mem.slice(0), db:dvgram.mem.slice(0),
sw:switches.slice(0), sw:switches.slice(0),
nmic:nmicount nmic:nmicount
@ -402,10 +398,6 @@ var Z80ColorVectorPlatform = function(mainElement, proto) {
this.reset(); this.reset();
} }
this.getRasterPosition = function() {
return {x:0, y:0}; // TODO
}
this.isRunning = function() { this.isRunning = function() {
return timer && timer.isRunning(); return timer && timer.isRunning();
} }
@ -424,7 +416,7 @@ var Z80ColorVectorPlatform = function(mainElement, proto) {
this.loadState = function(state) { this.loadState = function(state) {
cpu.loadState(state.c); cpu.loadState(state.c);
cpuram.mem.set(state.cb); cpuram.mem.set(state.b);
dvgram.mem.set(state.db); dvgram.mem.set(state.db);
switches.set(state.sw); switches.set(state.sw);
mathram.set(state.mr); mathram.set(state.mr);
@ -432,7 +424,7 @@ var Z80ColorVectorPlatform = function(mainElement, proto) {
this.saveState = function() { this.saveState = function() {
return { return {
c:cpu.saveState(), c:cpu.saveState(),
cb:cpuram.mem.slice(0), b:cpuram.mem.slice(0),
db:dvgram.mem.slice(0), db:dvgram.mem.slice(0),
sw:switches.slice(0), sw:switches.slice(0),
mr:mathram.slice(0), mr:mathram.slice(0),
@ -515,7 +507,7 @@ var DVGBWStateMachine = function(bus, video, bofs) {
var z = w2 >> 12; var z = w2 >> 12;
var x2 = x + ((decodeSigned(w2, 10) << 7) >> sc); var x2 = x + ((decodeSigned(w2, 10) << 7) >> sc);
var y2 = y + ((decodeSigned(w, 10) << 7) >> sc); var y2 = y + ((decodeSigned(w, 10) << 7) >> sc);
video.drawLine(x, y, x2, y2, z, 255); video.drawLine(x, y, x2, y2, z*32, 7);
//console.log(pc.toString(16), w.toString(16), w2.toString(16), gsc, sc, x, y, x2, y2); //console.log(pc.toString(16), w.toString(16), w2.toString(16), gsc, sc, x, y, x2, y2);
x = x2; x = x2;
y = y2; y = y2;
@ -545,7 +537,7 @@ var DVGBWStateMachine = function(bus, video, bofs) {
var x2 = x + ((decodeSigned(w, 2) << 7) >> sc); var x2 = x + ((decodeSigned(w, 2) << 7) >> sc);
var y2 = y + ((decodeSigned(w>>8, 2) << 7) >> sc); var y2 = y + ((decodeSigned(w>>8, 2) << 7) >> sc);
var z = (w >> 4) & 0xf; var z = (w >> 4) & 0xf;
video.drawLine(x, y, x2, y2, z, 255); video.drawLine(x, y, x2, y2, z*32, 7);
x = x2; x = x2;
y = y2; y = y2;
break; break;