home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 2
/
ctrom_ii_b.zip
/
ctrom_ii_b
/
PROGRAM
/
PASCAL
/
MKMSG104
/
MKMSGCVT
/
MKAVATAR.PAS
next >
Wrap
Pascal/Delphi Source File
|
1994-01-09
|
19KB
|
705 lines
Unit MKAvatar;
{$I-}
{$I MKB.Def}
{
MKAvatar - Copyright 1993 by Mark May - MK Software
You are free to use this code in your programs, however
it may not be included in Source/TPU function libraries
without my permission.
Mythical Kingom Tech BBS (513)237-7737 HST/v32
FidoNet: 1:110/290
Rime: ->MYTHKING
You may also reach me at maym@dmapub.dma.org
}
Interface
{$IFDEF WINDOWS}
Uses MKWCrt;
{$ELSE}
{$IfDef OPRO}
Uses OpCrt,
{$ELSE}
Uses Crt,
{$EndIf}
MKScrn;
{$EndIF}
Function InAvatar: Boolean;
Function AnsiColor (Fore:Byte;Back:Byte):String;
{return Ansi String to set color}
Function AnsiAttr(AA: Byte): String;
{return ansi string for attribute}
Function AnsiAttrDiff(OldA: Byte; NewA: Byte): String;
{return minimal ansi string to update attribute}
Procedure AvatarChar (ch:Char);
{interpret Ansi/Avatar codes and display to screen}
Function CvtColor(colr:Byte):String;
{Convert attr color codes to ansi numbers}
Procedure AVReset;
Procedure AvStr(St: String);
Procedure AvStrLn(St: String);
Const AnsiSoundOn: Boolean = True;
Implementation
Uses MKMusic;
Const
ControlCh: Set of Char = ['A','B','C','D','f','s','u','H','J','K','m',';',
'P', '@', 'M', 'L'];
MusicCh: Set of Char = ['A','B','C','D','E','F','G','#','+','-','O','>',
'<','N','L','P','T','L','S','0','1','2','3','4','5','6','7','8','9','.',
' '];
Const
MaxParms = 200;
Var
AvState: Word; {0=normal, 1=esc, 2=esc[} {Ansi}
{5=^Y, 6=^Y#, 7=^V, 8=^V^A} {Avatar}
{9=^V^H 10=^V^H#}
{11=Collect Parameters}
{12="ansi" music, 13="ansi" music}
AvAttr: Byte;
AnsiParm: Array [1..MaxParms] of Byte;
AnsiParmNo: Byte;
SaveX: Byte;
SaveY: Byte;
InsertMode: Boolean;
CommandType: Word;
RemainingParms: Byte;
RepCount: Byte;
MusicStr: String[128];
Function InAvatar: Boolean;
Begin
InAvatar := (AvState > 0);
End;
Procedure AvStr(St: String);
Var
i: Word;
Begin
For i := 1 To Length(St) Do
AvatarChar(St[i]);
End;
Procedure AvStrLn(St: String);
Begin
AvStr(St);
AvatarChar(#13);
AvatarChar(#10);
End;
Function CvtColor(colr:Byte):String;
Begin
Colr := Colr mod 8;
Case Colr of
0: cvtcolor := '0';
1: cvtcolor := '4';
2: cvtcolor := '2';
3: cvtcolor := '6';
4: cvtcolor := '1';
5: cvtcolor := '5';
6: cvtcolor := '3';
7: cvtcolor := '7';
End;
End;
Function AnsiAttrDiff(OldA: Byte; NewA: Byte): String;
Var
DoReset: Boolean;
DoBlink: Boolean;
DoHigh: Boolean;
DoFore: Boolean;
DoBack: Boolean;
TmpStr: String;
Begin
If OldA = NewA Then
AnsiAttrDiff := ''
Else
Begin
DoReset := ((OldA and $88) and (Not (NewA and $88))) <> 0;
DoBlink := ((NewA and $80) <> 0) And (DoReset or (OldA and $80 = 0));
DoHigh := ((NewA and $08) <> 0) and (DoReset or (OldA and $08 = 0));
DoFore := (((NewA and $07) <> (OldA and $07)) or (DoReset and ((NewA and $07) <> 7)));
DoBack := (((NewA and $70) <> (OldA and $70)) or (DoReset and ((NewA and $70) <> 0)));
TmpStr := #27 + '[';
If DoReset Then
TmpStr := TmpStr + '0;';
If DoBlink Then
TmpStr := TmpStr + '5;';
If DoHigh Then
TmpStr := TmpStr + '1;';
If DoFore Then
TmpStr := TmpStr + '3' + CvtColor(NewA and $07) + ';';
If DoBack Then
TmpStr := TmpStr + '4' + CvtColor((NewA shr 4) and $07) + ';';
TmpStr[Length(TmpStr)] := 'm';
AnsiAttrDiff := TmpStr;
End;
End;
Function AnsiColor(Fore:Byte;Back:Byte):String;
Var
TempStr: String;
Begin
TempStr := #027;
TempStr := TempStr +'['+ '0;';
If Fore > 7 Then
Begin
TempStr := TempStr + '1;';
Fore := Fore - 8;
End;
If Back > 7 Then
Begin
TempStr := TempStr + '5;';
Back := Back - 8;
End;
TempStr := TempStr + '3';
TempStr := TempStr + CvtColor(Fore) + ';' + '4' + CvtColor(Back) + 'm';
AnsiColor := TempStr;
End;
Function AnsiAttr(AA: Byte): String;
Begin
AnsiAttr := AnsiColor(AA and $0f, AA shr 4);
End;
Procedure AVReset;
Begin
AvState := 0;
AvAttr := 3;
TextAttr := AvAttr;
ClrScr;
InsertMode := False;
End;
Procedure AVInit;
Begin
SaveX := 0;
SaveY := 0;
AvState := 0;
AvAttr := 3;
TextAttr := AvAttr;
InsertMode := False;
End;
Procedure ColorParm(Parm:Byte);
Var
Temp: Word;
Begin
Case parm of
00: AvAttr := LightGray;
01: AvAttr := AvAttr or $08; {Hi intensity}
04: AvAttr := (AvAttr and $F8) or Blue;
05: AvAttr := AvAttr or $80; {Blink}
07: Begin
Temp := AvAttr and $77;
AvAttr := (AvAttr and $88) or ((Temp shr 4) and $07);
AvAttr := AvAttr or ((Temp shl 4) and $70);
End;
08: AvAttr := AvAttr and $88; {black on black}
30: AvAttr := (AvAttr and $F8) or Black;
31: AvAttr := (AvAttr and $F8) or Red;
32: AvAttr := (AvAttr and $F8) or Green;
33: AvAttr := (AvAttr and $F8) or Brown;
34: AvAttr := (AvAttr and $F8) or Blue;
35: AvAttr := (AvAttr and $F8) or Magenta;
36: AvAttr := (AvAttr and $F8) or Cyan;
37: AvAttr := (AvAttr and $F8) or LightGray;
40: AvAttr := (AvAttr and $8F) or (Black shl 4);
41: AvAttr := (AvAttr and $8F) or (Red shl 4);
42: AvAttr := (AvAttr and $8F) or (Green shl 4);
43: AvAttr := (AvAttr and $8F) or (Brown shl 4);
44: AvAttr := (AvAttr and $8F) or (Blue shl 4);
45: AvAttr := (AvAttr and $8F) or (Magenta shl 4);
46: AvAttr := (AvAttr and $8F) or (Cyan shl 4);
47: AvAttr := (AvAttr and $8F) or (LightGray shl 4);
End;
End;
Procedure ProcCtl(ch:Char);
Var
i: Word;
Begin
Case ch of
';': Begin
Ansiparmno := Ansiparmno + 1;
if Ansiparmno > 10 Then
Ansiparmno := 10;
End;
'A': Begin {cursor up}
If Ansiparm[1] = 0 Then
Ansiparm[1] := 1;
i := WhereY;
Dec(i,AnsiParm[1]);
If i < 0 Then
i := 0;
GoToXy(WhereX, i);
AvState := 0;
End;
'B': Begin {cursor down}
If Ansiparm[1] = 0 Then
AnsiParm[1] := 1;
GoToXy(WhereX, WhereY + AnsiParm[1]);
AvState := 0;
End;
'C': Begin {cursor right}
If Ansiparm[1] = 0 Then
Ansiparm[1] := 1;
GoToXy(WhereX + AnsiParm[1], WhereY);
AvState := 0;
End;
'D': Begin {cursor left}
If AnsiParm[1] = 0 Then
AnsiParm[1] := 1;
i := WhereX;
Dec(i, AnsiParm[1]);
If i < 0 Then
i := 0;
GoToXy(i, WhereY);
AvState := 0;
End;
'H','f': {set cursor position}
Begin
if Ansiparm[1] = 0 Then
Ansiparm[1] := 1;
If Ansiparm[2] = 0 Then
Ansiparm[2] := 1;
GoToXy(Ansiparm[2],Ansiparm[1]);
AvState := 0;
End;
'J': Begin
AvState := 0;
Case AnsiParm[1] of
0: Begin {erase to end of screen}
ClrEol;
InitializeScrnRegion(1, WhereY + 1, ScrnWidth, ScrnHeight, ' ');
End;
1: Begin {erase from start of screen}
InitializeScrnRegion(1, 1, ScrnWidth, WhereY - 1, ' ');
InitializeScrnRegion(1, WhereY, WhereX - 1, WhereY, ' ');
End;
2: Begin {clear screen}
TextAttr := AvAttr;
ClrScr;
End;
End;
End;
'K': Begin
AvState := 0;
Case AnsiParm[1] of
0: Begin {clear to end of line}
ClrEol;
End;
1: Begin {clear from start of line}
InitializeScrnRegion(1, WhereY, WhereX - 1, WhereY, ' ');
End;
2: Begin {erase whole line}
InitializeScrnRegion(1, WhereY ,ScrnWidth, WhereY, ' ');
End;
End;
End;
's': Begin {save cursor position}
SaveX := WhereX;
SaveY := WhereY;
AvState := 0;
End;
'u': Begin {restore cursor position}
GoToXy(SaveX, SaveY);
AvState := 0;
End;
'm': Begin {set color attribute}
AvState := 0;
If AnsiParmNo > 0 Then
For i := 1 to AnsiParmNo Do
ColorParm(AnsiParm[i]);
TextAttr := AvAttr;
End;
'P': Begin {delete characters}
AvState := 0;
If AnsiParm[1] = 0 Then
AnsiParm[1] := 1;
For i := 1 to AnsiParm[1] Do
DelCharInLine(WhereX, WhereY);
End;
'@': Begin {insert characters}
AvState := 0;
If AnsiParm[1] = 0 Then
AnsiParm[1] := 1;
For i := 1 to AnsiParm[1] Do
InsCharInLine(WhereX, WhereY, ' ');
End;
'M': Begin {delete lines or "ansi" music}
If ((AnsiParmNo = 1) and (AnsiParm[1] = 0)) Then
Begin
AvState := 12;
MusicStr := '';
End
Else
Begin
AvState := 0;
If AnsiParm[1] = 0 Then
AnsiParm[1] := 1;
ScrollScrnRegionUp(1, WhereY + 1, ScrnWidth, ScrnHeight, AnsiParm[1]);
End;
End;
'L': Begin {insert lines}
AvState := 0;
If AnsiParm[1] = 0 Then
AnsiParm[1] := 1;
ScrollScrnRegionDown(1, WhereY, ScrnWidth, ScrnHeight, AnsiParm[1]);
End;
Else
AvState := 0;
End;
End;
Procedure Accum(ch: Char);
Begin
AnsiParm[AnsiParmNo] := (AnsiParm[AnsiParmNo] * 10) + (Ord(ch) - 48);
End;
Procedure MusicChar(ch: Char);
Begin
Case ch of
#27: AvState := 1;
#$0e: AvState := 0;
#13: Begin
If Length(MusicStr) > 0 Then
Begin
If AnsiSoundOn Then
Play(MusicStr);
MusicStr := '';
End;
End;
#10:;
Else
Begin
If ch in MusicCh Then
Begin
If Length(MusicStr) > 120 Then
Begin
If AnsiSoundOn Then
Play(MusicStr);
MusicStr := '';
End;
Inc(MusicStr[0]);
MusicStr[Length(MusicStr)] := ch;
End
Else
Begin
AVState := 0;
End;
End;
End;
If ((AvState < 12) and (Length(MusicStr) > 0)) Then
Begin
If AnsiSoundOn Then
Play(MusicStr);
MusicStr := '';
End;
End;
Procedure AvatarChar(ch:Char);
Var
i: Word;
Begin
Case AvState of
0: Begin
Case ch of
#027: AvState := 1;
#012: AvReset; {^L - Avatar}
#025: AvState := 5; {^Y - Avatar}
#022: AvState := 7; {^V - Avatar}
Else
If InsertMode Then
InsCharInLine(WhereX, WhereY, ch);
Write(ch);
End;
End;
1: Begin
Case ch of
#27: Begin
AvState := 1;
If InsertMode Then
InsCharInLine(WhereX, WhereY, #27);
Write(#27);
End;
'[': Begin
AvState := 2;
AnsiParmNo := 1;
For i := 1 To 10 Do
Ansiparm[i] := 0;
End;
#12: Begin
AvReset;
AvState := 0;
End;
#25: Begin
If InsertMode Then
InsCharInLine(WhereX, WhereY, #27);
Write(#27);
AvState := 5;
End;
#22: Begin
If InsertMode Then
InsCharInLine(WhereX, WhereY, #27);
Write(#27);
AvState := 6;
End
Else
Begin
If InsertMode Then
InsCharInLine(WhereX, WhereY, #27);
Write(#27);
If InsertMode Then
InsCharInLine(WhereX, WhereY, ch);
Write(ch);
AvState := 0;
End;
End;
End;
2: Begin
Case ch of
#27: Begin
AvState := 1;
If InsertMode Then
InsCharInLine(WhereX, WhereY, #27);
Write(#27);
If InsertMode Then
InsCharInLine(WhereX, WhereY, '[');
Write('[');
End;
'0' .. '9': Accum(ch);
Else
If ch in ControlCh Then
ProcCtl(ch)
Else
AvState :=0;
End;
End;
5: Begin
AnsiParm[1] := Ord(ch);
AvState := 6;
End;
6: Begin
AvState := 0;
i := 1;
While i <= Ord(ch) Do
Begin
If InsertMode Then
InsCharInLine(WhereX, WhereY, Chr(AnsiParm[1]));
Write(Chr(AnsiParm[1]));
Inc(i);
End;
End;
7: Begin
Case ch of
#001: AvState := 8; {^V^A}
#002: Begin
AvAttr := AvAttr or Blink; {^B}
InsertMode := False;
AvState := 0;
End;
#003: Begin
If WhereY > 1 Then {^C}
GoToXy(WhereX, WhereY - 1);
InsertMode := False;
AvState := 0;
End;
#004: Begin
GoToXy(WhereX, WhereY + 1); {^D}
InsertMode := False;
AvState := 0;
End;
#005: Begin
GoToXy(WhereX + 1, WhereY); {^E}
InsertMode := False;
AvState := 0;
End;
#006: Begin
If WhereX > 1 Then {^F}
GoToXy(WhereX - 1, WhereY);
InsertMode := False;
AvState := 0;
End;
#007: Begin
ClrEol; {^G}
InsertMode := False;
AvState := 0;
End;
#008: AvState := 9; {^H}
#009: Begin
InsertMode := True; {^I}
AvState := 0;
End;
#010: Begin {^J}
AvState := 11;
RemainingParms := 5;
CommandType := 1;
InsertMode := False;
AnsiParmNo := 1;
End;
#011: Begin {^K}
AvState := 11;
RemainingParms := 5;
CommandType := 2;
InsertMode := False;
AnsiParmNo := 1;
End;
#012: Begin {^L}
AvState := 11;
RemainingParms := 3;
CommandType := 3;
InsertMode := False;
AnsiParmNo := 1;
End;
#013: Begin {^M}
AvState := 11;
RemainingParms := 4;
CommandType := 4;
InsertMode := False;
AnsiParmNo := 1;
End;
#014: Begin
DelCharInLine(WhereX, WhereY);{^N}
InsertMode := False;
AvState := 0;
End;
#025: Begin {^Y}
AvState := 11;
RemainingParms := 1;
CommandType := 5;
AnsiParmNo := 1;
End;
End;
End;
8: Begin {^V^A}
AvAttr := Ord(ch);
TextAttr := AvAttr;
AvState := 0;
InsertMode := False;
End;
9: Begin {^V^H}
AvState := 10;
AnsiParm[1] := Ord(ch);
End;
10:Begin {^V^H#}
AvState := 0;
GoToXy(Ord(ch), AnsiParm[1]);
InsertMode := False;
End;
11:Begin
AnsiParm[AnsiParmNo] := Ord(ch);
Inc(AnsiParmNo);
If AnsiParmNo > MaxParms Then
AnsiParmNo := MaxParms;
Dec(RemainingParms);
If RemainingParms < 1 Then
Begin
Case CommandType of
1: Begin {^V^J}
ScrollScrnRegionUp(AnsiParm[3], AnsiParm[2], AnsiParm[5],
AnsiParm[4], AnsiParm[1]);
AvState := 0;
End;
2: Begin {^V^K}
ScrollScrnRegionDown(AnsiParm[3], AnsiParm[2], AnsiParm[5],
AnsiParm[4], AnsiParm[1]);
AvState := 0;
End;
3: Begin {^V^L}
TextAttr := AnsiParm[1];
InitializeScrnRegion(WhereX, WhereY, WhereX + AnsiParm[3],
WhereY + AnsiParm[2], ' ');
AvState := 0;
End;
4: Begin {^V^M}
TextAttr := AnsiParm[1];
InitializeScrnRegion(WhereX, WhereY, WhereX + AnsiParm[4],
WhereY + AnsiParm[3], Chr(AnsiParm[2]));
AvState := 0;
End;
5: Begin {Have num chars swith to 6}
RemainingParms := Ord(Ch) + 2;
CommandType := 6;
End;
6: Begin {^V^Y}
RepCount := AnsiParm[AnsiParmNo - 1];
While RepCount > 0 Do
Begin
AnsiParmNo := 2;
While AnsiParmNo < (AnsiParm[1]+ 3) Do
Begin
Write(Chr(AnsiParm[AnsiParmNo]));
Inc(AnsiParmNo);
End;
Dec(RepCount);
End;
AvState := 0;
End;
End;
End;
End;
12:Begin {"ansi" music}
Case ch of
'F': AvState := 13;
'B': AvState := 13;
Else
Begin
AvState := 13;
MusicChar(UpCase(ch));
End;
End;
End;
13:Begin {"Ansi" music after F/B}
MusicChar(UpCase(ch));
End;
End;
End;
Begin
AvInit;
End.