summaryrefslogtreecommitdiffstats
path: root/source/ui.js
diff options
context:
space:
mode:
authorBen Firshman <ben@firshman.co.uk>2010-07-06 12:29:39 +0100
committerBen Firshman <ben@firshman.co.uk>2010-07-06 12:29:39 +0100
commitbe9c0d63d55192153b1623630c5f8a0331fa9ca0 (patch)
tree39ca273d0857de080673fc39e67015c878936ebc /source/ui.js
parent3afbd7a7f3007c586448e484e1e2b5fdc30b4f4e (diff)
downloadjsnes-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.js234
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);
+}