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