mirror of
https://github.com/libretro/mgba.git
synced 2025-02-22 16:51:25 +00:00
Merge from upstream, fixes cheevos.
This commit is contained in:
commit
5473b3f705
25
src/gb/gb.c
25
src/gb/gb.c
@ -15,6 +15,8 @@
|
||||
#include "util/patch.h"
|
||||
#include "util/vfs.h"
|
||||
|
||||
#define CLEANUP_THRESHOLD 15
|
||||
|
||||
const uint32_t CGB_LR35902_FREQUENCY = 0x800000;
|
||||
const uint32_t SGB_LR35902_FREQUENCY = 0x418B1E;
|
||||
|
||||
@ -174,6 +176,27 @@ void GBResizeSram(struct GB* gb, size_t size) {
|
||||
}
|
||||
}
|
||||
|
||||
void GBSramClean(struct GB* gb, uint32_t frameCount) {
|
||||
// TODO: Share with GBASavedataClean
|
||||
if (!gb->sramVf) {
|
||||
return;
|
||||
}
|
||||
if (gb->sramDirty & GB_SRAM_DIRT_NEW) {
|
||||
gb->sramDirtAge = frameCount;
|
||||
gb->sramDirty &= ~GB_SRAM_DIRT_NEW;
|
||||
if (!(gb->sramDirty & GB_SRAM_DIRT_SEEN)) {
|
||||
gb->sramDirty |= GB_SRAM_DIRT_SEEN;
|
||||
}
|
||||
} else if ((gb->sramDirty & GB_SRAM_DIRT_SEEN) && frameCount - gb->sramDirtAge > CLEANUP_THRESHOLD) {
|
||||
gb->sramDirty = 0;
|
||||
if (gb->memory.sram && gb->sramVf->sync(gb->sramVf, gb->memory.sram, gb->sramSize)) {
|
||||
mLOG(GB_MEM, INFO, "Savedata synced");
|
||||
} else {
|
||||
mLOG(GB_MEM, INFO, "Savedata failed to sync!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GBSavedataMask(struct GB* gb, struct VFile* vf) {
|
||||
GBSramDeinit(gb);
|
||||
gb->sramVf = vf;
|
||||
@ -601,6 +624,8 @@ void GBGetGameCode(struct GB* gb, char* out) {
|
||||
}
|
||||
|
||||
void GBFrameEnded(struct GB* gb) {
|
||||
GBSramClean(gb, gb->video.frameCounter);
|
||||
|
||||
if (gb->cpu->components && gb->cpu->components[CPU_COMPONENT_CHEAT_DEVICE]) {
|
||||
struct mCheatDevice* device = (struct mCheatDevice*) gb->cpu->components[CPU_COMPONENT_CHEAT_DEVICE];
|
||||
size_t i;
|
||||
|
@ -68,6 +68,8 @@ struct GB {
|
||||
struct VFile* sramVf;
|
||||
struct VFile* sramRealVf;
|
||||
uint32_t sramSize;
|
||||
int sramDirty;
|
||||
int32_t sramDirtAge;
|
||||
|
||||
struct mAVStream* stream;
|
||||
|
||||
@ -111,12 +113,13 @@ void GBHalt(struct LR35902Core* cpu);
|
||||
struct VFile;
|
||||
bool GBLoadROM(struct GB* gb, struct VFile* vf);
|
||||
bool GBLoadSave(struct GB* gb, struct VFile* vf);
|
||||
void GBResizeSram(struct GB* gb, size_t size);
|
||||
void GBYankROM(struct GB* gb);
|
||||
void GBUnloadROM(struct GB* gb);
|
||||
|
||||
void GBLoadBIOS(struct GB* gb, struct VFile* vf);
|
||||
|
||||
void GBSramClean(struct GB* gb, uint32_t frameCount);
|
||||
void GBResizeSram(struct GB* gb, size_t size);
|
||||
void GBSavedataMask(struct GB* gb, struct VFile* vf);
|
||||
void GBSavedataUnmask(struct GB* gb);
|
||||
|
||||
@ -127,7 +130,6 @@ bool GBIsROM(struct VFile* vf);
|
||||
void GBGetGameTitle(struct GB* gba, char* out);
|
||||
void GBGetGameCode(struct GB* gba, char* out);
|
||||
|
||||
void GBFrameStarted(struct GB* gb);
|
||||
void GBFrameEnded(struct GB* gb);
|
||||
|
||||
#endif
|
||||
|
@ -220,6 +220,7 @@ void GBStore8(struct LR35902Core* cpu, uint16_t address, int8_t value) {
|
||||
} else if (memory->mbcType == GB_MBC7) {
|
||||
GBMBC7Write(memory, address, value);
|
||||
}
|
||||
gb->sramDirty |= GB_SRAM_DIRT_NEW;
|
||||
return;
|
||||
case GB_REGION_WORKING_RAM_BANK0:
|
||||
case GB_REGION_WORKING_RAM_BANK0 + 2:
|
||||
|
@ -55,6 +55,11 @@ enum {
|
||||
GB_SIZE_HRAM = 0x7F,
|
||||
};
|
||||
|
||||
enum {
|
||||
GB_SRAM_DIRT_NEW = 1,
|
||||
GB_SRAM_DIRT_SEEN = 2
|
||||
};
|
||||
|
||||
struct GBMemory;
|
||||
typedef void (*GBMemoryBankController)(struct GB*, uint16_t address, uint8_t value);
|
||||
|
||||
|
@ -112,7 +112,8 @@ mLOG_DECLARE_CATEGORY(GB_STATE);
|
||||
* | 0x000CD: Palette flags
|
||||
* | bit 0: BCP increment
|
||||
* | bit 1: OCP increment
|
||||
* | bits 2 - 7: Reserved
|
||||
* | bits 2 - 3: Mode
|
||||
* | bits 4 - 7: Reserved
|
||||
* | 0x000CE - 0x000CF: Reserved
|
||||
* | 0x000D0 - 0x000D1: BCP index
|
||||
* | 0x000D1 - 0x000D3: OCP index
|
||||
@ -214,6 +215,7 @@ DECL_BIT(GBSerializedTimerFlags, IrqPending, 0);
|
||||
DECL_BITFIELD(GBSerializedVideoFlags, uint8_t);
|
||||
DECL_BIT(GBSerializedVideoFlags, BcpIncrement, 0);
|
||||
DECL_BIT(GBSerializedVideoFlags, OcpIncrement, 1);
|
||||
DECL_BITS(GBSerializedVideoFlags, Mode, 2, 2);
|
||||
|
||||
DECL_BITFIELD(GBSerializedMBC7Flags, uint8_t);
|
||||
DECL_BITS(GBSerializedMBC7Flags, Command, 0, 2);
|
||||
|
@ -455,6 +455,7 @@ void GBVideoSerialize(const struct GBVideo* video, struct GBSerializedState* sta
|
||||
GBSerializedVideoFlags flags = 0;
|
||||
flags = GBSerializedVideoFlagsSetBcpIncrement(flags, video->bcpIncrement);
|
||||
flags = GBSerializedVideoFlagsSetOcpIncrement(flags, video->ocpIncrement);
|
||||
flags = GBSerializedVideoFlagsSetMode(flags, video->mode);
|
||||
state->video.flags = flags;
|
||||
STORE_16LE(video->bcpIndex, 0, &state->video.bcpIndex);
|
||||
STORE_16LE(video->ocpIndex, 0, &state->video.ocpIndex);
|
||||
@ -481,6 +482,7 @@ void GBVideoDeserialize(struct GBVideo* video, const struct GBSerializedState* s
|
||||
GBSerializedVideoFlags flags = state->video.flags;
|
||||
video->bcpIncrement = GBSerializedVideoFlagsGetBcpIncrement(flags);
|
||||
video->ocpIncrement = GBSerializedVideoFlagsGetOcpIncrement(flags);
|
||||
video->mode = GBSerializedVideoFlagsGetMode(flags);
|
||||
LOAD_16LE(video->bcpIndex, 0, &state->video.bcpIndex);
|
||||
video->bcpIndex &= 0x3F;
|
||||
LOAD_16LE(video->ocpIndex, 0, &state->video.ocpIndex);
|
||||
|
@ -296,71 +296,13 @@ void retro_run(void) {
|
||||
*/
|
||||
}
|
||||
|
||||
void retro_reset(void) {
|
||||
core->reset(core);
|
||||
|
||||
if (rumbleCallback) {
|
||||
CircleBufferClear(&rumbleHistory);
|
||||
}
|
||||
}
|
||||
|
||||
bool retro_load_game(const struct retro_game_info* game) {
|
||||
struct VFile* rom;
|
||||
if (game->data) {
|
||||
data = anonymousMemoryMap(game->size);
|
||||
dataSize = game->size;
|
||||
memcpy(data, game->data, game->size);
|
||||
rom = VFileFromMemory(data, game->size);
|
||||
} else {
|
||||
data = 0;
|
||||
rom = VFileOpen(game->path, O_RDONLY);
|
||||
}
|
||||
if (!rom) {
|
||||
return false;
|
||||
}
|
||||
|
||||
core = mCoreFindVF(rom);
|
||||
if (!core) {
|
||||
rom->close(rom);
|
||||
mappedMemoryFree(data, game->size);
|
||||
return false;
|
||||
}
|
||||
mCoreInitConfig(core, NULL);
|
||||
core->init(core);
|
||||
core->setAVStream(core, &stream);
|
||||
|
||||
#ifdef _3DS
|
||||
outputBuffer = linearMemAlign(256 * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL, 0x80);
|
||||
#else
|
||||
outputBuffer = malloc(256 * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL);
|
||||
#endif
|
||||
core->setVideoBuffer(core, outputBuffer, 256);
|
||||
|
||||
core->setAudioBufferSize(core, SAMPLES);
|
||||
|
||||
blip_set_rates(core->getAudioChannel(core, 0), core->frequency(core), 32768);
|
||||
blip_set_rates(core->getAudioChannel(core, 1), core->frequency(core), 32768);
|
||||
|
||||
core->setRumble(core, &rumble);
|
||||
|
||||
void static _setupMaps(struct mCore* core) {
|
||||
#ifdef M_CORE_GBA
|
||||
if (core->platform(core) == PLATFORM_GBA) {
|
||||
struct GBA* gba = core->board;
|
||||
gba->luminanceSource = &lux;
|
||||
|
||||
const char* sysDir = 0;
|
||||
if (environCallback(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &sysDir)) {
|
||||
char biosPath[PATH_MAX];
|
||||
snprintf(biosPath, sizeof(biosPath), "%s%s%s", sysDir, PATH_SEP, "gba_bios.bin");
|
||||
struct VFile* bios = VFileOpen(biosPath, O_RDONLY);
|
||||
if (bios) {
|
||||
core->loadBIOS(core, bios, 0);
|
||||
}
|
||||
}
|
||||
|
||||
struct retro_memory_descriptor descs[11];
|
||||
struct retro_memory_map mmaps;
|
||||
size_t romSize = game->size + (game->size & 1);
|
||||
size_t romSize = gba->memory.romSize + (gba->memory.romSize & 1);
|
||||
|
||||
memset(descs, 0, sizeof(descs));
|
||||
size_t savedataSize = retro_get_memory_size(RETRO_MEMORY_SAVE_RAM);
|
||||
@ -436,6 +378,55 @@ bool retro_load_game(const struct retro_game_info* game) {
|
||||
environCallback(RETRO_ENVIRONMENT_SET_SUPPORT_ACHIEVEMENTS, &yes);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void retro_reset(void) {
|
||||
core->reset(core);
|
||||
_setupMaps(core);
|
||||
|
||||
if (rumbleCallback) {
|
||||
CircleBufferClear(&rumbleHistory);
|
||||
}
|
||||
}
|
||||
|
||||
bool retro_load_game(const struct retro_game_info* game) {
|
||||
struct VFile* rom;
|
||||
if (game->data) {
|
||||
data = anonymousMemoryMap(game->size);
|
||||
dataSize = game->size;
|
||||
memcpy(data, game->data, game->size);
|
||||
rom = VFileFromMemory(data, game->size);
|
||||
} else {
|
||||
data = 0;
|
||||
rom = VFileOpen(game->path, O_RDONLY);
|
||||
}
|
||||
if (!rom) {
|
||||
return false;
|
||||
}
|
||||
|
||||
core = mCoreFindVF(rom);
|
||||
if (!core) {
|
||||
rom->close(rom);
|
||||
mappedMemoryFree(data, game->size);
|
||||
return false;
|
||||
}
|
||||
mCoreInitConfig(core, NULL);
|
||||
core->init(core);
|
||||
core->setAVStream(core, &stream);
|
||||
|
||||
#ifdef _3DS
|
||||
outputBuffer = linearMemAlign(256 * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL, 0x80);
|
||||
#else
|
||||
outputBuffer = malloc(256 * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL);
|
||||
#endif
|
||||
core->setVideoBuffer(core, outputBuffer, 256);
|
||||
|
||||
core->setAudioBufferSize(core, SAMPLES);
|
||||
|
||||
blip_set_rates(core->getAudioChannel(core, 0), core->frequency(core), 32768);
|
||||
blip_set_rates(core->getAudioChannel(core, 1), core->frequency(core), 32768);
|
||||
|
||||
core->setRumble(core, &rumble);
|
||||
|
||||
savedata = anonymousMemoryMap(SIZE_CART_FLASH1M);
|
||||
struct VFile* save = VFileFromMemory(savedata, SIZE_CART_FLASH1M);
|
||||
@ -443,7 +434,27 @@ bool retro_load_game(const struct retro_game_info* game) {
|
||||
_reloadSettings();
|
||||
core->loadROM(core, rom);
|
||||
core->loadSave(core, save);
|
||||
|
||||
#ifdef M_CORE_GBA
|
||||
if (core->platform(core) == PLATFORM_GBA) {
|
||||
struct GBA* gba = core->board;
|
||||
gba->luminanceSource = &lux;
|
||||
|
||||
const char* sysDir = 0;
|
||||
if (environCallback(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &sysDir)) {
|
||||
char biosPath[PATH_MAX];
|
||||
snprintf(biosPath, sizeof(biosPath), "%s%s%s", sysDir, PATH_SEP, "gba_bios.bin");
|
||||
struct VFile* bios = VFileOpen(biosPath, O_RDONLY);
|
||||
if (bios) {
|
||||
core->loadBIOS(core, bios, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
core->reset(core);
|
||||
_setupMaps(core);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user