//----------------------------------------------------------------------------- // Torque Game Engine // Copyright (C) GarageGames.com, Inc. //----------------------------------------------------------------------------- #ifdef _MSC_VER #pragma warning(disable : 4786) #endif #include "appConfig.h" #include "appNode.h" namespace DTS { static AppConfig gAppConfig; AppConfig * AppConfig::smConfig = &gAppConfig; AppConfig::AppConfig() { setInitialDefaults(); setupConfigParams(); } AppConfig::~AppConfig() { clearConfigLists(); clearConfigParams(); if (smConfig==this) smConfig=&gAppConfig; } void AppConfig::setInitialDefaults() { mEnableSequences = true; mExportOptimized = true; mAllowUnusedMeshes = true; mAllowCollapseTransform = true; mNoMipMap = false; mNoMipMapTranslucent = false; mZapBorder = true; mAnimationDelta = 0.0001f; mSameVertTOL = 0.00005f; mSameNormTOL = 0.005f; mSameVertTOL = 0.00005f; mWeightThreshhold = 0.001f; mWeightsPerVertex = 10; mCyclicSequencePadding = 1.0f / 30.0f; mAppFramesPerSec = 30.0f; mDumpConfig = 0xFFFFFFFF; mErrorString = NULL; clearConfigLists(); } void AppConfig::clearConfigLists() { S32 i; for (i=0; i<mAlwaysExport.size(); i++) delete [] mAlwaysExport[i]; mAlwaysExport.clear(); for (i=0; i<mNeverExport.size(); i++) delete [] mNeverExport[i]; mNeverExport.clear(); for (i=0; i<mNeverAnimate.size(); i++) delete [] mNeverAnimate[i]; mNeverAnimate.clear(); } void AppConfig::setConfig(AppConfig * config) { assert(config != NULL); if (smConfig!=&gAppConfig) delete smConfig; smConfig = config; } bool AppConfig::setDumpFile(const char * path, const char * name) { // open dump file in path specified, with optional name (use dump.dmp by default) // path can include full file name...can also include \,/, or : as path delimitors assert(path && "No path set on dump file"); if (name==NULL) name = "dump.dmp"; char * fullpath = getFilePath(path,strlen(name)+1); strcat(fullpath,name); mDumpFile.open(fullpath,std::ofstream::binary); return mDumpFile.good(); } bool AppConfig::closeDumpFile() { mDumpFile.close(); return true; } void AppConfig::printDump(U32 mask, const char * str) { if (mask && AppConfig::GetDumpMask()) mDumpFile << str; } bool AppConfig::alwaysExport(AppNode * node) { const char * name = node->getName(); for (S32 i=0; i<mAlwaysExport.size(); i++) if (stringEqual(name,mAlwaysExport[i])) return true; return false; } bool AppConfig::neverExport(AppNode * node) { const char * name = node->getName(); for (S32 i=0; i<mNeverExport.size(); i++) if (stringEqual(name,mNeverExport[i])) return true; return false; } bool AppConfig::neverAnimate(AppNode * node) { const char * name = node->getName(); for (S32 i=0; i<mNeverAnimate.size(); i++) if (stringEqual(name,mNeverAnimate[i])) return true; return false; } S32 AppConfig::getParamEntry(const char * name, std::vector<char *> & nameTable) { for (S32 i=0; i<nameTable.size(); i++) { if (!strcmp(name,nameTable[i])) return i; } return -1; } bool AppConfig::searchConfigFile(const char * filename) { const char * ext = strrchr(filename,'.'); if (!ext) ext = ""; // just use filename as base const char * defaultName = "dtsScene.cfg"; const char * pos = filename+strlen(filename)-strlen(ext); char * newname = new char[strlen(filename)+strlen(defaultName)+1]; strcpy(newname,filename); // try using base filename with .cfg suffix strcpy(newname+(pos-filename),".cfg"); if (readConfigFile(newname)) { delete [] newname; return true; } // try using base filename except no number with .cfg suffix do pos--; while (pos>=filename && *pos<='9' && *pos>='0'); pos++; strcpy(newname+(pos-filename),".cfg"); if (readConfigFile(newname)) { delete [] newname; return true; } // try using dtsScene.cfg do pos--; while (pos>=filename && *pos!='\\' && *pos!='/' && *pos!=':'); pos++; strcpy(newname+(pos-filename),defaultName); if (readConfigFile(newname)) { delete [] newname; return true; } // no config file delete [] newname; return false; } bool AppConfig::readConfigFile(const char * filename) { clearConfigLists(); std::ifstream is; is.open(filename); if (!is.is_open()) { printDump(PDAlways,avar("\r\nConfig file \"%s\" not found.\r\n",filename)); return false; } printDump(PDAlways,avar("\r\nBegin reading config file \"%s\".\r\n",filename)); S32 mode = 0; // 0=AlwaysExport:, 1=NeverExport:, 2=NeverAnimate: char buffer[256]; do { is.getline(buffer,sizeof(buffer)); if (stringEqual(buffer,"AlwaysExport:*")) mode = 0; else if (stringEqual(buffer,"NeverExport:*")) mode = 1; else if (stringEqual(buffer,"NeverAnimate:*")) mode = 2; else if (buffer[0]=='+' || buffer[0]=='-') { bool newVal = buffer[0]=='+'; S32 idx = getParamEntry(buffer+1,mBoolParamNames); if (idx>=0) { if (mBoolParamBit[idx]) { if (newVal) *mBoolParams[idx] |= mBoolParamBit[idx]; else *mBoolParams[idx] &= ~mBoolParamBit[idx]; } else *mBoolParams[idx] = newVal; printDump(PDAlways,avar("%s %s.\r\n",mBoolParamNames[idx],newVal ? "enabled" : "disabled")); } else printDump(PDAlways,avar("Unknown bool parameter \"%s\"\r\n",buffer+1)); } else if (buffer[0]=='=') { char * endName = strchr(buffer+1,' '); if (endName) { *endName = '\0'; S32 idx1 = getParamEntry(buffer+1,mFloatParamNames); S32 idx2 = getParamEntry(buffer+1,mStringParamNames); S32 idx3 = getParamEntry(buffer+1,mIntParamNames); if (idx1>=0) { // Float *mFloatParams[idx1] = atof(endName+1); printDump(PDAlways,avar("%s = %f\r\n",mFloatParamNames[idx1],*mFloatParams[idx1])); } if (idx2>=0) { // string S32 maxLen = mStringParamMaxLen[idx2]; strncpy(mStringParams[idx2],endName+1,maxLen-1); mStringParams[idx2][maxLen]='\0'; printDump(PDAlways,avar("%s = \"%s\"\r\n",mStringParamNames[idx2],mStringParams[idx2])); } if (idx3>=0) { // S32 *mIntParams[idx3] = atoi(endName+1); printDump(PDAlways,avar("%s = %i\r\n",mIntParamNames[idx3],*mIntParams[idx3])); } if (idx1<0 && idx2<0 && idx3<0) printDump(PDAlways,avar("Unknown parameter \"%s\"\r\n",buffer+1)); } } else if (buffer[0]!='\\' && buffer[0]!='/' && buffer[0]!=';') { char * name = buffer; while (*name==' ') name++; if (strlen(name)) { if (mode == 0) { mAlwaysExport.push_back(strnew(buffer)); printDump(PDAlways,avar("Always export node: \"%s\"\r\n",buffer)); } else if (mode == 1) { mNeverExport.push_back(strnew(buffer)); printDump(PDAlways,avar("Never export node: \"%s\"\r\n",buffer)); } else if (mode == 2) { mNeverAnimate.push_back(strnew(buffer)); printDump(PDAlways,avar("Never animate transform on node: \"%s\"\r\n",buffer)); } } } } while (is.good()); printDump(PDAlways,"End reading config file.\r\n"); return true; } void AppConfig::writeConfigFile(const char * filename) { S32 i; std::ofstream os; os.open(filename); os << "AlwaysExport:" << std::endl; for (i=0; i<mAlwaysExport.size(); i++) os << mAlwaysExport[i] << std::endl; os << "NeverExport:" << std::endl; for (i=0; i<mNeverExport.size(); i++) os << mNeverExport[i] << std::endl; os << "NeverAnimate:" << std::endl; for (i=0; i<mNeverAnimate.size(); i++) os << mNeverAnimate[i] << std::endl; for (i=0; i<mBoolParamNames.size(); i++) { bool enabled = mBoolParamBit[i] ? (mBoolParamBit[i] & *mBoolParams[i]) != 0 : *mBoolParams[i]!=0; os << (enabled ? "+" : "-") << mBoolParamNames[i] << std::endl; } for (i=0; i<mFloatParamNames.size(); i++) os << mFloatParamNames[i] << "= " << *mFloatParams[i] << std::endl; for (i=0; i<mIntParamNames.size(); i++) os << mIntParamNames[i] << "= " << *mIntParams[i] << std::endl; for (i=0; i<mStringParamNames.size(); i++) os << mStringParamNames[i] << "= " << mStringParams[i] << std::endl; os.close(); } void AppConfig::setupConfigParams() { // add bool config parameters mBoolParamNames.push_back(strnew("Dump::NodeCollection")); mBoolParams.push_back(&mDumpConfig); mBoolParamBit.push_back(PDPass1); mBoolParamNames.push_back(strnew("Dump::ShapeConstruction")); mBoolParams.push_back(&mDumpConfig); mBoolParamBit.push_back(PDPass2); mBoolParamNames.push_back(strnew("Dump::NodeCulling")); mBoolParams.push_back(&mDumpConfig); mBoolParamBit.push_back(PDPass3); mBoolParamNames.push_back(strnew("Dump::NodeStates")); mBoolParams.push_back(&mDumpConfig); mBoolParamBit.push_back(PDNodeStates); mBoolParamNames.push_back(strnew("Dump::NodeStateDetails")); mBoolParams.push_back(&mDumpConfig); mBoolParamBit.push_back(PDNodeStateDetails); mBoolParamNames.push_back(strnew("Dump::ObjectStates")); mBoolParams.push_back(&mDumpConfig); mBoolParamBit.push_back(PDObjectStates); mBoolParamNames.push_back(strnew("Dump::ObjectStateDetails")); mBoolParams.push_back(&mDumpConfig); mBoolParamBit.push_back(PDObjectStateDetails); mBoolParamNames.push_back(strnew("Dump::ObjectOffsets")); mBoolParams.push_back(&mDumpConfig); mBoolParamBit.push_back(PDObjectOffsets); mBoolParamNames.push_back(strnew("Dump::SequenceDetails")); mBoolParams.push_back(&mDumpConfig); mBoolParamBit.push_back(PDSequences); mBoolParamNames.push_back(strnew("Dump::ShapeHierarchy")); mBoolParams.push_back(&mDumpConfig); mBoolParamBit.push_back(PDShapeHierarchy); mBoolParamNames.push_back(strnew("Error::AllowUnusedMeshes")); mBoolParams.push_back((U32*)&mAllowUnusedMeshes); mBoolParamBit.push_back(0); mBoolParamNames.push_back(strnew("Param::CollapseTransforms")); mBoolParams.push_back((U32*)&mAllowCollapseTransform); mBoolParamBit.push_back(0); mBoolParamNames.push_back(strnew("Param::SequenceExport")); mBoolParams.push_back((U32*)&mEnableSequences); mBoolParamBit.push_back(0); mBoolParamNames.push_back(strnew("Materials::NoMipMap")); mBoolParams.push_back((U32*)&mNoMipMap); mBoolParamBit.push_back(0); mBoolParamNames.push_back(strnew("Materials::NoMipMapTranslucent")); mBoolParams.push_back((U32*)&mNoMipMapTranslucent); mBoolParamBit.push_back(0); mBoolParamNames.push_back(strnew("Materials::ZapBorder")); mBoolParams.push_back((U32*)&mZapBorder); mBoolParamBit.push_back(0); // add float config parameters mFloatParamNames.push_back(strnew("Params::AnimationDelta")); mFloatParams.push_back(&mAnimationDelta); mFloatParamNames.push_back(strnew("Params::SkinWeightThreshhold")); mFloatParams.push_back(&mWeightThreshhold); mFloatParamNames.push_back(strnew("Params::SameVertTOL")); mFloatParams.push_back(&mSameVertTOL); mFloatParamNames.push_back(strnew("Params::SameTVertTOL")); mFloatParams.push_back(&mSameTVertTOL); // add int config parameters mIntParamNames.push_back(strnew("Params::weightsPerVertex")); mIntParams.push_back(&mWeightsPerVertex); } void AppConfig::clearConfigParams() { S32 i; for (i=0; i<mBoolParamNames.size(); i++) delete [] mBoolParamNames[i]; for (i=0; i<mFloatParamNames.size(); i++) delete [] mFloatParamNames[i]; for (i=0; i<mIntParamNames.size(); i++) delete [] mIntParamNames[i]; for (i=0; i<mStringParamNames.size(); i++) delete [] mStringParamNames[i]; mBoolParamNames.clear(); mBoolParams.clear(); mBoolParamBit.clear(); mFloatParamNames.clear(); mFloatParams.clear(); mIntParamNames.clear(); mIntParams.clear(); mStringParamNames.clear(); mStringParams.clear(); mStringParamMaxLen.clear(); } }; // namespace DTS