Page 1 of 1
Implementing Textbox
Posted: Mon Sep 22, 2008 6:44 pm
by dandymcgee
Before I being a quick note: I'm using C++, SDL, and Lua for this project.
I've already implemented a textbox into my project, and here's what the function looks like right now.
Code: Select all
int showtextbox(const char* text, int delay = 0)
{
//show text box with text
if( delay != 0 )
{
Time TextBox Initiated = SDL_GetTicks();
TextBoxTimerStarted = 1;
Time After Which To Close Textbox = delay;
}
return 0;
}
Now Main() checks the difference between the time at which the textbox was initiated and Now, closing the textbox if it is greater than or equal to delay.
This works fine for hard-coded function calls.
Calling showtextbox from lua:
Code: Select all
int luashowtextbox(lua_State *L)
{
//grab text and delay from lua stack
showtextbox( text, delay );
return 0;
}
The problem is subsequent calls to luashowtextbox() from the lua script. Either the last textbox overwrites all of the previous ones so quickly it makes them impossible to read, or only the first one shows up.
I can only think of two solutions to this problem: 1) somehow tell the lua script to sleep for the same amount of time as the textbox's delay (not sure if sleeping is possible in lua?) or 2) create a queue that will store a predetermined number of textbox calls, and display one after another until the queue is empty (the only way i would know how to do this is an array of structs).
Which, if either method would you choose, or how would you change my textbox method altogether?
Feel free to provide support as your time allows. Any feedback is greatly appreciated :P.
Re: Implementing Textbox
Posted: Mon Sep 22, 2008 6:51 pm
by MarauderIIC
Use a single textbox, alter the content. Switch through your content pages (linked list, array, whatever). Try using your frames as a timer if you want it timed. But you're definitely missing this: If a textbox call happens and your textbox is being drawn -- determined by some state flag (not onscreen, onscreen but not ready to close, onscreen and ready to close) -- and/or, possibly, specified number of frames haven't gone by yet, or time designation hasn't been reached, handle it however you want to handle it.
Re: Implementing Textbox
Posted: Mon Sep 22, 2008 7:25 pm
by dandymcgee
Thanks for the reply Marauder. I'll definately look into a better way of implementing this based on your ideas, but for now the temporary fix is a messy lua function:
Code: Select all
showtextbox("blah text", 2000)
sleep(2)
showtextbox("more blah", 2000)
function sleep ( delay )
counter = os.clock()
while (true) do
currentTime = os.difftime(os.clock(), counter)
if currentTime > delay then
break
end
end
return
end
*Sigh* sleeping always ruins all my fun... If I didn't have school I'd stay up all night fixing this hehe.
Re: Implementing Textbox
Posted: Mon Sep 22, 2008 10:04 pm
by Falco Girgis
Okay, I'm not exactly sure how exactly you would like to implement this, but I will say a few things:
dandymcgee wrote:Code: Select all
if( delay != 0 )
{
Time TextBox Initiated = SDL_GetTicks();
TextBoxTimerStarted = 1;
Time After Which To Close Textbox = delay;
}
dandymcgee wrote:Code: Select all
counter = os.clock()
while (true) do
currentTime = os.difftime(os.clock(), counter)
if currentTime > delay then
break
end
end
Both of the preceding segments completely halt the execution of anything other than that given loop for the period of time. I'm not sure if you are aware of this. It's fine if you quite literally want to make them wait that period of time no matter what, but I wanted to at least bring this to your attention.
If you wanted to make it so that you push A to speed up the textbox, or make it immediately jump to the next frame, you couldn't. You aren't going to be getting input while that textbox is up, because the execution will never leave your loop. This is why I really don't ever recommend using any sort of sleep() style functions for a game. If you wanted to make it so that you
were getting input, you'd have to write the function so that it is called every frame until the given time is met (that way it leaves when it's done drawing and updating for this frame and continues doing the rest of the game's logic).
Now on the subject of adding additional frames, the cleanest, best way to do this would be to push the new strings (character arrays) into a vector with every call. After the set amount of time has gone by, increment your index by 1 so that you're now showing the next frame and so on until your index is equal to the end of your vector.
I know this advice is kind of a far cry from what you were probably expecting. I'd recommend worrying about the vector first (so you can do multiple frames) before worrying about getting rid of the sleep()s for now. Post if you get stuck.
Re: Implementing Textbox
Posted: Tue Sep 23, 2008 9:11 am
by dandymcgee
I know this advice is kind of a far cry from what you were probably expecting.
Not at all, it's actually exactly the sort I was looking for. The Sleep() idea was meant to be 100% temporary, until I could decide on which better method to implement. Thanks for the feedback, I'll read up on vectors as soon as I get home from school today.
EDIT: After rereading your post I see why you recommended using a vector. The only reason I was thinking of an array of structs is because my original idea was to allow each call to specify it's own delay depending on the length of the text being displayed (or just user preference), and a vector can only store one type of variable. I suppose I could use two separate vectors, being sure to properly align the corresponding strings and ints. I think I might have a go at twin vectors.
Re: Implementing Textbox
Posted: Tue Sep 23, 2008 5:49 pm
by dandymcgee
Alright thanks so much for the input and motivation Marauder and Gyrovorbis. I've completely removed all Sleep() like functions except for a single SDL_Delay in the frame rate limiter function (I'm pretty sure such functionality is required here). Without limiting frame rate the game plays ungodly fast on the computers at school (dunno like 600 fps). Vectors are actually pretty awesome, much more convenient than arrays.
Thanks again for the fast replies,
-Dan
EDIT: Next Question. Is there a logical way to use a word wrap feature in my textbox? I could probably do something like split the string at every space, and add up the number of characters in each word while it's <= the width of the textbox (provided it's a fixed-width font), then starting writing on the next line... but there must be an easier way?
Re: Implementing Textbox
Posted: Wed Sep 24, 2008 9:13 am
by Falco Girgis
Unfortunately, not really. That's pretty much exactly what we're doing in our textbox and input prompts. XD
But congrats on removing the sleep()s, that was fast.
Re: Implementing Textbox
Posted: Wed Sep 24, 2008 1:48 pm
by MarauderIIC
If you don't use a fixed-width font, generally the capital M is the largest letter in the particular font. So if you limit a line to x number of M's, you're set. Also there's probably some way to get the width of the string in pixels, if you wanted to bother doing that, instead of a character limitation. But wrapping at the space that is "closest without going over" as Bob Barker said is probably simpler.
Re: Implementing Textbox
Posted: Wed Sep 24, 2008 5:02 pm
by dandymcgee
@Gyro - really the only sleep I had was in Lua for the textbox, and thanks to your comment that was quite easily fixed with vectors
. Although I realize one major flaw in my code at the moment is not limiting the maximum size of the message queue. If someone were to call it once with a very long delay, and follow up with many more calls while the first call was still being displayed, the queue would be endlessly filled up. But that's an easy fix.
@Marauder - Yeah, I'll probably go with however many "M"s will fit in the textbox, and wrap at the last space before the end.
Once again, thanks for the input guys.