all repos — mgba @ 090048ec065e5777a7f3f1c256d1a45a4b248de5

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