| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- const SCREEN_WIDTH = 256;
- const SCREEN_HEIGHT = 240;
- const SAMPLE_REDUCTION = 4;
- const EventEmitter = require('events')
- const fs = require('fs')
- const jsnes = require('jsnes')
- const move = require('move-terminal-cursor')
- const chunk = (a, l) => Array(Math.ceil(a.length / l)).fill().map((_, i) => (a.slice ? a.slice(i * l, i * l + l) : a.substr(i * l, i * l + 1)))
- const sample = (a, n) => Array(Math.floor(a.length / n)).fill().map((_, i) => a[i * n])
- class Game extends EventEmitter {
- constructor() {
- super()
- const rom = fs.readFileSync('./Super Mario Bros. (World).nes', 'binary')
- this.nes = new jsnes.NES({
- onFrame: this.onFrame.bind(this)
- })
- this.nes.loadROM(rom)
- this.frameCount = 0
- this.packetBuffer = new ArrayBuffer(256 * 4 + SCREEN_WIDTH * SCREEN_HEIGHT)
- this.paletteBuffer = new Uint32Array(this.packetBuffer)
- this.pixelBuffer = new Uint8ClampedArray(this.packetBuffer, 256 * 4)
- this.frameBuffer = new ArrayBuffer(SCREEN_WIDTH * SCREEN_HEIGHT * 4)
- this.screen32 = new Uint32Array(this.frameBuffer)
- this.nes.ppu.buffer = this.screen32
- this.frameBytes = new Uint8ClampedArray(this.frameBuffer)
- }
- onFrame(frameBuffer) {
- // if (this.frameCount++ % SAMPLE_REDUCTION) {
- const colorMap = new Map()
- for (let i = 0; i < 256; i++) {
- this.paletteBuffer[i] = this.nes.ppu.palTable.curTable[i]
- colorMap.set(this.nes.ppu.palTable.curTable[i], i)
- }
- for (let i = 0; i < this.screen32.length; i++) {
- this.pixelBuffer[i] = colorMap.get(this.screen32[i])
- }
- this.emit('frame', this.packetBuffer)
- // }
-
- // if (true) {//(frameCount++ % 32 === 0) {
- // //move('toPos', {row: 1, col: 1})
- // const lines = sample(chunk(frameBuffer, SCREEN_WIDTH), SAMPLE_REDUCTION)
- // .map(line => sample(line, SAMPLE_REDUCTION))
- // //console.log(lines.map(l => Buffer.from(l).toString('hex')).join('\n'))
- // // console.log('\n\n\n' + chunk(Buffer.from(frameBuffer).toString('hex'), SCREEN_WIDTH * 2).join('\n'))
- // }
- }
- start() {
- if (!this.timer) this.timer = setInterval(() => this.nes.frame(), 1000 / 60)
- }
- stop() {
- if (this.timer) {
- clearInterval(this.timer)
- this.timer = null
- }
- }
- }
- module.exports = Game
|