all repos — mgba @ d86440e04f1dbfdcb954eeaae25ceee78ab26b65

mGBA Game Boy Advance Emulator

src/core/core.c (view raw)

  1/* Copyright (c) 2013-2016 Jeffrey Pfau
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6#include "core.h"
  7
  8#include "core/log.h"
  9#include "util/vfs.h"
 10
 11#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
 12#include "util/png-io.h"
 13
 14bool mCoreLoadFile(struct mCore* core, const char* path) {
 15	struct VFile* rom = mDirectorySetOpenPath(&core->dirs, path, core->isROM);
 16	if (!rom) {
 17		return false;
 18	}
 19
 20	bool ret = core->loadROM(core, rom);
 21	if (!ret) {
 22		rom->close(rom);
 23	}
 24	return ret;
 25}
 26
 27bool mCoreAutoloadSave(struct mCore* core) {
 28	return core->loadSave(core, mDirectorySetOpenSuffix(&core->dirs, ".sav", O_CREAT | O_RDWR));
 29}
 30
 31bool mCoreAutoloadPatch(struct mCore* core) {
 32	return core->loadPatch(core, mDirectorySetOpenSuffix(&core->dirs, ".ups", O_RDONLY)) ||
 33	       core->loadPatch(core, mDirectorySetOpenSuffix(&core->dirs, ".ips", O_RDONLY)) ||
 34	       core->loadPatch(core, mDirectorySetOpenSuffix(&core->dirs, ".bps", O_RDONLY));
 35}
 36
 37bool mCoreSaveState(struct mCore* core, int slot, int flags) {
 38	struct VFile* vf = mCoreGetState(core, slot, true);
 39	if (!vf) {
 40		return false;
 41	}
 42	bool success = core->saveState(core, vf, flags);
 43	vf->close(vf);
 44	if (success) {
 45		mLOG(STATUS, INFO, "State %i saved", slot);
 46	} else {
 47		mLOG(STATUS, INFO, "State %i failed to save", slot);
 48	}
 49
 50	return success;
 51}
 52
 53bool mCoreLoadState(struct mCore* core, int slot, int flags) {
 54	struct VFile* vf = mCoreGetState(core, slot, false);
 55	if (!vf) {
 56		return false;
 57	}
 58	bool success = core->loadState(core, vf, flags);
 59	vf->close(vf);
 60	if (success) {
 61		mLOG(STATUS, INFO, "State %i loaded", slot);
 62	} else {
 63		mLOG(STATUS, INFO, "State %i failed to loaded", slot);
 64	}
 65
 66	return success;
 67}
 68
 69struct VFile* mCoreGetState(struct mCore* core, int slot, bool write) {
 70	char name[PATH_MAX];
 71	snprintf(name, sizeof(name), "%s.ss%i", core->dirs.baseName, slot);
 72	return core->dirs.state->openFile(core->dirs.state, name, write ? (O_CREAT | O_TRUNC | O_RDWR) : O_RDONLY);
 73}
 74
 75void mCoreDeleteState(struct mCore* core, int slot) {
 76	char name[PATH_MAX];
 77	snprintf(name, sizeof(name), "%s.ss%i", core->dirs.baseName, slot);
 78	core->dirs.state->deleteFile(core->dirs.state, name);
 79}
 80
 81void mCoreTakeScreenshot(struct mCore* core) {
 82#ifdef USE_PNG
 83	size_t stride;
 84	color_t* pixels = 0;
 85	unsigned width, height;
 86	core->desiredVideoDimensions(core, &width, &height);
 87	struct VFile* vf = VDirFindNextAvailable(core->dirs.screenshot, core->dirs.baseName, "-", ".png", O_CREAT | O_TRUNC | O_WRONLY);
 88	bool success = false;
 89	if (vf) {
 90		core->getVideoBuffer(core, &pixels, &stride);
 91		png_structp png = PNGWriteOpen(vf);
 92		png_infop info = PNGWriteHeader(png, width, height);
 93		success = PNGWritePixels(png, width, height, stride, pixels);
 94		PNGWriteClose(png, info);
 95		vf->close(vf);
 96	}
 97	if (success) {
 98		mLOG(STATUS, INFO, "Screenshot saved");
 99		return;
100	}
101#else
102	UNUSED(core);
103#endif
104	mLOG(STATUS, WARN, "Failed to take screenshot");
105}
106#endif
107
108void mCoreInitConfig(struct mCore* core, const char* port) {
109	mCoreConfigInit(&core->config, port);
110}
111
112void mCoreLoadConfig(struct mCore* core) {
113#ifndef MINIMAL_CORE
114	mCoreConfigLoad(&core->config);
115#endif
116	mCoreConfigMap(&core->config, &core->opts);
117#ifndef MINIMAL_CORE
118	mDirectorySetMapOptions(&core->dirs, &core->opts);
119#endif
120	core->loadConfig(core);
121}