(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 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