mirror of https://github.com/mgba-emu/mgba.git
Merge branch 'master' into medusa
This commit is contained in:
commit
e654c188f9
|
@ -7,8 +7,8 @@ os: linux
|
|||
env:
|
||||
- DOCKER_TAG=ubuntu:xenial
|
||||
- DOCKER_TAG=ubuntu:bionic
|
||||
- DOCKER_TAG=ubuntu:cosmic
|
||||
- DOCKER_TAG=ubuntu:disco
|
||||
- DOCKER_TAG=ubuntu:eoan
|
||||
- DOCKER_TAG=3ds
|
||||
- DOCKER_TAG=wii
|
||||
- DOCKER_TAG=vita
|
||||
|
|
58
CHANGES
58
CHANGES
|
@ -41,6 +41,7 @@ Features:
|
|||
- Qt: Add export button for tile view (closes mgba.io/i/1507)
|
||||
- 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
|
||||
|
@ -48,39 +49,21 @@ Emulation fixes:
|
|||
- 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)
|
||||
- GBA Video: Fix wrapped sprite mosaic clamping (fixes mgba.io/i/1432)
|
||||
- GBA Memory: Fix STM to VRAM (fixes mgba.io/i/1430)
|
||||
- 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 Video: Increment BCPS/OCPS even in mode 3 (fixes mgba.io/i/1462)
|
||||
- GB Audio: Deschedule channel 3 when disabled (fixes mgba.io/i/1463)
|
||||
- GB Audio: Deschedule channel 1 when disabled by sweep (fixes mgba.io/i/1467)
|
||||
- GBA Memory: Fix STM/LDM to invalid VRAM
|
||||
- GB: Fix savedata initialization (fixes mgba.io/i/1473, mgba.io/i/1478)
|
||||
- GB Memory: Better emulate 0xFEA0 region on DMG, MGB and AGB
|
||||
- GB Printer: Reset printer buffer index after printing
|
||||
- GB Video: Fix mode 0 window edge case (fixes mgba.io/i/1519)
|
||||
- GBA Audio: Fix channel 4 aliasing (fixes mgba.io/i/1265)
|
||||
- GB Audio: Improve channel 4 supersampling
|
||||
- GB Audio: Fix channel 4 volume (fixes mgba.io/i/1529)
|
||||
Other fixes:
|
||||
- Qt: Fix some Qt display driver race conditions
|
||||
- Core: Improved lockstep driver reliability (Le Hoang Quyen)
|
||||
- Switch: Fix threading-related crash on second launch
|
||||
- Qt: Fix FPS target maxing out at 59.727 (fixes mgba.io/i/1421)
|
||||
- Core: Fix crashes if core directories aren't set
|
||||
- Qt: Fix menu bar staying hidden in full screen (fixes mgba.io/i/317)
|
||||
- GB SIO: Fix lockstep failing games aren't reloaded
|
||||
- Core: Fix crash when exiting game with cheats loaded
|
||||
- GBA Cheats: Fix PARv3 Thumb hooks
|
||||
- mGUI: Fix crash if last loaded ROM directory disappears (fixes mgba.io/i/1466)
|
||||
- Libretro: Fix crash changing allowing opposing directions (hhromic)
|
||||
- Qt: Fix race conditions initializing GDB stub
|
||||
- GBA: Set up GPIO mapping on null and ELF ROM regions (fixes mgba.io/i/1481)
|
||||
- GBA Cheats: Fix value incrementing in CB slide codes (fixes mgba.io/i/1501)
|
||||
- Qt: Only show emulator restart warning once per settings saving
|
||||
- Qt: Improve cheat view UX
|
||||
- GB: Fix SGB controller incrementing (fixes mgba.io/i/1104)
|
||||
- FFmpeg: Drain recording buffers
|
||||
- Shaders: Fix gba-color shader resolution (fixes mgba.io/i/1435)
|
||||
Misc:
|
||||
- GBA Savedata: EEPROM performance fixes
|
||||
- GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash
|
||||
|
@ -100,16 +83,47 @@ Misc:
|
|||
- Qt: Add native FPS button to settings view
|
||||
- Qt: Improve sync code
|
||||
- Switch: Dynamic display resizing
|
||||
- Qt: Make mute menu option also toggle fast-forward mute (fixes mgba.io/i/1424)
|
||||
- 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: Show error message if file failed to load
|
||||
- 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
|
||||
|
||||
0.7.3: (2019-09-15)
|
||||
Emulation fixes:
|
||||
- GB: Fix savedata initialization (fixes mgba.io/i/1473, mgba.io/i/1478)
|
||||
- GB: Fix SGB controller incrementing (fixes mgba.io/i/1104)
|
||||
- GB Audio: Improve channel 4 supersampling
|
||||
- GB Printer: Reset printer buffer index after printing
|
||||
- GB Audio: Deschedule channel 3 when disabled (fixes mgba.io/i/1463)
|
||||
- GB Audio: Deschedule channel 1 when disabled by sweep (fixes mgba.io/i/1467)
|
||||
- GB Video: Increment BCPS/OCPS even in mode 3 (fixes mgba.io/i/1462)
|
||||
- GBA Memory: Fix STM to VRAM (fixes mgba.io/i/1430)
|
||||
- GBA Memory: Fix STM/LDM to invalid VRAM
|
||||
- GBA Video: Fix wrapped sprite mosaic clamping (fixes mgba.io/i/1432)
|
||||
- GBA Audio: Fix channel 4 aliasing (fixes mgba.io/i/1265)
|
||||
Other fixes:
|
||||
- Core: Fix crashes if core directories aren't set
|
||||
- Core: Fix crash when exiting game with cheats loaded
|
||||
- GBA: Set up GPIO mapping on null and ELF ROM regions (fixes mgba.io/i/1481)
|
||||
- GBA Cheats: Fix PARv3 Thumb hooks
|
||||
- GBA Cheats: Fix value incrementing in CB slide codes (fixes mgba.io/i/1501)
|
||||
- Qt: Fix FPS target maxing out at 59.727 (fixes mgba.io/i/1421)
|
||||
- Qt: Cap audio buffer size to 8192 (fixes mgba.io/i/1433)
|
||||
- Qt: Fix race conditions initializing GDB stub
|
||||
- Qt: Improve cheat view UX
|
||||
- Libretro: Fix crash changing allowing opposing directions (hhromic)
|
||||
- mGUI: Fix crash if last loaded ROM directory disappears (fixes mgba.io/i/1466)
|
||||
- Switch: Fix threading-related crash on second launch
|
||||
Misc:
|
||||
- Qt: Make mute menu option also toggle fast-forward mute (fixes mgba.io/i/1424)
|
||||
- Qt: Show error message if file failed to load
|
||||
|
||||
0.7.2: (2019-05-25)
|
||||
Emulation fixes:
|
||||
|
|
|
@ -7,6 +7,8 @@ passes=1
|
|||
[pass.0]
|
||||
fragmentShader=gba-color.fs
|
||||
blend=1
|
||||
width=-1
|
||||
height=-1
|
||||
|
||||
[pass.0.uniform.darken_screen]
|
||||
type=float
|
||||
|
|
|
@ -770,7 +770,7 @@ static int32_t _updateSquareChannel(struct GBAudioSquareChannel* ch) {
|
|||
|
||||
static int16_t _coalesceNoiseChannel(struct GBAudioNoiseChannel* ch) {
|
||||
if (!ch->nSamples) {
|
||||
return ch->sample;
|
||||
return ch->sample << 3;
|
||||
}
|
||||
// TODO keep track of timing
|
||||
int16_t sample = (ch->samples << 3) / ch->nSamples;
|
||||
|
|
|
@ -45,7 +45,7 @@ static const struct mCoreChannelInfo _GBAudioChannels[] = {
|
|||
|
||||
static const struct mCoreMemoryBlock _GBMemoryBlocks[] = {
|
||||
{ -1, "mem", "All", "All", 0, 0x10000, 0x10000, mCORE_MEMORY_VIRTUAL },
|
||||
{ GB_REGION_CART_BANK0, "cart0", "ROM Bank", "Game Pak (32kiB)", GB_BASE_CART_BANK0, GB_SIZE_CART_BANK0 * 2, 0x800000, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED, 511 },
|
||||
{ GB_REGION_CART_BANK0, "cart0", "ROM Bank", "Game Pak (32kiB)", GB_BASE_CART_BANK0, GB_BASE_CART_BANK0 + GB_SIZE_CART_BANK0 * 2, 0x800000, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED, 511, GB_BASE_CART_BANK0 + GB_SIZE_CART_BANK0 },
|
||||
{ GB_REGION_VRAM, "vram", "VRAM", "Video RAM (8kiB)", GB_BASE_VRAM, GB_BASE_VRAM + GB_SIZE_VRAM, GB_SIZE_VRAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED },
|
||||
{ GB_REGION_EXTERNAL_RAM, "sram", "SRAM", "External RAM (8kiB)", GB_BASE_EXTERNAL_RAM, GB_BASE_EXTERNAL_RAM + GB_SIZE_EXTERNAL_RAM, GB_SIZE_EXTERNAL_RAM * 4, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED, 3 },
|
||||
{ GB_REGION_WORKING_RAM_BANK0, "wram", "WRAM", "Working RAM (8kiB)", GB_BASE_WORKING_RAM_BANK0, GB_BASE_WORKING_RAM_BANK0 + GB_SIZE_WORKING_RAM_BANK0 * 2 , GB_SIZE_WORKING_RAM_BANK0 * 2, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED },
|
||||
|
@ -56,10 +56,10 @@ static const struct mCoreMemoryBlock _GBMemoryBlocks[] = {
|
|||
|
||||
static const struct mCoreMemoryBlock _GBCMemoryBlocks[] = {
|
||||
{ -1, "mem", "All", "All", 0, 0x10000, 0x10000, mCORE_MEMORY_VIRTUAL },
|
||||
{ GB_REGION_CART_BANK0, "cart0", "ROM Bank", "Game Pak (32kiB)", GB_BASE_CART_BANK0, GB_SIZE_CART_BANK0 * 2, 0x800000, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED, 511 },
|
||||
{ GB_REGION_CART_BANK0, "cart0", "ROM Bank", "Game Pak (32kiB)", GB_BASE_CART_BANK0, GB_BASE_CART_BANK0 + GB_SIZE_CART_BANK0 * 2, 0x800000, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED, 511, GB_BASE_CART_BANK0 + GB_SIZE_CART_BANK0 },
|
||||
{ GB_REGION_VRAM, "vram", "VRAM", "Video RAM (8kiB)", GB_BASE_VRAM, GB_BASE_VRAM + GB_SIZE_VRAM, GB_SIZE_VRAM * 2, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED, 1 },
|
||||
{ GB_REGION_EXTERNAL_RAM, "sram", "SRAM", "External RAM (8kiB)", GB_BASE_EXTERNAL_RAM, GB_BASE_EXTERNAL_RAM + GB_SIZE_EXTERNAL_RAM, GB_SIZE_EXTERNAL_RAM * 4, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED, 3 },
|
||||
{ GB_REGION_WORKING_RAM_BANK0, "wram", "WRAM", "Working RAM (8kiB)", GB_BASE_WORKING_RAM_BANK0, GB_BASE_WORKING_RAM_BANK0 + GB_SIZE_WORKING_RAM_BANK0 * 2, GB_SIZE_WORKING_RAM_BANK0 * 8, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED, 7 },
|
||||
{ GB_REGION_WORKING_RAM_BANK0, "wram", "WRAM", "Working RAM (8kiB)", GB_BASE_WORKING_RAM_BANK0, GB_BASE_WORKING_RAM_BANK0 + GB_SIZE_WORKING_RAM_BANK0 * 2, GB_SIZE_WORKING_RAM_BANK0 * 8, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED, 7, GB_BASE_WORKING_RAM_BANK0 + GB_SIZE_WORKING_RAM_BANK0 },
|
||||
{ GB_BASE_OAM, "oam", "OAM", "OBJ Attribute Memory", GB_BASE_OAM, GB_BASE_OAM + GB_SIZE_OAM, GB_SIZE_OAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED },
|
||||
{ GB_BASE_IO, "io", "MMIO", "Memory-Mapped I/O", GB_BASE_IO, GB_BASE_IO + GB_SIZE_IO, GB_SIZE_IO, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED },
|
||||
{ GB_BASE_HRAM, "hram", "HRAM", "High RAM", GB_BASE_HRAM, GB_BASE_HRAM + GB_SIZE_HRAM, GB_SIZE_HRAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED },
|
||||
|
|
|
@ -6,7 +6,7 @@ const uint8_t hleBios[SIZE_BIOS] = {
|
|||
0x06, 0x00, 0x00, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x0b, 0x00, 0x00, 0xea,
|
||||
0xfe, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x00, 0x00, 0xa0, 0xe1,
|
||||
0x2c, 0x00, 0x00, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x02, 0x03, 0xa0, 0xe3,
|
||||
0x03, 0x10, 0xd0, 0xe5, 0xea, 0x00, 0x51, 0xe3, 0xec, 0x01, 0x9f, 0x15,
|
||||
0x03, 0x10, 0xd0, 0xe5, 0xea, 0x00, 0x51, 0xe3, 0xf8, 0x01, 0x9f, 0x15,
|
||||
0x10, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x29, 0xe1,
|
||||
0x00, 0x00, 0x5d, 0xe3, 0x01, 0xd3, 0xa0, 0x03, 0x20, 0xd0, 0x4d, 0x02,
|
||||
0x00, 0x58, 0x2d, 0xe9, 0x02, 0xb0, 0x5e, 0xe5, 0x9c, 0xc0, 0xa0, 0xe3,
|
||||
|
@ -20,7 +20,7 @@ const uint8_t hleBios[SIZE_BIOS] = {
|
|||
0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00,
|
||||
0xc8, 0x01, 0x00, 0x00, 0x0f, 0x50, 0x2d, 0xe9, 0x01, 0x03, 0xa0, 0xe3,
|
||||
0xd4, 0x01, 0x00, 0x00, 0x0f, 0x50, 0x2d, 0xe9, 0x01, 0x03, 0xa0, 0xe3,
|
||||
0x00, 0xe0, 0x8f, 0xe2, 0x04, 0xf0, 0x10, 0xe5, 0x0f, 0x50, 0xbd, 0xe8,
|
||||
0x04, 0xf0, 0x5e, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x5e, 0xe5,
|
||||
0x01, 0x00, 0xa0, 0xe3, 0x01, 0x10, 0xa0, 0xe3, 0x0c, 0x40, 0x2d, 0xe9,
|
||||
|
@ -29,18 +29,19 @@ const uint8_t hleBios[SIZE_BIOS] = {
|
|||
0x01, 0x30, 0xc3, 0xe1, 0xb8, 0x30, 0x4c, 0xe1, 0x01, 0x03, 0xcc, 0xe5,
|
||||
0x08, 0x02, 0xcc, 0xe5, 0xb8, 0x30, 0x5c, 0xe1, 0x01, 0x30, 0x13, 0xe0,
|
||||
0x01, 0x30, 0x23, 0x10, 0xb8, 0x30, 0x4c, 0x11, 0x08, 0x22, 0xcc, 0xe5,
|
||||
0xf7, 0xff, 0xff, 0x0a, 0x0c, 0x80, 0xbd, 0xe8, 0x00, 0x40, 0x2d, 0xe9,
|
||||
0x02, 0x36, 0xa0, 0xe1, 0x01, 0x04, 0x12, 0xe3, 0x0f, 0x00, 0x00, 0x0a,
|
||||
0x01, 0x03, 0x12, 0xe3, 0x05, 0x00, 0x00, 0x0a, 0x23, 0x35, 0x81, 0xe0,
|
||||
0x04, 0x00, 0xb0, 0xe8, 0x03, 0x00, 0x51, 0xe1, 0x04, 0x00, 0xa1, 0xb8,
|
||||
0xfc, 0xff, 0xff, 0xba, 0x14, 0x00, 0x00, 0xea, 0x01, 0x00, 0xc0, 0xe3,
|
||||
0x01, 0x10, 0xc1, 0xe3, 0xa3, 0x35, 0x81, 0xe0, 0xb0, 0x20, 0xd0, 0xe1,
|
||||
0x03, 0x00, 0x51, 0xe1, 0xb2, 0x20, 0xc1, 0xb0, 0xfc, 0xff, 0xff, 0xba,
|
||||
0x0c, 0x00, 0x00, 0xea, 0x01, 0x03, 0x12, 0xe3, 0x05, 0x00, 0x00, 0x0a,
|
||||
0x23, 0x35, 0x81, 0xe0, 0x03, 0x00, 0x51, 0xe1, 0x04, 0x00, 0xb0, 0xb8,
|
||||
0x04, 0x00, 0xa1, 0xb8, 0xfb, 0xff, 0xff, 0xba, 0x04, 0x00, 0x00, 0xea,
|
||||
0xa3, 0x35, 0x81, 0xe0, 0x03, 0x00, 0x51, 0xe1, 0xb2, 0x20, 0xd0, 0xb0,
|
||||
0xb2, 0x20, 0xc1, 0xb0, 0xfb, 0xff, 0xff, 0xba, 0x00, 0x80, 0xbd, 0xe8,
|
||||
0xf7, 0xff, 0xff, 0x0a, 0x0c, 0x80, 0xbd, 0xe8, 0x30, 0x40, 0x2d, 0xe9,
|
||||
0x02, 0x46, 0xa0, 0xe1, 0x00, 0xc0, 0xa0, 0xe1, 0x01, 0x50, 0xa0, 0xe1,
|
||||
0x01, 0x04, 0x12, 0xe3, 0x0f, 0x00, 0x00, 0x0a, 0x01, 0x03, 0x12, 0xe3,
|
||||
0x05, 0x00, 0x00, 0x0a, 0x24, 0x45, 0x85, 0xe0, 0x08, 0x00, 0xbc, 0xe8,
|
||||
0x04, 0x00, 0x55, 0xe1, 0x08, 0x00, 0xa5, 0xb8, 0xfc, 0xff, 0xff, 0xba,
|
||||
0x14, 0x00, 0x00, 0xea, 0x01, 0xc0, 0xcc, 0xe3, 0x01, 0x50, 0xc5, 0xe3,
|
||||
0xa4, 0x45, 0x85, 0xe0, 0xb0, 0x30, 0xdc, 0xe1, 0x04, 0x00, 0x55, 0xe1,
|
||||
0xb2, 0x30, 0xc5, 0xb0, 0xfc, 0xff, 0xff, 0xba, 0x0c, 0x00, 0x00, 0xea,
|
||||
0x01, 0x03, 0x12, 0xe3, 0x05, 0x00, 0x00, 0x0a, 0x24, 0x45, 0x85, 0xe0,
|
||||
0x04, 0x00, 0x55, 0xe1, 0x08, 0x00, 0xbc, 0xb8, 0x08, 0x00, 0xa5, 0xb8,
|
||||
0xfb, 0xff, 0xff, 0xba, 0x04, 0x00, 0x00, 0xea, 0xa4, 0x45, 0x85, 0xe0,
|
||||
0x04, 0x00, 0x55, 0xe1, 0xb2, 0x30, 0xdc, 0xb0, 0xb2, 0x30, 0xc5, 0xb0,
|
||||
0xfb, 0xff, 0xff, 0xba, 0x17, 0x3e, 0xa0, 0xe3, 0x30, 0x80, 0xbd, 0xe8,
|
||||
0xf0, 0x47, 0x2d, 0xe9, 0x01, 0x04, 0x12, 0xe3, 0x02, 0x36, 0xa0, 0xe1,
|
||||
0x23, 0x25, 0x81, 0xe0, 0x0b, 0x00, 0x00, 0x0a, 0x00, 0x30, 0x90, 0xe5,
|
||||
0x03, 0x40, 0xa0, 0xe1, 0x03, 0x50, 0xa0, 0xe1, 0x03, 0x60, 0xa0, 0xe1,
|
||||
|
|
|
@ -15,4 +15,4 @@ hle-bios.c: hle-bios.bin
|
|||
echo >> $@
|
||||
echo '#include <mgba/internal/gba/memory.h>' >> $@
|
||||
echo >> $@
|
||||
xxd -i $< | sed -e 's/unsigned char hle_bios_bin\[\]/const uint8_t hleBios[SIZE_BIOS]/' | grep -v hle_bios_bin_len >> $@
|
||||
xxd -i $< | sed -e 's/unsigned char hle_bios_bin\[\]/const uint8_t hleBios[SIZE_BIOS]/' -e 's/^ \+/\t/' | grep -v hle_bios_bin_len >> $@
|
||||
|
|
|
@ -65,7 +65,7 @@ swiTable:
|
|||
.word ArcTan2
|
||||
.word CpuSet
|
||||
.word CpuFastSet
|
||||
# ... The rest of this table isn't needed if the rest aren't implemented
|
||||
@ ... The rest of this table isn't needed if the rest aren't implemented
|
||||
|
||||
irqBase:
|
||||
stmfd sp!, {r0-r3, r12, lr}
|
||||
|
@ -83,7 +83,7 @@ mov r1, #1
|
|||
IntrWait:
|
||||
stmfd sp!, {r2-r3, lr}
|
||||
mov r12, #0x04000000
|
||||
# See if we want to return immediately
|
||||
@ See if we want to return immediately
|
||||
cmp r0, #0
|
||||
mov r0, #0
|
||||
mov r2, #1
|
||||
|
@ -91,11 +91,11 @@ beq 1f
|
|||
ldrh r3, [r12, #-8]
|
||||
bic r3, r1
|
||||
strh r3, [r12, #-8]
|
||||
# Halt
|
||||
@ Halt
|
||||
0:
|
||||
strb r0, [r12, #0x301]
|
||||
1:
|
||||
# Check which interrupts were acknowledged
|
||||
@ Check which interrupts were acknowledged
|
||||
strb r0, [r12, #0x208]
|
||||
ldrh r3, [r12, #-8]
|
||||
ands r3, r1
|
||||
|
@ -106,54 +106,57 @@ beq 0b
|
|||
ldmfd sp!, {r2-r3, pc}
|
||||
|
||||
CpuSet:
|
||||
stmfd sp!, {lr}
|
||||
mov r3, r2, lsl #12
|
||||
stmfd sp!, {r4, r5, lr}
|
||||
mov r4, r2, lsl #12
|
||||
mov r12, r0
|
||||
mov r5, r1
|
||||
tst r2, #0x01000000
|
||||
beq 0f
|
||||
# Fill
|
||||
@ Fill
|
||||
tst r2, #0x04000000
|
||||
beq 1f
|
||||
# Word
|
||||
add r3, r1, r3, lsr #10
|
||||
ldmia r0!, {r2}
|
||||
@ Word
|
||||
add r4, r5, r4, lsr #10
|
||||
ldmia r12!, {r3}
|
||||
2:
|
||||
cmp r1, r3
|
||||
stmltia r1!, {r2}
|
||||
cmp r5, r4
|
||||
stmltia r5!, {r3}
|
||||
blt 2b
|
||||
b 3f
|
||||
# Halfword
|
||||
@ Halfword
|
||||
1:
|
||||
bic r0, #1
|
||||
bic r1, #1
|
||||
add r3, r1, r3, lsr #11
|
||||
ldrh r2, [r0]
|
||||
bic r12, #1
|
||||
bic r5, #1
|
||||
add r4, r5, r4, lsr #11
|
||||
ldrh r3, [r12]
|
||||
2:
|
||||
cmp r1, r3
|
||||
strlth r2, [r1], #2
|
||||
cmp r5, r4
|
||||
strlth r3, [r5], #2
|
||||
blt 2b
|
||||
b 3f
|
||||
# Copy
|
||||
@ Copy
|
||||
0:
|
||||
tst r2, #0x04000000
|
||||
beq 1f
|
||||
# Word
|
||||
add r3, r1, r3, lsr #10
|
||||
@ Word
|
||||
add r4, r5, r4, lsr #10
|
||||
2:
|
||||
cmp r1, r3
|
||||
ldmltia r0!, {r2}
|
||||
stmltia r1!, {r2}
|
||||
cmp r5, r4
|
||||
ldmltia r12!, {r3}
|
||||
stmltia r5!, {r3}
|
||||
blt 2b
|
||||
b 3f
|
||||
# Halfword
|
||||
@ Halfword
|
||||
1:
|
||||
add r3, r1, r3, lsr #11
|
||||
add r4, r5, r4, lsr #11
|
||||
2:
|
||||
cmp r1, r3
|
||||
ldrlth r2, [r0], #2
|
||||
strlth r2, [r1], #2
|
||||
cmp r5, r4
|
||||
ldrlth r3, [r12], #2
|
||||
strlth r3, [r5], #2
|
||||
blt 2b
|
||||
3:
|
||||
ldmfd sp!, {pc}
|
||||
mov r3, #0x170 @ Match official BIOS's clobbered r3
|
||||
ldmfd sp!, {r4, r5, pc}
|
||||
|
||||
CpuFastSet:
|
||||
stmfd sp!, {r4-r10, lr}
|
||||
|
@ -161,7 +164,7 @@ tst r2, #0x01000000
|
|||
mov r3, r2, lsl #12
|
||||
add r2, r1, r3, lsr #10
|
||||
beq 0f
|
||||
# Fill
|
||||
@ Fill
|
||||
ldr r3, [r0]
|
||||
mov r4, r3
|
||||
mov r5, r3
|
||||
|
@ -175,7 +178,7 @@ cmp r1, r2
|
|||
stmltia r1!, {r3-r10}
|
||||
blt 1b
|
||||
b 2f
|
||||
# Copy
|
||||
@ Copy
|
||||
0:
|
||||
cmp r1, r2
|
||||
ldmltia r0!, {r3-r10}
|
||||
|
|
|
@ -178,6 +178,15 @@ static void mGLES2ContextSetDimensions(struct VideoBackend* v, unsigned width, u
|
|||
#else
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
#endif
|
||||
|
||||
size_t n;
|
||||
for (n = 0; n < context->nShaders; ++n) {
|
||||
if (context->shaders[n].width < 0 || context->shaders[n].height < 0) {
|
||||
context->shaders[n].dirty = true;
|
||||
}
|
||||
}
|
||||
context->initialShader.dirty = true;
|
||||
context->interframeShader.dirty = true;
|
||||
}
|
||||
|
||||
static void mGLES2ContextDeinit(struct VideoBackend* v) {
|
||||
|
@ -191,6 +200,7 @@ static void mGLES2ContextDeinit(struct VideoBackend* v) {
|
|||
}
|
||||
|
||||
static void mGLES2ContextResized(struct VideoBackend* v, unsigned w, unsigned h) {
|
||||
struct mGLES2Context* context = (struct mGLES2Context*) v;
|
||||
unsigned drawW = w;
|
||||
unsigned drawH = h;
|
||||
if (v->lockAspectRatio) {
|
||||
|
@ -208,6 +218,12 @@ static void mGLES2ContextResized(struct VideoBackend* v, unsigned w, unsigned h)
|
|||
drawH -= drawH % v->height;
|
||||
}
|
||||
}
|
||||
size_t n;
|
||||
for (n = 0; n < context->nShaders; ++n) {
|
||||
if (context->shaders[n].width == 0 || context->shaders[n].height == 0) {
|
||||
context->shaders[n].dirty = true;
|
||||
}
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glViewport((w - drawW) / 2, (h - drawH) / 2, drawW, drawH);
|
||||
}
|
||||
|
@ -221,8 +237,6 @@ static void mGLES2ContextClear(struct VideoBackend* v) {
|
|||
|
||||
void _drawShader(struct mGLES2Context* context, struct mGLES2Shader* shader) {
|
||||
GLint viewport[4];
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, shader->fbo);
|
||||
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
int drawW = shader->width;
|
||||
int drawH = shader->height;
|
||||
|
@ -246,6 +260,19 @@ void _drawShader(struct mGLES2Context* context, struct mGLES2Shader* shader) {
|
|||
drawW -= drawW % context->d.width;
|
||||
drawH -= drawH % context->d.height;
|
||||
}
|
||||
|
||||
if (shader->dirty) {
|
||||
if (shader->tex && (shader->width <= 0 || shader->height <= 0)) {
|
||||
GLint oldTex;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTex);
|
||||
glBindTexture(GL_TEXTURE_2D, shader->tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, drawW, drawH, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, oldTex);
|
||||
}
|
||||
shader->dirty = false;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, shader->fbo);
|
||||
glViewport(padW, padH, drawW, drawH);
|
||||
if (shader->blend) {
|
||||
glEnable(GL_BLEND);
|
||||
|
@ -256,14 +283,6 @@ void _drawShader(struct mGLES2Context* context, struct mGLES2Shader* shader) {
|
|||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
if (shader->tex && (shader->width <= 0 || shader->height <= 0)) {
|
||||
GLint oldTex;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTex);
|
||||
glBindTexture(GL_TEXTURE_2D, shader->tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, drawW, drawH, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, oldTex);
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, shader->filter ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shader->filter ? GL_LINEAR : GL_NEAREST);
|
||||
glUseProgram(shader->program);
|
||||
|
@ -340,6 +359,7 @@ void mGLES2ContextDrawFrame(struct VideoBackend* v) {
|
|||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
|
||||
context->finalShader.filter = v->filter;
|
||||
context->finalShader.dirty = true;
|
||||
_drawShader(context, &context->initialShader);
|
||||
if (v->interframeBlending) {
|
||||
context->interframeShader.blend = true;
|
||||
|
@ -404,6 +424,7 @@ void mGLES2ShaderInit(struct mGLES2Shader* shader, const char* vs, const char* f
|
|||
shader->integerScaling = integerScaling;
|
||||
shader->filter = false;
|
||||
shader->blend = false;
|
||||
shader->dirty = true;
|
||||
shader->uniforms = uniforms;
|
||||
shader->nUniforms = nUniforms;
|
||||
glGenFramebuffers(1, &shader->fbo);
|
||||
|
|
|
@ -60,6 +60,7 @@ struct mGLES2Shader {
|
|||
bool integerScaling;
|
||||
bool filter;
|
||||
bool blend;
|
||||
bool dirty;
|
||||
GLuint tex;
|
||||
GLuint fbo;
|
||||
GLuint vao;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
using namespace QGBA;
|
||||
|
||||
ArchiveInspector::ArchiveInspector(const QString& filename, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
connect(m_ui.archiveView, &LibraryController::doneLoading, [this]() {
|
||||
|
|
|
@ -83,6 +83,7 @@ set(SOURCE_FILES
|
|||
LogConfigModel.cpp
|
||||
LogView.cpp
|
||||
MapView.cpp
|
||||
MemoryDump.cpp
|
||||
MemoryModel.cpp
|
||||
MemorySearch.cpp
|
||||
MemoryView.cpp
|
||||
|
@ -129,6 +130,7 @@ set(UI_FILES
|
|||
LoadSaveState.ui
|
||||
LogView.ui
|
||||
MapView.ui
|
||||
MemoryDump.ui
|
||||
MemorySearch.ui
|
||||
MemoryView.ui
|
||||
ObjView.ui
|
||||
|
|
|
@ -1024,7 +1024,7 @@ const QList<IOViewer::RegisterDescription>& IOViewer::registerDescriptions() {
|
|||
}
|
||||
|
||||
IOViewer::IOViewer(std::shared_ptr<CoreController> controller, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
|
||||
, m_controller(controller)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
/* Copyright (c) 2013-2019 Jeffrey Pfau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "MemoryDump.h"
|
||||
|
||||
#include "CoreController.h"
|
||||
#include "GBAApp.h"
|
||||
#include "LogController.h"
|
||||
|
||||
using namespace QGBA;
|
||||
|
||||
MemoryDump::MemoryDump(std::shared_ptr<CoreController> controller, QWidget* parent)
|
||||
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
|
||||
, m_controller(controller)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
connect(this, &QDialog::accepted, this, &MemoryDump::save);
|
||||
}
|
||||
|
||||
void MemoryDump::save() {
|
||||
QString filename = GBAApp::app()->getSaveFileName(this, tr("Save memory region"));
|
||||
if (filename.isNull()) {
|
||||
return;
|
||||
}
|
||||
QFile outfile(filename);
|
||||
if (!outfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||
LOG(QT, WARN) << tr("Failed to open output file: %1").arg(filename);
|
||||
return;
|
||||
}
|
||||
QByteArray out(serialize());
|
||||
outfile.write(out);
|
||||
}
|
||||
|
||||
void MemoryDump::setAddress(uint32_t start) {
|
||||
m_ui.address->setValue(start);
|
||||
}
|
||||
|
||||
void MemoryDump::setSegment(int seg) {
|
||||
m_ui.segment->setValue(seg);
|
||||
}
|
||||
|
||||
void MemoryDump::setByteCount(uint32_t count) {
|
||||
m_ui.bytes->setValue(count);
|
||||
}
|
||||
|
||||
QByteArray MemoryDump::serialize() {
|
||||
CoreController::Interrupter interrupter(m_controller);
|
||||
mCore* core = m_controller->thread()->core;
|
||||
const mCoreMemoryBlock* blocks;
|
||||
size_t nBlocks = core->listMemoryBlocks(core, &blocks);
|
||||
|
||||
int size = m_ui.bytes->value();
|
||||
uint32_t start = m_ui.address->value();
|
||||
int segment = m_ui.segment->value();
|
||||
bool spanSegments = m_ui.spanSegments->isChecked();
|
||||
|
||||
QByteArray mem;
|
||||
while (size) {
|
||||
const mCoreMemoryBlock* bestMatch = NULL;
|
||||
const char* block = NULL;
|
||||
size_t blockSize = 0;
|
||||
for (size_t i = 0; i < nBlocks; ++i) {
|
||||
if (blocks[i].end <= start) {
|
||||
continue;
|
||||
}
|
||||
if (blocks[i].start > start) {
|
||||
continue;
|
||||
}
|
||||
block = static_cast<const char*>(core->getMemoryBlock(core, blocks[i].id, &blockSize));
|
||||
if (block) {
|
||||
bestMatch = &blocks[i];
|
||||
break;
|
||||
} else if (!bestMatch) {
|
||||
bestMatch = &blocks[i];
|
||||
blockSize = 0;
|
||||
}
|
||||
}
|
||||
if (!spanSegments) {
|
||||
blockSize = bestMatch->end - bestMatch->start;
|
||||
} else if (!blockSize) {
|
||||
blockSize = bestMatch->size;
|
||||
}
|
||||
size_t segmentSize = bestMatch->end - bestMatch->start;
|
||||
if (bestMatch->segmentStart) {
|
||||
segmentSize = bestMatch->segmentStart - bestMatch->start;
|
||||
}
|
||||
if (segment > 0) {
|
||||
start += segment * segmentSize;
|
||||
}
|
||||
int maxFromRegion = blockSize - (start - bestMatch->start);
|
||||
if (maxFromRegion <= 0) {
|
||||
continue;
|
||||
}
|
||||
int fromRegion = std::min(size, maxFromRegion);
|
||||
if (block && (segment >= 0 || segmentSize == blockSize)) {
|
||||
block = &block[start - bestMatch->start];
|
||||
mem.append(QByteArray::fromRawData(block, fromRegion));
|
||||
size -= fromRegion;
|
||||
start += fromRegion;
|
||||
if (spanSegments) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
char datum = core->rawRead8(core, start, segment);
|
||||
mem.append(datum);
|
||||
++start;
|
||||
--size;
|
||||
if (!size) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mem;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/* Copyright (c) 2013-2019 Jeffrey Pfau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#pragma once
|
||||
|
||||
#include "ui_MemoryDump.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace QGBA {
|
||||
|
||||
class CoreController;
|
||||
|
||||
class MemoryDump : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MemoryDump(std::shared_ptr<CoreController> controller, QWidget* parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void setSegment(int);
|
||||
void setAddress(uint32_t address);
|
||||
void setByteCount(uint32_t);
|
||||
|
||||
private slots:
|
||||
void save();
|
||||
|
||||
private:
|
||||
QByteArray serialize();
|
||||
|
||||
Ui::MemoryDump m_ui;
|
||||
|
||||
std::shared_ptr<CoreController> m_controller;
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MemoryDump</class>
|
||||
<widget class="QDialog" name="MemoryDump">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>448</width>
|
||||
<height>208</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Save Memory Range</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Start Address:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="segment">
|
||||
<property name="minimum">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>511</number>
|
||||
</property>
|
||||
<property name="displayIntegerBase">
|
||||
<number>16</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="address">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>0x</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>268435455</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="displayIntegerBase">
|
||||
<number>16</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Byte Count:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="bytes">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>0x</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>268435456</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>256</number>
|
||||
</property>
|
||||
<property name="displayIntegerBase">
|
||||
<number>16</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="spanSegments">
|
||||
<property name="text">
|
||||
<string>Dump across banks</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>MemoryDump</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>MemoryDump</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
|
@ -7,6 +7,7 @@
|
|||
#include "MemoryView.h"
|
||||
|
||||
#include "CoreController.h"
|
||||
#include "MemoryDump.h"
|
||||
|
||||
#include <mgba/core/core.h>
|
||||
|
||||
|
@ -44,6 +45,7 @@ MemoryView::MemoryView(std::shared_ptr<CoreController> controller, QWidget* pare
|
|||
connect(m_ui.setAddress, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
|
||||
this, static_cast<void (MemoryView::*)(uint32_t)>(&MemoryView::jumpToAddress));
|
||||
connect(m_ui.hexfield, &MemoryModel::selectionChanged, this, &MemoryView::updateSelection);
|
||||
connect(m_ui.saveRange, &QAbstractButton::clicked, this, &MemoryView::saveRange);
|
||||
|
||||
connect(controller.get(), &CoreController::stopping, this, &QWidget::close);
|
||||
|
||||
|
@ -69,6 +71,7 @@ void MemoryView::setIndex(int index) {
|
|||
m_region = qMakePair(info.start, info.end);
|
||||
m_ui.segments->setValue(-1);
|
||||
m_ui.segments->setVisible(info.maxSegment > 0);
|
||||
m_ui.segmentColon->setVisible(info.maxSegment > 0);
|
||||
m_ui.segments->setMaximum(info.maxSegment);
|
||||
m_ui.hexfield->setRegion(info.start, info.end - info.start, info.shortName);
|
||||
}
|
||||
|
@ -142,3 +145,12 @@ void MemoryView::updateStatus() {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryView::saveRange() {
|
||||
MemoryDump* memdump = new MemoryDump(m_controller);
|
||||
memdump->setAttribute(Qt::WA_DeleteOnClose);
|
||||
memdump->setAddress(m_selection.first);
|
||||
memdump->setSegment(m_ui.segments->value());
|
||||
memdump->setByteCount(m_selection.second - m_selection.first);
|
||||
memdump->show();
|
||||
}
|
|
@ -28,6 +28,7 @@ private slots:
|
|||
void setSegment(int);
|
||||
void updateSelection(uint32_t start, uint32_t end);
|
||||
void updateStatus();
|
||||
void saveRange();
|
||||
|
||||
private:
|
||||
Ui::MemoryView m_ui;
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>822</width>
|
||||
<height>886</height>
|
||||
<width>874</width>
|
||||
<height>900</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -52,6 +52,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="segmentColon">
|
||||
<property name="text">
|
||||
<string>:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="setAddress">
|
||||
<property name="accelerated">
|
||||
|
@ -271,6 +278,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="saveRange">
|
||||
<property name="text">
|
||||
<string>Save Range</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="load">
|
||||
<property name="text">
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
using namespace QGBA;
|
||||
|
||||
PlacementControl::PlacementControl(std::shared_ptr<CoreController> controller, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
|
||||
, m_controller(controller)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
using namespace QGBA;
|
||||
|
||||
PrinterView::PrinterView(std::shared_ptr<CoreController> controller, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
|
||||
, m_controller(controller)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
|
Loading…
Reference in New Issue