*/
Know a good article or link that we're missing? Submit it!
*/

View \SPLVIEW.PAS

SpellView V1.2

Submitted By: Unknown
Rating: (Not rated) (Rate It)


{ ************************************************************************** }
{ This is the complete source code of SpellView, version 1.3                 }
{ This program was coded by Spellcaster of Spell, and you can find general   }
{ info about the program in the info docs suplied with this package.         }
{ The reason why I released the source code of this program is that I want   }
{ people to learn... That how I did it... I learned with other people's      }
{ sources...                                                                 }
{ Of course, this source code is just for tutorial purposes and should not,  }
{ in any circunstance be used for comercial purposes.                        }
{ You can use this source code as you want, alter it to suit your needs, or  }
{ use it as a base to a great text viewer (better than this, anyway).        }
{ But, please, don't change just a line in the code and claim it as yours... }
{ That's f#$@$ lame !!! Don't be lame !!!                                    }
{ The code should be self-explainable, because, altough I'm a caothic        }
{ programmer, I took some care with the formatting of this one...            }
{ The program just uses the standart CRT unit, and other unit called Mode13h,}
{ that is used to do graphics (reading the PCX image). The unit and the rest }
{ of the programm should be easy to understand to someone that reads the     }
{ fabulous ezine, 'The Mag'. :))))                                           }
{ So, take care... And may the bytes be with you... (Shit, what a lame end   }
{ phrase !!!) :))                                                            }
{                                           Spellcaster of Spell             }
{                                                                            }
{ ************************************************************************** }

Program SpellView(input,output);

Uses Mode13h,Crt;

Const MaxParam=50;
      NPartials=1024;
      VidSeg=$B800;

Type TextPoint=^LineRec;
     LineRec=Record
                   Line:String[80];
                   Fg,Bg:Byte;
                   Next:TextPoint;
             End;

     ParsedType=Array[1..MaxParam] Of String[50];

     PartialType=Record
                       Color:Byte;
                       Line:Word;
                       X1,X2:Byte;
                 End;

Var FileName:String;
    TheText:TextPoint;
    CurrentLine:Word;
    A:Byte;
    C:Char;
    NLines:Word;

    TitleFg:Byte;
    TitleBg:Byte;
    TitleString:String[80];
    Bg:Byte;
    Fg:Byte;
    PNum:Word;

    Partials:Array[1..NPartials] Of PartialType;

Function Find(S:String;C:Char):byte;
Var B:Byte;
Begin
     B:=0;
     Find:=0;
     While (S[B]<>C) And (B<=Length(S)) Do
     Begin
          Inc(B);
          If S[B]=C Then Find:=B;
     End;
End;

Function Left(S:String;N:Byte):String;
Var P:string;
    H:byte;
Begin
     P:='';
     If Length(S)<N Then N:=Length(S);
     For H:=1 to N do
         P:=P+S[H];
     Left:=P
End;

Function Exist(Name:String):Boolean;
Var F:File;
Begin
     {$I-}
     Assign(F,Name);
     Reset(F);
     Close(F);
     {$I+}
     Exist:=(IOResult=0) And (Name<>'');
End;

Function FindSpace(S:String;Start:Byte):Byte;
Begin
     While (S[Start+1]<>' ') And (S[Start+1]<>',') And (Start<Length(S)) Do
       Inc(Start);
     FindSpace:=Start;
End;

Function GetString(S:String;Start,Finish:Byte):String;
Var A:Byte;
    Tmp:String;
Begin
     Tmp:='';
     For A:=Start+1 To Finish Do Tmp:=Tmp+S[A];
     GetString:=Tmp;
End;

Procedure Parse(S:String;Var Parsed:ParsedType);
Var ArrayIndex:Byte;
    StringIndex:Byte;
    NextSpace:Byte;
Begin
     ArrayIndex:=1;
     StringIndex:=0;
     NextSpace:=FindSpace(S,StringIndex);
     While (StringIndex<=Length(S)) And (ArrayIndex<=MaxParam) Do
     Begin
          NextSpace:=FindSpace(S,StringIndex);
          Parsed[ArrayIndex]:=GetString(S,StringIndex,NextSpace);
          StringIndex:=NextSpace+1;
          Inc(ArrayIndex);
     End;
End;

Function Upper(S:String):String;
Var Tmp:String;
    A:Byte;
Begin
     Tmp:='';
     For A:=1 To Length(S) Do Tmp:=Tmp+UpCase(S[A]);
     Upper:=Tmp;
End;

Procedure MyWrite(N:Word;BgC,FgC:Byte;S:String);
Var A:Word;
    P:Word;
    Cl:Byte;
Begin
     P:=0;
     For A:=1 To PNum Do If Partials[A].Line=N Then P:=A;
     For A:=1 To Length(S) Do
     Begin
          Cl:=BgC*16+FgC;
          If P<>0 Then
            If (A>=Partials[P].X1) And (A<=Partials[P].X2) Then
              Cl:=Partials[P].Color;
          TextColor(Cl And 143);
          TextBackground((Cl And 112) Shr 4);
          Write(S[A]);
     End;
End;

Procedure ReadText(Name:String);
Var F:Text;
    Tmp:TextPoint;
Begin
     Assign(F,Name);
     Reset(F);
     If MaxAvail<SizeOf(LineRec) Then
     Begin
          Writeln;
          Writeln('SPELLVIEW V1.3');
          Writeln('A Text Viewer by Spellcaster');
          Writeln;
          Writeln('Not enough memory to read text... :(');
          Writeln;
          Halt(0);
     End;
     New(TheText);
     Tmp:=TheText;
     NLines:=0;
     While Not Eof(F) Do
     Begin
          Readln(F,Tmp^.Line);
          Tmp^.Fg:=Fg;
          Tmp^.Bg:=Bg;
          Tmp^.Next:=NIL;
          If Not Eof(F) Then
          Begin
               If MaxAvail<SizeOf(LineRec) Then
               Begin
                    Writeln('Sorry, not enough memory to load text... :(');
                    Writeln;
                    Halt(0);
               End;
               New(Tmp^.Next);
               Tmp:=Tmp^.Next;
          End;
          Inc(NLines);
     End;
     Close(F);
End;

Function Col(S:String):Byte;
Var A,C:Word;
Begin
     Col:=0;
     If S='0' Then
     Begin
          Col:=0;
          Exit;
     End;
     Val(S,C,A);
     If C<>0 Then
     Begin
          Col:=C;
          Exit;
     End;
     If S='BLACK' Then Col:=0;
     If S='BLUE' Then Col:=1;
     If S='GREEN' Then Col:=2;
     If S='CYAN' Then Col:=3;
     If S='RED' Then Col:=4;
     If S='MAGENTA' Then Col:=5;
     If S='BROWN' Then Col:=6;
     If S='LIGHTGRAY' Then Col:=7;
     If S='DARKGRAY' Then Col:=8;
     If S='LIGHTBLUE' Then Col:=9;
     If S='LIGHTGREEN' Then Col:=10;
     If S='LIGHTCYAN' Then Col:=11;
     If S='LIGHTRED' Then Col:=12;
     If S='LIGHTMAGENTA' Then Col:=13;
     If S='YELLOW' Then Col:=14;
     If S='WHITE' Then Col:=15;
End;

Procedure SetBgCol(Line,Color:Word);
Var Tmp:TextPoint;
    A:Word;
Begin
     Tmp:=TheText;
     If (Line=0) Or (Line>Nlines) Then Exit;
     For A:=1 To Line-1 Do Tmp:=Tmp^.Next;
     Tmp^.Bg:=Color;
End;

Procedure SetFgCol(Line,Color:Word);
Var Tmp:TextPoint;
    A:Word;
Begin
     Tmp:=TheText;
     If (Line=0) Or (Line>Nlines) Then Exit;
     For A:=1 To Line-1 Do Tmp:=Tmp^.Next;
     Tmp^.Fg:=Color;
End;

Procedure ReadPref(Name:String);
Var A,Cl:Word;
    R,G,B,C:Word;
    Ch:Char;
    F:Text;
    Cmd:String;
    Parsed:ParsedType;
    Relative:Integer;
Begin
     Relative:=0;
     A:=Find(Name,'.');
     Name:=Left(Name,A);
     Name:=Name+'swd';
     If Exist(Name)=False Then Exit;
     Assign(F,Name);
     Reset(F);
     While Not Eof(F) Do
     Begin
          Readln(F,Cmd);
          For A:=1 To MaxParam Do Parsed[A]:='';
          Parse(Cmd,Parsed);
          For A:=1 To MaxParam Do Parsed[A]:=Upper(Parsed[A]);
          If Parsed[1]='BG' Then
          Begin
               Cl:=Col(Parsed[2]);
               A:=3;
               While Parsed[A]<>'' Do
               Begin
                    Val(Parsed[A],B,C);
                    B:=Relative+B;
                    If B<>0 Then SetBgCol(B,Cl);
                    Inc(A);
               End;
          End;
          If Parsed[1]='RELATIVE' Then Val(Parsed[2],Relative,C);
          If Parsed[1]='RANGEBG' Then
          Begin
               Cl:=Col(Parsed[2]);
               Val(Parsed[3],R,C);
               R:=Relative+R;
               Val(Parsed[4],G,C);
               G:=Relative+G;
               For A:=R To G Do SetBgCol(A,Cl);
          End;
          If Parsed[1]='FG' Then
          Begin
               Cl:=Col(Parsed[2]);
               A:=3;
               If Parsed[3]='BLINK' Then
               Begin
                    Cl:=Cl+Blink;
                    A:=4;
               End;
               While Parsed[A]<>'' Do
               Begin
                    Val(Parsed[A],B,C);
                    B:=Relative+B;
                    If B<>0 Then SetFgCol(B,Cl);
                    Inc(A);
               End;
          End;
          If Parsed[1]='RANGEFG' Then
          Begin
               Cl:=Col(Parsed[2]);
               Val(Parsed[3],R,C);
               Val(Parsed[4],G,C);
               R:=Relative+R;
               G:=Relative+G;
               For A:=R To G Do SetFgCol(A,Cl);
          End;
          If Parsed[1]='TITLE' Then
          Begin
               TitleFg:=Col(Parsed[2]);
               TitleBg:=Col(Parsed[3]);
               A:=4;
               TitleString:='';
               While Parsed[A]<>'' Do
               Begin
                    TitleString:=TitleString+Parsed[A]+' ';
                    Inc(A);
               End;
          End;
          If Parsed[1]='NOTITLE' Then
          Begin
               TitleFg:=0;
               TitleBg:=0;
               TitleString:='';
          End;
          If Parsed[1]='RGB' Then
          Begin
               Cl:=Col(Parsed[2]);
               Val(Parsed[3],R,C);
               Val(Parsed[4],G,C);
               Val(Parsed[5],B,C);
               SetColor(Cl,R,G,B);
          End;
          If Parsed[1]='PARTIAL' Then
          Begin
               If PNum<=NPartials Then
               Begin
                    R:=Col(Parsed[2]);
                    G:=Col(Parsed[3]);
                    Cl:=R*16+G;
                    Partials[PNum].Color:=Cl;
                    Val(Parsed[4],A,C);
                    B:=Relative+B;
                    Partials[PNum].Line:=A;
                    Val(Parsed[5],A,C);
                    Partials[PNum].X1:=A;
                    Val(Parsed[6],A,C);
                    Partials[PNum].X2:=A;
                    Inc(PNum);
               End;
          End;
          If Parsed[1]='TITLEPCX' Then
          Begin
               If Exist(Parsed[2]) Then
               Begin
                    InitGraph;
                    For A:=0 To 255 Do
                    Begin
                         PCXPal[A].R:=0;
                         PCXPal[A].G:=0;
                         PCXPal[A].B:=0;
                    End;
                    SetPalette(PCXPal);
                    LoadPCX(Parsed[2],VGA);
                    Fade(PCXPal);
                    Ch:=Readkey;
                    For A:=0 To 255 Do
                    Begin
                         PCXPal[A].R:=0;
                         PCXPal[A].G:=0;
                         PCXPal[A].B:=0;
                    End;
                    Fade(PCXPal);
                    CloseGraph;
               End;
          End;
     End;
     Close(F);
End;

Procedure ReadPrePref(Name:String);
Var A,Cl:Byte;
    R,G,B,C:Word;
    Ch:Char;
    F:Text;
    Cmd:String;
    Parsed:ParsedType;
Begin
     A:=Find(Name,'.');
     Name:=Left(Name,A);
     Name:=Name+'swd';
     If Exist(Name)=False Then Exit;
     Assign(F,Name);
     Reset(F);
     While Not Eof(F) Do
     Begin
          Readln(F,Cmd);
          For A:=1 To MaxParam Do Parsed[A]:='';
          Parse(Cmd,Parsed);
          For A:=1 To MaxParam Do Parsed[A]:=Upper(Parsed[A]);
          If Parsed[1]='BACKGROUND' Then Bg:=Col(Parsed[2]);
          If Parsed[1]='FOREGROUND' Then Fg:=Col(Parsed[2]);
     End;
     Close(F);
End;

Procedure DestroyText;
Var Tmp1,Tmp2:TextPoint;
Begin
     Tmp1:=TheText;
     While Tmp1^.Next<>NIL Do
     Begin
          Tmp2:=Tmp1;
          Tmp1:=Tmp1^.Next;
          Dispose(Tmp2);
     End;
End;

Function Spaces(N:Byte):String;
Var S:String;
    A:Byte;
Begin
     S:='';
     For A:=1 To N Do S:=S+' ';
     Spaces:=S;
End;

Procedure TypeTitle;
Begin
     GotoXY(1,1);
     TextColor(TitleFg);
     TextBackground(TitleBg);
     Writeln(Spaces(80));
     GotoXY(1,1);
     Writeln(TitleString);
End;

Procedure DisplayText;
Var Tmp:TextPoint;
    A:Word;
Begin
     Tmp:=TheText;
     For A:=1 To CurrentLine-1 Do Tmp:=Tmp^.Next;
     For A:=1 to 22 Do
     Begin
          GotoXY(1,A+1);
          MyWrite(CurrentLine+A-1,Tmp^.Bg,Tmp^.Fg,Tmp^.Line);
          Tmp:=Tmp^.Next;
     End;
End;

Procedure ClearTextArea;
Var A:Byte;
Begin
     TextBackground(Bg);
     ClrScr;
     TypeTitle;
End;

Procedure SetUpDefaults;
Var A:Word;
Begin
     Bg:=Black;
     Fg:=White;
     TitleFg:=Yellow;
     TitleBg:=Red;
     TitleString:=Filename;
     For A:=1 To NPartials Do
     Begin
          Partials[A].Color:=0;
          Partials[A].Line:=0;
          Partials[A].X1:=0;
          Partials[A].X2:=0;
     End;
     PNum:=1;
End;

Procedure ScrollDown;
Begin
     Move(Mem[47104:160],Mem[47104:320],3360);
     GotoXY(1,2);
     TextColor(Fg);
     TextBackground(Bg);
     Writeln(Spaces(80));
End;

Procedure ScrollUp;
Begin
     Move(Mem[47104:320],Mem[47104:160],3360);
     GotoXY(1,23);
     TextColor(Fg);
     TextBackground(Bg);
     Writeln(Spaces(80));
End;

Procedure DisplayCurrentLineTop;
Var Tmp:TextPoint;
    A:Word;
Begin
     Tmp:=TheText;
     For A:=1 To CurrentLine-1 Do Tmp:=Tmp^.Next;
     GotoXY(1,2);
     MyWrite(CurrentLine,Tmp^.Bg,Tmp^.Fg,Tmp^.Line);
End;

Procedure DisplayCurrentLineBottom;
Var Tmp:TextPoint;
    A:Word;
Begin
     Tmp:=TheText;
     For A:=1 To CurrentLine+20 Do Tmp:=Tmp^.Next;
     GotoXY(1,23);
     TextColor(Tmp^.Fg);
     TextBackground(Tmp^.Bg);
     MyWrite(CurrentLine+21,Tmp^.Bg,Tmp^.Fg,Tmp^.Line);
End;

Begin
     If ParamCount<>1 Then
     Begin
          Writeln;
          Writeln('SPELLVIEW V1.3');
          Writeln('A Text Viewer by Spellcaster');
          Writeln;
          Writeln('Usage:');
          Writeln('       SPLVIEW <filename>');
          Writeln;
          Halt(0);
     End;
     FileName:=ParamStr(1);
     If Not Exist(Filename) Then
     Begin
          Writeln;
          Writeln('SPELLVIEW V1.3');
          Writeln('A Text Viewer by Spellcaster');
          Writeln;
          Writeln('File not found... :(');
          Writeln;
          Halt(0);
     End;
     SetUpDefaults;
     ReadPrePref(Filename);
     ReadText(FileName);
     ReadPref(FileName);
     TextBackground(Bg);
     ClrScr;
     TypeTitle;
     CurrentLine:=1;
     DisplayText;
     Repeat
           C:=UpCase(ReadKey);
           If (C=Chr(0)) then
           Begin
                Repeat Until Keypressed;
                C:=Readkey;
                If (C=chr(72)) And (CurrentLine>1) Then
                Begin
                     Dec(CurrentLine);
                     ScrollDown;
                     DisplayCurrentLineTop;
                     C:=Chr(255);
                End;
                If (C=Chr(80)) And (CurrentLine<Nlines-21) Then
                Begin
                     Inc(CurrentLine);
                     ScrollUp;
                     DisplayCurrentLineBottom;
                     C:=Chr(255);
                End;
                If C=Chr(73) Then
                Begin
                     If CurrentLine>22 Then Dec(CurrentLine,22) Else
                       CurrentLine:=1;
                     ClearTextArea;
                     DisplayText;
                     C:=Chr(255);
                End;
                If C=Chr(81) Then
                Begin
                     If CurrentLine>=Integer(Nlines)-45 Then CurrentLine:=NLines-21 Else
                       Inc(CurrentLine,22);
                     ClearTextArea;
                     DisplayText;
                     C:=Chr(255);
                End;
                C:=Chr(255);
           End;
           If (C='L') Then
           Begin
                ClearTextArea;
                DisplayText;
                C:=Chr(255);
           End;
           If ((C='P') Or (C='-')) Then
           Begin
                If CurrentLine>22 Then Dec(CurrentLine,22) Else
                  CurrentLine:=1;
                ClearTextArea;
                DisplayText;
                C:=Chr(255);
           End;
           If ((C='N') Or (C=' ') Or (C='+')) Then
           Begin
                If CurrentLine>=Nlines-45 Then CurrentLine:=NLines-21 Else
                  Inc(CurrentLine,22);
                ClearTextArea;
                DisplayText;
                C:=Chr(255);
           End;
     Until (C='X') Or (C=Chr(27)) Or (C='Q');
     DestroyText;
     Closegraph;
End.

corner
© 1996-2008 CommunityHeaven LLC. All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
North American business development: Nicolai Wadstrom. Publisher: Lars Hagelin.