English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. AMOS

 
 
Thread Tools
Old 21 November 2014, 16:56   #1
rockersuke
Registered User
 
Join Date: Mar 2006
Location: Madrid / Spain
Age: 50
Posts: 253
Simple and ugly text wrapping routine

AmigaPD has just released a public demo of his DangerMouse choice-based text adventure and is asking for some feedback in order to finish it.

The job includes properly formatting the text for the description of almost 200 locations, which is a boring task! This is the routine I use in my never-ending AMOS text adventure WIP. It basically receives a text string and tries its best to do a right word-wrapping for a determined printing area asuming you're using an ordinary non-proportinal font.

The procedure receives the text to be printed in the variable X$, and uses a global variable called WIN_WIDTH which is asumed to contain the length in characters of a line of text in your printing space.

In my case, that space is a window with a defined border, and somehow the border interferes with the calculations, so I needed to set WIN_WIDTH to a couple of characters less than the theorical needed number. Other than that it works OK.

Of course, the routine is amateurish, unelegant, and less than perfect in every sense you could imagine. but it does the job and could save AmigaPD a lot of hours of tedious manual work he could invest in improving Dangermouse in other areas. Improvements will be very wellcome, anyway.

I've commented the callings to CHECK_WIN_SCROLL. In my WIP that routine counts the lines printed and, if needed, pauses the process with a "PRESS ANY KEY" message. Useful if there is a very long text and the player could miss part of it. As this is very unlikely to happen in Dangermouse I've just commented it to keep things simple.

This routine is also known to fail in the unlikely event that a single word is longer than the printing area (which at least happened to me once! )

Code:
'The procedure WIN_PRINT[]
'Receives the text to be printed and, hopefully,
'properly wrapped in the string X$.
'It asumes that a global variable called WIN_WIDTH contains
'the length in characters of a line of text in your printing area

Procedure WIN_PRINT[X$]
MYLABEL:
   If Len(X$)<WIN_WIDTH
      Print X$
      'CHECK_WIN_SCROLL 'Unlikely to be needed in this case
      Pop Proc
   End If 
   If Mid$(X$,WIN_WIDTH,1)=" "
      Print Left$(X$,WIN_WIDTH)
      'CHECK_WIN_SCROLL ' Same as above
      X$=Right$(X$,Len(X$)-(WIN_WIDTH))
      Goto MYLABEL
   End If 
   For X=WIN_WIDTH To 1 Step -1
      If Mid$(X$,X,1)=" "
         Print Left$(X$,X)
         'CHECK_WIN_SCROLL 'Same as above
         X$=Right$(X$,Len(X$)-(X))
         Goto MYLABEL
      End If 
   Next 
   Goto MYLABEL
End Proc
--
rockersuke is offline  
AdSense AdSense  
Old 21 November 2014, 17:50   #2
alkis
Registered User

 
Join Date: Dec 2010
Location: Athens/Greece
Age: 46
Posts: 365
I think you can omit the "if" statement just before the for loop, cause you for loop also includes that check
alkis is offline  
Old 21 November 2014, 19:26   #3
rockersuke
Registered User
 
Join Date: Mar 2006
Location: Madrid / Spain
Age: 50
Posts: 253
Quote:
Originally Posted by alkis View Post
I think you can omit the "if" statement just before the for loop, cause you for loop also includes that check
Thanks!
Yup! It was certainly redundant!

Minor changes added where commented:

Code:
'The procedure WIN_PRINT[]
'Receives the text to be printed and, hopefully,
'properly wrapped in the string X$.
'It asumes that a global variable called WIN_WIDTH contains
'the length in characters of a line of text in your printing area

Procedure WIN_PRINT[X$]
MYLABEL:
   If Len(X$)<=WIN_WIDTH  '"< " replaced by "<="
      Print X$
      'CHECK_WIN_SCROLL 'Unlikely to be needed in this case
      Pop Proc
   End If  
   For X=WIN_WIDTH To 1 Step -1
      If Mid$(X$,X,1)=" "
         Print Left$(X$,X-1) ' "X" replaced by "X-1"
         'CHECK_WIN_SCROLL 'Same as above
         X$=Right$(X$,Len(X$)-(X))
         Goto MYLABEL
      End If 
   Next 
   Goto MYLABEL
End Proc
rockersuke is offline  
Old 21 November 2014, 19:45   #4
alkis
Registered User

 
Join Date: Dec 2010
Location: Athens/Greece
Age: 46
Posts: 365
That last "Goto MYLABEL" bothers me.

You should never reach that point. (You data should/could guarantee that) BUT IF YOU DO reach it, you are in an infinite loop.

I'd go about it with something like:
Code:
Print Left$(X$,WIN_WIDTH)
X$=Right$(X$,Len(X$)-WIN_WIDTH)
Goto MYLABEL
I just noticed you mentioned in the first post
Quote:
This routine is also known to fail in the unlikely event that a single word is longer than the printing area (which at least happened to me once! )
The above should work as a 'fix'
alkis is offline  
Old 21 November 2014, 21:29   #5
rockersuke
Registered User
 
Join Date: Mar 2006
Location: Madrid / Spain
Age: 50
Posts: 253
Quote:
Originally Posted by alkis View Post
That last "Goto MYLABEL" bothers me.

You should never reach that point. (You data should/could guarantee that) BUT IF YOU DO reach it, you are in an infinite loop.

I'd go about it with something like:
Code:
Print Left$(X$,WIN_WIDTH)
X$=Right$(X$,Len(X$)-WIN_WIDTH)
Goto MYLABEL
I just noticed you mentioned in the first post

The above should work as a 'fix'

Right again!
That last GOTO was an unnoticed and totally useless surviving line from early attempts. As it never was reached under normal circumstances I forgot to remove it ^_^' (and under not so normal circumstances, as when a longer than WIN_WIDTH word popped up, it indeed caused infinite loops)
Thanks for catching that up!

So our routine now looks something like this:


Code:
'The procedure WIN_PRINT[]
'Receives the text to be printed and, hopefully,
'properly wrapped in the string X$.
'It asumes that a global variable called WIN_WIDTH contains
'the length in characters of a line of text in your printing area

Procedure WIN_PRINT[X$]
MYLABEL:
   If Len(X$)<=WIN_WIDTH
      Print X$
      Pop Proc
   End If 
   For X=WIN_WIDTH To 1 Step -1
      If Mid$(X$,X,1)=" "
         Print Left$(X$,X-1)
         X$=Right$(X$,Len(X$)-(X))
         Goto MYLABEL
      End If 
   Next 
End Proc
It still cannot handle longer than WIN_WIDTH words, but it won't crash the Amiga in an infinite loop, as before. In Dangermouse, WIN_WIDTH currently means 80 characters per line, so we can safely asume that problems will arise in very rare occasions.

(Still testing it with every posible situation that comes to mind in any case )

--
rockersuke is offline  
Old 21 November 2014, 22:09   #6
alkis
Registered User

 
Join Date: Dec 2010
Location: Athens/Greece
Age: 46
Posts: 365
Errr, if you leave the three lines I wrote after the "Next" line, it should handle longer than WIN_WIDTH words. Just saying...
alkis is offline  
Old 21 November 2014, 22:51   #7
rockersuke
Registered User
 
Join Date: Mar 2006
Location: Madrid / Spain
Age: 50
Posts: 253
Quote:
Originally Posted by alkis View Post
Errr, if you leave the three lines I wrote after the "Next" line, it should handle longer than WIN_WIDTH words. Just saying...
Aha! I totally missunderstood that! Yeah, It works like a charm!

Code:
Procedure WIN_PRINT[X$]
MYLABEL:
   If Len(X$)<=WIN_WIDTH
      Print X$
      Pop Proc
   End If 
   For X=WIN_WIDTH To 1 Step -1
      If Mid$(X$,X,1)=" "
         Print Left$(X$,X-1)
         X$=Right$(X$,Len(X$)-(X))
         Goto MYLABEL
      End If 
   Next
   Print Left$(X$,WIN_WIDTH)
   X$=Right$(X$,Len(X$)-WIN_WIDTH)
   Goto MYLABEL 
End Proc
(very minor glitch, if by any chance win_width coincides with the width in charcters of the screen -40 in lowres, 80 in hires-, AMOS might unilaterally decide to insert some ugly carriage return if the end of some of the print sentences coincides with the screen border. I can live with that anyway!)

And many thanks again. This not only could be of help to AmigaPD but is also improving my own stuff!

--
rockersuke is offline  
Old 21 November 2014, 23:31   #8
alkis
Registered User

 
Join Date: Dec 2010
Location: Athens/Greece
Age: 46
Posts: 365
Glad I could help

Now for the last glitch...I would try two things
a) You have three Print commands. Leave the first as it is and try ending the other two by semicolon ; (put that right at the end of each line) if that works most of the time, just change the <=WIN_WIDTH to <WIN_WIDTH on the first "if".
b) if solution a doesn't work, change all appearances of WIN_WIDTH to (WIN_WIDTH-1)
alkis is offline  
AdSense AdSense  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Huge and ugly status panels Codetapper Nostalgia & memories 63 15 November 2012 09:52
Searching for a simple Text Editor Morbane request.Apps 2 01 January 2012 02:05
APPLE IIe. Ugly. Damn ugly. Fred the Fop Retrogaming General Discussion 22 12 January 2005 23:07
Good games, with ugly covers Tolismlf Nostalgia & memories 25 29 December 2004 05:59

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 03:25.


Powered by vBulletin® Version 3.8.8 Beta 1
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Page generated in 0.31438 seconds with 14 queries