00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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;
00085 char drive;
00086 Directory *dirs;
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
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
00129
00130
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
00153 while (p[i] && (p[i] == '\\' || p[i] == '/')) i++;
00154
00155
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
00173 void Path::AddString(const char *p)
00174 {
00175 int len = std::strlen (p);
00176
00177
00178 if (*p == '\\' || *p == '/')
00179 {
00180
00181 RemoveAll();
00182
00183 p++;
00184
00185
00186 if (*p == '\\')
00187 {
00188 network = true;
00189 p++;
00190 }
00191
00192 }
00193 else if (p[0] && p[1] == ':')
00194 {
00195 RemoveAll();
00196 drive = *p;
00197 network = false;
00198 p+= 2;
00199 }
00200
00201
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
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
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
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
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