diff --git a/package-lock.json b/package-lock.json index 7c8acca..d5201c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@popperjs/core": "^2.11.8", "bootstrap": "5.2.0", - "jsnes": "git+ssh://git@github.com/bfirsh/jsnes.git", + "jsnes": "https://github.com/bfirsh/jsnes.git", "prop-types": "^15.8.1", "raven-js": "^3.27.2", "react": "^18.2.0", @@ -19,13 +19,13 @@ "react-ga": "^3.3.1", "react-router-dom": "^6.3.0", "reactstrap": "^9.1.3", - "ringbufferjs": "^1.1.0", + "ringbufferjs": "^2.0.0", "sass": "^1.54.5" }, "devDependencies": { "@svgr/webpack": "^6.3.1", "canvas": "^3.1.2", - "prettier": "^1.16.4", + "prettier": "^3.6.2", "prettier-check": "^2.0.0", "react-scripts": "5.0.1" } @@ -12959,7 +12959,7 @@ }, "node_modules/jsnes": { "version": "1.2.1", - "resolved": "git+ssh://git@github.com/bfirsh/jsnes.git#7ac5678afb97d52f5d002d7820a35c55afd34b2c", + "resolved": "git+ssh://git@github.com/bfirsh/jsnes.git#15924fd0cc4bbaaa624cc4bcd736e0a31cd0e808", "license": "Apache-2.0" }, "node_modules/json-buffer": { @@ -15868,16 +15868,19 @@ } }, "node_modules/prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "license": "MIT", "bin": { - "prettier": "bin-prettier.js" + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=4" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/prettier-check": { @@ -17021,9 +17024,9 @@ } }, "node_modules/ringbufferjs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ringbufferjs/-/ringbufferjs-1.1.0.tgz", - "integrity": "sha512-Hd1Z8xyaQLhdKtmbOuRCwCT9rKYk7SwUXENsA9pSAj6Jv4otUh7IwOlEhj0xu/xcP7hosMnmE7AYaVp6m8MCPQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ringbufferjs/-/ringbufferjs-2.0.0.tgz", + "integrity": "sha512-GCOqTzUsTHF7nrqcgtNGAFotXztLgiePpIDpyWZ7R5I02tmfJWV+/yuJc//Hlsd8G+WzI1t/dc2y/w2imDZdog==", "license": "MIT" }, "node_modules/rollup": { @@ -19119,9 +19122,9 @@ } }, "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "license": "Apache-2.0", "peer": true, @@ -19130,7 +19133,7 @@ "tsserver": "bin/tsserver" }, "engines": { - "node": ">=14.17" + "node": ">=4.2.0" } }, "node_modules/unbox-primitive": { diff --git a/package.json b/package.json index ed2e7d8..29193be 100644 --- a/package.json +++ b/package.json @@ -14,13 +14,13 @@ "react-ga": "^3.3.1", "react-router-dom": "^6.3.0", "reactstrap": "^9.1.3", - "ringbufferjs": "^1.1.0", + "ringbufferjs": "^2.0.0", "sass": "^1.54.5" }, "devDependencies": { "@svgr/webpack": "^6.3.1", "canvas": "^3.1.2", - "prettier": "^1.16.4", + "prettier": "^3.6.2", "prettier-check": "^2.0.0", "react-scripts": "5.0.1" }, diff --git a/src/ControlMapperRow.js b/src/ControlMapperRow.js index 391fb5d..678c7d7 100644 --- a/src/ControlMapperRow.js +++ b/src/ControlMapperRow.js @@ -6,7 +6,7 @@ class ControlMapperRow extends Component { this.state = { playerOneButton: "", playerTwoButton: "", - waitingForKey: 0 + waitingForKey: 0, }; this.handleClick = this.handleClick.bind(this); } @@ -25,7 +25,7 @@ class ControlMapperRow extends Component { } this.setState({ playerOneButton: playerButtons[0], - playerTwoButton: playerButtons[1] + playerTwoButton: playerButtons[1], }); } @@ -46,14 +46,14 @@ class ControlMapperRow extends Component { } var searchButton = (gamepadConfig, buttonId) => { - return gamepadConfig.buttons.filter(b => b.buttonId === buttonId)[0]; + return gamepadConfig.buttons.filter((b) => b.buttonId === buttonId)[0]; }; var searchNewButton = (prevGamepadConfig, gamepadConfig) => { - return gamepadConfig.buttons.filter(b => { + return gamepadConfig.buttons.filter((b) => { return ( !prevGamepadConfig || - !prevGamepadConfig.buttons.some(b2 => b2.buttonId === b.buttonId) + !prevGamepadConfig.buttons.some((b2) => b2.buttonId === b.buttonId) ); })[0]; }; @@ -61,7 +61,7 @@ class ControlMapperRow extends Component { var waitingForKey = 0; var waitingForKeyPlayer = 0; - var gamepadButtonName = gamepadButton => { + var gamepadButtonName = (gamepadButton) => { if (gamepadButton.type === "button") return "Btn-" + gamepadButton.code; if (gamepadButton.type === "axis") return "Axis-" + gamepadButton.code + " " + gamepadButton.value; @@ -73,11 +73,11 @@ class ControlMapperRow extends Component { playerButtons[0] = ""; gamepadButton = searchButton( this.props.gamepadConfig.configs[playerGamepadId[0]], - button + button, ); newButton = searchNewButton( prevProps.gamepadConfig.configs[playerGamepadId[0]], - this.props.gamepadConfig.configs[playerGamepadId[0]] + this.props.gamepadConfig.configs[playerGamepadId[0]], ); if (gamepadButton) { playerButtons[0] = gamepadButtonName(gamepadButton); @@ -95,11 +95,11 @@ class ControlMapperRow extends Component { playerButtons[1] = ""; gamepadButton = searchButton( this.props.gamepadConfig.configs[playerGamepadId[1]], - button + button, ); newButton = searchNewButton( prevProps.gamepadConfig.configs[playerGamepadId[1]], - this.props.gamepadConfig.configs[playerGamepadId[1]] + this.props.gamepadConfig.configs[playerGamepadId[1]], ); if (gamepadButton) { playerButtons[1] = gamepadButtonName(gamepadButton); @@ -148,7 +148,7 @@ class ControlMapperRow extends Component { handleClick(player) { this.props.handleClick([player, this.props.button]); this.setState({ - waitingForKey: player + waitingForKey: player, }); } diff --git a/src/ControlsModal.js b/src/ControlsModal.js index b9bd5f1..9fd1128 100644 --- a/src/ControlsModal.js +++ b/src/ControlsModal.js @@ -5,7 +5,7 @@ import { ModalHeader, ModalBody, ModalFooter, - Table + Table, } from "reactstrap"; import { Controller } from "jsnes"; import ControlMapperRow from "./ControlMapperRow"; @@ -20,7 +20,7 @@ class ControlsModal extends Component { gamepadConfig: props.gamepadConfig, keys: props.keys, button: undefined, - modified: false + modified: false, }; this.handleKeyDown = this.handleKeyDown.bind(this); this.handleGamepadButtonDown = this.handleGamepadButtonDown.bind(this); @@ -32,10 +32,10 @@ class ControlsModal extends Component { this.state.gamepadConfig.configs = this.state.gamepadConfig.configs || {}; this.state.controllerIcon = this.state.gamepadConfig.playerGamepadId.map( - gamepadId => (gamepadId ? GAMEPAD_ICON : KEYBOARD_ICON) + (gamepadId) => (gamepadId ? GAMEPAD_ICON : KEYBOARD_ICON), ); this.state.controllerIconAlt = this.state.gamepadConfig.playerGamepadId.map( - gamepadId => (gamepadId ? "gamepad" : "keyboard") + (gamepadId) => (gamepadId ? "gamepad" : "keyboard"), ); this.state.currentPromptButton = -1; } @@ -74,7 +74,7 @@ class ControlsModal extends Component { playerGamepadId[playerId - 1] = gamepadId; - const rejectButtonId = b => { + const rejectButtonId = (b) => { return b.buttonId !== buttonId; }; @@ -82,12 +82,12 @@ class ControlsModal extends Component { code: buttonInfo.code, type: buttonInfo.type, buttonId: buttonId, - value: buttonInfo.value + value: buttonInfo.value, }; newConfig[gamepadId] = { buttons: (gamepadConfig.configs[gamepadId] || { buttons: [] }).buttons .filter(rejectButtonId) - .concat([newButton]) + .concat([newButton]), }; const configs = Object.assign({}, gamepadConfig.configs, newConfig); @@ -95,13 +95,13 @@ class ControlsModal extends Component { this.setState({ gamepadConfig: { configs: configs, - playerGamepadId: playerGamepadId + playerGamepadId: playerGamepadId, }, currentPromptButton: -1, - controllerIcon: playerGamepadId.map(gamepadId => - gamepadId ? GAMEPAD_ICON : KEYBOARD_ICON + controllerIcon: playerGamepadId.map((gamepadId) => + gamepadId ? GAMEPAD_ICON : KEYBOARD_ICON, ), - modified: true + modified: true, }); } @@ -126,22 +126,22 @@ class ControlsModal extends Component { ...newKeys, [event.keyCode]: [ ...button.slice(0, 2), - event.key.length > 1 ? event.key : String(event.key).toUpperCase() - ] + event.key.length > 1 ? event.key : String(event.key).toUpperCase(), + ], }, button: undefined, gamepadConfig: { configs: this.state.gamepadConfig.configs, - playerGamepadId: playerGamepadId + playerGamepadId: playerGamepadId, }, currentPromptButton: -1, - controllerIcon: playerGamepadId.map(gamepadId => - gamepadId ? GAMEPAD_ICON : KEYBOARD_ICON + controllerIcon: playerGamepadId.map((gamepadId) => + gamepadId ? GAMEPAD_ICON : KEYBOARD_ICON, ), - controllerIconAlt: playerGamepadId.map(gamepadId => - gamepadId ? "gamepad" : "keyboard" + controllerIconAlt: playerGamepadId.map((gamepadId) => + gamepadId ? "gamepad" : "keyboard", ), - modified: true + modified: true, }); } diff --git a/src/Emulator.js b/src/Emulator.js index 8b0ab13..c8d354c 100644 --- a/src/Emulator.js +++ b/src/Emulator.js @@ -19,7 +19,7 @@ class Emulator extends Component { render() { return ( { + ref={(screen) => { this.screen = screen; }} onGenerateFrame={() => { @@ -54,7 +54,7 @@ class Emulator extends Component { // - System can't run emulator at full speed. In this case it'll stop // firing requestAnimationFrame. console.log( - "Buffer underrun, running another frame to try and catch up" + "Buffer underrun, running another frame to try and catch up", ); this.frameTimer.generateFrame(); @@ -65,14 +65,14 @@ class Emulator extends Component { console.log("Still buffer underrun, running a second frame"); this.frameTimer.generateFrame(); } - } + }, }); this.nes = new NES({ onFrame: this.screen.setBuffer, onStatusUpdate: console.log, onAudioSample: this.speakers.writeSample, - sampleRate: this.speakers.getSampleRate() + sampleRate: this.speakers.getSampleRate(), }); // For debugging. (["nes"] instead of .nes to avoid VS Code type errors.) @@ -80,13 +80,13 @@ class Emulator extends Component { this.frameTimer = new FrameTimer({ onGenerateFrame: Raven.wrap(this.nes.frame), - onWriteFrame: Raven.wrap(this.screen.writeBuffer) + onWriteFrame: Raven.wrap(this.screen.writeBuffer), }); // Set up gamepad and keyboard this.gamepadController = new GamepadController({ onButtonDown: this.nes.buttonDown, - onButtonUp: this.nes.buttonUp + onButtonUp: this.nes.buttonUp, }); this.gamepadController.loadGamepadConfig(); @@ -94,11 +94,11 @@ class Emulator extends Component { this.keyboardController = new KeyboardController({ onButtonDown: this.gamepadController.disableIfGamepadEnabled( - this.nes.buttonDown + this.nes.buttonDown, ), onButtonUp: this.gamepadController.disableIfGamepadEnabled( - this.nes.buttonUp - ) + this.nes.buttonUp, + ), }); // Load keys from localStorage (if they exist) @@ -108,7 +108,7 @@ class Emulator extends Component { document.addEventListener("keyup", this.keyboardController.handleKeyUp); document.addEventListener( "keypress", - this.keyboardController.handleKeyPress + this.keyboardController.handleKeyPress, ); this.nes.loadROM(this.props.romData); @@ -121,12 +121,12 @@ class Emulator extends Component { // Unbind keyboard document.removeEventListener( "keydown", - this.keyboardController.handleKeyDown + this.keyboardController.handleKeyDown, ); document.removeEventListener("keyup", this.keyboardController.handleKeyUp); document.removeEventListener( "keypress", - this.keyboardController.handleKeyPress + this.keyboardController.handleKeyPress, ); // Stop gamepad @@ -171,7 +171,7 @@ class Emulator extends Component { Emulator.propTypes = { paused: PropTypes.bool, - romData: PropTypes.string.isRequired + romData: PropTypes.string.isRequired, }; export default Emulator; diff --git a/src/FrameTimer.js b/src/FrameTimer.js index 811a57c..97b59dc 100644 --- a/src/FrameTimer.js +++ b/src/FrameTimer.js @@ -32,7 +32,7 @@ export default class FrameTimer { this.lastFrameTime += this.interval; } - onAnimationFrame = time => { + onAnimationFrame = (time) => { this.requestAnimationFrame(); // how many ms after 60fps frame time let excess = time % this.interval; @@ -48,7 +48,7 @@ export default class FrameTimer { } let numFrames = Math.round( - (newFrameTime - this.lastFrameTime) / this.interval + (newFrameTime - this.lastFrameTime) / this.interval, ); // This can happen a lot on a 144Hz display @@ -67,9 +67,12 @@ export default class FrameTimer { // until next frame draw let timeToNextFrame = this.interval - excess; for (let i = 1; i < numFrames; i++) { - setTimeout(() => { - this.generateFrame(); - }, (i * timeToNextFrame) / numFrames); + setTimeout( + () => { + this.generateFrame(); + }, + (i * timeToNextFrame) / numFrames, + ); } if (numFrames > 1) console.log("SKIP", numFrames - 1, this.lastFrameTime); }; diff --git a/src/GamepadController.js b/src/GamepadController.js index db44cf0..6d38966 100644 --- a/src/GamepadController.js +++ b/src/GamepadController.js @@ -6,7 +6,7 @@ export default class GamepadController { this.buttonCallback = null; } - disableIfGamepadEnabled = callback => { + disableIfGamepadEnabled = (callback) => { var self = this; return (playerId, buttonId) => { if (!self.gamepadConfig) { @@ -21,7 +21,7 @@ export default class GamepadController { }; }; - _getPlayerNumberFromGamepad = gamepad => { + _getPlayerNumberFromGamepad = (gamepad) => { if (this.gamepadConfig.playerGamepadId[0] === gamepad.id) { return 1; } @@ -66,7 +66,7 @@ export default class GamepadController { gamepadId: gamepad.id, type: "axis", code: code, - value: axis + value: axis, }); } @@ -75,7 +75,7 @@ export default class GamepadController { gamepadId: gamepad.id, type: "axis", code: code, - value: axis + value: axis, }); } } @@ -87,7 +87,7 @@ export default class GamepadController { this.buttonCallback({ gamepadId: gamepad.id, type: "button", - code: code + code: code, }); } } @@ -101,8 +101,8 @@ export default class GamepadController { usedPlayers.push(playerNumber); if (this.gamepadConfig.configs[gamepad.id]) { - const configButtons = this.gamepadConfig.configs[gamepad.id] - .buttons; + const configButtons = + this.gamepadConfig.configs[gamepad.id].buttons; for (let i = 0; i < configButtons.length; i++) { const configButton = configButtons[i]; @@ -141,19 +141,19 @@ export default class GamepadController { } this.gamepadState[gamepadIndex] = { - buttons: buttons.map(b => { + buttons: buttons.map((b) => { return { pressed: b.pressed }; }), - axes: gamepad.axes.slice(0) + axes: gamepad.axes.slice(0), }; } }; - promptButton = f => { + promptButton = (f) => { if (!f) { this.buttonCallback = f; } else { - this.buttonCallback = buttonInfo => { + this.buttonCallback = (buttonInfo) => { this.buttonCallback = null; f(buttonInfo); }; @@ -174,7 +174,7 @@ export default class GamepadController { this.gamepadConfig = gamepadConfig; }; - setGamepadConfig = gamepadConfig => { + setGamepadConfig = (gamepadConfig) => { try { localStorage.setItem("gamepadConfig", JSON.stringify(gamepadConfig)); this.gamepadConfig = gamepadConfig; @@ -200,7 +200,7 @@ export default class GamepadController { return { stop: () => { stopped = true; - } + }, }; }; } diff --git a/src/KeyboardController.js b/src/KeyboardController.js index e7f11c1..efc2334 100644 --- a/src/KeyboardController.js +++ b/src/KeyboardController.js @@ -18,7 +18,7 @@ const KEYS = { 104: [2, Controller.BUTTON_UP, "Num-8"], // Num-8 98: [2, Controller.BUTTON_DOWN, "Num-2"], // Num-2 100: [2, Controller.BUTTON_LEFT, "Num-4"], // Num-4 - 102: [2, Controller.BUTTON_RIGHT, "Num-6"] // Num-6 + 102: [2, Controller.BUTTON_RIGHT, "Num-6"], // Num-6 }; export default class KeyboardController { @@ -41,7 +41,7 @@ export default class KeyboardController { this.keys = keys || KEYS; }; - setKeys = newKeys => { + setKeys = (newKeys) => { try { localStorage.setItem("keys", JSON.stringify(newKeys)); this.keys = newKeys; @@ -50,7 +50,7 @@ export default class KeyboardController { } }; - handleKeyDown = e => { + handleKeyDown = (e) => { var key = this.keys[e.keyCode]; if (key) { this.onButtonDown(key[0], key[1]); @@ -58,7 +58,7 @@ export default class KeyboardController { } }; - handleKeyUp = e => { + handleKeyUp = (e) => { var key = this.keys[e.keyCode]; if (key) { this.onButtonUp(key[0], key[1]); @@ -66,7 +66,7 @@ export default class KeyboardController { } }; - handleKeyPress = e => { + handleKeyPress = (e) => { e.preventDefault(); }; } diff --git a/src/ListPage.js b/src/ListPage.js index d21d456..318c2a7 100644 --- a/src/ListPage.js +++ b/src/ListPage.js @@ -10,7 +10,7 @@ class ListPage extends Component { constructor(props) { super(props); this.state = { - romLibrary: RomLibrary.load() + romLibrary: RomLibrary.load(), }; } render() { @@ -36,7 +36,7 @@ class ListPage extends Component { {Object.keys(config.ROMS) .sort() - .map(key => ( + .map((key) => ( {this.state.romLibrary .sort((a, b) => new Date(b.added) - new Date(a.added)) - .map(rom => ( + .map((rom) => ( {rom.name} { + onClick={(e) => { e.preventDefault(); this.deleteRom(rom.hash); }} @@ -90,7 +90,7 @@ class ListPage extends Component { ); } - deleteRom = hash => { + deleteRom = (hash) => { RomLibrary.delete(hash); this.updateLibrary(); }; @@ -99,19 +99,19 @@ class ListPage extends Component { this.setState({ romLibrary: RomLibrary.load() }); }; - handleDragOver = e => { + handleDragOver = (e) => { e.preventDefault(); e.dataTransfer.dropEffect = "copy"; }; - handleDrop = e => { + handleDrop = (e) => { e.preventDefault(); const file = e.dataTransfer.items ? e.dataTransfer.items[0].getAsFile() : e.dataTransfer.files[0]; - RomLibrary.save(file).then(rom => { + RomLibrary.save(file).then((rom) => { this.updateLibrary(); this.props.history.push({ pathname: "run/local-" + rom.hash }); }); diff --git a/src/ListPage.test.js b/src/ListPage.test.js index 036e790..71b2e7b 100644 --- a/src/ListPage.test.js +++ b/src/ListPage.test.js @@ -9,7 +9,7 @@ describe("ListPage", () => { root.render( - + , ); }); }); diff --git a/src/RomLibrary.js b/src/RomLibrary.js index 5e6e944..490da4f 100644 --- a/src/RomLibrary.js +++ b/src/RomLibrary.js @@ -1,4 +1,4 @@ -const pFileReader = function(file) { +const pFileReader = function (file) { return new Promise((resolve, reject) => { var reader = new FileReader(); reader.onload = resolve; @@ -6,10 +6,10 @@ const pFileReader = function(file) { }); }; -const hashFile = function(byteString) { - const asHex = buffer => { +const hashFile = function (byteString) { + const asHex = (buffer) => { return Array.from(new Uint8Array(buffer)) - .map(b => b.toString(16).padStart(2, "0")) + .map((b) => b.toString(16).padStart(2, "0")) .join(""); }; @@ -24,14 +24,14 @@ const hashFile = function(byteString) { }; const RomLibrary = { - getRomInfoByHash: function(hash) { - return this.load().find(rom => rom.hash === hash); + getRomInfoByHash: function (hash) { + return this.load().find((rom) => rom.hash === hash); }, - save: function(file) { + save: function (file) { return pFileReader(file) - .then(function(readFile) { + .then(function (readFile) { const byteString = readFile.target.result; - return hashFile(byteString).then(hash => { + return hashFile(byteString).then((hash) => { return { hash, byteString }; }); }) @@ -42,7 +42,7 @@ const RomLibrary = { const rom = { name: file.name, hash: hash, - added: Date.now() + added: Date.now(), }; const newRomInfo = JSON.stringify(existingLibrary.concat([rom])); @@ -53,20 +53,20 @@ const RomLibrary = { return rom; }); }, - load: function() { + load: function () { const localData = localStorage.getItem("savedRomInfo"); if (!localData) return []; const savedRomInfo = JSON.parse(localStorage.getItem("savedRomInfo")); return savedRomInfo || []; }, - delete: function(hash) { + delete: function (hash) { const existingLibrary = this.load(); localStorage.removeItem("blob-" + hash); localStorage.setItem( "savedRomInfo", - JSON.stringify(existingLibrary.filter(rom => rom.hash !== hash)) + JSON.stringify(existingLibrary.filter((rom) => rom.hash !== hash)), ); - } + }, }; export default RomLibrary; diff --git a/src/RunPage.js b/src/RunPage.js index 4fb4ac6..9bc2408 100644 --- a/src/RunPage.js +++ b/src/RunPage.js @@ -11,7 +11,7 @@ import { loadBinary } from "./utils"; import "./RunPage.css"; function withParams(Component) { - return props => ( + return (props) => ( ); } @@ -30,7 +30,7 @@ class RunPage extends Component { controlsModalOpen: false, loading: true, loadedPercent: 3, - error: null + error: null, }; } @@ -39,7 +39,7 @@ class RunPage extends Component {