Mercurial > web-gnusto
view web-zui.js @ 54:7dc2c7bded08
Added implementation of the restart opcode.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Fri, 16 May 2008 11:11:17 -0700 |
parents | 0abb2dbc2dd1 |
children | d9fa2605b044 |
line wrap: on
line source
var BACKSPACE_KEYCODE = 8; var RETURN_KEYCODE = 13; function WebZui() { this._size = [80, 255]; this._console = null; this._activeWindow = 0; this._inputString = ""; this._currentCallback = null; this._currStyles = ["z-roman"]; var self = this; this.__proto__ = { onConsoleRender: function() { var height = $("#top-window").get(0).clientHeight; $("#content").get(0).style.padding = "" + height + "px 0 0 0"; }, _finalize: function() { if (self._console) { self._console.close(); self._console = null; } $("#content").html(""); self._unbindEventHandlers(); }, _bindEventHandlers: function() { $(window).keypress(self._windowKeypress); $(window).resize(self._windowResize); $(window).keyup(self._windowKeyup); $(window).keydown(self._windowKeydown); }, _unbindEventHandlers: function() { $(window).unbind("keypress", self._windowKeypress); $(window).unbind("resize", self._windowResize); $(window).unbind("keyup", self._windowKeyup); $(window).unbind("keydown", self._windowKeydown); }, // We want to make sure that all key events don't bubble up, so // that anything listening in--such as Firefox's "Search for text // when I start typing" feature--doesn't think that we're not // doing anything with the keypresses. If we don't do this, such // listeners may think that they can intervene and capture // keystrokes before they get to us in the future. _windowKeyup: function(event) { return false; }, _windowKeydown: function(event) { return false; }, _windowKeypress: function(event) { if ($("#current-input").length == 0) { // We're not waiting for a line of input, but we may // be waiting for a character of input. // Note that we have to return a ZSCII keycode here. // // For more information, see: // // http://www.gnelson.demon.co.uk/zspec/sect03.html if (self._currentCallback) { var keyCode = 0; if (event.charCode) { keyCode = event.charCode; } else { // TODO: Deal w/ arrow keys, etc. switch (event.keyCode) { case RETURN_KEYCODE: keyCode = event.keyCode; break; } } if (keyCode != 0) { var callback = self._currentCallback; self._currentCallback = null; callback(keyCode); } } return false; } var oldInputString = self._inputString; if (event.charCode) { var newChar = String.fromCharCode(event.charCode); var lastChar = self._inputString.slice(-1); if (!(newChar == " " && lastChar == " ")) { self._inputString += newChar; } } else { switch (event.keyCode) { case BACKSPACE_KEYCODE: if (self._inputString) { self._inputString = self._inputString.slice(0, -1); } break; case RETURN_KEYCODE: var finalInputString = self._inputString; var callback = self._currentCallback; self._inputString = ""; self._currentCallback = null; finalInputString = finalInputString.entityify(); $("#current-input").replaceWith( ('<span class="finished-input">' + finalInputString + '</span><br/>') ); callback(finalInputString); } } if ($("#current-input") && oldInputString != self._inputString) { $("#current-input").html( self._inputString.entityify() + '<span id="cursor">_</span>' ); } }, _windowResize: function() { var contentLeft = $("#content").get(0).offsetLeft + "px"; $("#top-window").get(0).style.left = contentLeft; }, _eraseBottomWindow: function() { $("#content").html(""); }, getSize: function() { return self._size; }, onLineInput: function(callback) { self._currentCallback = callback; $("#content").append( '<span id="current-input"><span id="cursor">_</span></span>' ); }, onCharacterInput: function(callback) { self._currentCallback = callback; }, onQuit: function() { self._finalize(); }, onRestart: function() { self._finalize(); // TODO: It's not high-priority, but according to the Z-Machine // spec documentation for the restart opcode, we need to // preserve the "transcribing to printer" bit and the "use // fixed-pitch font" bit when restarting. window.setTimeout(_webZuiStartup, 0); }, onSetStyle: function(textStyle, foreground, background) { switch (textStyle) { case 0: this._currStyles = ["z-roman"]; break; case 1: this._currStyles.push("z-reverse-video"); break; case 2: this._currStyles.push("z-bold"); break; case 4: this._currStyles.push("z-italic"); break; case 8: this._currStyles.push("z-fixed-pitch"); break; default: throw new Error("Unknown style: " + textStyle); } }, onSetWindow: function(window) { // From the Z-Spec, section 8.7.2. if (window == 1) self._console.moveTo(0, 0); self._activeWindow = window; }, onEraseWindow: function(window) { if (window == -2) { self._console.clear(); self._eraseBottomWindow(); } else if (window == -1) { // From the Z-Spec, section 8.7.3.3. self.onSplitWindow(0); // TODO: Depending on the Z-Machine version, we want // to move the cursor to the bottom-left or top-left. self._eraseBottomWindow(); } else if (window == 0) { self._eraseBottomWindow(); } else if (window == 1) { self._console.clear(); } }, onSetCursor: function(x, y) { self._console.moveTo(x - 1, y - 1); }, onSetBufferMode: function(flag) { // TODO: How to emulate non-word wrapping in HTML? }, onSplitWindow: function(numlines) { if (numlines == 0) { self._console.close(); self._console = null; } else self._console = new Console(self._size[0], numlines, $("#top-window").get(0), self); }, onPrint: function(output) { var styles = self._currStyles.join(" "); if (self._activeWindow == 0) { var lines = output.split("\n"); for (var i = 0; i < lines.length; i++) { var addNewline = false; if (lines[i]) { var chunk = lines[i].entityify(); chunk = '<span class="' + styles + '">' + chunk + '</span>'; $("#content").append(chunk); if (i < lines.length - 1) addNewline = true; } else addNewline = true; if (addNewline) $("#content").append("<br/>"); } window.scroll(0, document.body.scrollHeight); } else { self._console.write(output, styles); } } }; self._windowResize(); self._bindEventHandlers(); self._eraseBottomWindow(); } function _webZuiStartup() { var logfunc = undefined; if (window.console) { logfunc = function(msg) { console.log(msg); }; } var engine = new GnustoEngine(); var zui = new WebZui(); var runner = new EngineRunner(engine, zui, logfunc); engine.loadStory(troll_z5.slice()); runner.run(); } $(document).ready(_webZuiStartup);