From eab6da2b0a2a82bf6afce8bff1c90385b64fed89 Mon Sep 17 00:00:00 2001 From: NuSkooler Date: Sun, 19 Oct 2014 21:06:39 -0600 Subject: [PATCH] * More View updates --- core/ansi_escape_parser.js | 17 +- core/ansi_term.js | 13 +- core/art.js | 6 +- core/client.js | 126 +++++++++++- core/string_util.js | 44 ++++- core/view.js | 394 +++++++++++++++++++++++++++++++++++-- mods/art/MATRIX_TEST1.ANS | Bin 6997 -> 7037 bytes mods/art/MCI_TEST1.ANS | Bin 0 -> 7097 bytes mods/art/MCI_TEST2.ANS | Bin 0 -> 1086 bytes mods/art/MCI_TEST3.ANS | Bin 0 -> 4413 bytes mods/matrix.js | 30 ++- 11 files changed, 592 insertions(+), 38 deletions(-) create mode 100644 mods/art/MCI_TEST1.ANS create mode 100644 mods/art/MCI_TEST2.ANS create mode 100644 mods/art/MCI_TEST3.ANS diff --git a/core/ansi_escape_parser.js b/core/ansi_escape_parser.js index 89ac9a99..65ffe220 100644 --- a/core/ansi_escape_parser.js +++ b/core/ansi_escape_parser.js @@ -4,6 +4,7 @@ var events = require('events'); var util = require('util'); var miscUtil = require('./misc_util.js'); +var ansi = require('./ansi_term.js'); exports.ANSIEscapeParser = ANSIEscapeParser; @@ -18,8 +19,6 @@ function ANSIEscapeParser(options) { this.flags = 0x00; this.scrollBack = 0; - - options = miscUtil.valueWithDefault(options, { mciReplaceChar : '', termHeight : 25, @@ -29,6 +28,12 @@ function ANSIEscapeParser(options) { this.mciReplaceChar = miscUtil.valueWithDefault(options.mciReplaceChar, ''); this.termHeight = miscUtil.valueWithDefault(options.termHeight, 25); this.termWidth = miscUtil.valueWithDefault(options.termWidth, 80); + + function saveLastColor() { + self.lastFlags = self.flags; + self.lastFgCololr = self.fgColor; + self.lastBgColor = self.bgColor; + } function getArgArray(array) { var i = array.length; @@ -125,7 +130,8 @@ function ANSIEscapeParser(options) { function getProcessedMCI(mci) { if(self.mciReplaceChar.length > 0) { - return new Array(mci.length + 1).join(self.mciReplaceChar); + var eraseColor = ansi.sgr(self.lastFlags, self.lastFgColor, self.lastBgColor); + return eraseColor + new Array(mci.length + 1).join(self.mciReplaceChar); } else { return mci; } @@ -254,6 +260,8 @@ function ANSIEscapeParser(options) { // set graphic rendition case 'm' : + saveLastColor(); + for(i = 0, len = args.length; i < len; ++i) { arg = args[i]; if(0x00 === arg) { @@ -280,6 +288,9 @@ function ANSIEscapeParser(options) { break; } } + + this.resetColor(); + saveLastColor(); } util.inherits(ANSIEscapeParser, events.EventEmitter); \ No newline at end of file diff --git a/core/ansi_term.js b/core/ansi_term.js index 4b7b57bd..1edc7e3c 100644 --- a/core/ansi_term.js +++ b/core/ansi_term.js @@ -16,7 +16,7 @@ var miscUtil = require('./misc_util.js'); exports.sgr = sgr; exports.clearScreen = clearScreen; -exports.clearScreenGoHome = clearScreenGoHome; +exports.resetScreen = resetScreen; exports.normal = normal; exports.goHome = goHome; exports.disableVT100LineWrapping = disableVT100LineWrapping; @@ -40,13 +40,18 @@ var CONTROL = { prevLine : 'F', horizAbsolute : 'G', eraseData : 'J', + eraseLine : 'K', + insertLine : 'L', + deleteLine : 'M', scrollUp : 'S', scrollDown : 'T', savePos : 's', restorePos : 'u', queryPos : '6n', goto : 'H', // row Pr, column Pc -- same as f - gotoAlt : 'f' // same as H + gotoAlt : 'f', // same as H + + emulationSpeed : '*r' // Set output emulation speed. See cterm.txt }; /* @@ -255,8 +260,8 @@ function clearScreen() { return exports.eraseData(2); } -function clearScreenGoHome() { - return exports.goto(1,1) + exports.eraseData(2); +function resetScreen() { + return exports.goHome() + exports.eraseData(2); } function normal() { diff --git a/core/art.js b/core/art.js index f57888bd..fcfd4254 100644 --- a/core/art.js +++ b/core/art.js @@ -418,7 +418,7 @@ function display(art, options, cb) { parser.on('mci', function onMCI(mciCode, args) { if(mci[mciCode]) { - mci[mciCode].altColor = { + mci[mciCode].focusColor = { fg : parser.fgColor, bg : parser.bgColor, flags : parser.flags, @@ -430,7 +430,9 @@ function display(art, options, cb) { fg : parser.fgColor, bg : parser.bgColor, flags : parser.flags, - } + }, + code : mciCode.substr(0, 2), + id : mciCode.substr(2, 1), // :TODO: This NEEDs to read 01-99 }; mciPosQueue.push(mciCode); diff --git a/core/client.js b/core/client.js index b2bc01a7..ae959201 100644 --- a/core/client.js +++ b/core/client.js @@ -10,6 +10,57 @@ var logger = require('./logger.js'); exports.Client = Client; +//var ANSI_CONTROL_REGEX = /(?:(?:\u001b\[)|\u009b)(?:(?:[0-9]{1,3})?(?:(?:;[0-9]{0,3})*)?[A-M|f-m])|\u001b[A-M]/g; + +// :TODO: Move all of the key stuff to it's own module +var ANSI_KEY_NAME_MAP = { + 0x08 : 'backspace', + 0x09 : 'tab', + 0x7f : 'del', + 0x1b : 'esc', + 0x0d : 'enter', +}; + +var ANSI_KEY_CSI_NAME_MAP = { + 0x40 : 'insert', // @ + 0x41 : 'up arrow', // A + 0x42 : 'down arrow', // B + 0x43 : 'right arrow', // C + 0x44 : 'left arrow', // D + + 0x48 : 'home', // H + 0x4b : 'end', // K + + 0x56 : 'page up', // V + 0x55 : 'page down', // U +}; + +var ANSI_F_KEY_NAME_MAP_1 = { + 0x50 : 'F1', + 0x51 : 'F2', + 0x52 : 'F3', + 0x53 : 'F4', + 0x74 : 'F5', +}; + +var ANSI_F_KEY_NAME_MAP_2 = { + // rxvt + 11 : 'F1', + 12 : 'F2', + 13 : 'F3', + 14 : 'F4', + 15 : 'F5', + + // SyncTERM + 17 : 'F6', + 18 : 'F7', + 19 : 'F8', + 20 : 'F9', + 21 : 'F10', + 23 : 'F11', + 24 : 'F12', +}; + function Client(input, output) { stream.call(this); @@ -19,19 +70,80 @@ function Client(input, output) { this.output = output; this.term = new term.ClientTerminal(this.output); - self.on('data', function onData(data) { - console.log('data: ' + data.length); + self.on('data', function onData1(data) { + console.log(data); + + onData(data); handleANSIControlResponse(data); }); function handleANSIControlResponse(data) { - console.log(data); + //console.log(data); ansi.forEachControlCode(data, function onControlResponse(name, params) { var eventName = 'on' + name[0].toUpperCase() + name.substr(1); console.log(eventName + ': ' + params); self.emit(eventName, params); }); } + + // + // Peek at |data| and emit for any specialized handling + // such as ANSI control codes or user/keyboard input + // + function onData(data) { + var len = data.length; + var c; + var name; + + if(1 === len) { + c = data[0]; + + if(0x00 === c) { + // ignore single NUL + return; + } + + name = ANSI_KEY_NAME_MAP[c]; + if(name) { + self.emit('special key', name); + self.emit('key press', data, true); + } else { + self.emit('key press', data, false); + } + } + + if(0x1b !== data[0]) { + return; + } + + if(3 === len) { + if(0x5b === data[1]) { + name = ANSI_KEY_CSI_NAME_MAP[data[2]]; + if(name) { + self.emit('special key', name); + self.emit('key press', data, true); + } + } else if(0x4f === data[1]) { + name = ANSI_F_KEY_NAME_MAP_1[data[2]]; + if(name) { + self.emit('special key', name); + self.emit('key press', data, true); + } + } + } else if(5 === len && 0x5b === data[1] && 0x7e === data[4]) { + var code = parseInt(data.slice(2,4), 10); + + if(!isNaN(code)) { + name = ANSI_F_KEY_NAME_MAP_2[code]; + if(name) { + self.emit('special key', name); + self.emit('key press', data, true); + } + } + } else if(len > 4 && len < 11 && 0x52 === data[len]) { + // :TODO: Look for various DSR responses such as cursor position + } + } } require('util').inherits(Client, stream); @@ -48,11 +160,9 @@ Client.prototype.destroySoon = function () { return this.output.destroySoon.apply(this.output, arguments); }; -Client.prototype.getch = function(cb) { - this.input.once('data', function onData(data) { - // :TODO: needs work. What about F keys and the like? - assert(data.length === 1); - cb(data); +Client.prototype.waitForKeyPress = function(cb) { + this.once('key press', function onKeyPress(kp) { + cb(kp); }); }; diff --git a/core/string_util.js b/core/string_util.js index 5696ce65..c5ba5685 100644 --- a/core/string_util.js +++ b/core/string_util.js @@ -1,7 +1,11 @@ /* jslint node: true */ 'use strict'; +var miscUtil = require('./misc_util.js'); + + exports.stylizeString = stylizeString; +exports.pad = pad; // :TODO: create Unicode verison of this var VOWELS = [ 'a', 'e', 'i', 'o', 'u' ]; @@ -25,26 +29,31 @@ function stylizeString(s, style) { var i; var stylized = ''; - switch(style) { + switch(style) { // UPPERCASE + case 'upper' : case 'U' : return s.toUpperCase(); // lowercase + case 'lower' : case 'l' : return s.toLowerCase(); // Proper Case + case 'proper' : case 'P' : return s.replace(/\w\S*/g, function onProperCaseChar(t) { return t.charAt(0).toUpperCase() + t.substr(1).toLowerCase(); }); // fIRST lOWER + case 'first lower' : case 'f' : return s.replace(/\w\S*/g, function onFirstLowerChar(t) { return t.charAt(0).toLowerCase() + t.substr(1).toUpperCase(); }); // SMaLL VoWeLS + case 'small vowels' : case 'v' : for(i = 0; i < len; ++i) { c = s[i]; @@ -57,6 +66,7 @@ function stylizeString(s, style) { return stylized; // bIg vOwELS + case 'big vowels' : case 'V' : for(i = 0; i < len; ++i) { c = s[i]; @@ -69,9 +79,11 @@ function stylizeString(s, style) { return stylized; // Small i's: DEMENTiA + case 'small i' : case 'i' : return s.toUpperCase().replace('I', 'i'); // mIxeD CaSE (random upper/lower) + case 'mixed' : case 'M' : for(i = 0; i < len; i++) { if(Math.random() < 0.5) { @@ -83,6 +95,7 @@ function stylizeString(s, style) { return stylized; // l337 5p34k + case 'l33t' : case '3' : for(i = 0; i < len; ++i) { c = SIMPLE_ELITE_MAP[s[i].toLowerCase()]; @@ -91,5 +104,34 @@ function stylizeString(s, style) { return stylized; } + return s; +} + +// Based on http://www.webtoolkit.info/ +function pad(s, len, padChar, dir) { + len = miscUtil.valueWithDefault(len, 0); + padChar = miscUtil.valueWithDefault(padChar, ' '); + dir = miscUtil.valueWithDefault(dir, 'right'); + + var padlen = len - s.length; + + switch(dir) { + case 'left' : + s = new Array(padlen).join(padChar) + s; + break; + + case 'both' : + var right = Math.ceil(padlen) / 2; + var left = padlen - right; + s = new Array(left + 1).join(padChar) + s + new Array(right + 1).join(padChar); + break; + + case 'right' : + s = s + new Array(padlen).join(padChar); + break; + + default : break; + } + return s; } \ No newline at end of file diff --git a/core/view.js b/core/view.js index d367c257..b3293b5e 100644 --- a/core/view.js +++ b/core/view.js @@ -3,42 +3,241 @@ var util = require('util'); var ansi = require('./ansi_term.js'); +var miscUtil = require('./misc_util.js'); +var strUtil = require('./string_util.js'); +var assert = require('assert'); +var events = require('events'); +var logger = require('./logger.js'); exports.View = View; exports.LabelView = LabelView; +exports.TextEditView = TextEditView; + +exports.ViewsController = ViewsController; function View(client) { + events.EventEmitter.call(this); + var self = this; - console.log('View ctor'); - - this.client = client; - -// this.width = width; -// this.height = height; + this.client = client; + this.acceptsFocus = false; + this.acceptsKeys = false; } -// :TODO: allow pos[] or x, y -View.prototype.draw = function(x, y) { +util.inherits(View, events.EventEmitter); + +View.prototype.place = function(pos) { + // + // We allow [x, y], { x : x, y : y }, or (x, y) + // + if(util.isArray(pos)) { + this.x = pos[0]; + this.y = pos[1]; + } else if(pos.x && pos.y) { + this.x = pos.x; + this.y = pos.y; + } else if(2 === arguments.length) { + var x = parseInt(arguments[0], 10); + var y = parseInt(arguments[1], 10); + if(!isNaN(x) && !isNaN(y)) { + this.x = x; + this.y = y; + } + } + + assert(this.x > 0 && this.x < this.client.term.termHeight); + assert(this.y > 0 && this.y < this.client.term.termWidth); + + this.client.term.write(ansi.goto(this.x, this.y)); }; -function LabelView(client, text, width) { +View.prototype.setFocus = function(focused) { + assert(this.x); + assert(this.y); +}; + +View.prototype.getColor = function() { + return this.options.color; +}; + +View.prototype.getFocusColor = function() { + return this.options.focusColor || this.getColor(); +}; + +function LabelView(client, text, options) { View.call(this, client); var self = this; - this.text = text; - this.width = width || text.length; + if(options) { + if(options.maxWidth) { + text = text.substr(0, options.maxWidth); + } + text = strUtil.stylizeString(text, options.style); + } + + this.value = text; + this.height = 1; + this.width = this.value.length; } util.inherits(LabelView, View); -LabelView.prototype.draw = function(x, y) { - LabelView.super_.prototype.draw.call(this, x, y); +LabelView.prototype.place = function(pos) { + LabelView.super_.prototype.place.apply(this, arguments); + + this.client.term.write(this.value); +}; - this.client.term.write(ansi.goto(x, y)); - this.client.term.write(this.text); +/////////////////////////////////////////////////////////////////////////////// + +var INTERACTIVE_VIEW_DEFAULT_SPECIAL_KEYSET = { + enter : [ 'enter' ], + exit : [ 'esc' ], + backspace : [ 'backspace', 'del' ], + next : [ 'tab' ], +}; + +function InteractiveView(client, options) { + View.call(this, client); + + this.acceptsFocus = true; + this.acceptsKeys = true; + + if(options) { + this.options = options; + } else { + this.options = { + }; + } + + this.options.specialKeySet = miscUtil.valueWithDefault( + options.specialKeySet, INTERACTIVE_VIEW_DEFAULT_SPECIAL_KEYSET + ); + + this.isSpecialKeyFor = function(checkFor, specialKey) { + return this.options.specialKeySet[checkFor].indexOf(specialKey) > -1; + }; + + this.backspace = function() { + this.client.term.write('\b \b'); + }; +} + +util.inherits(InteractiveView, View); + +InteractiveView.prototype.setFocus = function(focused) { + InteractiveView.super_.prototype.setFocus.call(this, focused); + + this.hasFocus = focused; +}; + +InteractiveView.prototype.setNextView = function(id) { + this.nextId = id; +}; + + +var TEXT_EDIT_INPUT_TYPES = [ + 'none', // :TODO: TextEditView -> TextView (optional focus/editable) + 'text', + 'password', + 'upper', + 'lower', +]; + + +function TextEditView(client, options) { + InteractiveView.call(this, client, options); + + if(!options) { + this.options.multiLine = false; + } + + this.options.inputType = miscUtil.valueWithDefault(this.options.inputType, 'text'); + assert(TEXT_EDIT_INPUT_TYPES.indexOf(this.options.inputType) > -1); + + if('password' === this.options.inputType) { + this.options.inputMaskChar = miscUtil.valueWithDefault(this.options.inputMaskChar, '*').substr(0,1); + } + + this.value = miscUtil.valueWithDefault(options.defaultValue, ''); + // :TODO: hilight, text, etc., should come from options or default for theme if not provided + + // focus=fg + bg + // standard=fg +bg + +} + +util.inherits(TextEditView, InteractiveView); + + +TextEditView.prototype.place = function(pos) { + TextEditView.super_.prototype.place.apply(this, arguments); + + if(!this.options.maxWidth) { + this.options.maxWidth = this.client.term.termWidth - this.x; + } + + this.width = this.options.maxWidth; +}; + +TextEditView.prototype.setFocus = function(focused) { + TextEditView.super_.prototype.setFocus.call(this, focused); + + this.client.term.write(ansi.goto(this.x, this.y)); + this.redraw(); + this.client.term.write(ansi.goto(this.x, this.y + this.value.length)); +}; + +TextEditView.prototype.redraw = function() { + var color = this.hasFocus ? this.getFocusColor() : this.getColor(); + + this.client.term.write(ansi.sgr(color.flags, color.fg, color.bg)); + this.client.term.write(strUtil.pad(this.value, this.width)); +}; + +TextEditView.prototype.onKeyPressed = function(k, isSpecial) { + assert(this.hasFocus); + + if(isSpecial) { + return; // handled via onSpecialKeyPressed() + } + + if(this.value.length < this.options.maxWidth) { + + k = strUtil.stylizeString(k, this.options.inputType); + + this.value += k; + + if('password' === this.options.inputType) { + this.client.term.write(this.options.inputMaskChar); + } else { + this.client.term.write(k); + } + } +}; + +TextEditView.prototype.onSpecialKeyPressed = function(keyName) { + assert(this.hasFocus); + + console.log(keyName); + + if(this.isSpecialKeyFor('backspace', keyName)) { + if(this.value.length > 0) { + this.value = this.value.substr(0, this.value.length - 1); + this.backspace(); + } + } else if(this.isSpecialKeyFor('enter', keyName)) { + if(this.options.multiLine) { + + } else { + this.emit('action', 'accepted'); + } + } else if(this.isSpecialKeyFor('next', keyName)) { + this.emit('action', 'next'); + } }; @@ -48,4 +247,167 @@ function MenuView(options) { function VerticalMenuView(options) { -} \ No newline at end of file +} + +/////////////////////////////////////////////////////// +// :TODO: Move to view_controller.js +function ViewsController(client) { + events.EventEmitter.call(this); + + var self = this; + + this.views = {}; + this.client = client; + + client.on('key press', function onKeyPress(k, isSpecial) { + if(self.focusedView && self.focusedView.acceptsKeys) { + self.focusedView.onKeyPressed(k, isSpecial); + } + }); + + client.on('special key', function onSpecialKey(keyName) { + if(self.focusedView && self.focusedView.acceptsKeys) { + self.focusedView.onSpecialKeyPressed(keyName); + } + }); + + this.onViewAction = function(action) { + console.log(action + '@ ' + this.id); + + self.emit('action', { id : this.id, action : action }); + + if('accepted' === action) { + self.nextFocus(); + } else if('next' === action) { + self.nextFocus(); + } + }; + +} + +util.inherits(ViewsController, events.EventEmitter); + +ViewsController.prototype.addView = function(viewInfo) { + viewInfo.view.id = viewInfo.id; + + this.views[viewInfo.id] = { + view : viewInfo.view, + pos : viewInfo.pos + }; + + viewInfo.view.place(viewInfo.pos); +}; + +ViewsController.prototype.viewExists = function(id) { + return id in this.views; +}; + +ViewsController.prototype.getView = function(id) { + return this.views[id].view; +}; + +ViewsController.prototype.switchFocus = function(id) { + var view = this.getView(id); + + if(!view) { + logger.log.warn('Invalid view', { id : id }); + return false; + } + + if(!view.acceptsFocus) { + logger.log.warn('View does not accept focus', { id : id }); + return false; + } + + this.focusedView = view; + view.setFocus(true); +}; + +ViewsController.prototype.nextFocus = function() { + var nextId = this.focusedView.nextId; + + this.focusedView.setFocus(false); + + if(nextId > 0) { + this.switchFocus(nextId); + } else { + this.switchFocus(this.firstId); + } +}; + +ViewsController.prototype.loadFromMCIMap = function(mciMap) { + var factory = new MCIViewFactory(this.client); + var view; + var mci; + + for(var entry in mciMap) { + mci = mciMap[entry]; + view = factory.createFromMCI(mci); + + if(view) { + this.addView({ + id : mci.id, + view : view, + pos : mci.position + }); + + view.on('action', this.onViewAction); + } + } +}; + +ViewsController.prototype.setViewOrder = function(order) { + var idOrder = []; + + if(order) { + // :TODO: + } else { + for(var id in this.views) { + idOrder.push(id); + } + // :TODO: simply sort + console.log(idOrder); + this.firstId = idOrder[0]; + } + + var view; + for(var i = 0; i < idOrder.length - 1; ++i) { + view = this.getView(idOrder[i]); + if(view) { + view.setNextView(idOrder[i + 1]); + } + } +}; + +/////////////////////////////////////////////////// + +function MCIViewFactory(client, mci) { + this.client = client; +} + +MCIViewFactory.prototype.createFromMCI = function(mci) { + assert(mci.code); + assert(mci.id > 0); + + var view; + var options = {}; + + switch(mci.code) { + case 'EV' : + if(mci.args.length > 0) { + options.maxWidth = mci.args[0]; + } + + if(mci.args.length > 1) { + + } + + options.color = mci.color; + options.focusColor = mci.focusColor; + + view = new TextEditView(this.client, options); + break; + } + + return view; +}; \ No newline at end of file diff --git a/mods/art/MATRIX_TEST1.ANS b/mods/art/MATRIX_TEST1.ANS index 75e9b2f444523ae1e2b3e1236f84d317eb746ca5..5d909d312cd5e3739a72f2733b62b8ec3e985533 100644 GIT binary patch delta 129 zcmca=_SbB~3{E*?gIrbDFhdO^15N2@6GLlbV=!Mj+8|dt+H&(&PAMi{g@DB3;`02W z6zOO~_^4N25ft0baNk1ad4&D%Jom{_Evjf^(m o<>q4qu}n7$@!E6n=WddYHZiw0HUu*aHb;y8VP(8BIYL?$0BDdI7ytkO diff --git a/mods/art/MCI_TEST1.ANS b/mods/art/MCI_TEST1.ANS new file mode 100644 index 0000000000000000000000000000000000000000..4bbc89c191c56dcc82b04660b6148b3a7309b82b GIT binary patch literal 7097 zcmZ{pL5n2E5rtP*gHJvfJeR&0WbmPTx@SgWPHV9kV+j_FrNf*SJQhOKF6^%H->T`q z(=}87WYPEDi_EH?mF7@gl^Gcs@!~~fRL#ZR_V%#7-QNtGi@V+JemjiQ#ogg%n7M9; zY36CGx&2|_c6WQ=cl20aa9l5FQ^?QLY1*(T$`3cvj_gi~(9I5Pd>A%Ok!0D@5)!#7 z!BY))4d(_=)1x(A+04a}3B8y;HuclfXLdH1Em#jSYj}{T>^;2u^34zTf04lgiE)Eu zOPk_xJO%<8jbD$`ruha^D`<`8f^A?lw8%?tGj%X*#zv1oG%5_nUTXx}X=+O>ATh&* zP>1a_BXhVOzz?%d6FT<$AsY6H_X^TsMhSRrHX|bT@<;?(do$QSJUc!M{i)N#@|a&L zWY1NF(nAZlQfGsL#zEdRue9Ep;(dG2v<+i;C&Nw5Ef^^{o6AX`xZF})6tIEjZk(J)s4m>@|rta%J9UjQ!*}<4OqqJ#Z-wuyWb2hS4xr($?uEW5px(7C; zrBl0fJ2r`F(ZX(;JqNCd;8D==csw1oo6zD{Msam8tkgcQEVe2L$=d5iErV$QfLi%1 z9Wme>M^8EKp0!&|w9&6t%J)PFbmt(UsCLx`A2X~;RL_)I)L42tGseqpW)H_{KE*;^ z@ycp?6zo^vP&OJ5-6Vpl69w1K(Cr6oLI@xm#+KbH+8*ynJDsyimBWZz2mqy5*ea8; zX_`X@d+M}gd;ezh1<8xM>u)S|t$ai2cDT5^VF+>aOje>ld~t=0+ib|N0s#UiFNEvN z@r(`5sMGN%G0{Y%@~)}LXFA3)J28kPS57F_?~)fWOs}l+aYeP9WlkKrCZm?X= zv~ii?;2AZEG{DR;qpSfdW5nkFtyV?hE&x42(dNUFD zJoe~aCq$rxDlj)}+%oV05QMwK#-L~v*s5|~58uA~@u#O?I^tr z<6z)J0&V=3vnX{zY~TeZ(3BxlJ4aEYyj%dnl0U!te)r|&mKFrXY`6DF;k8Y+8meBA zmWow*cgj9o?O_k8wXvBf(d!DRICIXjbuP!A=OdCYuLv$ zD|O`{8s~yTxQmnewS*kwrU4+|azMM(X<5?n_j4G$XR=2XHy&800NaZVYcmxVImyF?e#O4#} zu80I-ZhU~SJ(`hlQLhp~Us1+T%DEM>t^`r<6?7(=YB71iYu0g(?O1_pA(p*we0eOG zgi}L^A@!bxGk`4MZ)Qp!<}eaFI2P!amKG%~-19CV z=|VGUTdGNV=J{nS%FfGMqR$SMCA(_y@){!-ILJg1Cy|{nqyZps@#dzpiZHm{bNpyJ z0dciT0gc;o-^DG*6;G1%(Pc2AI$bNyGno)11`8Z%+t(?JWvd-Aj?SzdiOH@GPiS#z zUa0wIB`$B^nO{X#YOp)C+9Ix)afWfzUEHHYDd`EspJ__>ZA$Ri5|7ouWOo!u~J z70JLMQfN9x)B|3x1r3KlYH*yFa^WEHcn2n{H+vOyMGS*<4Q76ewWZtF)Pq{i813M44uLZFyA* zA|w6D8bLhaYzAezg13BKtN7JciE2SnZ{<=0o^Euk+L;z8>p4;UmHH*emuN|QPYm8i z^66LJpF2GJ3r0Zq9Gk^(@7Ki%N<$uo&#q%mQw4DSrb?8x>tpy2E}xBlGEd9RM*~XIslvRS5Aii%&i6N8*I1LaFfX?k6se zM^d*0+BbccVgIv+%HK}tsN^m+wUHt$=#dT+QEf6LbY_z}D;p9lWeZTsmmEO?wkj2b zJRe{1tmX_+$AvigTW`@bs%Nzsii<7oU!5P1^-rPYpjuchr$ohat}v~qKmF_FzrT64 z-Tw2Us!FZ}n1fBfyc&G&zQnWujJ1+4}iD*ylh literal 0 HcmV?d00001 diff --git a/mods/art/MCI_TEST2.ANS b/mods/art/MCI_TEST2.ANS new file mode 100644 index 0000000000000000000000000000000000000000..86b0138e14a43d75bdd2f69931db611f9d604e93 GIT binary patch literal 1086 zcmb1+Hn27^ur@Z#y-jT(9c^r$D;;fa;S6Mf%%`G&3EWVeu2ukBrvRdmEH^QSx&|UG z9c^R=6(FeG(AwB2*C#(cGfz6&0O&CzL!xv-%mtEWxvH*Vh8ji&n$ppR)+WZ*z~BLi zKuj|K5g-7s(9cQwpzu+sw)i;K(ii&CKW!9tKY6M$X^y448idYu4>`%SHljlp72 z^NeWaeuBP*`2=TDfTTPH^t3=u%7liy0x78(p$E4M$&!%@b_{iPH824Bj9S3Rz|h3d ez|e9pGXn!7V*rB$0~iQ#FXJXqd)JeVHG@*{rp{r^78#VMSf+BSRAW;)(n)oVgT05w2rWqnm|l9$%0*Vv;) zq@^M;+`|Vy_i1&wd@ZsZFnomL;x@l~%Nb~x@cSHBtbfW7Jgg4QE^&r5PP>;2#3gS3 zoh*Vj4id$Lbs8)1M+D}T%DYIxJFt-jVvVI?urXB=S6pT{_R}QgE|}P*W2bmwGr+=- zY>B?jI`b!dLeV~O%Pt{_0D8sIK`AxwmS5`S_O;}SjqKxCiO-+j{c(GT%`95xhZJDX1R&HSQ!@bcC^0Fb zed;DU<H6mW-b`*n;gkfJV=AV58iTS~&i%yYf9_Of9w3C;ta-2jJBo2Ff zRS8b>{7$8|s2mtlZ89SuWCBD)>N&o=AYIyPy13LF1b{W^i++s2AI1!4jHTc$2hBFKG1d&s@y|{*#XJ`h} z*%=QjVA(Ve(f}N}EHDLNC}I2ntq9t&Mei#dPHD%@627AgSy7N1296vZbR&(3vOvKf z46#{=l<2}3g;i@5@^J*LzImERp~#x&ndp>J=D96hWg2EZmQ34(8$1ug@x)dD*e-vB zh2G%3rBy_?@Y#sf)4>x61PAF6kpUwRl>AQ30{Jv)o(tBLQ*sl3Z>TfA@X-}JO4^+( zVi{Ywar&|>@UE3Ss&f8H^-lkLsO?~l4otn&Aa#+N=N>1{o6%r_ImAdtWe_oEw{g@+ z!5CC?EYgYhDNS@YJeMk1c1-?*136{kIGRWZ{Yq8t?qbDWbt%H3^ej~vWlwZC>a8WD zj3elK92<6>-38ztf4=ak%h`-w2Br%JEoi(8v9AuaZ3@e=#rO$^O^>RGf2jF9V~s?8 zfJ~CgsE4j(^l_Z3n8<}%u@XVKrhL1m5@xWqU?j`Cq`Q^=>u1H-X|z0%5bUL!yYxkt zK|#1Fe}J7BS8)6XQZJA@+z}W7LUKm9_@h0`#pl1g`t|jj^*Y_W|MT|mZ&`Hz_1xUO yOSkWTKbyY)?Ju%^_H16h+^;XUm;Zcnaq;5C^~GlwdOrQ}`=6_~KfLl=`TPJzp6EUR literal 0 HcmV?d00001 diff --git a/mods/matrix.js b/mods/matrix.js index 8f2b7908..90ce7e74 100644 --- a/mods/matrix.js +++ b/mods/matrix.js @@ -6,6 +6,8 @@ var ansi = require('../core/ansi_term.js'); var lineEditor = require('../core/line_editor.js'); var art = require('../core/art.js'); +var view = require('../core/view.js'); + exports.moduleInfo = { name : 'Matrix', desc : 'Standardish Matrix', @@ -17,19 +19,39 @@ exports.entryPoint = entryPoint; function entryPoint(client) { var term = client.term; - term.write(ansi.clearScreenGoHome()); + term.write(ansi.resetScreen()); + + //------------- + /* + client.on('position', function onPos(pos) { + console.log(pos); + }); + + term.write('Hello, world!'); + term.write(ansi.queryPos()); + term.write(ansi.goto(5,5)); + term.write('Yehawww a bunch of text incoming.... maybe that is what breaks it... hrm... who knows.\nHave to do more testing ;(\n'); + term.write(ansi.queryPos()); + return; + */ + + //------------- // :TODO: types, random, and others? could come from conf.mods.matrix or such //art.getArt('SO-CC1.ANS'/* 'MATRIX'*/, { types: ['.ans'], random: true}, function onArt(err, theArt) { - art.getArt('DM-ENIG2-MATRIX.ANS', {}, function onArt(err, theArt) { + art.getArt('MCI_TEST3.ANS', /*'MATRIX_TEST1.ANS'*/ {}, function onArt(err, theArt) { if(!err) { + art.display(theArt.data, { client : client, mciReplaceChar : ' ' }, function onArtDisplayed(err, mci) { if(err) { - return; + return; } - console.log(mci); + var vc = new view.ViewsController(client); + vc.loadFromMCIMap(mci); + vc.setViewOrder(); + vc.switchFocus(1); }); } });