Making custom message boxes

BlitzMax Forums/BlitzMax Programming/Making custom message boxes

I'm looking for some help or some ideas on how to impliment a scrollable messagebox into my game. My problem is making the text scroll and fit within the message box area. If you have done this in the past or could show me a good way to do it I would greatly appreciate it.


Perhaps this can explain better.


pseudo code....

message = "hello from me"
newmessage = ""
y = 0

***
search for next [space] in message
if there isnt one
word = message
message = ""
else
word = everything before space in message
remove word+[space] from message
endif

if fontwidth(newmessage+[space]+word) > xlimit
print newmessage at yth line
newmessage = word
add 1 line to y
else
add [space] + word to newmessage
endif

repeat *** until nothing in message


I think.

It's in BB but this might help.

I've done something like that some weeks ago, works like a charm using maxGUI, but that's not going to stop a potential graphics-mode version..

but first diner :P

So, exactly how should it work?

Since you're doing a game, I assume you're not using GUI I guess? But perhaps you do have the gui module for its events/eventhooks? (events so totally rock!)

Secondly, where does the text come from? From a string? From an incbin'ed textfile?

Sorry I have been at work. It will take a string parameter.

The string-format function is an easy one.. if you want me to make a displayer, I need to know whether or not I can use events (thus having MaxGUI)..

Unless I'm misunderstanding something about your approach CS_TBL, I don't know why you are concerned about MaxGUI. You don't need MaxGUI to utilize events or eventhooks in your code.

uhm.. ok, not sure, I didn't have any Max until MaxGUI was released... does the standard bmax have the full eventsystem? (minus the GUI events naturally)

Yup.

At least, I don't think MaxGUI added anything besides GUI events. I've got a basic event system set up in one of my programs now, and don't have MaxGUI (...yet).

I don't dare go into displayers as they're way too game-dependent, but the way I've solved the text-issue means you can use a typical 2d-mapviewer to display this text.

So, the only thing this does it put a string into a bank, wordwrapped. Note that tabs, newlines and such can be *stored* in a bank, but not *processed*. In these cases I recommend against them, just use spaces. ;P

SuperStrict
Type TSimpleformattedtext

	Rem
	
		TSimpleformattedtext
		
		by CS_TBL
		
		Formats a given string into a bank, with wordwrap.
		
	EndRem

	Field columns:Int
	Field rows:Int
	Field bank:TBank=CreateBank()
	
	Method Cleanup(s$ Var)
		s=Replace(s,Chr(10),"")
		s=Replace(s,Chr(13),"")
		s=Replace(s,Chr(9),"")
	End Method
	
	Method Convert:TBank(s$,col:Int=16,clean:Int=1)
		columns=Max(col,1)
		s:+" "	
		
		If clean Cleanup s' <- optional!
	
		Local word$
		Local wordlen:Int
		Local l:Int=Len(s)
		Local pointer:Int=0
		Local char$
		
		Local bankx:Int
		Local banky:Int
		
		Local adres:Int
		
		Local t:Int
		Local tt:Int
		
		
		ResizeBank bank,columns
		
		While pointer<l ' do all chars..
			
			char=Mid(s,pointer+1,1)
			
			If char<>" "
				word:+char
				pointer:+1
			Else
			
				If word<>"" ' word found!
					wordlen=Len(word)
					If wordlen<=columns
					
						If (bankx+wordlen)>columns ' word doesn't fit line anymore?
							' wrap
							
							For tt=bankx To columns-1
								PokeByte bank,tt+(banky*columns),32
							Next
							
							ResizeBank bank,BankSize(bank)+columns ' add new line
							bankx=0
							banky:+1
							
							' add word
							For t=0 To wordlen-1
								adres=bankx+(columns*banky)
								PokeByte bank,adres,Asc( Mid(word,t+1,1) )
								bankx:+1
							Next
							
							If bankx<columns-1
								PokeByte bank,bankx+(columns*banky),Asc(" ")
								bankx:+1							
							EndIf
							
						Else ' add word
						
							For t=0 To wordlen-1
								adres=bankx+(columns*banky)
								PokeByte bank,adres,Asc( Mid(word,t+1,1) )
								bankx:+1
							Next
							
							If bankx<columns-1
								PokeByte bank,bankx+(columns*banky),Asc(" ")
								bankx:+1							
							EndIf
							
						EndIf
					EndIf
				
				EndIf
				word=""
				pointer:+1
			EndIf
			rows=banky
		Wend
		
		If bankx<columns And bankx>0
			For tt=bankx To columns-1
				PokeByte bank,tt+(banky*columns),Asc(" ")
			Next
		EndIf
		If bankx=0'-1
			For tt=bankx To columns-1
				PokeByte bank,tt+(banky*columns),Asc(" ")
			Next
		EndIf
		
		rows=(BankSize(bank)/columns)
		
		Return bank
		
	End Method	

End Type


Local b:TSimpleformattedtext=New TSimpleformattedtext
b.Convert "Hi, let's parse some text hmkay? If everything's well, this ~ntext will be wordwrapped"+..
" at a given length, And the result will go into a type with a rows field, a columns field and a bank"+..
". From all this, it's easy to make a simple map-displayer like the ones we use in games, only this time it"+..
" displays text! The size of the bank is .rows * .columns! Big words that don't fit, like these: "+..
"123456789abcdef12345678 are cancelled out",20

DebugLog b.rows
DebugLog b.columns

Showformattedtext b

b.Convert "We can use the same instance for more text!"

Showformattedtext b


End


' here's how to read out this text of ours.., transform it into your own typical 2D-mapdisplayer for scrolling/showing..
Function Showformattedtext(sft:TSimpleformattedtext)
	Local x:Int,y:Int
	Local s$=Chr(10)+Chr(10)
	For y=0 To sft.rows-1
		For x=0 To sft.columns-1
			s:+Chr(  PeekByte(sft.bank,x+y*sft.columns) )
		Next
		s:+Chr(10)
	Next
	DebugLog s
End Function


Hey, that's really cool thanks! I think I can work with this.