Compare commits

...

34 Commits

Author SHA1 Message Date
Vicki Pfau e932068baa CHANGES: Update for 0.9.1 2021-04-18 21:47:22 -07:00
Vicki Pfau 973f6b819e Res: Update nointro.dat 2021-04-18 21:46:55 -07:00
Vicki Pfau 62309ca5c5 Res: Update patrons for April 2021-04-18 21:26:50 -07:00
Vicki Pfau 53b8fdf856 Qt: Restore maximized state when starting (fixes #487) 2021-04-18 18:46:28 -07:00
Vicki Pfau 679f36d7c0 Qt: Improve handling of disabling VBA bug compat mode (fixes #2129) 2021-04-18 18:46:27 -07:00
Vicki Pfau 56b0f95e6f Qt: Parse --version flag 2021-04-18 18:46:04 -07:00
Vicki Pfau 338e4ec7a9 ARM: Fix LDM^ with empty rlist (fixes #2127) 2021-04-18 18:45:27 -07:00
Vicki Pfau fdbb442bad Qt: Fix frames getting backlogged (fixes #2122) 2021-04-18 18:45:27 -07:00
Vicki Pfau fcdf6c53eb Qt: Fix saving settings enabling camera when camera name changes (fixes #2125) 2021-04-18 18:45:27 -07:00
Vicki Pfau 094fe8fec0 Libretro: Add missing rotation peripheral 2021-04-18 18:44:55 -07:00
Vicki Pfau bd87563aa0 Libretro: Fix GB SRAM in memory map 2021-04-18 18:44:55 -07:00
Vicki Pfau b8f410c0bd GB: Fix skipping BIOS 2021-04-18 18:44:55 -07:00
Vicki Pfau c9cbf185c1 Qt: Fix smudged window icon on Windows, recompress icons 2021-04-12 22:17:29 -07:00
Vicki Pfau a782e8b500 Qt: Fix OpenGL renderer lagging behind when fast-forwarding (fixes #2094) 2021-04-12 22:17:29 -07:00
Vicki Pfau ce080027a4 Qt: Remove no-longer used dependency 2021-04-12 22:17:29 -07:00
Vicki Pfau 043b37c51d Qt: Fix crash when switching from high-resolution OpenGL renderer to software 2021-04-12 22:17:29 -07:00
Vicki Pfau f04311a22a GBA Memory: Remove unused variable 2021-04-12 22:17:29 -07:00
Vicki Pfau 89928b86ac GBA Memory: Log GPIO writes on non-GPIO carts as Pak Hardware instead of Memory 2021-04-12 22:17:29 -07:00
Vicki Pfau 91cfbbf676 GBA Video: Fix mode 3-5 overflow with mosaic (fixes #1691) 2021-04-12 22:16:40 -07:00
Vicki Pfau 3c25e66769 GBA Video: Fix window start on modes 2-5 with mosaic (fixes #1690) 2021-04-12 22:16:40 -07:00
Vicki Pfau 2029f7fc86 GBA SIO: Silence initial mode switch 2021-04-12 22:16:40 -07:00
Vicki Pfau 3d54fb6d02 GBA Video: Don't attempt to copy invalid registers when switching renderer 2021-04-12 22:16:40 -07:00
Vicki Pfau 86a57ed51f Core: Truncate preloading ROMs that slightly exceed max size (fixes #2093) 2021-04-12 22:16:40 -07:00
Vicki Pfau 997e462a4f GBA e-Reader: Fix bitmap short strip scanning 2021-04-12 22:16:40 -07:00
Vicki Pfau 7740295a6c GBA Video: Fix mode 5 frame 1 caching (fixes #2075) 2021-04-12 22:15:59 -07:00
Vicki Pfau 02b814d3bb GBA: Default-enable VBA bug compat for Ruby and Emerald ROM hacks 2021-04-12 22:15:59 -07:00
Vicki Pfau fefe47d7dd GBA: Fix non-USA 1.0 FireRed misdetecting as a ROM hack (fixes #2100) 2021-04-12 22:15:59 -07:00
Vicki Pfau 927b70e6fd GB Serialize: Fix switching speed modes when loading a state (fixes #2097) 2021-04-12 22:15:59 -07:00
Vicki Pfau fee8255611 GBA: Fix crash when ROM loading fails 2021-04-12 22:15:23 -07:00
Vicki Pfau b6025e4108 Qt: Add ROM filename and size to bug reporter 2021-04-12 22:15:07 -07:00
Vicki Pfau 4c0294d7ff GBA: Fix FireRed revision misdetecting as a ROM hack 2021-04-12 22:14:59 -07:00
Vicki Pfau c4aa0717b7 Core: Fix first event scheduling after loading savestate 2021-04-12 22:14:24 -07:00
Vicki Pfau a325deb65e GBA Memory: Fix loading Thumb savestates when in ARM mode 2021-04-12 22:14:08 -07:00
Vicki Pfau f75e18137f CMake: Bump version 2021-03-28 18:32:41 -07:00
42 changed files with 383 additions and 125 deletions

28
CHANGES
View File

@ -1,3 +1,31 @@
0.9.1: (2021-04-18)
Emulation fixes:
- ARM: Fix LDM^ with empty rlist (fixes mgba.io/i/2127)
- Core: Fix first event scheduling after loading savestate
- GB Serialize: Fix switching speed modes when loading a state (fixes mgba.io/i/2097)
- GB: Fix skipping BIOS
- GBA Memory: Fix loading Thumb savestates when in ARM mode
- GBA Video: Fix window start on modes 3-5 with mosaic (fixes mgba.io/i/1690)
- GBA Video: Fix mode 3-5 overflow with mosaic (fixes mgba.io/i/1691)
Other fixes:
- GBA: Fix non-USA 1.0 FireRed misdetecting as a ROM hack (fixes mgba.io/i/2100)
- GBA: Fix crash when ROM loading fails
- GBA e-Reader: Fix bitmap short strip scanning
- GBA Video: Fix mode 5 frame 1 caching (fixes mgba.io/i/2075)
- GBA Video: Don't attempt to copy invalid registers when switching renderer
- Qt: Fix crash when switching from high-resolution OpenGL renderer to software
- Qt: Fix OpenGL renderer lagging behind when fast-forwarding (fixes mgba.io/i/2094)
- Qt: Fix smudged window icon on Windows
- Qt: Fix saving settings enabling camera when camera name changes (fixes mgba.io/i/2125)
- Qt: Fix frames getting backlogged (fixes mgba.io/i/2122)
- Qt: Restore maximized state when starting (fixes mgba.io/i/487)
Misc:
- Core: Truncate preloading ROMs that slightly exceed max size (fixes mgba.io/i/2093)
- GBA: Default-enable VBA bug compat for Ruby and Emerald ROM hacks
- GBA Memory: Log GPIO writes on non-GPIO carts as Pak Hardware instead of Memory
- Qt: Add ROM filename and size to bug reporter
- Qt: Improve handling of disabling VBA bug compat mode (fixes mgba.io/i/2129)
0.9.0: (2021-03-28)
Features:
- e-Reader card scanning

Binary file not shown.

Before

Width:  |  Height:  |  Size: 465 KiB

After

Width:  |  Height:  |  Size: 460 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -1,7 +1,7 @@
clrmamepro (
name "Nintendo - Game Boy Advance"
description "Nintendo - Game Boy Advance"
version 20210326-211504
version 20210415-050230
author "aci68, Aringon, Bent, BigFred, C. V. Reynolds, chillerecke, DeadSkullzJr, Densetsu, DeriLoko3, einstein95, ElBarto, Enker, fuzzball, Gefflon, Hiccup, hking0036, hydr0x, InternalLoss, Jack, jimmsu, kazumi213, Money_114, niemand, omonim2007, Powerpuff, PPLToast, relax, RetroGamer, Rifu, SonGoku, Tauwasser, Vallaine01, Whovian9369, xuom2, zg"
homepage No-Intro
url "http://www.no-intro.org"
@ -11842,7 +11842,7 @@ game (
game (
name "Mother 3 (Japan) (Virtual Console)"
description "Mother 3 (Japan) (Virtual Console)"
rom ( name "Mother 3 (Japan) (Virtual Console).gba" size 33554432 crc c704a567 sha1 A9FB9C36DF3B0FB24B266826F5853C56122F9D36 )
rom ( name "Mother 3 (Japan) (Virtual Console).gba" size 33554432 crc c704a567 sha1 A9FB9C36DF3B0FB24B266826F5853C56122F9D36 flags verified )
)
game (
@ -13450,7 +13450,7 @@ game (
game (
name "Pokemon - Version Rouge Feu (France)"
description "Pokemon - Version Rouge Feu (France)"
rom ( name "Pokemon - Version Rouge Feu (France).gba" size 16777216 crc 5dc668f6 sha1 FC663907256F06A3A09E2D6B967BC9AF4919F111 )
rom ( name "Pokemon - Version Rouge Feu (France).gba" size 16777216 crc 5dc668f6 sha1 FC663907256F06A3A09E2D6B967BC9AF4919F111 flags verified )
)
game (
@ -19951,8 +19951,8 @@ game (
clrmamepro (
name "Nintendo - Game Boy"
description "Nintendo - Game Boy"
version 20210311-081758
author "aci68, akubi, Aringon, Bent, BigFred, BitLooter, C. V. Reynolds, chillerecke, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, ElBarto, foxe, fuzzball, Gefflon, Hiccup, hking0036, jimmsu, kazumi213, leekindo, Money_114, NGEfreak, omonim2007, Powerpuff, PPLToast, relax, RetroUprising, rpg2813, SonGoku, Tauwasser, xNo, xuom2"
version 20210412-150119
author "aci68, akubi, Aringon, Bent, BigFred, BitLooter, C. V. Reynolds, chillerecke, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, ElBarto, foxe, fuzzball, Gefflon, Hiccup, hking0036, InternalLoss, jimmsu, kazumi213, leekindo, Money_114, NGEfreak, omonim2007, Powerpuff, PPLToast, relax, RetroUprising, rpg2813, SonGoku, Tauwasser, xNo, xuom2"
homepage No-Intro
url "http://www.no-intro.org"
)
@ -20170,7 +20170,7 @@ game (
game (
name "Akumajou Special - Boku Dracula-kun (Japan)"
description "Akumajou Special - Boku Dracula-kun (Japan)"
rom ( name "Akumajou Special - Boku Dracula-kun (Japan).gb" size 262144 crc e8335398 sha1 F2F15DA8ED94BC8652C23965428F6D767E506E38 )
rom ( name "Akumajou Special - Boku Dracula-kun (Japan).gb" size 262144 crc e8335398 sha1 F2F15DA8ED94BC8652C23965428F6D767E506E38 flags verified )
)
game (
@ -20185,6 +20185,12 @@ game (
rom ( name "Aladdin (USA) (SGB Enhanced).gb" size 262144 crc af6bdc50 sha1 81B4E56AE235FBB123D7AD4BD7C1D96C3B69EB72 )
)
game (
name "Aladdin (World) (Disney Classic Games) (SGB Enhanced)"
description "Aladdin (World) (Disney Classic Games) (SGB Enhanced)"
rom ( name "Aladdin (World) (Disney Classic Games) (SGB Enhanced).gb" size 262144 crc 53918941 sha1 C59C44051E41DC6AC8C2F693CFF2BA1FEFFD32F0 flags verified )
)
game (
name "Alfred Chicken (Europe)"
description "Alfred Chicken (Europe)"
@ -21518,9 +21524,15 @@ game (
)
game (
name "Contra (Japan)"
description "Contra (Japan)"
rom ( name "Contra (Japan).gb" size 131072 crc cde6de15 sha1 C8B34B5ABA3D448E357B59CDF106EE9B134713DB )
name "Contra (Japan) (En)"
description "Contra (Japan) (En)"
rom ( name "Contra (Japan) (En).gb" size 131072 crc cde6de15 sha1 C8B34B5ABA3D448E357B59CDF106EE9B134713DB )
)
game (
name "Contra (World) (Contra Anniversary Collection)"
description "Contra (World) (Contra Anniversary Collection)"
rom ( name "Contra (World) (Contra Anniversary Collection).gb" size 131072 crc cc67a046 sha1 6FEA1350AC04F418095CCA5F157A9C770A0505BC flags verified )
)
game (
@ -22435,18 +22447,36 @@ game (
rom ( name "Final Fantasy Adventure (World) (Collection of Mana).gb" size 262144 crc 8e5e5097 sha1 BD8369977CFBBAF3CC57F6268B564D6B11C27D45 flags verified )
)
game (
name "Final Fantasy Legend (World) (Collection of SaGa)"
description "Final Fantasy Legend (World) (Collection of SaGa)"
rom ( name "Final Fantasy Legend (World) (Collection of SaGa).gb" size 131072 crc 00388844 sha1 42450483C9894863C7543F9695C0CBAFFDCB7E99 )
)
game (
name "Final Fantasy Legend II (USA)"
description "Final Fantasy Legend II (USA)"
rom ( name "Final Fantasy Legend II (USA).gb" size 262144 crc 58314182 sha1 6AB6890E8F688BCD87E97886A1748A4D9D341909 flags verified )
)
game (
name "Final Fantasy Legend II (World) (Collection of SaGa)"
description "Final Fantasy Legend II (World) (Collection of SaGa)"
rom ( name "Final Fantasy Legend II (World) (Collection of SaGa).gb" size 262144 crc e84e051a sha1 EEDF962D01B733B5EAF2413905E59E671E04A51C )
)
game (
name "Final Fantasy Legend III (USA)"
description "Final Fantasy Legend III (USA)"
rom ( name "Final Fantasy Legend III (USA).gb" size 262144 crc 3e454710 sha1 3864AFA48A97DB826FFDA1D31A7FF9C6C315D5C9 )
)
game (
name "Final Fantasy Legend III (World) (Collection of SaGa)"
description "Final Fantasy Legend III (World) (Collection of SaGa)"
rom ( name "Final Fantasy Legend III (World) (Collection of SaGa).gb" size 262144 crc 0c5171ef sha1 5190B0EF6264E26AF21DC0097FD5608CB619FB63 )
)
game (
name "Final Fantasy Legend, The (USA)"
description "Final Fantasy Legend, The (USA)"
@ -24511,6 +24541,12 @@ game (
rom ( name "Lion King, The (Europe).gb" size 524288 crc 8fc3ca73 sha1 043D29EDE2AF013C000FF650231C10B3F62D7ACA flags verified )
)
game (
name "Lion King, The (World) (Disney Classic Games)"
description "Lion King, The (World) (Disney Classic Games)"
rom ( name "Lion King, The (World) (Disney Classic Games).gb" size 524288 crc e435ed72 sha1 170C071DB25DA7A2B39DD1FB2675ACEB8EEB87A1 flags verified )
)
game (
name "Litti's Summer Sports (Germany)"
description "Litti's Summer Sports (Germany)"
@ -24697,6 +24733,12 @@ game (
rom ( name "Makai Toushi Sa-Ga (Japan) (Rev 1).gb" size 131072 crc 1953820f sha1 CBF480BC92BD98BAE4FB79294B604D341FE58CBE flags verified )
)
game (
name "Makai Toushi Sa-Ga (World) (Ja) (Rev 1) (Collection of SaGa)"
description "Makai Toushi Sa-Ga (World) (Ja) (Rev 1) (Collection of SaGa)"
rom ( name "Makai Toushi Sa-Ga (World) (Ja) (Rev 1) (Collection of SaGa).gb" size 131072 crc 0006612d sha1 3CE39646BFFE38A9C8FD4913F0E950BAE061D094 )
)
game (
name "Makaimura Gaiden - The Demon Darkness (Japan)"
description "Makaimura Gaiden - The Demon Darkness (Japan)"
@ -26041,6 +26083,12 @@ game (
rom ( name "Operation C (USA).gb" size 131072 crc 2ebbc1ae sha1 1DC3E1C62E62F77AC633408B544AC1D02B3761EB flags verified )
)
game (
name "Operation C (World) (Contra Anniversary Collection)"
description "Operation C (World) (Contra Anniversary Collection)"
rom ( name "Operation C (World) (Contra Anniversary Collection).gb" size 131072 crc a7a5d9c2 sha1 BD528F1B20051502E2B4418845E0C6698E1C5B4B flags verified )
)
game (
name "Osawagase! Penguin Boy (Japan)"
description "Osawagase! Penguin Boy (Japan)"
@ -26758,13 +26806,13 @@ game (
game (
name "Pokemon - Version Jaune - Edition Speciale Pikachu (France) (CGB+SGB Enhanced)"
description "Pokemon - Version Jaune - Edition Speciale Pikachu (France) (CGB+SGB Enhanced)"
rom ( name "Pokemon - Version Jaune - Edition Speciale Pikachu (France) (CGB+SGB Enhanced).gb" size 1048576 crc d03426e9 sha1 0ACEEC0EF7AA2CA5AA831554598D91F61A925591 )
rom ( name "Pokemon - Version Jaune - Edition Speciale Pikachu (France) (CGB+SGB Enhanced).gb" size 1048576 crc d03426e9 sha1 0ACEEC0EF7AA2CA5AA831554598D91F61A925591 flags verified )
)
game (
name "Pokemon - Version Rouge (France) (SGB Enhanced)"
description "Pokemon - Version Rouge (France) (SGB Enhanced)"
rom ( name "Pokemon - Version Rouge (France) (SGB Enhanced).gb" size 1048576 crc 337fce11 sha1 47A7622FA30E6402A3891FE65B3A930BF9BD7AEC )
rom ( name "Pokemon - Version Rouge (France) (SGB Enhanced).gb" size 1048576 crc 337fce11 sha1 47A7622FA30E6402A3891FE65B3A930BF9BD7AEC flags verified )
)
game (
@ -26983,6 +27031,12 @@ game (
rom ( name "Probotector (Europe).gb" size 131072 crc c9acc4f4 sha1 45482A44CE0CDFA33FC58A8A8AFE2D7284DFA498 flags verified )
)
game (
name "Probotector (World) (Contra Anniversary Collection)"
description "Probotector (World) (Contra Anniversary Collection)"
rom ( name "Probotector (World) (Contra Anniversary Collection).gb" size 131072 crc 1c03c0ee sha1 BC58585F8A1B2E27712AE5D44E3D851F4535A53F flags verified )
)
game (
name "Probotector 2 (Europe) (SGB Enhanced)"
description "Probotector 2 (Europe) (SGB Enhanced)"
@ -27505,12 +27559,24 @@ game (
rom ( name "Sa-Ga 2 - Hihou Densetsu (Japan) (Rev 1).gb" size 262144 crc f6cfcfb1 sha1 96EF7D31AD098A620BA7AC57AFEF416972707EA3 flags verified )
)
game (
name "Sa-Ga 2 - Hihou Densetsu (World) (Ja) (Rev 1) (Collection of SaGa)"
description "Sa-Ga 2 - Hihou Densetsu (World) (Ja) (Rev 1) (Collection of SaGa)"
rom ( name "Sa-Ga 2 - Hihou Densetsu (World) (Ja) (Rev 1) (Collection of SaGa).gb" size 262144 crc 2fe38e18 sha1 1DF1F6E277BF6406B865DD5A3E12C0277C3C65F2 )
)
game (
name "Sa-Ga 3 - Jikuu no Hasha (Japan)"
description "Sa-Ga 3 - Jikuu no Hasha (Japan)"
rom ( name "Sa-Ga 3 - Jikuu no Hasha (Japan).gb" size 262144 crc 575d6d9d sha1 C8DCBEFC0352B0590FD85A683D983B5510A63519 )
)
game (
name "Sa-Ga 3 - Jikuu no Hasha (World) (Ja) (Collection of SaGa)"
description "Sa-Ga 3 - Jikuu no Hasha (World) (Ja) (Collection of SaGa)"
rom ( name "Sa-Ga 3 - Jikuu no Hasha (World) (Ja) (Collection of SaGa).gb" size 262144 crc dc4f4e34 sha1 8125677EE63E9ABB4B956ED0BEE18FAE3E04193B )
)
game (
name "Sagaia (Japan)"
description "Sagaia (Japan)"
@ -28810,7 +28876,7 @@ game (
game (
name "Tecmo Bowl GB (Japan)"
description "Tecmo Bowl GB (Japan)"
rom ( name "Tecmo Bowl GB (Japan).gb" size 262144 crc cfd74e34 sha1 2447006C578E1DF0256E9155C8B65FA2A6B0004B )
rom ( name "Tecmo Bowl GB (Japan).gb" size 262144 crc cfd74e34 sha1 2447006C578E1DF0256E9155C8B65FA2A6B0004B flags verified )
)
game (
@ -30004,8 +30070,8 @@ game (
clrmamepro (
name "Nintendo - Game Boy Color"
description "Nintendo - Game Boy Color"
version 20210303-092238
author "akubi, Aringon, Bent, BigFred, BitLooter, C. V. Reynolds, chillerecke, coraz, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, foxe, fuzzball, Hiccup, hking0036, kazumi213, Money_114, NGEfreak, omonim2007, PPLToast, relax, Rifu, SonGoku, Tauwasser, Whovian9369, xuom2, zg"
version 20210410-081930
author "akubi, Aringon, Bent, BigFred, BitLooter, C. V. Reynolds, chillerecke, coraz, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, foxe, fuzzball, Hiccup, hking0036, InternalLoss, kazumi213, Money_114, NGEfreak, omonim2007, PPLToast, relax, Rifu, SonGoku, Tauwasser, Whovian9369, xuom2, zg"
homepage No-Intro
url "http://www.no-intro.org"
)
@ -34873,7 +34939,7 @@ game (
game (
name "Mobile Golf (Japan)"
description "Mobile Golf (Japan)"
rom ( name "Mobile Golf (Japan).gbc" size 4194304 crc 35fc5b32 sha1 FDE414FC9EFEF2C30D1A9E0A2ED35AD2EFC0EDEE )
rom ( name "Mobile Golf (Japan).gbc" size 4194304 crc 35fc5b32 sha1 FDE414FC9EFEF2C30D1A9E0A2ED35AD2EFC0EDEE flags verified )
)
game (
@ -35887,7 +35953,7 @@ game (
game (
name "Pokemon - Silberne Edition (Germany) (Beta) (SGB Enhanced) (GB Compatible)"
description "Pokemon - Silberne Edition (Germany) (Beta) (SGB Enhanced) (GB Compatible)"
rom ( name "Pokemon - Silberne Edition (Germany) (Beta) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 576f5ced sha1 76FA60D66B2F22A035ADC54C61AAD9A415C894CD )
rom ( name "Pokemon - Silberne Edition (Germany) (Beta) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 576f5ced sha1 76FA60D66B2F22A035ADC54C61AAD9A415C894CD flags verified )
)
game (

View File

@ -2,7 +2,11 @@ Miras Absar
Emily A. Bellows
Jaime J. Denizard
Benedikt Feih
Tyler Jenkins
Jezzabel
MichaelK_
Lothar Serra Mari
NimbusFox
Petru-Sebastian Toader
Lucas Towers
Zach

View File

@ -421,7 +421,7 @@ ATTRIBUTE_NOINLINE static void _neutralS(struct ARMCore* cpu, int32_t d) {
#define ARM_MS_PRE_load \
enum PrivilegeMode privilegeMode; \
if (!(rs & 0x8000)) { \
if (!(rs & 0x8000) && rs) { \
privilegeMode = cpu->privilegeMode; \
ARMSetPrivilegeMode(cpu, MODE_SYSTEM); \
}
@ -429,7 +429,7 @@ ATTRIBUTE_NOINLINE static void _neutralS(struct ARMCore* cpu, int32_t d) {
#define ARM_MS_POST_store ARMSetPrivilegeMode(cpu, privilegeMode);
#define ARM_MS_POST_load \
if (!(rs & 0x8000)) { \
if (!(rs & 0x8000) && rs) { \
ARMSetPrivilegeMode(cpu, privilegeMode); \
} else if (_ARMModeHasSPSR(cpu->cpsr.priv)) { \
cpu->cpsr = cpu->spsr; \

View File

@ -139,18 +139,18 @@ void mBitmapCacheCleanRow(struct mBitmapCache* cache, struct mBitmapCacheEntry*
return;
}
size_t offset = cache->bitsStart[cache->buffer] + y * mBitmapCacheSystemInfoGetWidth(cache->sysConfig);
size_t offset = y * mBitmapCacheSystemInfoGetWidth(cache->sysConfig);
void* vram;
int bpe = mBitmapCacheSystemInfoGetEntryBPP(cache->sysConfig);
uint32_t (*lookupEntry)(void*, uint32_t);
switch (bpe) {
case 3:
lookupEntry = _lookupEntry8;
vram = &cache->vram[offset];
vram = &cache->vram[offset + cache->bitsStart[cache->buffer]];
break;
case 4:
lookupEntry = _lookupEntry15;
vram = &cache->vram[offset << 1];
vram = &cache->vram[offset * 2 + cache->bitsStart[cache->buffer]];
break;
default:
abort();
@ -184,4 +184,4 @@ bool mBitmapCacheCheckRow(struct mBitmapCache* cache, const struct mBitmapCacheE
const color_t* mBitmapCacheGetRow(struct mBitmapCache* cache, unsigned y) {
color_t* row = &cache->cache[(cache->buffer * mBitmapCacheSystemInfoGetHeight(cache->sysConfig) + y) * mBitmapCacheSystemInfoGetWidth(cache->sysConfig)];
return row;
}
}

View File

@ -159,7 +159,13 @@ bool mCorePreloadVFCB(struct mCore* core, struct VFile* vf, void (cb)(size_t, si
extern uint32_t* romBuffer;
extern size_t romBufferSize;
if (size > romBufferSize) {
return false;
if (size - romBufferSize < romBufferSize / 2) {
// Some ROM hacks accidentally overflow the size a bit, but since those are broken
// on hardware anyway we can just silently truncate them without issue.
size = romBufferSize;
} else {
return false;
}
}
vfm = VFileFromMemory(romBuffer, size);
#else

View File

@ -100,7 +100,10 @@ int32_t mTimingTick(struct mTiming* timing, int32_t cycles) {
if (timing->reroot) {
timing->root = timing->reroot;
timing->reroot = NULL;
*timing->nextEvent = mTimingNextEvent(timing);
*timing->nextEvent = mTimingNextEvent(timing);
if (*timing->nextEvent <= 0) {
return mTimingTick(timing, 0);
}
}
return *timing->nextEvent;
}

View File

@ -582,13 +582,13 @@ void GBSkipBIOS(struct GB* gb) {
mTimingDeschedule(&gb->timing, &gb->timer.event);
mTimingSchedule(&gb->timing, &gb->timer.event, gb->timer.nextDiv);
GBIOWrite(gb, GB_REG_LCDC, 0x91);
gb->memory.io[GB_REG_BANK] = 0x1;
GBVideoSkipBIOS(&gb->video);
if (gb->biosVf) {
GBUnmapBIOS(gb);
}
GBIOWrite(gb, GB_REG_LCDC, 0x91);
gb->memory.io[GB_REG_BANK] = 0x1;
GBVideoSkipBIOS(&gb->video);
}
void GBMapBIOS(struct GB* gb) {

View File

@ -172,6 +172,7 @@ bool GBDeserialize(struct GB* gb, const struct GBSerializedState* state) {
gb->cpu->condition = GBSerializedCpuFlagsGetCondition(flags);
gb->cpu->irqPending = GBSerializedCpuFlagsGetIrqPending(flags);
gb->doubleSpeed = GBSerializedCpuFlagsGetDoubleSpeed(flags);
gb->cpu->tMultiplier = 2 - gb->doubleSpeed;
gb->cpu->halted = GBSerializedCpuFlagsGetHalted(flags);
gb->cpuBlocked = GBSerializedCpuFlagsGetBlocked(flags);

View File

@ -300,6 +300,7 @@ static void _GBACoreLoadConfig(struct mCore* core, const struct mCoreConfig* con
mCoreConfigCopyValue(&core->config, config, "gba.bios");
mCoreConfigCopyValue(&core->config, config, "gba.forceGbp");
mCoreConfigCopyValue(&core->config, config, "gba.audioHle");
mCoreConfigCopyValue(&core->config, config, "vbaBugCompat");
#ifndef DISABLE_THREADING
mCoreConfigCopyValue(&core->config, config, "threadedVideo");
@ -610,6 +611,10 @@ static void _GBACoreReset(struct mCore* core) {
if (mCoreConfigGetIntValue(&core->config, "gba.forceGbp", &fakeBool)) {
forceGbp = fakeBool;
}
bool vbaBugCompat = true;
if (mCoreConfigGetIntValue(&core->config, "vbaBugCompat", &fakeBool)) {
vbaBugCompat = fakeBool;
}
if (!forceGbp) {
gba->memory.hw.devices &= ~HW_GB_PLAYER_DETECTION;
}
@ -617,6 +622,9 @@ static void _GBACoreReset(struct mCore* core) {
if (forceGbp) {
gba->memory.hw.devices |= HW_GB_PLAYER_DETECTION;
}
if (!vbaBugCompat) {
gba->vbaBugCompat = false;
}
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
if (!gba->biosVf && core->opts.useBios) {

View File

@ -370,6 +370,11 @@ void GBAHardwareEReaderScan(struct GBACartridgeHardware* hw, const void* data, s
// Bitmap sizes
case 5456:
bitmap = true;
blocks = 124;
break;
case 3520:
bitmap = true;
blocks = 80;
break;
default:
return;
@ -380,9 +385,9 @@ void GBAHardwareEReaderScan(struct GBACartridgeHardware* hw, const void* data, s
if (bitmap) {
size_t x;
for (i = 0; i < 40; ++i) {
const uint8_t* line = &cdata[(i + 2) * 124];
const uint8_t* line = &cdata[(i + 2) * blocks];
uint8_t* origin = &hw->eReaderDots[EREADER_DOTCODE_STRIDE * i + 200];
for (x = 0; x < 124; ++x) {
for (x = 0; x < blocks; ++x) {
uint8_t byte = line[x];
if (x == 123) {
byte &= 0xE0;

View File

@ -411,6 +411,7 @@ bool GBALoadROM(struct GBA* gba, struct VFile* vf) {
gba->memory.romSize = gba->pristineRomSize;
}
if (!gba->memory.rom) {
gba->romVf = NULL;
mLOG(GBA, WARN, "Couldn't map ROM");
return false;
}

View File

@ -345,7 +345,7 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
cpu->memory.activeSeqCycles16 = memory->waitstatesSeq16[memory->activeRegion];
cpu->memory.activeNonseqCycles32 = memory->waitstatesNonseq32[memory->activeRegion];
cpu->memory.activeNonseqCycles16 = memory->waitstatesNonseq16[memory->activeRegion];
cpu->memory.activeMask &= -(cpu->executionMode == MODE_THUMB ? WORD_SIZE_THUMB : WORD_SIZE_ARM);
cpu->memory.activeMask &= -(cpu->cpsr.t ? WORD_SIZE_THUMB : WORD_SIZE_ARM);
}
#define LOAD_BAD \
@ -912,7 +912,11 @@ void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle
}
break;
case REGION_CART0:
if (memory->hw.devices != HW_NONE && IS_GPIO_REGISTER(address & 0xFFFFFE)) {
if (IS_GPIO_REGISTER(address & 0xFFFFFE)) {
if (memory->hw.devices == HW_NONE) {
mLOG(GBA_HW, WARN, "Write to GPIO address %08X on cartridge without GPIO", address);
break;
}
uint32_t reg = address & 0xFFFFFE;
GBAHardwareGPIOWrite(&memory->hw, reg, value);
break;
@ -926,7 +930,6 @@ void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle
if ((address & 0x00FFFFFF) >= AGB_PRINT_BASE) {
uint32_t agbPrintAddr = address & 0x00FFFFFF;
if (agbPrintAddr == AGB_PRINT_PROTECT) {
bool wasProtected = memory->agbPrintProtect != 0x20;
memory->agbPrintProtect = value;
if (!memory->agbPrintBuffer) {

View File

@ -375,8 +375,45 @@ void GBAOverrideApplyDefaults(struct GBA* gba, const struct Configuration* overr
if (cart) {
memcpy(override.id, &cart->id, sizeof(override.id));
if (!strncmp("pokemon red version", &((const char*) gba->memory.rom)[0x108], 20) && gba->romCrc32 != 0xDD88761C) {
// Enable FLASH1M and RTC on Pokémon FireRed ROM hacks
static const uint32_t pokemonTable[] = {
// Emerald
0x4881F3F8, // BPEJ
0x8C4D3108, // BPES
0x1F1C08FB, // BPEE
0x34C9DF89, // BPED
0xA3FDCCB1, // BPEF
0xA0AEC80A, // BPEI
// FireRed
0x1A81EEDF, // BPRD
0x3B2056E9, // BPRJ
0x5DC668F6, // BPRF
0x73A72167, // BPRI
0x84EE4776, // BPRE rev 1
0x9F08064E, // BPRS
0xBB640DF7, // BPRJ rev 1
0xDD88761C, // BPRE
// Ruby
0x61641576, // AXVE rev 1
0xAEAC73E6, // AXVE rev 2
0xF0815EE7, // AXVE
};
bool isPokemon = false;
isPokemon = isPokemon || !strncmp("pokemon red version", &((const char*) gba->memory.rom)[0x108], 20);
isPokemon = isPokemon || !strncmp("pokemon emerald version", &((const char*) gba->memory.rom)[0x108], 24);
isPokemon = isPokemon || !strncmp("AXVE", &((const char*) gba->memory.rom)[0xAC], 4);
bool isKnownPokemon = false;
if (isPokemon) {
size_t i;
for (i = 0; !isKnownPokemon && i < sizeof(pokemonTable) / sizeof(*pokemonTable); ++i) {
isKnownPokemon = gba->romCrc32 == pokemonTable[i];
}
}
if (isPokemon && !isKnownPokemon) {
// Enable FLASH1M and RTC on Pokémon ROM hacks
override.savetype = SAVEDATA_FLASH1M;
override.hardware = HW_RTC;
override.vbaBugCompat = true;

View File

@ -13,15 +13,21 @@
int32_t y = background->sy + (renderer->start - 1) * background->dy; \
int mosaicH = 0; \
int mosaicWait = 0; \
if (background->mosaic) { \
int mosaicV = GBAMosaicControlGetBgV(renderer->mosaic) + 1; \
y -= (inY % mosaicV) * background->dmy; \
x -= (inY % mosaicV) * background->dmx; \
mosaicH = GBAMosaicControlGetBgH(renderer->mosaic); \
mosaicWait = renderer->start % (mosaicH + 1); \
} \
int32_t localX; \
int32_t localY; \
if (background->mosaic) { \
int mosaicV = GBAMosaicControlGetBgV(renderer->mosaic) + 1; \
mosaicH = GBAMosaicControlGetBgH(renderer->mosaic) + 1; \
mosaicWait = (mosaicH - renderer->start + GBA_VIDEO_HORIZONTAL_PIXELS * mosaicH) % mosaicH; \
int32_t startX = renderer->start - (renderer->start % mosaicH); \
--mosaicH; \
localX = -(inY % mosaicV) * background->dmx; \
localY = -(inY % mosaicV) * background->dmy; \
x += localX; \
y += localY; \
localX += background->sx + startX * background->dx; \
localY += background->sy + startX * background->dy; \
} \
\
uint32_t flags = (background->priority << OFFSET_PRIORITY) | (background->index << OFFSET_INDEX) | FLAG_IS_BACKGROUND; \
flags |= FLAG_TARGET_2 * background->target2; \
@ -49,16 +55,14 @@
UNUSED(palette); \
PREPARE_OBJWIN;
#define BACKGROUND_BITMAP_ITERATE(W, H) \
x += background->dx; \
y += background->dy; \
\
if (x < 0 || y < 0 || (x >> 8) >= W || (y >> 8) >= H) { \
continue; \
} else { \
localX = x; \
localY = y; \
}
#define BACKGROUND_BITMAP_ITERATE(W, H) \
x += background->dx; \
y += background->dy; \
if ((x < 0 || y < 0 || (x >> 8) >= W || (y >> 8) >= H) && !mosaicWait) { \
continue; \
} \
localX = x; \
localY = y;
#define MODE_2_COORD_OVERFLOW \
localX = x & (sizeAdjusted - 1); \
@ -102,12 +106,20 @@
#define DRAW_BACKGROUND_MODE_2(BLEND, OBJWIN) \
if (background->overflow) { \
if (mosaicH > 1) { \
localX &= sizeAdjusted - 1; \
localY &= sizeAdjusted - 1; \
MODE_2_NO_MOSAIC(); \
MODE_2_LOOP(MODE_2_MOSAIC, MODE_2_COORD_OVERFLOW, BLEND, OBJWIN); \
} else { \
MODE_2_LOOP(MODE_2_NO_MOSAIC, MODE_2_COORD_OVERFLOW, BLEND, OBJWIN); \
} \
} else { \
if (mosaicH > 1) { \
if (!((x | y) & ~(sizeAdjusted - 1))) { \
localX &= sizeAdjusted - 1; \
localY &= sizeAdjusted - 1; \
MODE_2_NO_MOSAIC(); \
} \
MODE_2_LOOP(MODE_2_MOSAIC, MODE_2_COORD_NO_OVERFLOW, BLEND, OBJWIN); \
} else { \
MODE_2_LOOP(MODE_2_NO_MOSAIC, MODE_2_COORD_NO_OVERFLOW, BLEND, OBJWIN); \
@ -146,6 +158,10 @@ void GBAVideoSoftwareRendererDrawBackgroundMode3(struct GBAVideoSoftwareRenderer
BACKGROUND_BITMAP_INIT;
uint32_t color = renderer->normalPalette[0];
if (mosaicWait && localX >= 0 && localY >= 0) {
LOAD_16(color, ((localX >> 8) + (localY >> 8) * GBA_VIDEO_HORIZONTAL_PIXELS) << 1, renderer->d.vram);
color = mColorFrom555(color);
}
int outX;
uint32_t* pixel;
@ -185,6 +201,9 @@ void GBAVideoSoftwareRendererDrawBackgroundMode4(struct GBAVideoSoftwareRenderer
if (GBARegisterDISPCNTIsFrameSelect(renderer->dispcnt)) {
offset = 0xA000;
}
if (mosaicWait && localX >= 0 && localY >= 0) {
color = ((uint8_t*)renderer->d.vram)[offset + (localX >> 8) + (localY >> 8) * GBA_VIDEO_HORIZONTAL_PIXELS];
}
int outX;
uint32_t* pixel;
@ -223,6 +242,10 @@ void GBAVideoSoftwareRendererDrawBackgroundMode5(struct GBAVideoSoftwareRenderer
if (GBARegisterDISPCNTIsFrameSelect(renderer->dispcnt)) {
offset = 0xA000;
}
if (mosaicWait && localX >= 0 && localY >= 0) {
LOAD_16(color, offset + (localX >> 8) * 2 + (localY >> 8) * 320, renderer->d.vram);
color = mColorFrom555(color);
}
int outX;
uint32_t* pixel;

View File

@ -60,7 +60,9 @@ static void _switchMode(struct GBASIO* sio) {
if (sio->activeDriver && sio->activeDriver->unload) {
sio->activeDriver->unload(sio->activeDriver);
}
mLOG(GBA_SIO, DEBUG, "Switching mode from %s to %s", _modeName(sio->mode), _modeName(newMode));
if (sio->mode != (enum GBASIOMode) -1) {
mLOG(GBA_SIO, DEBUG, "Switching mode from %s to %s", _modeName(sio->mode), _modeName(newMode));
}
sio->mode = newMode;
sio->activeDriver = _lookupDriver(sio, sio->mode);
if (sio->activeDriver && sio->activeDriver->load) {

View File

@ -130,7 +130,10 @@ void GBAVideoAssociateRenderer(struct GBAVideo* video, struct GBAVideoRenderer*
renderer->writeVideoRegister(renderer, REG_DISPCNT, video->p->memory.io[REG_DISPCNT >> 1]);
renderer->writeVideoRegister(renderer, REG_GREENSWP, video->p->memory.io[REG_GREENSWP >> 1]);
int address;
for (address = REG_BG0CNT; address < REG_SOUND1CNT_LO; address += 2) {
for (address = REG_BG0CNT; address < 0x56; address += 2) {
if (address == 0x4E) {
continue;
}
renderer->writeVideoRegister(renderer, address, video->p->memory.io[address >> 1]);
}
}

View File

@ -618,8 +618,8 @@ static void _setupMaps(struct mCore* core) {
i++;
/* Map External RAM */
if (gb->memory.sram) {
descs[i].ptr = gb->memory.sram;
if (savedataSize) {
descs[i].ptr = savedata;
descs[i].start = GB_BASE_EXTERNAL_RAM;
descs[i].len = savedataSize;
i++;
@ -690,6 +690,7 @@ bool retro_load_game(const struct retro_game_info* game) {
blip_set_rates(core->getAudioChannel(core, 1), core->frequency(core), 32768);
core->setPeripheral(core, mPERIPH_RUMBLE, &rumble);
core->setPeripheral(core, mPERIPH_ROTATION, &rotation);
savedata = anonymousMemoryMap(SIZE_CART_FLASH1M);
memset(savedata, 0xFF, SIZE_CART_FLASH1M);

View File

@ -22,7 +22,7 @@ endif()
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt5 COMPONENTS Core Widgets OpenGL Network Multimedia)
find_package(Qt5 COMPONENTS Core Widgets Network Multimedia)
if(NOT BUILD_GL AND NOT BUILD_GLES2)
message(WARNING "OpenGL is recommended to build the Qt port")
@ -165,7 +165,7 @@ set(GB_SRC
PrinterView.cpp)
set(QT_LIBRARIES)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libqt5widgets5,libqt5opengl5")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libqt5widgets5")
set(AUDIO_SRC)
if(BUILD_SDL)
@ -301,7 +301,7 @@ endif()
list(APPEND QT_LIBRARIES Qt5::Widgets Qt5::Network)
if(BUILD_GL OR BUILD_GLES2 OR BUILD_EPOXY)
list(APPEND QT_LIBRARIES Qt5::OpenGL ${OPENGL_LIBRARY} ${OPENGLES2_LIBRARY})
list(APPEND QT_LIBRARIES ${OPENGL_LIBRARY} ${OPENGLES2_LIBRARY})
endif()
if(QT_STATIC)
find_library(QTPCRE NAMES qtpcre2 qtpcre)

View File

@ -799,7 +799,7 @@ void CoreController::scanCard(const QString& path) {
QFile file(path);
file.open(QIODevice::ReadOnly);
m_eReaderData = file.read(2912);
} else if (image.size() == QSize(989, 44)) {
} else if (image.size() == QSize(989, 44) || image.size() == QSize(639, 44)) {
const uchar* bits = image.constBits();
size_t size;
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))

View File

@ -368,6 +368,10 @@ void PainterGL::resizeContext() {
m_interrupter.resume();
QSize size = m_context->screenDimensions();
if (m_dims == size) {
return;
}
dequeueAll(false);
m_backend->setDimensions(m_backend, size.width(), size.height());
}
@ -425,26 +429,19 @@ void PainterGL::start() {
}
void PainterGL::draw() {
if (!m_active || m_queue.isEmpty()) {
return;
}
if (m_lagging >= 1) {
if (!m_started || m_queue.isEmpty()) {
return;
}
mCoreSync* sync = &m_context->thread()->impl->sync;
if (!mCoreSyncWaitFrameStart(sync)) {
mCoreSyncWaitFrameEnd(sync);
++m_lagging;
if ((sync->audioWait || sync->videoFrameWait) && m_delayTimer.elapsed() < 1000 / m_surface->screen()->refreshRate()) {
QTimer::singleShot(1, this, &PainterGL::draw);
}
return;
}
dequeue();
if (m_videoProxy) {
// Only block on the next frame if we're trying to run at roughly 60fps via audio
m_videoProxy->setBlocking(sync->audioWait && std::abs(60.f - sync->fpsTarget) < 0.1f);
}
bool forceRedraw = !m_videoProxy;
if (!m_delayTimer.isValid()) {
m_delayTimer.start();
} else {
@ -452,13 +449,23 @@ void PainterGL::draw() {
while (m_delayTimer.nsecsElapsed() + 2000000 < 1000000000 / sync->fpsTarget) {
QThread::usleep(500);
}
forceRedraw = true;
} else if (!forceRedraw) {
forceRedraw = m_delayTimer.nsecsElapsed() + 2000000 >= 1000000000 / m_surface->screen()->refreshRate();
}
m_delayTimer.restart();
}
mCoreSyncWaitFrameEnd(sync);
performDraw();
m_backend->swap(m_backend);
if (forceRedraw) {
m_delayTimer.restart();
performDraw();
m_backend->swap(m_backend);
}
QMutexLocker locker(&m_mutex);
if (!m_queue.isEmpty()) {
QTimer::singleShot(1, this, &PainterGL::draw);
}
}
void PainterGL::forceDraw() {
@ -475,7 +482,7 @@ void PainterGL::forceDraw() {
void PainterGL::stop() {
m_active = false;
m_started = false;
dequeueAll();
dequeueAll(false);
if (m_context) {
if (m_videoProxy) {
m_videoProxy->detach(m_context.get());
@ -497,10 +504,10 @@ void PainterGL::stop() {
void PainterGL::pause() {
m_active = false;
dequeueAll(true);
}
void PainterGL::unpause() {
m_lagging = 0;
m_active = true;
}
@ -534,7 +541,6 @@ void PainterGL::enqueue(const uint32_t* backing) {
memcpy(buffer, backing, size.width() * size.height() * BYTES_PER_PIXEL);
}
}
m_lagging = 0;
m_queue.enqueue(buffer);
}
@ -551,23 +557,24 @@ void PainterGL::dequeue() {
m_buffer = buffer;
}
void PainterGL::dequeueAll() {
void PainterGL::dequeueAll(bool keep) {
QMutexLocker locker(&m_mutex);
uint32_t* buffer = 0;
m_mutex.lock();
while (!m_queue.isEmpty()) {
buffer = m_queue.dequeue();
if (buffer) {
if (keep) {
if (m_buffer && buffer) {
m_free.append(m_buffer);
m_buffer = buffer;
}
} else if (buffer) {
m_free.append(buffer);
}
}
if (buffer) {
m_backend->postFrame(m_backend, buffer);
}
if (m_buffer) {
if (m_buffer && !keep) {
m_free.append(m_buffer);
m_buffer = nullptr;
}
m_mutex.unlock();
}
void PainterGL::setVideoProxy(std::shared_ptr<VideoProxy> proxy) {

View File

@ -136,13 +136,12 @@ private:
void makeCurrent();
void performDraw();
void dequeue();
void dequeueAll();
void dequeueAll(bool keep = false);
std::array<std::array<uint32_t, 0x100000>, 3> m_buffers;
QList<uint32_t*> m_free;
QQueue<uint32_t*> m_queue;
QAtomicInt m_lagging = 0;
uint32_t* m_buffer;
uint32_t* m_buffer = nullptr;
QPainter m_painter;
QMutex m_mutex;
QWindow* m_surface;
@ -158,6 +157,7 @@ private:
VideoShader m_shader{};
VideoBackend* m_backend = nullptr;
QSize m_size;
QSize m_dims;
MessagePainter* m_messagePainter = nullptr;
QElapsedTimer m_delayTimer;
std::shared_ptr<VideoProxy> m_videoProxy;

View File

@ -6,6 +6,7 @@
#include "GBAOverride.h"
#include <mgba/core/core.h>
#include <mgba/internal/gba/gba.h>
using namespace QGBA;
@ -13,7 +14,11 @@ void GBAOverride::apply(struct mCore* core) {
if (core->platform(core) != mPLATFORM_GBA) {
return;
}
GBAOverrideApply(static_cast<GBA*>(core->board), &override);
GBA* gba = static_cast<GBA*>(core->board);
if (!vbaBugCompatSet) {
override.vbaBugCompat = gba->vbaBugCompat;
}
GBAOverrideApply(gba, &override);
}
void GBAOverride::identify(const struct mCore* core) {

View File

@ -18,6 +18,7 @@ public:
void save(struct Configuration*) const override;
struct GBACartridgeOverride override;
bool vbaBugCompatSet;
};
}

View File

@ -94,23 +94,23 @@ InputController::InputController(int playerId, QWidget* topLevel, QObject* paren
InputControllerImage* image = static_cast<InputControllerImage*>(context);
image->w = w;
image->h = h;
image->p->m_cameraActive = true;
if (image->image.isNull()) {
image->image.load(":/res/no-cam.png");
}
#ifdef BUILD_QT_MULTIMEDIA
if (image->p->m_config->getQtOption("cameraDriver").toInt() == static_cast<int>(CameraDriver::QT_MULTIMEDIA)) {
QByteArray camera = image->p->m_config->getQtOption("camera").toByteArray();
if (!camera.isNull()) {
QMetaObject::invokeMethod(image->p, "setCamera", Q_ARG(QByteArray, camera));
}
QMetaObject::invokeMethod(image->p, "setupCam");
QByteArray camera = image->p->m_config->getQtOption("camera").toByteArray();
if (!camera.isNull()) {
image->p->m_cameraDevice = camera;
}
QMetaObject::invokeMethod(image->p, "setupCam");
#endif
};
m_image.stopRequestImage = [](mImageSource* context) {
InputControllerImage* image = static_cast<InputControllerImage*>(context);
#ifdef BUILD_QT_MULTIMEDIA
image->p->m_cameraActive = false;
QMetaObject::invokeMethod(image->p, "teardownCam");
#endif
};
@ -766,10 +766,18 @@ void InputController::setLuminanceValue(uint8_t value) {
void InputController::setupCam() {
#ifdef BUILD_QT_MULTIMEDIA
if (m_config->getQtOption("cameraDriver").toInt() != static_cast<int>(CameraDriver::QT_MULTIMEDIA)) {
return;
}
if (!m_camera) {
m_camera = std::make_unique<QCamera>();
m_camera = std::make_unique<QCamera>(m_cameraDevice);
connect(m_camera.get(), &QCamera::statusChanged, this, &InputController::prepareCamSettings, Qt::QueuedConnection);
}
if (m_camera->status() == QCamera::UnavailableStatus) {
m_camera.reset();
return;
}
m_camera->setCaptureMode(QCamera::CaptureVideo);
m_camera->setViewfinder(&m_videoDumper);
m_camera->load();
@ -820,20 +828,22 @@ void InputController::prepareCamSettings(QCamera::Status status) {
void InputController::teardownCam() {
#ifdef BUILD_QT_MULTIMEDIA
if (m_camera) {
m_camera->stop();
m_camera->unload();
m_camera.reset();
}
#endif
}
void InputController::setCamera(const QByteArray& name) {
#ifdef BUILD_QT_MULTIMEDIA
bool needsRestart = false;
if (m_camera) {
needsRestart = m_camera->state() == QCamera::ActiveState;
if (m_cameraDevice == name) {
return;
}
m_camera = std::make_unique<QCamera>(name);
connect(m_camera.get(), &QCamera::statusChanged, this, &InputController::prepareCamSettings, Qt::QueuedConnection);
if (needsRestart) {
m_cameraDevice = name;
if (m_camera && m_camera->state() == QCamera::ActiveState) {
teardownCam();
}
if (m_cameraActive) {
setupCam();
}
#endif

View File

@ -158,6 +158,8 @@ private:
} m_image;
#ifdef BUILD_QT_MULTIMEDIA
bool m_cameraActive = false;
QByteArray m_cameraDevice;
std::unique_ptr<QCamera> m_camera;
VideoDumper m_videoDumper;
#endif

View File

@ -144,6 +144,7 @@ void OverrideView::updateOverrides() {
gba->override.idleLoop = IDLE_LOOP_NONE;
gba->override.mirroring = false;
gba->override.vbaBugCompat = false;
gba->vbaBugCompatSet = false;
if (!m_ui.hwAutodetect->isChecked()) {
hasOverride = true;
@ -168,9 +169,10 @@ void OverrideView::updateOverrides() {
hasOverride = true;
gba->override.hardware |= HW_GB_PLAYER_DETECTION;
}
if (m_ui.vbaBugCompat->isChecked()) {
if (m_ui.vbaBugCompat->checkState() != Qt::PartiallyChecked) {
hasOverride = true;
gba->override.vbaBugCompat = true;
gba->vbaBugCompatSet = true;
gba->override.vbaBugCompat = m_ui.vbaBugCompat->isChecked();
}
bool ok;
@ -270,7 +272,7 @@ void OverrideView::gameStopped() {
m_ui.tabWidget->setEnabled(true);
m_ui.savetype->setCurrentIndex(0);
m_ui.idleLoop->clear();
m_ui.vbaBugCompat->setChecked(false);
m_ui.vbaBugCompat->setCheckState(Qt::PartiallyChecked);
m_ui.mbc->setCurrentIndex(0);
m_ui.gbModel->setCurrentIndex(0);

View File

@ -186,6 +186,12 @@
<property name="text">
<string>VBA bug compatibility mode</string>
</property>
<property name="tristate">
<bool>true</bool>
</property>
<property name="checkState">
<enum>Qt::PartiallyChecked</enum>
</property>
</widget>
</item>
</layout>

View File

@ -245,6 +245,11 @@ void ReportView::generateReport() {
{
CoreController::Interrupter interrupter(controller);
QFileInfo rom(window->windowFilePath());
if (rom.exists()) {
windowReport << QString("Filename: %1").arg(redact(rom.filePath()));
windowReport << QString("Size: %1").arg(rom.size());
}
addROMInfo(windowReport, controller.get());
if (m_ui.includeSave->isChecked() && !m_ui.includeState->isChecked()) {

View File

@ -429,6 +429,7 @@ void SettingsView::updateConfig() {
saveSetting("dynamicTitle", m_ui.dynamicTitle);
saveSetting("videoScale", m_ui.videoScale);
saveSetting("gba.forceGbp", m_ui.forceGbp);
saveSetting("vbaBugCompat", m_ui.vbaBugCompat);
if (m_ui.audioBufferSize->currentText().toInt() > 8192) {
m_ui.audioBufferSize->setCurrentText("8192");
@ -503,9 +504,12 @@ void SettingsView::updateConfig() {
}
QVariant camera = m_ui.camera->itemData(m_ui.camera->currentIndex());
if (camera != m_controller->getQtOption("camera")) {
QVariant oldCamera = m_controller->getQtOption("camera");
if (camera != oldCamera) {
m_controller->setQtOption("camera", camera);
emit cameraChanged(camera.toByteArray());
if (!oldCamera.isNull()) {
emit cameraChanged(camera.toByteArray());
}
}
QLocale language = m_ui.languages->itemData(m_ui.languages->currentIndex()).toLocale();
@ -619,6 +623,7 @@ void SettingsView::reloadConfig() {
loadSetting("gba.audioHle", m_ui.audioHle);
loadSetting("dynamicTitle", m_ui.dynamicTitle, true);
loadSetting("gba.forceGbp", m_ui.forceGbp);
loadSetting("vbaBugCompat", m_ui.vbaBugCompat, true);
m_ui.libraryStyle->setCurrentIndex(loadSetting("libraryStyle").toInt());

View File

@ -873,21 +873,28 @@
</property>
</widget>
</item>
<item row="10" column="0" colspan="2">
<item row="9" column="1">
<widget class="QCheckBox" name="forceGbp">
<property name="text">
<string>Enable Game Boy Player features by default</string>
</property>
</widget>
</item>
<item row="11" column="0" colspan="2">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="11" column="0">
<item row="12" column="0">
<widget class="QLabel" name="label_24">
<property name="text">
<string>Save state extra data:</string>
</property>
</widget>
</item>
<item row="11" column="1">
<item row="12" column="1">
<widget class="QCheckBox" name="saveStateScreenshot">
<property name="text">
<string>Screenshot</string>
@ -897,7 +904,7 @@
</property>
</widget>
</item>
<item row="12" column="1">
<item row="13" column="1">
<widget class="QCheckBox" name="saveStateSave">
<property name="text">
<string>Save game</string>
@ -907,7 +914,7 @@
</property>
</widget>
</item>
<item row="13" column="1">
<item row="14" column="1">
<widget class="QCheckBox" name="saveStateCheats">
<property name="text">
<string>Cheat codes</string>
@ -917,21 +924,21 @@
</property>
</widget>
</item>
<item row="14" column="0" colspan="2">
<item row="15" column="0" colspan="2">
<widget class="Line" name="line_9">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="15" column="0">
<item row="16" column="0">
<widget class="QLabel" name="label_25">
<property name="text">
<string>Load state extra data:</string>
</property>
</widget>
</item>
<item row="15" column="1">
<item row="16" column="1">
<widget class="QCheckBox" name="loadStateScreenshot">
<property name="text">
<string>Screenshot</string>
@ -941,24 +948,27 @@
</property>
</widget>
</item>
<item row="16" column="1">
<item row="17" column="1">
<widget class="QCheckBox" name="loadStateSave">
<property name="text">
<string>Save game</string>
</property>
</widget>
</item>
<item row="17" column="1">
<item row="18" column="1">
<widget class="QCheckBox" name="loadStateCheats">
<property name="text">
<string>Cheat codes</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QCheckBox" name="forceGbp">
<item row="10" column="1">
<widget class="QCheckBox" name="vbaBugCompat">
<property name="text">
<string>Enable Game Boy Player features by default</string>
<string>Enable VBA bug compatibility in ROM hacks</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>

View File

@ -14,7 +14,7 @@ using namespace QGBA;
VideoProxy::VideoProxy() {
mVideoLoggerRendererCreate(&m_logger.d, false);
m_logger.d.block = true;
m_logger.d.waitOnFlush = false;
m_logger.d.waitOnFlush = true;
m_logger.d.init = &cbind<&VideoProxy::init>;
m_logger.d.reset = &cbind<&VideoProxy::reset>;

View File

@ -620,6 +620,7 @@ void Window::showEvent(QShowEvent* event) {
m_wasOpened = true;
resizeFrame(m_screenWidget->sizeHint());
QVariant windowPos = m_config->getQtOption("windowPos");
bool maximized = m_config->getQtOption("maximized").toBool();
QRect geom = windowHandle()->screen()->availableGeometry();
if (!windowPos.isNull() && geom.contains(windowPos.toPoint())) {
move(windowPos.toPoint());
@ -628,6 +629,9 @@ void Window::showEvent(QShowEvent* event) {
rect.moveCenter(geom.center());
move(rect.topLeft());
}
if (maximized) {
showMaximized();
}
if (m_fullscreenOnStart) {
enterFullScreen();
m_fullscreenOnStart = false;
@ -652,6 +656,7 @@ void Window::hideEvent(QHideEvent* event) {
void Window::closeEvent(QCloseEvent* event) {
emit shutdown();
m_config->setQtOption("windowPos", pos());
m_config->setQtOption("maximized", isMaximized());
if (m_savedScale > 0) {
m_config->setOption("height", GBA_VIDEO_VERTICAL_PIXELS * m_savedScale);

View File

@ -61,9 +61,17 @@ int main(int argc, char* argv[]) {
mSubParser subparser;
initParserForGraphics(&subparser, &graphicsOpts);
bool loaded = configController.parseArguments(&args, argc, argv, &subparser);
if (loaded && args.showHelp) {
usage(argv[0], subparser.usage);
return 0;
if (loaded) {
if (args.showHelp) {
usage(argv[0], subparser.usage);
freeArguments(&args);
return 0;
}
if (args.showVersion) {
version(argv[0]);
freeArguments(&args);
return 0;
}
}
QApplication::setApplicationName(projectName);
@ -79,7 +87,7 @@ int main(int argc, char* argv[]) {
GBAApp application(argc, argv, &configController);
#ifndef Q_OS_MAC
QApplication::setWindowIcon(QIcon(":/res/mgba-1024.png"));
QApplication::setWindowIcon(QIcon(":/res/mgba-256.png"));
#endif
QTranslator qtTranslator;

View File

@ -2,6 +2,7 @@
<RCC version="1.0">
<qresource>
<file>../../../res/mgba-1024.png</file>
<file>../../../res/mgba-256.png</file>
<file>../../../res/keymap.qpic</file>
<file>../../../res/patrons.txt</file>
<file>../../../res/no-cam.png</file>

View File

@ -3,7 +3,7 @@ if(NOT PROJECT_NAME)
endif()
set(LIB_VERSION_MAJOR 0)
set(LIB_VERSION_MINOR 9)
set(LIB_VERSION_PATCH 0)
set(LIB_VERSION_PATCH 1)
set(LIB_VERSION_ABI 0.9)
set(LIB_VERSION_STRING ${LIB_VERSION_MAJOR}.${LIB_VERSION_MINOR}.${LIB_VERSION_PATCH})
set(SUMMARY "${PROJECT_NAME} Game Boy Advance Emulator")