topical media & game development

talk show tell print

lib-js-terminal-termlib-invaders.js / js



  /*
  
          termlib-invaders
          a termlib.js application
          (c) mass:werk (N. Landsteiner) 2008
          based on JS/UIX invaders (c) mass:werk (N. Landsteiner) 2005
          all rights reserved
          v1.1
          
          termlib-invaders is a simple text-mode invaders game.
          requires termlib.js 1.4 or better.
          requires a terminal set to at least 68 cols x 20 rows.
          uses namespace 'invaders' in object 'env' of the termlib.js Terminal instance.
          the entire code is contained inside the single global object 'TermlibInvaders'.
          (the massive 'apply'-syntax is a bit awkward, but this is, which does it.)
          
          example call from inside a termlib.js Terminal instance's handler:
          
            if ( TermlibInvaders.start(this) ) {
              return;
            }
            else {
                    // oops, terminal doesn't meet the requirements
                    this.write('Sorry, invaders failed.');
            }
          
          call with a max game screen of 80 cols x 25 rows:
          
            TermlibInvaders.start(this, 80, 25);
  
  */
  
  TermlibInvaders = {
          version: '1.1 (original)',
          start: function( termref, maxcols, maxrows ) {
                  if (!Terminal || !termref || parseFloat(termref.version)<1.4) {
                          // color support required
                          return false;
                  }
                  if (termref.conf.cols<68 || termref.conf.rows<20) {
                          // required min. dimensions: 68 x 20
                          return false;
                  }
                  var gc=TermlibInvaders.getStyleColorFromHexString;
                  termref.env.invaders= {
                          termref: termref,
                          maxCols: maxcols || 0,
                          maxRows: maxrows || 0,
                          charMode: termref.charMode,
                          paused: false,
                          moveAll: true,
                          // setup values
                          rows: 3,
                          cols: 5,
                          maxBombs: 3,
                          bombRate: 0.005,
                          timer: null,
                          delay: 50,
                          newWaveDelay: 1500,
                          textColor: gc(TermlibInvaders.textColor),
                          invaderColor: gc(TermlibInvaders.invaderColor),
                          invaderHitColor: gc(TermlibInvaders.invaderHitColor),
                          bombColor: gc(TermlibInvaders.bombColor),
                          blockColor: gc(TermlibInvaders.blockColor),
                          statusColor: gc(TermlibInvaders.statusColor),
                          shotColor: gc(TermlibInvaders.shotColor),
                          shipColor: gc(TermlibInvaders.shipColor),
                          shipHitColor: gc(TermlibInvaders.shipHitColor),
                          alertColor: gc(TermlibInvaders.alertColor),
                          frameColor: gc(TermlibInvaders.frameColor)
                  };
                  TermlibInvaders.init.apply(termref);
                  return true;
          },
          // color definitions (colors will match nearest webcolor)
          textColor: '#00cc00',
          invaderColor: '#00cc00',
          invaderHitColor: '#66aa66',
          bombColor: '#cccc00',
          blockColor: '#bbbb00',
          statusColor: '#00bb00',
          shotColor: '#aacc00',
          shipColor: '#aacc00',
          shipHitColor: '#aaaaaa',
          alertColor: '#ff9900',
          // frame definitions
          // the frame is only drawn, if the terminal is bigger
          // than the game's max dimensions. if you do not want
          // to draw any frames leave 'frameChar' empty ('').
          frameChar: '*',
          frameColor: '#777777',
          // global assets
          sprites: [
          '       ',' (^o^) ',' (^-^) ','  ( ) ',' (   )',
          ' (=^=) ',' ((.)) ',' ( . ) ','( (.) )',
          ' ( . ) ','(  .  )','   .   ','       '
          ],
          splashScreen: [
                  '\%c(#0c0)%+i** T E R M L I B - I N V A D E R S **%-i',
                  '',
                  '',
                  '\%c(#0c0)Instructions:',
                  '',
                  '\%c(#0c0)  use cursor LEFT and RIGHT to move',
                  '\%c(#0c0)  (or use vi movements alternatively)',
                  '\%c(#0c0)  press space to fire',
                  '\%c(#0c0)',
                  '\%c(#0c0)  press "q" or "esc" to quit,',
                  '\%c(#0c0)  "p" to pause the game.',
                  '',
                  '',
                  '\%c(#0c0)%+r   press any key to start the game   %-r',
                  '',
                  '',
                  '\%c(#0c0)(c) mass:werk N.Landsteiner 2005-2008',
                  '\%c(#0c0)based on JS/UIX-Invaders by mass:werk'
          ],
          splashScreenWidth: 40, // width of splash-screen in chars
          gameOverScreen: [
                  '                          ',
                  '\%c(#f90)    G A M E  O V E R !    ',
                  '                          ',
                  '\%c(#0c0) press any key to restart,',
                  '\%c(#0c0) "q" or "esc" for quit.   ',
                  '                          '
          ],
          gameOverScreenWidth: 26,
          invObject: function(y,x) {
                  this.x=x;
                  this.y=y;
                  this.status=1;
          },
          // handlers:
          //   'this' refers to ther termlib.js Terminal instcance
          //   'inv' refers to the TermlibInvaders instance
          init: function() {
                  var inv=this.env.invaders;
                  // back up the terminal state
                  inv.termHandler=this.handler;
                  if (this.maxLines != this.conf.rows) {
                          inv.charBuf=new Array();
                          inv.styleBuf=new Array();
                          for (var r=this.conf.rows-1; r>=this.maxLines; r--) {
                                  var cb=new Array();
                                  var sb=new Array();
                                  var tcb=this.charBuf[r];
                                  var tsb=this.styleBuf[r];
                                  for (var c=0; c=this.conf.cols; c++) {
                                          cb[c]=tcb[c];
                                          sb[c]=tsb[c];
                                  }
                                  inv.charBuf.push(cb);
                                  inv.styleBuf.push(sb);
                          }
                          this.maxLines = this.conf.rows;
                  }
                  if (this.maxCols!=this.conf.cols) {
                          inv.termMaxCols=this.maxCols;
                          this.maxCols=this.conf.cols;
                  }
                  else {
                          inv.termMaxCols=-1;
                  }
                  inv.keyRepeatDelay1=this.keyRepeatDelay1;
                  inv.keyRepeatDelay2=this.keyRepeatDelay2;
                  this.keyRepeatDelay1=this.keyRepeatDelay2=inv.delay-1;
                  // output init-screen
                  this.clear();
                  TermlibInvaders.writeToCenter.apply(this, [TermlibInvaders.splashScreen, TermlibInvaders.splashScreenWidth]);
                  this.charMode=true;
                  this.lock=false;
                  this.handler=TermlibInvaders.splashScreenHandler;
          },
          splashScreenHandler: function() {
                  var key = this.inputChar;
                  if (key==this.termKey.ESC || key==113) {
                          TermlibInvaders.exit.apply(this);
                          return;
                  }
                  // setup the game
                  var inv=this.env.invaders;
                  TermlibInvaders.buildScreen.apply(this);
                  inv.maxRight=inv.width-7;
                  inv.wave=0;
                  inv.score=0;
                  var d=Math.floor(inv.width/5);
                  var d1=Math.floor((inv.width-3*d)/2);
                  inv.blockpos=new Array();
                  for (var i=0; i<4; i++) {
                          var x=d1+i*d;
                          inv.blockpos.push(x-1);
                          inv.blockpos.push(x);
                          inv.blockpos.push(x+1);
                  }
                  TermlibInvaders.newWave.apply(this);
          },
          newWave: function() {
                  this.clear();
                  var inv=this.env.invaders;
                  inv.wave++;
                  var s='W A V E  # '+inv.wave;
                  var c=Math.floor((this.conf.cols-s.length)/2);
                  var r=Math.floor((this.conf.rows-3)/2)-4;
                  this.typeAt(r, c, s, 4 | inv.textColor);
                  this.typeAt(r+2, c, 'Get ready ...', inv.textColor);
                  inv.timer=setTimeout(function() { TermlibInvaders.waveStart.apply(inv.termref); }, inv.newWaveDelay);
                  this.lock=true;
          },
          waveStart: function() {
                  var inv=this.env.invaders;
                  clearTimeout(inv.timer);
                  this.clear();
                  TermlibInvaders.drawFrame.apply(this);
                  inv.smove=0;
                  inv.phase=1;
                  inv.dir=1;
                  inv.population=0;
                  inv.shot= inv.shotX= 0
                  inv.over=false;
                  inv.bombs=0;
                  inv.invrows=(inv.wave==2)? inv.rows+1:inv.rows;
                  inv.invcols=(inv.wave<=2)? inv.cols:inv.cols+1;
                  var changed=inv.changed=new Array();
                  inv.inv=new Array();
                  for (var r=0; r<inv.invrows; r++) {
                          var ir=inv.inv[r]=new Array();
                          for (var c=0; c<inv.invcols; c++) {
                                  ir[c]=new TermlibInvaders.invObject(r*2+1,c*8);
                                  inv.population++;
                          }
                  }
                  inv.block=this.getRowArray(inv.width, false);
                  for (var i=0; i<inv.blockpos.length; i++) {
                          var x=inv.blockpos[i];
                          inv.block[x]=true;
                          TermlibInvaders.drawSprite(this, inv.blockY, x, 'H', inv.blockColor);
                  }
                  inv.bomb=new Array();
                  inv.shipX=inv.shipCenter;
                  TermlibInvaders.drawScoreBG.apply(this);
                  TermlibInvaders.displayScore.apply(this);
                  TermlibInvaders.drawSprite(this, inv.shipY, inv.shipX, TermlibInvaders.sprites[5], inv.shipColor);
                  for (var i=0; i<this.maxLines; i++) {
                          this.redraw(i);
                          changed[i]=false;
                  }
                  inv.moveAll=true;
                  TermlibInvaders.invStep(inv);
                  inv.timer=setTimeout(function() { TermlibInvaders.mainLoop.apply(inv.termref); }, inv.delay);
                  this.lock=false;
                  this.handler=TermlibInvaders.keyHandler;
          },
          mainLoop: function() {
                  var inv=this.env.invaders;
                  clearTimeout(inv.timer);
                  var now=new Date();
                  var enterTime=now.getTime();
                  if (inv.smove) {
                          inv.shipX+=inv.smove;
                          inv.smove=0;
                          TermlibInvaders.drawSprite(this, inv.shipY, inv.shipX, TermlibInvaders.sprites[5], inv.shipColor);
                  }
                  var s=inv.sore;
                  TermlibInvaders.invStep(inv);
                  var changed=inv.changed;
                  for (var i=0; i<this.maxLines; i++) {
                          if (changed[i]) {
                                  this.redraw(i);
                                  changed[i]=false;
                          }
                  }
                  inv.moveAll=!inv.moveAll;
                  if (s!=inv.score) TermlibInvaders.displayScore.apply(this);
                  if (inv.population==0) {
                          this.lock=true;
                          inv.phase=-1;
                          inv.timer=setTimeout(function() { TermlibInvaders.waveEnd.apply(inv.termref); }, inv.delay*2);
                  }
                  else if (inv.invbottom==inv.shipY || inv.over) {
                          this.lock=true;
                          inv.phase=(inv.over)? 6:5;
                          TermlibInvaders.gameOver.apply(this);
                  }
                  else {
                          now=new Date();
                          var delay=Math.max(1, inv.delay-(now.getTime()-enterTime));
                          inv.timer=setTimeout(function() { TermlibInvaders.mainLoop.apply(inv.termref); }, delay);
                  }
          },
          invStep: function(inv) {
                  var term=inv.termref;
                  var br=0, bl=inv.right, bb=0, dir=inv.dir;
                  var linestep= ((inv.invleft==0) || (inv.invright==inv.maxRight));
                  var shot= (inv.shot>0), shotx=inv.shotX, shoty=inv.shipY-inv.shot;
                  var bomb= inv.bomb,block=inv.block, blocky=inv.blockY, isblockrow=false;
                  var sprites=TermlibInvaders.sprites, invclr=inv.invaderColor;
                  var moveAll=inv.moveAll;
                  if (shot && inv.shot>1) TermlibInvaders.drawSprite(term, shoty+1,shotx,' ',0);
                  for (var r=0; r<inv.invrows; r++) {
                          var ir=inv.inv[r];
                          for (var c=0; c<inv.invcols; c++) {
                                  var i=ir[c];
                                  if (i.status==1) {
                                          if (moveAll && linestep) {
                                                  TermlibInvaders.drawSprite(term, i.y,i.x, sprites[0], invclr);
                                                  i.y++;
                                          }
                                          if (shot && shoty==i.y && shotx>i.x && shotx<(i.x+6)) {
                                                  i.status=2;
                                                  inv.population--;
                                                  inv.score+=50;
                                                  inv.shot=shot=0;
                                                  TermlibInvaders.drawSprite(term, i.y,i.x, sprites[3], inv.invaderHitColor);
                                          }
                                          else if (moveAll) {
                                                  TermlibInvaders.drawSprite(term, i.y,i.x, sprites[inv.phase], invclr );
                                                  if (i.y<inv.bombMaxY && inv.bombs<inv.maxBombs && Math.random()<inv.bombRate) {
                                                          for (var n=0; n<inv.maxBombs; n++) {
                                                                  if (bomb[n]==null) {
                                                                          bomb[n]=new TermlibInvaders.invObject(i.y+1,i.x+3);
                                                                          inv.bombs++;
                                                                          break;
                                                                  }
                                                          }
                                                  }
                                                  if (i.y==blocky) isblockrow=true;
                                                  bb=Math.max(i.y,bb);
                                          }
                                          else {
                                                  i.x+=dir;
                                                  br=Math.max(i.x,br);
                                                  bl=Math.min(i.x,bl);
                                          }
                                  }
                                  else if (i.status==2) {
                                          TermlibInvaders.drawSprite(term, i.y,i.x, sprites[4], inv.invaderHitColor);
                                          i.status=3
                                  }
                                  else if (i.status==3) {
                                          TermlibInvaders.drawSprite(term, i.y,i.x, sprites[0], invclr);
                                          i.status=0;
                                  }
                          }
                  }
                  for (var n=0; n<inv.maxBombs; n++) {
                          var b=bomb[n];
                          if (b!=null) {
                                  var _br=inv.top+b.y-1;
                                  var _bc=inv.left+b.x;
                                  if (term.charBuf [br] [bc]==86) TermlibInvaders.drawSprite(term, b.y-1,b.x, ' ', 0);
                                  if (b.y==blocky && block[b.x]) {
                                          block[b.x]=false;
                                          TermlibInvaders.drawSprite(term, blocky,b.x, ' ', 0);
                                          b=bomb[n]=null;
                                          inv.bombs--;
                                  }
                                  else if (b.y==inv.shipY) {
                                          if (b.x>inv.shipX && b.x<(inv.shipX+6)) {
                                                  inv.over=true;
                                          }
                                          else {
                                                  b=bomb[n]=null;
                                                  inv.bombs--;
                                          }
                                  }
                                  else if (shot) {
                                          if ((b.y==shoty || b.y==shoty+1) && Math.abs(b.x-shotx)<2) {
                                                  b=bomb[n]=null;
                                                  inv.bombs--;
                                                  inv.score+=5;
                                                  inv.shot=shot=0
                                          }
                                  }
                                  if (b) {
                                          TermlibInvaders.drawSprite(term, b.y,b.x, 'V', inv.bombColor);
                                          b.y++;
                                  }
                          }
                  }
                  if (shot) {
                          if (shoty>0) {
                                  if (shoty==blocky && inv.block[shotx]) {
                                          inv.block[shotx]=false;
                                          TermlibInvaders.drawSprite(term, blocky,shotx, ' ', 0);
                                          inv.shot=0;
                                          
                                  }
                                  else {
                                          TermlibInvaders.drawSprite(term, shoty,shotx, '|', inv.shotColor);
                                          inv.shot++;
                                  }
                          }
                          else {
                                  inv.shot=0;
                          }
                  }
                  if (moveAll) {
                          inv.invbottom=bb;
                  }
                  else {
                          inv.invleft=bl;
                          inv.invright=br;
                          if (dir==-1 && bl==0) {
                                  inv.dir=1;
                          }
                          else if (dir==1 && br==inv.maxRight) {
                                  inv.dir=-1;
                          }
                          inv.phase=(inv.phase==1)? 2:1;
                  }
                  // restore any overwritten blocks
                  if (isblockrow) {
                          var blockpos=inv.blockpos;
                          for (var i=0; i<inv.blockpos.length; i++) {
                                  var x=blockpos[i];
                                  if (block[x] && term.charBuf[inv.top+blocky][inv.left+x]<=32) {
                                          TermlibInvaders.drawSprite(term, blocky,x, 'H', inv.blockColor);
                                  }
                          }
                  }
          },
          waveEnd: function() {
                  var inv=this.env.invaders;
                  clearTimeout(inv.timer);
                  var drawblocks=false;
                  var r;
                  if (inv.phase==0) {
                          this.clear();
                          TermlibInvaders.drawFrame.apply(this);
                          TermlibInvaders.drawScoreBG.apply(this);
                          TermlibInvaders.displayScore.apply(this);
                          if (inv.width+1<this.maxCols || inv.height+1<this.maxLines) {
                                  for (r=0; r<this.maxLines; r++) this.redraw(r);
                          }
                          drawblocks=true;
                  }
                  else {
                          r=inv.shipY-inv.phase;
                          TermlibInvaders.drawSprite(this, r, inv.shipX, TermlibInvaders.sprites[0], inv.shipColor);
                          this.redraw(inv.top+r);
                          if (inv.shipY-inv.phase==inv.blockY) drawblocks=true;
                  }
                  if (inv.phase==inv.shipY) {
                          inv.timer=setTimeout(function() { TermlibInvaders.newWave.apply(inv.termref); }, inv.delay);
                  }
                  else {
                          inv.phase++;
                          r=inv.shipY-inv.phase;
                          TermlibInvaders.drawSprite(this, r, inv.shipX, TermlibInvaders.sprites[5], inv.shipColor);
                          this.redraw(inv.top+r);
                          if (r==inv.blockY) drawblocks=true;
                          if (drawblocks) {
                                  var block=inv.block;
                                  var blockpos=inv.blockpos;
                                  r=inv.blockY;
                                  for (var i=0; i<inv.blockpos.length; i++) {
                                          var x=blockpos[i];
                                          if (block[x] && term.charBuf[inv.top+r][inv.left+x]<=32) {
                                                  TermlibInvaders.drawSprite(term, r,x, 'H', inv.blockColor);
                                          }
                                  }
                                  this.redraw(inv.top+r)
                          }
                          inv.timer=setTimeout(function() { TermlibInvaders.waveEnd.apply(inv.termref); }, Math.max(10, inv.delay*2-inv.phase*2));
                  }
          },
          gameOver: function() {
                  var inv=this.env.invaders;
                  clearTimeout(inv.timer);
                  if (inv.phase>=TermlibInvaders.sprites.length) {
                          TermlibInvaders.writeToCenter.apply(this, [TermlibInvaders.gameOverScreen, TermlibInvaders.gameOverScreenWidth]);
                          this.lock=false;
                          this.handler=TermlibInvaders.splashScreenHandler;
                  }
                  else {
                          TermlibInvaders.drawSprite(this, inv.shipY,inv.shipX, TermlibInvaders.sprites[inv.phase++], inv.shipHitColor);
                          this.redraw(inv.top+inv.shipY);
                          inv.timer=setTimeout(function() { TermlibInvaders.gameOver.apply(inv.termref); }, inv.delay*3);
                  }
          },
          keyHandler: function() {
                  var inv=this.env.invaders;
                  var key=this.inputChar;
                  if (key==this.termKey.ESC || key==113) {
                          // esc or q
                          TermlibInvaders.exit.apply(this);
                  }
                  else if (key==112 || inv.paused) {
                          // p or paused
                          TermlibInvaders.pause.apply(this);
                  }
                  // cursor movements
                  else if (key==this.termKey.LEFT || key==104) {
                          // left
                          if (inv.shipX>0) inv.smove=-1;
                          return;
                  }
                  else if (key==this.termKey.RIGHT || key==108) {
                          // right
                          if (inv.shipX<inv.maxRight) inv.smove=1;
                          return;
                  }
                  else if (key==32) {
                          // space
                          if (inv.shot==0) {
                                  inv.shot=1;
                                  inv.shotX=inv.shipX+3;
                          }
                  }
          },
          pause: function() {
                  var inv=this.env.invaders;
                  clearTimeout(inv.timer);
                  inv.paused=!inv.paused;
                  var text=(inv.paused)? ' *** P A U S E D *** ' :'                     ';
                  this.typeAt(Math.floor(this.maxLines/2)-2, Math.floor((this.maxCols-text.length)/2), text, inv.alertColor);
                  if (!inv.paused) TermlibInvaders.mainLoop.apply(this);
          },
          drawSprite: function(termref, r,c,t,s) {
                  var inv=termref.env.invaders;
                  r+=inv.top;
                  c+=inv.left;
                  var cb=termref.charBuf[r];
                  var sb=termref.styleBuf[r];
                  for (var i=0; i<t.length; i++, c++) {
                          cb[c]=t.charCodeAt(i);
                          sb[c]=s;
                  }
                  inv.changed[r]=true;
          },
          drawScoreBG: function() {
                  var inv=this.env.invaders;
                  var srs=this.styleBuf[inv.statusRow];
                  var src=this.charBuf[inv.statusRow];
                  var clr=inv.statusColor | 1;
                  for (var c=inv.left; c<inv.right; c++) {
                          srs[c]=clr;
                          src[c]=0;
                  }
          },
          displayScore: function() {
                  var inv=this.env.invaders;
                  var text='Invaders | "q","esc": quit "p": pause |  Wave: '+inv.wave+'  Score: '+inv.score;
                  var x=inv.left+Math.floor((inv.width-text.length)/2);
                  var b=this.charBuf[inv.statusRow];
                  for (var i=0; i<text.length; i++) b[x+i]=text.charCodeAt(i);
                  this.redraw(inv.statusRow);
          },
          writeToCenter: function(buffer, bufferWidth) {
                  var sx = Math.max(0, Math.floor((this.maxCols-bufferWidth)/2));
                  var sy = Math.max(0, Math.floor((this.maxLines-buffer.length)/2));
                  for (var i=0; i<buffer.length; i++) {
                          this.cursorSet(sy+i, sx);
                          this.write(buffer[i]);
                  }
          },
          buildScreen: function() {
                  // (re)build a screen on max dimensions
                  this.clear();
                  var inv=this.env.invaders;
                  if (inv.maxCols>0 && this.maxCols>inv.maxCols) {
                          inv.width = inv.maxCols;
                          inv.left= Math.floor((this.maxCols-inv.maxCols)/2);
                          inv.right= inv.left+inv.width;
                  }
                  else {
                          inv.width= inv.right= this.maxCols;
                          inv.left=0;
                  }
                  if (inv.maxRows>0 && this.maxLines>inv.maxRows) {
                          inv.height = inv.maxRows;
                          inv.top= Math.floor((this.maxLines-inv.maxRows)/2);
                          inv.bottom=inv.top+inv.height;
                  }
                  else {
                          inv.height= inv.bottom= this.maxLines;
                          inv.top=0;
                  }
                  inv.shipCenter=Math.floor((inv.width-3)/2);
                  inv.statusRow=inv.bottom-1;
                  inv.maxRight=inv.width-7;
                  inv.shipY=inv.height-3;
                  inv.bombMaxY=inv.height-7;
                  inv.blockY=inv.height-5;
          },
          drawFrame: function() {
                  var inv=this.env.invaders;
                  if (TermlibInvaders.frameChar) {
                          var r0, r1, i;
                          var c = TermlibInvaders.frameChar.charCodeAt(0);
                          var cc= inv.frameColor;
                          if (inv.height+1<this.maxLines) {
                                  r0=Math.max(inv.left-1, 0);
                                  r1=Math.min(inv.right+1, this.maxCols);
                                  var cb1=this.charBuf[inv.top-1];
                                  var sb1=this.styleBuf[inv.top-1];
                                  var cb2=this.charBuf[inv.bottom];
                                  var sb2=this.styleBuf[inv.bottom];
                                  for (i=r0; i<r1; i++) {
                                          cb1[i]=cb2[i]=c;
                                          sb1[i]=sb2[i]=cc;
                                  }
                          }
                          if (inv.width+1<this.maxCols) {
                                  r0=Math.max(inv.top-1, 0);
                                  r1=Math.min(inv.bottom+1, this.maxLines);
                                  var p1=inv.left-1;
                                  var p2=inv.right;
                                  for (i=r0; i<r1; i++) {
                                          var b=this.charBuf[i];
                                          b[p1]=b[p2]=c;
                                          b=this.styleBuf[i];
                                          b[p1]=b[p2]=cc;
                                  }
                          }
                  }
          },
          exit: function() {
                  this.clear();
                  var inv=this.env.invaders;
                  // reset the terminal
                  this.handler=inv.termHandler;
                  if (inv.charBuf) {
                          for (var r=0; r<inv.charBuff.length; r++) {
                                  var tr=this.maxLines-1;
                                  this.charBuf[tr]=inv.charBuf[r];
                                  this.styleBuf[tr]=inv.styleBuf[r];
                                  this.redraw(tr);
                                  this.maxLines--;
                          }
                  }
                  if (inv.termMaxCols>=0) this.maxCols=inv.termMaxCols;
                  this.keyRepeatDelay1=inv.keyRepeatDelay1;
                  this.keyRepeatDelay2=inv.keyRepeatDelay2;
                  delete inv.termref;
                  this.lock=false;
                  this.charMode=inv.charMode;
                  // delete instance and leave with a prompt
                  delete this.env.invaders;
                  this.prompt();
          },
          getStyleColorFromHexString: function(clr) {
                  // returns a stylevector for the given color-string
                  var cc=Terminal.prototype.globals.webifyColor(clr.replace(/^#/,''));
                  if (cc) {
                          return Terminal.prototype.globals.webColors[cc]*0x10000;
                  }
                  return 0;
          }
  };
  
  // eof


(C) Æliens 04/09/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.