diff --git a/CHANGES b/CHANGES index ebaf8b945..6ced7d569 100644 --- a/CHANGES +++ b/CHANGES @@ -40,6 +40,7 @@ Features: - Support for unlicensed Wisdom Tree Game Boy mapper - Qt: Add export button for tile view (closes mgba.io/i/1507) - Qt: Add recent game list clearing (closes mgba.io/i/1380) + - GB: Yanking gamepak now supported Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs @@ -58,6 +59,7 @@ Emulation fixes: - GB: Fix savedata initialization (fixes mgba.io/i/1473, mgba.io/i/1478) - GB Memory: Better emulate 0xFEA0 region on DMG, MGB and AGB - GB Printer: Reset printer buffer index after printing + - GB Video: Fix mode 0 window edge case (fixes mgba.io/i/1519) Other fixes: - Qt: Fix some Qt display driver race conditions - Core: Improved lockstep driver reliability (Le Hoang Quyen) @@ -75,7 +77,7 @@ Other fixes: - GBA Cheats: Fix value incrementing in CB slide codes (fixes mgba.io/i/1501) - Qt: Only show emulator restart warning once per settings saving - Qt: Improve cheat view UX - - GB: Fix SGB controller selection initialization (fixes mgba.io/i/1104) + - GB: Fix SGB controller incrementing (fixes mgba.io/i/1104) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/cinema/gb/window/zin-head/baseline_0000.png b/cinema/gb/window/zin-head/baseline_0000.png new file mode 100644 index 000000000..d3c2c0f9d Binary files /dev/null and b/cinema/gb/window/zin-head/baseline_0000.png differ diff --git a/cinema/gb/window/zin-head/baseline_0001.png b/cinema/gb/window/zin-head/baseline_0001.png new file mode 100644 index 000000000..5d583d227 Binary files /dev/null and b/cinema/gb/window/zin-head/baseline_0001.png differ diff --git a/cinema/gb/window/zin-head/baseline_0002.png b/cinema/gb/window/zin-head/baseline_0002.png new file mode 100644 index 000000000..5d583d227 Binary files /dev/null and b/cinema/gb/window/zin-head/baseline_0002.png differ diff --git a/cinema/gb/window/zin-head/baseline_0003.png b/cinema/gb/window/zin-head/baseline_0003.png new file mode 100644 index 000000000..5d583d227 Binary files /dev/null and b/cinema/gb/window/zin-head/baseline_0003.png differ diff --git a/cinema/gb/window/zin-head/baseline_0004.png b/cinema/gb/window/zin-head/baseline_0004.png new file mode 100644 index 000000000..5d583d227 Binary files /dev/null and b/cinema/gb/window/zin-head/baseline_0004.png differ diff --git a/cinema/gb/window/zin-head/baseline_0005.png b/cinema/gb/window/zin-head/baseline_0005.png new file mode 100644 index 000000000..d3c2c0f9d Binary files /dev/null and b/cinema/gb/window/zin-head/baseline_0005.png differ diff --git a/cinema/gb/window/zin-head/test.mvl b/cinema/gb/window/zin-head/test.mvl new file mode 100644 index 000000000..009337411 Binary files /dev/null and b/cinema/gb/window/zin-head/test.mvl differ diff --git a/include/mgba/internal/gb/gb.h b/include/mgba/internal/gb/gb.h index 22abf2080..cda0901f3 100644 --- a/include/mgba/internal/gb/gb.h +++ b/include/mgba/internal/gb/gb.h @@ -94,6 +94,7 @@ struct GB { bool isPristine; size_t pristineRomSize; size_t yankedRomSize; + enum GBMemoryBankControllerType yankedMbc; uint32_t romCrc32; struct VFile* romVf; struct VFile* biosVf; @@ -109,6 +110,7 @@ struct GB { uint8_t sgbPacket[16]; uint8_t sgbControllers; uint8_t sgbCurrentController; + bool sgbIncrement; struct mCoreCallbacksList coreCallbacks; struct mAVStream* stream; @@ -162,6 +164,7 @@ bool GBLoadROM(struct GB* gb, struct VFile* vf); bool GBLoadSave(struct GB* gb, struct VFile* vf); void GBUnloadROM(struct GB* gb); void GBSynthesizeROM(struct VFile* vf); +void GBYankROM(struct GB* gb); void GBLoadBIOS(struct GB* gb, struct VFile* vf); diff --git a/include/mgba/internal/gb/serialize.h b/include/mgba/internal/gb/serialize.h index 7b1feb93e..a7f321358 100644 --- a/include/mgba/internal/gb/serialize.h +++ b/include/mgba/internal/gb/serialize.h @@ -263,6 +263,7 @@ DECL_BITS(GBSerializedSGBFlags, RenderMode, 2, 2); DECL_BITS(GBSerializedSGBFlags, BufferIndex, 4, 3); DECL_BITS(GBSerializedSGBFlags, CurrentController, 7, 2); DECL_BITS(GBSerializedSGBFlags, ReqControllers, 9, 2); +DECL_BIT(GBSerializedSGBFlags, Increment, 11); #pragma pack(push, 1) struct GBSerializedState { diff --git a/src/gb/gb.c b/src/gb/gb.c index 4cff00c9a..0e065a0a2 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -127,6 +127,19 @@ bool GBLoadROM(struct GB* gb, struct VFile* vf) { return true; } +void GBYankROM(struct GB* gb) { + gb->yankedRomSize = gb->memory.romSize; + gb->yankedMbc = gb->memory.mbcType; + gb->memory.romSize = 0; + gb->memory.mbcType = GB_MBC_NONE; + gb->memory.sramAccess = false; + + if (gb->cpu) { + struct LR35902Core* cpu = gb->cpu; + cpu->memory.setActiveRegion(cpu, cpu->pc); + } +} + static void GBSramDeinit(struct GB* gb) { if (gb->sramVf) { gb->sramVf->unmap(gb->sramVf, gb->memory.sram, gb->sramSize); @@ -430,13 +443,15 @@ void GBReset(struct LR35902Core* cpu) { if (gb->yankedRomSize) { gb->memory.romSize = gb->yankedRomSize; + gb->memory.mbcType = gb->yankedMbc; gb->yankedRomSize = 0; } gb->sgbBit = -1; gb->sgbControllers = 0; - gb->sgbCurrentController = 3; + gb->sgbCurrentController = 0; gb->currentSgbBits = 0; + gb->sgbIncrement = false; memset(gb->sgbPacket, 0, sizeof(gb->sgbPacket)); mTimingClear(&gb->timing); diff --git a/src/gb/io.c b/src/gb/io.c index f75e5b83b..155c2c624 100644 --- a/src/gb/io.c +++ b/src/gb/io.c @@ -115,23 +115,21 @@ static void _writeSGBBits(struct GB* gb, int bits) { if (bits == gb->currentSgbBits) { return; } - gb->currentSgbBits = bits; - if (gb->sgbBit > 128) { - switch (bits) { - case 1: - gb->sgbBit |= 2; - break; - case 2: - gb->sgbBit |= 4; - break; - case 3: - if (gb->sgbBit == 135) { - gb->sgbBit &= ~6; - gb->sgbCurrentController = (gb->sgbCurrentController + 1) & gb->sgbControllers; - } - break; + switch (bits) { + case 0: + case 1: + if (gb->currentSgbBits & 2) { + gb->sgbIncrement = !gb->sgbIncrement; } + break; + case 3: + if (gb->sgbIncrement) { + gb->sgbIncrement = false; + gb->sgbCurrentController = (gb->sgbCurrentController + 1) & gb->sgbControllers; + } + break; } + gb->currentSgbBits = bits; if (gb->sgbBit == 128 && bits == 2) { GBVideoWriteSGBPacket(&gb->video, gb->sgbPacket); ++gb->sgbBit; @@ -460,6 +458,9 @@ void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) { value = gb->video.stat; break; case 0x50: + if (gb->memory.io[0x50] != 0xFF) { + break; + } GBUnmapBIOS(gb); if (gb->model >= GB_MODEL_CGB && gb->memory.io[REG_UNK4C] < 0x80) { gb->model = GB_MODEL_DMG; @@ -535,13 +536,13 @@ void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) { static uint8_t _readKeys(struct GB* gb) { uint8_t keys = *gb->keySource; - if (gb->sgbCurrentController & gb->sgbControllers) { + if (gb->sgbCurrentController != 0) { keys = 0; } uint8_t joyp = gb->memory.io[REG_JOYP]; switch (joyp & 0x30) { case 0x30: - keys = gb->sgbCurrentController & gb->sgbControllers; + keys = gb->sgbCurrentController; break; case 0x20: keys >>= 4; diff --git a/src/gb/memory.c b/src/gb/memory.c index b3b9b8bcf..e5817cefe 100644 --- a/src/gb/memory.c +++ b/src/gb/memory.c @@ -16,6 +16,8 @@ mLOG_DEFINE_CATEGORY(GB_MEM, "GB Memory", "gb.memory"); +static const uint8_t _yankBuffer[] = { 0xFF }; + enum GBBus { GB_BUS_CPU, GB_BUS_MAIN, @@ -69,6 +71,14 @@ static void GBSetActiveRegion(struct LR35902Core* cpu, uint16_t address) { cpu->memory.activeRegion = memory->romBase; cpu->memory.activeRegionEnd = GB_BASE_CART_BANK1; cpu->memory.activeMask = GB_SIZE_CART_BANK0 - 1; + if (gb->memory.romSize < GB_SIZE_CART_BANK0) { + if (address >= gb->memory.romSize) { + cpu->memory.activeRegion = _yankBuffer; + cpu->memory.activeMask = 0; + } else { + cpu->memory.activeRegionEnd = gb->memory.romSize; + } + } break; case GB_REGION_CART_BANK1: case GB_REGION_CART_BANK1 + 1: @@ -89,6 +99,14 @@ static void GBSetActiveRegion(struct LR35902Core* cpu, uint16_t address) { cpu->memory.activeRegionEnd = GB_BASE_CART_BANK1 + 0x2000; } } + if (gb->memory.romSize < GB_SIZE_CART_BANK0 * 2) { + if (address >= gb->memory.romSize) { + cpu->memory.activeRegion = _yankBuffer; + cpu->memory.activeMask = 0; + } else { + cpu->memory.activeRegionEnd = gb->memory.romSize; + } + } break; default: cpu->memory.cpuLoad8 = GBLoad8; @@ -243,6 +261,9 @@ uint8_t GBLoad8(struct LR35902Core* cpu, uint16_t address) { case GB_REGION_CART_BANK0 + 1: case GB_REGION_CART_BANK0 + 2: case GB_REGION_CART_BANK0 + 3: + if (address >= memory->romSize) { + return 0xFF; + } return memory->romBase[address & (GB_SIZE_CART_BANK0 - 1)]; case GB_REGION_CART_BANK1 + 2: case GB_REGION_CART_BANK1 + 3: @@ -252,6 +273,9 @@ uint8_t GBLoad8(struct LR35902Core* cpu, uint16_t address) { // Fall through case GB_REGION_CART_BANK1: case GB_REGION_CART_BANK1 + 1: + if (address >= memory->romSize) { + return 0xFF; + } return memory->romBank[address & (GB_SIZE_CART_BANK0 - 1)]; case GB_REGION_VRAM: case GB_REGION_VRAM + 1: diff --git a/src/gb/renderers/software.c b/src/gb/renderers/software.c index 93b2d3085..c0e5c2367 100644 --- a/src/gb/renderers/software.c +++ b/src/gb/renderers/software.c @@ -224,6 +224,9 @@ static void GBVideoSoftwareRendererUpdateWindow(struct GBVideoSoftwareRenderer* if (renderer->lastY >= GB_VIDEO_VERTICAL_PIXELS || !(after || before)) { return; } + if (!renderer->hasWindow && renderer->lastX == GB_VIDEO_HORIZONTAL_PIXELS) { + return; + } if (renderer->lastY >= oldWy) { if (!after) { renderer->currentWy -= renderer->lastY; diff --git a/src/gb/serialize.c b/src/gb/serialize.c index 78d455300..78614feb5 100644 --- a/src/gb/serialize.c +++ b/src/gb/serialize.c @@ -225,6 +225,7 @@ void GBSGBSerialize(struct GB* gb, struct GBSerializedState* state) { flags = GBSerializedSGBFlagsSetRenderMode(flags, gb->video.renderer->sgbRenderMode); flags = GBSerializedSGBFlagsSetBufferIndex(flags, gb->video.sgbBufferIndex); flags = GBSerializedSGBFlagsSetReqControllers(flags, gb->sgbControllers); + flags = GBSerializedSGBFlagsSetIncrement(flags, gb->sgbIncrement); flags = GBSerializedSGBFlagsSetCurrentController(flags, gb->sgbCurrentController); STORE_32LE(flags, 0, &state->sgb.flags); @@ -260,6 +261,12 @@ void GBSGBDeserialize(struct GB* gb, const struct GBSerializedState* state) { gb->video.sgbBufferIndex = GBSerializedSGBFlagsGetBufferIndex(flags); gb->sgbControllers = GBSerializedSGBFlagsGetReqControllers(flags); gb->sgbCurrentController = GBSerializedSGBFlagsGetCurrentController(flags); + gb->sgbIncrement = GBSerializedSGBFlagsGetIncrement(flags); + + // Old versions of mGBA stored the increment bits here + if (gb->sgbBit > 129 && gb->sgbBit & 2) { + gb->sgbIncrement = true; + } memcpy(gb->video.sgbPacketBuffer, state->sgb.packet, sizeof(state->sgb.packet)); memcpy(gb->sgbPacket, state->sgb.inProgressPacket, sizeof(state->sgb.inProgressPacket)); diff --git a/src/gb/video.c b/src/gb/video.c index 329174e02..43a9d7637 100644 --- a/src/gb/video.c +++ b/src/gb/video.c @@ -701,6 +701,9 @@ void GBVideoWriteSGBPacket(struct GBVideo* video, uint8_t* data) { case SGB_ATTR_SET: break; case SGB_MLT_REQ: + if ((video->sgbPacketBuffer[1] & 0x3) == 2) { // XXX: This unmasked increment appears to be an SGB hardware bug + ++video->p->sgbCurrentController; + } video->p->sgbControllers = video->sgbPacketBuffer[1] & 0x3; video->p->sgbCurrentController &= video->p->sgbControllers; return; diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 9ce687831..e5aaa2c7b 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -633,13 +633,16 @@ void CoreController::replaceGame(const QString& path) { } void CoreController::yankPak() { -#ifdef M_CORE_GBA - if (platform() != PLATFORM_GBA) { - return; - } Interrupter interrupter(this); - GBAYankROM(static_cast(m_threadContext.core->board)); -#endif + + switch (platform()) { + case PLATFORM_GBA: + GBAYankROM(static_cast(m_threadContext.core->board)); + break; + case PLATFORM_GB: + GBYankROM(static_cast(m_threadContext.core->board)); + break; + } } #ifdef USE_PNG diff --git a/src/platform/qt/ts/medusa-emu-de.ts b/src/platform/qt/ts/medusa-emu-de.ts index 77c75e62e..7d1b59723 100644 --- a/src/platform/qt/ts/medusa-emu-de.ts +++ b/src/platform/qt/ts/medusa-emu-de.ts @@ -1352,12 +1352,12 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.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 @@ -3801,222 +3801,222 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.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... @@ -4051,57 +4051,57 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Über... - + %1× %1x - + Bilinear filtering Bilineare Filterung - + Native (59.7275) Nativ (59.7275) - + Record A/V... Audio/Video 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... @@ -4111,87 +4111,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 @@ -4639,11 +4639,6 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.High-resolution scale: Hochauflösende Skalierung: - - - {size} - {size} - XQ GBA audio (experimental) @@ -4915,6 +4910,11 @@ wenn vorhanden Autofire interval: Autofeuer-Intervall: + + + (240×160) + (240×160) + GB BIOS file: diff --git a/src/platform/qt/ts/mgba-zh_CN.ts b/src/platform/qt/ts/mgba-zh_CN.ts index faafd280a..f1979889f 100644 --- a/src/platform/qt/ts/mgba-zh_CN.ts +++ b/src/platform/qt/ts/mgba-zh_CN.ts @@ -26,13 +26,13 @@ {projectName} would like to thank the following patrons from Patreon: - {projectName} 感谢以下来自Patreon平台的赞助者: + {projectName} 感谢以下来自 Patreon 平台的赞助者: - © 2013 – 2018 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 + © 2013 – 2019 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,基于Mozilla公共许可证(版本 2.0)授权 + © 2013 – 2019 Jeffrey Pfau,基于 Mozilla 公共许可证(版本 2.0)授权 Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标。 @@ -48,7 +48,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 {projectName} is an open-source Game Boy Advance emulator - {projectName}是开放源代码的Game Boy Advance模拟器 + {projectName} 是开放源代码的 Game Boy Advance 模拟器 @@ -79,7 +79,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 Tile # - 标题 # + 瓷贴 # @@ -105,17 +105,17 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 Red - 红色 + Green - 绿色 + 绿 Blue - 蓝色 + @@ -226,15 +226,20 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 载入 - + Add New Set - 新建 + 添加新集 - + Add 添加 + + + Enter codes here... + 在此处输入代码... + DebuggerConsole @@ -246,7 +251,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 Enter command (try `help` for more info) - 输入命令(尝试输入 `help` 以获取更多信息) + 输入命令(尝试输入 `help` 获取更多信息) @@ -254,6 +259,49 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 断点 + + FrameView + + + Inspect frame + 检查框架 + + + + × + × + + + + Magnification + 缩放率 + + + + Freeze frame + 冻结框架 + + + + Backdrop color + 背幕颜色 + + + + Disable scanline effects + 禁用扫描线效果 + + + + Export + 导出 + + + + Reset + 重置 + + GIFView @@ -417,13 +465,13 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 LoadSaveState - + %1 State %1 即时存档 - + @@ -436,18 +484,18 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 - 1 - 1 + 5 + 5 - - 2 - 2 + + 6 + 6 - 3 - 3 + 8 + 8 @@ -456,13 +504,13 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 - 5 - 5 + 1 + 1 - 6 - 6 + 3 + 3 @@ -471,13 +519,18 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 - 8 - 8 + 9 + 9 - 9 - 9 + 2 + 2 + + + + Cancel + 取消 @@ -546,19 +599,19 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 贴图 - + + Export + 导出 + + + × × - + Magnification - 放大率 - - - - Export - 导出 + 缩放率 @@ -795,7 +848,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 Transform - 转换 + 变换 @@ -871,7 +924,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 Tile - 贴图 + 瓷贴 @@ -891,7 +944,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 Dimensions - 方向 + 维度 @@ -943,7 +996,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 Tilt - 图块 + 瓷贴 @@ -1231,14 +1284,14 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 QGBA::AssetTile - + %0%1%2 %0%1%2 - - - + + + 0x%0 (%1) 0x%0 (%1) @@ -1277,6 +1330,35 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 无法在无输入的情况下启动音频处理器 + + QGBA::BattleChipView + + + BattleChip data missing + BattleChip 数据已丢失 + + + + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? + BattleChip 数据已丢失。您仍然可以使用 BattleChip Gate,但部分图形会丢失。您想立即下载数据吗? + + + + + Select deck file + 选择卡组文件 + + + + Incompatible deck + 不兼容的卡组 + + + + The selected deck is not compatible with this Chip Gate + 所选卡组与本 Chip Gate 不兼容 + + QGBA::CheatsModel @@ -1311,7 +1393,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 Add GameGenie - 添加 Game Génie + 添加 GameGenie @@ -1323,22 +1405,22 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 QGBA::CoreController - + Failed to open save file: %1 无法打开存档: %1 - + Failed to open game file: %1 无法打开游戏文件: %1 - + Failed to open snapshot file for reading: %1 无法读取快照文件: %1 - + Failed to open snapshot file for writing: %1 无法写入快照文件: %1 @@ -1351,6 +1433,49 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 无法打开游戏文件: %1 + + QGBA::FrameView + + + Export frame + 导出框架 + + + + Portable Network Graphics (*.png) + 便携式网络图形 (*.png) + + + + None + + + + + Background + 背景 + + + + Window + 窗口 + + + + Sprite + 精灵图 + + + + Backdrop + 背幕 + + + + %1 %2 + %1 %2 + + QGBA::GBAApp @@ -1453,32 +1578,32 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 Mode 0: 4 tile layers - 模式0: 4个图块层 + 模式0: 4 个瓷贴层 Mode 1: 2 tile layers + 1 rotated/scaled tile layer - 模式 1: 2个图块层 + 1个已旋转/缩放图块层 + 模式 1: 2 个瓷贴层 + 1 个已旋转/缩放瓷贴层 Mode 2: 2 rotated/scaled tile layers - 模式 2: 2个已旋转/缩放图块层 + 模式 2: 2 个已旋转或缩放瓷贴层 Mode 3: Full 15-bit bitmap - 模式 3: 完整15位位图 + 模式 3: 完整 15 位位图 Mode 4: Full 8-bit bitmap - 模式 4: 完整8位位图 + 模式 4: 完整 8 位位图 Mode 5: Small 15-bit bitmap - 模式 5: 15位小位图 + 模式 5: 15 位小位图 @@ -1498,7 +1623,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 Linear OBJ tile mapping - 线性 OBJ 图块映射 + 线性 OBJ 瓷贴映射 @@ -1599,7 +1724,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 Tile data base (* 16kB) - 图块数据基 (* 16kB) + 瓷贴数据基 (* 16kB) @@ -1623,7 +1748,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 Tile map base (* 2kB) - 图块映射基 (* 2kB) + 瓷贴映射基 (* 2kB) @@ -1891,7 +2016,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 Backdrop target 1 - 背景目标 1 + 背幕目标 1 @@ -1946,7 +2071,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 Backdrop target 2 - 背景目标 2 + 背幕目标 2 @@ -2823,27 +2948,27 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 QGBA::LoadSaveState - + Load State 载入即时存档 - + Save State 即时存档 - + Empty - + Corrupted 已损坏 - + Slot %1 插槽 %1 @@ -2900,37 +3025,42 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 [%1] %2: %3 - + + An error occurred + 发生错误 + + + DEBUG DEBUG - + STUB STUB - + INFO INFO - + WARN WARN - + ERROR ERROR - + FATAL FATAL - + GAME ERROR GAME ERROR @@ -2938,47 +3068,80 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 QGBA::MapView - + + Priority + 优先级 + + + + + Map base + 映射基 + + + + + Tile base + 瓷贴基 + + + + Size + 大小 + + + + + offset + 偏移 + + + + Xform + 变换 + + + Map Addr. 映射地址 - + Mirror 镜像 - + None - + Both 两者 - + Horizontal 水平 - + Vertical 垂直 - + Export map 导出映射 - + Portable Network Graphics (*.png) 便携式网络图形 (*.png) - + Failed to open output PNG file: %1 打开输出 PNG 文件失败: %1 @@ -3015,6 +3178,13 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 Load TBL 载入 TBL + + + + + N/A + + Save selected memory @@ -3072,57 +3242,52 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 QGBA::ObjView - - + + 0x%0 0x%0 - + Off - + Normal 一般 - + Trans - Trans + 变换 - + OBJWIN OBJWIN - + Invalid 无效 - - + + N/A - + Export sprite 导出精灵图 - + Portable Network Graphics (*.png) 便携式网络图形 (*.png) - - - Failed to open output PNG file: %1 - 无法打开输出的 PNG 文件: %1 - QGBA::PaletteView @@ -3156,7 +3321,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 Windows PAL (*.pal);;Adobe Color Table (*.act) - Windows PAL (*.pal);;Adobe 颜色表 (*.act) + Windows 调色板 (*.pal);;Adobe 颜色表 (*.act) @@ -3203,62 +3368,67 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 QGBA::SettingsView - - + + Qt Multimedia Qt Multimedia - + SDL SDL - + Software (Qt) 软件渲染 (Qt) - + OpenGL OpenGL - + OpenGL (force version 1.x) OpenGL (强制版本 1.x) - + None (Still Image) 无 (静止图像) - + Keyboard 键盘 - + Controllers 控制器 - + Shortcuts 快捷键 - - + + Shaders 着色器 - + Select BIOS 选择 BIOS + + + (%1×%2) + (%1×%2) + QGBA::ShaderSelector @@ -3275,7 +3445,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 No shader loaded - 未载入任何着色器 + 未载入着色器 @@ -3296,27 +3466,40 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 QGBA::ShortcutController - + Action 动作 - + Keyboard 键盘 - + Gamepad 游戏手柄 + + QGBA::TileView + + + Export tiles + 导出文件 + + + + Portable Network Graphics (*.png) + 便携式网络图形 (*.png) + + QGBA::VideoView Failed to open output video file: %1 - 无法打开输出的视频文件: %1 + 无法打开输出视频文件: %1 @@ -3332,108 +3515,108 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 QGBA::Window - + Game Boy Advance ROMs (%1) Game Boy Advance ROM (%1) - + Game Boy ROMs (%1) Game Boy ROM (%1) - + All ROMs (%1) 所有 ROM (%1) - + %1 Video Logs (*.mvl) %1 视频日志 (*.mvl) - + Archives (%1) 压缩文件 (%1) - - - + + + Select ROM 选择 ROM - + Select folder 选择文件夹 - + Game Boy Advance save files (%1) Game Boy Advance 存档文件 (%1) - - - + + + Select save 选择存档 - + mGBA savestate files (%1) mGBA 即时存档文件 (%1) - - + + Select savestate 选择即时存档 - + Select patch 选择补丁 - + Patches (*.ips *.ups *.bps) 补丁文件 (*.ips *.ups *.bps) - + Select image 选择图片 - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) 图像文件 (*.png *.gif *.jpg *.jpeg);;所有文件 (*) - - + + GameShark saves (*.sps *.xps) GameShark 存档 (*.sps *.xps) - + Select video log 选择视频日志 - + Video logs (*.mvl) - 视频日志 (*.mvl) + 视频日志文件 (*.mvl) - + Crash 崩溃 - + The game has crashed with the following error: %1 @@ -3442,218 +3625,188 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 %1 - + Couldn't Load 无法载入 - + Could not load game. Are you sure it's in the correct format? - 无法载入游戏。请确认游戏格式是否无误 + 无法载入游戏。请确认游戏格式是否无误。 - + Unimplemented BIOS call 未实现的 BIOS 调用 - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. 该游戏使用了尚未实现的 BIOS 调用。请使用官方 BIOS 以获得最佳游戏体验。 - + 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 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 fps) - %4 - + &File 文件(&F) - + Load &ROM... 载入 ROM(&R)... - + Load ROM in archive... 从压缩文件中载入 ROM... - + Add folder to library... 将文件夹添加到库中... - + Load alternate save... 读取其他的存档... - + Load temporary save... 读取临时存档... - + Load &patch... 载入补丁文件(&P)... - + Boot BIOS 引导 BIOS - + Replace ROM... 替换 ROM... - + ROM &info... ROM 信息(&I)... - + Recent - 最近打开的游戏 + 最近打开 - + Make portable 程序便携化 - + &Load state 读取即时存档(&L) - - F10 - F10 - - - + Load state file... 载入即时存档文件... - + &Save state 保存即时存档(&S) - - Shift+F10 - Shift+F10 - - - + Save state file... 保存即时存档文件... - + Quick load 快速读档 - + Quick save 快速存档 - + Load recent - 载入最近的即时存档 + 载入最近 - + Save recent - 保存最近的即时存档 + 保存最近 - + Undo load state 撤消读档 - - F11 - F11 - - - + Undo save state 撤消存档 - - Shift+F11 - Shift+F11 - - - - + + State &%1 即时存档 1(&1) - - F%1 - F%1 - - - - Shift+F%1 - Shift+F%1 - - - + Load camera image... 读取相机图片... - + Import GameShark Save 导入 GameShark 存档 @@ -3663,410 +3816,390 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 导出 GameShark 存档 - + New multiplayer window 新建多人游戏窗口 - + About... 关于... - + E&xit 退出(&X) - + &Emulation 模拟(&E) - + &Reset 复位(&R) - - Ctrl+R - Ctrl+R - - - + Sh&utdown 关机(&U) - + Yank game pak 快速抽出游戏卡带 - + &Pause 暂停(&P) - - Ctrl+P - Ctrl+P - - - + &Next frame 下一帧(&N) - - Ctrl+N - Ctrl+N - - - + Fast forward (held) 快进 (长按) - + &Fast forward 快进(&F) - - Shift+Tab - Shift+Tab - - - + Fast forward speed 快进速度 - + Unbounded 不限制 - + %0x %0x - + Rewind (held) 回退 (长按) - + Re&wind 回退(&W) - - ~ - ~ - - - + Step backwards 后退 - - Ctrl+B - Ctrl+B - - - + Sync to &video 视频同步(&V) - + Sync to &audio 音频同步(&A) - + Solar sensor 光线传感器 - + Increase solar level 增加光线级别 - + Decrease solar level 降低光线级别 - + Brightest solar level 光线级别为最亮 - + Darkest solar level 光线级别为最暗 - + Brightness %1 亮度 %1 - + Game Boy Printer... Game Boy 打印机.. - + BattleChip Gate... BattleChip Gate... - + Audio/&Video 音频/视频(&V) - + Frame size 帧率 - - %1x - %1x + + %1× + %1× - + Toggle fullscreen 切换全屏 - + Lock aspect ratio 锁定纵横比 - + Force integer scaling 强制整数缩放 - + + Interframe blending + 帧间混合 + + + Bilinear filtering 双线性过滤 - + Frame&skip 跳帧(&S) - + Mute 静音 - + FPS target 目标 FPS - + Native (59.7275) 原生 (59.7275) - + Take &screenshot 截图(&S) - - F12 - F12 + + Record A/V... + 录制音频/视频... - - Record output... - 录制导出... - - - + Record GIF... 录制 GIF... - - Record video log... - 记录视频日志... - - - - Stop video log - 停止记录视频日志 - - - + Video layers 视频图层 - + Audio channels 音频通道 - + Adjust layer placement... 调整图层布局 - + &Tools 工具(&T) - + View &logs... 查看日志(&L)... - + Game &overrides... 覆盖游戏(&O)... - + Game &Pak sensors... 游戏卡带传感器(&P)... - + &Cheats... 作弊码(&C)... - + Settings... 设置... - + Open debugger console... 打开调试器控制台... - + Start &GDB server... 打开 GDB 服务器(&G)... - + View &palette... 查看调色板(&P)... - + View &sprites... 查看精灵图(&S) - + View &tiles... - 查看图块(&T) + 查看瓷贴(&T) - + View &map... 查看映射(&M) - + + Frame inspector + 框架检查 + + + View memory... 查看内存... - + Search memory... 搜索内存... - + View &I/O registers... 查看 I/O 寄存器(&I)... - + + Record video log... + 记录视频日志... + + + + Stop video log + 停止记录视频日志 + + + Exit fullscreen 退出全屏 - + GameShark Button (held) GameShark 键 (长按) - + Autofire 连发 - + Autofire A 连发 A - + Autofire B 连发 B - + Autofire L 连发 L - + Autofire R 连发 R - + Autofire Start 连发 Start - + Autofire Select 连发 Select - + Autofire Up 连发 上 - + Autofire Right 连发 右 - + Autofire Down 连发 下 - + Autofire Left 连发 左 + + + Clear + 清除 + QObject @@ -4267,12 +4400,12 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 Game Boy - + Audio driver: 音频驱动: - + Audio buffer: 音频缓冲: @@ -4381,7 +4514,7 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 - + frames @@ -4426,373 +4559,395 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 双线性过滤 - + + Native (59.7275) + 原生 (59.7275) + + + + Interframe blending + 帧间混合 + + + Language 语言 - + English 英语 - + Library: 库: - + List view 列表查看 - + Tree view 树状查看 - + Show when no game open 未打开游戏时显示 - + Clear cache 清除缓存 - + Allow opposing input directions 允许逆向输入 - + Suspend screensaver 停用屏幕保护程序 - + Pause when inactive 非活动时暂停 - + Show FPS in title bar 在标题栏显示 FPS - + Automatically save cheats 自动保存作弊码 - + Automatically load cheats 自动载入作弊码 - + Automatically save state 自动存档 - + Automatically load state 自动读档 - + Enable Discord Rich Presence 启用 Enable Discord Rich Presence - + 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 将整个 ROM 预加载到内存中 - + Savestate extra data: 即时存档额外数据: - - + + Screenshot 截图 - - + + Save data 保存数据 - - + + Cheat codes 作弊码 - + Load extra data: 载入额外数据: - + Video renderer: 视频渲染器: - + Software 软件 - + OpenGL OpenGL - + OpenGL enhancements OpenGL 增强 - + High-resolution scale: 高分辨率比例: - + + (240×160) + (240×160) + + + XQ GBA audio (experimental) XQ GBA 音频 (实验) - - - - - - - - - - Browse - 浏览 - - - + GB BIOS file: GB BIOS 文件: - + + + + + + + + + + Browse + 浏览 + + + Use BIOS file if found 当可用时使用 BIOS 文件 - + Skip BIOS intro 跳过 BIOS 启动画面 - + GBA BIOS file: GBA BIOS 文件: - + GBC BIOS file: GBC BIOS 文件: - + SGB BIOS file: SGB BIOS 文件: - + Save games 游戏存档 - - - - - + + + + + Same directory as the ROM 保存在 ROM 所在目录 - + Save states 即时存档 - + Screenshots 截图 - + Patches 补丁 - + Cheats 作弊码 - + Log to file 记录日志到文件 - + Log to console 记录日志到控制台 - + Select Log File 选择日志文件 - + Game Boy model: Game Boy 模型: - - - + + + Autodetect 自动检测 - - - + + + 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: Super Game Boy 模型: - + Game Boy Color model: Game Boy Color 模型: - + Default BG colors: 默认背景颜色: - + Super Game Boy borders Super Game Boy 边框 - + Camera driver: 相机驱动: - + Default sprite colors 1: 默认精灵图颜色 1: - + Default sprite colors 2: 默认精灵图颜色 2: - + Use GBC colors in GB games 在 GB 游戏中使用 GBC 颜色 - + Camera: 相机 @@ -4863,33 +5018,38 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 Tiles - 图块 + 瓷贴 - + 256 colors 256 色 - + × × - + Magnification 缩放率 - + Tiles per row - 每行图块 + 每行瓷贴 - + Fit to window 自适应窗口 + + + Export + 导出 + VideoView @@ -4969,6 +5129,11 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 MKV MKV + + + WebM + WebM + AVI