mirror of https://github.com/mgba-emu/mgba.git
Merge branch 'master' (early part) into medusa
This commit is contained in:
commit
e2e48a1c58
13
CHANGES
13
CHANGES
|
@ -22,6 +22,7 @@ Misc:
|
|||
Features:
|
||||
- Improved logging configuration
|
||||
- One-Player BattleChip/Progress/Beast Link Gate support
|
||||
- Add Game Boy Color palettes for original Game Boy games
|
||||
Bugfixes:
|
||||
- GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208)
|
||||
- GBA: Reset now reloads multiboot ROMs
|
||||
|
@ -35,6 +36,17 @@ Bugfixes:
|
|||
- Switch: Fix gyroscope orientation (fixes mgba.io/i/1300)
|
||||
- GBA SIO: Prevent writing read-only multiplayer bits
|
||||
- Qt: Fix color picking in sprite view (fixes mgba.io/i/1307)
|
||||
- GB: Fix crash when accessing SRAM if no save loaded and cartridge has no SRAM
|
||||
- Python: Fix crash when deleting files owned by library
|
||||
- Python: Make sure GB link object isn't GC'd before GB object
|
||||
- GBA DMA: Fix Display Start DMAs
|
||||
- GBA DMA: Fix DMA start/end timing
|
||||
- Qt: Fix window icon on X11
|
||||
- GB, GBA Serialize: Fix loading two states in a row
|
||||
- GBA Video: Fix enabling layers in non-tile modes (fixes mgba.io/i/1317)
|
||||
- Qt: Fix quick load recent accidentally saving (fixes mgba.io/i/1309)
|
||||
- GBA: Fix video timing when skipping BIOS (fixes mgba.io/i/1318)
|
||||
- 3DS: Work around menu freezing (fixes mgba.io/i/1294)
|
||||
Misc:
|
||||
- GBA Savedata: EEPROM performance fixes
|
||||
- GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash
|
||||
|
@ -42,6 +54,7 @@ Misc:
|
|||
- Qt: Don't unload ROM immediately if it crashes
|
||||
- GBA Video: Improve sprite cycle counting (fixes mgba.io/i/1274)
|
||||
- Debugger: Add breakpoint and watchpoint listing
|
||||
- Qt: Updated Italian translation (by Vecna)
|
||||
|
||||
0.7.0: (2019-01-26)
|
||||
Features:
|
||||
|
|
|
@ -32,6 +32,7 @@ typedef uint32_t color_t;
|
|||
#define M_B8(X) (((((X) >> 7) & 0xF8) * 0x21) >> 5)
|
||||
|
||||
#define M_RGB5_TO_BGR8(X) ((M_R5(X) << 3) | (M_G5(X) << 11) | (M_B5(X) << 19))
|
||||
#define M_RGB5_TO_RGB8(X) ((M_R5(X) << 19) | (M_G5(X) << 11) | (M_B5(X) << 3))
|
||||
#define M_RGB8_TO_BGR5(X) ((((X) & 0xF8) >> 3) | (((X) & 0xF800) >> 6) | (((X) & 0xF80000) >> 9))
|
||||
#define M_RGB8_TO_RGB5(X) ((((X) & 0xF8) << 7) | (((X) & 0xF800) >> 6) | (((X) & 0xF80000) >> 19))
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ struct GBCartridgeOverride {
|
|||
|
||||
struct Configuration;
|
||||
bool GBOverrideFind(const struct Configuration*, struct GBCartridgeOverride* override);
|
||||
bool GBOverrideColorFind(struct GBCartridgeOverride* override);
|
||||
void GBOverrideSave(struct Configuration*, const struct GBCartridgeOverride* override);
|
||||
|
||||
struct GB;
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 483 B |
Binary file not shown.
After Width: | Height: | Size: 475 B |
Binary file not shown.
After Width: | Height: | Size: 476 B |
|
@ -548,6 +548,10 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) {
|
|||
runner->params.drawStart();
|
||||
runner->drawFrame(runner, true);
|
||||
runner->params.drawEnd();
|
||||
#ifdef _3DS
|
||||
// XXX: Why does this fix #1294?
|
||||
usleep(1000);
|
||||
#endif
|
||||
GUIPollInput(&runner->params, 0, &keys);
|
||||
}
|
||||
if (runner->unpaused) {
|
||||
|
|
|
@ -220,6 +220,7 @@ static void _GBCoreLoadConfig(struct mCore* core, const struct mCoreConfig* conf
|
|||
mCoreConfigCopyValue(&core->config, config, "gb.model");
|
||||
mCoreConfigCopyValue(&core->config, config, "sgb.model");
|
||||
mCoreConfigCopyValue(&core->config, config, "cgb.model");
|
||||
mCoreConfigCopyValue(&core->config, config, "useCgbColors");
|
||||
mCoreConfigCopyValue(&core->config, config, "allowOpposingDirections");
|
||||
|
||||
int fakeBool = 0;
|
||||
|
@ -371,10 +372,13 @@ static void _GBCoreReset(struct mCore* core) {
|
|||
}
|
||||
|
||||
if (gb->memory.rom) {
|
||||
int doColorOverride = 0;
|
||||
mCoreConfigGetIntValue(&core->config, "useCgbColors", &doColorOverride);
|
||||
|
||||
struct GBCartridgeOverride override;
|
||||
const struct GBCartridge* cart = (const struct GBCartridge*) &gb->memory.rom[0x100];
|
||||
override.headerCrc32 = doCrc32(cart, sizeof(*cart));
|
||||
if (GBOverrideFind(gbcore->overrides, &override)) {
|
||||
if (GBOverrideFind(gbcore->overrides, &override) || (doColorOverride && GBOverrideColorFind(&override))) {
|
||||
GBOverrideApply(gb, &override);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -202,7 +202,7 @@ void GBResizeSram(struct GB* gb, size_t size) {
|
|||
if (gb->memory.sram == (void*) -1) {
|
||||
gb->memory.sram = NULL;
|
||||
}
|
||||
} else {
|
||||
} else if (size) {
|
||||
uint8_t* newSram = anonymousMemoryMap(size);
|
||||
if (gb->memory.sram) {
|
||||
if (size > gb->sramSize) {
|
||||
|
|
|
@ -11,6 +11,482 @@
|
|||
#include <mgba-util/configuration.h>
|
||||
#include <mgba-util/crc32.h>
|
||||
|
||||
#define PAL_ENTRY(A, B, C, D) \
|
||||
0xFF000000 | M_RGB5_TO_RGB8(A), \
|
||||
0xFF000000 | M_RGB5_TO_RGB8(B), \
|
||||
0xFF000000 | M_RGB5_TO_RGB8(C), \
|
||||
0xFF000000 | M_RGB5_TO_RGB8(D)
|
||||
|
||||
#define PAL0 PAL_ENTRY(0x7FFF, 0x32BF, 0x00D0, 0x0000)
|
||||
#define PAL1 PAL_ENTRY(0x639F, 0x4279, 0x15B0, 0x04CB)
|
||||
#define PAL2 PAL_ENTRY(0x7FFF, 0x6E31, 0x454A, 0x0000)
|
||||
#define PAL3 PAL_ENTRY(0x7FFF, 0x1BEF, 0x0200, 0x0000)
|
||||
#define PAL4 PAL_ENTRY(0x7FFF, 0x421F, 0x1CF2, 0x0000)
|
||||
#define PAL5 PAL_ENTRY(0x7FFF, 0x5294, 0x294A, 0x0000)
|
||||
#define PAL6 PAL_ENTRY(0x7FFF, 0x03FF, 0x012F, 0x0000)
|
||||
#define PAL7 PAL_ENTRY(0x7FFF, 0x03EF, 0x01D6, 0x0000)
|
||||
#define PAL8 PAL_ENTRY(0x7FFF, 0x42B5, 0x3DC8, 0x0000)
|
||||
#define PAL9 PAL_ENTRY(0x7E74, 0x03FF, 0x0180, 0x0000)
|
||||
#define PAL10 PAL_ENTRY(0x67FF, 0x77AC, 0x1A13, 0x2D6B)
|
||||
#define PAL11 PAL_ENTRY(0x7ED6, 0x4BFF, 0x2175, 0x0000)
|
||||
#define PAL12 PAL_ENTRY(0x53FF, 0x4A5F, 0x7E52, 0x0000)
|
||||
#define PAL13 PAL_ENTRY(0x4FFF, 0x7ED2, 0x3A4C, 0x1CE0)
|
||||
#define PAL14 PAL_ENTRY(0x03ED, 0x7FFF, 0x255F, 0x0000)
|
||||
#define PAL15 PAL_ENTRY(0x036A, 0x021F, 0x03FF, 0x7FFF)
|
||||
#define PAL16 PAL_ENTRY(0x7FFF, 0x01DF, 0x0112, 0x0000)
|
||||
#define PAL17 PAL_ENTRY(0x231F, 0x035F, 0x00F2, 0x0009)
|
||||
#define PAL18 PAL_ENTRY(0x7FFF, 0x03EA, 0x011F, 0x0000)
|
||||
#define PAL19 PAL_ENTRY(0x299F, 0x001A, 0x000C, 0x0000)
|
||||
#define PAL20 PAL_ENTRY(0x7FFF, 0x027F, 0x001F, 0x0000)
|
||||
#define PAL21 PAL_ENTRY(0x7FFF, 0x03E0, 0x0206, 0x0120)
|
||||
#define PAL22 PAL_ENTRY(0x7FFF, 0x7EEB, 0x001F, 0x7C00)
|
||||
#define PAL23 PAL_ENTRY(0x7FFF, 0x3FFF, 0x7E00, 0x001F)
|
||||
#define PAL24 PAL_ENTRY(0x7FFF, 0x03FF, 0x001F, 0x0000)
|
||||
#define PAL25 PAL_ENTRY(0x03FF, 0x001F, 0x000C, 0x0000)
|
||||
#define PAL26 PAL_ENTRY(0x7FFF, 0x033F, 0x0193, 0x0000)
|
||||
#define PAL27 PAL_ENTRY(0x0000, 0x4200, 0x037F, 0x7FFF)
|
||||
#define PAL28 PAL_ENTRY(0x7FFF, 0x7E8C, 0x7C00, 0x0000)
|
||||
#define PAL29 PAL_ENTRY(0x7FFF, 0x1BEF, 0x6180, 0x0000)
|
||||
#define PAL30 PAL_ENTRY(0x7C00, 0x7FFF, 0x3FFF, 0x7E00)
|
||||
#define PAL31 PAL_ENTRY(0x7FFF, 0x7FFF, 0x7E8C, 0x7C00)
|
||||
#define PAL32 PAL_ENTRY(0x0000, 0x7FFF, 0x421F, 0x1CF2)
|
||||
|
||||
#define PALETTE(X, Y, Z) { PAL ## X, PAL ## Y, PAL ## Z }
|
||||
|
||||
static const struct GBCartridgeOverride _colorOverrides[] = {
|
||||
// Adventures of Lolo (Europe)
|
||||
{ 0xFBE65286, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
|
||||
|
||||
// Alleyway (World)
|
||||
{ 0xCBAA161B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 9, 9) },
|
||||
|
||||
// Arcade Classic No. 1 - Asteroids & Missile Command (USA, Europe)
|
||||
{ 0x309FDB70, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 4) },
|
||||
|
||||
// Arcade Classic No. 3 - Galaga & Galaxian (USA)
|
||||
{ 0xE13EF629, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(27, 27, 27) },
|
||||
|
||||
// Arcade Classic No. 4 - Defender & Joust (USA, Europe)
|
||||
{ 0x5C8B229D, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
|
||||
|
||||
// Balloon Kid (USA, Europe)
|
||||
{ 0xEC3438FA, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(20, 20, 20) },
|
||||
|
||||
// Baseball (World)
|
||||
{ 0xE02904BD, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(15, 31, 4) },
|
||||
|
||||
// Battle Arena Toshinden (USA)
|
||||
{ 0xA2C3DF62, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
|
||||
|
||||
// Battletoads in Ragnarok's World (Europe)
|
||||
{ 0x51B259CF, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 3, 3) },
|
||||
|
||||
// Chessmaster, The (DMG-EM) (Europe)
|
||||
{ 0x96A68366, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 28) },
|
||||
|
||||
// David Crane's The Rescue of Princess Blobette Starring A Boy and His Blob (Europe)
|
||||
{ 0x6413F5E2, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 3, 28) },
|
||||
|
||||
// Donkey Kong (Japan, USA)
|
||||
{ 0xA777EE2F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(20, 4, 4) },
|
||||
|
||||
// Donkey Kong (World) (Rev A)
|
||||
{ 0xC8F8ACDA, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(20, 4, 4) },
|
||||
|
||||
// Donkey Kong Land (Japan)
|
||||
{ 0x2CA7EEF3, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 17, 22) },
|
||||
|
||||
// Donkey Kong Land (USA, Europe)
|
||||
{ 0x0D3E401D, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(13, 17, 4) },
|
||||
|
||||
// Donkey Kong Land 2 (USA, Europe)
|
||||
{ 0x07ED9445, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 17, 22) },
|
||||
|
||||
// Donkey Kong Land III (USA, Europe)
|
||||
{ 0xCA01A31C, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 17, 22) },
|
||||
|
||||
// Donkey Kong Land III (USA, Europe) (Rev A)
|
||||
{ 0x6805BA1E, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 17, 22) },
|
||||
|
||||
// Dr. Mario (World)
|
||||
{ 0xA3C2C1E9, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 28, 4) },
|
||||
|
||||
// Dr. Mario (World) (Rev A)
|
||||
{ 0x69975661, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 28, 4) },
|
||||
|
||||
// Dr. Mario (World) (Beta)
|
||||
{ 0x22E55535, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) },
|
||||
|
||||
// Dynablaster (Europe)
|
||||
{ 0xD9D0211F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 28) },
|
||||
|
||||
// F-1 Race (World)
|
||||
{ 0x8434CB2C, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
|
||||
|
||||
// F-1 Race (World) (Rev A)
|
||||
{ 0xBA63383B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
|
||||
|
||||
// Game & Watch Gallery (Europe)
|
||||
{ 0x4A43B8B9, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(7, 4, 4) },
|
||||
|
||||
// Game & Watch Gallery (USA)
|
||||
{ 0xBD0736D4, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(7, 4, 4) },
|
||||
|
||||
// Game & Watch Gallery (USA) (Rev A)
|
||||
{ 0xA969B4F0, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(7, 4, 4) },
|
||||
|
||||
// Game Boy Camera Gold (USA)
|
||||
{ 0x83947EC8, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) },
|
||||
|
||||
// Game Boy Gallery (Japan)
|
||||
{ 0xDC3C3642, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(7, 4, 4) },
|
||||
|
||||
// Game Boy Gallery - 5 Games in One (Europe)
|
||||
{ 0xD83E3F82, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
|
||||
|
||||
// Game Boy Gallery 2 (Australia)
|
||||
{ 0x6C477A30, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(7, 4, 4) },
|
||||
|
||||
// Game Boy Gallery 2 (Japan)
|
||||
{ 0xC5AAAFDA, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(7, 4, 4) },
|
||||
|
||||
// Game Boy Wars (Japan)
|
||||
{ 0x03E3ED72, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 16, 22) },
|
||||
|
||||
// Golf (World)
|
||||
{ 0x885C242D, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 4) },
|
||||
|
||||
// Hoshi no Kirby (Japan)
|
||||
{ 0x4AA02A13, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) },
|
||||
|
||||
// Hoshi no Kirby (Japan) (Rev A)
|
||||
{ 0x88D03280, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) },
|
||||
|
||||
// Hoshi no Kirby 2 (Japan)
|
||||
{ 0x58B7A321, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) },
|
||||
|
||||
// James Bond 007 (USA, Europe)
|
||||
{ 0x7DDEB68E, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(29, 4, 29) },
|
||||
|
||||
// Kaeru no Tame ni Kane wa Naru (Japan)
|
||||
{ 0x7F805941, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 4, 2) },
|
||||
|
||||
// Kid Icarus - Of Myths and Monsters (USA, Europe)
|
||||
{ 0x5D93DB0F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 4, 4) },
|
||||
|
||||
// Killer Instinct (USA, Europe)
|
||||
{ 0x117043A9, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 4, 0) },
|
||||
|
||||
// King of Fighters '95, The (USA)
|
||||
{ 0x0F81CC70, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
|
||||
|
||||
// King of the Zoo (Europe)
|
||||
{ 0xB492FB51, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 28) },
|
||||
|
||||
// Kirby no Block Ball (Japan)
|
||||
{ 0x4203B79F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) },
|
||||
|
||||
// Kirby no Kirakira Kids (Japan)
|
||||
{ 0x74C3A937, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
|
||||
|
||||
// Kirby no Pinball (Japan)
|
||||
{ 0x89239AED, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 19) },
|
||||
|
||||
// Kirby's Block Ball (USA, Europe)
|
||||
{ 0xCE8B1B18, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) },
|
||||
|
||||
// Kirby's Dream Land (USA, Europe)
|
||||
{ 0x302017CC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) },
|
||||
|
||||
// Kirby's Dream Land 2 (USA, Europe)
|
||||
{ 0xF6C9E5A8, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) },
|
||||
|
||||
// Kirby's Pinball Land (USA, Europe)
|
||||
{ 0x9C4AA9D8, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 19) },
|
||||
|
||||
// Kirby's Star Stacker (USA, Europe)
|
||||
{ 0xC1B481CA, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
|
||||
|
||||
// Legend of Zelda, The - Link's Awakening (Canada)
|
||||
{ 0x9F54D47B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) },
|
||||
|
||||
// Legend of Zelda, The - Link's Awakening (France)
|
||||
{ 0x441D7FAD, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) },
|
||||
|
||||
// Legend of Zelda, The - Link's Awakening (Germany)
|
||||
{ 0x838D65D6, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) },
|
||||
|
||||
// Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev A)
|
||||
{ 0x24CAAB4D, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) },
|
||||
|
||||
// Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev B)
|
||||
{ 0xBCBB6BDB, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) },
|
||||
|
||||
// Legend of Zelda, The - Link's Awakening (USA, Europe)
|
||||
{ 0x9A193109, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) },
|
||||
|
||||
// Magnetic Soccer (Europe)
|
||||
{ 0x6735A1F5, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 28) },
|
||||
|
||||
// Mario & Yoshi (Europe)
|
||||
{ 0xEC14B007, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(18, 4, 4) },
|
||||
|
||||
// Mario no Picross (Japan)
|
||||
{ 0x602C2371, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
|
||||
|
||||
// Mario's Picross (USA, Europe)
|
||||
{ 0x725BBFF6, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
|
||||
|
||||
// Mega Man - Dr. Wily's Revenge (Europe)
|
||||
{ 0xB2FE1EDB, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
|
||||
|
||||
// Mega Man II (Europe)
|
||||
{ 0xC5EE1580, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
|
||||
|
||||
// Mega Man III (Europe)
|
||||
{ 0x88249B90, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
|
||||
|
||||
// Metroid II - Return of Samus (World)
|
||||
{ 0xBDCCC648, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 25, 3) },
|
||||
|
||||
// Moguranya (Japan)
|
||||
{ 0x41C1D13C, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 16, 16) },
|
||||
|
||||
// Mole Mania (USA, Europe)
|
||||
{ 0x32E8EEA3, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 16, 16) },
|
||||
|
||||
// Mystic Quest (Europe)
|
||||
{ 0x8DC57012, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 28) },
|
||||
|
||||
// Mystic Quest (France)
|
||||
{ 0x09728780, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 28) },
|
||||
|
||||
// Mystic Quest (Germany)
|
||||
{ 0x6F8568A8, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 28) },
|
||||
|
||||
// Nigel Mansell's World Championship Racing (Europe)
|
||||
{ 0xAC2D636D, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
|
||||
|
||||
// Nintendo World Cup (USA, Europe)
|
||||
{ 0xB43E44C1, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 4) },
|
||||
|
||||
// Othello (Europe)
|
||||
{ 0x45F34317, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 28) },
|
||||
|
||||
// Pac-In-Time (Europe)
|
||||
{ 0x8C608574, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(29, 4, 28) },
|
||||
|
||||
// Picross 2 (Japan)
|
||||
{ 0xBA91DDD8, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
|
||||
|
||||
// Pinocchio (Europe)
|
||||
{ 0x849C74C0, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 2, 17) },
|
||||
|
||||
// Play Action Football (USA)
|
||||
{ 0x2B703514, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 4) },
|
||||
|
||||
// Pocket Bomberman (Europe)
|
||||
{ 0x9C5E0D5E, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 17, 17) },
|
||||
|
||||
// Pocket Camera (Japan) (Rev A)
|
||||
{ 0x211A85AC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(26, 26, 26) },
|
||||
|
||||
// Pocket Monsters - Aka (Japan)
|
||||
{ 0x29D07340, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) },
|
||||
|
||||
// Pocket Monsters - Aka (Japan) (Rev A)
|
||||
{ 0x6BB566EC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) },
|
||||
|
||||
// Pocket Monsters - Ao (Japan)
|
||||
{ 0x65EF364B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 28) },
|
||||
|
||||
// Pocket Monsters - Midori (Japan)
|
||||
{ 0x923D46DD, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(29, 4, 29) },
|
||||
|
||||
// Pocket Monsters - Midori (Japan) (Rev A)
|
||||
{ 0x6C926BFF, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(29, 4, 29) },
|
||||
|
||||
// Pocket Monsters - Pikachu (Japan)
|
||||
{ 0xF52AD7C1, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 24) },
|
||||
|
||||
// Pocket Monsters - Pikachu (Japan) (Rev A)
|
||||
{ 0x0B54FAEB, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 24) },
|
||||
|
||||
// Pocket Monsters - Pikachu (Japan) (Rev B)
|
||||
{ 0x9A161366, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 24) },
|
||||
|
||||
// Pocket Monsters - Pikachu (Japan) (Rev C)
|
||||
{ 0x8E1C14E4, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 24) },
|
||||
|
||||
// Pokemon - Blaue Edition (Germany)
|
||||
{ 0x6C3587F2, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 28) },
|
||||
|
||||
// Pokemon - Blue Version (USA, Europe)
|
||||
{ 0x28323CE0, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 28) },
|
||||
|
||||
// Pokemon - Edicion Azul (Spain)
|
||||
{ 0x93FCE15B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 28) },
|
||||
|
||||
// Pokemon - Edicion Roja (Spain)
|
||||
{ 0xFD20BB1C, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) },
|
||||
|
||||
// Pokemon - Red Version (USA, Europe)
|
||||
{ 0xCC25454F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) },
|
||||
|
||||
// Pokemon - Rote Edition (Germany)
|
||||
{ 0xE5DD23CE, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) },
|
||||
|
||||
// Pokemon - Version Bleue (France)
|
||||
{ 0x98BFEC5A, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 28) },
|
||||
|
||||
// Pokemon - Version Rouge (France)
|
||||
{ 0x1D6D8022, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) },
|
||||
|
||||
// Pokemon - Versione Blu (Italy)
|
||||
{ 0x7864DECC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 28) },
|
||||
|
||||
// Pokemon - Versione Rossa (Italy)
|
||||
{ 0xFE2A3F93, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) },
|
||||
|
||||
// QIX (World)
|
||||
{ 0x5EECB346, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 22) },
|
||||
|
||||
// Radar Mission (Japan)
|
||||
{ 0xD03B1A15, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 16, 8) },
|
||||
|
||||
// Radar Mission (USA, Europe)
|
||||
{ 0xCEDD9FEB, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 16, 8) },
|
||||
|
||||
// Soccer (Europe)
|
||||
{ 0xB0274CDA, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(14, 31, 0) },
|
||||
|
||||
// SolarStriker (World)
|
||||
{ 0x981620E7, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(27, 27, 27) },
|
||||
|
||||
// Space Invaders (Europe)
|
||||
{ 0x3B032784, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(27, 27, 27) },
|
||||
|
||||
// Space Invaders (USA)
|
||||
{ 0x63A767E2, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(27, 27, 27) },
|
||||
|
||||
// Star Wars (USA, Europe) (Rev A)
|
||||
{ 0x44CE17EE, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 3, 28) },
|
||||
|
||||
// Street Fighter II (USA)
|
||||
{ 0xC512D0B1, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
|
||||
|
||||
// Street Fighter II (USA, Europe) (Rev A)
|
||||
{ 0x79E16545, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
|
||||
|
||||
// Super Donkey Kong GB (Japan)
|
||||
{ 0x940D4974, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(13, 17, 4) },
|
||||
|
||||
// Super Mario Land (World)
|
||||
{ 0x6C0ACA9F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(11, 32, 32) },
|
||||
|
||||
// Super Mario Land (World) (Rev A)
|
||||
{ 0xCA117ACC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(11, 32, 32) },
|
||||
|
||||
// Super Mario Land 2 - 6 Golden Coins (USA, Europe) (Rev A)
|
||||
{ 0x423E09E6, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(10, 16, 28) },
|
||||
|
||||
// Super Mario Land 2 - 6 Golden Coins (USA, Europe) (Rev B)
|
||||
{ 0x445A0358, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(10, 16, 28) },
|
||||
|
||||
// Super Mario Land 2 - 6 Golden Coins (USA, Europe)
|
||||
{ 0xDE2960A1, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(10, 16, 28) },
|
||||
|
||||
// Super Mario Land 2 - 6-tsu no Kinka (Japan)
|
||||
{ 0xD47CED78, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(10, 16, 28) },
|
||||
|
||||
// Super Mario Land 2 - 6-tsu no Kinka (Japan) (Rev A)
|
||||
{ 0xA4B4F9F9, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(10, 16, 28) },
|
||||
|
||||
// Super Mario Land 2 - 6-tsu no Kinka (Japan) (Rev B)
|
||||
{ 0x5842F25D, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(10, 16, 28) },
|
||||
|
||||
// Super R.C. Pro-Am (USA, Europe)
|
||||
{ 0x8C39B1C8, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
|
||||
|
||||
// Tennis (World)
|
||||
{ 0xD2BEBF08, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(14, 31, 0) },
|
||||
|
||||
// Tetris (World)
|
||||
{ 0xE906C6A6, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 24) },
|
||||
|
||||
// Tetris (World) (Rev A)
|
||||
{ 0x4674B43F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 24) },
|
||||
|
||||
// Tetris 2 (USA)
|
||||
{ 0x687505F1, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 22) },
|
||||
|
||||
// Tetris 2 (USA, Europe)
|
||||
{ 0x6761459F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 22) },
|
||||
|
||||
// Tetris Attack (USA)
|
||||
{ 0x00E9474B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(18, 18, 22) },
|
||||
|
||||
// Tetris Blast (USA, Europe)
|
||||
{ 0xDDDEEEDE, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(20, 20, 20) },
|
||||
|
||||
// Tetris Attack (USA, Europe) (Rev A)
|
||||
{ 0x6628C535, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(18, 18, 22) },
|
||||
|
||||
// Tetris Flash (Japan)
|
||||
{ 0xED669A78, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 22) },
|
||||
|
||||
// Top Rank Tennis (USA)
|
||||
{ 0xA6497CC0, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(14, 31, 0) },
|
||||
|
||||
// Top Ranking Tennis (Europe)
|
||||
{ 0x62C12E05, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(14, 31, 0) },
|
||||
|
||||
// Toy Story (Europe)
|
||||
{ 0x67066E28, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 4) },
|
||||
|
||||
// Vegas Stakes (USA, Europe)
|
||||
{ 0x80CB217F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 28) },
|
||||
|
||||
// Wario Land - Super Mario Land 3 (World)
|
||||
{ 0xF1EA10E9, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 16, 22) },
|
||||
|
||||
// Wario Land II (USA, Europe)
|
||||
{ 0xD56A50A1, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 0, 28) },
|
||||
|
||||
// Wave Race (USA, Europe)
|
||||
{ 0x52A6E4CC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 23) },
|
||||
|
||||
// X (Japan)
|
||||
{ 0xFED4C47F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(5, 5, 5) },
|
||||
|
||||
// Yakuman (Japan)
|
||||
{ 0x40604F17, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
|
||||
|
||||
// Yakuman (Japan) (Rev A)
|
||||
{ 0x2959ACFC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
|
||||
|
||||
// Yoshi (USA)
|
||||
{ 0xAB1605B9, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(18, 4, 4) },
|
||||
|
||||
// Yoshi no Cookie (Japan)
|
||||
{ 0x841753DA, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(20, 20, 22) },
|
||||
|
||||
// Yoshi no Panepon (Japan)
|
||||
{ 0xAA1AD903, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(18, 18, 22) },
|
||||
|
||||
// Yoshi no Tamago (Japan)
|
||||
{ 0xD4098A6B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(18, 4, 4) },
|
||||
|
||||
// Yoshi's Cookie (USA, Europe)
|
||||
{ 0x940EDD87, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(20, 20, 22) },
|
||||
|
||||
// Zelda no Densetsu - Yume o Miru Shima (Japan)
|
||||
{ 0x259C9A82, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) },
|
||||
|
||||
// Zelda no Densetsu - Yume o Miru Shima (Japan) (Rev A)
|
||||
{ 0x61F269CD, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) },
|
||||
};
|
||||
|
||||
static const struct GBCartridgeOverride _overrides[] = {
|
||||
// Pokemon Spaceworld 1997 demo
|
||||
{ 0x232a067d, GB_MODEL_AUTODETECT, GB_MBC3_RTC, { 0 } }, // Gold (debug)
|
||||
|
@ -21,6 +497,17 @@ static const struct GBCartridgeOverride _overrides[] = {
|
|||
{ 0, 0, 0, { 0 } }
|
||||
};
|
||||
|
||||
bool GBOverrideColorFind(struct GBCartridgeOverride* override) {
|
||||
int i;
|
||||
for (i = 0; _colorOverrides[i].headerCrc32; ++i) {
|
||||
if (override->headerCrc32 == _colorOverrides[i].headerCrc32) {
|
||||
memcpy(override->gbColors, _colorOverrides[i].gbColors, sizeof(override->gbColors));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GBOverrideFind(const struct Configuration* config, struct GBCartridgeOverride* override) {
|
||||
override->model = GB_MODEL_AUTODETECT;
|
||||
override->mbc = GB_MBC_AUTODETECT;
|
||||
|
|
|
@ -138,7 +138,7 @@ bool GBDeserialize(struct GB* gb, const struct GBSerializedState* state) {
|
|||
if (error) {
|
||||
return false;
|
||||
}
|
||||
gb->timing.root = NULL;
|
||||
mTimingClear(&gb->timing);
|
||||
LOAD_32LE(gb->timing.masterCycles, 0, &state->masterCycles);
|
||||
|
||||
gb->cpu->a = state->cpu.a;
|
||||
|
|
|
@ -182,7 +182,7 @@ void _dmaEvent(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
|||
dma->nextCount = 0;
|
||||
bool noRepeat = !GBADMARegisterIsRepeat(dma->reg);
|
||||
noRepeat |= GBADMARegisterGetTiming(dma->reg) == GBA_DMA_TIMING_NOW;
|
||||
noRepeat |= memory->activeDMA == 3 && GBADMARegisterGetTiming(dma->reg) == GBA_DMA_TIMING_CUSTOM;
|
||||
noRepeat |= memory->activeDMA == 3 && GBADMARegisterGetTiming(dma->reg) == GBA_DMA_TIMING_CUSTOM && gba->video.vcount == VIDEO_VERTICAL_PIXELS + 1;
|
||||
if (noRepeat) {
|
||||
dma->reg = GBADMARegisterClearEnable(dma->reg);
|
||||
|
||||
|
@ -237,9 +237,6 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) {
|
|||
|
||||
gba->cpuBlocked = true;
|
||||
if (info->count == info->nextCount) {
|
||||
if (sourceRegion < REGION_CART0 || destRegion < REGION_CART0) {
|
||||
cycles += 2;
|
||||
}
|
||||
if (width == 4) {
|
||||
cycles += memory->waitstatesNonseq32[sourceRegion] + memory->waitstatesNonseq32[destRegion];
|
||||
} else {
|
||||
|
@ -302,6 +299,9 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) {
|
|||
info->nextDest = dest;
|
||||
if (!wordsRemaining) {
|
||||
info->nextCount |= 0x80000000;
|
||||
if (sourceRegion < REGION_CART0 || destRegion < REGION_CART0) {
|
||||
info->when += 2;
|
||||
}
|
||||
}
|
||||
GBADMAUpdate(gba);
|
||||
}
|
||||
|
|
|
@ -254,7 +254,8 @@ void GBASkipBIOS(struct GBA* gba) {
|
|||
} else {
|
||||
cpu->gprs[ARM_PC] = BASE_WORKING_RAM;
|
||||
}
|
||||
gba->memory.io[REG_VCOUNT >> 1] = 0x7E;
|
||||
gba->video.vcount = 0x7D;
|
||||
gba->memory.io[REG_VCOUNT >> 1] = 0x7D;
|
||||
gba->memory.io[REG_POSTFLG >> 1] = 1;
|
||||
ARMWritePC(cpu);
|
||||
}
|
||||
|
|
|
@ -774,7 +774,8 @@ static void _enableBg(struct GBAVideoSoftwareRenderer* renderer, int bg, bool ac
|
|||
if (!active) {
|
||||
renderer->bg[bg].enabled = 0;
|
||||
} else if (!wasActive && active) {
|
||||
if (renderer->nextY == 0) {
|
||||
if (renderer->nextY == 0 || GBARegisterDISPCNTGetMode(renderer->dispcnt) > 2) {
|
||||
// TODO: Investigate in more depth how switching background works in different modes
|
||||
renderer->bg[bg].enabled = 4;
|
||||
} else {
|
||||
renderer->bg[bg].enabled = 1;
|
||||
|
|
|
@ -132,7 +132,7 @@ bool GBADeserialize(struct GBA* gba, const struct GBASerializedState* state) {
|
|||
if (error) {
|
||||
return false;
|
||||
}
|
||||
gba->timing.root = NULL;
|
||||
mTimingClear(&gba->timing);
|
||||
LOAD_32(gba->timing.masterCycles, 0, &state->masterCycles);
|
||||
|
||||
size_t i;
|
||||
|
|
|
@ -186,11 +186,17 @@ class Core(object):
|
|||
|
||||
@protected
|
||||
def load_bios(self, vfile, id=0):
|
||||
return bool(self._core.loadBIOS(self._core, vfile.handle, id))
|
||||
res = bool(self._core.loadBIOS(self._core, vfile.handle, id))
|
||||
if res:
|
||||
vfile._claimed = True
|
||||
return res
|
||||
|
||||
@protected
|
||||
def load_save(self, vfile):
|
||||
return bool(self._core.loadSave(self._core, vfile.handle))
|
||||
res = bool(self._core.loadSave(self._core, vfile.handle))
|
||||
if res:
|
||||
vfile._claimed = True
|
||||
return res
|
||||
|
||||
@protected
|
||||
def load_temporary_save(self, vfile):
|
||||
|
|
|
@ -27,6 +27,7 @@ class GB(Core):
|
|||
self.sprites = GBObjs(self)
|
||||
self.cpu = LR35902Core(self._core.cpu)
|
||||
self.memory = None
|
||||
self._link = None
|
||||
|
||||
@needs_reset
|
||||
def _init_cache(self, cache):
|
||||
|
@ -43,10 +44,13 @@ class GB(Core):
|
|||
self.memory = GBMemory(self._core)
|
||||
|
||||
def attach_sio(self, link):
|
||||
self._link = link
|
||||
lib.GBSIOSetDriver(ffi.addressof(self._native.sio), link._native)
|
||||
|
||||
def __del__(self):
|
||||
lib.GBSIOSetDriver(ffi.addressof(self._native.sio), ffi.NULL)
|
||||
if self._link:
|
||||
lib.GBSIOSetDriver(ffi.addressof(self._native.sio), ffi.NULL)
|
||||
self._link = None
|
||||
|
||||
|
||||
create_callback("GBSIOPythonDriver", "init")
|
||||
|
|
|
@ -112,11 +112,16 @@ class VFile:
|
|||
def __init__(self, vf, _no_gc=None):
|
||||
self.handle = vf
|
||||
self._no_gc = _no_gc
|
||||
self._claimed = False
|
||||
|
||||
def __del__(self):
|
||||
self.close()
|
||||
if not self._claimed:
|
||||
self.close()
|
||||
|
||||
def close(self):
|
||||
if self._claimed:
|
||||
return False
|
||||
self._claimed = True
|
||||
return bool(self.handle.close(self.handle))
|
||||
|
||||
def seek(self, offset, whence):
|
||||
|
|
|
@ -5,17 +5,31 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "BattleChipView.h"
|
||||
|
||||
#include "ConfigController.h"
|
||||
#include "CoreController.h"
|
||||
#include "GBAApp.h"
|
||||
#include "ShortcutController.h"
|
||||
#include "Window.h"
|
||||
|
||||
#include <QtAlgorithms>
|
||||
#include <QFile>
|
||||
#include <QFontMetrics>
|
||||
#include <QMessageBox>
|
||||
#include <QMultiMap>
|
||||
#include <QResource>
|
||||
#include <QSettings>
|
||||
#include <QStringList>
|
||||
|
||||
using namespace QGBA;
|
||||
|
||||
BattleChipView::BattleChipView(std::shared_ptr<CoreController> controller, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
BattleChipView::BattleChipView(std::shared_ptr<CoreController> controller, Window* window, QWidget* parent)
|
||||
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
|
||||
, m_controller(controller)
|
||||
, m_window(window)
|
||||
{
|
||||
QResource::registerResource(GBAApp::dataDir() + "/chips.rcc", "/exe");
|
||||
QResource::registerResource(ConfigController::configDir() + "/chips.rcc", "/exe");
|
||||
|
||||
m_ui.setupUi(this);
|
||||
|
||||
char title[9];
|
||||
|
@ -25,6 +39,13 @@ BattleChipView::BattleChipView(std::shared_ptr<CoreController> controller, QWidg
|
|||
core->getGameCode(core, title);
|
||||
QString qtitle(title);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
int size = QFontMetrics(QFont()).height() / ((int) ceil(devicePixelRatioF()) * 12);
|
||||
#else
|
||||
int size = QFontMetrics(QFont()).height() / (devicePixelRatio() * 12);
|
||||
#endif
|
||||
m_ui.chipList->setIconSize(m_ui.chipList->iconSize() * size);
|
||||
m_ui.chipList->setGridSize(m_ui.chipList->gridSize() * size);
|
||||
|
||||
connect(m_ui.chipId, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), m_ui.inserted, [this]() {
|
||||
m_ui.inserted->setChecked(Qt::Unchecked);
|
||||
|
@ -34,7 +55,13 @@ BattleChipView::BattleChipView(std::shared_ptr<CoreController> controller, QWidg
|
|||
});
|
||||
|
||||
connect(m_ui.inserted, &QAbstractButton::toggled, this, &BattleChipView::insertChip);
|
||||
connect(m_ui.insert, &QAbstractButton::clicked, this, &BattleChipView::reinsert);
|
||||
connect(m_ui.add, &QAbstractButton::clicked, this, &BattleChipView::addChip);
|
||||
connect(m_ui.remove, &QAbstractButton::clicked, this, &BattleChipView::removeChip);
|
||||
connect(controller.get(), &CoreController::stopping, this, &QWidget::close);
|
||||
connect(m_ui.save, &QAbstractButton::clicked, this, &BattleChipView::saveDeck);
|
||||
connect(m_ui.load, &QAbstractButton::clicked, this, &BattleChipView::loadDeck);
|
||||
connect(m_ui.buttonBox->button(QDialogButtonBox::Reset), &QAbstractButton::clicked, m_ui.chipList, &QListWidget::clear);
|
||||
|
||||
connect(m_ui.gateBattleChip, &QAbstractButton::toggled, this, [this](bool on) {
|
||||
if (on) {
|
||||
|
@ -56,6 +83,16 @@ BattleChipView::BattleChipView(std::shared_ptr<CoreController> controller, QWidg
|
|||
}
|
||||
});
|
||||
|
||||
connect(m_controller.get(), &CoreController::frameAvailable, this, &BattleChipView::advanceFrameCounter);
|
||||
|
||||
connect(m_ui.chipList, &QListWidget::itemClicked, this, [this](QListWidgetItem* item) {
|
||||
QVariant chip = item->data(Qt::UserRole);
|
||||
bool blocked = m_ui.chipId->blockSignals(true);
|
||||
m_ui.chipId->setValue(chip.toInt());
|
||||
m_ui.chipId->blockSignals(blocked);
|
||||
reinsert();
|
||||
});
|
||||
|
||||
m_controller->attachBattleChipGate();
|
||||
setFlavor(4);
|
||||
if (qtitle.startsWith("AGB-B4B") || qtitle.startsWith("AGB-B4W") || qtitle.startsWith("AGB-BR4") || qtitle.startsWith("AGB-BZ3")) {
|
||||
|
@ -77,6 +114,9 @@ void BattleChipView::setFlavor(int flavor) {
|
|||
}
|
||||
|
||||
void BattleChipView::insertChip(bool inserted) {
|
||||
bool blocked = m_ui.inserted->blockSignals(true);
|
||||
m_ui.inserted->setChecked(inserted);
|
||||
m_ui.inserted->blockSignals(blocked);
|
||||
if (inserted) {
|
||||
m_controller->setBattleChipId(m_ui.chipId->value());
|
||||
} else {
|
||||
|
@ -84,16 +124,53 @@ void BattleChipView::insertChip(bool inserted) {
|
|||
}
|
||||
}
|
||||
|
||||
void BattleChipView::reinsert() {
|
||||
if (m_ui.inserted->isChecked()) {
|
||||
insertChip(false);
|
||||
m_next = true;
|
||||
m_frameCounter = UNINSERTED_TIME;
|
||||
} else {
|
||||
insertChip(true);
|
||||
}
|
||||
m_window->setWindowState(m_window->windowState() & ~Qt::WindowActive);
|
||||
m_window->setWindowState(m_window->windowState() | Qt::WindowActive);
|
||||
}
|
||||
|
||||
void BattleChipView::addChip() {
|
||||
int insertedChip = m_ui.chipId->value();
|
||||
if (insertedChip < 1) {
|
||||
return;
|
||||
}
|
||||
addChipId(insertedChip);
|
||||
}
|
||||
|
||||
void BattleChipView::addChipId(int id) {
|
||||
QListWidgetItem* add = new QListWidgetItem(m_chipIdToName[id]);
|
||||
add->setData(Qt::UserRole, id);
|
||||
QString path = QString(":/exe/exe%1/%2.png").arg(m_flavor).arg(id, 3, 10, QLatin1Char('0'));
|
||||
if (!QFile(path).exists()) {
|
||||
path = QString(":/exe/exe%1/placeholder.png").arg(m_flavor);
|
||||
}
|
||||
add->setIcon(QPixmap(path).scaled(m_ui.chipList->iconSize()));
|
||||
m_ui.chipList->addItem(add);
|
||||
}
|
||||
|
||||
void BattleChipView::removeChip() {
|
||||
qDeleteAll(m_ui.chipList->selectedItems());
|
||||
}
|
||||
|
||||
void BattleChipView::loadChipNames(int flavor) {
|
||||
QStringList chipNames;
|
||||
chipNames.append(tr("(None)"));
|
||||
|
||||
m_chipIndexToId.clear();
|
||||
m_chipIdToName.clear();
|
||||
if (flavor == GBA_FLAVOR_BEAST_LINK_GATE_US) {
|
||||
flavor = GBA_FLAVOR_BEAST_LINK_GATE;
|
||||
}
|
||||
m_flavor = flavor;
|
||||
|
||||
QFile file(QString(":/res/chip-names-%1.txt").arg(flavor));
|
||||
QFile file(QString(":/exe/exe%1/chip-names.txt").arg(flavor));
|
||||
file.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
int id = 0;
|
||||
while (true) {
|
||||
|
@ -105,10 +182,71 @@ void BattleChipView::loadChipNames(int flavor) {
|
|||
if (line.trimmed().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
QString name = QString::fromUtf8(line).trimmed();
|
||||
m_chipIndexToId[chipNames.length()] = id;
|
||||
chipNames.append(QString::fromUtf8(line).trimmed());
|
||||
m_chipIdToName[id] = name;
|
||||
chipNames.append(name);
|
||||
}
|
||||
|
||||
m_ui.chipName->clear();
|
||||
m_ui.chipName->addItems(chipNames);
|
||||
}
|
||||
}
|
||||
|
||||
void BattleChipView::advanceFrameCounter() {
|
||||
if (m_frameCounter == 0) {
|
||||
insertChip(m_next);
|
||||
}
|
||||
if (m_frameCounter >= 0) {
|
||||
--m_frameCounter;
|
||||
}
|
||||
}
|
||||
|
||||
void BattleChipView::saveDeck() {
|
||||
QString filename = GBAApp::app()->getSaveFileName(this, tr("Select deck file"), tr(("BattleChip deck file (*.deck)")));
|
||||
if (filename.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList deck;
|
||||
for (int i = 0; i < m_ui.chipList->count(); ++i) {
|
||||
deck.append(m_ui.chipList->item(i)->data(Qt::UserRole).toString());
|
||||
}
|
||||
|
||||
QSettings ini(filename, QSettings::IniFormat);
|
||||
ini.clear();
|
||||
ini.beginGroup("BattleChipDeck");
|
||||
ini.setValue("version", m_flavor);
|
||||
ini.setValue("deck", deck.join(','));
|
||||
ini.sync();
|
||||
}
|
||||
|
||||
void BattleChipView::loadDeck() {
|
||||
QString filename = GBAApp::app()->getOpenFileName(this, tr("Select deck file"), tr(("BattleChip deck file (*.deck)")));
|
||||
if (filename.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QSettings ini(filename, QSettings::IniFormat);
|
||||
ini.beginGroup("BattleChipDeck");
|
||||
int flavor = ini.value("version").toInt();
|
||||
if (flavor != m_flavor) {
|
||||
QMessageBox* error = new QMessageBox(this);
|
||||
error->setIcon(QMessageBox::Warning);
|
||||
error->setStandardButtons(QMessageBox::Ok);
|
||||
error->setWindowTitle(tr("Incompatible deck"));
|
||||
error->setText(tr("The selected deck is not compatible with this Chip Gate"));
|
||||
error->setAttribute(Qt::WA_DeleteOnClose);
|
||||
error->show();
|
||||
return;
|
||||
}
|
||||
|
||||
m_ui.chipList->clear();
|
||||
QStringList deck = ini.value("deck").toString().split(',');
|
||||
for (const auto& item : deck) {
|
||||
bool ok;
|
||||
int id = item.toInt(&ok);
|
||||
if (ok) {
|
||||
addChipId(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,25 +16,45 @@
|
|||
namespace QGBA {
|
||||
|
||||
class CoreController;
|
||||
class Window;
|
||||
|
||||
class BattleChipView : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BattleChipView(std::shared_ptr<CoreController> controller, QWidget* parent = nullptr);
|
||||
BattleChipView(std::shared_ptr<CoreController> controller, Window* window, QWidget* parent = nullptr);
|
||||
~BattleChipView();
|
||||
|
||||
public slots:
|
||||
void setFlavor(int);
|
||||
void insertChip(bool);
|
||||
void reinsert();
|
||||
|
||||
private slots:
|
||||
void advanceFrameCounter();
|
||||
void addChip();
|
||||
void addChipId(int);
|
||||
void removeChip();
|
||||
|
||||
void saveDeck();
|
||||
void loadDeck();
|
||||
|
||||
private:
|
||||
static const int UNINSERTED_TIME = 10;
|
||||
|
||||
void loadChipNames(int);
|
||||
|
||||
Ui::BattleChipView m_ui;
|
||||
|
||||
QMap<int, int> m_chipIndexToId;
|
||||
QMap<int, QString> m_chipIdToName;
|
||||
std::shared_ptr<CoreController> m_controller;
|
||||
int m_flavor;
|
||||
|
||||
int m_frameCounter = -1;
|
||||
bool m_next = false;
|
||||
|
||||
Window* m_window;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,90 +6,275 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>426</width>
|
||||
<height>278</height>
|
||||
<width>630</width>
|
||||
<height>722</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>BattleChip Gate</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="5" column="1">
|
||||
<widget class="QCheckBox" name="inserted">
|
||||
<property name="text">
|
||||
<string>Inserted</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Chip ID</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Chip name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QSpinBox" name="chipId">
|
||||
<property name="maximum">
|
||||
<number>65535</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="chipName"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Gate type</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QRadioButton" name="gateProgress">
|
||||
<property name="text">
|
||||
<string>Progress &Gate</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">gate</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QRadioButton" name="gateBattleChip">
|
||||
<property name="text">
|
||||
<string>Ba&ttleChip Gate</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,0,0,0,0,0">
|
||||
<item>
|
||||
<widget class="QListWidget" name="chipList">
|
||||
<property name="acceptDrops">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::InternalMove</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::MoveAction</enum>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>56</width>
|
||||
<height>48</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="movement">
|
||||
<enum>QListView::Static</enum>
|
||||
</property>
|
||||
<property name="isWrapping" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="resizeMode">
|
||||
<enum>QListView::Adjust</enum>
|
||||
</property>
|
||||
<property name="gridSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>72</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="viewMode">
|
||||
<enum>QListView::IconMode</enum>
|
||||
</property>
|
||||
<property name="uniformItemSizes">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="selectionRectVisible">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">gate</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QRadioButton" name="gateBeastLink">
|
||||
<property name="text">
|
||||
<string>Beast &Link Gate</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">gate</string>
|
||||
</attribute>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,0">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_4">
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="chipName"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Chip name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="insert">
|
||||
<property name="text">
|
||||
<string>Insert</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="save">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="load">
|
||||
<property name="text">
|
||||
<string>Load</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="add">
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="remove">
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="advanced" native="true">
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Gate type</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QRadioButton" name="gateBattleChip">
|
||||
<property name="text">
|
||||
<string>Ba&ttleChip Gate</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QRadioButton" name="gateProgress">
|
||||
<property name="text">
|
||||
<string>Progress &Gate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QRadioButton" name="gateBeastLink">
|
||||
<property name="text">
|
||||
<string>Beast &Link Gate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_5">
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="inserted">
|
||||
<property name="text">
|
||||
<string>Inserted</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="chipId">
|
||||
<property name="maximum">
|
||||
<number>65535</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Chip ID</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showAdvanced">
|
||||
<property name="text">
|
||||
<string>Show advanced</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close|QDialogButtonBox::Reset</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<buttongroups>
|
||||
<buttongroup name="gate"/>
|
||||
</buttongroups>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>BattleChipView</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>416</x>
|
||||
<y>690</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>314</x>
|
||||
<y>360</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>showAdvanced</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>advanced</receiver>
|
||||
<slot>setVisible(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>109</x>
|
||||
<y>34</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>396</x>
|
||||
<y>654</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>chipList</sender>
|
||||
<signal>indexesMoved(QModelIndexList)</signal>
|
||||
<receiver>chipList</receiver>
|
||||
<slot>doItemsLayout()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>314</x>
|
||||
<y>203</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>314</x>
|
||||
<y>203</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
|
|
|
@ -112,6 +112,8 @@ ConfigController::ConfigController(QObject* parent)
|
|||
m_opts.lockAspectRatio = true;
|
||||
mCoreConfigLoad(&m_config);
|
||||
mCoreConfigLoadDefaults(&m_config, &m_opts);
|
||||
mCoreConfigSetDefaultIntValue(&m_config, "sgb.borders", 1);
|
||||
mCoreConfigSetDefaultIntValue(&m_config, "useCgbColors", 1);
|
||||
mCoreConfigMap(&m_config, &m_opts);
|
||||
}
|
||||
|
||||
|
|
|
@ -357,6 +357,7 @@ void SettingsView::updateConfig() {
|
|||
saveSetting("ds.bios7", m_ui.dsBios7);
|
||||
saveSetting("ds.bios9", m_ui.dsBios9);
|
||||
saveSetting("ds.firmware", m_ui.dsFirmware);
|
||||
saveSetting("useCgbColors", m_ui.useCgbColors);
|
||||
saveSetting("useBios", m_ui.useBios);
|
||||
saveSetting("skipBios", m_ui.skipBios);
|
||||
saveSetting("audioBuffers", m_ui.audioBufferSize);
|
||||
|
@ -497,6 +498,7 @@ void SettingsView::reloadConfig() {
|
|||
loadSetting("ds.bios7", m_ui.dsBios7);
|
||||
loadSetting("ds.bios9", m_ui.dsBios9);
|
||||
loadSetting("ds.firmware", m_ui.dsFirmware);
|
||||
loadSetting("useCgbColors", m_ui.useCgbColors, true);
|
||||
loadSetting("useBios", m_ui.useBios);
|
||||
loadSetting("skipBios", m_ui.skipBios);
|
||||
loadSetting("audioBuffers", m_ui.audioBufferSize);
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
<item row="1" column="1">
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<property name="currentIndex">
|
||||
<number>5</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="av">
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
|
@ -1295,7 +1295,7 @@
|
|||
<item>
|
||||
<widget class="QTableView" name="loggingView">
|
||||
<attribute name="horizontalHeaderDefaultSectionSize">
|
||||
<number>0</number>
|
||||
<number>77</number>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderMinimumSectionSize">
|
||||
<number>0</number>
|
||||
|
@ -1620,28 +1620,28 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<item row="8" column="1">
|
||||
<widget class="QCheckBox" name="sgbBorders">
|
||||
<property name="text">
|
||||
<string>Super Game Boy borders</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="2">
|
||||
<item row="9" column="0" colspan="2">
|
||||
<widget class="Line" name="line_11">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_27">
|
||||
<property name="text">
|
||||
<string>Camera driver:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<item row="10" column="1">
|
||||
<widget class="QComboBox" name="cameraDriver">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
|
@ -1745,6 +1745,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QCheckBox" name="useCgbColors">
|
||||
<property name="text">
|
||||
<string>Use GBC colors in GB games</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
|
|
|
@ -107,6 +107,7 @@ Window::Window(CoreManager* manager, ConfigController* config, int playerId, QWi
|
|||
|
||||
m_logo.setDevicePixelRatio(m_screenWidget->devicePixelRatio());
|
||||
m_logo = m_logo; // Free memory left over in old pixmap
|
||||
setWindowIcon(m_logo);
|
||||
|
||||
#if defined(M_CORE_GBA)
|
||||
float i = 2;
|
||||
|
@ -1165,7 +1166,7 @@ void Window::setupMenu(QMenuBar* menubar) {
|
|||
addControlledAction(quickLoadMenu, quickLoad, "quickLoad");
|
||||
|
||||
QAction* quickSave = new QAction(tr("Save recent"), quickSaveMenu);
|
||||
connect(quickLoad, &QAction::triggered, [this] {
|
||||
connect(quickSave, &QAction::triggered, [this] {
|
||||
m_controller->saveState();
|
||||
});
|
||||
m_gameActions.append(quickSave);
|
||||
|
@ -1433,7 +1434,7 @@ void Window::setupMenu(QMenuBar* menubar) {
|
|||
|
||||
#ifdef M_CORE_GBA
|
||||
QAction* bcGate = new QAction(tr("BattleChip Gate..."), emulationMenu);
|
||||
connect(bcGate, &QAction::triggered, openControllerTView<BattleChipView>());
|
||||
connect(bcGate, &QAction::triggered, openControllerTView<BattleChipView>(this));
|
||||
addControlledAction(emulationMenu, bcGate, "bcGate");
|
||||
m_platformActions.append(qMakePair(bcGate, SUPPORT_GBA));
|
||||
m_gameActions.append(bcGate);
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<!DOCTYPE RCC>
|
||||
<RCC version="1.0">
|
||||
<qresource>
|
||||
<file>../../../res/medusa-bg.jpg</file>
|
||||
<file>../../../res/patrons.txt</file>
|
||||
<file>../../../res/no-cam.png</file>
|
||||
<file>input/default-profiles.ini</file>
|
||||
<file>../../../res/chip-names-4.txt</file>
|
||||
<file>../../../res/chip-names-5.txt</file>
|
||||
<file>../../../res/chip-names-6.txt</file>
|
||||
<file>../../../res/medusa-bg.jpg</file>
|
||||
<file>../../../res/patrons.txt</file>
|
||||
<file>../../../res/no-cam.png</file>
|
||||
<file>input/default-profiles.ini</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
<qresource prefix="/exe">
|
||||
<file alias="exe4/chip-names.txt">../../../res/exe4/chip-names.txt</file>
|
||||
<file alias="exe4/placeholder.png">../../../res/exe4/placeholder.png</file>
|
||||
<file alias="exe5/chip-names.txt">../../../res/exe5/chip-names.txt</file>
|
||||
<file alias="exe5/placeholder.png">../../../res/exe5/placeholder.png</file>
|
||||
<file alias="exe6/chip-names.txt">../../../res/exe6/chip-names.txt</file>
|
||||
<file alias="exe6/placeholder.png">../../../res/exe6/placeholder.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue