[Back to SCREEN SWAG index]  [Back to Main SWAG index]  [Original]

{
{TEXT EFFECTS, otherwise known as TextFX, is a pascal unit, created in
{TURBO Pascal 4.0".  It's sole purpose is to add a little flair to text
{based pascal programs.  This is done via binary files, that can be made
{in pascal and saved to disk using the included SaveScreen procedure, or
{made in any text image design program that will save its data as a binary
{file, such as "TheDraw", by TheSoft Programming Services.
{
{
{
{This is a first release, and as such, is not certified to be error free
{and I shall take no responsibility for ANY damages caused by using this
{Unit.
{
{To all programmers:  This unit isn't all that fancy (YET) but, if it
{helps you to make a living, I'd appreciate it if you'd help me make my
{own.  Ideally this would be entail recognition in your final product, as
{well as a financial contribution that reflects how useful/profitable you
{found the unit to be.  Also acceptible would be one or the other as both
{are of great help.  ThanX.
{
{I am always looking for more text effects for upcoming versions, so if
{you think of something, drop me a line.  Don't forget to include your
{name or I won't be able to give you any credit for it.  Please note that
{credit will be given only once for each effect.  If two messages com in
{detailing the same effect, credit will go to the first I come across.
{
{Here's my address:
{
{   Tony Peardon
{   Comp 1, RR 2, Erb Site,
{   Quesnel BC, Canada.
{   V2J-3H6
{
{Or I can be reached in the Pascal Programmers Echo....
{
{
{ ...And so, without further adu... I present TextFX!!
}
UNIT TextFX;  {Version 1.00 - By Tony Peardon         (Mar.14`95) }

INTERFACE

USES Dos, Crt;

TYPE
  PageType = ARRAY[1..25,1..80] OF RECORD
                                    Char: char;
                                    Attr: byte;
                                  END;

  FlipMethod = (DragLeft,DragRight,DragUp,DragDown,
                PushLeft,PushRight,PushUp,PushDown,
                PullLeft,PullRight,PullUp,PullDown,
                ScanLeft,ScanRight,ScanUp,ScanDown,

                DragHSides,DragHCenter,DragVSides,DragVCenter,
                PushHSides,PushHCenter,PushVSides,PushVCenter,
                PullHSides,PullHCenter,PullVSides,PullVCenter,
                ScanHSides,ScanHCenter,ScanVSides,ScanVCenter,

                PushRand,PullRand,ScanRand,DragRand,AllRand);

VAR
  Monitor: PageType absolute $B800:$0000; {Change to $B000:$0000 FOR MONO}


PROCEDURE SaveScreen(VAR Screen: PageType; FileName: String);
PROCEDURE LoadScreen(VAR Screen: PageType; FileName: String);
PROCEDURE MoveBlock(VAR Source, Destin: PageType;
                     X1,Y1,X2,Y2,DX,DY: integer);
PROCEDURE PageFlip(ToPage: PageType; Method: FlipMethod);




IMPLEMENTATION

PROCEDURE ErrorCheck;
{
{ Echos an error message if any errors are encountered
{ during I/O operations.
}
VAR
  Key: Char;
BEGIN
  IF DosError = 0 THEN exit;
  gotoxy(1,25);
  write('ERROR #',DosError,': ');
  CASE DosError OF
    2:write('File Not Found.');
    3:write('Path Not Found.');
    5:write('Access Denied.');
    6:write('Invalid Handle.');
    8:write('Not Enough Memory.');
    10:write('Invalid Environment.');
    11:write('Invalid Format.');
    18:write('File Not Found.');
  END;
  IF NOT DosError IN [2,3,5,6,8,10,11,18] THEN write('Unknown Error.');
  write(#7,#7,#7);
  delay(500);
  write(' --- Press Any Key ---');
  WHILE KeyPressed DO Key := ReadKey;
  REPEAT UNTIL KeyPressed;
  halt;
END;

PROCEDURE SaveScreen(VAR Screen: PageType; FileName: String);
{
{ Saves an 80/25 screen to a binary file
}

VAR
  Saving: File;
  Search:SearchRec;
BEGIN
  assign(Saving,FileName);
{$I-}
  rewrite(Saving,4000); ErrorCheck;
  blockwrite(Saving,Screen,1);  ErrorCheck;
  close(Saving);  ErrorCheck;
{$I+}
END;


PROCEDURE LoadScreen(VAR Screen: PageType; FileName: String);
{
{ Loads an 80/25 screen from a file
}
VAR
  Loading: File;
  Search: SearchRec;
BEGIN
  assign(Loading,FileName);
{$I-}
  findfirst(FileName,AnyFile,Search);  ErrorCheck;
  reset(Loading,4000); ErrorCheck;
  blockread(Loading,Screen,1);  ErrorCheck;
  close(Loading);  ErrorCheck;
{$I+}
END;

PROCEDURE MoveBlock(VAR Source, Destin: PageType;
                    X1,Y1,X2,Y2,DX,DY: integer);
{
{  Moves a block of binary information from one page to another.
{  Note that DX and DY refer to the top left point on the desti-
{  nation page where the defined block will begin to be displayed.
}
VAR
  YRange, YCount, XSize: integer;
  Temp: PageType;
BEGIN
  YRange := Y2 - Y1;
  XSize := (X2 - X1+1)*2;
  FOR YCount := 0 TO YRange DO BEGIN
    move(Source[Y1+YCount,X1],Temp[DY+YCount,DX],XSize);
  END;
  Destin := Temp;
END;


PROCEDURE PageFlip(ToPage: PageType; Method: FlipMethod);
{
{  A collection of fancy page flipping routines following one of
{  four basic styles.
{
{   PUSH: Pushes 'ToPage' over the current page.
{   PULL: Pulls the current page revealing 'ToPage' beneith.
{   SCAN: Replaces Each Position.
{   DRAG: Pulls the current page and drags 'To Page' behind it.
}
VAR
  C1,C2: integer;  {Counters}
BEGIN
  IF Method = AllRand THEN CASE random(4) OF
    0: Method := ScanRand;
    1: Method := PushRand;
    2: Method := PullRand;
    3: Method := DragRand;
  END;
  IF Method IN[ScanRand,PushRand,PullRand,DragRand] THEN BEGIN
    IF Method = ScanRand THEN BEGIN
      CASE random(8) OF
        0: Method := ScanUp;
        1: Method := ScanDown;
        2: Method := ScanLeft;
        3: Method := ScanRight;
        4: Method := ScanHCenter;
        5: Method := ScanHSides;
        6: Method := ScanVCenter;
        7: Method := ScanVSides;
      END;
    END;
    IF Method = PullRand THEN BEGIN
      CASE random(8) OF
        0: Method := PullUp;
        1: Method := PullDown;
        2: Method := PullLeft;
        3: Method := PullRight;
        4: Method := PullHCenter;
        5: Method := PullHSides;
        6: Method := PullVCenter;
        7: Method := PullVSides;
      END;
    END;
    IF Method = PushRand THEN BEGIN
      CASE random(8) OF
        0: Method := PushUp;
        1: Method := PushDown;
        2: Method := PushLeft;
        3: Method := PushRight;
        4: Method := PushHCenter;
        5: Method := PushHSides;
        6: Method := PushVCenter;
        7: Method := PushVSides;
      END;
    END;
    IF Method = DragRand THEN BEGIN
      CASE random(8) OF
        0: Method := DragUp;
        1: Method := DragDown;
        2: Method := DragLeft;
        3: Method := DragRight;
        4: Method := DragHCenter;
        5: Method := DragHSides;
        6: Method := DragVCenter;
        7: Method := DragVSides;
      END;
    END;
  END;
  CASE Method OF

    DragLeft:     BEGIN
                    FOR C1 := 1 TO 80 DO BEGIN
                      moveblock(Monitor,Monitor,2,1,80,25,1,1);
                      moveblock(ToPage,Monitor,C1,1,C1,25,80,1);
                    END;
                  END;
    DragRight:    BEGIN
                    FOR C1 := 80 DOWNTO 1 DO BEGIN
                      moveblock(Monitor,Monitor,1,1,79,25,2,1);
                      moveblock(ToPage,Monitor,C1,1,C1,25,1,1);
                    END;
                  END;
    DragUp:       BEGIN
                    FOR C1 := 1 TO 25 DO BEGIN
                      moveblock(Monitor,Monitor,1,2,80,25,1,1);
                      moveblock(ToPage,Monitor,1,C1,80,C1,1,25);
                    END;
                  END;
    DragDown:     BEGIN
                    FOR C1 := 25 DOWNTO 1 DO BEGIN
                      moveblock(Monitor,Monitor,1,1,80,24,1,2);
                      moveblock(ToPage,Monitor,1,C1,80,C1,1,1);
                    END;
                  END;
    DragHSides:   BEGIN
                    C1 := 0;
                    C2 := 81;
                    REPEAT
                      C1 := C1 + 1;
                      C2 := C2 - 1;
                      moveblock(Monitor,Monitor,2,1,40,25,1,1);
                      moveblock(Monitor,Monitor,41,1,79,25,42,1);
                      moveblock(ToPage,Monitor,C1,1,C1,25,40,1);
                      moveblock(ToPage,Monitor,C2,1,C2,25,41,1);
                    UNTIL C1 = 40;
                  END;
    DragHCenter:  BEGIN
                    C1 := 41;
                    C2 := 40;
                    REPEAT
                      C1 := C1 - 1;
                      C2 := C2 + 1;
                      moveblock(Monitor,Monitor,1,1,40,25,2,1);
                      moveblock(Monitor,Monitor,42,1,80,25,41,1);
                      moveblock(ToPage,Monitor,C1,1,C1,25,1,1);
                      moveblock(ToPage,Monitor,C2,1,C2,25,80,1);
                    UNTIL C2 = 80;
                  END;
    DragVSides:   BEGIN
                  {Not advailable till the next release}
                  END;
    DragVCenter:  BEGIN
                  {Not advailable till the next release}
                  END;


    PushLeft:     BEGIN
                    FOR C1 := 1 TO 80 DO BEGIN
                      moveblock(ToPage,Monitor,1,1,C1,25,81-C1,1);
                    END;
                  END;
    PushRight:    BEGIN
                    FOR C1 := 80 DOWNTO 1 DO BEGIN
                      moveblock(ToPage,Monitor,C1,1,80,25,1,1);
                    END;
                  END;
    PushUp:       BEGIN
                    FOR C1 := 1 TO 25 DO BEGIN
                      moveblock(ToPage,Monitor,1,1,80,C1,1,26-C1);
                    END;
                  END;
    PushDown:     BEGIN
                    FOR C1 := 25 DOWNTO 1 DO BEGIN
                      moveblock(ToPage,Monitor,1,C1,80,25,1,1);
                    END;
                  END;
    PushHSides:   BEGIN
                    C1 := 0;
                    C2 := 81;
                    REPEAT
                      C1 := C1 + 1;
                      C2 := C2 - 1;
                      moveblock(ToPage,Monitor,1,1,C1,25,41-C1,1);
                      moveblock(ToPage,Monitor,C2,1,80,25,41,1);
                    UNTIL C1 = 40;
                  END;
    PushHCenter:  BEGIN
                    C1 := 41;
                    C2 := 40;
                    REPEAT
                      C1 := C1 - 1;
                      C2 := C2 + 1;
                      moveblock(ToPage,Monitor,C1,1,40,25,1,1);
                      moveblock(ToPage,Monitor,41,1,C2,25,80-(C2-41),1);
                    UNTIL C1 = 1;
                  END;
    PushVSides:   BEGIN
                  {Not advailable till the next release}
                  END;
    PushVCenter:  BEGIN
                  {Not advailable till the next release}
                  END;
    ScanLeft:     BEGIN
                    FOR C1 := 80 DOWNTO 1 DO BEGIN
                      moveblock(ToPage,Monitor,C1,1,C1,25,C1,1);
                    END;
                  END;
    ScanRight:    BEGIN
                    FOR C1 := 1 TO 80 DO BEGIN
                      moveblock(ToPage,Monitor,C1,1,C1,25,C1,1);
                    END;
                  END;
    ScanUp:       BEGIN
                    FOR C1 := 25 DOWNTO 1 DO BEGIN
                      moveblock(ToPage,Monitor,1,C1,80,C1,1,C1);
                    END;
                  END;
    ScanDown:     BEGIN
                    FOR C1 := 1 TO 25 DO BEGIN
                      moveblock(ToPage,Monitor,1,C1,80,C1,1,C1);
                    END;
                  END;
    ScanHSides:   BEGIN
                    C1 := 0;
                    C2 := 81;
                    REPEAT
                      C1 := C1 + 1;
                      C2 := C2 - 1;
                      moveblock(ToPage,Monitor,C1,1,C1,25,C1,1);
                      moveblock(ToPage,Monitor,C2,1,C2,25,C2,1);
                    UNTIL C1 = 40;
                  END;
    ScanHCenter:  BEGIN
                    C1 := 41;
                    C2 := 40;
                    REPEAT
                      C1 := C1 - 1;
                      C2 := C2 + 1;
                      moveblock(ToPage,Monitor,C1,1,C1,25,C1,1);
                      moveblock(ToPage,Monitor,C2,1,C2,25,C2,1);
                    UNTIL C2 = 80;
                  END;
    ScanVSides:   BEGIN
                  {Not advailable till the next release}
                  END;
    ScanVCenter:  BEGIN
                  {Not advailable till the next release}
                  END;


    PullLeft:     BEGIN
                    FOR C1 := 80 DOWNTO 1 DO BEGIN
                      moveblock(Monitor,Monitor,2,1,C1,25,1,1);
                      moveblock(ToPage,Monitor,C1,1,C1,25,C1,1);
                    END;
                  END;
    PullRight:    BEGIN
                    FOR C1 := 1 TO 80 DO BEGIN
                      moveblock(Monitor,Monitor,C1,1,79,25,C1+1,1);
                      moveblock(ToPage,Monitor,C1,1,C1,25,C1,1);
                    END;
                  END;
    PullUp:       BEGIN
                    FOR C1 := 25 DOWNTO 1 DO BEGIN
                      moveblock(Monitor,Monitor,1,2,80,C1,1,1);
                      moveblock(ToPage,Monitor,1,C1,80,C1,1,C1);
                    END;
                  END;
    PullDown:     BEGIN
                    FOR C1 := 1 TO 25 DO BEGIN
                      moveblock(Monitor,Monitor,1,C1,80,24,1,C1+1);
                      moveblock(ToPage,Monitor,1,C1,80,C1,1,C1);
                    END;
                  END;
    PullHSides:   BEGIN
                    C1 := 41;
                    C2 := 40;
                    REPEAT
                      C1 := C1 - 1;
                      C2 := C2 + 1;
                      moveblock(Monitor,Monitor,2,1,C1,25,1,1);
                      moveblock(Monitor,Monitor,C2,1,79,25,C2+1,1);
                      moveblock(ToPage,Monitor,C1,1,C2,25,C1,1);
                    UNTIL C1 = 1;
                  END;
    PullHCenter:  BEGIN
                    C1 := 0;
                    C2 := 81;
                    REPEAT
                      C1 := C1 + 1;
                      C2 := C2 - 1;
                      moveblock(Monitor,Monitor,C1,1,39,25,C1+1,1);
                      moveblock(Monitor,Monitor,42,1,C2,25,41,1);
                      moveblock(ToPage,Monitor,C1,1,C1,25,C1,1);
                      moveblock(ToPage,Monitor,C2,1,C2,25,C2,1);
                    UNTIL C1 = 40;
                  END;
    PullVSides:   BEGIN
                  {Not advailable till the next release}
                  END;
    PullVCenter:  BEGIN
                  {Not advailable till the next release}
                  END;

  END;
END;

BEGIN
END.

PROGRAM TestFx;
USES TextFX, Crt;
{ Compile this little program into an EXE and run it with two
{ command line parameters.  Both parameters should be the path
{ and name of two binary text screen files.  Such as those created
{ by the draw.
{
{ NOTE: Esc will end the Demonstration
}

VAR
  Page: ARRAY[0..2] OF PageType;
  Counter: integer;
  Key: char;

BEGIN
  Page[0] := Monitor;
  LoadScreen(Page[1],paramstr(1));
  LoadScreen(Page[2],paramstr(2));
  REPEAT
    WHILE KeyPressed DO Key := ReadKey;
    IF Counter = 1 THEN Counter := 2 ELSE Counter := 1;
    PageFlip(Page[Counter],AllRand);
  UNTIL Key = #27;
  PageFlip(Page[0],AllRand);
END.

[Back to SCREEN SWAG index]  [Back to Main SWAG index]  [Original]