Turbo Pascal Text Adventure Primer cover: BEACON, the adventure the primer builds in Turbo Pascal 2.0, mid-game on the Tatung Einstein
← Back to Modules
module
12

A File Of Messages

Introduction

If the text cannot live in the program, it can live on the disc. The simplest file there is a text file: lines of characters, which you can write with Turbo's editor or any other. BEACON's whole world is in one, BEACON.TXT, on the primer's disc. This section reads a message out of it when the game needs it, and prints it properly.

BEACON.TXT

It is 71 lines and about 3,400 characters, laid out like this:

*ROOM Beach
5 3 4 2 0 0
You are on a strip of shingle at the foot of the cliffs. ...
*ROOM Cove
0 0 1 0 0 0
A small cove, choked with driftwood and weed. ...
...
*MSG 13 Dark stairs
It is too dark to climb any further.
...
*END

A line starting with * begins a new message: the rooms first, in order, then the other messages. Under a room is a line of six numbers, its exits, which S17 uses. The text itself is one paragraph to a line.

Finding Message N

A text file can only be read from the start, one line after another. Turbo will not Seek in one (Error 63: Textfiles are not allowed here). So to find message 14, Say goes back to the start with Reset, reads lines and counts the *s until it has passed fourteen, then prints lines until the next *. Lines that start with a digit, the exits, are skipped.

The cost is time. Every message means reading the file from the top. On the Einstein, finding the first message takes about 0.8 of a second, and the 27th, near the end, about 2 seconds, before a single word is printed.

Notice the test:

if (Line <> '') and
   not (Line[1] in ['0'..'9']) then

Turbo works out both sides of an and, so for an empty line Line[1] is still looked at. It is only the leftover byte after the length, and the first test makes the answer right whatever it holds.

Printing In Whole Words

Print a 209-character line with Writeln and it breaks wherever the 40th column falls, in the middle of a word:

An iron staircase winds up the inside of
 the tower. Your footsteps ring on the t
reads.

Wrap breaks it at spaces instead. While the text is longer than the screen, it looks at column 40 and walks back to the last space, prints up to there, and deletes what it printed. No line it prints is longer than 39 characters.

Wrap also treats a | as "start a new line here". BEACON.TXT has none, but S13's file will.

The Code

program FromFile;
type
  Str255 = string[255];
var
  T: Text;

procedure Wrap(S: Str255);
var
  P: Integer;
begin
  S := S + '|';
  while S <> '' do
  begin
    P := Pos('|', S);
    if P > 40 then
    begin
      P := 40;
      while S[P] <> ' ' do
        P := P - 1;
    end;
    Writeln(Copy(S, 1, P - 1));
    Delete(S, 1, P);
  end;
end;

procedure Say(N: Integer);
var
  Line: Str255;
  K: Integer;
begin
  Reset(T);
  K := 0;
  while (K < N) and not Eof(T) do
  begin
    Readln(T, Line);
    if Copy(Line, 1, 1) = '*' then
      K := K + 1;
  end;
  Readln(T, Line);
  while Copy(Line, 1, 1) <> '*' do
  begin
    if (Line <> '') and
       not (Line[1] in ['0'..'9']) then
      Wrap(Line);
    Readln(T, Line);
  end;
end;

begin
  Assign(T, 'BEACON.TXT');
  Writeln('Go');
  Say(1);
  Say(27);
  Say(14);
  Close(T);
end.

Starting from

A new work file FROMFILE, on the primer's disc.

What you should see

Go
You are on a strip of shingle at the
foot of the cliffs. Wreckage from your
boat rolls in the surf. A path climbs
north. The beach runs west to a cove
and south to a jetty, and a store shed
stands to the east.
The ship is close now. You can see her
lights rising and falling in the swell.
The keeper's log. The last entries
read: "Oct 12. Glass falling. Lamp
...

Watch the pause before each message: longest before the second.

Change One Thing

  • In Wrap, change both 40s to 30. What does the text look like?
  • Replace the if in Say with just Wrap(Line);. What appears above the beach's description?
  • Change Say(14) to Say(13). Which message is it?

Exercises

12.1 Print the name of every room: the rest of each line that starts *ROOM.

12.2 Count the lines and the characters in BEACON.TXT.

12.3 Find a message by its name instead of its number: make Say take a string and stop at the first * line that contains it. Say('Logbook') should print the keeper's log.

Worked solutions are in Appendix II.

When It Goes Wrong

SymptomCause
Error 63: Textfiles are not allowed hereSeek on a text file. Text files are read from the start.
Rows of numbers in the textThe exits lines are not being skipped.
I/O error 01BEACON.TXT is not on the disc in the drive.
Words split at the edge of the screenThe text went to Writeln, not Wrap.

Summary

A text file holds as much text as the disc will take and costs the program nothing to keep. The price is time: every message means reading from the start, up to two seconds for one near the end. Wrap prints any length of text in whole words, breaking at the last space before column 40.

Next

S13, Straight To The Message: a file you can jump about in.

Get the Newsletter

New guides, disk images and community finds, roughly once a quarter. No spam, we promise, this isn't Tatung's marketing department.
Your subscription could not be saved. Please try again.
Your subscription has been successful.

Newsletter

Subscribe to our newsletter and stay updated.

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.