Esempio n. 1
0
void GBASavedataDeinit(struct GBASavedata* savedata) {
	if (savedata->vf) {
		size_t size = GBASavedataSize(savedata);
		if (savedata->data) {
			savedata->vf->unmap(savedata->vf, savedata->data, size);
		}
		savedata->vf = NULL;
	} else {
		switch (savedata->type) {
		case SAVEDATA_SRAM:
			mappedMemoryFree(savedata->data, SIZE_CART_SRAM);
			break;
		case SAVEDATA_FLASH512:
			mappedMemoryFree(savedata->data, SIZE_CART_FLASH512);
			break;
		case SAVEDATA_FLASH1M:
			mappedMemoryFree(savedata->data, SIZE_CART_FLASH1M);
			break;
		case SAVEDATA_EEPROM:
			mappedMemoryFree(savedata->data, SIZE_CART_EEPROM);
			break;
		case SAVEDATA_EEPROM512:
			mappedMemoryFree(savedata->data, SIZE_CART_EEPROM512);
			break;
		case SAVEDATA_FORCE_NONE:
		case SAVEDATA_AUTODETECT:
			break;
		}
	}
	savedata->data = 0;
	savedata->type = SAVEDATA_AUTODETECT;
}
Esempio n. 2
0
void GBUnloadROM(struct GB* gb) {
	// TODO: Share with GBAUnloadROM
	if (gb->memory.rom && gb->pristineRom != gb->memory.rom) {
		if (gb->yankedRomSize) {
			gb->yankedRomSize = 0;
		}
		mappedMemoryFree(gb->memory.rom, GB_SIZE_CART_MAX);
	}
	gb->memory.rom = 0;

	if (gb->romVf) {
#ifndef _3DS
		gb->romVf->unmap(gb->romVf, gb->pristineRom, gb->pristineRomSize);
#endif
		gb->romVf->close(gb->romVf);
		gb->pristineRom = 0;
		gb->romVf = 0;
	}

	if (gb->sramVf) {
		gb->sramVf->unmap(gb->sramVf, gb->memory.sram, 0x8000);
		gb->sramVf = 0;
	} else if (gb->memory.sram) {
		mappedMemoryFree(gb->memory.sram, 0x8000);
	}
	gb->memory.sram = 0;
}
Esempio n. 3
0
void retro_unload_game(void) {
	core->deinit(core);
	mappedMemoryFree(data, dataSize);
	data = 0;
	mappedMemoryFree(savedata, SIZE_CART_FLASH1M);
	savedata = 0;
	CircleBufferDeinit(&rumbleHistory);
}
Esempio n. 4
0
void GBVideoReset(struct GBVideo* video) {
	video->ly = 0;
	video->mode = 1;
	video->stat = 1;

	video->nextEvent = INT_MAX;
	video->eventDiff = 0;

	video->nextMode = INT_MAX;
	video->dotCounter = INT_MIN;
	video->nextFrame = INT_MAX;

	video->frameCounter = 0;
	video->frameskipCounter = 0;

	if (video->vram) {
		mappedMemoryFree(video->vram, GB_SIZE_VRAM);
	}
	video->vram = anonymousMemoryMap(GB_SIZE_VRAM);
	GBVideoSwitchBank(video, 0);
	video->renderer->vram = video->vram;
	memset(&video->oam, 0, sizeof(video->oam));
	video->renderer->oam = &video->oam;
	memset(&video->palette, 0, sizeof(video->palette));

	video->renderer->deinit(video->renderer);
	video->renderer->init(video->renderer, video->p->model);
}
Esempio n. 5
0
bool _vfmCloseFree(struct VFile* vf) {
	struct VFileMem* vfm = (struct VFileMem*) vf;
	mappedMemoryFree(vfm->mem, vfm->bufferSize);
	vfm->mem = 0;
	free(vfm);
	return true;
}
Esempio n. 6
0
void GBUnloadROM(struct GB* gb) {
	// TODO: Share with GBAUnloadROM
	if (gb->memory.rom && gb->pristineRom != gb->memory.rom) {
		if (gb->yankedRomSize) {
			gb->yankedRomSize = 0;
		}
		mappedMemoryFree(gb->memory.rom, GB_SIZE_CART_MAX);
		gb->memory.rom = gb->pristineRom;
	}
	if (gb->memory.rom && gb->memory.romBase != gb->memory.rom) {
		free(gb->memory.romBase);
	}
	gb->memory.rom = 0;

	if (gb->romVf) {
#ifndef _3DS
		gb->romVf->unmap(gb->romVf, gb->pristineRom, gb->pristineRomSize);
#endif
		gb->romVf->close(gb->romVf);
		gb->romVf = 0;
	}
	gb->pristineRom = 0;

	GBSavedataUnmask(gb);
	GBSramDeinit(gb);
	if (gb->sramRealVf) {
		gb->sramRealVf->close(gb->sramRealVf);
	}
	gb->sramRealVf = NULL;
	gb->sramVf = NULL;
}
Esempio n. 7
0
void GBResizeSram(struct GB* gb, size_t size) {
	if (gb->memory.sram && size <= gb->sramSize) {
		return;
	}
	mLOG(GB, INFO, "Resizing SRAM to %"PRIz"u bytes", size);
	struct VFile* vf = gb->sramVf;
	if (vf) {
		if (vf == gb->sramRealVf) {
			ssize_t vfSize = vf->size(vf);
			if (vfSize >= 0 && (size_t) vfSize < size) {
				uint8_t extdataBuffer[0x100];
				if (vfSize & 0xFF) {
					vf->seek(vf, -(vfSize & 0xFF), SEEK_END);
					vf->read(vf, extdataBuffer, vfSize & 0xFF);
				}
				if (gb->memory.sram) {
					vf->unmap(vf, gb->memory.sram, gb->sramSize);
				}
				vf->truncate(vf, size + (vfSize & 0xFF));
				if (vfSize & 0xFF) {
					vf->seek(vf, size, SEEK_SET);
					vf->write(vf, extdataBuffer, vfSize & 0xFF);
				}
				gb->memory.sram = vf->map(vf, size, MAP_WRITE);
				memset(&gb->memory.sram[gb->sramSize], 0xFF, size - gb->sramSize);
			} else if (size > gb->sramSize || !gb->memory.sram) {
				if (gb->memory.sram) {
					vf->unmap(vf, gb->memory.sram, gb->sramSize);
				}
				gb->memory.sram = vf->map(vf, size, MAP_WRITE);
			}
		} else {
			if (gb->memory.sram) {
				vf->unmap(vf, gb->memory.sram, gb->sramSize);
			}
			gb->memory.sram = vf->map(vf, size, MAP_READ);
		}
		if (gb->memory.sram == (void*) -1) {
			gb->memory.sram = NULL;
		}
	} else {
		uint8_t* newSram = anonymousMemoryMap(size);
		if (gb->memory.sram) {
			if (size > gb->sramSize) {
				memcpy(newSram, gb->memory.sram, gb->sramSize);
				memset(&newSram[gb->sramSize], 0xFF, size - gb->sramSize);
			} else {
				memcpy(newSram, gb->memory.sram, size);
			}
			mappedMemoryFree(gb->memory.sram, gb->sramSize);
		} else {
			memset(newSram, 0xFF, size);
		}
		gb->memory.sram = newSram;
	}
	if (gb->sramSize < size) {
		gb->sramSize = size;
	}
}
Esempio n. 8
0
static void _vffUnmap(struct VFile* vf, void* memory, size_t size) {
	struct VFileFILE* vff = (struct VFileFILE*) vf;
	long pos = ftell(vff->file);
	fseek(vff->file, 0, SEEK_SET);
	fwrite(memory, size, 1, vff->file);
	fseek(vff->file, pos, SEEK_SET);
	mappedMemoryFree(memory, size);
}
Esempio n. 9
0
static void GBVideoSoftwareRendererFinishFrame(struct GBVideoRenderer* renderer) {
	struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer;

	if (softwareRenderer->temporaryBuffer) {
		mappedMemoryFree(softwareRenderer->temporaryBuffer, GB_VIDEO_HORIZONTAL_PIXELS * GB_VIDEO_VERTICAL_PIXELS * 4);
		softwareRenderer->temporaryBuffer = 0;
	}
	softwareRenderer->currentWy = softwareRenderer->wy;
}
Esempio n. 10
0
bool _vfzClose(struct VFile* vf) {
	struct VFileZip* vfz = (struct VFileZip*) vf;
	unzCloseCurrentFile(vfz->z);
	if (vfz->buffer) {
		mappedMemoryFree(vfz->buffer, vfz->bufferSize);
	}
	free(vfz);
	return true;
}
Esempio n. 11
0
static void _vfsceUnmap(struct VFile* vf, void* memory, size_t size) {
	struct VFileSce* vfsce = (struct VFileSce*) vf;
	SceOff cur = sceIoLseek(vfsce->fd, 0, SEEK_CUR);
	sceIoLseek(vfsce->fd, 0, SEEK_SET);
	sceIoWrite(vfsce->fd, memory, size);
	sceIoLseek(vfsce->fd, cur, SEEK_SET);
	sceIoSyncByFd(vfsce->fd);
	mappedMemoryFree(memory, size);
}
Esempio n. 12
0
void _vfzUnmap(struct VFile* vf, void* memory, size_t size) {
	struct VFileZip* vfz = (struct VFileZip*) vf;

	if (memory != vfz->buffer) {
		return;
	}

	mappedMemoryFree(vfz->buffer, size);
	vfz->buffer = 0;
}
Esempio n. 13
0
void GBMemoryReset(struct GB* gb) {
	if (gb->memory.wram) {
		mappedMemoryFree(gb->memory.wram, GB_SIZE_WORKING_RAM);
	}
	gb->memory.wram = anonymousMemoryMap(GB_SIZE_WORKING_RAM);
	if (gb->model >= GB_MODEL_CGB) {
		uint32_t* base = (uint32_t*) gb->memory.wram;
		size_t i;
		uint32_t pattern = 0;
		for (i = 0; i < GB_SIZE_WORKING_RAM / 4; i += 4) {
			if ((i & 0x1FF) == 0) {
				pattern = ~pattern;
			}
			base[i + 0] = pattern;
			base[i + 1] = pattern;
			base[i + 2] = ~pattern;
			base[i + 3] = ~pattern;
		}
	}
	GBMemorySwitchWramBank(&gb->memory, 1);
	gb->memory.romBank = &gb->memory.rom[GB_SIZE_CART_BANK0];
	gb->memory.currentBank = 1;
	gb->memory.sramCurrentBank = 0;

	gb->memory.ime = false;
	gb->memory.ie = 0;

	gb->memory.dmaNext = INT_MAX;
	gb->memory.dmaRemaining = 0;
	gb->memory.dmaSource = 0;
	gb->memory.dmaDest = 0;
	gb->memory.hdmaNext = INT_MAX;
	gb->memory.hdmaRemaining = 0;
	gb->memory.hdmaSource = 0;
	gb->memory.hdmaDest = 0;
	gb->memory.isHdma = false;

	gb->memory.sramAccess = false;
	gb->memory.rtcAccess = false;
	gb->memory.activeRtcReg = 0;
	gb->memory.rtcLatched = false;
	memset(&gb->memory.rtcRegs, 0, sizeof(gb->memory.rtcRegs));

	memset(&gb->memory.hram, 0, sizeof(gb->memory.hram));
	memset(&gb->memory.mbcState, 0, sizeof(gb->memory.mbcState));

	GBMBCInit(gb);
	gb->memory.sramBank = gb->memory.sram;

	if (!gb->memory.wram) {
		GBMemoryDeinit(gb);
	}
}
Esempio n. 14
0
static void GBSramDeinit(struct GB* gb) {
	if (gb->sramVf) {
		gb->sramVf->unmap(gb->sramVf, gb->memory.sram, gb->sramSize);
		if (gb->memory.mbcType == GB_MBC3_RTC) {
			GBMBCRTCWrite(gb);
		}
		gb->sramVf = NULL;
	} else if (gb->memory.sram) {
		mappedMemoryFree(gb->memory.sram, gb->sramSize);
	}
	gb->memory.sram = 0;
}
Esempio n. 15
0
void GBVideoDeinit(struct GBVideo* video) {
	video->renderer->deinit(video->renderer);
	mappedMemoryFree(video->vram, GB_SIZE_VRAM);
	if (video->renderer->sgbCharRam) {
		mappedMemoryFree(video->renderer->sgbCharRam, SGB_SIZE_CHAR_RAM);
		video->renderer->sgbCharRam = NULL;
	}
	if (video->renderer->sgbMapRam) {
		mappedMemoryFree(video->renderer->sgbMapRam, SGB_SIZE_MAP_RAM);
		video->renderer->sgbMapRam = NULL;
	}
	if (video->renderer->sgbPalRam) {
		mappedMemoryFree(video->renderer->sgbPalRam, SGB_SIZE_PAL_RAM);
		video->renderer->sgbPalRam = NULL;
	}
	if (video->renderer->sgbAttributeFiles) {
		mappedMemoryFree(video->renderer->sgbAttributeFiles, SGB_SIZE_ATF_RAM);
		video->renderer->sgbAttributeFiles = NULL;
	}
	if (video->renderer->sgbAttributes) {
		free(video->renderer->sgbAttributes);
		video->renderer->sgbAttributes = NULL;
	}
}
Esempio n. 16
0
void GBApplyPatch(struct GB* gb, struct Patch* patch) {
	size_t patchedSize = patch->outputSize(patch, gb->memory.romSize);
	if (!patchedSize) {
		return;
	}
	if (patchedSize > GB_SIZE_CART_MAX) {
		patchedSize = GB_SIZE_CART_MAX;
	}
	gb->memory.rom = anonymousMemoryMap(GB_SIZE_CART_MAX);
	if (!patch->applyPatch(patch, gb->pristineRom, gb->pristineRomSize, gb->memory.rom, patchedSize)) {
		mappedMemoryFree(gb->memory.rom, patchedSize);
		gb->memory.rom = gb->pristineRom;
		return;
	}
	gb->memory.romSize = patchedSize;
	gb->romCrc32 = doCrc32(gb->memory.rom, gb->memory.romSize);
}
Esempio n. 17
0
void _vfmExpand(struct VFileMem* vfm, size_t newSize) {
	size_t alignedSize = toPow2(newSize);
	if (alignedSize > vfm->bufferSize) {
		void* oldBuf = vfm->mem;
		vfm->mem = anonymousMemoryMap(alignedSize);
		if (oldBuf) {
			if (newSize < vfm->size) {
				memcpy(vfm->mem, oldBuf, newSize);
			} else {
				memcpy(vfm->mem, oldBuf, vfm->size);
			}
			mappedMemoryFree(oldBuf, vfm->bufferSize);
		}
		vfm->bufferSize = alignedSize;
	}
	vfm->size = newSize;
}
Esempio n. 18
0
void GBMemoryReset(struct GB* gb) {
	if (gb->memory.wram) {
		mappedMemoryFree(gb->memory.wram, GB_SIZE_WORKING_RAM);
	}
	gb->memory.wram = anonymousMemoryMap(GB_SIZE_WORKING_RAM);
	if (gb->model >= GB_MODEL_CGB) {
		uint32_t* base = (uint32_t*) gb->memory.wram;
		size_t i;
		uint32_t pattern = 0;
		for (i = 0; i < GB_SIZE_WORKING_RAM / 4; i += 4) {
			if ((i & 0x1FF) == 0) {
				pattern = ~pattern;
			}
			base[i + 0] = pattern;
			base[i + 1] = pattern;
			base[i + 2] = ~pattern;
			base[i + 3] = ~pattern;
		}
	}
	GBMemorySwitchWramBank(&gb->memory, 1);
	gb->memory.romBank = &gb->memory.rom[GB_SIZE_CART_BANK0];
	gb->memory.currentBank = 1;
	gb->memory.sramCurrentBank = 0;

	gb->memory.ime = false;
	gb->memory.ie = 0;

	gb->memory.dmaRemaining = 0;
	gb->memory.dmaSource = 0;
	gb->memory.dmaDest = 0;
	gb->memory.hdmaRemaining = 0;
	gb->memory.hdmaSource = 0;
	gb->memory.hdmaDest = 0;
	gb->memory.isHdma = false;


	gb->memory.dmaEvent.context = gb;
	gb->memory.dmaEvent.name = "GB DMA";
	gb->memory.dmaEvent.callback = _GBMemoryDMAService;
	gb->memory.dmaEvent.priority = 0x40;
	gb->memory.hdmaEvent.context = gb;
	gb->memory.hdmaEvent.name = "GB HDMA";
	gb->memory.hdmaEvent.callback = _GBMemoryHDMAService;
	gb->memory.hdmaEvent.priority = 0x41;

	memset(&gb->memory.hram, 0, sizeof(gb->memory.hram));
	switch (gb->memory.mbcType) {
	case GB_MBC1:
		gb->memory.mbcState.mbc1.mode = 0;
		break;
	default:
		memset(&gb->memory.mbcState, 0, sizeof(gb->memory.mbcState));
	}

	GBMBCInit(gb);
	gb->memory.sramBank = gb->memory.sram;

	if (!gb->memory.wram) {
		GBMemoryDeinit(gb);
	}
}
Esempio n. 19
0
void GBMemoryDeinit(struct GB* gb) {
	mappedMemoryFree(gb->memory.wram, GB_SIZE_WORKING_RAM);
	if (gb->memory.rom) {
		mappedMemoryFree(gb->memory.rom, gb->memory.romSize);
	}
}
Esempio n. 20
0
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 = NULL;
#ifdef M_CORE_GBA
	if (!core && GBAIsROM(rom)) {
		core = GBACoreCreate();
	}
#endif
#ifdef M_CORE_GB
	if (!core && GBIsROM(rom)) {
		core = GBCoreCreate();
	}
#endif
	if (!core) {
		rom->close(rom);
		mappedMemoryFree(data, game->size);
		return false;
	}
	mCoreInitConfig(core, NULL);
	core->init(core);
	core->setAVStream(core, &stream);

	outputBuffer = malloc(256 * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL);
	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);

#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);
			}
		}

		GBACheatDeviceCreate(&cheats);
		GBACheatAttachDevice(gba, &cheats);
		GBACheatSetInit(&cheatSet, "libretro");
		GBACheatAddSet(&cheats, &cheatSet);
	}
#endif

	savedata = anonymousMemoryMap(SIZE_CART_FLASH1M);
	struct VFile* save = VFileFromMemory(savedata, SIZE_CART_FLASH1M);

	_reloadSettings();
	core->loadROM(core, rom);
	core->loadSave(core, save);
	core->reset(core);
	return true;
}
Esempio n. 21
0
void RingFIFODeinit(struct RingFIFO* buffer) {
	mappedMemoryFree(buffer->data, buffer->capacity);
	buffer->data = 0;
}
Esempio n. 22
0
void GBADeallocateState(struct GBASerializedState* state) {
	mappedMemoryFree(state, sizeof(struct GBASerializedState));
}
Esempio n. 23
0
static void _vf3dUnmap(struct VFile* vf, void* memory, size_t size) {
	struct VFile3DS* vf3d = (struct VFile3DS*) vf;
	u32 sizeWritten;
	FSFILE_Write(vf3d->handle, &sizeWritten, 0, memory, size, FS_WRITE_FLUSH);
	mappedMemoryFree(memory, size);
}
Esempio n. 24
0
void GBVideoDeinit(struct GBVideo* video) {
	GBVideoAssociateRenderer(video, &dummyRenderer);
	mappedMemoryFree(video->vram, GB_SIZE_VRAM);
}
Esempio n. 25
0
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);

	size_t size = 256 * 224 * BYTES_PER_PIXEL;
	outputBuffer = malloc(size);
	memset(outputBuffer, 0xFF, size);
	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->setPeripheral(core, mPERIPH_RUMBLE, &rumble);

	savedata = anonymousMemoryMap(SIZE_CART_FLASH1M);
	struct VFile* save = VFileFromMemory(savedata, SIZE_CART_FLASH1M);

	_reloadSettings();
	core->loadROM(core, rom);
	core->loadSave(core, save);

	const char* sysDir = 0;
	const char* biosName = 0;
	char biosPath[PATH_MAX];
	environCallback(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &sysDir);

#ifdef M_CORE_GBA
	if (core->platform(core) == PLATFORM_GBA) {
		core->setPeripheral(core, mPERIPH_GBA_LUMINANCE, &lux);
		biosName = "gba_bios.bin";

	}
#endif

#ifdef M_CORE_GB
	if (core->platform(core) == PLATFORM_GB) {
		memset(&cam, 0, sizeof(cam));
		cam.height = GBCAM_HEIGHT;
		cam.width = GBCAM_WIDTH;
		cam.caps = 1 << RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER;
		cam.frame_raw_framebuffer = _updateCamera;
		core->setPeripheral(core, mPERIPH_IMAGE_SOURCE, &imageSource);

		environCallback(RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE, &cam);
		const char* modelName = mCoreConfigGetValue(&core->config, "gb.model");
		struct GB* gb = core->board;

		if (modelName) {
			gb->model = GBNameToModel(modelName);
		} else {
			GBDetectModel(gb);
		}

		switch (gb->model) {
		case GB_MODEL_AGB:
		case GB_MODEL_CGB:
			biosName = "gbc_bios.bin";
			break;
		case GB_MODEL_SGB:
			biosName = "sgb_bios.bin";
			break;
		case GB_MODEL_DMG:
		default:
			biosName = "gb_bios.bin";
			break;
		}
	}
#endif

	if (core->opts.useBios && sysDir && biosName) {
		snprintf(biosPath, sizeof(biosPath), "%s%s%s", sysDir, PATH_SEP, biosName);
		struct VFile* bios = VFileOpen(biosPath, O_RDONLY);
		if (bios) {
			core->loadBIOS(core, bios, 0);
		}
	}

	core->reset(core);
	_setupMaps(core);

	return true;
}