Merge branch 'master' (early part) into medusa

This commit is contained in:
Vicki Pfau 2022-05-30 17:33:32 -07:00
commit dfdccb12a9
34 changed files with 5747 additions and 4857 deletions

View File

@ -75,7 +75,6 @@ Emulation fixes:
- GBA Video: Fix Hblank timing (fixes mgba.io/i/2131, mgba.io/i/2310)
- GBA Video: Fix rare crash in modes 3-5
Other fixes:
- 3DS: Ensure writes update file modification time (fixes mgba.io/i/2444)
- 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)
- FFmpeg: Fix crash when encoding audio with some containers
@ -83,11 +82,13 @@ Other fixes:
- GB: Fix temporary saves
- GB, GBA: Save writeback-pending masked saves on unload (fixes mgba.io/i/2396)
- mGUI: Fix FPS counter after closing menu
- Qt: Fix some hangs when using the debugger console
- VFS: Failed file mapping should return NULL on POSIX
Misc:
- Core: Suspend runloop when a core crashes
- Debugger: Save and restore CLI history
- Debugger: GDB now works while the game is paused
- 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
- GBA: Refine multiboot detection (fixes mgba.io/i/2192)

View File

@ -85,6 +85,7 @@ struct mCoreThreadInternal {
struct mCoreSync sync;
struct mCoreRewindContext rewind;
struct mCore* core;
};
#endif

View File

@ -143,6 +143,8 @@ struct mDebugger {
void (*update)(struct mDebugger*);
void (*entered)(struct mDebugger*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*);
void (*custom)(struct mDebugger*);
void (*interrupt)(struct mDebugger*);
};
struct mDebugger* mDebuggerCreate(enum mDebuggerType type, struct mCore*);

View File

@ -77,6 +77,7 @@ struct CLIDebuggerBackend {
void (*lineAppend)(struct CLIDebuggerBackend*, const char* line);
const char* (*historyLast)(struct CLIDebuggerBackend*, size_t* len);
void (*historyAppend)(struct CLIDebuggerBackend*, const char* line);
void (*interrupt)(struct CLIDebuggerBackend*);
};
struct CLIDebugger {
@ -87,6 +88,7 @@ struct CLIDebugger {
int traceRemaining;
struct VFile* traceVf;
bool skipStatus;
};
void CLIDebuggerCreate(struct CLIDebugger*);

View File

@ -92,6 +92,15 @@ static void _wait(struct mCoreThreadInternal* threadContext) {
MutexUnlock(&threadContext->sync.audioBufferMutex);
}
#ifdef USE_DEBUGGERS
if (threadContext->core && threadContext->core->debugger) {
struct mDebugger* debugger = threadContext->core->debugger;
if (debugger->interrupt) {
debugger->interrupt(debugger);
}
}
#endif
MutexLock(&threadContext->stateMutex);
ConditionWake(&threadContext->stateCond);
}
@ -216,6 +225,7 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) {
}
core->reset(core);
threadContext->impl->core = core;
_changeState(threadContext->impl, mTHREAD_RUNNING, true);
if (threadContext->resetCallback) {
@ -519,7 +529,11 @@ void mCoreThreadContinue(struct mCoreThread* threadContext) {
MutexLock(&threadContext->impl->stateMutex);
--threadContext->impl->interruptDepth;
if (threadContext->impl->interruptDepth < 1 && mCoreThreadIsActive(threadContext)) {
threadContext->impl->state = mTHREAD_REQUEST;
if (threadContext->impl->requested) {
threadContext->impl->state = mTHREAD_REQUEST;
} else {
threadContext->impl->state = mTHREAD_RUNNING;
}
ConditionWake(&threadContext->impl->stateCond);
}
MutexUnlock(&threadContext->impl->stateMutex);

View File

@ -994,21 +994,33 @@ bool CLIDebuggerRunCommand(struct CLIDebugger* debugger, const char* line, size_
static void _commandLine(struct mDebugger* debugger) {
struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger;
const char* line;
size_t len;
_printStatus(cliDebugger, 0);
size_t len;
if (cliDebugger->skipStatus) {
cliDebugger->skipStatus = false;
} else {
_printStatus(cliDebugger, 0);
}
while (debugger->state == DEBUGGER_PAUSED) {
line = cliDebugger->backend->readline(cliDebugger->backend, &len);
if (!line || len == 0) {
debugger->state = DEBUGGER_SHUTDOWN;
return;
}
if (line[0] == '\033') {
cliDebugger->skipStatus = true;
return;
}
if (line[0] == '\n') {
line = cliDebugger->backend->historyLast(cliDebugger->backend, &len);
if (line && len) {
CLIDebuggerRunCommand(cliDebugger, line, len);
}
} else {
CLIDebuggerRunCommand(cliDebugger, line, len);
if (line[0] == '#') {
cliDebugger->skipStatus = true;
} else {
CLIDebuggerRunCommand(cliDebugger, line, len);
}
cliDebugger->backend->historyAppend(cliDebugger->backend, line);
}
}
@ -1019,6 +1031,7 @@ static void _reportEntry(struct mDebugger* debugger, enum mDebuggerEntryReason r
if (cliDebugger->traceRemaining > 0) {
cliDebugger->traceRemaining = 0;
}
cliDebugger->skipStatus = false;
switch (reason) {
case DEBUGGER_ENTER_MANUAL:
case DEBUGGER_ENTER_ATTACHED:
@ -1077,6 +1090,7 @@ static void _cliDebuggerInit(struct mDebugger* debugger) {
struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger;
cliDebugger->traceRemaining = 0;
cliDebugger->traceVf = NULL;
cliDebugger->skipStatus = false;
cliDebugger->backend->init(cliDebugger->backend);
if (cliDebugger->system && cliDebugger->system->init) {
cliDebugger->system->init(cliDebugger->system);
@ -1119,6 +1133,13 @@ static void _cliDebuggerCustom(struct mDebugger* debugger) {
}
}
static void _cliDebuggerInterrupt(struct mDebugger* debugger) {
struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger;
if (cliDebugger->backend->interrupt) {
cliDebugger->backend->interrupt(cliDebugger->backend);
}
}
void CLIDebuggerCreate(struct CLIDebugger* debugger) {
debugger->d.init = _cliDebuggerInit;
debugger->d.deinit = _cliDebuggerDeinit;
@ -1126,6 +1147,7 @@ void CLIDebuggerCreate(struct CLIDebugger* debugger) {
debugger->d.paused = _commandLine;
debugger->d.update = NULL;
debugger->d.entered = _reportEntry;
debugger->d.interrupt = _cliDebuggerInterrupt;
debugger->d.type = DEBUGGER_CLI;
debugger->system = NULL;

View File

@ -761,12 +761,13 @@ size_t _parseGDBMessage(struct GDBStub* stub, const char* message) {
void GDBStubCreate(struct GDBStub* stub) {
stub->socket = INVALID_SOCKET;
stub->connection = INVALID_SOCKET;
stub->d.init = 0;
stub->d.init = NULL;
stub->d.deinit = _gdbStubDeinit;
stub->d.paused = _gdbStubWait;
stub->d.update = _gdbStubUpdate;
stub->d.entered = _gdbStubEntered;
stub->d.custom = _gdbStubPoll;
stub->d.interrupt = NULL;
stub->d.type = DEBUGGER_GDB;
stub->untilPoll = GDB_STUB_INTERVAL;
stub->lineAck = GDB_ACK_PENDING;

View File

@ -152,7 +152,7 @@ void _CLIDebuggerEditLineHistoryAppend(struct CLIDebuggerBackend* be, const char
}
struct CLIDebuggerBackend* CLIDebuggerEditLineBackendCreate(void) {
struct CLIDebuggerEditLineBackend* elbe = malloc(sizeof(*elbe));
struct CLIDebuggerEditLineBackend* elbe = calloc(1, sizeof(*elbe));
elbe->d.printf = _CLIDebuggerEditLinePrintf;
elbe->d.init = _CLIDebuggerEditLineInit;
elbe->d.deinit = _CLIDebuggerEditLineDeinit;
@ -160,5 +160,6 @@ struct CLIDebuggerBackend* CLIDebuggerEditLineBackendCreate(void) {
elbe->d.lineAppend = _CLIDebuggerEditLineLineAppend;
elbe->d.historyLast = _CLIDebuggerEditLineHistoryLast;
elbe->d.historyAppend = _CLIDebuggerEditLineHistoryAppend;
elbe->d.interrupt = NULL;
return &elbe->d;
}

View File

@ -18,11 +18,12 @@ const uint32_t GB_LOGO_HASH = 0x46195417;
mLOG_DEFINE_CATEGORY(GB_MBC, "GB MBC", "gb.mbc");
static void _GBMBCNone(struct GB* gb, uint16_t address, uint8_t value) {
UNUSED(gb);
UNUSED(address);
UNUSED(value);
mLOG(GB_MBC, GAME_ERROR, "Wrote to invalid MBC");
if (!gb->yankedRomSize) {
mLOG(GB_MBC, GAME_ERROR, "Wrote to invalid MBC");
}
}
static void _GBMBC1(struct GB*, uint16_t address, uint8_t value);

View File

@ -26,6 +26,7 @@ DebuggerConsoleController::DebuggerConsoleController(QObject* parent)
m_backend.d.lineAppend = lineAppend;
m_backend.d.historyLast = historyLast;
m_backend.d.historyAppend = historyAppend;
m_backend.d.interrupt = interrupt;
m_backend.self = this;
CLIDebuggerCreate(&m_cliDebugger);
@ -90,7 +91,6 @@ void DebuggerConsoleController::deinit(struct CLIDebuggerBackend* be) {
const char* DebuggerConsoleController::readLine(struct CLIDebuggerBackend* be, size_t* len) {
Backend* consoleBe = reinterpret_cast<Backend*>(be);
DebuggerConsoleController* self = consoleBe->self;
CoreController::Interrupter interrupter(self->m_gameController);
QMutexLocker lock(&self->m_mutex);
while (self->m_lines.isEmpty()) {
self->m_cond.wait(&self->m_mutex);
@ -132,6 +132,17 @@ void DebuggerConsoleController::historyAppend(struct CLIDebuggerBackend* be, con
self->m_history.append(QString::fromUtf8(line));
}
void DebuggerConsoleController::interrupt(struct CLIDebuggerBackend* be) {
Backend* consoleBe = reinterpret_cast<Backend*>(be);
DebuggerConsoleController* self = consoleBe->self;
QMutexLocker lock(&self->m_mutex);
self->m_cond.wakeOne();
if (!self->m_lines.isEmpty()) {
return;
}
self->m_lines.append("\033");
}
void DebuggerConsoleController::historyLoad() {
QFile log(ConfigController::configDir() + "/cli_history.log");
QStringList history;

View File

@ -46,6 +46,7 @@ private:
static void lineAppend(struct CLIDebuggerBackend* be, const char* line);
static const char* historyLast(struct CLIDebuggerBackend* be, size_t* len);
static void historyAppend(struct CLIDebuggerBackend* be, const char* line);
static void interrupt(struct CLIDebuggerBackend* be);
CLIDebugger m_cliDebugger{};

View File

@ -463,6 +463,7 @@ void PainterGL::create() {
painter->m_gl->swapBuffers(painter->m_surface);
painter->makeCurrent();
#if defined(BUILD_GLES2) || defined(BUILD_GLES3)
if (painter->m_widget && painter->supportsShaders()) {
QOpenGLFunctions_Baseline* fn = painter->m_gl->versionFunctions<QOpenGLFunctions_Baseline>();
fn->glFinish();
@ -472,6 +473,7 @@ void PainterGL::create() {
gl2Backend->finalShader.tex = painter->m_finalTex[painter->m_finalTexIdx];
mGLES2ContextUseFramebuffer(gl2Backend);
}
#endif
};
m_backend->init(m_backend, 0);

View File

@ -577,6 +577,9 @@ void FrameView::frameCallback(FrameView* viewer, std::shared_ptr<bool> lock) {
void FrameView::exportFrame() {
QString filename = GBAApp::app()->getSaveFileName(this, tr("Export frame"),
tr("Portable Network Graphics (*.png)"));
if (filename.isNull()) {
return;
}
CoreController::Interrupter interrupter(m_controller);
m_framebuffer.save(filename, "PNG");
}

View File

@ -86,7 +86,9 @@ void GIFView::stopRecording() {
void GIFView::selectFile() {
QString filename = GBAApp::app()->getSaveFileName(this, tr("Select output file"), tr("Graphics Interchange Format (*.gif);;WebP ( *.webp);;Animated Portable Network Graphics (*.png *.apng)"));
m_ui.filename->setText(filename);
if (!filename.isNull()) {
m_ui.filename->setText(filename);
}
}
void GIFView::setFilename(const QString& filename) {

View File

@ -266,6 +266,7 @@ void ObjView::updateObjList(int maxObj) {
item->setText(QString::number(i));
item->setData(Qt::UserRole, i);
item->setSizeHint(QSize(64, 96));
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
if (m_objId == i) {
item->setSelected(true);
}

View File

@ -136,6 +136,9 @@ void PaletteView::exportPalette(int start, int length) {
CoreController::Interrupter interrupter(m_controller);
QString filename = GBAApp::app()->getSaveFileName(this, tr("Export palette"),
tr("Windows PAL (*.pal);;Adobe Color Table (*.act)"));
if (filename.isNull()) {
return;
}
VFile* vf = VFileDevice::open(filename, O_WRONLY | O_CREAT | O_TRUNC);
if (!vf) {
LOG(QT, ERROR) << tr("Failed to open output palette file: %1").arg(filename);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<app version="1">
<name>mGBA</name>
<coder>Jeffrey Pfau (endrift)</coder>
<coder>Vicki Pfau (endrift)</coder>
<version>${VERSION_STRING}</version>
<short_description>mGBA Game Boy Advance emulator</short_description>
</app>