RPGDXThe center of Indie-RPG gaming
Not logged in. [log in] [register]
 
Need HELP implementing complex dialogue ripper
 
Post new topic Reply to topic  
View previous topic - View next topic  
Author Message
DeveloperX
202192397


Joined: 04 May 2003
Posts: 1626
Location: Decatur, IL, USA

PostPosted: 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

PostPosted: 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

PostPosted: Mon Feb 16, 2009 7:39 pm    Post subject: [quote]

Thanks Scrim.

I'll look over what you've got and see if I can make something from it.

To everyone:
The request for help still stands. :)
_________________
Principal Software Architect
Rambling Indie Games, LLC

See my professional portfolio
Back to top  
DeveloperX
202192397


Joined: 04 May 2003
Posts: 1626
Location: Decatur, IL, USA

PostPosted: 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

PostPosted: 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

PostPosted: 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

PostPosted: 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

PostPosted: 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

PostPosted: 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  
Post new topic Reply to topic Page 1 of 1 All times are GMT
 



Display posts from previous:   
Jump to:  
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