summaryrefslogtreecommitdiff
path: root/config.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'config.cpp')
-rw-r--r--config.cpp1248
1 files changed, 1248 insertions, 0 deletions
diff --git a/config.cpp b/config.cpp
new file mode 100644
index 0000000..ebfd68b
--- /dev/null
+++ b/config.cpp
@@ -0,0 +1,1248 @@
+//
+// glgrav - OpenGL N-Body gravity simulator
+//
+// Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk)
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// -------------------------------------------------------------------------
+//
+// Data file handling
+//
+static const char id[]="$Id$";
+
+#include "config.h"
+
+#include <cctype>
+#include <GL/gl.h>
+
+#define RAD(x) ((x)*(M_PI/180.0))
+
+// ---------------------------------------- CONSTRUCTION/DESTRUCTION
+//
+Config::Config()
+{
+ int f;
+
+ m_error="";
+
+ for(f=0;f<num_flags;f++)
+ m_flag[f]=false;
+
+ m_collide=none;
+
+ m_light="";
+ m_lr=m_lg=m_lb=1.0f;
+
+ m_const=0.0;
+
+ m_x=0.0f;
+ m_y=0.0f;
+ m_z=0.0f;
+ m_yaw=0.0f;
+
+ m_glid=0;
+ m_glid_no=0;
+ m_glid_idx=0;
+
+ m_scale=1.0;
+
+ m_particles=false;
+
+ m_plane=xy_plane;
+
+ m_look_at=-1;
+ m_travel_as=-1;
+
+ m_s_no=10;
+ m_s_delta=5.0;
+ m_s_min=10.0;
+ m_s_max=1000.0;
+ m_s_shield=100;
+
+ m_sparks=false;
+
+ m_winw=640;
+ m_winh=480;
+
+ m_max_mass=1000000;
+
+ m_fog_dist=0.0f;
+ m_fog_r=0.0f;
+ m_fog_g=0.0f;
+ m_fog_b=0.0f;
+ m_fog_light=false;
+}
+
+Config::~Config()
+{
+ if (m_glid)
+ delete[] m_glid;
+}
+
+
+// ---------------------------------------- PUBLIC MEMBERS
+//
+bool Config::read(const string& fname,vector<Mass>& mass)
+{
+ static struct
+ {
+ Command cmd;
+ string token;
+ int val;
+ } enum_list[]=
+ {
+ {enable_cmd,"solid",static_cast<int>(solid)},
+ {enable_cmd,"lighting",static_cast<int>(lighting)},
+ {enable_cmd,"texture",static_cast<int>(texture)},
+ {collide_cmd,"none",static_cast<int>(none)},
+ {collide_cmd,"merge",static_cast<int>(merge)},
+ {collide_cmd,"delta_merge",static_cast<int>(delta_merge)},
+ {collide_cmd,"shatter",static_cast<int>(shatter)},
+ {plane_cmd,"xy",static_cast<int>(xy_plane)},
+ {plane_cmd,"xz",static_cast<int>(xz_plane)},
+ {plane_cmd,"yz",static_cast<int>(yz_plane)},
+ {cmd_error,"",0}
+ };
+
+ Mass parent;
+ Mass *nm;
+ Command cmd;
+ vector<string> arg;
+ ifstream file(fname.c_str());
+ bool found;
+ int f;
+ vector<Mass>::size_type idx;
+ vector<string>::size_type sidx;
+
+ if (!file)
+ {
+ m_error="File not found : " + fname;
+ return false;
+ }
+
+ try
+ {
+ while(getCommand(file,cmd,arg))
+ {
+ switch(cmd)
+ {
+ case enable_cmd:
+ f=0;
+ found=false;
+ while(enum_list[f].token!="")
+ {
+ if (enum_list[f].cmd==enable_cmd &&
+ CompareNoCase(enum_list[f].token,arg[0]))
+ {
+ found=true;
+ m_flag[static_cast<Flag>(enum_list[f].val)]=true;
+ break;
+ }
+ f++;
+ }
+
+ if (!found)
+ {
+ m_error="Illegal argument to enable : " + arg[0];
+ throw m_error;
+ }
+
+ break;
+
+ case disable_cmd:
+ f=0;
+ found=false;
+ while(enum_list[f].token!="")
+ {
+ if (enum_list[f].cmd==enable_cmd &&
+ CompareNoCase(enum_list[f].token,arg[0]))
+ {
+ found=true;
+ m_flag[static_cast<Flag>(enum_list[f].val)]=false;
+ break;
+ }
+ f++;
+ }
+
+ if (!found)
+ {
+ m_error="Illegal argument to disable : " + arg[0];
+ throw m_error;
+ }
+
+ break;
+
+ case collide_cmd:
+ f=0;
+ found=false;
+ while(enum_list[f].token!="")
+ {
+ if (enum_list[f].cmd==collide_cmd &&
+ CompareNoCase(enum_list[f].token,arg[0]))
+ {
+ found=true;
+ m_collide=static_cast<Collide>(enum_list[f].val);
+ break;
+ }
+ f++;
+ }
+
+ if (!found)
+ {
+ m_error="Illegal argument to collide : " + arg[0];
+ throw m_error;
+ }
+
+ break;
+
+ case const_cmd:
+ m_const=toDouble(arg[0]);
+ break;
+
+ case body_cmd:
+ nm=
+ new Mass
+ (arg[0], toDouble(arg[1]), m_scale,
+ toDouble(arg[2]), toDouble(arg[3]), toDouble(arg[4]),
+ toDouble(arg[5]), toDouble(arg[6]), toDouble(arg[7]),
+ toGLfloat(arg[8]), toGLfloat(arg[9]),
+ toGLfloat(arg[10]), toDouble(arg[11]));
+
+ if (mass.size()<m_max_mass)
+ mass.push_back(*nm);
+
+ delete nm;
+ break;
+
+ case radial_cmd:
+ if (findMass(mass,arg[2],parent))
+ {
+ genRadial(&nm,parent,
+ arg[0],toDouble(arg[1]),
+ toDouble(arg[3]),RAD(toDouble(arg[4])),
+ toDouble(arg[5]),
+ toGLfloat(arg[6]),toGLfloat(arg[7]),
+ toGLfloat(arg[8]),
+ toDouble(arg[9]));
+
+ if (mass.size()<m_max_mass)
+ mass.push_back(*nm);
+
+ delete nm;
+ }
+ else
+ {
+ m_error="Unknown parent in radial : " + arg[2];
+ throw m_error;
+ }
+ break;
+
+ case multiple_cmd:
+ if (findMass(mass,arg[4],parent))
+ {
+ string name=arg[0];
+ int num=toInt(arg[1]);
+ double ms=toDouble(arg[2]);
+ double ms_i=toDouble(arg[3]);
+ double dist=toDouble(arg[5]);
+ double dist_i=toDouble(arg[6]);
+ double ang=toDouble(arg[7]);
+ double ang_i=toDouble(arg[8]);
+ double spd=toDouble(arg[9]);
+ double spd_i=toDouble(arg[10]);
+ GLfloat r=toGLfloat(arg[11]);
+ GLfloat g=toGLfloat(arg[12]);
+ GLfloat b=toGLfloat(arg[13]);
+ double rot=toDouble(arg[14]);
+
+ int f;
+
+ for(f=0;f<num;f++)
+ {
+ genRadial(&nm,parent,
+ makeName(name,f+1),ms,
+ dist,ang,spd,
+ r,g,b,
+ rot);
+
+ ms+=ms_i;
+ dist+=dist_i;
+ ang+=ang_i;
+ spd+=spd_i;
+
+ if (mass.size()<m_max_mass)
+ mass.push_back(*nm);
+
+ delete nm;
+ }
+ }
+ else
+ {
+ m_error="Unknown parent in multiple : " + arg[4];
+ throw m_error;
+ }
+ break;
+
+ case light_cmd:
+ m_light=arg[0];
+ m_lr=toGLfloat(arg[1]);
+ m_lg=toGLfloat(arg[2]);
+ m_lb=toGLfloat(arg[3]);
+ break;
+
+ case camera_cmd:
+ m_x=toGLfloat(arg[0]);
+ m_y=toGLfloat(arg[1]);
+ m_z=toGLfloat(arg[2]);
+ m_yaw=toGLfloat(arg[3]);
+ break;
+
+ case look_cmd:
+ if (findMass(mass,arg[0],parent))
+ m_look.push_back(arg[0]);
+ else
+ {
+ m_error="Unknown object in look : " + arg[0];
+ throw m_error;
+ }
+ break;
+
+ case mlook_cmd:
+ {
+ int num=toInt(arg[1]);
+ string name=arg[0];
+ int f;
+
+ for(f=0;f<num;f++)
+ {
+ string ss;
+
+ ss=makeName(name,f+1);
+
+ if (findMass(mass,ss,idx))
+ {
+ m_look.push_back(ss);
+ }
+ else
+ {
+ m_error="Unknown object in mlook : " + ss;
+ throw m_error;
+ }
+ }
+ }
+ break;
+
+ case texture_cmd:
+ if (!m_glid)
+ {
+ m_error="texture used without preceeding num_texture";
+ throw m_error;
+ }
+
+ if (findMass(mass,arg[0],idx))
+ {
+ if (m_glid_no==m_glid_idx)
+ {
+ m_error="more textures than expected";
+ throw m_error;
+ }
+
+ GLuint id=m_glid[m_glid_idx++];
+
+ if (bindTexture(arg[1],toInt(arg[2]),toInt(arg[3]),id))
+ mass[idx].setTexture(id);
+ else
+ {
+ m_error="Failed to bind texture : " + m_error;
+ throw m_error;
+ }
+ }
+ else
+ {
+ m_error="Unknown object in texture : " + arg[0];
+ throw m_error;
+ }
+ break;
+
+ case num_texture_cmd:
+ if (m_glid)
+ {
+ m_error="num_texture used more than once";
+ throw m_error;
+ }
+
+ m_glid_no=toInt(arg[0]);
+ m_glid=new GLuint[m_glid_no];
+ glGenTextures(m_glid_no,m_glid);
+
+ break;
+
+ case reuse_cmd:
+ if (findMass(mass,arg[0],idx))
+ {
+ if (findMass(mass,arg[1],parent))
+ {
+ GLuint id;
+
+ if (parent.getTexture(id) ||
+ parent.getRingTexture(id))
+ mass[idx].setTexture(id);
+ else
+ {
+ m_error="reuse object has no texture : " +
+ arg[1];
+ throw m_error;
+ }
+ }
+ else
+ {
+ m_error="Unknown object in reuse : " + arg[1];
+ throw m_error;
+ }
+ }
+ else
+ {
+ m_error="Unknown object in reuse : " + arg[0];
+ throw m_error;
+ }
+ break;
+
+ case mreuse_cmd:
+ if (findMass(mass,arg[2],parent))
+ {
+ int num=toInt(arg[1]);
+ string name=arg[0];
+ int f;
+
+ for(f=0;f<num;f++)
+ {
+ string ss=makeName(name,f+1);
+
+ if (findMass(mass,ss,idx))
+ {
+ GLuint id;
+
+ if (parent.getTexture(id) ||
+ parent.getRingTexture(id))
+ mass[idx].setTexture(id);
+ else
+ {
+ m_error="mreuse object has no texture : " +
+ arg[2];
+ throw m_error;
+ }
+ }
+ else
+ {
+ m_error="Unknown object in mreuse : " + ss;
+ throw m_error;
+ }
+ }
+ }
+ else
+ {
+ m_error="Unknown object in mreuse : " + arg[2];
+ throw m_error;
+ }
+ break;
+
+ case ring_cmd:
+ if (findMass(mass,arg[0],idx))
+ {
+ mass[idx].setRing(toDouble(arg[1]),toDouble(arg[2]),
+ toGLfloat(arg[3]),
+ toGLfloat(arg[4]),
+ toGLfloat(arg[5]),
+ toGLfloat(arg[6]),
+ toDouble(arg[7]),
+ toDouble(arg[8]));
+ }
+ else
+ {
+ m_error="Unknown object in ring : " + arg[0];
+ throw m_error;
+ }
+ break;
+
+ case mring_cmd:
+ {
+ int num=toInt(arg[1]);
+ string name=arg[0];
+ int f;
+
+ for(f=0;f<num;f++)
+ {
+ string ss=makeName(name,f+1);
+
+ if (findMass(mass,ss,idx))
+ {
+ mass[idx].setRing(toDouble(arg[2]),toDouble(arg[3]),
+ toGLfloat(arg[4]),
+ toGLfloat(arg[5]),
+ toGLfloat(arg[6]),
+ toGLfloat(arg[7]),
+ toDouble(arg[8]),
+ toDouble(arg[9]));
+ }
+ else
+ {
+ m_error="Unknown object in mring : " + ss;
+ throw m_error;
+ }
+ }
+ }
+ break;
+
+ case ring_texture_cmd:
+ if (!m_glid)
+ {
+ m_error="ring used without preceeding num_texture";
+ throw m_error;
+ }
+
+ if (findMass(mass,arg[0],idx))
+ {
+ if (m_glid_no==m_glid_idx)
+ {
+ m_error="more textures than expected";
+ throw m_error;
+ }
+
+ GLuint id=m_glid[m_glid_idx++];
+
+ if (bindTexture(arg[1],toInt(arg[2]),toInt(arg[3]),id))
+ mass[idx].setRingTexture(id);
+ else
+ {
+ m_error="Failed to bind texture : " + m_error;
+ throw m_error;
+ }
+ }
+ else
+ {
+ m_error="Unknown object in ring : " + arg[0];
+ throw m_error;
+ }
+ break;
+
+ case ring_reuse_cmd:
+ if (findMass(mass,arg[0],idx))
+ {
+ if (findMass(mass,arg[1],parent))
+ {
+ GLuint id;
+
+ if (parent.getRingTexture(id) ||
+ parent.getTexture(id))
+ mass[idx].setRingTexture(id);
+ else
+ {
+ m_error="ring_reuse object has no texture : " +
+ arg[1];
+ throw m_error;
+ }
+ }
+ else
+ {
+ m_error="Unknown object in ring_reuse : " + arg[1];
+ throw m_error;
+ }
+ }
+ else
+ {
+ m_error="Unknown object in ring_reuse : " + arg[0];
+ throw m_error;
+ }
+ break;
+
+ case ring_mreuse_cmd:
+ if (findMass(mass,arg[2],parent))
+ {
+ int num=toInt(arg[1]);
+ string name=arg[0];
+ int f;
+
+ for(f=0;f<num;f++)
+ {
+ string ss=makeName(name,f+1);
+
+ if (findMass(mass,ss,idx))
+ {
+ GLuint id;
+
+ if (parent.getRingTexture(id) ||
+ parent.getTexture(id))
+ mass[idx].setRingTexture(id);
+ else
+ {
+ m_error="ring_mreuse object has "
+ "no texture : " + arg[2];
+ throw m_error;
+ }
+ }
+ else
+ {
+ m_error="Unknown object in ring_mreuse : " + ss;
+ throw m_error;
+ }
+ }
+ }
+ else
+ {
+ m_error="Unknown object in ring_mreuse : " + arg[2];
+ throw m_error;
+ }
+ break;
+
+ case particles_cmd:
+ m_particles=true;
+ m_p_adec=toGLfloat(arg[0]);
+ m_p_amin=toGLfloat(arg[1]);
+ m_p_size=toGLfloat(arg[2]);
+ break;
+
+ case plane_cmd:
+ f=0;
+ found=false;
+ while(enum_list[f].token!="")
+ {
+ if (enum_list[f].cmd==plane_cmd &&
+ CompareNoCase(enum_list[f].token,arg[0]))
+ {
+ found=true;
+ m_plane=static_cast<Plane>(enum_list[f].val);
+ break;
+ }
+ f++;
+ }
+
+ if (!found)
+ {
+ m_error="Illegal argument to plane : " + arg[0];
+ throw m_error;
+ }
+
+ break;
+
+ case shatter_cmd:
+ m_s_no=toInt(arg[0]);
+ m_s_delta=toDouble(arg[1]);
+ m_s_min=toDouble(arg[2]);
+ m_s_max=toDouble(arg[3]);
+ m_s_shield=toInt(arg[4]);
+ break;
+
+ case scale_cmd:
+ m_scale=toDouble(arg[0]);
+ break;
+
+ case look_at_cmd:
+ found=false;
+
+ for(sidx=0;sidx<m_look.size();sidx++)
+ if (m_look[sidx]==arg[0])
+ {
+ m_look_at=sidx;
+ found=true;
+ }
+
+ if (!found)
+ {
+ m_error="Illegal argument to look_at : " + arg[0];
+ throw m_error;
+ }
+ break;
+
+ case travel_as_cmd:
+ found=false;
+
+ for(sidx=0;sidx<m_look.size();sidx++)
+ if (m_look[sidx]==arg[0])
+ {
+ m_travel_as=sidx;
+ found=true;
+ }
+
+ if (!found)
+ {
+ m_error="Illegal argument to travel_as : " + arg[0];
+ throw m_error;
+ }
+ break;
+
+ case window_size_cmd:
+ m_winw=toInt(arg[0]);
+ m_winh=toInt(arg[1]);
+ break;
+
+ case sparks_cmd:
+ m_sparks=true;
+ m_sp_no=toInt(arg[0]);
+ m_sp_adec=toGLfloat(arg[1]);
+ m_sp_amin=toGLfloat(arg[2]);
+ m_sp_length=toInt(arg[3]);
+ m_sp_delta=toGLfloat(arg[4]);
+ break;
+
+ case max_mass_cmd:
+ m_max_mass=toInt(arg[0]);
+ break;
+
+ case fog_cmd:
+ m_flag[fog]=true;
+ m_fog_dist=toGLfloat(arg[0]);
+ m_fog_r=toGLfloat(arg[1]);
+ m_fog_g=toGLfloat(arg[2]);
+ m_fog_b=toGLfloat(arg[3]);
+ m_fog_light=toYesNo(arg[4]);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ catch(...)
+ {
+ file.close();
+ return false;
+ }
+
+ if (cmd==cmd_eof)
+ {
+ file.close();
+ return true;
+ }
+ else
+ return false;
+}
+
+void Config::getCamera(GLfloat& x, GLfloat& y, GLfloat& z, GLfloat& yaw) const
+{
+ x=m_x;
+ y=m_y;
+ z=m_z;
+ yaw=m_yaw;
+}
+
+bool Config::enabled(Config::Flag flag) const
+{
+ return m_flag[flag];
+}
+
+Config::Collide Config::collide() const
+{
+ return m_collide;
+}
+
+string Config::light(GLfloat v[4]) const
+{
+ v[0]=m_lr;
+ v[1]=m_lg;
+ v[2]=m_lb;
+ v[3]=1.0f;
+ return m_light;
+}
+
+double Config::gravConst() const
+{
+ return m_const;
+}
+
+double Config::scale() const
+{
+ return m_scale;
+}
+
+void Config::look(vector<string>& l) const
+{
+ l=m_look;
+}
+
+bool Config::particlesDefined() const
+{
+ return m_particles;
+}
+
+void Config::getParticles(GLfloat& alpha_dec, GLfloat& alpha_min,
+ GLfloat& size ) const
+{
+ alpha_dec=m_p_adec;
+ alpha_min=m_p_amin;
+ size=m_p_size;
+}
+
+void Config::getLookAndTravel(int& look, int &travel) const
+{
+ look=m_look_at;
+ travel=m_travel_as;
+}
+
+void Config::getShatter(int& num, double& delta,
+ double& min_mass, double& max_mass, int& shield) const
+{
+ num=m_s_no;
+ delta=m_s_delta;
+ min_mass=m_s_min;
+ max_mass=m_s_max;
+ shield=m_s_shield;
+}
+
+
+bool Config::sparksDefined() const
+{
+ return m_sparks;
+}
+
+
+void Config::getSparks(int& num, GLfloat& alpha_dec, GLfloat& alpha_min,
+ int& length, GLfloat& delta) const
+{
+ num=m_sp_no;
+ alpha_dec=m_sp_adec;
+ alpha_min=m_sp_amin;
+ length=m_sp_length;
+ delta=m_sp_delta;
+}
+
+
+size_t Config::maxMass() const
+{
+ return m_max_mass;
+}
+
+
+void Config::getFog(GLfloat& dist, GLfloat& r, GLfloat& g, GLfloat& b,
+ bool& fog_light)
+{
+ dist=m_fog_dist;
+ r=m_fog_r;
+ g=m_fog_g;
+ b=m_fog_b;
+ fog_light=m_fog_light;
+}
+
+void Config::windowSize(int& w, int& h) const
+{
+ w=m_winw;
+ h=m_winh;
+}
+
+
+string Config::error() const
+{
+ return m_error;
+}
+
+
+// ---------------------------------------- PRIVATE MEMBERS
+//
+bool Config::CompareNoCase(const string& s1, const string& s2)
+{
+ const char *p1,*p2;
+
+ p1=s1.c_str();
+ p2=s2.c_str();
+
+ while((*p1)&&(tolower(*p1)==tolower(*p2)))
+ {
+ p1++;
+ p2++;
+ }
+
+ if (tolower(*p1)-tolower(*p2))
+ return false;
+ else
+ return true;
+}
+
+
+Config::GetWordStatus Config::getWord(ifstream& file, string& word,
+ const string& ignore, const string& term)
+{
+ bool done=false;
+ bool in_word=false;
+ bool in_comment=false;
+ string not_allowed;
+ char c;
+
+ if (term==";")
+ not_allowed=",";
+ else if (term==",")
+ not_allowed=";";
+ else
+ not_allowed=",;";
+
+ word="";
+
+ while(!done)
+ {
+ file.get(c);
+
+ if (file.eof())
+ return GWEof;
+
+ if (in_comment)
+ {
+ if (c=='\n')
+ in_comment=false;
+ }
+ else
+ {
+ if (c=='#')
+ in_comment=true;
+ else
+ if (in_word)
+ {
+ bool at_term=(term.find(c)!=string::npos);
+ bool in_error=(not_allowed.find(c)!=string::npos);
+
+ if (in_error)
+ {
+ if (term==",")
+ return GWTooFewArgs;
+ else if (term==";")
+ return GWTooManyArgs;
+ else
+ return GWSyntax;
+ }
+
+ if (at_term)
+ done=true;
+ else
+ if (c!='\n')
+ word+=c;
+ }
+ else
+ {
+ bool in_ignore=(ignore.find(c)!=string::npos);
+
+ if (!in_ignore)
+ {
+ word+=c;
+ in_word=true;
+ }
+ }
+ }
+ }
+
+ return GWOK;
+}
+
+
+bool Config::getCommand(ifstream& file, Config::Command& cmd,
+ vector<string>& arg)
+{
+ static struct
+ {
+ string cmd;
+ Command token;
+ int args;
+ } cmd_list[]=
+ {
+ {"enable",enable_cmd,1},
+ {"disable",disable_cmd,1},
+ {"collide",collide_cmd,1},
+ {"const",const_cmd,1},
+ {"body",body_cmd,12},
+ {"radial",radial_cmd,10},
+ {"light",light_cmd,4},
+ {"camera",camera_cmd,4},
+ {"look",look_cmd,1},
+ {"texture",texture_cmd,4},
+ {"num_texture",num_texture_cmd,1},
+ {"reuse",reuse_cmd,2},
+ {"particles",particles_cmd,3},
+ {"shatter",shatter_cmd,5},
+ {"multiple",multiple_cmd,15},
+ {"mreuse",mreuse_cmd,3},
+ {"plane",plane_cmd,1},
+ {"scale",scale_cmd,1},
+ {"look_at",look_at_cmd,1},
+ {"travel_as",travel_as_cmd,1},
+ {"window_size",window_size_cmd,2},
+ {"sparks",sparks_cmd,5},
+ {"max_mass",max_mass_cmd,1},
+ {"mlook",mlook_cmd,2},
+ {"ring",ring_cmd,9},
+ {"mring",mring_cmd,10},
+ {"ring_texture",ring_texture_cmd,4},
+ {"ring_reuse",ring_reuse_cmd,2},
+ {"ring_mreuse",ring_mreuse_cmd,3},
+ {"fog",fog_cmd,5},
+ {"",cmd_error,1}
+ };
+
+ string word;
+ string cmd_string;
+ int expect;
+ int f;
+
+ switch (getWord(file,word," \t\n"," \t\n"))
+ {
+ case GWEof:
+ cmd=cmd_eof;
+ return false;
+ case GWSyntax:
+ m_error="Syntax error in command " + word;
+ return false;
+ default:
+ break;
+ }
+
+ f=0;
+ cmd=cmd_error;
+
+ while(cmd_list[f].cmd!="")
+ {
+ if (CompareNoCase(cmd_list[f].cmd,word))
+ {
+ cmd_string=word;
+ cmd=cmd_list[f].token;
+ expect=cmd_list[f].args;
+ break;
+ }
+
+ f++;
+ }
+
+ if (cmd==cmd_error)
+ {
+ m_error="Unrecognised command " + word;
+ return false;
+ }
+
+ arg.clear();
+
+ for(f=0;f<expect;f++)
+ {
+ string error;
+
+ switch (getWord(file,word," \t\n",(f==expect-1) ? ";" : ","))
+ {
+ case GWOK:
+ break;
+
+ case GWTooManyArgs:
+ cmd=cmd_error;
+ m_error="Too many arguments in " + cmd_string;
+ return false;
+
+ case GWTooFewArgs:
+ cmd=cmd_error;
+ m_error="Too few arguments in " + cmd_string;
+ return false;
+
+ case GWEof:
+ cmd=cmd_error;
+ m_error="Unexpected EOF in " + cmd_string;
+ return false;
+
+ case GWSyntax:
+ cmd=cmd_error;
+ m_error="Syntax error in " + cmd_string;
+ return false;
+ }
+
+ arg.push_back(word);
+ }
+
+ return true;
+}
+
+double Config::toDouble(const string& s)
+{
+ double r;
+ char *p;
+
+ r=strtod(s.c_str(),&p);
+
+ if (*p)
+ {
+ m_error="Invalid floating point number : " + s;
+ throw m_error;
+ }
+
+ return r;
+}
+
+
+GLfloat Config::toGLfloat(const string& s)
+{
+ return static_cast<GLfloat>(toDouble(s));
+}
+
+
+int Config::toInt(const string& s)
+{
+ int i;
+ char *p;
+
+ i=static_cast<int>(strtol(s.c_str(),&p,0));
+
+ if (*p)
+ {
+ m_error="Invalid integer : " + s;
+ throw m_error;
+ }
+
+ return i;
+}
+
+
+size_t Config::toSize(const string& s)
+{
+ size_t i;
+ char *p;
+
+ i=static_cast<size_t>(strtol(s.c_str(),&p,0));
+
+ if (*p)
+ {
+ m_error="Invalid integer : " + s;
+ throw m_error;
+ }
+
+ return i;
+}
+
+
+bool Config::toYesNo(const string& s)
+{
+ if (s!="yes" && s!="no")
+ {
+ m_error="Invalid yes/no : " + s;
+ throw m_error;
+ }
+
+ return s=="yes";
+}
+
+
+bool Config::bindTexture(const string& name, int w, int h, GLuint id)
+{
+ FILE *fp;
+ ifstream file(name.c_str());
+ GLubyte *mem;
+ int x,y;
+
+ if (!(fp=fopen(name.c_str(),"r")))
+ {
+ m_error="file " + name + " not found";
+ return false;
+ }
+
+ mem=new GLubyte[w*h*3];
+
+ for(y=0;y<h;y++)
+ for(x=w-1;x>=0;x--)
+ {
+ mem[x*3+y*w*3]=fgetc(fp);
+ mem[x*3+y*w*3+1]=fgetc(fp);
+ mem[x*3+y*w*3+2]=fgetc(fp);
+
+ if (feof(fp))
+ {
+ fclose(fp);
+ m_error="file " + name + " to short";
+ delete[] mem;
+ return false;
+ }
+ }
+
+ fclose(fp);
+
+ glBindTexture(GL_TEXTURE_2D,id);
+ glTexImage2D(GL_TEXTURE_2D,0,3,w,h,0,GL_RGB,GL_UNSIGNED_BYTE,mem);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
+
+ delete[] mem;
+
+ return true;
+}
+
+void Config::genRadial(Mass **newMass, const Mass& parent,
+ const string& name, double mass,
+ double dist, double ang, double spd,
+ GLfloat r, GLfloat g, GLfloat b, double rot)
+{
+ double px,py,pz;
+ double pdx,pdy,pdz;
+ double ox,oy,oz;
+ double dx,dy,dz;
+
+ parent.getPosition(px,py,pz);
+ parent.getDelta(pdx,pdy,pdz);
+
+ switch(m_plane)
+ {
+ case xy_plane:
+ ox=px+dist*sin(ang);
+ oy=py-dist*cos(ang);
+ oz=pz;
+ ang+=RAD(90);
+ dx=spd*sin(ang);
+ dy=-spd*cos(ang);
+ dz=0.0;
+ break;
+
+ case xz_plane:
+ ox=px+dist*sin(ang);
+ oy=py;
+ oz=pz-dist*cos(ang);
+ ang+=RAD(90);
+ dx=spd*sin(ang);
+ dy=0.0;
+ dz=-spd*cos(ang);
+ break;
+
+ case yz_plane:
+ ox=px;
+ oy=py+dist*sin(ang);
+ oz=pz-dist*cos(ang);
+ ang+=RAD(90);
+ dx=0.0;
+ dy=spd*sin(ang);
+ dz=-spd*cos(ang);
+ break;
+
+ default:
+ m_error="INTERNAL ERROR: invalid plane defined";
+ throw m_error;
+ }
+
+ dx+=pdx;
+ dy+=pdy;
+ dz+=pdz;
+
+ *newMass=new Mass(name, mass, m_scale, ox,oy,oz, dx,dy,dz, r,g,b,rot);
+}
+
+
+string Config::makeName(string& name, int no)
+{
+ char s[1024];
+ string n;
+
+ sprintf(s,"%s %d",name.c_str(),no);
+ n=s;
+
+ return n;
+}
+
+
+// END OF FILE //