mirror of https://github.com/mgba-emu/mgba.git
Merge branch 'master' (early part) into medusa
This commit is contained in:
commit
f03389bfca
|
@ -1,8 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
|
||||||
if [ $TRAVIS_OS_NAME = "osx" ]; then
|
if [ $TRAVIS_OS_NAME = "osx" ]; then
|
||||||
brew update
|
brew update
|
||||||
brew install qt5 ffmpeg imagemagick sdl2 libedit libelf libpng libzip
|
brew install qt5 ffmpeg sdl2 libedit libelf libpng libzip
|
||||||
else
|
else
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get -y install libseccomp2
|
sudo apt-get -y install libseccomp2
|
||||||
|
|
103
CHANGES
103
CHANGES
|
@ -43,68 +43,91 @@ Features:
|
||||||
- GB: Yanking gamepak now supported
|
- GB: Yanking gamepak now supported
|
||||||
- Qt: Memory range dumping (closes mgba.io/i/1298)
|
- Qt: Memory range dumping (closes mgba.io/i/1298)
|
||||||
Emulation fixes:
|
Emulation fixes:
|
||||||
|
- 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 Video: Fix color scaling in AGB mode
|
||||||
- GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208)
|
- GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208)
|
||||||
- GBA: Reset now reloads multiboot ROMs
|
- GBA: Reset now reloads multiboot ROMs
|
||||||
- GBA BIOS: Fix multiboot entry point (fixes Magic Floor)
|
- 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 Audio: Only reset channel 3 sample in DMG mode
|
|
||||||
- GB Audio: Sample inactive channels (fixes mgba.io/i/1455, mgba.io/i/1456)
|
|
||||||
- GB Memory: Better emulate 0xFEA0 region on DMG, MGB and AGB
|
|
||||||
- GB Video: Fix mode 0 window edge case (fixes mgba.io/i/1519)
|
|
||||||
- GB Audio: Fix channel 4 volume (fixes mgba.io/i/1529)
|
|
||||||
- GB Video: Fix color scaling in AGB mode
|
|
||||||
- GB: Fix using boot ROM with MMM01 games
|
|
||||||
Other fixes:
|
Other fixes:
|
||||||
- Qt: Fix some Qt display driver race conditions
|
|
||||||
- Core: Improved lockstep driver reliability (Le Hoang Quyen)
|
- Core: Improved lockstep driver reliability (Le Hoang Quyen)
|
||||||
- Qt: Fix menu bar staying hidden in full screen (fixes mgba.io/i/317)
|
|
||||||
- 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)
|
|
||||||
- Qt: Only show emulator restart warning once per settings saving
|
|
||||||
- FFmpeg: Drain recording buffers
|
- FFmpeg: Drain recording buffers
|
||||||
- Shaders: Fix gba-color shader resolution (fixes mgba.io/i/1435)
|
|
||||||
- Qt: Fix LibraryController initialization (fixes mgba.io/i/1324)
|
|
||||||
- Switch: Fix audio when video rate desyncs (fixes mgba.io/i/1532)
|
|
||||||
- GB: Fix reading ROM immediately after unmapping BIOS
|
- GB: Fix reading ROM immediately after unmapping BIOS
|
||||||
|
- GB SIO: Fix lockstep failing games aren't reloaded
|
||||||
|
- 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
|
||||||
|
- 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)
|
||||||
Misc:
|
Misc:
|
||||||
- GBA Savedata: EEPROM performance fixes
|
- CMake: Don't use libzip on embedded platforms (fixes mgba.io/i/1527)
|
||||||
- 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
|
|
||||||
- Qt: Support switching webcams
|
|
||||||
- Core: Add keysRead callback
|
- Core: Add keysRead callback
|
||||||
- Qt: Cap window size on start to monitor size
|
- Core: Create game-related paths if they don't exist (fixes mgba.io/i/1446)
|
||||||
- GBA BIOS: Add timings for HLE BIOS math functions (fixes mgba.io/i/1396)
|
- Core: Add more memory search ops (closes mgba.io/i/1510)
|
||||||
- Debugger: Make tracing compatible with breakpoints/watchpoints
|
- Debugger: Make tracing compatible with breakpoints/watchpoints
|
||||||
- Debugger: Print breakpoint/watchpoint number when inserting
|
- Debugger: Print breakpoint/watchpoint number when inserting
|
||||||
- Qt: Open a message box for Qt frontend errors
|
- Feature: Switch from ImageMagick to FFmpeg for GIF generation
|
||||||
- FFmpeg: Support audio-only recording
|
- 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
|
||||||
|
- 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
|
||||||
|
- Qt: Cap window size on start to monitor size
|
||||||
|
- Qt: Open a message box for Qt frontend errors
|
||||||
- Qt: Increase maximum magnifications and scaling
|
- Qt: Increase maximum magnifications and scaling
|
||||||
- Qt: Add native FPS button to settings view
|
- Qt: Add native FPS button to settings view
|
||||||
- Qt: Improve sync code
|
- 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)
|
- 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: 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
|
- 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: 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: Add copy and QoL improvements to graphic views (closes mgba.io/i/1541)
|
||||||
- Qt: Show list of all sprites in sprite view
|
- Qt: Show list of all sprites in sprite view
|
||||||
- Qt: Add option for disabling OSD messages
|
- 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)
|
0.7.3: (2019-09-15)
|
||||||
Emulation fixes:
|
Emulation fixes:
|
||||||
|
|
|
@ -636,7 +636,7 @@ if(USE_LIBZIP)
|
||||||
if (LIBZIP_VERSION_MAJOR LESS 1)
|
if (LIBZIP_VERSION_MAJOR LESS 1)
|
||||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libzip2")
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libzip2")
|
||||||
elseif(LIBZIP_VERSION_MAJOR EQUAL 1)
|
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()
|
else()
|
||||||
message(AUTHOR_WARNING Unknown version of libzip detected: ${libzip_VERSION})
|
message(AUTHOR_WARNING Unknown version of libzip detected: ${libzip_VERSION})
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -299,16 +299,14 @@ void ARMHalt(struct ARMCore* cpu) {
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
void ARM ## VERSION ## Run(struct ARMCore* cpu) { \
|
void ARM ## VERSION ## Run(struct ARMCore* cpu) { \
|
||||||
if (cpu->cycles < cpu->nextEvent) { \
|
while (cpu->cycles >= cpu->nextEvent) { \
|
||||||
if (cpu->executionMode == MODE_THUMB) { \
|
|
||||||
Thumb ## VERSION ## Step(cpu); \
|
|
||||||
} else { \
|
|
||||||
ARM ## VERSION ## Step(cpu); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
if (cpu->cycles >= cpu->nextEvent) { \
|
|
||||||
cpu->irqh.processEvents(cpu); \
|
cpu->irqh.processEvents(cpu); \
|
||||||
} \
|
} \
|
||||||
|
if (cpu->executionMode == MODE_THUMB) { \
|
||||||
|
Thumb ## VERSION ## Step(cpu); \
|
||||||
|
} else { \
|
||||||
|
ARM ## VERSION ## Step(cpu); \
|
||||||
|
} \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
void ARM ## VERSION ## RunLoop(struct ARMCore* cpu) { \
|
void ARM ## VERSION ## RunLoop(struct ARMCore* cpu) { \
|
||||||
|
|
|
@ -259,6 +259,11 @@ ATTRIBUTE_NOINLINE static void _neutralS(struct ARMCore* cpu, int32_t d) {
|
||||||
currentCycles += ARMWritePC(cpu); \
|
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_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_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)
|
#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 @@ ATTRIBUTE_NOINLINE static void _neutralS(struct ARMCore* cpu, int32_t d) {
|
||||||
y = ARM_SXT_16(cpu->gprs[rs] >> 16); \
|
y = ARM_SXT_16(cpu->gprs[rs] >> 16); \
|
||||||
BODY) \
|
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, \
|
DEFINE_INSTRUCTION_ARM(NAME, \
|
||||||
uint32_t address; \
|
uint32_t address; \
|
||||||
int rn = (opcode >> 16) & 0xF; \
|
int rn = (opcode >> 16) & 0xF; \
|
||||||
|
@ -434,57 +439,58 @@ ATTRIBUTE_NOINLINE static void _neutralS(struct ARMCore* cpu, int32_t d) {
|
||||||
int rm = opcode & 0xF; \
|
int rm = opcode & 0xF; \
|
||||||
UNUSED(rm); \
|
UNUSED(rm); \
|
||||||
address = ADDRESS; \
|
address = ADDRESS; \
|
||||||
WRITEBACK; \
|
ADDR_MODE_2_WRITEBACK_PRE_ ## LS (WRITEBACK); \
|
||||||
BODY;)
|
BODY; \
|
||||||
|
ADDR_MODE_2_WRITEBACK_POST_ ## LS (WRITEBACK);)
|
||||||
|
|
||||||
#define DEFINE_LOAD_STORE_INSTRUCTION_SHIFTER_ARM(NAME, SHIFTER, 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)), 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)), 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), , 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), 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), , 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), 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 DEFINE_LOAD_STORE_INSTRUCTION_ARM(NAME, LS, BODY) \
|
||||||
DEFINE_LOAD_STORE_INSTRUCTION_SHIFTER_ARM(NAME ## _LSL_, ADDR_MODE_2_LSL, 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, 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, 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, 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)), 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)), 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), , 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), 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), , 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), 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 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)), BODY) \
|
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)), 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), , 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), ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_ADDRESS), 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), , 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), 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)), 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, WRITEBACK(ADDR_MODE_3_INDEX(+, ADDR_MODE_3_IMMEDIATE)), 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), , 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), 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), , 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), 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_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, BODY) DEFINE_LOAD_STORE_MODE_3_WRITEBACK_WIDTH_INSTRUCTION_ARM(NAME, BODY, ADDR_MODE_3_WRITEBACK_64)
|
#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 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)), 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)), 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 DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(NAME, LS, BODY) \
|
||||||
DEFINE_LOAD_STORE_T_INSTRUCTION_SHIFTER_ARM(NAME ## _LSL_, ADDR_MODE_2_LSL, 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, 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, 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, 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)), 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)), 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 \
|
#define ARM_MS_PRE \
|
||||||
enum PrivilegeMode privilegeMode = cpu->privilegeMode; \
|
enum PrivilegeMode privilegeMode = cpu->privilegeMode; \
|
||||||
|
@ -636,19 +642,19 @@ DEFINE_MULTIPLY_INSTRUCTION_2_ARM(UMULL,
|
||||||
|
|
||||||
// Begin load/store definitions
|
// Begin load/store definitions
|
||||||
|
|
||||||
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDR, cpu->gprs[rd] = cpu->memory.load32(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY;)
|
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDR, LOAD, cpu->gprs[rd] = cpu->memory.load32(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY;)
|
||||||
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRv5, cpu->gprs[rd] = cpu->memory.load32(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY_v5;)
|
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRv5, LOAD, cpu->gprs[rd] = cpu->memory.load32(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY_v5;)
|
||||||
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRB, cpu->gprs[rd] = cpu->memory.load8(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY;)
|
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRB, LOAD, cpu->gprs[rd] = cpu->memory.load8(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY;)
|
||||||
DEFINE_LOAD_STORE_MODE_3_DOUBLE_INSTRUCTION_ARM(LDRD, cpu->gprs[rd & ~1] = cpu->memory.load32(cpu, address, ¤tCycles); cpu->gprs[rd | 1] = cpu->memory.load32(cpu, address + 4, ¤tCycles); ARM_LOAD_POST_BODY;)
|
DEFINE_LOAD_STORE_MODE_3_DOUBLE_INSTRUCTION_ARM(LDRD, LOAD, cpu->gprs[rd & ~1] = cpu->memory.load32(cpu, address, ¤tCycles); cpu->gprs[rd | 1] = cpu->memory.load32(cpu, address + 4, ¤tCycles); ARM_LOAD_POST_BODY;)
|
||||||
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRH, cpu->gprs[rd] = cpu->memory.load16(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY;)
|
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRH, LOAD, cpu->gprs[rd] = cpu->memory.load16(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY;)
|
||||||
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSB, cpu->gprs[rd] = ARM_SXT_8(cpu->memory.load8(cpu, address, ¤tCycles)); ARM_LOAD_POST_BODY;)
|
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSB, LOAD, cpu->gprs[rd] = ARM_SXT_8(cpu->memory.load8(cpu, address, ¤tCycles)); 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, ¤tCycles)) : ARM_SXT_16(cpu->memory.load16(cpu, address, ¤tCycles)); 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, ¤tCycles)) : ARM_SXT_16(cpu->memory.load16(cpu, address, ¤tCycles)); ARM_LOAD_POST_BODY;)
|
||||||
DEFINE_LOAD_STORE_INSTRUCTION_ARM(STR, cpu->memory.store32(cpu, address, cpu->gprs[rd], ¤tCycles); ARM_STORE_POST_BODY;)
|
DEFINE_LOAD_STORE_INSTRUCTION_ARM(STR, STORE, cpu->memory.store32(cpu, address, cpu->gprs[rd], ¤tCycles); ARM_STORE_POST_BODY;)
|
||||||
DEFINE_LOAD_STORE_INSTRUCTION_ARM(STRB, cpu->memory.store8(cpu, address, cpu->gprs[rd], ¤tCycles); ARM_STORE_POST_BODY;)
|
DEFINE_LOAD_STORE_INSTRUCTION_ARM(STRB, STORE, cpu->memory.store8(cpu, address, cpu->gprs[rd], ¤tCycles); ARM_STORE_POST_BODY;)
|
||||||
DEFINE_LOAD_STORE_MODE_3_DOUBLE_INSTRUCTION_ARM(STRD, cpu->memory.store32(cpu, address, cpu->gprs[rd & ~1], ¤tCycles); cpu->memory.store32(cpu, address + 4, cpu->gprs[rd | 1], ¤tCycles); ARM_STORE_POST_BODY;)
|
DEFINE_LOAD_STORE_MODE_3_DOUBLE_INSTRUCTION_ARM(STRD, STORE, cpu->memory.store32(cpu, address, cpu->gprs[rd & ~1], ¤tCycles); cpu->memory.store32(cpu, address + 4, cpu->gprs[rd | 1], ¤tCycles); ARM_STORE_POST_BODY;)
|
||||||
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(STRH, cpu->memory.store16(cpu, address, cpu->gprs[rd], ¤tCycles); ARM_STORE_POST_BODY;)
|
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(STRH, STORE, cpu->memory.store16(cpu, address, cpu->gprs[rd], ¤tCycles); ARM_STORE_POST_BODY;)
|
||||||
|
|
||||||
DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(LDRBT,
|
DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(LDRBT, LOAD,
|
||||||
enum PrivilegeMode priv = cpu->privilegeMode;
|
enum PrivilegeMode priv = cpu->privilegeMode;
|
||||||
ARMSetPrivilegeMode(cpu, MODE_USER);
|
ARMSetPrivilegeMode(cpu, MODE_USER);
|
||||||
int32_t r = cpu->memory.load8(cpu, address, ¤tCycles);
|
int32_t r = cpu->memory.load8(cpu, address, ¤tCycles);
|
||||||
|
@ -656,7 +662,7 @@ DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(LDRBT,
|
||||||
cpu->gprs[rd] = r;
|
cpu->gprs[rd] = r;
|
||||||
ARM_LOAD_POST_BODY;)
|
ARM_LOAD_POST_BODY;)
|
||||||
|
|
||||||
DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(LDRT,
|
DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(LDRT, LOAD,
|
||||||
enum PrivilegeMode priv = cpu->privilegeMode;
|
enum PrivilegeMode priv = cpu->privilegeMode;
|
||||||
ARMSetPrivilegeMode(cpu, MODE_USER);
|
ARMSetPrivilegeMode(cpu, MODE_USER);
|
||||||
int32_t r = cpu->memory.load32(cpu, address, ¤tCycles);
|
int32_t r = cpu->memory.load32(cpu, address, ¤tCycles);
|
||||||
|
@ -664,7 +670,7 @@ DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(LDRT,
|
||||||
cpu->gprs[rd] = r;
|
cpu->gprs[rd] = r;
|
||||||
ARM_LOAD_POST_BODY;)
|
ARM_LOAD_POST_BODY;)
|
||||||
|
|
||||||
DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(STRBT,
|
DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(STRBT, STORE,
|
||||||
enum PrivilegeMode priv = cpu->privilegeMode;
|
enum PrivilegeMode priv = cpu->privilegeMode;
|
||||||
int32_t r = cpu->gprs[rd];
|
int32_t r = cpu->gprs[rd];
|
||||||
ARMSetPrivilegeMode(cpu, MODE_USER);
|
ARMSetPrivilegeMode(cpu, MODE_USER);
|
||||||
|
@ -672,7 +678,7 @@ DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(STRBT,
|
||||||
ARMSetPrivilegeMode(cpu, priv);
|
ARMSetPrivilegeMode(cpu, priv);
|
||||||
ARM_STORE_POST_BODY;)
|
ARM_STORE_POST_BODY;)
|
||||||
|
|
||||||
DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(STRT,
|
DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(STRT, STORE,
|
||||||
enum PrivilegeMode priv = cpu->privilegeMode;
|
enum PrivilegeMode priv = cpu->privilegeMode;
|
||||||
int32_t r = cpu->gprs[rd];
|
int32_t r = cpu->gprs[rd];
|
||||||
ARMSetPrivilegeMode(cpu, MODE_USER);
|
ARMSetPrivilegeMode(cpu, MODE_USER);
|
||||||
|
@ -683,7 +689,7 @@ DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(STRT,
|
||||||
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(LDM,
|
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(LDM,
|
||||||
load,
|
load,
|
||||||
currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32;
|
currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32;
|
||||||
if (rs & 0x8000) {
|
if ((rs & 0x8000) || !rs) {
|
||||||
currentCycles += ARMWritePC(cpu);
|
currentCycles += ARMWritePC(cpu);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -295,6 +295,9 @@ DEFINE_LOAD_STORE_MULTIPLE_THUMB(LDMIA,
|
||||||
IA,
|
IA,
|
||||||
,
|
,
|
||||||
THUMB_LOAD_POST_BODY;
|
THUMB_LOAD_POST_BODY;
|
||||||
|
if (!rs) {
|
||||||
|
currentCycles += ThumbWritePC(cpu);
|
||||||
|
}
|
||||||
if (!((1 << rn) & rs)) {
|
if (!((1 << rn) & rs)) {
|
||||||
cpu->gprs[rn] = address;
|
cpu->gprs[rn] = address;
|
||||||
})
|
})
|
||||||
|
|
|
@ -11,6 +11,7 @@ void mBitmapCacheInit(struct mBitmapCache* cache) {
|
||||||
// TODO: Reconfigurable cache for space savings
|
// TODO: Reconfigurable cache for space savings
|
||||||
cache->cache = NULL;
|
cache->cache = NULL;
|
||||||
cache->config = mBitmapCacheConfigurationFillShouldStore(0);
|
cache->config = mBitmapCacheConfigurationFillShouldStore(0);
|
||||||
|
cache->sysConfig = 0;
|
||||||
cache->status = NULL;
|
cache->status = NULL;
|
||||||
cache->palette = NULL;
|
cache->palette = NULL;
|
||||||
cache->buffer = 0;
|
cache->buffer = 0;
|
||||||
|
@ -18,14 +19,18 @@ void mBitmapCacheInit(struct mBitmapCache* cache) {
|
||||||
|
|
||||||
static void _freeCache(struct mBitmapCache* cache) {
|
static void _freeCache(struct mBitmapCache* cache) {
|
||||||
size_t size = mBitmapCacheSystemInfoGetHeight(cache->sysConfig) * mBitmapCacheSystemInfoGetBuffers(cache->sysConfig);
|
size_t size = mBitmapCacheSystemInfoGetHeight(cache->sysConfig) * mBitmapCacheSystemInfoGetBuffers(cache->sysConfig);
|
||||||
mappedMemoryFree(cache->cache, mBitmapCacheSystemInfoGetWidth(cache->sysConfig) * size * sizeof(color_t));
|
if (cache->cache) {
|
||||||
mappedMemoryFree(cache->status, size * sizeof(*cache->status));
|
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) {
|
if (cache->palette) {
|
||||||
free(cache->palette);
|
free(cache->palette);
|
||||||
|
cache->palette = NULL;
|
||||||
}
|
}
|
||||||
cache->cache = NULL;
|
|
||||||
cache->status = NULL;
|
|
||||||
cache->palette = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _redoCacheSize(struct mBitmapCache* cache) {
|
static void _redoCacheSize(struct mBitmapCache* cache) {
|
||||||
|
|
|
@ -334,7 +334,7 @@ bool mCheatParseEZFChtFile(struct mCheatDevice* device, struct VFile* vf) {
|
||||||
char cheat[MAX_LINE_LENGTH];
|
char cheat[MAX_LINE_LENGTH];
|
||||||
char cheatName[MAX_LINE_LENGTH];
|
char cheatName[MAX_LINE_LENGTH];
|
||||||
char miniline[32];
|
char miniline[32];
|
||||||
size_t cheatNameLength;
|
size_t cheatNameLength = 0;
|
||||||
struct mCheatSet* set = NULL;
|
struct mCheatSet* set = NULL;
|
||||||
|
|
||||||
cheatName[MAX_LINE_LENGTH - 1] = '\0';
|
cheatName[MAX_LINE_LENGTH - 1] = '\0';
|
||||||
|
|
|
@ -11,15 +11,20 @@ void mMapCacheInit(struct mMapCache* cache) {
|
||||||
// TODO: Reconfigurable cache for space savings
|
// TODO: Reconfigurable cache for space savings
|
||||||
cache->cache = NULL;
|
cache->cache = NULL;
|
||||||
cache->config = mMapCacheConfigurationFillShouldStore(0);
|
cache->config = mMapCacheConfigurationFillShouldStore(0);
|
||||||
|
cache->sysConfig = 0;
|
||||||
cache->status = NULL;
|
cache->status = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _freeCache(struct mMapCache* cache) {
|
static void _freeCache(struct mMapCache* cache) {
|
||||||
size_t tiles = (1 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig)) * (1 << mMapCacheSystemInfoGetTilesHigh(cache->sysConfig));
|
size_t tiles = (1 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig)) * (1 << mMapCacheSystemInfoGetTilesHigh(cache->sysConfig));
|
||||||
mappedMemoryFree(cache->cache, 8 * 8 * sizeof(color_t) * tiles);
|
if (cache->cache) {
|
||||||
mappedMemoryFree(cache->status, tiles * sizeof(*cache->status));
|
mappedMemoryFree(cache->cache, 8 * 8 * sizeof(color_t) * tiles);
|
||||||
cache->cache = NULL;
|
cache->cache = NULL;
|
||||||
cache->status = NULL;
|
}
|
||||||
|
if (cache->status) {
|
||||||
|
mappedMemoryFree(cache->status, tiles * sizeof(*cache->status));
|
||||||
|
cache->status = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _redoCacheSize(struct mMapCache* cache) {
|
static void _redoCacheSize(struct mMapCache* cache) {
|
||||||
|
|
|
@ -51,6 +51,9 @@ static void _redoCacheSize(struct mTileCache* cache) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void mTileCacheConfigure(struct mTileCache* cache, mTileCacheConfiguration config) {
|
void mTileCacheConfigure(struct mTileCache* cache, mTileCacheConfiguration config) {
|
||||||
|
if (cache->config == config) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
_freeCache(cache);
|
_freeCache(cache);
|
||||||
cache->config = config;
|
cache->config = config;
|
||||||
_redoCacheSize(cache);
|
_redoCacheSize(cache);
|
||||||
|
@ -278,5 +281,9 @@ const color_t* mTileCacheGetPalette(struct mTileCache* cache, unsigned paletteId
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint16_t* mTileCacheGetVRAM(struct mTileCache* cache, unsigned tileId) {
|
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)];
|
return &cache->vram[tileId << (cache->bpp + 2)];
|
||||||
}
|
}
|
||||||
|
|
|
@ -649,7 +649,15 @@ void GBPatch8(struct LR35902Core* cpu, uint16_t address, int8_t value, int8_t* o
|
||||||
break;
|
break;
|
||||||
case GB_REGION_EXTERNAL_RAM:
|
case GB_REGION_EXTERNAL_RAM:
|
||||||
case GB_REGION_EXTERNAL_RAM + 1:
|
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;
|
return;
|
||||||
case GB_REGION_WORKING_RAM_BANK0:
|
case GB_REGION_WORKING_RAM_BANK0:
|
||||||
case GB_REGION_WORKING_RAM_BANK0 + 2:
|
case GB_REGION_WORKING_RAM_BANK0 + 2:
|
||||||
|
|
|
@ -12,11 +12,13 @@
|
||||||
|
|
||||||
void GBVideoCacheInit(struct mCacheSet* cache) {
|
void GBVideoCacheInit(struct mCacheSet* cache) {
|
||||||
mCacheSetInit(cache, 2, 0, 1);
|
mCacheSetInit(cache, 2, 0, 1);
|
||||||
mTileCacheConfiguration config = 0;
|
mTileCacheSystemInfo sysconfig = 0;
|
||||||
config = mTileCacheSystemInfoSetPaletteBPP(config, 1); // 2^(2^1) = 4 entries
|
mTileCacheConfiguration config = mTileCacheConfigurationFillShouldStore(0);
|
||||||
config = mTileCacheSystemInfoSetPaletteCount(config, 4); // 16 palettes
|
sysconfig = mTileCacheSystemInfoSetPaletteBPP(sysconfig, 1); // 2^(2^1) = 4 entries
|
||||||
config = mTileCacheSystemInfoSetMaxTiles(config, 1024);
|
sysconfig = mTileCacheSystemInfoSetPaletteCount(sysconfig, 4); // 16 palettes
|
||||||
mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 0), config, 0, 0);
|
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, 0)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0);
|
||||||
mMapCacheSetGetPointer(&cache->maps, 1)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0);
|
mMapCacheSetGetPointer(&cache->maps, 1)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0);
|
||||||
|
|
|
@ -95,6 +95,8 @@ uint16_t GBADMAWriteCNT_HI(struct GBA* gba, int dma, uint16_t control) {
|
||||||
if (currentDma->nextDest & (width - 1)) {
|
if (currentDma->nextDest & (width - 1)) {
|
||||||
mLOG(GBA_MEM, GAME_ERROR, "Misaligned DMA destination address: 0x%08X", currentDma->nextDest);
|
mLOG(GBA_MEM, GAME_ERROR, "Misaligned DMA destination address: 0x%08X", currentDma->nextDest);
|
||||||
}
|
}
|
||||||
|
currentDma->nextSource &= -width;
|
||||||
|
currentDma->nextDest &= -width;
|
||||||
|
|
||||||
GBADMASchedule(gba, dma, currentDma);
|
GBADMASchedule(gba, dma, currentDma);
|
||||||
}
|
}
|
||||||
|
@ -242,8 +244,6 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) {
|
||||||
} else {
|
} else {
|
||||||
cycles += memory->waitstatesNonseq16[sourceRegion] + memory->waitstatesNonseq16[destRegion];
|
cycles += memory->waitstatesNonseq16[sourceRegion] + memory->waitstatesNonseq16[destRegion];
|
||||||
}
|
}
|
||||||
source &= -width;
|
|
||||||
dest &= -width;
|
|
||||||
} else {
|
} else {
|
||||||
if (width == 4) {
|
if (width == 4) {
|
||||||
cycles += memory->waitstatesSeq32[sourceRegion] + memory->waitstatesSeq32[destRegion];
|
cycles += memory->waitstatesSeq32[sourceRegion] + memory->waitstatesSeq32[destRegion];
|
||||||
|
|
|
@ -353,10 +353,10 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
|
||||||
case REGION_WORKING_IRAM: \
|
case REGION_WORKING_IRAM: \
|
||||||
/* This doesn't handle prefetch clobbering */ \
|
/* This doesn't handle prefetch clobbering */ \
|
||||||
if (cpu->gprs[ARM_PC] & 2) { \
|
if (cpu->gprs[ARM_PC] & 2) { \
|
||||||
value |= cpu->prefetch[0] << 16; \
|
|
||||||
} else { \
|
|
||||||
value <<= 16; \
|
value <<= 16; \
|
||||||
value |= cpu->prefetch[0]; \
|
value |= cpu->prefetch[0]; \
|
||||||
|
} else { \
|
||||||
|
value |= cpu->prefetch[0] << 16; \
|
||||||
} \
|
} \
|
||||||
break; \
|
break; \
|
||||||
default: \
|
default: \
|
||||||
|
@ -1326,6 +1326,12 @@ void GBAPatch8(struct ARMCore* cpu, uint32_t address, int8_t value, int8_t* old)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LDM_LOOP(LDM) \
|
#define LDM_LOOP(LDM) \
|
||||||
|
if (UNLIKELY(!mask)) { \
|
||||||
|
LDM; \
|
||||||
|
cpu->gprs[ARM_PC] = value; \
|
||||||
|
wait += 16; \
|
||||||
|
address += 64; \
|
||||||
|
} \
|
||||||
for (i = 0; i < 16; i += 4) { \
|
for (i = 0; i < 16; i += 4) { \
|
||||||
if (UNLIKELY(mask & (1 << i))) { \
|
if (UNLIKELY(mask & (1 << i))) { \
|
||||||
LDM; \
|
LDM; \
|
||||||
|
@ -1438,6 +1444,12 @@ uint32_t GBALoadMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum L
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STM_LOOP(STM) \
|
#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) { \
|
for (i = 0; i < 16; i += 4) { \
|
||||||
if (UNLIKELY(mask & (1 << i))) { \
|
if (UNLIKELY(mask & (1 << i))) { \
|
||||||
value = cpu->gprs[i]; \
|
value = cpu->gprs[i]; \
|
||||||
|
|
|
@ -17,20 +17,20 @@ void GBAVideoCacheInit(struct mCacheSet* cache) {
|
||||||
sysconfig = mTileCacheSystemInfoSetPaletteBPP(sysconfig, 2); // 2^(2^2) = 16 entries
|
sysconfig = mTileCacheSystemInfoSetPaletteBPP(sysconfig, 2); // 2^(2^2) = 16 entries
|
||||||
sysconfig = mTileCacheSystemInfoSetPaletteCount(sysconfig, 4); // 16 palettes
|
sysconfig = mTileCacheSystemInfoSetPaletteCount(sysconfig, 4); // 16 palettes
|
||||||
sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 2048);
|
sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 2048);
|
||||||
mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 0), config);
|
|
||||||
mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 0), sysconfig, 0, 0);
|
mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 0), sysconfig, 0, 0);
|
||||||
|
mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 0), config);
|
||||||
sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 1024);
|
sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 1024);
|
||||||
mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 2), config);
|
|
||||||
mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 2), sysconfig, 0x10000, 0x100);
|
mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 2), sysconfig, 0x10000, 0x100);
|
||||||
|
mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 2), config);
|
||||||
|
|
||||||
sysconfig = mTileCacheSystemInfoSetPaletteBPP(sysconfig, 3); // 2^(2^3) = 256 entries
|
sysconfig = mTileCacheSystemInfoSetPaletteBPP(sysconfig, 3); // 2^(2^3) = 256 entries
|
||||||
sysconfig = mTileCacheSystemInfoSetPaletteCount(sysconfig, 0); // 1 palettes
|
sysconfig = mTileCacheSystemInfoSetPaletteCount(sysconfig, 0); // 1 palettes
|
||||||
sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 2048);
|
sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 2048);
|
||||||
mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 1), config);
|
|
||||||
mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 1), sysconfig, 0, 0);
|
mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 1), sysconfig, 0, 0);
|
||||||
|
mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 1), config);
|
||||||
sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 1024);
|
sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 1024);
|
||||||
mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 3), config);
|
|
||||||
mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 3), sysconfig, 0x10000, 0x100);
|
mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 3), sysconfig, 0x10000, 0x100);
|
||||||
|
mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 3), config);
|
||||||
|
|
||||||
mBitmapCacheSystemInfo bitConfig;
|
mBitmapCacheSystemInfo bitConfig;
|
||||||
bitConfig = mBitmapCacheSystemInfoSetEntryBPP(0, 4);
|
bitConfig = mBitmapCacheSystemInfoSetEntryBPP(0, 4);
|
||||||
|
@ -50,6 +50,11 @@ void GBAVideoCacheInit(struct mCacheSet* cache) {
|
||||||
mBitmapCacheConfigureSystem(mBitmapCacheSetGetPointer(&cache->bitmaps, 1), bitConfig);
|
mBitmapCacheConfigureSystem(mBitmapCacheSetGetPointer(&cache->bitmaps, 1), bitConfig);
|
||||||
mBitmapCacheSetGetPointer(&cache->bitmaps, 1)->bitsStart[0] = 0;
|
mBitmapCacheSetGetPointer(&cache->bitmaps, 1)->bitsStart[0] = 0;
|
||||||
mBitmapCacheSetGetPointer(&cache->bitmaps, 1)->bitsStart[1] = 0xA000;
|
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) {
|
void GBAVideoCacheAssociate(struct mCacheSet* cache, struct GBAVideo* video) {
|
||||||
|
|
|
@ -145,21 +145,21 @@ static const char* const _renderMode0 =
|
||||||
" if (mosaic.y > 1) {\n"
|
" if (mosaic.y > 1) {\n"
|
||||||
" coord.y -= coord.y % mosaic.y;\n"
|
" coord.y -= coord.y % mosaic.y;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
" coord += (ivec2(0x3FF, 0x3FF000) & offset[int(texCoord.y)]) >> ivec2(0, 12);\n"
|
" coord += (ivec2(0x1FF, 0x1FF000) & offset[int(texCoord.y)]) >> ivec2(0, 12);\n"
|
||||||
" ivec2 wrap = ivec2(255, 511);\n"
|
" ivec2 wrap = ivec2(255, 255);\n"
|
||||||
" if (size == 3) {\n"
|
" int doty = 0;\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"
|
|
||||||
" if ((size & 1) == 1) {\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"
|
" }\n"
|
||||||
" coord &= wrap;\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"
|
" int mapAddress = screenBase + (coord.x >> 3) + (coord.y >> 3) * 32;\n"
|
||||||
" vec4 map = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0);\n"
|
" vec4 map = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0);\n"
|
||||||
" int tileFlags = int(map.g * 15.9);\n"
|
" int tileFlags = int(map.g * 15.9);\n"
|
||||||
|
|
|
@ -47,6 +47,7 @@ bool GBASIOLockstepAttachNode(struct GBASIOLockstep* lockstep, struct GBASIOLock
|
||||||
lockstep->players[lockstep->d.attached] = node;
|
lockstep->players[lockstep->d.attached] = node;
|
||||||
node->p = lockstep;
|
node->p = lockstep;
|
||||||
node->id = lockstep->d.attached;
|
node->id = lockstep->d.attached;
|
||||||
|
node->transferFinished = true;
|
||||||
++lockstep->d.attached;
|
++lockstep->d.attached;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -417,6 +417,46 @@ static void _gameUnloaded(struct mGUIRunner* runner) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
static void _drawTex(struct mCore* core, bool faded, bool both) {
|
||||||
unsigned screen_w, screen_h;
|
unsigned screen_w, screen_h;
|
||||||
switch (screenMode) {
|
switch (screenMode) {
|
||||||
|
@ -485,45 +525,10 @@ static void _drawTex(struct mCore* core, bool faded, bool both) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 color;
|
uint32_t color = _setupTex(activeOutputTexture, faded);
|
||||||
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]);
|
|
||||||
ctrAddRectEx(color, x, y, w, h, 0, 0, corew, coreh, 0);
|
ctrAddRectEx(color, x, y, w, h, 0, 0, corew, coreh, 0);
|
||||||
if (both) {
|
if (both) {
|
||||||
ctrActivateTexture(&outputTexture[activeOutputTexture ^ 1]);
|
color = _setupTex(activeOutputTexture ^ 1, faded);
|
||||||
ctrAddRectEx(color & 0x7FFFFFFF, x, y, w, h, 0, 0, corew, coreh, 0);
|
ctrAddRectEx(color & 0x7FFFFFFF, x, y, w, h, 0, 0, corew, coreh, 0);
|
||||||
}
|
}
|
||||||
ctrFlushBatch();
|
ctrFlushBatch();
|
||||||
|
|
|
@ -165,6 +165,7 @@ int main() {
|
||||||
|
|
||||||
sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START);
|
sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START);
|
||||||
sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG_WIDE);
|
sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG_WIDE);
|
||||||
|
sceCtrlSetSamplingModeExt(SCE_CTRL_MODE_ANALOG_WIDE);
|
||||||
sceSysmoduleLoadModule(SCE_SYSMODULE_PHOTO_EXPORT);
|
sceSysmoduleLoadModule(SCE_SYSMODULE_PHOTO_EXPORT);
|
||||||
sceSysmoduleLoadModule(SCE_SYSMODULE_APPUTIL);
|
sceSysmoduleLoadModule(SCE_SYSMODULE_APPUTIL);
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,9 @@ void AssetView::showEvent(QShowEvent*) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetView::compositeTile(const void* tBuffer, void* buffer, size_t stride, size_t x, size_t y, int depth) {
|
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);
|
const uint8_t* tile = static_cast<const uint8_t*>(tBuffer);
|
||||||
uint8_t* pixels = static_cast<uint8_t*>(buffer);
|
uint8_t* pixels = static_cast<uint8_t*>(buffer);
|
||||||
size_t base = stride * y + x;
|
size_t base = stride * y + x;
|
||||||
|
|
|
@ -129,7 +129,6 @@ void CheatsView::addSet() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheatsView::removeSet() {
|
void CheatsView::removeSet() {
|
||||||
GBACheatSet* set;
|
|
||||||
QModelIndexList selection = m_ui.cheatList->selectionModel()->selectedIndexes();
|
QModelIndexList selection = m_ui.cheatList->selectionModel()->selectedIndexes();
|
||||||
if (selection.count() < 1) {
|
if (selection.count() < 1) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -637,12 +637,16 @@ void CoreController::yankPak() {
|
||||||
Interrupter interrupter(this);
|
Interrupter interrupter(this);
|
||||||
|
|
||||||
switch (platform()) {
|
switch (platform()) {
|
||||||
|
#ifdef M_CORE_GBA
|
||||||
case PLATFORM_GBA:
|
case PLATFORM_GBA:
|
||||||
GBAYankROM(static_cast<GBA*>(m_threadContext.core->board));
|
GBAYankROM(static_cast<GBA*>(m_threadContext.core->board));
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef M_CORE_GB
|
||||||
case PLATFORM_GB:
|
case PLATFORM_GB:
|
||||||
GBYankROM(static_cast<GB*>(m_threadContext.core->board));
|
GBYankROM(static_cast<GB*>(m_threadContext.core->board));
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -226,7 +226,7 @@ private:
|
||||||
|
|
||||||
bool m_autosave;
|
bool m_autosave;
|
||||||
bool m_autoload;
|
bool m_autoload;
|
||||||
int m_autosaveCounter;
|
int m_autosaveCounter = 0;
|
||||||
|
|
||||||
int m_fastForward = false;
|
int m_fastForward = false;
|
||||||
int m_fastForwardForced = false;
|
int m_fastForwardForced = false;
|
||||||
|
|
|
@ -26,7 +26,11 @@ Display* Display::create(QWidget* parent) {
|
||||||
switch (s_driver) {
|
switch (s_driver) {
|
||||||
#if defined(BUILD_GL) || defined(BUILD_GLES2) || defined(USE_EPOXY)
|
#if defined(BUILD_GL) || defined(BUILD_GLES2) || defined(USE_EPOXY)
|
||||||
case Driver::OPENGL:
|
case Driver::OPENGL:
|
||||||
format.setVersion(3, 2);
|
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) {
|
||||||
|
format.setVersion(3, 0);
|
||||||
|
} else {
|
||||||
|
format.setVersion(3, 2);
|
||||||
|
}
|
||||||
format.setProfile(QSurfaceFormat::CoreProfile);
|
format.setProfile(QSurfaceFormat::CoreProfile);
|
||||||
return new DisplayGL(format, parent);
|
return new DisplayGL(format, parent);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -232,7 +232,7 @@ void GBAKeyEditor::save() {
|
||||||
|
|
||||||
#ifdef BUILD_SDL
|
#ifdef BUILD_SDL
|
||||||
if (m_profileSelect) {
|
if (m_profileSelect) {
|
||||||
m_controller->setPreferredGamepad(m_type, m_profileSelect->currentText());
|
m_controller->setPreferredGamepad(m_type, m_profileSelect->currentIndex());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -167,6 +167,7 @@ void MapView::updateTilesGBA(bool force) {
|
||||||
int frame = 0;
|
int frame = 0;
|
||||||
QString offset(tr("N/A"));
|
QString offset(tr("N/A"));
|
||||||
QString transform(tr("N/A"));
|
QString transform(tr("N/A"));
|
||||||
|
#ifdef M_CORE_GBA
|
||||||
if (m_controller->platform() == PLATFORM_GBA) {
|
if (m_controller->platform() == PLATFORM_GBA) {
|
||||||
uint16_t* io = static_cast<GBA*>(m_controller->thread()->core->board)->memory.io;
|
uint16_t* io = static_cast<GBA*>(m_controller->thread()->core->board)->memory.io;
|
||||||
int mode = GBARegisterDISPCNTGetMode(io[REG_DISPCNT >> 1]);
|
int mode = GBARegisterDISPCNTGetMode(io[REG_DISPCNT >> 1]);
|
||||||
|
@ -199,12 +200,15 @@ void MapView::updateTilesGBA(bool force) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef M_CORE_GB
|
||||||
if (m_controller->platform() == PLATFORM_GB) {
|
if (m_controller->platform() == PLATFORM_GB) {
|
||||||
uint8_t* io = static_cast<GB*>(m_controller->thread()->core->board)->memory.io;
|
uint8_t* io = static_cast<GB*>(m_controller->thread()->core->board)->memory.io;
|
||||||
int x = io[m_map == 0 ? 0x42 : 0x4A];
|
int x = io[m_map == 0 ? 0x42 : 0x4A];
|
||||||
int y = io[m_map == 0 ? 0x43 : 0x4B];
|
int y = io[m_map == 0 ? 0x43 : 0x4B];
|
||||||
offset = QString("%1, %2").arg(x).arg(y);
|
offset = QString("%1, %2").arg(x).arg(y);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (bitmap >= 0) {
|
if (bitmap >= 0) {
|
||||||
mBitmapCache* bitmapCache = mBitmapCacheSetGetPointer(&m_cacheSet->bitmaps, bitmap);
|
mBitmapCache* bitmapCache = mBitmapCacheSetGetPointer(&m_cacheSet->bitmaps, bitmap);
|
||||||
int width = mBitmapCacheSystemInfoGetWidth(bitmapCache->sysConfig);
|
int width = mBitmapCacheSystemInfoGetWidth(bitmapCache->sysConfig);
|
||||||
|
@ -266,4 +270,4 @@ void MapView::exportMap() {
|
||||||
void MapView::copyMap() {
|
void MapView::copyMap() {
|
||||||
CoreController::Interrupter interrupter(m_controller);
|
CoreController::Interrupter interrupter(m_controller);
|
||||||
GBAApp::app()->clipboard()->setImage(m_rawMap);
|
GBAApp::app()->clipboard()->setImage(m_rawMap);
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,19 @@ MemoryModel::MemoryModel(QWidget* parent)
|
||||||
update();
|
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"));
|
setRegion(0, 0x10000000, tr("All"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,11 +22,13 @@ MultiplayerController::Player::Player(CoreController* coreController, GBSIOLocks
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef M_CORE_GBA
|
||||||
MultiplayerController::Player::Player(CoreController* coreController, GBASIOLockstepNode* node)
|
MultiplayerController::Player::Player(CoreController* coreController, GBASIOLockstepNode* node)
|
||||||
: controller(coreController)
|
: controller(coreController)
|
||||||
, gbaNode(node)
|
, gbaNode(node)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
MultiplayerController::MultiplayerController() {
|
MultiplayerController::MultiplayerController() {
|
||||||
mLockstepInit(&m_lockstep);
|
mLockstepInit(&m_lockstep);
|
||||||
|
@ -71,10 +73,12 @@ MultiplayerController::MultiplayerController() {
|
||||||
if (!id) {
|
if (!id) {
|
||||||
for (int i = 1; i < controller->m_players.count(); ++i) {
|
for (int i = 1; i < controller->m_players.count(); ++i) {
|
||||||
Player* player = &controller->m_players[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) {
|
if (player->controller->platform() == PLATFORM_GBA && player->gbaNode->d.p->mode != controller->m_players[0].gbaNode->d.p->mode) {
|
||||||
player->controller->setSync(true);
|
player->controller->setSync(true);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
player->controller->setSync(false);
|
player->controller->setSync(false);
|
||||||
player->cyclesPosted += cycles;
|
player->cyclesPosted += cycles;
|
||||||
if (player->awake < 1) {
|
if (player->awake < 1) {
|
||||||
|
|
|
@ -45,8 +45,12 @@ signals:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Player {
|
struct Player {
|
||||||
|
#ifdef M_CORE_GB
|
||||||
Player(CoreController* controller, GBSIOLockstepNode* node);
|
Player(CoreController* controller, GBSIOLockstepNode* node);
|
||||||
|
#endif
|
||||||
|
#ifdef M_CORE_GBA
|
||||||
Player(CoreController* controller, GBASIOLockstepNode* node);
|
Player(CoreController* controller, GBASIOLockstepNode* node);
|
||||||
|
#endif
|
||||||
|
|
||||||
CoreController* controller;
|
CoreController* controller;
|
||||||
GBSIOLockstepNode* gbNode = nullptr;
|
GBSIOLockstepNode* gbNode = nullptr;
|
||||||
|
|
|
@ -69,6 +69,7 @@ OverrideView::OverrideView(ConfigController* config, QWidget* parent)
|
||||||
m_ui.hwRumble->setEnabled(!enabled);
|
m_ui.hwRumble->setEnabled(!enabled);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
#ifdef M_CORE_GB
|
||||||
m_colorPickers[0] = ColorPicker(m_ui.color0, QColor(0xF8, 0xF8, 0xF8));
|
m_colorPickers[0] = ColorPicker(m_ui.color0, QColor(0xF8, 0xF8, 0xF8));
|
||||||
m_colorPickers[1] = ColorPicker(m_ui.color1, QColor(0xA8, 0xA8, 0xA8));
|
m_colorPickers[1] = ColorPicker(m_ui.color1, QColor(0xA8, 0xA8, 0xA8));
|
||||||
m_colorPickers[2] = ColorPicker(m_ui.color2, QColor(0x50, 0x50, 0x50));
|
m_colorPickers[2] = ColorPicker(m_ui.color2, QColor(0x50, 0x50, 0x50));
|
||||||
|
@ -86,6 +87,7 @@ OverrideView::OverrideView(ConfigController* config, QWidget* parent)
|
||||||
m_gbColors[colorId] = color.rgb() | 0xFF000000;
|
m_gbColors[colorId] = color.rgb() | 0xFF000000;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef M_CORE_GBA
|
#ifndef M_CORE_GBA
|
||||||
m_ui.tabWidget->removeTab(m_ui.tabWidget->indexOf(m_ui.tabGBA));
|
m_ui.tabWidget->removeTab(m_ui.tabWidget->indexOf(m_ui.tabGBA));
|
||||||
|
|
|
@ -33,6 +33,7 @@ ShaderSelector::ShaderSelector(Display* display, ConfigController* config, QWidg
|
||||||
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
|
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
|
||||||
, m_display(display)
|
, m_display(display)
|
||||||
, m_config(config)
|
, m_config(config)
|
||||||
|
, m_shaderPath(config->getOption("shader"))
|
||||||
{
|
{
|
||||||
m_ui.setupUi(this);
|
m_ui.setupUi(this);
|
||||||
|
|
||||||
|
@ -41,9 +42,6 @@ ShaderSelector::ShaderSelector(Display* display, ConfigController* config, QWidg
|
||||||
connect(m_ui.load, &QAbstractButton::clicked, this, &ShaderSelector::selectShader);
|
connect(m_ui.load, &QAbstractButton::clicked, this, &ShaderSelector::selectShader);
|
||||||
connect(m_ui.unload, &QAbstractButton::clicked, this, &ShaderSelector::clearShader);
|
connect(m_ui.unload, &QAbstractButton::clicked, this, &ShaderSelector::clearShader);
|
||||||
connect(m_ui.buttonBox, &QDialogButtonBox::clicked, this, &ShaderSelector::buttonPressed);
|
connect(m_ui.buttonBox, &QDialogButtonBox::clicked, this, &ShaderSelector::buttonPressed);
|
||||||
connect(this, &ShaderSelector::saved, [this]() {
|
|
||||||
m_config->setOption("shader", m_shaderPath);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderSelector::~ShaderSelector() {
|
ShaderSelector::~ShaderSelector() {
|
||||||
|
@ -85,12 +83,14 @@ void ShaderSelector::loadShader(const QString& path) {
|
||||||
m_display->setShaders(shader);
|
m_display->setShaders(shader);
|
||||||
shader->close(shader);
|
shader->close(shader);
|
||||||
m_shaderPath = path;
|
m_shaderPath = path;
|
||||||
|
m_config->setOption("shader", m_shaderPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderSelector::clearShader() {
|
void ShaderSelector::clearShader() {
|
||||||
m_display->clearShaders();
|
m_display->clearShaders();
|
||||||
refreshShaders();
|
refreshShaders();
|
||||||
m_shaderPath = "";
|
m_shaderPath = "";
|
||||||
|
m_config->setOption("shader", m_shaderPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderSelector::refreshShaders() {
|
void ShaderSelector::refreshShaders() {
|
||||||
|
@ -119,10 +119,6 @@ void ShaderSelector::refreshShaders() {
|
||||||
disconnect(this, &ShaderSelector::reset, 0, 0);
|
disconnect(this, &ShaderSelector::reset, 0, 0);
|
||||||
disconnect(this, &ShaderSelector::resetToDefault, 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 !defined(_WIN32) || defined(USE_EPOXY)
|
||||||
if (m_shaders->preprocessShader) {
|
if (m_shaders->preprocessShader) {
|
||||||
m_ui.passes->addTab(makePage(static_cast<mGLES2Shader*>(m_shaders->preprocessShader), "default", 0), tr("Preprocessing"));
|
m_ui.passes->addTab(makePage(static_cast<mGLES2Shader*>(m_shaders->preprocessShader), "default", 0), tr("Preprocessing"));
|
||||||
|
|
|
@ -26,6 +26,9 @@ void TilePainter::paintEvent(QPaintEvent* event) {
|
||||||
|
|
||||||
void TilePainter::resizeEvent(QResizeEvent* event) {
|
void TilePainter::resizeEvent(QResizeEvent* event) {
|
||||||
int w = width() / m_size;
|
int w = width() / m_size;
|
||||||
|
if (!w) {
|
||||||
|
w = 1;
|
||||||
|
}
|
||||||
int calculatedHeight = (m_tileCount + w - 1) * m_size / w;
|
int calculatedHeight = (m_tileCount + w - 1) * m_size / w;
|
||||||
calculatedHeight -= calculatedHeight % m_size;
|
calculatedHeight -= calculatedHeight % m_size;
|
||||||
if (width() / m_size != m_backing.width() / m_size || m_backing.height() != calculatedHeight) {
|
if (width() / m_size != m_backing.width() / m_size || m_backing.height() != calculatedHeight) {
|
||||||
|
|
|
@ -1497,7 +1497,9 @@ void Window::setupMenu(QMenuBar* menubar) {
|
||||||
ConfigOption* mute = m_config->addOption("mute");
|
ConfigOption* mute = m_config->addOption("mute");
|
||||||
mute->addBoolean(tr("Mute"), &m_actions, "av");
|
mute->addBoolean(tr("Mute"), &m_actions, "av");
|
||||||
mute->connect([this](const QVariant& value) {
|
mute->connect([this](const QVariant& value) {
|
||||||
m_config->setOption("fastForwardMute", static_cast<bool>(value.toInt()));
|
if (value.toInt()) {
|
||||||
|
m_config->setOption("fastForwardMute", true);
|
||||||
|
}
|
||||||
reloadConfig();
|
reloadConfig();
|
||||||
}, this);
|
}, this);
|
||||||
m_config->updateOption("mute");
|
m_config->updateOption("mute");
|
||||||
|
|
|
@ -383,11 +383,13 @@ void InputController::setGamepad(uint32_t type, int index) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputController::setPreferredGamepad(uint32_t type, const QString& device) {
|
void InputController::setPreferredGamepad(uint32_t type, int index) {
|
||||||
if (!m_config) {
|
if (!m_config) {
|
||||||
return;
|
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() {
|
mRumble* InputController::rumble() {
|
||||||
|
|
|
@ -99,7 +99,7 @@ public:
|
||||||
QStringList connectedGamepads(uint32_t type) const;
|
QStringList connectedGamepads(uint32_t type) const;
|
||||||
int gamepad(uint32_t type) const;
|
int gamepad(uint32_t type) const;
|
||||||
void setGamepad(uint32_t type, int index);
|
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 registerTiltAxisX(int axis);
|
||||||
void registerTiltAxisY(int axis);
|
void registerTiltAxisY(int axis);
|
||||||
|
|
|
@ -3820,7 +3820,7 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.</tran
|
||||||
<message>
|
<message>
|
||||||
<location filename="../Window.cpp" line="1121"/>
|
<location filename="../Window.cpp" line="1121"/>
|
||||||
<source>Load state file...</source>
|
<source>Load state file...</source>
|
||||||
<translation>Ssavestate-Datei laden...</translation>
|
<translation>Savestate-Datei laden...</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../Window.cpp" line="1126"/>
|
<location filename="../Window.cpp" line="1126"/>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -198,15 +198,15 @@ bool mSDLAttachPlayer(struct mSDLEvents* events, struct mSDLPlayer* player) {
|
||||||
firstUnclaimed = i;
|
firstUnclaimed = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* joystickName;
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
#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
|
#else
|
||||||
joystickName = SDL_JoystickName(SDL_JoystickIndex(SDL_JoystickListGetPointer(&events->joysticks, i)->joystick));
|
const char* joystickName = SDL_JoystickName(SDL_JoystickIndex(SDL_JoystickListGetPointer(&events->joysticks, i)->joystick));
|
||||||
#endif
|
|
||||||
if (!joystickName) {
|
if (!joystickName) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (events->preferredJoysticks[player->playerId] && strcmp(events->preferredJoysticks[player->playerId], joystickName) == 0) {
|
if (events->preferredJoysticks[player->playerId] && strcmp(events->preferredJoysticks[player->playerId], joystickName) == 0) {
|
||||||
index = i;
|
index = i;
|
||||||
break;
|
break;
|
||||||
|
@ -253,13 +253,14 @@ void mSDLPlayerLoadConfig(struct mSDLPlayer* context, const struct Configuration
|
||||||
if (context->joystick) {
|
if (context->joystick) {
|
||||||
mInputMapLoad(context->bindings, SDL_BINDING_BUTTON, config);
|
mInputMapLoad(context->bindings, SDL_BINDING_BUTTON, config);
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
#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
|
#else
|
||||||
const char* name = SDL_JoystickName(SDL_JoystickIndex(context->joystick->joystick));
|
const char* name = SDL_JoystickName(SDL_JoystickIndex(context->joystick->joystick));
|
||||||
#endif
|
|
||||||
if (!name) {
|
if (!name) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
mInputProfileLoad(context->bindings, SDL_BINDING_BUTTON, config, name);
|
mInputProfileLoad(context->bindings, SDL_BINDING_BUTTON, config, name);
|
||||||
|
|
||||||
const char* value;
|
const char* value;
|
||||||
|
@ -307,13 +308,14 @@ void mSDLPlayerLoadConfig(struct mSDLPlayer* context, const struct Configuration
|
||||||
void mSDLPlayerSaveConfig(const struct mSDLPlayer* context, struct Configuration* config) {
|
void mSDLPlayerSaveConfig(const struct mSDLPlayer* context, struct Configuration* config) {
|
||||||
if (context->joystick) {
|
if (context->joystick) {
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
#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
|
#else
|
||||||
const char* name = SDL_JoystickName(SDL_JoystickIndex(context->joystick->joystick));
|
const char* name = SDL_JoystickName(SDL_JoystickIndex(context->joystick->joystick));
|
||||||
#endif
|
|
||||||
if (!name) {
|
if (!name) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
char value[16];
|
char value[16];
|
||||||
snprintf(value, sizeof(value), "%i", context->rotation.axisX);
|
snprintf(value, sizeof(value), "%i", context->rotation.axisX);
|
||||||
mInputSetCustomValue(config, "gba", SDL_BINDING_BUTTON, "tiltAxisX", value, name);
|
mInputSetCustomValue(config, "gba", SDL_BINDING_BUTTON, "tiltAxisX", value, name);
|
||||||
|
@ -354,14 +356,15 @@ void mSDLUpdateJoysticks(struct mSDLEvents* events, const struct Configuration*
|
||||||
joystick->haptic = SDL_HapticOpenFromJoystick(joystick->joystick);
|
joystick->haptic = SDL_HapticOpenFromJoystick(joystick->joystick);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char* joystickName;
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
|
||||||
joystickName = SDL_JoystickName(joystick->joystick);
|
|
||||||
#else
|
|
||||||
joystickName = SDL_JoystickName(SDL_JoystickIndex(joystick->joystick));
|
|
||||||
#endif
|
|
||||||
size_t i;
|
size_t i;
|
||||||
if (joystickName) {
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
|
char joystickName[34] = {0};
|
||||||
|
SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick->joystick), joystickName, sizeof(joystickName));
|
||||||
|
#else
|
||||||
|
const char* joystickName = SDL_JoystickName(SDL_JoystickIndex(joystick->joystick));
|
||||||
|
if (joystickName)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
for (i = 0; (int) i < events->playersAttached; ++i) {
|
for (i = 0; (int) i < events->playersAttached; ++i) {
|
||||||
if (events->players[i]->joystick) {
|
if (events->players[i]->joystick) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -48,15 +48,11 @@ LicenseFile={#BinDir}\LICENSE.txt
|
||||||
#define IsRelease = 'no'
|
#define IsRelease = 'no'
|
||||||
AppVerName={#AppName} {#VersionString} (Development build)
|
AppVerName={#AppName} {#VersionString} (Development build)
|
||||||
#endif
|
#endif
|
||||||
#if '{#WinBits}' == '64'
|
|
||||||
ArchitecturesInstallIn64BitMode=x64
|
|
||||||
ArchitecturesAllows=x64
|
|
||||||
#endif
|
|
||||||
OutputBaseFilename={#AppName}-setup-{#CleanVersionString}-win{#WinBits}
|
OutputBaseFilename={#AppName}-setup-{#CleanVersionString}-win{#WinBits}
|
||||||
UsePreviousLanguage=False
|
UsePreviousLanguage=False
|
||||||
DisableWelcomePage=False
|
DisableWelcomePage=False
|
||||||
VersionInfoDescription={#AppName} is an open-source Game Boy Advance emulator
|
VersionInfoDescription={#AppName} is an open-source Game Boy Advance emulator
|
||||||
VersionInfoCopyright=© 2013–2018 Jeffrey Pfau
|
VersionInfoCopyright=© 2013–2019 Jeffrey Pfau
|
||||||
VersionInfoProductName={#AppName}
|
VersionInfoProductName={#AppName}
|
||||||
VersionInfoVersion={#AppVer}
|
VersionInfoVersion={#AppVer}
|
||||||
Compression=lzma2/ultra64
|
Compression=lzma2/ultra64
|
||||||
|
@ -64,6 +60,8 @@ SolidCompression=True
|
||||||
VersionInfoTextVersion={#AppVer}
|
VersionInfoTextVersion={#AppVer}
|
||||||
VersionInfoProductVersion={#AppVer}
|
VersionInfoProductVersion={#AppVer}
|
||||||
VersionInfoProductTextVersion={#AppVer}
|
VersionInfoProductTextVersion={#AppVer}
|
||||||
|
ArchitecturesInstallIn64BitMode=x64
|
||||||
|
ArchitecturesAllowed=x86 x64
|
||||||
|
|
||||||
[Languages]
|
[Languages]
|
||||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||||
|
|
Loading…
Reference in New Issue