Merge branch 'master' into medusa

This commit is contained in:
Vicki Pfau 2022-08-23 21:06:35 -07:00
commit ddbdb62473
28 changed files with 734 additions and 600 deletions

View File

@ -97,6 +97,7 @@ Other fixes:
- Core: Fix the runloop resuming after a game has crashed (fixes mgba.io/i/2451) - Core: Fix the runloop resuming after a game has crashed (fixes mgba.io/i/2451)
- Core: Fix crash if library can't be opened - Core: Fix crash if library can't be opened
- Debugger: Fix crash with extremely long CLI strings - Debugger: Fix crash with extremely long CLI strings
- Debugger: Fix multiple conditional watchpoints at the same address
- FFmpeg: Fix crash when encoding audio with some containers - FFmpeg: Fix crash when encoding audio with some containers
- FFmpeg: Fix GIF recording (fixes mgba.io/i/2393) - FFmpeg: Fix GIF recording (fixes mgba.io/i/2393)
- GB: Fix temporary saves - GB: Fix temporary saves

View File

@ -21,14 +21,11 @@ if(NOT LIBMGBA_ONLY)
set(BINARY_NAME ${BINARY_NAME} CACHE INTERNAL "Name of output binaries") set(BINARY_NAME ${BINARY_NAME} CACHE INTERNAL "Name of output binaries")
endif() endif()
set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD 11)
if(NOT MSVC) if(NOT MSVC)
set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF) set(CMAKE_C_EXTENSIONS OFF)
if(SWITCH OR 3DS) if(SWITCH OR 3DS OR (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "4.3"))
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_EXTENSIONS ON)
elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "4.3")
set(CMAKE_C_EXTENSIONS ON) set(CMAKE_C_EXTENSIONS ON)
endif() endif()
set(WARNING_FLAGS "-Wall -Wextra -Wno-missing-field-initializers") set(WARNING_FLAGS "-Wall -Wextra -Wno-missing-field-initializers")
@ -39,8 +36,8 @@ if(NOT MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=implicit-function-declaration") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=implicit-function-declaration")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}")
else() else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS /wd4003 /wd4244 /wd4146 /wd4267") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS /wd4003 /wd4244 /wd4146 /wd4267 /Zc:preprocessor-")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CRT_SECURE_NO_WARNINGS /wd4003 /wd4244 /wd4146 /wd4267") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CRT_SECURE_NO_WARNINGS /wd4003 /wd4244 /wd4146 /wd4267 /Zc:preprocessor-")
endif() endif()
if(NOT LIBMGBA_ONLY) if(NOT LIBMGBA_ONLY)

View File

@ -136,7 +136,7 @@ DS default controls are slightly different:
Compiling Compiling
--------- ---------
Compiling requires using CMake 3.1 or newer. GCC and Clang are both known to work to compile medusa, but Visual Studio 2013 and older are known not to work. Support for Visual Studio 2015 and newer is coming soon. Compiling requires using CMake 3.1 or newer. GCC, Clang and Visual Studio 2019 known to work to compile medusa.
#### Docker building #### Docker building

View File

@ -20,6 +20,7 @@
CXX_GUARD_START CXX_GUARD_START
#include <assert.h>
#include <ctype.h> #include <ctype.h>
#include <fcntl.h> #include <fcntl.h>
#include <inttypes.h> #include <inttypes.h>

View File

@ -24,7 +24,6 @@ typedef THREAD_ENTRY (*ThreadEntry)(void*);
typedef pthread_t Thread; typedef pthread_t Thread;
typedef pthread_mutex_t Mutex; typedef pthread_mutex_t Mutex;
typedef pthread_cond_t Condition; typedef pthread_cond_t Condition;
typedef pthread_key_t ThreadLocal;
static inline int MutexInit(Mutex* mutex) { static inline int MutexInit(Mutex* mutex) {
return pthread_mutex_init(mutex, 0); return pthread_mutex_init(mutex, 0);
@ -104,6 +103,9 @@ static inline int ThreadSetName(const char* name) {
#endif #endif
} }
#if (__STDC_VERSION__ < 201112L) || (__STDC_NO_THREADS__ == 1)
typedef pthread_key_t ThreadLocal;
static inline void ThreadLocalInitKey(ThreadLocal* key) { static inline void ThreadLocalInitKey(ThreadLocal* key) {
pthread_key_create(key, 0); pthread_key_create(key, 0);
} }
@ -115,6 +117,7 @@ static inline void ThreadLocalSetKey(ThreadLocal key, void* value) {
static inline void* ThreadLocalGetValue(ThreadLocal key) { static inline void* ThreadLocalGetValue(ThreadLocal key) {
return pthread_getspecific(key); return pthread_getspecific(key);
} }
#endif
CXX_GUARD_END CXX_GUARD_END

View File

@ -17,7 +17,6 @@ typedef struct {
} Condition; } Condition;
#define THREAD_ENTRY int #define THREAD_ENTRY int
typedef THREAD_ENTRY (*ThreadEntry)(void*); typedef THREAD_ENTRY (*ThreadEntry)(void*);
typedef int ThreadLocal;
static inline int MutexInit(Mutex* mutex) { static inline int MutexInit(Mutex* mutex) {
Mutex id = sceKernelCreateMutex("mutex", 0, 0, 0); Mutex id = sceKernelCreateMutex("mutex", 0, 0, 0);
@ -145,6 +144,9 @@ static inline int ThreadSetName(const char* name) {
return -1; return -1;
} }
#if (__STDC_VERSION__ < 201112L) || (__STDC_NO_THREADS__ == 1)
typedef int ThreadLocal;
static inline void ThreadLocalInitKey(ThreadLocal* key) { static inline void ThreadLocalInitKey(ThreadLocal* key) {
static int base = 0x90; static int base = 0x90;
*key = __atomic_fetch_add(&base, 1, __ATOMIC_SEQ_CST); *key = __atomic_fetch_add(&base, 1, __ATOMIC_SEQ_CST);
@ -160,3 +162,4 @@ static inline void* ThreadLocalGetValue(ThreadLocal key) {
return *tls; return *tls;
} }
#endif #endif
#endif

View File

@ -16,7 +16,6 @@ typedef THREAD_ENTRY ThreadEntry(LPVOID);
typedef HANDLE Thread; typedef HANDLE Thread;
typedef CRITICAL_SECTION Mutex; typedef CRITICAL_SECTION Mutex;
typedef CONDITION_VARIABLE Condition; typedef CONDITION_VARIABLE Condition;
typedef DWORD ThreadLocal;
static inline int MutexInit(Mutex* mutex) { static inline int MutexInit(Mutex* mutex) {
InitializeCriticalSection(mutex); InitializeCriticalSection(mutex);
@ -89,6 +88,9 @@ static inline int ThreadSetName(const char* name) {
return -1; return -1;
} }
#if (__STDC_VERSION__ < 201112L) || (__STDC_NO_THREADS__ == 1)
typedef DWORD ThreadLocal;
static inline void ThreadLocalInitKey(ThreadLocal* key) { static inline void ThreadLocalInitKey(ThreadLocal* key) {
*key = TlsAlloc(); *key = TlsAlloc();
} }
@ -100,5 +102,6 @@ static inline void ThreadLocalSetKey(ThreadLocal key, void* value) {
static inline void* ThreadLocalGetValue(ThreadLocal key) { static inline void* ThreadLocalGetValue(ThreadLocal key) {
return TlsGetValue(key); return TlsGetValue(key);
} }
#endif
#endif #endif

View File

@ -39,6 +39,10 @@ typedef SOCKET Socket;
typedef int Socket; typedef int Socket;
#endif #endif
#if !defined(__3DS__) && !defined(GEKKO)
#define HAS_IPV6
#endif
enum IP { enum IP {
IPV4, IPV4,
IPV6 IPV6
@ -152,12 +156,36 @@ static inline int SocketClose(Socket socket) {
#endif #endif
} }
static inline Socket SocketOpenTCP(int port, const struct Address* bindAddress) { static inline void SocketCloseQuiet(Socket socket) {
#ifdef GEKKO int savedErrno = SocketError();
Socket sock = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP); SocketClose(socket);
#ifdef _WIN32
WSASetLastError(savedErrno);
#else #else
Socket sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); errno = savedErrno;
#endif #endif
}
static inline Socket SocketCreate(bool useIPv6, int protocol) {
if (useIPv6) {
#ifdef HAS_IPV6
return socket(AF_INET6, SOCK_STREAM, protocol);
#else
errno = EAFNOSUPPORT;
return INVALID_SOCKET;
#endif
} else {
#ifdef GEKKO
return net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
#else
return socket(AF_INET, SOCK_STREAM, protocol);
#endif
}
}
static inline Socket SocketOpenTCP(int port, const struct Address* bindAddress) {
bool useIPv6 = bindAddress && (bindAddress->version == IPV6);
Socket sock = SocketCreate(useIPv6, IPPROTO_TCP);
if (SOCKET_FAILED(sock)) { if (SOCKET_FAILED(sock)) {
return sock; return sock;
} }
@ -178,7 +206,7 @@ static inline Socket SocketOpenTCP(int port, const struct Address* bindAddress)
#else #else
err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo)); err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo));
#endif #endif
} else if (bindAddress->version == IPV4) { } else if (!useIPv6) {
struct sockaddr_in bindInfo; struct sockaddr_in bindInfo;
memset(&bindInfo, 0, sizeof(bindInfo)); memset(&bindInfo, 0, sizeof(bindInfo));
bindInfo.sin_family = AF_INET; bindInfo.sin_family = AF_INET;
@ -200,18 +228,15 @@ static inline Socket SocketOpenTCP(int port, const struct Address* bindAddress)
#endif #endif
} }
if (err) { if (err) {
SocketClose(sock); SocketCloseQuiet(sock);
return INVALID_SOCKET; return INVALID_SOCKET;
} }
return sock; return sock;
} }
static inline Socket SocketConnectTCP(int port, const struct Address* destinationAddress) { static inline Socket SocketConnectTCP(int port, const struct Address* destinationAddress) {
#ifdef GEKKO bool useIPv6 = destinationAddress && (destinationAddress->version == IPV6);
Socket sock = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP); Socket sock = SocketCreate(useIPv6, IPPROTO_TCP);
#else
Socket sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
#endif
if (SOCKET_FAILED(sock)) { if (SOCKET_FAILED(sock)) {
return sock; return sock;
} }
@ -238,7 +263,7 @@ static inline Socket SocketConnectTCP(int port, const struct Address* destinatio
#else #else
err = connect(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo)); err = connect(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo));
#endif #endif
#if !defined(__3DS__) && !defined(GEKKO) #ifdef HAS_IPV6
} else { } else {
struct sockaddr_in6 bindInfo; struct sockaddr_in6 bindInfo;
memset(&bindInfo, 0, sizeof(bindInfo)); memset(&bindInfo, 0, sizeof(bindInfo));
@ -250,7 +275,7 @@ static inline Socket SocketConnectTCP(int port, const struct Address* destinatio
} }
if (err) { if (err) {
SocketClose(sock); SocketCloseQuiet(sock);
return INVALID_SOCKET; return INVALID_SOCKET;
} }
return sock; return sock;

View File

@ -11,12 +11,6 @@
CXX_GUARD_START CXX_GUARD_START
#ifndef DISABLE_THREADING #ifndef DISABLE_THREADING
#if (__STDC_VERSION__ >= 201112L) && (__STDC_NO_THREADS__ != 1)
#define ThreadLocal _Thread_local void*
#define ThreadLocalInitKey(X)
#define ThreadLocalSetKey(K, V) K = V
#define ThreadLocalGetValue(K) K
#endif
#ifdef USE_PTHREADS #ifdef USE_PTHREADS
#include <mgba-util/platform/posix/threading.h> #include <mgba-util/platform/posix/threading.h>
#elif defined(_WIN32) #elif defined(_WIN32)
@ -31,7 +25,15 @@ CXX_GUARD_START
#define DISABLE_THREADING #define DISABLE_THREADING
#endif #endif
#endif #endif
#ifdef DISABLE_THREADING
#ifndef DISABLE_THREADING
#if (__STDC_VERSION__ >= 201112L) && (__STDC_NO_THREADS__ != 1)
#define ThreadLocal _Thread_local void*
#define ThreadLocalInitKey(X)
#define ThreadLocalSetKey(K, V) K = V
#define ThreadLocalGetValue(K) K
#endif
#else
#ifdef __3DS__ #ifdef __3DS__
// ctrulib already has a type called Thread // ctrulib already has a type called Thread
#include <3ds/thread.h> #include <3ds/thread.h>

View File

@ -164,12 +164,12 @@ mLOG_DECLARE_CATEGORY(GB_STATE);
* | 0x00197: Reserved (leave zero) * | 0x00197: Reserved (leave zero)
* 0x00198 - 0x0019F: Global cycle counter * 0x00198 - 0x0019F: Global cycle counter
* 0x001A0 - 0x001A1: Program counter for last cartridge read * 0x001A0 - 0x001A1: Program counter for last cartridge read
* 0x001A2 - 0x00247: Reserved (leave zero) * 0x001A2 - 0x001D7: Reserved (leave zero)
* 0x00248 - 0x0025F: Additional audio state * 0x001D8 - 0x0025F: Additional audio state
* | 0x00248 - 0x0024B: Last sample timestamp * | 0x001D8 - 0x001DB: Last sample timestamp
* | 0x0024C: Current audio sample index * | 0x001DC: Current audio sample index
* | 0x0024D - 0x0024F: Reserved (leave zero) * | 0x001DD - 0x001DF: Reserved (leave zero)
* | 0x00250 - 0x0025F: Audio rendered samples * | 0x001E0 - 0x0025F: Audio rendered samples
* 0x00260 - 0x002FF: OAM * 0x00260 - 0x002FF: OAM
* 0x00300 - 0x0037F: I/O memory * 0x00300 - 0x0037F: I/O memory
* 0x00380 - 0x003FE: HRAM * 0x00380 - 0x003FE: HRAM
@ -442,7 +442,7 @@ struct GBSerializedState {
int32_t lastSample; int32_t lastSample;
uint8_t sampleIndex; uint8_t sampleIndex;
uint8_t reserved[3]; uint8_t reserved[3];
struct mStereoSample currentSamples[32]; struct mStereoSample currentSamples[GB_MAX_SAMPLES];
} audio2; } audio2;
uint8_t oam[GB_SIZE_OAM]; uint8_t oam[GB_SIZE_OAM];
@ -473,6 +473,8 @@ struct GBSerializedState {
}; };
#pragma pack(pop) #pragma pack(pop)
static_assert(sizeof(struct GBSerializedState) == 0x11800, "GB savestate struct sized wrong");
bool GBDeserialize(struct GB* gb, const struct GBSerializedState* state); bool GBDeserialize(struct GB* gb, const struct GBSerializedState* state);
void GBSerialize(struct GB* gb, struct GBSerializedState* state); void GBSerialize(struct GB* gb, struct GBSerializedState* state);

View File

@ -402,7 +402,7 @@ struct GBASerializedState {
int8_t chB[16]; int8_t chB[16];
} samples; } samples;
struct mStereoSample currentSamples[16]; struct mStereoSample currentSamples[GBA_MAX_SAMPLES];
uint32_t reserved[12]; uint32_t reserved[12];
@ -414,6 +414,8 @@ struct GBASerializedState {
uint8_t wram[SIZE_WORKING_RAM]; uint8_t wram[SIZE_WORKING_RAM];
}; };
static_assert(sizeof(struct GBASerializedState) == 0x61000, "GBA savestate struct sized wrong");
struct VDir; struct VDir;
void GBASerialize(struct GBA* gba, struct GBASerializedState* state); void GBASerialize(struct GBA* gba, struct GBASerializedState* state);

View File

@ -84,7 +84,9 @@ CXX_GUARD_START
extern const struct mScriptType mSTStruct_ ## STRUCT; \ extern const struct mScriptType mSTStruct_ ## STRUCT; \
extern const struct mScriptType mSTStructConst_ ## STRUCT; \ extern const struct mScriptType mSTStructConst_ ## STRUCT; \
extern const struct mScriptType mSTStructPtr_ ## STRUCT; \ extern const struct mScriptType mSTStructPtr_ ## STRUCT; \
extern const struct mScriptType mSTStructPtrConst_ ## STRUCT; extern const struct mScriptType mSTStructPtrConst_ ## STRUCT; \
extern const struct mScriptType mSTWrapper_ ## STRUCT; \
extern const struct mScriptType mSTWrapperConst_ ## STRUCT;
#define mSCRIPT_DEFINE_STRUCT(STRUCT) \ #define mSCRIPT_DEFINE_STRUCT(STRUCT) \
const struct mScriptType mSTStruct_ ## STRUCT; \ const struct mScriptType mSTStruct_ ## STRUCT; \

View File

@ -0,0 +1,25 @@
[shader]
name=TV Mode
author=Dominus Iniquitatis
description=Scanlines along with a subtle blurring.
passes=1
[pass.0]
fragmentShader=tv.fs
blend=1
width=-2
height=-2
[pass.0.uniform.lineBrightness]
type=float
readableName=Line brightness
default=0.75
min=0.0
max=1.0
[pass.0.uniform.blurring]
type=float
readableName=Blurring
default=1.0
min=0.0
max=1.0

View File

@ -0,0 +1,44 @@
/*
TV Mode Shader
Copyright (C) 2022 Dominus Iniquitatis - zerosaiko@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
uniform sampler2D tex;
uniform vec2 texSize;
varying vec2 texCoord;
uniform float lineBrightness;
uniform float blurring;
void main()
{
vec4 c = texture2D(tex, texCoord);
vec4 n = texture2D(tex, texCoord + vec2(1.0 / texSize.x * 0.5, 0.0));
vec4 color = mix(c, (c + n) / 2.0, blurring);
color.a = c.a;
if (int(mod(texCoord.t * texSize.y * 2.0, 2.0)) == 0)
{
color.rgb *= lineBrightness;
}
gl_FragColor = color;
}

View File

@ -102,7 +102,7 @@ static bool _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, st
int32_t value; int32_t value;
int segment; int segment;
if (!mDebuggerEvaluateParseTree(debugger->d.p, watchpoint->condition, &value, &segment) || !(value || segment >= 0)) { if (!mDebuggerEvaluateParseTree(debugger->d.p, watchpoint->condition, &value, &segment) || !(value || segment >= 0)) {
return false; continue;
} }
} }

View File

@ -717,7 +717,7 @@ static void mScriptConsoleLog(struct mScriptConsole* console, struct mScriptStri
if (console->logger) { if (console->logger) {
mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg->buffer); mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg->buffer);
} else { } else {
mLog(_mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg->buffer); mLog(_mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg->buffer);
} }
} }
@ -725,7 +725,7 @@ static void mScriptConsoleWarn(struct mScriptConsole* console, struct mScriptStr
if (console->logger) { if (console->logger) {
mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg->buffer); mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg->buffer);
} else { } else {
mLog(_mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg->buffer); mLog(_mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg->buffer);
} }
} }
@ -733,7 +733,7 @@ static void mScriptConsoleError(struct mScriptConsole* console, struct mScriptSt
if (console->logger) { if (console->logger) {
mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_ERROR, "%s", msg->buffer); mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_ERROR, "%s", msg->buffer);
} else { } else {
mLog(_mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg->buffer); mLog(_mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg->buffer);
} }
} }
@ -818,7 +818,7 @@ mSCRIPT_DEFINE_STRUCT(mScriptTextBuffer)
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, clear) mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, clear)
mSCRIPT_DEFINE_DOCSTRING("Set the number of rows and columns") mSCRIPT_DEFINE_DOCSTRING("Set the number of rows and columns")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, setSize) mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, setSize)
mSCRIPT_DEFINE_DOCSTRING("Set the posiiton of the cursor") mSCRIPT_DEFINE_DOCSTRING("Set the position of the cursor")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, moveCursor) mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, moveCursor)
mSCRIPT_DEFINE_DOCSTRING("Advance the cursor a number of columns") mSCRIPT_DEFINE_DOCSTRING("Advance the cursor a number of columns")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, advance) mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, advance)

View File

@ -474,9 +474,8 @@ void GBAudioRun(struct GBAudio* audio, int32_t timestamp, int channels) {
if (!audio->enable) { if (!audio->enable) {
return; return;
} }
if (audio->p && channels != 0xF && timestamp - audio->lastSample > SAMPLE_INTERVAL) { if (audio->p && channels != 0xF && timestamp - audio->lastSample > (int) (SAMPLE_INTERVAL * audio->timingFactor)) {
GBAudioSample(audio, timestamp); GBAudioSample(audio, timestamp);
return;
} }
if (audio->playingCh1 && (channels & 0x1)) { if (audio->playingCh1 && (channels & 0x1)) {
@ -747,10 +746,9 @@ void GBAudioSamplePSG(struct GBAudio* audio, int16_t* left, int16_t* right) {
} }
void GBAudioSample(struct GBAudio* audio, int32_t timestamp) { void GBAudioSample(struct GBAudio* audio, int32_t timestamp) {
timestamp -= audio->lastSample;
timestamp -= audio->sampleIndex * SAMPLE_INTERVAL;
int interval = SAMPLE_INTERVAL * audio->timingFactor; int interval = SAMPLE_INTERVAL * audio->timingFactor;
timestamp -= audio->lastSample;
timestamp -= audio->sampleIndex * interval;
int sample; int sample;
for (sample = audio->sampleIndex; timestamp >= interval && sample < GB_MAX_SAMPLES; ++sample, timestamp -= interval) { for (sample = audio->sampleIndex; timestamp >= interval && sample < GB_MAX_SAMPLES; ++sample, timestamp -= interval) {

View File

@ -627,7 +627,7 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i
if (startX == 0) { if (startX == 0) {
_cleanOAM(softwareRenderer, y); _cleanOAM(softwareRenderer, y);
} }
if (GBRegisterLCDCIsObjEnable(softwareRenderer->lcdc) && !softwareRenderer->d.disableOBJ && (softwareRenderer->model != GB_MODEL_SCGB || softwareRenderer->sgbTransfer != 1)) { if (GBRegisterLCDCIsObjEnable(softwareRenderer->lcdc) && !softwareRenderer->d.disableOBJ) {
int i; int i;
for (i = 0; i < softwareRenderer->objMax; ++i) { for (i = 0; i < softwareRenderer->objMax; ++i) {
GBVideoSoftwareRendererDrawObj(softwareRenderer, &softwareRenderer->obj[i], startX, endX, y); GBVideoSoftwareRendererDrawObj(softwareRenderer, &softwareRenderer->obj[i], startX, endX, y);
@ -917,7 +917,7 @@ static void GBVideoSoftwareRendererDrawBackground(struct GBVideoSoftwareRenderer
bgTile = ((int8_t*) maps)[topX + topY]; bgTile = ((int8_t*) maps)[topX + topY];
} }
int p = highlight ? PAL_HIGHLIGHT_BG : PAL_BG; int p = highlight ? PAL_HIGHLIGHT_BG : PAL_BG;
if (renderer->model >= GB_MODEL_CGB && (!(renderer->model & GB_MODEL_SGB) || renderer->sgbTransfer != 1)) { if (renderer->model >= GB_MODEL_CGB) {
GBObjAttributes attrs = attr[topX + topY]; GBObjAttributes attrs = attr[topX + topY];
p |= GBObjAttributesGetCGBPalette(attrs) * 4; p |= GBObjAttributesGetCGBPalette(attrs) * 4;
if (GBObjAttributesIsPriority(attrs) && GBRegisterLCDCIsBgEnable(renderer->lcdc)) { if (GBObjAttributesIsPriority(attrs) && GBRegisterLCDCIsBgEnable(renderer->lcdc)) {
@ -952,7 +952,7 @@ static void GBVideoSoftwareRendererDrawBackground(struct GBVideoSoftwareRenderer
bgTile = ((int8_t*) maps)[topX + topY]; bgTile = ((int8_t*) maps)[topX + topY];
} }
int p = highlight ? PAL_HIGHLIGHT_BG : PAL_BG; int p = highlight ? PAL_HIGHLIGHT_BG : PAL_BG;
if (renderer->model >= GB_MODEL_CGB && (!(renderer->model & GB_MODEL_SGB) || renderer->sgbTransfer != 1)) { if (renderer->model >= GB_MODEL_CGB) {
GBObjAttributes attrs = attr[topX + topY]; GBObjAttributes attrs = attr[topX + topY];
p |= GBObjAttributesGetCGBPalette(attrs) * 4; p |= GBObjAttributesGetCGBPalette(attrs) * 4;
if (GBObjAttributesIsPriority(attrs) && GBRegisterLCDCIsBgEnable(renderer->lcdc)) { if (GBObjAttributesIsPriority(attrs) && GBRegisterLCDCIsBgEnable(renderer->lcdc)) {

View File

@ -12,6 +12,9 @@
#include <QMenu> #include <QMenu>
#include <mgba/feature/commandline.h> #include <mgba/feature/commandline.h>
#ifdef M_CORE_GB
#include <mgba/internal/gb/overrides.h>
#endif
static const mOption s_frontendOptions[] = { static const mOption s_frontendOptions[] = {
{ "ecard", true, '\0' }, { "ecard", true, '\0' },
@ -128,8 +131,10 @@ ConfigController::ConfigController(QObject* parent)
m_opts.interframeBlending = false; m_opts.interframeBlending = false;
mCoreConfigLoad(&m_config); mCoreConfigLoad(&m_config);
mCoreConfigLoadDefaults(&m_config, &m_opts); mCoreConfigLoadDefaults(&m_config, &m_opts);
#ifdef M_CORE_GB
mCoreConfigSetDefaultIntValue(&m_config, "sgb.borders", 1); mCoreConfigSetDefaultIntValue(&m_config, "sgb.borders", 1);
mCoreConfigSetDefaultIntValue(&m_config, "useCgbColors", 1); mCoreConfigSetDefaultIntValue(&m_config, "gb.colors", GB_COLORS_CGB);
#endif
mCoreConfigMap(&m_config, &m_opts); mCoreConfigMap(&m_config, &m_opts);
mSubParserGraphicsInit(&m_subparsers[0], &m_graphicsOpts); mSubParserGraphicsInit(&m_subparsers[0], &m_graphicsOpts);

View File

@ -221,7 +221,7 @@ void DisplayGL::startDrawing(std::shared_ptr<CoreController> controller) {
CoreController::Interrupter interrupter(controller); CoreController::Interrupter interrupter(controller);
QMetaObject::invokeMethod(m_painter.get(), "start"); QMetaObject::invokeMethod(m_painter.get(), "start");
if (!m_gl) { if (!m_gl) {
if (QGuiApplication::platformName() == "windows") { if (shouldDisableUpdates()) {
setUpdatesEnabled(false); setUpdatesEnabled(false);
} }
} else { } else {
@ -309,7 +309,7 @@ void DisplayGL::unpauseDrawing() {
if (m_hasStarted) { if (m_hasStarted) {
m_isDrawing = true; m_isDrawing = true;
QMetaObject::invokeMethod(m_painter.get(), "unpause", Qt::BlockingQueuedConnection); QMetaObject::invokeMethod(m_painter.get(), "unpause", Qt::BlockingQueuedConnection);
if (!m_gl && QGuiApplication::platformName() == "windows") { if (!m_gl && shouldDisableUpdates()) {
setUpdatesEnabled(false); setUpdatesEnabled(false);
} }
} }
@ -388,6 +388,16 @@ void DisplayGL::resizePainter() {
} }
} }
bool DisplayGL::shouldDisableUpdates() {
if (QGuiApplication::platformName() == "windows") {
return true;
}
if (QGuiApplication::platformName() == "xcb") {
return true;
}
return false;
}
void DisplayGL::setVideoProxy(std::shared_ptr<VideoProxy> proxy) { void DisplayGL::setVideoProxy(std::shared_ptr<VideoProxy> proxy) {
Display::setVideoProxy(proxy); Display::setVideoProxy(proxy);
if (proxy) { if (proxy) {

View File

@ -112,6 +112,7 @@ protected:
private: private:
void resizePainter(); void resizePainter();
bool shouldDisableUpdates();
static QHash<QSurfaceFormat, bool> s_supports; static QHash<QSurfaceFormat, bool> s_supports;

View File

@ -165,10 +165,16 @@ Window::Window(CoreManager* manager, ConfigController* config, int playerId, QWi
}); });
#endif #endif
#if defined(M_CORE_GBA) #if defined(M_CORE_GBA)
resizeFrame(QSize(GBA_VIDEO_HORIZONTAL_PIXELS * i, GBA_VIDEO_VERTICAL_PIXELS * i)); QSize minimumSize = QSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS);
#elif defined(M_CORE_GB) #elif defined(M_CORE_GB)
resizeFrame(QSize(GB_VIDEO_HORIZONTAL_PIXELS * i, GB_VIDEO_VERTICAL_PIXELS * i)); QSize minimumSize = QSize(GB_VIDEO_HORIZONTAL_PIXELS, GB_VIDEO_VERTICAL_PIXELS);
#endif #endif
setMinimumSize(minimumSize);
if (i > 0) {
m_initialSize = minimumSize * i;
} else {
m_initialSize = minimumSize * 2;
}
setLogo(); setLogo();
connect(this, &Window::shutdown, m_logView, &QWidget::hide); connect(this, &Window::shutdown, m_logView, &QWidget::hide);
@ -232,7 +238,7 @@ void Window::argumentsPassed() {
} }
#endif #endif
if (m_config->graphicsOpts()->multiplier) { if (m_config->graphicsOpts()->multiplier > 0) {
m_savedScale = m_config->graphicsOpts()->multiplier; m_savedScale = m_config->graphicsOpts()->multiplier;
#if defined(M_CORE_GBA) #if defined(M_CORE_GBA)
@ -240,7 +246,7 @@ void Window::argumentsPassed() {
#elif defined(M_CORE_GB) #elif defined(M_CORE_GB)
QSize size(GB_VIDEO_HORIZONTAL_PIXELS, GB_VIDEO_VERTICAL_PIXELS); QSize size(GB_VIDEO_HORIZONTAL_PIXELS, GB_VIDEO_VERTICAL_PIXELS);
#endif #endif
resizeFrame(size * m_savedScale); m_initialSize = size * m_savedScale;
} }
if (args->fname) { if (args->fname) {
@ -263,9 +269,8 @@ void Window::resizeFrame(const QSize& size) {
newSize.setHeight(geom.height()); newSize.setHeight(geom.height());
} }
} }
m_screenWidget->setSizeHint(newSize);
newSize -= m_screenWidget->size();
newSize += this->size(); newSize += this->size();
newSize -= centralWidget()->size();
if (!isFullScreen()) { if (!isFullScreen()) {
resize(newSize); resize(newSize);
} }
@ -295,7 +300,7 @@ void Window::loadConfig() {
reloadConfig(); reloadConfig();
if (opts->width && opts->height) { if (opts->width && opts->height) {
resizeFrame(QSize(opts->width, opts->height)); m_initialSize = QSize(opts->width, opts->height);
} }
if (opts->fullscreen) { if (opts->fullscreen) {
@ -715,9 +720,10 @@ void Window::scriptingOpen() {
#endif #endif
void Window::resizeEvent(QResizeEvent*) { void Window::resizeEvent(QResizeEvent*) {
QSize newSize = centralWidget()->size();
if (!isFullScreen()) { if (!isFullScreen()) {
m_config->setOption("height", m_screenWidget->height()); m_config->setOption("height", newSize.height());
m_config->setOption("width", m_screenWidget->width()); m_config->setOption("width", newSize.width());
} }
int factor = 0; int factor = 0;
@ -725,9 +731,9 @@ void Window::resizeEvent(QResizeEvent*) {
if (m_controller) { if (m_controller) {
size = m_controller->screenDimensions(); size = m_controller->screenDimensions();
} }
if (m_screenWidget->width() % size.width() == 0 && m_screenWidget->height() % size.height() == 0 && if (newSize.width() % size.width() == 0 && newSize.height() % size.height() == 0 &&
m_screenWidget->width() / size.width() == m_screenWidget->height() / size.height()) { newSize.width() / size.width() == newSize.height() / size.height()) {
factor = m_screenWidget->width() / size.width(); factor = newSize.width() / size.width();
} }
m_savedScale = factor; m_savedScale = factor;
for (QMap<int, Action*>::iterator iter = m_frameSizes.begin(); iter != m_frameSizes.end(); ++iter) { for (QMap<int, Action*>::iterator iter = m_frameSizes.begin(); iter != m_frameSizes.end(); ++iter) {
@ -754,7 +760,9 @@ void Window::showEvent(QShowEvent* event) {
return; return;
} }
m_wasOpened = true; m_wasOpened = true;
resizeFrame(m_screenWidget->sizeHint()); if (m_initialSize.isValid()) {
resizeFrame(m_initialSize);
}
QVariant windowPos = m_config->getQtOption("windowPos", m_playerId > 0 ? QString("player%0").arg(m_playerId) : QString()); QVariant windowPos = m_config->getQtOption("windowPos", m_playerId > 0 ? QString("player%0").arg(m_playerId) : QString());
bool maximized = m_config->getQtOption("maximized").toBool(); bool maximized = m_config->getQtOption("maximized").toBool();
QRect geom = windowHandle()->screen()->availableGeometry(); QRect geom = windowHandle()->screen()->availableGeometry();
@ -910,7 +918,7 @@ void Window::exitFullScreen() {
if (!isFullScreen()) { if (!isFullScreen()) {
return; return;
} }
m_screenWidget->unsetCursor(); centralWidget()->unsetCursor();
menuBar()->show(); menuBar()->show();
showNormal(); showNormal();
} }
@ -973,7 +981,7 @@ void Window::gameStarted() {
} }
m_focusCheck.start(); m_focusCheck.start();
if (m_display->underMouse()) { if (m_display->underMouse()) {
m_screenWidget->setCursor(Qt::BlankCursor); centralWidget()->setCursor(Qt::BlankCursor);
} }
CoreController::Interrupter interrupter(m_controller); CoreController::Interrupter interrupter(m_controller);
@ -1118,11 +1126,11 @@ void Window::reloadDisplayDriver() {
connect(m_display.get(), &QGBA::Display::hideCursor, [this]() { connect(m_display.get(), &QGBA::Display::hideCursor, [this]() {
if (centralWidget() == m_display.get()) { if (centralWidget() == m_display.get()) {
m_screenWidget->setCursor(Qt::BlankCursor); centralWidget()->setCursor(Qt::BlankCursor);
} }
}); });
connect(m_display.get(), &QGBA::Display::showCursor, [this]() { connect(m_display.get(), &QGBA::Display::showCursor, [this]() {
m_screenWidget->unsetCursor(); centralWidget()->unsetCursor();
}); });
m_display->configure(m_config); m_display->configure(m_config);
@ -2207,7 +2215,7 @@ void Window::updateMute() {
void Window::setLogo() { void Window::setLogo() {
m_screenWidget->setPixmap(m_logo); m_screenWidget->setPixmap(m_logo);
m_screenWidget->setDimensions(m_logo.width(), m_logo.height()); m_screenWidget->setDimensions(m_logo.width(), m_logo.height());
m_screenWidget->unsetCursor(); centralWidget()->unsetCursor();
} }
WindowBackground::WindowBackground(QWidget* parent) WindowBackground::WindowBackground(QWidget* parent)

View File

@ -195,6 +195,7 @@ private:
std::unique_ptr<AudioProcessor> m_audioProcessor; std::unique_ptr<AudioProcessor> m_audioProcessor;
std::unique_ptr<QGBA::Display> m_display; std::unique_ptr<QGBA::Display> m_display;
QSize m_initialSize;
int m_savedScale; int m_savedScale;
// TODO: Move these to a new class // TODO: Move these to a new class

View File

@ -180,7 +180,7 @@ Tamaño de la descarga: %3</translation>
<message> <message>
<location filename="../AudioDevice.cpp" line="62"/> <location filename="../AudioDevice.cpp" line="62"/>
<source>Writing data to read-only audio device</source> <source>Writing data to read-only audio device</source>
<translation type="unfinished"></translation> <translation>Escribiendo datos a dispositivo de audio de sólo lectura</translation>
</message> </message>
</context> </context>
<context> <context>
@ -188,7 +188,7 @@ Tamaño de la descarga: %3</translation>
<message> <message>
<location filename="../AudioProcessorQt.cpp" line="43"/> <location filename="../AudioProcessorQt.cpp" line="43"/>
<source>Can&apos;t start an audio processor without input</source> <source>Can&apos;t start an audio processor without input</source>
<translation type="unfinished"></translation> <translation>Sin entrada no se puede iniciar un procesador de audio</translation>
</message> </message>
</context> </context>
<context> <context>
@ -196,7 +196,7 @@ Tamaño de la descarga: %3</translation>
<message> <message>
<location filename="../AudioProcessorSDL.cpp" line="34"/> <location filename="../AudioProcessorSDL.cpp" line="34"/>
<source>Can&apos;t start an audio processor without input</source> <source>Can&apos;t start an audio processor without input</source>
<translation type="unfinished"></translation> <translation>Sin entrada no se puede iniciar un procesador de audio</translation>
</message> </message>
</context> </context>
<context> <context>
@ -264,12 +264,12 @@ Tamaño de la descarga: %3</translation>
<message> <message>
<location filename="../BattleChipView.cpp" line="117"/> <location filename="../BattleChipView.cpp" line="117"/>
<source>BattleChip data missing</source> <source>BattleChip data missing</source>
<translation type="unfinished"></translation> <translation type="unfinished">Faltan los datos de BattleChip</translation>
</message> </message>
<message> <message>
<location filename="../BattleChipView.cpp" line="118"/> <location filename="../BattleChipView.cpp" line="118"/>
<source>BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now?</source> <source>BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now?</source>
<translation type="unfinished"></translation> <translation>Faltan los datos de BattleChip. BattleChip Gates seguirán funcionando, pero faltarán algunos gráficos. ¿Quiere descargar los datos ahora?</translation>
</message> </message>
<message> <message>
<location filename="../BattleChipView.cpp" line="184"/> <location filename="../BattleChipView.cpp" line="184"/>
@ -358,7 +358,7 @@ Tamaño de la descarga: %3</translation>
<message> <message>
<location filename="../CheatsView.cpp" line="187"/> <location filename="../CheatsView.cpp" line="187"/>
<source>Some cheats could not be added. Please ensure they&apos;re formatted correctly and/or try other cheat types.</source> <source>Some cheats could not be added. Please ensure they&apos;re formatted correctly and/or try other cheat types.</source>
<translation type="unfinished"></translation> <translation type="unfinished">Algunos trucos no se pudieron añadir. Asegúrese de que están formateados correctamente y/o pruebe otros tipos de trucos.</translation>
</message> </message>
</context> </context>
<context> <context>
@ -793,7 +793,7 @@ Tamaño de la descarga: %3</translation>
<message> <message>
<location filename="../GameBoy.cpp" line="75"/> <location filename="../GameBoy.cpp" line="75"/>
<source>ROM Only</source> <source>ROM Only</source>
<translation type="unfinished"></translation> <translation type="unfinished">Sólo ROM</translation>
</message> </message>
<message> <message>
<location filename="../GameBoy.cpp" line="76"/> <location filename="../GameBoy.cpp" line="76"/>

View File

@ -758,37 +758,37 @@ Dimensione del download: %3</translation>
<message> <message>
<location filename="../GameBoy.cpp" line="56"/> <location filename="../GameBoy.cpp" line="56"/>
<source>Game Boy (DMG)</source> <source>Game Boy (DMG)</source>
<translation type="unfinished"></translation> <translation>Game Boy (DMG)</translation>
</message> </message>
<message> <message>
<location filename="../GameBoy.cpp" line="57"/> <location filename="../GameBoy.cpp" line="57"/>
<source>Game Boy Pocket (MGB)</source> <source>Game Boy Pocket (MGB)</source>
<translation type="unfinished"></translation> <translation>Game Boy Pocket (MGB)</translation>
</message> </message>
<message> <message>
<location filename="../GameBoy.cpp" line="58"/> <location filename="../GameBoy.cpp" line="58"/>
<source>Super Game Boy (SGB)</source> <source>Super Game Boy (SGB)</source>
<translation type="unfinished"></translation> <translation>Super Game Boy (SGB)</translation>
</message> </message>
<message> <message>
<location filename="../GameBoy.cpp" line="59"/> <location filename="../GameBoy.cpp" line="59"/>
<source>Super Game Boy 2 (SGB)</source> <source>Super Game Boy 2 (SGB)</source>
<translation type="unfinished"></translation> <translation>Super Game Boy 2 (SGB)</translation>
</message> </message>
<message> <message>
<location filename="../GameBoy.cpp" line="60"/> <location filename="../GameBoy.cpp" line="60"/>
<source>Game Boy Color (CGB)</source> <source>Game Boy Color (CGB)</source>
<translation type="unfinished"></translation> <translation>Game Boy Color (CGB)</translation>
</message> </message>
<message> <message>
<location filename="../GameBoy.cpp" line="61"/> <location filename="../GameBoy.cpp" line="61"/>
<source>Game Boy Advance (AGB)</source> <source>Game Boy Advance (AGB)</source>
<translation type="unfinished"></translation> <translation>Game Boy Advance (AGB)</translation>
</message> </message>
<message> <message>
<location filename="../GameBoy.cpp" line="62"/> <location filename="../GameBoy.cpp" line="62"/>
<source>Super Game Boy Color (SGB + CGB)</source> <source>Super Game Boy Color (SGB + CGB)</source>
<translation type="unfinished"></translation> <translation>Super Game Boy Color (SGB + CGB)</translation>
</message> </message>
<message> <message>
<location filename="../GameBoy.cpp" line="75"/> <location filename="../GameBoy.cpp" line="75"/>
@ -4788,7 +4788,7 @@ Dimensione del download: %3</translation>
<message> <message>
<location filename="../SettingsView.ui" line="555"/> <location filename="../SettingsView.ui" line="555"/>
<source>Load last state</source> <source>Load last state</source>
<translation type="unfinished"></translation> <translation>Carica l&apos;ultimo stato</translation>
</message> </message>
<message> <message>
<location filename="../SettingsView.ui" line="565"/> <location filename="../SettingsView.ui" line="565"/>
@ -4798,7 +4798,7 @@ Dimensione del download: %3</translation>
<message> <message>
<location filename="../SettingsView.ui" line="592"/> <location filename="../SettingsView.ui" line="592"/>
<source>Save entered cheats</source> <source>Save entered cheats</source>
<translation type="unfinished"></translation> <translation>Salva i trucchi inseriti</translation>
</message> </message>
<message> <message>
<location filename="../SettingsView.ui" line="813"/> <location filename="../SettingsView.ui" line="813"/>
@ -4979,7 +4979,7 @@ Dimensione del download: %3</translation>
<message> <message>
<location filename="../SettingsView.ui" line="582"/> <location filename="../SettingsView.ui" line="582"/>
<source>Periodically autosave state</source> <source>Periodically autosave state</source>
<translation type="unfinished"></translation> <translation>Salva periodicamente in automatico lo stato</translation>
</message> </message>
<message> <message>
<location filename="../SettingsView.ui" line="865"/> <location filename="../SettingsView.ui" line="865"/>

File diff suppressed because it is too large Load Diff

View File

@ -4008,12 +4008,12 @@ Download size: %3</source>
<message> <message>
<location filename="../PrinterView.cpp" line="59"/> <location filename="../PrinterView.cpp" line="59"/>
<source>Save Printout</source> <source>Save Printout</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../PrinterView.cpp" line="59"/> <location filename="../PrinterView.cpp" line="59"/>
<source>Portable Network Graphics (*.png)</source> <source>Portable Network Graphics (*.png)</source>
<translation type="unfinished">便 (*.png)</translation> <translation>便 (*.png)</translation>
</message> </message>
</context> </context>
<context> <context>
@ -4337,17 +4337,17 @@ Download size: %3</source>
<message> <message>
<location filename="../scripting/ScriptingView.cpp" line="60"/> <location filename="../scripting/ScriptingView.cpp" line="60"/>
<source>Select script to load</source> <source>Select script to load</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../scripting/ScriptingView.cpp" line="85"/> <location filename="../scripting/ScriptingView.cpp" line="85"/>
<source>Lua scripts (*.lua)</source> <source>Lua scripts (*.lua)</source>
<translation type="unfinished">Lua (*.lua)</translation> <translation>Lua (*.lua)</translation>
</message> </message>
<message> <message>
<location filename="../scripting/ScriptingView.cpp" line="87"/> <location filename="../scripting/ScriptingView.cpp" line="87"/>
<source>All files (*.*)</source> <source>All files (*.*)</source>
<translation type="unfinished"> (*.*)</translation> <translation> (*.*)</translation>
</message> </message>
</context> </context>
<context> <context>
@ -4796,22 +4796,22 @@ Download size: %3</source>
<message> <message>
<location filename="../SettingsView.ui" line="548"/> <location filename="../SettingsView.ui" line="548"/>
<source>On loading a game:</source> <source>On loading a game:</source>
<translation type="unfinished"></translation> <translation>:</translation>
</message> </message>
<message> <message>
<location filename="../SettingsView.ui" line="555"/> <location filename="../SettingsView.ui" line="555"/>
<source>Load last state</source> <source>Load last state</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../SettingsView.ui" line="565"/> <location filename="../SettingsView.ui" line="565"/>
<source>Load cheats</source> <source>Load cheats</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../SettingsView.ui" line="592"/> <location filename="../SettingsView.ui" line="592"/>
<source>Save entered cheats</source> <source>Save entered cheats</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../SettingsView.ui" line="813"/> <location filename="../SettingsView.ui" line="813"/>
@ -5641,12 +5641,12 @@ Download size: %3</source>
<message> <message>
<location filename="../VideoView.ui" line="277"/> <location filename="../VideoView.ui" line="277"/>
<source>H.264</source> <source>H.264</source>
<translation type="unfinished">H.264</translation> <translation>H.264</translation>
</message> </message>
<message> <message>
<location filename="../VideoView.ui" line="282"/> <location filename="../VideoView.ui" line="282"/>
<source>H.264 (NVENC)</source> <source>H.264 (NVENC)</source>
<translation type="unfinished">H.264 (NVENC)</translation> <translation>H.264 (NVENC)</translation>
</message> </message>
<message> <message>
<location filename="../VideoView.ui" line="455"/> <location filename="../VideoView.ui" line="455"/>
@ -5656,7 +5656,7 @@ Download size: %3</source>
<message> <message>
<location filename="../VideoView.ui" line="468"/> <location filename="../VideoView.ui" line="468"/>
<source>CRF</source> <source>CRF</source>
<translation type="unfinished">CRF</translation> <translation>CRF</translation>
</message> </message>
<message> <message>
<location filename="../VideoView.ui" line="484"/> <location filename="../VideoView.ui" line="484"/>
@ -6338,7 +6338,7 @@ Download size: %3</source>
<message> <message>
<location filename="../Window.cpp" line="1665"/> <location filename="../Window.cpp" line="1665"/>
<source>Game state views</source> <source>Game state views</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Window.cpp" line="1666"/> <location filename="../Window.cpp" line="1666"/>
@ -6363,7 +6363,7 @@ Download size: %3</source>
<message> <message>
<location filename="../Window.cpp" line="1671"/> <location filename="../Window.cpp" line="1671"/>
<source>&amp;Frame inspector...</source> <source>&amp;Frame inspector...</source>
<translation>(&amp;F)...</translation> <translation>(&amp;F)...</translation>
</message> </message>
<message> <message>
<location filename="../Window.cpp" line="1687"/> <location filename="../Window.cpp" line="1687"/>

View File

@ -52,7 +52,7 @@ static bool _checkWatchpoints(struct SM83Debugger* debugger, uint16_t address, s
int32_t value; int32_t value;
int segment; int segment;
if (!mDebuggerEvaluateParseTree(debugger->d.p, watchpoint->condition, &value, &segment) || !(value || segment >= 0)) { if (!mDebuggerEvaluateParseTree(debugger->d.p, watchpoint->condition, &value, &segment) || !(value || segment >= 0)) {
return false; continue;
} }
} }
uint8_t oldValue = debugger->originalMemory.load8(debugger->cpu, address); uint8_t oldValue = debugger->originalMemory.load8(debugger->cpu, address);