diff --git a/.travis-deps.sh b/.travis-deps.sh
index 02e336f75..cf70b5010 100755
--- a/.travis-deps.sh
+++ b/.travis-deps.sh
@@ -1,5 +1,9 @@
#!/bin/sh
+set -e
if [ $TRAVIS_OS_NAME = "osx" ]; then
brew update
brew install qt5 ffmpeg imagemagick sdl2 libedit libelf libpng libzip
+else
+ sudo apt-get update
+ sudo apt-get -y install libseccomp2
fi
diff --git a/.travis.yml b/.travis.yml
index 9bec872a2..f411d0fe6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -24,7 +24,7 @@ matrix:
before_install:
- '[ -z "$DOCKER_TAG" ] || docker pull mgba/$DOCKER_TAG'
-- '[ "$TRAVIS_OS_NAME" != "osx" ] || . ./.travis-deps.sh'
+- '. ./.travis-deps.sh'
- 'mkdir build && chmod 777 build'
script:
diff --git a/CHANGES b/CHANGES
index 961b508e4..5ffcfb0c1 100644
--- a/CHANGES
+++ b/CHANGES
@@ -54,6 +54,8 @@ Emulation fixes:
- GB Memory: Better emulate 0xFEA0 region on DMG, MGB and AGB
- GB Video: Fix mode 0 window edge case (fixes mgba.io/i/1519)
- GB Audio: Fix channel 4 volume (fixes mgba.io/i/1529)
+ - GB Video: Fix color scaling in AGB mode
+ - GB: Fix using boot ROM with MMM01 games
Other fixes:
- Qt: Fix some Qt display driver race conditions
- Core: Improved lockstep driver reliability (Le Hoang Quyen)
@@ -64,6 +66,9 @@ Other fixes:
- Qt: Only show emulator restart warning once per settings saving
- FFmpeg: Drain recording buffers
- Shaders: Fix gba-color shader resolution (fixes mgba.io/i/1435)
+ - Qt: Fix LibraryController initialization (fixes mgba.io/i/1324)
+ - Switch: Fix audio when video rate desyncs (fixes mgba.io/i/1532)
+ - GB: Fix reading ROM immediately after unmapping BIOS
Misc:
- GBA Savedata: EEPROM performance fixes
- GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash
@@ -94,6 +99,12 @@ Misc:
- OpenGL: Only resize textures when needed
- GBA BIOS: Fix clobbered registers in CpuSet (fixes mgba.io/i/1531)
- Qt: Remove What's This icon from dialogs
+ - CMake: Don't use libzip on embedded platforms (fixes mgba.io/i/1527)
+ - Qt: Printer quality of life improvements (fixes mgba.io/i/1540)
+ - Qt: Add copy and QoL improvements to graphic views (closes mgba.io/i/1541)
+ - Qt: Show list of all sprites in sprite view
+ - Qt: Add option for disabling OSD messages
+ - Core: Add more memory search ops (closes mgba.io/i/1510)
0.7.3: (2019-09-15)
Emulation fixes:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ad44f44e1..a2206d926 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -250,6 +250,7 @@ if(DEFINED 3DS OR DEFINED PSP2 OR DEFINED WII OR DEFINED SWITCH)
set(USE_DEBUGGERS OFF)
set(USE_SQLITE3 OFF)
set(USE_DISCORD_RPC OFF)
+ set(USE_LIBZIP OFF CACHE BOOL "")
endif()
if(DEFINED 3DS)
diff --git a/README.md b/README.md
index 370ccb70e..e84fd937e 100644
--- a/README.md
+++ b/README.md
@@ -93,7 +93,7 @@ Other Unix-like platforms, such as OpenBSD, are known to work as well, but are u
### System requirements
-Requirements are minimal[[2]](#dscaveat). Any computer that can run Windows Vista or newer should be able to handle emulation. Support for OpenGL 1.1 or newer is also required, with OpenGL 3.0 or newer for shaders and advanced features.
+Requirements are minimal[[2]](#dscaveat). Any computer that can run Windows Vista or newer should be able to handle emulation. Support for OpenGL 1.1 or newer is also required, with OpenGL 3.2 or newer for shaders and advanced features.
Downloads
---------
diff --git a/README_DE.md b/README_DE.md
index d0e0ab18c..cd834f0e4 100644
--- a/README_DE.md
+++ b/README_DE.md
@@ -86,7 +86,7 @@ Andere Unix-ähnliche Plattformen wie OpenBSD sind ebenfalls dafür bekannt, mit
### Systemvoraussetzungen
-Die Systemvoraussetzungen sind minimal. Jeder Computer, der mit Windows Vista oder neuer läuft, sollte in der Lage sein, die Emulation zu bewältigen. Unterstützung für OpenGL 1.1 oder neuer ist ebenfalls voraussgesetzt. OpenGL 3.0 oder neuer wird für Shader und erweiterte Funktionen benötigt.
+Die Systemvoraussetzungen sind minimal. Jeder Computer, der mit Windows Vista oder neuer läuft, sollte in der Lage sein, die Emulation zu bewältigen. Unterstützung für OpenGL 1.1 oder neuer ist ebenfalls voraussgesetzt. OpenGL 3.2 oder neuer wird für Shader und erweiterte Funktionen benötigt.
Downloads
---------
@@ -145,7 +145,7 @@ Damit wird mGBA gebaut und in `/usr/bin` und `/usr/lib` installiert. Installiert
Wenn Du macOS verwendest, sind die einzelnen Schritte etwas anders. Angenommen, dass Du den Homebrew-Paketmanager verwendest, werden folgende Schritte zum installieren der Abhängigkeiten und anschließenden bauen von mGBA empfohlen:
- brew install cmake ffmpeg imagemagick libzip qt5 sdl2 libedit pkg-config
+ brew install cmake ffmpeg libzip qt5 sdl2 libedit pkg-config
mkdir build
cd build
cmake -DCMAKE_PREFIX_PATH='brew --prefix qt5' ..
@@ -159,11 +159,11 @@ Um mGBA auf Windows zu kompilieren, wird MSYS2 empfohlen. Befolge die Installati
Für x86 (32 Bit):
- pacman -Sy --needed base-devel git mingw-w64-i686-{cmake,ffmpeg,gcc,gdb,imagemagick,libelf,libepoxy,libzip,pkg-config,qt5,SDL2,ntldd-git}
+ pacman -Sy --needed base-devel git mingw-w64-i686-{cmake,ffmpeg,gcc,gdb,libelf,libepoxy,libzip,pkg-config,qt5,SDL2,ntldd-git}
Für x86_64 (64 Bit):
- pacman -Sy --needed base-devel git mingw-w64-x86_64-{cmake,ffmpeg,gcc,gdb,imagemagick,libelf,libepoxy,libzip,pkg-config,qt5,SDL2,ntldd-git}
+ pacman -Sy --needed base-devel git mingw-w64-x86_64-{cmake,ffmpeg,gcc,gdb,libelf,libepoxy,libzip,pkg-config,qt5,SDL2,ntldd-git}
Lade den aktuellen mGBA-Quellcode mithilfe des folgenden Kommandos herunter:
diff --git a/cinema/gb/mooneye-gb/misc/boot_regs-A/baseline_0000.png b/cinema/gb/mooneye-gb/misc/boot_regs-A/baseline_0000.png
index e8fd37e04..96dc85bdd 100644
Binary files a/cinema/gb/mooneye-gb/misc/boot_regs-A/baseline_0000.png and b/cinema/gb/mooneye-gb/misc/boot_regs-A/baseline_0000.png differ
diff --git a/cinema/gb/window/wmm-hud/baseline_0000.png b/cinema/gb/window/wmm-hud/baseline_0000.png
index 73af7e9c5..bf01a3469 100644
Binary files a/cinema/gb/window/wmm-hud/baseline_0000.png and b/cinema/gb/window/wmm-hud/baseline_0000.png differ
diff --git a/include/mgba/core/mem-search.h b/include/mgba/core/mem-search.h
index c18c20922..d45601556 100644
--- a/include/mgba/core/mem-search.h
+++ b/include/mgba/core/mem-search.h
@@ -22,7 +22,11 @@ enum mCoreMemorySearchOp {
mCORE_MEMORY_SEARCH_EQUAL,
mCORE_MEMORY_SEARCH_GREATER,
mCORE_MEMORY_SEARCH_LESS,
+ mCORE_MEMORY_SEARCH_ANY,
mCORE_MEMORY_SEARCH_DELTA,
+ mCORE_MEMORY_SEARCH_DELTA_POSITIVE,
+ mCORE_MEMORY_SEARCH_DELTA_NEGATIVE,
+ mCORE_MEMORY_SEARCH_DELTA_ANY,
};
struct mCoreMemorySearchParams {
diff --git a/res/patrons.txt b/res/patrons.txt
index 306534b40..b203109e2 100644
--- a/res/patrons.txt
+++ b/res/patrons.txt
@@ -1,8 +1,9 @@
Jaime J. Denizard
-Fog
-Philip Horton
+Benedikt Feih
Oskenso Kashi
+The Libretro Team
Mored1984
-Rohit Nirmal
Rhys Powell
+Johnathan Roatch
Yuri Kunde Schlesner
+Voidheim
diff --git a/src/core/mem-search.c b/src/core/mem-search.c
index c6404638f..7f0c215a1 100644
--- a/src/core/mem-search.c
+++ b/src/core/mem-search.c
@@ -19,6 +19,14 @@ static bool _op(int32_t value, int32_t match, enum mCoreMemorySearchOp op) {
case mCORE_MEMORY_SEARCH_EQUAL:
case mCORE_MEMORY_SEARCH_DELTA:
return value == match;
+ case mCORE_MEMORY_SEARCH_DELTA_POSITIVE:
+ return value > 0;
+ case mCORE_MEMORY_SEARCH_DELTA_NEGATIVE:
+ return value < 0;
+ case mCORE_MEMORY_SEARCH_DELTA_ANY:
+ return value != 0;
+ case mCORE_MEMORY_SEARCH_ANY:
+ return true;
}
return false;
}
@@ -244,20 +252,20 @@ bool _testGuess(struct mCore* core, struct mCoreMemorySearchResult* res, const s
int64_t value;
int32_t offset = 0;
char* end;
- if (params->op == mCORE_MEMORY_SEARCH_DELTA) {
+ if (params->op >= mCORE_MEMORY_SEARCH_DELTA) {
offset = res->oldValue;
}
value = strtoll(params->valueStr, &end, 10);
if (end) {
res->oldValue += value;
- if (_op(core->rawRead8(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier, value + offset, params->op)) {
+ if (_op(core->rawRead8(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier - offset, value, params->op)) {
return true;
}
- if (!(res->address & 1) && (res->width >= 2 || res->width == -1) && _op(core->rawRead16(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier, value + offset, params->op)) {
+ if (!(res->address & 1) && (res->width >= 2 || res->width == -1) && _op(core->rawRead16(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier - offset, value, params->op)) {
return true;
}
- if (!(res->address & 3) && (res->width >= 4 || res->width == -1) && _op(core->rawRead32(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier, value + offset, params->op)) {
+ if (!(res->address & 3) && (res->width >= 4 || res->width == -1) && _op(core->rawRead32(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier - offset, value, params->op)) {
return true;
}
res->oldValue -= value;
@@ -266,13 +274,13 @@ bool _testGuess(struct mCore* core, struct mCoreMemorySearchResult* res, const s
value = strtoll(params->valueStr, &end, 16);
if (end) {
res->oldValue += value;
- if (_op(core->rawRead8(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier, value + offset, params->op)) {
+ if (_op(core->rawRead8(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier - offset, value, params->op)) {
return true;
}
- if (!(res->address & 1) && (res->width >= 2 || res->width == -1) && _op(core->rawRead16(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier, value + offset, params->op)) {
+ if (!(res->address & 1) && (res->width >= 2 || res->width == -1) && _op(core->rawRead16(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier - offset, value, params->op)) {
return true;
}
- if (!(res->address & 3) && (res->width >= 4 || res->width == -1) && _op(core->rawRead32(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier, value + offset, params->op)) {
+ if (!(res->address & 3) && (res->width >= 4 || res->width == -1) && _op(core->rawRead32(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier - offset, value, params->op)) {
return true;
}
res->oldValue -= value;
@@ -293,10 +301,7 @@ void mCoreMemorySearchRepeat(struct mCore* core, const struct mCoreMemorySearchP
--i;
}
} else if (params->type == mCORE_MEMORY_SEARCH_INT) {
- int32_t oldValue = params->valueInt;
- if (params->op == mCORE_MEMORY_SEARCH_DELTA) {
- oldValue += res->oldValue;
- }
+ int32_t match = params->valueInt;
int32_t value = 0;
switch (params->width) {
case 1:
@@ -311,7 +316,11 @@ void mCoreMemorySearchRepeat(struct mCore* core, const struct mCoreMemorySearchP
default:
break;
}
- if (!_op(value, oldValue, params->op)) {
+ int32_t opValue = value;
+ if (params->op >= mCORE_MEMORY_SEARCH_DELTA) {
+ opValue -= res->oldValue;
+ }
+ if (!_op(opValue, match, params->op)) {
*res = *mCoreMemorySearchResultsGetPointer(inout, mCoreMemorySearchResultsSize(inout) - 1);
mCoreMemorySearchResultsResize(inout, -1);
--i;
@@ -322,7 +331,7 @@ void mCoreMemorySearchRepeat(struct mCore* core, const struct mCoreMemorySearchP
break;
case mCORE_MEMORY_SEARCH_STRING:
case mCORE_MEMORY_SEARCH_GUESS:
- // TOOD
+ // TODO
break;
}
}
diff --git a/src/gb/gb.c b/src/gb/gb.c
index 0e065a0a2..1357e713a 100644
--- a/src/gb/gb.c
+++ b/src/gb/gb.c
@@ -415,23 +415,6 @@ void GBReset(struct LR35902Core* cpu) {
gb->memory.romBase = gb->memory.rom;
GBDetectModel(gb);
- if (gb->biosVf) {
- if (!GBIsBIOS(gb->biosVf)) {
- gb->biosVf->close(gb->biosVf);
- gb->biosVf = NULL;
- } else {
- GBMapBIOS(gb);
- cpu->a = 0;
- cpu->f.packed = 0;
- cpu->c = 0;
- cpu->e = 0;
- cpu->h = 0;
- cpu->l = 0;
- cpu->sp = 0;
- cpu->pc = 0;
- }
- }
-
cpu->b = 0;
cpu->d = 0;
@@ -457,6 +440,24 @@ void GBReset(struct LR35902Core* cpu) {
mTimingClear(&gb->timing);
GBMemoryReset(gb);
+
+ if (gb->biosVf) {
+ if (!GBIsBIOS(gb->biosVf)) {
+ gb->biosVf->close(gb->biosVf);
+ gb->biosVf = NULL;
+ } else {
+ GBMapBIOS(gb);
+ cpu->a = 0;
+ cpu->f.packed = 0;
+ cpu->c = 0;
+ cpu->e = 0;
+ cpu->h = 0;
+ cpu->l = 0;
+ cpu->sp = 0;
+ cpu->pc = 0;
+ }
+ }
+
GBVideoReset(&gb->video);
GBTimerReset(&gb->timer);
if (!gb->biosVf) {
@@ -561,18 +562,23 @@ void GBSkipBIOS(struct GB* gb) {
void GBMapBIOS(struct GB* gb) {
gb->biosVf->seek(gb->biosVf, 0, SEEK_SET);
+ uint8_t* oldRomBase = gb->memory.romBase;
gb->memory.romBase = malloc(GB_SIZE_CART_BANK0);
ssize_t size = gb->biosVf->read(gb->biosVf, gb->memory.romBase, GB_SIZE_CART_BANK0);
- memcpy(&gb->memory.romBase[size], &gb->memory.rom[size], GB_SIZE_CART_BANK0 - size);
+ memcpy(&gb->memory.romBase[size], &oldRomBase[size], GB_SIZE_CART_BANK0 - size);
if (size > 0x100) {
- memcpy(&gb->memory.romBase[0x100], &gb->memory.rom[0x100], sizeof(struct GBCartridge));
+ memcpy(&gb->memory.romBase[0x100], &oldRomBase[0x100], sizeof(struct GBCartridge));
}
}
void GBUnmapBIOS(struct GB* gb) {
if (gb->memory.romBase < gb->memory.rom || gb->memory.romBase > &gb->memory.rom[gb->memory.romSize - 1]) {
free(gb->memory.romBase);
- gb->memory.romBase = gb->memory.rom;
+ if (gb->memory.mbcType == GB_MMM01) {
+ GBMBCSwitchBank0(gb, gb->memory.romSize / GB_SIZE_CART_BANK0 - 2);
+ } else {
+ GBMBCSwitchBank0(gb, 0);
+ }
}
// XXX: Force AGB registers for AGB-mode
if (gb->model == GB_MODEL_AGB && gb->cpu->pc == 0x100) {
diff --git a/src/gb/renderers/software.c b/src/gb/renderers/software.c
index c0e5c2367..661a4363f 100644
--- a/src/gb/renderers/software.c
+++ b/src/gb/renderers/software.c
@@ -461,8 +461,11 @@ static void GBVideoSoftwareRendererWritePalette(struct GBVideoRenderer* renderer
color = mColorFrom555(r | (g << 5) | (b << 10));
#else
r >>= 2;
+ r += r >> 4;
g >>= 2;
+ g += g >> 4;
b >>= 2;
+ b += b >> 4;
color = r | (g << 8) | (b << 16);
#endif
}
diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c
index 510a37c89..844164829 100644
--- a/src/gba/renderers/gl.c
+++ b/src/gba/renderers/gl.c
@@ -64,7 +64,7 @@ static const GLchar* const _gles3Header =
"precision highp isampler2D;\n";
static const GLchar* const _gl3Header =
- "#version 130\n"
+ "#version 150 core\n"
"#define OUT(n)\n"
PALETTE_ENTRY
"precision highp float;\n";
diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c
index f87f1edae..56ed625ae 100644
--- a/src/gba/renderers/video-software.c
+++ b/src/gba/renderers/video-software.c
@@ -141,6 +141,8 @@ static void GBAVideoSoftwareRendererReset(struct GBAVideoRenderer* renderer) {
memset(softwareRenderer->cache, 0, sizeof(softwareRenderer->cache));
memset(softwareRenderer->nextIo, 0, sizeof(softwareRenderer->nextIo));
+ softwareRenderer->lastHighlightAmount = 0;
+
for (i = 0; i < 4; ++i) {
struct GBAVideoSoftwareBackground* bg = &softwareRenderer->bg[i];
bg->index = i;
diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c
index 09848b476..33dcad053 100644
--- a/src/platform/opengl/gles2.c
+++ b/src/platform/opengl/gles2.c
@@ -21,8 +21,17 @@ static const GLchar* const _gles2Header =
"#version 100\n"
"precision mediump float;\n";
-static const GLchar* const _gl3Header =
- "#version 120\n";
+static const GLchar* const _gl32VHeader =
+ "#version 150 core\n"
+ "#define attribute in\n"
+ "#define varying out\n";
+
+static const GLchar* const _gl32FHeader =
+ "#version 150 core\n"
+ "#define varying in\n"
+ "#define texture2D texture\n"
+ "out vec4 compat_FragColor;\n"
+ "#define gl_FragColor compat_FragColor\n";
static const char* const _vertexShader =
"attribute vec4 position;\n"
@@ -449,7 +458,7 @@ void mGLES2ShaderInit(struct mGLES2Shader* shader, const char* vs, const char* f
const GLchar* shaderBuffer[2];
const GLubyte* version = glGetString(GL_VERSION);
if (strncmp((const char*) version, "OpenGL ES ", strlen("OpenGL ES "))) {
- shaderBuffer[0] = _gl3Header;
+ shaderBuffer[0] = _gl32VHeader;
} else {
shaderBuffer[0] = _gles2Header;
}
@@ -460,6 +469,9 @@ void mGLES2ShaderInit(struct mGLES2Shader* shader, const char* vs, const char* f
}
glShaderSource(shader->vertexShader, 2, shaderBuffer, 0);
+ if (strncmp((const char*) version, "OpenGL ES ", strlen("OpenGL ES "))) {
+ shaderBuffer[0] = _gl32FHeader;
+ }
if (fs) {
shaderBuffer[1] = fs;
} else {
diff --git a/src/platform/qt/AssetTile.cpp b/src/platform/qt/AssetTile.cpp
index 0f87f7654..23ff4ff56 100644
--- a/src/platform/qt/AssetTile.cpp
+++ b/src/platform/qt/AssetTile.cpp
@@ -116,6 +116,9 @@ void AssetTile::selectIndex(int index) {
m_ui.preview->setColor(i ^ flip, data[i]);
}
m_ui.preview->update();
+
+ QImage tile(reinterpret_cast(data), 8, 8, QImage::Format_ARGB32);
+ m_activeTile = tile.rgbSwapped();
}
void AssetTile::setFlip(bool h, bool v) {
diff --git a/src/platform/qt/AssetTile.h b/src/platform/qt/AssetTile.h
index 676582387..d90572018 100644
--- a/src/platform/qt/AssetTile.h
+++ b/src/platform/qt/AssetTile.h
@@ -21,6 +21,7 @@ Q_OBJECT
public:
AssetTile(QWidget* parent = nullptr);
void setController(std::shared_ptr);
+ QImage activeTile() const { return m_activeTile; }
public slots:
void setPalette(int);
@@ -48,6 +49,7 @@ private:
bool m_flipV = false;
QMap m_customProperties;
+ QImage m_activeTile;
};
}
diff --git a/src/platform/qt/Display.cpp b/src/platform/qt/Display.cpp
index f92e0ae62..809d9c5ce 100644
--- a/src/platform/qt/Display.cpp
+++ b/src/platform/qt/Display.cpp
@@ -26,7 +26,8 @@ Display* Display::create(QWidget* parent) {
switch (s_driver) {
#if defined(BUILD_GL) || defined(BUILD_GLES2) || defined(USE_EPOXY)
case Driver::OPENGL:
- format.setVersion(3, 0);
+ format.setVersion(3, 2);
+ format.setProfile(QSurfaceFormat::CoreProfile);
return new DisplayGL(format, parent);
#endif
#ifdef BUILD_GL
@@ -91,6 +92,10 @@ void Display::interframeBlending(bool lock) {
m_interframeBlending = lock;
}
+void Display::showOSDMessages(bool enable) {
+ m_showOSD = enable;
+}
+
void Display::filter(bool filter) {
m_filter = filter;
}
diff --git a/src/platform/qt/Display.h b/src/platform/qt/Display.h
index 5ff888e3c..c5792f0a4 100644
--- a/src/platform/qt/Display.h
+++ b/src/platform/qt/Display.h
@@ -44,6 +44,7 @@ public:
bool isIntegerScalingLocked() const { return m_lockIntegerScaling; }
bool hasInterframeBlending() const { return m_interframeBlending; }
bool isFiltered() const { return m_filter; }
+ bool isShowOSD() const { return m_showOSD; }
virtual void startDrawing(std::shared_ptr) = 0;
virtual bool isDrawing() const = 0;
@@ -68,6 +69,7 @@ public slots:
virtual void lockAspectRatio(bool lock);
virtual void lockIntegerScaling(bool lock);
virtual void interframeBlending(bool enable);
+ virtual void showOSDMessages(bool enable);
virtual void filter(bool filter);
virtual void framePosted() = 0;
virtual void setShaders(struct VDir*) = 0;
@@ -89,6 +91,7 @@ private:
static const int MOUSE_DISAPPEAR_TIMER = 1000;
MessagePainter m_messagePainter;
+ bool m_showOSD = true;
bool m_lockAspectRatio = false;
bool m_lockIntegerScaling = false;
bool m_interframeBlending = false;
diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp
index 25e0655ef..e20e4baaa 100644
--- a/src/platform/qt/DisplayGL.cpp
+++ b/src/platform/qt/DisplayGL.cpp
@@ -114,6 +114,7 @@ void DisplayGL::startDrawing(std::shared_ptr controller) {
lockAspectRatio(isAspectRatioLocked());
lockIntegerScaling(isIntegerScalingLocked());
interframeBlending(hasInterframeBlending());
+ showOSDMessages(isShowOSD());
filter(isFiltered());
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
messagePainter()->resize(size(), isAspectRatioLocked(), devicePixelRatioF());
@@ -187,6 +188,13 @@ void DisplayGL::interframeBlending(bool enable) {
}
}
+void DisplayGL::showOSDMessages(bool enable) {
+ Display::showOSDMessages(enable);
+ if (m_drawThread) {
+ QMetaObject::invokeMethod(m_painter, "showOSD", Q_ARG(bool, enable));
+ }
+}
+
void DisplayGL::filter(bool filter) {
Display::filter(filter);
if (m_drawThread) {
@@ -353,6 +361,7 @@ void PainterGL::setMessagePainter(MessagePainter* messagePainter) {
void PainterGL::resize(const QSize& size) {
m_size = size;
+ m_window->setSize(m_size);
if (m_started && !m_active) {
forceDraw();
}
@@ -372,6 +381,10 @@ void PainterGL::interframeBlending(bool enable) {
m_backend->interframeBlending = enable;
}
+void PainterGL::showOSD(bool enable) {
+ m_showOSD = enable;
+}
+
void PainterGL::filter(bool filter) {
m_backend->filter = filter;
if (m_started && !m_active) {
@@ -460,7 +473,7 @@ void PainterGL::performDraw() {
m_backend->resized(m_backend, m_size.width() * r, m_size.height() * r);
m_backend->drawFrame(m_backend);
m_painter.endNativePainting();
- if (m_messagePainter) {
+ if (m_showOSD && m_messagePainter) {
m_messagePainter->paint(&m_painter);
}
}
diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h
index ffe433f90..3eb5d8eeb 100644
--- a/src/platform/qt/DisplayGL.h
+++ b/src/platform/qt/DisplayGL.h
@@ -29,6 +29,8 @@
#include "platform/video-backend.h"
+class QOpenGLPaintDevice;
+
namespace QGBA {
class PainterGL;
@@ -54,6 +56,7 @@ public slots:
void lockAspectRatio(bool lock) override;
void lockIntegerScaling(bool lock) override;
void interframeBlending(bool enable) override;
+ void showOSDMessages(bool enable) override;
void filter(bool filter) override;
void framePosted() override;
void setShaders(struct VDir*) override;
@@ -100,6 +103,7 @@ public slots:
void lockAspectRatio(bool lock);
void lockIntegerScaling(bool lock);
void interframeBlending(bool enable);
+ void showOSD(bool enable);
void filter(bool filter);
void resizeContext();
@@ -119,12 +123,13 @@ private:
QPainter m_painter;
QMutex m_mutex;
QWindow* m_surface;
- QPaintDevice* m_window;
+ QOpenGLPaintDevice* m_window;
QOpenGLContext* m_gl;
bool m_active = false;
bool m_started = false;
std::shared_ptr m_context = nullptr;
bool m_supportsShaders;
+ bool m_showOSD;
VideoShader m_shader{};
VideoBackend* m_backend = nullptr;
QSize m_size;
diff --git a/src/platform/qt/DisplayQt.cpp b/src/platform/qt/DisplayQt.cpp
index dfa4b9385..983268b62 100644
--- a/src/platform/qt/DisplayQt.cpp
+++ b/src/platform/qt/DisplayQt.cpp
@@ -123,5 +123,7 @@ void DisplayQt::paintEvent(QPaintEvent*) {
}
painter.drawImage(full, m_backing, QRect(0, 0, m_width, m_height));
painter.setOpacity(1);
- messagePainter()->paint(&painter);
+ if (isShowOSD()) {
+ messagePainter()->paint(&painter);
+ }
}
diff --git a/src/platform/qt/MapView.cpp b/src/platform/qt/MapView.cpp
index 0fe80c2c3..f71baf0fe 100644
--- a/src/platform/qt/MapView.cpp
+++ b/src/platform/qt/MapView.cpp
@@ -22,7 +22,9 @@
#include
#endif
+#include
#include
+#include
#include
#include
#include
@@ -88,11 +90,19 @@ MapView::MapView(std::shared_ptr controller, QWidget* parent)
});
group->addButton(button);
}
-#ifdef USE_PNG
connect(m_ui.exportButton, &QAbstractButton::clicked, this, &MapView::exportMap);
-#else
- m_ui.exportButton->setVisible(false);
-#endif
+ connect(m_ui.copyButton, &QAbstractButton::clicked, this, &MapView::copyMap);
+
+ QAction* exportAction = new QAction(this);
+ exportAction->setShortcut(QKeySequence::Save);
+ connect(exportAction, &QAction::triggered, this, &MapView::exportMap);
+ addAction(exportAction);
+
+ QAction* copyAction = new QAction(this);
+ copyAction->setShortcut(QKeySequence::Copy);
+ connect(copyAction, &QAction::triggered, this, &MapView::copyMap);
+ addAction(copyAction);
+
m_ui.map->installEventFilter(this);
m_ui.tile->addCustomProperty("mapAddr", tr("Map Addr."));
m_ui.tile->addCustomProperty("flip", tr("Mirror"));
@@ -211,7 +221,7 @@ void MapView::updateTilesGBA(bool force) {
mBitmapCacheCleanRow(bitmapCache, m_bitmapStatus, j);
memcpy(static_cast(&bgBits[width * j * 4]), mBitmapCacheGetRow(bitmapCache, j), width * 4);
}
- m_rawMap = m_rawMap.rgbSwapped();
+ m_rawMap = m_rawMap.convertToFormat(QImage::Format_RGB32).rgbSwapped();
} else {
mMapCache* mapCache = mMapCacheSetGetPointer(&m_cacheSet->maps, m_map);
int tilesW = 1 << mMapCacheSystemInfoGetTilesWide(mapCache->sysConfig);
@@ -242,23 +252,18 @@ void MapView::updateTilesGB(bool force) {
}
#endif
-#ifdef USE_PNG
void MapView::exportMap() {
QString filename = GBAApp::app()->getSaveFileName(this, tr("Export map"),
tr("Portable Network Graphics (*.png)"));
- VFile* vf = VFileDevice::open(filename, O_WRONLY | O_CREAT | O_TRUNC);
- if (!vf) {
- LOG(QT, ERROR) << tr("Failed to open output PNG file: %1").arg(filename);
+ if (filename.isNull()) {
return;
}
CoreController::Interrupter interrupter(m_controller);
- png_structp png = PNGWriteOpen(vf);
- png_infop info = PNGWriteHeaderA(png, m_rawMap.width(), m_rawMap.height());
-
- QImage map = m_rawMap.rgbSwapped();
- PNGWritePixelsA(png, map.width(), map.height(), map.bytesPerLine() / 4, static_cast(map.constBits()));
- PNGWriteClose(png, info);
- vf->close(vf);
+ m_rawMap.save(filename, "PNG");
}
-#endif
+
+void MapView::copyMap() {
+ CoreController::Interrupter interrupter(m_controller);
+ GBAApp::app()->clipboard()->setImage(m_rawMap);
+}
\ No newline at end of file
diff --git a/src/platform/qt/MapView.h b/src/platform/qt/MapView.h
index 4b39dcd7a..89c09259b 100644
--- a/src/platform/qt/MapView.h
+++ b/src/platform/qt/MapView.h
@@ -21,10 +21,9 @@ Q_OBJECT
public:
MapView(std::shared_ptr controller, QWidget* parent = nullptr);
-#ifdef USE_PNG
public slots:
void exportMap();
-#endif
+ void copyMap();
private slots:
void selectMap(int);
diff --git a/src/platform/qt/MapView.ui b/src/platform/qt/MapView.ui
index d21cce841..2d733c934 100644
--- a/src/platform/qt/MapView.ui
+++ b/src/platform/qt/MapView.ui
@@ -13,38 +13,7 @@
Maps
-
- -
-
-
- -
-
-
-
-
-
-
-
- -
-
-
- Export
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 0
- 0
-
-
-
-
+
-
-
@@ -79,7 +48,7 @@
- -
+
-
true
@@ -133,21 +102,59 @@
+ -
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Export
+
+
+
+ -
+
+
+
+
+
+
+
+ -
+
+
+ Copy
+
+
+
-
- QGBA::AssetInfo
- QGroupBox
-
- 1
-
QGBA::AssetTile
QGroupBox
1
+
+ QGBA::AssetInfo
+ QGroupBox
+
+ 1
+
diff --git a/src/platform/qt/MemorySearch.cpp b/src/platform/qt/MemorySearch.cpp
index 4ff967da5..f3f82c9ed 100644
--- a/src/platform/qt/MemorySearch.cpp
+++ b/src/platform/qt/MemorySearch.cpp
@@ -35,19 +35,28 @@ MemorySearch::~MemorySearch() {
}
bool MemorySearch::createParams(mCoreMemorySearchParams* params) {
- params->memoryFlags = mCORE_MEMORY_RW;
+ params->memoryFlags = mCORE_MEMORY_WRITE;
+ if (m_ui.searchROM->isChecked()) {
+ params->memoryFlags |= mCORE_MEMORY_READ;
+ }
mCore* core = m_controller->thread()->core;
QByteArray string;
bool ok = false;
if (m_ui.typeNum->isChecked()) {
params->type = mCORE_MEMORY_SEARCH_INT;
- if (m_ui.opDelta->isChecked()) {
+ if (m_ui.opDelta->isChecked() || m_ui.opDelta0->isChecked()) {
params->op = mCORE_MEMORY_SEARCH_DELTA;
} else if (m_ui.opGreater->isChecked()) {
params->op = mCORE_MEMORY_SEARCH_GREATER;
} else if (m_ui.opLess->isChecked()) {
params->op = mCORE_MEMORY_SEARCH_LESS;
+ } else if (m_ui.opUnknown->isChecked()) {
+ params->op = mCORE_MEMORY_SEARCH_ANY;
+ } else if (m_ui.opDeltaPositive->isChecked()) {
+ params->op = mCORE_MEMORY_SEARCH_DELTA_POSITIVE;
+ } else if (m_ui.opDeltaNegative->isChecked()) {
+ params->op = mCORE_MEMORY_SEARCH_DELTA_NEGATIVE;
} else {
params->op = mCORE_MEMORY_SEARCH_EQUAL;
}
@@ -103,9 +112,15 @@ bool MemorySearch::createParams(mCoreMemorySearchParams* params) {
}
if (m_ui.numGuess->isChecked()) {
params->type = mCORE_MEMORY_SEARCH_GUESS;
- m_string = m_ui.value->text().toLocal8Bit();
+ if (m_ui.opDelta0->isChecked()) {
+ m_string = QString("0").toLocal8Bit();
+ } else {
+ m_string = m_ui.value->text().toLocal8Bit();
+ }
params->valueStr = m_string.constData();
ok = true;
+ } else if (m_ui.opDelta0->isChecked()) {
+ params->valueInt = 0;
}
}
if (m_ui.typeStr->isChecked()) {
@@ -140,6 +155,9 @@ void MemorySearch::searchWithin() {
mCore* core = m_controller->thread()->core;
if (createParams(¶ms)) {
+ if (m_ui.opUnknown->isChecked()) {
+ params.op = mCORE_MEMORY_SEARCH_DELTA_ANY;
+ }
mCoreMemorySearchRepeat(core, ¶ms, &m_results);
}
@@ -153,6 +171,9 @@ void MemorySearch::refresh() {
m_ui.results->clearContents();
m_ui.results->setRowCount(mCoreMemorySearchResultsSize(&m_results));
m_ui.opDelta->setEnabled(false);
+ m_ui.opDelta0->setEnabled(false);
+ m_ui.opDeltaPositive->setEnabled(false);
+ m_ui.opDeltaNegative->setEnabled(false);
for (size_t i = 0; i < mCoreMemorySearchResultsSize(&m_results); ++i) {
mCoreMemorySearchResult* result = mCoreMemorySearchResultsGetPointer(&m_results, i);
QTableWidgetItem* item = new QTableWidgetItem(QString("%1").arg(result->address, 8, 16, QChar('0')));
@@ -214,9 +235,18 @@ void MemorySearch::refresh() {
m_ui.results->setItem(i, 1, item);
m_ui.results->setItem(i, 2, type);
m_ui.opDelta->setEnabled(true);
+ m_ui.opDelta0->setEnabled(true);
+ m_ui.opDeltaPositive->setEnabled(true);
+ m_ui.opDeltaNegative->setEnabled(true);
}
if (m_ui.opDelta->isChecked() && !m_ui.opDelta->isEnabled()) {
m_ui.opEqual->setChecked(true);
+ } else if (m_ui.opDelta0->isChecked() && !m_ui.opDelta0->isEnabled()) {
+ m_ui.opEqual->setChecked(true);
+ } else if (m_ui.opDeltaPositive->isChecked() && !m_ui.opDeltaPositive->isEnabled()) {
+ m_ui.opEqual->setChecked(true);
+ } else if (m_ui.opDeltaNegative->isChecked() && !m_ui.opDeltaNegative->isEnabled()) {
+ m_ui.opEqual->setChecked(true);
}
m_ui.results->sortItems(0);
}
diff --git a/src/platform/qt/MemorySearch.ui b/src/platform/qt/MemorySearch.ui
index 4e8649e42..7811c14a3 100644
--- a/src/platform/qt/MemorySearch.ui
+++ b/src/platform/qt/MemorySearch.ui
@@ -6,14 +6,20 @@
0
0
- 540
- 491
+ 725
+ 813
+
+
+ 0
+ 0
+
+
540
- 241
+ 400
@@ -99,21 +105,21 @@
- -
+
-
Qt::Horizontal
- -
+
-
Width
- -
+
-
Guess
@@ -126,7 +132,7 @@
- -
+
-
1 Byte (8-bit)
@@ -136,7 +142,7 @@
- -
+
-
2 Bytes (16-bit)
@@ -146,7 +152,7 @@
- -
+
-
4 Bytes (32-bit)
@@ -159,21 +165,21 @@
- -
+
-
Qt::Horizontal
- -
+
-
Number type
- -
+
-
Guess
@@ -183,38 +189,38 @@
- -
+
-
Decimal
- -
+
-
Hexadecimal
- -
+
-
Qt::Horizontal
- -
+
-
- Compare
+ Search type
- -
+
-
- Equal
+ Equal to value
true
@@ -224,20 +230,10 @@
- -
+
-
- Greater
-
-
- op
-
-
-
- -
-
-
- Less
+ Greater than value
op
@@ -245,18 +241,84 @@
-
+
+
+ Less than value
+
+
+ op
+
+
+
+ -
+
+
+ Unknown/changed
+
+
+ op
+
+
+
+ -
false
- Delta
+ Changed by value
op
+ -
+
+
+ false
+
+
+ Unchanged
+
+
+ op
+
+
+
+ -
+
+
+ false
+
+
+ Increased
+
+
+ op
+
+
+
+ -
+
+
+ false
+
+
+ Decreased
+
+
+ op
+
+
+
+ -
+
+
+ Search ROM
+
+
+
-
@@ -271,7 +333,7 @@
-
- Search
+ New Search
@@ -318,10 +380,26 @@
+
+ opDelta0
+ toggled(bool)
+ value
+ setDisabled(bool)
+
+
+ 231
+ 768
+
+
+ 272
+ 26
+
+
+
-
+
diff --git a/src/platform/qt/ObjView.cpp b/src/platform/qt/ObjView.cpp
index e482f023b..fbbfdf309 100644
--- a/src/platform/qt/ObjView.cpp
+++ b/src/platform/qt/ObjView.cpp
@@ -8,7 +8,10 @@
#include "CoreController.h"
#include "GBAApp.h"
+#include
+#include
#include
+#include
#include
#include "LogController.h"
@@ -52,10 +55,36 @@ ObjView::ObjView(std::shared_ptr controller, QWidget* parent)
updateTiles(true);
});
connect(m_ui.exportButton, &QAbstractButton::clicked, this, &ObjView::exportObj);
+ connect(m_ui.copyButton, &QAbstractButton::clicked, this, &ObjView::copyObj);
+
+ connect(m_ui.objList, &QListWidget::currentItemChanged, [this]() {
+ QListWidgetItem* item = m_ui.objList->currentItem();
+ if (item) {
+ selectObj(item->data(Qt::UserRole).toInt());
+ }
+ });
+
+ QAction* exportAction = new QAction(this);
+ exportAction->setShortcut(QKeySequence::Save);
+ connect(exportAction, &QAction::triggered, this, &ObjView::exportObj);
+ addAction(exportAction);
+
+ QAction* copyAction = new QAction(this);
+ copyAction->setShortcut(QKeySequence::Copy);
+ connect(copyAction, &QAction::triggered, this, &ObjView::copyObj);
+ addAction(copyAction);
}
void ObjView::selectObj(int obj) {
m_objId = obj;
+ bool blocked = m_ui.objId->blockSignals(true);
+ m_ui.objId->setValue(m_objId);
+ m_ui.objId->blockSignals(blocked);
+ if (m_objs.size() > obj) {
+ blocked = m_ui.objList->blockSignals(true);
+ m_ui.objList->setCurrentItem(m_objs[obj]);
+ m_ui.objList->blockSignals(blocked);
+ }
updateTiles(true);
}
@@ -71,6 +100,8 @@ void ObjView::updateTilesGBA(bool force) {
const GBA* gba = static_cast(m_controller->thread()->core->board);
const GBAObj* obj = &gba->video.oam.obj[m_objId];
+ updateObjList(128);
+
ObjInfo newInfo;
lookupObj(m_objId, &newInfo);
@@ -153,6 +184,8 @@ void ObjView::updateTilesGB(bool force) {
const GB* gb = static_cast(m_controller->thread()->core->board);
const GBObj* obj = &gb->video.oam.obj[m_objId];
+ updateObjList(40);
+
ObjInfo newInfo;
lookupObj(m_objId, &newInfo);
@@ -200,10 +233,38 @@ void ObjView::updateTilesGB(bool force) {
}
#endif
+void ObjView::updateObjList(int maxObj) {
+ for (int i = 0; i < maxObj; ++i) {
+ if (m_objs.size() <= i) {
+ QListWidgetItem* item = new QListWidgetItem;
+ item->setText(QString::number(i));
+ item->setData(Qt::UserRole, i);
+ item->setSizeHint(QSize(64, 96));
+ if (m_objId == i) {
+ item->setSelected(true);
+ }
+ m_objs.append(item);
+ m_ui.objList->addItem(item);
+ }
+ QListWidgetItem* item = m_objs[i];
+ ObjInfo info;
+ lookupObj(i, &info);
+ item->setIcon(QPixmap::fromImage(std::move(compositeObj(info))));
+ }
+}
+
void ObjView::exportObj() {
QString filename = GBAApp::app()->getSaveFileName(this, tr("Export sprite"),
tr("Portable Network Graphics (*.png)"));
+ if (filename.isNull()) {
+ return;
+ }
CoreController::Interrupter interrupter(m_controller);
QImage obj = compositeObj(m_objInfo);
obj.save(filename, "PNG");
}
+
+void ObjView::copyObj() {
+ CoreController::Interrupter interrupter(m_controller);
+ GBAApp::app()->clipboard()->setImage(compositeObj(m_objInfo));
+}
diff --git a/src/platform/qt/ObjView.h b/src/platform/qt/ObjView.h
index 42cd3f65e..c10d661c3 100644
--- a/src/platform/qt/ObjView.h
+++ b/src/platform/qt/ObjView.h
@@ -9,8 +9,12 @@
#include "ui_ObjView.h"
+#include
+
#include
+class QListWidgetItem;
+
namespace QGBA {
class CoreController;
@@ -23,6 +27,7 @@ public:
public slots:
void exportObj();
+ void copyObj();
private slots:
void selectObj(int);
@@ -36,6 +41,8 @@ private:
void updateTilesGB(bool force) override;
#endif
+ void updateObjList(int maxObj);
+
Ui::ObjView m_ui;
std::shared_ptr m_controller;
@@ -43,6 +50,8 @@ private:
int m_objId = 0;
ObjInfo m_objInfo = {};
+ QList m_objs;
+
int m_tileOffset;
int m_boundary;
};
diff --git a/src/platform/qt/ObjView.ui b/src/platform/qt/ObjView.ui
index df0a003a9..7584deff6 100644
--- a/src/platform/qt/ObjView.ui
+++ b/src/platform/qt/ObjView.ui
@@ -6,21 +6,178 @@
0
0
- 454
- 385
+ 800
+ 730
Sprites
-
- -
+
+
-
+
+
+ Copy
+
+
+
+ -
+
+
+ Geometry
+
+
+
-
+
+
-
+
+
+ Position
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 0
+ 20
+
+
+
+
+ -
+
+
+
+ 20
+ 0
+
+
+
+ 0
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ ,
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 20
+ 0
+
+
+
+ 0
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+
+
+ -
+
+
-
+
+
+ Dimensions
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 0
+ 20
+
+
+
+
+ -
+
+
+
+ 20
+ 0
+
+
+
+ 8
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ ×
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 20
+ 0
+
+
+
+ 8
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+
+
+
+
+
+ -
QFrame::StyledPanel
-
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
0
-
@@ -42,44 +199,21 @@
- -
-
-
-
-
-
-
- 0
- 0
-
-
-
- ×
-
-
- 1
-
-
- 8
-
-
-
- -
-
-
- Magnification
-
-
-
- -
-
-
- Export
-
-
-
-
+ -
+
+
+ Tile
+
+
- -
+
-
+
+
+ Export
+
+
+
+ -
Attributes
@@ -383,154 +517,6 @@
- -
-
-
- Tile
-
-
-
- -
-
-
- Geometry
-
-
-
-
-
-
-
-
-
- Position
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 0
- 20
-
-
-
-
- -
-
-
-
- 20
- 0
-
-
-
- 0
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
- ,
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
-
- 20
- 0
-
-
-
- 0
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
-
-
- -
-
-
-
-
-
- Dimensions
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 0
- 20
-
-
-
-
- -
-
-
-
- 20
- 0
-
-
-
- 8
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
- ×
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
-
- 20
- 0
-
-
-
- 8
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
-
-
-
-
-
-
-
@@ -568,6 +554,64 @@
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ ×
+
+
+ 1
+
+
+ 8
+
+
+
+ -
+
+
+ Magnification
+
+
+
+
+
+ -
+
+
+
+ 64
+ 64
+
+
+
+ QListView::LeftToRight
+
+
+ QListView::Adjust
+
+
+
+ 64
+ 96
+
+
+
+ QListView::IconMode
+
+
+ true
+
+
+
diff --git a/src/platform/qt/OverrideView.cpp b/src/platform/qt/OverrideView.cpp
index 1259761ee..f2957a5d2 100644
--- a/src/platform/qt/OverrideView.cpp
+++ b/src/platform/qt/OverrideView.cpp
@@ -42,9 +42,12 @@ OverrideView::OverrideView(ConfigController* config, QWidget* parent)
s_mbcList.append(GB_MBC3_RTC);
s_mbcList.append(GB_MBC5);
s_mbcList.append(GB_MBC5_RUMBLE);
+ s_mbcList.append(GB_MBC6);
s_mbcList.append(GB_MBC7);
+ s_mbcList.append(GB_MMM01);
s_mbcList.append(GB_POCKETCAM);
s_mbcList.append(GB_TAMA5);
+ s_mbcList.append(GB_HuC1);
s_mbcList.append(GB_HuC3);
}
if (s_gbModelList.isEmpty()) {
diff --git a/src/platform/qt/OverrideView.ui b/src/platform/qt/OverrideView.ui
index 108622ffc..6d908247d 100644
--- a/src/platform/qt/OverrideView.ui
+++ b/src/platform/qt/OverrideView.ui
@@ -319,11 +319,21 @@
MBC5 + Rumble
+ -
+
+ MBC6
+
+
-
MBC7
+ -
+
+ MMM01
+
+
-
Pocket Cam
@@ -334,6 +344,11 @@
TAMA5
+ -
+
+ HuC-1
+
+
-
HuC-3
diff --git a/src/platform/qt/PrinterView.cpp b/src/platform/qt/PrinterView.cpp
index 2a2b621cf..3e56e4dc0 100644
--- a/src/platform/qt/PrinterView.cpp
+++ b/src/platform/qt/PrinterView.cpp
@@ -8,6 +8,7 @@
#include "CoreController.h"
#include "GBAApp.h"
+#include
#include
using namespace QGBA;
@@ -24,6 +25,22 @@ PrinterView::PrinterView(std::shared_ptr controller, QWidget* pa
connect(m_ui.tear, &QAbstractButton::clicked, this, &PrinterView::clear);
connect(m_ui.buttonBox, &QDialogButtonBox::accepted, this, &PrinterView::save);
m_timer.setInterval(80);
+
+ connect(m_ui.magnification, static_cast(&QSpinBox::valueChanged), [this](int mag) {
+ if (m_image.isNull()) {
+ return;
+ }
+ int oldMag = m_ui.image->size().width() / m_image.size().width();
+ m_ui.image->setPixmap(m_image.scaled(m_image.size() * mag));
+ m_ui.image->setFixedWidth(m_image.size().width() * mag);
+ m_ui.image->setFixedHeight(m_ui.image->size().height() / oldMag * mag);
+ });
+
+ QAction* save = new QAction(this);
+ save->setShortcut(QKeySequence::Save);
+ connect(save, &QAction::triggered, this, &PrinterView::save);
+ addAction(save);
+
clear();
}
@@ -52,22 +69,22 @@ void PrinterView::printImage(const QImage& image) {
painter.drawPixmap(0, 0, m_image);
painter.drawImage(0, m_image.height(), image);
m_image = pixmap;
- m_ui.image->setPixmap(m_image);
+ m_ui.image->setPixmap(m_image.scaled(m_image.size() * m_ui.magnification->value()));
m_timer.start();
m_ui.hurry->setEnabled(true);
}
void PrinterView::printLine() {
- m_ui.image->setFixedHeight(m_ui.image->height() + 1);
+ m_ui.image->setFixedHeight(m_ui.image->height() + m_ui.magnification->value());
m_ui.scrollArea->ensureVisible(0, m_ui.image->height(), 0, 0);
- if (m_ui.image->height() >= m_image.height()) {
+ if (m_ui.image->height() >= m_image.height() * m_ui.magnification->value()) {
printAll();
}
}
void PrinterView::printAll() {
m_timer.stop();
- m_ui.image->setFixedHeight(m_image.height());
+ m_ui.image->setFixedHeight(m_image.height() * m_ui.magnification->value());
m_controller->endPrint();
m_ui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(true);
m_ui.hurry->setEnabled(false);
diff --git a/src/platform/qt/PrinterView.ui b/src/platform/qt/PrinterView.ui
index ceac7c577..b103ae768 100644
--- a/src/platform/qt/PrinterView.ui
+++ b/src/platform/qt/PrinterView.ui
@@ -6,15 +6,15 @@
0
0
- 241
- 311
+ 246
+ 425
Game Boy Printer
-
-
+
-
QFrame::NoFrame
@@ -23,10 +23,15 @@
true
-
-
- 0
-
+
+
+ 0
+ 0
+ 234
+ 249
+
+
+
0
@@ -39,14 +44,36 @@
0
-
-
+
+ 0
+
+
-
Qt::Vertical
+
+
+ 0
+ 0
+
+
- -
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 0
+ 0
+
+
+
+
+ -
@@ -60,18 +87,12 @@
1
-
-
- 160
- 16777215
-
-
Qt::AlignHCenter|Qt::AlignTop
- -
+
-
QFrame::Plain
@@ -81,6 +102,19 @@
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 0
+ 0
+
+
+
+
@@ -106,6 +140,62 @@
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ ×
+
+
+ 1
+
+
+ 8
+
+
+
+ -
+
+
+ Magnification
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
-
diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp
index 609e49b61..25dd34a53 100644
--- a/src/platform/qt/SettingsView.cpp
+++ b/src/platform/qt/SettingsView.cpp
@@ -371,6 +371,7 @@ void SettingsView::updateConfig() {
saveSetting("lockAspectRatio", m_ui.lockAspectRatio);
saveSetting("lockIntegerScaling", m_ui.lockIntegerScaling);
saveSetting("interframeBlending", m_ui.interframeBlending);
+ saveSetting("showOSD", m_ui.showOSD);
saveSetting("volume", m_ui.volume);
saveSetting("mute", m_ui.mute);
saveSetting("fastForwardVolume", m_ui.volumeFf);
@@ -546,6 +547,7 @@ void SettingsView::reloadConfig() {
loadSetting("lockAspectRatio", m_ui.lockAspectRatio);
loadSetting("lockIntegerScaling", m_ui.lockIntegerScaling);
loadSetting("interframeBlending", m_ui.interframeBlending);
+ loadSetting("showOSD", m_ui.showOSD, true);
loadSetting("volume", m_ui.volume, 0x100);
loadSetting("mute", m_ui.mute, false);
loadSetting("fastForwardVolume", m_ui.volumeFf, m_ui.volume->value());
diff --git a/src/platform/qt/SettingsView.ui b/src/platform/qt/SettingsView.ui
index a2f15db8c..0cef85ed1 100644
--- a/src/platform/qt/SettingsView.ui
+++ b/src/platform/qt/SettingsView.ui
@@ -6,7 +6,7 @@
0
0
- 849
+ 885
797
@@ -562,7 +562,21 @@
- -
+
-
+
+
+ Pause when minimized
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
Show FPS in title bar
@@ -572,41 +586,21 @@
- -
+
-
+
+
+ Enable Discord Rich Presence
+
+
+
+ -
Qt::Horizontal
- -
-
-
- Qt::Horizontal
-
-
-
- -
-
-
- Automatically save cheats
-
-
- true
-
-
-
- -
-
-
- Automatically load cheats
-
-
- true
-
-
-
- -
+
-
Automatically save state
@@ -616,7 +610,7 @@
- -
+
-
Automatically load state
@@ -626,17 +620,40 @@
- -
-
-
- Enable Discord Rich Presence
+
-
+
+
+ Qt::Horizontal
- -
-
+
-
+
- Pause when minimized
+ Automatically save cheats
+
+
+ true
+
+
+
+ -
+
+
+ Automatically load cheats
+
+
+ true
+
+
+
+ -
+
+
+ Show OSD messages
+
+
+ true
@@ -2106,6 +2123,16 @@
toggled(bool)
fastForwardHeldRatio
setDisabled(bool)
+
+
+ 20
+ 20
+
+
+ 20
+ 20
+
+
diff --git a/src/platform/qt/TileView.cpp b/src/platform/qt/TileView.cpp
index 972d5f419..166114a1d 100644
--- a/src/platform/qt/TileView.cpp
+++ b/src/platform/qt/TileView.cpp
@@ -8,6 +8,8 @@
#include "CoreController.h"
#include "GBAApp.h"
+#include
+#include
#include
#include
@@ -87,7 +89,20 @@ TileView::TileView(std::shared_ptr controller, QWidget* parent)
updateTiles(true);
});
- connect(m_ui.exportButton, &QAbstractButton::clicked, this, &TileView::exportTiles);
+ connect(m_ui.exportAll, &QAbstractButton::clicked, this, &TileView::exportTiles);
+ connect(m_ui.exportOne, &QAbstractButton::clicked, this, &TileView::exportTile);
+ connect(m_ui.copyAll, &QAbstractButton::clicked, this, &TileView::copyTiles);
+ connect(m_ui.copyOne, &QAbstractButton::clicked, this, &TileView::copyTile);
+
+ QAction* exportAll = new QAction(this);
+ exportAll->setShortcut(QKeySequence::Save);
+ connect(exportAll, &QAction::triggered, this, &TileView::exportTiles);
+ addAction(exportAll);
+
+ QAction* copyOne = new QAction(this);
+ copyOne->setShortcut(QKeySequence::Copy);
+ connect(copyOne, &QAction::triggered, this, &TileView::copyTile);
+ addAction(copyOne);
}
#ifdef M_CORE_GBA
@@ -162,8 +177,36 @@ void TileView::updatePalette(int palette) {
void TileView::exportTiles() {
QString filename = GBAApp::app()->getSaveFileName(this, tr("Export tiles"),
tr("Portable Network Graphics (*.png)"));
+ if (filename.isNull()) {
+ return;
+ }
CoreController::Interrupter interrupter(m_controller);
updateTiles(false);
QPixmap pixmap(m_ui.tiles->backing());
pixmap.save(filename, "PNG");
}
+
+void TileView::exportTile() {
+ QString filename = GBAApp::app()->getSaveFileName(this, tr("Export tile"),
+ tr("Portable Network Graphics (*.png)"));
+ if (filename.isNull()) {
+ return;
+ }
+ CoreController::Interrupter interrupter(m_controller);
+ updateTiles(false);
+ QImage image(m_ui.tile->activeTile());
+ image.save(filename, "PNG");
+}
+
+void TileView::copyTiles() {
+ CoreController::Interrupter interrupter(m_controller);
+ updateTiles(false);
+ QPixmap pixmap();
+ GBAApp::app()->clipboard()->setPixmap(m_ui.tiles->backing());
+}
+
+void TileView::copyTile() {
+ CoreController::Interrupter interrupter(m_controller);
+ updateTiles(false);
+ GBAApp::app()->clipboard()->setImage(m_ui.tile->activeTile());
+}
diff --git a/src/platform/qt/TileView.h b/src/platform/qt/TileView.h
index bf89f5645..0f6e0017b 100644
--- a/src/platform/qt/TileView.h
+++ b/src/platform/qt/TileView.h
@@ -24,6 +24,9 @@ public:
public slots:
void updatePalette(int);
void exportTiles();
+ void exportTile();
+ void copyTiles();
+ void copyTile();
private:
#ifdef M_CORE_GBA
diff --git a/src/platform/qt/TileView.ui b/src/platform/qt/TileView.ui
index 521ad27b0..d979459fc 100644
--- a/src/platform/qt/TileView.ui
+++ b/src/platform/qt/TileView.ui
@@ -6,14 +6,28 @@
0
0
- 693
- 467
+ 748
+ 823
Tiles
-
+
+ -
+
+
+ Export Selected
+
+
+
+ -
+
+
+ Export All
+
+
+
-
-
@@ -104,17 +118,7 @@
- -
-
-
- -
-
-
- Export
-
-
-
- -
+
-
@@ -133,7 +137,7 @@
0
0
- 405
+ 480
768
@@ -179,6 +183,23 @@
+ -
+
+
+ -
+
+
+ Copy Selected
+
+
+
+ -
+
+
+ Copy All
+
+
+
diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp
index 8751c8057..71bc39c19 100644
--- a/src/platform/qt/Window.cpp
+++ b/src/platform/qt/Window.cpp
@@ -802,6 +802,7 @@ void Window::gameStarted() {
m_config->updateOption("lockIntegerScaling");
m_config->updateOption("lockAspectRatio");
m_config->updateOption("interframeBlending");
+ m_config->updateOption("showOSD");
if (m_savedScale > 0) {
resizeFrame(size * m_savedScale);
}
@@ -971,8 +972,10 @@ void Window::reloadDisplayDriver() {
const mCoreOptions* opts = m_config->options();
m_display->lockAspectRatio(opts->lockAspectRatio);
+ m_display->lockIntegerScaling(opts->lockIntegerScaling);
m_display->interframeBlending(opts->interframeBlending);
m_display->filter(opts->resampleVideo);
+ m_config->updateOption("showOSD");
#if defined(BUILD_GL) || defined(BUILD_GLES2)
if (opts->shader) {
struct VDir* shader = VDirOpen(opts->shader);
@@ -1694,6 +1697,13 @@ void Window::setupMenu(QMenuBar* menubar) {
}
}, this);
+ ConfigOption* showOSD = m_config->addOption("showOSD");
+ showOSD->connect([this](const QVariant& value) {
+ if (m_display) {
+ m_display->showOSDMessages(value.toBool());
+ }
+ }, this);
+
m_actions.addHiddenAction(tr("Exit fullscreen"), "exitFullScreen", this, &Window::exitFullScreen, "frame", QKeySequence("Esc"));
m_actions.addHeldAction(tr("GameShark Button (held)"), "holdGSButton", [this](bool held) {
diff --git a/src/platform/qt/library/LibraryController.cpp b/src/platform/qt/library/LibraryController.cpp
index 3f2a5fc96..b7756437b 100644
--- a/src/platform/qt/library/LibraryController.cpp
+++ b/src/platform/qt/library/LibraryController.cpp
@@ -51,6 +51,7 @@ LibraryController::LibraryController(QWidget* parent, const QString& path, Confi
m_libraryGrid = std::make_unique(this);
addWidget(m_libraryGrid->widget());
+ m_currentStyle = LibraryStyle::STYLE_TREE; // Make sure setViewStyle does something
setViewStyle(LibraryStyle::STYLE_LIST);
refresh();
}
diff --git a/src/platform/qt/ts/medusa-emu-de.ts b/src/platform/qt/ts/medusa-emu-de.ts
index 7d1b59723..79322f4cc 100644
--- a/src/platform/qt/ts/medusa-emu-de.ts
+++ b/src/platform/qt/ts/medusa-emu-de.ts
@@ -310,35 +310,25 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.GIF aufzeichnen
-
+
Start
-
+
Stop
-
+
Datei wählen
-
+
Frameskip
-
-
-
- Bildverzögerung (ms)
-
-
-
-
- Automatisch
-
IOViewer
@@ -599,142 +589,206 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Maps
-
+
×
-
+
Vergrößerung
-
+
Exportieren
+
+
+
+ Kopieren
+
+
+
+ MemoryDump
+
+
+
+ Speicherbereich abspeichern
+
+
+
+
+ Start-Adresse:
+
+
+
+
+ :
+
+
+
+
+
+ 0x
+
+
+
+
+ Bytes:
+
+
+
+
+ Über Speicherbänke hinweg dumpen
+
MemorySearch
-
+
Speicher durchsuchen
-
+
Adresse
-
+
Aktueller Wert
-
-
+
+
Typ
-
+
Wert
-
+
Numerisch
-
+
Text
-
+
Breite
-
+
1 Byte (8-bit)
-
+
2 Bytes (16-bit)
-
+
4 Bytes (32-bit)
-
+
Zahlensystem
-
+
Hexadezimal
-
+
+
+ Suche nach
+
+
+
+
+ Entspricht dem Wert
+
+
+
+
+ Größer als der Wert
+
+
+
+
+ Kleiner als der Wert
+
+
+
+
+ Unbekannt/geändert
+
+
+
+
+ Geändert durch Wert
+
+
+
+
+ Unverändert
+
+
+
+
+ Erhöht
+
+
+
+
+ Verringert
+
+
+
+
+ ROM durchsuchen
+
+
+
+
+ Neue Suche
+
+
+
Dezimal
-
-
+
+
automatisch
-
-
- Vergleichen
-
-
-
-
- Gleichwertig
-
-
-
-
- Größer
-
-
-
-
- Kleiner
-
-
-
-
- Differenz
-
-
-
-
- Suchen
-
-
-
+
Suchen innerhalb
-
+
Im Speicher-Monitor öffnen
-
+
Aktualisieren
@@ -752,67 +806,77 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Untersuche Adresse:
-
+
+
+ :
+
+
+
0x
-
+
Ausrichtung festlegen:
-
+
&1 Byte
-
+
&2 Bytes
-
+
&4 Bytes
-
+
Signed Integer:
-
+
String:
-
+
TBL laden
-
+
Auswahl kopieren
-
+
Einfügen
-
+
Auswahl speichern
-
+
+
+ Bereich speichern
+
+
+
Laden
-
+
Unsigned Integer:
@@ -825,140 +889,145 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Sprites
-
-
+
+
×
-
+
Vergrößerung
-
+
Exportieren
-
+
Eigenschaften
-
+
Transform
-
+
Aus
-
+
Palette
-
-
-
-
+
+
+
+
0
-
+
+
+ Kopieren
+
+
+
Doppelte Größe
-
-
-
-
+
+
+
+
Eingabe, Strg+R
-
+
Gespiegelt
-
+
H
-
+
V
-
+
Modus
-
+
Normal
-
+
Mosaic
-
+
Aktiviert
-
+
Priorität
-
+
-
+
Geometrie
-
+
Position
-
+
,
-
+
Abmessungen
-
-
+
+
8
-
+
Adresse
-
+
0x07000000
@@ -1116,36 +1185,51 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.
+
+ MBC6
+
+
+
MBC7
-
+
+
+ MMM01
+
+
+
Pocket Cam
-
+
TAMA5
-
+
+
+ HuC-1
+
+
+
HuC-3
-
+
Hintergrund-Farbpalette
-
+
Sprite-Farbpalette 1
-
+
Sprite-Farbpalette 2
@@ -1271,15 +1355,25 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Game Boy Printer
-
+
Los geht's!
-
+
Abreißen
+
+
+
+ ×
+
+
+
+
+ Vergrößerung
+
QGBA::AssetTile
@@ -1289,9 +1383,9 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.%0%1%2
-
-
-
+
+
+
0x%0 (%1)
@@ -1342,22 +1436,22 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.
QGBA::CoreController
-
+
Fehler beim Öffnen der Speicherdatei: %1
-
+
Fehler beim Öffnen der Spieldatei: %1
-
+
Konnte Snapshot-Datei %1 nicht zum Lesen öffnen
-
+
Konnte Snapshot-Datei %1 nicht zum Schreiben öffnen
@@ -1490,17 +1584,17 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.
QGBA::GIFView
-
+
Fehler beim Öffnen der Ausgabe-GIF-Datei: %1
-
+
Ausgabedatei auswählen
-
+
Graphics Interchange Format (*.gif)
@@ -3036,89 +3130,97 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.
QGBA::MapView
-
+
Priorität
-
-
+
+
Map-Basis
-
-
+
+
Tile-Basis
-
+
Größe
-
-
+
+
Versatz
-
+
Xform
-
+
Map-Addr.
-
+
Spiegel
-
+
Keiner
-
+
Beidseitig
-
+
Horizontal
-
+
Vertikal
-
-
-
+
+
+
N/A
-
+
Map exportieren
-
+
Portable Network Graphics (*.png)
+
+
+ QGBA::MemoryDump
-
-
- Fehler beim Öffnen der Ausgabe-PNG-Datei: %1
+
+
+ Speicherbereich abspeichern
+
+
+
+
+ Fehler beim Öffnen der Ausgabedatei: %1
@@ -3187,22 +3289,22 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.
QGBA::MemorySearch
-
+
(%0/%1×)
-
+
(⅟%0×)
-
+
(%0×)
-
+
%1 byte%2
@@ -3210,49 +3312,49 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.
QGBA::ObjView
-
-
+
+
0x%0
-
+
Aus
-
+
Normal
-
+
Trans
-
+
OBJWIN
-
+
Ungültig
-
-
+
+
N/A
-
+
Sprite exportieren
-
+
Portable Network Graphics (*.png)
@@ -3380,7 +3482,7 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.BIOS auswählen
-
+
(%1×%2)
@@ -3439,15 +3541,21 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.
QGBA::TileView
-
+
Tiles exportieren
-
+
+
Portable Network Graphics (*.png)
+
+
+
+ Tile exportieren
+
QGBA::VideoView
@@ -3470,7 +3578,7 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.
QGBA::Window
-
+
Game Boy Advance-ROMs (%1)
@@ -3480,78 +3588,78 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.DS-ROMs (%1)
-
+
Game Boy-ROMs (%1)
-
+
Alle ROMs (%1)
-
+
%1 Video-Logs (*.mvl)
-
+
Archive (%1)
-
-
-
+
+
+
ROM auswählen
-
+
Game Boy Advance-Speicherdateien (%1)
-
-
-
+
+
+
Speicherdatei wählen
-
+
mGBA Savestate-Dateien (%1)
-
-
+
+
Savestate auswählen
-
+
Patch wählen
-
+
Patches (*.ips *.ups *.bps)
-
+
Bild auswählen
-
+
Bild-Datei (*.png *.gif *.jpg *.jpeg);;Alle Dateien (*)
-
-
+
+
GameShark-Speicherdaten (*.sps *.xps)
@@ -3566,22 +3674,22 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.DS-Unterstützung erfordert ein Abbild des BIOS und der Firmware.
-
+
Video-Log auswählen
-
+
Video-Logs (*.mvl)
-
+
Absturz
-
+
@@ -3590,433 +3698,433 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.
-
+
Konnte nicht geladen werden
-
+
Konnte das Spiel nicht laden. Sind Sie sicher, dass es im korrekten Format vorliegt?
-
+
Nicht implementierter BIOS-Aufruf
-
+
Dieses Spiel verwendet einen BIOS-Aufruf, der nicht implementiert ist. Bitte verwenden Sie für die beste Spielerfahrung das offizielle BIOS.
-
+
Portablen Modus wirklich aktivieren?
-
+
Diese Einstellung wird den Emulator so konfigurieren, dass er seine Konfiguration aus dem gleichen Verzeichnis wie die Programmdatei lädt. Möchten Sie fortfahren?
-
+
Neustart benötigt
-
+
Einige Änderungen werden erst übernommen, wenn der Emulator neu gestartet wurde.
-
+
- Spieler %1 von %2
-
+
%1 - %2
-
+
%1 - %2 - %3
-
+
%1 - %2 (%3 Bilder/Sekunde) - %4
-
+
&Datei
-
+
&ROM laden...
-
+
ROM aus Archiv laden...
-
+
Alternative Speicherdatei laden...
-
+
Temporäre Speicherdatei laden...
-
+
&Patch laden...
-
+
BIOS booten
-
+
ROM ersetzen...
-
+
ROM-&Informationen...
-
+
Zuletzt verwendet
-
+
Portablen Modus aktivieren
-
+
Savestate (aktueller Zustand) &laden
-
+
Ssavestate-Datei laden...
-
+
Savestate (aktueller Zustand) &speichern
-
+
Savestate-Datei speichern...
-
+
Schnell laden
-
+
Schnell speichern
-
+
Lade zuletzt gespeicherten Savestate
-
+
Speichere aktuellen Zustand
-
+
Laden des Savestate rückgängig machen
-
+
Speichern des Savestate rückgängig machen
-
-
+
+
Savestate &%1
-
+
Lade Kamerabild...
-
+
Importiere GameShark-Speicherstand
-
+
Exportiere GameShark-Speicherstand
-
+
Neues Multiplayer-Fenster
-
+
&Beenden
-
+
&Emulation
-
+
Zu&rücksetzen
-
+
Schli&eßen
-
+
Spielmodul herausziehen
-
+
&Pause
-
+
&Nächstes Bild
-
+
Schneller Vorlauf (gehalten)
-
+
Schneller &Vorlauf
-
+
Vorlauf-Geschwindigkeit
-
+
Unbegrenzt
-
+
%0x
-
+
Zurückspulen (gehalten)
-
+
Zur&ückspulen
-
+
Schrittweiser Rücklauf
-
+
Mit &Video synchronisieren
-
+
Mit &Audio synchronisieren
-
+
Sonnen-Sensor
-
+
Sonnen-Level erhöhen
-
+
Sonnen-Level verringern
-
+
Hellster Sonnen-Level
-
+
Dunkelster Sonnen-Level
-
+
Helligkeit %1
-
+
BattleChip Gate...
-
+
Audio/&Video
-
+
Bildgröße
-
+
Vollbildmodus umschalten
-
+
Seitenverhältnis korrigieren
-
+
Pixelgenaue Skalierung (Integer scaling)
-
+
Interframe-Überblendung
-
+
Frame&skip
-
+
Stummschalten
-
+
Bildwiederholrate
-
+
&Screenshot erstellen
-
+
F12
-
+
GIF aufzeichen...
-
+
Leeren
-
+
Game Boy Printer...
-
+
Video-Ebenen
-
+
Audio-Kanäle
-
+
Lage der Bildebenen anpassen...
-
+
&Werkzeuge
-
+
&Logs ansehen...
-
+
Spiel-&Überschreibungen...
-
+
&Cheats...
-
+
Debugger-Konsole öffnen...
-
+
&GDB-Server starten...
-
+
Einstellungen...
@@ -4036,72 +4144,72 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.DS
-
+
Ordner auswählen
-
+
Ordner zur Bibliothek hinzufügen...
-
+
Über...
-
+
%1x
-
+
Bilineare Filterung
-
+
Nativ (59.7275)
-
+
Audio/Video aufzeichnen...
-
+
Spielmodul-Sensoren...
-
+
&Palette betrachten...
-
+
&Sprites betrachten...
-
+
&Tiles betrachten...
-
+
&Map betrachten...
-
+
&Bildbetrachter...
-
+
Speicher betrachten...
@@ -4111,87 +4219,87 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.&I/O-Register betrachten...
-
+
Speicher durchsuchen...
-
+
&I/O-Register betrachten...
-
+
Video-Protokoll aufzeichnen...
-
+
Aufzeichnen des Video-Protokolls beenden
-
+
Vollbildmodus beenden
-
+
GameShark-Taste (gehalten)
-
+
Autofeuer
-
+
Autofeuer A
-
+
Autofeuer B
-
+
Autofeuer L
-
+
Autofeuer R
-
+
Autofeuer Start
-
+
Autofeuer Select
-
+
Autofeuer nach oben
-
+
Autofeuer rechts
-
+
Autofeuer nach unten
-
+
Autofeuer links
@@ -4504,7 +4612,7 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.
-
+
Bild(er)
@@ -4575,177 +4683,182 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Baumansicht
-
+
Bildwiederholrate in der Titelleiste anzeigen
-
+
Cheats automatisch speichern
-
+
Cheats automatisch laden
-
+
Zustand (Savestate) automatisch speichern
-
+
Zustand (Savestate) automatisch laden
-
+
Discord-Integration aktivieren
-
+
Pause, wenn minimiert
-
+
+
+ Bildschirmmeldungen anzeigen
+
+
+
Vorlauf-Geschwindigkeit (halten):
-
+
Video-Renderer:
-
+
Software
-
+
OpenGL
-
+
OpenGL-Verbesserungen
-
+
Hochauflösende Skalierung:
-
+
XQ GBA-Audio (experimentell)
-
+
Cheats
-
+
In Datei protokollieren
-
+
Auf die Konsole protokollieren
-
+
Protokoll-Datei auswählen
-
+
Kamera:
-
-
-
+
+
+
Automatisch erkennen
-
-
-
+
+
+
Game Boy (DMG)
-
-
-
+
+
+
Super Game Boy (SGB)
-
-
-
+
+
+
Game Boy Color (CGB)
-
-
-
+
+
+
Game Boy Advance (AGB)
-
+
Standard-Hintergrundfarben:
-
+
Standard-Sprite-Farben 1:
-
+
Standard-Sprite-Farben 2:
-
+
Verwende GBC-Farben in GB-Spielen
-
+
Super Game Boy-Rahmen
-
+
Game Boy-Modell:
-
+
Super Game Boy-Modell:
-
+
Game Boy Color-Modell:
-
+
Kamera-Treiber:
@@ -4765,26 +4878,26 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Cache leeren
-
+
Vorlauf-Geschwindigkeit:
-
+
ROM-Datei vollständig
in Arbeitsspeicher vorladen
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
Durchsuchen
@@ -4799,26 +4912,26 @@ in Arbeitsspeicher vorladen
DS-BIOS 9:
-
+
BIOS-Datei verwenden,
wenn vorhanden
-
+
BIOS-Intro überspringen
-
-
-
+
+
+
×
-
-
+
+
unbegrenzt
@@ -4838,17 +4951,17 @@ wenn vorhanden
Pause, wenn inaktiv
-
+
Alle ausführen
-
+
Bekannte entfernen
-
+
Erkennen und entfernen
@@ -4858,25 +4971,25 @@ wenn vorhanden
Gegensätzliche Eingaberichtungen erlauben
-
-
+
+
Screenshot
-
-
+
+
Speicherdaten
-
-
+
+
Cheat-Codes
-
+
Rücklauf aktivieren
@@ -4886,47 +4999,47 @@ wenn vorhanden
Bilineare Filterung
-
+
Rücklauf-Verlauf:
-
+
Leerlaufprozesse:
-
+
Zusätzliche Savestate-Daten:
-
+
Lade zusätzliche Daten:
-
+
Autofeuer-Intervall:
-
+
(240×160)
-
+
Datei mit GB-BIOS:
-
+
Datei mit GBA-BIOS:
-
+
Datei mit GBC-BIOS:
@@ -4936,36 +5049,36 @@ wenn vorhanden
DS-Firmware:
-
+
Datei mit SGB-BIOS:
-
+
Spielstände
-
-
-
-
-
+
+
+
+
+
Verzeichnis der ROM-Datei
-
+
Savestates
-
+
Screenshots
-
+
Patches
@@ -5039,34 +5152,49 @@ wenn vorhanden
Tiles
-
+
+
+ Auswahl exportieren
+
+
+
+
+ Alle exportieren
+
+
+
256 Farben
-
+
×
-
+
Vergrößerung
-
+
Tiles pro Zeile
-
+
An Fenster anpassen
-
-
- Exportieren
+
+
+ Auswahl kopieren
+
+
+
+
+ Alle kopieren
diff --git a/src/platform/qt/ts/medusa-emu-es.ts b/src/platform/qt/ts/medusa-emu-es.ts
index 2e950a8df..6df49af91 100644
--- a/src/platform/qt/ts/medusa-emu-es.ts
+++ b/src/platform/qt/ts/medusa-emu-es.ts
@@ -232,15 +232,20 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Cargar
-
+
Agregar nuevo conjunto
-
+
Agregar
+
+
+
+ Ingresa los códigos aquí...
+
DebuggerConsole
@@ -260,6 +265,49 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Entrar a depuración
+
+ FrameView
+
+
+
+ Inspeccionar cuadro
+
+
+
+
+ ×
+
+
+
+
+ Ampliación
+
+
+
+
+ Congelar cuadro
+
+
+
+
+ Color de telón de fondo (backdrop)
+
+
+
+
+ Desactivar efectos de línea de trazado
+
+
+
+
+ Exportar
+
+
+
+
+ Reinicializar
+
+
GIFView
@@ -268,34 +316,32 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Grabar GIF
-
+
Iniciar
-
+
Detener
-
+
Seleccionar archivo
-
+
Salto
-
- Retraso (ms)
+ Retraso (ms)
-
- Automático
+ Automático
@@ -423,13 +469,13 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
LoadSaveState
-
+
%1 estado
-
+
@@ -441,17 +487,22 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Sin estado
-
+
1
-
+
2
-
+
+
+ Cancelar
+
+
+
3
@@ -461,12 +512,12 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
4
-
+
5
-
+
6
@@ -476,12 +527,12 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
7
-
+
8
-
+
9
@@ -541,7 +592,7 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
- Líneas max.
+ Líneas max
@@ -552,142 +603,230 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Mapas
-
+
x
-
+
Ampliación
-
+
Exportar
+
+
+
+ Copiar
+
+
+
+ MemoryDump
+
+
+
+ Volcar rango de memoria
+
+
+
+
+ Dirección de inicio:
+
+
+
+
+ :
+
+
+
+
+
+ 0x
+
+
+
+
+ Cantidad de bytes:
+
+
+
+
+ Volcar entre bancos de memoria
+
MemorySearch
-
+
Búsqueda en la memoria
-
+
Dirección
-
+
Valor actual
-
-
+
+
Tipo
-
+
Valor
-
+
Numérico
-
+
Texto
-
+
Ancho
-
+
1 byte (8 bits)
-
+
2 bytes (16 bits)
-
+
4 bytes (32 bits)
-
+
Tipo de número
-
+
Hexadecimal
-
+
+
+ Tipo de búsqueda
+
+
+
+
+ Igual a valor
+
+
+
+
+ Mayor que valor
+
+
+
+
+ Menor que valor
+
+
+
+
+ Desconocido/cambiado
+
+
+
+
+ Cambiado a valor
+
+
+
+
+ Sin cambios
+
+
+
+
+ Aumentado
+
+
+
+
+ Disminuido
+
+
+
+
+ Buscar ROM
+
+
+
+
+ Nueva búsqueda
+
+
+
Decimal
-
-
+
+
Adivinar
-
- Comparar
+ Comparar
-
- Igual a
+ Igual a
-
- Mayor que
+ Mayor que
-
- Menor que
+ Menor que
-
- Diferencia
+ Diferencia
-
- Buscar
+ Buscar
-
+
Buscar dentro
-
+
Abrir en el Visor de memoria
-
+
Actualizar
@@ -705,12 +844,17 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Inspeccionar dirección:
-
+
+
+ :
+
+
+
0x
-
+
Alinear a:
@@ -727,57 +871,62 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
4 bytes
-
+
-
+
-
+
-
+
Entero sin signo:
-
+
Entero con signo:
-
+
Cadena de texto:
-
+
Cargar TBL
-
+
Copiar selección
-
+
Pegar
-
+
Guardar selección
-
+
+
+ Guardar rango
+
+
+
Cargar
@@ -790,140 +939,145 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Sprites
-
-
+
+
x
-
+
Ampliación
-
+
Esportar
-
+
Atributos
-
+
Transform
-
+
No
-
+
Paleta
-
-
-
-
+
+
+
+
0
-
+
+
+ Copiar
+
+
+
Tamaño doble
-
-
-
-
+
+
+
+
Volver, Ctrl+R
-
+
Volteo
-
+
H
-
+
V
-
+
Modo
-
+
Normal
-
+
Mosaico
-
+
Habilitado
-
+
Prioridad
-
+
Tile
-
+
Geometría
-
+
Posición
-
+
,
-
+
Dimensiones
-
-
+
+
8
-
+
Dirección
-
+
0x07000000
@@ -1081,36 +1235,51 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
+
+ MBC6
+
+
+
MBC7
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+ HuC-1
+
+
+
HuC-3
-
+
Colores de fondo
-
+
Colores de sprite 1
-
+
Colores de sprite 2
@@ -1240,27 +1409,37 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Game Boy Printer
-
+
¡Apúrate!
-
+
Arrancar papel
+
+
+
+
+
+
+
+
+ Ampliación
+
QGBA::AssetTile
-
+
%0%1%2
-
-
-
+
+
+
0x%0 (%1)
@@ -1374,22 +1553,22 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
QGBA::CoreController
-
+
Error al abrir el archivo de guardado: %1
-
+
Error al abrir el archivo del juego: %1
-
+
Error al leer del archivo de captura: %1
-
+
Error al escribir al archivo de captura: %1
@@ -1402,6 +1581,49 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Error al abrir el archivo del juego: %1
+
+ QGBA::FrameView
+
+
+
+ Exportar cuadro
+
+
+
+
+ Gráficos de red portátiles (*.png)
+
+
+
+
+ Ninguno
+
+
+
+
+ Fondo (BG)
+
+
+
+
+ Ventana (WIN)
+
+
+
+
+ Sprite
+
+
+
+
+ Telón de fondo (backdrop)
+
+
+
+
+ %1× {1 %2?}
+
+
QGBA::GBAApp
@@ -1479,17 +1701,17 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
QGBA::GIFView
-
+
Error al abrir el archivo GIF de salida: %1
-
+
Seleccionar archivo de salida
-
+
Graphics Interchange Format (*.gif)
@@ -2897,27 +3119,27 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
QGBA::LoadSaveState
-
+
Cargar estado
-
+
Guardar estado
-
+
Vacío
-
+
Dañado
-
+
Espacio %1
@@ -3017,49 +3239,101 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
QGBA::MapView
-
-
- Dir de mapa
+
+
+ Prioridad
-
+
+
+
+ Base mapas
+
+
+
+
+
+ Base tiles
+
+
+
+
+ Tamaño
+
+
+
+
+
+ Posición
+
+
+
+
+ Xform
+
+
+
+
+ Dir. de mapa
+
+
+
Espejar
-
+
Ninguno
-
+
Ambos
-
+
Horizontal
-
+
Vertical
-
+
+
+
+
+ n/d
+
+
+
Exportar mapa
-
+
Gráficos de red portátiles (*.png)
-
- Error al abrir el archivo PNG de salida: %1
+ Error al abrir el archivo PNG de salida: %1
+
+
+
+ QGBA::MemoryDump
+
+
+
+ Guardar región de memoria
+
+
+
+
+ Error al abrir el archivo de salida: %1
@@ -3128,22 +3402,22 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
QGBA::MemorySearch
-
+
(%0/%1×)
-
+
(⅟%0×)
-
+
(%0×)
-
+
%1 byte%2
@@ -3163,56 +3437,55 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
QGBA::ObjView
-
-
+
+
0x%0
-
+
No
-
+
Normal
-
+
Trans
-
+
OBJWIN
-
+
Inválido
-
-
+
+
n/d
-
+
Exportar sprite
-
+
Portable Network Graphics (*.png)
-
- Error al abrir el archivo PNG de salida: %1
+ Error al abrir el archivo PNG de salida: %1
@@ -3258,12 +3531,12 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
QGBA::PrinterView
-
+
Guardar impresión
-
+
Gráficos de red portátiles (*.png)
@@ -3294,62 +3567,67 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
QGBA::SettingsView
-
-
+
+
Qt Multimedia
-
+
SDL
-
+
Software (Qt)
-
+
OpenGL
-
+
OpenGL (forzar versión 1.x)
-
+
Nada (imagen estática)
-
+
Teclado
-
+
Controladores
-
+
Atajos de teclado
-
-
+
+
Shaders
-
+
Seleccionar BIOS
+
+
+
+
+
QGBA::ShaderSelector
@@ -3417,6 +3695,25 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Mando
+
+ QGBA::TileView
+
+
+
+ Exportar tiles
+
+
+
+
+
+ Gráficos de red portátiles (*.png)
+
+
+
+
+ Exportar tile
+
+
QGBA::VideoView
@@ -3534,12 +3831,12 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Video-registros (*.mvl)
-
+
Error fatal
-
+
@@ -3548,146 +3845,156 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
%1
-
+
No se pudo cargar
-
+
No se pudo cargar el juego. ¿Estás seguro de que está en el formato correcto?
-
+
Llamada a BIOS no implementada
-
+
Este juego utiliza una llamada al BIOS que no se ha implementado. Utiliza el BIOS oficial para obtener la mejor experiencia.
-
+
¿Hacer "portable"?
-
+
Esto hará que el emulador cargue su configuración desde el mismo directorio que el ejecutable. ¿Quieres continuar?
-
+
Reinicio necesario
-
+
Algunos cambios no surtirán efecto hasta que se reinicie el emulador.
-
+
- Jugador %1 de %2
-
+
%1 - %2
-
+
%1 - %2 - %3
-
+
%1 - %2 (%3 fps) - %4
-
+
&Archivo
-
+
Cargar &ROM...
-
+
Cargar ROM desde contenedor...
-
+
Agregar carpeta a la biblioteca...
-
+
Cargar guardado alternativo...
-
+
Cargar guardado temporal...
-
+
Cargar &parche...
-
+
Arrancar BIOS
-
+
Reemplazar ROM...
-
+
&Información de la ROM...
-
+
Recientes
-
+
Hacer "portable"
-
+
Ca&rgar estado
-
+
Acerca de...
+
+
+
+ Sensores del cartucho...
+
+
+
+
+ Limpiar
+
F10
-
+
Cargar archivo de estado...
-
+
Guardar e&stado
@@ -3696,32 +4003,32 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Shift+F10
-
+
Guardar archivo de estado...
-
+
Cargado rápido
-
+
Guardado rápido
-
+
Cargar reciente
-
+
Guardar reciente
-
+
Deshacer cargar estado
@@ -3730,7 +4037,7 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
F11
-
+
Deshacer guardar estado
@@ -3739,8 +4046,8 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Shift+F11
-
-
+
+
Estado &%1
@@ -3753,22 +4060,22 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Shift+F%1
-
+
Cargar imagen para la cámara...
-
+
Importar guardado de GameShark
-
+
Exportar guardado de GameShark
-
+
Nueva ventana multijugador
@@ -3777,17 +4084,17 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Acerca de
-
+
Salir (&X)
-
+
&Emulación
-
+
&Reinicializar
@@ -3796,17 +4103,17 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Ctrl+R
-
+
Apagar (&U)
-
+
Tirar del cartucho
-
+
&Pausar
@@ -3815,7 +4122,7 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Ctrl+P
-
+
Cuadro siguie&nte
@@ -3824,12 +4131,12 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Ctrl+N
-
+
Avance rápido (mantener)
-
+
&Avance rápido
@@ -3838,27 +4145,27 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Shift+Tab
-
+
Velocidad de avance rápido
-
+
Sin límite
-
+
%0x
-
+
Rebobinar (mantener)
-
+
Re&bobinar
@@ -3867,7 +4174,7 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
~
-
+
Paso hacia atrás
@@ -3876,52 +4183,52 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Ctrl+B
-
+
Sincronizar a &video
-
+
Sincronizar a au&dio
-
+
Sensor solar
-
+
Subir nivel
-
+
Bajar nivel
-
+
Más claro
-
+
Más oscuro
-
+
Brillo %1
-
+
Audio/&video
-
+
Tamaño del cuadro
@@ -3930,42 +4237,42 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
%1x
-
+
Pantalla completa
-
+
Bloquear proporción de aspecto
-
+
Forzar escala a enteros
-
+
Filtro bilineal
-
+
&Salto de cuadros
-
+
Silenciar
-
+
Objetivo de FPS
-
+
Nativo (59,7275)
@@ -4002,12 +4309,12 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
240
-
+
Tomar pan&tallazo
-
+
F12
@@ -4016,7 +4323,7 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Grabar salida...
-
+
Grabar GIF...
@@ -4029,187 +4336,196 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Detener video-registro
-
+
Game Boy Printer...
-
+
BattleChip Gate...
-
+
%1×
-
+
+
+ Mezcla entre cuadros
+
+
+
Grabar A/V...
-
+
Capas de video
-
+
Canales de audio
-
+
Ajustar ubicación de capas...
-
+
Herramien&tas
-
+
Ver re&gistros...
-
+
Ajustes específic&os por juego...
-
- Sensores del Game &Pak...
+ Sensores del Game &Pak...
-
+
Tru&cos...
-
+
Ajustes...
-
+
Abrir consola de depuración...
-
+
Iniciar servidor &GDB...
-
+
Ver &paleta...
-
+
Ver &sprites...
-
+
Ver &tiles...
-
+
Ver &mapa...
-
+
+
+ Inspec&tor de cuadros...
+
+
+
Ver memoria...
-
+
Buscar memoria...
-
+
Ver registros &I/O...
-
+
Grabar registro de depuración de video...
-
+
Detener registro de depuración de video
-
+
Salir de pantalla completa
-
+
Botón GameShark (mantener)
-
+
Disparo automático
-
+
Disparo automático A
-
+
Disparo automático B
-
+
Disparo automático L
-
+
Disparo automático R
-
+
Disparo automático Start
-
+
Disparo automático Select
-
+
Disparo automático Arriba
-
+
Disparo automático Derecha
-
+
Disparo automático Abajo
-
+
Disparo automático Izquierda
@@ -4527,7 +4843,7 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
-
+
cuadros
@@ -4567,42 +4883,72 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Filtro bilineal
-
+
+
+ Nativo (59,7275)
+
+
+
+
+ Mezcla entre cuadros
+
+
+
+
+ Pausar al estar minimizado
+
+
+
+
+ Mostrar mensajes en el OSD
+
+
+
+
+ Avance rápido (mantenido):
+
+
+
+
+ (240×160)
+
+
+
Guardar a archivo
-
+
Guardar a consola
-
+
Seleccionar
-
+
Modelo de Game Boy:
-
+
Modelo de Super Game Boy:
-
+
Modelo de Game Boy Color:
-
+
Usar colores de GBC en juegos GB
-
+
Cámara:
@@ -4612,156 +4958,158 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Forzar escalado a valores enteros
-
+
Idioma
-
+
English
-
+
Biblioteca:
-
+
Lista
-
+
Árbol
-
+
Mostrar cuando no haya un juego abierto
-
+
Limpiar caché
-
+
Permitir direcciones opuestas al mismo tiempo
-
+
Suspender protector de pantalla
-
+
Pausar al no estar activo
-
+
Mostrar FPS en la barra de título
-
+
Guardar trucos automáticamente
-
+
Cargar trucos automáticamente
-
+
Guardar estado automáticamente
-
+
Cargar estado automáticamente
-
+
Hablitar Rich Presence en Discord
-
+
Avance rápido:
-
-
+
+
+
×
-
+
+
Sin límite
-
+
Habilitar el rebobinar
-
+
Hist. de rebobinado:
-
+
Bucles inactivos:
-
+
Ejecutarlos todos
-
+
Eliminar los conocidos
-
+
Detectar y eliminar
-
+
Guardar datos extra:
-
-
+
+
Pantallazo
-
-
+
+
Datos de guardado
-
-
+
+
Trucos
-
+
Cargar datos extra:
@@ -4770,119 +5118,119 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
El rebobinar afecta los datos de guardado
-
+
Cargar ROM completa a la memoria
-
+
Intervalo de turbo:
-
+
Renderizador de video:
-
+
Software
-
+
OpenGL
-
+
Mejoras para OpenGL
-
+
Escala de alta resolución:
-
+
Mejorar audio GBA (experimental)
-
+
Archivo BIOS GB:
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
Examinar
-
+
Usar archivo BIOS si fue encontrado
-
+
Saltar animación de entrada del BIOS
-
+
Archivo BIOS GBA:
-
+
Archivo BIOS GBC:
-
+
Archivo BIOS SGB:
-
+
Datos de guardado
-
-
-
-
-
+
+
+
+
+
Al mismo directorio que la ROM
-
+
Estados de guardado
-
+
Pantallazos
-
+
Parches
-
+
Trucos
@@ -4891,37 +5239,37 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Modelo de Game Boy
-
-
-
+
+
+
Detección automática
-
-
-
+
+
+
Game Boy (DMG)
-
-
-
+
+
+
-
-
-
+
+
+
Game Boy Color (CGB)
-
-
-
+
+
+
Game Boy Advance (AGB)
@@ -4934,27 +5282,27 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Modelo de Game Boy Color
-
+
Colores de fondo por defecto:
-
+
Bordes de Super Game Boy
-
+
Controlador de cámara:
-
+
Colores de sprite 1 por defecto:
-
+
Colores de sprite 2 por defecto:
@@ -5028,30 +5376,50 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd.
Tiles
-
+
+
+ Exportar seleccionados
+
+
+
+
+ Exportar todos
+
+
+
256 colores
-
+
×
-
+
Ampliación
-
+
Tiles por fila
-
+
Ajustar a ventana
+
+
+
+ Copiar seleccionados
+
+
+
+
+ Copiar todos
+
VideoView
diff --git a/src/platform/qt/ts/mgba-zh_CN.ts b/src/platform/qt/ts/mgba-zh_CN.ts
index f1979889f..6840ea2b2 100644
--- a/src/platform/qt/ts/mgba-zh_CN.ts
+++ b/src/platform/qt/ts/mgba-zh_CN.ts
@@ -310,34 +310,24 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标
录制 GIF
-
-
- 开始
-
-
-
-
- 停止
-
-
-
-
- 选择文件
-
-
-
+
跳帧
-
-
- 帧延迟 (ms)
+
+
+ 开始
-
-
- 自动设置
+
+
+ 停止
+
+
+
+
+ 选择文件
@@ -614,6 +604,40 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标
缩放率
+
+ MemoryDump
+
+
+
+ 保存内存范围
+
+
+
+
+ 起始地址:
+
+
+
+
+ :
+
+
+
+
+
+ 0x
+
+
+
+
+ 字节数:
+
+
+
+
+ 跨 bank 转储
+
+
MemorySearch
@@ -816,6 +840,11 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标
载入
+
+
+
+ 保存范围
+
ObjView
@@ -1405,22 +1434,22 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标
QGBA::CoreController
-
+
无法打开存档: %1
-
+
无法打开游戏文件: %1
-
+
无法读取快照文件: %1
-
+
无法写入快照文件: %1
@@ -1553,17 +1582,17 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标
QGBA::GIFView
-
+
无法打开输出的 GIF 文件: %1
-
+
选择输出文件
-
+
图形交换格式 (*.gif)
@@ -3445,12 +3474,12 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标
- 未载入着色器
+ 不载入着色器
- by %1
+ 由 %1
@@ -3460,7 +3489,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标
- Pass %1
+ 通道 %1
@@ -3515,108 +3544,108 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标
QGBA::Window
-
+
Game Boy Advance ROM (%1)
-
+
Game Boy ROM (%1)
-
+
所有 ROM (%1)
-
+
%1 视频日志 (*.mvl)
-
+
压缩文件 (%1)
-
-
-
+
+
+
选择 ROM
-
+
选择文件夹
-
+
Game Boy Advance 存档文件 (%1)
-
-
-
+
+
+
选择存档
-
+
mGBA 即时存档文件 (%1)
-
-
+
+
选择即时存档
-
+
选择补丁
-
+
补丁文件 (*.ips *.ups *.bps)
-
+
选择图片
-
+
图像文件 (*.png *.gif *.jpg *.jpeg);;所有文件 (*)
-
-
+
+
GameShark 存档 (*.sps *.xps)
-
+
选择视频日志
-
+
视频日志文件 (*.mvl)
-
+
崩溃
-
+
@@ -3625,578 +3654,578 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标
%1
-
+
无法载入
-
+
无法载入游戏。请确认游戏格式是否无误。
-
+
未实现的 BIOS 调用
-
+
该游戏使用了尚未实现的 BIOS 调用。请使用官方 BIOS 以获得最佳游戏体验。
-
+
确定进行程序便携化?
-
+
进行此操作后,模拟器将从模拟器可执行文件所在目录内加载模拟器配置。您想继续吗?
-
+
需要重新启动
-
+
更改将在模拟器下次启动时生效。
-
+
- 玩家 %1 共 %2
-
+
%1 - %2
-
+
%1 - %2 - %3
-
+
%1 - %2 (%3 fps) - %4
-
+
文件(&F)
-
+
载入 ROM(&R)...
-
+
从压缩文件中载入 ROM...
-
+
将文件夹添加到库中...
-
+
读取其他的存档...
-
+
读取临时存档...
-
+
载入补丁文件(&P)...
-
+
引导 BIOS
-
+
替换 ROM...
-
+
ROM 信息(&I)...
-
+
最近打开
-
+
程序便携化
-
+
读取即时存档(&L)
-
+
载入即时存档文件...
-
+
保存即时存档(&S)
-
+
保存即时存档文件...
-
+
快速读档
-
+
快速存档
-
+
载入最近
-
+
保存最近
-
+
撤消读档
-
+
撤消存档
+
-
即时存档 1(&1)
-
+
读取相机图片...
-
+
导入 GameShark 存档
-
+
导出 GameShark 存档
-
+
新建多人游戏窗口
-
+
关于...
-
+
退出(&X)
-
+
模拟(&E)
-
+
复位(&R)
-
+
关机(&U)
-
+
快速抽出游戏卡带
-
+
暂停(&P)
-
+
下一帧(&N)
-
+
快进 (长按)
-
+
快进(&F)
-
+
快进速度
-
+
不限制
-
+
%0x
-
+
回退 (长按)
-
+
回退(&W)
-
+
后退
-
+
视频同步(&V)
-
+
音频同步(&A)
-
+
光线传感器
-
+
增加光线级别
-
+
降低光线级别
-
+
光线级别为最亮
-
+
光线级别为最暗
-
+
亮度 %1
-
+
- Game Boy 打印机..
+ Game Boy 打印机...
-
+
BattleChip Gate...
-
+
音频/视频(&V)
-
+
帧率
-
+
%1×
-
+
切换全屏
-
+
锁定纵横比
-
+
强制整数缩放
-
+
帧间混合
-
+
双线性过滤
-
+
跳帧(&S)
-
+
静音
-
+
目标 FPS
-
+
原生 (59.7275)
-
+
截图(&S)
-
+
录制音频/视频...
-
+
录制 GIF...
-
+
视频图层
-
+
音频通道
-
+
- 调整图层布局
+ 调整图层布局...
-
+
工具(&T)
-
+
查看日志(&L)...
-
+
覆盖游戏(&O)...
-
-
- 游戏卡带传感器(&P)...
+
+
+ 游戏卡带传感器...
-
+
作弊码(&C)...
-
+
设置...
-
+
打开调试器控制台...
-
+
打开 GDB 服务器(&G)...
-
+
查看调色板(&P)...
-
+
- 查看精灵图(&S)
+ 查看精灵图(&S)...
-
+
- 查看瓷贴(&T)
+ 查看瓷贴(&T)...
-
+
- 查看映射(&M)
+ 查看映射(&M)...
-
-
- 框架检查
+
+
+ 框架检查(&F)
-
+
查看内存...
-
+
搜索内存...
-
+
查看 I/O 寄存器(&I)...
-
-
- 记录视频日志...
+
+
+ 记录调试视频日志...
-
-
- 停止记录视频日志
+
+
+ 停止记录调试视频日志
-
+
退出全屏
-
+
GameShark 键 (长按)
-
+
连发
-
+
连发 A
-
+
连发 B
-
+
连发 L
-
+
连发 R
-
+
连发 Start
-
+
连发 Select
-
+
连发 上
-
+
连发 右
-
+
连发 下
-
+
连发 左
-
+
清除
@@ -4648,6 +4677,11 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标
启用 Enable Discord Rich Presence
+
+
+
+ 最小化时暂停
+
@@ -4667,8 +4701,8 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标
不限制
-
-
+
+
快进 (按住) 速度:
@@ -4694,7 +4728,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标
- 运行所有
+ 运行全部
@@ -4949,7 +4983,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标
- 相机
+ 相机:
@@ -4982,7 +5016,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标
- 未载入着色器
+ 卸载着色器
@@ -5129,11 +5163,6 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标
MKV
-
-
-
- WebM
-
@@ -5211,12 +5240,12 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标
-
+
比特率 (kbps)
-
+
VBR
diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c
index f87caf667..45560cab4 100644
--- a/src/platform/switch/main.c
+++ b/src/platform/switch/main.c
@@ -20,7 +20,7 @@
#include
#define AUTO_INPUT 0x4E585031
-#define SAMPLES 0x400
+#define SAMPLES 0x200
#define BUFFER_SIZE 0x1000
#define N_BUFFERS 4
#define ANALOG_DEADZONE 0x4000
@@ -281,6 +281,8 @@ static void _setup(struct mGUIRunner* runner) {
if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode < SM_MAX) {
screenMode = mode;
}
+
+ runner->core->setAudioBufferSize(runner->core, SAMPLES);
}
static void _gameLoaded(struct mGUIRunner* runner) {
@@ -539,6 +541,11 @@ static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* rig
if (enqueuedBuffers >= N_BUFFERS - 1 && R_SUCCEEDED(audoutWaitPlayFinish(&releasedBuffers, &audoutNReleasedBuffers, 10000000))) {
enqueuedBuffers -= audoutNReleasedBuffers;
}
+ if (enqueuedBuffers >= N_BUFFERS) {
+ blip_clear(left);
+ blip_clear(right);
+ return;
+ }
struct GBAStereoSample* samples = audioBuffer[audioBufferActive];
blip_read_samples(left, &samples[0].left, SAMPLES, true);
@@ -754,7 +761,7 @@ int main(int argc, char* argv[]) {
audoutBuffer[i].next = NULL;
audoutBuffer[i].buffer = audioBuffer[i];
audoutBuffer[i].buffer_size = BUFFER_SIZE;
- audoutBuffer[i].data_size = BUFFER_SIZE;
+ audoutBuffer[i].data_size = SAMPLES * 4;
audoutBuffer[i].data_offset = 0;
}