exconfig.cpp

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2000-2002  Ryan Nunn
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 /*
00020  *  What is this?
00021  *
00022  *  EXCONFIG is a dll that is used by the InstallShield Wizard to get and set the
00023  *  Black Gate and Serpent Isle paths.
00024  *
00025  */
00026 
00027 #include "stdafx.h"
00028 #include "exconfig.h"
00029 #include "Configuration.h"
00030 #include <string>
00031 
00032 #define MAX_STRLEN  512
00033 
00034 #ifdef _DEBUF
00035 #define MessageBoxDebug(a,b,c,d) MessageBox(a,b,c,d);
00036 #else
00037 #define MessageBoxDebug(a,b,c,d)
00038 #endif
00039 
00040 const std::string c_empty_string;
00041 
00042 char *config_defaults[] =
00043 {
00044   "config/disk/game/blackgate/keys",  "(default)",
00045   "config/disk/game/blackgate/waves", "jmsfx.flx",
00046   "config/disk/game/serpentisle/keys",  "(default)",
00047   "config/disk/game/serpentisle/waves", "jmsisfx.flx",
00048   "config/audio/enabled",     "yes",
00049   "config/audio/effects/enabled",   "yes",
00050   "config/audio/effects/convert",   "gs",
00051   "config/audio/midi/enabled",    "yes",
00052   "config/audio/midi/convert",    "gm",
00053   "config/audio/midi/reverb/enabled", "no",
00054   "config/audio/midi/reverb/level", "0",
00055   "config/audio/midi/chorus/enabled", "no",
00056   "config/audio/midi/chorus/level", "0",
00057   "config/audio/midi/volume_curve", "1.000000",
00058   "config/audio/speech/enabled",    "yes",
00059   "config/gameplay/cheat",    "yes",
00060   "config/gameplay/skip_intro",   "no",
00061   "config/gameplay/skip_splash",    "no",
00062   "config/video/width",     "320",
00063   "config/video/height",      "200",
00064   "config/video/scale",     "2",
00065   "config/video/scale_method",    "2xSaI",
00066   "config/video/fullscreen",    "no",
00067   "config/video/disable_fades",   "no",
00068   "config/video/gamma/red",   "1.00",
00069   "config/video/gamma/green",   "1.00",
00070   "config/video/gamma/blue",    "1.00",
00071   0
00072 };
00073 
00074 class Path
00075 {
00076   struct Directory
00077   {
00078     char    name[256];
00079     Directory *next;
00080 
00081     Directory() : next(0) { name[0] = 0; }
00082   };
00083 
00084   bool    network;// Networked?
00085   char    drive;  // Drive letter (if set)
00086   Directory *dirs;  // Directories
00087 
00088   void RemoveAll();
00089   int Addit(const char* p);
00090 public:
00091 
00092   Path() : network(false), drive(0), dirs(0) { }
00093   Path(const char* p) : network(false), drive(0), dirs(0) { AddString(p); }
00094   ~Path();
00095 
00096   void RemoveLast() { Addit(".."); }
00097   void AddString(const char* p);
00098   void GetString(char p[MAX_STRLEN]);
00099 
00100 };
00101 
00102 // Destructor
00103 Path::~Path()
00104 {
00105   RemoveAll();
00106   network = false;
00107   drive = 0;
00108 }
00109 
00110 void Path::RemoveAll()
00111 {
00112   Directory *d = dirs;
00113   while (d)
00114   {
00115     Directory *next = d->next;
00116     delete d;
00117     d = next;
00118   }
00119   dirs = 0;
00120 }
00121 
00122 int Path::Addit(const char* p)
00123 {
00124   Directory *d = dirs;
00125   Directory *prev = 0;
00126   Directory *prevprev = 0;
00127 
00128   // Check for . and ..
00129 
00130   // Create new
00131   if (!d)
00132   {
00133     dirs = d = new Directory;
00134   }
00135   else
00136   {
00137     while (d->next)
00138     {
00139       prevprev = d;
00140       d = d->next;
00141     }
00142     d->next = new Directory;
00143     prev = d;
00144     d = d->next;
00145   }
00146 
00147   for (int i = 0; p[i] != 0 && p[i] != '\\' && p[i] != '/'; i++)
00148     d->name[i] = p[i];
00149 
00150   d->name[i] = 0;
00151 
00152   // Skip all 'slashes'
00153   while (p[i] && (p[i] == '\\' || p[i] == '/')) i++;
00154 
00155   // Check for . and ..
00156   if (!std::strcmp(d->name, "."))
00157   {
00158     delete d;
00159     prev->next = 0;
00160   }
00161   else if (!std::strcmp(d->name, ".."))
00162   {
00163     delete d;
00164     delete prev;
00165     prevprev->next = 0;
00166 
00167   }
00168 
00169   return i;
00170 }
00171 
00172 // Add path
00173 void Path::AddString(const char *p)
00174 {
00175   int len = std::strlen (p);
00176 
00177   // Root dir of this drive
00178   if (*p == '\\' || *p == '/')
00179   {
00180     // Remove all the entires
00181     RemoveAll();
00182 
00183     p++;
00184 
00185     // Could be network drive
00186     if (*p == '\\')
00187     {
00188       network = true;
00189       p++;
00190     }
00191 
00192   }
00193   else if (p[0] && p[1] == ':') // Drive
00194   {
00195     RemoveAll();
00196     drive = *p;
00197     network = false;
00198     p+= 2;
00199   }
00200 
00201   // Skip all slashes
00202   while (*p && (*p == '\\' || *p == '/')) p++;
00203 
00204   while (*p)
00205   {
00206     p+= Addit(p);
00207   }
00208 }
00209 
00210 void Path::GetString(char p[MAX_STRLEN])
00211 {
00212   p[0] = 0;
00213 
00214   if (network) std::strncat(p, "\\\\", MAX_STRLEN);
00215   else if (drive) _snprintf (p, MAX_STRLEN, "%c:\\", drive);
00216   else std::strncat(p, "\\", MAX_STRLEN);
00217 
00218   Directory *d = dirs;
00219   while (d)
00220   {
00221     std::strncat (p, d->name, MAX_STRLEN);
00222     d = d->next;
00223     if (d) std::strncat(p, "\\", MAX_STRLEN);
00224   }
00225 
00226 }
00227 // The exports
00228 
00229 #ifdef __cplusplus
00230 extern "C" {
00231 #endif
00232 
00233 EXCONFIG_API LONG APIENTRY GetPaths(HWND hwnd, LPLONG lpIValue, LPSTR lpszValue)
00234 {
00235   Path  path(lpszValue);
00236 
00237   char p[MAX_STRLEN];
00238 
00239   path.AddString("exult.cfg");
00240   path.GetString(p);
00241 
00242   char *si_pathdef = "";
00243   char *bg_pathdef = "";
00244 
00245   MessageBoxDebug (hwnd, lpszValue, p, MB_OK);
00246 
00247   try
00248   {
00249     //chdir (lpszValue);
00250     Configuration config;
00251     config.read_config_file(p);
00252 
00253     std::string data_directory;
00254 
00255     config.value("config/disk/game/serpentisle/path",data_directory,si_pathdef);
00256     if (data_directory != si_pathdef)
00257     {
00258       path.~Path();
00259       path.AddString(lpszValue);
00260       path.AddString(data_directory.c_str());
00261       path.GetString(p);
00262     }
00263     else
00264     {
00265       std::strncpy (p, si_pathdef, MAX_STRLEN);
00266     }
00267 
00268     config.value("config/disk/game/blackgate/path",data_directory,bg_pathdef);
00269     if (data_directory != bg_pathdef)
00270     {
00271       path.~Path();
00272       path.AddString(lpszValue);
00273       path.AddString(data_directory.c_str());
00274       path.GetString(lpszValue);
00275     }
00276     else
00277     {
00278       std::strncpy (lpszValue, bg_pathdef, MAX_STRLEN);
00279     }
00280 
00281     std::strncat(lpszValue, "\n", MAX_STRLEN);
00282     std::strncat(lpszValue, p, MAX_STRLEN);
00283 
00284     MessageBoxDebug (hwnd, lpszValue, data_directory.c_str(), MB_OK);
00285   }
00286   catch(...)
00287   {
00288     std::strncpy(lpszValue, bg_pathdef, MAX_STRLEN);
00289     std::strncat(lpszValue, "\n", MAX_STRLEN);
00290     std::strncat(lpszValue, si_pathdef, MAX_STRLEN);
00291   }
00292   return 0;
00293 }
00294 
00295 EXCONFIG_API LONG APIENTRY WriteConfig(HWND hwnd, LPLONG lpIValue, LPSTR lpszValue)
00296 {
00297   MessageBoxDebug (hwnd, lpszValue, "WriteConfig", MB_OK);
00298 
00299   int len = std::strlen (lpszValue);
00300   char *p = new char [len+1];
00301   int i, j, bgstart, sistart;
00302 
00303   for (i = 0; i < len && lpszValue[i] != '\n'; i++) p[i] = lpszValue[i];
00304   p[i] = 0;
00305   bgstart = i+1;
00306 
00307   Path  path(p);
00308 
00309   path.AddString("exult.cfg");
00310   path.GetString(p);
00311   MessageBoxDebug (hwnd, p, "WriteConfig: p", MB_OK);
00312 
00313   try
00314   {
00315     //chdir (lpszValue);
00316     Configuration config;
00317     config.read_config_file(p);
00318 
00319     for (j = 0, i = bgstart; i < len && lpszValue[i] != '\n'; j++, i++) p[j] = lpszValue[i];
00320     p[j] = 0;
00321     sistart = i+1;
00322     if (j > 1 && p[j-1] == '\\') p[j-1] = 0;
00323 
00324     MessageBoxDebug (hwnd, p, "WriteConfig: BG", MB_OK);
00325     config.set("config/disk/game/blackgate/path", p, true);
00326 
00327     for (j = 0, i = sistart ; i < len && lpszValue[i]; j++, i++) p[j] = lpszValue[i];
00328     p[j] = 0;
00329     if (j > 1 && p[j-1] == '\\') p[j-1] = 0;
00330 
00331     MessageBoxDebug (hwnd, p, "WriteConfig: SI", MB_OK);
00332     config.set("config/disk/game/serpentisle/path", p, true);
00333 
00334     std::string s;
00335     for (i = 0; config_defaults[i]; i+=2)
00336     {
00337       config.value(config_defaults[i], s, "");
00338       if (s.empty()) config.set(config_defaults[i], config_defaults[i+1], true);
00339     }
00340 
00341     // Fix broken SI SFX stuff
00342     config.value("config/disk/game/serpentisle/waves", s, "");
00343 
00344     const char *si_sfx = s.c_str();
00345     int slen = std::strlen(si_sfx);
00346     slen -= std::strlen ("jmsfxsi.flx");
00347 
00348     if (slen >= 0 && !std::strcmp(si_sfx+slen, "jmsfxsi.flx"))
00349     {
00350       char *fixed = new char[slen+1];
00351       std::strncpy (fixed, si_sfx, slen);
00352       fixed[slen] = 0;
00353       s = fixed;
00354       s += "jmsisfx.flx";
00355 
00356       config.set("config/disk/game/serpentisle/waves", s, true);
00357     }
00358 
00359     config.write_back();
00360   }
00361   catch(...)
00362   {
00363   }
00364 
00365   delete [] p;
00366   return 0;
00367 }
00368 
00369 EXCONFIG_API LONG APIENTRY LaunchApp(HWND hwnd, LPLONG lpIValue, LPSTR lpszValue)
00370 {
00371   Path      path(lpszValue);
00372   char      p[MAX_STRLEN];
00373   PROCESS_INFORMATION pi;
00374   STARTUPINFO   si;
00375 
00376   path.RemoveLast();
00377   path.GetString(p);
00378 
00379   std::memset (&si, 0, sizeof(si));
00380   si.cb = sizeof(si);
00381 
00382   MessageBoxDebug(hwnd, lpszValue, "LaunchApp", MB_OK);
00383 
00384   CreateProcess (NULL, lpszValue, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL,
00385     *lpIValue==1?p:NULL, &si, &pi);
00386 
00387         return 0;
00388 }
00389 
00390 #ifdef __cplusplus
00391 }
00392 #endif
00393 
00394 BOOL APIENTRY DllMain( HANDLE hModule, 
00395                        DWORD  ul_reason_for_call, 
00396                        LPVOID lpReserved
00397            )
00398 {
00399     switch (ul_reason_for_call)
00400   {
00401     case DLL_PROCESS_ATTACH:
00402     case DLL_THREAD_ATTACH:
00403     case DLL_THREAD_DETACH:
00404     case DLL_PROCESS_DETACH:
00405       break;
00406     }
00407     return TRUE;
00408 }
00409 

Generated on Mon Jul 9 14:42:48 2007 for ExultEngine by  doxygen 1.5.1