all repos — mgba @ f03389bfca8e6ec52815ae2d9941ec7f0a9e691c

mGBA Game Boy Advance Emulator

Merge branch 'master' (early part) into medusa
Vicki Pfau vi@endrift.com
Mon, 17 Feb 2020 16:35:15 -0800
commit

f03389bfca8e6ec52815ae2d9941ec7f0a9e691c

parent

9dbd15c144d49fc10dfe7e6e5485287e7650897b

M .travis-deps.sh.travis-deps.sh

@@ -1,8 +1,7 @@

#!/bin/sh -set -e if [ $TRAVIS_OS_NAME = "osx" ]; then brew update - brew install qt5 ffmpeg imagemagick sdl2 libedit libelf libpng libzip + brew install qt5 ffmpeg sdl2 libedit libelf libpng libzip else sudo apt-get update sudo apt-get -y install libseccomp2
M CHANGESCHANGES

@@ -43,68 +43,91 @@ - Qt: Add recent game list clearing (closes mgba.io/i/1380)

- GB: Yanking gamepak now supported - Qt: Memory range dumping (closes mgba.io/i/1298) Emulation fixes: - - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - - GBA: Reset now reloads multiboot ROMs - - GBA BIOS: Fix multiboot entry point (fixes Magic Floor) - - GB Video: Delay LYC STAT check (fixes mgba.io/i/1331) - - GB Video: Fix window being enabled mid-scanline (fixes mgba.io/i/1328) - - GB I/O: Filter IE top bits properly (fixes mgba.io/i/1329) + - GB: Fix using boot ROM with MMM01 games - GB Audio: Only reset channel 3 sample in DMG mode - GB Audio: Sample inactive channels (fixes mgba.io/i/1455, mgba.io/i/1456) + - GB Audio: Fix channel 4 volume (fixes mgba.io/i/1529) + - GB I/O: Filter IE top bits properly (fixes mgba.io/i/1329) - GB Memory: Better emulate 0xFEA0 region on DMG, MGB and AGB + - GB Video: Delay LYC STAT check (fixes mgba.io/i/1331) + - GB Video: Fix window being enabled mid-scanline (fixes mgba.io/i/1328) - GB Video: Fix mode 0 window edge case (fixes mgba.io/i/1519) - - GB Audio: Fix channel 4 volume (fixes mgba.io/i/1529) - GB Video: Fix color scaling in AGB mode - - GB: Fix using boot ROM with MMM01 games + - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) + - GBA: Reset now reloads multiboot ROMs + - GBA BIOS: Fix multiboot entry point (fixes Magic Floor) Other fixes: - - Qt: Fix some Qt display driver race conditions - Core: Improved lockstep driver reliability (Le Hoang Quyen) - - Qt: Fix menu bar staying hidden in full screen (fixes mgba.io/i/317) + - FFmpeg: Drain recording buffers + - GB: Fix reading ROM immediately after unmapping BIOS - GB SIO: Fix lockstep failing games aren't reloaded - - Libretro: Fix crash changing allowing opposing directions (hhromic) - GBA Cheats: Fix value incrementing in CB slide codes (fixes mgba.io/i/1501) + - Libretro: Fix crash changing allowing opposing directions (hhromic) + - Qt: Fix some Qt display driver race conditions + - Qt: Fix menu bar staying hidden in full screen (fixes mgba.io/i/317) - Qt: Only show emulator restart warning once per settings saving - - FFmpeg: Drain recording buffers - - Shaders: Fix gba-color shader resolution (fixes mgba.io/i/1435) - Qt: Fix LibraryController initialization (fixes mgba.io/i/1324) + - Shaders: Fix gba-color shader resolution (fixes mgba.io/i/1435) - Switch: Fix audio when video rate desyncs (fixes mgba.io/i/1532) - - GB: Fix reading ROM immediately after unmapping BIOS Misc: + - CMake: Don't use libzip on embedded platforms (fixes mgba.io/i/1527) + - Core: Add keysRead callback + - Core: Create game-related paths if they don't exist (fixes mgba.io/i/1446) + - Core: Add more memory search ops (closes mgba.io/i/1510) + - Debugger: Make tracing compatible with breakpoints/watchpoints + - Debugger: Print breakpoint/watchpoint number when inserting + - Feature: Switch from ImageMagick to FFmpeg for GIF generation + - FFmpeg: Support audio-only recording + - GB Memory: Support running from blocked memory + - GBA BIOS: Add timings for HLE BIOS math functions (fixes mgba.io/i/1396) + - GBA BIOS: Fix clobbered registers in CpuSet (fixes mgba.io/i/1531) - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash - - GB Memory: Support running from blocked memory - - Qt: Don't unload ROM immediately if it crashes - Debugger: Add breakpoint and watchpoint listing - LR35902: Support PC-relative opcode decoding + - mGUI: Remember name and position of last loaded game + - OpenGL: Only resize textures when needed + - Qt: Don't unload ROM immediately if it crashes - Qt: Support switching webcams - - Core: Add keysRead callback - Qt: Cap window size on start to monitor size - - GBA BIOS: Add timings for HLE BIOS math functions (fixes mgba.io/i/1396) - - Debugger: Make tracing compatible with breakpoints/watchpoints - - Debugger: Print breakpoint/watchpoint number when inserting - Qt: Open a message box for Qt frontend errors - - FFmpeg: Support audio-only recording - Qt: Increase maximum magnifications and scaling - Qt: Add native FPS button to settings view - Qt: Improve sync code - - Switch: Dynamic display resizing - - Vita: L2/R2 and L3/R3 can now be mapped on PSTV (fixes mgba.io/i/1292) - - mGUI: Remember name and position of last loaded game - - Core: Create game-related paths if they don't exist (fixes mgba.io/i/1446) - Qt: Add option to pause on minimizing window (closes mgba.io/i/1379) - - Switch: Support file associations - Qt: Scale pixel color values to full range (fixes mgba.io/i/1511) - - Qt, OpenGL: Disable integer scaling for dimensions that don't fit - - Feature: Switch from ImageMagick to FFmpeg for GIF generation - - OpenGL: Only resize textures when needed - - GBA BIOS: Fix clobbered registers in CpuSet (fixes mgba.io/i/1531) - Qt: Remove What's This icon from dialogs - - CMake: Don't use libzip on embedded platforms (fixes mgba.io/i/1527) - Qt: Printer quality of life improvements (fixes mgba.io/i/1540) - Qt: Add copy and QoL improvements to graphic views (closes mgba.io/i/1541) - Qt: Show list of all sprites in sprite view - Qt: Add option for disabling OSD messages - - Core: Add more memory search ops (closes mgba.io/i/1510) + - Qt, OpenGL: Disable integer scaling for dimensions that don't fit + - Switch: Dynamic display resizing + - Switch: Support file associations + - Vita: L2/R2 and L3/R3 can now be mapped on PSTV (fixes mgba.io/i/1292) +Changes from beta 1: +Emulation fixes: + - ARM: Fix STR writeback pipeline stage + - ARM: Partially fix LDM/STM writeback with empty register list + - ARM: Fix stepping when events are pending + - GBA DMA: Fix case where DMAs could get misaligned (fixes mgba.io/i/1092) + - GBA Video: Fix OpenGL renderer 512x512 backgrounds (fixes mgba.io/i/1572) + - GBA Memory: Fix open bus from IWRAM (fixes mgba.io/i/1575) +Other fixes: + - 3DS: Fix screen darkening (fixes mgba.io/i/1562) + - Core: Fix uninitialized memory issues with graphics caches + - Core: Return null for out of bounds cached tile VRAM querying + - Vita: Fix analog controls (fixes mgba.io/i/1554) + - Qt: Fix fast forward mute being reset (fixes mgba.io/i/1574) + - Qt: Fix scrollbar arrows in memory view (fixes mgba.io/i/1558) + - Qt: Fix several cases where shader selections don't get saved + - Qt: Fix division by zero error in invalid TilePainter state +Misc: + - GB Memory: Support manual SRAM editing (fixes mgba.io/i/1580) + - SDL: Use controller GUID instead of name + +0.8 beta 1: (2019-10-20) +- Initial beta for 0.8 0.7.3: (2019-09-15) Emulation fixes:
M CMakeLists.txtCMakeLists.txt

@@ -636,7 +636,7 @@ string(REGEX MATCH "^[0-9]+" LIBZIP_VERSION_MAJOR ${libzip_VERSION})

if (LIBZIP_VERSION_MAJOR LESS 1) set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libzip2") elseif(LIBZIP_VERSION_MAJOR EQUAL 1) - set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libzip4") + set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libzip4|libzip5") else() message(AUTHOR_WARNING Unknown version of libzip detected: ${libzip_VERSION}) endif()
M src/arm/arm.csrc/arm/arm.c

@@ -299,15 +299,13 @@ instruction(cpu, opcode); \

} \ \ void ARM ## VERSION ## Run(struct ARMCore* cpu) { \ - if (cpu->cycles < cpu->nextEvent) { \ - if (cpu->executionMode == MODE_THUMB) { \ - Thumb ## VERSION ## Step(cpu); \ - } else { \ - ARM ## VERSION ## Step(cpu); \ - } \ - } \ - if (cpu->cycles >= cpu->nextEvent) { \ + while (cpu->cycles >= cpu->nextEvent) { \ cpu->irqh.processEvents(cpu); \ + } \ + if (cpu->executionMode == MODE_THUMB) { \ + Thumb ## VERSION ## Step(cpu); \ + } else { \ + ARM ## VERSION ## Step(cpu); \ } \ } \ \
M src/arm/isa-arm.csrc/arm/isa-arm.c

@@ -259,6 +259,11 @@ if (UNLIKELY(rn == ARM_PC)) { \

currentCycles += ARMWritePC(cpu); \ } +#define ADDR_MODE_2_WRITEBACK_PRE_STORE(WB) +#define ADDR_MODE_2_WRITEBACK_POST_STORE(WB) WB +#define ADDR_MODE_2_WRITEBACK_PRE_LOAD(WB) WB +#define ADDR_MODE_2_WRITEBACK_POST_LOAD(WB) + #define ADDR_MODE_2_LSL (cpu->gprs[rm] << ADDR_MODE_2_I) #define ADDR_MODE_2_LSR (ADDR_MODE_2_I_TEST ? ((uint32_t) cpu->gprs[rm]) >> ADDR_MODE_2_I : 0) #define ADDR_MODE_2_ASR (ADDR_MODE_2_I_TEST ? ((int32_t) cpu->gprs[rm]) >> ADDR_MODE_2_I : ((int32_t) cpu->gprs[rm]) >> 31)

@@ -426,7 +431,7 @@ UNUSED(x); \

y = ARM_SXT_16(cpu->gprs[rs] >> 16); \ BODY) \ -#define DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, ADDRESS, WRITEBACK, BODY) \ +#define DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, ADDRESS, WRITEBACK, LS, BODY) \ DEFINE_INSTRUCTION_ARM(NAME, \ uint32_t address; \ int rn = (opcode >> 16) & 0xF; \

@@ -434,57 +439,58 @@ int rd = (opcode >> 12) & 0xF; \

int rm = opcode & 0xF; \ UNUSED(rm); \ address = ADDRESS; \ - WRITEBACK; \ - BODY;) + ADDR_MODE_2_WRITEBACK_PRE_ ## LS (WRITEBACK); \ + BODY; \ + ADDR_MODE_2_WRITEBACK_POST_ ## LS (WRITEBACK);) -#define DEFINE_LOAD_STORE_INSTRUCTION_SHIFTER_ARM(NAME, SHIFTER, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(-, SHIFTER)), BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## U, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(+, SHIFTER)), BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## P, ADDR_MODE_2_INDEX(-, SHIFTER), , BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PW, ADDR_MODE_2_INDEX(-, SHIFTER), ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_ADDRESS), BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PU, ADDR_MODE_2_INDEX(+, SHIFTER), , BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PUW, ADDR_MODE_2_INDEX(+, SHIFTER), ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_ADDRESS), BODY) +#define DEFINE_LOAD_STORE_INSTRUCTION_SHIFTER_ARM(NAME, SHIFTER, LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(-, SHIFTER)), LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## U, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(+, SHIFTER)), LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## P, ADDR_MODE_2_INDEX(-, SHIFTER), , LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PW, ADDR_MODE_2_INDEX(-, SHIFTER), ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_ADDRESS), LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PU, ADDR_MODE_2_INDEX(+, SHIFTER), , LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PUW, ADDR_MODE_2_INDEX(+, SHIFTER), ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_ADDRESS), LS, BODY) -#define DEFINE_LOAD_STORE_INSTRUCTION_ARM(NAME, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_SHIFTER_ARM(NAME ## _LSL_, ADDR_MODE_2_LSL, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_SHIFTER_ARM(NAME ## _LSR_, ADDR_MODE_2_LSR, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_SHIFTER_ARM(NAME ## _ASR_, ADDR_MODE_2_ASR, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_SHIFTER_ARM(NAME ## _ROR_, ADDR_MODE_2_ROR, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## I, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(-, ADDR_MODE_2_IMMEDIATE)), BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IU, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(+, ADDR_MODE_2_IMMEDIATE)), BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IP, ADDR_MODE_2_INDEX(-, ADDR_MODE_2_IMMEDIATE), , BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPW, ADDR_MODE_2_INDEX(-, ADDR_MODE_2_IMMEDIATE), ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_ADDRESS), BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPU, ADDR_MODE_2_INDEX(+, ADDR_MODE_2_IMMEDIATE), , BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPUW, ADDR_MODE_2_INDEX(+, ADDR_MODE_2_IMMEDIATE), ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_ADDRESS), BODY) \ +#define DEFINE_LOAD_STORE_INSTRUCTION_ARM(NAME, LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_SHIFTER_ARM(NAME ## _LSL_, ADDR_MODE_2_LSL, LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_SHIFTER_ARM(NAME ## _LSR_, ADDR_MODE_2_LSR, LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_SHIFTER_ARM(NAME ## _ASR_, ADDR_MODE_2_ASR, LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_SHIFTER_ARM(NAME ## _ROR_, ADDR_MODE_2_ROR, LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## I, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(-, ADDR_MODE_2_IMMEDIATE)), LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IU, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(+, ADDR_MODE_2_IMMEDIATE)), LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IP, ADDR_MODE_2_INDEX(-, ADDR_MODE_2_IMMEDIATE), , LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPW, ADDR_MODE_2_INDEX(-, ADDR_MODE_2_IMMEDIATE), ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_ADDRESS), LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPU, ADDR_MODE_2_INDEX(+, ADDR_MODE_2_IMMEDIATE), , LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPUW, ADDR_MODE_2_INDEX(+, ADDR_MODE_2_IMMEDIATE), ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_ADDRESS), LS, BODY) \ -#define DEFINE_LOAD_STORE_MODE_3_WRITEBACK_WIDTH_INSTRUCTION_ARM(NAME, BODY, WRITEBACK) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, ADDR_MODE_3_RN, WRITEBACK(ADDR_MODE_3_INDEX(-, ADDR_MODE_3_RM)), BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## U, ADDR_MODE_3_RN, WRITEBACK(ADDR_MODE_3_INDEX(+, ADDR_MODE_3_RM)), BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## P, ADDR_MODE_3_INDEX(-, ADDR_MODE_3_RM), , BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PW, ADDR_MODE_3_INDEX(-, ADDR_MODE_3_RM), ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_ADDRESS), BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PU, ADDR_MODE_3_INDEX(+, ADDR_MODE_3_RM), , BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PUW, ADDR_MODE_3_INDEX(+, ADDR_MODE_3_RM), ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_ADDRESS), BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## I, ADDR_MODE_3_RN, WRITEBACK(ADDR_MODE_3_INDEX(-, ADDR_MODE_3_IMMEDIATE)), BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IU, ADDR_MODE_3_RN, WRITEBACK(ADDR_MODE_3_INDEX(+, ADDR_MODE_3_IMMEDIATE)), BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IP, ADDR_MODE_3_INDEX(-, ADDR_MODE_3_IMMEDIATE), , BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPW, ADDR_MODE_3_INDEX(-, ADDR_MODE_3_IMMEDIATE), ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_ADDRESS), BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPU, ADDR_MODE_3_INDEX(+, ADDR_MODE_3_IMMEDIATE), , BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPUW, ADDR_MODE_3_INDEX(+, ADDR_MODE_3_IMMEDIATE), ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_ADDRESS), BODY) \ +#define DEFINE_LOAD_STORE_MODE_3_WRITEBACK_WIDTH_INSTRUCTION_ARM(NAME, LS, BODY, WRITEBACK) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, ADDR_MODE_3_RN, WRITEBACK(ADDR_MODE_3_INDEX(-, ADDR_MODE_3_RM)), LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## U, ADDR_MODE_3_RN, WRITEBACK(ADDR_MODE_3_INDEX(+, ADDR_MODE_3_RM)), LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## P, ADDR_MODE_3_INDEX(-, ADDR_MODE_3_RM), , LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PW, ADDR_MODE_3_INDEX(-, ADDR_MODE_3_RM), WRITEBACK(ADDR_MODE_3_ADDRESS), LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PU, ADDR_MODE_3_INDEX(+, ADDR_MODE_3_RM), , LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PUW, ADDR_MODE_3_INDEX(+, ADDR_MODE_3_RM), ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_ADDRESS), LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## I, ADDR_MODE_3_RN, WRITEBACK(ADDR_MODE_3_INDEX(-, ADDR_MODE_3_IMMEDIATE)), LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IU, ADDR_MODE_3_RN, ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_INDEX(+, ADDR_MODE_3_IMMEDIATE)), LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IP, ADDR_MODE_3_INDEX(-, ADDR_MODE_3_IMMEDIATE), , LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPW, ADDR_MODE_3_INDEX(-, ADDR_MODE_3_IMMEDIATE), ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_ADDRESS), LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPU, ADDR_MODE_3_INDEX(+, ADDR_MODE_3_IMMEDIATE), , LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPUW, ADDR_MODE_3_INDEX(+, ADDR_MODE_3_IMMEDIATE), ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_ADDRESS), LS, BODY) \ -#define DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(NAME, BODY) DEFINE_LOAD_STORE_MODE_3_WRITEBACK_WIDTH_INSTRUCTION_ARM(NAME, BODY, ADDR_MODE_3_WRITEBACK) -#define DEFINE_LOAD_STORE_MODE_3_DOUBLE_INSTRUCTION_ARM(NAME, BODY) DEFINE_LOAD_STORE_MODE_3_WRITEBACK_WIDTH_INSTRUCTION_ARM(NAME, BODY, ADDR_MODE_3_WRITEBACK_64) +#define DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(NAME, LS, BODY) DEFINE_LOAD_STORE_MODE_3_WRITEBACK_WIDTH_INSTRUCTION_ARM(NAME, LS, BODY, ADDR_MODE_3_WRITEBACK) +#define DEFINE_LOAD_STORE_MODE_3_DOUBLE_INSTRUCTION_ARM(NAME, LS, BODY) DEFINE_LOAD_STORE_MODE_3_WRITEBACK_WIDTH_INSTRUCTION_ARM(NAME, LS, BODY, ADDR_MODE_3_WRITEBACK_64) -#define DEFINE_LOAD_STORE_T_INSTRUCTION_SHIFTER_ARM(NAME, SHIFTER, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, SHIFTER, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(-, ADDR_MODE_2_RM)), BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## U, SHIFTER, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(+, ADDR_MODE_2_RM)), BODY) \ +#define DEFINE_LOAD_STORE_T_INSTRUCTION_SHIFTER_ARM(NAME, SHIFTER, LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, SHIFTER, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(-, ADDR_MODE_2_RM)), LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## U, SHIFTER, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(+, ADDR_MODE_2_RM)), LS, BODY) \ -#define DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(NAME, BODY) \ - DEFINE_LOAD_STORE_T_INSTRUCTION_SHIFTER_ARM(NAME ## _LSL_, ADDR_MODE_2_LSL, BODY) \ - DEFINE_LOAD_STORE_T_INSTRUCTION_SHIFTER_ARM(NAME ## _LSR_, ADDR_MODE_2_LSR, BODY) \ - DEFINE_LOAD_STORE_T_INSTRUCTION_SHIFTER_ARM(NAME ## _ASR_, ADDR_MODE_2_ASR, BODY) \ - DEFINE_LOAD_STORE_T_INSTRUCTION_SHIFTER_ARM(NAME ## _ROR_, ADDR_MODE_2_ROR, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## I, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(-, ADDR_MODE_2_IMMEDIATE)), BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IU, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(+, ADDR_MODE_2_IMMEDIATE)), BODY) \ +#define DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(NAME, LS, BODY) \ + DEFINE_LOAD_STORE_T_INSTRUCTION_SHIFTER_ARM(NAME ## _LSL_, ADDR_MODE_2_LSL, LS, BODY) \ + DEFINE_LOAD_STORE_T_INSTRUCTION_SHIFTER_ARM(NAME ## _LSR_, ADDR_MODE_2_LSR, LS, BODY) \ + DEFINE_LOAD_STORE_T_INSTRUCTION_SHIFTER_ARM(NAME ## _ASR_, ADDR_MODE_2_ASR, LS, BODY) \ + DEFINE_LOAD_STORE_T_INSTRUCTION_SHIFTER_ARM(NAME ## _ROR_, ADDR_MODE_2_ROR, LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## I, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(-, ADDR_MODE_2_IMMEDIATE)), LS, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IU, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(+, ADDR_MODE_2_IMMEDIATE)), LS, BODY) \ #define ARM_MS_PRE \ enum PrivilegeMode privilegeMode = cpu->privilegeMode; \

@@ -636,19 +642,19 @@ // End multiply definitions

// Begin load/store definitions -DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDR, cpu->gprs[rd] = cpu->memory.load32(cpu, address, &currentCycles); ARM_LOAD_POST_BODY;) -DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRv5, cpu->gprs[rd] = cpu->memory.load32(cpu, address, &currentCycles); ARM_LOAD_POST_BODY_v5;) -DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRB, cpu->gprs[rd] = cpu->memory.load8(cpu, address, &currentCycles); ARM_LOAD_POST_BODY;) -DEFINE_LOAD_STORE_MODE_3_DOUBLE_INSTRUCTION_ARM(LDRD, cpu->gprs[rd & ~1] = cpu->memory.load32(cpu, address, &currentCycles); cpu->gprs[rd | 1] = cpu->memory.load32(cpu, address + 4, &currentCycles); ARM_LOAD_POST_BODY;) -DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRH, cpu->gprs[rd] = cpu->memory.load16(cpu, address, &currentCycles); ARM_LOAD_POST_BODY;) -DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSB, cpu->gprs[rd] = ARM_SXT_8(cpu->memory.load8(cpu, address, &currentCycles)); ARM_LOAD_POST_BODY;) -DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSH, cpu->gprs[rd] = address & 1 ? ARM_SXT_8(cpu->memory.load16(cpu, address, &currentCycles)) : ARM_SXT_16(cpu->memory.load16(cpu, address, &currentCycles)); ARM_LOAD_POST_BODY;) -DEFINE_LOAD_STORE_INSTRUCTION_ARM(STR, cpu->memory.store32(cpu, address, cpu->gprs[rd], &currentCycles); ARM_STORE_POST_BODY;) -DEFINE_LOAD_STORE_INSTRUCTION_ARM(STRB, cpu->memory.store8(cpu, address, cpu->gprs[rd], &currentCycles); ARM_STORE_POST_BODY;) -DEFINE_LOAD_STORE_MODE_3_DOUBLE_INSTRUCTION_ARM(STRD, cpu->memory.store32(cpu, address, cpu->gprs[rd & ~1], &currentCycles); cpu->memory.store32(cpu, address + 4, cpu->gprs[rd | 1], &currentCycles); ARM_STORE_POST_BODY;) -DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(STRH, cpu->memory.store16(cpu, address, cpu->gprs[rd], &currentCycles); ARM_STORE_POST_BODY;) +DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDR, LOAD, cpu->gprs[rd] = cpu->memory.load32(cpu, address, &currentCycles); ARM_LOAD_POST_BODY;) +DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRv5, LOAD, cpu->gprs[rd] = cpu->memory.load32(cpu, address, &currentCycles); ARM_LOAD_POST_BODY_v5;) +DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRB, LOAD, cpu->gprs[rd] = cpu->memory.load8(cpu, address, &currentCycles); ARM_LOAD_POST_BODY;) +DEFINE_LOAD_STORE_MODE_3_DOUBLE_INSTRUCTION_ARM(LDRD, LOAD, cpu->gprs[rd & ~1] = cpu->memory.load32(cpu, address, &currentCycles); cpu->gprs[rd | 1] = cpu->memory.load32(cpu, address + 4, &currentCycles); ARM_LOAD_POST_BODY;) +DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRH, LOAD, cpu->gprs[rd] = cpu->memory.load16(cpu, address, &currentCycles); ARM_LOAD_POST_BODY;) +DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSB, LOAD, cpu->gprs[rd] = ARM_SXT_8(cpu->memory.load8(cpu, address, &currentCycles)); ARM_LOAD_POST_BODY;) +DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSH, LOAD, cpu->gprs[rd] = address & 1 ? ARM_SXT_8(cpu->memory.load16(cpu, address, &currentCycles)) : ARM_SXT_16(cpu->memory.load16(cpu, address, &currentCycles)); ARM_LOAD_POST_BODY;) +DEFINE_LOAD_STORE_INSTRUCTION_ARM(STR, STORE, cpu->memory.store32(cpu, address, cpu->gprs[rd], &currentCycles); ARM_STORE_POST_BODY;) +DEFINE_LOAD_STORE_INSTRUCTION_ARM(STRB, STORE, cpu->memory.store8(cpu, address, cpu->gprs[rd], &currentCycles); ARM_STORE_POST_BODY;) +DEFINE_LOAD_STORE_MODE_3_DOUBLE_INSTRUCTION_ARM(STRD, STORE, cpu->memory.store32(cpu, address, cpu->gprs[rd & ~1], &currentCycles); cpu->memory.store32(cpu, address + 4, cpu->gprs[rd | 1], &currentCycles); ARM_STORE_POST_BODY;) +DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(STRH, STORE, cpu->memory.store16(cpu, address, cpu->gprs[rd], &currentCycles); ARM_STORE_POST_BODY;) -DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(LDRBT, +DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(LDRBT, LOAD, enum PrivilegeMode priv = cpu->privilegeMode; ARMSetPrivilegeMode(cpu, MODE_USER); int32_t r = cpu->memory.load8(cpu, address, &currentCycles);

@@ -656,7 +662,7 @@ ARMSetPrivilegeMode(cpu, priv);

cpu->gprs[rd] = r; ARM_LOAD_POST_BODY;) -DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(LDRT, +DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(LDRT, LOAD, enum PrivilegeMode priv = cpu->privilegeMode; ARMSetPrivilegeMode(cpu, MODE_USER); int32_t r = cpu->memory.load32(cpu, address, &currentCycles);

@@ -664,7 +670,7 @@ ARMSetPrivilegeMode(cpu, priv);

cpu->gprs[rd] = r; ARM_LOAD_POST_BODY;) -DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(STRBT, +DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(STRBT, STORE, enum PrivilegeMode priv = cpu->privilegeMode; int32_t r = cpu->gprs[rd]; ARMSetPrivilegeMode(cpu, MODE_USER);

@@ -672,7 +678,7 @@ cpu->memory.store8(cpu, address, r, &currentCycles);

ARMSetPrivilegeMode(cpu, priv); ARM_STORE_POST_BODY;) -DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(STRT, +DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(STRT, STORE, enum PrivilegeMode priv = cpu->privilegeMode; int32_t r = cpu->gprs[rd]; ARMSetPrivilegeMode(cpu, MODE_USER);

@@ -683,7 +689,7 @@

DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(LDM, load, currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32; - if (rs & 0x8000) { + if ((rs & 0x8000) || !rs) { currentCycles += ARMWritePC(cpu); })
M src/arm/isa-thumb.csrc/arm/isa-thumb.c

@@ -295,6 +295,9 @@ load,

IA, , THUMB_LOAD_POST_BODY; + if (!rs) { + currentCycles += ThumbWritePC(cpu); + } if (!((1 << rn) & rs)) { cpu->gprs[rn] = address; })
M src/core/bitmap-cache.csrc/core/bitmap-cache.c

@@ -11,6 +11,7 @@ void mBitmapCacheInit(struct mBitmapCache* cache) {

// TODO: Reconfigurable cache for space savings cache->cache = NULL; cache->config = mBitmapCacheConfigurationFillShouldStore(0); + cache->sysConfig = 0; cache->status = NULL; cache->palette = NULL; cache->buffer = 0;

@@ -18,14 +19,18 @@ }

static void _freeCache(struct mBitmapCache* cache) { size_t size = mBitmapCacheSystemInfoGetHeight(cache->sysConfig) * mBitmapCacheSystemInfoGetBuffers(cache->sysConfig); - mappedMemoryFree(cache->cache, mBitmapCacheSystemInfoGetWidth(cache->sysConfig) * size * sizeof(color_t)); - mappedMemoryFree(cache->status, size * sizeof(*cache->status)); + if (cache->cache) { + mappedMemoryFree(cache->cache, mBitmapCacheSystemInfoGetWidth(cache->sysConfig) * size * sizeof(color_t)); + cache->cache = NULL; + } + if (cache->status) { + mappedMemoryFree(cache->status, size * sizeof(*cache->status)); + cache->status = NULL; + } if (cache->palette) { free(cache->palette); + cache->palette = NULL; } - cache->cache = NULL; - cache->status = NULL; - cache->palette = NULL; } static void _redoCacheSize(struct mBitmapCache* cache) {
M src/core/cheats.csrc/core/cheats.c

@@ -334,7 +334,7 @@ bool mCheatParseEZFChtFile(struct mCheatDevice* device, struct VFile* vf) {

char cheat[MAX_LINE_LENGTH]; char cheatName[MAX_LINE_LENGTH]; char miniline[32]; - size_t cheatNameLength; + size_t cheatNameLength = 0; struct mCheatSet* set = NULL; cheatName[MAX_LINE_LENGTH - 1] = '\0';
M src/core/map-cache.csrc/core/map-cache.c

@@ -11,15 +11,20 @@ void mMapCacheInit(struct mMapCache* cache) {

// TODO: Reconfigurable cache for space savings cache->cache = NULL; cache->config = mMapCacheConfigurationFillShouldStore(0); + cache->sysConfig = 0; cache->status = NULL; } static void _freeCache(struct mMapCache* cache) { size_t tiles = (1 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig)) * (1 << mMapCacheSystemInfoGetTilesHigh(cache->sysConfig)); - mappedMemoryFree(cache->cache, 8 * 8 * sizeof(color_t) * tiles); - mappedMemoryFree(cache->status, tiles * sizeof(*cache->status)); - cache->cache = NULL; - cache->status = NULL; + if (cache->cache) { + mappedMemoryFree(cache->cache, 8 * 8 * sizeof(color_t) * tiles); + cache->cache = NULL; + } + if (cache->status) { + mappedMemoryFree(cache->status, tiles * sizeof(*cache->status)); + cache->status = NULL; + } } static void _redoCacheSize(struct mMapCache* cache) {
M src/core/tile-cache.csrc/core/tile-cache.c

@@ -51,6 +51,9 @@ cache->palette = malloc(size * bpp * sizeof(*cache->palette));

} void mTileCacheConfigure(struct mTileCache* cache, mTileCacheConfiguration config) { + if (cache->config == config) { + return; + } _freeCache(cache); cache->config = config; _redoCacheSize(cache);

@@ -278,5 +281,9 @@ return &cache->palette[paletteId << (1 << cache->bpp)];

} const uint16_t* mTileCacheGetVRAM(struct mTileCache* cache, unsigned tileId) { + unsigned tiles = mTileCacheSystemInfoGetMaxTiles(cache->sysConfig); + if (tileId >= tiles) { + return NULL; + } return &cache->vram[tileId << (cache->bpp + 2)]; }
M src/gb/memory.csrc/gb/memory.c

@@ -649,7 +649,15 @@ }

break; case GB_REGION_EXTERNAL_RAM: case GB_REGION_EXTERNAL_RAM + 1: - mLOG(GB_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address); + if (memory->rtcAccess) { + memory->rtcRegs[memory->activeRtcReg] = value; + } else if (memory->sramAccess && memory->sram && memory->mbcType != GB_MBC2) { + // TODO: Remove sramAccess check? + memory->sramBank[address & (GB_SIZE_EXTERNAL_RAM - 1)] = value; + } else { + memory->mbcWrite(gb, address, value); + } + gb->sramDirty |= GB_SRAM_DIRT_NEW; return; case GB_REGION_WORKING_RAM_BANK0: case GB_REGION_WORKING_RAM_BANK0 + 2:
M src/gb/renderers/cache-set.csrc/gb/renderers/cache-set.c

@@ -12,11 +12,13 @@ #include <mgba/internal/gb/video.h>

void GBVideoCacheInit(struct mCacheSet* cache) { mCacheSetInit(cache, 2, 0, 1); - mTileCacheConfiguration config = 0; - config = mTileCacheSystemInfoSetPaletteBPP(config, 1); // 2^(2^1) = 4 entries - config = mTileCacheSystemInfoSetPaletteCount(config, 4); // 16 palettes - config = mTileCacheSystemInfoSetMaxTiles(config, 1024); - mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 0), config, 0, 0); + mTileCacheSystemInfo sysconfig = 0; + mTileCacheConfiguration config = mTileCacheConfigurationFillShouldStore(0); + sysconfig = mTileCacheSystemInfoSetPaletteBPP(sysconfig, 1); // 2^(2^1) = 4 entries + sysconfig = mTileCacheSystemInfoSetPaletteCount(sysconfig, 4); // 16 palettes + sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 1024); + mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 0), sysconfig, 0, 0); + mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 0), config); mMapCacheSetGetPointer(&cache->maps, 0)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0); mMapCacheSetGetPointer(&cache->maps, 1)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0);
M src/gba/dma.csrc/gba/dma.c

@@ -95,6 +95,8 @@ }

if (currentDma->nextDest & (width - 1)) { mLOG(GBA_MEM, GAME_ERROR, "Misaligned DMA destination address: 0x%08X", currentDma->nextDest); } + currentDma->nextSource &= -width; + currentDma->nextDest &= -width; GBADMASchedule(gba, dma, currentDma); }

@@ -242,8 +244,6 @@ cycles += memory->waitstatesNonseq32[sourceRegion] + memory->waitstatesNonseq32[destRegion];

} else { cycles += memory->waitstatesNonseq16[sourceRegion] + memory->waitstatesNonseq16[destRegion]; } - source &= -width; - dest &= -width; } else { if (width == 4) { cycles += memory->waitstatesSeq32[sourceRegion] + memory->waitstatesSeq32[destRegion];
M src/gba/memory.csrc/gba/memory.c

@@ -353,10 +353,10 @@ break; \

case REGION_WORKING_IRAM: \ /* This doesn't handle prefetch clobbering */ \ if (cpu->gprs[ARM_PC] & 2) { \ - value |= cpu->prefetch[0] << 16; \ - } else { \ value <<= 16; \ value |= cpu->prefetch[0]; \ + } else { \ + value |= cpu->prefetch[0] << 16; \ } \ break; \ default: \

@@ -1326,6 +1326,12 @@ }

} #define LDM_LOOP(LDM) \ + if (UNLIKELY(!mask)) { \ + LDM; \ + cpu->gprs[ARM_PC] = value; \ + wait += 16; \ + address += 64; \ + } \ for (i = 0; i < 16; i += 4) { \ if (UNLIKELY(mask & (1 << i))) { \ LDM; \

@@ -1438,6 +1444,12 @@ return address | addressMisalign;

} #define STM_LOOP(STM) \ + if (UNLIKELY(!mask)) { \ + value = cpu->gprs[ARM_PC] + (cpu->executionMode == MODE_ARM ? WORD_SIZE_ARM : WORD_SIZE_THUMB); \ + STM; \ + wait += 16; \ + address += 64; \ + } \ for (i = 0; i < 16; i += 4) { \ if (UNLIKELY(mask & (1 << i))) { \ value = cpu->gprs[i]; \
M src/gba/renderers/cache-set.csrc/gba/renderers/cache-set.c

@@ -17,20 +17,20 @@ mTileCacheConfiguration config = mTileCacheConfigurationFillShouldStore(0);

sysconfig = mTileCacheSystemInfoSetPaletteBPP(sysconfig, 2); // 2^(2^2) = 16 entries sysconfig = mTileCacheSystemInfoSetPaletteCount(sysconfig, 4); // 16 palettes sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 2048); - mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 0), config); mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 0), sysconfig, 0, 0); + mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 0), config); sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 1024); - mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 2), config); mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 2), sysconfig, 0x10000, 0x100); + mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 2), config); sysconfig = mTileCacheSystemInfoSetPaletteBPP(sysconfig, 3); // 2^(2^3) = 256 entries sysconfig = mTileCacheSystemInfoSetPaletteCount(sysconfig, 0); // 1 palettes sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 2048); - mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 1), config); mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 1), sysconfig, 0, 0); + mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 1), config); sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 1024); - mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 3), config); mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 3), sysconfig, 0x10000, 0x100); + mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 3), config); mBitmapCacheSystemInfo bitConfig; bitConfig = mBitmapCacheSystemInfoSetEntryBPP(0, 4);

@@ -50,6 +50,11 @@ bitConfig = mBitmapCacheSystemInfoSetBuffers(bitConfig, 2);

mBitmapCacheConfigureSystem(mBitmapCacheSetGetPointer(&cache->bitmaps, 1), bitConfig); mBitmapCacheSetGetPointer(&cache->bitmaps, 1)->bitsStart[0] = 0; mBitmapCacheSetGetPointer(&cache->bitmaps, 1)->bitsStart[1] = 0xA000; + + mMapCacheSetGetPointer(&cache->maps, 0)->context = NULL; + mMapCacheSetGetPointer(&cache->maps, 1)->context = NULL; + mMapCacheSetGetPointer(&cache->maps, 2)->context = NULL; + mMapCacheSetGetPointer(&cache->maps, 3)->context = NULL; } void GBAVideoCacheAssociate(struct mCacheSet* cache, struct GBAVideo* video) {
M src/gba/renderers/gl.csrc/gba/renderers/gl.c

@@ -145,21 +145,21 @@ " }\n"

" if (mosaic.y > 1) {\n" " coord.y -= coord.y % mosaic.y;\n" " }\n" - " coord += (ivec2(0x3FF, 0x3FF000) & offset[int(texCoord.y)]) >> ivec2(0, 12);\n" - " ivec2 wrap = ivec2(255, 511);\n" - " if (size == 3) {\n" - " coord.y += (coord.y & 256) << 1;\n" - " wrap.y = 1023;\n" - " } else if (size == 0) {\n" - " wrap.y = 255;\n" - " }\n" - " if (size != 2) {\n" - " coord.y &= ~256;\n" - " }\n" + " coord += (ivec2(0x1FF, 0x1FF000) & offset[int(texCoord.y)]) >> ivec2(0, 12);\n" + " ivec2 wrap = ivec2(255, 255);\n" + " int doty = 0;\n" " if ((size & 1) == 1) {\n" - " coord.y += coord.x & 256;\n" + " wrap.x = 511;\n" + " ++doty;\n" + " }\n" + " if ((size & 2) == 2) {\n" + " wrap.y = 511;\n" + " ++doty;\n" " }\n" " coord &= wrap;\n" + " wrap = coord & 256;\n" + " coord &= 255;\n" + " coord.y += wrap.x + wrap.y * doty;\n" " int mapAddress = screenBase + (coord.x >> 3) + (coord.y >> 3) * 32;\n" " vec4 map = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0);\n" " int tileFlags = int(map.g * 15.9);\n"
M src/gba/sio/lockstep.csrc/gba/sio/lockstep.c

@@ -47,6 +47,7 @@ }

lockstep->players[lockstep->d.attached] = node; node->p = lockstep; node->id = lockstep->d.attached; + node->transferFinished = true; ++lockstep->d.attached; return true; }
M src/platform/3ds/main.csrc/platform/3ds/main.c

@@ -417,6 +417,46 @@ break;

} } +static u32 _setupTex(int out, bool faded) { + ctrActivateTexture(&outputTexture[out]); + u32 color; + if (!faded) { + color = 0xFFFFFFFF; + switch (darkenMode) { + case DM_NATIVE: + case DM_MAX: + break; + case DM_MULT_SCALE_BIAS: + ctrTextureBias(0x070707); + // Fall through + case DM_MULT_SCALE: + color = 0xFF707070; + // Fall through + case DM_MULT: + ctrTextureMultiply(); + break; + } + } else { + color = 0xFF484848; + switch (darkenMode) { + case DM_NATIVE: + case DM_MAX: + break; + case DM_MULT_SCALE_BIAS: + ctrTextureBias(0x030303); + // Fall through + case DM_MULT_SCALE: + color = 0xFF303030; + // Fall through + case DM_MULT: + ctrTextureMultiply(); + break; + } + + } + return color; +} + static void _drawTex(struct mCore* core, bool faded, bool both) { unsigned screen_w, screen_h; switch (screenMode) {

@@ -485,45 +525,10 @@ ctrSetViewportSize(screen_w, screen_h, false);

break; } - u32 color; - if (!faded) { - color = 0xFFFFFFFF; - switch (darkenMode) { - case DM_NATIVE: - case DM_MAX: - break; - case DM_MULT_SCALE_BIAS: - ctrTextureBias(0x070707); - // Fall through - case DM_MULT_SCALE: - color = 0xFF707070; - // Fall through - case DM_MULT: - ctrTextureMultiply(); - break; - } - } else { - color = 0xFF484848; - switch (darkenMode) { - case DM_NATIVE: - case DM_MAX: - break; - case DM_MULT_SCALE_BIAS: - ctrTextureBias(0x030303); - // Fall through - case DM_MULT_SCALE: - color = 0xFF303030; - // Fall through - case DM_MULT: - ctrTextureMultiply(); - break; - } - - } - ctrActivateTexture(&outputTexture[activeOutputTexture]); + uint32_t color = _setupTex(activeOutputTexture, faded); ctrAddRectEx(color, x, y, w, h, 0, 0, corew, coreh, 0); if (both) { - ctrActivateTexture(&outputTexture[activeOutputTexture ^ 1]); + color = _setupTex(activeOutputTexture ^ 1, faded); ctrAddRectEx(color & 0x7FFFFFFF, x, y, w, h, 0, 0, corew, coreh, 0); } ctrFlushBatch();
M src/platform/psp2/main.csrc/platform/psp2/main.c

@@ -165,6 +165,7 @@ };

sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START); sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG_WIDE); + sceCtrlSetSamplingModeExt(SCE_CTRL_MODE_ANALOG_WIDE); sceSysmoduleLoadModule(SCE_SYSMODULE_PHOTO_EXPORT); sceSysmoduleLoadModule(SCE_SYSMODULE_APPUTIL);
M src/platform/qt/AssetView.cppsrc/platform/qt/AssetView.cpp

@@ -66,6 +66,9 @@ updateTiles(true);

} void AssetView::compositeTile(const void* tBuffer, void* buffer, size_t stride, size_t x, size_t y, int depth) { + if (!tBuffer) { + return; + } const uint8_t* tile = static_cast<const uint8_t*>(tBuffer); uint8_t* pixels = static_cast<uint8_t*>(buffer); size_t base = stride * y + x;
M src/platform/qt/CheatsView.cppsrc/platform/qt/CheatsView.cpp

@@ -129,7 +129,6 @@ m_model.addSet(set);

} void CheatsView::removeSet() { - GBACheatSet* set; QModelIndexList selection = m_ui.cheatList->selectionModel()->selectedIndexes(); if (selection.count() < 1) { return;
M src/platform/qt/CoreController.cppsrc/platform/qt/CoreController.cpp

@@ -637,12 +637,16 @@ void CoreController::yankPak() {

Interrupter interrupter(this); switch (platform()) { +#ifdef M_CORE_GBA case PLATFORM_GBA: GBAYankROM(static_cast<GBA*>(m_threadContext.core->board)); break; +#endif +#ifdef M_CORE_GB case PLATFORM_GB: GBYankROM(static_cast<GB*>(m_threadContext.core->board)); break; +#endif } }
M src/platform/qt/CoreController.hsrc/platform/qt/CoreController.h

@@ -226,7 +226,7 @@ bool m_videoSync = VIDEO_SYNC;

bool m_autosave; bool m_autoload; - int m_autosaveCounter; + int m_autosaveCounter = 0; int m_fastForward = false; int m_fastForwardForced = false;
M src/platform/qt/Display.cppsrc/platform/qt/Display.cpp

@@ -26,7 +26,11 @@

switch (s_driver) { #if defined(BUILD_GL) || defined(BUILD_GLES2) || defined(USE_EPOXY) case Driver::OPENGL: - format.setVersion(3, 2); + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) { + format.setVersion(3, 0); + } else { + format.setVersion(3, 2); + } format.setProfile(QSurfaceFormat::CoreProfile); return new DisplayGL(format, parent); #endif
M src/platform/qt/GBAKeyEditor.cppsrc/platform/qt/GBAKeyEditor.cpp

@@ -232,7 +232,7 @@ m_controller->saveConfiguration(m_type);

#ifdef BUILD_SDL if (m_profileSelect) { - m_controller->setPreferredGamepad(m_type, m_profileSelect->currentText()); + m_controller->setPreferredGamepad(m_type, m_profileSelect->currentIndex()); } #endif
M src/platform/qt/MapView.cppsrc/platform/qt/MapView.cpp

@@ -167,6 +167,7 @@ int priority = -1;

int frame = 0; QString offset(tr("N/A")); QString transform(tr("N/A")); +#ifdef M_CORE_GBA if (m_controller->platform() == PLATFORM_GBA) { uint16_t* io = static_cast<GBA*>(m_controller->thread()->core->board)->memory.io; int mode = GBARegisterDISPCNTGetMode(io[REG_DISPCNT >> 1]);

@@ -199,12 +200,15 @@ .arg(io[(REG_BG2PD >> 1) + ((m_map - 2) << 2)] / 256., 3, 'f', 2);

} } +#endif +#ifdef M_CORE_GB if (m_controller->platform() == PLATFORM_GB) { uint8_t* io = static_cast<GB*>(m_controller->thread()->core->board)->memory.io; int x = io[m_map == 0 ? 0x42 : 0x4A]; int y = io[m_map == 0 ? 0x43 : 0x4B]; offset = QString("%1, %2").arg(x).arg(y); } +#endif if (bitmap >= 0) { mBitmapCache* bitmapCache = mBitmapCacheSetGetPointer(&m_cacheSet->bitmaps, bitmap); int width = mBitmapCacheSystemInfoGetWidth(bitmapCache->sysConfig);

@@ -266,4 +270,4 @@

void MapView::copyMap() { CoreController::Interrupter interrupter(m_controller); GBAApp::app()->clipboard()->setImage(m_rawMap); -}+}
M src/platform/qt/MemoryModel.cppsrc/platform/qt/MemoryModel.cpp

@@ -88,6 +88,19 @@ m_top = position;

update(); }); + connect(verticalScrollBar(), &QSlider::actionTriggered, [this](int action) { + if (action == QSlider::SliderSingleStepAdd) { + ++m_top; + } else if (action == QSlider::SliderSingleStepSub) { + --m_top; + } else { + return; + } + boundsCheck(); + verticalScrollBar()->setValue(m_top); + update(); + }); + setRegion(0, 0x10000000, tr("All")); }
M src/platform/qt/MultiplayerController.cppsrc/platform/qt/MultiplayerController.cpp

@@ -22,11 +22,13 @@ , gbNode(node)

{ } +#ifdef M_CORE_GBA MultiplayerController::Player::Player(CoreController* coreController, GBASIOLockstepNode* node) : controller(coreController) , gbaNode(node) { } +#endif MultiplayerController::MultiplayerController() { mLockstepInit(&m_lockstep);

@@ -71,10 +73,12 @@ MultiplayerController* controller = static_cast<MultiplayerController*>(lockstep->context);

if (!id) { for (int i = 1; i < controller->m_players.count(); ++i) { Player* player = &controller->m_players[i]; +#ifdef M_CORE_GBA if (player->controller->platform() == PLATFORM_GBA && player->gbaNode->d.p->mode != controller->m_players[0].gbaNode->d.p->mode) { player->controller->setSync(true); continue; } +#endif player->controller->setSync(false); player->cyclesPosted += cycles; if (player->awake < 1) {
M src/platform/qt/MultiplayerController.hsrc/platform/qt/MultiplayerController.h

@@ -45,8 +45,12 @@ void gameDetached();

private: struct Player { +#ifdef M_CORE_GB Player(CoreController* controller, GBSIOLockstepNode* node); +#endif +#ifdef M_CORE_GBA Player(CoreController* controller, GBASIOLockstepNode* node); +#endif CoreController* controller; GBSIOLockstepNode* gbNode = nullptr;
M src/platform/qt/OverrideView.cppsrc/platform/qt/OverrideView.cpp

@@ -69,6 +69,7 @@ m_ui.hwTilt->setEnabled(!enabled);

m_ui.hwRumble->setEnabled(!enabled); }); +#ifdef M_CORE_GB m_colorPickers[0] = ColorPicker(m_ui.color0, QColor(0xF8, 0xF8, 0xF8)); m_colorPickers[1] = ColorPicker(m_ui.color1, QColor(0xA8, 0xA8, 0xA8)); m_colorPickers[2] = ColorPicker(m_ui.color2, QColor(0x50, 0x50, 0x50));

@@ -86,6 +87,7 @@ connect(&m_colorPickers[colorId], &ColorPicker::colorChanged, this, [this, colorId](const QColor& color) {

m_gbColors[colorId] = color.rgb() | 0xFF000000; }); } +#endif #ifndef M_CORE_GBA m_ui.tabWidget->removeTab(m_ui.tabWidget->indexOf(m_ui.tabGBA));
M src/platform/qt/ShaderSelector.cppsrc/platform/qt/ShaderSelector.cpp

@@ -33,6 +33,7 @@ ShaderSelector::ShaderSelector(Display* display, ConfigController* config, QWidget* parent)

: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint) , m_display(display) , m_config(config) + , m_shaderPath(config->getOption("shader")) { m_ui.setupUi(this);

@@ -41,9 +42,6 @@

connect(m_ui.load, &QAbstractButton::clicked, this, &ShaderSelector::selectShader); connect(m_ui.unload, &QAbstractButton::clicked, this, &ShaderSelector::clearShader); connect(m_ui.buttonBox, &QDialogButtonBox::clicked, this, &ShaderSelector::buttonPressed); - connect(this, &ShaderSelector::saved, [this]() { - m_config->setOption("shader", m_shaderPath); - }); } ShaderSelector::~ShaderSelector() {

@@ -85,12 +83,14 @@ }

m_display->setShaders(shader); shader->close(shader); m_shaderPath = path; + m_config->setOption("shader", m_shaderPath); } void ShaderSelector::clearShader() { m_display->clearShaders(); refreshShaders(); m_shaderPath = ""; + m_config->setOption("shader", m_shaderPath); } void ShaderSelector::refreshShaders() {

@@ -118,10 +118,6 @@

disconnect(this, &ShaderSelector::saved, 0, 0); disconnect(this, &ShaderSelector::reset, 0, 0); disconnect(this, &ShaderSelector::resetToDefault, 0, 0); - - connect(this, &ShaderSelector::saved, [this]() { - m_config->setOption("shader", m_shaderPath); - }); #if !defined(_WIN32) || defined(USE_EPOXY) if (m_shaders->preprocessShader) {
M src/platform/qt/TilePainter.cppsrc/platform/qt/TilePainter.cpp

@@ -26,6 +26,9 @@ }

void TilePainter::resizeEvent(QResizeEvent* event) { int w = width() / m_size; + if (!w) { + w = 1; + } int calculatedHeight = (m_tileCount + w - 1) * m_size / w; calculatedHeight -= calculatedHeight % m_size; if (width() / m_size != m_backing.width() / m_size || m_backing.height() != calculatedHeight) {
M src/platform/qt/Window.cppsrc/platform/qt/Window.cpp

@@ -1497,7 +1497,9 @@

ConfigOption* mute = m_config->addOption("mute"); mute->addBoolean(tr("Mute"), &m_actions, "av"); mute->connect([this](const QVariant& value) { - m_config->setOption("fastForwardMute", static_cast<bool>(value.toInt())); + if (value.toInt()) { + m_config->setOption("fastForwardMute", true); + } reloadConfig(); }, this); m_config->updateOption("mute");
M src/platform/qt/input/InputController.cppsrc/platform/qt/input/InputController.cpp

@@ -383,11 +383,13 @@ }

#endif } -void InputController::setPreferredGamepad(uint32_t type, const QString& device) { +void InputController::setPreferredGamepad(uint32_t type, int index) { if (!m_config) { return; } - mInputSetPreferredDevice(m_config->input(), "gba", type, m_playerId, device.toUtf8().constData()); + char name[34] = {0}; + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, index)->joystick), name, sizeof(name)); + mInputSetPreferredDevice(m_config->input(), "gba", type, m_playerId, name); } mRumble* InputController::rumble() {
M src/platform/qt/input/InputController.hsrc/platform/qt/input/InputController.h

@@ -99,7 +99,7 @@

QStringList connectedGamepads(uint32_t type) const; int gamepad(uint32_t type) const; void setGamepad(uint32_t type, int index); - void setPreferredGamepad(uint32_t type, const QString& device); + void setPreferredGamepad(uint32_t type, int index); void registerTiltAxisX(int axis); void registerTiltAxisY(int axis);
M src/platform/qt/ts/medusa-emu-de.tssrc/platform/qt/ts/medusa-emu-de.ts

@@ -3820,7 +3820,7 @@ </message>

<message> <location filename="../Window.cpp" line="1121"/> <source>Load state file...</source> - <translation>Ssavestate-Datei laden...</translation> + <translation>Savestate-Datei laden...</translation> </message> <message> <location filename="../Window.cpp" line="1126"/>
M src/platform/qt/ts/mgba-zh_CN.tssrc/platform/qt/ts/mgba-zh_CN.ts

@@ -589,19 +589,25 @@ <source>Maps</source>

<translation>贴图</translation> </message> <message> - <location filename="../MapView.ui" line="31"/> - <source>Export</source> - <translation>导出</translation> - </message> - <message> + <location filename="../MapView.ui" line="30"/> <location filename="../MapView.ui" line="61"/> <source>×</source> <translation>×</translation> </message> <message> - <location filename="../MapView.ui" line="74"/> + <location filename="../MapView.ui" line="43"/> <source>Magnification</source> <translation>缩放率</translation> + </message> + <message> + <location filename="../MapView.ui" line="124"/> + <source>Export</source> + <translation>导出</translation> + </message> + <message> + <location filename="../MapView.ui" line="139"/> + <source>Copy</source> + <translation>复制</translation> </message> </context> <context>

@@ -641,124 +647,149 @@ </context>

<context> <name>MemorySearch</name> <message> - <location filename="../MemorySearch.ui" line="20"/> + <location filename="../MemorySearch.ui" line="26"/> <source>Memory Search</source> <translation>内存查找</translation> </message> <message> - <location filename="../MemorySearch.ui" line="45"/> + <location filename="../MemorySearch.ui" line="51"/> <source>Address</source> <translation>地址</translation> </message> <message> - <location filename="../MemorySearch.ui" line="50"/> + <location filename="../MemorySearch.ui" line="56"/> <source>Current Value</source> <translation>当前值</translation> </message> <message> - <location filename="../MemorySearch.ui" line="55"/> - <location filename="../MemorySearch.ui" line="75"/> + <location filename="../MemorySearch.ui" line="61"/> + <location filename="../MemorySearch.ui" line="81"/> <source>Type</source> <translation>类型</translation> </message> <message> - <location filename="../MemorySearch.ui" line="65"/> + <location filename="../MemorySearch.ui" line="71"/> <source>Value</source> <translation>值</translation> </message> <message> - <location filename="../MemorySearch.ui" line="82"/> + <location filename="../MemorySearch.ui" line="88"/> <source>Numeric</source> <translation>数字</translation> </message> <message> - <location filename="../MemorySearch.ui" line="95"/> + <location filename="../MemorySearch.ui" line="101"/> <source>Text</source> <translation>文本</translation> </message> <message> - <location filename="../MemorySearch.ui" line="112"/> + <location filename="../MemorySearch.ui" line="118"/> <source>Width</source> <translation>位宽</translation> </message> <message> - <location filename="../MemorySearch.ui" line="119"/> - <location filename="../MemorySearch.ui" line="179"/> + <location filename="../MemorySearch.ui" line="125"/> + <location filename="../MemorySearch.ui" line="185"/> <source>Guess</source> - <translation>猜测</translation> + <translation>估计</translation> </message> <message> - <location filename="../MemorySearch.ui" line="132"/> + <location filename="../MemorySearch.ui" line="138"/> <source>1 Byte (8-bit)</source> <translation>1 字节 (8 位)</translation> </message> <message> - <location filename="../MemorySearch.ui" line="142"/> + <location filename="../MemorySearch.ui" line="148"/> <source>2 Bytes (16-bit)</source> <translation>2 字节 (16 位)</translation> </message> <message> - <location filename="../MemorySearch.ui" line="152"/> + <location filename="../MemorySearch.ui" line="158"/> <source>4 Bytes (32-bit)</source> <translation>4 字节 (32 位)</translation> </message> <message> - <location filename="../MemorySearch.ui" line="172"/> + <location filename="../MemorySearch.ui" line="178"/> <source>Number type</source> <translation>数字进制</translation> </message> <message> - <location filename="../MemorySearch.ui" line="189"/> + <location filename="../MemorySearch.ui" line="195"/> <source>Decimal</source> <translation>十进制</translation> </message> <message> - <location filename="../MemorySearch.ui" line="196"/> + <location filename="../MemorySearch.ui" line="202"/> <source>Hexadecimal</source> <translation>十六进制</translation> </message> <message> - <location filename="../MemorySearch.ui" line="210"/> + <location filename="../MemorySearch.ui" line="216"/> <source>Compare</source> <translation>比较</translation> </message> <message> - <location filename="../MemorySearch.ui" line="217"/> - <source>Equal</source> - <translation>等于</translation> + <location filename="../MemorySearch.ui" line="223"/> + <source>Equal to value</source> + <translation>约等于下值</translation> </message> <message> - <location filename="../MemorySearch.ui" line="230"/> - <source>Greater</source> - <translation>大于</translation> + <location filename="../MemorySearch.ui" line="236"/> + <source>Greater than value</source> + <translation>大于下值</translation> </message> <message> - <location filename="../MemorySearch.ui" line="240"/> - <source>Less</source> - <translation>小于</translation> + <location filename="../MemorySearch.ui" line="246"/> + <source>Less than value</source> + <translation>小于下值</translation> </message> <message> - <location filename="../MemorySearch.ui" line="253"/> - <source>Delta</source> - <translation>相差</translation> + <location filename="../MemorySearch.ui" line="256"/> + <source>Unknown/changed</source> + <translation>未知/已更改</translation> + </message> + <message> + <location filename="../MemorySearch.ui" line="269"/> + <source>Changed by value</source> + <translation>由下值更改</translation> + </message> + <message> + <location filename="../MemorySearch.ui" line="282"/> + <source>Unchanged</source> + <translation>无更改</translation> + </message> + <message> + <location filename="../MemorySearch.ui" line="295"/> + <source>Increased</source> + <translation>增加</translation> + </message> + <message> + <location filename="../MemorySearch.ui" line="308"/> + <source>Decreased</source> + <translation>减少</translation> </message> <message> - <location filename="../MemorySearch.ui" line="274"/> - <source>Search</source> - <translation>查找</translation> + <location filename="../MemorySearch.ui" line="318"/> + <source>Search ROM</source> + <translation>查找 ROM</translation> </message> <message> - <location filename="../MemorySearch.ui" line="281"/> + <location filename="../MemorySearch.ui" line="336"/> + <source>New Search</source> + <translation>新的查找</translation> + </message> + <message> + <location filename="../MemorySearch.ui" line="343"/> <source>Search Within</source> <translation>在结果中查找</translation> </message> <message> - <location filename="../MemorySearch.ui" line="288"/> + <location filename="../MemorySearch.ui" line="350"/> <source>Open in Memory Viewer</source> <translation>在内存查看器中打开</translation> </message> <message> - <location filename="../MemorySearch.ui" line="295"/> + <location filename="../MemorySearch.ui" line="357"/> <source>Refresh</source> <translation>刷新</translation> </message>

@@ -854,142 +885,147 @@ <source>Sprites</source>

<translation>精灵图</translation> </message> <message> - <location filename="../ObjView.ui" line="56"/> - <location filename="../ObjView.ui" line="506"/> + <location filename="../ObjView.ui" line="20"/> + <source>Copy</source> + <translation>复制</translation> + </message> + <message> + <location filename="../ObjView.ui" line="35"/> + <source>Position</source> + <translation>位置</translation> + </message> + <message> + <location filename="../ObjView.ui" line="61"/> + <location filename="../ObjView.ui" line="87"/> + <location filename="../ObjView.ui" line="278"/> + <location filename="../ObjView.ui" line="508"/> + <source>0</source> + <translation>0</translation> + </message> + <message> + <location filename="../ObjView.ui" line="71"/> + <source>, </source> + <translation>, </translation> + </message> + <message> + <location filename="../ObjView.ui" line="101"/> + <source>Dimensions</source> + <translation>维度</translation> + </message> + <message> + <location filename="../ObjView.ui" line="127"/> + <location filename="../ObjView.ui" line="153"/> + <source>8</source> + <translation>8</translation> + </message> + <message> + <location filename="../ObjView.ui" line="137"/> + <location filename="../ObjView.ui" line="568"/> <source>×</source> <translation>×</translation> </message> <message> - <location filename="../ObjView.ui" line="69"/> - <source>Magnification</source> - <translation>缩放率</translation> + <location filename="../ObjView.ui" line="205"/> + <source>Tile</source> + <translation>瓷贴</translation> </message> <message> - <location filename="../ObjView.ui" line="76"/> + <location filename="../ObjView.ui" line="212"/> <source>Export</source> <translation>导出</translation> </message> <message> - <location filename="../ObjView.ui" line="85"/> + <location filename="../ObjView.ui" line="219"/> <source>Attributes</source> <translation>属性</translation> </message> <message> - <location filename="../ObjView.ui" line="93"/> + <location filename="../ObjView.ui" line="227"/> <source>Transform</source> <translation>变换</translation> </message> <message> - <location filename="../ObjView.ui" line="113"/> + <location filename="../ObjView.ui" line="247"/> <source>Off</source> <translation>关</translation> </message> <message> - <location filename="../ObjView.ui" line="124"/> + <location filename="../ObjView.ui" line="258"/> <source>Palette</source> <translation>调色板</translation> </message> <message> - <location filename="../ObjView.ui" line="144"/> - <location filename="../ObjView.ui" line="374"/> - <location filename="../ObjView.ui" line="430"/> - <location filename="../ObjView.ui" line="456"/> - <source>0</source> - <translation>0</translation> - </message> - <message> - <location filename="../ObjView.ui" line="158"/> + <location filename="../ObjView.ui" line="292"/> <source>Double Size</source> <translation>双倍大小</translation> </message> <message> - <location filename="../ObjView.ui" line="184"/> - <location filename="../ObjView.ui" line="228"/> - <location filename="../ObjView.ui" line="241"/> - <location filename="../ObjView.ui" line="309"/> + <location filename="../ObjView.ui" line="318"/> + <location filename="../ObjView.ui" line="362"/> + <location filename="../ObjView.ui" line="375"/> + <location filename="../ObjView.ui" line="443"/> <source>Return, Ctrl+R</source> <translation>回车键、Ctrl+R</translation> </message> <message> - <location filename="../ObjView.ui" line="202"/> + <location filename="../ObjView.ui" line="336"/> <source>Flipped</source> <translation>已翻转</translation> </message> <message> - <location filename="../ObjView.ui" line="225"/> + <location filename="../ObjView.ui" line="359"/> <source>H</source> <translation>水平</translation> </message> <message> - <location filename="../ObjView.ui" line="238"/> + <location filename="../ObjView.ui" line="372"/> <source>V</source> <translation>垂直</translation> </message> <message> - <location filename="../ObjView.ui" line="252"/> + <location filename="../ObjView.ui" line="386"/> <source>Mode</source> <translation>模式</translation> </message> <message> - <location filename="../ObjView.ui" line="272"/> + <location filename="../ObjView.ui" line="406"/> <source>Normal</source> <translation>普通</translation> </message> <message> - <location filename="../ObjView.ui" line="283"/> + <location filename="../ObjView.ui" line="417"/> <source>Mosaic</source> <translation>马赛克</translation> </message> <message> - <location filename="../ObjView.ui" line="320"/> + <location filename="../ObjView.ui" line="454"/> <source>Enabled</source> <translation>已启用</translation> </message> <message> - <location filename="../ObjView.ui" line="354"/> + <location filename="../ObjView.ui" line="488"/> <source>Priority</source> <translation>优先级</translation> </message> <message> - <location filename="../ObjView.ui" line="389"/> - <source>Tile</source> - <translation>瓷贴</translation> - </message> - <message> <location filename="../ObjView.ui" line="396"/> <source>Geometry</source> <translation>几何图像</translation> </message> <message> - <location filename="../ObjView.ui" line="404"/> - <source>Position</source> - <translation>位置</translation> - </message> - <message> - <location filename="../ObjView.ui" line="440"/> - <source>,</source> - <translation>,</translation> - </message> - <message> - <location filename="../ObjView.ui" line="470"/> - <source>Dimensions</source> - <translation>维度</translation> - </message> - <message> - <location filename="../ObjView.ui" line="496"/> - <location filename="../ObjView.ui" line="522"/> - <source>8</source> - <translation>8</translation> - </message> - <message> - <location filename="../ObjView.ui" line="552"/> + <location filename="../ObjView.ui" line="538"/> <source>Address</source> <translation>地址</translation> </message> <message> - <location filename="../ObjView.ui" line="559"/> + <location filename="../ObjView.ui" line="545"/> <source>0x07000000</source> <translation>0x07000000</translation> + </message> + <message> + <location filename="../ObjView.ui" line="581"/> + <source>Magnification</source> + <translation>缩放率</translation> </message> </context> <context>

@@ -1145,36 +1181,51 @@ <translation>MBC5 + 振动</translation>

</message> <message> <location filename="../OverrideView.ui" line="324"/> + <source>MBC6</source> + <translation>MBC6</translation> + </message> + <message> + <location filename="../OverrideView.ui" line="329"/> <source>MBC7</source> <translation>MBC7</translation> </message> <message> - <location filename="../OverrideView.ui" line="329"/> + <location filename="../OverrideView.ui" line="334"/> + <source>MMM01</source> + <translation>MMM01</translation> + </message> + <message> + <location filename="../OverrideView.ui" line="339"/> <source>Pocket Cam</source> <translation>Pocket Cam</translation> </message> <message> - <location filename="../OverrideView.ui" line="334"/> + <location filename="../OverrideView.ui" line="344"/> <source>TAMA5</source> <translation>TAMA5</translation> </message> <message> - <location filename="../OverrideView.ui" line="339"/> + <location filename="../OverrideView.ui" line="349"/> + <source>HuC-1</source> + <translation>HuC-1</translation> + </message> + <message> + <location filename="../OverrideView.ui" line="354"/> <source>HuC-3</source> <translation>HuC-3</translation> </message> <message> - <location filename="../OverrideView.ui" line="347"/> + <location filename="../OverrideView.ui" line="362"/> <source>Background Colors</source> <translation>背景颜色</translation> </message> <message> - <location filename="../OverrideView.ui" line="434"/> + <location filename="../OverrideView.ui" line="449"/> <source>Sprite Colors 1</source> <translation>精灵图颜色 1</translation> </message> <message> - <location filename="../OverrideView.ui" line="441"/> + <location filename="../OverrideView.ui" line="456"/> <source>Sprite Colors 2</source> <translation>精灵图颜色 2</translation> </message>

@@ -1300,15 +1351,25 @@ <source>Game Boy Printer</source>

<translation>Game Boy 打印机</translation> </message> <message> - <location filename="../PrinterView.ui" line="96"/> + <location filename="../PrinterView.ui" line="130"/> <source>Hurry up!</source> <translation>Hurry up!</translation> </message> <message> - <location filename="../PrinterView.ui" line="103"/> + <location filename="../PrinterView.ui" line="137"/> <source>Tear off</source> <translation>Tear off</translation> </message> + <message> + <location filename="../PrinterView.ui" line="167"/> + <source>×</source> + <translation>×</translation> + </message> + <message> + <location filename="../PrinterView.ui" line="180"/> + <source>Magnification</source> + <translation>缩放率</translation> + </message> </context> <context> <name>QGBA::AssetTile</name>

@@ -1318,9 +1379,9 @@ <source>%0%1%2</source>

<translation>%0%1%2</translation> </message> <message> - <location filename="../AssetTile.cpp" line="140"/> - <location filename="../AssetTile.cpp" line="141"/> - <location filename="../AssetTile.cpp" line="152"/> + <location filename="../AssetTile.cpp" line="143"/> + <location filename="../AssetTile.cpp" line="144"/> + <location filename="../AssetTile.cpp" line="145"/> <source>0x%0 (%1)</source> <translation>0x%0 (%1)</translation> </message>

@@ -3097,82 +3158,84 @@ </context>

<context> <name>QGBA::MapView</name> <message> - <location filename="../MapView.cpp" line="46"/> + <location filename="../MapView.cpp" line="48"/> <source>Priority</source> <translation>优先级</translation> </message> <message> - <location filename="../MapView.cpp" line="47"/> - <location filename="../MapView.cpp" line="59"/> + <location filename="../MapView.cpp" line="49"/> + <location filename="../MapView.cpp" line="61"/> <source>Map base</source> <translation>映射基</translation> </message> <message> - <location filename="../MapView.cpp" line="48"/> - <location filename="../MapView.cpp" line="60"/> + <location filename="../MapView.cpp" line="50"/> + <location filename="../MapView.cpp" line="62"/> <source>Tile base</source> <translation>瓷贴基</translation> </message> <message> - <location filename="../MapView.cpp" line="49"/> + <location filename="../MapView.cpp" line="51"/> <source>Size</source> <translation>大小</translation> </message> <message> - <location filename="../MapView.cpp" line="50"/> - <location filename="../MapView.cpp" line="61"/> + <location filename="../MapView.cpp" line="52"/> + <location filename="../MapView.cpp" line="63"/> <source>offset</source> <translation>偏移</translation> </message> <message> - <location filename="../MapView.cpp" line="51"/> + <location filename="../MapView.cpp" line="53"/> <source>Xform</source> <translation>变换</translation> </message> <message> - <location filename="../MapView.cpp" line="97"/> + <location filename="../MapView.cpp" line="107"/> <source>Map Addr.</source> <translation>映射地址</translation> </message> <message> - <location filename="../MapView.cpp" line="98"/> + <location filename="../MapView.cpp" line="108"/> <source>Mirror</source> <translation>镜像</translation> </message> <message> - <location filename="../MapView.cpp" line="126"/> + <location filename="../MapView.cpp" line="136"/> <source>None</source> <translation>无</translation> </message> <message> - <location filename="../MapView.cpp" line="128"/> + <location filename="../MapView.cpp" line="138"/> <source>Both</source> <translation>两者</translation> </message> <message> - <location filename="../MapView.cpp" line="130"/> + <location filename="../MapView.cpp" line="140"/> <source>Horizontal</source> <translation>水平</translation> </message> <message> - <location filename="../MapView.cpp" line="132"/> + <location filename="../MapView.cpp" line="142"/> <source>Vertical</source> <translation>垂直</translation> </message> <message> - <location filename="../MapView.cpp" line="247"/> + <location filename="../MapView.cpp" line="168"/> + <location filename="../MapView.cpp" line="169"/> + <location filename="../MapView.cpp" line="213"/> + <source>N/A</source> + <translation>无</translation> + </message> + <message> + <location filename="../MapView.cpp" line="256"/> <source>Export map</source> <translation>导出映射</translation> </message> <message> - <location filename="../MapView.cpp" line="248"/> + <location filename="../MapView.cpp" line="257"/> <source>Portable Network Graphics (*.png)</source> <translation>便携式网络图形 (*.png)</translation> - </message> - <message> - <location filename="../MapView.cpp" line="251"/> - <source>Failed to open output PNG file: %1</source> - <translation>打开输出 PNG 文件失败: %1</translation> </message> </context> <context>

@@ -3248,22 +3311,22 @@ </context>

<context> <name>QGBA::MemorySearch</name> <message> - <location filename="../MemorySearch.cpp" line="200"/> + <location filename="../MemorySearch.cpp" line="221"/> <source> (%0/%1×)</source> <translation> (%0/%1×)</translation> </message> <message> - <location filename="../MemorySearch.cpp" line="202"/> + <location filename="../MemorySearch.cpp" line="223"/> <source> (⅟%0×)</source> <translation> (⅟%0×)</translation> </message> <message> - <location filename="../MemorySearch.cpp" line="205"/> + <location filename="../MemorySearch.cpp" line="226"/> <source> (%0×)</source> <translation> (%0×)</translation> </message> <message> - <location filename="../MemorySearch.cpp" line="209"/> + <location filename="../MemorySearch.cpp" line="230"/> <source>%1 byte%2</source> <translation>%1 字节%2</translation> </message>

@@ -3271,49 +3334,49 @@ </context>

<context> <name>QGBA::ObjView</name> <message> - <location filename="../ObjView.cpp" line="119"/> - <location filename="../ObjView.cpp" line="191"/> + <location filename="../ObjView.cpp" line="150"/> + <location filename="../ObjView.cpp" line="224"/> <source>0x%0</source> <translation>0x%0</translation> </message> <message> - <location filename="../ObjView.cpp" line="130"/> + <location filename="../ObjView.cpp" line="161"/> <source>Off</source> <translation>关</translation> </message> <message> - <location filename="../ObjView.cpp" line="135"/> + <location filename="../ObjView.cpp" line="166"/> <source>Normal</source> <translation>一般</translation> </message> <message> - <location filename="../ObjView.cpp" line="138"/> + <location filename="../ObjView.cpp" line="169"/> <source>Trans</source> <translation>变换</translation> </message> <message> - <location filename="../ObjView.cpp" line="141"/> + <location filename="../ObjView.cpp" line="172"/> <source>OBJWIN</source> <translation>OBJWIN</translation> </message> <message> - <location filename="../ObjView.cpp" line="144"/> + <location filename="../ObjView.cpp" line="175"/> <source>Invalid</source> <translation>无效</translation> </message> <message> - <location filename="../ObjView.cpp" line="198"/> - <location filename="../ObjView.cpp" line="199"/> + <location filename="../ObjView.cpp" line="231"/> + <location filename="../ObjView.cpp" line="232"/> <source>N/A</source> <translation>无</translation> </message> <message> - <location filename="../ObjView.cpp" line="204"/> + <location filename="../ObjView.cpp" line="257 "/> <source>Export sprite</source> <translation>导出精灵图</translation> </message> <message> - <location filename="../ObjView.cpp" line="205"/> + <location filename="../ObjView.cpp" line="258"/> <source>Portable Network Graphics (*.png)</source> <translation>便携式网络图形 (*.png)</translation> </message>

@@ -3361,12 +3424,12 @@ </context>

<context> <name>QGBA::PrinterView</name> <message> - <location filename="../PrinterView.cpp" line="35"/> + <location filename="../PrinterView.cpp" line="52"/> <source>Save Printout</source> <translation>保存输出</translation> </message> <message> - <location filename="../PrinterView.cpp" line="35"/> + <location filename="../PrinterView.cpp" line="52"/> <source>Portable Network Graphics (*.png)</source> <translation>便携式网络图形 (*.png)</translation> </message>

@@ -3513,12 +3576,14 @@ </context>

<context> <name>QGBA::TileView</name> <message> - <location filename="../TileView.cpp" line="163"/> + <location filename="../TileView.cpp" line="178"/> + <location filename="../TileView.cpp" line="190"/> <source>Export tiles</source> <translation>导出文件</translation> </message> <message> - <location filename="../TileView.cpp" line="164"/> + <location filename="../TileView.cpp" line="179"/> + <location filename="../TileView.cpp" line="191"/> <source>Portable Network Graphics (*.png)</source> <translation>便携式网络图形 (*.png)</translation> </message>

@@ -3611,7 +3676,7 @@ </message>

<message> <location filename="../Window.cpp" line="415"/> <source>Patches (*.ips *.ups *.bps)</source> - <translation>补丁文件 (*.ips *.ups *.bps)</translation> + <translation>补丁 (*.ips *.ups *.bps)</translation> </message> <message> <location filename="../Window.cpp" line="432"/>

@@ -3640,12 +3705,12 @@ <source>Video logs (*.mvl)</source>

<translation>视频日志文件 (*.mvl)</translation> </message> <message> - <location filename="../Window.cpp" line="853"/> + <location filename="../Window.cpp" line="854"/> <source>Crash</source> <translation>崩溃</translation> </message> <message> - <location filename="../Window.cpp" line="854"/> + <location filename="../Window.cpp" line="855"/> <source>The game has crashed with the following error: %1</source>

@@ -3654,107 +3719,107 @@

%1</translation> </message> <message> - <location filename="../Window.cpp" line="861"/> + <location filename="../Window.cpp" line="862"/> <source>Couldn&apos;t Load</source> <translation>无法载入</translation> </message> <message> - <location filename="../Window.cpp" line="862"/> + <location filename="../Window.cpp" line="863"/> <source>Could not load game. Are you sure it&apos;s in the correct format?</source> <translation>无法载入游戏。请确认游戏格式是否无误。</translation> </message> <message> - <location filename="../Window.cpp" line="875"/> + <location filename="../Window.cpp" line="876"/> <source>Unimplemented BIOS call</source> <translation>未实现的 BIOS 调用</translation> </message> <message> - <location filename="../Window.cpp" line="876"/> + <location filename="../Window.cpp" line="877"/> <source>This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience.</source> <translation>该游戏使用了尚未实现的 BIOS 调用。请使用官方 BIOS 以获得最佳游戏体验。</translation> </message> <message> - <location filename="../Window.cpp" line="961"/> + <location filename="../Window.cpp" line="964"/> <source>Really make portable?</source> <translation>确定进行程序便携化?</translation> </message> <message> - <location filename="../Window.cpp" line="962"/> + <location filename="../Window.cpp" line="965"/> <source>This will make the emulator load its configuration from the same directory as the executable. Do you want to continue?</source> <translation>进行此操作后,模拟器将从模拟器可执行文件所在目录内加载模拟器配置。您想继续吗?</translation> </message> <message> - <location filename="../Window.cpp" line="974"/> + <location filename="../Window.cpp" line="977"/> <source>Restart needed</source> <translation>需要重新启动</translation> </message> <message> - <location filename="../Window.cpp" line="975"/> + <location filename="../Window.cpp" line="978"/> <source>Some changes will not take effect until the emulator is restarted.</source> <translation>更改将在模拟器下次启动时生效。</translation> </message> <message> - <location filename="../Window.cpp" line="1022"/> + <location filename="../Window.cpp" line="1026"/> <source> - Player %1 of %2</source> <translation> - 玩家 %1 共 %2</translation> </message> <message> - <location filename="../Window.cpp" line="1034"/> + <location filename="../Window.cpp" line="1037"/> <source>%1 - %2</source> <translation>%1 - %2</translation> </message> <message> - <location filename="../Window.cpp" line="1036"/> + <location filename="../Window.cpp" line="1039"/> <source>%1 - %2 - %3</source> <translation>%1 - %2 - %3</translation> </message> <message> - <location filename="../Window.cpp" line="1038"/> + <location filename="../Window.cpp" line="1041"/> <source>%1 - %2 (%3 fps) - %4</source> <translation>%1 - %2 (%3 fps) - %4</translation> </message> <message> - <location filename="../Window.cpp" line="1079"/> + <location filename="../Window.cpp" line="1082"/> <source>&amp;File</source> <translation>文件(&amp;F)</translation> </message> <message> - <location filename="../Window.cpp" line="1081"/> + <location filename="../Window.cpp" line="1084"/> <source>Load &amp;ROM...</source> <translation>载入 ROM(&amp;R)...</translation> </message> <message> - <location filename="../Window.cpp" line="1083"/> + <location filename="../Window.cpp" line="1087"/> <source>Load ROM in archive...</source> <translation>从压缩文件中载入 ROM...</translation> </message> <message> - <location filename="../Window.cpp" line="1085"/> + <location filename="../Window.cpp" line="1088"/> <source>Add folder to library...</source> <translation>将文件夹添加到库中...</translation> </message> <message> - <location filename="../Window.cpp" line="1088"/> + <location filename="../Window.cpp" line="1091"/> <source>Load alternate save...</source> - <translation>读取其他的存档...</translation> + <translation>读取其他存档...</translation> </message> <message> - <location filename="../Window.cpp" line="1091"/> + <location filename="../Window.cpp" line="1094"/> <source>Load temporary save...</source> <translation>读取临时存档...</translation> </message> <message> - <location filename="../Window.cpp" line="1095"/> + <location filename="../Window.cpp" line="1098"/> <source>Load &amp;patch...</source> <translation>载入补丁文件(&amp;P)...</translation> </message> <message> - <location filename="../Window.cpp" line="1098"/> + <location filename="../Window.cpp" line="1101"/> <source>Boot BIOS</source> <translation>引导 BIOS</translation> </message> <message> - <location filename="../Window.cpp" line="1102"/> + <location filename="../Window.cpp" line="1106"/> <source>Replace ROM...</source> <translation>替换 ROM...</translation> </message>

@@ -3764,468 +3829,468 @@ <source>ROM &amp;info...</source>

<translation>ROM 信息(&amp;I)...</translation> </message> <message> - <location filename="../Window.cpp" line="1107"/> + <location filename="../Window.cpp" line="1110"/> <source>Recent</source> <translation>最近打开</translation> </message> <message> - <location filename="../Window.cpp" line="1110"/> + <location filename="../Window.cpp" line="1113"/> <source>Make portable</source> <translation>程序便携化</translation> </message> <message> - <location filename="../Window.cpp" line="1113"/> + <location filename="../Window.cpp" line="1116"/> <source>&amp;Load state</source> <translation>读取即时存档(&amp;L)</translation> </message> <message> - <location filename="../Window.cpp" line="1118"/> + <location filename="../Window.cpp" line="1121"/> <source>Load state file...</source> <translation>载入即时存档文件...</translation> </message> <message> - <location filename="../Window.cpp" line="1123"/> + <location filename="../Window.cpp" line="1126"/> <source>&amp;Save state</source> <translation>保存即时存档(&amp;S)</translation> </message> <message> - <location filename="../Window.cpp" line="1128"/> + <location filename="../Window.cpp" line="1131"/> <source>Save state file...</source> <translation>保存即时存档文件...</translation> </message> <message> - <location filename="../Window.cpp" line="1133"/> + <location filename="../Window.cpp" line="1136"/> <source>Quick load</source> <translation>快速读档</translation> </message> <message> - <location filename="../Window.cpp" line="1134"/> + <location filename="../Window.cpp" line="1137"/> <source>Quick save</source> <translation>快速存档</translation> </message> <message> - <location filename="../Window.cpp" line="1136"/> + <location filename="../Window.cpp" line="1139"/> <source>Load recent</source> <translation>载入最近</translation> </message> <message> - <location filename="../Window.cpp" line="1141"/> + <location filename="../Window.cpp" line="1144"/> <source>Save recent</source> <translation>保存最近</translation> </message> <message> - <location filename="../Window.cpp" line="1149"/> + <location filename="../Window.cpp" line="1152"/> <source>Undo load state</source> <translation>撤消读档</translation> </message> <message> - <location filename="../Window.cpp" line="1154"/> + <location filename="../Window.cpp" line="1157"/> <source>Undo save state</source> <translation>撤消存档</translation> </message> <message> - <location filename="../Window.cpp" line="1163"/> - <location filename="../Window.cpp" line="1168"/> + <location filename="../Window.cpp" line="1166"/> + <location filename="../Window.cpp" line="1171"/> <source>State &amp;%1</source> <translation>即时存档 1(&amp;1)</translation> </message> <message> - <location filename="../Window.cpp" line="1175"/> + <location filename="../Window.cpp" line="1178"/> <source>Load camera image...</source> <translation>读取相机图片...</translation> </message> <message> - <location filename="../Window.cpp" line="1179"/> + <location filename="../Window.cpp" line="1182"/> <source>Import GameShark Save</source> <translation>导入 GameShark 存档</translation> </message> <message> - <location filename="../Window.cpp" line="1182"/> + <location filename="../Window.cpp" line="1185"/> <source>Export GameShark Save</source> <translation>导出 GameShark 存档</translation> </message> <message> - <location filename="../Window.cpp" line="1187"/> + <location filename="../Window.cpp" line="1190"/> <source>New multiplayer window</source> <translation>新建多人游戏窗口</translation> </message> <message> - <location filename="../Window.cpp" line="1195"/> + <location filename="../Window.cpp" line="1198"/> <source>About...</source> <translation>关于...</translation> </message> <message> - <location filename="../Window.cpp" line="1198"/> + <location filename="../Window.cpp" line="1201"/> <source>E&amp;xit</source> <translation>退出(&amp;X)</translation> </message> <message> - <location filename="../Window.cpp" line="1201"/> + <location filename="../Window.cpp" line="1204"/> <source>&amp;Emulation</source> <translation>模拟(&amp;E)</translation> </message> <message> - <location filename="../Window.cpp" line="1202"/> + <location filename="../Window.cpp" line="1205"/> <source>&amp;Reset</source> - <translation>复位(&amp;R)</translation> + <translation>重置(&amp;R)</translation> </message> <message> - <location filename="../Window.cpp" line="1206"/> + <location filename="../Window.cpp" line="1209"/> <source>Sh&amp;utdown</source> <translation>关机(&amp;U)</translation> </message> <message> - <location filename="../Window.cpp" line="1210"/> + <location filename="../Window.cpp" line="1213"/> <source>Yank game pak</source> <translation>快速抽出游戏卡带</translation> </message> <message> - <location filename="../Window.cpp" line="1216"/> + <location filename="../Window.cpp" line="1219"/> <source>&amp;Pause</source> <translation>暂停(&amp;P)</translation> </message> <message> - <location filename="../Window.cpp" line="1225"/> + <location filename="../Window.cpp" line="1228"/> <source>&amp;Next frame</source> <translation>下一帧(&amp;N)</translation> </message> <message> - <location filename="../Window.cpp" line="1231"/> + <location filename="../Window.cpp" line="1234"/> <source>Fast forward (held)</source> <translation>快进 (长按)</translation> </message> <message> - <location filename="../Window.cpp" line="1237"/> + <location filename="../Window.cpp" line="1240"/> <source>&amp;Fast forward</source> <translation>快进(&amp;F)</translation> </message> <message> - <location filename="../Window.cpp" line="1241"/> + <location filename="../Window.cpp" line="1244"/> <source>Fast forward speed</source> <translation>快进速度</translation> </message> <message> - <location filename="../Window.cpp" line="1246"/> + <location filename="../Window.cpp" line="1249"/> <source>Unbounded</source> <translation>不限制</translation> </message> <message> - <location filename="../Window.cpp" line="1250"/> + <location filename="../Window.cpp" line="1253"/> <source>%0x</source> <translation>%0x</translation> </message> <message> - <location filename="../Window.cpp" line="1254"/> + <location filename="../Window.cpp" line="1257"/> <source>Rewind (held)</source> - <translation>回退 (长按)</translation> + <translation>倒带 (长按)</translation> </message> <message> - <location filename="../Window.cpp" line="1261"/> + <location filename="../Window.cpp" line="1264"/> <source>Re&amp;wind</source> - <translation>回退(&amp;W)</translation> + <translation>倒带(&amp;W)</translation> </message> <message> - <location filename="../Window.cpp" line="1266"/> + <location filename="../Window.cpp" line="1269"/> <source>Step backwards</source> - <translation>后退</translation> + <translation>步退</translation> </message> <message> - <location filename="../Window.cpp" line="1272"/> + <location filename="../Window.cpp" line="1275"/> <source>Sync to &amp;video</source> <translation>视频同步(&amp;V)</translation> </message> <message> - <location filename="../Window.cpp" line="1279"/> + <location filename="../Window.cpp" line="1282"/> <source>Sync to &amp;audio</source> <translation>音频同步(&amp;A)</translation> </message> <message> - <location filename="../Window.cpp" line="1287"/> + <location filename="../Window.cpp" line="1290"/> <source>Solar sensor</source> <translation>光线传感器</translation> </message> <message> - <location filename="../Window.cpp" line="1288"/> + <location filename="../Window.cpp" line="1291"/> <source>Increase solar level</source> <translation>增加光线级别</translation> </message> <message> - <location filename="../Window.cpp" line="1289"/> + <location filename="../Window.cpp" line="1292"/> <source>Decrease solar level</source> <translation>降低光线级别</translation> </message> <message> - <location filename="../Window.cpp" line="1290"/> + <location filename="../Window.cpp" line="1293"/> <source>Brightest solar level</source> <translation>光线级别为最亮</translation> </message> <message> - <location filename="../Window.cpp" line="1293"/> + <location filename="../Window.cpp" line="1296"/> <source>Darkest solar level</source> <translation>光线级别为最暗</translation> </message> <message> - <location filename="../Window.cpp" line="1299"/> + <location filename="../Window.cpp" line="1302"/> <source>Brightness %1</source> <translation>亮度 %1</translation> </message> <message> - <location filename="../Window.cpp" line="1305"/> + <location filename="../Window.cpp" line="1308"/> <source>Game Boy Printer...</source> <translation>Game Boy 打印机...</translation> </message> <message> - <location filename="../Window.cpp" line="1314"/> + <location filename="../Window.cpp" line="1317"/> <source>BattleChip Gate...</source> <translation>BattleChip Gate...</translation> </message> <message> - <location filename="../Window.cpp" line="1318"/> + <location filename="../Window.cpp" line="1321"/> <source>Audio/&amp;Video</source> <translation>音频/视频(&amp;V)</translation> </message> <message> - <location filename="../Window.cpp" line="1319"/> + <location filename="../Window.cpp" line="1322"/> <source>Frame size</source> <translation>帧率</translation> </message> <message> - <location filename="../Window.cpp" line="1321"/> + <location filename="../Window.cpp" line="1324"/> <source>%1×</source> <translation>%1×</translation> </message> <message> - <location filename="../Window.cpp" line="1346"/> + <location filename="../Window.cpp" line="1349"/> <source>Toggle fullscreen</source> <translation>切换全屏</translation> </message> <message> - <location filename="../Window.cpp" line="1349"/> + <location filename="../Window.cpp" line="1352"/> <source>Lock aspect ratio</source> <translation>锁定纵横比</translation> </message> <message> - <location filename="../Window.cpp" line="1361"/> + <location filename="../Window.cpp" line="1364"/> <source>Force integer scaling</source> <translation>强制整数缩放</translation> </message> <message> - <location filename="../Window.cpp" line="1373"/> + <location filename="../Window.cpp" line="1376"/> <source>Interframe blending</source> <translation>帧间混合</translation> </message> <message> - <location filename="../Window.cpp" line="1382"/> + <location filename="../Window.cpp" line="1385"/> <source>Bilinear filtering</source> <translation>双线性过滤</translation> </message> <message> - <location filename="../Window.cpp" line="1390"/> + <location filename="../Window.cpp" line="1393"/> <source>Frame&amp;skip</source> <translation>跳帧(&amp;S)</translation> </message> <message> - <location filename="../Window.cpp" line="1403"/> + <location filename="../Window.cpp" line="1406"/> <source>Mute</source> <translation>静音</translation> </message> <message> - <location filename="../Window.cpp" line="1410"/> + <location filename="../Window.cpp" line="1413"/> <source>FPS target</source> <translation>目标 FPS</translation> </message> <message> - <location filename="../Window.cpp" line="1418"/> + <location filename="../Window.cpp" line="1421"/> <source>Native (59.7275)</source> <translation>原生 (59.7275)</translation> </message> <message> - <location filename="../Window.cpp" line="1433"/> + <location filename="../Window.cpp" line="1436"/> <source>Take &amp;screenshot</source> <translation>截图(&amp;S)</translation> </message> <message> - <location filename="../Window.cpp" line="1439"/> + <location filename="../Window.cpp" line="1442"/> <source>Record A/V...</source> <translation>录制音频/视频...</translation> </message> <message> - <location filename="../Window.cpp" line="1440"/> + <location filename="../Window.cpp" line="1443"/> <source>Record GIF...</source> <translation>录制 GIF...</translation> </message> <message> - <location filename="../Window.cpp" line="1444"/> + <location filename="../Window.cpp" line="1447"/> <source>Video layers</source> <translation>视频图层</translation> </message> <message> - <location filename="../Window.cpp" line="1445"/> + <location filename="../Window.cpp" line="1448"/> <source>Audio channels</source> <translation>音频通道</translation> </message> <message> - <location filename="../Window.cpp" line="1447"/> + <location filename="../Window.cpp" line="1450"/> <source>Adjust layer placement...</source> <translation>调整图层布局...</translation> </message> <message> - <location filename="../Window.cpp" line="1449"/> + <location filename="../Window.cpp" line="1452"/> <source>&amp;Tools</source> <translation>工具(&amp;T)</translation> </message> <message> - <location filename="../Window.cpp" line="1450"/> + <location filename="../Window.cpp" line="1453"/> <source>View &amp;logs...</source> <translation>查看日志(&amp;L)...</translation> </message> <message> - <location filename="../Window.cpp" line="1452"/> + <location filename="../Window.cpp" line="1455"/> <source>Game &amp;overrides...</source> <translation>覆盖游戏(&amp;O)...</translation> </message> <message> - <location filename="../Window.cpp" line="1464"/> + <location filename="../Window.cpp" line="1467"/> <source>Game Pak sensors...</source> <translation>游戏卡带传感器...</translation> </message> <message> - <location filename="../Window.cpp" line="1475"/> + <location filename="../Window.cpp" line="1478"/> <source>&amp;Cheats...</source> <translation>作弊码(&amp;C)...</translation> </message> <message> - <location filename="../Window.cpp" line="1478"/> + <location filename="../Window.cpp" line="1481"/> <source>Settings...</source> <translation>设置...</translation> </message> <message> - <location filename="../Window.cpp" line="1482"/> + <location filename="../Window.cpp" line="1485"/> <source>Open debugger console...</source> <translation>打开调试器控制台...</translation> </message> <message> - <location filename="../Window.cpp" line="1484"/> + <location filename="../Window.cpp" line="1487"/> <source>Start &amp;GDB server...</source> <translation>打开 GDB 服务器(&amp;G)...</translation> </message> <message> - <location filename="../Window.cpp" line="1490"/> + <location filename="../Window.cpp" line="1493"/> <source>View &amp;palette...</source> <translation>查看调色板(&amp;P)...</translation> </message> <message> - <location filename="../Window.cpp" line="1491"/> + <location filename="../Window.cpp" line="1494"/> <source>View &amp;sprites...</source> <translation>查看精灵图(&amp;S)...</translation> </message> <message> - <location filename="../Window.cpp" line="1492"/> + <location filename="../Window.cpp" line="1495"/> <source>View &amp;tiles...</source> <translation>查看瓷贴(&amp;T)...</translation> </message> <message> - <location filename="../Window.cpp" line="1493"/> + <location filename="../Window.cpp" line="1496"/> <source>View &amp;map...</source> <translation>查看映射(&amp;M)...</translation> </message> <message> - <location filename="../Window.cpp" line="1506"/> - <source>&amp;Frame inspector</source> - <translation>框架检查(&amp;F)</translation> + <location filename="../Window.cpp" line="1499"/> + <source>&amp;Frame inspector...</source> + <translation>框架检查(&amp;F)...</translation> </message> <message> - <location filename="../Window.cpp" line="1514"/> + <location filename="../Window.cpp" line="1517"/> <source>View memory...</source> <translation>查看内存...</translation> </message> <message> - <location filename="../Window.cpp" line="1515"/> + <location filename="../Window.cpp" line="1518"/> <source>Search memory...</source> <translation>搜索内存...</translation> </message> <message> - <location filename="../Window.cpp" line="1518"/> + <location filename="../Window.cpp" line="1521"/> <source>View &amp;I/O registers...</source> <translation>查看 I/O 寄存器(&amp;I)...</translation> </message> <message> - <location filename="../Window.cpp" line="1523"/> + <location filename="../Window.cpp" line="1526"/> <source>Record debug video log...</source> <translation>记录调试视频日志...</translation> </message> <message> - <location filename="../Window.cpp" line="1524"/> + <location filename="../Window.cpp" line="1527"/> <source>Stop debug video log</source> <translation>停止记录调试视频日志</translation> </message> <message> - <location filename="../Window.cpp" line="1605"/> + <location filename="../Window.cpp" line="1615"/> <source>Exit fullscreen</source> <translation>退出全屏</translation> </message> <message> - <location filename="../Window.cpp" line="1607"/> + <location filename="../Window.cpp" line="1617"/> <source>GameShark Button (held)</source> <translation>GameShark 键 (长按)</translation> </message> <message> - <location filename="../Window.cpp" line="1613"/> + <location filename="../Window.cpp" line="1623"/> <source>Autofire</source> <translation>连发</translation> </message> <message> - <location filename="../Window.cpp" line="1614"/> + <location filename="../Window.cpp" line="1624"/> <source>Autofire A</source> <translation>连发 A</translation> </message> <message> - <location filename="../Window.cpp" line="1619"/> + <location filename="../Window.cpp" line="1629"/> <source>Autofire B</source> <translation>连发 B</translation> </message> <message> - <location filename="../Window.cpp" line="1624"/> + <location filename="../Window.cpp" line="1634"/> <source>Autofire L</source> <translation>连发 L</translation> </message> <message> - <location filename="../Window.cpp" line="1629"/> + <location filename="../Window.cpp" line="1639"/> <source>Autofire R</source> <translation>连发 R</translation> </message> <message> - <location filename="../Window.cpp" line="1634"/> + <location filename="../Window.cpp" line="1644"/> <source>Autofire Start</source> <translation>连发 Start</translation> </message> <message> - <location filename="../Window.cpp" line="1639"/> + <location filename="../Window.cpp" line="1649"/> <source>Autofire Select</source> <translation>连发 Select</translation> </message> <message> - <location filename="../Window.cpp" line="1644"/> + <location filename="../Window.cpp" line="1654"/> <source>Autofire Up</source> <translation>连发 上</translation> </message> <message> - <location filename="../Window.cpp" line="1649"/> + <location filename="../Window.cpp" line="1659"/> <source>Autofire Right</source> <translation>连发 右</translation> </message> <message> - <location filename="../Window.cpp" line="1654"/> + <location filename="../Window.cpp" line="1664"/> <source>Autofire Down</source> <translation>连发 下</translation> </message> <message> - <location filename="../Window.cpp" line="1659"/> + <location filename="../Window.cpp" line="1669"/> <source>Autofire Left</source> <translation>连发 左</translation> </message> <message> - <location filename="../Window.cpp" line="1713"/> + <location filename="../Window.cpp" line="1723"/> <source>Clear</source> <translation>清除</translation> </message>

@@ -4543,7 +4608,7 @@ <translation>每间隔</translation>

</message> <message> <location filename="../SettingsView.ui" line="362"/> - <location filename="../SettingsView.ui" line="786"/> + <location filename="../SettingsView.ui" line="803"/> <source>frames</source> <translation>帧</translation> </message>

@@ -4615,12 +4680,12 @@ </message>

<message> <location filename="../SettingsView.ui" line="507"/> <source>List view</source> - <translation>列表查看</translation> + <translation>列表视图</translation> </message> <message> <location filename="../SettingsView.ui" line="512"/> <source>Tree view</source> - <translation>树状查看</translation> + <translation>树状视图</translation> </message> <message> <location filename="../SettingsView.ui" line="520"/>

@@ -4649,339 +4714,344 @@ <translation>非活动时暂停</translation>

</message> <message> <location filename="../SettingsView.ui" line="568"/> + <source>Pause when minimized</source> + <translation>最小化时暂停</translation> + </message> + <message> + <location filename="../SettingsView.ui" line="582"/> <source>Show FPS in title bar</source> <translation>在标题栏显示 FPS</translation> </message> <message> <location filename="../SettingsView.ui" line="592"/> - <source>Automatically save cheats</source> - <translation>自动保存作弊码</translation> + <source>Enable Discord Rich Presence</source> + <translation>启用 Enable Discord Rich Presence</translation> </message> <message> - <location filename="../SettingsView.ui" line="602"/> - <source>Automatically load cheats</source> - <translation>自动载入作弊码</translation> - </message> - <message> - <location filename="../SettingsView.ui" line="612"/> + <location filename="../SettingsView.ui" line="606"/> <source>Automatically save state</source> <translation>自动存档</translation> </message> <message> - <location filename="../SettingsView.ui" line="622"/> + <location filename="../SettingsView.ui" line="616"/> <source>Automatically load state</source> <translation>自动读档</translation> </message> <message> - <location filename="../SettingsView.ui" line="632"/> - <source>Enable Discord Rich Presence</source> - <translation>启用 Enable Discord Rich Presence</translation> + <location filename="../SettingsView.ui" line="633"/> + <source>Automatically save cheats</source> + <translation>自动保存作弊码</translation> </message> <message> - <location filename="../SettingsView.ui" line="639"/> - <source>Pause when minimized</source> - <translation>最小化时暂停</translation> + <location filename="../SettingsView.ui" line="643"/> + <source>Automatically load cheats</source> + <translation>自动载入作弊码</translation> </message> <message> <location filename="../SettingsView.ui" line="653"/> + <source>Show OSD messages</source> + <translation>显示 OSD 信息</translation> + </message> + <message> + <location filename="../SettingsView.ui" line="670"/> <source>Fast forward speed:</source> <translation>快进速度:</translation> </message> <message> - <location filename="../SettingsView.ui" line="665"/> - <location filename="../SettingsView.ui" line="708"/> - <location filename="../SettingsView.ui" line="957"/> + <location filename="../SettingsView.ui" line="682"/> + <location filename="../SettingsView.ui" line="725"/> + <location filename="../SettingsView.ui" line="974"/> <source>×</source> <translation>×</translation> </message> <message> - <location filename="../SettingsView.ui" line="684"/> - <location filename="../SettingsView.ui" line="727"/> + <location filename="../SettingsView.ui" line="701"/> + <location filename="../SettingsView.ui" line="744"/> <source>Unbounded</source> <translation>不限制</translation> </message> <message> - <location filename="../SettingsView.ui" line="696"/> + <location filename="../SettingsView.ui" line="713"/> <source>Fast forward (held) speed:</source> <translation>快进 (按住) 速度:</translation> </message> <message> - <location filename="../SettingsView.ui" line="739"/> + <location filename="../SettingsView.ui" line="756"/> <source>Autofire interval:</source> <translation>连发间隔:</translation> </message> <message> - <location filename="../SettingsView.ui" line="763"/> + <location filename="../SettingsView.ui" line="780"/> <source>Enable rewind</source> - <translation>启用回退</translation> + <translation>启用倒带</translation> </message> <message> - <location filename="../SettingsView.ui" line="770"/> + <location filename="../SettingsView.ui" line="787"/> <source>Rewind history:</source> - <translation>回退历史:</translation> + <translation>倒带历史:</translation> </message> <message> - <location filename="../SettingsView.ui" line="802"/> + <location filename="../SettingsView.ui" line="819"/> <source>Idle loops:</source> <translation>空循环:</translation> </message> <message> - <location filename="../SettingsView.ui" line="810"/> + <location filename="../SettingsView.ui" line="827"/> <source>Run all</source> <translation>运行全部</translation> </message> <message> - <location filename="../SettingsView.ui" line="815"/> + <location filename="../SettingsView.ui" line="832"/> <source>Remove known</source> <translation>移除已知</translation> </message> <message> - <location filename="../SettingsView.ui" line="820"/> + <location filename="../SettingsView.ui" line="837"/> <source>Detect and remove</source> <translation>检测并移除</translation> </message> <message> - <location filename="../SettingsView.ui" line="828"/> + <location filename="../SettingsView.ui" line="845"/> <source>Preload entire ROM into memory</source> <translation>将整个 ROM 预加载到内存中</translation> </message> <message> - <location filename="../SettingsView.ui" line="842"/> + <location filename="../SettingsView.ui" line="859"/> <source>Savestate extra data:</source> <translation>即时存档额外数据:</translation> </message> <message> - <location filename="../SettingsView.ui" line="849"/> - <location filename="../SettingsView.ui" line="893"/> + <location filename="../SettingsView.ui" line="866"/> + <location filename="../SettingsView.ui" line="910"/> <source>Screenshot</source> <translation>截图</translation> </message> <message> - <location filename="../SettingsView.ui" line="859"/> - <location filename="../SettingsView.ui" line="903"/> + <location filename="../SettingsView.ui" line="876"/> + <location filename="../SettingsView.ui" line="920"/> <source>Save data</source> <translation>保存数据</translation> </message> <message> - <location filename="../SettingsView.ui" line="869"/> - <location filename="../SettingsView.ui" line="910"/> + <location filename="../SettingsView.ui" line="886"/> + <location filename="../SettingsView.ui" line="927"/> <source>Cheat codes</source> <translation>作弊码</translation> </message> <message> - <location filename="../SettingsView.ui" line="886"/> + <location filename="../SettingsView.ui" line="903"/> <source>Load extra data:</source> <translation>载入额外数据:</translation> </message> <message> - <location filename="../SettingsView.ui" line="921"/> + <location filename="../SettingsView.ui" line="938"/> <source>Video renderer:</source> <translation>视频渲染器:</translation> </message> <message> - <location filename="../SettingsView.ui" line="929"/> + <location filename="../SettingsView.ui" line="946"/> <source>Software</source> <translation>软件</translation> </message> <message> - <location filename="../SettingsView.ui" line="934"/> + <location filename="../SettingsView.ui" line="951"/> <source>OpenGL</source> <translation>OpenGL</translation> </message> <message> - <location filename="../SettingsView.ui" line="942"/> + <location filename="../SettingsView.ui" line="959"/> <source>OpenGL enhancements</source> <translation>OpenGL 增强</translation> </message> <message> - <location filename="../SettingsView.ui" line="948"/> + <location filename="../SettingsView.ui" line="965"/> <source>High-resolution scale:</source> <translation>高分辨率比例:</translation> </message> <message> - <location filename="../SettingsView.ui" line="986"/> + <location filename="../SettingsView.ui" line="1003"/> <source>(240×160)</source> <translation>(240×160)</translation> </message> <message> - <location filename="../SettingsView.ui" line="1011"/> + <location filename="../SettingsView.ui" line="1028"/> <source>XQ GBA audio (experimental)</source> <translation>XQ GBA 音频 (实验)</translation> </message> <message> - <location filename="../SettingsView.ui" line="1022"/> + <location filename="../SettingsView.ui" line="1039"/> <source>GB BIOS file:</source> <translation>GB BIOS 文件:</translation> </message> <message> - <location filename="../SettingsView.ui" line="1041"/> - <location filename="../SettingsView.ui" line="1079"/> - <location filename="../SettingsView.ui" line="1114"/> - <location filename="../SettingsView.ui" line="1142"/> - <location filename="../SettingsView.ui" line="1183"/> - <location filename="../SettingsView.ui" line="1231"/> - <location filename="../SettingsView.ui" line="1279"/> - <location filename="../SettingsView.ui" line="1327"/> - <location filename="../SettingsView.ui" line="1375"/> + <location filename="../SettingsView.ui" line="1058"/> + <location filename="../SettingsView.ui" line="1096"/> + <location filename="../SettingsView.ui" line="1131"/> + <location filename="../SettingsView.ui" line="1159"/> + <location filename="../SettingsView.ui" line="1200"/> + <location filename="../SettingsView.ui" line="1248"/> + <location filename="../SettingsView.ui" line="1296"/> + <location filename="../SettingsView.ui" line="1344"/> + <location filename="../SettingsView.ui" line="1392"/> <source>Browse</source> <translation>浏览</translation> </message> <message> - <location filename="../SettingsView.ui" line="1050"/> + <location filename="../SettingsView.ui" line="1067"/> <source>Use BIOS file if found</source> <translation>当可用时使用 BIOS 文件</translation> </message> <message> - <location filename="../SettingsView.ui" line="1060"/> + <location filename="../SettingsView.ui" line="1077"/> <source>Skip BIOS intro</source> <translation>跳过 BIOS 启动画面</translation> </message> <message> - <location filename="../SettingsView.ui" line="1088"/> + <location filename="../SettingsView.ui" line="1105"/> <source>GBA BIOS file:</source> <translation>GBA BIOS 文件:</translation> </message> <message> - <location filename="../SettingsView.ui" line="1095"/> + <location filename="../SettingsView.ui" line="1112"/> <source>GBC BIOS file:</source> <translation>GBC BIOS 文件:</translation> </message> <message> - <location filename="../SettingsView.ui" line="1123"/> + <location filename="../SettingsView.ui" line="1140"/> <source>SGB BIOS file:</source> <translation>SGB BIOS 文件:</translation> </message> <message> - <location filename="../SettingsView.ui" line="1158"/> + <location filename="../SettingsView.ui" line="1175"/> <source>Save games</source> <translation>游戏存档</translation> </message> <message> - <location filename="../SettingsView.ui" line="1192"/> - <location filename="../SettingsView.ui" line="1240"/> - <location filename="../SettingsView.ui" line="1288"/> - <location filename="../SettingsView.ui" line="1336"/> - <location filename="../SettingsView.ui" line="1384"/> + <location filename="../SettingsView.ui" line="1209"/> + <location filename="../SettingsView.ui" line="1257"/> + <location filename="../SettingsView.ui" line="1305"/> + <location filename="../SettingsView.ui" line="1353"/> + <location filename="../SettingsView.ui" line="1401"/> <source>Same directory as the ROM</source> <translation>保存在 ROM 所在目录</translation> </message> <message> - <location filename="../SettingsView.ui" line="1206"/> + <location filename="../SettingsView.ui" line="1223"/> <source>Save states</source> <translation>即时存档</translation> </message> <message> - <location filename="../SettingsView.ui" line="1254"/> + <location filename="../SettingsView.ui" line="1271"/> <source>Screenshots</source> <translation>截图</translation> </message> <message> - <location filename="../SettingsView.ui" line="1302"/> + <location filename="../SettingsView.ui" line="1319"/> <source>Patches</source> <translation>补丁</translation> </message> <message> - <location filename="../SettingsView.ui" line="1350"/> + <location filename="../SettingsView.ui" line="1367"/> <source>Cheats</source> <translation>作弊码</translation> </message> <message> - <location filename="../SettingsView.ui" line="1407"/> + <location filename="../SettingsView.ui" line="1421"/> <source>Log to file</source> <translation>记录日志到文件</translation> </message> <message> - <location filename="../SettingsView.ui" line="1414"/> + <location filename="../SettingsView.ui" line="1431"/> <source>Log to console</source> <translation>记录日志到控制台</translation> </message> <message> - <location filename="../SettingsView.ui" line="1428"/> + <location filename="../SettingsView.ui" line="1445"/> <source>Select Log File</source> <translation>选择日志文件</translation> </message> <message> - <location filename="../SettingsView.ui" line="1441"/> + <location filename="../SettingsView.ui" line="1458"/> <source>Game Boy model:</source> <translation>Game Boy 模型:</translation> </message> <message> - <location filename="../SettingsView.ui" line="1449"/> - <location filename="../SettingsView.ui" line="1485"/> - <location filename="../SettingsView.ui" line="1521"/> + <location filename="../SettingsView.ui" line="1466"/> + <location filename="../SettingsView.ui" line="1502"/> + <location filename="../SettingsView.ui" line="1538"/> <source>Autodetect</source> <translation>自动检测</translation> </message> <message> - <location filename="../SettingsView.ui" line="1454"/> - <location filename="../SettingsView.ui" line="1490"/> - <location filename="../SettingsView.ui" line="1526"/> + <location filename="../SettingsView.ui" line="1471"/> + <location filename="../SettingsView.ui" line="1507"/> + <location filename="../SettingsView.ui" line="1543"/> <source>Game Boy (DMG)</source> <translation>Game Boy (DMG)</translation> </message> <message> - <location filename="../SettingsView.ui" line="1459"/> - <location filename="../SettingsView.ui" line="1495"/> - <location filename="../SettingsView.ui" line="1531"/> + <location filename="../SettingsView.ui" line="1476"/> + <location filename="../SettingsView.ui" line="1512"/> + <location filename="../SettingsView.ui" line="1548"/> <source>Super Game Boy (SGB)</source> <translation>Super Game Boy (SGB)</translation> </message> <message> - <location filename="../SettingsView.ui" line="1464"/> - <location filename="../SettingsView.ui" line="1500"/> - <location filename="../SettingsView.ui" line="1536"/> + <location filename="../SettingsView.ui" line="1481"/> + <location filename="../SettingsView.ui" line="1517"/> + <location filename="../SettingsView.ui" line="1553"/> <source>Game Boy Color (CGB)</source> <translation>Game Boy Color (CGB)</translation> </message> <message> - <location filename="../SettingsView.ui" line="1469"/> - <location filename="../SettingsView.ui" line="1505"/> - <location filename="../SettingsView.ui" line="1541"/> + <location filename="../SettingsView.ui" line="1486"/> + <location filename="../SettingsView.ui" line="1522"/> + <location filename="../SettingsView.ui" line="1558"/> <source>Game Boy Advance (AGB)</source> <translation>Game Boy Advance (AGB)</translation> </message> <message> - <location filename="../SettingsView.ui" line="1477"/> + <location filename="../SettingsView.ui" line="1494"/> <source>Super Game Boy model:</source> <translation>Super Game Boy 模型:</translation> </message> <message> - <location filename="../SettingsView.ui" line="1513"/> + <location filename="../SettingsView.ui" line="1530"/> <source>Game Boy Color model:</source> <translation>Game Boy Color 模型:</translation> </message> <message> - <location filename="../SettingsView.ui" line="1556"/> + <location filename="../SettingsView.ui" line="1573"/> <source>Default BG colors:</source> <translation>默认背景颜色:</translation> </message> <message> - <location filename="../SettingsView.ui" line="1723"/> + <location filename="../SettingsView.ui" line="1740"/> <source>Super Game Boy borders</source> <translation>Super Game Boy 边框</translation> </message> <message> - <location filename="../SettingsView.ui" line="1737"/> + <location filename="../SettingsView.ui" line="1754"/> <source>Camera driver:</source> <translation>相机驱动:</translation> </message> <message> - <location filename="../SettingsView.ui" line="1834"/> + <location filename="../SettingsView.ui" line="1851"/> <source>Default sprite colors 1:</source> <translation>默认精灵图颜色 1:</translation> </message> <message> - <location filename="../SettingsView.ui" line="1841"/> + <location filename="../SettingsView.ui" line="1858"/> <source>Default sprite colors 2:</source> <translation>默认精灵图颜色 2:</translation> </message> <message> - <location filename="../SettingsView.ui" line="1848"/> + <location filename="../SettingsView.ui" line="1865"/> <source>Use GBC colors in GB games</source> <translation>在 GB 游戏中使用 GBC 颜色</translation> </message> <message> - <location filename="../SettingsView.ui" line="1855"/> + <location filename="../SettingsView.ui" line="1872"/> <source>Camera:</source> <translation>相机:</translation> </message>

@@ -5055,34 +5125,49 @@ <source>Tiles</source>

<translation>瓷贴</translation> </message> <message> - <location filename="../TileView.ui" line="29"/> + <location filename="../TileView.ui" line="20"/> + <source>Export Selected</source> + <translation>导出所选</translation> + </message> + <message> + <location filename="../TileView.ui" line="27"/> + <source>Export All</source> + <translation>导出全部</translation> + </message> + <message> + <location filename="../TileView.ui" line="43"/> <source>256 colors</source> <translation>256 色</translation> </message> <message> - <location filename="../TileView.ui" line="42"/> + <location filename="../TileView.ui" line="56"/> <source>×</source> <translation>×</translation> </message> <message> - <location filename="../TileView.ui" line="55"/> + <location filename="../TileView.ui" line="69"/> <source>Magnification</source> <translation>缩放率</translation> </message> <message> - <location filename="../TileView.ui" line="78"/> + <location filename="../TileView.ui" line="92"/> <source>Tiles per row</source> <translation>每行瓷贴</translation> </message> <message> - <location filename="../TileView.ui" line="85"/> + <location filename="../TileView.ui" line="99"/> <source>Fit to window</source> <translation>自适应窗口</translation> </message> <message> - <location filename="../TileView.ui" line="113"/> - <source>Export</source> - <translation>导出</translation> + <location filename="../TileView.ui" line="192"/> + <source>Copy Selected</source> + <translation>复制所选</translation> + </message> + <message> + <location filename="../TileView.ui" line="199"/> + <source>Copy All</source> + <translation>复制全部</translation> </message> </context> <context>
M src/platform/sdl/sdl-events.csrc/platform/sdl/sdl-events.c

@@ -198,15 +198,15 @@ if (!claimed && firstUnclaimed == SIZE_MAX) {

firstUnclaimed = i; } - const char* joystickName; #if SDL_VERSION_ATLEAST(2, 0, 0) - joystickName = SDL_JoystickName(SDL_JoystickListGetPointer(&events->joysticks, i)->joystick); + char joystickName[34] = {0}; + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(SDL_JoystickListGetPointer(&events->joysticks, i)->joystick), joystickName, sizeof(joystickName)); #else - joystickName = SDL_JoystickName(SDL_JoystickIndex(SDL_JoystickListGetPointer(&events->joysticks, i)->joystick)); -#endif + const char* joystickName = SDL_JoystickName(SDL_JoystickIndex(SDL_JoystickListGetPointer(&events->joysticks, i)->joystick)); if (!joystickName) { continue; } +#endif if (events->preferredJoysticks[player->playerId] && strcmp(events->preferredJoysticks[player->playerId], joystickName) == 0) { index = i; break;

@@ -253,13 +253,14 @@ mInputMapLoad(context->bindings, SDL_BINDING_KEY, config);

if (context->joystick) { mInputMapLoad(context->bindings, SDL_BINDING_BUTTON, config); #if SDL_VERSION_ATLEAST(2, 0, 0) - const char* name = SDL_JoystickName(context->joystick->joystick); + char name[34] = {0}; + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(context->joystick->joystick), name, sizeof(name)); #else const char* name = SDL_JoystickName(SDL_JoystickIndex(context->joystick->joystick)); -#endif if (!name) { return; } +#endif mInputProfileLoad(context->bindings, SDL_BINDING_BUTTON, config, name); const char* value;

@@ -307,13 +308,14 @@

void mSDLPlayerSaveConfig(const struct mSDLPlayer* context, struct Configuration* config) { if (context->joystick) { #if SDL_VERSION_ATLEAST(2, 0, 0) - const char* name = SDL_JoystickName(context->joystick->joystick); + char name[34] = {0}; + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(context->joystick->joystick), name, sizeof(name)); #else const char* name = SDL_JoystickName(SDL_JoystickIndex(context->joystick->joystick)); -#endif if (!name) { return; } +#endif char value[16]; snprintf(value, sizeof(value), "%i", context->rotation.axisX); mInputSetCustomValue(config, "gba", SDL_BINDING_BUTTON, "tiltAxisX", value, name);

@@ -354,14 +356,15 @@ #if SDL_VERSION_ATLEAST(2, 0, 0)

joystick->haptic = SDL_HapticOpenFromJoystick(joystick->joystick); #endif - const char* joystickName; + size_t i; #if SDL_VERSION_ATLEAST(2, 0, 0) - joystickName = SDL_JoystickName(joystick->joystick); + char joystickName[34] = {0}; + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick->joystick), joystickName, sizeof(joystickName)); #else - joystickName = SDL_JoystickName(SDL_JoystickIndex(joystick->joystick)); + const char* joystickName = SDL_JoystickName(SDL_JoystickIndex(joystick->joystick)); + if (joystickName) #endif - size_t i; - if (joystickName) { + { for (i = 0; (int) i < events->playersAttached; ++i) { if (events->players[i]->joystick) { continue;
M src/platform/windows/setup/setup.iss.insrc/platform/windows/setup/setup.iss.in

@@ -48,15 +48,11 @@ #else

#define IsRelease = 'no' AppVerName={#AppName} {#VersionString} (Development build) #endif -#if '{#WinBits}' == '64' - ArchitecturesInstallIn64BitMode=x64 - ArchitecturesAllows=x64 -#endif OutputBaseFilename={#AppName}-setup-{#CleanVersionString}-win{#WinBits} UsePreviousLanguage=False DisableWelcomePage=False VersionInfoDescription={#AppName} is an open-source Game Boy Advance emulator -VersionInfoCopyright= 20132018 Jeffrey Pfau +VersionInfoCopyright= 20132019 Jeffrey Pfau VersionInfoProductName={#AppName} VersionInfoVersion={#AppVer} Compression=lzma2/ultra64

@@ -64,6 +60,8 @@ SolidCompression=True

VersionInfoTextVersion={#AppVer} VersionInfoProductVersion={#AppVer} VersionInfoProductTextVersion={#AppVer} +ArchitecturesInstallIn64BitMode=x64 +ArchitecturesAllowed=x86 x64 [Languages] Name: "english"; MessagesFile: "compiler:Default.isl"