all repos — mgba @ 56dd9c4158d156fbf8d5280bcb35fb261a42942c

mGBA Game Boy Advance Emulator

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

  1/* Copyright (c) 2013-2015 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
  7#include "gba/renderers/video-software.h"
  8#include "gba/supervisor/context.h"
  9#include "gba/video.h"
 10#include "util/memory.h"
 11
 12#include "3ds-vfs.h"
 13
 14#include <3ds.h>
 15#include <sf2d.h>
 16
 17FS_archive sdmcArchive;
 18
 19static void GBA3DSLog(struct GBAThread* thread, enum GBALogLevel level, const char* format, va_list args);
 20static Handle logFile;
 21
 22static void _drawStart(void) {
 23	sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
 24}
 25static void _drawEnd(void) {
 26	sf2d_end_frame();
 27	sf2d_swapbuffers();
 28}
 29
 30int main() {
 31	struct GBAContext context;
 32	srvInit();
 33	aptInit();
 34	hidInit(0);
 35	fsInit();
 36
 37	sf2d_init();
 38	sf2d_set_clear_color(0);
 39	sf2d_texture* tex = sf2d_create_texture(256, 256, TEXFMT_RGB565, SF2D_PLACE_RAM);
 40
 41	sdmcArchive = (FS_archive) {
 42		ARCH_SDMC,
 43		(FS_path) { PATH_EMPTY, 1, (const u8*)"" },
 44		0, 0
 45	};
 46	FSUSER_OpenArchive(0, &sdmcArchive);
 47	FSUSER_OpenFile(0, &logFile, sdmcArchive, FS_makePath(PATH_CHAR, "/mgba.log"), FS_OPEN_WRITE | FS_OPEN_CREATE, FS_ATTRIBUTE_NONE);
 48
 49	GBAContextInit(&context, 0);
 50	struct GBAOptions opts = {
 51		.useBios = true,
 52		.logLevel = 0,
 53		.idleOptimization = IDLE_LOOP_REMOVE
 54	};
 55	GBAConfigLoadDefaults(&context.config, &opts);
 56	context.gba->logHandler = GBA3DSLog;
 57
 58	struct GBAVideoSoftwareRenderer renderer;
 59	GBAVideoSoftwareRendererCreate(&renderer);
 60	renderer.outputBuffer = anonymousMemoryMap(256 * VIDEO_VERTICAL_PIXELS * 2);
 61	renderer.outputBufferStride = 256;
 62	GBAVideoAssociateRenderer(&context.gba->video, &renderer.d);
 63
 64	GBAContextLoadROM(&context, "/rom.gba", true);
 65	GBAContextStart(&context);
 66
 67	while (aptMainLoop()) {
 68		hidScanInput();
 69		int activeKeys = hidKeysHeld() & 0x3FF;
 70		if (hidKeysDown() & KEY_X) {
 71			break;
 72		}
 73		GBAContextFrame(&context, activeKeys);
 74		uint32_t* texdest = (uint32_t*) tex->data;
 75		uint32_t* texsrc = (uint32_t*) renderer.outputBuffer;
 76		int x, y;
 77		for (y = 0; y < VIDEO_VERTICAL_PIXELS; y += 8) {
 78			for (x = 0; x < 16; ++x) {
 79				texdest[ 0 + x * 64 + y * 128] = texsrc[0 + x * 8 + (y + 0) * 128];
 80				texdest[ 2 + x * 64 + y * 128] = texsrc[1 + x * 8 + (y + 0) * 128];
 81				texdest[ 8 + x * 64 + y * 128] = texsrc[2 + x * 8 + (y + 0) * 128];
 82				texdest[10 + x * 64 + y * 128] = texsrc[3 + x * 8 + (y + 0) * 128];
 83				texdest[32 + x * 64 + y * 128] = texsrc[4 + x * 8 + (y + 0) * 128];
 84				texdest[34 + x * 64 + y * 128] = texsrc[5 + x * 8 + (y + 0) * 128];
 85				texdest[40 + x * 64 + y * 128] = texsrc[6 + x * 8 + (y + 0) * 128];
 86				texdest[42 + x * 64 + y * 128] = texsrc[7 + x * 8 + (y + 0) * 128];
 87
 88				texdest[ 1 + x * 64 + y * 128] = texsrc[0 + x * 8 + (y + 1) * 128];
 89				texdest[ 3 + x * 64 + y * 128] = texsrc[1 + x * 8 + (y + 1) * 128];
 90				texdest[ 9 + x * 64 + y * 128] = texsrc[2 + x * 8 + (y + 1) * 128];
 91				texdest[11 + x * 64 + y * 128] = texsrc[3 + x * 8 + (y + 1) * 128];
 92				texdest[33 + x * 64 + y * 128] = texsrc[4 + x * 8 + (y + 1) * 128];
 93				texdest[35 + x * 64 + y * 128] = texsrc[5 + x * 8 + (y + 1) * 128];
 94				texdest[41 + x * 64 + y * 128] = texsrc[6 + x * 8 + (y + 1) * 128];
 95				texdest[43 + x * 64 + y * 128] = texsrc[7 + x * 8 + (y + 1) * 128];
 96
 97				texdest[ 4 + x * 64 + y * 128] = texsrc[0 + x * 8 + (y + 2) * 128];
 98				texdest[ 6 + x * 64 + y * 128] = texsrc[1 + x * 8 + (y + 2) * 128];
 99				texdest[12 + x * 64 + y * 128] = texsrc[2 + x * 8 + (y + 2) * 128];
100				texdest[14 + x * 64 + y * 128] = texsrc[3 + x * 8 + (y + 2) * 128];
101				texdest[36 + x * 64 + y * 128] = texsrc[4 + x * 8 + (y + 2) * 128];
102				texdest[38 + x * 64 + y * 128] = texsrc[5 + x * 8 + (y + 2) * 128];
103				texdest[44 + x * 64 + y * 128] = texsrc[6 + x * 8 + (y + 2) * 128];
104				texdest[46 + x * 64 + y * 128] = texsrc[7 + x * 8 + (y + 2) * 128];
105
106				texdest[ 5 + x * 64 + y * 128] = texsrc[0 + x * 8 + (y + 3) * 128];
107				texdest[ 7 + x * 64 + y * 128] = texsrc[1 + x * 8 + (y + 3) * 128];
108				texdest[13 + x * 64 + y * 128] = texsrc[2 + x * 8 + (y + 3) * 128];
109				texdest[15 + x * 64 + y * 128] = texsrc[3 + x * 8 + (y + 3) * 128];
110				texdest[37 + x * 64 + y * 128] = texsrc[4 + x * 8 + (y + 3) * 128];
111				texdest[39 + x * 64 + y * 128] = texsrc[5 + x * 8 + (y + 3) * 128];
112				texdest[45 + x * 64 + y * 128] = texsrc[6 + x * 8 + (y + 3) * 128];
113				texdest[47 + x * 64 + y * 128] = texsrc[7 + x * 8 + (y + 3) * 128];
114
115				texdest[16 + x * 64 + y * 128] = texsrc[0 + x * 8 + (y + 4) * 128];
116				texdest[18 + x * 64 + y * 128] = texsrc[1 + x * 8 + (y + 4) * 128];
117				texdest[24 + x * 64 + y * 128] = texsrc[2 + x * 8 + (y + 4) * 128];
118				texdest[26 + x * 64 + y * 128] = texsrc[3 + x * 8 + (y + 4) * 128];
119				texdest[48 + x * 64 + y * 128] = texsrc[4 + x * 8 + (y + 4) * 128];
120				texdest[50 + x * 64 + y * 128] = texsrc[5 + x * 8 + (y + 4) * 128];
121				texdest[56 + x * 64 + y * 128] = texsrc[6 + x * 8 + (y + 4) * 128];
122				texdest[58 + x * 64 + y * 128] = texsrc[7 + x * 8 + (y + 4) * 128];
123
124				texdest[17 + x * 64 + y * 128] = texsrc[0 + x * 8 + (y + 5) * 128];
125				texdest[19 + x * 64 + y * 128] = texsrc[1 + x * 8 + (y + 5) * 128];
126				texdest[25 + x * 64 + y * 128] = texsrc[2 + x * 8 + (y + 5) * 128];
127				texdest[27 + x * 64 + y * 128] = texsrc[3 + x * 8 + (y + 5) * 128];
128				texdest[49 + x * 64 + y * 128] = texsrc[4 + x * 8 + (y + 5) * 128];
129				texdest[51 + x * 64 + y * 128] = texsrc[5 + x * 8 + (y + 5) * 128];
130				texdest[57 + x * 64 + y * 128] = texsrc[6 + x * 8 + (y + 5) * 128];
131				texdest[59 + x * 64 + y * 128] = texsrc[7 + x * 8 + (y + 5) * 128];
132
133				texdest[20 + x * 64 + y * 128] = texsrc[0 + x * 8 + (y + 6) * 128];
134				texdest[22 + x * 64 + y * 128] = texsrc[1 + x * 8 + (y + 6) * 128];
135				texdest[28 + x * 64 + y * 128] = texsrc[2 + x * 8 + (y + 6) * 128];
136				texdest[30 + x * 64 + y * 128] = texsrc[3 + x * 8 + (y + 6) * 128];
137				texdest[52 + x * 64 + y * 128] = texsrc[4 + x * 8 + (y + 6) * 128];
138				texdest[54 + x * 64 + y * 128] = texsrc[5 + x * 8 + (y + 6) * 128];
139				texdest[60 + x * 64 + y * 128] = texsrc[6 + x * 8 + (y + 6) * 128];
140				texdest[62 + x * 64 + y * 128] = texsrc[7 + x * 8 + (y + 6) * 128];
141
142				texdest[21 + x * 64 + y * 128] = texsrc[0 + x * 8 + (y + 7) * 128];
143				texdest[23 + x * 64 + y * 128] = texsrc[1 + x * 8 + (y + 7) * 128];
144				texdest[29 + x * 64 + y * 128] = texsrc[2 + x * 8 + (y + 7) * 128];
145				texdest[31 + x * 64 + y * 128] = texsrc[3 + x * 8 + (y + 7) * 128];
146				texdest[53 + x * 64 + y * 128] = texsrc[4 + x * 8 + (y + 7) * 128];
147				texdest[55 + x * 64 + y * 128] = texsrc[5 + x * 8 + (y + 7) * 128];
148				texdest[61 + x * 64 + y * 128] = texsrc[6 + x * 8 + (y + 7) * 128];
149				texdest[63 + x * 64 + y * 128] = texsrc[7 + x * 8 + (y + 7) * 128];
150			}
151		}
152		_drawStart();
153		sf2d_draw_texture_scale(tex, 40, 300, 1, -1);
154		_drawEnd();
155	}
156
157	GBAContextStop(&context);
158	GBAContextDeinit(&context);
159
160cleanup:
161	mappedMemoryFree(renderer.outputBuffer, 0);
162
163	FSFILE_Close(logFile);
164
165	sf2d_free_texture(tex);
166	sf2d_fini();
167
168	fsExit();
169	gfxExit();
170	hidExit();
171	aptExit();
172	srvExit();
173	return 0;
174}
175
176static void GBA3DSLog(struct GBAThread* thread, enum GBALogLevel level, const char* format, va_list args) {
177	UNUSED(thread);
178	UNUSED(level);
179	char out[256];
180	u64 size;
181	u32 written;
182	size_t len = vsnprintf(out, sizeof(out), format, args);
183	if (len >= 256) {
184		len = 255;
185	}
186	out[len] = '\n';
187	FSFILE_GetSize(logFile, &size);
188	FSFILE_Write(logFile, &written, size, out, len + 1, FS_WRITE_FLUSH);
189}