/***********************************************************************\
*
* Level 9 interpreter
* Version 5.1
* Copyright (c) 1996-2011 Glen Summers and contributors.
* Contributions from David Kinder, Alan Staniforth, Simon Baldwin,
* Dieter Baron and Andreas Scherrer.
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
*
* The input routine will repond to the following 'hash' commands
* #save saves position file directly (bypasses any
* disk change prompts)
* #restore restores position file directly (bypasses any
* protection code)
* #quit terminates current game, RunGame() will return FALSE
* #cheat tries to bypass restore protection on v3,4 games
* (can be slow)
* #dictionary lists game dictionary (press a key to interrupt)
* #picture <n> show picture <n>
* #seed <n> set the random number seed to the value <n>
* #play plays back a file as the input to the game
*
\***********************************************************************/
#include <ctype.h>
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "level9.h"
/* #define L9DEBUG */
/* #define CODEFOLLOW */
/* #define FULLSCAN */
/* "L901" */
#define L9_ID 0x4c393031
#define IBUFFSIZE 500
#define RAMSAVESLOTS 10
#define GFXSTACKSIZE 100
#define FIRSTLINESIZE 96
/* Typedefs */
typedef struct
{
L9UINT16 vartable[256];
L9BYTE listarea[LISTAREASIZE];
} SaveStruct;
/* Enumerations */
enum L9GameTypes { L9_V1, L9_V2, L9_V3, L9_V4 };
enum L9MsgTypes { MSGT_V1, MSGT_V2 };
/*
Graphics type Resolution Scale stack reset
-------------------------------------------------
GFX_V2 160 x 128 yes
GFX_V3A 160 x 96 yes
GFX_V3B 160 x 96 no
GFX_V3C 320 x 96 no
*/
enum L9GfxTypes { GFX_V2, GFX_V3A, GFX_V3B, GFX_V3C };
/* Global Variables */
L9BYTE* startfile=NULL,*pictureaddress=NULL,*picturedata=NULL;
L9BYTE* startdata;
L9UINT32 FileSize,picturesize;
L9BYTE *L9Pointers[12];
L9BYTE *absdatablock,*list2ptr,*list3ptr,*list9startptr,*acodeptr;
L9BYTE *startmd,*endmd,*endwdp5,*wordtable,*dictdata,*defdict;
L9UINT16 dictdatalen;
L9BYTE *startmdV2;
int wordcase;
int unpackcount;
char unpackbuf[8];
L9BYTE* dictptr;
char threechars[34];
int L9GameType;
int L9MsgType;
char LastGame[MAX_PATH];
char FirstLine[FIRSTLINESIZE];
int FirstLinePos=0;
int FirstPicture=-1;
#if defined(AMIGA) && defined(_DCC)
__far SaveStruct ramsavearea[RAMSAVESLOTS];
#else
SaveStruct ramsavearea[RAMSAVESLOTS];
#endif
GameState workspace;
L9UINT16 randomseed;
L9UINT16 constseed=0;
L9BOOL Running;
char ibuff[IBUFFSIZE];
L9BYTE* ibuffptr;
char obuff[34];
FILE* scriptfile=NULL;
L9BOOL Cheating=FALSE;
int CheatWord;
GameState CheatWorkspace;
int reflectflag,scale,gintcolour,option;
int l9textmode=0,drawx=0,drawy=0,screencalled=0,showtitle=1;
L9BYTE *gfxa5=NULL;
Bitmap* bitmap=NULL;
int gfx_mode=GFX_V2;
L9BYTE* GfxA5Stack[GFXSTACKSIZE];
int GfxA5StackPos=0;
int GfxScaleStack[GFXSTACKSIZE];
int GfxScaleStackPos=0;
char lastchar='.';
char lastactualchar=0;
int d5;
L9BYTE* codeptr; /* instruction codes */
L9BYTE code;
L9BYTE* list9ptr;
int unpackd3;
L9BYTE exitreversaltable[16]= {0x00,0x04,0x06,0x07,0x01,0x08,0x02,0x03,0x05,0x0a,0x09,0x0c,0x0b,0xff,0xff,0x0f};
L9UINT16 gnostack[128];
L9BYTE gnoscratch[32];
int object,gnosp,numobjectfound,searchdepth,inithisearchpos;
struct L9V1GameInfo
{
L9BYTE dictVal1, dictVal2;
int dictStart, L9Ptrs[5], absData, msgStart, msgLen;
};
struct L9V1GameInfo L9V1Games[] =
{
0x1a,0x24,301, 0x0000,-0x004b, 0x0080,-0x002b, 0x00d0,0x03b0, 0x0f80,0x4857, /* Colossal Adventure */
0x20,0x3b,283,-0x0583, 0x0000,-0x0508,-0x04e0, 0x0000,0x0800, 0x1000,0x39d1, /* Adventure Quest */
0x14,0xff,153,-0x00d6, 0x0000, 0x0000, 0x0000, 0x0000,0x0a20, 0x16bf,0x420d, /* Dungeon Adventure */
0x15,0x5d,252,-0x3e70, 0x0000,-0x3d30,-0x3ca0, 0x0100,0x4120,-0x3b9d,0x3988, /* Lords of Time */
0x15,0x6c,284,-0x00f0, 0x0000,-0x0050,-0x0050,-0x0050,0x0300, 0x1930,0x3c17, /* Snowball */
};
int L9V1Game = -1;
/* Prototypes */
L9BOOL LoadGame2(char *filename,char *picname);
int getlongcode(void);
L9BOOL GetWordV2(char *buff,int Word);
L9BOOL GetWordV3(char *buff,int Word);
void show_picture(int pic);
#ifdef CODEFOLLOW
#define CODEFOLLOWFILE "c:\\temp\\level9.txt"
FILE *f;
L9UINT16 *cfvar,*cfvar2;
char *codes[]=
{
"Goto",
"intgosub",
"intreturn",
"printnumber",
"messagev",
"messagec",
"function",
"input",
"varcon",
"varvar",
"_add",
"_sub",
"ilins",
"ilins",
"jump",
"Exit",
"ifeqvt",
"ifnevt",
"ifltvt",
"ifgtvt",
"screen",
"cleartg",
"picture",
"getnextobject",
"ifeqct",
"ifnect",
"ifltct",
"ifgtct",
"printinput",
"ilins",
"ilins",
"ilins",
};
char *functions[]=
{
"calldriver",
"L9Random",
"save",
"restore",
"clearworkspace",
"clearstack"
};
char *drivercalls[]=
{
"init",
"drivercalcchecksum",
"driveroswrch",
"driverosrdch",
"driverinputline",
"driversavefile",
"driverloadfile",
"settext",
"resettask",
"returntogem",
"10 *",
"loadgamedatafile",
"randomnumber",
"13 *",
"driver14",
"15 *",
"driverclg",
"line",
"fill",
"driverchgcol",
"20 *",
"21 *",
"ramsave",
"ramload",
"24 *",
"lensdisplay",
"26 *",
"27 *",
"28 *",
"29 *",
"allocspace",
"31 *",
"showbitmap",
"33 *",
"checkfordisc"
};
#endif
void initdict(L9BYTE *ptr)
{
dictptr=ptr;
unpackcount=8;
}
char getdictionarycode(void)
{
if (unpackcount!=8) return unpackbuf[unpackcount++];
else
{
/* unpackbytes */
L9BYTE d1=*dictptr++,d2;
unpackbuf[0]=d1>>3;
d2=*dictptr++;
unpackbuf[1]=((d2>>6) + (d1<<2)) & 0x1f;
d1=*dictptr++;
unpackbuf[2]=(d2>>1) & 0x1f;
unpackbuf[3]=((d1>>4) + (d2<<4)) & 0x1f;
d2=*dictptr++;
unpackbuf[4]=((d1<<1) + (d2>>7)) & 0x1f;
d1=*dictptr++;
unpackbuf[5]=(d2>>2) & 0x1f;
unpackbuf[6]=((d2<<3) + (d1>>5)) & 0x1f;
unpackbuf[7]=d1 & 0x1f;
unpackcount=1;
return unpackbuf[0];
}
}
int getdictionary(int d0)
{
if (d0>=0x1a) return getlongcode();
else return d0+0x61;
}
int getlongcode(void)
{
int d0,d1;
d0=getdictionarycode();
if (d0==0x10)
{
wordcase=1;
d0=getdictionarycode();
return getdictionary(d0); /* reentrant? */
}
d1=getdictionarycode();
return 0x80 | ((d0<<5) & 0xe0) | (d1 & 0x1f);
}
void printchar(char c)
{
if (Cheating) return;
if (c&128)
lastchar=(c&=0x7f);
else if (c!=0x20 && c!=0x0d && (c<'\"' || c>='.'))
{
if (lastchar=='!' || lastchar=='?' || lastchar=='.') c=toupper(c);
lastchar=c;
}
/* eat multiple CRs */
if (c!=0x0d || lastactualchar!=0x0d)
{
os_printchar(c);
if (FirstLinePos < FIRSTLINESIZE-1)
FirstLine[FirstLinePos++]=tolower(c);
}
lastactualchar=c;
}
void printstring(char*buf)
{
int i;
for (i=0;i< (int) strlen(buf);i++) printchar(buf[i]);
}
void printdecimald0(int d0)
{
char temp[12];
sprintf(temp,"%d",d0);
printstring(temp);
}
void error(char *fmt,...)
{
char buf[256];
int i;
va_list ap;
va_start(ap,fmt);
vsprintf(buf,fmt,ap);
va_end(ap);
for (i=0;i< (int) strlen(buf);i++)
os_printchar(buf[i]);
}
void printautocase(int d0)
{
if (d0 & 128) printchar((char) d0);
else
{
if (wordcase) printchar((char) toupper(d0));
else if (d5<6) printchar((char) d0);
else
{
wordcase=0;
printchar((char) toupper(d0));
}
}
}
void displaywordref(L9UINT16 Off)
{
static int mdtmode=0;
wordcase=0;
d5=(Off>>12)&7;
Off&=0xfff;
if (Off<0xf80)
{
/* dwr01 */
L9BYTE *a0,*oPtr,*a3;
int d0,d2,i;
if (mdtmode==1) printchar(0x20);
mdtmode=1;
/* setindex */
a0=dictdata;
d2=dictdatalen;
/* dwr02 */
oPtr=a0;
while (d2 && Off >= L9WORD(a0+2))
{
a0+=4;
d2--;
}
/* dwr04 */
if (a0==oPtr)
{
a0=defdict;
}
else
{
a0-=4;
Off-=L9WORD(a0+2);
a0=startdata+L9WORD(a0);
}
/* dwr04b */
Off++;
initdict(a0);
a3=(L9BYTE*) threechars; /* a3 not set in original, prevent possible spam */
/* dwr05 */
while (TRUE)
{
d0=getdictionarycode();
if (d0<0x1c)
{
/* dwr06 */
if (d0>=0x1a) d0=getlongcode();
else d0+=0x61;
*a3++=d0;
}
else
{
d0&=3;
a3=(L9BYTE*) threechars+d0;
if (--Off==0) break;
}
}
for (i=0;i<d0;i++) printautocase(threechars[i]);
/* dwr10 */
while (TRUE)
{
d0=getdictionarycode();
if (d0>=0x1b) return;
printautocase(getdictionary(d0));
}
}
else
{
if (d5&2) printchar(0x20); /* prespace */
mdtmode=2;
Off&=0x7f;
if (Off!=0x7e) printchar((char)Off);
if (d5&1) printchar(0x20); /* postspace */
}
}
int getmdlength(L9BYTE **Ptr)
{
int tot=0,len;
do
{
len=(*(*Ptr)++ -1) & 0x3f;
tot+=len;
} while (len==0x3f);
return tot;
}
void printmessage(int Msg)
{
L9BYTE* Msgptr=startmd;
L9BYTE Data;
int len;
L9UINT16 Off;
while (Msg>0 && Msgptr-endmd<=0)
{
Data=*Msgptr;
if (Data&128)
{
Msgptr++;
Msg-=Data&0x7f;
}
else {
len=getmdlength(&Msgptr);
Msgptr+=len;
}
Msg--;
}
if (Msg<0 || *Msgptr & 128) return;
len=getmdlength(&Msgptr);
if (len==0) return;
while (len)
{
Data=*Msgptr++;
len--;
if (Data&128)
Lines 1–500 of 3974. Load more
/***********************************************************************\ * * Level 9 interpreter * Version 5.1 * Copyright (c) 1996-2011 Glen Summers and contributors. * Contributions from David Kinder, Alan Staniforth, Simon Baldwin, * Dieter Baron and Andreas Scherrer. * * 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 2 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * * The input routine will repond to the following 'hash' commands * #save saves position file directly (bypasses any * disk change prompts) * #restore restores position file directly (bypasses any * protection code) * #quit terminates current game, RunGame() will return FALSE * #cheat tries to bypass restore protection on v3,4 games * (can be slow) * #dictionary lists game dictionary (press a key to interrupt) * #picture <n> show picture <n> * #seed <n> set the random number seed to the value <n> * #play plays back a file as the input to the game * \***********************************************************************/ #include <ctype.h> #include <math.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "level9.h" /* #define L9DEBUG */ /* #define CODEFOLLOW */ /* #define FULLSCAN */ /* "L901" */ #define L9_ID 0x4c393031 #define IBUFFSIZE 500 #define RAMSAVESLOTS 10 #define GFXSTACKSIZE 100 #define FIRSTLINESIZE 96 /* Typedefs */ typedef struct { L9UINT16 vartable[256]; L9BYTE listarea[LISTAREASIZE]; } SaveStruct; /* Enumerations */ enum L9GameTypes { L9_V1, L9_V2, L9_V3, L9_V4 }; enum L9MsgTypes { MSGT_V1, MSGT_V2 }; /* Graphics type Resolution Scale stack reset ------------------------------------------------- GFX_V2 160 x 128 yes GFX_V3A 160 x 96 yes GFX_V3B 160 x 96 no GFX_V3C 320 x 96 no */ enum L9GfxTypes { GFX_V2, GFX_V3A, GFX_V3B, GFX_V3C }; /* Global Variables */ L9BYTE* startfile=NULL,*pictureaddress=NULL,*picturedata=NULL; L9BYTE* startdata; L9UINT32 FileSize,picturesize; L9BYTE *L9Pointers[12]; L9BYTE *absdatablock,*list2ptr,*list3ptr,*list9startptr,*acodeptr; L9BYTE *startmd,*endmd,*endwdp5,*wordtable,*dictdata,*defdict; L9UINT16 dictdatalen; L9BYTE *startmdV2; int wordcase; int unpackcount; char unpackbuf[8]; L9BYTE* dictptr; char threechars[34]; int L9GameType; int L9MsgType; char LastGame[MAX_PATH]; char FirstLine[FIRSTLINESIZE]; int FirstLinePos=0; int FirstPicture=-1; #if defined(AMIGA) && defined(_DCC) __far SaveStruct ramsavearea[RAMSAVESLOTS]; #else SaveStruct ramsavearea[RAMSAVESLOTS]; #endif GameState workspace; L9UINT16 randomseed; L9UINT16 constseed=0; L9BOOL Running; char ibuff[IBUFFSIZE]; L9BYTE* ibuffptr; char obuff[34]; FILE* scriptfile=NULL; L9BOOL Cheating=FALSE; int CheatWord; GameState CheatWorkspace; int reflectflag,scale,gintcolour,option; int l9textmode=0,drawx=0,drawy=0,screencalled=0,showtitle=1; L9BYTE *gfxa5=NULL; Bitmap* bitmap=NULL; int gfx_mode=GFX_V2; L9BYTE* GfxA5Stack[GFXSTACKSIZE]; int GfxA5StackPos=0; int GfxScaleStack[GFXSTACKSIZE]; int GfxScaleStackPos=0; char lastchar='.'; char lastactualchar=0; int d5; L9BYTE* codeptr; /* instruction codes */ L9BYTE code; L9BYTE* list9ptr; int unpackd3; L9BYTE exitreversaltable[16]= {0x00,0x04,0x06,0x07,0x01,0x08,0x02,0x03,0x05,0x0a,0x09,0x0c,0x0b,0xff,0xff,0x0f}; L9UINT16 gnostack[128]; L9BYTE gnoscratch[32]; int object,gnosp,numobjectfound,searchdepth,inithisearchpos; struct L9V1GameInfo { L9BYTE dictVal1, dictVal2; int dictStart, L9Ptrs[5], absData, msgStart, msgLen; }; struct L9V1GameInfo L9V1Games[] = { 0x1a,0x24,301, 0x0000,-0x004b, 0x0080,-0x002b, 0x00d0,0x03b0, 0x0f80,0x4857, /* Colossal Adventure */ 0x20,0x3b,283,-0x0583, 0x0000,-0x0508,-0x04e0, 0x0000,0x0800, 0x1000,0x39d1, /* Adventure Quest */ 0x14,0xff,153,-0x00d6, 0x0000, 0x0000, 0x0000, 0x0000,0x0a20, 0x16bf,0x420d, /* Dungeon Adventure */ 0x15,0x5d,252,-0x3e70, 0x0000,-0x3d30,-0x3ca0, 0x0100,0x4120,-0x3b9d,0x3988, /* Lords of Time */ 0x15,0x6c,284,-0x00f0, 0x0000,-0x0050,-0x0050,-0x0050,0x0300, 0x1930,0x3c17, /* Snowball */ }; int L9V1Game = -1; /* Prototypes */ L9BOOL LoadGame2(char *filename,char *picname); int getlongcode(void); L9BOOL GetWordV2(char *buff,int Word); L9BOOL GetWordV3(char *buff,int Word); void show_picture(int pic); #ifdef CODEFOLLOW #define CODEFOLLOWFILE "c:\\temp\\level9.txt" FILE *f; L9UINT16 *cfvar,*cfvar2; char *codes[]= { "Goto", "intgosub", "intreturn", "printnumber", "messagev", "messagec", "function", "input", "varcon", "varvar", "_add", "_sub", "ilins", "ilins", "jump", "Exit", "ifeqvt", "ifnevt", "ifltvt", "ifgtvt", "screen", "cleartg", "picture", "getnextobject", "ifeqct", "ifnect", "ifltct", "ifgtct", "printinput", "ilins", "ilins", "ilins", }; char *functions[]= { "calldriver", "L9Random", "save", "restore", "clearworkspace", "clearstack" }; char *drivercalls[]= { "init", "drivercalcchecksum", "driveroswrch", "driverosrdch", "driverinputline", "driversavefile", "driverloadfile", "settext", "resettask", "returntogem", "10 *", "loadgamedatafile", "randomnumber", "13 *", "driver14", "15 *", "driverclg", "line", "fill", "driverchgcol", "20 *", "21 *", "ramsave", "ramload", "24 *", "lensdisplay", "26 *", "27 *", "28 *", "29 *", "allocspace", "31 *", "showbitmap", "33 *", "checkfordisc" }; #endif void initdict(L9BYTE *ptr) { dictptr=ptr; unpackcount=8; } char getdictionarycode(void) { if (unpackcount!=8) return unpackbuf[unpackcount++]; else { /* unpackbytes */ L9BYTE d1=*dictptr++,d2; unpackbuf[0]=d1>>3; d2=*dictptr++; unpackbuf[1]=((d2>>6) + (d1<<2)) & 0x1f; d1=*dictptr++; unpackbuf[2]=(d2>>1) & 0x1f; unpackbuf[3]=((d1>>4) + (d2<<4)) & 0x1f; d2=*dictptr++; unpackbuf[4]=((d1<<1) + (d2>>7)) & 0x1f; d1=*dictptr++; unpackbuf[5]=(d2>>2) & 0x1f; unpackbuf[6]=((d2<<3) + (d1>>5)) & 0x1f; unpackbuf[7]=d1 & 0x1f; unpackcount=1; return unpackbuf[0]; } } int getdictionary(int d0) { if (d0>=0x1a) return getlongcode(); else return d0+0x61; } int getlongcode(void) { int d0,d1; d0=getdictionarycode(); if (d0==0x10) { wordcase=1; d0=getdictionarycode(); return getdictionary(d0); /* reentrant? */ } d1=getdictionarycode(); return 0x80 | ((d0<<5) & 0xe0) | (d1 & 0x1f); } void printchar(char c) { if (Cheating) return; if (c&128) lastchar=(c&=0x7f); else if (c!=0x20 && c!=0x0d && (c<'\"' || c>='.')) { if (lastchar=='!' || lastchar=='?' || lastchar=='.') c=toupper(c); lastchar=c; } /* eat multiple CRs */ if (c!=0x0d || lastactualchar!=0x0d) { os_printchar(c); if (FirstLinePos < FIRSTLINESIZE-1) FirstLine[FirstLinePos++]=tolower(c); } lastactualchar=c; } void printstring(char*buf) { int i; for (i=0;i< (int) strlen(buf);i++) printchar(buf[i]); } void printdecimald0(int d0) { char temp[12]; sprintf(temp,"%d",d0); printstring(temp); } void error(char *fmt,...) { char buf[256]; int i; va_list ap; va_start(ap,fmt); vsprintf(buf,fmt,ap); va_end(ap); for (i=0;i< (int) strlen(buf);i++) os_printchar(buf[i]); } void printautocase(int d0) { if (d0 & 128) printchar((char) d0); else { if (wordcase) printchar((char) toupper(d0)); else if (d5<6) printchar((char) d0); else { wordcase=0; printchar((char) toupper(d0)); } } } void displaywordref(L9UINT16 Off) { static int mdtmode=0; wordcase=0; d5=(Off>>12)&7; Off&=0xfff; if (Off<0xf80) { /* dwr01 */ L9BYTE *a0,*oPtr,*a3; int d0,d2,i; if (mdtmode==1) printchar(0x20); mdtmode=1; /* setindex */ a0=dictdata; d2=dictdatalen; /* dwr02 */ oPtr=a0; while (d2 && Off >= L9WORD(a0+2)) { a0+=4; d2--; } /* dwr04 */ if (a0==oPtr) { a0=defdict; } else { a0-=4; Off-=L9WORD(a0+2); a0=startdata+L9WORD(a0); } /* dwr04b */ Off++; initdict(a0); a3=(L9BYTE*) threechars; /* a3 not set in original, prevent possible spam */ /* dwr05 */ while (TRUE) { d0=getdictionarycode(); if (d0<0x1c) { /* dwr06 */ if (d0>=0x1a) d0=getlongcode(); else d0+=0x61; *a3++=d0; } else { d0&=3; a3=(L9BYTE*) threechars+d0; if (--Off==0) break; } } for (i=0;i<d0;i++) printautocase(threechars[i]); /* dwr10 */ while (TRUE) { d0=getdictionarycode(); if (d0>=0x1b) return; printautocase(getdictionary(d0)); } } else { if (d5&2) printchar(0x20); /* prespace */ mdtmode=2; Off&=0x7f; if (Off!=0x7e) printchar((char)Off); if (d5&1) printchar(0x20); /* postspace */ } } int getmdlength(L9BYTE **Ptr) { int tot=0,len; do { len=(*(*Ptr)++ -1) & 0x3f; tot+=len; } while (len==0x3f); return tot; } void printmessage(int Msg) { L9BYTE* Msgptr=startmd; L9BYTE Data; int len; L9UINT16 Off; while (Msg>0 && Msgptr-endmd<=0) { Data=*Msgptr; if (Data&128) { Msgptr++; Msg-=Data&0x7f; } else { len=getmdlength(&Msgptr); Msgptr+=len; } Msg--; } if (Msg<0 || *Msgptr & 128) return; len=getmdlength(&Msgptr); if (len==0) return; while (len) { Data=*Msgptr++; len--; if (Data&128)