Archived

This topic is now archived and is closed to further replies.

tagged

Loading config Files...

Recommended Posts

I have looked around the site and have been unable to find something helpful to cure this problem. I want to be able to program in the ability to load config files like that of quake series... ie, r_speed 10 r_death 1 i am able to save/load varibles in binary format, but i am unable to figure out how to load just plain text, figure out what varible is it and store the number in there... Cheers BTW. Im using C++ [edited by - tagged on December 27, 2002 6:19:16 AM]

Share this post


Link to post
Share on other sites
I may be wrong with this, but I think you can use ofstreams to output variables in text.

  
#include <iostream>
#include <fstream>
using namespace std;

void saveCfg(string fname)
{
int r_speed = 10, r_death = 1;
ofstream file(fname.c_str());
file << "r_speed " << r_speed << "\n" << "r_death " << r_death << "\n";
}


I think that should work.

For loading, you need to get the string "10" and convert it to an integer again.


"Reality is merely an illusion, albeit a very persistent one." (Albert Einstein)
My Homepage

Share this post


Link to post
Share on other sites
OMG LOL!! (riped from my current game)

  
bool LoadConfig(char* filename)
{
ifstream File(filename, ios::binary);
if(!File)
{
MessageBox(g_hwnd, "Could not open config file for reading.", "Error", MB_OK | MB_ICONERROR);
Jester->Log("Could not open config file for reading.");
File.close();
return false;
}

File.seekg(0, ios::end);
int iSize = File.tellg();
File.seekg(ios::beg);

char* pszFileBuff = new char[iSize];
File.read(pszFileBuff, iSize);
File.close();

char szWord[200];
char szValue[200];

for(int i = 0; i < iSize; i++)
{
// Is it a comment?

// Note: comments cant be nested

if(pszFileBuff[i] == ''['')
{
for(int error = 0; error < iSize; error++)
{
if(pszFileBuff[++i
] == '']'')break;
}
if(error >= (iSize-1))
{
MessageBox(g_hwnd, "Could not read Config.cfg, unclosed comment?", "Error", MB_OK|MB_ICONERROR);
Jester->Log("Could not read Config.cfg, unclosed comment");
return false;
}
}
else
{
if(pszFileBuff[i] == ''\r''){i++; continue;} // Get rid of any new lines


// Read word

for(int p = 0; p < 199; p++)
{
szWord[p] = pszFileBuff[i++];
if(pszFileBuff[i] == '' '')
{
szWord[++p] = ''\0'';
break;
}
}

i++; // Get rid of space


// Read Value

for(int t = 0; t < 199; t++)
{
szValue[t] = pszFileBuff[i++];
if(pszFileBuff[i] == ''\r'')
{
szValue[++t] = ''\0'';
i++;
break;
}
}

// Do stuff with our variables

if(!strcmp(szWord, "bFullScreen"))
{
if(!strcmp(szValue, "1")) g_bWindowed = false;
else if(!strcmp(szValue, "0")) g_bWindowed = true;
else
{
MessageBox(g_hwnd, "Unknown value read from Config.cfg... See error log for more details.", "Error", MB_OK|MB_ICONERROR);
Jester->Log("Unknown value read from Config.cfg, variable: ", 0);
Jester->Log(szWord, 0);
Jester->Log(", value: ", 0);
Jester->Log(szValue);
return false;
}
}
}
}
return true;
}

Share this post


Link to post
Share on other sites

    
// V A R I A B L E S

char buffer[5];
int ID[10];

// L O A D I D 's

for( int i = 0; i < 10; i++ )
{
ifile.getline( buffer, sizeof( buffer ), ',' );
sscanf( buffer, "%ld", ID[i] );
}


ripped also, but this is to load numbers:
1,2,3,4,5,6,7,8,9,0


dont do the "buffer" with a pointer instead of an array, you'll get errors.

not much help but you should be able to figure out how to...



.lick

[edited by - Pipo DeClown on December 27, 2002 7:50:33 AM]

[edited by - Pipo DeClown on December 27, 2002 7:54:23 AM]

Share this post


Link to post
Share on other sites
***PLUG TIME!!!!!***   

Heh heh... so I love watching the "downloads" counter go up, sue me. I wrote a simple sidescroller that uses a configuration file to set some initial variables. It's hosted here in the Showcase, with all source included: 'Genus!!!' Or, if you were just wondering about the function, it uses ifstream to parse the configuration file, while using an ofstream object to take notes of what information it found (I have a lot of bugchecking like that in the game):
  //-----------------------------------------------------------------------------

// Name: InitConfigFile()

// Desc: Sets game defaults at beginning of program. Note that

// InitConfigFile will overwrite anything it chooses to.

//-----------------------------------------------------------------------------

VOID GenusGFX::InitConfigFile()
{
ifstream File("game.cfg", ios::in|ios::binary, filebuf::sh_read||filebuf::sh_write);
// if that didn't work, we don't need to be here.

ofstream CommentFile("ParsedCfg.txt",ios::trunc|ios::binary,filebuf::sh_read||filebuf::sh_write);
CommentFile << "Opening Comment file on Genus config file parsing:\r\n";
if(!File)
return;
CommentFile << " Config file found and opened.";
while(!File.eof())
{
char flag[100]; // text buffer

float i; // temp variable

File >> flag;
CommentFile << "\r\n Read from file: '"<<flag<<"'";
switch(flag[0])
{
// Brake information:

case 'B':
File >> BrakeFactor;
CommentFile << "\r\n BrakeFactor found and set to:"<<BrakeFactor;
break;
// SpeedCap information:

case 'C':
File >> SpeedCap;
CommentFile << "\r\n SpeedCap found and set to:"<<SpeedCap;
break;
// Jump information:

case 'J':
File >> JumpVel;
CommentFile << "\r\n JumpVel NULL found and set to:"<<JumpVel;
break;
// StatWidth information:

case 'S':
File >> StatWidth;
CommentFile << "\r\n StatWidth found and set to:"<<StatWidth;
break;
// Frames Per Second

case 'F':
File >> i;
if(i > 0.0f)
{
show_fps = true;
CommentFile << "\r\n FPS value "<<i<<" read and declared as true.";
}
else
{
show_fps = false;
CommentFile << "\r\n FPS value "<<i<<" read and declared as false.";
}
break;
// Display Title screen toggle

case 'T':
File >> i;
if(i > 0.0f)
{
bDisplayTitle = true;
CommentFile << "\r\n bDisplayTitle value "<<i<<" read and declared as true.";
}
else
{
bDisplayTitle = false;
CommentFile << "\r\n bDisplayTitle value "<<i<<" read and declared as false.";
}
break;
// Parse the Walk information:

case 'W':
File >> WalkChange;
CommentFile << "\r\n WalkChange found and set to:"<<WalkChange;
break;

// Ignore da crap!

case '\n': // Ignore newline feeds as they are- somethings on the next line.

break;
default:
CommentFile << " ... Non-match. Line ignored.";
File.ignore(1000,'\n'); // We jump to the end of the line.

break;
}
}
CommentFile << "\r\nEnd of parsing. Closing File.";
CommentFile.close();
File.close(); // Thank you Mr. File... and goodnight. :)

}
That takes a configuration file like so: (I'm using source to 'box' this, so it might get funny:
  
// Genus Engine Config File //

. Use any non-letter symbol to notate (slashes, periods)
. Try anything- Genus will just crash if you get it wrong. ;)
. A Key followed by a value to set a parameter.
. Keys will usually only check for the first few characters, to a max
. of 100 characters. For example, as long as there's a "J" starting it, your
. telling the parser to look for a jumping velocity
. Read the output file "ParsedCfg.txt", and InitConfigFile() in Genus.cpp
. for more information.
. Note: all velocities are in units of tiles/milliseconds

// Width of stat information:

. (currently your "life" along the top left of the screen)
. This is the width, in tiles, of the statistics displayed at
. the top of your screen.
. S 0.5 is standard.
Stat_Width 0.8

// Title Screen:

. to skip it, turn off with T -1.0f
. to display it, turn on with T 1.0f.
T 1.0

// Jumping Velocity:

. How much initial velocity the character will have upon jumping
. J -0.01 is standard.
Jump -0.01

// Change in Walking Velocity:

. W 0.001 is standard.
Walking_Accelleration 0.0008

// Braking Factor:

. This number is X'd to the horizontal velocity each
. tick.
. B 0 is standard for instant stopping
. B 0.8 is standard slowdown
Brake 0.8

// Speed Cap:

. C 0.015 is standard.
CapSpeed 0.012

// Frames Per Second:

. false is default.
. use 1.0 to turn fps on, -1.0 to turn it off.
FPS -1.0
Edit: picky [ ]'s!!!
---email--- Tok ----surf----
~The Feature Creep of the Family~

[edited by - Tok on December 27, 2002 9:32:23 PM]

Share this post


Link to post
Share on other sites
Here''s an alternate solution that I''m using and works very well for me. The system I built for loading files was to use the oftstream to output and input data. However I didn''t bother with data tags like:

r_jump 10
r_speed 200
r_strength 100

instead I just outputted a straight data file:

10 200 100

This makes it easier to read in since you don''t have to parse the data file looking for tags or keywords, you just have to load the data in the correct order. Of course, it also makes reading the files and editing them a bitch, so I built a simple Visual Basic app that reads the files and lets you edit the various properties of the file and ouput the new file. Of course, if you don''t know VB then this suggestion is moot (making an MFC app for this purpose would so be overkill methinks) but I figured I''d try anyways

Oh and elis-cool, I''m just curious as to whether the close() call to the file is really neccessary if the open() call failed as it did, cause I didn''t think to close the file when I catch that error. Better safe than sorry I guess?

_________________________________________________________________

Drew Sikora
A.K.A. Gaiiden

ICQ #: 70449988
AOLIM: DarkPylat

Blade Edge Software
Staff Member, GDNet
Public Relations, Game Institute

3-time Contributing author, Game Design Methods , Charles River Media
Online column - Design Corner at Pixelate

Unnoficial IGDA chat! [polaris.starchat.net -> #igda]
NJ IGDA Chapter - NJ developers unite!! [Chapter Home | Chapter Forum]

"Real programmers don''t work from 9 to 5. If any real programmers are around at 9am it''s because they were up all night."
-Anon.

"It''s not the size of the source that matters, it''s how you use it"
- Self

Share this post


Link to post
Share on other sites
quote:
Original post by Pipo DeClown
dont do the "buffer" with a pointer instead of an array, you''ll get errors.


That''s close but not quite right. An array essentially IS a pointer. You''ll get errors if you try applying sizeof to a dynamically allocated array as opposed to a static array such as "buffer" in your example.

Share this post


Link to post
Share on other sites
I threw this together real quick because I was bored
It seemed to get the job done


  

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int ship_speed, ship_health, ship_ammo;

int main(int argc, char* argv[])
{
char variable[100];
char value[100];
ifstream in("default.cfg");
int k;

if (!in.good())
return 0;

while (!in.eof())
{
memset(variable, 0, 100);
memset(value, 0, 100);

in >> variable;

if (variable[0] == ''/'' && variable[1] == ''/'')
{
in.ignore(100, ''\n'');
continue;
}

in >> value;

if (value[0] == ''"'')
{
strcpy(value, &value[1]);
k = strlen(value);
in.getline(&value[k], 100, ''"
'');
}

if (!strcmp(variable, "ship_speed"))
{
cout << "setting ship speed to " << value << "\n";
ship_speed = atoi(value);
}
else if (!strcmp(variable, "ship_health"))
{
cout << "setting ship health to " << value << "\n";
ship_health = atoi(value);
}
else if (!strcmp(variable, "ship_ammo"))
{
cout << "settings ship ammo to " << value << "\n";
ship_ammo = atoi(value);
}

}

in.close();

return 0;
}


and heres what default.cfg looks like:


  
// comments are just like C++

// set r_speed to a nice value


dummy "hello world" // useless...

dummy "this does absolutely nothing"


// this'' what we want

ship_speed 35
ship_health 140
ship_ammo 155

Share this post


Link to post
Share on other sites
I use my dad''s dll that allows me to manipulate strings and extract strings...

my config files are like this

player_speed=10

and i call a function in the dll and i can get everything on that line, i can get anything before a delimeter that i tell it (in this case an = sign) and everything after the equal sign...

if you want i guess i can give it to you...

<- Digital Explosions ->
"Discipline is my sword, faith is my shield
do not dive into uncertainty, and you may live to reap the rewards" - (Unreal Championship)

Share this post


Link to post
Share on other sites