[EDIT]
- Problem solved!
[/EDIT]
I'm loading default fonts into my game using a script file called fonts.res (really just a text file). At startup, the program parses this file and creates all the fonts it finds in there. Here is how my fonts.res file looks:
| 1 | ; This is a script file used for loading fonts. |
| 2 | ; All lines beginning with semi-colons are comments. |
| 3 | ; Syntax: |
| 4 | ; |
| 5 | ; FontName (as referred to in code) |
| 6 | ; FontDataPath (path to any font data format supported by alfont) |
| 7 | ; Size (size that the renderer prints this font) |
| 8 | |
| 9 | ; Default 14 pt arial font |
| 10 | arial_14 |
| 11 | data/resources/arial.ttf |
| 12 | 14 |
| 13 | |
| 14 | ; Larger arial |
| 15 | arial_18 |
| 16 | data/resources/arial.ttf |
| 17 | 18 |
And here is the current code that parses this file:
| 1 | gameresult CGameRenderer::LoadResFiles() |
| 2 | { |
| 3 | //load font resources |
| 4 | std::ifstream file( FONT_RESOURCE_FILE ); |
| 5 | |
| 6 | if ( !file.is_open() ) |
| 7 | { |
| 8 | conwarning( "Font resource file '%s' not loaded!", FONT_RESOURCE_FILE ); |
| 9 | return GAME_FILENOTFOUND; |
| 10 | } |
| 11 | |
| 12 | bool foundName = false; |
| 13 | bool foundPath = false; |
| 14 | bool foundSize = false; |
| 15 | std::string bufstr, curPath, curSize; |
| 16 | |
| 17 | Font_t tempFont; |
| 18 | tempFont.name = ""; |
| 19 | tempFont.size = 12; |
| 20 | |
| 21 | int num_loaded = 0; |
| 22 | int dbglines = 0; |
| 23 | |
| 24 | while ( !file.eof() ) |
| 25 | { |
| 26 | std::getline( file, bufstr ); |
| 27 | dbglines++; |
| 28 | |
| 29 | /* TODO: Make a correct COMMENT_STRINGS macro somewhere containing |
| 30 | standard C comment syntax (ie. // and /* etc). Really what I need |
| 31 | to do is make a unified script parser with key/value pairs that all |
| 32 | systems use, but this is good enough right here for the time being. */ |
| 33 | |
| 34 | if ( bufstr.length() && (bufstr[0] != ';') ) |
| 35 | { |
| 36 | // find a name |
| 37 | if ( !foundName ) |
| 38 | { |
| 39 | conmsg("Found name: %s", (char*)bufstr.c_str()); |
| 40 | tempFont.name = bufstr; |
| 41 | foundName = true; |
| 42 | } |
| 43 | else if ( !foundPath ) |
| 44 | { |
| 45 | conmsg("Found path: %s", (char*)bufstr.c_str()); |
| 46 | curPath = bufstr; |
| 47 | foundPath = true; |
| 48 | } |
| 49 | else if ( !foundSize ) |
| 50 | { |
| 51 | conmsg("Found size: %s", (char*)bufstr.c_str()); |
| 52 | tempFont.size = atoi( bufstr.c_str() ); |
| 53 | foundSize = true; |
| 54 | } |
| 55 | else |
| 56 | { |
| 57 | //got one, load font and reset everything |
| 58 | conmsg("Loading font!"); |
| 59 | if ( LoadFont( (char*)curPath.c_str(), (char*)tempFont.name.c_str(), tempFont.size ) ) |
| 60 | num_loaded++; |
| 61 | |
| 62 | foundName = false; |
| 63 | foundPath = false; |
| 64 | foundSize = false; |
| 65 | curPath = ""; |
| 66 | curSize = ""; |
| 67 | tempFont.name = ""; |
| 68 | tempFont.size = 12; |
| 69 | } |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | file.close(); |
| 74 | |
| 75 | conmsg( "Loaded %i font%s from script file", num_loaded, num_fonts == 1 ? "" : "s" ); |
| 76 | conmsg( "%i lines read", dbglines ); |
| 77 | |
| 78 | return num_loaded; |
| 79 | } |
This works nicely for the first font, but the second (or anything past it) is botched because it seems to be skipping a line and giving wrong values.
The output in my game's console looks like:
As you can see, for the second entry, it is reading path into name, size into path, and then reaching eof.
My brain is a little tired right now and I can't figure out how to prevent getline from going past the first line I'm trying to read
Are you REALLY sure that's the source that's generating that output? I think we're missing a few things there.... like the actual parsing.
Maybe "parsing" isn't the right word then 
All it's doing is going line by line, excluding whitespace/return/semicolon and reading in Name, Path, and Size in that order. When all 3 have been found, it uses the LoadFont( path, name, size ) function, resets itself to looking for a name, and goes again until eof.
The "output" i'm showing you is just some debug printing for me to see what exactly it is filling Name, Path, and Size with.
[EDIT]
I solved it 
I had to change
std::getline( file, bufstr );
To
if ( !( foundName && foundPath && foundSize) ) std::getline( file, bufstr );
To prevent an extra line from being read if all values had been found already. This ended up only partially fixing it, where all values would be found, but the last font would never reach its loading function because EOF had been reached and the loop wouldn't run again - so I added another check past EOF to make sure the last entry is loaded if all values were found.