Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / Text wrap / user input debacle..

Author
Message
Neco
18
Years of Service
User Offline
Joined: 13th Jul 2008
Location: Waterloo, Wisconsin USA
Posted: 28th Apr 2010 21:54 Edited at: 28th Apr 2010 21:57
Hi,

I'm really stuck trying to modify TDK's text wrapping example. I am kind of loathe to ask someone to comb through it (it is a bit of code) as I'm trying to make an honest effort to do it myself..

But I am unable to modify it to meet my goals.. (which are)

1. A main text "area" of the screen where the game prints information for the player.. This would be a few lines per room with the Location, Room Description, any objects in the room, any monsters in the room. Then Exits avialable, printing last.

2. And of course I need a text input area, that updates by character, from the Keyboard Buffer, clears the buffer when Return is struck, but ALSO clears what is in the box..

I almost got this to work with TDK's example.. but I can't get it to clear the box after hitting return. It will clear the buffer and the box will ONLY clear once you hit a key after clearing the buffer.


Here is a basic example of the look I am going for..
Quote: "
[A Rank Dungeon, North Corridor]
You notice a foul stench as you enter the room and the source
soon becomes apparent.Scanning your surroundings you notice an
old, decaying, corpse. It is dressed in the uniform of The King's Old Guard.
You also see: an oak door, a nest of spiders
Obvious Exits: South, East, Northwest
>
"


Basically how I've done this in the past is using the TextWrap module in Python - which I obviously don't know anything about other than how to use it... But literally this is what my print statements looked like..
(this is Python code)


It's not the whole picture, as these are excerpts from my Render function that includes a bunch of stuff for assembling the data necesarry.. But the idea is that all it takes is to call the function and pass a a variable into that function, a text string, to be wrapped if required..

Clearly there is a lot of data manipulation (in the function definition) going on in TDK's example, that is way over my head..

The second requirement is obviously, a text input area for the player, based on the ENTRY$() command. As I need to pull from the KB Buffer in real-time to prevent blocking the rest of the programs background processing. I'm OK with this area being a static placement at the bottom of the window, as long as is never encroached upon by the main windows output..

But I also don't mind a more traditional "console" style entry line, that starts at 0,0 and then scrolls down as data is pushed onto the display, (like the windows command prompt)..

Anything anyone can provide that might be helpful to get me in the right direction, would be great.. An example wrapping function that acts like a print statement for instance.. Or something based on TDK's example, but modified with comments showing what everything is doing.. Or even just someone (TDK or someone else) going back and commenting the function itself, as detailed as possible, explaining what every line is doing, and whats being affected, etc..


Finally.. here is the horribly mutilated (I'm sure) version of TDK's example code that I've been trying to work with.. Some parts have been taken out, others have been modified slightly, etc..

Basically, I'd like to have the long user input box update like a real input widget, in real time as keys are pressed.. be able to backspace for corrections.. Then once enter is hit, the data is sent to the parser and then the buffer will clear and the BOX ITSELF should clear. I'm not too worried about handling long strings that go beyond the box boundaries, but considerations for it are appreciated as well.



TDK
Retired Moderator
23
Years of Service
User Offline
Joined: 19th Nov 2002
Location: UK
Posted: 29th Apr 2010 00:01 Edited at: 29th Apr 2010 00:19
OK, let's see if I can help.

First of all, the function only works as an output window, so for input it can't help.

WindowNum is obviously the output window number so you can have multiple windows on the screen.

Quote: "1. A main text "area" of the screen where the game prints information for the player.. This would be a few lines per room with the Location, Room Description, any objects in the room, any monsters in the room. Then Exits avialable, printing last."


XPos, YPos, ScrollBoxWidth and ScrollBoxHeight allow you to define any part of the screen you want as the scrolling text box and the function uses those values to work out how much text will fit on a line.

What specific part of the function can't you figure out? If it's to clear the text box, although not ideal, you could try:



[Edit] Just read your comment in another thread. Are you trying to get whatever you type in at the bottom of the screen in my demo program to appear in one of the text boxes character by character as you type it - rather than after you have pressed Enter at the end of the line of text?

If the answer is yes the the Input command is obviously no use and you will need a function to accept input and the ScrollPrint() function modified to allow adding a single character (plus word-wrapping on the fly).

Doesn't sound too difficult... if that's what you are actually after.

TDK

Neco
18
Years of Service
User Offline
Joined: 13th Jul 2008
Location: Waterloo, Wisconsin USA
Posted: 29th Apr 2010 00:51
I understand how the basic stuff like the width and height and position work.. I'll try not to bounce all over the place, since I do have your attention

It's the function itself I was interested in learning more about? (if really necesarry) i.e the entire declaration.. What each line of code is manipulating, and whats being affected it..


However.. Yes I need to get rid of the input command.. And use ENTRY$() from the keyboard buffer.

If I am to use one of your scroll boxes, I'd need it to show up character by character, and then clear the buffer (deleting whats in the "input" designated box" so it appears empty and ready to accept new input.. Like a typical input textbox widget on a Win32 form might behave..

I'm sure I can work out where to insert the bit to toss it to the parser before it gets deleted, but if you wanted to advise on that it would be good.. (I'd assume after the Keypress detection for ENTER key, just assign EXTRY$() to a variable, THEN clear the buffer and then call my parser with the varible)

So.. if you would be so kind, and this doesn't sound like a lot I will try and draw a clear picture for you..

I need a "box" as your demo was intended. You simply pass a string variable of some sort to it and it'll print that out and word wrap to its bounds. If possible, maybe it could accept more than one variable? I am thinking to cover situations where I might use multiple PRINT commands to push a lot of "different" but related data onto the screen at once.. i.e Sending all that room data in one go... Perhaps an example of how that might be passed to your scrollbox ?

So that is the main game "window", if you will.. Anything the game does to show data to the player (moving to a room, manipulating inventory, scratching your head, monsters walks in / leaves / attacks, etc) will be passed to that box.. Hopefully with as little repetition as possible.

Then a second box ideally would be below it..
It would be the same width, but one row of text high, and would NOT scroll vertically, but can it be made to scroll horizontally? Like the discussion in the other thread.. If that makes it a lot more complicated then please don't worry about the horizontal scrolling - I can use tricks like a smaller input font size, and keeping commands short and simple to keep it from ever needing to scroll, I'm sure..

Finally, yes the second "user input" box, would echo each keypress as it is made, but when ENTER key is struck, the text in the box/keyboard buffer would be assigned to a variable, the box emptied so no text is there / entry buffer cleared. then the data in that variable is passed on to the input parser, and its ready to receive the next text string to do it all over again.

I almost got the real time entry down, but as each letter was typed, it was displaying on as many lines high as the box was.. but I lost that code in frustration.. so I was never really able to try and combine it with other attempts to see if I could get anything to work reasonably..


I hope this all makes sense to you.. I really like your scrollbox function, I just lack the skill to do what I want with it

Neco
18
Years of Service
User Offline
Joined: 13th Jul 2008
Location: Waterloo, Wisconsin USA
Posted: 29th Apr 2010 01:02 Edited at: 29th Apr 2010 02:18
Some expansion on the passing more than one string to the scrollbox train of thought..

Basically when printing a Room, it involves several independent "lines" to be printed.. like in my example.

[Area Title, Room Name]
[Description]
[Objects]
[People / Monsters]
[Exits]

That's 5 potential lines to print into the main, wrapped window.. But you can't just dump that all into one variable, because it will come out as one continuous line-wrap, right?

I would need a way (or reassurance thats how it works now) to either make multiple calls to the scrollbox function, or pass multiple string variables to it, each starting on their own brand new line; regardless of the previous entry made and whether or not it wrapped a few lines or not.

I just thought I should clarify that portion..

Thank you for any assistance you can provide.

Edit: One last late edit... sorry I forgot to think of this before.. But I have an idea on the backburner that I hopefully intend to implement and I didn't realize at the time that all this would probably affect it.. I plan to do colorized text, although I don't know how DB implements that yet and how restrictive it may be..

Basically certain words will be specific colors, monsters/npcs may be highlighted a certain color, etc.. But it can't be by line obviously, it needs to be down to individual words that perhaps carry a certain flag, or involve some kind of variable, etc.. (like a monster list, any monsters shown on that list are printed in yellow text, an NPC's name no matter what it may be, might be printed in yellow text.. The Area / Room title might be a brighter version of the standard text color, etc)..

Would that interfere with any of this? Or can it be done independently without worry?

If its going to complicate things.. obviously I wouldn't worry about putting that much extra work into it at this time.. Hopefully this is something I can do by myself in the future.

CodemanV
20
Years of Service
User Offline
Joined: 25th Aug 2005
Location: South Wales Valleys, UK
Posted: 29th Apr 2010 04:06
Hello

I've altered the code so the textboxes use a UDT array to store their dimensions, text and colours.

The <ScrollPrint> function now has one parameter, an index to a textbox UDT array.

By doing this, you'll have an easier time adding textboxes to your project without rembering all the parameters for each one of them.



This is a bit of a hack but sorts out the input window update using your supplied code.

Personally, I would use an alternative custom input routine using scancodes which could then cater for BACKSPACE, CURSORS, etc.

All The Best
Neco
18
Years of Service
User Offline
Joined: 13th Jul 2008
Location: Waterloo, Wisconsin USA
Posted: 29th Apr 2010 16:54 Edited at: 29th Apr 2010 17:24
Wow, I will do my best to try to make this work out.

I'm not familiar with getting input by scancodes (in any language really) so I will have to do some research and see if I can make that work, and how much better it is for me.

I'm not quite familiar with data statements either.. So I will look those up too.

I Appreciate the work.

Edit: hrmm maybe I need a tiny nudge here.. I've read most of it several times.. But I'm unsure of where to drop in any statements for passing a string into an existing text box (for instance).

A little example usage perhaps? Just running the program to see what it does, makes the default text in the DATA statements just scroll infinitely far as I can tell. So maybe I'm just being stupid here.. Complex code is not my forte

I know doing a text game is a complicated endeavor, but I never expected to get hung up on the basic interface, of all things

Neco
18
Years of Service
User Offline
Joined: 13th Jul 2008
Location: Waterloo, Wisconsin USA
Posted: 1st May 2010 00:33 Edited at: 1st May 2010 00:36
TDK,

If you wouldn't mind.. Would be be able to comment the lines in your function declaration? I really have a feeling I would understand this better if I actually knew what was going on in each step..


If nothing else, it would allow me to at least start building my own basic function to play around with, and be able to grasp the concept of what is going on, and how to modify things for the way I might want to do various things..

Not necesarrily every single line (unless you want to) but basically I need an outline of all the variable names involved, when you do an operation on them, what is it doing and what is the expected result.. thank kind of thing?

I'm not asking for a full blown tutorial or anything, and I'd rather not have to rely on others to modify stuff for me, but I can't decipher it without you, I'm just too new I guess and its frustrating.

I won't ask anything else of you on this topic, if you could oblige me... Thanks.



TDK
Retired Moderator
23
Years of Service
User Offline
Joined: 19th Nov 2002
Location: UK
Posted: 1st May 2010 15:11 Edited at: 1st May 2010 18:00
OK, here's a small demo, along with a commented version of the function.



I'm not sure that it will help though as the function was written to take a lengthy string and word-wrap it into a box of a specific width and height - scrolling the lines if necessary.

It was never intended to do the same thing a character at a time - which if I understand you correctly is what you are trying to do.

All you need is a routine to read in a keypress at a time and pass it to another routine to place it in the box, word-wrapping when required.

See if you can figure it out yourself first and if you have no luck, let me know and I'll see what I can come up with for you.

TDK

Neco
18
Years of Service
User Offline
Joined: 13th Jul 2008
Location: Waterloo, Wisconsin USA
Posted: 1st May 2010 18:28 Edited at: 1st May 2010 18:29
Hi,

My Apologies if I wasn't making myself clear enough.

Just to clarify.. My primary purpose is to use this function for the main text box, and print all the game data through it, and I am not dead set on using it to echo user input at the same time, as I understand it wasn't really designed for that.. But the hope is that by studying the commented version, I'll be able to come up with an input version for my needs, if possible.


Using it to echo input is more of an afterthought, as I can rely on the bottom of the screen being free (since the box can be placed static) for a more traditional keypress echoing setup.

I appreciate your commenting the code for me very much, and now I am off to study it and hopefully it will all 'click' for me

Neco
18
Years of Service
User Offline
Joined: 13th Jul 2008
Location: Waterloo, Wisconsin USA
Posted: 1st May 2010 22:52 Edited at: 1st May 2010 22:57
I have an interesting (I hope) question?

I have been reading things slowly, over and over and I believe I am beginning to understand how this is working.

It looks like you are basically using an Array as a screen buffer, yes? And the Array Pointer, tells it which lines in the buffer to display? So It if you have a box 15 lines high, it says

"Display lines 0 - 14" and then when it becomes full its in essence starts saying "Ok, now display lines 1 - 15, 2 - 16" etc.. And that creates the "scrolling" effect? Am I even close to right?

One thing perplexes me though, and maybe I missed it.. But how do you reset the buffer without messing up the display of text already in the buffer? To me it would seem that if it looped around and started storing from index 0, and displaying from 0, again.. It would mess up whats actually being displayed ?

Or does it just keep adding text to the buffer continuously, and then start increasing the size of the array storing all that text? That's what has me perplexed.. Because if it works by simply increasing the size of the array, eventually it would slow down / run out of memory.... wouldn't it?

I'm really interested to know how that works, if you could explain it.


Before I got your commented code back, I had been thinking hard about how I might try to build one blind (from scratch, with no idea what I'm doing) and I pretty much thought "OK, build a virtual buffer, and increment the displayed lines".. But I always got stuck on how to clear the buffer, and reset it so it could be used again, without either clearing the whole screen, or messing up the text already on the screen.

To me, it seems if you had a buffer holding 20 lines, and also set that as your pointer limit / box height, etc.. If you would get to 20, and then "reset" your array pointer and also begin storing on line 0 once again.. You would get line 0 at the wrong end of the box, appearing before / after lines 1 - 19?

Hope this makes sense.. I wonder if I haven't simply confused myself.

sladeiw
17
Years of Service
User Offline
Joined: 16th May 2009
Location: UK
Posted: 2nd May 2010 00:14
Here is a really simple output routine to display text in a scrolling window. You would need to add to it to provide extra usability like clearing the whole window, skipping lines etc.
It uses IanM's matrix utils which makes string splitting much easier.

As it stands you will need to add hyphenation if a single word is longer than the width of the output window.

Right-justify can also look nice, but to do that you have to build a whole line of words before outputting them with padding inbetween.

Hope it helps.

CodemanV
20
Years of Service
User Offline
Joined: 25th Aug 2005
Location: South Wales Valleys, UK
Posted: 2nd May 2010 03:06 Edited at: 2nd May 2010 07:36
Hello again

I went through my old projects and dug this TextBox method out. I've adapted the demo to suit text adventure genre.

They're basic TextBoxes which wrap words, align text and each have their own colours, fonts and font-styles.

They are buggy with some fonts though - stick with basic default Windows fonts for now, i.e., "Courier New"-size 12 doesn't work, "Courier"-size 12 does!?

The DATA statements are messy, I'm cleaning up a ini-type-file to work with saving/loading TextBox properties.




I'll explain anything my comments left out but for now,
The Heroes Finale is on so I'm off for a bit.

All the best.

***** EDIT *****

This snippet is a cleaner and improved version of just the TextBox functions. Some of the functions have been altered to the previous snippet but are more stable and user friendly



All The Best
TDK
Retired Moderator
23
Years of Service
User Offline
Joined: 19th Nov 2002
Location: UK
Posted: 2nd May 2010 15:56 Edited at: 2nd May 2010 16:05
Quote: ""Display lines 0 - 14" and then when it becomes full its in essence starts saying "Ok, now display lines 1 - 15, 2 - 16" etc.. And that creates the "scrolling" effect? Am I even close to right?"


Nearly. The Display$() array only ever contains the number of viewable lines in the text box. As the lines are scrolled up, the ones which disappear off the top aren't stored - the lines are simply shuffled up the array to make way for the new lines which are added at the bottom.



Note that this bit only ever counts from 0 to NumLines. If your designated scrolling box can hold 12 lines then that's how many elements are in the array.

So, there's no buffer as such to clear.

The pointer array (in case you were wondering) was only implemented in case you wanted multiple text boxes - say you had two characters talking in a game, each with their own text boxes for 'speech bubbles'. The pointer could then keep track of the next free line for each individual text box.

Although it wasn't implemented in the function I originally posted, to add a clear command would be quite simply a case of clearing the Display$() array and resetting the pointer. This example uses three hash symbols (###) but can be changed to whatever you want.



Check the new code from lines 113 to 124.

TDK

Neco
18
Years of Service
User Offline
Joined: 13th Jul 2008
Location: Waterloo, Wisconsin USA
Posted: 2nd May 2010 18:08 Edited at: 2nd May 2010 22:24
CodeManV, thanks for the further samples. That certainly is a lot of code, but perhaps I can pull some ideas from it..


TDK,

Hmm. I'd be lying if I said "Oh I get it".. I guess I am just not seeing where the array is being told "shift your contents up by one (x) index(es)".. Or is that not what you meant?

I know the idea I was thinking of was either to manually build & control some kind of FIFO based list, or perhaps use a List Array in the same manner.. Something to that effect.

Although I suppose whatever I could come up with would be much less efficient, I may go ahead and give it a try just to get feedback. It would probably be a good excersize for me anyway. I probably need to learn about the particulars of DarkBasic Arrays as although they feel similar to most others, they seem uniquely different in a way. Or perhaps I'm just imagining that.

Thanks for your continued wisdom.


Edit: While I do admittedly have trouble understanding some things about your code (the comments helped tremendously in explaining the concept & flow of execution) I have being playing around with Queues in particular and kinda see how things work now.. I will probably build my first (hopefully) working example on a Queue system since I'm just going with what's working for me / what I can comprehend at the moment..

TDK
Retired Moderator
23
Years of Service
User Offline
Joined: 19th Nov 2002
Location: UK
Posted: 2nd May 2010 23:04
Quote: "I guess I am just not seeing where the array is being told "shift your contents up by one (x) index(es)".."


When adding 1 new line:



When adding multiple lines:



In a nutshell, if your box is big enough for 10 lines, each will be in a different element of the array Display$(). Once you add another line, element 2 of array Display$() is copied to element 1 (losing what was there), element 3 is copied to element 2 and so on. The new line is popped into the resulting gap at the end.

TDK

Neco
18
Years of Service
User Offline
Joined: 13th Jul 2008
Location: Waterloo, Wisconsin USA
Posted: 3rd May 2010 17:01
Interesting... I had a feeling it was working like that. Although I guess I am one of those people that feels more comfortable seeing "add/remove" queue statements.

That's what I used when I had some time to play around with a few static text placements in a small function. I'm probably going to approach it a little differently, like not reading in one character at a time. But I should be able to pull it off now I think.

Don't think I have any other questions in the mean time, but you've been a great help.

Login to post a reply

Server time is: 2026-07-28 04:27:52
Your offset time is: 2026-07-28 04:27:52