diff options
author | Ben Firshman <ben@firshman.co.uk> | 2010-07-06 12:29:39 +0100 |
---|---|---|
committer | Ben Firshman <ben@firshman.co.uk> | 2010-07-06 12:29:39 +0100 |
commit | be9c0d63d55192153b1623630c5f8a0331fa9ca0 (patch) | |
tree | 39ca273d0857de080673fc39e67015c878936ebc /source/ui.js | |
parent | 3afbd7a7f3007c586448e484e1e2b5fdc30b4f4e (diff) | |
download | jsnes-be9c0d63d55192153b1623630c5f8a0331fa9ca0.zip jsnes-be9c0d63d55192153b1623630c5f8a0331fa9ca0.tar.gz jsnes-be9c0d63d55192153b1623630c5f8a0331fa9ca0.tar.bz2 |
Added support for building distribution packages with Jake
Diffstat (limited to 'source/ui.js')
-rw-r--r-- | source/ui.js | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/source/ui.js b/source/ui.js new file mode 100644 index 0000000..cbb7e69 --- /dev/null +++ b/source/ui.js @@ -0,0 +1,234 @@ +/* +JSNES, based on Jamie Sanders' vNES +Copyright (C) 2010 Ben Firshman + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +JSNES.DummyUI = function(nes) { + this.nes = nes; + this.enable = function() {}; + this.updateStatus = function() {}; + this.writeAudio = function() {}; + this.writeFrame = function() {}; +}; + +if (typeof jQuery !== 'undefined') { + (function($) { + $.fn.JSNESUI = function(roms) { + var parent = this; + var UI = function(nes) { + var self = this; + self.nes = nes; + + self.root = $('<div></div>'); + self.screen = $('<canvas class="nes-screen" width="256" height="240"></canvas>').appendTo(self.root); + self.controls = $('<div class="nes-controls"></div>').appendTo(self.root); + self.romSelect = $('<select class="nes-roms"></select>').appendTo(self.controls); + self.buttons = { + pause: $('<input type="button" value="pause" class="nes-pause" disabled="disabled">').appendTo(self.controls), + restart: $('<input type="button" value="restart" class="nes-restart" disabled="disabled">').appendTo(self.controls), + sound: $('<input type="button" value="enable sound" class="nes-enablesound">').appendTo(self.controls), + zoom: $('<input type="button" value="zoom in" class="nes-zoom">').appendTo(self.controls) + }; + self.status = $('<p class="nes-status">Booting up...</p>').appendTo(self.root); + self.root.appendTo(parent); + + self.romSelect.change(function() { + self.updateStatus("Downloading..."); + $.ajax({ + url: escape(self.romSelect.val()), + xhr: function() { + var xhr = $.ajaxSettings.xhr(); + // Download as binary + xhr.overrideMimeType('text/plain; charset=x-user-defined'); + return xhr; + }, + success: function(data) { + self.nes.loadRom(data); + self.nes.start(); + self.enable(); + } + }); + }); + + self.buttons.pause.click(function() { + if (self.nes.isRunning) { + self.nes.stop(); + self.updateStatus("Paused"); + self.buttons.pause.attr("value", "resume"); + } + else { + self.nes.start(); + self.buttons.pause.attr("value", "pause"); + } + }); + + self.buttons.restart.click(function() { + self.nes.reloadRom(); + self.nes.start(); + }); + + self.buttons.sound.click(function() { + if (self.nes.opts.emulateSound) { + self.nes.opts.emulateSound = false; + self.buttons.sound.attr("value", "enable sound"); + } + else { + self.nes.opts.emulateSound = true; + self.buttons.sound.attr("value", "disable sound"); + } + }); + + self.zoomed = false; + self.buttons.zoom.click(function() { + if (self.zoomed) { + self.screen.animate({ + width: '256px', + height: '240px' + }); + self.buttons.zoom.attr("value", "zoom in"); + self.zoomed = false; + } + else { + self.screen.animate({ + width: '512px', + height: '480px' + }); + self.buttons.zoom.attr("value", "zoom out"); + self.zoomed = true; + } + }); + + // Mouse experiments. Requires jquery.dimensions.js + if ($.offset) { + self.screen.mousedown(function(e) { + if (self.nes.mmap) { + self.nes.mmap.mousePressed = true; + // FIXME: does not take into account zoom + self.nes.mmap.mouseX = e.pageX - self.screen.offset().left; + self.nes.mmap.mouseY = e.pageY - self.screen.offset().top; + } + }).mouseup(function() { + setTimeout(function() { + if (self.nes.mmap) { + self.nes.mmap.mousePressed = false; + self.nes.mmap.mouseX = 0; + self.nes.mmap.mouseY = 0; + } + }, 500); + }); + } + + if (typeof roms != 'undefined') { + self.setRoms(roms); + } + + // Canvas + self.canvasContext = self.screen[0].getContext('2d'); + self.canvasImageData = self.canvasContext.getImageData(0, 0, 256, 240); + self.canvasContext.fillStyle = 'black'; + self.canvasContext.fillRect(0, 0, 256, 240); // set alpha to opaque + + // Set alpha + for (var i = 3; i < this.canvasImageData.data.length-3; i+=4) { + this.canvasImageData.data[i] = 0xFF; + } + + // Keyboard + $(document). + bind('keydown', function(evt) { + self.nes.keyboard.keyDown(evt); + }). + bind('keyup', function(evt) { + self.nes.keyboard.keyUp(evt); + }). + bind('keypress', function(evt) { + self.nes.keyboard.keyPress(evt); + }); + + // Sound + self.dynamicaudio = new DynamicAudio({ + swf: nes.opts.swfPath+'dynamicaudio.swf' + }); + } + + UI.prototype = { + // Enable and reset UI elements + enable: function() { + this.buttons.pause.attr("disabled", null); + if (this.nes.isRunning) { + this.buttons.pause.attr("value", "pause"); + } + else { + this.buttons.pause.attr("value", "resume"); + } + this.buttons.restart.attr("disabled", null); + if (this.nes.opts.emulateSound) { + this.buttons.sound.attr("value", "disable sound"); + } + else { + this.buttons.sound.attr("value", "enable sound"); + } + }, + + updateStatus: function(s) { + this.status.text(s); + }, + + setRoms: function(roms) { + this.romSelect.children().remove(); + $("<option>Select a ROM...</option>").appendTo(this.romSelect); + for (var groupName in roms) { + if (roms.hasOwnProperty(groupName)) { + var optgroup = $('<optgroup></optgroup>'). + attr("label", groupName); + for (var i = 0; i < roms[groupName].length; i++) { + $('<option>'+roms[groupName][i][0]+'</option>') + .attr("value", roms[groupName][i][1]) + .appendTo(optgroup); + } + this.romSelect.append(optgroup); + } + } + }, + + writeAudio: function(samples) { + return this.dynamicaudio.writeInt(samples); + }, + + writeFrame: function(buffer, prevBuffer) { + var imageData = this.canvasImageData.data; + var pixel, j; + + for (i=0; i<256*240; i++) { + pixel = buffer[i]; + + if (pixel != prevBuffer[i]) { + j = i*4; + imageData[j] = pixel & 0xFF; + imageData[j+1] = (pixel >> 8) & 0xFF; + imageData[j+2] = (pixel >> 16) & 0xFF; + prevBuffer[i] = pixel; + } + } + + this.canvasContext.putImageData(this.canvasImageData, 0, 0); + } + }; + + return UI; + }; + })(jQuery); +} |