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}