1 #include "ConfigManager.h"
2 extern "C" {
3 #include "../common/iniparser.h"
4 }
5
6 #include <stdarg.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <cmath>
13 #include <unistd.h>
14
15 #include "../AutoBuild.h"
16 #include "../version.h"
17
18 #include "../common/Patch.h"
19 #include "../common/ConfigManager.h"
20 #include "../gba/GBA.h"
21 #include "../gba/agbprint.h"
22 #include "../gba/Flash.h"
23 #include "../gba/Cheats.h"
24 #include "../gba/remote.h"
25 #include "../gba/RTC.h"
26 #include "../gba/Sound.h"
27 #include "../gb/gb.h"
28 #include "../gb/gbGlobals.h"
29 #include "../gb/gbCheats.h"
30 #include "../gb/gbSound.h"
31 #include "../Util.h"
32
33 #ifndef _WIN32
34 #define GETCWD getcwd
35 #else // _WIN32
36 #include <direct.h>
37 #define GETCWD _getcwd
38 #define snprintf sprintf
39 #endif // _WIN32
40
41 #ifndef __GNUC__
42 #define HAVE_DECL_GETOPT 0
43 #define __STDC__ 1
44 #include "getopt.h"
45 #else // ! __GNUC__
46 #define HAVE_DECL_GETOPT 1
47 #include <getopt.h>
48 #endif // ! __GNUC__
49 #include <string>
50
51 enum named_opts
52 {
53 OPT_AGB_PRINT = 1000,
54 OPT_AUTOFIRE,
55 OPT_AUTO_FRAME_SKIP,
56 OPT_AVI_RECORD_DIR,
57 OPT_BATTERY_DIR,
58 OPT_BIOS_FILE_NAME_GB,
59 OPT_BIOS_FILE_NAME_GBA,
60 OPT_BIOS_FILE_NAME_GBC,
61 OPT_CAPTURE_FORMAT,
62 OPT_CHEAT,
63 OPT_CPU_SAVE_TYPE,
64 OPT_DOTCODE_FILE_NAME_LOAD,
65 OPT_DOTCODE_FILE_NAME_SAVE,
66 OPT_EMULATOR_TYPE,
67 OPT_FS_ADAPTER,
68 OPT_FS_COLOR_DEPTH,
69 OPT_FS_FREQUENCY,
70 OPT_FS_HEIGHT,
71 OPT_FS_WIDTH,
72 OPT_GB_EMULATOR_TYPE,
73 OPT_GB_FRAME_SKIP,
74 OPT_GB_PALETTE_OPTION,
75 OPT_GDB_PORT,
76 OPT_GL_FILTER,
77 OPT_IFB_TYPE,
78 OPT_JOYPAD_DEFAULT,
79 OPT_LANGUAGE_OPTION,
80 OPT_LINK_AUTO,
81 OPT_LINK_HACKS,
82 OPT_LINK_HOST_ADDR,
83 OPT_LINK_MODE,
84 OPT_LINK_NUM_PLAYERS,
85 OPT_LINK_TIMEOUT,
86 OPT_MAX_SCALE,
87 OPT_MOVIE_RECORD_DIR,
88 OPT_OPT_FLASH_SIZE,
89 OPT_REWIND_TIMER,
90 OPT_ROM_DIR_GB,
91 OPT_ROM_DIR_GBA,
92 OPT_ROM_DIR_GBC,
93 OPT_RTC_ENABLED,
94 OPT_SAVE_DIR,
95 OPT_SCREEN_SHOT_DIR,
96 OPT_SHOW_SPEED,
97 OPT_SHOW_SPEED_TRANSPARENT,
98 OPT_SOUND_FILTERING,
99 OPT_SOUND_RECORD_DIR,
100 OPT_SYNCHRONIZE,
101 OPT_THREAD_PRIORITY,
102 OPT_VIDEO_OPTION,
103 OPT_WINDOW_POSITION_X,
104 OPT_WINDOW_POSITION_Y
105
106 };
107
108 #define SOUND_MAX_VOLUME 2.0
109 #define SOUND_ECHO 0.2
110 #define SOUND_STEREO 0.15
111
112 #define REWIND_NUM 8
113 #define REWIND_SIZE 400000
114
115 char path[2048];
116
117 dictionary* preferences;
118
119 bool cpuIsMultiBoot = false;
120 bool mirroringEnable = true;
121 bool parseDebug = true;
122 bool speedHack = false;
123 bool speedup = false;
124 char* aviRecordDir;
125 char* batteryDir;
126 char* biosFileNameGB;
127 char* biosFileNameGBA;
128 char* biosFileNameGBC;
129 char* loadDotCodeFile;
130 char* saveDotCodeFile;
131 char* linkHostAddr;
132 char* movieRecordDir;
133 char* rewindMemory = NULL;
134 char* romDirGB;
135 char* romDirGBA;
136 char* romDirGBC;
137 char* saveDir;
138 char* screenShotDir;
139 char* soundRecordDir;
140 int active = 1;
141 int agbPrint;
142 int autoFire;
143 int autoFireMaxCount = 1;
144 int autoFireToggle;
145 int autoFrameSkip = 0;
146 int autoLoadMostRecent;
147 int autoPatch;
148 int autoSaveLoadCheatList;
149 int aviRecording;
150 int captureFormat = 0;
151 int cheatsEnabled = true;
152 int cpuDisableSfx = false;
153 int cpuSaveType = 0;
154 int disableMMX;
155 int disableStatusMessages = 0;
156 int dsoundDisableHardwareAcceleration;
157 int filterHeight;
158 int filterMagnification;
159 int filterMT; // enable multi-threading for pixel filters
160 int filter = kStretch2x;
161 int filterWidth;
162 int frameSkip = 1;
163 int frameskipadjust;
164 int fsAdapter;
165 int fsColorDepth;
166 int fsForceChange;
167 int fsFrequency;
168 int fsHeight;
169 int fsWidth;
170 int fullScreen;
171 int fullScreenStretch;
172 int gdbBreakOnLoad;
173 int gdbPort;
174 int glFilter;
175 int ifbType = kIFBNone;
176 int joypadDefault;
177 int languageOption;
178 int layerEnable = 0xff00;
179 int layerSettings = 0xff00;
180 int linkAuto;
181 int linkHacks = 1;
182 int linkMode;
183 int linkNumPlayers;
184 int linkTimeout = 1;
185 int maxScale;
186 int mouseCounter = 0;
187 int movieFrame;
188 int moviePlayFrame;
189 int moviePlaying;
190 int movieRecording;
191 int openGL;
192 int optFlashSize;
193 int optPrintUsage;
194 int paused;
195 int pauseWhenInactive = 0;
196 int preparedCheats = 0;
197 int recentFreeze;
198 int renderedFrames;
199 int rewindCount;
200 int rewindCounter;
201 int rewindPos;
202 int rewindSaveNeeded = 0;
203 int rewindTimer = 0;
204 int rewindTopPos;
205 int rtcEnabled;
206 int saveType = 0;
207 int screenMessage;
208 int sensorX;
209 int sensorY;
210 int showRenderedFrames;
211 int showSpeed;
212 int showSpeedTransparent;
213 int sizeX;
214 int sizeY;
215 int skipBios = 0;
216 int skipSaveGameBattery = false;
217 int skipSaveGameCheats = false;
218 int soundRecording;
219 int speedupToggle;
220 int sunBars;
221 int surfaceSizeX;
222 int surfaceSizeY;
223 int threadPriority;
224 int tripleBuffering;
225 int useBios = 0;
226 int useBiosFileGB;
227 int useBiosFileGBA;
228 int useBiosFileGBC;
229 int videoOption;
230 int vsync;
231 int wasPaused = 0;
232 int windowPositionX;
233 int windowPositionY;
234 int winFlashSize;
235 int winGbBorderOn;
236 int winGbPrinterEnabled;
237 int winPauseNextFrame;
238 int* rewindSerials = NULL;
239 u32 autoFrameSkipLastTime;
240 u32 movieLastJoypad;
241 u32 movieNextJoypad;
242 int throttle;
243
244 const char* preparedCheatCodes[MAX_CHEATS];
245
246 FilterFunc filterFunction = 0;
247 IFBFilterFunc ifbFunction = 0;
248
249 // allow up to 100 IPS/UPS/PPF patches given on commandline
250 int patchNum = 0;
251 char *(patchNames[PATCH_MAX_NUM]) = { NULL }; // and so on
252
253 void(*dbgMain)() = remoteStubMain;
254 void(*dbgSignal)(int, int) = remoteStubSignal;
255 void(*dbgOutput)(const char *, u32) = debuggerOutput;
256
257 char* homeDir = NULL;
258 char* arg0 = NULL;
259
260
261 struct option argOptions[] = {
262
263 { "agb-print", required_argument, 0, OPT_AGB_PRINT },
264 { "auto-frame-skip", required_argument, 0, OPT_AUTO_FRAME_SKIP },
265 { "auto-load-most-recent", no_argument, &autoLoadMostRecent, 1 },
266 { "auto-patch", no_argument, &autoPatch, 1 },
267 { "auto-save-cheat-list", no_argument, &autoSaveLoadCheatList, 1 },
268 { "auto-save-load-cheat-list", no_argument, &autoSaveLoadCheatList, 1 },
269 { "autofire", required_argument, 0, OPT_AUTOFIRE },
270 { "avi-record-dir", required_argument, 0, OPT_AVI_RECORD_DIR },
271 { "battery-dir", required_argument, 0, OPT_BATTERY_DIR },
272 { "bios", required_argument, 0, 'b' },
273 { "bios-file-name-gb", required_argument, 0, OPT_BIOS_FILE_NAME_GB },
274 { "bios-file-name-gba", required_argument, 0, OPT_BIOS_FILE_NAME_GBA },
275 { "bios-file-name-gbc", required_argument, 0, OPT_BIOS_FILE_NAME_GBC },
276 { "border-automatic", no_argument, &gbBorderAutomatic, 1 },
277 { "border-on", no_argument, &gbBorderOn, 1 },
278 { "capture-format", required_argument, 0, OPT_CAPTURE_FORMAT },
279 { "cheat", required_argument, 0, OPT_CHEAT },
280 { "cheats-enabled", no_argument, &cheatsEnabled, 1 },
281 { "color-option", no_argument, &gbColorOption, 1 },
282 { "config", required_argument, 0, 'c' },
283 { "cpu-disable-sfx", no_argument, &cpuDisableSfx, 1 },
284 { "cpu-save-type", required_argument, 0, OPT_CPU_SAVE_TYPE },
285 { "debug", no_argument, 0, 'd' },
286 { "disable-mmx", no_argument, &disableMMX, 1 },
287 { "disable-sfx", no_argument, &cpuDisableSfx, 1 },
288 { "disable-status-messages", no_argument, &disableStatusMessages, 1 },
289 { "dotcode-file-name-load", required_argument, 0, OPT_DOTCODE_FILE_NAME_LOAD },
290 { "dotcode-file-name-save", required_argument, 0, OPT_DOTCODE_FILE_NAME_SAVE },
291 { "emulator-type", required_argument, 0, OPT_EMULATOR_TYPE },
292 { "filter", required_argument, 0, 'f' },
293 { "filter-enable-multi-threading", no_argument, &filterMT, 1 },
294 { "filter-mt", no_argument, &filterMT, 1 },
295 { "flash-128k", no_argument, &optFlashSize, 1 },
296 { "flash-64k", no_argument, &optFlashSize, 0 },
297 { "flash-size", required_argument, 0, 'S' },
298 { "frameskip", required_argument, 0, 's' },
299 { "fs-adapter", required_argument, 0, OPT_FS_ADAPTER },
300 { "fs-color-depth", required_argument, 0, OPT_FS_COLOR_DEPTH },
301 { "fs-frequency", required_argument, 0, OPT_FS_FREQUENCY },
302 { "fs-height", required_argument, 0, OPT_FS_HEIGHT },
303 { "fs-width", required_argument, 0, OPT_FS_WIDTH },
304 { "full-screen", no_argument, &fullScreen, 1 },
305 { "full-screen-stretch", no_argument, &fullScreenStretch, 1 },
306 { "gb-border-automatic", no_argument, &gbBorderAutomatic, 1 },
307 { "gb-border-on", no_argument, &gbBorderOn, 1 },
308 { "gb-color-option", no_argument, &gbColorOption, 1 },
309 { "gb-emulator-type", required_argument, 0, OPT_GB_EMULATOR_TYPE },
310 { "gb-frame-skip", required_argument, 0, OPT_GB_FRAME_SKIP },
311 { "gb-palette-option", required_argument, 0, OPT_GB_PALETTE_OPTION },
312 { "gb-printer", no_argument, &winGbPrinterEnabled, 1 },
313 { "gdb", required_argument, 0, 'G' },
314 { "gdb-break-on-load", no_argument, &gdbBreakOnLoad, 1 },
315 { "gdb-port", required_argument, 0, OPT_GDB_PORT },
316 { "gl-filter", required_argument, 0, OPT_GL_FILTER },
317 { "help", no_argument, &optPrintUsage, 1 },
318 { "ifb-filter", required_argument, 0, 'I' },
319 { "ifb-type", required_argument, 0, OPT_IFB_TYPE },
320 { "joypad-default", required_argument, 0, OPT_JOYPAD_DEFAULT },
321 { "language-option", required_argument, 0, OPT_LANGUAGE_OPTION },
322 { "link-auto", required_argument, 0, OPT_LINK_AUTO },
323 { "link-hacks", required_argument, 0, OPT_LINK_HACKS },
324 { "link-host-addr", required_argument, 0, OPT_LINK_HOST_ADDR },
325 { "link-mode", required_argument, 0, OPT_LINK_MODE },
326 { "link-num-players", required_argument, 0, OPT_LINK_NUM_PLAYERS },
327 { "link-timeout", required_argument, 0, OPT_LINK_TIMEOUT },
328 { "max-scale", required_argument, 0, OPT_MAX_SCALE },
329 { "movie-record-dir", required_argument, 0, OPT_MOVIE_RECORD_DIR },
330 { "no-agb-print", no_argument, &agbPrint, 0 },
331 { "no-auto-frameskip", no_argument, &autoFrameSkip, 0 },
332 { "no-debug", no_argument, 0, 'N' },
333 { "no-opengl", no_argument, &openGL, 0 },
334 { "no-patch", no_argument, &autoPatch, 0 },
335 { "no-pause-when-inactive", no_argument, &pauseWhenInactive, 0 },
336 { "no-rtc", no_argument, &rtcEnabled, 0 },
337 { "no-show-speed", no_argument, &showSpeed, 0 },
338 { "opengl", required_argument, 0, 'O' },
339 { "opengl-bilinear", no_argument, &openGL, 2 },
340 { "opengl-nearest", no_argument, &openGL, 1 },
341 { "opt-flash-size", required_argument, 0, OPT_OPT_FLASH_SIZE },
342 { "patch", required_argument, 0, 'i' },
343 { "pause-when-inactive", no_argument, &pauseWhenInactive, 1 },
344 { "profile", optional_argument, 0, 'p' },
345 { "recent-freeze", no_argument, &recentFreeze, 1 },
346 { "rewind-timer", required_argument, 0, OPT_REWIND_TIMER },
347 { "rom-dir-gb", required_argument, 0, OPT_ROM_DIR_GB },
348 { "rom-dir-gba", required_argument, 0, OPT_ROM_DIR_GBA },
349 { "rom-dir-gbc", required_argument, 0, OPT_ROM_DIR_GBC },
350 { "rtc", no_argument, &rtcEnabled, 1 },
351 { "rtc-enabled", required_argument, 0, OPT_RTC_ENABLED },
352 { "save-auto", no_argument, &cpuSaveType, 0 },
353 { "save-dir", required_argument, 0, OPT_SAVE_DIR },
354 { "save-eeprom", no_argument, &cpuSaveType, 1 },
355 { "save-flash", no_argument, &cpuSaveType, 3 },
356 { "save-none", no_argument, &cpuSaveType, 5 },
357 { "save-sensor", no_argument, &cpuSaveType, 4 },
358 { "save-sram", no_argument, &cpuSaveType, 2 },
359 { "save-type", required_argument, 0, 't' },
360 { "screen-shot-dir", required_argument, 0, OPT_SCREEN_SHOT_DIR },
361 { "show-speed", required_argument, 0, OPT_SHOW_SPEED },
362 { "show-speed-detailed", no_argument, &showSpeed, 2 },
363 { "show-speed-normal", no_argument, &showSpeed, 1 },
364 { "show-speed-transparent", required_argument, 0, OPT_SHOW_SPEED_TRANSPARENT },
365 { "skip-bios", no_argument, &skipBios, 1 },
366 { "skip-save-game-battery", no_argument, &skipSaveGameBattery, 1 },
367 { "skip-save-game-cheats", no_argument, &skipSaveGameCheats, 1 },
368 { "sound-filtering", required_argument, 0, OPT_SOUND_FILTERING },
369 { "sound-record-dir", required_argument, 0, OPT_SOUND_RECORD_DIR },
370 { "stretch", no_argument, &fullScreenStretch, 1 },
371 { "synchronize", required_argument, 0, OPT_SYNCHRONIZE },
372 { "thread-priority", required_argument, 0, OPT_THREAD_PRIORITY },
373 { "throttle", required_argument, 0, 'T' },
374 { "triple-buffering", no_argument, &tripleBuffering, 1 },
375 { "use-bios", no_argument, &useBios, 1 },
376 { "use-bios-file-gb", no_argument, &useBiosFileGB, 1 },
377 { "use-bios-file-gba", no_argument, &useBiosFileGBA, 1 },
378 { "use-bios-file-gbc", no_argument, &useBiosFileGBC, 1 },
379 { "verbose", required_argument, 0, 'v' },
380 { "video-option", required_argument, 0, OPT_VIDEO_OPTION },
381 { "vsync", no_argument, &vsync, 1 },
382 { "win-gb-printer-enabled", no_argument, &winGbPrinterEnabled, 1 },
383 { "window-position-x", required_argument, 0, OPT_WINDOW_POSITION_X },
384 { "window-position-y", required_argument, 0, OPT_WINDOW_POSITION_Y },
385
386
387 { NULL, no_argument, NULL, 0 }
388 };
389
390
fromHex(char * s)391 u32 fromHex(char *s)
392 {
393 if (!s)
394 return 0;
395 u32 value;
396 sscanf(s, "%x", &value);
397 return value;
398 }
399
fromDec(char * s)400 u32 fromDec(char *s)
401 {
402 if (!s)
403 return 0;
404 u32 value = 0;
405 sscanf(s, "%u", &value);
406 return value;
407 }
408
SetHome(char * _arg0)409 void SetHome(char *_arg0)
410 {
411 arg0 = _arg0;
412 }
413
OpenPreferences(const char * name)414 void OpenPreferences(const char *name)
415 {
416 if (!preferences && name)
417 preferences = iniparser_load(name);
418 }
419
ValidateConfig()420 void ValidateConfig()
421 {
422 if (gbEmulatorType < 0 || gbEmulatorType > 5)
423 gbEmulatorType = 1;
424 if (frameSkip < 0 || frameSkip > 9)
425 frameSkip = 2;
426 if (gbFrameSkip < 0 || gbFrameSkip > 9)
427 gbFrameSkip = 0;
428 if (filter < kStretch1x || filter >= kInvalidFilter)
429 filter = kStretch2x;
430
431 if (cpuSaveType < 0 || cpuSaveType > 5)
432 cpuSaveType = 0;
433 if (optFlashSize != 0 && optFlashSize != 1)
434 optFlashSize = 0;
435 if (ifbType < kIFBNone || ifbType >= kInvalidIFBFilter)
436 ifbType = kIFBNone;
437 if (showSpeed < 0 || showSpeed > 2)
438 showSpeed = 1;
439 if (rewindTimer < 0 || rewindTimer > 600)
440 rewindTimer = 0;
441 if (autoFireMaxCount < 1)
442 autoFireMaxCount = 1;
443
444 if (rewindTimer) {
445 rewindMemory = (char *)malloc(REWIND_NUM*REWIND_SIZE);
446 rewindSerials = (int *)calloc(REWIND_NUM, sizeof(int)); // init to zeroes
447 }
448 }
449
LoadConfig()450 void LoadConfig()
451 {
452 agbPrint = ReadPrefHex("agbPrint");
453 autoFireMaxCount = fromDec(ReadPrefString("autoFireMaxCount"));
454 autoFrameSkip = ReadPref("autoFrameSkip", 0);
455 autoLoadMostRecent = ReadPref("autoLoadMostRecent", 0);
456 autoPatch = ReadPref("autoPatch", 1);
457 autoSaveLoadCheatList = ReadPref("autoSaveCheatList", 1);
458 aviRecordDir = ReadPrefString("aviRecordDir");
459 batteryDir = ReadPrefString("batteryDir");
460 biosFileNameGB = ReadPrefString("biosFileGB");
461 biosFileNameGBA = ReadPrefString("biosFileGBA");
462 biosFileNameGBC = ReadPrefString("biosFileGBC");
463 captureFormat = ReadPref("captureFormat", 0);
464 cheatsEnabled = ReadPref("cheatsEnabled", 0);
465 cpuDisableSfx = ReadPref("disableSfx", 0);
466 cpuSaveType = ReadPrefHex("saveType");
467 disableMMX = ReadPref("disableMMX", 0);
468 disableStatusMessages = ReadPrefHex("disableStatus");
469 filterMT = ReadPref("filterEnableMultiThreading", 0);
470 filter = ReadPref("filter", 0);
471 frameSkip = ReadPref("frameSkip", 0);
472 fsAdapter = ReadPref("fsAdapter", 0);
473 fsColorDepth = ReadPref("fsColorDepth", 32);
474 fsFrequency = ReadPref("fsFrequency", 60);
475 fsHeight = ReadPref("fsHeight", 600);
476 fsWidth = ReadPref("fsWidth", 800);
477 fullScreen = ReadPrefHex("fullScreen");
478 fullScreenStretch = ReadPref("stretch", 0);
479 gbBorderAutomatic = ReadPref("borderAutomatic", 0);
480 gbBorderOn = ReadPrefHex("borderOn");
481 gbColorOption = ReadPref("colorOption", 0);
482 gbEmulatorType = ReadPref("emulatorType", 1);
483 gbFrameSkip = ReadPref("gbFrameSkip", 0);
484 gbPaletteOption = ReadPref("gbPaletteOption", 0);
485 gbSoundSetDeclicking(ReadPref("gbSoundDeclicking", 1));
486 gb_effects_config.echo = (float)ReadPref("gbSoundEffectsEcho", 20) / 100.0f;
487 gb_effects_config.enabled = ReadPref("gbSoundEffectsEnabled", 0);
488 gb_effects_config.stereo = (float)ReadPref("gbSoundEffectsStereo", 15) / 100.0f;
489 gb_effects_config.surround = ReadPref("gbSoundEffectsSurround", 0);
490 gdbBreakOnLoad = ReadPref("gdbBreakOnLoad", 0);
491 gdbPort = ReadPref("gdbPort", 55555);
492 glFilter = ReadPref("glFilter", 1);
493 ifbType = ReadPref("ifbType", 0);
494 joypadDefault = ReadPref("joypadDefault", 0);
495 languageOption = ReadPref("language", 1);
496 linkAuto = ReadPref("LinkAuto", 1);
497 linkHacks = ReadPref("LinkHacks", 0);
498 linkHostAddr = ReadPrefString("LinkHostAddr", "localhost");
499 linkMode = ReadPref("LinkMode", 0); // LINK_DISCONNECTED = 0
500 linkNumPlayers = ReadPref("LinkNumPlayers", 2);
501 linkTimeout = ReadPref("LinkTimeout", 1);
502 loadDotCodeFile = ReadPrefString("loadDotCodeFile");
503 maxScale = ReadPref("maxScale", 0);
504 movieRecordDir = ReadPrefString("movieRecordDir");
505 openGL = ReadPrefHex("openGL");
506 optFlashSize = ReadPrefHex("flashSize");
507 pauseWhenInactive = ReadPref("pauseWhenInactive", 1);
508 recentFreeze = ReadPref("recentFreeze", 0);
509 rewindTimer = ReadPref("rewindTimer", 0);
510 romDirGB = ReadPrefString("romDirGB");
511 romDirGBA = ReadPrefString("romDirGBA");
512 romDirGBC = ReadPrefString("romDirGBC");
513 rtcEnabled = ReadPref("rtcEnabled", 0);
514 saveDir = ReadPrefString("saveDir");
515 saveDotCodeFile = ReadPrefString("saveDotCodeFile");
516 screenShotDir = ReadPrefString("screenShotDir");
517 showSpeed = ReadPref("showSpeed", 0);
518 showSpeedTransparent = ReadPref("showSpeedTransparent", 1);
519 skipBios = ReadPref("skipBios", 0);
520 skipSaveGameBattery = ReadPref("skipSaveGameBattery", 0);
521 skipSaveGameCheats = ReadPref("skipSaveGameCheats", 0);
522 soundFiltering = (float)ReadPref("gbaSoundFiltering", 50) / 100.0f;
523 soundInterpolation = ReadPref("gbaSoundInterpolation", 1);
524 soundRecordDir = ReadPrefString("soundRecordDir");
525 threadPriority = ReadPref("priority", 2);
526 throttle = ReadPref("throttle", 100);
527 tripleBuffering = ReadPref("tripleBuffering", 0);
528 useBios = ReadPrefHex("useBiosGBA");
529 useBiosFileGB = ReadPref("useBiosGB", 0);
530 useBiosFileGBA = ReadPref("useBiosGBA", 0);
531 useBiosFileGBC = ReadPref("useBiosGBC", 0);
532 videoOption = ReadPref("video", 2); // VIDEO_3X = 2
533 vsync = ReadPref("vsync", false);
534 windowPositionX = ReadPref("windowX", 0);
535 windowPositionY = ReadPref("windowY", 0);
536 winFlashSize = ReadPref("flashSize", 0x10000);
537 winGbBorderOn = ReadPref("borderOn", 0);
538 winGbPrinterEnabled = ReadPref("gbPrinter", 0);
539
540 int soundQuality = (ReadPrefHex("soundQuality"));
541 switch (soundQuality) {
542 case 1:
543 case 2:
544 case 4:
545 break;
546 default:
547 log("Unknown sound quality %d. Defaulting to 22Khz\n", soundQuality);
548 soundQuality = 2;
549 break;
550 }
551 soundSetSampleRate(44100 / soundQuality);
552 int volume = ReadPref("soundVolume", 100);
553 float volume_percent = volume / 100.0f;
554 if (volume_percent < 0.0 || volume_percent > SOUND_MAX_VOLUME)
555 volume_percent = 1.0;
556 soundSetVolume(volume_percent);
557
558 soundSetEnable((ReadPrefHex("soundEnable")) & 0x30f);
559 if ((ReadPrefHex("soundStereo"))) {
560 gb_effects_config.enabled = true;
561 }
562 if ((ReadPrefHex("soundEcho"))) {
563 gb_effects_config.enabled = true;
564 }
565 if ((ReadPrefHex("soundSurround"))) {
566 gb_effects_config.surround = true;
567 gb_effects_config.enabled = true;
568 }
569
570 if (optFlashSize == 0)
571 flashSetSize(0x10000);
572 else
573 flashSetSize(0x20000);
574
575 rtcEnable(rtcEnabled ? true : false);
576 agbPrintEnable(agbPrint ? true : false);
577
578 for (int i = 0; i < 24;) {
579 systemGbPalette[i++] = (0x1f) | (0x1f << 5) | (0x1f << 10);
580 systemGbPalette[i++] = (0x15) | (0x15 << 5) | (0x15 << 10);
581 systemGbPalette[i++] = (0x0c) | (0x0c << 5) | (0x0c << 10);
582 systemGbPalette[i++] = 0;
583 }
584
585 systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
586
587 optPrintUsage = 0;
588
589 // TODO
590 //int s = ReadPref("mapViewStretch", 0);
591 //m_size = ReadPref("memViewerDataSize", 0);
592 //m_stretch = ReadPref("GBOamViewStretch", 0);
593 //m_stretch = ReadPref("tileViewStretch", 0);
594 //numberType = ReadPref("cheatsNumberType", 2);
595 //numberType = ReadPref("gbCheatsNumberType", 2);
596 //restoreValues = ReadPref("cheatsRestore", 0) ?
597 //scale = ReadPref("printerScale", 0);
598 //searchType = ReadPref("cheatsSearchType", SEARCH_EQ);
599 //searchType = ReadPref("gbCheatsSearchType",
600 //selectedFilter = ReadPref(("selectedFilter"), 0);
601 //sizeType = ReadPref("cheatsSizeType", 0);
602 //sizeType = ReadPref("gbCheatsSizeType", 0);
603 //updateValues = ReadPref("cheatsUpdate", 0);
604 //updateValues = ReadPref("gbCheatsUpdate", 0);
605 //valueType = ReadPref("cheatsValueType", 0);
606 //valueType = ReadPref("gbCheatsValueType", 0);
607
608 ValidateConfig();
609 }
610
CloseConfig()611 void CloseConfig()
612 {
613 if (preferences)
614 iniparser_freedict(preferences);
615 }
616
FindConfigFile(char * name)617 char* FindConfigFile(char *name)
618 {
619 char buffer[4096];
620
621 #ifdef _WIN32
622 #define PATH_SEP ";"
623 #define FILE_SEP '\\'
624 #define EXE_NAME "vbam.exe"
625 #else // ! _WIN32
626 #define PATH_SEP ":"
627 #define FILE_SEP '/'
628 #define EXE_NAME "vbam"
629 #endif // ! _WIN32
630
631 if (GETCWD(buffer, 2048)) {
632 }
633
634 if (FileExists(name))
635 {
636 return name;
637 }
638
639 if (homeDir) {
640 sprintf(path, "%s%c%s%c%s", homeDir, FILE_SEP, DOT_DIR, FILE_SEP, name);
641 if (FileExists(path))
642 {
643 return path;
644 }
645 }
646
647 #ifdef _WIN32
648 char *home = getenv("USERPROFILE");
649 if (home != NULL) {
650 sprintf(path, "%s%c%s", home, FILE_SEP, name);
651 if (FileExists(path))
652 {
653 return path;
654 }
655 }
656
657 if (!strchr(arg0, '/') &&
658 !strchr(arg0, '\\')) {
659 char *path = getenv("PATH");
660
661 if (path != NULL) {
662 strncpy(buffer, path, 4096);
663 buffer[4095] = 0;
664 char *tok = strtok(buffer, PATH_SEP);
665
666 while (tok) {
667 sprintf(path, "%s%c%s", tok, FILE_SEP, EXE_NAME);
668 if (FileExists(path)) {
669 char path2[2048];
670 sprintf(path2, "%s%c%s", tok, FILE_SEP, name);
671 if (FileExists(path2)) {
672 return path2;
673 }
674 }
675 tok = strtok(NULL, PATH_SEP);
676 }
677 }
678 }
679 else {
680 // executable is relative to some directory
681 strcpy(buffer, arg0);
682 char *p = strrchr(buffer, FILE_SEP);
683 if (p) {
684 *p = 0;
685 sprintf(path, "%s%c%s", buffer, FILE_SEP, name);
686 if (FileExists(path))
687 {
688 return path;
689 }
690 }
691 }
692 #else // ! _WIN32
693 sprintf(path, "%s%c%s", PKGDATADIR, FILE_SEP, name);
694 if (FileExists(path))
695 {
696 return path;
697 }
698
699 sprintf(path, "%s%c%s", SYSCONFDIR, FILE_SEP, name);
700 if (FileExists(path))
701 {
702 return path;
703 }
704 #endif // ! _WIN32
705 return 0;
706 }
707
LoadConfigFile()708 void LoadConfigFile()
709 {
710 #ifndef _WIN32
711 // Get home dir
712 char buf[1024];
713 struct stat s;
714 homeDir = getenv("HOME");
715 snprintf(buf, 1024, "%s/%s", homeDir, DOT_DIR);
716 // Make dot dir if not existent
717 if (stat(buf, &s) == -1 || !S_ISDIR(s.st_mode))
718 mkdir(buf, 0755);
719 #else
720 homeDir = 0;
721 #endif
722
723 if (preferences == NULL)
724 {
725 char* configFile = FindConfigFile("vbam.ini");
726 OpenPreferences(configFile);
727 }
728
729 if (preferences == NULL)
730 {
731 char* configFile = FindConfigFile("vbam.cfg");
732 OpenPreferences(configFile);
733 }
734 }
735
SaveConfigFile()736 void SaveConfigFile()
737 {
738 #ifndef _WIN32
739 // Get home dir
740 char buf[1024];
741 struct stat s;
742 homeDir = getenv("HOME");
743 snprintf(buf, 1024, "%s/%s", homeDir, DOT_DIR);
744 // Make dot dir if not existent
745 if (stat(buf, &s) == -1 || !S_ISDIR(s.st_mode))
746 mkdir(buf, 0755);
747 #else
748 homeDir = 0;
749 #endif
750
751 char* configFile = FindConfigFile("vbam.ini");
752
753 if (configFile == NULL)
754 {
755 configFile = FindConfigFile("vbam.cfg");
756 }
757
758 if (configFile != NULL)
759 {
760 FILE *f = fopen(configFile, "w");
761 // Needs mixed case version of the option name to add new options into the ini
762 //for (int i = 0; i < (sizeof(argOptions) / sizeof(option)); i++)
763 //{
764 // std::string pref = "preferences:";
765 // pref.append(argOptions[i].name);
766 // if (!iniparser_find_entry(preferences, pref.c_str()))
767 // {
768 // iniparser_set(preferences, pref.c_str(), NULL);
769 // }
770 //}
771 iniparser_dump_ini(preferences, f);
772 fclose(f);
773 }
774 }
775
ReadPrefHex(char * pref_key)776 u32 ReadPrefHex(char* pref_key)
777 {
778 LoadConfigFile();
779 std::string pref = "preferences:";
780 pref.append(pref_key);
781 return fromHex(iniparser_getstring(preferences, pref.c_str(), 0));
782 }
783
ReadPref(char * pref_key,int default_value)784 u32 ReadPref(char* pref_key, int default_value)
785 {
786 LoadConfigFile();
787 std::string pref = "preferences:";
788 pref.append(pref_key);
789 return iniparser_getint(preferences, pref.c_str(), default_value);
790 }
791
ReadPref(char * pref_key)792 u32 ReadPref(char* pref_key)
793 {
794 return ReadPref(pref_key, 0);
795 }
796
ReadPrefString(char * pref_key,char * default_value)797 char* ReadPrefString(char* pref_key, char* default_value)
798 {
799 LoadConfigFile();
800 std::string pref = "preferences:";
801 pref.append(pref_key);
802 return iniparser_getstring(preferences, pref.c_str(), default_value);
803 }
804
ReadPrefString(char * pref_key)805 char* ReadPrefString(char* pref_key)
806 {
807 return ReadPrefString(pref_key, "");
808 }
809
ReadOpts(int argc,char ** argv)810 int ReadOpts(int argc, char ** argv)
811 {
812 int op = -1;
813 while ((op = getopt_long(argc,
814 argv,
815 "FNO:T:Y:G:I:D:b:c:df:hi:p::s:t:v:",
816 argOptions,
817 NULL)) != -1) {
818 switch (op) {
819 case 0:
820 // long option already processed by getopt_long
821 break;
822 case OPT_CHEAT:
823 // --cheat
824 if (preparedCheats >= MAX_CHEATS) {
825 log("Warning: cannot add more than %d cheats.\n", MAX_CHEATS);
826 break;
827 }
828 {
829 //char* cpy;
830 //cpy = (char *)malloc(1 + strlen(optarg));
831 //strcpy(cpy, optarg);
832 //preparedCheatCodes[preparedCheats++] = cpy;
833 std::string cpy = optarg;
834 preparedCheatCodes[preparedCheats++] = cpy.c_str();
835 }
836 break;
837 case OPT_AUTOFIRE:
838 // --autofire
839 autoFireMaxCount = fromDec(optarg);
840 if (autoFireMaxCount < 1)
841 autoFireMaxCount = 1;
842 break;
843 case 'b':
844 useBios = true;
845 if (optarg == NULL) {
846 log("Missing BIOS file name\n");
847 break;
848 }
849 strcpy(biosFileNameGBA, optarg);
850 break;
851 case 'c':
852 {
853 if (optarg == NULL) {
854 log("Missing config file name\n");
855 break;
856 }
857 FILE *f = fopen(optarg, "r");
858 if (f == NULL) {
859 log("File not found %s\n", optarg);
860 break;
861 }
862 preferences = NULL;
863 OpenPreferences(optarg);
864 fclose(f);
865 }
866 break;
867 case 'd':
868 debugger = true;
869 break;
870 case 'h':
871 optPrintUsage = 1;
872 break;
873 case 'i':
874 if (optarg == NULL) {
875 log("Missing patch name\n");
876 break;
877 }
878 if (patchNum >= PATCH_MAX_NUM) {
879 log("Too many patches given at %s (max is %d). Ignoring.\n", optarg, PATCH_MAX_NUM);
880 }
881 else {
882 patchNames[patchNum] = (char *)malloc(1 + strlen(optarg));
883 strcpy(patchNames[patchNum], optarg);
884 patchNum++;
885 }
886 break;
887 case 'G':
888 dbgMain = remoteStubMain;
889 dbgSignal = remoteStubSignal;
890 dbgOutput = remoteOutput;
891 debugger = true;
892 if (optarg) {
893 char *s = optarg;
894 if (strncmp(s, "tcp:", 4) == 0) {
895 s += 4;
896 int port = atoi(s);
897 remoteSetProtocol(0);
898 remoteSetPort(port);
899 }
900 else if (strcmp(s, "tcp") == 0) {
901 remoteSetProtocol(0);
902 }
903 else if (strcmp(s, "pipe") == 0) {
904 remoteSetProtocol(1);
905 }
906 else {
907 log("Unknown protocol %s\n", s);
908 break;
909 }
910 }
911 else {
912 remoteSetProtocol(0);
913 }
914 break;
915 case 'N':
916 parseDebug = false;
917 break;
918 case 'F':
919 fullScreen = 1;
920 mouseCounter = 120;
921 break;
922 case 'f':
923 if (optarg) {
924 filter = (Filter)atoi(optarg);
925 }
926 else {
927 filter = kStretch2x;
928 }
929 break;
930 case 'I':
931 if (optarg) {
932 ifbType = (IFBFilter)atoi(optarg);
933 }
934 else {
935 ifbType = kIFBNone;
936 }
937 break;
938 case 'p':
939 #ifdef PROFILING
940 if (optarg) {
941 cpuEnableProfiling(atoi(optarg));
942 }
943 else
944 cpuEnableProfiling(100);
945 #endif
946 break;
947 case 'S':
948 optFlashSize = atoi(optarg);
949 if (optFlashSize < 0 || optFlashSize > 1)
950 optFlashSize = 0;
951 break;
952 case 's':
953 if (optarg) {
954 int a = atoi(optarg);
955 if (a >= 0 && a <= 9) {
956 gbFrameSkip = a;
957 frameSkip = a;
958 }
959 }
960 else {
961 frameSkip = 2;
962 gbFrameSkip = 0;
963 }
964 break;
965 case 't':
966 if (optarg) {
967 int a = atoi(optarg);
968 if (a < 0 || a > 5)
969 a = 0;
970 cpuSaveType = a;
971 }
972 break;
973 case 'v':
974 if (optarg) {
975 systemVerbose = atoi(optarg);
976 }
977 else
978 systemVerbose = 0;
979 break;
980 case '?':
981 optPrintUsage = 1;
982 break;
983 case 'O':
984 if (optarg) {
985 openGL = atoi(optarg);
986 if (openGL < 0 || openGL > 2)
987 openGL = 1;
988 }
989 else
990 openGL = 0;
991 break;
992
993 case OPT_CAPTURE_FORMAT:
994 // --capture-format
995 if (optarg) {
996 captureFormat = atoi(optarg);
997 }
998 break;
999
1000 case OPT_SHOW_SPEED_TRANSPARENT:
1001 // --show-speed-transparent
1002 if (optarg) {
1003 showSpeedTransparent = atoi(optarg);
1004 }
1005 break;
1006
1007 case OPT_AUTO_FRAME_SKIP:
1008 // --auto-frame-skip
1009 if (optarg) {
1010 autoFrameSkip = atoi(optarg);
1011 }
1012 break;
1013
1014 case OPT_AGB_PRINT:
1015 // --agb-print
1016 if (optarg) {
1017 agbPrint = atoi(optarg);
1018 }
1019 break;
1020
1021 case OPT_RTC_ENABLED:
1022 // --rtc-enabled
1023 if (optarg) {
1024 rtcEnabled = atoi(optarg);
1025 }
1026 break;
1027
1028 case OPT_VIDEO_OPTION:
1029 // --video-option
1030 if (optarg) {
1031 videoOption = atoi(optarg);
1032 }
1033 break;
1034
1035 case OPT_LANGUAGE_OPTION:
1036 // --language-option
1037 if (optarg) {
1038 languageOption = atoi(optarg);
1039 }
1040 break;
1041
1042 case OPT_GB_FRAME_SKIP:
1043 // --gb-frame-skip
1044 if (optarg) {
1045 gbFrameSkip = atoi(optarg);
1046 }
1047 break;
1048
1049 case OPT_FS_ADAPTER:
1050 // --fs-adapter
1051 if (optarg) {
1052 fsAdapter = atoi(optarg);
1053 }
1054 break;
1055
1056 case OPT_FS_WIDTH:
1057 // --fs-width
1058 if (optarg) {
1059 fsWidth = atoi(optarg);
1060 }
1061 break;
1062
1063 case OPT_FS_HEIGHT:
1064 // --fs-height
1065 if (optarg) {
1066 fsHeight = atoi(optarg);
1067 }
1068 break;
1069
1070 case OPT_FS_COLOR_DEPTH:
1071 // --fs-color-depth
1072 if (optarg) {
1073 fsColorDepth = atoi(optarg);
1074 }
1075 break;
1076
1077 case OPT_FS_FREQUENCY:
1078 // --fs-frequency
1079 if (optarg) {
1080 fsFrequency = atoi(optarg);
1081 }
1082 break;
1083
1084 case OPT_WINDOW_POSITION_X:
1085 // --window-position-x
1086 if (optarg) {
1087 windowPositionX = atoi(optarg);
1088 }
1089 break;
1090
1091 case OPT_WINDOW_POSITION_Y:
1092 // --window-position-y
1093 if (optarg) {
1094 windowPositionY = atoi(optarg);
1095 }
1096 break;
1097
1098 case OPT_SOUND_FILTERING:
1099 // --sound-filtering
1100 if (optarg) {
1101 soundFiltering = atoi(optarg);
1102 }
1103 break;
1104
1105 case OPT_GL_FILTER:
1106 // --gl-filter
1107 if (optarg) {
1108 glFilter = atoi(optarg);
1109 }
1110 break;
1111
1112 case OPT_SHOW_SPEED:
1113 // --show-speed
1114 if (optarg) {
1115 showSpeed = atoi(optarg);
1116 }
1117 break;
1118
1119 case OPT_IFB_TYPE:
1120 // --ifb-type
1121 if (optarg) {
1122 ifbType = atoi(optarg);
1123 }
1124 break;
1125
1126 case OPT_GB_EMULATOR_TYPE:
1127 // --gb-emulator-type
1128 if (optarg) {
1129 gbEmulatorType = atoi(optarg);
1130 }
1131 break;
1132
1133 case OPT_THREAD_PRIORITY:
1134 // --thread-priority
1135 if (optarg) {
1136 threadPriority = atoi(optarg);
1137 }
1138 break;
1139
1140 case OPT_GB_PALETTE_OPTION:
1141 // --gb-palette-option
1142 if (optarg) {
1143 gbPaletteOption = atoi(optarg);
1144 }
1145 break;
1146
1147 case OPT_REWIND_TIMER:
1148 // --rewind-timer
1149 if (optarg) {
1150 rewindTimer = atoi(optarg);
1151 }
1152 break;
1153
1154 case OPT_JOYPAD_DEFAULT:
1155 // --joypad-default
1156 if (optarg) {
1157 joypadDefault = atoi(optarg);
1158 }
1159 break;
1160
1161 case OPT_MAX_SCALE:
1162 // --max-scale
1163 if (optarg) {
1164 maxScale = atoi(optarg);
1165 }
1166 break;
1167
1168 case OPT_LINK_TIMEOUT:
1169 // --link-timeout
1170 if (optarg) {
1171 linkTimeout = atoi(optarg);
1172 }
1173 break;
1174
1175 case OPT_LINK_MODE:
1176 // --link-mode
1177 if (optarg) {
1178 linkMode = atoi(optarg);
1179 }
1180 break;
1181
1182 case OPT_LINK_AUTO:
1183 // --link-auto
1184 if (optarg) {
1185 linkAuto = atoi(optarg);
1186 }
1187 break;
1188
1189 case OPT_LINK_HACKS:
1190 // --link-hacks
1191 if (optarg) {
1192 linkHacks = atoi(optarg);
1193 }
1194 break;
1195
1196 case OPT_LINK_NUM_PLAYERS:
1197 // --link-num-players
1198 if (optarg) {
1199 linkNumPlayers = atoi(optarg);
1200 }
1201 break;
1202
1203 case OPT_GDB_PORT:
1204 // --gdb-port
1205 if (optarg) {
1206 gdbPort = atoi(optarg);
1207 }
1208 break;
1209
1210 case OPT_BIOS_FILE_NAME_GB:
1211 // --bios-file-name-gb
1212 biosFileNameGB = optarg;
1213 break;
1214
1215 case OPT_BIOS_FILE_NAME_GBA:
1216 // --bios-file-name-gba
1217 biosFileNameGBA = optarg;
1218 break;
1219
1220 case OPT_BIOS_FILE_NAME_GBC:
1221 // --bios-file-name-gbc
1222 biosFileNameGBC = optarg;
1223 break;
1224
1225 case OPT_AVI_RECORD_DIR:
1226 // --avi-record-dir
1227 aviRecordDir = optarg;
1228 break;
1229
1230 case OPT_MOVIE_RECORD_DIR:
1231 // --movie-record-dir
1232 movieRecordDir = optarg;
1233 break;
1234
1235 case OPT_SOUND_RECORD_DIR:
1236 // --sound-record-dir
1237 soundRecordDir = optarg;
1238 break;
1239
1240 case OPT_SCREEN_SHOT_DIR:
1241 // --screen-shot-dir
1242 screenShotDir = optarg;
1243 break;
1244
1245 case OPT_SAVE_DIR:
1246 // --save-dir
1247 saveDir = optarg;
1248 break;
1249
1250 case OPT_BATTERY_DIR:
1251 // --battery-dir
1252 batteryDir = optarg;
1253 break;
1254
1255 case OPT_ROM_DIR_GBC:
1256 // --rom-dir-gbc
1257 romDirGBC = optarg;
1258 break;
1259
1260 case OPT_ROM_DIR_GB:
1261 // --rom-dir-gb
1262 romDirGB = optarg;
1263 break;
1264
1265 case OPT_ROM_DIR_GBA:
1266 // --rom-dir-gba
1267 romDirGBA = optarg;
1268 break;
1269
1270 case OPT_LINK_HOST_ADDR:
1271 // --link-host-addr
1272 linkHostAddr = optarg;
1273 break;
1274
1275 case OPT_CPU_SAVE_TYPE:
1276 // --cpu-save-type
1277 if (optarg) {
1278 cpuSaveType = atoi(optarg);
1279 }
1280 break;
1281
1282 case OPT_OPT_FLASH_SIZE:
1283 // --opt-flash-size
1284 if (optarg) {
1285 optFlashSize = atoi(optarg);
1286 }
1287 break;
1288
1289 case OPT_DOTCODE_FILE_NAME_LOAD:
1290 // --dotcode-file-name-load
1291 loadDotCodeFile = optarg;
1292 break;
1293
1294 case OPT_DOTCODE_FILE_NAME_SAVE:
1295 // --dotcode-file-name-save
1296 saveDotCodeFile = optarg;
1297 break;
1298 }
1299 }
1300 return op;
1301 }
1302
1303