92ec0afb4dc2ae4b35121a877a3cecb4735fdbe3
[clinton/Virtual-Jaguar-Rx.git] / src / gui / app.cpp
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