diff --git a/CHANGES b/CHANGES index 620cc609b..c53953535 100644 --- a/CHANGES +++ b/CHANGES @@ -37,7 +37,11 @@ Misc: Features: - e-Reader card scanning - Add WebP and APNG recording + - Add mute option in homebrew ports + - Add status indicators for fast-forward and mute in homebrew ports - Support for unlicensed Pokemon Jade/Diamond Game Boy mapper + - Support for unlicensed BBD Game Boy mapper + - Support for unlicensed Hitek Game Boy mapper - Stack tracing tools in ARM debugger (by ahigerd) - Command scripts for CLI debugger (by ahigerd) Emulation fixes: @@ -47,15 +51,21 @@ Emulation fixes: - 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 Video: Fix state after skipping BIOS (fixes mgba.io/i/1715 and mgba.io/i/1716) - GBA: Fix timing advancing too quickly in rare cases - 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 - GBA BIOS: Fix reloading video registers after reset (fixes mgba.io/i/1808) - 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 Memory: Improve gamepak prefetch timing - GBA Memory: Stall on VRAM access in mode 2 (fixes mgba.io/i/190) - GBA SIO: Fix copying Normal mode transfer values @@ -64,21 +74,27 @@ Emulation fixes: - 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) - 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) - 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 - mGUI: Fix closing down a game if an exit is signalled - mVL: Fix injecting accidentally draining non-injection buffer - SM83: Simplify register pair access on big endian @@ -93,7 +109,9 @@ Misc: - Qt: Renderer can be changed while a game is running - Qt: Add hex index to palette view - Qt: Add transformation matrix info to sprite view + - Qt: Memory viewer now supports editing decimal values directly (closes mgba.io/i/1705) - Util: Reset vector size on deinit + - VFS: Change semantics of VFile.sync on mapped files (fixes mgba.io/i/1730) 0.8.3: (2020-08-03) Emulation fixes: diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ea562456..a2e353a9c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1137,7 +1137,7 @@ if(DISTBUILD) elseif(WII) set(CPACK_COMPONENTS_ALL ${BINARY_NAME} ${BINARY_NAME}-dbg ${BINARY_NAME}-wii ${BINARY_NAME}-perf) elseif(PSP2) - set(CPACK_COMPONENTS_ALL ${BINARY_NAME} ${BINARY_NAME}-dbg ${BINARY_NAME}-psp2) + set(CPACK_COMPONENTS_ALL ${BINARY_NAME} ${BINARY_NAME}-dbg ${BINARY_NAME}-psp2 ${BINARY_NAME}-perf) elseif(SWITCH) set(CPACK_COMPONENTS_ALL ${BINARY_NAME} ${BINARY_NAME}-dbg ${BINARY_NAME}-switch) endif() diff --git a/README.md b/README.md index 9d276e453..84356ece8 100644 --- a/README.md +++ b/README.md @@ -53,21 +53,23 @@ The following mappers are fully supported: - MBC7 - Wisdom Tree (unlicensed) - Pokémon Jade/Diamond (unlicensed) +- BBD (unlicensed MBC5-like) +- Hitek (unlicensed MBC5-like) The following mappers are partially supported: -- MBC6 +- MBC6 (missing flash memory support) - MMM01 - Pocket Cam -- TAMA5 -- HuC-1 -- HuC-3 +- TAMA5 (missing RTC support) +- HuC-1 (missing IR support) +- HuC-3 (missing RTC and IR support) ### Planned features - Networked multiplayer link cable support. - Dolphin/JOY bus link cable support. -- M4A audio mixing, for higher quality sound than hardware. +- MP2k audio mixing, for higher quality sound than hardware. - Re-recording support for tool-assist runs. - Lua support for scripting. - A comprehensive debug suite. diff --git a/README_DE.md b/README_DE.md index 0847bbe3b..781aaa284 100644 --- a/README_DE.md +++ b/README_DE.md @@ -27,7 +27,7 @@ Features - Unterstützung für Screenshots. - Unterstützung für Cheat-Codes. - 9 Speicherstände für Savestates/Spielzustände. Savestates können auch als Screenshots dargestellt werden. -- Video- und GIF-Aufzeichnung. +- Video-, GIF-, WebP- und APNG-Aufzeichnung. - e-Reader-Unterstützung. - Frei wählbare Tastenbelegungen für Tastaturen und Controller. - Unterstützung für ZIP- und 7z-Archive. @@ -51,21 +51,24 @@ Die folgenden Mapper werden vollständig unterstützt: - MBC5+Rumble (MBC5+Rüttel-Modul) - MBC7 - Wisdom Tree (nicht lizenziert) +- Pokémon Jade/Diamond (nicht lizenziert) +- BBD (nicht lizenziert, ählich MBC5) +- Hitek (nicht lizenziert, ähnlich MBC5) Die folgenden Mapper werden teilweise unterstützt: -- MBC6 +- MBC6 (fehlende Flash-Unterstützung) - MMM01 - Pocket Cam -- TAMA5 -- HuC-1 -- HuC-3 +- TAMA5 (fehlende RTC-Unterstützung) +- HuC-1 (fehlende Infrarot-Unterstützung) +- HuC-3 (fehlende RTC- und Infrarot-Unterstützung) ### Geplante Features - Unterstützung für Link-Kabel-Multiplayer über ein Netzwerk. - Unterstützung für Link-Kabel über Dolphin/JOY-Bus. -- M4A-Audio-Abmischung für höhere Audio-Qualität als echte Hardware. +- MP2k-Audio-Abmischung für höhere Audio-Qualität als echte Hardware. - Unterstützung für Tool-Assisted Speedruns. - Lua-Unterstützung für Scripting. - Eine umfangreiche Debugging-Suite. @@ -75,10 +78,11 @@ Unterstützte Plattformen ------------------------ - Windows Vista oder neuer -- OS X 10.7 (Lion)[[3]](#osxver) oder neuer +- OS X 10.8 (Mountain Lion)[[3]](#osxver) oder neuer - Linux - FreeBSD - Nintendo 3DS +- Nintendo Switch - Wii - PlayStation Vita @@ -112,7 +116,7 @@ Um mGBA kompilieren zu können, wird CMake 3.1 oder neuer benötigt. GCC und Cla #### Kompilieren mit Docker -Der empfohlene Weg, um mGBA für die meisten Plattformen zu kompilieren, ist Docker. Mehrere Docker-Images sind verfügbar, welche die benötigte Compiler-Umgebung und alle benötigten Abhängigkeiten beinhaltet, um mGBA für verschiedene Plattformen zu bauen. +Der empfohlene Weg, um mGBA für die meisten Plattformen zu kompilieren, ist die Verwendung von Docker. Mehrere Docker-Images sind verfügbar, welche die benötigte Compiler-Umgebung und alle benötigten Abhängigkeiten beinhaltet, um mGBA für verschiedene Plattformen zu bauen. Um ein Docker-Image zum Bau von mGBA zu verwenden, führe einfach folgenden Befehl in dem Verzeichnis aus, in welches Du den mGBA-Quellcode ausgecheckt hast: @@ -150,12 +154,14 @@ Wenn Du macOS verwendest, sind die einzelnen Schritte etwas anders. Angenommen, brew install cmake ffmpeg libzip qt5 sdl2 libedit pkg-config mkdir build cd build - cmake -DCMAKE_PREFIX_PATH='brew --prefix qt5' .. + cmake -DCMAKE_PREFIX_PATH=`brew --prefix qt5` .. make -Bitte beachte, dass Du unter macOS nicht 'make install' verwenden solltest, da dies nicht korrekt funktionieren wird. +Bitte beachte, dass Du unter macOS nicht `make install` verwenden solltest, da dies nicht korrekt funktionieren wird. -### Für Entwickler: Kompilieren unter Windows +#### Für Entwickler: Kompilieren unter Windows + +##### MSYS2 Um mGBA auf Windows zu kompilieren, wird MSYS2 empfohlen. Befolge die Installationsschritte auf der [MSYS2-Website](https://msys2.github.io). Stelle sicher, dass Du die 32-Bit-Version ("MSYS2 MinGW 32-bit") (oder die 64-Bit-Version "MSYS2 MinGW 64-bit", wenn Du mGBA für x86_64 kompilieren willst) verwendest und führe folgendes Kommando (einschließlich der Klammern) aus, um alle benötigten Abhängigkeiten zu installieren. Bitte beachte, dass dafür über 1100MiB an Paketen heruntergeladen werden, was eine Weile dauern kann: @@ -181,6 +187,20 @@ Abschließend wird mGBA über folgende Kommandos kompiliert: Bitte beachte, dass mGBA für Windows aufgrund der Vielzahl an benötigten DLLs nicht für die weitere Verteilung geeignet ist, wenn es auf diese Weise gebaut wurde. Es ist jedoch perfekt für Entwickler geeignet. Soll mGBA dennoch weiter verteilt werden (beispielsweise zu Testzwecken auf Systemen, auf denen keine MSYS2-Umgebung installiert ist), kann mithilfe des Befehls `cpack -G ZIP` ein ZIP-Archiv mit allen benötigten DLLs erstellt werden. +##### Visual Studio + +mGBA mit Visual Studio zu bauen erfordert ein ähnlich kompliziertes Setup. Zuerst musst Du [vcpkg](https://github.com/Microsoft/vcpkg) installieren. Nachdem vcpkg installiert ist, musst Du noch folgende zusätzlichen Pakete installieren: + + vcpkg install ffmpeg[vpx,x264] libepoxy libpng libzip sdl2 sqlite3 + +Bitte beachte, dass diese Installation keine hardwarebeschleunigtes Video-Encoding auf Nvidia-Hardware unterstützen wird. Wenn Du darauf Wert legst, musst Du zuerst CUDA installieren und anschließend den vorherigen Befehl um `ffmpeg[vpx,x264,nvcodec]` ergänzen. + +Zusätzlich wirst Du auch Qt installieren müssen. Unglücklicherweise steht für Qt kein Offline-Installationsprogramm für die jeweils aktuelle Version bereit. Daher musst Du entweder auf eine [ältere Version](https://download.qt.io/official_releases/qt/5.12/5.12.9/qt-opensource-windows-x86-5.12.9.exe) zurückgreifen (hierfür benötigst Du ein ansonsten nutzloses Benutzerkonto, aber Du kannst das umgehen, indem Du temporär einen ungültigen Netzwerk-Proxy hinterlegst oder über andere Methoden deine Netzwerkverbindung deaktivierst). Alternativ kannst Du auch den Online-Installer nutzen (für den ohnehin ein Benutzeraccount erfortderlich ist) oder Qt selbst mithilfe von vcpkg bauen (was verhältnismäßig lange dauert). Keine dieser Optionen ist besonders elegant. Bitte achte bei der Verwendung eines Installers darauf, die passende MSVC-Version zu wählen. Der Offline-Installer unterstützt aktuell noch nicht MSVC 2019. Die Installation mit vcpkg dauert ein wenig länger, besonders, wenn Du einen Computer mit vier oder weniger CPU-Cores nutzt: + + vcpkg install qt5-base qt5-multimedia + +Öffne anschließend Visual Studio, wähle "Clone Repository" und gib dort `https://github.com/mgba-emu/mgba.git` ein. Wenn Visual Studio das Repository geklont hat, gehe zu "Datei > CMake" und öffne die Datei CMakeLists.txt im Stammverzeichnis des ausgecheckten Repos. Anschließend kann mGBA in Visual Studio entwickelt werden, ähnlich wie andere Visual Studio CMake-Projekte. + #### Kompilieren mithilfe einer Toolchain Wenn Du devkitARM (für 3DS), devkitPPC (für Wii), devkitA64 (für Switch) oder vitasdk (für PS Vita) installiert hast, kannst Du die folgenden Befehle zum Kompilieren verwenden: @@ -207,7 +227,6 @@ mGBA hat keine "harten" Abhängigkeiten. Dennoch werden die folgenden optionalen - libedit: Für die Unterstützung des Kommandozeilen-Debuggers. - ffmpeg oder libav: Für Videoaufzeichnungen. - libzip oder zlib: Um ROMs aus ZIP-Dateien zu laden. -- ImageMagick: Für GIF-Aufzeichnungen. - SQLite3: Für Spiele-Datenbanken. - libelf: Für das Laden von ELF-Dateien. @@ -222,7 +241,7 @@ Fußnoten [2] In manchen Fällen ist es nicht möglich, die Größe des Flash-Speichers automatisch zu ermitteln. Diese kann dann zur Laufzeit konfiguriert werden, es wird jedoch empfohlen, den Fehler zu melden. -[3] 10.7 wird nur für die Qt-Portierung benötigt. Die SDL-Portierung ist dafür bekannt, mit 10.5 und möglicherweise auf älteren Versionen zu funktionieren. +[3] 10.8 wird nur für die Qt-Portierung benötigt. Es ist wahrscheinlich möglich, die Qt-Portierung unter macOS 10.7 und älter zu bauen und zu nutzen, aber das wird nicht offiziell unterstützt. Die SDL-Portierung ist dafür bekannt, mit 10.7 und möglicherweise auf älteren Versionen zu funktionieren. [downloads]: http://mgba.io/downloads.html [source]: https://github.com/mgba-emu/mgba/ @@ -234,7 +253,7 @@ Copyright für mGBA © 2013 – 2020 Jeffrey Pfau. mGBA wird unter der [Mozilla mGBA beinhaltet die folgenden Bibliotheken von Drittanbietern: -- [inih](https://github.com/benhoyt/inih), Copyright © 2009 Ben Hoyt, verwendet unter einer BSD 3-clause-Lizenz. +- [inih](https://github.com/benhoyt/inih), Copyright © 2009 - 2020 Ben Hoyt, verwendet unter einer BSD 3-clause-Lizenz. - [blip-buf](https://code.google.com/archive/b/blip-buf), Copyright © 2003 - 2009 Shay Green, verwendet unter einer Lesser GNU Public License. - [LZMA SDK](http://www.7-zip.org/sdk.html), Public Domain. - [MurmurHash3](https://github.com/aappleby/smhasher), Implementierung von Austin Appleby, Public Domain. diff --git a/include/mgba-util/common.h b/include/mgba-util/common.h index 6048a70fc..dfd2a11ff 100644 --- a/include/mgba-util/common.h +++ b/include/mgba-util/common.h @@ -129,31 +129,32 @@ typedef intptr_t ssize_t; #define LOAD_32BE(DEST, ADDR, ARR) DEST = *(uint32_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) #if defined(__PPC__) || defined(__POWERPC__) #define LOAD_32LE(DEST, ADDR, ARR) { \ - uint32_t _addr = (ADDR); \ + size_t _addr = (ADDR); \ const void* _ptr = (ARR); \ __asm__("lwbrx %0, %1, %2" : "=r"(DEST) : "b"(_ptr), "r"(_addr)); \ } #define LOAD_16LE(DEST, ADDR, ARR) { \ - uint32_t _addr = (ADDR); \ + size_t _addr = (ADDR); \ const void* _ptr = (ARR); \ __asm__("lhbrx %0, %1, %2" : "=r"(DEST) : "b"(_ptr), "r"(_addr)); \ } #define STORE_32LE(SRC, ADDR, ARR) { \ - uint32_t _addr = (ADDR); \ + size_t _addr = (ADDR); \ void* _ptr = (ARR); \ __asm__("stwbrx %0, %1, %2" : : "r"(SRC), "b"(_ptr), "r"(_addr) : "memory"); \ } #define STORE_16LE(SRC, ADDR, ARR) { \ - uint32_t _addr = (ADDR); \ + size_t _addr = (ADDR); \ void* _ptr = (ARR); \ __asm__("sthbrx %0, %1, %2" : : "r"(SRC), "b"(_ptr), "r"(_addr) : "memory"); \ } +#ifndef _ARCH_PWR7 #define LOAD_64LE(DEST, ADDR, ARR) { \ - uint32_t _addr = (ADDR); \ + size_t _addr = (ADDR); \ union { \ struct { \ uint32_t hi; \ @@ -170,7 +171,7 @@ typedef intptr_t ssize_t; } #define STORE_64LE(SRC, ADDR, ARR) { \ - uint32_t _addr = (ADDR); \ + size_t _addr = (ADDR); \ union { \ struct { \ uint32_t hi; \ @@ -184,6 +185,19 @@ typedef intptr_t ssize_t; "stwbrx %1, %2, %4 \n" \ : : "r"(bswap.hi), "r"(bswap.lo), "b"(_ptr), "r"(_addr), "r"(_addr + 4) : "memory"); \ } +#else +#define LOAD_64LE(DEST, ADDR, ARR) { \ + size_t _addr = (ADDR); \ + const void* _ptr = (ARR); \ + __asm__("ldbrx %0, %1, %2" : "=r"(DEST) : "b"(_ptr), "r"(_addr)); \ +} + +#define STORE_64LE(SRC, ADDR, ARR) { \ + size_t _addr = (ADDR); \ + void* _ptr = (ARR); \ + __asm__("stdbrx %0, %1, %2" : : "r"(SRC), "b"(_ptr), "r"(_addr) : "memory"); \ +} +#endif #elif defined(__llvm__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) #define LOAD_64LE(DEST, ADDR, ARR) DEST = __builtin_bswap64(((uint64_t*) ARR)[(ADDR) >> 3]) diff --git a/include/mgba-util/gui/font.h b/include/mgba-util/gui/font.h index 3ace00071..7f1ba34ce 100644 --- a/include/mgba-util/gui/font.h +++ b/include/mgba-util/gui/font.h @@ -53,6 +53,8 @@ enum GUIIcon { GUI_ICON_BUTTON_TRIANGLE, GUI_ICON_BUTTON_SQUARE, GUI_ICON_BUTTON_HOME, + GUI_ICON_STATUS_FAST_FORWARD, + GUI_ICON_STATUS_MUTE, GUI_ICON_MAX, }; diff --git a/include/mgba-util/platform/3ds/threading.h b/include/mgba-util/platform/3ds/threading.h index 27e2b39d1..dfc03342d 100644 --- a/include/mgba-util/platform/3ds/threading.h +++ b/include/mgba-util/platform/3ds/threading.h @@ -69,12 +69,14 @@ static inline int ThreadCreate(Thread* thread, ThreadEntry entry, void* context) if (!entry || !thread) { return 1; } - *thread = threadCreate(entry, context, 0x8000, 0x18, 2, true); + *thread = threadCreate(entry, context, 0x8000, 0x18, 2, false); return !*thread; } static inline int ThreadJoin(Thread* thread) { - return threadJoin(*thread, U64_MAX); + Result res = threadJoin(*thread, U64_MAX); + threadFree(*thread); + return res; } static inline void ThreadSetName(const char* name) { diff --git a/include/mgba-util/socket.h b/include/mgba-util/socket.h index aecbe9959..377d53a2e 100644 --- a/include/mgba-util/socket.h +++ b/include/mgba-util/socket.h @@ -64,6 +64,10 @@ extern u32* SOCUBuffer; #ifdef __SWITCH__ #include #endif +#ifdef PSP2 +#include +#include +#endif static inline void SocketSubsystemInit() { #ifdef _WIN32 @@ -78,6 +82,10 @@ static inline void SocketSubsystemInit() { socketInitializeDefault(); #elif defined(GEKKO) net_init(); +#elif defined(PSP2) + static uint8_t netMem[1024*1024]; + sceSysmoduleLoadModule(SCE_SYSMODULE_NET); + sceNetInit(&(SceNetInitParam) { netMem, sizeof(netMem) }); #endif } @@ -92,6 +100,9 @@ static inline void SocketSubsystemDeinit() { socketExit(); #elif defined(GEKKO) net_deinit(); +#elif defined(PSP2) + sceNetTerm(); + sceSysmoduleUnloadModule(SCE_SYSMODULE_NET); #endif } @@ -249,6 +260,11 @@ static inline Socket SocketListen(Socket socket, int queueLength) { #ifdef GEKKO return net_listen(socket, queueLength); #else +#ifdef PSP2 + if (queueLength <= 0) { + queueLength = 1; + } +#endif return listen(socket, queueLength); #endif } diff --git a/include/mgba-util/table.h b/include/mgba-util/table.h index bd8d62993..8e668b767 100644 --- a/include/mgba-util/table.h +++ b/include/mgba-util/table.h @@ -17,9 +17,10 @@ struct Table { size_t tableSize; size_t size; void (*deinitializer)(void*); + uint32_t seed; }; -void TableInit(struct Table*, size_t initialSize, void (deinitializer(void*))); +void TableInit(struct Table*, size_t initialSize, void (*deinitializer)(void*)); void TableDeinit(struct Table*); void* TableLookup(const struct Table*, uint32_t key); @@ -28,10 +29,10 @@ void TableInsert(struct Table*, uint32_t key, void* value); void TableRemove(struct Table*, uint32_t key); void TableClear(struct Table*); -void TableEnumerate(const struct Table*, void (handler(uint32_t key, void* value, void* user)), void* user); +void TableEnumerate(const struct Table*, void (*handler)(uint32_t key, void* value, void* user), void* user); size_t TableSize(const struct Table*); -void HashTableInit(struct Table* table, size_t initialSize, void (deinitializer(void*))); +void HashTableInit(struct Table* table, size_t initialSize, void (*deinitializer)(void*)); void HashTableDeinit(struct Table* table); void* HashTableLookup(const struct Table*, const char* key); @@ -43,8 +44,9 @@ void HashTableRemove(struct Table*, const char* key); void HashTableRemoveBinary(struct Table*, const void* key, size_t keylen); void HashTableClear(struct Table*); -void HashTableEnumerate(const struct Table*, void (handler(const char* key, void* value, void* user)), void* user); -const char* HashTableSearch(const struct Table* table, bool (predicate(const char* key, const void* value, const void* user)), const void* user); +void HashTableEnumerate(const struct Table*, void (*handler)(const char* key, void* value, void* user), void* user); +void HashTableEnumerateBinary(const struct Table*, void (*handler)(const char* key, size_t keylen, void* value, void* user), void* user); +const char* HashTableSearch(const struct Table* table, bool (*predicate)(const char* key, const void* value, const void* user), const void* user); const char* HashTableSearchPointer(const struct Table* table, const void* value); const char* HashTableSearchData(const struct Table* table, const void* value, size_t bytes); const char* HashTableSearchString(const struct Table* table, const char* value); diff --git a/include/mgba-util/vfs.h b/include/mgba-util/vfs.h index 0ac676d5f..8100541e0 100644 --- a/include/mgba-util/vfs.h +++ b/include/mgba-util/vfs.h @@ -47,7 +47,7 @@ struct VFile { void (*unmap)(struct VFile* vf, void* memory, size_t size); void (*truncate)(struct VFile* vf, size_t size); ssize_t (*size)(struct VFile* vf); - bool (*sync)(struct VFile* vf, const void* buffer, size_t size); + bool (*sync)(struct VFile* vf, void* buffer, size_t size); }; struct VDirEntry { diff --git a/include/mgba/core/serialize.h b/include/mgba/core/serialize.h index afbf8de54..968f3f16f 100644 --- a/include/mgba/core/serialize.h +++ b/include/mgba/core/serialize.h @@ -36,7 +36,7 @@ struct mStateExtdata { struct mStateExtdataItem data[EXTDATA_MAX]; }; -bool mStateExtdataInit(struct mStateExtdata*); +void mStateExtdataInit(struct mStateExtdata*); void mStateExtdataDeinit(struct mStateExtdata*); void mStateExtdataPut(struct mStateExtdata*, enum mStateExtdataTag, struct mStateExtdataItem*); bool mStateExtdataGet(struct mStateExtdata*, enum mStateExtdataTag, struct mStateExtdataItem*); @@ -49,6 +49,7 @@ struct mCore; bool mCoreSaveStateNamed(struct mCore* core, struct VFile* vf, int flags); bool mCoreLoadStateNamed(struct mCore* core, struct VFile* vf, int flags); void* mCoreExtractState(struct mCore* core, struct VFile* vf, struct mStateExtdata* extdata); +bool mCoreExtractExtdata(struct mCore* core, struct VFile* vf, struct mStateExtdata* extdata); CXX_GUARD_END diff --git a/include/mgba/gb/interface.h b/include/mgba/gb/interface.h index 99c4fb01b..c834f5d78 100644 --- a/include/mgba/gb/interface.h +++ b/include/mgba/gb/interface.h @@ -38,6 +38,8 @@ enum GBMemoryBankControllerType { GB_MBC5_RUMBLE = 0x105, GB_UNL_WISDOM_TREE = 0x200, GB_UNL_PKJD = 0x203, + GB_UNL_BBD = 0x220, // Also used as a mask for MBCs that need special read behavior + GB_UNL_HITEK = 0x221, }; struct GBSIODriver { diff --git a/include/mgba/internal/gb/memory.h b/include/mgba/internal/gb/memory.h index ca55b672c..676a8d5bb 100644 --- a/include/mgba/internal/gb/memory.h +++ b/include/mgba/internal/gb/memory.h @@ -150,6 +150,11 @@ struct GBPKJDState { uint8_t reg[2]; }; +struct GBBBDState { + int dataSwapMode; + int bankSwapMode; +}; + union GBMBCState { struct GBMBC1State mbc1; struct GBMBC6State mbc6; @@ -158,6 +163,7 @@ union GBMBCState { struct GBPocketCamState pocketCam; struct GBTAMA5State tama5; struct GBPKJDState pkjd; + struct GBBBDState bbd; }; struct mRotationSource; diff --git a/include/mgba/internal/gb/serialize.h b/include/mgba/internal/gb/serialize.h index 6df5d2859..c7d1532be 100644 --- a/include/mgba/internal/gb/serialize.h +++ b/include/mgba/internal/gb/serialize.h @@ -391,6 +391,10 @@ struct GBSerializedState { uint8_t locked; uint8_t bank0; } mmm01; + struct { + uint8_t dataSwapMode; + uint8_t bankSwapMode; + } bbd; struct { uint8_t reserved[16]; } padding; diff --git a/include/mgba/internal/gba/audio.h b/include/mgba/internal/gba/audio.h index f08f845b6..212e1b860 100644 --- a/include/mgba/internal/gba/audio.h +++ b/include/mgba/internal/gba/audio.h @@ -15,6 +15,8 @@ CXX_GUARD_START #include #include +#define GBA_AUDIO_FIFO_SIZE 8 + #define MP2K_MAGIC 0x68736D53 #define MP2K_MAX_SOUND_CHANNELS 12 @@ -26,7 +28,11 @@ extern const unsigned GBA_AUDIO_SAMPLES; extern const int GBA_AUDIO_VOLUME_MAX; struct GBAAudioFIFO { - struct CircleBuffer fifo; + uint32_t fifo[GBA_AUDIO_FIFO_SIZE]; + int fifoWrite; + int fifoRead; + uint32_t internalSample; + int internalRemaining; int dmaSource; int8_t sample; }; @@ -298,7 +304,7 @@ void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value); void GBAAudioWriteSOUNDBIAS(struct GBAAudio* audio, uint16_t value); void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value); -void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value); +uint32_t GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value); void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles); struct GBASerializedState; diff --git a/include/mgba/internal/gba/serialize.h b/include/mgba/internal/gba/serialize.h index 24cc1b85c..2b372e51d 100644 --- a/include/mgba/internal/gba/serialize.h +++ b/include/mgba/internal/gba/serialize.h @@ -20,7 +20,7 @@ extern const uint32_t GBA_SAVESTATE_VERSION; mLOG_DECLARE_CATEGORY(GBA_STATE); /* Savestate format: - * 0x00000 - 0x00003: Version Magic (0x01000001) + * 0x00000 - 0x00003: Version Magic (0x01000004) * 0x00004 - 0x00007: BIOS checksum (e.g. 0xBAAE187F for official BIOS) * 0x00008 - 0x0000B: ROM CRC32 * 0x0000C - 0x0000F: Master cycles @@ -69,10 +69,16 @@ mLOG_DECLARE_CATEGORY(GBA_STATE); * 0x0018C - 0x001AB: Audio FIFO 1 * 0x001AC - 0x001CB: Audio FIFO 2 * 0x001CC - 0x001DF: Audio miscellaneous state - * | 0x001CC - 0x001CF: FIFO 1 size - * | 0x001D0 - 0x001D3: Reserved + * | 0x001CC - 0x001CF: Channel A internal audio samples + * | 0x001D0 - 0x001D3: Channel B internal audio samples * | 0x001D4 - 0x001D7: Next sample - * | 0x001D8 - 0x001DB: FIFO 2 size + * | 0x001D8: Channel A current sample + * | 0x001D9: Channel B current sample + * | 0x001DA - 0x001DB: Flags + * | bits 0 - 1: Channel B internal samples remaining + * | bits 2 - 4: Channel B readable words + * | bits 5 - 6: Channel A internal samples remaining + * | bits 7 - 9: Channel A readable words * | TODO: Fix this, they're in big-endian order, but field is little-endian * | 0x001DC - 0x001DC: Channel 1 envelope state * | bits 0 - 3: Current volume @@ -217,6 +223,12 @@ mLOG_DECLARE_CATEGORY(GBA_STATE); * Total size: 0x61000 (397,312) bytes */ +DECL_BITFIELD(GBASerializedAudioFlags, uint16_t); +DECL_BITS(GBASerializedAudioFlags, FIFOInternalSamplesB, 0, 2); +DECL_BITS(GBASerializedAudioFlags, FIFOSamplesB, 2, 3); // Yay legacy? +DECL_BITS(GBASerializedAudioFlags, FIFOInternalSamplesA, 5, 2); +DECL_BITS(GBASerializedAudioFlags, FIFOSamplesA, 7, 3); + DECL_BITFIELD(GBASerializedVideoFlags, uint32_t); DECL_BITS(GBASerializedVideoFlags, Mode, 0, 2); @@ -267,12 +279,14 @@ struct GBASerializedState { struct { struct GBSerializedPSGState psg; - uint8_t fifoA[32]; - uint8_t fifoB[32]; - uint32_t fifoSizeA; - int32_t reserved; + uint32_t fifoA[8]; + uint32_t fifoB[8]; + uint32_t internalA; + uint32_t internalB; int32_t nextSample; - uint32_t fifoSizeB; + int8_t sampleA; + int8_t sampleB; + GBASerializedAudioFlags gbaFlags; GBSerializedAudioFlags flags; } audio; diff --git a/res/font-new.png b/res/font-new.png index 1e7876a33..66389c44b 100644 Binary files a/res/font-new.png and b/res/font-new.png differ diff --git a/res/icons.png b/res/icons.png index d953c5588..1a2b57407 100644 Binary files a/res/icons.png and b/res/icons.png differ diff --git a/res/icons2x.png b/res/icons2x.png index ddd0f9647..31f4945e8 100644 Binary files a/res/icons2x.png and b/res/icons2x.png differ diff --git a/src/core/core.c b/src/core/core.c index 1d2e0523e..af59439b9 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -400,9 +400,11 @@ bool mCoreLoadELF(struct mCore* core, struct ELF* elf) { if (block && bsize >= phdr->p_filesz && esize > phdr->p_offset && esize >= phdr->p_filesz + phdr->p_offset) { memcpy(block, &bytes[phdr->p_offset], phdr->p_filesz); } else { + ELFProgramHeadersDeinit(&ph); return false; } } + ELFProgramHeadersDeinit(&ph); return true; } diff --git a/src/core/serialize.c b/src/core/serialize.c index f194cd759..d7bd65144 100644 --- a/src/core/serialize.c +++ b/src/core/serialize.c @@ -31,9 +31,8 @@ struct mStateExtdataHeader { int64_t offset; }; -bool mStateExtdataInit(struct mStateExtdata* extdata) { +void mStateExtdataInit(struct mStateExtdata* extdata) { memset(extdata->data, 0, sizeof(extdata->data)); - return true; } void mStateExtdataDeinit(struct mStateExtdata* extdata) { @@ -43,6 +42,7 @@ void mStateExtdataDeinit(struct mStateExtdata* extdata) { extdata->data[i].clean(extdata->data[i].data); } } + memset(extdata->data, 0, sizeof(extdata->data)); } void mStateExtdataPut(struct mStateExtdata* extdata, enum mStateExtdataTag tag, struct mStateExtdataItem* item) { @@ -215,7 +215,7 @@ static int _loadPNGChunkHandler(png_structp png, png_unknown_chunkp chunk) { if (!strcmp((const char*) chunk->name, "gbAs")) { void* state = bundle->state; if (!state) { - return 0; + return 1; } uLongf len = bundle->stateSize; uncompress((Bytef*) state, &len, chunk->data, chunk->size); @@ -296,6 +296,54 @@ static void* _loadPNGState(struct mCore* core, struct VFile* vf, struct mStateEx } return state; } + +static bool _loadPNGExtadata(struct VFile* vf, struct mStateExtdata* extdata) { + png_structp png = PNGReadOpen(vf, PNG_HEADER_BYTES); + png_infop info = png_create_info_struct(png); + png_infop end = png_create_info_struct(png); + if (!png || !info || !end) { + PNGReadClose(png, info, end); + return false; + } + struct mBundledState bundle = { + .stateSize = 0, + .state = NULL, + .extdata = extdata + }; + + PNGInstallChunkHandler(png, &bundle, _loadPNGChunkHandler, "gbAs gbAx"); + bool success = PNGReadHeader(png, info); + if (!success) { + PNGReadClose(png, info, end); + return false; + } + + unsigned width = png_get_image_width(png, info); + unsigned height = png_get_image_height(png, info); + uint32_t* pixels = NULL; + pixels = malloc(width * height * 4); + if (!pixels) { + PNGReadClose(png, info, end); + return false; + } + + success = PNGReadPixels(png, info, pixels, width, height, width); + success = success && PNGReadFooter(png, end); + PNGReadClose(png, info, end); + + if (success) { + struct mStateExtdataItem item = { + .size = width * height * 4, + .data = pixels, + .clean = free + }; + mStateExtdataPut(extdata, EXTDATA_SCREENSHOT, &item); + } else { + free(pixels); + return false; + } + return true; +} #endif bool mCoreSaveStateNamed(struct mCore* core, struct VFile* vf, int flags) { @@ -423,6 +471,20 @@ void* mCoreExtractState(struct mCore* core, struct VFile* vf, struct mStateExtda return state; } +bool mCoreExtractExtdata(struct mCore* core, struct VFile* vf, struct mStateExtdata* extdata) { +#ifdef USE_PNG + if (isPNG(vf)) { + return _loadPNGExtadata(vf, extdata); + } +#endif + if (!core) { + return false; + } + ssize_t stateSize = core->stateSize(core); + vf->seek(vf, stateSize, SEEK_SET); + return mStateExtdataDeserialize(extdata, vf); +} + bool mCoreLoadStateNamed(struct mCore* core, struct VFile* vf, int flags) { struct mStateExtdata extdata; mStateExtdataInit(&extdata); diff --git a/src/feature/gui/gui-config.c b/src/feature/gui/gui-config.c index ee14a019c..bdf50108a 100644 --- a/src/feature/gui/gui-config.c +++ b/src/feature/gui/gui-config.c @@ -61,6 +61,16 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t }, .nStates = 2 }; + *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { + .title = "Show status OSD", + .data = "showOSD", + .submenu = 0, + .state = true, + .validStates = (const char*[]) { + "Off", "On" + }, + .nStates = 2 + }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Autosave state", .data = "autosave", @@ -81,6 +91,16 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t }, .nStates = 2 }; + *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { + .title = "Mute", + .data = "mute", + .submenu = 0, + .state = false, + .validStates = (const char*[]) { + "Off", "On" + }, + .nStates = 2 + }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Use BIOS if found", .data = "useBios", @@ -91,10 +111,12 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t }, .nStates = 2 }; +#ifdef M_CORE_GBA *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Select GBA BIOS path", .data = "gba.bios", }; +#endif #ifdef M_CORE_GB *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Select GB BIOS path", diff --git a/src/feature/gui/gui-runner.c b/src/feature/gui/gui-runner.c index 5d45f69ad..75e2961c8 100644 --- a/src/feature/gui/gui-runner.c +++ b/src/feature/gui/gui-runner.c @@ -56,6 +56,7 @@ static const struct mInputPlatformInfo _mGUIKeyInfo = { [mGUI_INPUT_SCREENSHOT] = "Take screenshot", [mGUI_INPUT_FAST_FORWARD_HELD] = "Fast forward (held)", [mGUI_INPUT_FAST_FORWARD_TOGGLE] = "Fast forward (toggle)", + [mGUI_INPUT_MUTE_TOGGLE] = "Mute (toggle)", }, .nKeys = GUI_INPUT_MAX }; @@ -201,6 +202,7 @@ void mGUIInit(struct mGUIRunner* runner, const char* port) { #else mCoreConfigSetDefaultIntValue(&runner->config, "autosave", true); #endif + mCoreConfigSetDefaultIntValue(&runner->config, "showOSD", true); mCoreConfigLoad(&runner->config); mCoreConfigGetIntValue(&runner->config, "logLevel", &logger.logLevel); @@ -429,6 +431,12 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) { mCoreLoadState(runner->core, 0, SAVESTATE_SCREENSHOT | SAVESTATE_RTC); } + int showOSD = true; + mCoreConfigGetIntValue(&runner->config, "showOSD", &showOSD); + + int drawFps = false; + mCoreConfigGetIntValue(&runner->config, "fpsCounter", &drawFps); + bool running = true; #ifndef DISABLE_THREADING @@ -490,6 +498,11 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) { runner->setFrameLimiter(runner, true); } } + if (guiKeys & (1 << mGUI_INPUT_MUTE_TOGGLE)) { + int mute = !runner->core->opts.mute; + mCoreConfigSetUIntValue(&runner->config, "mute", mute); + runner->core->reloadConfigOption(runner->core, "mute", &runner->config); + } uint16_t keys = runner->pollGameInput(runner); if (runner->prepareForFrame) { runner->prepareForFrame(runner); @@ -497,16 +510,29 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) { runner->core->setKeys(runner->core, keys); runner->core->runFrame(runner->core); if (runner->drawFrame) { - int drawFps = false; - mCoreConfigGetIntValue(&runner->config, "fpsCounter", &drawFps); - runner->params.drawStart(); runner->drawFrame(runner, false); - if (drawFps) { + if (showOSD || drawFps) { if (runner->params.guiPrepare) { runner->params.guiPrepare(); } - GUIFontPrintf(runner->params.font, 0, GUIFontHeight(runner->params.font), GUI_ALIGN_LEFT, 0x7FFFFFFF, "%.2f fps", runner->fps); + if (drawFps) { + GUIFontPrintf(runner->params.font, 0, GUIFontHeight(runner->params.font), GUI_ALIGN_LEFT, 0x7FFFFFFF, "%.2f fps", runner->fps); + } + if (showOSD) { + unsigned origin = runner->params.width - GUIFontHeight(runner->params.font) / 2; + unsigned w; + if (fastForward || (heldKeys & (1 << mGUI_INPUT_FAST_FORWARD_HELD))) { + GUIFontDrawIcon(runner->params.font, origin, GUIFontHeight(runner->params.font) / 2, GUI_ALIGN_RIGHT, 0, 0x7FFFFFFF, GUI_ICON_STATUS_FAST_FORWARD); + GUIFontIconMetrics(runner->params.font, GUI_ICON_STATUS_FAST_FORWARD, &w, NULL); + origin -= w + GUIFontHeight(runner->params.font) / 2; + } + if (runner->core->opts.mute) { + GUIFontDrawIcon(runner->params.font, origin, GUIFontHeight(runner->params.font) / 2, GUI_ALIGN_RIGHT, 0, 0x7FFFFFFF, GUI_ICON_STATUS_MUTE); + GUIFontIconMetrics(runner->params.font, GUI_ICON_STATUS_MUTE, &w, NULL); + origin -= w + GUIFontHeight(runner->params.font) / 2; + } + } if (runner->params.guiFinish) { runner->params.guiFinish(); } @@ -597,6 +623,8 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) { if (runner->unpaused) { runner->unpaused(runner); } + mCoreConfigGetIntValue(&runner->config, "fpsCounter", &drawFps); + mCoreConfigGetIntValue(&runner->config, "showOSD", &showOSD); } mLOG(GUI_RUNNER, DEBUG, "Shutting down..."); if (runner->gameUnloaded) { diff --git a/src/feature/gui/gui-runner.h b/src/feature/gui/gui-runner.h index fda78f982..6b5c87619 100644 --- a/src/feature/gui/gui-runner.h +++ b/src/feature/gui/gui-runner.h @@ -23,7 +23,8 @@ enum mGUIInput { mGUI_INPUT_SCREEN_MODE, mGUI_INPUT_SCREENSHOT, mGUI_INPUT_FAST_FORWARD_HELD, - mGUI_INPUT_FAST_FORWARD_TOGGLE + mGUI_INPUT_FAST_FORWARD_TOGGLE, + mGUI_INPUT_MUTE_TOGGLE, }; struct mGUIBackground { diff --git a/src/feature/thread-proxy.c b/src/feature/thread-proxy.c index 5f3f1f543..ac56f1b47 100644 --- a/src/feature/thread-proxy.c +++ b/src/feature/thread-proxy.c @@ -206,10 +206,6 @@ static THREAD_ENTRY _proxyThread(void* logger) { } } MutexUnlock(&proxyRenderer->mutex); - -#ifdef _3DS - svcExitThread(); -#endif return 0; } diff --git a/src/feature/video-logger.c b/src/feature/video-logger.c index cd738f75b..5c2a98f5c 100644 --- a/src/feature/video-logger.c +++ b/src/feature/video-logger.c @@ -296,11 +296,16 @@ bool mVideoLoggerRendererRun(struct mVideoLogger* logger, bool block) { mVideoLoggerRendererRunInjected(logger); ignorePackets = channel->ignorePackets; } + struct mVideoLoggerDirtyInfo buffer = {0}; struct mVideoLoggerDirtyInfo item = {0}; - while (logger->readData(logger, &item, sizeof(item), block)) { + while (logger->readData(logger, &buffer, sizeof(buffer), block)) { + LOAD_32LE(item.type, 0, &buffer.type); if (ignorePackets & (1 << item.type)) { continue; } + LOAD_32LE(item.address, 0, &buffer.address); + LOAD_32LE(item.value, 0, &buffer.value); + LOAD_32LE(item.value2, 0, &buffer.value2); switch (item.type) { case DIRTY_SCANLINE: if (channel && channel->injectionPoint == LOGGER_INJECTION_FIRST_SCANLINE && !channel->injecting && item.address == 0) { diff --git a/src/gb/core.c b/src/gb/core.c index f1c74aac1..254144319 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -138,8 +138,10 @@ static void _GBCoreDeinit(struct mCore* core) { GBDestroy(core->board); mappedMemoryFree(core->cpu, sizeof(struct SM83Core)); mappedMemoryFree(core->board, sizeof(struct GB)); -#if defined USE_DEBUGGERS && (!defined(MINIMAL_CORE) || MINIMAL_CORE < 2) +#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 mDirectorySetDeinit(&core->dirs); +#endif +#ifdef USE_DEBUGGERS if (core->symbolTable) { mDebuggerSymbolTableDestroy(core->symbolTable); } diff --git a/src/gb/io.c b/src/gb/io.c index c6baa5a30..ea9eb7b2e 100644 --- a/src/gb/io.c +++ b/src/gb/io.c @@ -700,7 +700,7 @@ void GBIODeserialize(struct GB* gb, const struct GBSerializedState* state) { gb->memory.ie = state->ie; gb->audio.enable = GBAudioEnableGetEnable(*gb->audio.nr52); - if (GBAudioEnableGetEnable(gb->audio.enable)) { + if (gb->audio.enable) { GBIOWrite(gb, REG_NR10, gb->memory.io[REG_NR10]); GBIOWrite(gb, REG_NR11, gb->memory.io[REG_NR11]); GBIOWrite(gb, REG_NR12, gb->memory.io[REG_NR12]); diff --git a/src/gb/mbc.c b/src/gb/mbc.c index 407cd8e79..310c8bb95 100644 --- a/src/gb/mbc.c +++ b/src/gb/mbc.c @@ -37,6 +37,8 @@ static void _GBPocketCam(struct GB* gb, uint16_t address, uint8_t value); static void _GBTAMA5(struct GB* gb, uint16_t address, uint8_t value); static void _GBWisdomTree(struct GB* gb, uint16_t address, uint8_t value); static void _GBPKJD(struct GB* gb, uint16_t address, uint8_t value); +static void _GBBBD(struct GB* gb, uint16_t address, uint8_t value); +static void _GBHitek(struct GB* gb, uint16_t address, uint8_t value); static uint8_t _GBMBC2Read(struct GBMemory*, uint16_t address); static uint8_t _GBMBC6Read(struct GBMemory*, uint16_t address); @@ -45,6 +47,8 @@ static void _GBMBC7Write(struct GBMemory* memory, uint16_t address, uint8_t valu static uint8_t _GBTAMA5Read(struct GBMemory*, uint16_t address); static uint8_t _GBPKJDRead(struct GBMemory*, uint16_t address); +static uint8_t _GBBBDRead(struct GBMemory*, uint16_t address); +static uint8_t _GBHitekRead(struct GBMemory*, uint16_t address); static uint8_t _GBPocketCamRead(struct GBMemory*, uint16_t address); static void _GBPocketCamCapture(struct GBMemory*); @@ -145,6 +149,31 @@ static bool _isWisdomTree(const uint8_t* mem, size_t size) { return false; } +static enum GBMemoryBankControllerType _detectUnlMBC(const uint8_t* mem, size_t size) { + const struct GBCartridge* cart = (const struct GBCartridge*) &mem[0x100]; + + switch (cart->type) { + case 0: + if (_isWisdomTree(mem, size)) { + return GB_UNL_WISDOM_TREE; + } + break; + } + + uint32_t secondaryLogo = doCrc32(&mem[0x184], 0x30); + switch (secondaryLogo) { + case 0x4fdab691: + return GB_UNL_HITEK; + case 0xc7d8c1df: + case 0x6d1ea662: // Garou + if (mem[0x7FFF] != 0x01) { // Make sure we're not using a "fixed" version + return GB_UNL_BBD; + } + } + + return GB_MBC_AUTODETECT; +} + void GBMBCSwitchSramBank(struct GB* gb, int bank) { size_t bankStart = bank * GB_SIZE_EXTERNAL_RAM; if (bankStart + GB_SIZE_EXTERNAL_RAM > gb->sramSize) { @@ -202,15 +231,13 @@ void GBMBCInit(struct GB* gb) { gb->sramSize = 0x10000; break; } + if (gb->memory.mbcType == GB_MBC_AUTODETECT) { + gb->memory.mbcType = _detectUnlMBC(gb->memory.rom, gb->memory.romSize); + } if (gb->memory.mbcType == GB_MBC_AUTODETECT) { switch (cart->type) { case 0: - if (_isWisdomTree(gb->memory.rom, gb->memory.romSize)) { - gb->memory.mbcType = GB_UNL_WISDOM_TREE; - break; - } - // Fall through case 8: case 9: gb->memory.mbcType = GB_MBC_NONE; @@ -346,6 +373,16 @@ void GBMBCInit(struct GB* gb) { case GB_UNL_WISDOM_TREE: gb->memory.mbcWrite = _GBWisdomTree; break; + case GB_UNL_BBD: + gb->memory.mbcWrite = _GBBBD; + gb->memory.mbcRead = _GBBBDRead; + break; + case GB_UNL_HITEK: + gb->memory.mbcWrite = _GBHitek; + gb->memory.mbcRead = _GBHitekRead; + gb->memory.mbcState.bbd.dataSwapMode = 7; + gb->memory.mbcState.bbd.bankSwapMode = 7; + break; case GB_UNL_PKJD: gb->memory.mbcWrite = _GBPKJD; gb->memory.mbcRead = _GBPKJDRead; @@ -1306,6 +1343,123 @@ static uint8_t _GBPKJDRead(struct GBMemory* memory, uint16_t address) { } } +static uint8_t _reorderBits(uint8_t input, const uint8_t* reorder) { + uint8_t newbyte = 0; + int i; + for(i = 0; i < 8; ++i) { + int oldbit = reorder[i]; + int newbit = i; + newbyte += ((input >> oldbit) & 1) << newbit; + } + + return newbyte; +} + +static const uint8_t _bbdDataReordering[8][8] = { + { 0, 1, 2, 3, 4, 5, 6, 7 }, // 00 - Normal + { 0, 1, 2, 3, 4, 5, 6, 7 }, // 01 - NOT KNOWN YET + { 0, 1, 2, 3, 4, 5, 6, 7 }, // 02 - NOT KNOWN YET + { 0, 1, 2, 3, 4, 5, 6, 7 }, // 03 - NOT KNOWN YET + { 0, 5, 1, 3, 4, 2, 6, 7 }, // 04 - Garou + { 0, 4, 2, 3, 1, 5, 6, 7 }, // 05 - Harry + { 0, 1, 2, 3, 4, 5, 6, 7 }, // 06 - NOT KNOWN YET + { 0, 1, 5, 3, 4, 2, 6, 7 }, // 07 - Digimon +}; + +static const uint8_t _bbdBankReordering[8][8] = { + { 0, 1, 2, 3, 4, 5, 6, 7 }, // 00 - Normal + { 0, 1, 2, 3, 4, 5, 6, 7 }, // 01 - NOT KNOWN YET + { 0, 1, 2, 3, 4, 5, 6, 7 }, // 02 - NOT KNOWN YET + { 3, 4, 2, 0, 1, 5, 6, 7 }, // 03 - 0,1 unconfirmed. Digimon/Garou + { 0, 1, 2, 3, 4, 5, 6, 7 }, // 04 - NOT KNOWN YET + { 1, 2, 3, 4, 0, 5, 6, 7 }, // 05 - 0,1 unconfirmed. Harry + { 0, 1, 2, 3, 4, 5, 6, 7 }, // 06 - NOT KNOWN YET + { 0, 1, 2, 3, 4, 5, 6, 7 }, // 07 - NOT KNOWN YET +}; + +void _GBBBD(struct GB* gb, uint16_t address, uint8_t value) { + struct GBMemory* memory = &gb->memory; + switch (address & 0xF0FF) { + case 0x2000: + value = _reorderBits(value, _bbdBankReordering[memory->mbcState.bbd.bankSwapMode]); + break; + case 0x2001: + memory->mbcState.bbd.dataSwapMode = value & 0x07; + if (!(memory->mbcState.bbd.dataSwapMode == 0x07 || memory->mbcState.bbd.dataSwapMode == 0x05 || memory->mbcState.bbd.dataSwapMode == 0x04 || memory->mbcState.bbd.dataSwapMode == 0x00)) { + mLOG(GB_MBC, STUB, "Bitswap mode unsupported: %X", memory->mbcState.bbd.dataSwapMode); + } + break; + case 0x2080: + memory->mbcState.bbd.bankSwapMode = value & 0x07; + if (!(memory->mbcState.bbd.bankSwapMode == 0x03 || memory->mbcState.bbd.bankSwapMode == 0x05 || memory->mbcState.bbd.bankSwapMode == 0x00)) { + mLOG(GB_MBC, STUB, "Bankswap mode unsupported: %X", memory->mbcState.bbd.dataSwapMode); + } + break; + } + _GBMBC5(gb, address, value); +} + +uint8_t _GBBBDRead(struct GBMemory* memory, uint16_t address) { + switch (address >> 14) { + case 0: + default: + return memory->romBank[address & (GB_SIZE_CART_BANK0 - 1)]; + case 1: + return _reorderBits(memory->romBank[address & (GB_SIZE_CART_BANK0 - 1)], _bbdDataReordering[memory->mbcState.bbd.dataSwapMode]); + } +} + +static const uint8_t _hitekDataReordering[8][8] = { + { 0, 1, 2, 3, 4, 5, 6, 7 }, + { 0, 6, 5, 3, 4, 1, 2, 7 }, + { 0, 5, 6, 3, 4, 2, 1, 7 }, + { 0, 6, 2, 3, 4, 5, 1, 7 }, + { 0, 6, 1, 3, 4, 5, 2, 7 }, + { 0, 1, 6, 3, 4, 5, 2, 7 }, + { 0, 2, 6, 3, 4, 1, 5, 7 }, + { 0, 6, 2, 3, 4, 1, 5, 7 }, +}; + +static const uint8_t _hitekBankReordering[8][8] = { + { 0, 1, 2, 3, 4, 5, 6, 7 }, + { 3, 2, 1, 0, 4, 5, 6, 7 }, + { 2, 1, 0, 3, 4, 5, 6, 7 }, + { 1, 0, 3, 2, 4, 5, 6, 7 }, + { 0, 3, 2, 1, 4, 5, 6, 7 }, + { 2, 3, 0, 1, 4, 5, 6, 7 }, + { 3, 0, 1, 2, 4, 5, 6, 7 }, + { 2, 0, 3, 1, 4, 5, 6, 7 }, +}; + +void _GBHitek(struct GB* gb, uint16_t address, uint8_t value) { + struct GBMemory* memory = &gb->memory; + switch (address & 0xF0FF) { + case 0x2000: + value = _reorderBits(value, _hitekBankReordering[memory->mbcState.bbd.bankSwapMode]); + break; + case 0x2001: + memory->mbcState.bbd.dataSwapMode = value & 0x07; + break; + case 0x2080: + memory->mbcState.bbd.bankSwapMode = value & 0x07; + break; + case 0x300: + // See hhugboy src/memory/mbc/MbcUnlHitek.cpp for commentary on this return + return; + } + _GBMBC5(gb, address, value); +} + +uint8_t _GBHitekRead(struct GBMemory* memory, uint16_t address) { + switch (address >> 14) { + case 0: + default: + return memory->romBank[address & (GB_SIZE_CART_BANK0 - 1)]; + case 1: + return _reorderBits(memory->romBank[address & (GB_SIZE_CART_BANK0 - 1)], _hitekDataReordering[memory->mbcState.bbd.dataSwapMode]); + } +} + void GBMBCRTCRead(struct GB* gb) { struct GBMBCRTCSaveBuffer rtcBuffer; struct VFile* vf = gb->sramVf; diff --git a/src/gb/memory.c b/src/gb/memory.c index a6abaf166..5eccfbc11 100644 --- a/src/gb/memory.c +++ b/src/gb/memory.c @@ -84,6 +84,10 @@ static void GBSetActiveRegion(struct SM83Core* cpu, uint16_t address) { case GB_REGION_CART_BANK1 + 1: case GB_REGION_CART_BANK1 + 2: case GB_REGION_CART_BANK1 + 3: + if ((gb->memory.mbcType & GB_UNL_BBD) == GB_UNL_BBD) { + cpu->memory.cpuLoad8 = GBLoad8; + break; + } cpu->memory.cpuLoad8 = GBFastLoad8; if (gb->memory.mbcType != GB_MBC6) { cpu->memory.activeRegion = memory->romBank; @@ -277,6 +281,9 @@ uint8_t GBLoad8(struct SM83Core* cpu, uint16_t address) { if (address >= memory->romSize) { return 0xFF; } + if ((memory->mbcType & GB_UNL_BBD) == GB_UNL_BBD) { + return memory->mbcRead(memory, address); + } return memory->romBank[address & (GB_SIZE_CART_BANK0 - 1)]; case GB_REGION_VRAM: case GB_REGION_VRAM + 1: @@ -754,6 +761,11 @@ void GBMemorySerialize(const struct GB* gb, struct GBSerializedState* state) { state->memory.mmm01.locked = memory->mbcState.mmm01.locked; state->memory.mmm01.bank0 = memory->mbcState.mmm01.currentBank0; break; + case GB_UNL_BBD: + case GB_UNL_HITEK: + state->memory.bbd.dataSwapMode = memory->mbcState.bbd.dataSwapMode; + state->memory.bbd.bankSwapMode = memory->mbcState.bbd.bankSwapMode; + break; default: break; } @@ -841,6 +853,11 @@ void GBMemoryDeserialize(struct GB* gb, const struct GBSerializedState* state) { GBMBCSwitchBank0(gb, gb->memory.romSize / GB_SIZE_CART_BANK0 - 2); } break; + case GB_UNL_BBD: + case GB_UNL_HITEK: + memory->mbcState.bbd.dataSwapMode = state->memory.bbd.dataSwapMode & 0x7; + memory->mbcState.bbd.bankSwapMode = state->memory.bbd.bankSwapMode & 0x7; + break; default: break; } diff --git a/src/gba/audio.c b/src/gba/audio.c index c0a275834..b936edd1d 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -23,7 +23,6 @@ mLOG_DEFINE_CATEGORY(GBA_AUDIO, "GBA Audio", "gba.audio"); const unsigned GBA_AUDIO_SAMPLES = 2048; -const unsigned GBA_AUDIO_FIFO_SIZE = 8 * sizeof(int32_t); const int GBA_AUDIO_VOLUME_MAX = 0x100; static const int CLOCKS_PER_FRAME = 0x800; @@ -48,8 +47,6 @@ void GBAAudioInit(struct GBAAudio* audio, size_t samples) { // Guess too large; we hang producing extra samples if we guess too low blip_set_rates(audio->psg.left, GBA_ARM7TDMI_FREQUENCY, 96000); blip_set_rates(audio->psg.right, GBA_ARM7TDMI_FREQUENCY, 96000); - CircleBufferInit(&audio->chA.fifo, GBA_AUDIO_FIFO_SIZE); - CircleBufferInit(&audio->chB.fifo, GBA_AUDIO_FIFO_SIZE); audio->externalMixing = false; audio->forceDisableChA = false; @@ -64,7 +61,17 @@ void GBAAudioReset(struct GBAAudio* audio) { mTimingSchedule(&audio->p->timing, &audio->sampleEvent, 0); audio->chA.dmaSource = 1; audio->chB.dmaSource = 2; + audio->chA.fifoWrite = 0; + audio->chA.fifoRead = 0; + audio->chA.internalSample = 0; + audio->chA.internalRemaining = 0; + memset(audio->chA.fifo, 0, sizeof(audio->chA.fifo)); audio->chA.sample = 0; + audio->chB.fifoWrite = 0; + audio->chB.fifoRead = 0; + audio->chB.internalSample = 0; + audio->chB.internalRemaining = 0; + memset(audio->chB.fifo, 0, sizeof(audio->chB.fifo)); audio->chB.sample = 0; audio->sampleRate = 0x8000; audio->soundbias = 0x200; @@ -84,14 +91,10 @@ void GBAAudioReset(struct GBAAudio* audio) { blip_clear(audio->psg.left); blip_clear(audio->psg.right); audio->clock = 0; - CircleBufferClear(&audio->chA.fifo); - CircleBufferClear(&audio->chB.fifo); } void GBAAudioDeinit(struct GBAAudio* audio) { GBAudioDeinit(&audio->psg); - CircleBufferDeinit(&audio->chA.fifo); - CircleBufferDeinit(&audio->chB.fifo); } void GBAAudioResizeBuffer(struct GBAAudio* audio, size_t samples) { @@ -199,10 +202,12 @@ void GBAAudioWriteSOUNDCNT_HI(struct GBAAudio* audio, uint16_t value) { audio->chBLeft = GBARegisterSOUNDCNT_HIGetChBLeft(value); audio->chBTimer = GBARegisterSOUNDCNT_HIGetChBTimer(value); if (GBARegisterSOUNDCNT_HIIsChAReset(value)) { - CircleBufferClear(&audio->chA.fifo); + audio->chA.fifoWrite = 0; + audio->chA.fifoRead = 0; } if (GBARegisterSOUNDCNT_HIIsChBReset(value)) { - CircleBufferClear(&audio->chB.fifo); + audio->chB.fifoWrite = 0; + audio->chB.fifoRead = 0; } } @@ -219,26 +224,25 @@ void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value) { audio->psg.ch3.wavedata32[address | (!audio->psg.ch3.bank * 4)] = value; } -void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value) { - struct CircleBuffer* fifo; +uint32_t GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value) { + struct GBAAudioFIFO* channel; switch (address) { case REG_FIFO_A_LO: - fifo = &audio->chA.fifo; + channel = &audio->chA; break; case REG_FIFO_B_LO: - fifo = &audio->chB.fifo; + channel = &audio->chB; break; default: mLOG(GBA_AUDIO, ERROR, "Bad FIFO write to address 0x%03x", address); - return; + return value; } - int i; - for (i = 0; i < 4; ++i) { - while (!CircleBufferWrite8(fifo, value >> (8 * i))) { - int8_t dummy; - CircleBufferRead8(fifo, &dummy); - } + channel->fifo[channel->fifoWrite] = value; + ++channel->fifoWrite; + if (channel->fifoWrite == GBA_AUDIO_FIFO_SIZE) { + channel->fifoWrite = 0; } + return channel->fifo[channel->fifoWrite]; } void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles) { @@ -251,17 +255,33 @@ void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles) { mLOG(GBA_AUDIO, ERROR, "Bad FIFO write to address 0x%03x", fifoId); return; } - if (CircleBufferSize(&channel->fifo) <= 4 * sizeof(int32_t) && channel->dmaSource > 0) { + int fifoSize; + if (channel->fifoWrite >= channel->fifoRead) { + fifoSize = channel->fifoWrite - channel->fifoRead; + } else { + fifoSize = GBA_AUDIO_FIFO_SIZE - channel->fifoRead + channel->fifoWrite; + } + if (GBA_AUDIO_FIFO_SIZE - fifoSize > 4 && channel->dmaSource > 0) { struct GBADMA* dma = &audio->p->memory.dma[channel->dmaSource]; if (GBADMARegisterGetTiming(dma->reg) == GBA_DMA_TIMING_CUSTOM) { dma->when = mTimingCurrentTime(&audio->p->timing) - cycles; dma->nextCount = 4; GBADMASchedule(audio->p, channel->dmaSource, dma); - } else { - channel->dmaSource = 0; } } - CircleBufferRead8(&channel->fifo, (int8_t*) &channel->sample); + if (!channel->internalRemaining && fifoSize) { + channel->internalSample = channel->fifo[channel->fifoRead]; + channel->internalRemaining = 4; + ++channel->fifoRead; + if (channel->fifoRead == GBA_AUDIO_FIFO_SIZE) { + channel->fifoRead = 0; + } + } + channel->sample = channel->internalSample; + if (channel->internalRemaining) { + channel->internalSample >>= 8; + --channel->internalRemaining; + } } static int _applyBias(struct GBAAudio* audio, int sample) { @@ -345,37 +365,76 @@ static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) { void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state) { GBAudioPSGSerialize(&audio->psg, &state->audio.psg, &state->audio.flags); - CircleBufferDump(&audio->chA.fifo, state->audio.fifoA, sizeof(state->audio.fifoA)); - CircleBufferDump(&audio->chB.fifo, state->audio.fifoB, sizeof(state->audio.fifoB)); - uint32_t fifoSize = CircleBufferSize(&audio->chA.fifo); - STORE_32(fifoSize, 0, &state->audio.fifoSizeA); - fifoSize = CircleBufferSize(&audio->chB.fifo); - STORE_32(fifoSize, 0, &state->audio.fifoSizeB); + STORE_32(audio->chA.internalSample, 0, &state->audio.internalA); + STORE_32(audio->chB.internalSample, 0, &state->audio.internalB); + state->audio.sampleA = audio->chA.sample; + state->audio.sampleB = audio->chB.sample; + + int readA = audio->chA.fifoRead; + int readB = audio->chB.fifoRead; + size_t i; + for (i = 0; i < GBA_AUDIO_FIFO_SIZE; ++i) { + STORE_32(audio->chA.fifo[readA], i << 2, state->audio.fifoA); + STORE_32(audio->chB.fifo[readB], i << 2, state->audio.fifoB); + ++readA; + if (readA == GBA_AUDIO_FIFO_SIZE) { + readA = 0; + } + ++readB; + if (readB == GBA_AUDIO_FIFO_SIZE) { + readB = 0; + } + } + + int fifoSizeA; + if (audio->chA.fifoWrite >= audio->chA.fifoRead) { + fifoSizeA = audio->chA.fifoWrite - audio->chA.fifoRead; + } else { + fifoSizeA = GBA_AUDIO_FIFO_SIZE - audio->chA.fifoRead + audio->chA.fifoWrite; + } + + int fifoSizeB; + if (audio->chB.fifoWrite >= audio->chB.fifoRead) { + fifoSizeB = audio->chB.fifoWrite - audio->chB.fifoRead; + } else { + fifoSizeB = GBA_AUDIO_FIFO_SIZE - audio->chB.fifoRead + audio->chB.fifoWrite; + } + + GBASerializedAudioFlags flags = 0; + flags = GBASerializedAudioFlagsSetFIFOSamplesA(flags, fifoSizeA); + flags = GBASerializedAudioFlagsSetFIFOSamplesB(flags, fifoSizeB); + flags = GBASerializedAudioFlagsSetFIFOInternalSamplesA(flags, audio->chA.internalRemaining); + flags = GBASerializedAudioFlagsSetFIFOInternalSamplesB(flags, audio->chB.internalRemaining); + STORE_16(flags, 0, &state->audio.gbaFlags); STORE_32(audio->sampleEvent.when - mTimingCurrentTime(&audio->p->timing), 0, &state->audio.nextSample); } void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState* state) { GBAudioPSGDeserialize(&audio->psg, &state->audio.psg, &state->audio.flags); - CircleBufferClear(&audio->chA.fifo); - CircleBufferClear(&audio->chB.fifo); - uint32_t fifoSize; - LOAD_32(fifoSize, 0, &state->audio.fifoSizeA); - if (fifoSize > CircleBufferCapacity(&audio->chA.fifo)) { - fifoSize = CircleBufferCapacity(&audio->chA.fifo); - } - size_t i; - for (i = 0; i < fifoSize; ++i) { - CircleBufferWrite8(&audio->chA.fifo, state->audio.fifoA[i]); - } + LOAD_32(audio->chA.internalSample, 0, &state->audio.internalA); + LOAD_32(audio->chB.internalSample, 0, &state->audio.internalB); + audio->chA.sample = state->audio.sampleA; + audio->chB.sample = state->audio.sampleB; - LOAD_32(fifoSize, 0, &state->audio.fifoSizeB); - if (fifoSize > CircleBufferCapacity(&audio->chB.fifo)) { - fifoSize = CircleBufferCapacity(&audio->chB.fifo); - } - for (i = 0; i < fifoSize; ++i) { - CircleBufferWrite8(&audio->chB.fifo, state->audio.fifoB[i]); + int readA = 0; + int readB = 0; + size_t i; + for (i = 0; i < GBA_AUDIO_FIFO_SIZE; ++i) { + LOAD_32(audio->chA.fifo[readA], i << 2, state->audio.fifoA); + LOAD_32(audio->chB.fifo[readB], i << 2, state->audio.fifoB); + ++readA; + ++readB; } + audio->chA.fifoRead = 0; + audio->chB.fifoRead = 0; + + GBASerializedAudioFlags flags; + LOAD_16(flags, 0, &state->audio.gbaFlags); + audio->chA.fifoWrite = GBASerializedAudioFlagsGetFIFOSamplesA(flags); + audio->chB.fifoWrite = GBASerializedAudioFlagsGetFIFOSamplesB(flags); + audio->chA.internalRemaining = GBASerializedAudioFlagsGetFIFOInternalSamplesA(flags); + audio->chB.internalRemaining = GBASerializedAudioFlagsGetFIFOInternalSamplesB(flags); uint32_t when; LOAD_32(when, 0, &state->audio.nextSample); diff --git a/src/gba/core.c b/src/gba/core.c index a7c85ef54..13df13bdc 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -228,6 +228,11 @@ static void _GBACoreDeinit(struct mCore* core) { #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 mDirectorySetDeinit(&core->dirs); #endif +#ifdef USE_DEBUGGERS + if (core->symbolTable) { + mDebuggerSymbolTableDestroy(core->symbolTable); + } +#endif struct GBACore* gbacore = (struct GBACore*) core; free(gbacore->debuggerPlatform); diff --git a/src/gba/dma.c b/src/gba/dma.c index 543ac95e0..d30f0291a 100644 --- a/src/gba/dma.c +++ b/src/gba/dma.c @@ -134,29 +134,37 @@ void GBADMASchedule(struct GBA* gba, int number, struct GBADMA* info) { void GBADMARunHblank(struct GBA* gba, int32_t cycles) { struct GBAMemory* memory = &gba->memory; struct GBADMA* dma; + bool found = false; int i; for (i = 0; i < 4; ++i) { dma = &memory->dma[i]; if (GBADMARegisterIsEnable(dma->reg) && GBADMARegisterGetTiming(dma->reg) == GBA_DMA_TIMING_HBLANK && !dma->nextCount) { dma->when = mTimingCurrentTime(&gba->timing) + 3 + cycles; dma->nextCount = dma->count; + found = true; } } - GBADMAUpdate(gba); + if (found) { + GBADMAUpdate(gba); + } } void GBADMARunVblank(struct GBA* gba, int32_t cycles) { struct GBAMemory* memory = &gba->memory; struct GBADMA* dma; + bool found = false; int i; for (i = 0; i < 4; ++i) { dma = &memory->dma[i]; if (GBADMARegisterIsEnable(dma->reg) && GBADMARegisterGetTiming(dma->reg) == GBA_DMA_TIMING_VBLANK && !dma->nextCount) { dma->when = mTimingCurrentTime(&gba->timing) + 3 + cycles; dma->nextCount = dma->count; + found = true; } } - GBADMAUpdate(gba); + if (found) { + GBADMAUpdate(gba); + } } void GBADMARunDisplayStart(struct GBA* gba, int32_t cycles) { @@ -211,7 +219,7 @@ void GBADMAUpdate(struct GBA* gba) { struct GBADMA* dma = &memory->dma[i]; if (GBADMARegisterIsEnable(dma->reg) && dma->nextCount) { int32_t time = dma->when - currentTime; - if (memory->activeDMA == -1 || (dma->count == dma->nextCount && time < leastTime)) { + if (memory->activeDMA == -1 || time < leastTime) { leastTime = time; memory->activeDMA = i; } @@ -295,6 +303,16 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) { info->nextCount = wordsRemaining; info->nextSource = source; info->nextDest = dest; + + int i; + for (i = 0; i < 4; ++i) { + struct GBADMA* dma = &memory->dma[i]; + int32_t time = dma->when - info->when; + if (time < 0 && GBADMARegisterIsEnable(dma->reg) && dma->nextCount) { + dma->when = info->when; + } + } + if (!wordsRemaining) { info->nextCount |= 0x80000000; if (sourceRegion < REGION_CART0 || destRegion < REGION_CART0) { diff --git a/src/gba/extra/audio-mixer.c b/src/gba/extra/audio-mixer.c index 85941536e..fe9ed6901 100644 --- a/src/gba/extra/audio-mixer.c +++ b/src/gba/extra/audio-mixer.c @@ -289,9 +289,11 @@ void _mp2kStep(struct GBAAudioMixer* mixer) { CircleBufferRead16(&mixer->activeTracks[track].buffer, &value); sample.right += value; } + sample.left = (sample.left * mixer->p->masterVolume) >> 8; + sample.right = (sample.right * mixer->p->masterVolume) >> 8; if (mixer->p->externalMixing) { blip_add_delta(mixer->p->psg.left, mixer->p->clock + i * interval, sample.left - mixer->last.left); - blip_add_delta(mixer->p->psg.right, mixer->p->clock + i * interval, sample.left - mixer->last.left); + blip_add_delta(mixer->p->psg.right, mixer->p->clock + i * interval, sample.right - mixer->last.right); } mixer->last = sample; } diff --git a/src/gba/extra/proxy.c b/src/gba/extra/proxy.c index d485023f7..e03a21e23 100644 --- a/src/gba/extra/proxy.c +++ b/src/gba/extra/proxy.c @@ -192,13 +192,13 @@ static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerD break; case DIRTY_PALETTE: if (item->address < SIZE_PALETTE_RAM) { - logger->palette[item->address >> 1] = item->value; + STORE_16LE(item->value, item->address, logger->palette); proxyRenderer->backend->writePalette(proxyRenderer->backend, item->address, item->value); } break; case DIRTY_OAM: if (item->address < SIZE_OAM) { - logger->oam[item->address] = item->value; + STORE_16LE(item->value, item->address << 1, logger->oam); proxyRenderer->backend->writeOAM(proxyRenderer->backend, item->address); } break; diff --git a/src/gba/hardware.c b/src/gba/hardware.c index 374132f6c..1defb314d 100644 --- a/src/gba/hardware.c +++ b/src/gba/hardware.c @@ -495,15 +495,15 @@ uint8_t GBAHardwareTiltRead(struct GBACartridgeHardware* hw, uint32_t address) { // == Game Boy Player -static const uint16_t _logoPalette[] = { - 0xFFDF, 0x640C, 0xE40C, 0xE42D, 0x644E, 0xE44E, 0xE46E, 0x68AF, - 0xE8B0, 0x68D0, 0x68F0, 0x6911, 0xE911, 0x6D32, 0xED32, 0xED73, - 0x6D93, 0xED94, 0x6DB4, 0xF1D5, 0x71F5, 0xF1F6, 0x7216, 0x7257, - 0xF657, 0x7678, 0xF678, 0xF699, 0xF6B9, 0x76D9, 0xF6DA, 0x7B1B, - 0xFB1B, 0xFB3C, 0x7B5C, 0x7B7D, 0xFF7D, 0x7F9D, 0x7FBE, 0x7FFF, - 0x642D, 0x648E, 0xE88F, 0xE8F1, 0x6D52, 0x6D73, 0xF1B4, 0xF216, - 0x7237, 0x7698, 0x7AFA, 0xFAFA, 0xFB5C, 0xFFBE, 0x7FDE, 0xFFFF, - 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 +static const uint8_t _logoPalette[] = { + 0xDF, 0xFF, 0x0C, 0x64, 0x0C, 0xE4, 0x2D, 0xE4, 0x4E, 0x64, 0x4E, 0xE4, 0x6E, 0xE4, 0xAF, 0x68, + 0xB0, 0xE8, 0xD0, 0x68, 0xF0, 0x68, 0x11, 0x69, 0x11, 0xE9, 0x32, 0x6D, 0x32, 0xED, 0x73, 0xED, + 0x93, 0x6D, 0x94, 0xED, 0xB4, 0x6D, 0xD5, 0xF1, 0xF5, 0x71, 0xF6, 0xF1, 0x16, 0x72, 0x57, 0x72, + 0x57, 0xF6, 0x78, 0x76, 0x78, 0xF6, 0x99, 0xF6, 0xB9, 0xF6, 0xD9, 0x76, 0xDA, 0xF6, 0x1B, 0x7B, + 0x1B, 0xFB, 0x3C, 0xFB, 0x5C, 0x7B, 0x7D, 0x7B, 0x7D, 0xFF, 0x9D, 0x7F, 0xBE, 0x7F, 0xFF, 0x7F, + 0x2D, 0x64, 0x8E, 0x64, 0x8F, 0xE8, 0xF1, 0xE8, 0x52, 0x6D, 0x73, 0x6D, 0xB4, 0xF1, 0x16, 0xF2, + 0x37, 0x72, 0x98, 0x76, 0xFA, 0x7A, 0xFA, 0xFA, 0x5C, 0xFB, 0xBE, 0xFF, 0xDE, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const uint32_t _logoHash = 0xEEDA6963; diff --git a/src/gba/io.c b/src/gba/io.c index 7953e0d62..8e22ed9d3 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -429,12 +429,12 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) { case REG_FIFO_A_LO: case REG_FIFO_B_LO: GBAIOWrite32(gba, address, (gba->memory.io[(address >> 1) + 1] << 16) | value); - break; + return; case REG_FIFO_A_HI: case REG_FIFO_B_HI: GBAIOWrite32(gba, address - 2, gba->memory.io[(address >> 1) - 1] | (value << 16)); - break; + return; // DMA case REG_DMA0SAD_LO: @@ -630,7 +630,7 @@ void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) { break; case REG_FIFO_A_LO: case REG_FIFO_B_LO: - GBAAudioWriteFIFO(&gba->audio, address, value); + value = GBAAudioWriteFIFO(&gba->audio, address, value); break; case REG_DMA0SAD_LO: value = GBADMAWriteSAD(gba, 0, value); diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index aa3b77de2..80eb4f441 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -1636,6 +1636,10 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB int32_t x = (uint32_t) GBAObjAttributesBGetX(sprite->b) << 23; x >>= 23; + if (GBARegisterDISPCNTGetMode(renderer->dispcnt) >= 3 && GBAObjAttributesCGetTile(sprite->c) < 512) { + return; + } + int align = GBAObjAttributesAIs256Color(sprite->a) && !GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt); unsigned charBase = (BASE_TILE >> 1) + (GBAObjAttributesCGetTile(sprite->c) & ~align) * 0x10; int stride = GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt) ? (width >> 3) : (0x20 >> GBAObjAttributesAGet256Color(sprite->a)); diff --git a/src/gba/renderers/software-bg.c b/src/gba/renderers/software-bg.c index ddc5668ec..2f8b1ff43 100644 --- a/src/gba/renderers/software-bg.c +++ b/src/gba/renderers/software-bg.c @@ -57,7 +57,7 @@ \ uint32_t current = renderer->row[outX]; \ MOSAIC(COORD) \ - if (pixelData) { \ + if (pixelData && IS_WRITABLE(current)) { \ COMPOSITE_256_ ## OBJWIN (BLEND, 0); \ } \ } diff --git a/src/gba/renderers/software-private.h b/src/gba/renderers/software-private.h index 5d02634ca..bdaeffae8 100644 --- a/src/gba/renderers/software-private.h +++ b/src/gba/renderers/software-private.h @@ -47,7 +47,7 @@ static inline void _compositeBlendObjwin(struct GBAVideoSoftwareRenderer* render if (current & FLAG_TARGET_1 && color & FLAG_TARGET_2) { color = _mix(renderer->alphaA[x], current, renderer->alphaB[x], color); } else { - color = (current & 0x00FFFFFF) | (current & (FLAG_REBLEND | FLAG_OBJWIN)); + color = current & (0x00FFFFFF | FLAG_REBLEND | FLAG_OBJWIN); } } else { color = (color & ~FLAG_TARGET_2) | (current & FLAG_OBJWIN); @@ -56,14 +56,11 @@ static inline void _compositeBlendObjwin(struct GBAVideoSoftwareRenderer* render } static inline void _compositeBlendNoObjwin(struct GBAVideoSoftwareRenderer* renderer, int x, uint32_t color, uint32_t current) { - if (!IS_WRITABLE(current)) { \ - return; \ - } \ if (color >= current) { if (current & FLAG_TARGET_1 && color & FLAG_TARGET_2) { color = _mix(renderer->alphaA[x], current, renderer->alphaB[x], color); } else { - color = (current & 0x00FFFFFF) | (current & (FLAG_REBLEND | FLAG_OBJWIN)); + color = current & (0x00FFFFFF | FLAG_REBLEND | FLAG_OBJWIN); } } else { color = color & ~FLAG_TARGET_2; @@ -77,7 +74,7 @@ static inline void _compositeNoBlendObjwin(struct GBAVideoSoftwareRenderer* rend if (color < current) { color |= (current & FLAG_OBJWIN); } else { - color = (current & 0x00FFFFFF) | (current & (FLAG_REBLEND | FLAG_OBJWIN)); + color = current & (0x00FFFFFF | FLAG_REBLEND | FLAG_OBJWIN); } renderer->row[x] = color; } @@ -86,15 +83,12 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re uint32_t current) { UNUSED(renderer); if (color >= current) { - color = (current & 0x00FFFFFF) | (current & (FLAG_REBLEND | FLAG_OBJWIN)); + color = current & (0x00FFFFFF | FLAG_REBLEND | FLAG_OBJWIN); } renderer->row[x] = color; } #define COMPOSITE_16_OBJWIN(BLEND, IDX) \ - if (!IS_WRITABLE(current)) { \ - continue; \ - } \ if (objwinForceEnable || (!(current & FLAG_OBJWIN)) == objwinOnly) { \ unsigned color = (current & FLAG_OBJWIN) ? objwinPalette[paletteData | pixelData] : palette[pixelData]; \ unsigned mergedFlags = flags; \ @@ -108,9 +102,6 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re _composite ## BLEND ## NoObjwin(renderer, outX + IDX, palette[pixelData] | flags, current); #define COMPOSITE_256_OBJWIN(BLEND, IDX) \ - if (!IS_WRITABLE(current)) { \ - continue; \ - } \ if (objwinForceEnable || (!(current & FLAG_OBJWIN)) == objwinOnly) { \ unsigned color = (current & FLAG_OBJWIN) ? objwinPalette[pixelData] : palette[pixelData]; \ unsigned mergedFlags = flags; \ diff --git a/src/gba/serialize.c b/src/gba/serialize.c index 8732d2ec1..fe4e15bef 100644 --- a/src/gba/serialize.c +++ b/src/gba/serialize.c @@ -15,7 +15,7 @@ #include const uint32_t GBA_SAVESTATE_MAGIC = 0x01000000; -const uint32_t GBA_SAVESTATE_VERSION = 0x00000003; +const uint32_t GBA_SAVESTATE_VERSION = 0x00000004; mLOG_DEFINE_CATEGORY(GBA_STATE, "GBA Savestate", "gba.serialize"); diff --git a/src/gba/sharkport.c b/src/gba/sharkport.c index f3d033c8d..de8ccd4d4 100644 --- a/src/gba/sharkport.c +++ b/src/gba/sharkport.c @@ -69,7 +69,7 @@ bool GBASavedataImportSharkPort(struct GBA* gba, struct VFile* vf, bool testChec return false; } LOAD_32(size, 0, &buffer.i); - if (size < 0x1C || size >= SIZE_CART_FLASH1M + 0x1C) { + if (size < 0x1C || size > SIZE_CART_FLASH1M + 0x1C) { return false; } char* payload = malloc(size); diff --git a/src/platform/3ds/3ds-vfs.c b/src/platform/3ds/3ds-vfs.c index 8f5864745..508b9fac3 100644 --- a/src/platform/3ds/3ds-vfs.c +++ b/src/platform/3ds/3ds-vfs.c @@ -38,7 +38,7 @@ static void* _vf3dMap(struct VFile* vf, size_t size, int flags); static void _vf3dUnmap(struct VFile* vf, void* memory, size_t size); static void _vf3dTruncate(struct VFile* vf, size_t size); static ssize_t _vf3dSize(struct VFile* vf); -static bool _vf3dSync(struct VFile* vf, const void* buffer, size_t size); +static bool _vf3dSync(struct VFile* vf, void* buffer, size_t size); static bool _vd3dClose(struct VDir* vd); static void _vd3dRewind(struct VDir* vd); @@ -160,14 +160,12 @@ ssize_t _vf3dSize(struct VFile* vf) { return size; } -static bool _vf3dSync(struct VFile* vf, const void* buffer, size_t size) { +static bool _vf3dSync(struct VFile* vf, void* buffer, size_t size) { struct VFile3DS* vf3d = (struct VFile3DS*) vf; if (buffer) { u32 sizeWritten; Result res = FSFILE_Write(vf3d->handle, &sizeWritten, 0, buffer, size, FS_WRITE_FLUSH); - if (res) { - return false; - } + return R_SUCCEEDED(res); } FSFILE_Flush(vf3d->handle); return true; diff --git a/src/platform/3ds/CMakeLists.txt b/src/platform/3ds/CMakeLists.txt index d345c1405..a0c97b617 100644 --- a/src/platform/3ds/CMakeLists.txt +++ b/src/platform/3ds/CMakeLists.txt @@ -7,6 +7,7 @@ find_program(BANNERTOOL bannertool) find_program(MAKEROM makerom) find_program(PICASSO picasso) find_program(RAW2C raw2c) +find_program(TEX3DS tex3ds) set(STRIP "${cross_prefix_path}strip" CACHE INTERNAL "symbol stripper") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-format" PARENT_SCOPE) @@ -65,9 +66,15 @@ add_custom_command(OUTPUT ${BINARY_NAME}.bnr COMMAND ${BANNERTOOL} makebanner -ci ${CMAKE_CURRENT_SOURCE_DIR}/banner.cgfx -a ${CMAKE_CURRENT_SOURCE_DIR}/bios.wav -o ${BINARY_NAME}.bnr DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/banner.cgfx ${CMAKE_CURRENT_SOURCE_DIR}/bios.wav) +# tex3ds binaries as of 2.0.1-3 crash if you try to do this +#add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icons.t3x +# COMMAND ${TEX3DS} -f rgb5551 -o icons.t3x ${CMAKE_SOURCE_DIR}/res/icons.png +# MAIN_DEPENDENCY ${CMAKE_SOURCE_DIR}/res/icons.png +# WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icons.c - COMMAND ${RAW2C} ${CMAKE_SOURCE_DIR}/src/platform/3ds/icons.raw - DEPENDS ${CMAKE_SOURCE_DIR}/src/platform/3ds/icons.raw) + COMMAND ${RAW2C} ${CMAKE_CURRENT_SOURCE_DIR}/icons.t3x + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/icons.t3x) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/uishader.shbin ${CMAKE_CURRENT_BINARY_DIR}/uishader.shbin.h diff --git a/src/platform/3ds/ctr-gpu.c b/src/platform/3ds/ctr-gpu.c index df99d1e10..4a95c4640 100644 --- a/src/platform/3ds/ctr-gpu.c +++ b/src/platform/3ds/ctr-gpu.c @@ -80,6 +80,10 @@ bool ctrInitGpu(void) { AttrInfo_AddLoader(attrInfo, 2, GPU_UNSIGNED_BYTE, 4); // in_col AttrInfo_AddLoader(attrInfo, 3, GPU_FLOAT, 2); // in_rot + C3D_BufInfo* bufInfo = C3D_GetBufInfo(); + BufInfo_Init(bufInfo); + BufInfo_Add(bufInfo, ctrVertexBuffer, sizeof(struct ctrUIVertex), 4, 0x3210); + return true; } @@ -213,13 +217,8 @@ void ctrStartFrame(void) { ctrNumVerts = 0; ctrVertStart = 0; activeTexture = NULL; - - C3D_BufInfo* bufInfo = C3D_GetBufInfo(); - BufInfo_Init(bufInfo); - BufInfo_Add(bufInfo, ctrVertexBuffer, sizeof(struct ctrUIVertex), 4, 0x3210); } void ctrEndFrame(void) { ctrFlushBatch(); - GSPGPU_FlushDataCache(ctrVertexBuffer, sizeof(struct ctrUIVertex) * ctrNumVerts); } diff --git a/src/platform/3ds/gui-font.c b/src/platform/3ds/gui-font.c index 4d4a4f01e..7d073c709 100644 --- a/src/platform/3ds/gui-font.c +++ b/src/platform/3ds/gui-font.c @@ -9,6 +9,7 @@ #include #include "icons.h" +#include #include "ctr-gpu.h" #define FONT_SIZE 15.6f @@ -44,12 +45,8 @@ struct GUIFont* GUIFontCreate(void) { tex->param = GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) | GPU_TEXTURE_MIN_FILTER(GPU_LINEAR) | GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_EDGE) | GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_EDGE); } - tex = &guiFont->icons; - C3D_TexInitVRAM(tex, 256, 64, GPU_RGBA5551); - - GSPGPU_FlushDataCache(icons, icons_size); - GX_RequestDma((u32*) icons, tex->data, icons_size); - gspWaitForDMA(); + Tex3DS_Texture t3x = Tex3DS_TextureImport(icons, icons_size, &guiFont->icons, NULL, true); + Tex3DS_TextureFree(t3x); return guiFont; } @@ -136,23 +133,28 @@ void GUIFontDrawIcon(const struct GUIFont* font, int x, int y, enum GUIAlignment y -= metric.height; break; } + s16 origin = font->icons.height - metric.y - metric.height; + switch (orient) { case GUI_ORIENT_HMIRROR: - ctrAddRectEx(color, x + metric.width, y, - -metric.width, metric.height, - metric.x, metric.y, + ctrAddRectEx(color, x + metric.width, y + metric.height, + -metric.width, -metric.height, + metric.x, origin, metric.width, metric.height, 0); break; case GUI_ORIENT_VMIRROR: - ctrAddRectEx(color, x, y + metric.height, - metric.width, -metric.height, - metric.x, metric.y, + ctrAddRectEx(color, x, y, + metric.width, metric.height, + metric.x, origin, metric.width, metric.height, 0); break; case GUI_ORIENT_0: default: // TODO: Rotation - ctrAddRect(color, x, y, metric.x, metric.y, metric.width, metric.height); + ctrAddRectEx(color, x, y + metric.height, + metric.width, -metric.height, + metric.x, origin, + metric.width, metric.height, 0); break; } } @@ -163,11 +165,10 @@ void GUIFontDrawIconSize(const struct GUIFont* font, int x, int y, int w, int h, if (icon >= GUI_ICON_MAX) { return; } - struct GUIIconMetric metric = defaultIconMetrics[icon]; - ctrAddRectEx(color, x, y, + ctrAddRectEx(color, x, y + (h ? h : metric.height), w ? w : metric.width, - h ? h : metric.height, - metric.x, metric.y, + h ? -h : -metric.height, + metric.x, font->icons.height - metric.y - metric.height, metric.width, metric.height, 0); } diff --git a/src/platform/3ds/icons.raw b/src/platform/3ds/icons.raw deleted file mode 100644 index d60815862..000000000 Binary files a/src/platform/3ds/icons.raw and /dev/null differ diff --git a/src/platform/3ds/icons.t3x b/src/platform/3ds/icons.t3x new file mode 100644 index 000000000..171b8bd01 Binary files /dev/null and b/src/platform/3ds/icons.t3x differ diff --git a/src/platform/psp2/CMakeLists.txt b/src/platform/psp2/CMakeLists.txt index 1fb0c9928..47094b9f9 100644 --- a/src/platform/psp2/CMakeLists.txt +++ b/src/platform/psp2/CMakeLists.txt @@ -28,6 +28,7 @@ set(OS_LIB -lvita2d -l${M_LIBRARY} -lScePower_stub -lSceSysmodule_stub -lSceTouch_stub) +set(OS_LIB ${OS_LIB} PARENT_SCOPE) set(OBJCOPY_CMD ${OBJCOPY} -I binary -O elf32-littlearm -B arm) list(APPEND GUI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gui-font.c) @@ -61,5 +62,30 @@ vita_create_vpk(${BINARY_NAME}.vpk MGBA00001 ${BINARY_NAME}.self FILE ${CMAKE_CURRENT_SOURCE_DIR}/startup.png sce_sys/livearea/contents/startup.png FILE ${CMAKE_CURRENT_BINARY_DIR}/template.xml sce_sys/livearea/contents/template.xml) +if(BUILD_PERF) + add_executable(perf-main.elf perf.c) + set_target_properties(perf-main.elf PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}") + target_link_libraries(perf-main.elf ${OS_LIB}) + + vita_create_self(perf.bin ../${BINARY_NAME}-perf) + vita_create_self(perf-main.self perf-main.elf) + + vita_create_vpk(${BINARY_NAME}-perf.vpk MGBA00002 perf-main.self + NAME "${PROJECT_NAME} Perf Tester" + FILE ${CMAKE_CURRENT_BINARY_DIR}/perf.bin perf.bin + FILE ${CMAKE_CURRENT_SOURCE_DIR}/icon0.png sce_sys/icon0.png + FILE ${CMAKE_CURRENT_SOURCE_DIR}/pic0.png sce_sys/pic0.png + FILE ${CMAKE_CURRENT_SOURCE_DIR}/bg.png sce_sys/livearea/contents/bg.png + FILE ${CMAKE_CURRENT_SOURCE_DIR}/startup.png sce_sys/livearea/contents/startup.png + FILE ${CMAKE_CURRENT_BINARY_DIR}/template.xml sce_sys/livearea/contents/template.xml) + add_dependencies(${BINARY_NAME}-perf.vpk perf.bin) + + install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/perf.bin + ${CMAKE_CURRENT_SOURCE_DIR}/perf-start.sh + ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}-perf.vpk + DESTINATION . COMPONENT ${BINARY_NAME}-perf) +endif() + install(TARGETS ${BINARY_NAME}.elf DESTINATION . COMPONENT ${BINARY_NAME}-dbg) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}.vpk DESTINATION . COMPONENT ${BINARY_NAME}-psp2) diff --git a/src/platform/psp2/perf-start.sh b/src/platform/psp2/perf-start.sh new file mode 100755 index 000000000..d6c593e96 --- /dev/null +++ b/src/platform/psp2/perf-start.sh @@ -0,0 +1,17 @@ +#!/bin/sh +IP=$1 +shift + +# Kill any previous session +echo | nc $IP 7215 > /dev/null +echo | nc $IP 7216 > /dev/null + +curl -sT perf.bin ftp://$IP:1337/ux0:app/MGBA00002/ +echo launch MGBA00002 | nc $IP 1338 > /dev/null + +sleep 2 + +(for ARG in $@; do + echo $ARG +done; echo) | nc $IP 7215 +exit 0 diff --git a/src/platform/psp2/perf.c b/src/platform/psp2/perf.c new file mode 100644 index 000000000..5e6de8b91 --- /dev/null +++ b/src/platform/psp2/perf.c @@ -0,0 +1,57 @@ +/* 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 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include + +#include +#include +#include + +#define MAX_ARGS 19 + + +void connectServer(char* args[]) { + Socket server = SocketOpenTCP(7215, NULL); + if (SOCKET_FAILED(server)) { + return; + } + if (SOCKET_FAILED(SocketListen(server, 0))) { + SocketClose(server); + return; + } + Socket conn = SocketAccept(server, NULL); + if (SOCKET_FAILED(conn)) { + SocketClose(server); + return; + } + + int i = 0; + ssize_t len; + char arg[1024]; + while (i < MAX_ARGS && (len = SocketRecv(conn, arg, sizeof(arg) - 1)) > 0) { + arg[len] = '\0'; + char* tok; + for (tok = strtok(arg, "\n"); tok && i < MAX_ARGS; ++i) { + args[i] = strdup(tok); + tok = strtok(NULL, "\n"); + } + if (arg[len - 1] == '\n') { + return; + } + } + + SocketClose(conn); + SocketClose(server); +} + +int main() { + char* args[MAX_ARGS + 1] = { 0 }; + SocketSubsystemInit(); + connectServer(args); + SocketSubsystemDeinit(); + sceAppMgrLoadExec("app0:/perf.bin", args, NULL); + sceKernelExitProcess(0); + return 0; +} diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index 74eb7b039..420bd444b 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -50,7 +50,6 @@ static enum ScreenMode { SM_MAX } screenMode; -static void* outputBuffer; static int currentTex; static vita2d_texture* tex[2]; static vita2d_texture* screenshot; @@ -493,7 +492,6 @@ void mPSP2Teardown(struct mGUIRunner* runner) { vita2d_free_texture(tex[0]); vita2d_free_texture(tex[1]); vita2d_free_texture(screenshot); - mappedMemoryFree(outputBuffer, 256 * 256 * 4); frameLimiter = true; } diff --git a/src/platform/psp2/psp2-memory.c b/src/platform/psp2/psp2-memory.c index 7ff56318b..a8d342a30 100644 --- a/src/platform/psp2/psp2-memory.c +++ b/src/platform/psp2/psp2-memory.c @@ -4,21 +4,11 @@ * 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 -#include #include #include -DECLARE_VECTOR(SceUIDList, SceUID); -DEFINE_VECTOR(SceUIDList, SceUID); - -static struct SceUIDList uids; -static bool listInit = false; - void* anonymousMemoryMap(size_t size) { - if (!listInit) { - SceUIDListInit(&uids, 8); - } if (size & 0xFFF) { // Align to 4kB pages size += ((~size) & 0xFFF) + 1; @@ -27,7 +17,6 @@ void* anonymousMemoryMap(size_t size) { if (memblock < 0) { return 0; } - *SceUIDListAppend(&uids) = memblock; void* ptr; if (sceKernelGetMemBlockBase(memblock, &ptr) < 0) { return 0; @@ -36,18 +25,8 @@ void* anonymousMemoryMap(size_t size) { } void mappedMemoryFree(void* memory, size_t size) { - UNUSED(size); - size_t i; - for (i = 0; i < SceUIDListSize(&uids); ++i) { - SceUID uid = *SceUIDListGetPointer(&uids, i); - void* ptr; - if (sceKernelGetMemBlockBase(uid, &ptr) < 0) { - continue; - } - if (ptr == memory) { - sceKernelFreeMemBlock(uid); - SceUIDListShift(&uids, i, 1); - return; - } + SceUID uid = sceKernelFindMemBlockByAddr(memory, size); + if (uid >= 0) { + sceKernelFreeMemBlock(uid); } } diff --git a/src/platform/psp2/sce-vfs.c b/src/platform/psp2/sce-vfs.c index c200d8903..22b05950f 100644 --- a/src/platform/psp2/sce-vfs.c +++ b/src/platform/psp2/sce-vfs.c @@ -40,7 +40,7 @@ static void* _vfsceMap(struct VFile* vf, size_t size, int flags); static void _vfsceUnmap(struct VFile* vf, void* memory, size_t size); static void _vfsceTruncate(struct VFile* vf, size_t size); static ssize_t _vfsceSize(struct VFile* vf); -static bool _vfsceSync(struct VFile* vf, const void* memory, size_t size); +static bool _vfsceSync(struct VFile* vf, void* memory, size_t size); static bool _vdsceClose(struct VDir* vd); static void _vdsceRewind(struct VDir* vd); @@ -146,13 +146,14 @@ ssize_t _vfsceSize(struct VFile* vf) { return end; } -bool _vfsceSync(struct VFile* vf, const void* buffer, size_t size) { +bool _vfsceSync(struct VFile* vf, void* buffer, size_t size) { struct VFileSce* vfsce = (struct VFileSce*) vf; if (buffer && size) { SceOff cur = sceIoLseek(vfsce->fd, 0, SEEK_CUR); sceIoLseek(vfsce->fd, 0, SEEK_SET); - sceIoWrite(vfsce->fd, buffer, size); + int res = sceIoWrite(vfsce->fd, buffer, size); sceIoLseek(vfsce->fd, cur, SEEK_SET); + return res == size; } return sceIoSyncByFd(vfsce->fd) >= 0; } @@ -362,4 +363,4 @@ bool VDirCreate(const char* path) { // TODO: Verify vitasdk explanation of return values sceIoMkdir(path, 0777); return true; -} \ No newline at end of file +} diff --git a/src/platform/python/mgba/arm.py b/src/platform/python/mgba/arm.py index 7d1e6ac98..a2459a8a7 100644 --- a/src/platform/python/mgba/arm.py +++ b/src/platform/python/mgba/arm.py @@ -22,8 +22,36 @@ class _ARMRegisters: class ARMCore: + SP = 13 + LR = 14 + PC = 15 + def __init__(self, native): self._native = ffi.cast("struct ARMCore*", native) self.gprs = _ARMRegisters(self) self.cpsr = self._native.cpsr self.spsr = self._native.spsr + + @property + def sp(self): + return self.gprs[self.SP] + + @sp.setter + def sp(self, value): + self.gprs[self.SP] = value + + @property + def lr(self): + return self.gprs[self.LR] + + @lr.setter + def lr(self, value): + self.gprs[self.LR] = value + + @property + def pc(self): + return self.gprs[self.PC] + + @pc.setter + def pc(self, value): + self.gprs[self.PC] = value diff --git a/src/platform/python/mgba/vfs.py b/src/platform/python/mgba/vfs.py index bab78c799..af527284b 100644 --- a/src/platform/python/mgba/vfs.py +++ b/src/platform/python/mgba/vfs.py @@ -73,8 +73,9 @@ def _vfpSync(vf, buffer, size): if buffer and size: pos = f.tell() f.seek(0, os.SEEK_SET) - _vfpWrite(vf, buffer, size) + res = _vfpWrite(vf, buffer, size) f.seek(pos, os.SEEK_SET) + return res == size f.flush() os.fsync() return True @@ -114,6 +115,10 @@ class VFile: self._no_gc = _no_gc self._claimed = False + @staticmethod + def fromEmpty(): + return VFile(lib.VFileMemChunk(ffi.NULL, 0)) + def __del__(self): if not self._claimed: self.close() diff --git a/src/platform/python/vfs-py.h b/src/platform/python/vfs-py.h index 2f913a741..377474a8a 100644 --- a/src/platform/python/vfs-py.h +++ b/src/platform/python/vfs-py.h @@ -22,4 +22,4 @@ PYEXPORT void* _vfpMap(struct VFile* vf, size_t size, int flags); PYEXPORT void _vfpUnmap(struct VFile* vf, void* memory, size_t size); PYEXPORT void _vfpTruncate(struct VFile* vf, size_t size); PYEXPORT ssize_t _vfpSize(struct VFile* vf); -PYEXPORT bool _vfpSync(struct VFile* vf, const void* buffer, size_t size); +PYEXPORT bool _vfpSync(struct VFile* vf, void* buffer, size_t size); diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index 7baa7deb5..5c9b2cb8f 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -42,6 +42,9 @@ BattleChipView::BattleChipView(std::shared_ptr controller, Windo #else int size = QFontMetrics(QFont()).height() / (devicePixelRatio() * 12); #endif + if (!size) { + size = 1; + } m_ui.chipList->setIconSize(m_ui.chipList->iconSize() * size); m_ui.chipList->setGridSize(m_ui.chipList->gridSize() * size); m_model.setScale(size); @@ -259,4 +262,4 @@ void BattleChipView::updateData() { m_updater = nullptr; }); m_updater->downloadUpdate(); -} \ No newline at end of file +} diff --git a/src/platform/qt/CoreManager.cpp b/src/platform/qt/CoreManager.cpp index 74c38d1ea..fdd94ba80 100644 --- a/src/platform/qt/CoreManager.cpp +++ b/src/platform/qt/CoreManager.cpp @@ -7,12 +7,16 @@ #include "CoreController.h" #include "LogController.h" +#include "VFileDevice.h" #include #ifdef M_CORE_GBA #include #endif +#ifdef M_CORE_GB +#include +#endif #include #include @@ -27,6 +31,57 @@ void CoreManager::setMultiplayerController(MultiplayerController* multiplayer) { m_multiplayer = multiplayer; } +QByteArray CoreManager::getExtdata(const QString& filename, mStateExtdataTag extdataType) { + VFileDevice vf(filename, QIODevice::ReadOnly); + + if (!vf.isOpen()) { + return {}; + } + + mStateExtdata extdata; + mStateExtdataInit(&extdata); + + QByteArray bytes; + auto extract = [&bytes, &extdata, &vf, extdataType](mCore* core) -> bool { + if (mCoreExtractExtdata(core, vf, &extdata)) { + mStateExtdataItem extitem; + if (!mStateExtdataGet(&extdata, extdataType, &extitem)) { + return false; + } + if (extitem.size) { + bytes = QByteArray::fromRawData(static_cast(extitem.data), extitem.size); + } + return true; + } + return false; + }; + + bool done = false; + struct mCore* core = nullptr; +#ifdef USE_PNG + done = extract(nullptr); +#endif +#ifdef M_CORE_GBA + if (!done) { + core = GBACoreCreate(); + core->init(core); + done = extract(core); + core->deinit(core); + } +#endif +#ifdef M_CORE_GB + if (!done) { + core = GBCoreCreate(); + core->init(core); + done = extract(core); + core->deinit(core); + } +#endif + + mStateExtdataDeinit(&extdata); + return bytes; +} + CoreController* CoreManager::loadGame(const QString& path) { QFileInfo info(path); if (!info.isReadable()) { diff --git a/src/platform/qt/CoreManager.h b/src/platform/qt/CoreManager.h index da7460f22..3a31288b9 100644 --- a/src/platform/qt/CoreManager.h +++ b/src/platform/qt/CoreManager.h @@ -9,6 +9,8 @@ #include #include +#include + struct mCoreConfig; struct VFile; @@ -25,6 +27,8 @@ public: void setMultiplayerController(MultiplayerController*); void setPreload(bool preload) { m_preload = preload; } + static QByteArray getExtdata(const QString& filename, mStateExtdataTag extdataType); + public slots: CoreController* loadGame(const QString& path); CoreController* loadGame(VFile* vf, const QString& path, const QString& base); diff --git a/src/platform/qt/MemoryView.cpp b/src/platform/qt/MemoryView.cpp index 0aefb642f..23e727354 100644 --- a/src/platform/qt/MemoryView.cpp +++ b/src/platform/qt/MemoryView.cpp @@ -13,6 +13,97 @@ using namespace QGBA; +IntValidator::IntValidator(bool isSigned, QObject* parent) + : QValidator(parent) + , m_signed(isSigned) +{ +} + +QValidator::State IntValidator::validate(QString& input, int&) const { + if (input.isEmpty()) { + return QValidator::Intermediate; + } + if (input.size() == 1 && input[0] == '-') { + if (m_signed) { + return QValidator::Intermediate; + } else { + return QValidator::Invalid; + } + } + if (input[0].isSpace()) { + return QValidator::Invalid; + } + if (input[input.size() - 1].isSpace()) { + return QValidator::Invalid; + } + if (input.size() > 1 && input[0] == '0') { + return QValidator::Invalid; + } + + bool ok = false; + qlonglong val = locale().toLongLong(input, &ok); + if (!ok) { + return QValidator::Invalid; + } + + qlonglong hardmax; + qlonglong hardmin; + qlonglong max; + qlonglong min; + + if (m_signed) { + switch (m_width) { + case 1: + hardmax = 999LL; + hardmin = -999LL; + max = 0x7FLL; + min = -0x80LL; + break; + case 2: + hardmax = 99999LL; + hardmin = -99999LL; + max = 0x7FFFLL; + min = -0x8000LL; + break; + case 4: + hardmax = 9999999999LL; + hardmin = -9999999999LL; + max = 0x7FFFFFFFLL; + min = -0x80000000LL; + break; + default: + return QValidator::Invalid; + } + } else { + hardmin = 0; + min = 0; + + switch (m_width) { + case 1: + hardmax = 999LL; + max = 0xFFLL; + break; + case 2: + hardmax = 99999LL; + max = 0xFFFFLL; + break; + case 4: + hardmax = 9999999999LL; + max = 0xFFFFFFFFLL; + break; + default: + return QValidator::Invalid; + } + } + if (val < hardmin || val > hardmax) { + return QValidator::Invalid; + } + if (val < min || val > max) { + return QValidator::Intermediate; + } + return QValidator::Acceptable; +} + MemoryView::MemoryView(std::shared_ptr controller, QWidget* parent) : QWidget(parent) , m_controller(controller) @@ -21,6 +112,9 @@ MemoryView::MemoryView(std::shared_ptr controller, QWidget* pare m_ui.hexfield->setController(controller); + m_ui.sintVal->setValidator(&m_sintValidator); + m_ui.uintVal->setValidator(&m_uintValidator); + mCore* core = m_controller->thread()->core; const mCoreMemoryBlock* info; size_t nBlocks = core->listMemoryBlocks(core, &info); @@ -39,9 +133,21 @@ MemoryView::MemoryView(std::shared_ptr controller, QWidget* pare } } - connect(m_ui.width8, &QAbstractButton::clicked, [this]() { m_ui.hexfield->setAlignment(1); }); - connect(m_ui.width16, &QAbstractButton::clicked, [this]() { m_ui.hexfield->setAlignment(2); }); - connect(m_ui.width32, &QAbstractButton::clicked, [this]() { m_ui.hexfield->setAlignment(4); }); + connect(m_ui.width8, &QAbstractButton::clicked, [this]() { + m_ui.hexfield->setAlignment(1); + m_sintValidator.setWidth(1); + m_uintValidator.setWidth(1); + }); + connect(m_ui.width16, &QAbstractButton::clicked, [this]() { + m_ui.hexfield->setAlignment(2); + m_sintValidator.setWidth(2); + m_uintValidator.setWidth(2); + }); + connect(m_ui.width32, &QAbstractButton::clicked, [this]() { + m_ui.hexfield->setAlignment(4); + m_sintValidator.setWidth(4); + m_uintValidator.setWidth(4); + }); connect(m_ui.setAddress, static_cast(&QSpinBox::valueChanged), this, static_cast(&MemoryView::jumpToAddress)); connect(m_ui.hexfield, &MemoryModel::selectionChanged, this, &MemoryView::updateSelection); @@ -60,6 +166,41 @@ MemoryView::MemoryView(std::shared_ptr controller, QWidget* pare connect(m_ui.load, &QAbstractButton::clicked, m_ui.hexfield, &MemoryModel::load); connect(m_ui.loadTBL, &QAbstractButton::clicked, m_ui.hexfield, &MemoryModel::loadTBL); + + connect(m_ui.sintVal, &QLineEdit::returnPressed, this, [this]() { + int align = m_ui.hexfield->alignment(); + mCore* core = m_controller->thread()->core; + int32_t value = m_ui.sintVal->text().toInt(); + switch (align) { + case 1: + core->rawWrite8(core, m_selection.first, m_ui.segments->value(), value); + break; + case 2: + core->rawWrite16(core, m_selection.first, m_ui.segments->value(), value); + break; + case 4: + core->rawWrite32(core, m_selection.first, m_ui.segments->value(), value); + break; + } + update(); + }); + connect(m_ui.uintVal, &QLineEdit::returnPressed, this, [this]() { + int align = m_ui.hexfield->alignment(); + mCore* core = m_controller->thread()->core; + uint32_t value = m_ui.uintVal->text().toUInt(); + switch (align) { + case 1: + core->rawWrite8(core, m_selection.first, m_ui.segments->value(), value); + break; + case 2: + core->rawWrite16(core, m_selection.first, m_ui.segments->value(), value); + break; + case 4: + core->rawWrite32(core, m_selection.first, m_ui.segments->value(), value); + break; + } + update(); + }); } void MemoryView::setIndex(int index) { @@ -116,7 +257,9 @@ void MemoryView::updateStatus() { if (m_selection.first & (align - 1) || m_selection.second - m_selection.first != align) { m_ui.sintVal->clear(); + m_ui.sintVal->setReadOnly(true); m_ui.uintVal->clear(); + m_ui.uintVal->setReadOnly(true); return; } union { @@ -144,6 +287,8 @@ void MemoryView::updateStatus() { m_ui.uintVal->setText(QString::number(value.u32)); break; } + m_ui.sintVal->setReadOnly(false); + m_ui.uintVal->setReadOnly(false); } void MemoryView::saveRange() { @@ -153,4 +298,4 @@ void MemoryView::saveRange() { memdump->setSegment(m_ui.segments->value()); memdump->setByteCount(m_selection.second - m_selection.first); memdump->show(); -} \ No newline at end of file +} diff --git a/src/platform/qt/MemoryView.h b/src/platform/qt/MemoryView.h index ac4bfe53d..f68052a06 100644 --- a/src/platform/qt/MemoryView.h +++ b/src/platform/qt/MemoryView.h @@ -5,6 +5,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #pragma once +#include + #include "MemoryModel.h" #include "ui_MemoryView.h" @@ -13,6 +15,20 @@ namespace QGBA { class CoreController; +class IntValidator : public QValidator { +Q_OBJECT + +public: + IntValidator(bool isSigned, QObject* parent = nullptr); + + virtual QValidator::State validate(QString& input, int& pos) const override; + void setWidth(int bytes) { m_width = bytes; } + +private: + int m_width = 1; + bool m_signed; +}; + class MemoryView : public QWidget { Q_OBJECT @@ -32,6 +48,8 @@ private slots: private: Ui::MemoryView m_ui; + IntValidator m_sintValidator{true}; + IntValidator m_uintValidator{false}; std::shared_ptr m_controller; QPair m_region; diff --git a/src/platform/qt/MemoryView.ui b/src/platform/qt/MemoryView.ui index fb43fbe22..472ed87eb 100644 --- a/src/platform/qt/MemoryView.ui +++ b/src/platform/qt/MemoryView.ui @@ -190,6 +190,9 @@ + + 10 + true @@ -208,6 +211,9 @@ + + 11 + true @@ -304,6 +310,23 @@ 1 + + regions + segments + setAddress + width8 + width16 + width32 + sintVal + uintVal + stringVal + loadTBL + copy + paste + save + saveRange + load + diff --git a/src/platform/qt/OverrideView.cpp b/src/platform/qt/OverrideView.cpp index e73f657ba..b045caecb 100644 --- a/src/platform/qt/OverrideView.cpp +++ b/src/platform/qt/OverrideView.cpp @@ -50,6 +50,8 @@ OverrideView::OverrideView(ConfigController* config, QWidget* parent) s_mbcList.append(GB_HuC1); s_mbcList.append(GB_HuC3); s_mbcList.append(GB_UNL_WISDOM_TREE); + s_mbcList.append(GB_UNL_BBD); + s_mbcList.append(GB_UNL_HITEK); s_mbcList.append(GB_UNL_PKJD); } if (s_gbModelList.isEmpty()) { diff --git a/src/platform/qt/OverrideView.ui b/src/platform/qt/OverrideView.ui index 61d4449fb..28fb357e2 100644 --- a/src/platform/qt/OverrideView.ui +++ b/src/platform/qt/OverrideView.ui @@ -359,6 +359,16 @@ Wisdom Tree (Unlicensed) + + + BBD (Unlicensed) + + + + + Hitek (Unlicensed) + + Pokémon Jade/Diamond (Unlicensed) diff --git a/src/platform/qt/VFileDevice.cpp b/src/platform/qt/VFileDevice.cpp index 49b761768..5b4eee49b 100644 --- a/src/platform/qt/VFileDevice.cpp +++ b/src/platform/qt/VFileDevice.cpp @@ -19,6 +19,23 @@ VFileDevice::VFileDevice(VFile* vf, QObject* parent) } } +VFileDevice::VFileDevice(const QString& filename, QIODevice::OpenMode mode, QObject* parent) + : QIODevice(parent) +{ + int posixMode = 0; + if ((mode & QIODevice::ReadWrite) == QIODevice::ReadWrite) { + posixMode = O_RDWR; + } else if (mode & QIODevice::ReadOnly) { + posixMode = O_RDONLY; + } else if (mode & QIODevice::WriteOnly) { + posixMode = O_WRONLY; + } + m_vf = open(filename, posixMode); + if (m_vf) { + setOpenMode(mode); + } +} + void VFileDevice::close() { if (!m_vf) { return; diff --git a/src/platform/qt/VFileDevice.h b/src/platform/qt/VFileDevice.h index 180be2e6e..4edc29c47 100644 --- a/src/platform/qt/VFileDevice.h +++ b/src/platform/qt/VFileDevice.h @@ -17,6 +17,7 @@ Q_OBJECT public: VFileDevice(VFile* vf = nullptr, QObject* parent = nullptr); + VFileDevice(const QString&, QIODevice::OpenMode, QObject* parent = nullptr); virtual void close() override; virtual bool seek(qint64 pos) override; diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index c30ae7fc6..f0ecb93d6 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1518,12 +1518,9 @@ void Window::setupMenu(QMenuBar* menubar) { ConfigOption* mute = m_config->addOption("mute"); mute->addBoolean(tr("Mute"), &m_actions, "av"); mute->connect([this](const QVariant& value) { - if (value.toInt()) { - m_config->setOption("fastForwardMute", true); - } + m_config->setOption("fastForwardMute", static_cast(value.toInt())); reloadConfig(); }, this); - m_config->updateOption("mute"); m_actions.addMenu(tr("FPS target"),"target", "av"); ConfigOption* fpsTargetOption = m_config->addOption("fpsTarget"); diff --git a/src/platform/qt/ts/medusa-emu-de.ts b/src/platform/qt/ts/medusa-emu-de.ts index 02af19f14..b05656268 100644 --- a/src/platform/qt/ts/medusa-emu-de.ts +++ b/src/platform/qt/ts/medusa-emu-de.ts @@ -306,26 +306,46 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.GIFView - Record GIF - GIF aufzeichnen + Record GIF/APNG + GIF/APNG aufzeichnen - + + Loop + Wiederholen + + + Start Start - + Stop Stop - + Select File Datei wählen - + + APNG + APNG + + + + GIF + GIF + + + + WebP + WebP + + + Frameskip Frameskip @@ -889,145 +909,162 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Sprites - - + + × × - + Magnification Vergrößerung - + Export Exportieren - + Attributes Eigenschaften - + Transform Transform - + Off Aus - + Palette Palette - - - - + + + + 0 0 - + Copy Kopieren - + + + +0.00 + +0.00 + + + + + +1.00 + +1.00 + + + + Matrix + Matrix + + + Double Size Doppelte Größe - - - - + + + + Return, Ctrl+R Eingabe, Strg+R - + Flipped Gespiegelt - + H H - + V V - + Mode Modus - + Normal Normal - + Mosaic Mosaic - + Enabled Aktiviert - + Priority Priorität - + Tile - + Geometry Geometrie - + Position Position - + , , - + Dimensions - Abmessungen + Größe - - + + 8 8 - + Address Adresse - + 0x07000000 0x07000000 @@ -1219,17 +1256,27 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.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 @@ -1305,8 +1352,8 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - 000 - 000 + 0x000 (000) + 0x000 (000) @@ -1436,22 +1483,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 @@ -1463,46 +1510,56 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.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? + QGBA::FrameView - + Export frame Bild exportieren - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - + None Keine - + Background Hintergrund - + Window Fenster - + Sprite Sprite - + Backdrop Hintergrund - + %1 %2 %1 %2 @@ -1584,19 +1641,19 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::GIFView - - Failed to open output GIF file: %1 - Fehler beim Öffnen der Ausgabe-GIF-Datei: %1 + + Failed to open output file: %1 + Fehler beim Öffnen der Ausgabedatei: %1 - + Select output file Ausgabedatei auswählen - - Graphics Interchange Format (*.gif) - Graphics Interchange Format (*.gif) + + Graphics Interchange Format (*.gif);;Animated Portable Network Graphics (*.png *.webp *.apng) + Graphics Interchange Format (*.gif);;Animated Portable Network Graphics (*.png *.webp *.apng) @@ -3001,11 +3058,26 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::KeyEditor - - + + --- --- + + + Super (L) + Super (L) + + + + Super (R) + Super (R) + + + + Menu + Menü + QGBA::LoadSaveState @@ -3082,47 +3154,47 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::LogController - + [%1] %2: %3 [%1] %2: %3 - + An error occurred Ein Fehler ist aufgetreten - + DEBUG DEBUG - + STUB STUB - + INFO INFO - + WARN WARN - + ERROR ERROR - + FATAL FATAL - + GAME ERROR GAME ERROR @@ -3195,17 +3267,17 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - + N/A N/A - + Export map Map exportieren - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) @@ -3246,42 +3318,42 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Laden - + All Alle - + Load TBL TBL laden - + Save selected memory Ausgewählten Speicher abspeichern - + Failed to open output file: %1 Fehler beim Öffnen der Ausgabedatei: %1 - + Load memory Lade Speicher - + Failed to open input file: %1 Fehler beim Laden der Eingabedatei: %1 - + TBL TBL - + ISO-8859-1 ISO-8859-1 @@ -3289,22 +3361,22 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::MemorySearch - + (%0/%1×) (%0/%1×) - + (⅟%0×) (⅟%0×) - + (%0×) (%0×) - + %1 byte%2 %1 byte%2 @@ -3312,49 +3384,61 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::ObjView - - + + 0x%0 0x%0 - + Off Aus - + + + + + + + + + --- + --- + + + Normal Normal - + Trans Trans - + OBJWIN OBJWIN - + Invalid Ungültig - - + + N/A N/A - + Export sprite Sprite exportieren - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) @@ -3373,10 +3457,6 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - %0 - %0 - - @@ -3482,7 +3562,7 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.BIOS auswählen - + (%1×%2) (%1×%2) @@ -3490,12 +3570,12 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::ShaderSelector - + No shader active Kein Shader aktiv - + Load shader Shader laden @@ -3510,12 +3590,12 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.von %1 - + Preprocessing Vorbehandlung - + Pass %1 Durchlauf %1 @@ -3560,12 +3640,12 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::VideoView - + Failed to open output video file: %1 Fehler beim Öffnen der Ausgabe-Videodatei: %1 - + Native (%0x%1) Nativ (%0x%1) @@ -3578,7 +3658,7 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::Window - + Game Boy Advance ROMs (%1) Game Boy Advance-ROMs (%1) @@ -3588,78 +3668,78 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.DS-ROMs (%1) - + Game Boy ROMs (%1) 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) @@ -3674,22 +3754,22 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.DS-Unterstützung erfordert ein Abbild des BIOS und der Firmware. - + Select video log Video-Log auswählen - + Video logs (*.mvl) Video-Logs (*.mvl) - + Crash Absturz - + The game has crashed with the following error: %1 @@ -3698,433 +3778,408 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - - Couldn't Load - Konnte nicht geladen werden - - - - Could not load game. Are you sure it's in the correct format? - Konnte das Spiel nicht laden. Sind Sie sicher, dass es im korrekten Format vorliegt? - - - + 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... - - Import GameShark Save - Importiere GameShark-Speicherstand - - - - Export GameShark Save - Exportiere GameShark-Speicherstand - - - + 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 - - Record GIF... - GIF aufzeichen... - - - + 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... @@ -4144,72 +4199,112 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.DS - + Select folder 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... @@ -4219,87 +4314,87 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.&I/O-Register betrachten... - + Search memory... 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 @@ -4322,6 +4417,29 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.? + + QShortcut + + + Shift + Shift + + + + Control + Strg + + + + Alt + Alt + + + + Meta + AltGr + + ROMInfo @@ -4612,7 +4730,7 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - + frames Bild(er) @@ -4723,142 +4841,148 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.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 - + Camera: Kamera: - - - - - Autodetect - Automatisch erkennen - - - - - - Game Boy (DMG) - Game Boy (DMG) - - Super Game Boy (SGB) - Super Game Boy (SGB) + Autodetect + Automatisch erkennen - Game Boy Color (CGB) - Game Boy Color (CGB) + 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: @@ -4878,26 +5002,26 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Cache leeren - + Fast forward speed: Vorlauf-Geschwindigkeit: - + Preload entire ROM into memory ROM-Datei vollständig in Arbeitsspeicher vorladen - - - - - - - - - + + + + + + + + + Browse Durchsuchen @@ -4912,26 +5036,26 @@ in Arbeitsspeicher vorladen DS-BIOS 9: - + Use BIOS file if found BIOS-Datei verwenden, wenn vorhanden - + Skip BIOS intro BIOS-Intro überspringen - - - + + + × × - - + + Unbounded unbegrenzt @@ -4951,17 +5075,17 @@ wenn vorhanden Pause, wenn inaktiv - + Run all Alle ausführen - + Remove known Bekannte entfernen - + Detect and remove Erkennen und entfernen @@ -4971,25 +5095,25 @@ wenn vorhanden Gegensätzliche Eingaberichtungen erlauben - - + + Screenshot Screenshot - - + + Save data Speicherdaten - - + + Cheat codes Cheat-Codes - + Enable rewind Rücklauf aktivieren @@ -4999,47 +5123,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: @@ -5049,36 +5173,36 @@ wenn vorhanden DS-Firmware: - + SGB BIOS file: Datei mit SGB-BIOS: - + Save games Spielstände - - - - - + + + + + Same directory as the ROM Verzeichnis der ROM-Datei - + Save states Savestates - + Screenshots Screenshots - + Patches Patches @@ -5226,27 +5350,28 @@ wenn vorhanden - + WebM WebM - + Format Format - + MKV MKV - + AVI AVI - + + MP4 MP4 @@ -5261,132 +5386,143 @@ wenn vorhanden &YouTube - + &Lossless Ver&lustfrei - + + 4K + 4K + + + &1080p &1080p - + &720p &720p - + &480p &480p - + &Native &Nativ - + h.264 h.264 - + h.264 (NVENC) h.264 (NVENC) - + HEVC HEVC - + HEVC (NVENC) HEVC (NVENC) - + VP8 VP8 - + VP9 VP9 - + FFV1 FFV1 - + + + None + Leer + + + FLAC FLAC - + Opus Opus - + Vorbis Vorbis - + MP3 MP3 - + AAC AAC - + Uncompressed Unkomprimiert - + Bitrate (kbps) Bitrate (kbps) - + VBR VBR - + ABR ABR - + Dimensions Abmessungen - + : : - + × × - + Lock aspect ratio Seitenverhältnis sperren - + Show advanced Erweiterte Optionen anzeigen diff --git a/src/platform/qt/ts/medusa-emu-es.ts b/src/platform/qt/ts/medusa-emu-es.ts index f02368962..f58e84d4d 100644 --- a/src/platform/qt/ts/medusa-emu-es.ts +++ b/src/platform/qt/ts/medusa-emu-es.ts @@ -33,12 +33,6 @@ © 2013 – 2020 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 Game Boy Advance is a registered trademark of Nintendo Co., Ltd. © 2013 – 2020 Jeffrey Pfau, licenciado bajo la Mozilla Public License, versión 2.0 -Game Boy Advance es una marca registrada de Nintendo Co., Ltd. - - - © 2013 – 2018 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 -Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - © 2013 – 2018 Jeffrey Pfau, licenciado bajo la Mozilla Public License, versión 2.0 Game Boy Advance es una marca registrada de Nintendo Co., Ltd. @@ -312,37 +306,49 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. GIFView - Record GIF - Grabar GIF + Record GIF/APNG + - + + Loop + + + + Start Iniciar - + Stop Detener - + Select File Seleccionar archivo - + + APNG + + + + + GIF + + + + + WebP + + + + Frameskip Salto - - Frame delay (ms) - Retraso (ms) - - - Automatic - Automático - IOViewer @@ -791,30 +797,6 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Guess Adivinar - - Compare - Comparar - - - Equal - Igual a - - - Greater - Mayor que - - - Less - Menor que - - - Delta - Diferencia - - - Search - Buscar - Search Within @@ -858,18 +840,6 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Set Alignment: Alinear a: - - 1 Byte - 1 byte - - - 2 Bytes - 2 bytes - - - 4 Bytes - 4 bytes - &1 Byte @@ -939,145 +909,162 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Sprites - - + + × x - + Magnification Ampliación - + Export Esportar - + Attributes Atributos - + Transform Transform - + Off No - + Palette Paleta - - - - + + + + 0 0 - + Copy Copiar - + + + +0.00 + + + + + + +1.00 + + + + + Matrix + + + + Double Size Tamaño doble - - - - + + + + Return, Ctrl+R Volver, Ctrl+R - + Flipped Volteo - + H H - + V V - + Mode Modo - + Normal Normal - + Mosaic Mosaico - + Enabled Habilitado - + Priority Prioridad - + Tile Tile - + Geometry Geometría - + Position Posición - + , , - + Dimensions Dimensiones - - + + 8 8 - + Address Dirección - + 0x07000000 0x07000000 @@ -1269,24 +1256,30 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. HuC-3 - + + Wisdom Tree (Unlicensed) + + + + + Pokémon Jade/Diamond (Unlicensed) + + + + Background Colors Colores de fondo - + Sprite Colors 1 Colores de sprite 1 - + Sprite Colors 2 Colores de sprite 2 - - Colors - Colores - PaletteView @@ -1359,8 +1352,8 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. - 000 - 000 + 0x000 (000) + 0x000 (000) {0x?} @@ -1444,69 +1437,6 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. 0x%0 (%1) - - QGBA::AudioDevice - - - Can't set format of context-less audio device - No se puede establecer el formato de un dispositivo de audio sin contexto - - - - Audio device is missing its core - El dispositivo de audio no tiene núcleo - - - - Writing data to read-only audio device - Escribiendo datos a un dispositivo de audio de sólo lectura - - - - QGBA::AudioProcessorQt - - - Can't start an audio processor without input - No se puede iniciar un procesador de audio sin entrada - - - - QGBA::AudioProcessorSDL - - - Can't start an audio processor without input - No se puede iniciar un procesador de audio sin entrada - - - - QGBA::BattleChipView - - - BattleChip data missing - Datos del BattleChip no encontrados - - - - BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? - Faltan los datos de BattleChip. Las BattleChip Gates seguirán funcionando, pero faltarán algunos gráficos. ¿Quieres descargar los datos ahora? - - - - - Select deck file - Elegir archivo de baraja - - - - Incompatible deck - Baraja incompatible - - - - The selected deck is not compatible with this Chip Gate - La baraja seleccionada no es compatible con esta Chip Gate - - QGBA::CheatsModel @@ -1553,22 +1483,22 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. QGBA::CoreController - + Failed to open save file: %1 Error al abrir el archivo de guardado: %1 - + Failed to open game file: %1 Error al abrir el archivo del juego: %1 - + Failed to open snapshot file for reading: %1 Error al leer del archivo de captura: %1 - + Failed to open snapshot file for writing: %1 Error al escribir al archivo de captura: %1 @@ -1580,46 +1510,56 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Failed to open game file: %1 Error al abrir el archivo del juego: %1 + + + Could not load game. Are you sure it's in the correct format? + No se pudo cargar el juego. ¿Estás seguro de que está en el formato correcto? + + + + Failed to open save file. Is the save directory writable? + + QGBA::FrameView - + Export frame Exportar cuadro - + Portable Network Graphics (*.png) Gráficos de red portátiles (*.png) - + None Ninguno - + Background Fondo (BG) - + Window Ventana (WIN) - + Sprite Sprite - + Backdrop Telón de fondo (backdrop) - + %1 %2 %1× {1 %2?} @@ -1701,42 +1641,19 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. QGBA::GIFView - - Failed to open output GIF file: %1 - Error al abrir el archivo GIF de salida: %1 + + Failed to open output file: %1 + Error al abrir el archivo de salida: %1 - + Select output file Seleccionar archivo de salida - - Graphics Interchange Format (*.gif) - Graphics Interchange Format (*.gif) - - - - QGBA::GameController - - Failed to open game file: %1 - Error al abrir el archivo del juego: %1 - - - Failed to open save file: %1 - Error al abrir el archivo de guardado: %1 - - - Failed to open snapshot file for reading: %1 - Error al leer del archivo de captura: %1 - - - Failed to open snapshot file for writing: %1 - Error al escribir al archivo de captura: %1 - - - Failed to start audio processor - Error al iniciar el procesador de audio + + Graphics Interchange Format (*.gif);;Animated Portable Network Graphics (*.png *.webp *.apng) + @@ -3110,11 +3027,26 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. QGBA::KeyEditor - - + + --- --- + + + Super (L) + + + + + Super (R) + + + + + Menu + + QGBA::LoadSaveState @@ -3191,47 +3123,47 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. QGBA::LogController - + [%1] %2: %3 [%1] %2: %3 - + An error occurred Ocurrió un error - + DEBUG DEPURACIÓN - + STUB STUB - + INFO INFORMACIÓN - + WARN ADVERTENCIA - + ERROR ERROR - + FATAL FATAL - + GAME ERROR ERROR DE JUEGO @@ -3304,24 +3236,20 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. - + N/A n/d - + Export map Exportar mapa - + Portable Network Graphics (*.png) Gráficos de red portátiles (*.png) - - Failed to open output PNG file: %1 - Error al abrir el archivo PNG de salida: %1 - QGBA::MemoryDump @@ -3359,42 +3287,42 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Cargar - + All Todo - + Load TBL Cargar TBL - + Save selected memory Guardar memoria seleccionada - + Failed to open output file: %1 Error al abrir el archivo de salida: %1 - + Load memory Cargar memoria - + Failed to open input file: %1 Error al abrir el archivo de entrada: %1 - + TBL TBL - + ISO-8859-1 ISO-8859-1 @@ -3402,91 +3330,87 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. QGBA::MemorySearch - + (%0/%1×) (%0/%1×) - + (⅟%0×) (⅟%0×) - + (%0×) (%0×) - + %1 byte%2 %1 byte%2 - - 1 byte%0 - 1 byte%0 - - - 2 bytes%0 - 2 bytes%0 - - - 4 bytes%0 - 4 bytes%0 - QGBA::ObjView - - + + 0x%0 0x%0 - + Off No - + + + + + + + + + --- + --- + + + Normal Normal - + Trans Trans - + OBJWIN OBJWIN - + Invalid Inválido - - + + N/A n/d - + Export sprite Exportar sprite - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - - Failed to open output PNG file: %1 - Error al abrir el archivo PNG de salida: %1 - QGBA::PaletteView @@ -3502,10 +3426,6 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. - %0 - %0 - - @@ -3528,19 +3448,6 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Error al abrir el archivo de paleta de salida: %1 - - QGBA::PrinterView - - - Save Printout - Guardar impresión - - - - Portable Network Graphics (*.png) - Gráficos de red portátiles (*.png) - - QGBA::ROMInfo @@ -3624,7 +3531,7 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Seleccionar BIOS - + (%1×%2) @@ -3632,12 +3539,12 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. QGBA::ShaderSelector - + No shader active No hay shader activo - + Load shader Cargar shader @@ -3652,31 +3559,16 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. por %1 - + Preprocessing Preproceso - + Pass %1 Paso %1 - - QGBA::ShortcutController - - Action - Acción - - - Keyboard - Teclado - - - Gamepad - Mando - - QGBA::ShortcutModel @@ -3717,17 +3609,17 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. QGBA::VideoView - + Failed to open output video file: %1 Error al abrir el archivo de video de salida: %1 - + Native (%0x%1) Native (%0x%1) - + Select output file Seleccionar archivo de salida @@ -3735,108 +3627,118 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. QGBA::Window - + Game Boy Advance ROMs (%1) ROMs de Game Boy Advance (%1) - + Game Boy ROMs (%1) ROMs de Game Boy (%1) - + All ROMs (%1) Todas las ROMs (%1) - + %1 Video Logs (*.mvl) Video-registros de %1 (*.mvl) - + Archives (%1) Contenedores (%1) - - - + + + Select ROM Seleccionar ROM - + Select folder Seleccionar carpeta - + Game Boy Advance save files (%1) Archivos de guardado de Game Boy Advance (%1) - - - + + + Select save Seleccionar guardado - + mGBA savestate files (%1) Archivos de estado de guardado de mGBA (%1) - - + + Select savestate Elegir estado de guardado - + Select patch Seleccionar parche - + Patches (*.ips *.ups *.bps) Parches (*.ips *.ups *.bps) - + + Select e-Reader dotcode + + + + + e-Reader card (*.raw *.bin *.bmp) + + + + Select image Seleccionar imagen - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Archivo de imagen (*.png *.gif *.jpg *.jpeg);;Todos los archivos (*) - - + + GameShark saves (*.sps *.xps) Guardados de GameShark (*.sps *.xps) - + Select video log Seleccionar video-registro - + Video logs (*.mvl) Video-registros (*.mvl) - + Crash Error fatal - + The game has crashed with the following error: %1 @@ -3845,687 +3747,588 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. %1 - - Couldn't Load - No se pudo cargar - - - - Could not load game. Are you sure it's in the correct format? - No se pudo cargar el juego. ¿Estás seguro de que está en el formato correcto? - - - + Unimplemented BIOS call Llamada a BIOS no implementada - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Este juego utiliza una llamada al BIOS que no se ha implementado. Utiliza el BIOS oficial para obtener la mejor experiencia. - + Really make portable? ¿Hacer "portable"? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? Esto hará que el emulador cargue su configuración desde el mismo directorio que el ejecutable. ¿Quieres continuar? - + Restart needed Reinicio necesario - + Some changes will not take effect until the emulator is restarted. Algunos cambios no surtirán efecto hasta que se reinicie el emulador. - + - Player %1 of %2 - Jugador %1 de %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 fps) - %4 - + &File &Archivo - + Load &ROM... Cargar &ROM... - + Load ROM in archive... Cargar ROM desde contenedor... - + Add folder to library... Agregar carpeta a la biblioteca... - + Load alternate save... Cargar guardado alternativo... - + Load temporary save... Cargar guardado temporal... - + Load &patch... Cargar &parche... - + Boot BIOS Arrancar BIOS - + Replace ROM... Reemplazar ROM... - + ROM &info... &Información de la ROM... - + Recent Recientes - + Make portable Hacer "portable" - + &Load state Ca&rgar estado - + About... Acerca de... - + Game Pak sensors... Sensores del cartucho... - + Clear Limpiar - F10 - F10 - - - + Load state file... Cargar archivo de estado... - + &Save state Guardar e&stado - Shift+F10 - Shift+F10 - - - + Save state file... Guardar archivo de estado... - + Quick load Cargado rápido - + Quick save Guardado rápido - + Load recent Cargar reciente - + Save recent Guardar reciente - + Undo load state Deshacer cargar estado - F11 - F11 - - - + Undo save state Deshacer guardar estado - Shift+F11 - Shift+F11 - - - - + + State &%1 Estado &%1 - F%1 - F%1 - - - Shift+F%1 - Shift+F%1 - - - + Load camera image... Cargar imagen para la cámara... - - Import GameShark Save - Importar guardado de GameShark - - - - Export GameShark Save - Exportar guardado de GameShark - - - + New multiplayer window Nueva ventana multijugador - About - Acerca de - - - + E&xit Salir (&X) - + &Emulation &Emulación - + &Reset &Reinicializar - Ctrl+R - Ctrl+R - - - + Sh&utdown Apagar (&U) - + Yank game pak Tirar del cartucho - + &Pause &Pausar - Ctrl+P - Ctrl+P - - - + &Next frame Cuadro siguie&nte - Ctrl+N - Ctrl+N - - - + Fast forward (held) Avance rápido (mantener) - + &Fast forward &Avance rápido - Shift+Tab - Shift+Tab - - - + Fast forward speed Velocidad de avance rápido - + Unbounded Sin límite - + %0x %0x - + Rewind (held) Rebobinar (mantener) - + Re&wind Re&bobinar - ~ - ~ - - - + Step backwards Paso hacia atrás - Ctrl+B - Ctrl+B - - - + Sync to &video Sincronizar a &video - + Sync to &audio Sincronizar a au&dio - + Solar sensor Sensor solar - + Increase solar level Subir nivel - + Decrease solar level Bajar nivel - + Brightest solar level Más claro - + Darkest solar level Más oscuro - + Brightness %1 Brillo %1 - + Audio/&Video Audio/&video - + Frame size Tamaño del cuadro - %1x - %1x - - - + Toggle fullscreen Pantalla completa - + Lock aspect ratio Bloquear proporción de aspecto - + Force integer scaling Forzar escala a enteros - + Bilinear filtering Filtro bilineal - + Frame&skip &Salto de cuadros - + Mute Silenciar - + FPS target Objetivo de FPS - + Native (59.7275) Nativo (59,7275) - 15 - 15 - - - 30 - 30 - - - 45 - 45 - - - Native (59.7) - Nativo (59.7) - - - 60 - 60 - - - 90 - 90 - - - 120 - Bilineal120 - - - 240 - 240 - - - + Take &screenshot Tomar pan&tallazo - + F12 F12 - Record output... - Grabar salida... - - - - Record GIF... - Grabar GIF... - - - Record video log... - Grabar video-registro... - - - Stop video log - Detener video-registro - - - + Game Boy Printer... Game Boy Printer... - + BattleChip Gate... BattleChip Gate... - + %1× %1× - + Interframe blending Mezcla entre cuadros - + Record A/V... Grabar A/V... - + Video layers Capas de video - + Audio channels Canales de audio - + Adjust layer placement... Ajustar ubicación de capas... - + &Tools Herramien&tas - + View &logs... Ver re&gistros... - + Game &overrides... Ajustes específic&os por juego... - Game &Pak sensors... - Sensores del Game &Pak... + + Couldn't Start + + + + + Could not start game. + + + + + Scan e-Reader dotcodes... + + + + + Import GameShark Save... + + + + + Export GameShark Save... + + Record GIF/WebP/APNG... + + + + &Cheats... Tru&cos... - + Settings... Ajustes... - + Open debugger console... Abrir consola de depuración... - + Start &GDB server... Iniciar servidor &GDB... - + View &palette... Ver &paleta... - + View &sprites... Ver &sprites... - + View &tiles... Ver &tiles... - + View &map... Ver &mapa... - + &Frame inspector... Inspec&tor de cuadros... - + View memory... Ver memoria... - + Search memory... Buscar memoria... - + View &I/O registers... Ver registros &I/O... - + Record debug video log... Grabar registro de depuración de video... - + Stop debug video log Detener registro de depuración de video - + Exit fullscreen Salir de pantalla completa - + GameShark Button (held) Botón GameShark (mantener) - + Autofire Disparo automático - + Autofire A Disparo automático A - + Autofire B Disparo automático B - + Autofire L Disparo automático L - + Autofire R Disparo automático R - + Autofire Start Disparo automático Start - + Autofire Select Disparo automático Select - + Autofire Up Disparo automático Arriba - + Autofire Right Disparo automático Derecha - + Autofire Down Disparo automático Abajo - + Autofire Left Disparo automático Izquierda @@ -4548,6 +4351,29 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. ? + + QShortcut + + + Shift + + + + + Control + + + + + Alt + + + + + Meta + + + ROMInfo @@ -4843,7 +4669,7 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. - + frames cuadros @@ -4903,52 +4729,57 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Mostrar mensajes en el OSD - + + Show filename instead of ROM name in title bar + + + + Fast forward (held) speed: Avance rápido (mantenido): - + (240×160) (240×160) - + Log to file Guardar a archivo - + Log to console Guardar a consola - + Select Log File Seleccionar - + Game Boy model: Modelo de Game Boy: - + Super Game Boy model: Modelo de Super Game Boy: - + Game Boy Color model: Modelo de Game Boy Color: - + Use GBC colors in GB games Usar colores de GBC en juegos GB - + Camera: Cámara: @@ -5038,271 +4869,255 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Hablitar Rich Presence en Discord - + Fast forward speed: Avance rápido: - - - + + + × × - - + + Unbounded Sin límite - + Enable rewind Habilitar el rebobinar - + Rewind history: Hist. de rebobinado: - + Idle loops: Bucles inactivos: - + Run all Ejecutarlos todos - + Remove known Eliminar los conocidos - + Detect and remove Detectar y eliminar - + Savestate extra data: Guardar datos extra: - - + + Screenshot Pantallazo - - + + Save data Datos de guardado - - + + Cheat codes Trucos - + Load extra data: Cargar datos extra: - Rewind affects save data - El rebobinar afecta los datos de guardado - - - + Preload entire ROM into memory Cargar ROM completa a la memoria - + Autofire interval: Intervalo de turbo: - + Video renderer: Renderizador de video: - + Software Software - + OpenGL OpenGL - + OpenGL enhancements Mejoras para OpenGL - + High-resolution scale: Escala de alta resolución: - + XQ GBA audio (experimental) Mejorar audio GBA (experimental) - + GB BIOS file: Archivo BIOS GB: - - - - - - - - - + + + + + + + + + Browse Examinar - + Use BIOS file if found Usar archivo BIOS si fue encontrado - + Skip BIOS intro Saltar animación de entrada del BIOS - + GBA BIOS file: Archivo BIOS GBA: - + GBC BIOS file: Archivo BIOS GBC: - + SGB BIOS file: Archivo BIOS SGB: - + Save games Datos de guardado - - - - - + + + + + Same directory as the ROM Al mismo directorio que la ROM - + Save states Estados de guardado - + Screenshots Pantallazos - + Patches Parches - + Cheats Trucos - - Game Boy model - Modelo de Game Boy - - - - - - Autodetect - Detección automática - - - - - - Game Boy (DMG) - Game Boy (DMG) - - Super Game Boy (SGB) - + Autodetect + Detección automática - Game Boy Color (CGB) - Game Boy Color (CGB) + Game Boy (DMG) + Game Boy (DMG) + Super Game Boy (SGB) + + + + + + + Game Boy Color (CGB) + Game Boy Color (CGB) + + + + + Game Boy Advance (AGB) Game Boy Advance (AGB) - Super Game Boy model - Modelo de Super Game Boy - - - Game Boy Color model - Modelo de Game Boy Color - - - + Default BG colors: Colores de fondo por defecto: - + Super Game Boy borders Bordes de Super Game Boy - + Camera driver: Controlador de cámara: - + Default sprite colors 1: Colores de sprite 1 por defecto: - + Default sprite colors 2: Colores de sprite 2 por defecto: @@ -5448,64 +5263,33 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Presets Ajustes predefinidos - - High Quality - Alta calidad - - - YouTube - YouTube - - + WebM WebM - Lossless - Sin pérdidas - - - 1080p - 1080p - - - 720p - 720p - - - 480p - 480p - - - Native - Nativa - - - + Format Formato - + MKV MKV - + AVI AVI - + + MP4 MP4 - - PNG - PNG - High &Quality @@ -5517,132 +5301,143 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. &YouTube - + &Lossless Sin pér&didas - + + 4K + 480p {4K?} + + + &1080p &1080p - + &720p &720p - + &480p &480p - + &Native &NAtivo - + h.264 h.264 - + h.264 (NVENC) h.264 (NVENC) - + HEVC HEVC - + HEVC (NVENC) HEVC (NVENC) - + VP8 VP8 - + VP9 VP9 - + FFV1 FFV1 - + + + None + Ninguno + + + FLAC FLAC - + Opus Opus - + Vorbis Vorbis - + MP3 MP3 - + AAC AAC - + Uncompressed Sin comprimir - + Bitrate (kbps) Tasa de bits (kbps) - + VBR VBR - + ABR ABR - + Dimensions Dimensiones - + : : - + × × - + Lock aspect ratio Bloquear proporción de aspecto - + Show advanced Mostrar ajustes avanzados diff --git a/src/platform/qt/ts/medusa-emu-it.ts b/src/platform/qt/ts/medusa-emu-it.ts index 30ddd86bb..dc24db16a 100644 --- a/src/platform/qt/ts/medusa-emu-it.ts +++ b/src/platform/qt/ts/medusa-emu-it.ts @@ -310,37 +310,42 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. Registra GIF/APNG - + APNG APNG - + Start Avvia - + Stop Ferma - + Select File Seleziona File - + + WebP + + + + Frameskip Salto Frame - + GIF GIF - + Loop Loop @@ -438,6 +443,34 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. B + + LibraryTree + + + Name + Nome + + + + Location + + + + + Platform + + + + + Size + Dimensioni + + + + CRC32 + CRC32: {32?} + + LoadSaveState @@ -1223,17 +1256,27 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. HuC-3 - + + Wisdom Tree (Unlicensed) + + + + + Pokémon Jade/Diamond (Unlicensed) + + + + Background Colors Colori di sfondo - + Sprite Colors 1 Colori Sprite 1 - + Sprite Colors 2 Colori Sprite 2 @@ -1394,69 +1437,6 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. 0x%0 (%1) - - QGBA::AudioDevice - - - Can't set format of context-less audio device - Impossibile impostare il formato del dispositivo audio - - - - Audio device is missing its core - Il dispositivo audio non possiede alcun core - - - - Writing data to read-only audio device - Scrittura dei dati per il dispositivo audio in sola-lettura - - - - QGBA::AudioProcessorQt - - - Can't start an audio processor without input - Impossibile avviare un processore audio senza input - - - - QGBA::AudioProcessorSDL - - - Can't start an audio processor without input - Impossibile avviare un processore audio senza input - - - - QGBA::BattleChipView - - - BattleChip data missing - BattleCHip dati mancanti - - - - BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? - I dati BattleChip sono mancanti. BattleChip Gate continuerà a funzionare, ma alcune grafiche saranno mancanti. Vuoi scaricare questi dati ora? - - - - - Select deck file - Seleziona file deck - - - - Incompatible deck - Deck non compatibile - - - - The selected deck is not compatible with this Chip Gate - Il deck selezionato non è compatibile con questo Chip Gate - - QGBA::CheatsModel @@ -1531,50 +1511,55 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. Impossibile aprire il file di gioco: %1 - + Could not load game. Are you sure it's in the correct format? Impossibile caricare il gioco. Sei sicuro che sia nel formato corretto? + + + Failed to open save file. Is the save directory writable? + + QGBA::FrameView - + Export frame Esporta Frame - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - + None Nessuno - + Background Sfondo - + Window Finestra - + Sprite Sprite - + Backdrop Sfondo - + %1 %2 %1x {1 %2?} @@ -1656,19 +1641,19 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. QGBA::GIFView - - Failed to open output GIF or APNG file: %1 - Apertura del file output GIT o APNG fallita: %1 + + Failed to open output file: %1 + Impossibile aprire il file di output: %1 - + Select output file Seleziona file di output - - Graphics Interchange Format (*.gif);;Animated Portable Network Graphics (*.png *.apng) - Graphics Interchange Format (*.gif);;Animated Portable Network Graphics (*.png *.apng) + + Graphics Interchange Format (*.gif);;Animated Portable Network Graphics (*.png *.webp *.apng) + @@ -3302,42 +3287,42 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. Carica - + All Tutto - + Load TBL Carica TBL - + Save selected memory Salva la memoria selezionata - + Failed to open output file: %1 Impossibile aprire il file di output: %1 - + Load memory Carica memoria - + Failed to open input file: %1 Impossibile aprire il file di input: %1 - + TBL TBL - + ISO-8859-1 ISO-8859-1 @@ -3345,22 +3330,22 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. QGBA::MemorySearch - + (%0/%1×) (%0/%1×) - + (⅟%0×) (⅟%0×) - + (%0×) (%0×) - + %1 byte%2 %1 byte%2 @@ -3463,19 +3448,6 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. Errore nell'aprire il file palette di output: %1 - - QGBA::PrinterView - - - Save Printout - Salva Stampa - - - - Portable Network Graphics (*.png) - Portable Network Graphics (*.png) - - QGBA::ROMInfo @@ -3559,7 +3531,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. Seleziona BIOS - + (%1×%2) (%1×%2) @@ -3637,17 +3609,17 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. QGBA::VideoView - + Failed to open output video file: %1 Errore durante l'archiviazione del video: %1 - + Native (%0x%1) Nativo (%0x%1) - + Select output file Seleziona file di uscita @@ -3800,343 +3772,348 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. Alcune modifiche non avranno effetto finché l'emulatore non verrà riavviato. - + - Player %1 of %2 - Giocatore %1 di %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 fps) - %4 - + &File File - + Load &ROM... Carica ROM... - + Load ROM in archive... Carica la ROM in archivio... - + Load alternate save... Carica il salvataggio alternativo... - + Load temporary save... Carica il salvataggio temporaneo.. - + Load &patch... Carica patch... - + Boot BIOS Avvia BIOS - + Replace ROM... Sostituisci la ROM... - + Scan e-Reader dotcodes... Scansiona e-Reader dotcode... - + ROM &info... Informazioni ROM... - + Recent Recente - + Make portable Rendi portatile - + &Load state Carica stato - + &Save state Salva stato - + Quick load Caricamento rapido - + Quick save Salvataggio rapido - + Load recent Carica recente - + Save recent Salva recente - + Undo load state Annulla il caricamento dello stato - + Undo save state Annulla salvataggio stato - - + + State &%1 Stato %1 - + Load camera image... Carica immagine camera... - + New multiplayer window Nuova finestra multigiocatore - + E&xit Esci (&X) - + &Emulation Emulazione - + &Reset Reset - + Sh&utdown Spegni (&U) - + Yank game pak Yank game pak - + &Pause Pausa - + &Next frame Salta il prossimo frame (&N) - + Fast forward (held) Avanzamento rapido (tieni premuto) - + &Fast forward Avanzamento rapido (&F) - + Fast forward speed Velocità di avanzamento rapido - + Unbounded Illimitata - + %0x %0x - + Rewind (held) Riavvolgimento (tieni premuto) - + Re&wind Riavvolgimento (&W) - + Step backwards Torna indietro - + Sync to &video Sincronizza con il video - + Sync to &audio Sincronizza con l'audio - + Solar sensor Sensore solare - + Increase solar level Aumenta il livello solare - + Decrease solar level Riduce il livello solare - + Brightest solar level Livello solare brillante - + Darkest solar level Livello solare più scuro - + Brightness %1 Luminosità %1 - + Audio/&Video Audio/Video - + Frame size Dimensioni Frame - + Toggle fullscreen Abilita Schermo Intero - + Lock aspect ratio Blocca rapporti aspetto - + Frame&skip Salto frame - + Mute Muto - + FPS target FPS finali - + Take &screenshot Acquisisci screenshot - + F12 F12 - + + Record GIF/WebP/APNG... + + + + Video layers Layers video - + Audio channels Canali audio - + &Tools Strumenti - + View &logs... Visualizza registri... (&L) - + Game &overrides... Valore specifico per il gioco... - + &Cheats... Trucchi... - + Open debugger console... Apri debugger console... - + Start &GDB server... Avvia server GDB... - + Settings... Impostazioni... @@ -4156,207 +4133,202 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. NOn è stato possibile avviare il gioco - + Add folder to library... Aggiungi cartella alla libreria... - + Load state file... Carica stato di salvataggio... - + Save state file... Salva stato di salvataggio... - + Import GameShark Save... Importa Salvataggio GameShark... - + Export GameShark Save... Esporta Salvataggio GameShark... - + About... Info - + Force integer scaling Forza l'integer scaling - + Bilinear filtering Filtro bilineare - + Game Boy Printer... Stampante Game Boy... - + BattleChip Gate... BattleChip Gate... - + %1× %1x - + Interframe blending Interframe blending - + Native (59.7275) Nativo (59.7) - + Record A/V... Registra A/V - - Record GIF/APNG... - Registra GIF/APNG - - - + Adjust layer placement... Regola posizionamento layer... - + Game Pak sensors... Sensori Game Pak... - + View &palette... Mostra palette... - + View &sprites... Mostra sprites... - + View &tiles... Mostra tiles... - + View &map... Mostra mappa... - + &Frame inspector... &Frame inspector... - + View memory... Mostra memoria... - + Search memory... Ricerca memoria... - + View &I/O registers... Mostra registri I/O... - + Record debug video log... Registra debug video log... - + Stop debug video log Ferma debug video log... - + Exit fullscreen Esci da Schermo Intero - + GameShark Button (held) Pulsante GameShark (tieni premuto) - + Autofire Pulsanti Autofire - + Autofire A Autofire A - + Autofire B Autofire B - + Autofire L Autofire L - + Autofire R Autofire R - + Autofire Start Autofire Start - + Autofire Select Autofire Select - + Autofire Up Autofire Su - + Autofire Right AAutofire Destra - + Autofire Down Autofire Giù - + Autofire Left Autofire Sinistra - + Clear Pulisci @@ -4692,7 +4664,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. - + frames frames @@ -4752,147 +4724,152 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. Mostra messaggi OSD - + + Show filename instead of ROM name in title bar + + + + Fast forward (held) speed: Velocità di crociera: - + Video renderer: Video renderer: - + Software Software - + OpenGL OpenGL - + OpenGL enhancements Migliore OpenGL - + High-resolution scale: Rapporto alta risoluzione: - + (240×160) (240×160) - + XQ GBA audio (experimental) XQ GBA audio (sperimentale) - + Cheats Trucchi - + Log to file Registro log in file - + Log to console Registro log in console - + Select Log File Seleziona file log - + Game Boy model: Modello GameBoy - + Super Game Boy model: Modello Super GameBoy - + Game Boy Color model: Modello GameBoy Colore: - + Use GBC colors in GB games Usa colori GBC in giochi GB - + Camera: Camera: - - - - - Autodetect - Rilevamento automatico - - - - - - Game Boy (DMG) - Game Boy (DMG) - - Super Game Boy (SGB) - + Autodetect + Rilevamento automatico - Game Boy Color (CGB) - Game Boy Color (CGB) + Game Boy (DMG) + Game Boy (DMG) + Super Game Boy (SGB) + + + + + + + Game Boy Color (CGB) + Game Boy Color (CGB) + + + + + Game Boy Advance (AGB) Game Boy Advance (AGB) - + Default BG colors: Colori predefiniti BG: - + Super Game Boy borders Bordi Super Game Boy - + Camera driver: Driver della fotocamera: - + Default sprite colors 1: Colori predefiniti sprite 1: - + Default sprite colors 2: Colori predefiniti sprite 2: @@ -4912,43 +4889,43 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. Svuota la cache - + Fast forward speed: Velocità di avanzamento rapido: - - - - - - - - - + + + + + + + + + Browse Sfoglia - + Use BIOS file if found Usa il file del BIOS se è presente - + Skip BIOS intro Salta intro del BIOS - - - + + + × × - - + + Unbounded Illimitato @@ -4968,17 +4945,17 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. In Pausa se inattivo - + Run all Avvia tutto - + Remove known Rimuovi conosciuto - + Detect and remove Rileva e rimuovi @@ -4988,25 +4965,25 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. Consenti direzioni opposte - - + + Screenshot Screenshot - - + + Save data Salva dati - - + + Cheat codes Trucchi - + Enable rewind Abilita riavvolgimento @@ -5066,81 +5043,81 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. Carica stato automaticamente - + Rewind history: Cronologia riavvolgimento: - + Idle loops: Idle loops: - + Savestate extra data: Dati extra salvataggio stato: - + Load extra data: Carica dati extra: - + Preload entire ROM into memory Precarica tutta la ROM nella memoria - + Autofire interval: Intervallo Autofire: - + GB BIOS file: File BIOS del GB: - + GBA BIOS file: File BIOS del GBA: - + GBC BIOS file: File BIOS del GBC: - + SGB BIOS file: File BIOS del SGB: - + Save games Salva le partite - - - - - + + + + + Same directory as the ROM Stessa cartella della ROM - + Save states Salvataggio Stati - + Screenshots Screenshot - + Patches Patches diff --git a/src/platform/qt/ts/mgba-fr.ts b/src/platform/qt/ts/mgba-fr.ts index c22b50fb3..cb91feeb9 100644 --- a/src/platform/qt/ts/mgba-fr.ts +++ b/src/platform/qt/ts/mgba-fr.ts @@ -125,6 +125,84 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.0x00 (00) + + BattleChipView + + + BattleChip Gate + + + + + Chip name + + + + + Insert + + + + + Save + Sauvegarder + + + + Load + Charger + + + + Add + Ajouter + + + + Remove + Supprimer + + + + Gate type + + + + + Ba&ttleChip Gate + + + + + Progress &Gate + + + + + Beast &Link Gate + + + + + Inserted + + + + + Chip ID + + + + + Update Chip data + + + + + Show advanced + Paramètres avancés + + CheatsView @@ -149,15 +227,20 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.Charger - + Add New Set Ajouter un nouvel ensemble - + Add Ajouter + + + Enter codes here... + + DebuggerConsole @@ -177,42 +260,95 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.Arrêter + + FrameView + + + Inspect frame + + + + + × + × + + + + Magnification + Agrandissement + + + + Freeze frame + + + + + Backdrop color + + + + + Disable scanline effects + + + + + Export + Exporter + + + + Reset + Réinitialiser + + GIFView - Record GIF - Enregistrer un GIF + Record GIF/APNG + - + + Loop + + + + Start Démarrer - + Stop Arrêter - + Select File Choisir un fichier - - Frameskip - Saut d'image - - - - Frame delay (ms) - Délai d'image (ms) + + APNG + - Automatic - Automatique + GIF + + + + + WebP + + + + + Frameskip + Saut d'image @@ -340,13 +476,13 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.LoadSaveState - + %1 State %1 État - + @@ -358,17 +494,22 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.Pas de sauvegarde - + 1 1 - + 2 2 - + + Cancel + + + + 3 3 @@ -378,12 +519,12 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.4 - + 5 5 - + 6 6 @@ -393,12 +534,12 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.7 - + 8 8 - + 9 9 @@ -469,142 +610,206 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.Cartes - + × × - + Magnification Agrandissement - + Export Exporter + + + Copy + + + + + MemoryDump + + + Save Memory Range + + + + + Start Address: + + + + + : + : + + + + + 0x + 0x + + + + Byte Count: + + + + + Dump across banks + + MemorySearch - + Memory Search Recherche dans la mémoire - + Address Adresse - + Current Value Valeur actuelle - - + + Type Type - + Value Valeur - + Numeric Numérique - + Text Texte - + Width Longueur - - + + Guess Devinez - + 1 Byte (8-bit) 1 octet (8 bits) - + 2 Bytes (16-bit) 2 octets (16 bits) - + 4 Bytes (32-bit) 4 octets (32 bits) - + Number type Type de numéro - + Decimal Décimal - + Hexadecimal Héxadécimal - - Compare - Comparer + + Search type + - - Equal - Egal + + Equal to value + - - Greater - Plus grand que + + Greater than value + - - Less - Plus petit que + + Less than value + - - Delta - Delta + + Unknown/changed + - - Search - Rechercher + + Changed by value + - + + Unchanged + + + + + Increased + + + + + Decreased + + + + + Search ROM + + + + + New Search + + + + Search Within Rechercher dans - + Open in Memory Viewer Ouvrir dans le visionneur mémoire - + Refresh Rafraîchir @@ -622,67 +827,77 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.Inspecter l'adresse : - + + : + : + + + 0x 0x - + Set Alignment: Choisir l'alignement : - - 1 Byte - 1 octet + + &1 Byte + - - 2 Bytes - 2 octets + + &2 Bytes + - - 4 Bytes - 4 octets + + &4 Bytes + - + Unsigned Integer: Entier non signé : - + Signed Integer: Entier signé : - + String: Chaîne de caractères : - + Load TBL Charger TBL - + Copy Selection Copier la sélection - + Paste Coller - + Save Selection Sauvegarder la sélection - + + Save Range + + + + Load Charger @@ -695,140 +910,162 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.Sprites - - + + × × - + Magnification Agrandissement - + Export Exporter - + Attributes Attributs - + Transform Transformer - + Off Off - + Palette Palette - - - - + + + + 0 0 - + + Copy + + + + + + +0.00 + + + + + + +1.00 + + + + + Matrix + + + + Double Size Double taille - - - - + + + + Return, Ctrl+R Entrée, Ctrl+R - + Flipped Inversé - + H H - + V V - + Mode Mode - + Normal Normal - + Mosaic Mosaïque - + Enabled Activé - + Priority Priorité - + Tile Tile - + Geometry Géométrie - + Position Position - + , , - + Dimensions Dimensions - - + + 8 8 - + Address Adresse - + 0x07000000 0x07000000 @@ -986,36 +1223,61 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. + MBC6 + MBC6 + + + MBC7 MBC7 - + + MMM01 + + + + Pocket Cam Caméra de poche - + TAMA5 TAMA5 - + + HuC-1 + HuC-1 + + + HuC-3 HuC-3 - + + Wisdom Tree (Unlicensed) + + + + + Pokémon Jade/Diamond (Unlicensed) + + + + Background Colors Couleurs d'arrière-plan - + Sprite Colors 1 Couleurs du Sprite n°1 - + Sprite Colors 2 Couleurs du Sprite n°2 @@ -1091,8 +1353,8 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. - 000 - 000 + 0x000 (000) + 0x000 (000) {0x?} @@ -1141,65 +1403,41 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.Imprimante Game Boy - + Hurry up! Dépêchez-vous ! - + Tear off Tear off + + + × + × + + + + Magnification + Agrandissement + QGBA::AssetTile - + %0%1%2 %0%1%2 - - - + + + 0x%0 (%1) 0x%0 (%1) - - QGBA::AudioDevice - - - Can't set format of context-less audio device - Impossible de définir le format d'un appareil audio sans contexte - - - - Audio device is missing its core - Il manque le noyau du périphérique audio - - - - Writing data to read-only audio device - Écriture de données sur un appareil audio en lecture seule - - - - QGBA::AudioProcessorQt - - - Can't start an audio processor without input - Impossible de démarrer un processeur audio sans entrée - - - - QGBA::AudioProcessorSDL - - - Can't start an audio processor without input - Impossible de démarrer un processeur audio sans entrée - - QGBA::CheatsModel @@ -1246,22 +1484,22 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. QGBA::CoreController - + Failed to open save file: %1 Échec de l'ouverture du fichier de sauvegarde : %1 - + Failed to open game file: %1 Échec de l'ouverture du fichier de jeu : %1 - + Failed to open snapshot file for reading: %1 Échec de l'ouverture de l'instantané pour lire : %1 - + Failed to open snapshot file for writing: %1 Échec de l'ouverture de l'instantané pour écrire : %1 @@ -1273,6 +1511,67 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.Failed to open game file: %1 Échec de l'ouverture du fichier de jeu : %1 + + + Could not load game. Are you sure it's in the correct format? + Impossible de charger le jeu. Êtes-vous sûr qu'il est dans le bon format ? + + + + Failed to open save file. Is the save directory writable? + + + + + QGBA::FrameView + + + Export frame + + + + + Portable Network Graphics (*.png) + Portable Network Graphics (*.png) + + + + None + Aucun + + + + Background + Arrière plan + + + + Window + + + + + Sprite + + + + + Backdrop + + + + + %1 %2 + %1x {1 %2?} + + + + QGBA::GBAApp + + + Enable Discord Rich Presence + + QGBA::GBAKeyEditor @@ -1343,19 +1642,19 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. QGBA::GIFView - - Failed to open output GIF file: %1 - Impossible d'ouvrir le fichier GIF : %1 + + Failed to open output file: %1 + Impossible d'ouvrir le fichier de sortie : %1 - + Select output file Sélectionner le fichier de sortie - - Graphics Interchange Format (*.gif) - Graphics Interchange Format (*.gif) + + Graphics Interchange Format (*.gif);;Animated Portable Network Graphics (*.png *.webp *.apng) + @@ -2740,80 +3039,149 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. QGBA::KeyEditor - - + + --- --- + + + Super (L) + + + + + Super (R) + + + + + Menu + + QGBA::LoadSaveState - + Load State Charger un Etat - + Save State Sauvegarder un Etat - + Empty Vide - + Corrupted Corrompue - + Slot %1 Emplacement %1 + + QGBA::LogConfigModel + + + + Default + + + + + Fatal + Fatal + + + + Error + Erreur + + + + Warning + Avertissement + + + + Info + Info + + + + Debug + Débogage + + + + Stub + Stub + + + + Game Error + Erreur du jeu + + QGBA::LogController - + + [%1] %2: %3 + + + + + An error occurred + + + + DEBUG There is no need to translate this. DEBUG - + STUB There is no need to translate this. STUB - + INFO There is no need to translate this. INFO - + WARN There is no need to translate this. WARN - + ERROR There is no need to translate this. ERROR - + FATAL There is no need to translate this. FATAL - + GAME ERROR There is no need to translate this. GAME ERROR @@ -2822,49 +3190,97 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. QGBA::MapView - + + Priority + Priorité + + + + + Map base + + + + + + Tile base + + + + + Size + Taille + + + + + Offset + Offset + + + + Xform + + + + Map Addr. Adresse de la map. - + Mirror Miroir - + None Aucun - + Both Les deux - + Horizontal Horizontal - + Vertical Vertical - + + + + N/A + N/A + + + Export map Exporter la map - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) + + + QGBA::MemoryDump - - Failed to open output PNG file: %1 - Impossible d'ouvrir le fichier PNG de sortie : %1 + + Save memory region + + + + + Failed to open output file: %1 + Impossible d'ouvrir le fichier de sortie : %1 @@ -2890,43 +3306,42 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.Charger - - + All Tout - + Load TBL Charger le TBL - + Save selected memory Sauvegarder la mémoire sélectionné - + Failed to open output file: %1 Impossible d'ouvrir le fichier de sortie : %1 - + Load memory Charger la mémoire - + Failed to open input file: %1 Impossible d'ouvrir le fichier d'entrée : %1 - + TBL TBL - + ISO-8859-1 ISO-8859-1 @@ -2934,22 +3349,22 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. QGBA::MemorySearch - + (%0/%1×) (%0/%1×) - + (⅟%0×) (⅟%0×) - + (%0×) (%0×) - + %1 byte%2 %1 octet%2 @@ -2957,57 +3372,64 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. QGBA::ObjView - - + + 0x%0 0x%0 - + Off Off - + + + + + + + + + --- + --- + + + Normal Normal - + Trans Trans - + OBJWIN OBJWIN - + Invalid Invalide - - + + N/A N/A - + Export sprite Exporter le Sprite - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - - - Failed to open output PNG file: %1 - Echec de l'ouverture du fichier d'entrée : %1 - QGBA::PaletteView @@ -3023,10 +3445,6 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. - %0 - %0 - - @@ -3049,19 +3467,6 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.Impossible d'ouvrir le fichier de la palette de sortie : %1 - - QGBA::PrinterView - - - Save Printout - Sauvegarder l'impression - - - - Portable Network Graphics (*.png) - Portable Network Graphics (*.png) - - QGBA::ROMInfo @@ -3088,72 +3493,77 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. QGBA::SettingsView - - + + Qt Multimedia Qt Multimédia - + SDL SDL - + Software (Qt) Software (Qt) - + OpenGL OpenGL - + OpenGL (force version 1.x) OpenGL (version forcée 1.x) - + None (Still Image) Aucun (Image fixe) - + Keyboard Clavier - + Controllers Contrôleurs - + Shortcuts Raccourcis - - + + Shaders Shaders - + Select BIOS Choisir le BIOS + + + (%1×%2) + + QGBA::ShaderSelector - + No shader active Aucun shader actif - + Load shader Charger un shader @@ -3168,48 +3578,67 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.de %1 - + Preprocessing Pré-traitement - + Pass %1 Passe %1 - QGBA::ShortcutController + QGBA::ShortcutModel - + Action - Action + Action - + Keyboard - Clavier + Clavier - + Gamepad - Manette de jeu + Manette de jeu + + + + QGBA::TileView + + + Export tiles + + + + + + Portable Network Graphics (*.png) + Portable Network Graphics (*.png) + + + + Export tile + QGBA::VideoView - + Failed to open output video file: %1 Impossible d'ouvrir le fichier vidéo de sortie : %1 - + Native (%0x%1) Natif (%0x%1) - + Select output file Choisir le fichier de sortie @@ -3217,97 +3646,118 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. QGBA::Window - + Game Boy Advance ROMs (%1) ROMs de Game Boy Advance (%1) - + Game Boy ROMs (%1) ROMs de Game Boy (%1) - + All ROMs (%1) Toutes les ROMs (%1) - + %1 Video Logs (*.mvl) %1 Journaux vidéo (*.mvl) - + Archives (%1) Archives (%1) - - - + + + Select ROM Choisir une ROM - + Select folder Choisir un dossier - + Game Boy Advance save files (%1) Fichiers de sauvegarde Game Boy Advance (%1) - - - + + + Select save Choisir une sauvegarde - + + mGBA savestate files (%1) + + + + + + Select savestate + + + + Select patch Sélectionner un correctif - + Patches (*.ips *.ups *.bps) Correctifs/Patches (*.ips *.ups *.bps) - + + Select e-Reader dotcode + + + + + e-Reader card (*.raw *.bin *.bmp) + + + + Select image Choisir une image - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Image (*.png *.gif *.jpg *.jpeg);;Tous les fichiers (*) - - + + GameShark saves (*.sps *.xps) Sauvegardes GameShark (*.sps *.xps) - + Select video log Sélectionner un journal vidéo - + Video logs (*.mvl) Journaux vidéo (*.mvl) - + Crash Plantage - + The game has crashed with the following error: %1 @@ -3316,518 +3766,368 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. - - Couldn't Load - Impossible à charger - - - - Could not load game. Are you sure it's in the correct format? - Impossible de charger le jeu. Êtes-vous sûr qu'il est dans le bon format ? - - - + Unimplemented BIOS call Requête au BIOS non supporté - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Ce jeu utilise un appel BIOS qui n'est pas implémenté. Veuillez utiliser le BIOS officiel pour une meilleure expérience. - + Really make portable? Vraiment rendre portable ? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? Cela amènera l'émulateur à charger sa configuration depuis le même répertoire que l'exécutable. Souhaitez vous continuer ? - + Restart needed Un redémarrage est nécessaire - + Some changes will not take effect until the emulator is restarted. Certains changements ne prendront effet qu'après le redémarrage de l'émulateur. - + - Player %1 of %2 - Joueur %1 of %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 fps) - %4 - + &File &Fichier - + Load &ROM... Charger une &ROM… - + Load ROM in archive... Charger la ROM d'une archive… - + Add folder to library... Ajouter un dossier à la bibliothèque… - + Load alternate save... Charger une sauvegarde alternative… - + Load temporary save... Charger une sauvegarde temporaire… - + Load &patch... Charger un c&orrectif… - + Boot BIOS Démarrer le BIOS - + Replace ROM... Remplacer la ROM… - + ROM &info... &Infos sur la ROM… - + Recent Récent - + Make portable Rendre portable - + &Load state &Charger un état - - F10 - F10 - - - + &Save state &Sauvegarder un état - - Shift+F10 - Maj+F10 - - - + Quick load Chargement rapide - + Quick save Sauvegarde rapide - + Load recent Charger un fichier récent - + Save recent Sauvegarder un fichier récent - + Undo load state Annuler le chargement de l'état - - F11 - F11 - - - + Undo save state Annuler la sauvegarde de l'état - - Shift+F11 - Maj+F11 - - - - + + State &%1 État &%1 - - F%1 - F%1 - - - - Shift+F%1 - Maj+F%1 - - - + Load camera image... Charger une image de la caméra… - - Import GameShark Save - Importer une sauvegarde GameShark - - - - Export GameShark Save - Exporter une sauvegarde GameShark - - - + New multiplayer window Nouvelle fenêtre multijoueur - - About - À propos de - - - + E&xit &Quitter - + &Emulation &Emulation - + &Reset &Réinitialiser - - Ctrl+R - Ctrl+R - - - + Sh&utdown Extin&ction - + Yank game pak Extraire game pak - + &Pause &Pause - - Ctrl+P - Ctrl+P - - - + &Next frame &Image suivante - - Ctrl+N - Ctrl+N - - - + Fast forward (held) Avance rapide (maintenir) - + &Fast forward A&vance rapide - - Shift+Tab - Maj+Tab - - - + Fast forward speed Vitesse de l'avance rapide - + Unbounded Non lié - + %0x %0x - + Rewind (held) Rembobiner (maintenir) - + Re&wind Rem&bobiner - - ~ - ~ - - - + Step backwards Retour en arrière - - Ctrl+B - Ctrl+B - - - + Sync to &video Synchro &vidéo - + Sync to &audio Synchro &audio - + Solar sensor Capteur solaire - + Increase solar level Augmenter le niveau solaire - + Decrease solar level Diminuer le niveau solaire - + Brightest solar level Tester le niveau solaire - + Darkest solar level Assombrir le niveau solaire - + Brightness %1 Luminosité %1 - + Audio/&Video Audio/&Vidéo - + Frame size Taille de l'image - - %1x - %1x - - - + Toggle fullscreen Basculer en plein écran - + Lock aspect ratio Bloquer les proportions - + Force integer scaling Forcer la mise à l'échelle par des nombres entiers - + Bilinear filtering Filtrage bilinèaire - + Frame&skip &Saut d'image - + Mute Muet - + FPS target FPS ciblé - - 15 - 15 - - - - 30 - 30 - - - - 45 - 45 - - - - Native (59.7) - Natif (59.7) - - - - 60 - 60 - - - - 90 - 90 - - - - 120 - 120 - - - - 240 - 240 - - - + Take &screenshot Prendre une ca&pture d'écran - + F12 F12 - - Record output... - Enregistrer la sortie… - - - - Record GIF... - Enregistrer un GIF… - - - - Record video log... - Enregistrer le journal vidéo… - - - - Stop video log - Arrêter le journal vidéo - - - + Game Boy Printer... Imprimante GameBoy… - + Video layers Couches vidéo - + Audio channels Canaux audio - + Adjust layer placement... Ajuster la disposition… - + &Tools Ou&tils - + View &logs... Voir les &journaux… @@ -3837,130 +4137,220 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.Passer &outre le jeu… - - Game &Pak sensors... - Capteurs Game &Pak… + + Couldn't Start + - + + Could not start game. + + + + + Scan e-Reader dotcodes... + + + + + Load state file... + + + + + Save state file... + + + + + Import GameShark Save... + + + + + Export GameShark Save... + + + + + About... + + + + + BattleChip Gate... + + + + + %1× + %1x {1×?} + + + + Interframe blending + + + + + Native (59.7275) + Natif (59.7) {59.7275)?} + + + + Record A/V... + + + + + Record GIF/WebP/APNG... + + + + + Game Pak sensors... + + + + &Cheats... &Cheats… - + Settings... Paramètres… - + Open debugger console... Ouvrir la console de débug… - + Start &GDB server... Démarrer le serveur &GDB… - + View &palette... Voir la &palette… - + View &sprites... Voir les &sprites… - + View &tiles... Voir les &tiles… - + View &map... Voir la &map… - + + &Frame inspector... + + + + View memory... Voir la mémoire… - + Search memory... Recherche dans la mémoire… - + View &I/O registers... Voir les registres d'&E/S... - + + Record debug video log... + + + + + Stop debug video log + + + + Exit fullscreen Quitter le plein écran - + GameShark Button (held) Bouton GameShark (maintenir) - + Autofire Tir automatique - + Autofire A Tir automatique A - + Autofire B Tir automatique B - + Autofire L Tir automatique L - + Autofire R Tir automatique R - + Autofire Start Tir automatique Start - + Autofire Select Tir automatique Select - + Autofire Up Tir automatique Up - + Autofire Right Tir automatique Right - + Autofire Down Tir automatique Down - + Autofire Left Tir automatique Gauche + + + Clear + Vider + QObject @@ -3980,6 +4370,29 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.? + + QShortcut + + + Shift + + + + + Control + + + + + Alt + + + + + Meta + + + ROMInfo @@ -4122,500 +4535,609 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.Paramètres - + Audio/Video Audio/Vidéo - + Interface Interface - + Emulation Émulation - + + Enhancements + + + + BIOS BIOS - + Paths Chemins - + + Logging + + + + Game Boy Game Boy - + Audio driver: Pilote Audio : - + Audio buffer: Tampon audio : - - + + 1536 1536 - + 512 512 - + 768 768 - + 1024 1024 - + 2048 2048 - + 3072 3072 - + 4096 4096 - + samples échantillons - + Sample rate: Taux d'échantillonnage : - - + + 44100 44100 - + 22050 22050 - + 32000 32000 - + 48000 48000 - + Hz Hz - + Volume: Volume : - + + Mute Muet - + + Fast forward volume: + + + + Display driver: Pilote d'affichage : - + Frameskip: Saut d'image : - + Skip every Sauter chaque - - + + frames images - + FPS target: FPS ciblé : - + frames per second images par secondes - + Sync: Synchronisation : - + Video Vidéo - + Audio Audio - + Lock aspect ratio Bloquer les proportions - + Bilinear filtering Filtrage bilinèaire - + + Log to file + + + + + Log to console + + + + + Select Log File + + + + + Game Boy model: + + + + + Super Game Boy model: + + + + + Game Boy Color model: + + + + + Use GBC colors in GB games + + + + + Camera: + + + + Force integer scaling Forcer la mise à l'échelle en entier - + Language Langue - + English Anglais - + Library: Bibliothèque : - + List view Vue par liste - + Tree view Vue en arborescence - + Show when no game open Afficher quand aucun jeu n'est ouvert - + Clear cache Vider le cache - + Allow opposing input directions Autoriser les directions opposées - + Suspend screensaver Suspendre l'économiseur d'écran - + Pause when inactive Mettre en pause en cas d'inactivité - + Show FPS in title bar Afficher le nombre de FPS dans la barre de titre - + Automatically save cheats Sauvegarder automatiquement les cheats - + Automatically load cheats Charger automatiquement les cheats - + Automatically save state Sauvegarder automatiquement l'état - + + Native (59.7275) + Natif (59.7) {59.7275)?} + + + + Interframe blending + + + + + Pause when minimized + + + + + Enable Discord Rich Presence + + + + Automatically load state Charger automatiquement l'état - + + Show OSD messages + + + + + Show filename instead of ROM name in title bar + + + + Fast forward speed: Vitesse d'avance rapide : - + + + × × - + + Unbounded Sans limites - + + Fast forward (held) speed: + + + + Enable rewind Permettre le rembobinage - + Rewind history: Historique du rembobinage : - + Idle loops: Boucles d'inactivité : - + Run all Tout lancer - + Remove known Supprimer les éléments connus - + Detect and remove Détecter et supprimer - + Savestate extra data: Enregistrer des données supplémentaires : - - + + Screenshot Capture d'écran - - + + Save data Sauvegarder les données - - + + Cheat codes Codes de triches - + Load extra data: Chargez des données supplémentaires : - - Rewind affects save data - Le rembobinage affecte la sauvegarde des données - - - + Preload entire ROM into memory Précharger toute la ROM en mémoire - + Autofire interval: Intervalle de tir automatique : - + + Video renderer: + + + + + Software + + + + + OpenGL + OpenGL + + + + OpenGL enhancements + + + + + High-resolution scale: + + + + + (240×160) + + + + + XQ GBA audio (experimental) + + + + GB BIOS file: GB BIOS : - - - - - - - - - + + + + + + + + + Browse Parcourir - + Use BIOS file if found Utiliser le fichier BIOS si trouvé - + Skip BIOS intro Passer l'intro du BIOS - + GBA BIOS file: GBA BIOS : - + GBC BIOS file: GBC BIOS : - + SGB BIOS file: SGB BIOS : - + Save games Sauvegarder les jeux - - - - - + + + + + Same directory as the ROM Même répertoire que la ROM - + Save states Sauvegarder les états - + Screenshots Captures d'écran - + Patches Correctifs - + Cheats Cheats - - Game Boy model - Modèle de Game Boy - - - - - + + + Autodetect Détection automatique - - - + + + 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) - - Super Game Boy model - Modèle de la Super Game Boy - - - - Game Boy Color model - Modèle de la Game Boy Color - - - + Default BG colors: Couleurs par défaut de l'arrière plan : - + Super Game Boy borders Bordures Super Game Boy - + Camera driver: Pilote de la caméra : - + Default sprite colors 1: Couleurs par défaut de la sprite n°1 : - + Default sprite colors 2: Couleurs par défaut de la sprite n°2 : @@ -4689,20 +5211,50 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.Tiles - + + Export Selected + + + + + Export All + + + + 256 colors 256 couleurs - + × × - + Magnification Agrandissement + + + Tiles per row + + + + + Fit to window + + + + + Copy Selected + + + + + Copy All + + VideoView @@ -4731,159 +5283,181 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd.Presets Préréglages - - - High Quality - Haute qualité - - - - YouTube - YouTube - - + WebM WebM - - Lossless - Sans perte - - - - 1080p - 1080p - - - - 720p - 720p - - - - 480p - 480p - - - - Native - Natif - - - + Format Format - + MKV MKV - + AVI AVI - + + MP4 MP4 - + + High &Quality + + + + + &YouTube + + + + + &Lossless + + + + + 4K + 480p {4K?} + + + + &1080p + + + + + &720p + + + + + &480p + + + + + &Native + + + + h.264 H.264 - + h.264 (NVENC) H.264 (NVENC) - + HEVC HEVC - + + HEVC (NVENC) + + + + VP8 VP8 - + + VP9 + VP9 + + + FFV1 FFV1 - + + + None + Aucun + + + FLAC FLAC - + Opus Opus - + Vorbis Vorbis - + MP3 MP3 - + AAC AAC - + Uncompressed Non compressé - + Bitrate (kbps) Bitrate (kbps) - + VBR VBR - + ABR ABR - + Dimensions Dimensions - + : : - + × × - + Lock aspect ratio Bloquer les proportions - + Show advanced Paramètres avancés diff --git a/src/platform/qt/ts/mgba-nl.ts b/src/platform/qt/ts/mgba-nl.ts index c9307aaa4..31930f846 100644 --- a/src/platform/qt/ts/mgba-nl.ts +++ b/src/platform/qt/ts/mgba-nl.ts @@ -304,30 +304,50 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. GIFView - - Record GIF - - - - + Frameskip - + Start - + + Record GIF/APNG + + + + + Loop + + + + Stop - + Select File + + + APNG + + + + + GIF + + + + + WebP + + IOViewer @@ -888,145 +908,162 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - + Copy - + Geometry - + Position - - - - + + + + 0 - + , - + Dimensions - - + + 8 - - + + × - + Tile - + Export - + + + +0.00 + + + + + + +1.00 + + + + + Matrix + + + + Attributes - + Transform - + Off - + Palette - + Double Size - - - - + + + + Return, Ctrl+R - + Flipped - + H - + V - + Mode - + Normal - + Mosaic - + Enabled - + Priority - + Address - + 0x07000000 - + Magnification @@ -1218,17 +1255,27 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - + + Wisdom Tree (Unlicensed) + + + + + Pokémon Jade/Diamond (Unlicensed) + + + + Background Colors - + Sprite Colors 1 - + Sprite Colors 2 @@ -1304,7 +1351,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - 000 + 0x000 (000) @@ -1389,69 +1436,6 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - - QGBA::AudioDevice - - - Can't set format of context-less audio device - - - - - Audio device is missing its core - - - - - Writing data to read-only audio device - - - - - QGBA::AudioProcessorQt - - - Can't start an audio processor without input - - - - - QGBA::AudioProcessorSDL - - - Can't start an audio processor without input - - - - - QGBA::BattleChipView - - - BattleChip data missing - - - - - BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? - - - - - - Select deck file - - - - - Incompatible deck - - - - - The selected deck is not compatible with this Chip Gate - - - QGBA::CheatsModel @@ -1498,22 +1482,22 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. QGBA::CoreController - + Failed to open save file: %1 - + Failed to open game file: %1 - + Failed to open snapshot file for reading: %1 - + Failed to open snapshot file for writing: %1 @@ -1525,46 +1509,56 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Failed to open game file: %1 + + + Could not load game. Are you sure it's in the correct format? + + + + + Failed to open save file. Is the save directory writable? + + QGBA::FrameView - + Export frame - + Portable Network Graphics (*.png) - + None - + Background - + Window - + Sprite - + Backdrop - + %1 %2 @@ -1646,18 +1640,18 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. QGBA::GIFView - - Failed to open output GIF file: %1 + + Failed to open output file: %1 - + Select output file - - Graphics Interchange Format (*.gif) + + Graphics Interchange Format (*.gif);;Animated Portable Network Graphics (*.png *.webp *.apng) @@ -3032,11 +3026,26 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. QGBA::KeyEditor - - + + --- + + + Super (L) + + + + + Super (R) + + + + + Menu + + QGBA::LoadSaveState @@ -3113,47 +3122,47 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. QGBA::LogController - + [%1] %2: %3 - + An error occurred - + DEBUG - + STUB - + INFO - + WARN - + ERROR - + FATAL - + GAME ERROR @@ -3277,42 +3286,42 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - + All - + Load TBL - + Save selected memory - + Failed to open output file: %1 - + Load memory - + Failed to open input file: %1 - + TBL - + ISO-8859-1 @@ -3320,22 +3329,22 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. QGBA::MemorySearch - + (%0/%1×) - + (⅟%0×) - + (%0×) - + %1 byte%2 @@ -3343,49 +3352,61 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. QGBA::ObjView - - + + 0x%0 - + Off - + + + + + + + + + --- + + + + Normal - + Trans - + OBJWIN - + Invalid - - + + N/A - + Export sprite - + Portable Network Graphics (*.png) @@ -3404,10 +3425,6 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - %0 - - - @@ -3430,19 +3447,6 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - - QGBA::PrinterView - - - Save Printout - - - - - Portable Network Graphics (*.png) - - - QGBA::ROMInfo @@ -3526,7 +3530,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - + (%1×%2) @@ -3604,17 +3608,17 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. QGBA::VideoView - + Failed to open output video file: %1 - + Native (%0x%1) - + Select output file @@ -3665,8 +3669,8 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - + Select save @@ -3692,621 +3696,636 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - - Select image + + Select e-Reader dotcode - - Image file (*.png *.gif *.jpg *.jpeg);;All files (*) + + e-Reader card (*.raw *.bin *.bmp) + Select image + + + + + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) + + + + GameShark saves (*.sps *.xps) - + Select video log - + Video logs (*.mvl) - + Crash - + The game has crashed with the following error: %1 - - Couldn't Load + + Couldn't Start - - Could not load game. Are you sure it's in the correct format? + + Could not start game. - + Unimplemented BIOS call - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. - + Really make portable? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? - + Restart needed - + Some changes will not take effect until the emulator is restarted. - + - Player %1 of %2 - + %1 - %2 - + %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 - + &File - + Load &ROM... - + Load ROM in archive... - + Add folder to library... - + Load alternate save... - + Load temporary save... - + Load &patch... - + Boot BIOS - + Replace ROM... - + + Scan e-Reader dotcodes... + + + + ROM &info... - + Recent - + Make portable - + &Load state - + Load state file... - + &Save state - + Save state file... - + Quick load - + Quick save - + Load recent - + Save recent - + Undo load state - + Undo save state - - + + State &%1 - + Load camera image... - + Import GameShark Save... - + Export GameShark Save... - + New multiplayer window - + About... - + E&xit - + &Emulation - + &Reset - + Sh&utdown - + Yank game pak - + &Pause - + &Next frame - + Fast forward (held) - + &Fast forward - + Fast forward speed - + Unbounded - + %0x - + Rewind (held) - + Re&wind - + Step backwards - + Sync to &video - + Sync to &audio - + Solar sensor - + Increase solar level - + Decrease solar level - + Brightest solar level - + Darkest solar level - + Brightness %1 - + Game Boy Printer... - + BattleChip Gate... - + Audio/&Video - + Frame size - + %1× - + Toggle fullscreen - + Lock aspect ratio - + Force integer scaling - + Interframe blending - + Bilinear filtering - + Frame&skip - + Mute - + FPS target - + Native (59.7275) - + Take &screenshot - + F12 - + Record A/V... - - Record GIF... + + Record GIF/WebP/APNG... - + Video layers - + Audio channels - + Adjust layer placement... - + &Tools - + View &logs... - + Game &overrides... - + Game Pak sensors... - + &Cheats... - + Settings... - + Open debugger console... - + Start &GDB server... - + View &palette... - + View &sprites... - + View &tiles... - + View &map... - + &Frame inspector... - + View memory... - + Search memory... - + View &I/O registers... - + Record debug video log... - + Stop debug video log - + Exit fullscreen - + GameShark Button (held) - + Autofire - + Autofire A - + Autofire B - + Autofire L - + Autofire R - + Autofire Start - + Autofire Select - + Autofire Up - + Autofire Right - + Autofire Down - + Autofire Left - + Clear @@ -4329,6 +4348,29 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. + + QShortcut + + + Shift + + + + + Control + + + + + Alt + + + + + Meta + + + ROMInfo @@ -4624,7 +4666,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - + frames @@ -4769,305 +4811,310 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - + + Show filename instead of ROM name in title bar + + + + Fast forward speed: - - - + + + × - - + + Unbounded - + Fast forward (held) speed: - + Autofire interval: - + Enable rewind - + Rewind history: - + Idle loops: - + Run all - + Remove known - + Detect and remove - + Preload entire ROM into memory - + Savestate extra data: - - - - Screenshot - - - Save data + Screenshot - + + Save data + + + + + Cheat codes - + Load extra data: - + Video renderer: - + Software - + OpenGL - + OpenGL enhancements - + High-resolution scale: - + (240×160) - + XQ GBA audio (experimental) - + GB BIOS file: - - - - - - - - - + + + + + + + + + Browse - + Use BIOS file if found - + Skip BIOS intro - + GBA BIOS file: - + GBC BIOS file: - + SGB BIOS file: - + Save games - - - - - + + + + + Same directory as the ROM - + Save states - + Screenshots - + Patches - + Cheats - + Log to file - + Log to console - + Select Log File - + Game Boy model: - - - - - Autodetect - - - - - - - Game Boy (DMG) - - - Super Game Boy (SGB) + Autodetect - Game Boy Color (CGB) + Game Boy (DMG) + Super Game Boy (SGB) + + + + + + + Game Boy Color (CGB) + + + + + + Game Boy Advance (AGB) - + Super Game Boy model: - + Game Boy Color model: - + Default BG colors: - + Super Game Boy borders - + Camera driver: - + Default sprite colors 1: - + Default sprite colors 2: - + Use GBC colors in GB games - + Camera: @@ -5225,157 +5272,169 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - + WebM - + &Lossless - + &1080p - + &720p - + &480p - + &Native - + Format - + MKV - + AVI - + + MP4 - + + 4K + + + + h.264 - + h.264 (NVENC) - + HEVC - + HEVC (NVENC) - + VP8 - + VP9 - + FFV1 - + + + None + + + + FLAC - + Opus - + Vorbis - + MP3 - + AAC - + Uncompressed - + Bitrate (kbps) - + VBR - + ABR - + Dimensions - + : - + × - + Lock aspect ratio - + Show advanced diff --git a/src/platform/qt/ts/mgba-ru.ts b/src/platform/qt/ts/mgba-ru.ts index 965bbb920..b28cf94cf 100644 --- a/src/platform/qt/ts/mgba-ru.ts +++ b/src/platform/qt/ts/mgba-ru.ts @@ -304,30 +304,50 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. GIFView - - Record GIF - - - - + Frameskip - + Start - + + Record GIF/APNG + + + + + Loop + + + + Stop - + Select File + + + APNG + + + + + GIF + + + + + WebP + + IOViewer @@ -888,145 +908,162 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - + Copy - + Geometry - + Position - - - - + + + + 0 - + , - + Dimensions - - + + 8 - - + + × - + Tile - + Export - + + + +0.00 + + + + + + +1.00 + + + + + Matrix + + + + Attributes - + Transform - + Off - + Palette - + Double Size - - - - + + + + Return, Ctrl+R - + Flipped - + H - + V - + Mode - + Normal - + Mosaic - + Enabled - + Priority - + Address - + 0x07000000 - + Magnification @@ -1218,17 +1255,27 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - + + Wisdom Tree (Unlicensed) + + + + + Pokémon Jade/Diamond (Unlicensed) + + + + Background Colors - + Sprite Colors 1 - + Sprite Colors 2 @@ -1304,7 +1351,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - 000 + 0x000 (000) @@ -1389,69 +1436,6 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - - QGBA::AudioDevice - - - Can't set format of context-less audio device - - - - - Audio device is missing its core - - - - - Writing data to read-only audio device - - - - - QGBA::AudioProcessorQt - - - Can't start an audio processor without input - - - - - QGBA::AudioProcessorSDL - - - Can't start an audio processor without input - - - - - QGBA::BattleChipView - - - BattleChip data missing - - - - - BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? - - - - - - Select deck file - - - - - Incompatible deck - - - - - The selected deck is not compatible with this Chip Gate - - - QGBA::CheatsModel @@ -1498,22 +1482,22 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. QGBA::CoreController - + Failed to open save file: %1 - + Failed to open game file: %1 - + Failed to open snapshot file for reading: %1 - + Failed to open snapshot file for writing: %1 @@ -1525,46 +1509,56 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Failed to open game file: %1 + + + Could not load game. Are you sure it's in the correct format? + + + + + Failed to open save file. Is the save directory writable? + + QGBA::FrameView - + Export frame - + Portable Network Graphics (*.png) - + None - + Background - + Window - + Sprite - + Backdrop - + %1 %2 @@ -1646,18 +1640,18 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. QGBA::GIFView - - Failed to open output GIF file: %1 + + Failed to open output file: %1 - + Select output file - - Graphics Interchange Format (*.gif) + + Graphics Interchange Format (*.gif);;Animated Portable Network Graphics (*.png *.webp *.apng) @@ -3032,11 +3026,26 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. QGBA::KeyEditor - - + + --- + + + Super (L) + + + + + Super (R) + + + + + Menu + + QGBA::LoadSaveState @@ -3113,47 +3122,47 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. QGBA::LogController - + [%1] %2: %3 - + An error occurred - + DEBUG - + STUB - + INFO - + WARN - + ERROR - + FATAL - + GAME ERROR @@ -3277,42 +3286,42 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - + All - + Load TBL - + Save selected memory - + Failed to open output file: %1 - + Load memory - + Failed to open input file: %1 - + TBL - + ISO-8859-1 @@ -3320,22 +3329,22 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. QGBA::MemorySearch - + (%0/%1×) - + (⅟%0×) - + (%0×) - + %1 byte%2 @@ -3343,49 +3352,61 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. QGBA::ObjView - - + + 0x%0 - + Off - + + + + + + + + + --- + + + + Normal - + Trans - + OBJWIN - + Invalid - - + + N/A - + Export sprite - + Portable Network Graphics (*.png) @@ -3404,10 +3425,6 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - %0 - - - @@ -3430,19 +3447,6 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - - QGBA::PrinterView - - - Save Printout - - - - - Portable Network Graphics (*.png) - - - QGBA::ROMInfo @@ -3526,7 +3530,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - + (%1×%2) @@ -3604,17 +3608,17 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. QGBA::VideoView - + Failed to open output video file: %1 - + Native (%0x%1) - + Select output file @@ -3665,8 +3669,8 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - + Select save @@ -3692,621 +3696,636 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - - Select image + + Select e-Reader dotcode - - Image file (*.png *.gif *.jpg *.jpeg);;All files (*) + + e-Reader card (*.raw *.bin *.bmp) + Select image + + + + + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) + + + + GameShark saves (*.sps *.xps) - + Select video log - + Video logs (*.mvl) - + Crash - + The game has crashed with the following error: %1 - - Couldn't Load + + Couldn't Start - - Could not load game. Are you sure it's in the correct format? + + Could not start game. - + Unimplemented BIOS call - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. - + Really make portable? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? - + Restart needed - + Some changes will not take effect until the emulator is restarted. - + - Player %1 of %2 - + %1 - %2 - + %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 - + &File - + Load &ROM... - + Load ROM in archive... - + Add folder to library... - + Load alternate save... - + Load temporary save... - + Load &patch... - + Boot BIOS - + Replace ROM... - + + Scan e-Reader dotcodes... + + + + ROM &info... - + Recent - + Make portable - + &Load state - + Load state file... - + &Save state - + Save state file... - + Quick load - + Quick save - + Load recent - + Save recent - + Undo load state - + Undo save state - - + + State &%1 - + Load camera image... - + Import GameShark Save... - + Export GameShark Save... - + New multiplayer window - + About... - + E&xit - + &Emulation - + &Reset - + Sh&utdown - + Yank game pak - + &Pause - + &Next frame - + Fast forward (held) - + &Fast forward - + Fast forward speed - + Unbounded - + %0x - + Rewind (held) - + Re&wind - + Step backwards - + Sync to &video - + Sync to &audio - + Solar sensor - + Increase solar level - + Decrease solar level - + Brightest solar level - + Darkest solar level - + Brightness %1 - + Game Boy Printer... - + BattleChip Gate... - + Audio/&Video - + Frame size - + %1× - + Toggle fullscreen - + Lock aspect ratio - + Force integer scaling - + Interframe blending - + Bilinear filtering - + Frame&skip - + Mute - + FPS target - + Native (59.7275) - + Take &screenshot - + F12 - + Record A/V... - - Record GIF... + + Record GIF/WebP/APNG... - + Video layers - + Audio channels - + Adjust layer placement... - + &Tools - + View &logs... - + Game &overrides... - + Game Pak sensors... - + &Cheats... - + Settings... - + Open debugger console... - + Start &GDB server... - + View &palette... - + View &sprites... - + View &tiles... - + View &map... - + &Frame inspector... - + View memory... - + Search memory... - + View &I/O registers... - + Record debug video log... - + Stop debug video log - + Exit fullscreen - + GameShark Button (held) - + Autofire - + Autofire A - + Autofire B - + Autofire L - + Autofire R - + Autofire Start - + Autofire Select - + Autofire Up - + Autofire Right - + Autofire Down - + Autofire Left - + Clear @@ -4329,6 +4348,29 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. + + QShortcut + + + Shift + + + + + Control + + + + + Alt + + + + + Meta + + + ROMInfo @@ -4624,7 +4666,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - + frames @@ -4769,305 +4811,310 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - + + Show filename instead of ROM name in title bar + + + + Fast forward speed: - - - + + + × - - + + Unbounded - + Fast forward (held) speed: - + Autofire interval: - + Enable rewind - + Rewind history: - + Idle loops: - + Run all - + Remove known - + Detect and remove - + Preload entire ROM into memory - + Savestate extra data: - - - - Screenshot - - - Save data + Screenshot - + + Save data + + + + + Cheat codes - + Load extra data: - + Video renderer: - + Software - + OpenGL - + OpenGL enhancements - + High-resolution scale: - + (240×160) - + XQ GBA audio (experimental) - + GB BIOS file: - - - - - - - - - + + + + + + + + + Browse - + Use BIOS file if found - + Skip BIOS intro - + GBA BIOS file: - + GBC BIOS file: - + SGB BIOS file: - + Save games - - - - - + + + + + Same directory as the ROM - + Save states - + Screenshots - + Patches - + Cheats - + Log to file - + Log to console - + Select Log File - + Game Boy model: - - - - - Autodetect - - - - - - - Game Boy (DMG) - - - Super Game Boy (SGB) + Autodetect - Game Boy Color (CGB) + Game Boy (DMG) + Super Game Boy (SGB) + + + + + + + Game Boy Color (CGB) + + + + + + Game Boy Advance (AGB) - + Super Game Boy model: - + Game Boy Color model: - + Default BG colors: - + Super Game Boy borders - + Camera driver: - + Default sprite colors 1: - + Default sprite colors 2: - + Use GBC colors in GB games - + Camera: @@ -5225,157 +5272,169 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - + WebM - + &Lossless - + &1080p - + &720p - + &480p - + &Native - + Format - + MKV - + AVI - + + MP4 - + + 4K + + + + h.264 - + h.264 (NVENC) - + HEVC - + HEVC (NVENC) - + VP8 - + VP9 - + FFV1 - + + + None + + + + FLAC - + Opus - + Vorbis - + MP3 - + AAC - + Uncompressed - + Bitrate (kbps) - + VBR - + ABR - + Dimensions - + : - + × - + Lock aspect ratio - + Show advanced diff --git a/src/platform/qt/ts/mgba-tr.ts b/src/platform/qt/ts/mgba-tr.ts index 7a160ba7c..b1862a283 100644 --- a/src/platform/qt/ts/mgba-tr.ts +++ b/src/platform/qt/ts/mgba-tr.ts @@ -226,15 +226,20 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır.Yükle - + Add New Set Yeni set ekle - + Add Ekle + + + Enter codes here... + + DebuggerConsole @@ -254,42 +259,95 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. + + FrameView + + + Inspect frame + + + + + × + + + + + Magnification + + + + + Freeze frame + + + + + Backdrop color + + + + + Disable scanline effects + + + + + Export + + + + + Reset + Reset + + GIFView - Record GIF - GIF kaydet + Record GIF/APNG + - + + Loop + + + + Start Başlat - + Stop Durdur - + Select File Dosya Seç - - Frameskip - Kare atlama - - - - Frame delay (ms) - Kare geçkimesi (ms) + + APNG + - Automatic - Otomatik + GIF + + + + + WebP + + + + + Frameskip + Kare atlama @@ -417,13 +475,13 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır.LoadSaveState - + %1 State - + @@ -435,17 +493,22 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır.Kayıt yok - + 1 - + 2 - + + Cancel + + + + 3 @@ -455,12 +518,12 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. - + 5 - + 6 @@ -470,12 +533,12 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. - + 8 - + 9 @@ -546,142 +609,206 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır.Haritalar - + × - + Magnification Büyüt - + Export Dışarı aktar + + + Copy + + + + + MemoryDump + + + Save Memory Range + + + + + Start Address: + + + + + : + + + + + + 0x + + + + + Byte Count: + + + + + Dump across banks + + MemorySearch - + Memory Search - + Address - + Current Value Mevcut değer - - + + Type Tip - + Value Değer - + Numeric Sayısal - + Text Yazı - + Width Genişlik - - + + Guess Tahmini - + 1 Byte (8-bit) - + 2 Bytes (16-bit) - + 4 Bytes (32-bit) - + Number type Numara tipi - + Decimal Ondalık - + Hexadecimal Onaltılık - - Compare - Karşılaştır + + Search type + - - Equal - Eşittir + + Equal to value + - - Greater - Büyüktür + + Greater than value + - - Less - Küçüktür + + Less than value + - - Delta - + + Unknown/changed + - - Search - Ara + + Changed by value + - + + Unchanged + + + + + Increased + + + + + Decreased + + + + + Search ROM + + + + + New Search + + + + Search Within Aralığında ara - + Open in Memory Viewer Memory Viewer'da aç - + Refresh Yenile @@ -699,67 +826,77 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır.Kontrol edilecek adres: - + + : + + + + 0x - + Set Alignment: Hizalamayı Ayarla: - + &1 Byte - + &2 Bytes - + &4 Bytes - + Unsigned Integer: İşaretsiz tam sayı: - + Signed Integer: İşaretlenmiş tam sayı: - + String: Sicim: - + Load TBL TBL yükle - + Copy Selection Seçilenleri kopyala - + Paste Yapıştır - + Save Selection Seçilenleri kaydet - + + Save Range + + + + Load Yükle @@ -772,140 +909,162 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. - - + + × - + Magnification Büyüklük - + Export Dışa aktar - + Attributes Değerler - + Transform Dönüştür - + Off Kapalı - + Palette Palet - - - - + + + + 0 - + + Copy + + + + + + +0.00 + + + + + + +1.00 + + + + + Matrix + + + + Double Size Çift taraf - - - - + + + + Return, Ctrl+R - + Flipped Çevirilmiş - + H - + V - + Mode Mod - + Normal Normal - + Mosaic Mozaik - + Enabled Aktifleştir - + Priority Öncelik - + Tile - + Geometry Geometri - + Position Pozisyon - + , - + Dimensions Boyutlar - - + + 8 - + Address Adres - + 0x07000000 @@ -1063,36 +1222,61 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. + MBC6 + + + + MBC7 - + + MMM01 + + + + Pocket Cam - + TAMA5 - + + HuC-1 + + + + HuC-3 - + + Wisdom Tree (Unlicensed) + + + + + Pokémon Jade/Diamond (Unlicensed) + + + + Background Colors Arkaplan renkleri - + Sprite Colors 1 Sprite Renkleri 1 - + Sprite Colors 2 Sprite Renkleri 2 @@ -1168,8 +1352,8 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. - 000 - + 0x000 (000) + @@ -1218,27 +1402,37 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. - + Hurry up! - + Tear off + + + × + + + + + Magnification + + QGBA::AssetTile - + %0%1%2 - - - + + + 0x%0 (%1) @@ -1289,22 +1483,22 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. QGBA::CoreController - + Failed to open save file: %1 Kayıt dosyası açılamadı: %1 - + Failed to open game file: %1 Oyun dosyası açılamadı: %1 - + Failed to open snapshot file for reading: %1 Anlık görüntü dosyası okuma için açılamadı: %1 - + Failed to open snapshot file for writing: %1 Anlık görüntü dosyası yazma için açılamadı: %1 @@ -1316,6 +1510,59 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır.Failed to open game file: %1 Oyun dosyası açılamadı: %1 + + + Could not load game. Are you sure it's in the correct format? + Oyun yüklenemedi. Doğru formatta olduğundan emin misin? + + + + Failed to open save file. Is the save directory writable? + + + + + QGBA::FrameView + + + Export frame + + + + + Portable Network Graphics (*.png) + + + + + None + Hiçbiri + + + + Background + Arkaplan + + + + Window + + + + + Sprite + + + + + Backdrop + + + + + %1 %2 + + QGBA::GBAApp @@ -1394,19 +1641,19 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. QGBA::GIFView - - Failed to open output GIF file: %1 - Çıkış GIF dosyası açılamadı:%1 + + Failed to open output file: %1 + Çıkış dosyası açılamadı:%1 - + Select output file Çıktı dosyasını seçin - - Graphics Interchange Format (*.gif) - Grafik Değişim Biçimi (* .gif) + + Graphics Interchange Format (*.gif);;Animated Portable Network Graphics (*.png *.webp *.apng) + @@ -2780,36 +3027,51 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. QGBA::KeyEditor - - + + --- + + + Super (L) + + + + + Super (R) + + + + + Menu + + QGBA::LoadSaveState - + Load State Konum yükle - + Save State Konumu kaydet - + Empty Boş - + Corrupted Bozulmuş - + Slot %1 @@ -2861,42 +3123,47 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. QGBA::LogController - + [%1] %2: %3 - + + An error occurred + + + + DEBUG - + STUB - + INFO - + WARN - + ERROR - + FATAL - + GAME ERROR @@ -2904,49 +3171,97 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. QGBA::MapView - + + Priority + Öncelik + + + + + Map base + + + + + + Tile base + + + + + Size + Boyut + + + + + Offset + Çıkıntı + + + + Xform + + + + Map Addr. - + Mirror - + None Hiçbiri - + Both - + Horizontal Yatay - + Vertical Dikey - + + + + N/A + + + + Export map - + Portable Network Graphics (*.png) + + + QGBA::MemoryDump - - Failed to open output PNG file: %1 - PNG dosyası açılamadı:%1 + + Save memory region + + + + + Failed to open output file: %1 + Çıkış dosyası açılamadı:%1 @@ -2972,42 +3287,42 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır.Yükle - + All Hepsi - + Load TBL TBL yükle - + Save selected memory Seçilen memory'i kaydet - + Failed to open output file: %1 Çıkış dosyası açılamadı:%1 - + Load memory Memory yükle - + Failed to open input file: %1 Giriş dosyası açılamadı:%1 - + TBL - + ISO-8859-1 @@ -3015,22 +3330,22 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. QGBA::MemorySearch - + (%0/%1×) - + (⅟%0×) - + (%0×) - + %1 byte%2 @@ -3038,57 +3353,64 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. QGBA::ObjView - - + + 0x%0 - + Off - + + + + + + + + + --- + + + + Normal - + Trans - + OBJWIN - + Invalid Geçersiz - + N/A - + Export sprite Sprite dışarı aktar - + Portable Network Graphics (*.png) - - - Failed to open output PNG file: %1 - PNG dosyası açılamadı:%1 - QGBA::PaletteView @@ -3104,10 +3426,6 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. - %0 - - - @@ -3156,72 +3474,77 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. QGBA::SettingsView - - + + Qt Multimedia - + SDL - + Software (Qt) Yazılım - + OpenGL - + OpenGL (force version 1.x) - + None (Still Image) - + Keyboard Klavye - + Controllers - + Shortcuts Kısayollar - - + + Shaders Gölgelendiricler - + Select BIOS BIOS seç + + + (%1×%2) + + QGBA::ShaderSelector - + No shader active Hiçbir Gölgelendirici aktif değil - + Load shader Gölgelendirici yükle @@ -3236,48 +3559,67 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. - + Preprocessing İşleniyor - + Pass %1 - QGBA::ShortcutController + QGBA::ShortcutModel - + Action - + - + Keyboard - Klavye + Klavye - + Gamepad - + + + + + QGBA::TileView + + + Export tiles + + + + + + Portable Network Graphics (*.png) + + + + + Export tile + QGBA::VideoView - + Failed to open output video file: %1 Çıkış video dosyası açılamadı:%1 - + Native (%0x%1) - + Select output file Çıkış dosyasını seç @@ -3285,108 +3627,118 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. QGBA::Window - + Game Boy Advance ROMs (%1) Game Boy Advance ROMları (%1) - + Game Boy ROMs (%1) Game Boy ROMları (%1) - + All ROMs (%1) Bütün ROMlar (%1) - + %1 Video Logs (*.mvl) - + Archives (%1) Arşivler (%1) - - - + + + Select ROM ROM seç - + Select folder Klasör seç - + Game Boy Advance save files (%1) Game Boy Advance kayıt dosyaları (%1) - - - + + + Select save Kayıt seç - + mGBA savestate files (%1) mGBA kaydedilmiş konu kayıtları (%1) - - + + Select savestate Konumkaydedici seç - + Select patch Yama seç - + Patches (*.ips *.ups *.bps) Yamalar (*.ips *.ups *.bps) - + + Select e-Reader dotcode + + + + + e-Reader card (*.raw *.bin *.bmp) + + + + Select image Resim seç - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Resim dosyası (*.png *.gif *.jpg *.jpeg);;All files (*) - - + + GameShark saves (*.sps *.xps) GameShark kayıtları (*.sps *.xps) - + Select video log Video günlüğü seç - + Video logs (*.mvl) Video günlükleri (*.mvl) - + Crash Çökme - + The game has crashed with the following error: %1 @@ -3395,631 +3747,591 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. - - Couldn't Load - Yüklenemedi - - - - Could not load game. Are you sure it's in the correct format? - Oyun yüklenemedi. Doğru formatta olduğundan emin misin? - - - + Unimplemented BIOS call Uygulanmamış BIOS girişi - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Oyun BIOS dosyasına ihtiyacı var. Lütfen en iyi deneyim için resmi BIOS'u kullanın. - + Really make portable? Taşınabilir yapılsın mı? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? Emülatörün yapılandırmasını yürütülebilir dosya ile aynı dizinden yüklemesini sağlar. Devam etmek istiyor musun? - + Restart needed Yeniden başlatma gerekli - + Some changes will not take effect until the emulator is restarted. Bazı değişiklikler emülatör yeniden başlatılıncaya kadar etkili olmaz. - + - Player %1 of %2 - + %1 - %2 - + %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 - + &File - + Load &ROM... &ROM yükle... - + Load ROM in archive... ROM'u arşivden yükle ... - + Add folder to library... Kütüphaneye klasör ekle ... - + Load alternate save... Alternatif kaydetme yükle ... - + Load temporary save... Geçici kaydetmeyi yükle ... - + Load &patch... &Patch yükle... - + Boot BIOS BIOS boot et - + Replace ROM... ROM değişti... - + ROM &info... ROM &info... - + Recent Son kullanılanlar - + Make portable Portatif yap - + &Load state &Kaydedilmiş konum yükle - - F10 - - - - + Load state file... Kaydedilmiş konum dosyası yükle... - + &Save state &Konumu kaydet - - Shift+F10 - - - - + Save state file... Konum dosyasını kaydet... - + Quick load Hızlı Yükle - + Quick save Hızlı kaydet - + Load recent En son yükle - + Save recent Hızlı kaydet - + Undo load state Kaydedilen konum yüklemeyi geri al - - F11 - - - - + Undo save state Konum kaydetmeyi geri al - - Shift+F11 - - - - - + + State &%1 Konum &%1 - - F%1 - - - - - Shift+F%1 - - - - + Load camera image... Kamera resmini yükle ... - - Import GameShark Save - GameShark kaydını içe aktarın - - - - Export GameShark Save - GameShark oyun kaydını dışarı aktar - - - + New multiplayer window Yeni çokoyunculu ekranı - + About... Hakkında... - + E&xit Çıkış - + &Emulation Emülasyon - + &Reset &Reset - - Ctrl+R - - - - + Sh&utdown Kapat - + Yank game pak - + &Pause &Durdur - - Ctrl+P - - - - + &Next frame &Sonraki kare - - Ctrl+N - - - - + Fast forward (held) İleriye sar(basılı tutun) - + &Fast forward &İleriye sar - - Shift+Tab - - - - + Fast forward speed İleriye sarma hızı - + Unbounded - + %0x - + Rewind (held) Geri sar (basılı tutun) - + Re&wind Geri sar - - ~ - - - - + Step backwards Geriye doğru adım - - Ctrl+B - - - - + Sync to &video &Videoya eşitle - + Sync to &audio &Sese eşitle - + Solar sensor - + Increase solar level Solar seviyesini arttır - + Decrease solar level Solar seviyesini düşür - + Brightest solar level En parlak solar seviyesi - + Darkest solar level En karanlık solar seviyesi - + Brightness %1 Parlaklık:%1 - + Game Boy Printer... Game Boy yazıcısı... - + BattleChip Gate... - + Audio/&Video Ses/&Video - + Frame size Çerçeve boyutu - - %1x - - - - + Toggle fullscreen Tamekranı aç/kapa - + Lock aspect ratio En boy oranını kilitle - + Force integer scaling Tamsayılı ölçeklendirmeyi zorla - + Bilinear filtering Bilinear filtreleme - + Frame&skip Kare atlama - + Mute Sessiz - + FPS target FPS hedefi - + Native (59.7275) - + Take &screenshot Ekran görüntüsü al - + F12 - - Record output... - Video kaydetme... - - - - Record GIF... - GIF kaydet... - - - - Record video log... - Video günlüğünü kaydet... - - - - Stop video log - Video günlüğünü durdur - - - + Video layers - + Audio channels Ses kanalları - + Adjust layer placement... Katman yerleşimini ayarlayın... - + &Tools &Araçlar - + View &logs... Kayıtları görüntüle... - + Game &overrides... Oyunların üzerine yazılanlar - - Game &Pak sensors... - &Pa sensörleri... + + Couldn't Start + - + + Could not start game. + + + + + Scan e-Reader dotcodes... + + + + + Import GameShark Save... + + + + + Export GameShark Save... + + + + + %1× + + + + + Interframe blending + + + + + Record A/V... + + + + + Record GIF/WebP/APNG... + + + + + Game Pak sensors... + + + + &Cheats... &Hileler... - + Settings... Ayarlar... - + Open debugger console... Hata ayıklayıcı konsolunu aç ... - + Start &GDB server... &GDB sunucusunu başlat... - + View &palette... &Renk Paletini gör... - + View &sprites... &Spriteları gör... - + View &tiles... &Desenleri gör... - + View &map... &Haritayı gör - + + &Frame inspector... + + + + View memory... Hafıza gör... - + Search memory... Hafızada ara... - + View &I/O registers... &I/O kayıtlarını görüntüle - + + Record debug video log... + + + + + Stop debug video log + + + + Exit fullscreen Tam ekrandan çık - + GameShark Button (held) GameShark Butonu (basılı tutun) - + Autofire Otomatik basma - + Autofire A Otomatik basma A - + Autofire B Otomatik basma B - + Autofire L Otomatik basma L - + Autofire R Otomatik basma R - + Autofire Start Otomatik basma Start - + Autofire Select Otomatik basma Select - + Autofire Up Otomatik basma Up - + Autofire Right Otomatik basma Right - + Autofire Down Otomatik basma Down - + Autofire Left Otomatik basma Sol + + + Clear + Temizle + QObject @@ -4039,6 +4351,29 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. + + QShortcut + + + Shift + + + + + Control + + + + + Alt + + + + + Meta + + + ROMInfo @@ -4196,520 +4531,593 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. + Enhancements + + + + BIOS - + Paths Dizinler - + Logging Günlükler - + Game Boy - + Audio driver: Ses sürücüsü: - + Audio buffer: Ses arttırma: - - + + 1536 - + 512 - + 768 - + 1024 - + 2048 - + 3072 - + 4096 - + samples değerler - + Sample rate: Değer oranı - - + + 44100 - + 22050 - + 32000 - + 48000 - + Hz - + Volume: Ses - - + + Mute Sessiz - + Fast forward volume: Hızlı sarma ses seviyesi: - + Display driver: Görüntü sürücüsü: - + Frameskip: Kare atlama: - + Skip every Hepsini atla - - + + frames Kare - + FPS target: Hedef FPS: - + frames per second Saniye başına kare - + Sync: Eşitle - + Video Video - + Audio Ses - + Lock aspect ratio En boy oranını kilitle - + Force integer scaling Tamsayılı ölçeklendirmeyi zorla - + Bilinear filtering Bilinear filtreleme - + + Native (59.7275) + + + + + Interframe blending + + + + Language Dil - + English İngilizce - + Library: Kütüphane - + List view Liste görünümü - + Tree view Sıralı görünüm - + Show when no game open Oyun açılmadığında göster - + Clear cache Ön belleği temizle - + Allow opposing input directions Karşıt giriş yönlerine izin ver - + Suspend screensaver Ekran koruyucuyu askıya alın - + Pause when inactive Etkin değilken duraklat - + + Pause when minimized + + + + Show FPS in title bar FPS'i başlık çubuğunda göster - + Automatically save cheats Otomatik hile kaydedici - + Automatically load cheats Otomatik hile yükleyici - + Automatically save state Otomatik konum kaydedici - + Automatically load state Otomatik konum yükleyici - + Enable Discord Rich Presence Discord etkinliğini etkinleştir - + + Show OSD messages + + + + + Show filename instead of ROM name in title bar + + + + Fast forward speed: Hızlı sarma hızı: - + + + × - + + Unbounded Sınırsız - + + Fast forward (held) speed: + + + + Autofire interval: Otomatik ateşleme aralığı: - + Enable rewind Geri sarmayı etkinleştir - + Rewind history: Geri alma tarihi: - + Idle loops: - + Run all Hepsini çalıştır - + Remove known Bilinenleri kaldır - + Detect and remove Algıla ve kaldır - + Preload entire ROM into memory Tüm ROM'u belleğe önceden yükle - + Savestate extra data: Konum kaydedici kaydeder: - - + + Screenshot Ekran görüntüsü - - + + Save data Verileri kaydet - - + + Cheat codes Hile kodları - + Load extra data: Ekstra veri yükle: - + + Video renderer: + + + + + Software + + + + + OpenGL + + + + + OpenGL enhancements + + + + + High-resolution scale: + + + + + (240×160) + + + + + XQ GBA audio (experimental) + + + + GB BIOS file: GB BIOS dosyası: - - - - - - - - - + + + + + + + + + Browse Gözat - + Use BIOS file if found Varsa BIOS dosyasını kullan - + Skip BIOS intro BIOS girişini atla - + GBA BIOS file: GBA BIOS dosyası: - + GBC BIOS file: GBC BIOS dosyası: - + SGB BIOS file: SGB BIOS dosyası: - + Save games Oyunları kaydet - - - - - + + + + + Same directory as the ROM ROM ile aynı dizin - + Save states Konum kaydedici - + Screenshots Ekran görüntüleri: - + Patches Yamalar - + Cheats Hileler - + Log to file Dosyaya günlüğünü gir - + Log to console Konsola günlüğünü gir - + Select Log File Günlük Dosyasını Seç - + Game Boy model: Game Boy modeli: - - - + + + Autodetect Otomatik tespit - - - + + + Game Boy (DMG) - - - + + + Super Game Boy (SGB) - - - + + + Game Boy Color (CGB) - - - + + + Game Boy Advance (AGB) - + Super Game Boy model: Super Game Boy modeli: - + Game Boy Color model: Game Boy Color modeli: - + Default BG colors: - + Super Game Boy borders Super Game Boy sınırları - + Camera driver: Kamera sürücüsü: - + Default sprite colors 1: Varsayılan sprite renkleri 1: - + Default sprite colors 2: Varsayılan sprite renkleri 2: - + Use GBC colors in GB games GB oyunlarında GBC renklerini kullan - + Camera: Kamera @@ -4783,30 +5191,50 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. - + + Export Selected + + + + + Export All + + + + 256 colors 256 renkleri - + × - + Magnification Büyütme - + Tiles per row - + Fit to window Pencereye sığdır + + + Copy Selected + + + + + Copy All + + VideoView @@ -4847,157 +5275,169 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. - + WebM - + &Lossless - + &1080p - + &720p - + &480p - + &Native - + Format Format - + MKV - + AVI - + + MP4 - + + 4K + + + + h.264 - + h.264 (NVENC) - + HEVC - + HEVC (NVENC) - + VP8 - + VP9 - + FFV1 - + + + None + Hiçbiri + + + FLAC - + Opus - + Vorbis - + MP3 - + AAC - + Uncompressed Sıkıştırılmamış - + Bitrate (kbps) - + VBR - + ABR - + Dimensions Boyutlar - + : - + × - + Lock aspect ratio En boy oranını kilitle - + Show advanced Gelişmişi göster diff --git a/src/platform/test/cinema-main.c b/src/platform/test/cinema-main.c index dc74992fa..de70484f7 100644 --- a/src/platform/test/cinema-main.c +++ b/src/platform/test/cinema-main.c @@ -1350,6 +1350,7 @@ void _log(struct mLogger* log, int category, enum mLogLevel level, const char* f int main(int argc, char** argv) { ThreadLocalInitKey(&logStream); ThreadLocalSetKey(logStream, NULL); + putenv("TZ=UTC"); int status = 0; if (!parseCInemaArgs(argc, argv)) { diff --git a/src/platform/test/perf-main.c b/src/platform/test/perf-main.c index dc563d238..e9f5fae1e 100644 --- a/src/platform/test/perf-main.c +++ b/src/platform/test/perf-main.c @@ -31,6 +31,10 @@ uint32_t* romBuffer; size_t romBufferSize; #endif #endif +#ifdef PSP2 +#include +#include +#endif #include #include @@ -108,6 +112,8 @@ int main(int argc, char** argv) { romBuffer = SYS_GetArena2Lo(); SYS_SetArena2Lo((void*)((intptr_t) romBuffer + romBufferSize)); #endif +#elif defined(PSP2) + scePowerSetArmClockFrequency(444); #else signal(SIGINT, _mPerfShutdown); #endif @@ -177,6 +183,8 @@ int main(int argc, char** argv) { VIDEO_Flush(); VIDEO_WaitVSync(); VIDEO_WaitVSync(); +#elif defined(PSP2) + sceKernelExitProcess(0); #endif return didFail; diff --git a/src/platform/wii/CMakeLists.txt b/src/platform/wii/CMakeLists.txt index 318c176a6..fc69083d2 100644 --- a/src/platform/wii/CMakeLists.txt +++ b/src/platform/wii/CMakeLists.txt @@ -23,14 +23,24 @@ add_executable(${BINARY_NAME}.elf ${GUI_SRC} main.c) set_target_properties(${BINARY_NAME}.elf PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}") target_link_libraries(${BINARY_NAME}.elf ${BINARY_NAME} ${OS_LIB}) +add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/font.tpl + COMMAND ${GXTEXCONV} -i ${CMAKE_SOURCE_DIR}/res/font2x.png -o font.tpl colfmt=5 mipmap=no + MAIN_DEPENDENCY ${CMAKE_SOURCE_DIR}/res/font2x.png + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/font.c - COMMAND ${RAW2C} ${CMAKE_SOURCE_DIR}/src/platform/wii/font.tpl - MAIN_DEPENDENCY ${CMAKE_SOURCE_DIR}/src/platform/wii/font.tpl + COMMAND ${RAW2C} ${CMAKE_CURRENT_BINARY_DIR}/font.tpl + MAIN_DEPENDENCY ${CMAKE_CURRENT_BINARY_DIR}/font.tpl + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + +add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icons.tpl + COMMAND ${GXTEXCONV} -i ${CMAKE_SOURCE_DIR}/res/icons2x.png -o icons.tpl colfmt=5 mipmap=no + MAIN_DEPENDENCY ${CMAKE_SOURCE_DIR}/res/icons2x.png WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icons.c - COMMAND ${RAW2C} ${CMAKE_SOURCE_DIR}/src/platform/wii/icons.tpl - MAIN_DEPENDENCY ${CMAKE_SOURCE_DIR}/src/platform/wii/icons.tpl + COMMAND ${RAW2C} ${CMAKE_CURRENT_BINARY_DIR}/icons.tpl + MAIN_DEPENDENCY ${CMAKE_CURRENT_BINARY_DIR}/icons.tpl WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) add_custom_target(${BINARY_NAME}.dol ALL diff --git a/src/platform/wii/font.tpl b/src/platform/wii/font.tpl deleted file mode 100644 index ec3f8cdaf..000000000 Binary files a/src/platform/wii/font.tpl and /dev/null differ diff --git a/src/platform/wii/icons.tpl b/src/platform/wii/icons.tpl deleted file mode 100644 index 9a3c54885..000000000 Binary files a/src/platform/wii/icons.tpl and /dev/null differ diff --git a/src/util/gui/font-metrics.c b/src/util/gui/font-metrics.c index 99bc2daf6..1a7b3f539 100644 --- a/src/util/gui/font-metrics.c +++ b/src/util/gui/font-metrics.c @@ -152,4 +152,6 @@ const struct GUIIconMetric defaultIconMetrics[] = { [GUI_ICON_BUTTON_TRIANGLE] = { 34, 34, 12, 11 }, [GUI_ICON_BUTTON_SQUARE] = { 50, 34, 12, 11 }, [GUI_ICON_BUTTON_HOME] = { 66, 34, 12, 11 }, + [GUI_ICON_STATUS_FAST_FORWARD] = { 2, 50, 12, 12 }, + [GUI_ICON_STATUS_MUTE] = { 17, 50, 14, 12 }, }; diff --git a/src/util/hash.c b/src/util/hash.c index c75cb2ab1..ebf157442 100644 --- a/src/util/hash.c +++ b/src/util/hash.c @@ -28,7 +28,9 @@ static inline uint32_t rotl32 ( uint32_t x, int8_t r ) { // handle aligned reads, do the conversion here static FORCE_INLINE uint32_t getblock32 ( const uint32_t * p, int i ) { - return p[i]; + uint32_t ret; + LOAD_32LE(ret, i << 2, p); + return ret; } //----------------------------------------------------------------------------- diff --git a/src/util/table.c b/src/util/table.c index 0bfe24a87..a0d98b22e 100644 --- a/src/util/table.c +++ b/src/util/table.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014 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,18 +6,18 @@ #include #include +#include #include -#define LIST_INITIAL_SIZE 8 +#define LIST_INITIAL_SIZE 4 #define TABLE_INITIAL_SIZE 8 +#define REBALANCE_THRESHOLD 4 #define TABLE_COMPARATOR(LIST, INDEX) LIST->list[(INDEX)].key == key #define HASH_TABLE_STRNCMP_COMPARATOR(LIST, INDEX) LIST->list[(INDEX)].key == hash && strncmp(LIST->list[(INDEX)].stringKey, key, LIST->list[(INDEX)].keylen) == 0 -#define HASH_TABLE_MEMCMP_COMPARATOR(LIST, INDEX) LIST->list[(INDEX)].key == hash && memcmp(LIST->list[(INDEX)].stringKey, key, LIST->list[(INDEX)].keylen) == 0 +#define HASH_TABLE_MEMCMP_COMPARATOR(LIST, INDEX) LIST->list[(INDEX)].key == hash && LIST->list[(INDEX)].keylen == keylen && memcmp(LIST->list[(INDEX)].stringKey, key, LIST->list[(INDEX)].keylen) == 0 -#define TABLE_LOOKUP_START(COMPARATOR, LIST, KEY) \ - uint32_t entry = (KEY) & (table->tableSize - 1); \ - LIST = &table->table[entry]; \ +#define TABLE_LOOKUP_START(COMPARATOR, LIST) \ size_t i; \ for (i = 0; i < LIST->nEntries; ++i) { \ if (COMPARATOR(LIST, i)) { \ @@ -42,6 +42,18 @@ struct TableList { size_t listSize; }; +void HashTableInsertBinaryMoveKey(struct Table* table, void* key, size_t keylen, void* value); + +static inline const struct TableList* _getConstList(const struct Table* table, uint32_t key) { + uint32_t entry = key & (table->tableSize - 1); + return &table->table[entry]; +} + +static inline struct TableList* _getList(struct Table* table, uint32_t key) { + uint32_t entry = key & (table->tableSize - 1); + return &table->table[entry]; +} + static struct TableList* _resizeAsNeeded(struct Table* table, struct TableList* list, uint32_t key) { UNUSED(table); UNUSED(key); @@ -65,14 +77,36 @@ static void _removeItemFromList(struct Table* table, struct TableList* list, siz } } -void TableInit(struct Table* table, size_t initialSize, void (deinitializer(void*))) { - if (initialSize < 2 || (initialSize & (initialSize - 1))) { +static void _rebalance(struct Table* table) { + struct Table newTable; + TableInit(&newTable, table->tableSize * REBALANCE_THRESHOLD, NULL); + newTable.seed = table->seed * 134775813 + 1; + size_t i; + for (i = 0; i < table->tableSize; ++i) { + const struct TableList* list = &table->table[i]; + size_t j; + for (j = 0; j < list->nEntries; ++j) { + HashTableInsertBinaryMoveKey(&newTable, list->list[j].stringKey, list->list[j].keylen, list->list[j].value); + } + free(list->list); + } + free(table->table); + table->tableSize = newTable.tableSize; + table->table = newTable.table; + table->seed = newTable.seed; +} + +void TableInit(struct Table* table, size_t initialSize, void (*deinitializer)(void*)) { + if (initialSize < 2) { initialSize = TABLE_INITIAL_SIZE; + } else if (initialSize & (initialSize - 1)) { + initialSize = toPow2(initialSize); } table->tableSize = initialSize; table->table = calloc(table->tableSize, sizeof(struct TableList)); table->size = 0; table->deinitializer = deinitializer; + table->seed = 0; size_t i; for (i = 0; i < table->tableSize; ++i) { @@ -101,16 +135,16 @@ void TableDeinit(struct Table* table) { } void* TableLookup(const struct Table* table, uint32_t key) { - const struct TableList* list; - TABLE_LOOKUP_START(TABLE_COMPARATOR, list, key) { + const struct TableList* list = _getConstList(table, key); + TABLE_LOOKUP_START(TABLE_COMPARATOR, list) { return lookupResult->value; } TABLE_LOOKUP_END; return 0; } void TableInsert(struct Table* table, uint32_t key, void* value) { - struct TableList* list; - TABLE_LOOKUP_START(TABLE_COMPARATOR, list, key) { + struct TableList* list = _getList(table, key); + TABLE_LOOKUP_START(TABLE_COMPARATOR, list) { if (value != lookupResult->value) { if (table->deinitializer) { table->deinitializer(lookupResult->value); @@ -128,8 +162,8 @@ void TableInsert(struct Table* table, uint32_t key, void* value) { } void TableRemove(struct Table* table, uint32_t key) { - struct TableList* list; - TABLE_LOOKUP_START(TABLE_COMPARATOR, list, key) { + struct TableList* list = _getList(table, key); + TABLE_LOOKUP_START(TABLE_COMPARATOR, list) { _removeItemFromList(table, list, i); // TODO: Move i out of the macro } TABLE_LOOKUP_END; } @@ -151,7 +185,7 @@ void TableClear(struct Table* table) { } } -void TableEnumerate(const struct Table* table, void (handler(uint32_t key, void* value, void* user)), void* user) { +void TableEnumerate(const struct Table* table, void (*handler)(uint32_t key, void* value, void* user), void* user) { size_t i; for (i = 0; i < table->tableSize; ++i) { const struct TableList* list = &table->table[i]; @@ -166,8 +200,9 @@ size_t TableSize(const struct Table* table) { return table->size; } -void HashTableInit(struct Table* table, size_t initialSize, void (deinitializer(void*))) { +void HashTableInit(struct Table* table, size_t initialSize, void (*deinitializer)(void*)) { TableInit(table, initialSize, deinitializer); + table->seed = 1; } void HashTableDeinit(struct Table* table) { @@ -175,27 +210,32 @@ void HashTableDeinit(struct Table* table) { } void* HashTableLookup(const struct Table* table, const char* key) { - uint32_t hash = hash32(key, strlen(key), 0); - const struct TableList* list; - TABLE_LOOKUP_START(HASH_TABLE_STRNCMP_COMPARATOR, list, hash) { + uint32_t hash = hash32(key, strlen(key), table->seed); + const struct TableList* list = _getConstList(table, hash); + TABLE_LOOKUP_START(HASH_TABLE_STRNCMP_COMPARATOR, list) { return lookupResult->value; } TABLE_LOOKUP_END; return 0; } void* HashTableLookupBinary(const struct Table* table, const void* key, size_t keylen) { - uint32_t hash = hash32(key, keylen, 0); - const struct TableList* list; - TABLE_LOOKUP_START(HASH_TABLE_MEMCMP_COMPARATOR, list, hash) { + uint32_t hash = hash32(key, keylen, table->seed); + const struct TableList* list = _getConstList(table, hash); + TABLE_LOOKUP_START(HASH_TABLE_MEMCMP_COMPARATOR, list) { return lookupResult->value; } TABLE_LOOKUP_END; return 0; } void HashTableInsert(struct Table* table, const char* key, void* value) { - uint32_t hash = hash32(key, strlen(key), 0); - struct TableList* list; - TABLE_LOOKUP_START(HASH_TABLE_STRNCMP_COMPARATOR, list, hash) { + uint32_t hash = hash32(key, strlen(key), table->seed); + struct TableList* list = _getList(table, hash); + if (table->size >= table->tableSize * REBALANCE_THRESHOLD) { + _rebalance(table); + hash = hash32(key, strlen(key), table->seed); + list = _getList(table, hash); + } + TABLE_LOOKUP_START(HASH_TABLE_STRNCMP_COMPARATOR, list) { if (value != lookupResult->value) { if (table->deinitializer) { table->deinitializer(lookupResult->value); @@ -214,9 +254,14 @@ void HashTableInsert(struct Table* table, const char* key, void* value) { } void HashTableInsertBinary(struct Table* table, const void* key, size_t keylen, void* value) { - uint32_t hash = hash32(key, keylen, 0); - struct TableList* list; - TABLE_LOOKUP_START(HASH_TABLE_MEMCMP_COMPARATOR, list, hash) { + uint32_t hash = hash32(key, keylen, table->seed); + struct TableList* list = _getList(table, hash); + if (table->size >= table->tableSize * REBALANCE_THRESHOLD) { + _rebalance(table); + hash = hash32(key, keylen, table->seed); + list = _getList(table, hash); + } + TABLE_LOOKUP_START(HASH_TABLE_MEMCMP_COMPARATOR, list) { if (value != lookupResult->value) { if (table->deinitializer) { table->deinitializer(lookupResult->value); @@ -235,18 +280,44 @@ void HashTableInsertBinary(struct Table* table, const void* key, size_t keylen, ++table->size; } +void HashTableInsertBinaryMoveKey(struct Table* table, void* key, size_t keylen, void* value) { + uint32_t hash = hash32(key, keylen, table->seed); + struct TableList* list = _getList(table, hash); + if (table->size >= table->tableSize * REBALANCE_THRESHOLD) { + _rebalance(table); + hash = hash32(key, keylen, table->seed); + list = _getList(table, hash); + } + TABLE_LOOKUP_START(HASH_TABLE_MEMCMP_COMPARATOR, list) { + if (value != lookupResult->value) { + if (table->deinitializer) { + table->deinitializer(lookupResult->value); + } + lookupResult->value = value; + } + return; + } TABLE_LOOKUP_END; + list = _resizeAsNeeded(table, list, hash); + list->list[list->nEntries].key = hash; + list->list[list->nEntries].stringKey = key; + list->list[list->nEntries].keylen = keylen; + list->list[list->nEntries].value = value; + ++list->nEntries; + ++table->size; +} + void HashTableRemove(struct Table* table, const char* key) { - uint32_t hash = hash32(key, strlen(key), 0); - struct TableList* list; - TABLE_LOOKUP_START(HASH_TABLE_STRNCMP_COMPARATOR, list, hash) { + uint32_t hash = hash32(key, strlen(key), table->seed); + struct TableList* list = _getList(table, hash); + TABLE_LOOKUP_START(HASH_TABLE_STRNCMP_COMPARATOR, list) { _removeItemFromList(table, list, i); // TODO: Move i out of the macro } TABLE_LOOKUP_END; } void HashTableRemoveBinary(struct Table* table, const void* key, size_t keylen) { - uint32_t hash = hash32(key, keylen, 0); - struct TableList* list; - TABLE_LOOKUP_START(HASH_TABLE_MEMCMP_COMPARATOR, list, hash) { + uint32_t hash = hash32(key, keylen, table->seed); + struct TableList* list = _getList(table, hash); + TABLE_LOOKUP_START(HASH_TABLE_MEMCMP_COMPARATOR, list) { _removeItemFromList(table, list, i); // TODO: Move i out of the macro } TABLE_LOOKUP_END; } @@ -269,7 +340,7 @@ void HashTableClear(struct Table* table) { } } -void HashTableEnumerate(const struct Table* table, void (handler(const char* key, void* value, void* user)), void* user) { +void HashTableEnumerate(const struct Table* table, void (*handler)(const char* key, void* value, void* user), void* user) { size_t i; for (i = 0; i < table->tableSize; ++i) { const struct TableList* list = &table->table[i]; @@ -280,7 +351,18 @@ void HashTableEnumerate(const struct Table* table, void (handler(const char* key } } -const char* HashTableSearch(const struct Table* table, bool (predicate(const char* key, const void* value, const void* user)), const void* user) { +void HashTableEnumerateBinary(const struct Table* table, void (*handler)(const char* key, size_t keylen, void* value, void* user), void* user) { + size_t i; + for (i = 0; i < table->tableSize; ++i) { + const struct TableList* list = &table->table[i]; + size_t j; + for (j = 0; j < list->nEntries; ++j) { + handler(list->list[j].stringKey, list->list[j].keylen, list->list[j].value, user); + } + } +} + +const char* HashTableSearch(const struct Table* table, bool (*predicate)(const char* key, const void* value, const void* user), const void* user) { size_t i; const char* result = NULL; for (i = 0; i < table->tableSize; ++i) { diff --git a/src/util/vfs/vfs-fd.c b/src/util/vfs/vfs-fd.c index 8460a0253..c15ab5ca1 100644 --- a/src/util/vfs/vfs-fd.c +++ b/src/util/vfs/vfs-fd.c @@ -42,7 +42,7 @@ static void* _vfdMap(struct VFile* vf, size_t size, int flags); static void _vfdUnmap(struct VFile* vf, void* memory, size_t size); static void _vfdTruncate(struct VFile* vf, size_t size); static ssize_t _vfdSize(struct VFile* vf); -static bool _vfdSync(struct VFile* vf, const void* buffer, size_t size); +static bool _vfdSync(struct VFile* vf, void* buffer, size_t size); struct VFile* VFileOpenFD(const char* path, int flags) { if (!path) { @@ -195,7 +195,7 @@ static ssize_t _vfdSize(struct VFile* vf) { return stat.st_size; } -static bool _vfdSync(struct VFile* vf, const void* buffer, size_t size) { +static bool _vfdSync(struct VFile* vf, void* buffer, size_t size) { UNUSED(buffer); UNUSED(size); struct VFileFD* vfd = (struct VFileFD*) vf; @@ -206,7 +206,7 @@ static bool _vfdSync(struct VFile* vf, const void* buffer, size_t size) { futimes(vfd->fd, NULL); #endif if (buffer && size) { - return msync(buffer, size, MS_SYNC) == 0; + return msync(buffer, size, MS_ASYNC) == 0; } return fsync(vfd->fd) == 0; #else @@ -217,7 +217,7 @@ static bool _vfdSync(struct VFile* vf, const void* buffer, size_t size) { SystemTimeToFileTime(&st, &ft); SetFileTime(h, NULL, &ft, &ft); if (buffer && size) { - FlushViewOfFile(buffer, size); + return FlushViewOfFile(buffer, size); } return FlushFileBuffers(h); #endif diff --git a/src/util/vfs/vfs-fifo.c b/src/util/vfs/vfs-fifo.c index efff7bdab..5b6af5760 100644 --- a/src/util/vfs/vfs-fifo.c +++ b/src/util/vfs/vfs-fifo.c @@ -19,7 +19,7 @@ static void* _vffMap(struct VFile* vf, size_t size, int flags); static void _vffUnmap(struct VFile* vf, void* memory, size_t size); static void _vffTruncate(struct VFile* vf, size_t size); static ssize_t _vffSize(struct VFile* vf); -static bool _vffSync(struct VFile* vf, const void* buffer, size_t size); +static bool _vffSync(struct VFile* vf, void* buffer, size_t size); struct VFile* VFileFIFO(struct CircleBuffer* backing) { if (!backing) { @@ -94,7 +94,7 @@ static ssize_t _vffSize(struct VFile* vf) { return CircleBufferSize(vff->backing); } -static bool _vffSync(struct VFile* vf, const void* buffer, size_t size) { +static bool _vffSync(struct VFile* vf, void* buffer, size_t size) { UNUSED(vf); UNUSED(buffer); UNUSED(size); diff --git a/src/util/vfs/vfs-file.c b/src/util/vfs/vfs-file.c index bfde30e93..d3adc3177 100644 --- a/src/util/vfs/vfs-file.c +++ b/src/util/vfs/vfs-file.c @@ -24,7 +24,7 @@ static void* _vffMap(struct VFile* vf, size_t size, int flags); static void _vffUnmap(struct VFile* vf, void* memory, size_t size); static void _vffTruncate(struct VFile* vf, size_t size); static ssize_t _vffSize(struct VFile* vf); -static bool _vffSync(struct VFile* vf, const void* buffer, size_t size); +static bool _vffSync(struct VFile* vf, void* buffer, size_t size); struct VFile* VFileFOpen(const char* path, const char* mode) { if (!path && !mode) { @@ -144,13 +144,14 @@ static ssize_t _vffSize(struct VFile* vf) { return size; } -static bool _vffSync(struct VFile* vf, const void* buffer, size_t size) { +static bool _vffSync(struct VFile* vf, void* buffer, size_t size) { struct VFileFILE* vff = (struct VFileFILE*) vf; if (buffer && size) { long pos = ftell(vff->file); fseek(vff->file, 0, SEEK_SET); - fwrite(buffer, size, 1, vff->file); + size_t res = fwrite(buffer, size, 1, vff->file); fseek(vff->file, pos, SEEK_SET); + return res == 1; } return fflush(vff->file) == 0; } diff --git a/src/util/vfs/vfs-lzma.c b/src/util/vfs/vfs-lzma.c index a1c259ee4..a094c187a 100644 --- a/src/util/vfs/vfs-lzma.c +++ b/src/util/vfs/vfs-lzma.c @@ -58,7 +58,7 @@ static void* _vf7zMap(struct VFile* vf, size_t size, int flags); static void _vf7zUnmap(struct VFile* vf, void* memory, size_t size); static void _vf7zTruncate(struct VFile* vf, size_t size); static ssize_t _vf7zSize(struct VFile* vf); -static bool _vf7zSync(struct VFile* vf, const void* buffer, size_t size); +static bool _vf7zSync(struct VFile* vf, void* buffer, size_t size); static bool _vd7zClose(struct VDir* vd); static void _vd7zRewind(struct VDir* vd); @@ -327,7 +327,7 @@ bool _vd7zDeleteFile(struct VDir* vd, const char* path) { return false; } -bool _vf7zSync(struct VFile* vf, const void* memory, size_t size) { +bool _vf7zSync(struct VFile* vf, void* memory, size_t size) { UNUSED(vf); UNUSED(memory); UNUSED(size); diff --git a/src/util/vfs/vfs-mem.c b/src/util/vfs/vfs-mem.c index 2ccdc339c..05d5a599f 100644 --- a/src/util/vfs/vfs-mem.c +++ b/src/util/vfs/vfs-mem.c @@ -28,7 +28,7 @@ static void _vfmUnmap(struct VFile* vf, void* memory, size_t size); static void _vfmTruncate(struct VFile* vf, size_t size); static void _vfmTruncateNoop(struct VFile* vf, size_t size); static ssize_t _vfmSize(struct VFile* vf); -static bool _vfmSync(struct VFile* vf, const void* buffer, size_t size); +static bool _vfmSync(struct VFile* vf, void* buffer, size_t size); struct VFile* VFileFromMemory(void* mem, size_t size) { if (!mem || !size) { @@ -297,7 +297,7 @@ ssize_t _vfmSize(struct VFile* vf) { return vfm->size; } -bool _vfmSync(struct VFile* vf, const void* buffer, size_t size) { +bool _vfmSync(struct VFile* vf, void* buffer, size_t size) { UNUSED(vf); UNUSED(buffer); UNUSED(size); diff --git a/src/util/vfs/vfs-zip.c b/src/util/vfs/vfs-zip.c index c3849d8e7..912b048d3 100644 --- a/src/util/vfs/vfs-zip.c +++ b/src/util/vfs/vfs-zip.c @@ -74,7 +74,7 @@ static void* _vfzMap(struct VFile* vf, size_t size, int flags); static void _vfzUnmap(struct VFile* vf, void* memory, size_t size); static void _vfzTruncate(struct VFile* vf, size_t size); static ssize_t _vfzSize(struct VFile* vf); -static bool _vfzSync(struct VFile* vf, const void* buffer, size_t size); +static bool _vfzSync(struct VFile* vf, void* buffer, size_t size); static bool _vdzClose(struct VDir* vd); static void _vdzRewind(struct VDir* vd); @@ -426,7 +426,7 @@ bool _vdzDeleteFile(struct VDir* vd, const char* path) { return false; } -bool _vfzSync(struct VFile* vf, const void* memory, size_t size) { +bool _vfzSync(struct VFile* vf, void* memory, size_t size) { UNUSED(vf); UNUSED(memory); UNUSED(size); @@ -654,7 +654,7 @@ bool _vdzDeleteFile(struct VDir* vd, const char* path) { return false; } -bool _vfzSync(struct VFile* vf, const void* memory, size_t size) { +bool _vfzSync(struct VFile* vf, void* memory, size_t size) { UNUSED(vf); UNUSED(memory); UNUSED(size); diff --git a/tools/perf.py b/tools/perf.py index d5f78fc4f..75f05fb7f 100755 --- a/tools/perf.py +++ b/tools/perf.py @@ -72,18 +72,20 @@ class GameClockTest(PerfTest): class PerfServer(object): ITERATIONS_PER_INSTANCE = 50 - def __init__(self, address, command=None): + def __init__(self, address, root='/', command=None): s = address.rsplit(':', 1) if len(s) == 1: self.address = (s[0], 7216) else: self.address = (s[0], s[1]) + self.command = None if command: self.command = shlex.split(command) self.iterations = self.ITERATIONS_PER_INSTANCE self.socket = None self.results = [] self.reader = None + self.root = root def _start(self, test): if self.command: @@ -108,7 +110,7 @@ class PerfServer(object): def run(self, test): if not self.socket: self._start(test) - self.socket.send(os.path.join("/perfroms", test.rom).encode("utf-8")) + self.socket.send(os.path.join(self.root, test.rom).encode("utf-8")) self.results.append(next(self.reader)) self.iterations -= 1 if self.iterations == 0: @@ -178,6 +180,7 @@ if __name__ == '__main__': parser.add_argument('-s', '--server', metavar='ADDRESS', help='run on server') parser.add_argument('-S', '--server-command', metavar='COMMAND', help='command to launch server') parser.add_argument('-o', '--out', metavar='FILE', help='output file path') + parser.add_argument('-r', '--root', metavar='PATH', type=str, default='/perfroms', help='root path for server mode') parser.add_argument('directory', help='directory containing ROM files') args = parser.parse_args() @@ -189,9 +192,9 @@ if __name__ == '__main__': s = Suite(args.directory, wall=args.wall_time, game=args.game_frames, renderer=renderer) if args.server: if args.server_command: - server = PerfServer(args.server, args.server_command) + server = PerfServer(args.server, args.root, args.server_command) else: - server = PerfServer(args.server) + server = PerfServer(args.server, args.root) s.set_server(server) s.collect_tests() results = s.run()