(This is the "Dungeon Designs" column from the September 1994 issue of the Eamon Adventurer's Guild newsletter. Copyright 1994 Eamon Adventurer's Guild, 7625 Hawkhaven Dr., Clemmons, NC 27012-9408.  You may reproduce this freely as long as this credit remains attached to the article.)


Multi-Column Text Formatter

by Frank Kunze

(Ed. note: I was so impressed by the text in Franks Eamon "Adventure in Interzone" that I asked him to write it up for us.)

The following is a quick and efficient way to print text without wrap-around in any column width.  It can be easily integrated into the basic 7.1 MAIN PGM.

The text must be contained in the string variable A$ and the column width must be specified in the variable CP before use (this is normally automatically set at program startup). When you want to print your text, simply use the statement "GOSUB 11".

11  GOSUB 28
  : GOTO 16
14  IF LEFT$ (A$,1) = " " THEN
     A$ = MID$ (A$,2)
  : GOTO 14
16  IF LEN (A$) < = CP -1 THEN
     PRINT A$
  : GOSUB 52
  : GOTO 29
17  FOR K = CP - 1 TO 1 STEP - 1
  : IF MID$ (A$,K,1) = " " THEN
     PRINT LEFT$ (A$,K - 1)
  : A$ = RIGHT$ (A$,LEN(A$) - K)
  : GOSUB 52
  : GOTO 14
18  NEXT
  : PRINT "STRING TOO LONG
     ERROR"
  : STOP
28  F1 = PEEK (111) + PEEK (112)
     * 256
  : RETURN
29  IF PEEK (111) + PEEK (112) *
     256 < F1 THEN POKE 111,F1
     - INT (F1 / 256) * 256
  : POKE 112, INT (F1 / 256)
30  RETURN
45  GOSUB 28
  : F2 = F1
  : PRINT D$"READ"ED$",R"R
  : INPUT A$
  : PRINT D$
  : GOSUB 51
  : GOSUB 11
  : F1 = F2
  : GOSUB 29

(Delete the old Line 50.)

Explanation:

Line 14 stops any problems which would be caused by double spacing between sentences.

Line 16 checks to see if A$ is equal to or less than the column width set.  If so, it prints it, increments the line counter, and exits.

Line 17 starts a search for a space at CP - 1 characters and works backwards until it finds one.

Line 18 - If no space is found, then an error message is printed and the program halts.  This can only occur if there is a word longer than the column width.

Lines 28-29 circumvent string "garbage collection" by discarding A$ after use.

Line 45 reads in A$ from disk and calls the rest of this routine to parse and print it.

If you want to do something special to A$ such as convert it to all caps, put it in Line 11 after "GOSUB 28".

If you have any questions or need help integrating this routine into your program, write me with an exact description of what you're trying to do:

     Frank Kunze
     7384 Gardner Hills  Apt. B
     Ft. Campbell, KY 42223-1024

________________________________________________

A Tour of the MAIN PGM 7.1

45-50 string print subroutine
45 note the top of free memory and reads in A$
     from disk
50 perform screen pause calculation for A$
     length; print A$; then recover the memory
     that A$ occupied

51-59 screen pause routine
51 print blank line, increment line counter by
     one
52 increment line counter by one 54 print blank
     line, increment line counter by 3
56 print blank line, increment line counter by 2
58 check for full screen; if full then
59 pause screen and zero line counter

91-96 command error messages
98 normal return point for most commands
99 return point for Inventory, failed commands

100-200 YOU SEE routine
110-117 check status of Artifact light source
120 check status of SPEED spell
122-123 recovery of expended spell ability
     S2 is present level, SA is full ability;
     if S2 is less than SA, then increase by 10%
125 check room light; skip YOU SEE if dark
130 print room name
135 print room desc. if "seen" flag is zero
140 check for monsters in room
145 print monster desc. if "seen" flag is aero
150 print single-monster name
154 print multiple-monster name
155 print blank line if desc. was printed
160 check for artifacts in room
165 print artifact desc. if "seen" flag is zero
170 print artifact name
190 print personal-weapon name if in room

200-290 Command parser
210 ask for "YOUR COMMAND?"
220 strip any leading spaces
230 use last command if <RETURN> was input
240 find end of first word of command
250 assign command verb (V$) and object (S$)
260 strip leading spaces off object
270 check for verb match to direction command
     (N,S,E,W,U,D)
272 if not direction command, check for match
     to rest of command list
275 if no match to any command, print command
     list and go back to 210
290 if match was found, jump to command routine

300-495 PICK FOE routine
305 print blank line
310 foes present? if not, exit routine
320 find monsters present in room
330 if monster is neutral, look for another
333 if single-monster, check courage level,
     determine if monster flees room
334 if monster did not flee, proceed to combat
335 check multiple-monster courage level,
     determine if monster(s) flee room
336 multiple-monster member(s) flee room
340 if multiple-monster has more than 8 members,
     limit combat rounds to 8 (on theory that a
     max of 8 monsters could get in a hit in
     one round) (BAD LINE???)
350 assign monster as attacker (OF); determine
     if attacker is friend; if so, go to 400
360 determine if attacker is only enemy in room
370-380 find friendly defender (DF) for attack;
     go to 480
400-430 find enemy defender for attack
480 proceed to DO BATTLE routine

500-900 for every-round special programming

3000-3390 MOVE routine
3010 abort move if enemy present
3020 assign direction (D)
3030 get exit data; if door then proceed to
     GATE/DOOR routine
3040 if valid room connection then proceed to GO
     routine
3060 check for exit to Main Hall
3390 abort move if invalid exit

3400-3430 GATE/DOOR routine
3410 find room on other side of door; if door is
     not locked nor hidden then get room
     connection and return to MOVE routine
3420 if door still hidden then abort move
3430 if door locked then abort move
3500-3590 GO routine
3530 move to next room, check monster status
3540 get new room desc. and exits
3550 find number of exits from room
3560 get room natural light status and determine
     if room is dark
3590 exit to YOU SEE routine

3600-3670 ENEMY? subroutine
3610 initialize group monster strengths and hits
3620 check each monster...
3630 determine if monsters from last room follow
     and bring them in new room
3640 if monster did not follow then next monster
3650 determine monster friendliness
3660 add monster strength and hits into group
     totals and exit to calling routine

4000-4240 GET routine
4010 check for object of command S$; if "ALL"
     then go to ALL routine
4020 check to see if S$ is in room; if not, go
     to error message at 94
4030 if object weight is greater than 900 then
     abort with DON'T BE ABSURD message
4040 if object weight plus inventory would
     exceed ten times player's strength then
     abort with TOO HEAVY message
4050 if object is "prisoner" artifact than abort
     with TIED DOWN message
4140 get object; increase weight carried by
     player (WT); if player has no ready weapon
     and object is a weapon, proceed to READY
     routine
4150 exit to PICK FOE routine

4200-4240 GET ALL routine
4200 find all artifacts in room
4210 print name of artifact; if prisoner, skip
4215 if weight is over 900 then skip
4220 if weight would add too much to player's
     carried WT then skip
4230 get artifact and print TAKEN
4240 increment line counter and check for screen
     pause

4600-4780 SYNONYMS subroutine
4610 find length of object name
4620-4674 space for synonym data
4675 exit to calling routine
4680 compare synonym name to object name; if
     match, assign object name to artifact
     defined by synonym data

4700-4780 MONSTER SEARCH subroutine
4705 assign search locations to room and player
     inventory
4710 check for match between object name and
     monster names
4715 if no name match then return with F = 0
4720 if name match found then check to see if
     monster is in room or in player inventory
4750 increment F; if first match found then
     assign monster number (M) to match
4760 if name is an exact match then assign (M)
     and exit to calling routine
4770 check for additional matches
4780 exit to calling routine

4800-4870 ARTIFACT SEARCH subroutine
4801 assign all search locations to player
     inventory only; proceed to search (DROP)
4804 assign search locations to player
     inventory, room, and artifacts "embedded"
     in room (EXAMINE)
4805 assign search locations to room, artifacts
     "embedded" in room, and third location
     defined by calling routine (GET, REMOVE)
4810 check for synonyms; perform search for
     match to object name; abort if no match
4820-4830 determine if any artifact that is in
     one of defined locations matches name; if
     perfect match, assign artifact number (A)
     to match and exit subroutine
4850 search for additional matches; if found,
     ask WHICH DO YOU WANT? and exit to YOU SEE
4870 exit to calling routine

4900-4920 GET S$ subroutine
4905 if room is dark then abort to YOU SEE
4910 if no object defined by S$ then as for one
4920 exit to calling routine

5000-5150 DROP routine
5010 check for object of command S$; if "ALL"
     then go to DROP ALL routine
5030 check to see if player is carrying object;
     if not, go to print error at 91
5040 deduct object's weight from weight carried
     (WT); print "DROPPED" message and check
     for screen pause
5042 if dropped object was current carried light
     source, extinguish light and switch to
     room's natural light
5050 if dropping object increases weight carried
     beyond player's carrying capacity
     (eg: dropped object was something like a
     cart or wheelbarrow) then proceed to DROP
     ALL and dump entire inventory on ground
5060 if dropped object was ready weapon then
     change Ready Weapon status to unarmed
5070 exit to PICK FOE routine

5100-5150 DROP ALL routine
5100 search artifacts for those carried by
     player
5110 drop each to ground as it is found; print
     DROPPED and check for screen pause
5150 set weight carried to zero, mark player as
     unarmed

6000-6060 EXAMINE command
6010 check for object of command S$; find out if
     named object is an artifact present in the
     room or being carried; if not found then
     proceed to search for monster
6020 if object is an "embedded" artifact then
     change location to room to make visible
6032 if object is one of player's personal
     weapon then name it
6033 if object is hidden door then make door
     visible
6034 if object is drinkable then print number
     of swallows left; check for screen pause
6035 print artifact description; set "seen" flag
     to "seen"; exit to PICK FOE routine
6040 search monsters for match to object; if no
     match then named object is not an artifact
     nor a monster, so print YOU SEE NOTHING
     SPECIAL and exit
6050 print monster description; if group monster
     and uninjured then print THEY ARE IN
     PERFECT HEALTH; exit to PICK FOE routine
6060 print monster's health status; exit to
     PICK FOE routine

6500-6510 LOOK routine
6510 set room "seen" flag to zero (this will
     cause room desc. to be printed at next
     pass through YOU SEE routine); exit to
     PICK FOE routine

