annotate src/win32/WinMiscUtil.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
rev   line source
rlm@1 1 #include "stdafx.h"
rlm@1 2 #include "WinMiscUtil.h"
rlm@1 3 #include "WinResUtil.h"
rlm@1 4 #include "resource.h"
rlm@1 5 #include "../NLS.h"
rlm@1 6 #include "VBA.h"
rlm@1 7 #include "Reg.h"
rlm@1 8 #include "../common/movie.h"
rlm@1 9 #include <direct.h>
rlm@1 10
rlm@1 11 #include "GSACodeSelect.h"
rlm@1 12 #include "../gba/GBACheats.h"
rlm@1 13 #include "../gb/gbCheats.h"
rlm@1 14
rlm@1 15 // #undef WinDef macro garbage
rlm@1 16 #ifdef max
rlm@1 17 #undef max
rlm@1 18 #endif
rlm@1 19
rlm@1 20 #ifdef min
rlm@1 21 #undef min
rlm@1 22 #endif
rlm@1 23
rlm@1 24 using std::max;
rlm@1 25 using std::min;
rlm@1 26
rlm@1 27 extern int emulating;
rlm@1 28
rlm@1 29 extern const char IDS_ROM_DIR[] = "romDir";
rlm@1 30 extern const char IDS_GBXROM_DIR[] = "gbromDir";
rlm@1 31 extern const char IDS_BATTERY_DIR[] = "batteryDir";
rlm@1 32 extern const char IDS_SAVE_DIR[] = "saveDir";
rlm@1 33 extern const char IDS_MOVIE_DIR[] = "moviesDir";
rlm@1 34 extern const char IDS_CHEAT_DIR[] = "cheatsDir";
rlm@1 35 extern const char IDS_LUA_DIR[] = "luaDir";
rlm@1 36 extern const char IDS_IPS_DIR[] = "ipsDir";
rlm@1 37 extern const char IDS_AVI_DIR[] = "aviRecordDir";
rlm@1 38 extern const char IDS_WAV_DIR[] = "soundRecordDir";
rlm@1 39 extern const char IDS_CAPTURE_DIR[] = "captureDir";
rlm@1 40 extern const char IDS_WATCH_DIR[] = "watchDir";
rlm@1 41
rlm@1 42 extern const char IDS_ROM_DEFAULT_DIR[] = "\\roms";
rlm@1 43 extern const char IDS_GBXROM_DEFAULT_DIR[] = "\\gbroms";
rlm@1 44 extern const char IDS_BATTERY_DEFAULT_DIR[] = "\\battery";
rlm@1 45 extern const char IDS_SAVE_DEFAULT_DIR[] = "\\save";
rlm@1 46 extern const char IDS_MOVIE_DEFAULT_DIR[] = "\\movies";
rlm@1 47 extern const char IDS_CHEAT_DEFAULT_DIR[] = "\\cheats";
rlm@1 48 extern const char IDS_LUA_DEFAULT_DIR[] = "\\lua";
rlm@1 49 extern const char IDS_IPS_DEFAULT_DIR[] = "\\ips";
rlm@1 50 extern const char IDS_AVI_DEFAULT_DIR[] = "\\avi";
rlm@1 51 extern const char IDS_WAV_DEFAULT_DIR[] = "\\wav";
rlm@1 52 extern const char IDS_CAPTURE_DEFAULT_DIR[] = "\\screen";
rlm@1 53 extern const char IDS_WATCH_DEFAULT_DIR[] = "\\watches";
rlm@1 54
rlm@1 55 extern const char *IDS_tbl[] = {
rlm@1 56 IDS_ROM_DIR, IDS_GBXROM_DIR, IDS_BATTERY_DIR, IDS_SAVE_DIR,
rlm@1 57 IDS_MOVIE_DIR, IDS_CHEAT_DIR, IDS_LUA_DIR, IDS_IPS_DIR,
rlm@1 58 IDS_AVI_DIR, IDS_WAV_DIR, IDS_CAPTURE_DIR, IDS_WATCH_DIR
rlm@1 59 };
rlm@1 60
rlm@1 61 extern const char *IDS_def_tbl[] = {
rlm@1 62 IDS_ROM_DEFAULT_DIR, IDS_GBXROM_DEFAULT_DIR, IDS_BATTERY_DEFAULT_DIR, IDS_SAVE_DEFAULT_DIR,
rlm@1 63 IDS_MOVIE_DEFAULT_DIR, IDS_CHEAT_DEFAULT_DIR, IDS_LUA_DEFAULT_DIR, IDS_IPS_DEFAULT_DIR,
rlm@1 64 IDS_AVI_DEFAULT_DIR, IDS_WAV_DEFAULT_DIR, IDS_CAPTURE_DEFAULT_DIR, IDS_WATCH_DEFAULT_DIR
rlm@1 65 };
rlm@1 66
rlm@1 67 // these could be made VBA members, but the VBA class is already oversized too much
rlm@1 68 //
rlm@1 69
rlm@1 70 bool winFileExists(const CString &filename)
rlm@1 71 {
rlm@1 72 FILE *f = fopen(filename, "rb");
rlm@1 73 if (f)
rlm@1 74 {
rlm@1 75 fclose(f);
rlm@1 76 return true;
rlm@1 77 }
rlm@1 78 return false;
rlm@1 79 }
rlm@1 80
rlm@1 81 bool winIsDriveRoot(const CString &file)
rlm@1 82 {
rlm@1 83 if (file.GetLength() == 3)
rlm@1 84 {
rlm@1 85 if (file[1] == ':' && file[2] == '\\')
rlm@1 86 return true;
rlm@1 87 }
rlm@1 88 return false;
rlm@1 89 }
rlm@1 90
rlm@1 91 CString winGetOriginalFilename(const CString &file)
rlm@1 92 {
rlm@1 93 int index = file.Find('|');
rlm@1 94
rlm@1 95 if (index != -1)
rlm@1 96 return file.Left(index);
rlm@1 97 else
rlm@1 98 return file;
rlm@1 99 }
rlm@1 100
rlm@1 101 CString winGetDirFromFilename(const CString &file)
rlm@1 102 {
rlm@1 103 CString temp = winGetOriginalFilename(file);
rlm@1 104 int index = max(temp.ReverseFind('/'), temp.ReverseFind('\\'));
rlm@1 105 if (index != -1)
rlm@1 106 {
rlm@1 107 temp = temp.Left(index);
rlm@1 108 if (temp.GetLength() == 2 && temp[1] == ':')
rlm@1 109 temp += "\\";
rlm@1 110 }
rlm@1 111
rlm@1 112 return temp;
rlm@1 113 }
rlm@1 114
rlm@1 115 CString winGetDestDir(const CString &TargetDirReg)
rlm@1 116 {
rlm@1 117 CString targetDir = regQueryStringValue(TargetDirReg, NULL);
rlm@1 118 int pos = targetDir.ReverseFind('\\');
rlm@1 119 if (pos > 0 && pos == targetDir.GetLength() - 1)
rlm@1 120 targetDir.Delete(pos);
rlm@1 121
rlm@1 122 // it makes no sense to create rom directories
rlm@1 123 // see MainWnd::winFileOpenSelect for more info
rlm@1 124 if (!TargetDirReg.Compare(IDS_ROM_DIR) || !TargetDirReg.Compare(IDS_GBXROM_DIR))
rlm@1 125 return targetDir;
rlm@1 126
rlm@1 127 if (targetDir.IsEmpty())
rlm@1 128 {
rlm@1 129 targetDir = theApp.exeDir; // reset the targetDir to the application's path
rlm@1 130 if (!TargetDirReg.Compare(IDS_BATTERY_DIR))
rlm@1 131 {
rlm@1 132 targetDir += IDS_BATTERY_DEFAULT_DIR;
rlm@1 133 }
rlm@1 134 else if (!TargetDirReg.Compare(IDS_SAVE_DIR))
rlm@1 135 {
rlm@1 136 targetDir += IDS_SAVE_DEFAULT_DIR;
rlm@1 137 }
rlm@1 138 else if (!TargetDirReg.Compare(IDS_MOVIE_DIR))
rlm@1 139 {
rlm@1 140 targetDir += IDS_MOVIE_DEFAULT_DIR;
rlm@1 141 }
rlm@1 142 else if (!TargetDirReg.Compare(IDS_CHEAT_DIR))
rlm@1 143 {
rlm@1 144 targetDir += IDS_CHEAT_DEFAULT_DIR;
rlm@1 145 }
rlm@1 146 else if (!TargetDirReg.Compare(IDS_LUA_DIR))
rlm@1 147 {
rlm@1 148 targetDir += IDS_LUA_DEFAULT_DIR;
rlm@1 149 }
rlm@1 150 else if (!TargetDirReg.Compare(IDS_IPS_DIR))
rlm@1 151 {
rlm@1 152 targetDir += IDS_IPS_DEFAULT_DIR;
rlm@1 153 }
rlm@1 154 else if (!TargetDirReg.Compare(IDS_AVI_DIR))
rlm@1 155 {
rlm@1 156 targetDir += IDS_AVI_DEFAULT_DIR;
rlm@1 157 }
rlm@1 158 else if (!TargetDirReg.Compare(IDS_WAV_DIR))
rlm@1 159 {
rlm@1 160 targetDir += IDS_WAV_DEFAULT_DIR;
rlm@1 161 }
rlm@1 162 else if (!TargetDirReg.Compare(IDS_CAPTURE_DIR))
rlm@1 163 {
rlm@1 164 targetDir += IDS_CAPTURE_DEFAULT_DIR;
rlm@1 165 }
rlm@1 166 else if (!TargetDirReg.Compare(IDS_WATCH_DIR))
rlm@1 167 {
rlm@1 168 targetDir += IDS_WATCH_DEFAULT_DIR;
rlm@1 169 }
rlm@1 170 regSetStringValue(TargetDirReg, targetDir); // Add the directory to the INI file
rlm@1 171 }
rlm@1 172
rlm@1 173 _mkdir(targetDir); // make the directory
rlm@1 174
rlm@1 175 return targetDir;
rlm@1 176 }
rlm@1 177
rlm@1 178 CString winGetDestFilename(const CString &LogicalRomName, const CString &TargetDirReg, const CString &ext)
rlm@1 179 {
rlm@1 180 if (LogicalRomName.GetLength() == 0)
rlm@1 181 return CString();
rlm@1 182
rlm@1 183 CString targetDir = winGetDestDir(TargetDirReg);
rlm@1 184 targetDir += '\\';
rlm@1 185
rlm@1 186 CString buffer = LogicalRomName;
rlm@1 187
rlm@1 188 int index = max(buffer.ReverseFind('/'), max(buffer.ReverseFind('\\'), buffer.ReverseFind('|')));
rlm@1 189 if (index != -1)
rlm@1 190 buffer = buffer.Right(buffer.GetLength() - index - 1);
rlm@1 191
rlm@1 192 index = buffer.ReverseFind('.');
rlm@1 193 if (index != -1)
rlm@1 194 buffer = buffer.Left(index);
rlm@1 195
rlm@1 196 CString filename;
rlm@1 197 filename.Format("%s%s%s", targetDir, buffer, ext);
rlm@1 198 bool fileExists = winFileExists(filename);
rlm@1 199
rlm@1 200 // check for old style of naming, for better backward compatibility
rlm@1 201 if (!fileExists || theApp.filenamePreference == 0)
rlm@1 202 {
rlm@1 203 index = LogicalRomName.Find('|');
rlm@1 204 if (index != -1)
rlm@1 205 {
rlm@1 206 buffer = LogicalRomName.Left(index);
rlm@1 207 index = max(buffer.ReverseFind('/'), buffer.ReverseFind('\\'));
rlm@1 208
rlm@1 209 int dotIndex = buffer.ReverseFind('.');
rlm@1 210 if (dotIndex > index)
rlm@1 211 buffer = buffer.Left(dotIndex);
rlm@1 212
rlm@1 213 if (index != -1)
rlm@1 214 buffer = buffer.Right(buffer.GetLength() - index - 1);
rlm@1 215
rlm@1 216 CString filename2;
rlm@1 217 filename2.Format("%s%s%s", targetDir, buffer, ext);
rlm@1 218 bool file2Exists = winFileExists(filename2);
rlm@1 219
rlm@1 220 if ((file2Exists && !fileExists) || (theApp.filenamePreference == 0 && (file2Exists || !fileExists)))
rlm@1 221 return filename2;
rlm@1 222 }
rlm@1 223 }
rlm@1 224
rlm@1 225 return filename;
rlm@1 226 }
rlm@1 227
rlm@1 228 CString winGetSavestateFilename(const CString &LogicalRomName, int nID)
rlm@1 229 {
rlm@1 230 CString ext;
rlm@1 231 // size_t startindex; // forget about C89/ANSI-C
rlm@1 232 // size_t endindex;
rlm@1 233 if (VBAMovieActive() && theApp.AsscWithSaveState)
rlm@1 234 {
rlm@1 235 std::string fs(VBAMovieGetFilename()); // RVO tip
rlm@1 236 size_t startindex = fs.find_last_of("/\\") ;
rlm@1 237 if (startindex < fs.length())
rlm@1 238 ++startindex; // luckily the found character can't be at the end of fs
rlm@1 239 else
rlm@1 240 startindex = 0;
rlm@1 241 size_t endindex = fs.find_last_of(".");
rlm@1 242 if (endindex < fs.length() && endindex > startindex)
rlm@1 243 endindex; //??
rlm@1 244 else
rlm@1 245 endindex = fs.length();
rlm@1 246 fs = fs.substr(startindex, endindex - startindex);
rlm@1 247 ext.Format("-%s-%d.sgm", fs.c_str(), nID);
rlm@1 248 }
rlm@1 249 else
rlm@1 250 {
rlm@1 251 ext.Format("%d.sgm", nID);
rlm@1 252 }
rlm@1 253 return winGetDestFilename(LogicalRomName, IDS_SAVE_DIR, ext);
rlm@1 254 }
rlm@1 255
rlm@1 256 CString winGetSavestateMenuString(const CString &LogicalRomName, int nID)
rlm@1 257 {
rlm@1 258 CString str;
rlm@1 259 if (theApp.showSlotTime)
rlm@1 260 {
rlm@1 261 CFileStatus status;
rlm@1 262 if (emulating && CFile::GetStatus(winGetSavestateFilename(LogicalRomName, nID), status))
rlm@1 263 {
rlm@1 264 str.Format("#&%d %s", nID, status.m_mtime.Format("%Y/%m/%d %H:%M:%S"));
rlm@1 265 }
rlm@1 266 else
rlm@1 267 {
rlm@1 268 str.Format("#&%d ----/--/-- --:--:--", nID);
rlm@1 269 }
rlm@1 270 }
rlm@1 271 else
rlm@1 272 {
rlm@1 273 str.Format("Slot #&%d", nID);
rlm@1 274 }
rlm@1 275
rlm@1 276 return str;
rlm@1 277 }
rlm@1 278
rlm@1 279 void winCorrectPath(CString &path)
rlm@1 280 {
rlm@1 281 if (winFileExists(path))
rlm@1 282 {
rlm@1 283 return;
rlm@1 284 }
rlm@1 285
rlm@1 286 CString tempStr = theApp.exeDir;
rlm@1 287 tempStr += "\\";
rlm@1 288 tempStr += path;
rlm@1 289
rlm@1 290 if (winFileExists(tempStr))
rlm@1 291 {
rlm@1 292 path = tempStr;
rlm@1 293 return;
rlm@1 294 }
rlm@1 295
rlm@1 296 for (int i = 0; i < _countof(IDS_tbl); ++i)
rlm@1 297 {
rlm@1 298 tempStr = winGetDestDir(IDS_tbl[i]);
rlm@1 299 tempStr += "\\";
rlm@1 300 tempStr += path;
rlm@1 301
rlm@1 302 if (winFileExists(tempStr))
rlm@1 303 {
rlm@1 304 path = tempStr;
rlm@1 305 return;
rlm@1 306 }
rlm@1 307 }
rlm@1 308 }
rlm@1 309
rlm@1 310 void winCorrectPath(char *path)
rlm@1 311 {
rlm@1 312 CString pathCStr(path);
rlm@1 313 winCorrectPath(pathCStr);
rlm@1 314 strcpy(path, pathCStr);
rlm@1 315 }
rlm@1 316
rlm@1 317 // some file I/O
rlm@1 318
rlm@1 319 int winScreenCapture(int captureNumber)
rlm@1 320 {
rlm@1 321 CString ext;
rlm@1 322 CString captureName;
rlm@1 323
rlm@1 324 do
rlm@1 325 {
rlm@1 326 if (theApp.captureFormat == 0)
rlm@1 327 ext.Format("_%03d.png", captureNumber);
rlm@1 328 else
rlm@1 329 ext.Format("_%03d.bmp", captureNumber);
rlm@1 330
rlm@1 331 captureName = winGetDestFilename(theApp.gameFilename, IDS_CAPTURE_DIR, ext);
rlm@1 332 ++captureNumber;
rlm@1 333 } while (winFileExists(captureName) && captureNumber > 0);
rlm@1 334
rlm@1 335 if (captureNumber < 0)
rlm@1 336 {
rlm@1 337 systemMessage(0, "Too many existing files (not less than %d)! Screen capture failed!", captureNumber - 1);
rlm@1 338 return 0;
rlm@1 339 }
rlm@1 340
rlm@1 341 if (theApp.captureFormat == 0)
rlm@1 342 theApp.emulator.emuWritePNG(captureName);
rlm@1 343 else
rlm@1 344 theApp.emulator.emuWriteBMP(captureName);
rlm@1 345
rlm@1 346 systemScreenMessage(winResLoadString(IDS_SCREEN_CAPTURE));
rlm@1 347
rlm@1 348 return captureNumber;
rlm@1 349 }
rlm@1 350
rlm@1 351 bool winImportGSACodeFile(CString &fileName)
rlm@1 352 {
rlm@1 353 FILE *f = fopen(fileName, "rb");
rlm@1 354
rlm@1 355 if (f == NULL)
rlm@1 356 {
rlm@1 357 systemMessage(MSG_CANNOT_OPEN_FILE, "Cannot open file %s", fileName);
rlm@1 358 return false;
rlm@1 359 }
rlm@1 360
rlm@1 361 if (systemCartridgeType == 1)
rlm@1 362 {
rlm@1 363 fclose(f);
rlm@1 364 return gbCheatReadGSCodeFile(fileName);
rlm@1 365 }
rlm@1 366
rlm@1 367 u32 len;
rlm@1 368 fread(&len, 1, 4, f);
rlm@1 369 if (len != 14)
rlm@1 370 {
rlm@1 371 fclose(f);
rlm@1 372 systemMessage(MSG_UNSUPPORTED_CODE_FILE, "Unsupported code file %s",
rlm@1 373 fileName);
rlm@1 374 return false;
rlm@1 375 }
rlm@1 376 char buffer[16];
rlm@1 377 fread(buffer, 1, 14, f);
rlm@1 378 buffer[14] = 0;
rlm@1 379 if (memcmp(buffer, "SharkPortCODES", 14))
rlm@1 380 {
rlm@1 381 fclose(f);
rlm@1 382 systemMessage(MSG_UNSUPPORTED_CODE_FILE, "Unsupported code file %s",
rlm@1 383 fileName);
rlm@1 384 return false;
rlm@1 385 }
rlm@1 386 fseek(f, 0x1e, SEEK_SET);
rlm@1 387 fread(&len, 1, 4, f);
rlm@1 388 int game = 0;
rlm@1 389 if (len > 1)
rlm@1 390 {
rlm@1 391 GSACodeSelect dlg(f);
rlm@1 392 game = dlg.DoModal();
rlm@1 393 }
rlm@1 394 fclose(f);
rlm@1 395
rlm@1 396 bool v3 = false;
rlm@1 397
rlm@1 398 int index = fileName.ReverseFind('.');
rlm@1 399
rlm@1 400 if (index != -1)
rlm@1 401 {
rlm@1 402 if (fileName.Right(3).CompareNoCase("XPC") == 0)
rlm@1 403 v3 = true;
rlm@1 404 }
rlm@1 405
rlm@1 406 if (game != -1)
rlm@1 407 {
rlm@1 408 return cheatsImportGSACodeFile(fileName, game, v3);
rlm@1 409 }
rlm@1 410
rlm@1 411 return true;
rlm@1 412 }
rlm@1 413
rlm@1 414 void winLoadCheatList(const char *name)
rlm@1 415 {
rlm@1 416 bool res = false;
rlm@1 417
rlm@1 418 if (systemCartridgeType == 0)
rlm@1 419 res = cheatsLoadCheatList(name);
rlm@1 420 else
rlm@1 421 res = gbCheatsLoadCheatList(name);
rlm@1 422
rlm@1 423 if (res)
rlm@1 424 systemScreenMessage(winResLoadString(IDS_LOADED_CHEATS));
rlm@1 425 }
rlm@1 426
rlm@1 427 void winSaveCheatList(const char *name)
rlm@1 428 {
rlm@1 429 if (systemCartridgeType == 0)
rlm@1 430 cheatsSaveCheatList(name);
rlm@1 431 else
rlm@1 432 gbCheatsSaveCheatList(name);
rlm@1 433 }
rlm@1 434
rlm@1 435 void winLoadCheatListDefault()
rlm@1 436 {
rlm@1 437 CString cheatName = winGetDestFilename(theApp.gameFilename, IDS_CHEAT_DIR, ".clt");
rlm@1 438
rlm@1 439 winLoadCheatList(cheatName);
rlm@1 440 }
rlm@1 441
rlm@1 442 void winSaveCheatListDefault()
rlm@1 443 {
rlm@1 444 CString cheatName = winGetDestFilename(theApp.gameFilename, IDS_CHEAT_DIR, ".clt");
rlm@1 445
rlm@1 446 winSaveCheatList(cheatName);
rlm@1 447 }
rlm@1 448
rlm@1 449 bool winReadBatteryFile()
rlm@1 450 {
rlm@1 451 CString batteryName = winGetDestFilename(theApp.gameFilename, IDS_BATTERY_DIR, ".sav");
rlm@1 452
rlm@1 453 bool res = false;
rlm@1 454
rlm@1 455 if (theApp.emulator.emuReadBattery)
rlm@1 456 res = theApp.emulator.emuReadBattery(batteryName);
rlm@1 457
rlm@1 458 if (res)
rlm@1 459 systemScreenMessage(winResLoadString(IDS_LOADED_BATTERY));
rlm@1 460
rlm@1 461 return res;
rlm@1 462 }
rlm@1 463
rlm@1 464 bool winWriteBatteryFile()
rlm@1 465 {
rlm@1 466 CString batteryName = winGetDestFilename(theApp.gameFilename, IDS_BATTERY_DIR, ".sav");
rlm@1 467
rlm@1 468 if (theApp.emulator.emuWriteBattery)
rlm@1 469 return theApp.emulator.emuWriteBattery(batteryName);
rlm@1 470
rlm@1 471 return false;
rlm@1 472 }
rlm@1 473
rlm@1 474 bool winEraseBatteryFile()
rlm@1 475 {
rlm@1 476 CString batteryName = winGetDestFilename(theApp.gameFilename, IDS_BATTERY_DIR, ".sav");
rlm@1 477 return !remove(batteryName);
rlm@1 478 }
rlm@1 479
rlm@1 480 bool winReadSaveGame(const char *name)
rlm@1 481 {
rlm@1 482 if (theApp.emulator.emuReadState)
rlm@1 483 return theApp.emulator.emuReadState(name);
rlm@1 484 return false;
rlm@1 485 }
rlm@1 486
rlm@1 487 bool winWriteSaveGame(const char *name)
rlm@1 488 {
rlm@1 489 if (theApp.emulator.emuWriteState)
rlm@1 490 return theApp.emulator.emuWriteState(name);
rlm@1 491 return false;
rlm@1 492 }
rlm@1 493
rlm@1 494 bool winEraseSaveGame(const char *name)
rlm@1 495 {
rlm@1 496 return !remove(name);
rlm@1 497 }