Commit | Line | Data |
---|---|---|
cf76e892 JPM |
1 | // |
2 | // app.cpp - Qt-based GUI for Virtual Jaguar | |
3 | // | |
4 | // by James Hammons | |
5 | // (C) 2010 Underground Software | |
6 | // | |
7 | // JLH = James Hammons <jlhamm@acm.org> | |
8 | // JPM = Jean-Paul Mari <djipi.mari@gmail.com> | |
9 | // | |
10 | // Who When What | |
11 | // --- ---------- ----------------------------------------------------------- | |
12 | // JLH 12/23/2009 Created this file | |
13 | // JLH 01/21/2011 Added SDL initialization | |
14 | // JLH 06/26/2011 Added fix to keep SDL from hijacking main() on win32 | |
15 | // JLH 05/24/2012 Added option switches | |
16 | // JLH 03/05/2013 Fixed console redireciton on win32 platform :-P | |
17 | // JPM 06/06/2016 Visual Studio support | |
18 | // JPM 06/19/2016 Soft debugger support (--debugger) | |
19 | // JPM 09/ /2017 Added option (--dram-max) | |
20 | // JPM 09/06/2017 Added the 'Rx' word to the emulator name and updated the credits line | |
21 | // | |
22 | ||
23 | #include "app.h" | |
24 | ||
25 | #include <SDL.h> | |
26 | #include <QApplication> | |
27 | #include "gamepad.h" | |
28 | #include "log.h" | |
29 | #include "mainwin.h" | |
30 | #include "profile.h" | |
31 | #include "settings.h" | |
32 | #include "version.h" | |
33 | #include "debugger\DBGManager.h" | |
34 | ||
35 | // Apparently on win32, SDL is hijacking main from Qt. So let's do this: | |
36 | #if defined (__GCCWIN32__) || defined (_MSC_VER) | |
37 | #undef main | |
38 | #include <windows.h> // Ick, but needed for console redirection on win32 :-O | |
39 | #endif | |
40 | ||
41 | // Function prototypes... | |
42 | static bool ParseCommandLine(int argc, char * argv[]); | |
43 | static void ParseOptions(int argc, char * argv[]); | |
44 | ||
45 | ||
46 | //hm. :-/ | |
47 | // This is stuff we pass into the mainWindow... | |
48 | // Also, these are defaults. :-) | |
49 | bool noUntunedTankPlease = false; | |
50 | bool loadAndGo = false; | |
51 | bool useLogfile = false; | |
52 | QString filename; | |
53 | ||
54 | // Here's the main application loop--short and simple... | |
55 | int main(int argc, char * argv[]) | |
56 | { | |
57 | // Win32 console redirection, because MS and their band of super geniuses | |
58 | // decided that nobody would ever launch an app from the command line. :-P | |
59 | // [Unfortunately, this doesn't seem to work on Vista/7. :-(] | |
60 | #if defined (__GCCWIN32__) || defined (_MSC_VER) | |
61 | BOOL(WINAPI * AttachConsole)(DWORD dwProcessId); | |
62 | ||
63 | AttachConsole = (BOOL (WINAPI *)(DWORD)) | |
64 | GetProcAddress(LoadLibraryA("kernel32.dll"), "AttachConsole"); | |
65 | ||
66 | if (AttachConsole != NULL && AttachConsole(((DWORD)-1))) | |
67 | { | |
68 | if (_fileno(stdout) == -1) | |
69 | freopen("CONOUT$", "wb", stdout); | |
70 | if (_fileno(stderr) == -1) | |
71 | freopen("CONOUT$", "wb", stderr); | |
72 | if (_fileno(stdin) == -1) | |
73 | freopen("CONIN$", "rb", stdin); | |
74 | ||
75 | // Fix C++ | |
76 | std::ios::sync_with_stdio(); | |
77 | } | |
78 | #endif | |
79 | ||
80 | // Normally, this would be read in from the settings module... :-P | |
81 | vjs.hardwareTypeAlpine = false; | |
82 | vjs.softTypeDebugger = false; | |
83 | vjs.DRAM_size = 0x200000; | |
84 | // This is stuff we pass into the mainWindow... | |
85 | // noUntunedTankPlease = false; | |
86 | ||
87 | // Check for options that must be in place be constructing the App object | |
88 | if (!ParseCommandLine(argc, argv)) | |
89 | { | |
90 | return 0; | |
91 | } | |
92 | ||
93 | Q_INIT_RESOURCE(virtualjaguar); // This must the same name as the exe filename | |
94 | //or is it the .qrc filename??? | |
95 | // This is so we can pass this stuff using signal/slot mechanism... | |
96 | //this is left here to remind me not to try doing this again :-P | |
97 | //ick int id = qRegisterMetaType<uint32>(); | |
98 | ||
99 | int retVal = -1; // Default is failure | |
100 | ||
101 | if (useLogfile) | |
102 | { | |
103 | bool success = (bool)LogInit("./virtualjaguar.log"); // Init logfile | |
104 | ||
105 | if (!success) | |
106 | printf("Failed to open virtualjaguar.log for writing!\n"); | |
107 | } | |
108 | ||
109 | // Set up SDL library | |
110 | if (SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_AUDIO) < 0) | |
111 | { | |
112 | WriteLog("VJ: Could not initialize the SDL library: %s\n", SDL_GetError()); | |
113 | } | |
114 | else | |
115 | { | |
116 | WriteLog("VJ: SDL (joystick, audio) successfully initialized.\n"); | |
117 | DBGManager_Init(); | |
118 | App app(argc, argv); // Declare an instance of the application | |
119 | Gamepad::AllocateJoysticks(); | |
120 | AutoConnectProfiles(); | |
121 | retVal = app.exec(); // And run it! | |
122 | DBGManager_Close(); | |
123 | Gamepad::DeallocateJoysticks(); | |
124 | ||
125 | // Free SDL components last...! | |
126 | SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_AUDIO); | |
127 | SDL_Quit(); | |
128 | } | |
129 | ||
130 | #if defined (__GCCWIN32__) || defined (_MSC_VER) | |
131 | #if 0 | |
132 | fclose(ctt); | |
133 | #endif | |
134 | #endif | |
135 | // Close logfile | |
136 | LogDone(); | |
137 | return retVal; | |
138 | } | |
139 | ||
140 | // | |
141 | // Main app constructor--we stick globally accessible stuff here... (?) | |
142 | // | |
143 | App::App(int & argc, char * argv[]): QApplication(argc, argv) | |
144 | { | |
145 | bool loadAndGo = !filename.isEmpty(); | |
146 | ||
147 | mainWindow = new MainWin(loadAndGo); | |
148 | mainWindow->plzDontKillMyComputer = noUntunedTankPlease; | |
149 | // Override defaults with command line (if any) | |
150 | ParseOptions(argc, argv); | |
151 | mainWindow->SyncUI(); | |
152 | ||
153 | if (loadAndGo) | |
154 | { | |
155 | mainWindow->LoadFile(filename); | |
156 | ||
157 | if (!mainWindow->cartridgeLoaded) | |
158 | printf("Could not load file \"%s\"!\n", filename.toUtf8().data()); | |
159 | } | |
160 | ||
161 | mainWindow->show(); | |
162 | } | |
163 | ||
164 | ||
165 | // | |
166 | // Here we parse out stuff that needs to be looked at *before* we construct the | |
167 | // App object. | |
168 | // | |
169 | bool ParseCommandLine(int argc, char * argv[]) | |
170 | { | |
171 | for(int i=1; i<argc; i++) | |
172 | { | |
173 | if ((strcmp(argv[i], "--help") == 0) || (strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "-?") == 0)) | |
174 | { | |
175 | printf( | |
176 | "Virtual Jaguar " VJ_RELEASE_VERSION " (" VJ_RELEASE_SUBVERSION ") Rx\n" | |
177 | "Based upon Virtual Jaguar core v1.0.0 by David Raingeard.\n" | |
178 | "Based upon the work by James Hammons (Linux/WIN32), Niels Wagenaar (Linux/WIN32),\n" | |
179 | "Carwin Jones (BeOS), and Adam Green (MacOS)\n" | |
180 | "Contact: http://sdlemu.ngemu.com/ | sdlemu@ngemu.com\n" | |
181 | "\n" | |
182 | "Usage:\n" | |
183 | " virtualjaguar [<filename>] [switches]\n" | |
184 | "\n" | |
185 | " Option Description\n" | |
186 | " ---------------- -----------------------------------\n" | |
187 | " <filename> Name of file to autoload\n" | |
188 | " --alpine -a Put Virtual Jaguar into Alpine mode\n" | |
189 | " --debugger -d Put Virtual Jaguar into Debugger mode\n" | |
190 | " --pal -p PAL mode\n" | |
191 | " --ntsc -n NTSC mode\n" | |
192 | " --dram-max Set DRAM size to 8MB\n" | |
193 | " --bios -b Boot using Jagaur BIOS\n" | |
194 | " --no-bios Do not use Jaguar BIOS\n" | |
195 | " --gpu -g Enable GPU\n" | |
196 | " --no-gpu Disable GPU\n" | |
197 | " --dsp -d Enable DSP\n" | |
198 | " --no-dsp Disable DSP\n" | |
199 | " --fullscreen -f Start in full screen mode\n" | |
200 | " --blur -B Enable GL bilinear filter\n" | |
201 | " --no-blur Disable GL bilinear filtering\n" | |
202 | " --log -l Create and use log file\n" | |
203 | " --no-log Do not use log file (default)\n" | |
204 | " --help -h Show this message\n" | |
205 | " -? Show this message\n" | |
206 | " --please-dont-kill-my-computer\n" | |
207 | " -z Run Virtual Jaguar without \"snow\"\n" | |
208 | "\n" | |
209 | "Invoking Virtual Jaguar with no filename will cause it to boot up\n" | |
210 | "with the VJ GUI. Using Alpine mode will enable log file.\n" | |
211 | "\n"); | |
212 | return false; | |
213 | } | |
214 | ||
215 | // Easter egg | |
216 | if (strcmp(argv[i], "--yarrr") == 0) | |
217 | { | |
218 | printf("\n"); | |
219 | printf("Shiver me timbers!\n"); | |
220 | printf("\n"); | |
221 | return false; | |
222 | } | |
223 | ||
224 | // Alpine/Debug mode | |
225 | if ((strcmp(argv[i], "--alpine") == 0) || (strcmp(argv[i], "-a") == 0)) | |
226 | { | |
227 | printf("Alpine Mode enabled.\n"); | |
228 | vjs.hardwareTypeAlpine = true; | |
229 | // We also enable logging as well :-) | |
230 | useLogfile = true; | |
231 | } | |
232 | ||
233 | // Debugger mode | |
234 | if ((strcmp(argv[i], "--debugger") == 0) || (strcmp(argv[i], "-d") == 0)) | |
235 | { | |
236 | printf("Debugger mode enabled.\n"); | |
237 | vjs.softTypeDebugger = true; | |
238 | } | |
239 | ||
240 | // No snow display | |
241 | if ((strcmp(argv[i], "--please-dont-kill-my-computer") == 0) || (strcmp(argv[i], "-z") == 0)) | |
242 | { | |
243 | noUntunedTankPlease = true; | |
244 | } | |
245 | ||
246 | // Log file | |
247 | if ((strcmp(argv[i], "--log") == 0) || (strcmp(argv[i], "-l") == 0)) | |
248 | { | |
249 | printf("Log file enabled.\n"); | |
250 | useLogfile = true; | |
251 | } | |
252 | ||
253 | // No log file | |
254 | if (strcmp(argv[i], "--no-log") == 0) | |
255 | { | |
256 | printf("Log file disabled.\n"); | |
257 | useLogfile = false; | |
258 | } | |
259 | ||
260 | // DRAM size max | |
261 | if (strcmp(argv[i], "--dram-max") == 0) | |
262 | { | |
263 | printf("DRAM size set at 8 Mbytes.\n"); | |
264 | vjs.DRAM_size = 0x800000; | |
265 | } | |
266 | ||
267 | // Check for filename | |
268 | if (argv[i][0] != '-') | |
269 | { | |
270 | loadAndGo = true; | |
271 | filename = argv[i]; | |
272 | } | |
273 | } | |
274 | ||
275 | return true; | |
276 | } | |
277 | ||
278 | ||
279 | // | |
280 | // This is to override settings loaded from the config file. | |
281 | // Note that settings set here will become the new defaults! | |
282 | // (Not any more: Settings are only saved if the config dialog was OKed, or the toolbar buttons were pressed.) | |
283 | // | |
284 | void ParseOptions(int argc, char * argv[]) | |
285 | { | |
286 | for(int i=1; i<argc; i++) | |
287 | { | |
288 | // PAL mode | |
289 | if ((strcmp(argv[i], "--pal") == 0) || (strcmp(argv[i], "-p") == 0)) | |
290 | { | |
291 | vjs.hardwareTypeNTSC = false; | |
292 | } | |
293 | ||
294 | // NTSC mode | |
295 | if ((strcmp(argv[i], "--ntsc") == 0) || (strcmp(argv[i], "-n") == 0)) | |
296 | { | |
297 | vjs.hardwareTypeNTSC = true; | |
298 | } | |
299 | ||
300 | // Boot with Bios | |
301 | if ((strcmp(argv[i], "--bios") == 0) || (strcmp(argv[i], "-b") == 0)) | |
302 | { | |
303 | vjs.useJaguarBIOS = true; | |
304 | } | |
305 | ||
306 | // No boot with Bios | |
307 | if (strcmp(argv[i], "--no-bios") == 0) | |
308 | { | |
309 | vjs.useJaguarBIOS = false; | |
310 | } | |
311 | ||
312 | // GPU enable | |
313 | if ((strcmp(argv[i], "--gpu") == 0) || (strcmp(argv[i], "-g") == 0)) | |
314 | { | |
315 | vjs.GPUEnabled = true; | |
316 | } | |
317 | ||
318 | // GPU disable | |
319 | if (strcmp(argv[i], "--no-gpu") == 0) | |
320 | { | |
321 | vjs.GPUEnabled = false; | |
322 | } | |
323 | ||
324 | // DSP enable | |
325 | if ((strcmp(argv[i], "--dsp") == 0) || (strcmp(argv[i], "-d") == 0)) | |
326 | { | |
327 | vjs.DSPEnabled = true; | |
328 | vjs.audioEnabled = true; | |
329 | } | |
330 | ||
331 | // DSP disable | |
332 | if (strcmp(argv[i], "--no-dsp") == 0) | |
333 | { | |
334 | vjs.DSPEnabled = false; | |
335 | vjs.audioEnabled = false; | |
336 | } | |
337 | ||
338 | // Fullscreen mode | |
339 | if ((strcmp(argv[i], "--fullscreen") == 0) || (strcmp(argv[i], "-f") == 0)) | |
340 | { | |
341 | vjs.fullscreen = true; | |
342 | } | |
343 | ||
344 | // Enable GL bilinear filter | |
345 | if ((strcmp(argv[i], "--blur") == 0) || (strcmp(argv[i], "-B") == 0)) | |
346 | { | |
347 | vjs.glFilter = 1; | |
348 | } | |
349 | ||
350 | // Disable GL bilinear filter | |
351 | if (strcmp(argv[i], "--no-blur") == 0) | |
352 | { | |
353 | vjs.glFilter = 0; | |
354 | } | |
355 | } | |
356 | } | |
357 | ||
358 | #if 0 | |
359 | bool useJoystick; | |
360 | int32 joyport; // Joystick port | |
361 | bool hardwareTypeNTSC; // Set to false for PAL | |
362 | bool useJaguarBIOS; | |
363 | bool GPUEnabled; | |
364 | bool DSPEnabled; | |
365 | bool usePipelinedDSP; | |
366 | bool fullscreen; | |
367 | bool useOpenGL; | |
368 | uint32 glFilter; | |
369 | bool hardwareTypeAlpine; | |
370 | bool softTypeDebugger; | |
371 | bool audioEnabled; | |
372 | uint32 frameSkip; | |
373 | uint32 renderType; | |
374 | bool allowWritesToROM; | |
375 | ||
376 | // Keybindings in order of U, D, L, R, C, B, A, Op, Pa, 0-9, #, * | |
377 | ||
378 | uint32 p1KeyBindings[21]; | |
379 | uint32 p2KeyBindings[21]; | |
380 | ||
381 | // Paths | |
382 | ||
383 | char ROMPath[MAX_PATH]; | |
384 | char jagBootPath[MAX_PATH]; | |
385 | char CDBootPath[MAX_PATH]; | |
386 | char EEPROMPath[MAX_PATH]; | |
387 | char alpineROMPath[MAX_PATH]; | |
388 | char absROMPath[MAX_PATH]; | |
389 | #endif | |
390 |