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