From 99778e9b85bd4a16a9055587a273446068577100 Mon Sep 17 00:00:00 2001 From: Ian C Date: Tue, 2 May 2006 19:12:46 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r2, which included commits to RCS files with non-trunk default branches. --- config.cpp | 1248 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1248 insertions(+) create mode 100644 config.cpp (limited to 'config.cpp') 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 +#include + +#define RAD(x) ((x)*(M_PI/180.0)) + +// ---------------------------------------- CONSTRUCTION/DESTRUCTION +// +Config::Config() +{ + int f; + + m_error=""; + + for(f=0;f& mass) +{ + static struct + { + Command cmd; + string token; + int val; + } enum_list[]= + { + {enable_cmd,"solid",static_cast(solid)}, + {enable_cmd,"lighting",static_cast(lighting)}, + {enable_cmd,"texture",static_cast(texture)}, + {collide_cmd,"none",static_cast(none)}, + {collide_cmd,"merge",static_cast(merge)}, + {collide_cmd,"delta_merge",static_cast(delta_merge)}, + {collide_cmd,"shatter",static_cast(shatter)}, + {plane_cmd,"xy",static_cast(xy_plane)}, + {plane_cmd,"xz",static_cast(xz_plane)}, + {plane_cmd,"yz",static_cast(yz_plane)}, + {cmd_error,"",0} + }; + + Mass parent; + Mass *nm; + Command cmd; + vector arg; + ifstream file(fname.c_str()); + bool found; + int f; + vector::size_type idx; + vector::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(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(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(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()(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& 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& 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(toDouble(s)); +} + + +int Config::toInt(const string& s) +{ + int i; + char *p; + + i=static_cast(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(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=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 // -- cgit v1.2.3