VCS now supports replay; can test too
This commit is contained in:
parent
1ba3d621ce
commit
caf56e14e3
|
@ -56,6 +56,7 @@ TODO:
|
||||||
- intro/help text for each platform
|
- intro/help text for each platform
|
||||||
- make sure controls work with replay feature (we'll have to save control state every frame)
|
- make sure controls work with replay feature (we'll have to save control state every frame)
|
||||||
- vscode/atom extension?
|
- vscode/atom extension?
|
||||||
|
- navigator.getGamepads
|
||||||
|
|
||||||
FYI: Image links for the books on http://8bitworkshop.com/ are broken
|
FYI: Image links for the books on http://8bitworkshop.com/ are broken
|
||||||
On the website the additional grey spacing next to the program line numbers is not dynamically resized when the web browser window size is changed. Intentional?
|
On the website the additional grey spacing next to the program line numbers is not dynamically resized when the web browser window size is changed. Intentional?
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 500c33f4e8b854ddacaa588c47c23983feb27c24
|
Subproject commit 67d15ccb4940c0049fcd6444a72316148056e5b3
|
|
@ -85,6 +85,12 @@
|
||||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
|
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"atob": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"aws-sign2": {
|
"aws-sign2": {
|
||||||
"version": "0.7.0",
|
"version": "0.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||||
|
@ -129,6 +135,12 @@
|
||||||
"integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44=",
|
"integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"btoa": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"caseless": {
|
"caseless": {
|
||||||
"version": "0.12.0",
|
"version": "0.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bootstrap": "^3.x",
|
"@types/bootstrap": "^3.x",
|
||||||
"@types/jquery": "^2.x",
|
"@types/jquery": "^2.x",
|
||||||
|
"atob": "^2.1.2",
|
||||||
|
"btoa": "^1.2.1",
|
||||||
"heapdump": "^0.3.9",
|
"heapdump": "^0.3.9",
|
||||||
"jsdom": "^12.0.0",
|
"jsdom": "^12.0.0",
|
||||||
"mocha": "^5.2.0",
|
"mocha": "^5.2.0",
|
||||||
|
|
|
@ -62,8 +62,8 @@ class VCSPlatform {
|
||||||
// intercept clockPulse function
|
// intercept clockPulse function
|
||||||
Javatari.room.console.oldClockPulse = Javatari.room.console.clockPulse;
|
Javatari.room.console.oldClockPulse = Javatari.room.console.clockPulse;
|
||||||
Javatari.room.console.clockPulse = function() {
|
Javatari.room.console.clockPulse = function() {
|
||||||
this.oldClockPulse();
|
|
||||||
self.updateRecorder();
|
self.updateRecorder();
|
||||||
|
this.oldClockPulse();
|
||||||
}
|
}
|
||||||
this.paused = false;
|
this.paused = false;
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,10 @@ class VCSPlatform {
|
||||||
advance() {
|
advance() {
|
||||||
Javatari.room.console.clockPulse();
|
Javatari.room.console.clockPulse();
|
||||||
}
|
}
|
||||||
|
// for unit test
|
||||||
|
nextFrame() {
|
||||||
|
Javatari.room.console.clockPulse();
|
||||||
|
}
|
||||||
|
|
||||||
step() { Javatari.room.console.debugSingleStepCPUClock(); }
|
step() { Javatari.room.console.debugSingleStepCPUClock(); }
|
||||||
stepBack() { Javatari.room.console.debugStepBackInstruction(); }
|
stepBack() { Javatari.room.console.debugStepBackInstruction(); }
|
||||||
|
@ -145,6 +149,12 @@ class VCSPlatform {
|
||||||
loadState(state) {
|
loadState(state) {
|
||||||
return Javatari.room.console.loadState(state);
|
return Javatari.room.console.loadState(state);
|
||||||
}
|
}
|
||||||
|
saveControlsState() {
|
||||||
|
return Javatari.room.console.saveControlsState();
|
||||||
|
}
|
||||||
|
loadControlsState(state) {
|
||||||
|
Javatari.room.console.loadControlsState(state);
|
||||||
|
}
|
||||||
// TODO: load/save controls state
|
// TODO: load/save controls state
|
||||||
readAddress(addr) {
|
readAddress(addr) {
|
||||||
return this.current_output[addr & 0xfff]; // TODO: use bus to read
|
return this.current_output[addr & 0xfff]; // TODO: use bus to read
|
||||||
|
|
|
@ -8,12 +8,14 @@ const jsdom = require('jsdom');
|
||||||
const { JSDOM } = jsdom;
|
const { JSDOM } = jsdom;
|
||||||
const { window } = new JSDOM();
|
const { window } = new JSDOM();
|
||||||
|
|
||||||
const dom = new JSDOM(`<!DOCTYPE html><div id="emulator"></div>`);
|
const dom = new JSDOM(`<!DOCTYPE html><div id="emulator"><div id="javatari-screen"></div></div>`);
|
||||||
global.window = dom.window;
|
global.window = dom.window;
|
||||||
global.document = dom.window.document;
|
global.document = dom.window.document;
|
||||||
dom.window.Audio = null;
|
dom.window.Audio = null;
|
||||||
global.Image = function() { }
|
global.Image = function() { }
|
||||||
|
global.btoa = require('btoa');
|
||||||
|
global.atob = require('atob');
|
||||||
|
global['$'] = require("jquery/jquery-2.2.3.min.js");
|
||||||
includeInThisContext("javatari.js/release/javatari/javatari.js");
|
includeInThisContext("javatari.js/release/javatari/javatari.js");
|
||||||
Javatari.AUTO_START = false;
|
Javatari.AUTO_START = false;
|
||||||
includeInThisContext('src/cpu/z80fast.js');
|
includeInThisContext('src/cpu/z80fast.js');
|
||||||
|
@ -28,17 +30,31 @@ var jsnes = require("jsnes/jsnes.min.js");
|
||||||
var emu = require('gen/emu.js');
|
var emu = require('gen/emu.js');
|
||||||
var audio = require('gen/audio.js');
|
var audio = require('gen/audio.js');
|
||||||
var recorder = require('gen/recorder.js');
|
var recorder = require('gen/recorder.js');
|
||||||
var vicdual = require('gen/platform/vicdual.js');
|
var _vicdual = require('gen/platform/vicdual.js');
|
||||||
var apple2 = require('gen/platform/apple2.js');
|
var _apple2 = require('gen/platform/apple2.js');
|
||||||
|
var _vcs = require('gen/platform/vcs.js');
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
dom.window.HTMLCanvasElement.prototype.getContext = function() {
|
||||||
|
return {
|
||||||
|
getImageData: function(x,y,w,h) { return {data: new Uint32Array(w*h) }; },
|
||||||
|
fillRect: function(x,y,w,h) { },
|
||||||
|
drawImage: function(img,x,y,w,h) { },
|
||||||
|
putImageData: function(data,w,h) { }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
global.navigator = {};
|
||||||
|
|
||||||
|
var keycallback;
|
||||||
|
|
||||||
emu.RasterVideo = function(mainElement, width, height, options) {
|
emu.RasterVideo = function(mainElement, width, height, options) {
|
||||||
var datau32;
|
var datau32;
|
||||||
this.create = function() {
|
this.create = function() {
|
||||||
datau32 = new Uint32Array(width*height);
|
datau32 = new Uint32Array(width*height);
|
||||||
}
|
}
|
||||||
this.setKeyboardEvents = function(callback) {
|
this.setKeyboardEvents = function(callback) {
|
||||||
|
keycallback = callback;
|
||||||
}
|
}
|
||||||
this.getFrameData = function() { return datau32; }
|
this.getFrameData = function() { return datau32; }
|
||||||
this.updateFrame = function() { }
|
this.updateFrame = function() { }
|
||||||
|
@ -53,7 +69,7 @@ function testPlatform(platid, romname, maxframes, callback) {
|
||||||
platform.start();
|
platform.start();
|
||||||
var rom = fs.readFileSync('./test/roms/' + platid + '/' + romname);
|
var rom = fs.readFileSync('./test/roms/' + platid + '/' + romname);
|
||||||
rom = new Uint8Array(rom);
|
rom = new Uint8Array(rom);
|
||||||
platform.loadROM(rom);
|
platform.loadROM("ROM", rom);
|
||||||
platform.resume(); // so that recorder works
|
platform.resume(); // so that recorder works
|
||||||
platform.setRecorder(rec);
|
platform.setRecorder(rec);
|
||||||
for (var i=0; i<maxframes; i++) {
|
for (var i=0; i<maxframes; i++) {
|
||||||
|
@ -71,14 +87,26 @@ function testPlatform(platid, romname, maxframes, callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('Platform Replay', () => {
|
describe('Platform Replay', () => {
|
||||||
|
|
||||||
it('Should run apple2', () => {
|
it('Should run apple2', () => {
|
||||||
var platform = testPlatform('apple2', 'cosmic.c.rom', 70, (platform, frameno) => {
|
var platform = testPlatform('apple2', 'cosmic.c.rom', 70, (platform, frameno) => {
|
||||||
if (frameno == 60) {
|
if (frameno == 60) {
|
||||||
var cstate = platform.saveControlsState();
|
keycallback(32, 32, 1); // space bar
|
||||||
cstate.kbd = 0x80 | 0x20;
|
|
||||||
platform.loadControlsState(cstate);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
assert.equal(platform.saveState().kbd, 0x20); // strobe cleared
|
assert.equal(platform.saveState().kbd, 0x20); // strobe cleared
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Should run vcs', () => {
|
||||||
|
var platform = testPlatform('vcs', 'brickgame.rom', 70, (platform, frameno) => {
|
||||||
|
if (frameno == 60) {
|
||||||
|
var cstate = platform.saveControlsState();
|
||||||
|
cstate.SA = 0xff ^ 0x40; // stick left
|
||||||
|
platform.loadControlsState(cstate);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
assert.equal(platform.saveState().p.SA, 0xff ^ 0x40);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue