1 /*****************************************************************************\
2 Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3 This file is licensed under the Snes9x License.
4 For further information, consult the LICENSE file in the root directory.
5 \*****************************************************************************/
6
7 /***********************************************************************************
8 SNES9X for Mac OS (c) Copyright John Stiles
9
10 Snes9x for Mac OS X
11
12 (c) Copyright 2001 - 2011 zones
13 (c) Copyright 2002 - 2005 107
14 (c) Copyright 2002 PB1400c
15 (c) Copyright 2004 Alexander and Sander
16 (c) Copyright 2004 - 2005 Steven Seeger
17 (c) Copyright 2005 Ryan Vogt
18 ***********************************************************************************/
19
20
21 #include "snes9x.h"
22 #include "memmap.h"
23 #include "apu.h"
24 #include "snapshot.h"
25 #include "cheats.h"
26 #include "movie.h"
27 #include "display.h"
28
29 #include <wchar.h>
30
31 #include "mac-prefix.h"
32 #include "mac-audio.h"
33 #include "mac-cart.h"
34 #include "mac-cheatfinder.h"
35 #include "mac-dialog.h"
36 #include "mac-file.h"
37 #include "mac-multicart.h"
38 #include "mac-os.h"
39 #include "mac-quicktime.h"
40 #include "mac-screenshot.h"
41 #include "mac-stringtools.h"
42 #include "mac-snes9x.h"
43
44 extern wchar_t macRecordWChar[MOVIE_MAX_METADATA];
45
46
SNES9X_Go(void)47 void SNES9X_Go (void)
48 {
49 if (cartOpen)
50 running = true;
51 }
52
SNES9X_OpenCart(FSRef * inRef)53 bool8 SNES9X_OpenCart (FSRef *inRef)
54 {
55 OSStatus err;
56 FSRef cartRef;
57 char filename[PATH_MAX + 1];
58
59 DeinitGameWindow();
60
61 if (cartOpen)
62 {
63 SNES9X_SaveSRAM();
64 S9xResetSaveTimer(false);
65 S9xSaveCheatFile(S9xGetFilename(".cht", CHEAT_DIR));
66 }
67
68 ResetCheatFinder();
69
70 if (!inRef)
71 {
72 if (!NavOpenROMImage(&cartRef))
73 {
74 cartOpen = false;
75 return (false);
76 }
77 }
78 else
79 cartRef = *inRef;
80
81 spcFileCount = pngFileCount = 0;
82
83 CheckSaveFolder(&cartRef);
84
85 Settings.ForceLoROM = (romDetect == kLoROMForce );
86 Settings.ForceHiROM = (romDetect == kHiROMForce );
87 Settings.ForceHeader = (headerDetect == kHeaderForce );
88 Settings.ForceNoHeader = (headerDetect == kNoHeaderForce );
89 Settings.ForceInterleaved = (interleaveDetect == kInterleaveForce );
90 Settings.ForceInterleaved2 = (interleaveDetect == kInterleave2Force );
91 Settings.ForceInterleaveGD24 = (interleaveDetect == kInterleaveGD24 );
92 Settings.ForceNotInterleaved = (interleaveDetect == kNoInterleaveForce);
93 Settings.ForcePAL = (videoDetect == kPALForce );
94 Settings.ForceNTSC = (videoDetect == kNTSCForce );
95
96 GFX.InfoString = NULL;
97 GFX.InfoStringTimeout = 0;
98
99 S9xResetSaveTimer(true);
100
101 err = FSRefMakePath(&cartRef, (unsigned char *) filename, PATH_MAX);
102
103 SNES9X_InitSound();
104
105 if (Memory.LoadROM(filename))
106 {
107 cartOpen = true;
108
109 SNES9X_LoadSRAM();
110
111 ChangeTypeAndCreator(filename, 'CART', '~9X~');
112
113 AddRecentItem(&cartRef);
114 BuildRecentMenu();
115
116 ApplyNSRTHeaderControllers();
117
118 for (int a = 0; a < MAC_MAX_PLAYERS; a++)
119 for (int b = 0; b < 12; b++)
120 autofireRec[a].nextTime[b] = 0;
121
122 return (true);
123 }
124 else
125 {
126 cartOpen = false;
127 return (false);
128 }
129 }
130
SNES9X_OpenMultiCart(void)131 bool8 SNES9X_OpenMultiCart (void)
132 {
133 Boolean r;
134 char cart[2][PATH_MAX + 1];
135
136 DeinitGameWindow();
137
138 if (cartOpen)
139 {
140 SNES9X_SaveSRAM();
141 S9xResetSaveTimer(false);
142 S9xSaveCheatFile(S9xGetFilename(".cht", CHEAT_DIR));
143 }
144
145 ResetCheatFinder();
146
147 if (!MultiCartDialog())
148 {
149 cartOpen = false;
150 return (false);
151 }
152
153 spcFileCount = pngFileCount = 0;
154
155 Settings.ForceHeader = (headerDetect == kHeaderForce );
156 Settings.ForceNoHeader = (headerDetect == kNoHeaderForce);
157 Settings.ForcePAL = (videoDetect == kPALForce );
158 Settings.ForceNTSC = (videoDetect == kNTSCForce );
159
160 GFX.InfoString = NULL;
161 GFX.InfoStringTimeout = 0;
162
163 S9xResetSaveTimer(true);
164
165 for (int i = 0; i < 2; i++)
166 {
167 cart[i][0] = 0;
168 if (multiCartPath[i])
169 r = CFStringGetCString(multiCartPath[i], cart[i], PATH_MAX, kCFStringEncodingUTF8);
170 }
171
172 SNES9X_InitSound();
173
174 if (Memory.LoadMultiCart(cart[0], cart[1]))
175 {
176 cartOpen = true;
177
178 SNES9X_LoadSRAM();
179
180 for (int i = 0; i < 2; i++)
181 {
182 if (cart[i][0])
183 ChangeTypeAndCreator(cart[i], 'CART', '~9X~');
184 }
185
186 ApplyNSRTHeaderControllers();
187
188 for (int a = 0; a < MAC_MAX_PLAYERS; a++)
189 for (int b = 0; b < 12; b++)
190 autofireRec[a].nextTime[b] = 0;
191
192 return (true);
193 }
194 else
195 {
196 cartOpen = false;
197 return (false);
198 }
199 }
200
SNES9X_LoadSRAM(void)201 void SNES9X_LoadSRAM (void)
202 {
203 if (cartOpen)
204 Memory.LoadSRAM(S9xGetFilename(".srm", SRAM_DIR));
205 }
206
SNES9X_SaveSRAM(void)207 void SNES9X_SaveSRAM (void)
208 {
209 const char *sramFilename;
210
211 if (cartOpen)
212 {
213 sramFilename = S9xGetFilename(".srm", SRAM_DIR);
214 Memory.SaveSRAM(sramFilename);
215 ChangeTypeAndCreator(sramFilename, 'SRAM', '~9X~');
216 }
217 }
218
SNES9X_Reset(void)219 void SNES9X_Reset (void)
220 {
221 if (cartOpen)
222 {
223 SNES9X_SaveSRAM();
224 S9xReset();
225 SNES9X_LoadSRAM();
226 }
227 }
228
SNES9X_SoftReset(void)229 void SNES9X_SoftReset (void)
230 {
231 if (cartOpen)
232 {
233 SNES9X_SaveSRAM();
234 S9xSoftReset();
235 SNES9X_LoadSRAM();
236 }
237 }
238
SNES9X_Freeze(void)239 bool8 SNES9X_Freeze (void)
240 {
241 OSStatus err;
242 FSRef ref;
243 int which;
244 const char *filename;
245
246 if (cartOpen)
247 {
248 MacStopSound();
249
250 which = PromptFreezeDefrost(true);
251
252 if (which >= 0)
253 {
254 filename = S9xGetFreezeFilename(which);
255
256 err = FSPathMakeRef((unsigned char *) filename, &ref, NULL);
257 if (!err)
258 FSDeleteObject(&ref);
259
260 S9xFreezeGame(filename);
261 ChangeTypeAndCreator(filename, 'SAVE', '~9X~');
262 err = FSPathMakeRef((unsigned char *) filename, &ref, NULL);
263 WriteThumbnailToResourceFork(&ref, 128, 120);
264
265 SNES9X_Go();
266
267 MacStartSound();
268 return (true);
269 }
270 else
271 {
272 MacStartSound();
273 return (false);
274 }
275 }
276 else
277 return (false);
278 }
279
SNES9X_Defrost(void)280 bool8 SNES9X_Defrost (void)
281 {
282 int which;
283 const char *filename;
284
285 if (cartOpen)
286 {
287 MacStopSound();
288
289 which = PromptFreezeDefrost(false);
290
291 if (which >= 0)
292 {
293 filename = S9xGetFreezeFilename(which);
294 S9xUnfreezeGame(filename);
295
296 SNES9X_Go();
297
298 MacStartSound();
299 return (true);
300 }
301 else
302 {
303 MacStartSound();
304 return (false);
305 }
306 }
307 else
308 return (false);
309 }
310
SNES9X_FreezeTo(void)311 bool8 SNES9X_FreezeTo (void)
312 {
313 OSStatus err;
314 FSRef ref;
315 char filename[PATH_MAX + 1];
316
317 if (cartOpen)
318 {
319 if (NavFreezeTo(filename))
320 {
321 err = FSPathMakeRef((unsigned char *) filename, &ref, NULL);
322 if (!err)
323 FSDeleteObject(&ref);
324
325 S9xFreezeGame(filename);
326 ChangeTypeAndCreator(filename, 'SAVE', '~9X~');
327 err = FSPathMakeRef((unsigned char *) filename, &ref, NULL);
328 WriteThumbnailToResourceFork(&ref, 128, 120);
329
330 return (true);
331 }
332 }
333
334 return (false);
335 }
336
SNES9X_DefrostFrom(void)337 bool8 SNES9X_DefrostFrom (void)
338 {
339 char filename[PATH_MAX + 1];
340
341 if (cartOpen)
342 {
343 if (NavDefrostFrom(filename))
344 {
345 S9xUnfreezeGame(filename);
346
347 SNES9X_Go();
348
349 return (true);
350 }
351 }
352
353 return (false);
354 }
355
SNES9X_RecordMovie(void)356 bool8 SNES9X_RecordMovie (void)
357 {
358 OSStatus err;
359 FSRef ref;
360 char filename[PATH_MAX + 1];
361
362 if (cartOpen)
363 {
364 if (NavRecordMovieTo(filename))
365 {
366 err = FSPathMakeRef((unsigned char *) filename, &ref, NULL);
367 if (!err)
368 FSDeleteObject(&ref);
369
370 int r;
371 uint8 opt = 0, mask = 0;
372
373 for (int i = 0; i <= 4; i++)
374 if (macRecordFlag & (1 << i))
375 mask |= (1 << i);
376
377 if (macRecordFlag & (1 << 5))
378 opt |= MOVIE_OPT_FROM_RESET;
379 else
380 opt |= MOVIE_OPT_FROM_SNAPSHOT;
381
382 r = S9xMovieCreate(filename, mask, opt, macRecordWChar, wcslen(macRecordWChar));
383 if (r == SUCCESS)
384 {
385 ChangeTypeAndCreator(filename, 'SMOV', '~9X~');
386
387 if ((macRecordFlag & (1 << 5)) == 0)
388 {
389 err = FSPathMakeRef((unsigned char *) filename, &ref, NULL);
390 WriteThumbnailToResourceFork(&ref, 128, 120);
391 }
392
393 SNES9X_Go();
394
395 return (true);
396 }
397 }
398 }
399
400 return (false);
401 }
402
SNES9X_PlayMovie(void)403 bool8 SNES9X_PlayMovie (void)
404 {
405 char filename[PATH_MAX + 1];
406
407 if (cartOpen)
408 {
409 if (NavPlayMovieFrom(filename))
410 {
411 int r;
412
413 r = S9xMovieOpen(filename, macPlayFlag & 1);
414 if (r == SUCCESS)
415 {
416 SNES9X_Go();
417
418 return (true);
419 }
420 }
421 }
422
423 return (false);
424 }
425
SNES9X_QTMovieRecord(void)426 bool8 SNES9X_QTMovieRecord (void)
427 {
428 char filename[PATH_MAX + 1];
429
430 if (cartOpen)
431 {
432 if (NavQTMovieRecordTo(filename))
433 {
434 MacQTStartRecording(filename);
435 macQTRecord = true;
436 SNES9X_Go();
437
438 return (true);
439 }
440 }
441
442 macQTRecord = false;
443
444 return (false);
445 }
446
SNES9X_Quit(void)447 void SNES9X_Quit (void)
448 {
449 DeinitGameWindow();
450
451 if (cartOpen)
452 {
453 SNES9X_SaveSRAM();
454 S9xResetSaveTimer(false);
455 S9xSaveCheatFile(S9xGetFilename(".cht", CHEAT_DIR));
456 }
457
458 finished = true;
459 }
460
SNES9X_InitSound(void)461 void SNES9X_InitSound (void)
462 {
463 S9xInitSound(0);
464 }
465