diff --git a/CHANGES b/CHANGES index 13610b083..3067df0ad 100644 --- a/CHANGES +++ b/CHANGES @@ -46,23 +46,18 @@ Features: - Command scripts for CLI debugger (by ahigerd) - ARM disassembler now resolves addresses to symbol names - Add Game Boy Player feature support to ports + - Individual window types can now be toggled in GBA debugging views Emulation fixes: - ARM: Fix ALU reading PC after shifting - ARM: Fix STR storing PC after address calculation + - ARM: Fix Addressing mode 1 shifter on rs == pc (fixes mgba.io/i/1926) - GB: Partially fix timing for skipped BIOS - - GB Audio: Fix initial sweep state - GB Audio: Fix serializing sweep time - - GB Audio: Fix deserializing audio channels 2 and 3 - - GB Audio: Fix deserializing while audio was disabled (fixes mgba.io/i/1305) - GB MBC: Fix MBC1 mode changing behavior - GB MBC: Fix some MBC3 bit masking - GB Video: Fix state after skipping BIOS (fixes mgba.io/i/1715 and mgba.io/i/1716) - - GB Video: Fix drawing background when window is force-disabled by frontend - GBA: Fix timing advancing too quickly in rare cases - GBA: Clear GBP connection on reset - - GBA Audio: Fix deserializing SOUNDCNT_L - - GBA Audio: Fix stereo in XQ audio - - GBA Audio: Fix volume/mute in XQ audio (fixes mgba.io/i/1864) - GBA Audio: Revamp FIFO emulation (fixes mgba.io/i/356, mgba.io/i/875, mgba.io/i/1847) - GBA BIOS: Implement dummy sound driver calls - GBA BIOS: Improve HLE BIOS timing @@ -70,7 +65,6 @@ Emulation fixes: - GBA BIOS: Make HLE BIOS calls interruptable (fixes mgba.io/i/1711 and mgba.io/i/1823) - GBA DMA: Linger last DMA on bus (fixes mgba.io/i/301 and mgba.io/i/1320) - GBA DMA: Fix ordering and timing of overlapping DMAs - - GBA Hardware: Fix GB Player detection on big endian platforms - GBA I/O: Green swap register should be readable - GBA Memory: Improve gamepak prefetch timing - GBA Memory: Stall on VRAM access in mode 2 (fixes mgba.io/i/190) @@ -80,45 +74,24 @@ Emulation fixes: - GBA SIO: Fix deseralizing SIO registers - GBA Video: Latch scanline at end of Hblank (fixes mgba.io/i/1319) - GBA Video: Fix Hblank timing - - GBA Video: Invalidate map cache when modifying BGCNT (fixes mgba.io/i/1846) - - GBA Video: Don't draw sprites using unmapped VRAM in GL renderer (fixes mgba.io/i/1865) - GBA Video: Implement green swap (fixes mgba.io/i/1609) - - GBA Video: Fix rare regression blending semitransparent sprites (fixes mgba.io/i/1876) - GBA Video: Emulate sprite cycle limits in OpenGL renderer (fixes mgba.io/i/1635) - - GBA Video: Do not affect OBJ pixel priority when writing OBJWIN (fixes mgba.io/i/1890) - - GBA Video: Fix deferred blending when OBJWIN matches window (fixes mgba.io/i/1905) - - GBA Video: Fix mode 4 transparency in OpenGL (fixes mgba.io/i/1907) - SM83: Emulate HALT bug Other fixes: - - 3DS: Redo video sync to be more precise - - 3DS: Fix crash with libctru 2.0 when exiting - 3DS: Fix thread cleanup - All: Improve export headers (fixes mgba.io/i/1738) + - CMake: Fix build with downstream minizip that exports incompatible symbols - Core: Ensure ELF regions can be written before trying - - Core: Fix reported ROM size when a fixed buffer size is used - - Core: Fix memory leak loading ELF files - Debugger: Don't skip undefined instructions when debugger attached - FFmpeg: Fix some small memory leaks - FFmpeg: Fix encoding of time base - - GBA: Disable more checks when loading GS save with checks disabled (fixes mgba.io/i/1851) - - GBA: Fix endianness issues in renderer proxy - - GBA Core: Fix memory leak when loading symbols - Qt: Force OpenGL paint engine creation thread (fixes mgba.io/i/1642) - Qt: Fix static compilation in MinGW (fixes mgba.io/i/1769) - Qt: Fix a race condition in the frame inspector - - Qt: Add dummy English translation file (fixes mgba.io/i/1469) - - Qt: Fix Battle Chip view not displaying chips on some DPI settings - - Qt: Fix camera image being upside-down sometimes (fixes mgba.io/i/829 again) - - Qt: Fix drawing on macOS break when using OpenGL (fixes mgba.io/i/1899) - Qt: Load/save bytes from memory viewer in the order visible (fixes mgba.io/i/1900) - - Qt: Fix stride changing when toggling SGB borders (fixes mgba.io/i/1898) - - Qt: Fix aliasing on background logo (fixes mgba.io/i/1886) - - mGUI: Fix closing down a game if an exit is signalled - - mGUI: Fix cycling through config setting states with accept button - - mVL: Fix injecting accidentally draining non-injection buffer + - Qt: Fix running proxied video if it gets pushed to the main thread - SM83: Simplify register pair access on big endian - SM83: Disassemble STOP as one byte - - VFS: Fix directory node listing on some filesystems Misc: - 3DS: Use "wide mode" where applicable for slightly better filtering - Core: Add savedataUpdated callback @@ -128,7 +101,6 @@ Misc: - GBA: Allow pausing event loop while CPU is blocked - GBA BIOS: Division by zero should emit a FATAL error - GBA Video: Convert OpenGL VRAM texture to integer - - GBA Video: Improve speed of window texture generation on AMD - Debugger: Keep track of global cycle count - FFmpeg: Add looping option for GIF/APNG - mGUI: Show battery percentage @@ -141,6 +113,47 @@ Misc: - Util: Reset vector size on deinit - VFS: Change semantics of VFile.sync on mapped files (fixes mgba.io/i/1730) +0.8.4: (2020-10-29) +Emulation fixes: + - GB Audio: Fix initial sweep state + - GB Audio: Fix deserializing audio channels 2 and 3 + - GB Audio: Fix deserializing while audio was disabled (fixes mgba.io/i/1305) + - GB Video: Fix drawing background when window is force-disabled by frontend + - GB, GBA Video: Copy disable flags when drawing scanlines in proxy when not blocking + - GBA Audio: Fix deserializing SOUNDCNT_L + - GBA Audio: Fix stereo in XQ audio + - GBA Audio: Fix volume/mute in XQ audio (fixes mgba.io/i/1864) + - GBA Hardware: Fix GB Player detection on big endian platforms + - GBA Video: Invalidate map cache when modifying BGCNT (fixes mgba.io/i/1846) + - GBA Video: Don't draw sprites using unmapped VRAM in GL renderer (fixes mgba.io/i/1865) + - GBA Video: Fix rare regression blending semitransparent sprites (fixes mgba.io/i/1876) + - GBA Video: Do not affect OBJ pixel priority when writing OBJWIN (fixes mgba.io/i/1890) + - GBA Video: Fix deferred blending when OBJWIN matches window (fixes mgba.io/i/1905) + - GBA Video: Fix mode 4 transparency in OpenGL (fixes mgba.io/i/1907) +Other fixes: + - 3DS: Redo video sync to be more precise + - 3DS: Fix crash with libctru 2.0 when exiting + - ARM Decoder: Fix decoding pre-indexed writeback instructions (fixes mgba.io/i/1915) + - Core: Fix reported ROM size when a fixed buffer size is used + - Core: Fix memory leak loading ELF files + - GBA: Disable more checks when loading GS save with checks disabled (fixes mgba.io/i/1851) + - GBA: Fix endianness issues in renderer proxy + - GBA Core: Fix memory leak when loading symbols + - GBA Serialize: Ensure program counter is aligned when loading + - Qt: Add dummy English translation file (fixes mgba.io/i/1469) + - Qt: Fix Battle Chip view not displaying chips on some DPI settings + - Qt: Fix camera image being upside-down sometimes (fixes mgba.io/i/829 again) + - Qt: Fix drawing on macOS break when using OpenGL (fixes mgba.io/i/1899) + - Qt: Fix stride changing when toggling SGB borders (fixes mgba.io/i/1898) + - Qt: Fix aliasing on background logo (fixes mgba.io/i/1886) + - mGUI: Fix closing down a game if an exit is signalled + - mGUI: Fix cycling through config setting states with accept button + - mVL: Fix injecting accidentally draining non-injection buffer + - VFS: Fix directory node listing on some filesystems +Misc: + - GBA Video: Improve speed of window texture generation on AMD + - Vita: Clear both buffers when loading a game + 0.8.3: (2020-08-03) Emulation fixes: - ARM: Fix LDM^ writeback to user-mode register diff --git a/CMakeLists.txt b/CMakeLists.txt index 6232749dd..0b75faea1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -682,6 +682,12 @@ elseif(USE_MINIZIP) list(APPEND FEATURES MINIZIP) list(APPEND VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-zip.c) set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libminizip1") + set(CMAKE_REQUIRED_LIBRARIES ${MINIZIP_LIBRARIES}) + check_function_exists(unztell64 HAVE_UNZTELL64) + unset(CMAKE_REQUIRED_LIBRARIES) + if(NOT HAVE_UNZTELL64) + add_definitions(-Dunztell64=unzTell64) # Bug in downstream minizip that some distros use + endif() elseif(USE_ZLIB) list(APPEND VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-zip.c ${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/zlib/contrib/minizip/ioapi.c diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index 0c13834dd..b59d265a2 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -34,6 +34,17 @@ enum GBASIOJOYCommand { JOY_RECV = 0x15 }; +enum GBAVideoLayer { + GBA_LAYER_BG0 = 0, + GBA_LAYER_BG1, + GBA_LAYER_BG2, + GBA_LAYER_BG3, + GBA_LAYER_OBJ, + GBA_LAYER_WIN0, + GBA_LAYER_WIN1, + GBA_LAYER_OBJWIN, +}; + struct GBA; struct GBAAudio; struct GBASIO; diff --git a/include/mgba/internal/arm/debugger/debugger.h b/include/mgba/internal/arm/debugger/debugger.h index e3615049c..cbce4f120 100644 --- a/include/mgba/internal/arm/debugger/debugger.h +++ b/include/mgba/internal/arm/debugger/debugger.h @@ -40,7 +40,7 @@ struct ARMDebugger { void (*entered)(struct mDebugger*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); - ssize_t (*setSoftwareBreakpoint)(struct ARMDebugger*, uint32_t address, enum ExecutionMode mode, uint32_t* opcode); + bool (*setSoftwareBreakpoint)(struct ARMDebugger*, uint32_t address, enum ExecutionMode mode, uint32_t* opcode); void (*clearSoftwareBreakpoint)(struct ARMDebugger*, const struct ARMDebugBreakpoint*); }; diff --git a/include/mgba/internal/gba/renderers/video-software.h b/include/mgba/internal/gba/renderers/video-software.h index acef5d312..ac0fd327f 100644 --- a/include/mgba/internal/gba/renderers/video-software.h +++ b/include/mgba/internal/gba/renderers/video-software.h @@ -135,6 +135,8 @@ struct GBAVideoSoftwareRenderer { struct GBAVideoWindowRegion h; struct GBAVideoWindowRegion v; struct WindowControl control; + int16_t offsetX; + int16_t offsetY; } winN[2]; struct WindowControl winout; diff --git a/include/mgba/internal/gba/video.h b/include/mgba/internal/gba/video.h index 33ea4965f..3d90fc571 100644 --- a/include/mgba/internal/gba/video.h +++ b/include/mgba/internal/gba/video.h @@ -199,6 +199,8 @@ struct GBAVideoRenderer { bool disableBG[4]; bool disableOBJ; + bool disableWIN[2]; + bool disableOBJWIN; bool highlightBG[4]; bool highlightOBJ[128]; diff --git a/res/patrons.txt b/res/patrons.txt index d4d783657..47bdc9ab6 100644 --- a/res/patrons.txt +++ b/res/patrons.txt @@ -1,6 +1,4 @@ Miras Absar +Emily A. Bellows Jaime J. Denizard Benedikt Feih -Mored1984 -Johnathan Roatch -Yuri Kunde Schlesner diff --git a/src/arm/decoder-arm.c b/src/arm/decoder-arm.c index a2ea0e34d..63d6a21c0 100644 --- a/src/arm/decoder-arm.c +++ b/src/arm/decoder-arm.c @@ -218,6 +218,7 @@ ARM_MEMORY_ ## FORMAT, \ ADDRESSING_MODE, FORMAT ## _CYCLES, ARM_ACCESS_ ## TYPE, OTHER_AFFECTED) \ DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## PUW, MNEMONIC, \ + ARM_MEMORY_PRE_INCREMENT | \ ARM_MEMORY_WRITEBACK | \ ARM_MEMORY_ ## FORMAT, \ ADDRESSING_MODE, FORMAT ## _CYCLES, ARM_ACCESS_ ## TYPE, OTHER_AFFECTED) \ diff --git a/src/arm/isa-arm.c b/src/arm/isa-arm.c index 1c911c63b..aa5956457 100644 --- a/src/arm/isa-arm.c +++ b/src/arm/isa-arm.c @@ -20,15 +20,11 @@ static inline void _shiftLSL(struct ARMCore* cpu, uint32_t opcode) { if (opcode & 0x00000010) { int rs = (opcode >> 8) & 0x0000000F; ++cpu->cycles; - int shift = cpu->gprs[rs]; - if (rs == ARM_PC) { - shift += 4; - } - shift &= 0xFF; int32_t shiftVal = cpu->gprs[rm]; if (rm == ARM_PC) { shiftVal += 4; } + int shift = cpu->gprs[rs] & 0xFF; if (!shift) { cpu->shifterOperand = shiftVal; cpu->shifterCarryOut = cpu->cpsr.c; @@ -59,15 +55,11 @@ static inline void _shiftLSR(struct ARMCore* cpu, uint32_t opcode) { if (opcode & 0x00000010) { int rs = (opcode >> 8) & 0x0000000F; ++cpu->cycles; - int shift = cpu->gprs[rs]; - if (rs == ARM_PC) { - shift += 4; - } - shift &= 0xFF; uint32_t shiftVal = cpu->gprs[rm]; if (rm == ARM_PC) { shiftVal += 4; } + int shift = cpu->gprs[rs] & 0xFF; if (!shift) { cpu->shifterOperand = shiftVal; cpu->shifterCarryOut = cpu->cpsr.c; @@ -98,15 +90,11 @@ static inline void _shiftASR(struct ARMCore* cpu, uint32_t opcode) { if (opcode & 0x00000010) { int rs = (opcode >> 8) & 0x0000000F; ++cpu->cycles; - int shift = cpu->gprs[rs]; - if (rs == ARM_PC) { - shift += 4; - } - shift &= 0xFF; int shiftVal = cpu->gprs[rm]; if (rm == ARM_PC) { shiftVal += 4; } + int shift = cpu->gprs[rs] & 0xFF; if (!shift) { cpu->shifterOperand = shiftVal; cpu->shifterCarryOut = cpu->cpsr.c; @@ -137,15 +125,11 @@ static inline void _shiftROR(struct ARMCore* cpu, uint32_t opcode) { if (opcode & 0x00000010) { int rs = (opcode >> 8) & 0x0000000F; ++cpu->cycles; - int shift = cpu->gprs[rs]; - if (rs == ARM_PC) { - shift += 4; - } - shift &= 0xFF; int shiftVal = cpu->gprs[rm]; if (rm == ARM_PC) { shiftVal += 4; } + int shift = cpu->gprs[rs] & 0xFF; int rotate = shift & 0x1F; if (!shift) { cpu->shifterOperand = shiftVal; @@ -319,13 +303,13 @@ ATTRIBUTE_NOINLINE static void _neutralS(struct ARMCore* cpu, int32_t d) { #define DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, S_BODY, SHIFTER, BODY) \ DEFINE_INSTRUCTION_ARM(NAME, \ + SHIFTER(cpu, opcode); \ int rd = (opcode >> 12) & 0xF; \ int rn = (opcode >> 16) & 0xF; \ int32_t n = cpu->gprs[rn]; \ if (UNLIKELY(rn == ARM_PC && (opcode & 0x02000010) == 0x00000010)) { \ n += WORD_SIZE_ARM; \ } \ - SHIFTER(cpu, opcode); \ BODY; \ S_BODY; \ if (rd == ARM_PC) { \ diff --git a/src/gb/extra/proxy.c b/src/gb/extra/proxy.c index 2078afcdf..fd5d8d6cf 100644 --- a/src/gb/extra/proxy.c +++ b/src/gb/extra/proxy.c @@ -235,6 +235,9 @@ void GBVideoProxyRendererWriteOAM(struct GBVideoRenderer* renderer, uint16_t oam void GBVideoProxyRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y) { struct GBVideoProxyRenderer* proxyRenderer = (struct GBVideoProxyRenderer*) renderer; if (!proxyRenderer->logger->block) { + proxyRenderer->backend->disableBG = proxyRenderer->d.disableBG; + proxyRenderer->backend->disableWIN = proxyRenderer->d.disableWIN; + proxyRenderer->backend->disableOBJ = proxyRenderer->d.disableOBJ; proxyRenderer->backend->drawRange(proxyRenderer->backend, startX, endX, y); } mVideoLoggerRendererDrawRange(proxyRenderer->logger, startX, endX, y); diff --git a/src/gba/core.c b/src/gba/core.c index cc6afbbb9..6c89e3d76 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -37,11 +37,14 @@ #endif static const struct mCoreChannelInfo _GBAVideoLayers[] = { - { 0, "bg0", "Background 0", NULL }, - { 1, "bg1", "Background 1", NULL }, - { 2, "bg2", "Background 2", NULL }, - { 3, "bg3", "Background 3", NULL }, - { 4, "obj", "Objects", NULL }, + { GBA_LAYER_BG0, "bg0", "Background 0", NULL }, + { GBA_LAYER_BG1, "bg1", "Background 1", NULL }, + { GBA_LAYER_BG2, "bg2", "Background 2", NULL }, + { GBA_LAYER_BG3, "bg3", "Background 3", NULL }, + { GBA_LAYER_OBJ, "obj", "Objects", NULL }, + { GBA_LAYER_WIN0, "win0", "Window 0", NULL }, + { GBA_LAYER_WIN1, "win1", "Window 1", NULL }, + { GBA_LAYER_OBJWIN, "objwin", "Object Window", NULL }, }; static const struct mCoreChannelInfo _GBAAudioChannels[] = { @@ -1060,15 +1063,24 @@ static size_t _GBACoreListAudioChannels(const struct mCore* core, const struct m static void _GBACoreEnableVideoLayer(struct mCore* core, size_t id, bool enable) { struct GBA* gba = core->board; switch (id) { - case 0: - case 1: - case 2: - case 3: + case GBA_LAYER_BG0: + case GBA_LAYER_BG1: + case GBA_LAYER_BG2: + case GBA_LAYER_BG3: gba->video.renderer->disableBG[id] = !enable; break; - case 4: + case GBA_LAYER_OBJ: gba->video.renderer->disableOBJ = !enable; break; + case GBA_LAYER_WIN0: + gba->video.renderer->disableWIN[0] = !enable; + break; + case GBA_LAYER_WIN1: + gba->video.renderer->disableWIN[1] = !enable; + break; + case GBA_LAYER_OBJWIN: + gba->video.renderer->disableOBJWIN = !enable; + break; default: break; } @@ -1097,18 +1109,22 @@ static void _GBACoreEnableAudioChannel(struct mCore* core, size_t id, bool enabl static void _GBACoreAdjustVideoLayer(struct mCore* core, size_t id, int32_t x, int32_t y) { struct GBACore* gbacore = (struct GBACore*) core; switch (id) { - case 0: - case 1: - case 2: - case 3: + case GBA_LAYER_BG0: + case GBA_LAYER_BG1: + case GBA_LAYER_BG2: + case GBA_LAYER_BG3: gbacore->renderer.bg[id].offsetX = x; gbacore->renderer.bg[id].offsetY = y; break; - case 4: + case GBA_LAYER_OBJ: gbacore->renderer.objOffsetX = x; gbacore->renderer.objOffsetY = y; gbacore->renderer.oamDirty = 1; break; + case GBA_LAYER_WIN0: + gbacore->renderer.winN[id - GBA_LAYER_WIN0].offsetX = x; + gbacore->renderer.winN[id - GBA_LAYER_WIN0].offsetY = y; + break; default: return; } diff --git a/src/gba/extra/proxy.c b/src/gba/extra/proxy.c index e03a21e23..b7c9e967e 100644 --- a/src/gba/extra/proxy.c +++ b/src/gba/extra/proxy.c @@ -43,6 +43,9 @@ void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct renderer->d.disableBG[2] = false; renderer->d.disableBG[3] = false; renderer->d.disableOBJ = false; + renderer->d.disableWIN[0] = false; + renderer->d.disableWIN[1] = false; + renderer->d.disableOBJWIN = false; renderer->d.highlightBG[0] = false; renderer->d.highlightBG[1] = false; @@ -216,6 +219,9 @@ static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerD proxyRenderer->backend->disableBG[2] = proxyRenderer->d.disableBG[2]; proxyRenderer->backend->disableBG[3] = proxyRenderer->d.disableBG[3]; proxyRenderer->backend->disableOBJ = proxyRenderer->d.disableOBJ; + proxyRenderer->backend->disableWIN[0] = proxyRenderer->d.disableWIN[0]; + proxyRenderer->backend->disableWIN[1] = proxyRenderer->d.disableWIN[1]; + proxyRenderer->backend->disableOBJWIN = proxyRenderer->d.disableOBJWIN; proxyRenderer->backend->highlightBG[0] = proxyRenderer->d.highlightBG[0]; proxyRenderer->backend->highlightBG[1] = proxyRenderer->d.highlightBG[1]; proxyRenderer->backend->highlightBG[2] = proxyRenderer->d.highlightBG[2]; @@ -315,6 +321,18 @@ void GBAVideoProxyRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t o void GBAVideoProxyRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer; if (!proxyRenderer->logger->block) { + proxyRenderer->backend->disableBG[0] = proxyRenderer->d.disableBG[0]; + proxyRenderer->backend->disableBG[1] = proxyRenderer->d.disableBG[1]; + proxyRenderer->backend->disableBG[2] = proxyRenderer->d.disableBG[2]; + proxyRenderer->backend->disableBG[3] = proxyRenderer->d.disableBG[3]; + proxyRenderer->backend->disableOBJ = proxyRenderer->d.disableOBJ; + proxyRenderer->backend->disableWIN[0] = proxyRenderer->d.disableWIN[0]; + proxyRenderer->backend->disableWIN[1] = proxyRenderer->d.disableWIN[1]; + proxyRenderer->backend->disableOBJWIN = proxyRenderer->d.disableOBJWIN; + proxyRenderer->backend->highlightBG[0] = proxyRenderer->d.highlightBG[0]; + proxyRenderer->backend->highlightBG[1] = proxyRenderer->d.highlightBG[1]; + proxyRenderer->backend->highlightBG[2] = proxyRenderer->d.highlightBG[2]; + proxyRenderer->backend->highlightBG[3] = proxyRenderer->d.highlightBG[3]; proxyRenderer->backend->drawScanline(proxyRenderer->backend, y); } mVideoLoggerRendererDrawScanline(proxyRenderer->logger, y); diff --git a/src/gba/renderers/software-obj.c b/src/gba/renderers/software-obj.c index 47035b2d4..0993e6e9e 100644 --- a/src/gba/renderers/software-obj.c +++ b/src/gba/renderers/software-obj.c @@ -233,7 +233,7 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re uint32_t flags = GBAObjAttributesCGetPriority(sprite->c) << OFFSET_PRIORITY; flags |= FLAG_TARGET_1 * ((GBAWindowControlIsBlendEnable(renderer->currentWindow.packed) && renderer->target1Obj && renderer->blendEffect == BLEND_ALPHA) || GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT); flags |= FLAG_OBJWIN * (GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_OBJWIN); - if ((flags & FLAG_OBJWIN) && renderer->currentWindow.priority < renderer->objwin.priority) { + if ((flags & FLAG_OBJWIN) && (renderer->currentWindow.priority < renderer->objwin.priority || renderer->d.disableOBJWIN)) { return 0; } int32_t x = (uint32_t) GBAObjAttributesBGetX(sprite->b) << 23; diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 8c990d15f..e416c8c6e 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -59,6 +59,16 @@ void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer) { renderer->d.disableBG[2] = false; renderer->d.disableBG[3] = false; renderer->d.disableOBJ = false; + + renderer->d.disableWIN[0] = false; + renderer->d.disableWIN[1] = false; + renderer->d.disableOBJWIN = false; + + renderer->d.highlightBG[0] = false; + renderer->d.highlightBG[1] = false; + renderer->d.highlightBG[2] = false; + renderer->d.highlightBG[3] = false; + renderer->tileStride = 0x20; renderer->bitmapStride = 0; renderer->combinedObjSort = false; @@ -66,10 +76,6 @@ void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer) { renderer->masterHeight = GBA_VIDEO_VERTICAL_PIXELS; renderer->masterScanlines = VIDEO_VERTICAL_TOTAL_PIXELS; - renderer->d.highlightBG[0] = false; - renderer->d.highlightBG[1] = false; - renderer->d.highlightBG[2] = false; - renderer->d.highlightBG[3] = false; int i; for (i = 0; i < 128; ++i) { renderer->d.highlightOBJ[i] = false; @@ -457,13 +463,13 @@ static void GBAVideoSoftwareRendererWritePalette(struct GBAVideoRenderer* render static void _breakWindow(struct GBAVideoSoftwareRenderer* softwareRenderer, struct WindowN* win, int y) { if (win->v.end >= win->v.start) { - if (y >= win->v.end) { + if (y >= win->v.end + win->offsetY) { return; } - if (y < win->v.start) { + if (y < win->v.start + win->offsetY) { return; } - } else if (y >= win->v.end && y < win->v.start) { + } else if (y >= win->v.end + win->offsetY && y < win->v.start + win->offsetY) { return; } if (win->h.end > softwareRenderer->masterEnd || win->h.end < win->h.start) { @@ -880,10 +886,10 @@ void GBAVideoSoftwareRendererPreprocessBuffer(struct GBAVideoSoftwareRenderer* s softwareRenderer->nWindows = 1; if (GBARegisterDISPCNTIsWin0Enable(softwareRenderer->dispcnt) || GBARegisterDISPCNTIsWin1Enable(softwareRenderer->dispcnt) || GBARegisterDISPCNTIsObjwinEnable(softwareRenderer->dispcnt)) { softwareRenderer->windows[0].control = softwareRenderer->winout; - if (GBARegisterDISPCNTIsWin1Enable(softwareRenderer->dispcnt)) { + if (GBARegisterDISPCNTIsWin1Enable(softwareRenderer->dispcnt) && !softwareRenderer->d.disableWIN[1]) { _breakWindow(softwareRenderer, &softwareRenderer->winN[1], y); } - if (GBARegisterDISPCNTIsWin0Enable(softwareRenderer->dispcnt)) { + if (GBARegisterDISPCNTIsWin0Enable(softwareRenderer->dispcnt) && !softwareRenderer->d.disableWIN[0]) { _breakWindow(softwareRenderer, &softwareRenderer->winN[0], y); } } else { diff --git a/src/gba/serialize.c b/src/gba/serialize.c index 0e3c43f8c..464cef460 100644 --- a/src/gba/serialize.c +++ b/src/gba/serialize.c @@ -154,6 +154,11 @@ bool GBADeserialize(struct GBA* gba, const struct GBASerializedState* state) { LOAD_32(gba->cpu->bankedSPSRs[i], i * sizeof(gba->cpu->bankedSPSRs[0]), state->cpu.bankedSPSRs); } gba->cpu->privilegeMode = gba->cpu->cpsr.priv; + uint32_t pcMask = (gba->cpu->executionMode == MODE_THUMB ? WORD_SIZE_THUMB : WORD_SIZE_ARM) - 1; + if (gba->cpu->gprs[ARM_PC] & pcMask) { + mLOG(GBA_STATE, WARN, "Savestate has unaligned PC and is probably corrupted"); + gba->cpu->gprs[ARM_PC] &= ~pcMask; + } gba->cpu->memory.setActiveRegion(gba->cpu, gba->cpu->gprs[ARM_PC]); if (state->biosPrefetch) { LOAD_32(gba->memory.biosPrefetch, 0, &state->biosPrefetch); diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 1aec545e3..bca936aff 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -615,9 +615,10 @@ bool retro_load_game(const struct retro_game_info* game) { cam.width = GBCAM_WIDTH; cam.caps = 1 << RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER; cam.frame_raw_framebuffer = _updateCamera; - core->setPeripheral(core, mPERIPH_IMAGE_SOURCE, &imageSource); + if (environCallback(RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE, &cam)) { + core->setPeripheral(core, mPERIPH_IMAGE_SOURCE, &imageSource); + } - environCallback(RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE, &cam); const char* modelName = mCoreConfigGetValue(&core->config, "gb.model"); struct GB* gb = core->board; diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index 420bd444b..f6fe0150a 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -328,6 +328,9 @@ void mPSP2Setup(struct mGUIRunner* runner) { currentTex = 0; screenshot = vita2d_create_empty_texture_format(256, toPow2(height), SCE_GXM_TEXTURE_FORMAT_X8U8U8U8_1BGR); + memset(vita2d_texture_get_datap(tex[0]), 0xFF, 256 * toPow2(height) * 4); + memset(vita2d_texture_get_datap(tex[1]), 0xFF, 256 * toPow2(height) * 4); + runner->core->setVideoBuffer(runner->core, vita2d_texture_get_datap(tex[currentTex]), 256); runner->core->setAudioBufferSize(runner->core, PSP2_SAMPLES); diff --git a/src/platform/python/mgba/__init__.py b/src/platform/python/mgba/__init__.py index a8fef8ecd..7dc2bb7dd 100644 --- a/src/platform/python/mgba/__init__.py +++ b/src/platform/python/mgba/__init__.py @@ -5,7 +5,23 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from ._pylib import ffi, lib # pylint: disable=no-name-in-module -from collections import namedtuple + +class Git: + commit = None + if lib.gitCommit and lib.gitCommit != "(unknown)": + commit = ffi.string(lib.gitCommit).decode('utf-8') + + commitShort = None + if lib.gitCommitShort and lib.gitCommitShort != "(unknown)": + commitShort = ffi.string(lib.gitCommitShort).decode('utf-8') + + branch = None + if lib.gitBranch and lib.gitBranch != "(unknown)": + branch = ffi.string(lib.gitBranch).decode('utf-8') + + revision = None + if lib.gitRevision > 0: + revision = lib.gitRevision def create_callback(struct_name, cb_name, func_name=None): @@ -20,17 +36,3 @@ def create_callback(struct_name, cb_name, func_name=None): __version__ = ffi.string(lib.projectVersion).decode('utf-8') - -GitInfo = namedtuple("GitInfo", "commit commitShort branch revision") - -GIT = {} -if lib.gitCommit and lib.gitCommit != "(unknown)": - GIT['commit'] = ffi.string(lib.gitCommit).decode('utf-8') -if lib.gitCommitShort and lib.gitCommitShort != "(unknown)": - GIT['commitShort'] = ffi.string(lib.gitCommitShort).decode('utf-8') -if lib.gitBranch and lib.gitBranch != "(unknown)": - GIT['branch'] = ffi.string(lib.gitBranch).decode('utf-8') -if lib.gitRevision > 0: - GIT['revision'] = lib.gitRevision - -GIT = GitInfo(**GIT) diff --git a/src/platform/qt/FrameView.cpp b/src/platform/qt/FrameView.cpp index 9e32d692d..649c16e92 100644 --- a/src/platform/qt/FrameView.cpp +++ b/src/platform/qt/FrameView.cpp @@ -24,6 +24,7 @@ #endif #ifdef M_CORE_GB #include +#include #include #endif @@ -153,16 +154,44 @@ void FrameView::updateTilesGBA(bool) { uint16_t* io = static_cast(m_controller->thread()->core->board)->memory.io; QRgb backdrop = M_RGB5_TO_RGB8(static_cast(m_controller->thread()->core->board)->video.palette[0]); - m_gbaDispcnt = io[REG_DISPCNT >> 1]; - int mode = GBARegisterDISPCNTGetMode(m_gbaDispcnt); + GBARegisterDISPCNT gbaDispcnt = io[REG_DISPCNT >> 1]; + int mode = GBARegisterDISPCNTGetMode(gbaDispcnt); std::array enabled{ - bool(GBARegisterDISPCNTIsBg0Enable(m_gbaDispcnt)), - bool(GBARegisterDISPCNTIsBg1Enable(m_gbaDispcnt)), - bool(GBARegisterDISPCNTIsBg2Enable(m_gbaDispcnt)), - bool(GBARegisterDISPCNTIsBg3Enable(m_gbaDispcnt)), + bool(GBARegisterDISPCNTIsBg0Enable(gbaDispcnt)), + bool(GBARegisterDISPCNTIsBg1Enable(gbaDispcnt)), + bool(GBARegisterDISPCNTIsBg2Enable(gbaDispcnt)), + bool(GBARegisterDISPCNTIsBg3Enable(gbaDispcnt)), }; + if (GBARegisterDISPCNTIsWin0Enable(gbaDispcnt)) { + m_queue.append({ + { LayerId::WINDOW, 0 }, + !m_disabled.contains({ LayerId::WINDOW, 0 }), + {}, + {}, {0, 0}, true, false + }); + } + + if (GBARegisterDISPCNTIsWin1Enable(gbaDispcnt)) { + m_queue.append({ + { LayerId::WINDOW, 1 }, + !m_disabled.contains({ LayerId::WINDOW, 1 }), + {}, + {}, {0, 0}, true, false + }); + } + + if (GBARegisterDISPCNTIsObjwinEnable(gbaDispcnt)) { + m_queue.append({ + { LayerId::WINDOW, 2 }, + !m_disabled.contains({ LayerId::WINDOW, 2 }), + {}, + {}, {0, 0}, true, false + }); + + } + for (int priority = 0; priority < 4; ++priority) { for (int sprite = 0; sprite < 128; ++sprite) { ObjInfo info; @@ -270,6 +299,9 @@ void FrameView::injectGBA() { gba->video.renderer->highlightBG[layer.id.index] = true; } break; + case LayerId::WINDOW: + m_vl->enableVideoLayer(m_vl, GBA_LAYER_WIN0 + layer.id.index, layer.enabled); + break; } } if (m_overrideBackdrop.isValid()) { @@ -286,6 +318,9 @@ void FrameView::updateTilesGB(bool) { m_queue.clear(); { CoreController::Interrupter interrupter(m_controller); + uint8_t* io = static_cast(m_controller->thread()->core->board)->memory.io; + GBRegisterLCDC lcdc = io[GB_REG_LCDC]; + for (int sprite = 0; sprite < 40; ++sprite) { ObjInfo info; lookupObj(sprite, &info); @@ -312,6 +347,22 @@ void FrameView::updateTilesGB(bool) { } } + if (GBRegisterLCDCIsWindow(lcdc)) { + m_queue.append({ + { LayerId::WINDOW }, + !m_disabled.contains({ LayerId::WINDOW }), + {}, + {}, {0, 0}, false, false + }); + } + + m_queue.append({ + { LayerId::BACKGROUND }, + !m_disabled.contains({ LayerId::BACKGROUND }), + {}, + {}, {0, 0}, false, false + }); + updateRendered(); } invalidateQueue(m_controller->screenDimensions()); @@ -328,6 +379,12 @@ void FrameView::injectGB() { mVideoLoggerInjectOAM(logger, layer.id.index << 2, 0); } break; + case LayerId::BACKGROUND: + m_vl->enableVideoLayer(m_vl, GB_LAYER_BACKGROUND, layer.enabled); + break; + case LayerId::WINDOW: + m_vl->enableVideoLayer(m_vl, GB_LAYER_WINDOW, layer.enabled); + break; } } } @@ -495,6 +552,11 @@ QString FrameView::LayerId::readable() const { break; case WINDOW: typeStr = tr("Window"); +#ifdef M_CORE_GBA + if (index == 2) { + return tr("Objwin"); + } +#endif break; case SPRITE: typeStr = tr("Sprite"); diff --git a/src/platform/qt/FrameView.h b/src/platform/qt/FrameView.h index 5074a42bf..c3054b2a7 100644 --- a/src/platform/qt/FrameView.h +++ b/src/platform/qt/FrameView.h @@ -72,7 +72,7 @@ private: int index = -1; bool operator!=(const LayerId& other) const { return other.type != type || other.index != index; } - operator uint() const { return (type << 8) | index; } + operator uint() const { return (type << 12) | (index & 0xFFF); } QString readable() const; }; @@ -112,10 +112,6 @@ private: ColorPicker m_backdropPicker; QColor m_overrideBackdrop; -#ifdef M_CORE_GBA - uint16_t m_gbaDispcnt; -#endif - std::shared_ptr m_callbackLocker{std::make_shared(true)}; }; diff --git a/src/platform/qt/MemoryView.cpp b/src/platform/qt/MemoryView.cpp index 23e727354..cf111c9c3 100644 --- a/src/platform/qt/MemoryView.cpp +++ b/src/platform/qt/MemoryView.cpp @@ -207,6 +207,9 @@ void MemoryView::setIndex(int index) { mCore* core = m_controller->thread()->core; const mCoreMemoryBlock* blocks; size_t nBlocks = core->listMemoryBlocks(core, &blocks); + if (index < 0 || static_cast(index) >= nBlocks) { + return; + } const mCoreMemoryBlock& info = blocks[index]; m_region = qMakePair(info.start, info.end); @@ -221,7 +224,11 @@ void MemoryView::setSegment(int segment) { mCore* core = m_controller->thread()->core; const mCoreMemoryBlock* blocks; size_t nBlocks = core->listMemoryBlocks(core, &blocks); - const mCoreMemoryBlock& info = blocks[m_ui.regions->currentIndex()]; + int index = m_ui.regions->currentIndex(); + if (index < 0 || static_cast(index) >= nBlocks) { + return; + } + const mCoreMemoryBlock& info = blocks[index]; m_ui.hexfield->setSegment(info.maxSegment < segment ? info.maxSegment : segment); } diff --git a/src/platform/qt/VideoProxy.cpp b/src/platform/qt/VideoProxy.cpp index 8a89ea533..3e8549d69 100644 --- a/src/platform/qt/VideoProxy.cpp +++ b/src/platform/qt/VideoProxy.cpp @@ -58,11 +58,16 @@ void VideoProxy::deinit() { bool VideoProxy::writeData(const void* data, size_t length) { while (!RingFIFOWrite(&m_dirtyQueue, data, length)) { - emit dataAvailable(); - m_mutex.lock(); - m_toThreadCond.wakeAll(); - m_fromThreadCond.wait(&m_mutex); - m_mutex.unlock(); + if (QThread::currentThread() == thread()) { + // We're on the main thread + mVideoLoggerRendererRun(&m_logger.d, false); + } else { + emit dataAvailable(); + m_mutex.lock(); + m_toThreadCond.wakeAll(); + m_fromThreadCond.wait(&m_mutex); + m_mutex.unlock(); + } } return true; } @@ -112,9 +117,14 @@ void VideoProxy::unlock() { void VideoProxy::wait() { m_mutex.lock(); while (RingFIFOSize(&m_dirtyQueue)) { - emit dataAvailable(); - m_toThreadCond.wakeAll(); - m_fromThreadCond.wait(&m_mutex, 1); + if (QThread::currentThread() == thread()) { + // We're on the main thread + mVideoLoggerRendererRun(&m_logger.d, false); + } else { + emit dataAvailable(); + m_toThreadCond.wakeAll(); + m_fromThreadCond.wait(&m_mutex, 1); + } } m_mutex.unlock(); } diff --git a/src/platform/qt/ts/medusa-emu-de.ts b/src/platform/qt/ts/medusa-emu-de.ts index b05656268..8682e073f 100644 --- a/src/platform/qt/ts/medusa-emu-de.ts +++ b/src/platform/qt/ts/medusa-emu-de.ts @@ -856,42 +856,42 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.&4 Bytes - + Signed Integer: Signed Integer: - + String: String: - + Load TBL TBL laden - + Copy Selection Auswahl kopieren - + Paste Einfügen - + Save Selection Auswahl speichern - + Save Range Bereich speichern - + Load Laden @@ -1085,7 +1085,7 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - + Autodetect Automatisch erkennen @@ -1121,7 +1121,6 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - None keiner @@ -1166,117 +1165,22 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Game Boy-Modell - - Game Boy (DMG) - Game Boy (DMG) - - - - Super Game Boy (SGB) - Super Game Boy (SGB) - - - - Game Boy Color (CGB) - Game Boy Color (CGB) - - - - Game Boy Advance (AGB) - Game Boy Advance (AGB) - - - + Memory bank controller Speicherbank-Controller - - MBC1 - MBC1 - - - - MBC2 - MBC2 - - - - MBC3 - MBC3 - - - - MBC3 + RTC - MBC3 + RTC - - - - MBC5 - MBC5 - - - - MBC5 + Rumble - MBC5 + Rumble - - - - MBC6 - MBC6 - - - - MBC7 - MBC7 - - - - MMM01 - MMM01 - - - - Pocket Cam - Pocket Cam - - - - TAMA5 - TAMA5 - - - - HuC-1 - HuC-1 - - - - HuC-3 - HuC-3 - - - - Wisdom Tree (Unlicensed) - Wisdom Tree (nicht lizenziert) - - - - Pokémon Jade/Diamond (Unlicensed) - Pokémon Jade/Diamond (nicht lizenziert) - - - + Background Colors Hintergrund-Farbpalette - + Sprite Colors 1 Sprite-Farbpalette 1 - + Sprite Colors 2 Sprite-Farbpalette 2 @@ -1421,6 +1325,11 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Magnification Vergrößerung + + + Copy + Kopieren + QGBA::AssetTile @@ -1430,9 +1339,9 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.%0%1%2 + + - - 0x%0 (%1) 0x%0 (%1) @@ -1440,12 +1349,12 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::CheatsModel - + (untitled) (unbenannt) - + Failed to open cheats file: %1 Fehler beim Öffnen der Cheat-Datei: %1 @@ -1483,22 +1392,22 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::CoreController - + Failed to open save file: %1 Fehler beim Öffnen der Speicherdatei: %1 - + Failed to open game file: %1 Fehler beim Öffnen der Spieldatei: %1 - + Failed to open snapshot file for reading: %1 Konnte Snapshot-Datei %1 nicht zum Lesen öffnen - + Failed to open snapshot file for writing: %1 Konnte Snapshot-Datei %1 nicht zum Schreiben öffnen @@ -1506,17 +1415,17 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::CoreManager - + Failed to open game file: %1 Fehler beim Öffnen der Spieldatei: %1 - + Could not load game. Are you sure it's in the correct format? Konnte das Spiel nicht laden. Bist Du sicher, dass es im korrekten Format vorliegt? - + Failed to open save file. Is the save directory writable? Fehler beim Öffnen der Speicherdatei. Ist das Zielverzeichnis beschreibbar? @@ -1524,42 +1433,52 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::FrameView - + Export frame Bild exportieren - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - + None Keine - + Background Hintergrund - + Window Fenster - + + Objwin + Objwin + + + Sprite Sprite - + Backdrop Hintergrund - + + Frame + Frame + + + %1 %2 %1 %2 @@ -1652,8 +1571,8 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - Graphics Interchange Format (*.gif);;Animated Portable Network Graphics (*.png *.webp *.apng) - Graphics Interchange Format (*.gif);;Animated Portable Network Graphics (*.png *.webp *.apng) + Graphics Interchange Format (*.gif);;WebP ( *.webp);;Animated Portable Network Graphics (*.png *.apng) + Graphics Interchange Format (*.gif);;WebP ( *.webp);;Animated Portable Network Graphics (*.png *.apng) @@ -3443,6 +3362,24 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Portable Network Graphics (*.png) + + QGBA::OverrideView + + + Official MBCs + Offizielle MBCs + + + + Licensed MBCs + Lizenzierte MBCs + + + + Unlicensed MBCs + Nicht lizenzierte MBCs + + QGBA::PaletteView @@ -3505,64 +3442,64 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::SettingsView - - + + Qt Multimedia Qt Multimedia - + SDL SDL - + Software (Qt) Software (Qt) - + OpenGL OpenGL - + OpenGL (force version 1.x) OpenGL (erzwinge Version 1.x) - + None (Still Image) Keiner (Standbild) - + Keyboard Tastatur - + Controllers Gamepads - + Shortcuts Tastenkürzel - - + + Shaders Shader - + Select BIOS BIOS auswählen - + (%1×%2) (%1×%2) @@ -3603,17 +3540,17 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::ShortcutModel - + Action Aktion - + Keyboard Tastatur - + Gamepad Gamepad @@ -3658,7 +3595,7 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::Window - + Game Boy Advance ROMs (%1) Game Boy Advance-ROMs (%1) @@ -3673,73 +3610,73 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Game Boy-ROMs (%1) - + All ROMs (%1) Alle ROMs (%1) - + %1 Video Logs (*.mvl) %1 Video-Logs (*.mvl) - + Archives (%1) Archive (%1) + - - + Select ROM ROM auswählen - + Game Boy Advance save files (%1) Game Boy Advance-Speicherdateien (%1) - - - + + + Select save Speicherdatei wählen - + mGBA savestate files (%1) mGBA Savestate-Dateien (%1) - - + + Select savestate Savestate auswählen - + Select patch Patch wählen - + Patches (*.ips *.ups *.bps) Patches (*.ips *.ups *.bps) - + Select image Bild auswählen - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Bild-Datei (*.png *.gif *.jpg *.jpeg);;Alle Dateien (*) - - + + GameShark saves (*.sps *.xps) GameShark-Speicherdaten (*.sps *.xps) @@ -3759,17 +3696,17 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Video-Log auswählen - + Video logs (*.mvl) Video-Logs (*.mvl) - + Crash Absturz - + The game has crashed with the following error: %1 @@ -3778,408 +3715,408 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - + Unimplemented BIOS call Nicht implementierter BIOS-Aufruf - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Dieses Spiel verwendet einen BIOS-Aufruf, der nicht implementiert ist. Bitte verwenden Sie für die beste Spielerfahrung das offizielle BIOS. - + Really make portable? Portablen Modus wirklich aktivieren? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? Diese Einstellung wird den Emulator so konfigurieren, dass er seine Konfiguration aus dem gleichen Verzeichnis wie die Programmdatei lädt. Möchten Sie fortfahren? - + Restart needed Neustart benötigt - + Some changes will not take effect until the emulator is restarted. Einige Änderungen werden erst übernommen, wenn der Emulator neu gestartet wurde. - + - Player %1 of %2 - Spieler %1 von %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 Bilder/Sekunde) - %4 - + &File &Datei - + Load &ROM... &ROM laden... - + Load ROM in archive... ROM aus Archiv laden... - + Load alternate save... Alternative Speicherdatei laden... - + Load temporary save... Temporäre Speicherdatei laden... - + Load &patch... &Patch laden... - + Boot BIOS BIOS booten - + Replace ROM... ROM ersetzen... - + ROM &info... ROM-&Informationen... - + Recent Zuletzt verwendet - + Make portable Portablen Modus aktivieren - + &Load state Savestate (aktueller Zustand) &laden - + Load state file... Savestate-Datei laden... - + &Save state Savestate (aktueller Zustand) &speichern - + Save state file... Savestate-Datei speichern... - + Quick load Schnell laden - + Quick save Schnell speichern - + Load recent Lade zuletzt gespeicherten Savestate - + Save recent Speichere aktuellen Zustand - + Undo load state Laden des Savestate rückgängig machen - + Undo save state Speichern des Savestate rückgängig machen - - + + State &%1 Savestate &%1 - + Load camera image... Lade Kamerabild... - + New multiplayer window Neues Multiplayer-Fenster - + E&xit &Beenden - + &Emulation &Emulation - + &Reset Zu&rücksetzen - + Sh&utdown Schli&eßen - + Yank game pak Spielmodul herausziehen - + &Pause &Pause - + &Next frame &Nächstes Bild - + Fast forward (held) Schneller Vorlauf (gehalten) - + &Fast forward Schneller &Vorlauf - + Fast forward speed Vorlauf-Geschwindigkeit - + Unbounded Unbegrenzt - + %0x %0x - + Rewind (held) Zurückspulen (gehalten) - + Re&wind Zur&ückspulen - + Step backwards Schrittweiser Rücklauf - + Sync to &video Mit &Video synchronisieren - + Sync to &audio Mit &Audio synchronisieren - + Solar sensor Sonnen-Sensor - + Increase solar level Sonnen-Level erhöhen - + Decrease solar level Sonnen-Level verringern - + Brightest solar level Hellster Sonnen-Level - + Darkest solar level Dunkelster Sonnen-Level - + Brightness %1 Helligkeit %1 - + BattleChip Gate... BattleChip Gate... - + Audio/&Video Audio/&Video - + Frame size Bildgröße - + Toggle fullscreen Vollbildmodus umschalten - + Lock aspect ratio Seitenverhältnis korrigieren - + Force integer scaling Pixelgenaue Skalierung (Integer scaling) - + Interframe blending Interframe-Überblendung - + Frame&skip Frame&skip - + Mute Stummschalten - + FPS target Bildwiederholrate - + Take &screenshot &Screenshot erstellen - + F12 F12 - + Clear Leeren - + Game Boy Printer... Game Boy Printer... - + Video layers Video-Ebenen - + Audio channels Audio-Kanäle - + Adjust layer placement... Lage der Bildebenen anpassen... - + &Tools &Werkzeuge - + View &logs... &Logs ansehen... - + Game &overrides... Spiel-&Überschreibungen... - + &Cheats... &Cheats... - + Open debugger console... Debugger-Konsole öffnen... - + Start &GDB server... &GDB-Server starten... - + Settings... Einstellungen... @@ -4204,107 +4141,107 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Ordner auswählen - + Select e-Reader dotcode e-Reader-Code auswählen - + e-Reader card (*.raw *.bin *.bmp) e-Reader-Karte (*.raw *.bin *.bmp) - + Couldn't Start Konnte nicht gestartet werden - + Could not start game. Spiel konnte nicht gestartet werden. - + Add folder to library... Ordner zur Bibliothek hinzufügen... - + Scan e-Reader dotcodes... e-Reader-Code einlesen... - + Import GameShark Save... GameShare-Speicherstand importieren... - + Export GameShark Save... GameShark-Speicherstand exportieren... - + About... Über... - + %1× %1x - + Bilinear filtering Bilineare Filterung - + Native (59.7275) Nativ (59.7275) - + Record A/V... Audio/Video aufzeichnen... - + Record GIF/WebP/APNG... GIF/WebP/APNG aufzeichnen... - + Game Pak sensors... Spielmodul-Sensoren... - + View &palette... &Palette betrachten... - + View &sprites... &Sprites betrachten... - + View &tiles... &Tiles betrachten... - + View &map... &Map betrachten... - + &Frame inspector... &Bildbetrachter... - + View memory... Speicher betrachten... @@ -4319,82 +4256,82 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Speicher durchsuchen... - + View &I/O registers... &I/O-Register betrachten... - + Record debug video log... Video-Protokoll aufzeichnen... - + Stop debug video log Aufzeichnen des Video-Protokolls beenden - + Exit fullscreen Vollbildmodus beenden - + GameShark Button (held) GameShark-Taste (gehalten) - + Autofire Autofeuer - + Autofire A Autofeuer A - + Autofire B Autofeuer B - + Autofire L Autofeuer L - + Autofire R Autofeuer R - + Autofire Start Autofeuer Start - + Autofire Select Autofeuer Select - + Autofire Up Autofeuer nach oben - + Autofire Right Autofeuer rechts - + Autofire Down Autofeuer nach unten - + Autofire Left Autofeuer links @@ -4730,7 +4667,7 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - + frames Bild(er) @@ -4802,31 +4739,41 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. + Dynamically update window title + Fenster-Titel dynamisch aktualisieren + + + Show FPS in title bar Bildwiederholrate in der Titelleiste anzeigen - + + Super Game Boy/Game Boy Color model: + Super Game Boy/Game Boy Color-Modell: + + + Automatically save cheats Cheats automatisch speichern - + Automatically load cheats Cheats automatisch laden - + Automatically save state Zustand (Savestate) automatisch speichern - + Automatically load state Zustand (Savestate) automatisch laden - + Enable Discord Rich Presence Discord-Integration aktivieren @@ -4836,153 +4783,123 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Pause, wenn minimiert - + Show OSD messages Bildschirmmeldungen anzeigen - + Show filename instead of ROM name in title bar Dateinamen statt ROM-Namen in der Titelleiste anzeigen - + Fast forward (held) speed: Vorlauf-Geschwindigkeit (halten): - + Video renderer: Video-Renderer: - + Software Software - + OpenGL OpenGL - + OpenGL enhancements OpenGL-Verbesserungen - + High-resolution scale: Hochauflösende Skalierung: - + XQ GBA audio (experimental) XQ GBA-Audio (experimentell) - + Cheats Cheats - + Log to file In Datei protokollieren - + Log to console Auf die Konsole protokollieren - + Select Log File Protokoll-Datei auswählen - + + Game Boy-only model: + Game Boy-Modell: + + + + Game Boy Color-only model: + Game Boy Color-Modell: + + + + Game Boy/Game Boy Color model: + Game Boy/Game Boy Color-Modell: + + + Camera: Kamera: - - - - Autodetect - Automatisch erkennen - - - - - - Game Boy (DMG) - Game Boy (DMG) - - - - - - Super Game Boy (SGB) - Super Game Boy (SGB) - - - - - - Game Boy Color (CGB) - Game Boy Color (CGB) - - - - - - Game Boy Advance (AGB) - Game Boy Advance (AGB) - - - + Default BG colors: Standard-Hintergrundfarben: - + Default sprite colors 1: Standard-Sprite-Farben 1: - + Default sprite colors 2: Standard-Sprite-Farben 2: - + Use GBC colors in GB games Verwende GBC-Farben in GB-Spielen - + Super Game Boy borders Super Game Boy-Rahmen - - Game Boy model: - Game Boy-Modell: - - - + Super Game Boy model: Super Game Boy-Modell: - - Game Boy Color model: - Game Boy Color-Modell: - - - + Camera driver: Kamera-Treiber: @@ -5002,26 +4919,26 @@ Titelleiste anzeigen Cache leeren - + Fast forward speed: Vorlauf-Geschwindigkeit: - + Preload entire ROM into memory ROM-Datei vollständig in Arbeitsspeicher vorladen - - - - - - - - - + + + + + + + + + Browse Durchsuchen @@ -5042,20 +4959,20 @@ in Arbeitsspeicher vorladen wenn vorhanden - + Skip BIOS intro BIOS-Intro überspringen - - - + + + × × - - + + Unbounded unbegrenzt @@ -5075,17 +4992,17 @@ wenn vorhanden Pause, wenn inaktiv - + Run all Alle ausführen - + Remove known Bekannte entfernen - + Detect and remove Erkennen und entfernen @@ -5095,25 +5012,25 @@ wenn vorhanden Gegensätzliche Eingaberichtungen erlauben - - + + Screenshot Screenshot - - + + Save data Speicherdaten - - + + Cheat codes Cheat-Codes - + Enable rewind Rücklauf aktivieren @@ -5123,47 +5040,47 @@ wenn vorhanden Bilineare Filterung - + Rewind history: Rücklauf-Verlauf: - + Idle loops: Leerlaufprozesse: - + Savestate extra data: Zusätzliche Savestate-Daten: - + Load extra data: Lade zusätzliche Daten: - + Autofire interval: Autofeuer-Intervall: - + (240×160) (240×160) - + GB BIOS file: Datei mit GB-BIOS: - + GBA BIOS file: Datei mit GBA-BIOS: - + GBC BIOS file: Datei mit GBC-BIOS: @@ -5178,31 +5095,31 @@ wenn vorhanden Datei mit SGB-BIOS: - + Save games Spielstände - - - - - + + + + + Same directory as the ROM Verzeichnis der ROM-Datei - + Save states Savestates - + Screenshots Screenshots - + Patches Patches diff --git a/src/platform/switch/CMakeLists.txt b/src/platform/switch/CMakeLists.txt index 2d98ad0a5..a8d27e96a 100644 --- a/src/platform/switch/CMakeLists.txt +++ b/src/platform/switch/CMakeLists.txt @@ -10,7 +10,6 @@ list(APPEND GUI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gui-font.c) include_directories(AFTER ${OPENGLES3_INCLUDE_DIR} ${OPENGL_EGL_INCLUDE_DIR}) -file(GLOB OS_SRC ${CMAKE_SOURCE_DIR}/src/platform/wii/wii-*.c) if(${CMAKE_BUILD_TYPE} STREQUAL Debug OR ${CMAKE_BUILD_TYPE} STREQUAL RelWithDebInfo) find_library(NOUVEAU_LIBRARY drm_nouveaud REQUIRED) list(APPEND OS_LIB nxd) @@ -20,7 +19,6 @@ else() endif() set(CORE_VFS_SRC ${CORE_VFS_SRC} PARENT_SCOPE) set(OS_DEFINES ${OS_DEFINES} PARENT_SCOPE) -set(OS_SRC ${OS_SRC} PARENT_SCOPE) set(OS_LIB ${OS_LIB} PARENT_SCOPE) if(BUILD_PERF) diff --git a/src/platform/wii/CMakeLists.txt b/src/platform/wii/CMakeLists.txt index fc69083d2..8d1a60e87 100644 --- a/src/platform/wii/CMakeLists.txt +++ b/src/platform/wii/CMakeLists.txt @@ -8,9 +8,7 @@ list(APPEND CORE_VFS_SRC ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-file.c ${CMAKE_SOU include_directories(${CMAKE_CURRENT_BINARY_DIR}) -file(GLOB OS_SRC ${CMAKE_SOURCE_DIR}/src/platform/wii/wii-*.c) list(APPEND OS_LIB wiiuse bte fat ogc) -set(OS_SRC ${OS_SRC} PARENT_SCOPE) set(OS_LIB ${OS_LIB} PARENT_SCOPE) source_group("Wii-specific code" FILES ${OS_SRC}) set(CORE_VFS_SRC ${CORE_VFS_SRC} PARENT_SCOPE) diff --git a/src/platform/wii/wii-memory.c b/src/platform/wii/wii-memory.c deleted file mode 100644 index 419b58f9a..000000000 --- a/src/platform/wii/wii-memory.c +++ /dev/null @@ -1,15 +0,0 @@ -/* Copyright (c) 2013-2015 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 - -void* anonymousMemoryMap(size_t size) { - return malloc(size); -} - -void mappedMemoryFree(void* memory, size_t size) { - UNUSED(size); - free(memory); -} diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index b4e7e1b0b..c9e074389 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -30,10 +30,15 @@ set(TEST_FILES test/text-codec.c test/vfs.c) +if(NOT DEFINED OS_SRC) + set(OS_FILES memory.c) + export_directory(OS OS_FILES) +endif() + source_group("Utilities" FILES ${SOURCE_FILES}) source_group("GUI source" FILES ${GUI_FILES}) source_group("Utilities tests" FILES ${TEST_FILES}) export_directory(UTIL SOURCE_FILES) export_directory(GUI GUI_FILES) -export_directory(UTIL_TEST TEST_FILES) \ No newline at end of file +export_directory(UTIL_TEST TEST_FILES) diff --git a/src/platform/switch/memory.c b/src/util/memory.c similarity index 84% rename from src/platform/switch/memory.c rename to src/util/memory.c index 6459d6abb..89646d3bc 100644 --- a/src/platform/switch/memory.c +++ b/src/util/memory.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2018 Jeffrey Pfau +/* Copyright (c) 2013-2020 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 @@ -6,7 +6,7 @@ #include void* anonymousMemoryMap(size_t size) { - return malloc(size); + return calloc(1, size); } void mappedMemoryFree(void* memory, size_t size) {