|
|
View previous topic - View next topic |
Author |
Message |
DeveloperX 202192397
Joined: 04 May 2003 Posts: 1626 Location: Decatur, IL, USA
|
Posted: Mon Feb 16, 2009 2:41 pm Post subject: Need HELP implementing complex dialogue ripper |
[quote] |
|
Okay, I should be able to implement this..but I've never done it before, and have not been able to figure it out after 14 hours I'm getting tired of no results, and I need help.
I need to take a long piece of text that is stored in a C-style string, and cut it into pages of lines of a predetermined length.
There can be no more than 21 characters in each line, and no more than 6 lines per page.
Here is why this is proving to be difficult for me.
Each newline '\n' character in the piece of text needs to be translated into a new line, and all line/page calculations will then need to be re-calculated. Any tab '\t' characters in the piece of text will need to be translated into 4 spaces, and all line/page calculations will then need to be re-calculated yet again.
I have 2 simple structures that hold the data, and their format cannot change unless absolutely necessary.
Code: |
/// a page in the dialogue system is a list of strings
struct DialoguePage
{
std::vector<std::string> lines_;
};
/// a dialogue is a list of pages
struct Dialogue
{
std::vector<DialoguePage*> pages_;
};
/// the dialogue data structure
Dialogue dialogue_;
|
The limitations are stored as constants in the following namespace:
Code: |
/// constants and enumerations for the dialogue system
namespace DIALOGUE
{
/// maximum characters per line
const int LINE_LENGTH = 21;
/// maximum lines per page
const int LINES_PER_PAGE = 6;
} // end namespace
|
For an example, this long piece of text needs to be translated into 8 pages:
Code: |
const char* message =
"A young woman's body falls limp as some figure steps away"
"from her. A man races towards the figure from behind you,"
"nearly running into you as he passes.\n\n"
"Raising his hands to the heavens he speaks several words "
"in a foreign tongue and a white light emanates from "
"his palms and seem to pierce through the dark figure, "
"temporarily stunning it. You feel the hairs on the back of "
"your neck raise as the figure reaches out to the man quickly"
"advancing on him, lets out a violent scream that shatters "
"the unusally silent night and viciously attacks the man.\n\n"
"Your presence does not go unnoticed and the dark figure "
"begins to move towards you. You feel as if in a trance;"
"Unable to move, you feel the figure staring at you, his "
"dark gaze seems to have power over you.\n\n";
|
Words cannot be broken, so the resulting list of strings would be
Code: |
"A young woman's body"
"falls limp as some"
"figure steps away"
"from her. A man races"
"towards the figure"
"from behind you,"
"nearly running into"
"you as he passes."
""
""
"Raising his hands to"
"the heavens he"
"speaks several words"
"in a foreign tongue"
"and a white light"
"emanates from his"
"palms and seem to"
"pierce through the"
"dark figure,"
"temporarily stunning"
"it. You feel the"
"hairs on the back of"
"your neck raise as"
"the figure reaches"
"out to the man"
"quickly advancing on"
"him, lets out a"
"violent scream that"
"shatters the unusally"
"silent night and"
"viciously attacks the"
"man."
""
""
"Your presence does"
"not go unnoticed and"
"the dark figure"
"begins to move"
"towards you. You feel"
"as if in a trance;"
"Unable to move, you"
"feel the figure"
"staring at you, his"
"dark gaze seems to"
"have power over you."
""
""
|
If you can help, it would be MOST helpful, and I will be quite grateful. _________________ Principal Software Architect
Rambling Indie Games, LLC
See my professional portfolio
|
|
Back to top |
|
|
Scrim Mandrake's Little Slap Bitch
Joined: 05 Apr 2007 Posts: 69 Location: Canada
|
Posted: Mon Feb 16, 2009 4:46 pm Post subject: |
[quote] |
|
The thing that struck me about what you're asking is that you've said a newline or tab would cause you to recalculate the breaks. Why not just take them into account up front and just do one pass instead?
Here's a quick algorithm I dreamed up. I didn't fill in all the code - I just put comments in a lot of places saying what needed to be done.
Big caveat: I haven't actually tried this out, so I could well have overlooked something.
One thing I didn't do: transform the tab into four spaces. I just added 4 to the running total. The code (omitted) that make a line with a run of text will have to check for tabs and put in the spaces instead.
Edit: Another thing this code won't do is break a line that is one long continuous string with no gaps. Basically you'd have to add a check to see if lastGoodLineEnd still equals lineStart when you run out of space in the line...
Code: |
char* lineStart, *lastGoodLineEnd, *nextChar;
bool didEndLine = false;
int runningTotal = 1;
// first, make a new line and a new page
// point lineStart and lastGoodLineEnd and nextChar to the start of your text to rip
while ( /*there are still characters left to examine */) {
didEndLine = false;
if (runningTotal == maxLineLength) {
// we've run out of room in this line
// make a new line in the range
// lineStart to lastGoodLineEnd.
// move the nextChar pointer back to the end of the line
nextChar = lastGoodLineEnd;
while (*nextChar == ' ' || *nextChar=='\t') {
//skip any line-ending space since we'll break the line instead
nextChar++;
}
didEndLine = true;
}
else {
if (*nextChar == '\n') {
// grab all characters from lineStart to nextChar and make a line
didEndLine = true;
}
if (*nextChar == ' ') {
// we've found a word break, which means this is a good
// place to end the line if needed
lastGoodLineEnd = nextChar;
}
if (*nextChar == '\t') {
// this is basically like the space case, except we're
// going to add four spaces to the next line, which means
// we'll mark this as a good place to break, and up the count by 3
lastGoodLineEnd = nextChar;
runningTotal += 3;
}
}
if (didEndLine) {
// figure out if our line count for this page equals 6. If it does
// make a new page, otherwise, push the new line to the back
// of the current page
// reset for next time
runningTotal = 1;
nextChar++;
lineStart = nextChar;
lastGoodLineEnd = nextChar;
didEndLine = false;
}
else {
nextChar++;
runningTotal++;
}
}
|
|
|
Back to top |
|
|
DeveloperX 202192397
Joined: 04 May 2003 Posts: 1626 Location: Decatur, IL, USA
|
|
Back to top |
|
|
DeveloperX 202192397
Joined: 04 May 2003 Posts: 1626 Location: Decatur, IL, USA
|
Posted: Tue Feb 17, 2009 12:06 am Post subject: |
[quote] |
|
Heres what I've got...its far from working, but maybe someone can give me some more ideas.
Big ass wall-of code removed _________________ Principal Software Architect
Rambling Indie Games, LLC
See my professional portfolio
Last edited by DeveloperX on Tue Feb 17, 2009 1:50 am; edited 1 time in total
|
|
Back to top |
|
|
DeveloperX 202192397
Joined: 04 May 2003 Posts: 1626 Location: Decatur, IL, USA
|
Posted: Tue Feb 17, 2009 1:55 am Post subject: |
[quote] |
|
Okay I solved this problem by turning to a language better suited to solving it. XD
I decided to pre-process my dialogue text with PHP and then load in the processed text into my game's dialogue system.
For reference of anyone who stumbles on this, I provide my solution.
Code: |
<?php
/*
Dialogue Pre-Processing Utility
Developed by Richard Marks <ccpsceo@gmail.com>
http://www.ccpssolutions.com
*/
if (!IsSet($_POST['submitted']))
{
// show form
echo '<form method="post" action="', $_SERVER['PHP_SELF'], '">
<div style="font-family:monospace; font-size:12pt;">
<strong>Enter text to be processed:</strong><br />
<textarea style="font-family:monospace; font-size:10pt;" id="message" name="message" rows="25" cols="80"></textarea>
<br />
<input id="submit" name="submit" type="submit" value="Process Text" />
<input id="submitted" name="submitted" type="hidden" value="true" />
</div>
';
}
else
{
// process
$message = $_POST['message'];
$message = str_replace('\n', "\n", $message);
$message = str_replace('\t', " ", $message);
$processed = wordwrap($message, 21, "\n");
echo '<div style="font-family:monospace; font-size:12pt;">',
'<textarea style="font-family:monospace; font-size:10pt;" id="message" name="message" rows="25" cols="22">', stripslashes($processed), '</textarea></div>';
}
?>
|
save that to a php file and fire it up in your local web server and you've got it. XD I cannot believe that I slaved over my C++ writing and re-writing incomplete and non-working solutions for over 19 hours when all I had to do was code a handful of lines in PHP.
Thanks again Scrim for taking time to reply. _________________ Principal Software Architect
Rambling Indie Games, LLC
See my professional portfolio
|
|
Back to top |
|
|
Scrim Mandrake's Little Slap Bitch
Joined: 05 Apr 2007 Posts: 69 Location: Canada
|
Posted: Tue Feb 17, 2009 1:19 pm Post subject: |
[quote] |
|
That does look a lot simpler.
Hooray for C++'s awesome text processing capabilities =)
|
|
Back to top |
|
|
tcaudilllg Dragonmaster
Joined: 20 Jun 2002 Posts: 1731 Location: Cedar Bluff, VA
|
Posted: Fri May 22, 2009 7:26 am Post subject: |
[quote] |
|
You know I just realized something? It's worth it to embed a scripting language (like Dyne) into another program just for purposes like this. Then you could call a script written in the other language by invoking its interpreter upon it. You can get the return value and use it in your program. No more string messes.
|
|
Back to top |
|
|
DeveloperX 202192397
Joined: 04 May 2003 Posts: 1626 Location: Decatur, IL, USA
|
Posted: Fri May 22, 2009 11:30 am Post subject: |
[quote] |
|
LordGalbalan wrote: | You know I just realized something? It's worth it to embed a scripting language (like Dyne) into another program just for purposes like this. Then you could call a script written in the other language by invoking its interpreter upon it. You can get the return value and use it in your program. No more string messes. |
Yeah no kidding. I've messed with embedding Lua, Tcl, Perl, Python, Ruby, even SpiderMonkey into my stuff. Just never got around to building a full interface bridge between the scripting system and the engine.
One day I might. _________________ Principal Software Architect
Rambling Indie Games, LLC
See my professional portfolio
|
|
Back to top |
|
|
RedSlash Mage
Joined: 12 May 2005 Posts: 331
|
Posted: Fri May 22, 2009 4:04 pm Post subject: |
[quote] |
|
Scripting language seems excess for this kind of task, IMO. I normally see scripting as being used to dynamically extend the functionality of a engine, whereas in this case you're suggesting the usage of scripting to provide one of the core features. I think this kind of task is better implemented in engine code, despite how stupidly annoying it is to parse strings in C++. (Assuming this is for building game engine)
|
|
Back to top |
|
|
|
Page 1 of 1 |
All times are GMT
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|