mirror of https://github.com/mgba-emu/mgba.git
Merge branch 'master' (early part) into medusa
This commit is contained in:
commit
9dbd15c144
|
@ -1,5 +1,9 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
if [ $TRAVIS_OS_NAME = "osx" ]; then
|
if [ $TRAVIS_OS_NAME = "osx" ]; then
|
||||||
brew update
|
brew update
|
||||||
brew install qt5 ffmpeg imagemagick sdl2 libedit libelf libpng libzip
|
brew install qt5 ffmpeg imagemagick sdl2 libedit libelf libpng libzip
|
||||||
|
else
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get -y install libseccomp2
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -24,7 +24,7 @@ matrix:
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- '[ -z "$DOCKER_TAG" ] || docker pull mgba/$DOCKER_TAG'
|
- '[ -z "$DOCKER_TAG" ] || docker pull mgba/$DOCKER_TAG'
|
||||||
- '[ "$TRAVIS_OS_NAME" != "osx" ] || . ./.travis-deps.sh'
|
- '. ./.travis-deps.sh'
|
||||||
- 'mkdir build && chmod 777 build'
|
- 'mkdir build && chmod 777 build'
|
||||||
|
|
||||||
script:
|
script:
|
||||||
|
|
11
CHANGES
11
CHANGES
|
@ -54,6 +54,8 @@ Emulation fixes:
|
||||||
- GB Memory: Better emulate 0xFEA0 region on DMG, MGB and AGB
|
- 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 Video: Fix mode 0 window edge case (fixes mgba.io/i/1519)
|
||||||
- GB Audio: Fix channel 4 volume (fixes mgba.io/i/1529)
|
- 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:
|
Other fixes:
|
||||||
- Qt: Fix some Qt display driver race conditions
|
- Qt: Fix some Qt display driver race conditions
|
||||||
- Core: Improved lockstep driver reliability (Le Hoang Quyen)
|
- Core: Improved lockstep driver reliability (Le Hoang Quyen)
|
||||||
|
@ -64,6 +66,9 @@ Other fixes:
|
||||||
- Qt: Only show emulator restart warning once per settings saving
|
- Qt: Only show emulator restart warning once per settings saving
|
||||||
- FFmpeg: Drain recording buffers
|
- FFmpeg: Drain recording buffers
|
||||||
- Shaders: Fix gba-color shader resolution (fixes mgba.io/i/1435)
|
- 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:
|
Misc:
|
||||||
- GBA Savedata: EEPROM performance fixes
|
- GBA Savedata: EEPROM performance fixes
|
||||||
- GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash
|
- GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash
|
||||||
|
@ -94,6 +99,12 @@ Misc:
|
||||||
- OpenGL: Only resize textures when needed
|
- OpenGL: Only resize textures when needed
|
||||||
- GBA BIOS: Fix clobbered registers in CpuSet (fixes mgba.io/i/1531)
|
- GBA BIOS: Fix clobbered registers in CpuSet (fixes mgba.io/i/1531)
|
||||||
- Qt: Remove What's This icon from dialogs
|
- 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)
|
0.7.3: (2019-09-15)
|
||||||
Emulation fixes:
|
Emulation fixes:
|
||||||
|
|
|
@ -250,6 +250,7 @@ if(DEFINED 3DS OR DEFINED PSP2 OR DEFINED WII OR DEFINED SWITCH)
|
||||||
set(USE_DEBUGGERS OFF)
|
set(USE_DEBUGGERS OFF)
|
||||||
set(USE_SQLITE3 OFF)
|
set(USE_SQLITE3 OFF)
|
||||||
set(USE_DISCORD_RPC OFF)
|
set(USE_DISCORD_RPC OFF)
|
||||||
|
set(USE_LIBZIP OFF CACHE BOOL "")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(DEFINED 3DS)
|
if(DEFINED 3DS)
|
||||||
|
|
|
@ -93,7 +93,7 @@ Other Unix-like platforms, such as OpenBSD, are known to work as well, but are u
|
||||||
|
|
||||||
### System requirements
|
### System requirements
|
||||||
|
|
||||||
Requirements are minimal[<sup>[2]</sup>](#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[<sup>[2]</sup>](#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
|
Downloads
|
||||||
---------
|
---------
|
||||||
|
|
|
@ -86,7 +86,7 @@ Andere Unix-ähnliche Plattformen wie OpenBSD sind ebenfalls dafür bekannt, mit
|
||||||
|
|
||||||
### Systemvoraussetzungen
|
### 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
|
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:
|
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
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -DCMAKE_PREFIX_PATH='brew --prefix qt5' ..
|
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):
|
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):
|
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:
|
Lade den aktuellen mGBA-Quellcode mithilfe des folgenden Kommandos herunter:
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 6.0 KiB |
|
@ -22,7 +22,11 @@ enum mCoreMemorySearchOp {
|
||||||
mCORE_MEMORY_SEARCH_EQUAL,
|
mCORE_MEMORY_SEARCH_EQUAL,
|
||||||
mCORE_MEMORY_SEARCH_GREATER,
|
mCORE_MEMORY_SEARCH_GREATER,
|
||||||
mCORE_MEMORY_SEARCH_LESS,
|
mCORE_MEMORY_SEARCH_LESS,
|
||||||
|
mCORE_MEMORY_SEARCH_ANY,
|
||||||
mCORE_MEMORY_SEARCH_DELTA,
|
mCORE_MEMORY_SEARCH_DELTA,
|
||||||
|
mCORE_MEMORY_SEARCH_DELTA_POSITIVE,
|
||||||
|
mCORE_MEMORY_SEARCH_DELTA_NEGATIVE,
|
||||||
|
mCORE_MEMORY_SEARCH_DELTA_ANY,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mCoreMemorySearchParams {
|
struct mCoreMemorySearchParams {
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
Jaime J. Denizard
|
Jaime J. Denizard
|
||||||
Fog
|
Benedikt Feih
|
||||||
Philip Horton
|
|
||||||
Oskenso Kashi
|
Oskenso Kashi
|
||||||
|
The Libretro Team
|
||||||
Mored1984
|
Mored1984
|
||||||
Rohit Nirmal
|
|
||||||
Rhys Powell
|
Rhys Powell
|
||||||
|
Johnathan Roatch
|
||||||
Yuri Kunde Schlesner
|
Yuri Kunde Schlesner
|
||||||
|
Voidheim
|
||||||
|
|
|
@ -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_EQUAL:
|
||||||
case mCORE_MEMORY_SEARCH_DELTA:
|
case mCORE_MEMORY_SEARCH_DELTA:
|
||||||
return value == match;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -244,20 +252,20 @@ bool _testGuess(struct mCore* core, struct mCoreMemorySearchResult* res, const s
|
||||||
int64_t value;
|
int64_t value;
|
||||||
int32_t offset = 0;
|
int32_t offset = 0;
|
||||||
char* end;
|
char* end;
|
||||||
if (params->op == mCORE_MEMORY_SEARCH_DELTA) {
|
if (params->op >= mCORE_MEMORY_SEARCH_DELTA) {
|
||||||
offset = res->oldValue;
|
offset = res->oldValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = strtoll(params->valueStr, &end, 10);
|
value = strtoll(params->valueStr, &end, 10);
|
||||||
if (end) {
|
if (end) {
|
||||||
res->oldValue += value;
|
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;
|
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;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
res->oldValue -= value;
|
res->oldValue -= value;
|
||||||
|
@ -266,13 +274,13 @@ bool _testGuess(struct mCore* core, struct mCoreMemorySearchResult* res, const s
|
||||||
value = strtoll(params->valueStr, &end, 16);
|
value = strtoll(params->valueStr, &end, 16);
|
||||||
if (end) {
|
if (end) {
|
||||||
res->oldValue += value;
|
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;
|
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;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
res->oldValue -= value;
|
res->oldValue -= value;
|
||||||
|
@ -293,10 +301,7 @@ void mCoreMemorySearchRepeat(struct mCore* core, const struct mCoreMemorySearchP
|
||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
} else if (params->type == mCORE_MEMORY_SEARCH_INT) {
|
} else if (params->type == mCORE_MEMORY_SEARCH_INT) {
|
||||||
int32_t oldValue = params->valueInt;
|
int32_t match = params->valueInt;
|
||||||
if (params->op == mCORE_MEMORY_SEARCH_DELTA) {
|
|
||||||
oldValue += res->oldValue;
|
|
||||||
}
|
|
||||||
int32_t value = 0;
|
int32_t value = 0;
|
||||||
switch (params->width) {
|
switch (params->width) {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -311,7 +316,11 @@ void mCoreMemorySearchRepeat(struct mCore* core, const struct mCoreMemorySearchP
|
||||||
default:
|
default:
|
||||||
break;
|
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);
|
*res = *mCoreMemorySearchResultsGetPointer(inout, mCoreMemorySearchResultsSize(inout) - 1);
|
||||||
mCoreMemorySearchResultsResize(inout, -1);
|
mCoreMemorySearchResultsResize(inout, -1);
|
||||||
--i;
|
--i;
|
||||||
|
@ -322,7 +331,7 @@ void mCoreMemorySearchRepeat(struct mCore* core, const struct mCoreMemorySearchP
|
||||||
break;
|
break;
|
||||||
case mCORE_MEMORY_SEARCH_STRING:
|
case mCORE_MEMORY_SEARCH_STRING:
|
||||||
case mCORE_MEMORY_SEARCH_GUESS:
|
case mCORE_MEMORY_SEARCH_GUESS:
|
||||||
// TOOD
|
// TODO
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
46
src/gb/gb.c
46
src/gb/gb.c
|
@ -415,23 +415,6 @@ void GBReset(struct LR35902Core* cpu) {
|
||||||
gb->memory.romBase = gb->memory.rom;
|
gb->memory.romBase = gb->memory.rom;
|
||||||
GBDetectModel(gb);
|
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->b = 0;
|
||||||
cpu->d = 0;
|
cpu->d = 0;
|
||||||
|
|
||||||
|
@ -457,6 +440,24 @@ void GBReset(struct LR35902Core* cpu) {
|
||||||
mTimingClear(&gb->timing);
|
mTimingClear(&gb->timing);
|
||||||
|
|
||||||
GBMemoryReset(gb);
|
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);
|
GBVideoReset(&gb->video);
|
||||||
GBTimerReset(&gb->timer);
|
GBTimerReset(&gb->timer);
|
||||||
if (!gb->biosVf) {
|
if (!gb->biosVf) {
|
||||||
|
@ -561,18 +562,23 @@ void GBSkipBIOS(struct GB* gb) {
|
||||||
|
|
||||||
void GBMapBIOS(struct GB* gb) {
|
void GBMapBIOS(struct GB* gb) {
|
||||||
gb->biosVf->seek(gb->biosVf, 0, SEEK_SET);
|
gb->biosVf->seek(gb->biosVf, 0, SEEK_SET);
|
||||||
|
uint8_t* oldRomBase = gb->memory.romBase;
|
||||||
gb->memory.romBase = malloc(GB_SIZE_CART_BANK0);
|
gb->memory.romBase = malloc(GB_SIZE_CART_BANK0);
|
||||||
ssize_t size = gb->biosVf->read(gb->biosVf, gb->memory.romBase, 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) {
|
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) {
|
void GBUnmapBIOS(struct GB* gb) {
|
||||||
if (gb->memory.romBase < gb->memory.rom || gb->memory.romBase > &gb->memory.rom[gb->memory.romSize - 1]) {
|
if (gb->memory.romBase < gb->memory.rom || gb->memory.romBase > &gb->memory.rom[gb->memory.romSize - 1]) {
|
||||||
free(gb->memory.romBase);
|
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
|
// XXX: Force AGB registers for AGB-mode
|
||||||
if (gb->model == GB_MODEL_AGB && gb->cpu->pc == 0x100) {
|
if (gb->model == GB_MODEL_AGB && gb->cpu->pc == 0x100) {
|
||||||
|
|
|
@ -461,8 +461,11 @@ static void GBVideoSoftwareRendererWritePalette(struct GBVideoRenderer* renderer
|
||||||
color = mColorFrom555(r | (g << 5) | (b << 10));
|
color = mColorFrom555(r | (g << 5) | (b << 10));
|
||||||
#else
|
#else
|
||||||
r >>= 2;
|
r >>= 2;
|
||||||
|
r += r >> 4;
|
||||||
g >>= 2;
|
g >>= 2;
|
||||||
|
g += g >> 4;
|
||||||
b >>= 2;
|
b >>= 2;
|
||||||
|
b += b >> 4;
|
||||||
color = r | (g << 8) | (b << 16);
|
color = r | (g << 8) | (b << 16);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ static const GLchar* const _gles3Header =
|
||||||
"precision highp isampler2D;\n";
|
"precision highp isampler2D;\n";
|
||||||
|
|
||||||
static const GLchar* const _gl3Header =
|
static const GLchar* const _gl3Header =
|
||||||
"#version 130\n"
|
"#version 150 core\n"
|
||||||
"#define OUT(n)\n"
|
"#define OUT(n)\n"
|
||||||
PALETTE_ENTRY
|
PALETTE_ENTRY
|
||||||
"precision highp float;\n";
|
"precision highp float;\n";
|
||||||
|
|
|
@ -141,6 +141,8 @@ static void GBAVideoSoftwareRendererReset(struct GBAVideoRenderer* renderer) {
|
||||||
memset(softwareRenderer->cache, 0, sizeof(softwareRenderer->cache));
|
memset(softwareRenderer->cache, 0, sizeof(softwareRenderer->cache));
|
||||||
memset(softwareRenderer->nextIo, 0, sizeof(softwareRenderer->nextIo));
|
memset(softwareRenderer->nextIo, 0, sizeof(softwareRenderer->nextIo));
|
||||||
|
|
||||||
|
softwareRenderer->lastHighlightAmount = 0;
|
||||||
|
|
||||||
for (i = 0; i < 4; ++i) {
|
for (i = 0; i < 4; ++i) {
|
||||||
struct GBAVideoSoftwareBackground* bg = &softwareRenderer->bg[i];
|
struct GBAVideoSoftwareBackground* bg = &softwareRenderer->bg[i];
|
||||||
bg->index = i;
|
bg->index = i;
|
||||||
|
|
|
@ -21,8 +21,17 @@ static const GLchar* const _gles2Header =
|
||||||
"#version 100\n"
|
"#version 100\n"
|
||||||
"precision mediump float;\n";
|
"precision mediump float;\n";
|
||||||
|
|
||||||
static const GLchar* const _gl3Header =
|
static const GLchar* const _gl32VHeader =
|
||||||
"#version 120\n";
|
"#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 =
|
static const char* const _vertexShader =
|
||||||
"attribute vec4 position;\n"
|
"attribute vec4 position;\n"
|
||||||
|
@ -449,7 +458,7 @@ void mGLES2ShaderInit(struct mGLES2Shader* shader, const char* vs, const char* f
|
||||||
const GLchar* shaderBuffer[2];
|
const GLchar* shaderBuffer[2];
|
||||||
const GLubyte* version = glGetString(GL_VERSION);
|
const GLubyte* version = glGetString(GL_VERSION);
|
||||||
if (strncmp((const char*) version, "OpenGL ES ", strlen("OpenGL ES "))) {
|
if (strncmp((const char*) version, "OpenGL ES ", strlen("OpenGL ES "))) {
|
||||||
shaderBuffer[0] = _gl3Header;
|
shaderBuffer[0] = _gl32VHeader;
|
||||||
} else {
|
} else {
|
||||||
shaderBuffer[0] = _gles2Header;
|
shaderBuffer[0] = _gles2Header;
|
||||||
}
|
}
|
||||||
|
@ -460,6 +469,9 @@ void mGLES2ShaderInit(struct mGLES2Shader* shader, const char* vs, const char* f
|
||||||
}
|
}
|
||||||
glShaderSource(shader->vertexShader, 2, shaderBuffer, 0);
|
glShaderSource(shader->vertexShader, 2, shaderBuffer, 0);
|
||||||
|
|
||||||
|
if (strncmp((const char*) version, "OpenGL ES ", strlen("OpenGL ES "))) {
|
||||||
|
shaderBuffer[0] = _gl32FHeader;
|
||||||
|
}
|
||||||
if (fs) {
|
if (fs) {
|
||||||
shaderBuffer[1] = fs;
|
shaderBuffer[1] = fs;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -116,6 +116,9 @@ void AssetTile::selectIndex(int index) {
|
||||||
m_ui.preview->setColor(i ^ flip, data[i]);
|
m_ui.preview->setColor(i ^ flip, data[i]);
|
||||||
}
|
}
|
||||||
m_ui.preview->update();
|
m_ui.preview->update();
|
||||||
|
|
||||||
|
QImage tile(reinterpret_cast<const uchar*>(data), 8, 8, QImage::Format_ARGB32);
|
||||||
|
m_activeTile = tile.rgbSwapped();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetTile::setFlip(bool h, bool v) {
|
void AssetTile::setFlip(bool h, bool v) {
|
||||||
|
|
|
@ -21,6 +21,7 @@ Q_OBJECT
|
||||||
public:
|
public:
|
||||||
AssetTile(QWidget* parent = nullptr);
|
AssetTile(QWidget* parent = nullptr);
|
||||||
void setController(std::shared_ptr<CoreController>);
|
void setController(std::shared_ptr<CoreController>);
|
||||||
|
QImage activeTile() const { return m_activeTile; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setPalette(int);
|
void setPalette(int);
|
||||||
|
@ -48,6 +49,7 @@ private:
|
||||||
bool m_flipV = false;
|
bool m_flipV = false;
|
||||||
|
|
||||||
QMap<QString, QLabel*> m_customProperties;
|
QMap<QString, QLabel*> m_customProperties;
|
||||||
|
QImage m_activeTile;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,8 @@ Display* Display::create(QWidget* parent) {
|
||||||
switch (s_driver) {
|
switch (s_driver) {
|
||||||
#if defined(BUILD_GL) || defined(BUILD_GLES2) || defined(USE_EPOXY)
|
#if defined(BUILD_GL) || defined(BUILD_GLES2) || defined(USE_EPOXY)
|
||||||
case Driver::OPENGL:
|
case Driver::OPENGL:
|
||||||
format.setVersion(3, 0);
|
format.setVersion(3, 2);
|
||||||
|
format.setProfile(QSurfaceFormat::CoreProfile);
|
||||||
return new DisplayGL(format, parent);
|
return new DisplayGL(format, parent);
|
||||||
#endif
|
#endif
|
||||||
#ifdef BUILD_GL
|
#ifdef BUILD_GL
|
||||||
|
@ -91,6 +92,10 @@ void Display::interframeBlending(bool lock) {
|
||||||
m_interframeBlending = lock;
|
m_interframeBlending = lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Display::showOSDMessages(bool enable) {
|
||||||
|
m_showOSD = enable;
|
||||||
|
}
|
||||||
|
|
||||||
void Display::filter(bool filter) {
|
void Display::filter(bool filter) {
|
||||||
m_filter = filter;
|
m_filter = filter;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
bool isIntegerScalingLocked() const { return m_lockIntegerScaling; }
|
bool isIntegerScalingLocked() const { return m_lockIntegerScaling; }
|
||||||
bool hasInterframeBlending() const { return m_interframeBlending; }
|
bool hasInterframeBlending() const { return m_interframeBlending; }
|
||||||
bool isFiltered() const { return m_filter; }
|
bool isFiltered() const { return m_filter; }
|
||||||
|
bool isShowOSD() const { return m_showOSD; }
|
||||||
|
|
||||||
virtual void startDrawing(std::shared_ptr<CoreController>) = 0;
|
virtual void startDrawing(std::shared_ptr<CoreController>) = 0;
|
||||||
virtual bool isDrawing() const = 0;
|
virtual bool isDrawing() const = 0;
|
||||||
|
@ -68,6 +69,7 @@ public slots:
|
||||||
virtual void lockAspectRatio(bool lock);
|
virtual void lockAspectRatio(bool lock);
|
||||||
virtual void lockIntegerScaling(bool lock);
|
virtual void lockIntegerScaling(bool lock);
|
||||||
virtual void interframeBlending(bool enable);
|
virtual void interframeBlending(bool enable);
|
||||||
|
virtual void showOSDMessages(bool enable);
|
||||||
virtual void filter(bool filter);
|
virtual void filter(bool filter);
|
||||||
virtual void framePosted() = 0;
|
virtual void framePosted() = 0;
|
||||||
virtual void setShaders(struct VDir*) = 0;
|
virtual void setShaders(struct VDir*) = 0;
|
||||||
|
@ -89,6 +91,7 @@ private:
|
||||||
static const int MOUSE_DISAPPEAR_TIMER = 1000;
|
static const int MOUSE_DISAPPEAR_TIMER = 1000;
|
||||||
|
|
||||||
MessagePainter m_messagePainter;
|
MessagePainter m_messagePainter;
|
||||||
|
bool m_showOSD = true;
|
||||||
bool m_lockAspectRatio = false;
|
bool m_lockAspectRatio = false;
|
||||||
bool m_lockIntegerScaling = false;
|
bool m_lockIntegerScaling = false;
|
||||||
bool m_interframeBlending = false;
|
bool m_interframeBlending = false;
|
||||||
|
|
|
@ -114,6 +114,7 @@ void DisplayGL::startDrawing(std::shared_ptr<CoreController> controller) {
|
||||||
lockAspectRatio(isAspectRatioLocked());
|
lockAspectRatio(isAspectRatioLocked());
|
||||||
lockIntegerScaling(isIntegerScalingLocked());
|
lockIntegerScaling(isIntegerScalingLocked());
|
||||||
interframeBlending(hasInterframeBlending());
|
interframeBlending(hasInterframeBlending());
|
||||||
|
showOSDMessages(isShowOSD());
|
||||||
filter(isFiltered());
|
filter(isFiltered());
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||||
messagePainter()->resize(size(), isAspectRatioLocked(), devicePixelRatioF());
|
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) {
|
void DisplayGL::filter(bool filter) {
|
||||||
Display::filter(filter);
|
Display::filter(filter);
|
||||||
if (m_drawThread) {
|
if (m_drawThread) {
|
||||||
|
@ -353,6 +361,7 @@ void PainterGL::setMessagePainter(MessagePainter* messagePainter) {
|
||||||
|
|
||||||
void PainterGL::resize(const QSize& size) {
|
void PainterGL::resize(const QSize& size) {
|
||||||
m_size = size;
|
m_size = size;
|
||||||
|
m_window->setSize(m_size);
|
||||||
if (m_started && !m_active) {
|
if (m_started && !m_active) {
|
||||||
forceDraw();
|
forceDraw();
|
||||||
}
|
}
|
||||||
|
@ -372,6 +381,10 @@ void PainterGL::interframeBlending(bool enable) {
|
||||||
m_backend->interframeBlending = enable;
|
m_backend->interframeBlending = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PainterGL::showOSD(bool enable) {
|
||||||
|
m_showOSD = enable;
|
||||||
|
}
|
||||||
|
|
||||||
void PainterGL::filter(bool filter) {
|
void PainterGL::filter(bool filter) {
|
||||||
m_backend->filter = filter;
|
m_backend->filter = filter;
|
||||||
if (m_started && !m_active) {
|
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->resized(m_backend, m_size.width() * r, m_size.height() * r);
|
||||||
m_backend->drawFrame(m_backend);
|
m_backend->drawFrame(m_backend);
|
||||||
m_painter.endNativePainting();
|
m_painter.endNativePainting();
|
||||||
if (m_messagePainter) {
|
if (m_showOSD && m_messagePainter) {
|
||||||
m_messagePainter->paint(&m_painter);
|
m_messagePainter->paint(&m_painter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
|
|
||||||
#include "platform/video-backend.h"
|
#include "platform/video-backend.h"
|
||||||
|
|
||||||
|
class QOpenGLPaintDevice;
|
||||||
|
|
||||||
namespace QGBA {
|
namespace QGBA {
|
||||||
|
|
||||||
class PainterGL;
|
class PainterGL;
|
||||||
|
@ -54,6 +56,7 @@ public slots:
|
||||||
void lockAspectRatio(bool lock) override;
|
void lockAspectRatio(bool lock) override;
|
||||||
void lockIntegerScaling(bool lock) override;
|
void lockIntegerScaling(bool lock) override;
|
||||||
void interframeBlending(bool enable) override;
|
void interframeBlending(bool enable) override;
|
||||||
|
void showOSDMessages(bool enable) override;
|
||||||
void filter(bool filter) override;
|
void filter(bool filter) override;
|
||||||
void framePosted() override;
|
void framePosted() override;
|
||||||
void setShaders(struct VDir*) override;
|
void setShaders(struct VDir*) override;
|
||||||
|
@ -100,6 +103,7 @@ public slots:
|
||||||
void lockAspectRatio(bool lock);
|
void lockAspectRatio(bool lock);
|
||||||
void lockIntegerScaling(bool lock);
|
void lockIntegerScaling(bool lock);
|
||||||
void interframeBlending(bool enable);
|
void interframeBlending(bool enable);
|
||||||
|
void showOSD(bool enable);
|
||||||
void filter(bool filter);
|
void filter(bool filter);
|
||||||
void resizeContext();
|
void resizeContext();
|
||||||
|
|
||||||
|
@ -119,12 +123,13 @@ private:
|
||||||
QPainter m_painter;
|
QPainter m_painter;
|
||||||
QMutex m_mutex;
|
QMutex m_mutex;
|
||||||
QWindow* m_surface;
|
QWindow* m_surface;
|
||||||
QPaintDevice* m_window;
|
QOpenGLPaintDevice* m_window;
|
||||||
QOpenGLContext* m_gl;
|
QOpenGLContext* m_gl;
|
||||||
bool m_active = false;
|
bool m_active = false;
|
||||||
bool m_started = false;
|
bool m_started = false;
|
||||||
std::shared_ptr<CoreController> m_context = nullptr;
|
std::shared_ptr<CoreController> m_context = nullptr;
|
||||||
bool m_supportsShaders;
|
bool m_supportsShaders;
|
||||||
|
bool m_showOSD;
|
||||||
VideoShader m_shader{};
|
VideoShader m_shader{};
|
||||||
VideoBackend* m_backend = nullptr;
|
VideoBackend* m_backend = nullptr;
|
||||||
QSize m_size;
|
QSize m_size;
|
||||||
|
|
|
@ -123,5 +123,7 @@ void DisplayQt::paintEvent(QPaintEvent*) {
|
||||||
}
|
}
|
||||||
painter.drawImage(full, m_backing, QRect(0, 0, m_width, m_height));
|
painter.drawImage(full, m_backing, QRect(0, 0, m_width, m_height));
|
||||||
painter.setOpacity(1);
|
painter.setOpacity(1);
|
||||||
messagePainter()->paint(&painter);
|
if (isShowOSD()) {
|
||||||
|
messagePainter()->paint(&painter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,9 @@
|
||||||
#include <mgba/internal/gb/memory.h>
|
#include <mgba/internal/gb/memory.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
#include <QButtonGroup>
|
#include <QButtonGroup>
|
||||||
|
#include <QClipboard>
|
||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QRadioButton>
|
#include <QRadioButton>
|
||||||
|
@ -88,11 +90,19 @@ MapView::MapView(std::shared_ptr<CoreController> controller, QWidget* parent)
|
||||||
});
|
});
|
||||||
group->addButton(button);
|
group->addButton(button);
|
||||||
}
|
}
|
||||||
#ifdef USE_PNG
|
|
||||||
connect(m_ui.exportButton, &QAbstractButton::clicked, this, &MapView::exportMap);
|
connect(m_ui.exportButton, &QAbstractButton::clicked, this, &MapView::exportMap);
|
||||||
#else
|
connect(m_ui.copyButton, &QAbstractButton::clicked, this, &MapView::copyMap);
|
||||||
m_ui.exportButton->setVisible(false);
|
|
||||||
#endif
|
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.map->installEventFilter(this);
|
||||||
m_ui.tile->addCustomProperty("mapAddr", tr("Map Addr."));
|
m_ui.tile->addCustomProperty("mapAddr", tr("Map Addr."));
|
||||||
m_ui.tile->addCustomProperty("flip", tr("Mirror"));
|
m_ui.tile->addCustomProperty("flip", tr("Mirror"));
|
||||||
|
@ -211,7 +221,7 @@ void MapView::updateTilesGBA(bool force) {
|
||||||
mBitmapCacheCleanRow(bitmapCache, m_bitmapStatus, j);
|
mBitmapCacheCleanRow(bitmapCache, m_bitmapStatus, j);
|
||||||
memcpy(static_cast<void*>(&bgBits[width * j * 4]), mBitmapCacheGetRow(bitmapCache, j), width * 4);
|
memcpy(static_cast<void*>(&bgBits[width * j * 4]), mBitmapCacheGetRow(bitmapCache, j), width * 4);
|
||||||
}
|
}
|
||||||
m_rawMap = m_rawMap.rgbSwapped();
|
m_rawMap = m_rawMap.convertToFormat(QImage::Format_RGB32).rgbSwapped();
|
||||||
} else {
|
} else {
|
||||||
mMapCache* mapCache = mMapCacheSetGetPointer(&m_cacheSet->maps, m_map);
|
mMapCache* mapCache = mMapCacheSetGetPointer(&m_cacheSet->maps, m_map);
|
||||||
int tilesW = 1 << mMapCacheSystemInfoGetTilesWide(mapCache->sysConfig);
|
int tilesW = 1 << mMapCacheSystemInfoGetTilesWide(mapCache->sysConfig);
|
||||||
|
@ -242,23 +252,18 @@ void MapView::updateTilesGB(bool force) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_PNG
|
|
||||||
void MapView::exportMap() {
|
void MapView::exportMap() {
|
||||||
QString filename = GBAApp::app()->getSaveFileName(this, tr("Export map"),
|
QString filename = GBAApp::app()->getSaveFileName(this, tr("Export map"),
|
||||||
tr("Portable Network Graphics (*.png)"));
|
tr("Portable Network Graphics (*.png)"));
|
||||||
VFile* vf = VFileDevice::open(filename, O_WRONLY | O_CREAT | O_TRUNC);
|
if (filename.isNull()) {
|
||||||
if (!vf) {
|
|
||||||
LOG(QT, ERROR) << tr("Failed to open output PNG file: %1").arg(filename);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CoreController::Interrupter interrupter(m_controller);
|
CoreController::Interrupter interrupter(m_controller);
|
||||||
png_structp png = PNGWriteOpen(vf);
|
m_rawMap.save(filename, "PNG");
|
||||||
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<const void*>(map.constBits()));
|
|
||||||
PNGWriteClose(png, info);
|
|
||||||
vf->close(vf);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
void MapView::copyMap() {
|
||||||
|
CoreController::Interrupter interrupter(m_controller);
|
||||||
|
GBAApp::app()->clipboard()->setImage(m_rawMap);
|
||||||
|
}
|
|
@ -21,10 +21,9 @@ Q_OBJECT
|
||||||
public:
|
public:
|
||||||
MapView(std::shared_ptr<CoreController> controller, QWidget* parent = nullptr);
|
MapView(std::shared_ptr<CoreController> controller, QWidget* parent = nullptr);
|
||||||
|
|
||||||
#ifdef USE_PNG
|
|
||||||
public slots:
|
public slots:
|
||||||
void exportMap();
|
void exportMap();
|
||||||
#endif
|
void copyMap();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void selectMap(int);
|
void selectMap(int);
|
||||||
|
|
|
@ -13,38 +13,7 @@
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Maps</string>
|
<string>Maps</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0,0,0">
|
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0,0,0,0">
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QGBA::AssetTile" name="tile"/>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QGBA::AssetInfo" name="bgInfo">
|
|
||||||
<property name="title">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2"/>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QPushButton" name="exportButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Export</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<layout class="QVBoxLayout" name="bgLayout">
|
<layout class="QVBoxLayout" name="bgLayout">
|
||||||
<item>
|
<item>
|
||||||
|
@ -79,7 +48,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1" rowspan="5" colspan="2">
|
<item row="1" column="1" rowspan="6" colspan="2">
|
||||||
<widget class="QScrollArea" name="scrollArea">
|
<widget class="QScrollArea" name="scrollArea">
|
||||||
<property name="widgetResizable">
|
<property name="widgetResizable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -133,21 +102,59 @@
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QGBA::AssetTile" name="tile"/>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QPushButton" name="exportButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Export</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QGBA::AssetInfo" name="bgInfo">
|
||||||
|
<property name="title">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QPushButton" name="copyButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
|
||||||
<class>QGBA::AssetInfo</class>
|
|
||||||
<extends>QGroupBox</extends>
|
|
||||||
<header>AssetInfo.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>QGBA::AssetTile</class>
|
<class>QGBA::AssetTile</class>
|
||||||
<extends>QGroupBox</extends>
|
<extends>QGroupBox</extends>
|
||||||
<header>AssetTile.h</header>
|
<header>AssetTile.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>QGBA::AssetInfo</class>
|
||||||
|
<extends>QGroupBox</extends>
|
||||||
|
<header>AssetInfo.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|
|
@ -35,19 +35,28 @@ MemorySearch::~MemorySearch() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MemorySearch::createParams(mCoreMemorySearchParams* params) {
|
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;
|
mCore* core = m_controller->thread()->core;
|
||||||
|
|
||||||
QByteArray string;
|
QByteArray string;
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
if (m_ui.typeNum->isChecked()) {
|
if (m_ui.typeNum->isChecked()) {
|
||||||
params->type = mCORE_MEMORY_SEARCH_INT;
|
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;
|
params->op = mCORE_MEMORY_SEARCH_DELTA;
|
||||||
} else if (m_ui.opGreater->isChecked()) {
|
} else if (m_ui.opGreater->isChecked()) {
|
||||||
params->op = mCORE_MEMORY_SEARCH_GREATER;
|
params->op = mCORE_MEMORY_SEARCH_GREATER;
|
||||||
} else if (m_ui.opLess->isChecked()) {
|
} else if (m_ui.opLess->isChecked()) {
|
||||||
params->op = mCORE_MEMORY_SEARCH_LESS;
|
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 {
|
} else {
|
||||||
params->op = mCORE_MEMORY_SEARCH_EQUAL;
|
params->op = mCORE_MEMORY_SEARCH_EQUAL;
|
||||||
}
|
}
|
||||||
|
@ -103,9 +112,15 @@ bool MemorySearch::createParams(mCoreMemorySearchParams* params) {
|
||||||
}
|
}
|
||||||
if (m_ui.numGuess->isChecked()) {
|
if (m_ui.numGuess->isChecked()) {
|
||||||
params->type = mCORE_MEMORY_SEARCH_GUESS;
|
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();
|
params->valueStr = m_string.constData();
|
||||||
ok = true;
|
ok = true;
|
||||||
|
} else if (m_ui.opDelta0->isChecked()) {
|
||||||
|
params->valueInt = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_ui.typeStr->isChecked()) {
|
if (m_ui.typeStr->isChecked()) {
|
||||||
|
@ -140,6 +155,9 @@ void MemorySearch::searchWithin() {
|
||||||
mCore* core = m_controller->thread()->core;
|
mCore* core = m_controller->thread()->core;
|
||||||
|
|
||||||
if (createParams(¶ms)) {
|
if (createParams(¶ms)) {
|
||||||
|
if (m_ui.opUnknown->isChecked()) {
|
||||||
|
params.op = mCORE_MEMORY_SEARCH_DELTA_ANY;
|
||||||
|
}
|
||||||
mCoreMemorySearchRepeat(core, ¶ms, &m_results);
|
mCoreMemorySearchRepeat(core, ¶ms, &m_results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,6 +171,9 @@ void MemorySearch::refresh() {
|
||||||
m_ui.results->clearContents();
|
m_ui.results->clearContents();
|
||||||
m_ui.results->setRowCount(mCoreMemorySearchResultsSize(&m_results));
|
m_ui.results->setRowCount(mCoreMemorySearchResultsSize(&m_results));
|
||||||
m_ui.opDelta->setEnabled(false);
|
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) {
|
for (size_t i = 0; i < mCoreMemorySearchResultsSize(&m_results); ++i) {
|
||||||
mCoreMemorySearchResult* result = mCoreMemorySearchResultsGetPointer(&m_results, i);
|
mCoreMemorySearchResult* result = mCoreMemorySearchResultsGetPointer(&m_results, i);
|
||||||
QTableWidgetItem* item = new QTableWidgetItem(QString("%1").arg(result->address, 8, 16, QChar('0')));
|
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, 1, item);
|
||||||
m_ui.results->setItem(i, 2, type);
|
m_ui.results->setItem(i, 2, type);
|
||||||
m_ui.opDelta->setEnabled(true);
|
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()) {
|
if (m_ui.opDelta->isChecked() && !m_ui.opDelta->isEnabled()) {
|
||||||
m_ui.opEqual->setChecked(true);
|
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);
|
m_ui.results->sortItems(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,14 +6,20 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>540</width>
|
<width>725</width>
|
||||||
<height>491</height>
|
<height>813</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>540</width>
|
<width>540</width>
|
||||||
<height>241</height>
|
<height>400</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -99,21 +105,21 @@
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0" colspan="2">
|
<item row="4" column="0" colspan="2">
|
||||||
<widget class="Line" name="line">
|
<widget class="Line" name="line">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0">
|
<item row="5" column="0">
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QLabel" name="label_3">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Width</string>
|
<string>Width</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="5" column="1">
|
||||||
<widget class="QRadioButton" name="bitsGuess">
|
<widget class="QRadioButton" name="bitsGuess">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Guess</string>
|
<string>Guess</string>
|
||||||
|
@ -126,7 +132,7 @@
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1">
|
<item row="6" column="1">
|
||||||
<widget class="QRadioButton" name="bits8">
|
<widget class="QRadioButton" name="bits8">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>1 Byte (8-bit)</string>
|
<string>1 Byte (8-bit)</string>
|
||||||
|
@ -136,7 +142,7 @@
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="1">
|
<item row="7" column="1">
|
||||||
<widget class="QRadioButton" name="bits16">
|
<widget class="QRadioButton" name="bits16">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>2 Bytes (16-bit)</string>
|
<string>2 Bytes (16-bit)</string>
|
||||||
|
@ -146,7 +152,7 @@
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="1">
|
<item row="8" column="1">
|
||||||
<widget class="QRadioButton" name="bits32">
|
<widget class="QRadioButton" name="bits32">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>4 Bytes (32-bit)</string>
|
<string>4 Bytes (32-bit)</string>
|
||||||
|
@ -159,21 +165,21 @@
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="0" colspan="2">
|
<item row="9" column="0" colspan="2">
|
||||||
<widget class="Line" name="line_2">
|
<widget class="Line" name="line_2">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="9" column="0">
|
<item row="10" column="0">
|
||||||
<widget class="QLabel" name="label_4">
|
<widget class="QLabel" name="label_4">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Number type</string>
|
<string>Number type</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="9" column="1">
|
<item row="10" column="1">
|
||||||
<widget class="QRadioButton" name="numGuess">
|
<widget class="QRadioButton" name="numGuess">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Guess</string>
|
<string>Guess</string>
|
||||||
|
@ -183,38 +189,38 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="10" column="1">
|
<item row="11" column="1">
|
||||||
<widget class="QRadioButton" name="numDec">
|
<widget class="QRadioButton" name="numDec">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Decimal</string>
|
<string>Decimal</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="11" column="1">
|
<item row="12" column="1">
|
||||||
<widget class="QRadioButton" name="numHex">
|
<widget class="QRadioButton" name="numHex">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Hexadecimal</string>
|
<string>Hexadecimal</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="12" column="0" colspan="2">
|
<item row="13" column="0" colspan="2">
|
||||||
<widget class="Line" name="line_3">
|
<widget class="Line" name="line_3">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="13" column="0">
|
<item row="14" column="0">
|
||||||
<widget class="QLabel" name="label_5">
|
<widget class="QLabel" name="label_5">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Compare</string>
|
<string>Search type</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="13" column="1">
|
<item row="14" column="1">
|
||||||
<widget class="QRadioButton" name="opEqual">
|
<widget class="QRadioButton" name="opEqual">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Equal</string>
|
<string>Equal to value</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checked">
|
<property name="checked">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -224,20 +230,10 @@
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="14" column="1">
|
<item row="15" column="1">
|
||||||
<widget class="QRadioButton" name="opGreater">
|
<widget class="QRadioButton" name="opGreater">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Greater</string>
|
<string>Greater than value</string>
|
||||||
</property>
|
|
||||||
<attribute name="buttonGroup">
|
|
||||||
<string notr="true">op</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="15" column="1">
|
|
||||||
<widget class="QRadioButton" name="opLess">
|
|
||||||
<property name="text">
|
|
||||||
<string>Less</string>
|
|
||||||
</property>
|
</property>
|
||||||
<attribute name="buttonGroup">
|
<attribute name="buttonGroup">
|
||||||
<string notr="true">op</string>
|
<string notr="true">op</string>
|
||||||
|
@ -245,18 +241,84 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="16" column="1">
|
<item row="16" column="1">
|
||||||
|
<widget class="QRadioButton" name="opLess">
|
||||||
|
<property name="text">
|
||||||
|
<string>Less than value</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">op</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="17" column="1">
|
||||||
|
<widget class="QRadioButton" name="opUnknown">
|
||||||
|
<property name="text">
|
||||||
|
<string>Unknown/changed</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">op</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="18" column="1">
|
||||||
<widget class="QRadioButton" name="opDelta">
|
<widget class="QRadioButton" name="opDelta">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Delta</string>
|
<string>Changed by value</string>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="buttonGroup">
|
<attribute name="buttonGroup">
|
||||||
<string notr="true">op</string>
|
<string notr="true">op</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="21" column="1">
|
||||||
|
<widget class="QRadioButton" name="opDelta0">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Unchanged</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">op</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="19" column="1">
|
||||||
|
<widget class="QRadioButton" name="opDeltaPositive">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Increased</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">op</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="20" column="1">
|
||||||
|
<widget class="QRadioButton" name="opDeltaNegative">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Decreased</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">op</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QCheckBox" name="searchROM">
|
||||||
|
<property name="text">
|
||||||
|
<string>Search ROM</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0" colspan="2">
|
<item row="2" column="0" colspan="2">
|
||||||
|
@ -271,7 +333,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="search">
|
<widget class="QPushButton" name="search">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Search</string>
|
<string>New Search</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -318,10 +380,26 @@
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>opDelta0</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>value</receiver>
|
||||||
|
<slot>setDisabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>231</x>
|
||||||
|
<y>768</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>272</x>
|
||||||
|
<y>26</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
</connections>
|
</connections>
|
||||||
<buttongroups>
|
<buttongroups>
|
||||||
<buttongroup name="width"/>
|
|
||||||
<buttongroup name="type"/>
|
<buttongroup name="type"/>
|
||||||
<buttongroup name="op"/>
|
<buttongroup name="op"/>
|
||||||
|
<buttongroup name="width"/>
|
||||||
</buttongroups>
|
</buttongroups>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
|
@ -8,7 +8,10 @@
|
||||||
#include "CoreController.h"
|
#include "CoreController.h"
|
||||||
#include "GBAApp.h"
|
#include "GBAApp.h"
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
|
#include <QClipboard>
|
||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
|
#include <QListWidgetItem>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include "LogController.h"
|
#include "LogController.h"
|
||||||
|
@ -52,10 +55,36 @@ ObjView::ObjView(std::shared_ptr<CoreController> controller, QWidget* parent)
|
||||||
updateTiles(true);
|
updateTiles(true);
|
||||||
});
|
});
|
||||||
connect(m_ui.exportButton, &QAbstractButton::clicked, this, &ObjView::exportObj);
|
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) {
|
void ObjView::selectObj(int obj) {
|
||||||
m_objId = 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);
|
updateTiles(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +100,8 @@ void ObjView::updateTilesGBA(bool force) {
|
||||||
const GBA* gba = static_cast<const GBA*>(m_controller->thread()->core->board);
|
const GBA* gba = static_cast<const GBA*>(m_controller->thread()->core->board);
|
||||||
const GBAObj* obj = &gba->video.oam.obj[m_objId];
|
const GBAObj* obj = &gba->video.oam.obj[m_objId];
|
||||||
|
|
||||||
|
updateObjList(128);
|
||||||
|
|
||||||
ObjInfo newInfo;
|
ObjInfo newInfo;
|
||||||
lookupObj(m_objId, &newInfo);
|
lookupObj(m_objId, &newInfo);
|
||||||
|
|
||||||
|
@ -153,6 +184,8 @@ void ObjView::updateTilesGB(bool force) {
|
||||||
const GB* gb = static_cast<const GB*>(m_controller->thread()->core->board);
|
const GB* gb = static_cast<const GB*>(m_controller->thread()->core->board);
|
||||||
const GBObj* obj = &gb->video.oam.obj[m_objId];
|
const GBObj* obj = &gb->video.oam.obj[m_objId];
|
||||||
|
|
||||||
|
updateObjList(40);
|
||||||
|
|
||||||
ObjInfo newInfo;
|
ObjInfo newInfo;
|
||||||
lookupObj(m_objId, &newInfo);
|
lookupObj(m_objId, &newInfo);
|
||||||
|
|
||||||
|
@ -200,10 +233,38 @@ void ObjView::updateTilesGB(bool force) {
|
||||||
}
|
}
|
||||||
#endif
|
#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() {
|
void ObjView::exportObj() {
|
||||||
QString filename = GBAApp::app()->getSaveFileName(this, tr("Export sprite"),
|
QString filename = GBAApp::app()->getSaveFileName(this, tr("Export sprite"),
|
||||||
tr("Portable Network Graphics (*.png)"));
|
tr("Portable Network Graphics (*.png)"));
|
||||||
|
if (filename.isNull()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
CoreController::Interrupter interrupter(m_controller);
|
CoreController::Interrupter interrupter(m_controller);
|
||||||
QImage obj = compositeObj(m_objInfo);
|
QImage obj = compositeObj(m_objInfo);
|
||||||
obj.save(filename, "PNG");
|
obj.save(filename, "PNG");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjView::copyObj() {
|
||||||
|
CoreController::Interrupter interrupter(m_controller);
|
||||||
|
GBAApp::app()->clipboard()->setImage(compositeObj(m_objInfo));
|
||||||
|
}
|
||||||
|
|
|
@ -9,8 +9,12 @@
|
||||||
|
|
||||||
#include "ui_ObjView.h"
|
#include "ui_ObjView.h"
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
#include <mgba/core/tile-cache.h>
|
#include <mgba/core/tile-cache.h>
|
||||||
|
|
||||||
|
class QListWidgetItem;
|
||||||
|
|
||||||
namespace QGBA {
|
namespace QGBA {
|
||||||
|
|
||||||
class CoreController;
|
class CoreController;
|
||||||
|
@ -23,6 +27,7 @@ public:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void exportObj();
|
void exportObj();
|
||||||
|
void copyObj();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void selectObj(int);
|
void selectObj(int);
|
||||||
|
@ -36,6 +41,8 @@ private:
|
||||||
void updateTilesGB(bool force) override;
|
void updateTilesGB(bool force) override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void updateObjList(int maxObj);
|
||||||
|
|
||||||
Ui::ObjView m_ui;
|
Ui::ObjView m_ui;
|
||||||
|
|
||||||
std::shared_ptr<CoreController> m_controller;
|
std::shared_ptr<CoreController> m_controller;
|
||||||
|
@ -43,6 +50,8 @@ private:
|
||||||
int m_objId = 0;
|
int m_objId = 0;
|
||||||
ObjInfo m_objInfo = {};
|
ObjInfo m_objInfo = {};
|
||||||
|
|
||||||
|
QList<QListWidgetItem*> m_objs;
|
||||||
|
|
||||||
int m_tileOffset;
|
int m_tileOffset;
|
||||||
int m_boundary;
|
int m_boundary;
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,21 +6,178 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>454</width>
|
<width>800</width>
|
||||||
<height>385</height>
|
<height>730</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Sprites</string>
|
<string>Sprites</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,1">
|
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0,0,1" columnstretch="0,0,1,1">
|
||||||
<item row="0" column="2" rowspan="4">
|
<item row="4" column="3">
|
||||||
|
<widget class="QPushButton" name="copyButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Geometry</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Position</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="x">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="tileId_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>, </string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="y">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Dimensions</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="w">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>8</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="tileId_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>×</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="h">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>8</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2" rowspan="4" colspan="2">
|
||||||
<widget class="QFrame" name="frame">
|
<widget class="QFrame" name="frame">
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::StyledPanel</enum>
|
<enum>QFrame::StyledPanel</enum>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<property name="margin">
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item row="0" column="0" alignment="Qt::AlignHCenter|Qt::AlignVCenter">
|
<item row="0" column="0" alignment="Qt::AlignHCenter|Qt::AlignVCenter">
|
||||||
|
@ -42,44 +199,21 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="0" column="1" rowspan="5">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
<widget class="QGBA::AssetTile" name="tile">
|
||||||
<item>
|
<property name="title">
|
||||||
<widget class="QSpinBox" name="magnification">
|
<string>Tile</string>
|
||||||
<property name="sizePolicy">
|
</property>
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
</widget>
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="suffix">
|
|
||||||
<string>×</string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>8</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>Magnification</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="exportButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Export</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="4" column="2">
|
||||||
|
<widget class="QPushButton" name="exportButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Export</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0" rowspan="2">
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Attributes</string>
|
<string>Attributes</string>
|
||||||
|
@ -383,154 +517,6 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1" rowspan="4">
|
|
||||||
<widget class="QGBA::AssetTile" name="tile">
|
|
||||||
<property name="title">
|
|
||||||
<string>Tile</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QGroupBox" name="groupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Geometry</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Position</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="x">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>0</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="tileId_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>, </string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="y">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>0</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>Dimensions</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="w">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>8</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="tileId_5">
|
|
||||||
<property name="text">
|
|
||||||
<string>×</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="h">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>8</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
|
@ -568,6 +554,64 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="magnification">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string>×</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Magnification</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0" colspan="4">
|
||||||
|
<widget class="QListWidget" name="objList">
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>64</width>
|
||||||
|
<height>64</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="flow">
|
||||||
|
<enum>QListView::LeftToRight</enum>
|
||||||
|
</property>
|
||||||
|
<property name="resizeMode">
|
||||||
|
<enum>QListView::Adjust</enum>
|
||||||
|
</property>
|
||||||
|
<property name="gridSize">
|
||||||
|
<size>
|
||||||
|
<width>64</width>
|
||||||
|
<height>96</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="viewMode">
|
||||||
|
<enum>QListView::IconMode</enum>
|
||||||
|
</property>
|
||||||
|
<property name="uniformItemSizes">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
|
|
@ -42,9 +42,12 @@ OverrideView::OverrideView(ConfigController* config, QWidget* parent)
|
||||||
s_mbcList.append(GB_MBC3_RTC);
|
s_mbcList.append(GB_MBC3_RTC);
|
||||||
s_mbcList.append(GB_MBC5);
|
s_mbcList.append(GB_MBC5);
|
||||||
s_mbcList.append(GB_MBC5_RUMBLE);
|
s_mbcList.append(GB_MBC5_RUMBLE);
|
||||||
|
s_mbcList.append(GB_MBC6);
|
||||||
s_mbcList.append(GB_MBC7);
|
s_mbcList.append(GB_MBC7);
|
||||||
|
s_mbcList.append(GB_MMM01);
|
||||||
s_mbcList.append(GB_POCKETCAM);
|
s_mbcList.append(GB_POCKETCAM);
|
||||||
s_mbcList.append(GB_TAMA5);
|
s_mbcList.append(GB_TAMA5);
|
||||||
|
s_mbcList.append(GB_HuC1);
|
||||||
s_mbcList.append(GB_HuC3);
|
s_mbcList.append(GB_HuC3);
|
||||||
}
|
}
|
||||||
if (s_gbModelList.isEmpty()) {
|
if (s_gbModelList.isEmpty()) {
|
||||||
|
|
|
@ -319,11 +319,21 @@
|
||||||
<string>MBC5 + Rumble</string>
|
<string>MBC5 + Rumble</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>MBC6</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>MBC7</string>
|
<string>MBC7</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>MMM01</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Pocket Cam</string>
|
<string>Pocket Cam</string>
|
||||||
|
@ -334,6 +344,11 @@
|
||||||
<string>TAMA5</string>
|
<string>TAMA5</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>HuC-1</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>HuC-3</string>
|
<string>HuC-3</string>
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "CoreController.h"
|
#include "CoreController.h"
|
||||||
#include "GBAApp.h"
|
#include "GBAApp.h"
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
|
||||||
using namespace QGBA;
|
using namespace QGBA;
|
||||||
|
@ -24,6 +25,22 @@ PrinterView::PrinterView(std::shared_ptr<CoreController> controller, QWidget* pa
|
||||||
connect(m_ui.tear, &QAbstractButton::clicked, this, &PrinterView::clear);
|
connect(m_ui.tear, &QAbstractButton::clicked, this, &PrinterView::clear);
|
||||||
connect(m_ui.buttonBox, &QDialogButtonBox::accepted, this, &PrinterView::save);
|
connect(m_ui.buttonBox, &QDialogButtonBox::accepted, this, &PrinterView::save);
|
||||||
m_timer.setInterval(80);
|
m_timer.setInterval(80);
|
||||||
|
|
||||||
|
connect(m_ui.magnification, static_cast<void (QSpinBox::*)(int)>(&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();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,22 +69,22 @@ void PrinterView::printImage(const QImage& image) {
|
||||||
painter.drawPixmap(0, 0, m_image);
|
painter.drawPixmap(0, 0, m_image);
|
||||||
painter.drawImage(0, m_image.height(), image);
|
painter.drawImage(0, m_image.height(), image);
|
||||||
m_image = pixmap;
|
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_timer.start();
|
||||||
m_ui.hurry->setEnabled(true);
|
m_ui.hurry->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrinterView::printLine() {
|
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);
|
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();
|
printAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrinterView::printAll() {
|
void PrinterView::printAll() {
|
||||||
m_timer.stop();
|
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_controller->endPrint();
|
||||||
m_ui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(true);
|
m_ui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(true);
|
||||||
m_ui.hurry->setEnabled(false);
|
m_ui.hurry->setEnabled(false);
|
||||||
|
|
|
@ -6,15 +6,15 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>241</width>
|
<width>246</width>
|
||||||
<height>311</height>
|
<height>425</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Game Boy Printer</string>
|
<string>Game Boy Printer</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item alignment="Qt::AlignHCenter">
|
<item>
|
||||||
<widget class="QScrollArea" name="scrollArea">
|
<widget class="QScrollArea" name="scrollArea">
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::NoFrame</enum>
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
@ -23,10 +23,15 @@
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<property name="geometry">
|
||||||
<property name="spacing">
|
<rect>
|
||||||
<number>0</number>
|
<x>0</x>
|
||||||
</property>
|
<y>0</y>
|
||||||
|
<width>234</width>
|
||||||
|
<height>249</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout" rowstretch="1,0,1" columnminimumwidth="0,160,0">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
@ -39,14 +44,36 @@
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="1">
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="0" column="0">
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
<widget class="QLabel" name="image">
|
<widget class="QLabel" name="image">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
@ -60,18 +87,12 @@
|
||||||
<height>1</height>
|
<height>1</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>160</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignHCenter|Qt::AlignTop</set>
|
<set>Qt::AlignHCenter|Qt::AlignTop</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="2" column="1">
|
||||||
<widget class="Line" name="line">
|
<widget class="Line" name="line">
|
||||||
<property name="frameShadow">
|
<property name="frameShadow">
|
||||||
<enum>QFrame::Plain</enum>
|
<enum>QFrame::Plain</enum>
|
||||||
|
@ -81,6 +102,19 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -106,6 +140,62 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="magnification">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string>×</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Magnification</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="standardButtons">
|
<property name="standardButtons">
|
||||||
|
|
|
@ -371,6 +371,7 @@ void SettingsView::updateConfig() {
|
||||||
saveSetting("lockAspectRatio", m_ui.lockAspectRatio);
|
saveSetting("lockAspectRatio", m_ui.lockAspectRatio);
|
||||||
saveSetting("lockIntegerScaling", m_ui.lockIntegerScaling);
|
saveSetting("lockIntegerScaling", m_ui.lockIntegerScaling);
|
||||||
saveSetting("interframeBlending", m_ui.interframeBlending);
|
saveSetting("interframeBlending", m_ui.interframeBlending);
|
||||||
|
saveSetting("showOSD", m_ui.showOSD);
|
||||||
saveSetting("volume", m_ui.volume);
|
saveSetting("volume", m_ui.volume);
|
||||||
saveSetting("mute", m_ui.mute);
|
saveSetting("mute", m_ui.mute);
|
||||||
saveSetting("fastForwardVolume", m_ui.volumeFf);
|
saveSetting("fastForwardVolume", m_ui.volumeFf);
|
||||||
|
@ -546,6 +547,7 @@ void SettingsView::reloadConfig() {
|
||||||
loadSetting("lockAspectRatio", m_ui.lockAspectRatio);
|
loadSetting("lockAspectRatio", m_ui.lockAspectRatio);
|
||||||
loadSetting("lockIntegerScaling", m_ui.lockIntegerScaling);
|
loadSetting("lockIntegerScaling", m_ui.lockIntegerScaling);
|
||||||
loadSetting("interframeBlending", m_ui.interframeBlending);
|
loadSetting("interframeBlending", m_ui.interframeBlending);
|
||||||
|
loadSetting("showOSD", m_ui.showOSD, true);
|
||||||
loadSetting("volume", m_ui.volume, 0x100);
|
loadSetting("volume", m_ui.volume, 0x100);
|
||||||
loadSetting("mute", m_ui.mute, false);
|
loadSetting("mute", m_ui.mute, false);
|
||||||
loadSetting("fastForwardVolume", m_ui.volumeFf, m_ui.volume->value());
|
loadSetting("fastForwardVolume", m_ui.volumeFf, m_ui.volume->value());
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>849</width>
|
<width>885</width>
|
||||||
<height>797</height>
|
<height>797</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -562,7 +562,21 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="10" column="1">
|
<item row="9" column="1">
|
||||||
|
<widget class="QCheckBox" name="pauseOnMinimize">
|
||||||
|
<property name="text">
|
||||||
|
<string>Pause when minimized</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="10" column="0" colspan="2">
|
||||||
|
<widget class="Line" name="line_17">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="11" column="1">
|
||||||
<widget class="QCheckBox" name="showFps">
|
<widget class="QCheckBox" name="showFps">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Show FPS in title bar</string>
|
<string>Show FPS in title bar</string>
|
||||||
|
@ -572,41 +586,21 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="12" column="0" colspan="2">
|
<item row="13" column="1">
|
||||||
|
<widget class="QCheckBox" name="useDiscordPresence">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable Discord Rich Presence</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="14" column="0" colspan="2">
|
||||||
<widget class="Line" name="line_13">
|
<widget class="Line" name="line_13">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="15" column="0" colspan="2">
|
<item row="15" column="1">
|
||||||
<widget class="Line" name="line_16">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="16" column="1">
|
|
||||||
<widget class="QCheckBox" name="cheatAutosave">
|
|
||||||
<property name="text">
|
|
||||||
<string>Automatically save cheats</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="17" column="1">
|
|
||||||
<widget class="QCheckBox" name="cheatAutoload">
|
|
||||||
<property name="text">
|
|
||||||
<string>Automatically load cheats</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="13" column="1">
|
|
||||||
<widget class="QCheckBox" name="autosave">
|
<widget class="QCheckBox" name="autosave">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Automatically save state</string>
|
<string>Automatically save state</string>
|
||||||
|
@ -616,7 +610,7 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="14" column="1">
|
<item row="16" column="1">
|
||||||
<widget class="QCheckBox" name="autoload">
|
<widget class="QCheckBox" name="autoload">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Automatically load state</string>
|
<string>Automatically load state</string>
|
||||||
|
@ -626,17 +620,40 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="11" column="1">
|
<item row="17" column="0" colspan="2">
|
||||||
<widget class="QCheckBox" name="useDiscordPresence">
|
<widget class="Line" name="line_16">
|
||||||
<property name="text">
|
<property name="orientation">
|
||||||
<string>Enable Discord Rich Presence</string>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="9" column="1">
|
<item row="18" column="1">
|
||||||
<widget class="QCheckBox" name="pauseOnMinimize">
|
<widget class="QCheckBox" name="cheatAutosave">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Pause when minimized</string>
|
<string>Automatically save cheats</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="19" column="1">
|
||||||
|
<widget class="QCheckBox" name="cheatAutoload">
|
||||||
|
<property name="text">
|
||||||
|
<string>Automatically load cheats</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="12" column="1">
|
||||||
|
<widget class="QCheckBox" name="showOSD">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show OSD messages</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -2106,6 +2123,16 @@
|
||||||
<signal>toggled(bool)</signal>
|
<signal>toggled(bool)</signal>
|
||||||
<receiver>fastForwardHeldRatio</receiver>
|
<receiver>fastForwardHeldRatio</receiver>
|
||||||
<slot>setDisabled(bool)</slot>
|
<slot>setDisabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>20</x>
|
||||||
|
<y>20</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>20</x>
|
||||||
|
<y>20</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
</connections>
|
</connections>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#include "CoreController.h"
|
#include "CoreController.h"
|
||||||
#include "GBAApp.h"
|
#include "GBAApp.h"
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
|
#include <QClipboard>
|
||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
@ -87,7 +89,20 @@ TileView::TileView(std::shared_ptr<CoreController> controller, QWidget* parent)
|
||||||
updateTiles(true);
|
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
|
#ifdef M_CORE_GBA
|
||||||
|
@ -162,8 +177,36 @@ void TileView::updatePalette(int palette) {
|
||||||
void TileView::exportTiles() {
|
void TileView::exportTiles() {
|
||||||
QString filename = GBAApp::app()->getSaveFileName(this, tr("Export tiles"),
|
QString filename = GBAApp::app()->getSaveFileName(this, tr("Export tiles"),
|
||||||
tr("Portable Network Graphics (*.png)"));
|
tr("Portable Network Graphics (*.png)"));
|
||||||
|
if (filename.isNull()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
CoreController::Interrupter interrupter(m_controller);
|
CoreController::Interrupter interrupter(m_controller);
|
||||||
updateTiles(false);
|
updateTiles(false);
|
||||||
QPixmap pixmap(m_ui.tiles->backing());
|
QPixmap pixmap(m_ui.tiles->backing());
|
||||||
pixmap.save(filename, "PNG");
|
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());
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,9 @@ public:
|
||||||
public slots:
|
public slots:
|
||||||
void updatePalette(int);
|
void updatePalette(int);
|
||||||
void exportTiles();
|
void exportTiles();
|
||||||
|
void exportTile();
|
||||||
|
void copyTiles();
|
||||||
|
void copyTile();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef M_CORE_GBA
|
#ifdef M_CORE_GBA
|
||||||
|
|
|
@ -6,14 +6,28 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>693</width>
|
<width>748</width>
|
||||||
<height>467</height>
|
<height>823</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Tiles</string>
|
<string>Tiles</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
|
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,1,0,0,0,0" columnstretch="0,1">
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QPushButton" name="exportOne">
|
||||||
|
<property name="text">
|
||||||
|
<string>Export Selected</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
|
<widget class="QPushButton" name="exportAll">
|
||||||
|
<property name="text">
|
||||||
|
<string>Export All</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<layout class="QFormLayout" name="formLayout">
|
<layout class="QFormLayout" name="formLayout">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
|
@ -104,17 +118,7 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="0" column="1" rowspan="8">
|
||||||
<widget class="QGBA::AssetTile" name="tile"/>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QPushButton" name="exportButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Export</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1" rowspan="5">
|
|
||||||
<widget class="QScrollArea" name="scrollArea">
|
<widget class="QScrollArea" name="scrollArea">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||||
|
@ -133,7 +137,7 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>405</width>
|
<width>480</width>
|
||||||
<height>768</height>
|
<height>768</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -179,6 +183,23 @@
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QGBA::AssetTile" name="tile"/>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QPushButton" name="copyOne">
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy Selected</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QPushButton" name="copyAll">
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy All</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
|
|
@ -802,6 +802,7 @@ void Window::gameStarted() {
|
||||||
m_config->updateOption("lockIntegerScaling");
|
m_config->updateOption("lockIntegerScaling");
|
||||||
m_config->updateOption("lockAspectRatio");
|
m_config->updateOption("lockAspectRatio");
|
||||||
m_config->updateOption("interframeBlending");
|
m_config->updateOption("interframeBlending");
|
||||||
|
m_config->updateOption("showOSD");
|
||||||
if (m_savedScale > 0) {
|
if (m_savedScale > 0) {
|
||||||
resizeFrame(size * m_savedScale);
|
resizeFrame(size * m_savedScale);
|
||||||
}
|
}
|
||||||
|
@ -971,8 +972,10 @@ void Window::reloadDisplayDriver() {
|
||||||
|
|
||||||
const mCoreOptions* opts = m_config->options();
|
const mCoreOptions* opts = m_config->options();
|
||||||
m_display->lockAspectRatio(opts->lockAspectRatio);
|
m_display->lockAspectRatio(opts->lockAspectRatio);
|
||||||
|
m_display->lockIntegerScaling(opts->lockIntegerScaling);
|
||||||
m_display->interframeBlending(opts->interframeBlending);
|
m_display->interframeBlending(opts->interframeBlending);
|
||||||
m_display->filter(opts->resampleVideo);
|
m_display->filter(opts->resampleVideo);
|
||||||
|
m_config->updateOption("showOSD");
|
||||||
#if defined(BUILD_GL) || defined(BUILD_GLES2)
|
#if defined(BUILD_GL) || defined(BUILD_GLES2)
|
||||||
if (opts->shader) {
|
if (opts->shader) {
|
||||||
struct VDir* shader = VDirOpen(opts->shader);
|
struct VDir* shader = VDirOpen(opts->shader);
|
||||||
|
@ -1694,6 +1697,13 @@ void Window::setupMenu(QMenuBar* menubar) {
|
||||||
}
|
}
|
||||||
}, this);
|
}, 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.addHiddenAction(tr("Exit fullscreen"), "exitFullScreen", this, &Window::exitFullScreen, "frame", QKeySequence("Esc"));
|
||||||
|
|
||||||
m_actions.addHeldAction(tr("GameShark Button (held)"), "holdGSButton", [this](bool held) {
|
m_actions.addHeldAction(tr("GameShark Button (held)"), "holdGSButton", [this](bool held) {
|
||||||
|
|
|
@ -51,6 +51,7 @@ LibraryController::LibraryController(QWidget* parent, const QString& path, Confi
|
||||||
m_libraryGrid = std::make_unique<LibraryGrid>(this);
|
m_libraryGrid = std::make_unique<LibraryGrid>(this);
|
||||||
addWidget(m_libraryGrid->widget());
|
addWidget(m_libraryGrid->widget());
|
||||||
|
|
||||||
|
m_currentStyle = LibraryStyle::STYLE_TREE; // Make sure setViewStyle does something
|
||||||
setViewStyle(LibraryStyle::STYLE_LIST);
|
setViewStyle(LibraryStyle::STYLE_LIST);
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -20,7 +20,7 @@
|
||||||
#include <GLES3/gl31.h>
|
#include <GLES3/gl31.h>
|
||||||
|
|
||||||
#define AUTO_INPUT 0x4E585031
|
#define AUTO_INPUT 0x4E585031
|
||||||
#define SAMPLES 0x400
|
#define SAMPLES 0x200
|
||||||
#define BUFFER_SIZE 0x1000
|
#define BUFFER_SIZE 0x1000
|
||||||
#define N_BUFFERS 4
|
#define N_BUFFERS 4
|
||||||
#define ANALOG_DEADZONE 0x4000
|
#define ANALOG_DEADZONE 0x4000
|
||||||
|
@ -281,6 +281,8 @@ static void _setup(struct mGUIRunner* runner) {
|
||||||
if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode < SM_MAX) {
|
if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode < SM_MAX) {
|
||||||
screenMode = mode;
|
screenMode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runner->core->setAudioBufferSize(runner->core, SAMPLES);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _gameLoaded(struct mGUIRunner* runner) {
|
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))) {
|
if (enqueuedBuffers >= N_BUFFERS - 1 && R_SUCCEEDED(audoutWaitPlayFinish(&releasedBuffers, &audoutNReleasedBuffers, 10000000))) {
|
||||||
enqueuedBuffers -= audoutNReleasedBuffers;
|
enqueuedBuffers -= audoutNReleasedBuffers;
|
||||||
}
|
}
|
||||||
|
if (enqueuedBuffers >= N_BUFFERS) {
|
||||||
|
blip_clear(left);
|
||||||
|
blip_clear(right);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
struct GBAStereoSample* samples = audioBuffer[audioBufferActive];
|
struct GBAStereoSample* samples = audioBuffer[audioBufferActive];
|
||||||
blip_read_samples(left, &samples[0].left, SAMPLES, true);
|
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].next = NULL;
|
||||||
audoutBuffer[i].buffer = audioBuffer[i];
|
audoutBuffer[i].buffer = audioBuffer[i];
|
||||||
audoutBuffer[i].buffer_size = BUFFER_SIZE;
|
audoutBuffer[i].buffer_size = BUFFER_SIZE;
|
||||||
audoutBuffer[i].data_size = BUFFER_SIZE;
|
audoutBuffer[i].data_size = SAMPLES * 4;
|
||||||
audoutBuffer[i].data_offset = 0;
|
audoutBuffer[i].data_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue