mirror of https://github.com/mgba-emu/mgba.git
Merge branch 'master' (early part) into medusa
This commit is contained in:
commit
6c75f9b08c
5
CHANGES
5
CHANGES
|
@ -59,6 +59,7 @@ Emulation fixes:
|
|||
- ARM7: Fix unsigned multiply timing
|
||||
- GB: Copy logo from ROM if not running the BIOS intro (fixes mgba.io/i/2378)
|
||||
- GB Audio: Fix channel 1/2 reseting edge cases (fixes mgba.io/i/1925)
|
||||
- GB Audio: Properly apply per-model audio differences
|
||||
- GB Memory: Add cursory cartridge open bus emulation (fixes mgba.io/i/2032)
|
||||
- GB Serialize: Fix loading MBC1 states that affect bank 0 (fixes mgba.io/i/2402)
|
||||
- GB Video: Draw SGB border pieces that overlap GB graphics (fixes mgba.io/i/1339)
|
||||
|
@ -77,6 +78,7 @@ Emulation fixes:
|
|||
Other fixes:
|
||||
- Core: Don't attempt to restore rewind diffs past start of rewind
|
||||
- Core: Fix the runloop resuming after a game has crashed (fixes mgba.io/i/2451)
|
||||
- Core: Fix crash if library can't be opened
|
||||
- FFmpeg: Fix crash when encoding audio with some containers
|
||||
- FFmpeg: Fix GIF recording (fixes mgba.io/i/2393)
|
||||
- GB: Fix temporary saves
|
||||
|
@ -89,6 +91,7 @@ Misc:
|
|||
- Core: Suspend runloop when a core crashes
|
||||
- Debugger: Save and restore CLI history
|
||||
- Debugger: GDB now works while the game is paused
|
||||
- Debugger: Add command to load external symbol file (fixes mgba.io/i/2480)
|
||||
- GB MBC: Filter out MBC errors when cartridge is yanked (fixes mgba.io/i/2488)
|
||||
- GB Video: Add default SGB border
|
||||
- GBA: Automatically skip BIOS if ROM has invalid logo
|
||||
|
@ -109,6 +112,8 @@ Misc:
|
|||
- Qt: Enable -b for Boot BIOS menu option (fixes mgba.io/i/2074)
|
||||
- Qt: Add tile range selection to tile viewer (closes mgba.io/i/2455)
|
||||
- Qt: Show warning if XQ audio is toggled while loaded (fixes mgba.io/i/2295)
|
||||
- Qt: Add e-Card passing to the command line (closes mgba.io/i/2474)
|
||||
- Qt: Boot both a multiboot image and ROM with CLI args (closes mgba.io/i/1941)
|
||||
- Windows: Attach to console if present
|
||||
- Vita: Add bilinear filtering option (closes mgba.io/i/344)
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ Supported Platforms
|
|||
-------------------
|
||||
|
||||
- Windows 7 or newer
|
||||
- OS X 10.8 (Mountain Lion)[<sup>[4]</sup>](#osxver) or newer
|
||||
- OS X 10.9 (Mavericks)[<sup>[4]</sup>](#osxver) or newer
|
||||
- Linux
|
||||
- FreeBSD
|
||||
|
||||
|
@ -292,7 +292,7 @@ Missing features on DS are
|
|||
|
||||
<a name="flashdetect">[3]</a> Flash memory size detection does not work in some cases. These can be configured at runtime, but filing a bug is recommended if such a case is encountered.
|
||||
|
||||
<a name="osxver">[4]</a> 10.8 is only needed for the Qt port. It may be possible to build or running the Qt port on 10.7 or older, but this is not officially supported. The SDL port is known to work on 10.5, and may work on older.
|
||||
<a name="osxver">[4]</a> 10.9 is only needed for the Qt port. It may be possible to build or running the Qt port on 10.7 or older, but this is not officially supported. The SDL port is known to work on 10.5, and may work on older.
|
||||
|
||||
[downloads]: http://mgba.io/downloads.html
|
||||
[source]: https://github.com/mgba-emu/mgba/
|
||||
|
|
|
@ -80,7 +80,7 @@ Unterstützte Plattformen
|
|||
------------------------
|
||||
|
||||
- Windows 7 oder neuer
|
||||
- OS X 10.8 (Mountain Lion)[<sup>[3]</sup>](#osxver) oder neuer
|
||||
- OS X 10.9 (Mavericks)[<sup>[3]</sup>](#osxver) oder neuer
|
||||
- Linux
|
||||
- FreeBSD
|
||||
- Nintendo 3DS
|
||||
|
@ -234,7 +234,7 @@ Fußnoten
|
|||
|
||||
<a name="flashdetect">[2]</a> In manchen Fällen ist es nicht möglich, die Größe des Flash-Speichers automatisch zu ermitteln. Diese kann dann zur Laufzeit konfiguriert werden, es wird jedoch empfohlen, den Fehler zu melden.
|
||||
|
||||
<a name="osxver">[3]</a> 10.8 wird nur für die Qt-Portierung benötigt. Es ist wahrscheinlich möglich, die Qt-Portierung unter macOS 10.7 und älter zu bauen und zu nutzen, aber das wird nicht offiziell unterstützt. Die SDL-Portierung ist dafür bekannt, mit 10.7 und möglicherweise auf älteren Versionen zu funktionieren.
|
||||
<a name="osxver">[3]</a> 10.9 wird nur für die Qt-Portierung benötigt. Es ist wahrscheinlich möglich, die Qt-Portierung unter macOS 10.7 und älter zu bauen und zu nutzen, aber das wird nicht offiziell unterstützt. Die SDL-Portierung ist dafür bekannt, mit 10.7 und möglicherweise auf älteren Versionen zu funktionieren.
|
||||
|
||||
[downloads]: http://mgba.io/downloads.html
|
||||
[source]: https://github.com/mgba-emu/mgba/
|
||||
|
|
|
@ -80,7 +80,7 @@ Plataformas soportadas
|
|||
-------------------
|
||||
|
||||
- Windows 7 o más reciente
|
||||
- OS X 10.8 (Mountain Lion)[<sup>[3]</sup>](#osxver) o más reciente
|
||||
- OS X 10.9 (Mavericks)[<sup>[3]</sup>](#osxver) o más reciente
|
||||
- Linux
|
||||
- FreeBSD
|
||||
- Nintendo 3DS
|
||||
|
@ -234,7 +234,7 @@ Notas a pie
|
|||
|
||||
<a name="flashdetect">[2]</a> La detección del tamaño de la memoria flash no funciona en algunos casos. Se pueden configurar en tiempo de ejecución, pero se recomienda ingresar un bug si se encuentra un caso así.
|
||||
|
||||
<a name="osxver">[3]</a> 10.8 sólo se necesita para la versión con Qt. Puede ser posible compilar o hacer funcionar la versión Qt en 10.7 o versiones más antigas, pero esto no está oficialmente soportado. La versión SDL funciona en 10.5, y puede funcionar en versiones anteriores.
|
||||
<a name="osxver">[3]</a> 10.9 sólo se necesita para la versión con Qt. Puede ser posible compilar o hacer funcionar la versión Qt en 10.7 o versiones más antigas, pero esto no está oficialmente soportado. La versión SDL funciona en 10.5, y puede funcionar en versiones anteriores.
|
||||
|
||||
[downloads]: http://mgba.io/downloads.html
|
||||
[source]: https://github.com/mgba-emu/mgba/
|
||||
|
|
|
@ -78,7 +78,7 @@ mGBA 是一个运行 Game Boy Advance 游戏的模拟器。mGBA 的目标是比
|
|||
-------------------
|
||||
|
||||
- Windows 7 或更新
|
||||
- OS X 10.8(山狮 / Mountain Lion)[<sup>[3]</sup>](#osxver) 或更新
|
||||
- OS X 10.9(Mavericks)[<sup>[3]</sup>](#osxver) 或更新
|
||||
- Linux
|
||||
- FreeBSD
|
||||
- Nintendo 3DS
|
||||
|
@ -232,7 +232,7 @@ Footnotes
|
|||
|
||||
<a name="flashdetect">[2]</a> 闪存大小检测在某些情况下不起作用。 这些可以在运行时中进行配置,但如果遇到此类情况,建议提交错误。
|
||||
|
||||
<a name="osxver">[3]</a> 仅 Qt 端口需要 10.8。应该可以在 10.7 或更早版本上构建或运行 Qt 端口,但这类操作不受官方支持。已知 SDL 端口可以在 10.5 上运行,并且可能能够在旧版本上运行。
|
||||
<a name="osxver">[3]</a> 仅 Qt 端口需要 10.9。应该可以在 10.7 或更早版本上构建或运行 Qt 端口,但这类操作不受官方支持。已知 SDL 端口可以在 10.5 上运行,并且可能能够在旧版本上运行。
|
||||
|
||||
[downloads]: http://mgba.io/downloads.html
|
||||
[source]: https://github.com/mgba-emu/mgba/
|
||||
|
|
|
@ -31,12 +31,20 @@ struct mArguments {
|
|||
bool showVersion;
|
||||
};
|
||||
|
||||
struct mOption {
|
||||
const char* name;
|
||||
bool arg;
|
||||
char shortEquiv;
|
||||
};
|
||||
|
||||
struct mCoreConfig;
|
||||
struct mSubParser {
|
||||
const char* usage;
|
||||
bool (*parse)(struct mSubParser* parser, int option, const char* arg);
|
||||
bool (*parseLong)(struct mSubParser* parser, const char* option, const char* arg);
|
||||
void (*apply)(struct mSubParser* parser, struct mCoreConfig* config);
|
||||
const char* extraOptions;
|
||||
const struct mOption* longOptions;
|
||||
void* opts;
|
||||
};
|
||||
|
||||
|
@ -45,15 +53,14 @@ struct mGraphicsOpts {
|
|||
bool fullscreen;
|
||||
};
|
||||
|
||||
bool parseArguments(struct mArguments* args, int argc, char* const* argv,
|
||||
struct mSubParser* subparser);
|
||||
void applyArguments(const struct mArguments* args, struct mSubParser* subparser, struct mCoreConfig* config);
|
||||
void freeArguments(struct mArguments* args);
|
||||
|
||||
void usage(const char* arg0, const char* extraOptions);
|
||||
void usage(const char* arg0, const char* prologue, const char* epilogue, const struct mSubParser* subparsers, int nSubparsers);
|
||||
void version(const char* arg0);
|
||||
|
||||
void initParserForGraphics(struct mSubParser* parser, struct mGraphicsOpts* opts);
|
||||
bool mArgumentsParse(struct mArguments* args, int argc, char* const* argv, struct mSubParser* subparsers, int nSubparsers);
|
||||
void mArgumentsApply(const struct mArguments* args, struct mSubParser* subparsers, int nSubparsers, struct mCoreConfig* config);
|
||||
void mArgumentsDeinit(struct mArguments* args);
|
||||
|
||||
void mSubParserGraphicsInit(struct mSubParser* parser, struct mGraphicsOpts* opts);
|
||||
|
||||
CXX_GUARD_END
|
||||
|
||||
|
|
|
@ -98,6 +98,7 @@ struct GBA {
|
|||
uint32_t romCrc32;
|
||||
struct VFile* romVf;
|
||||
struct VFile* biosVf;
|
||||
struct VFile* mbVf;
|
||||
|
||||
struct mAVStream* stream;
|
||||
struct mKeyCallback* keyCallback;
|
||||
|
@ -171,6 +172,8 @@ void GBALoadBIOS(struct GBA* gba, struct VFile* vf);
|
|||
void GBAApplyPatch(struct GBA* gba, struct Patch* patch);
|
||||
|
||||
bool GBALoadMB(struct GBA* gba, struct VFile* vf);
|
||||
void GBAUnloadMB(struct GBA* gba);
|
||||
|
||||
bool GBALoadNull(struct GBA* gba);
|
||||
|
||||
void GBAGetGameCode(const struct GBA* gba, char* out);
|
||||
|
|
|
@ -199,6 +199,10 @@ error:
|
|||
}
|
||||
|
||||
void mLibraryDestroy(struct mLibrary* library) {
|
||||
if (!library) {
|
||||
return;
|
||||
}
|
||||
|
||||
sqlite3_finalize(library->insertPath);
|
||||
sqlite3_finalize(library->insertRom);
|
||||
sqlite3_finalize(library->insertRoot);
|
||||
|
|
|
@ -8,15 +8,17 @@
|
|||
#include <mgba/internal/debugger/symbols.h>
|
||||
|
||||
#include <mgba/core/core.h>
|
||||
#include <mgba/core/timing.h>
|
||||
#include <mgba/core/version.h>
|
||||
#include <mgba/internal/debugger/parser.h>
|
||||
#include <mgba-util/string.h>
|
||||
#include <mgba-util/vfs.h>
|
||||
|
||||
#ifdef ENABLE_SCRIPTING
|
||||
#include <mgba/core/scripting.h>
|
||||
#endif
|
||||
#include <mgba/core/timing.h>
|
||||
#include <mgba/core/version.h>
|
||||
#include <mgba/internal/debugger/parser.h>
|
||||
#ifdef USE_ELF
|
||||
#include <mgba-util/elf-read.h>
|
||||
#endif
|
||||
#include <mgba-util/string.h>
|
||||
#include <mgba-util/vfs.h>
|
||||
|
||||
#if !defined(NDEBUG) && !defined(_WIN32)
|
||||
#include <signal.h>
|
||||
|
@ -74,6 +76,7 @@ static void _source(struct CLIDebugger*, struct CLIDebugVector*);
|
|||
static void _backtrace(struct CLIDebugger*, struct CLIDebugVector*);
|
||||
static void _finish(struct CLIDebugger*, struct CLIDebugVector*);
|
||||
static void _setStackTraceMode(struct CLIDebugger*, struct CLIDebugVector*);
|
||||
static void _loadSymbols(struct CLIDebugger*, struct CLIDebugVector*);
|
||||
static void _setSymbol(struct CLIDebugger*, struct CLIDebugVector*);
|
||||
static void _findSymbol(struct CLIDebugger*, struct CLIDebugVector*);
|
||||
|
||||
|
@ -101,6 +104,7 @@ static struct CLIDebuggerCommandSummary _debuggerCommands[] = {
|
|||
{ "stack", _setStackTraceMode, "S", "Change the stack tracing mode" },
|
||||
{ "status", _printStatus, "", "Print the current status" },
|
||||
{ "symbol", _findSymbol, "I", "Find the symbol name for an address" },
|
||||
{ "load-symbols", _loadSymbols, "S", "Load symbols from an external file" },
|
||||
{ "trace", _trace, "Is", "Trace a number of instructions" },
|
||||
{ "w/1", _writeByte, "II", "Write a byte at a specified offset" },
|
||||
{ "w/2", _writeHalfword, "II", "Write a halfword at a specified offset" },
|
||||
|
@ -133,6 +137,7 @@ static struct CLIDebuggerCommandAlias _debuggerCommandAliases[] = {
|
|||
{ "h", "help" },
|
||||
{ "i", "status" },
|
||||
{ "info", "status" },
|
||||
{ "loadsyms", "load-symbols" },
|
||||
{ "lb", "listb" },
|
||||
{ "lw", "listw" },
|
||||
{ "n", "next" },
|
||||
|
@ -1291,6 +1296,40 @@ static void _setStackTraceMode(struct CLIDebugger* debugger, struct CLIDebugVect
|
|||
}
|
||||
}
|
||||
|
||||
static void _loadSymbols(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
||||
struct mDebuggerSymbols* symbolTable = debugger->d.core->symbolTable;
|
||||
if (!symbolTable) {
|
||||
debugger->backend->printf(debugger->backend, "No symbol table available.\n");
|
||||
return;
|
||||
}
|
||||
if (!dv || dv->next) {
|
||||
debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS);
|
||||
return;
|
||||
}
|
||||
if (dv->type != CLIDV_CHAR_TYPE) {
|
||||
debugger->backend->printf(debugger->backend, "%s\n", ERROR_INVALID_ARGS);
|
||||
return;
|
||||
}
|
||||
struct VFile* vf = VFileOpen(dv->charValue, O_RDONLY);
|
||||
if (!vf) {
|
||||
debugger->backend->printf(debugger->backend, "%s\n", "Could not open symbol file");
|
||||
return;
|
||||
}
|
||||
#ifdef USE_ELF
|
||||
struct ELF* elf = ELFOpen(vf);
|
||||
if (elf) {
|
||||
#ifdef USE_DEBUGGERS
|
||||
mCoreLoadELFSymbols(symbolTable, elf);
|
||||
#endif
|
||||
ELFClose(elf);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
mDebuggerLoadARMIPSSymbols(symbolTable, vf);
|
||||
}
|
||||
vf->close(vf);
|
||||
}
|
||||
|
||||
static void _setSymbol(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
||||
struct mDebuggerSymbols* symbolTable = debugger->d.core->symbolTable;
|
||||
if (!symbolTable) {
|
||||
|
|
|
@ -16,16 +16,12 @@
|
|||
#include <getopt.h>
|
||||
#endif
|
||||
|
||||
#define GRAPHICS_OPTIONS "123456f"
|
||||
#define GRAPHICS_OPTIONS "12345678f"
|
||||
#define GRAPHICS_USAGE \
|
||||
"\nGraphics options:\n" \
|
||||
" -1 1x viewport\n" \
|
||||
" -2 2x viewport\n" \
|
||||
" -3 3x viewport\n" \
|
||||
" -4 4x viewport\n" \
|
||||
" -5 5x viewport\n" \
|
||||
" -6 6x viewport\n" \
|
||||
" -f Start full-screen"
|
||||
"Graphics options:\n" \
|
||||
" -1, -2, -3, -4, -5, -6, -7, -8 Scale viewport by 1-8 times\n" \
|
||||
" -f, --fullscreen Start full-screen\n" \
|
||||
" --scale X Scale viewport by X times"
|
||||
|
||||
static const struct option _options[] = {
|
||||
{ "bios", required_argument, 0, 'b' },
|
||||
|
@ -45,7 +41,14 @@ static const struct option _options[] = {
|
|||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static const struct mOption _graphicsLongOpts[] = {
|
||||
{ "fullscreen", false, 'f' },
|
||||
{ "scale", true, '\0' },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
static bool _parseGraphicsArg(struct mSubParser* parser, int option, const char* arg);
|
||||
static bool _parseLongGraphicsArg(struct mSubParser* parser, const char* option, const char* arg);
|
||||
static void _applyGraphicsArgs(struct mSubParser* parser, struct mCoreConfig* config);
|
||||
|
||||
static void _tableInsert(struct Table* table, const char* pair) {
|
||||
|
@ -65,9 +68,9 @@ static void _tableApply(const char* key, void* value, void* user) {
|
|||
mCoreConfigSetOverrideValue(config, key, value);
|
||||
}
|
||||
|
||||
bool parseArguments(struct mArguments* args, int argc, char* const* argv, struct mSubParser* subparser) {
|
||||
bool mArgumentsParse(struct mArguments* args, int argc, char* const* argv, struct mSubParser* subparsers, int nSubparsers) {
|
||||
int ch;
|
||||
char options[64] =
|
||||
char options[128] =
|
||||
"b:c:C:hl:p:s:t:"
|
||||
#ifdef USE_EDITLINE
|
||||
"d"
|
||||
|
@ -76,23 +79,51 @@ bool parseArguments(struct mArguments* args, int argc, char* const* argv, struct
|
|||
"g"
|
||||
#endif
|
||||
;
|
||||
|
||||
struct option longOptions[128] = {0};
|
||||
memcpy(longOptions, _options, sizeof(_options));
|
||||
|
||||
memset(args, 0, sizeof(*args));
|
||||
args->frameskip = -1;
|
||||
args->logLevel = INT_MIN;
|
||||
HashTableInit(&args->configOverrides, 0, free);
|
||||
if (subparser && subparser->extraOptions) {
|
||||
// TODO: modularize options to subparsers
|
||||
strncat(options, subparser->extraOptions, sizeof(options) - strlen(options) - 1);
|
||||
int lastLongOpt;
|
||||
|
||||
int i, j;
|
||||
for (i = 0; _options[i].name; ++i); // Seek to end
|
||||
lastLongOpt = i;
|
||||
|
||||
for (i = 0; i < nSubparsers; ++i) {
|
||||
if (subparsers[i].extraOptions) {
|
||||
strncat(options, subparsers[i].extraOptions, sizeof(options) - strlen(options) - 1);
|
||||
}
|
||||
if (subparsers[i].longOptions) {
|
||||
for (j = 0; subparsers[i].longOptions[j].name; ++j) {
|
||||
longOptions[lastLongOpt].name = subparsers[i].longOptions[j].name;
|
||||
longOptions[lastLongOpt].has_arg = subparsers[i].longOptions[j].arg ? required_argument : no_argument;
|
||||
longOptions[lastLongOpt].flag = NULL;
|
||||
longOptions[lastLongOpt].val = subparsers[i].longOptions[j].shortEquiv;
|
||||
++lastLongOpt;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool ok = false;
|
||||
int index = 0;
|
||||
while ((ch = getopt_long(argc, argv, options, _options, &index)) != -1) {
|
||||
const struct option* opt = &_options[index];
|
||||
while ((ch = getopt_long(argc, argv, options, longOptions, &index)) != -1) {
|
||||
const struct option* opt = &longOptions[index];
|
||||
switch (ch) {
|
||||
case '\0':
|
||||
if (strcmp(opt->name, "version") == 0) {
|
||||
args->showVersion = true;
|
||||
} else {
|
||||
return false;
|
||||
for (i = 0; i < nSubparsers; ++i) {
|
||||
if (subparsers[i].parseLong) {
|
||||
ok = subparsers[i].parseLong(&subparsers[i], opt->name, optarg) || ok;
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'b':
|
||||
|
@ -136,11 +167,14 @@ bool parseArguments(struct mArguments* args, int argc, char* const* argv, struct
|
|||
args->savestate = strdup(optarg);
|
||||
break;
|
||||
default:
|
||||
if (subparser) {
|
||||
if (!subparser->parse(subparser, ch, optarg)) {
|
||||
return false;
|
||||
for (i = 0; i < nSubparsers; ++i) {
|
||||
if (subparsers[i].parse) {
|
||||
ok = subparsers[i].parse(&subparsers[i], ch, optarg) || ok;
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -156,7 +190,7 @@ bool parseArguments(struct mArguments* args, int argc, char* const* argv, struct
|
|||
return true;
|
||||
}
|
||||
|
||||
void applyArguments(const struct mArguments* args, struct mSubParser* subparser, struct mCoreConfig* config) {
|
||||
void mArgumentsApply(const struct mArguments* args, struct mSubParser* subparsers, int nSubparsers, struct mCoreConfig* config) {
|
||||
if (args->frameskip >= 0) {
|
||||
mCoreConfigSetOverrideIntValue(config, "frameskip", args->frameskip);
|
||||
}
|
||||
|
@ -168,12 +202,15 @@ void applyArguments(const struct mArguments* args, struct mSubParser* subparser,
|
|||
mCoreConfigSetOverrideIntValue(config, "useBios", true);
|
||||
}
|
||||
HashTableEnumerate(&args->configOverrides, _tableApply, config);
|
||||
if (subparser) {
|
||||
subparser->apply(subparser, config);
|
||||
int i;
|
||||
for (i = 0; i < nSubparsers; ++i) {
|
||||
if (subparsers[i].apply) {
|
||||
subparsers[i].apply(&subparsers[i], config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void freeArguments(struct mArguments* args) {
|
||||
void mArgumentsDeinit(struct mArguments* args) {
|
||||
free(args->fname);
|
||||
args->fname = 0;
|
||||
|
||||
|
@ -192,12 +229,14 @@ void freeArguments(struct mArguments* args) {
|
|||
HashTableDeinit(&args->configOverrides);
|
||||
}
|
||||
|
||||
void initParserForGraphics(struct mSubParser* parser, struct mGraphicsOpts* opts) {
|
||||
void mSubParserGraphicsInit(struct mSubParser* parser, struct mGraphicsOpts* opts) {
|
||||
parser->usage = GRAPHICS_USAGE;
|
||||
parser->opts = opts;
|
||||
parser->parse = _parseGraphicsArg;
|
||||
parser->parseLong = _parseLongGraphicsArg;
|
||||
parser->apply = _applyGraphicsArgs;
|
||||
parser->extraOptions = GRAPHICS_OPTIONS;
|
||||
parser->longOptions = _graphicsLongOpts;
|
||||
opts->multiplier = 0;
|
||||
opts->fullscreen = false;
|
||||
}
|
||||
|
@ -215,6 +254,8 @@ bool _parseGraphicsArg(struct mSubParser* parser, int option, const char* arg) {
|
|||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
if (graphicsOpts->multiplier) {
|
||||
return false;
|
||||
}
|
||||
|
@ -225,6 +266,18 @@ bool _parseGraphicsArg(struct mSubParser* parser, int option, const char* arg) {
|
|||
}
|
||||
}
|
||||
|
||||
bool _parseLongGraphicsArg(struct mSubParser* parser, const char* option, const char* arg) {
|
||||
struct mGraphicsOpts* graphicsOpts = parser->opts;
|
||||
if (strcmp(option, "scale") == 0) {
|
||||
if (graphicsOpts->multiplier) {
|
||||
return false;
|
||||
}
|
||||
graphicsOpts->multiplier = atoi(arg);
|
||||
return graphicsOpts->multiplier != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void _applyGraphicsArgs(struct mSubParser* parser, struct mCoreConfig* config) {
|
||||
struct mGraphicsOpts* graphicsOpts = parser->opts;
|
||||
if (graphicsOpts->fullscreen) {
|
||||
|
@ -232,25 +285,36 @@ void _applyGraphicsArgs(struct mSubParser* parser, struct mCoreConfig* config) {
|
|||
}
|
||||
}
|
||||
|
||||
void usage(const char* arg0, const char* extraOptions) {
|
||||
void usage(const char* arg0, const char* prologue, const char* epilogue, const struct mSubParser* subparsers, int nSubparsers) {
|
||||
printf("usage: %s [option ...] file\n", arg0);
|
||||
puts("\nGeneric options:");
|
||||
puts(" -b, --bios FILE GBA BIOS file to use");
|
||||
puts(" -c, --cheats FILE Apply cheat codes from a file");
|
||||
puts(" -C, --config OPTION=VALUE Override config value");
|
||||
if (prologue) {
|
||||
puts(prologue);
|
||||
}
|
||||
puts("\nGeneric options:\n"
|
||||
" -b, --bios FILE GBA BIOS file to use\n"
|
||||
" -c, --cheats FILE Apply cheat codes from a file\n"
|
||||
" -C, --config OPTION=VALUE Override config value\n"
|
||||
#ifdef USE_EDITLINE
|
||||
puts(" -d, --debug Use command-line debugger");
|
||||
" -d, --debug Use command-line debugger\n"
|
||||
#endif
|
||||
#ifdef USE_GDB_STUB
|
||||
puts(" -g, --gdb Start GDB session (default port 2345)");
|
||||
" -g, --gdb Start GDB session (default port 2345)\n"
|
||||
#endif
|
||||
puts(" -l, --log-level N Log level mask");
|
||||
puts(" -t, --savestate FILE Load savestate when starting");
|
||||
puts(" -p, --patch FILE Apply a specified patch file when running");
|
||||
puts(" -s, --frameskip N Skip every N frames");
|
||||
puts(" --version Print version and exit");
|
||||
if (extraOptions) {
|
||||
puts(extraOptions);
|
||||
" -l, --log-level N Log level mask\n"
|
||||
" -t, --savestate FILE Load savestate when starting\n"
|
||||
" -p, --patch FILE Apply a specified patch file when running\n"
|
||||
" -s, --frameskip N Skip every N frames\n"
|
||||
" --version Print version and exit"
|
||||
);
|
||||
int i;
|
||||
for (i = 0; i < nSubparsers; ++i) {
|
||||
if (subparsers[i].usage) {
|
||||
puts("");
|
||||
puts(subparsers[i].usage);
|
||||
}
|
||||
}
|
||||
if (epilogue) {
|
||||
puts(epilogue);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
34
src/gb/gb.c
34
src/gb/gb.c
|
@ -556,6 +556,23 @@ void GBReset(struct SM83Core* cpu) {
|
|||
}
|
||||
}
|
||||
|
||||
switch (gb->model) {
|
||||
case GB_MODEL_DMG:
|
||||
case GB_MODEL_SGB:
|
||||
case GB_MODEL_AUTODETECT: //Silence warnings
|
||||
gb->audio.style = GB_AUDIO_DMG;
|
||||
break;
|
||||
case GB_MODEL_MGB:
|
||||
case GB_MODEL_SGB2:
|
||||
gb->audio.style = GB_AUDIO_MGB;
|
||||
break;
|
||||
case GB_MODEL_AGB:
|
||||
case GB_MODEL_CGB:
|
||||
case GB_MODEL_SCGB:
|
||||
gb->audio.style = GB_AUDIO_CGB;
|
||||
break;
|
||||
}
|
||||
|
||||
GBVideoReset(&gb->video);
|
||||
GBTimerReset(&gb->timer);
|
||||
GBIOReset(gb);
|
||||
|
@ -779,23 +796,6 @@ void GBDetectModel(struct GB* gb) {
|
|||
gb->model = GB_MODEL_DMG;
|
||||
}
|
||||
}
|
||||
|
||||
switch (gb->model) {
|
||||
case GB_MODEL_DMG:
|
||||
case GB_MODEL_SGB:
|
||||
case GB_MODEL_AUTODETECT: //Silence warnings
|
||||
gb->audio.style = GB_AUDIO_DMG;
|
||||
break;
|
||||
case GB_MODEL_MGB:
|
||||
case GB_MODEL_SGB2:
|
||||
gb->audio.style = GB_AUDIO_MGB;
|
||||
break;
|
||||
case GB_MODEL_AGB:
|
||||
case GB_MODEL_CGB:
|
||||
case GB_MODEL_SCGB:
|
||||
gb->audio.style = GB_AUDIO_CGB;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int GBValidModels(const uint8_t* bank0) {
|
||||
|
|
|
@ -627,7 +627,7 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i
|
|||
if (startX == 0) {
|
||||
_cleanOAM(softwareRenderer, y);
|
||||
}
|
||||
if (GBRegisterLCDCIsObjEnable(softwareRenderer->lcdc) && !softwareRenderer->d.disableOBJ) {
|
||||
if (GBRegisterLCDCIsObjEnable(softwareRenderer->lcdc) && !softwareRenderer->d.disableOBJ && (softwareRenderer->model != GB_MODEL_SCGB || softwareRenderer->sgbTransfer != 1)) {
|
||||
int i;
|
||||
for (i = 0; i < softwareRenderer->objMax; ++i) {
|
||||
GBVideoSoftwareRendererDrawObj(softwareRenderer, &softwareRenderer->obj[i], startX, endX, y);
|
||||
|
@ -917,7 +917,7 @@ static void GBVideoSoftwareRendererDrawBackground(struct GBVideoSoftwareRenderer
|
|||
bgTile = ((int8_t*) maps)[topX + topY];
|
||||
}
|
||||
int p = highlight ? PAL_HIGHLIGHT_BG : PAL_BG;
|
||||
if (renderer->model >= GB_MODEL_CGB) {
|
||||
if (renderer->model >= GB_MODEL_CGB && (!(renderer->model & GB_MODEL_SGB) || renderer->sgbTransfer != 1)) {
|
||||
GBObjAttributes attrs = attr[topX + topY];
|
||||
p |= GBObjAttributesGetCGBPalette(attrs) * 4;
|
||||
if (GBObjAttributesIsPriority(attrs) && GBRegisterLCDCIsBgEnable(renderer->lcdc)) {
|
||||
|
@ -952,7 +952,7 @@ static void GBVideoSoftwareRendererDrawBackground(struct GBVideoSoftwareRenderer
|
|||
bgTile = ((int8_t*) maps)[topX + topY];
|
||||
}
|
||||
int p = highlight ? PAL_HIGHLIGHT_BG : PAL_BG;
|
||||
if (renderer->model >= GB_MODEL_CGB) {
|
||||
if (renderer->model >= GB_MODEL_CGB && (!(renderer->model & GB_MODEL_SGB) || renderer->sgbTransfer != 1)) {
|
||||
GBObjAttributes attrs = attr[topX + topY];
|
||||
p |= GBObjAttributesGetCGBPalette(attrs) * 4;
|
||||
if (GBObjAttributesIsPriority(attrs) && GBRegisterLCDCIsBgEnable(renderer->lcdc)) {
|
||||
|
|
|
@ -92,13 +92,14 @@ static void GBAInit(void* cpu, struct mCPUComponent* component) {
|
|||
|
||||
gba->keysActive = 0;
|
||||
gba->keysLast = 0x400;
|
||||
gba->rotationSource = 0;
|
||||
gba->luminanceSource = 0;
|
||||
gba->rtcSource = 0;
|
||||
gba->rumble = 0;
|
||||
gba->rotationSource = NULL;
|
||||
gba->luminanceSource = NULL;
|
||||
gba->rtcSource = NULL;
|
||||
gba->rumble = NULL;
|
||||
|
||||
gba->romVf = 0;
|
||||
gba->biosVf = 0;
|
||||
gba->romVf = NULL;
|
||||
gba->mbVf = NULL;
|
||||
gba->biosVf = NULL;
|
||||
|
||||
gba->stream = NULL;
|
||||
gba->keyCallback = NULL;
|
||||
|
@ -139,7 +140,7 @@ void GBAUnloadROM(struct GBA* gba) {
|
|||
|
||||
if (gba->romVf) {
|
||||
#ifndef FIXED_ROM_BUFFER
|
||||
if (gba->isPristine) {
|
||||
if (gba->isPristine && gba->memory.rom) {
|
||||
gba->romVf->unmap(gba->romVf, gba->memory.rom, gba->pristineRomSize);
|
||||
}
|
||||
#endif
|
||||
|
@ -147,6 +148,8 @@ void GBAUnloadROM(struct GBA* gba) {
|
|||
gba->romVf = NULL;
|
||||
}
|
||||
gba->memory.rom = NULL;
|
||||
gba->memory.romSize = 0;
|
||||
gba->memory.romMask = 0;
|
||||
gba->isPristine = false;
|
||||
|
||||
if (!gba->memory.savedata.dirty) {
|
||||
|
@ -163,6 +166,7 @@ void GBAUnloadROM(struct GBA* gba) {
|
|||
|
||||
void GBADestroy(struct GBA* gba) {
|
||||
GBAUnloadROM(gba);
|
||||
GBAUnloadMB(gba);
|
||||
|
||||
if (gba->biosVf) {
|
||||
gba->biosVf->unmap(gba->biosVf, gba->memory.bios, SIZE_BIOS);
|
||||
|
@ -228,16 +232,18 @@ void GBAReset(struct ARMCore* cpu) {
|
|||
|
||||
bool isELF = false;
|
||||
#ifdef USE_ELF
|
||||
struct ELF* elf = ELFOpen(gba->romVf);
|
||||
if (elf) {
|
||||
isELF = true;
|
||||
ELFClose(elf);
|
||||
if (gba->mbVf) {
|
||||
struct ELF* elf = ELFOpen(gba->mbVf);
|
||||
if (elf) {
|
||||
isELF = true;
|
||||
ELFClose(elf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (GBAIsMB(gba->romVf) && !isELF) {
|
||||
gba->romVf->seek(gba->romVf, 0, SEEK_SET);
|
||||
gba->romVf->read(gba->romVf, gba->memory.wram, gba->pristineRomSize);
|
||||
if (GBAIsMB(gba->mbVf) && !isELF) {
|
||||
gba->mbVf->seek(gba->mbVf, 0, SEEK_SET);
|
||||
gba->mbVf->read(gba->mbVf, gba->memory.wram, SIZE_WORKING_RAM);
|
||||
}
|
||||
|
||||
gba->lastJump = 0;
|
||||
|
@ -367,25 +373,24 @@ bool GBALoadNull(struct GBA* gba) {
|
|||
}
|
||||
|
||||
bool GBALoadMB(struct GBA* gba, struct VFile* vf) {
|
||||
GBAUnloadROM(gba);
|
||||
gba->romVf = vf;
|
||||
gba->pristineRomSize = vf->size(vf);
|
||||
GBAUnloadMB(gba);
|
||||
gba->mbVf = vf;
|
||||
vf->seek(vf, 0, SEEK_SET);
|
||||
if (gba->pristineRomSize > SIZE_WORKING_RAM) {
|
||||
gba->pristineRomSize = SIZE_WORKING_RAM;
|
||||
}
|
||||
gba->isPristine = true;
|
||||
memset(gba->memory.wram, 0, SIZE_WORKING_RAM);
|
||||
gba->yankedRomSize = 0;
|
||||
gba->memory.romSize = 0;
|
||||
gba->memory.romMask = 0;
|
||||
gba->romCrc32 = doCrc32(gba->memory.wram, gba->pristineRomSize);
|
||||
vf->read(vf, gba->memory.wram, SIZE_WORKING_RAM);
|
||||
if (gba->cpu && gba->memory.activeRegion == REGION_WORKING_RAM) {
|
||||
gba->cpu->memory.setActiveRegion(gba->cpu, gba->cpu->gprs[ARM_PC]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void GBAUnloadMB(struct GBA* gba) {
|
||||
if (gba->mbVf) {
|
||||
gba->mbVf->close(gba->mbVf);
|
||||
gba->mbVf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool GBALoadROM(struct GBA* gba, struct VFile* vf) {
|
||||
if (!vf) {
|
||||
return false;
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
const uint8_t hleBios[SIZE_BIOS] = {
|
||||
0x06, 0x00, 0x00, 0xea, 0x66, 0x00, 0x00, 0xea, 0x0c, 0x00, 0x00, 0xea,
|
||||
0xfe, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x00, 0x00, 0xa0, 0xe1,
|
||||
0x59, 0x00, 0x00, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x02, 0x03, 0xa0, 0xe3,
|
||||
0x03, 0x10, 0xd0, 0xe5, 0xea, 0x00, 0x51, 0xe3, 0x4c, 0x01, 0x9f, 0x15,
|
||||
0x59, 0x00, 0x00, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x58, 0x01, 0x9f, 0xe5,
|
||||
0x00, 0x10, 0x90, 0xe5, 0x00, 0x00, 0x51, 0xe3, 0x02, 0x03, 0xa0, 0x03,
|
||||
0x10, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x29, 0xe1,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0xe3, 0x01, 0xd3, 0xa0, 0x03,
|
||||
0x20, 0xd0, 0x4d, 0x02, 0x00, 0x58, 0x2d, 0xe9, 0x02, 0xc0, 0x5e, 0xe5,
|
||||
|
|
|
@ -17,10 +17,10 @@ b irqBase
|
|||
b fiqBase
|
||||
|
||||
resetBase:
|
||||
mov r0, #0x8000000
|
||||
ldrb r1, [r0, #3]
|
||||
cmp r1, #0xEA
|
||||
ldrne r0, =0x20000C0
|
||||
ldr r0, =0x20000C0
|
||||
ldr r1, [r0]
|
||||
cmp r1, #0
|
||||
moveq r0, #0x8000000
|
||||
bx r0
|
||||
.word 0
|
||||
.word 0xE129F000
|
||||
|
|
|
@ -16,14 +16,14 @@ int main(int argc, char** argv) {
|
|||
// Arguments from the command line are parsed by the parseArguments function.
|
||||
// The NULL here shows that we don't give it any arguments beyond the default ones.
|
||||
struct mArguments args = {};
|
||||
bool parsed = parseArguments(&args, argc, argv, NULL);
|
||||
bool parsed = mArgumentsParse(&args, argc, argv, NULL, 0);
|
||||
// Parsing can succeed without finding a filename, but we need one.
|
||||
if (!args.fname) {
|
||||
parsed = false;
|
||||
}
|
||||
if (!parsed || args.showHelp) {
|
||||
// If parsing failed, or the user passed --help, show usage.
|
||||
usage(argv[0], NULL);
|
||||
usage(argv[0], NULL, NULL, NULL, 0);
|
||||
didFail = !parsed;
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ int main(int argc, char** argv) {
|
|||
SocketSubsystemDeinit();
|
||||
|
||||
cleanup:
|
||||
freeArguments(&args);
|
||||
mArgumentsDeinit(&args);
|
||||
|
||||
return didFail;
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ bool _mExampleRun(const struct mArguments* args, Socket client) {
|
|||
// loaded into the config system, as well as manually overriding the
|
||||
// "idleOptimization" setting to ensure cores that can detect idle loops
|
||||
// will attempt the detection.
|
||||
applyArguments(args, NULL, &core->config);
|
||||
mArgumentsApply(args, NULL, 0, &core->config);
|
||||
mCoreConfigSetDefaultValue(&core->config, "idleOptimization", "detect");
|
||||
|
||||
// Tell the core to apply the configuration in the associated config object.
|
||||
|
|
|
@ -24,6 +24,7 @@ set(OS_LIB -lvita2d -l${M_LIBRARY}
|
|||
-lSceGxm_stub
|
||||
-lSceIme_stub
|
||||
-lSceMotion_stub
|
||||
-lSceNetCtl_stub
|
||||
-lScePgf_stub
|
||||
-lScePhotoExport_stub
|
||||
-lScePower_stub
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <mgba-util/platform/psp2/sce-vfs.h>
|
||||
|
||||
#include <psp2/io/dirent.h>
|
||||
#include <psp2/io/stat.h>
|
||||
|
||||
#include <mgba-util/vfs.h>
|
||||
#include <mgba-util/memory.h>
|
||||
|
|
|
@ -42,10 +42,18 @@ if(APPLE)
|
|||
list(APPEND QT_DEFINES USE_SHARE_WIDGET)
|
||||
endif()
|
||||
|
||||
if(Qt5Widgets_VERSION MATCHES "^5.1[0-9]")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.8")
|
||||
if(Qt5Widgets_VERSION MATCHES "^5.15")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.13")
|
||||
elseif(Qt5Widgets_VERSION MATCHES "^5.1[234]")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.12")
|
||||
elseif(Qt5Widgets_VERSION MATCHES "^5.11")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.11")
|
||||
elseif(Qt5Widgets_VERSION MATCHES "^5.(9|10)")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.10")
|
||||
elseif(Qt5Widgets_VERSION MATCHES "^5.8")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.9")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.8")
|
||||
endif()
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||
|
@ -275,7 +283,11 @@ if(BUILD_GL OR BUILD_GLES2 OR BUILD_EPOXY)
|
|||
endif()
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/res/nointro.dat DESTINATION ${DATADIR} COMPONENT ${BINARY_NAME}-qt)
|
||||
if(NOT WIN32 AND NOT APPLE)
|
||||
list(APPEND QT_DEFINES DATADIR="${CMAKE_INSTALL_PREFIX}/${DATADIR}")
|
||||
if(DATADIR MATCHES "^\\.[.\\]")
|
||||
list(APPEND QT_DEFINES DATADIR="${DATADIR}")
|
||||
else()
|
||||
list(APPEND QT_DEFINES DATADIR="${CMAKE_INSTALL_PREFIX}/${DATADIR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(Qt5LinguistTools)
|
||||
|
@ -340,11 +352,10 @@ if(QT_STATIC)
|
|||
elseif(APPLE)
|
||||
find_package(Cups)
|
||||
find_package(Qt5PrintSupport)
|
||||
find_library(QTFREETYPE NAMES qtfreetype)
|
||||
find_library(QTHARFBUZZ NAMES qtharfbuzzng qtharfbuzz)
|
||||
find_library(QTPLATFORMSUPPORT NAMES Qt5PlatformSupport)
|
||||
list(APPEND QT_LIBRARIES Cups Qt5::PrintSupport Qt5::QCocoaIntegrationPlugin Qt5::CoreAudioPlugin Qt5::AVFServicePlugin Qt5::QCocoaPrinterSupportPlugin ${QTPLATFORMSUPPORT} "-framework AVFoundation" "-framework CoreMedia" "-framework SystemConfiguration" "-framework Security")
|
||||
set_target_properties(Qt5::Core PROPERTIES INTERFACE_LINK_LIBRARIES "${QTPCRE};${QTHARFBUZZ};${QTFREETYPE}")
|
||||
list(APPEND QT_LIBRARIES Cups Qt5::PrintSupport Qt5::QCocoaIntegrationPlugin Qt5::CoreAudioPlugin Qt5::AVFServicePlugin Qt5::QCocoaPrinterSupportPlugin)
|
||||
list(APPEND QT_LIBRARIES Qt5AccessibilitySupport Qt5CglSupport Qt5ClipboardSupport Qt5FontDatabaseSupport Qt5GraphicsSupport Qt5ThemeSupport)
|
||||
list(APPEND QT_LIBRARIES "-framework AVFoundation" "-framework CoreMedia" "-framework SystemConfiguration" "-framework Security")
|
||||
set_target_properties(Qt5::Core PROPERTIES INTERFACE_LINK_LIBRARIES "${QTPCRE}")
|
||||
elseif(UNIX)
|
||||
list(APPEND QT_LIBRARIES Qt5::FontDatabaseSupport Qt5::XcbQpa)
|
||||
endif()
|
||||
|
|
|
@ -149,7 +149,11 @@ void CheatsView::enterCheat() {
|
|||
index = m_model.index(m_model.rowCount() - 1, 0, QModelIndex());
|
||||
m_ui.cheatList->selectionModel()->select(index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
|
||||
}
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
QStringList cheats = m_ui.codeEntry->toPlainText().split('\n', Qt::SkipEmptyParts);
|
||||
#else
|
||||
QStringList cheats = m_ui.codeEntry->toPlainText().split('\n', QString::SkipEmptyParts);
|
||||
#endif
|
||||
for (const QString& string : cheats) {
|
||||
m_model.beginAppendRow(index);
|
||||
mCheatAddLine(set, string.toUtf8().constData(), m_codeType);
|
||||
|
|
|
@ -13,6 +13,12 @@
|
|||
|
||||
#include <mgba/feature/commandline.h>
|
||||
|
||||
static const mOption s_frontendOptions[] = {
|
||||
{ "ecard", true, '\0' },
|
||||
{ "mb", true, '\0' },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
using namespace QGBA;
|
||||
|
||||
ConfigOption::ConfigOption(const QString& name, QObject* parent)
|
||||
|
@ -125,18 +131,57 @@ ConfigController::ConfigController(QObject* parent)
|
|||
mCoreConfigSetDefaultIntValue(&m_config, "sgb.borders", 1);
|
||||
mCoreConfigSetDefaultIntValue(&m_config, "useCgbColors", 1);
|
||||
mCoreConfigMap(&m_config, &m_opts);
|
||||
|
||||
mSubParserGraphicsInit(&m_subparsers[0], &m_graphicsOpts);
|
||||
|
||||
m_subparsers[1].usage = "Frontend options:\n"
|
||||
" --ecard FILE Scan an e-Reader card in the first loaded game\n"
|
||||
" Can be paassed multiple times for multiple cards\n"
|
||||
" --mb FILE Boot a multiboot image with FILE inserted into the ROM slot";
|
||||
m_subparsers[1].parse = nullptr;
|
||||
m_subparsers[1].parseLong = [](struct mSubParser* parser, const char* option, const char* arg) {
|
||||
ConfigController* self = static_cast<ConfigController*>(parser->opts);
|
||||
QString optionName(QString::fromUtf8(option));
|
||||
if (optionName == QLatin1String("ecard")) {
|
||||
QStringList ecards;
|
||||
if (self->m_argvOptions.contains(optionName)) {
|
||||
ecards = self->m_argvOptions[optionName].toStringList();
|
||||
}
|
||||
ecards.append(QString::fromUtf8(arg));
|
||||
self->m_argvOptions[optionName] = ecards;
|
||||
return true;
|
||||
}
|
||||
if (optionName == QLatin1String("mb")) {
|
||||
self->m_argvOptions[optionName] = QString::fromUtf8(arg);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
m_subparsers[1].apply = nullptr;
|
||||
m_subparsers[1].extraOptions = nullptr;
|
||||
m_subparsers[1].longOptions = s_frontendOptions;
|
||||
m_subparsers[1].opts = this;
|
||||
}
|
||||
|
||||
ConfigController::~ConfigController() {
|
||||
mCoreConfigDeinit(&m_config);
|
||||
mCoreConfigFreeOpts(&m_opts);
|
||||
|
||||
if (m_parsed) {
|
||||
mArgumentsDeinit(&m_args);
|
||||
}
|
||||
}
|
||||
|
||||
bool ConfigController::parseArguments(mArguments* args, int argc, char* argv[], mSubParser* subparser) {
|
||||
if (::parseArguments(args, argc, argv, subparser)) {
|
||||
bool ConfigController::parseArguments(int argc, char* argv[]) {
|
||||
if (m_parsed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mArgumentsParse(&m_args, argc, argv, m_subparsers.data(), m_subparsers.size())) {
|
||||
mCoreConfigFreeOpts(&m_opts);
|
||||
applyArguments(args, subparser, &m_config);
|
||||
mArgumentsApply(&m_args, m_subparsers.data(), m_subparsers.size(), &m_config);
|
||||
mCoreConfigMap(&m_config, &m_opts);
|
||||
m_parsed = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -192,6 +237,14 @@ QVariant ConfigController::getQtOption(const QString& key, const QString& group)
|
|||
return value;
|
||||
}
|
||||
|
||||
QVariant ConfigController::getArgvOption(const QString& key) const {
|
||||
return m_argvOptions.value(key);
|
||||
}
|
||||
|
||||
QVariant ConfigController::takeArgvOption(const QString& key) {
|
||||
return m_argvOptions.take(key);
|
||||
}
|
||||
|
||||
void ConfigController::saveOverride(const Override& override) {
|
||||
override.save(overrides());
|
||||
write();
|
||||
|
@ -299,6 +352,10 @@ void ConfigController::makePortable() {
|
|||
m_settings = std::move(settings2);
|
||||
}
|
||||
|
||||
void ConfigController::usage(const char* arg0) const {
|
||||
::usage(arg0, nullptr, nullptr, m_subparsers.data(), m_subparsers.size());
|
||||
}
|
||||
|
||||
bool ConfigController::isPortable() {
|
||||
return mCoreConfigIsPortable();
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <QSettings>
|
||||
#include <QVariant>
|
||||
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
|
@ -70,7 +71,7 @@ public:
|
|||
~ConfigController();
|
||||
|
||||
const mCoreOptions* options() const { return &m_opts; }
|
||||
bool parseArguments(mArguments* args, int argc, char* argv[], mSubParser* subparser = nullptr);
|
||||
bool parseArguments(int argc, char* argv[]);
|
||||
|
||||
ConfigOption* addOption(const char* key);
|
||||
void updateOption(const char* key);
|
||||
|
@ -80,6 +81,9 @@ public:
|
|||
|
||||
QVariant getQtOption(const QString& key, const QString& group = QString()) const;
|
||||
|
||||
QVariant getArgvOption(const QString& key) const;
|
||||
QVariant takeArgvOption(const QString& key);
|
||||
|
||||
QList<QString> getMRU() const;
|
||||
void setMRU(const QList<QString>& mru);
|
||||
|
||||
|
@ -91,6 +95,10 @@ public:
|
|||
const mCoreConfig* config() const { return &m_config; }
|
||||
mCoreConfig* config() { return &m_config; }
|
||||
|
||||
const mArguments* args() const { return &m_args; }
|
||||
const mGraphicsOpts* graphicsOpts() const { return &m_graphicsOpts; }
|
||||
void usage(const char* arg0) const;
|
||||
|
||||
static const QString& configDir();
|
||||
static bool isPortable();
|
||||
|
||||
|
@ -106,11 +114,18 @@ public slots:
|
|||
void write();
|
||||
|
||||
private:
|
||||
void addArgvOption(const QString& key, const QVariant& value);
|
||||
|
||||
Configuration* defaults() { return &m_config.defaultsTable; }
|
||||
|
||||
mCoreConfig m_config;
|
||||
mCoreOptions m_opts{};
|
||||
|
||||
mArguments m_args{};
|
||||
mGraphicsOpts m_graphicsOpts{};
|
||||
std::array<mSubParser, 2> m_subparsers;
|
||||
bool m_parsed = false;
|
||||
|
||||
QHash<QString, QVariant> m_argvOptions;
|
||||
QHash<QString, ConfigOption*> m_optionSet;
|
||||
std::unique_ptr<QSettings> m_settings;
|
||||
static QString s_configDir;
|
||||
|
|
|
@ -194,11 +194,11 @@ CoreController::CoreController(mCore* core, QObject* parent)
|
|||
}
|
||||
va_list argc;
|
||||
va_copy(argc, args);
|
||||
message = QString().vsprintf(format, argc);
|
||||
message = QString::vasprintf(format, argc);
|
||||
va_end(argc);
|
||||
QMetaObject::invokeMethod(controller, "statusPosted", Q_ARG(const QString&, message));
|
||||
}
|
||||
message = QString().vsprintf(format, args);
|
||||
message = QString::vasprintf(format, args);
|
||||
QMetaObject::invokeMethod(controller, "logPosted", Q_ARG(int, level), Q_ARG(int, category), Q_ARG(const QString&, message));
|
||||
if (level == mLOG_FATAL) {
|
||||
mCoreThreadMarkCrashed(controller->thread());
|
||||
|
@ -885,8 +885,31 @@ void CoreController::scanCard(const QString& path) {
|
|||
QImage image(path);
|
||||
if (image.isNull()) {
|
||||
QFile file(path);
|
||||
file.open(QIODevice::ReadOnly);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
return;
|
||||
}
|
||||
m_eReaderData = file.read(2912);
|
||||
|
||||
file.seek(0);
|
||||
QStringList lines;
|
||||
QDir basedir(QFileInfo(path).dir());
|
||||
|
||||
while (true) {
|
||||
QByteArray line = file.readLine().trimmed();
|
||||
if (line.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
QString filepath(QString::fromUtf8(line));
|
||||
if (filepath.isEmpty() || filepath[0] == QChar('#')) {
|
||||
continue;
|
||||
}
|
||||
if (QFileInfo(filepath).isRelative()) {
|
||||
lines.append(basedir.filePath(filepath));
|
||||
} else {
|
||||
lines.append(filepath);
|
||||
}
|
||||
}
|
||||
scanCards(lines);
|
||||
} else if (image.size() == QSize(989, 44) || image.size() == QSize(639, 44)) {
|
||||
const uchar* bits = image.constBits();
|
||||
size_t size;
|
||||
|
@ -905,6 +928,11 @@ void CoreController::scanCard(const QString& path) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void CoreController::scanCards(const QStringList& paths) {
|
||||
for (const QString& path : paths) {
|
||||
scanCard(path);
|
||||
}
|
||||
}
|
||||
|
||||
void CoreController::importSharkport(const QString& path) {
|
||||
#ifdef M_CORE_GBA
|
||||
|
|
|
@ -160,6 +160,7 @@ public slots:
|
|||
void loadSave(VFile*, bool temporary);
|
||||
void loadPatch(const QString&);
|
||||
void scanCard(const QString&);
|
||||
void scanCards(const QStringList&);
|
||||
void replaceGame(const QString&);
|
||||
void yankPak();
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ void DebuggerConsoleController::printf(struct CLIDebuggerBackend* be, const char
|
|||
DebuggerConsoleController* self = consoleBe->self;
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
self->log(QString().vsprintf(fmt, args));
|
||||
self->log(QString::vasprintf(fmt, args));
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
|
|
@ -97,7 +97,11 @@ private:
|
|||
int m_glowFrame;
|
||||
QTimer m_glowTimer;
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
QRecursiveMutex m_mutex;
|
||||
#else
|
||||
QMutex m_mutex{QMutex::Recursive};
|
||||
#endif
|
||||
VFile* m_currentFrame = nullptr;
|
||||
VFile* m_nextFrame = nullptr;
|
||||
mCore* m_vl = nullptr;
|
||||
|
|
|
@ -207,6 +207,9 @@ QString GBAApp::getOpenDirectoryName(QWidget* owner, const QString& title, const
|
|||
QString GBAApp::dataDir() {
|
||||
#ifdef DATADIR
|
||||
QString path = QString::fromUtf8(DATADIR);
|
||||
if (path.startsWith("./") || path.startsWith("../")) {
|
||||
path = QCoreApplication::applicationDirPath() + "/" + path;
|
||||
}
|
||||
#else
|
||||
QString path = QCoreApplication::applicationDirPath();
|
||||
#ifdef Q_OS_MAC
|
||||
|
|
|
@ -11,6 +11,12 @@
|
|||
|
||||
using namespace QGBA;
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
#define endl Qt::endl
|
||||
#else
|
||||
#define endl std::endl
|
||||
#endif
|
||||
|
||||
LogController LogController::s_global(mLOG_ALL);
|
||||
int LogController::s_qtCat{-1};
|
||||
|
||||
|
|
|
@ -80,7 +80,12 @@ MemoryModel::MemoryModel(QWidget* parent)
|
|||
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
m_margins = QMargins(metrics.width("0FFFFFF0 ") + 3, m_cellHeight + 1, metrics.width(" AAAAAAAAAAAAAAAA") + 3, 0);
|
||||
m_margins = QMargins(3, m_cellHeight + 1, 3, 0);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
|
||||
m_margins += QMargins(metrics.horizontalAdvance("0FFFFFF0 "), 0, metrics.horizontalAdvance(" AAAAAAAAAAAAAAAA"), 0);
|
||||
#else
|
||||
m_margins += QMargins(metrics.width("0FFFFFF0 "), 0, metrics.width(" AAAAAAAAAAAAAAAA"), 0);
|
||||
#endif
|
||||
m_cellSize = QSizeF((viewport()->size().width() - (m_margins.left() + m_margins.right())) / 16.0, m_cellHeight);
|
||||
|
||||
connect(verticalScrollBar(), &QSlider::sliderMoved, [this](int position) {
|
||||
|
|
|
@ -84,7 +84,11 @@ void MessagePainter::paint(QPainter* painter) {
|
|||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
painter->setFont(m_frameFont);
|
||||
painter->setPen(Qt::black);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
|
||||
painter->translate(-metrics.horizontalAdvance(frame), 0);
|
||||
#else
|
||||
painter->translate(-metrics.width(frame), 0);
|
||||
#endif
|
||||
const static int ITERATIONS = 11;
|
||||
for (int i = 0; i < ITERATIONS; ++i) {
|
||||
painter->save();
|
||||
|
|
|
@ -137,7 +137,11 @@ void ShortcutView::closeEvent(QCloseEvent*) {
|
|||
|
||||
void ShortcutView::showEvent(QShowEvent*) {
|
||||
QString longString("Ctrl+Alt+Shift+Tab");
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
|
||||
int width = QFontMetrics(QFont()).horizontalAdvance(longString);
|
||||
#else
|
||||
int width = QFontMetrics(QFont()).width(longString);
|
||||
#endif
|
||||
QHeaderView* header = m_ui.shortcutTable->header();
|
||||
header->resizeSection(0, header->length() - width * 2);
|
||||
header->resizeSection(1, width);
|
||||
|
|
|
@ -212,8 +212,8 @@ Window::~Window() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void Window::argumentsPassed(mArguments* args) {
|
||||
loadConfig();
|
||||
void Window::argumentsPassed() {
|
||||
const mArguments* args = m_config->args();
|
||||
|
||||
if (args->patch) {
|
||||
m_pendingPatch = args->patch;
|
||||
|
@ -236,9 +236,24 @@ void Window::argumentsPassed(mArguments* args) {
|
|||
}
|
||||
#endif
|
||||
|
||||
if (m_config->graphicsOpts()->multiplier) {
|
||||
m_savedScale = m_config->graphicsOpts()->multiplier;
|
||||
|
||||
#if defined(M_CORE_GBA)
|
||||
QSize size(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS);
|
||||
#elif defined(M_CORE_GB)
|
||||
QSize size(GB_VIDEO_HORIZONTAL_PIXELS, GB_VIDEO_VERTICAL_PIXELS);
|
||||
#endif
|
||||
resizeFrame(size * m_savedScale);
|
||||
}
|
||||
|
||||
if (args->fname) {
|
||||
setController(m_manager->loadGame(args->fname), args->fname);
|
||||
}
|
||||
|
||||
if (m_config->graphicsOpts()->fullscreen) {
|
||||
enterFullScreen();
|
||||
}
|
||||
}
|
||||
|
||||
void Window::resizeFrame(const QSize& size) {
|
||||
|
@ -975,8 +990,19 @@ void Window::gameStarted() {
|
|||
action->setActive(true);
|
||||
}
|
||||
}
|
||||
interrupter.resume();
|
||||
|
||||
m_actions.rebuildMenu(menuBar(), this, *m_shortcutController);
|
||||
|
||||
#ifdef M_CORE_GBA
|
||||
if (m_controller->platform() == mPLATFORM_GBA) {
|
||||
QVariant eCardList = m_config->takeArgvOption(QString("ecard"));
|
||||
if (eCardList.canConvert(QMetaType::QStringList)) {
|
||||
m_controller->scanCards(eCardList.toStringList());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_DISCORD_RPC
|
||||
DiscordCoordinator::gameStarted(m_controller);
|
||||
#endif
|
||||
|
@ -2071,6 +2097,15 @@ void Window::setController(CoreController* controller, const QString& fname) {
|
|||
connect(m_controller.get(), &CoreController::failed, this, &Window::gameFailed);
|
||||
connect(m_controller.get(), &CoreController::unimplementedBiosCall, this, &Window::unimplementedBiosCall);
|
||||
|
||||
#ifdef M_CORE_GBA
|
||||
if (m_controller->platform() == mPLATFORM_GBA) {
|
||||
QVariant mb = m_config->takeArgvOption(QString("mb"));
|
||||
if (mb.canConvert(QMetaType::QString)) {
|
||||
m_controller->replaceGame(mb.toString());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_GDB_STUB
|
||||
if (m_gdbController) {
|
||||
m_gdbController->setController(m_controller);
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
#include "LogController.h"
|
||||
#include "SettingsView.h"
|
||||
|
||||
struct mArguments;
|
||||
|
||||
namespace QGBA {
|
||||
|
||||
class AudioProcessor;
|
||||
|
@ -59,7 +57,7 @@ public:
|
|||
void setConfig(ConfigController*);
|
||||
ConfigController* config() { return m_config; }
|
||||
|
||||
void argumentsPassed(mArguments*);
|
||||
void argumentsPassed();
|
||||
|
||||
void resizeFrame(const QSize& size);
|
||||
|
||||
|
|
|
@ -68,22 +68,18 @@ int main(int argc, char* argv[]) {
|
|||
QLocale::setDefault(locale);
|
||||
}
|
||||
|
||||
mArguments args;
|
||||
mGraphicsOpts graphicsOpts;
|
||||
mSubParser subparser;
|
||||
initParserForGraphics(&subparser, &graphicsOpts);
|
||||
bool loaded = configController.parseArguments(&args, argc, argv, &subparser);
|
||||
if (loaded) {
|
||||
if (args.showHelp) {
|
||||
usage(argv[0], subparser.usage);
|
||||
freeArguments(&args);
|
||||
if (configController.parseArguments(argc, argv)) {
|
||||
if (configController.args()->showHelp) {
|
||||
configController.usage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
if (args.showVersion) {
|
||||
if (configController.args()->showVersion) {
|
||||
version(argv[0]);
|
||||
freeArguments(&args);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
configController.usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
QApplication::setApplicationName(projectName);
|
||||
|
@ -117,19 +113,8 @@ int main(int argc, char* argv[]) {
|
|||
application.installTranslator(&langTranslator);
|
||||
|
||||
Window* w = application.newWindow();
|
||||
if (loaded) {
|
||||
w->argumentsPassed(&args);
|
||||
} else {
|
||||
w->loadConfig();
|
||||
}
|
||||
freeArguments(&args);
|
||||
|
||||
if (graphicsOpts.multiplier) {
|
||||
w->resizeFrame(QSize(GBA_VIDEO_HORIZONTAL_PIXELS * graphicsOpts.multiplier, GBA_VIDEO_VERTICAL_PIXELS * graphicsOpts.multiplier));
|
||||
}
|
||||
if (graphicsOpts.fullscreen) {
|
||||
w->enterFullScreen();
|
||||
}
|
||||
w->loadConfig();
|
||||
w->argumentsPassed();
|
||||
|
||||
w->show();
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ endif()
|
|||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libsdl${SDL_VERSION_DEBIAN}" PARENT_SCOPE)
|
||||
|
||||
file(GLOB PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sdl-*.c)
|
||||
set(PLATFORM_LIBRARY ${SDL_LIBRARY} ${SDLMAIN_LIBRARY} ${PIXMAN-1_LIBRARIES})
|
||||
set(PLATFORM_LIBRARY ${SDL_LIBRARY} ${SDLMAIN_LIBRARY} ${SDL_LIBRARY} ${PIXMAN-1_LIBRARIES})
|
||||
include_directories(${CMAKE_SOURCE_DIR}/src/platform/sdl ${PIXMAN-1_INCLUDE_DIRS} ${SDL_INCLUDE_DIR})
|
||||
|
||||
set(SDL_INCLUDE_DIR "${SDL_INCLUDE_DIR}" PARENT_SCOPE)
|
||||
|
|
|
@ -80,37 +80,37 @@ int main(int argc, char** argv) {
|
|||
|
||||
struct mSubParser subparser;
|
||||
|
||||
initParserForGraphics(&subparser, &graphicsOpts);
|
||||
bool parsed = parseArguments(&args, argc, argv, &subparser);
|
||||
mSubParserGraphicsInit(&subparser, &graphicsOpts);
|
||||
bool parsed = mArgumentsParse(&args, argc, argv, &subparser, 1);
|
||||
if (!args.fname && !args.showVersion) {
|
||||
parsed = false;
|
||||
}
|
||||
if (!parsed || args.showHelp) {
|
||||
usage(argv[0], subparser.usage);
|
||||
freeArguments(&args);
|
||||
usage(argv[0], NULL, NULL, &subparser, 1);
|
||||
mArgumentsDeinit(&args);
|
||||
return !parsed;
|
||||
}
|
||||
if (args.showVersion) {
|
||||
version(argv[0]);
|
||||
freeArguments(&args);
|
||||
mArgumentsDeinit(&args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
printf("Could not initialize video: %s\n", SDL_GetError());
|
||||
freeArguments(&args);
|
||||
mArgumentsDeinit(&args);
|
||||
return 1;
|
||||
}
|
||||
|
||||
renderer.core = mCoreFind(args.fname);
|
||||
if (!renderer.core) {
|
||||
printf("Could not run game. Are you sure the file exists and is a compatible game?\n");
|
||||
freeArguments(&args);
|
||||
mArgumentsDeinit(&args);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!renderer.core->init(renderer.core)) {
|
||||
freeArguments(&args);
|
||||
mArgumentsDeinit(&args);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ int main(int argc, char** argv) {
|
|||
|
||||
mInputMapInit(&renderer.core->inputMap, renderer.core->inputInfo);
|
||||
mCoreInitConfig(renderer.core, PORT);
|
||||
applyArguments(&args, &subparser, &renderer.core->config);
|
||||
mArgumentsApply(&args, &subparser, 1, &renderer.core->config);
|
||||
|
||||
mCoreConfigLoadDefaults(&renderer.core->config, &opts);
|
||||
mCoreLoadConfig(renderer.core);
|
||||
|
@ -168,7 +168,7 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
|
||||
if (!renderer.init(&renderer)) {
|
||||
freeArguments(&args);
|
||||
mArgumentsDeinit(&args);
|
||||
mCoreConfigDeinit(&renderer.core->config);
|
||||
renderer.core->deinit(renderer.core);
|
||||
return 1;
|
||||
|
@ -199,7 +199,7 @@ int main(int argc, char** argv) {
|
|||
|
||||
mSDLDeinit(&renderer);
|
||||
|
||||
freeArguments(&args);
|
||||
mArgumentsDeinit(&args);
|
||||
mCoreConfigFreeOpts(&opts);
|
||||
mCoreConfigDeinit(&renderer.core->config);
|
||||
renderer.core->deinit(renderer.core);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#define FUZZ_OPTIONS "F:NO:S:V:"
|
||||
#define FUZZ_USAGE \
|
||||
"\nAdditional options:\n" \
|
||||
"Additional options:\n" \
|
||||
" -F FRAMES Run for the specified number of FRAMES before exiting\n" \
|
||||
" -N Disable video rendering entirely\n" \
|
||||
" -O OFFSET Offset to apply savestate overlay\n" \
|
||||
|
@ -53,12 +53,12 @@ int main(int argc, char** argv) {
|
|||
};
|
||||
|
||||
struct mArguments args;
|
||||
bool parsed = parseArguments(&args, argc, argv, &subparser);
|
||||
bool parsed = mArgumentsParse(&args, argc, argv, &subparser, 1);
|
||||
if (!args.fname) {
|
||||
parsed = false;
|
||||
}
|
||||
if (!parsed || args.showHelp) {
|
||||
usage(argv[0], FUZZ_USAGE);
|
||||
usage(argv[0], NULL, NULL, &subparser, 1);
|
||||
return !parsed;
|
||||
}
|
||||
if (args.showVersion) {
|
||||
|
@ -71,7 +71,7 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
core->init(core);
|
||||
mCoreInitConfig(core, "fuzz");
|
||||
applyArguments(&args, NULL, &core->config);
|
||||
mArgumentsApply(&args, NULL, 0, &core->config);
|
||||
|
||||
mCoreConfigSetDefaultValue(&core->config, "idleOptimization", "remove");
|
||||
|
||||
|
@ -161,7 +161,7 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
|
||||
loadError:
|
||||
freeArguments(&args);
|
||||
mArgumentsDeinit(&args);
|
||||
if (outputBuffer) {
|
||||
free(outputBuffer);
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ size_t romBufferSize;
|
|||
|
||||
#define PERF_OPTIONS "DF:L:NPS:T"
|
||||
#define PERF_USAGE \
|
||||
"\nBenchmark options:\n" \
|
||||
"Benchmark options:\n" \
|
||||
" -F FRAMES Run for the specified number of FRAMES before exiting\n" \
|
||||
" -N Disable video rendering entirely\n" \
|
||||
" -T Use threaded video rendering\n" \
|
||||
|
@ -131,12 +131,12 @@ int main(int argc, char** argv) {
|
|||
};
|
||||
|
||||
struct mArguments args = {};
|
||||
bool parsed = parseArguments(&args, argc, argv, &subparser);
|
||||
bool parsed = mArgumentsParse(&args, argc, argv, &subparser, 1);
|
||||
if (!args.fname && !perfOpts.server) {
|
||||
parsed = false;
|
||||
}
|
||||
if (!parsed || args.showHelp) {
|
||||
usage(argv[0], PERF_USAGE);
|
||||
usage(argv[0], NULL, NULL, &subparser, 1);
|
||||
didFail = !parsed;
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ int main(int argc, char** argv) {
|
|||
_savestate->close(_savestate);
|
||||
}
|
||||
cleanup:
|
||||
freeArguments(&args);
|
||||
mArgumentsDeinit(&args);
|
||||
|
||||
#ifdef __3DS__
|
||||
gfxExit();
|
||||
|
@ -217,7 +217,7 @@ bool _mPerfRunCore(const char* fname, const struct mArguments* args, const struc
|
|||
mCoreConfigMap(&core->config, &opts);
|
||||
opts.audioSync = false;
|
||||
opts.videoSync = false;
|
||||
applyArguments(args, NULL, &core->config);
|
||||
mArgumentsApply(args, NULL, 0, &core->config);
|
||||
mCoreConfigLoadDefaults(&core->config, &opts);
|
||||
mCoreConfigSetDefaultValue(&core->config, "idleOptimization", "detect");
|
||||
mCoreLoadConfig(core);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#define ROM_TEST_OPTIONS "S:R:"
|
||||
#define ROM_TEST_USAGE \
|
||||
"\nAdditional options:\n" \
|
||||
"Additional options:\n" \
|
||||
" -S SWI Run until specified SWI call before exiting\n" \
|
||||
" -R REGISTER General purpose register to return as exit code\n" \
|
||||
|
||||
|
@ -81,12 +81,12 @@ int main(int argc, char * argv[]) {
|
|||
};
|
||||
|
||||
struct mArguments args;
|
||||
bool parsed = parseArguments(&args, argc, argv, &subparser);
|
||||
bool parsed = mArgumentsParse(&args, argc, argv, &subparser, 1);
|
||||
if (!args.fname) {
|
||||
parsed = false;
|
||||
}
|
||||
if (!parsed || args.showHelp) {
|
||||
usage(argv[0], ROM_TEST_USAGE);
|
||||
usage(argv[0], NULL, NULL, &subparser, 1);
|
||||
return !parsed;
|
||||
}
|
||||
if (args.showVersion) {
|
||||
|
@ -99,7 +99,7 @@ int main(int argc, char * argv[]) {
|
|||
}
|
||||
core->init(core);
|
||||
mCoreInitConfig(core, "romTest");
|
||||
applyArguments(&args, NULL, &core->config);
|
||||
mArgumentsApply(&args, NULL, 0, &core->config);
|
||||
|
||||
mCoreConfigSetDefaultValue(&core->config, "idleOptimization", "remove");
|
||||
|
||||
|
@ -184,7 +184,7 @@ int main(int argc, char * argv[]) {
|
|||
cleanExit = true;
|
||||
|
||||
loadError:
|
||||
freeArguments(&args);
|
||||
mArgumentsDeinit(&args);
|
||||
mCoreConfigDeinit(&core->config);
|
||||
core->deinit(core);
|
||||
|
||||
|
|
|
@ -52,10 +52,10 @@ OutputBaseFilename={#AppName}-setup-{#CleanVersionString}-win{#WinBits}
|
|||
UsePreviousLanguage=False
|
||||
DisableWelcomePage=False
|
||||
VersionInfoDescription={#AppName} is an open-source Game Boy Advance emulator
|
||||
VersionInfoCopyright=© 2013–2020 Jeffrey Pfau
|
||||
VersionInfoCopyright=© 2013–2022 Jeffrey Pfau
|
||||
VersionInfoProductName={#AppName}
|
||||
VersionInfoVersion={#AppVer}
|
||||
Compression=lzma2/ultra64
|
||||
Compression=lzma2/ultra
|
||||
SolidCompression=True
|
||||
VersionInfoTextVersion={#VersionString}
|
||||
VersionInfoProductVersion={#AppVer}
|
||||
|
|
Loading…
Reference in New Issue