all repos — mgba @ d931dab37c7ef2889faec3fdfbdc1785ddb62bdd

mGBA Game Boy Advance Emulator

src/platform/3ds/main.c (view raw)

  1/* Copyright (c) 2013-2014 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 "gba.h"
  7#include "gba-video.h"
  8
  9#include "renderers/video-software.h"
 10#include "util/memory.h"
 11
 12#include "3ds-vfs.h"
 13
 14#include <3ds.h>
 15
 16int main() {
 17	srvInit();
 18	aptInit();
 19	hidInit(0);
 20	gfxInit();
 21	fsInit();
 22
 23	gfxSetScreenFormat(GFX_BOTTOM, GSP_RGB565_OES);
 24
 25	struct GBAVideoSoftwareRenderer renderer;
 26	GBAVideoSoftwareRendererCreate(&renderer);
 27
 28	size_t stride = VIDEO_HORIZONTAL_PIXELS * BYTES_PER_PIXEL;
 29	color_t* videoBuffer = anonymousMemoryMap(stride * VIDEO_VERTICAL_PIXELS);
 30	struct GBA* gba = anonymousMemoryMap(sizeof(struct GBA));
 31	struct ARMCore* cpu = anonymousMemoryMap(sizeof(struct ARMCore));
 32	int activeKeys = 0;
 33
 34	renderer.outputBuffer = videoBuffer;
 35	renderer.outputBufferStride = VIDEO_HORIZONTAL_PIXELS;
 36
 37	FS_archive sdmcArchive = (FS_archive) {
 38		ARCH_SDMC,
 39		(FS_path) { PATH_EMPTY, 1, (u8*)"" },
 40		0, 0
 41	};
 42	FSUSER_OpenArchive(0, &sdmcArchive);
 43
 44	struct VFile* rom = VFileOpen3DS(sdmcArchive, "/rom.gba", FS_OPEN_READ);
 45
 46	struct VFile* save = VFileOpen3DS(sdmcArchive, "/rom.sav", FS_OPEN_WRITE | FS_OPEN_CREATE);
 47
 48	GBACreate(gba);
 49	ARMSetComponents(cpu, &gba->d, 0, 0);
 50	ARMInit(cpu);
 51
 52	gba->keySource = &activeKeys;
 53	gba->sync = 0;
 54
 55	GBAVideoAssociateRenderer(&gba->video, &renderer.d);
 56
 57	GBALoadROM(gba, rom, save, 0);
 58
 59	ARMReset(cpu);
 60
 61	bool inVblank = false;
 62	while (aptMainLoop()) {
 63		ARMRunLoop(cpu);
 64
 65		if (!inVblank) {
 66			if (GBARegisterDISPSTATIsInVblank(gba->video.dispstat)) {
 67				u16 width, height;
 68				u16* screen = (u16*) gfxGetFramebuffer(GFX_BOTTOM, GFX_BOTTOM, &height, &width);
 69				u32 startX = (width - VIDEO_HORIZONTAL_PIXELS) / 2;
 70				u32 startY = (height + VIDEO_VERTICAL_PIXELS) / 2 - 1;
 71				u32 x, y;
 72				for (y = 0; y < VIDEO_VERTICAL_PIXELS; ++y) {
 73					for (x = 0; x < VIDEO_HORIZONTAL_PIXELS; ++x) {
 74						screen[startY - y + (startX + x) * height] = videoBuffer[y * VIDEO_HORIZONTAL_PIXELS + x];
 75					}
 76				}
 77				gfxFlushBuffers();
 78				gfxSwapBuffersGpu();
 79				gspWaitForVBlank();
 80				hidScanInput();
 81				activeKeys = hidKeysHeld() & 0x3FF;
 82				if (hidKeysDown() & KEY_X) {
 83					break;
 84				}
 85			}
 86		}
 87		inVblank = GBARegisterDISPSTATGetInVblank(gba->video.dispstat);
 88	}
 89
 90	ARMDeinit(cpu);
 91	GBADestroy(gba);
 92
 93	rom->close(rom);
 94	save->close(save);
 95
 96	mappedMemoryFree(gba, 0);
 97	mappedMemoryFree(cpu, 0);
 98
 99	mappedMemoryFree(videoBuffer, 0);
100
101	fsExit();
102	gfxExit();
103	hidExit();
104	aptExit();
105	srvExit();
106	return 0;
107}