Merge branch 'master' (early part) into medusa

This commit is contained in:
Vicki Pfau 2023-05-03 02:43:01 -07:00
commit 407a338a0f
17 changed files with 132 additions and 115 deletions

2
.gitignore vendored
View File

@ -10,10 +10,12 @@
*.a
*.dylib
*.dll
*.lib
*.exe
*.o
*.so
CMakeCache.txt
CMakeFiles
CMakeSettings.json
cmake_install.cmake
version.c

14
CHANGES
View File

@ -43,6 +43,13 @@ Misc:
Features:
- New unlicensed GB mappers: NT (older types 1 and 2), Li Cheng, GGB-81
- Debugger: Add range watchpoints
Emulation fixes:
- GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722)
Misc:
- GB Serialize: Add missing savestate support for MBC6 and NT (newer)
- GBA: Improve detection of valid ELF ROMs
0.10.1: (2023-01-10)
Emulation fixes:
- GB Audio: Fix channels 1/2 not playing when resetting volume (fixes mgba.io/i/2614)
- GB Audio: Fix channel 3 volume being changed between samples (fixes mgba.io/i/1896)
@ -52,21 +59,20 @@ Emulation fixes:
- GB Serialize: Don't write BGP/OBP when loading SCGB state (fixes mgba.io/i/2694)
- GB SIO: Further fix bidirectional transfer starting
- GBA: Fix resetting key IRQ state (fixes mgba.io/i/2716)
- GBA BIOS: Include timing in degenerate ArcTan2 cases (fixes mgba.io/i/2763)
- GBA Video: Ignore disabled backgrounds as OBJ blend target (fixes mgba.io/i/2489)
- GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722)
Other fixes:
- GBA: Fix forceskip BIOS logic for multiboot ROMs (fixes mgba.io/i/2753)
- GBA Cheats: Fix issues detecting unencrypted cheats (fixes mgba.io/i/2724)
- Qt: Manually split filename to avoid overzealous splitting (fixes mgba.io/i/2681)
- Qt: Expand criteria for tag branch names (fixes mgba.io/i/2679)
- Qt: Fix scanning specific e-Reader dotcodes (fixes mgba.io/i/2693)
- Qt: Don't re-enable sync if GBA link modes aren't the same (fixes mgba.io/i/2044)
- Qt: Improve handling of multiplayer syncing (fixes mgba.io/i/2720)
- Qt: Fix initializing update revision info
- Qt: Redo stable branch detection heuristic (fixes mgba.io/i/2679)
- Res: Fix species name location in Ruby/Sapphire revs 1/2 (fixes mgba.io/i/2685)
- VFS: Fix minizip write returning 0 on success instead of size
Misc:
- GB Serialize: Add missing savestate support for MBC6 and NT (newer)
- GBA: Improve detection of valid ELF ROMs
- macOS: Add category to plist (closes mgba.io/i/2691)
- macOS: Fix modern build with libepoxy (fixes mgba.io/i/2700)
- Qt: Keep track of current palette preset name (fixes mgba.io/i/2680)

View File

@ -6,6 +6,10 @@
#ifndef M_SCRIPT_SOCKET_H
#define M_SCRIPT_SOCKET_H
#include <mgba-util/common.h>
CXX_GUARD_START
enum mSocketErrorCode {
mSCRIPT_SOCKERR_UNKNOWN_ERROR = -1,
mSCRIPT_SOCKERR_OK = 0,
@ -22,4 +26,6 @@ enum mSocketErrorCode {
mSCRIPT_SOCKERR_UNSUPPORTED,
};
CXX_GUARD_END
#endif

View File

@ -12,6 +12,8 @@
#include <mgba/script/context.h>
#include <mgba/script/types.h>
#include "script/test.h"
#ifdef M_CORE_GBA
#include <mgba/internal/gba/memory.h>
#define TEST_PLATFORM mPLATFORM_GBA
@ -66,22 +68,6 @@ static const uint8_t _fakeGBROM[0x4000] = {
mCoreConfigDeinit(&core->config); \
core->deinit(core)
#define LOAD_PROGRAM(PROG) \
do { \
struct VFile* vf = VFileFromConstMemory(PROG, strlen(PROG)); \
assert_true(lua->load(lua, NULL, vf)); \
vf->close(vf); \
} while(0)
#define TEST_VALUE(TYPE, NAME, VALUE) \
do { \
struct mScriptValue val = mSCRIPT_MAKE(TYPE, VALUE); \
struct mScriptValue* global = lua->getGlobal(lua, NAME); \
assert_non_null(global); \
assert_true(global->type->equal(global, &val)); \
mScriptValueDeref(global); \
} while(0)
static void _mScriptTestLog(struct mLogger* log, int category, enum mLogLevel level, const char* format, va_list args) {
UNUSED(category);
struct mScriptTestLogger* logger = (struct mScriptTestLogger*) log;

View File

@ -499,7 +499,7 @@ void GBAudioRun(struct GBAudio* audio, int32_t timestamp, int channels) {
if (!audio->enable) {
return;
}
if (audio->p && channels != 0xF && timestamp - audio->lastSample > (int) (SAMPLE_INTERVAL * audio->timingFactor)) {
if (audio->p && channels != 0x1F && timestamp - audio->lastSample > (int) (SAMPLE_INTERVAL * audio->timingFactor)) {
GBAudioSample(audio, timestamp);
}
@ -779,7 +779,7 @@ void GBAudioSample(struct GBAudio* audio, int32_t timestamp) {
for (sample = audio->sampleIndex; timestamp >= interval && sample < GB_MAX_SAMPLES; ++sample, timestamp -= interval) {
int16_t sampleLeft = 0;
int16_t sampleRight = 0;
GBAudioRun(audio, sample * interval + audio->lastSample, 0xF);
GBAudioRun(audio, sample * interval + audio->lastSample, 0x1F);
GBAudioSamplePSG(audio, &sampleLeft, &sampleRight);
sampleLeft = (sampleLeft * audio->masterVolume * 6) >> 7;
sampleRight = (sampleRight * audio->masterVolume * 6) >> 7;

View File

@ -336,12 +336,14 @@ static int16_t _ArcTan(int32_t i, int32_t* r1, int32_t* r3, uint32_t* cycles) {
static int16_t _ArcTan2(int32_t x, int32_t y, int32_t* r1, uint32_t* cycles) {
if (!y) {
*cycles = 11;
if (x >= 0) {
return 0;
}
return 0x8000;
}
if (!x) {
*cycles = 11;
if (y >= 0) {
return 0x4000;
}

View File

@ -105,36 +105,36 @@ static bool GBACheatAddAutodetect(struct GBACheatSet* set, uint32_t op1, uint32_
char line[18] = "XXXXXXXX XXXXXXXX";
snprintf(line, sizeof(line), "%08X %08X", op1, op2);
int gsaP, rgsaP, parP, rparP;
int nextProbability;
int maxProbability = INT_MIN;
switch (set->gsaVersion) {
case 0:
// Try to detect GameShark version
GBACheatDecryptGameShark(&o1, &o2, GBACheatGameSharkSeeds);
gsaP = GBACheatGameSharkProbability(o1, o2);
nextProbability = GBACheatGameSharkProbability(o1, o2);
o1 = op1;
o2 = op2;
if (gsaP > maxProbability) {
maxProbability = gsaP;
if (nextProbability > maxProbability) {
maxProbability = nextProbability;
GBACheatSetGameSharkVersion(set, GBA_GS_GSAV1);
}
GBACheatDecryptGameShark(&o1, &o2, GBACheatProActionReplaySeeds);
parP = GBACheatProActionReplayProbability(o1, o2);
if (parP > maxProbability) {
maxProbability = parP;
nextProbability = GBACheatProActionReplayProbability(o1, o2);
if (nextProbability > maxProbability) {
maxProbability = nextProbability;
GBACheatSetGameSharkVersion(set, GBA_GS_PARV3);
}
rgsaP = GBACheatGameSharkProbability(op1, op2);
if (rgsaP > maxProbability) {
maxProbability = rgsaP;
nextProbability = GBACheatGameSharkProbability(op1, op2);
if (nextProbability > maxProbability) {
maxProbability = nextProbability;
GBACheatSetGameSharkVersion(set, GBA_GS_GSAV1_RAW);
}
rparP = GBACheatProActionReplayProbability(op1, op2);
if (rparP > maxProbability) {
maxProbability = rparP;
nextProbability = GBACheatProActionReplayProbability(op1, op2);
if (nextProbability > maxProbability) {
maxProbability = nextProbability;
GBACheatSetGameSharkVersion(set, GBA_GS_PARV3_RAW);
}

View File

@ -7,6 +7,7 @@
#include <QDir>
#include <QFileInfo>
#include <QRegularExpression>
#include "ApplicationUpdatePrompt.h"
#include "ConfigController.h"
@ -71,9 +72,10 @@ QStringList ApplicationUpdater::listChannels() {
}
QString ApplicationUpdater::currentChannel() {
QLatin1String version(projectVersion);
QLatin1String branch(gitBranch);
if (branch == QLatin1String("heads/") + version || branch == version) {
QString version(projectVersion);
QString branch(gitBranch);
QRegularExpression stable("^(?:(?:refs/)?(?:tags|heads)/)?[0-9]+\\.[0-9]+\\.[0-9]+$");
if (branch.contains(stable) || (branch == "(unknown)" && version.contains(stable))) {
return QLatin1String("stable");
} else {
return QLatin1String("dev");
@ -174,7 +176,8 @@ const char* ApplicationUpdater::platform() {
}
ApplicationUpdater::UpdateInfo::UpdateInfo(const QString& prefix, const mUpdate* update)
: size(update->size)
: rev(-1)
, size(update->size)
, url(prefix + update->path)
{
if (update->rev > 0) {

View File

@ -673,8 +673,20 @@ void PainterGL::filter(bool filter) {
}
}
#ifndef GL_DEBUG_OUTPUT_SYNCHRONOUS
#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
#endif
void PainterGL::start() {
makeCurrent();
#if defined(BUILD_GLES3) && !defined(Q_OS_MAC)
if (glContextHasBug(OpenGLBug::GLTHREAD_BLOCKS_SWAP)) {
// Suggested on Discord as a way to strongly hint that glthread should be disabled
// See https://gitlab.freedesktop.org/mesa/mesa/-/issues/8035
QOpenGLFunctions_Baseline* fn = m_gl->versionFunctions<QOpenGLFunctions_Baseline>();
fn->glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
}
#endif
#if defined(BUILD_GLES2) || defined(BUILD_GLES3)
if (m_supportsShaders && m_shader.passes) {

View File

@ -71,7 +71,7 @@
</property>
<item>
<property name="text">
<string>Latest stable verison</string>
<string>Latest stable version</string>
</property>
</item>
<item>

View File

@ -18,6 +18,7 @@ bool glContextHasBug(OpenGLBug bug) {
QOpenGLFunctions* fn = context->functions();
QString vendor(reinterpret_cast<const char*>(fn->glGetString(GL_VENDOR)));
QString renderer(reinterpret_cast<const char*>(fn->glGetString(GL_RENDERER)));
QString version(reinterpret_cast<const char*>(fn->glGetString(GL_VERSION)));
switch (bug) {
case OpenGLBug::CROSS_THREAD_FLUSH:
@ -26,6 +27,10 @@ bool glContextHasBug(OpenGLBug bug) {
#else
return vendor == "Intel";
#endif
case OpenGLBug::GLTHREAD_BLOCKS_SWAP:
return version.contains(" Mesa ");
default:
return false;
}

View File

@ -8,8 +8,8 @@
namespace QGBA {
enum class OpenGLBug {
// mgba.io/i/2761
CROSS_THREAD_FLUSH
CROSS_THREAD_FLUSH, // mgba.io/i/2761
GLTHREAD_BLOCKS_SWAP, // mgba.io/i/2767
};
bool glContextHasBug(OpenGLBug);

View File

@ -308,6 +308,7 @@ void ReportView::generateReport() {
deferredBinaries.append(qMakePair(QString("Save %1").arg(winId), save));
}
mStateExtdataDeinit(&extdata);
vf->close(vf);
}
}
} else {

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>885</width>
<height>797</height>
<width>880</width>
<height>700</height>
</rect>
</property>
<property name="sizePolicy">
@ -95,7 +95,7 @@
<item row="1" column="1">
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>9</number>
<number>1</number>
</property>
<widget class="QWidget" name="av">
<layout class="QVBoxLayout" name="formLayout">
@ -2171,45 +2171,37 @@
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QRadioButton" name="gbColor">
<property name="text">
<string>Default color palette only</string>
</property>
<attribute name="buttonGroup">
<string notr="true">gbColors</string>
</attribute>
</widget>
</item>
<item row="6" column="1">
<widget class="QRadioButton" name="sgbColor">
<property name="text">
<string>SGB color palette if available</string>
</property>
<attribute name="buttonGroup">
<string notr="true">gbColors</string>
</attribute>
</widget>
</item>
<item row="7" column="1">
<widget class="QRadioButton" name="cgbColor">
<property name="text">
<string>GBC color palette if available</string>
</property>
<attribute name="buttonGroup">
<string notr="true">gbColors</string>
</attribute>
</widget>
</item>
<item row="8" column="1">
<widget class="QRadioButton" name="scgbColor">
<property name="text">
<string>SGB (preferred) or GBC color palette if available</string>
</property>
<attribute name="buttonGroup">
<string notr="true">gbColors</string>
</attribute>
</widget>
<item row="5" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="1">
<widget class="QRadioButton" name="sgbColor">
<property name="text">
<string>SGB color palette if available</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QRadioButton" name="gbColor">
<property name="text">
<string>Default color palette only</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="cgbColor">
<property name="text">
<string>GBC color palette if available</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QRadioButton" name="scgbColor">
<property name="text">
<string>SGB (preferred) or GBC color palette if available</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>

29
src/script/test.h Normal file
View File

@ -0,0 +1,29 @@
/* Copyright (c) 2013-2022 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef M_SCRIPT_TEST_H
#define M_SCRIPT_TEST_H
#define LOAD_PROGRAM(PROG) \
do { \
struct VFile* vf = VFileFromConstMemory(PROG, strlen(PROG)); \
assert_true(lua->load(lua, NULL, vf)); \
vf->close(vf); \
} while(0)
#define TEST_VALUE(TYPE, NAME, VALUE) \
do { \
struct mScriptValue val = mSCRIPT_MAKE(TYPE, VALUE); \
struct mScriptValue* global = lua->getGlobal(lua, NAME); \
assert_non_null(global); \
assert_true(global->type->equal(global, &val)); \
mScriptValueDeref(global); \
} while(0)
#define TEST_PROGRAM(PROG) \
LOAD_PROGRAM(PROG); \
assert_true(lua->run(lua)); \
#endif

View File

@ -8,22 +8,13 @@
#include <mgba/internal/script/lua.h>
#include <mgba/script/macros.h>
#include "script/test.h"
#define SETUP_LUA \
struct mScriptContext context; \
mScriptContextInit(&context); \
struct mScriptEngineContext* lua = mScriptContextRegisterEngine(&context, mSCRIPT_ENGINE_LUA)
#define LOAD_PROGRAM(PROG) \
do { \
struct VFile* vf = VFileFromConstMemory(PROG, strlen(PROG)); \
assert_true(lua->load(lua, NULL, vf)); \
vf->close(vf); \
} while(0)
#define TEST_PROGRAM(PROG) \
LOAD_PROGRAM(PROG); \
assert_true(lua->run(lua)); \
struct Test {
int32_t i;
int32_t (*ifn0)(struct Test*);

View File

@ -10,32 +10,14 @@
#include <mgba/script/macros.h>
#include <mgba/script/types.h>
#include "script/test.h"
#define SETUP_LUA \
struct mScriptContext context; \
mScriptContextInit(&context); \
struct mScriptEngineContext* lua = mScriptContextRegisterEngine(&context, mSCRIPT_ENGINE_LUA); \
mScriptContextAttachStdlib(&context)
#define LOAD_PROGRAM(PROG) \
do { \
struct VFile* vf = VFileFromConstMemory(PROG, strlen(PROG)); \
assert_true(lua->load(lua, NULL, vf)); \
vf->close(vf); \
} while(0)
#define TEST_PROGRAM(PROG) \
LOAD_PROGRAM(PROG); \
assert_true(lua->run(lua)); \
#define TEST_VALUE(TYPE, NAME, VALUE) \
do { \
struct mScriptValue val = mSCRIPT_MAKE(TYPE, VALUE); \
struct mScriptValue* global = lua->getGlobal(lua, NAME); \
assert_non_null(global); \
assert_true(global->type->equal(global, &val)); \
mScriptValueDeref(global); \
} while(0)
M_TEST_SUITE_SETUP(mScriptStdlib) {
if (mSCRIPT_ENGINE_LUA->init) {
mSCRIPT_ENGINE_LUA->init(mSCRIPT_ENGINE_LUA);