home *** CD-ROM | disk | FTP | other *** search
- Unit MKAvatar;
- {$I-}
- {$I MKB.Def}
-
- 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.
-
-