src/gb/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/core.h"
9#include "gb/gb.h"
10#include "gb/renderers/software.h"
11#include "util/memory.h"
12
13struct GBCore {
14 struct mCore d;
15 struct GBVideoSoftwareRenderer renderer;
16 uint8_t keys;
17};
18
19static bool _GBCoreInit(struct mCore* core) {
20 struct GBCore* gbcore = (struct GBCore*) core;
21
22 struct LR35902Core* cpu = anonymousMemoryMap(sizeof(struct LR35902Core));
23 struct GB* gb = anonymousMemoryMap(sizeof(struct GB));
24 if (!cpu || !gb) {
25 free(cpu);
26 free(gb);
27 return false;
28 }
29 core->cpu = cpu;
30 core->board = gb;
31
32 GBCreate(gb);
33 LR35902SetComponents(cpu, &gb->d, 0, 0);
34 LR35902Init(cpu);
35
36 GBVideoSoftwareRendererCreate(&gbcore->renderer);
37 GBVideoAssociateRenderer(&gb->video, &gbcore->renderer.d);
38
39 gb->keySource = &gbcore->keys;
40
41 return true;
42}
43
44static void _GBCoreDeinit(struct mCore* core) {
45 LR35902Deinit(core->cpu);
46 GBDestroy(core->board);
47 mappedMemoryFree(core->cpu, sizeof(struct LR35902Core));
48 mappedMemoryFree(core->board, sizeof(struct GB));
49}
50
51static void _GBCoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) {
52 UNUSED(core);
53 *width = GB_VIDEO_HORIZONTAL_PIXELS;
54 *height = GB_VIDEO_VERTICAL_PIXELS;
55}
56
57static void _GBCoreSetVideoBuffer(struct mCore* core, void* buffer, size_t stride) {
58 struct GBCore* gbcore = (struct GBCore*) core;
59 gbcore->renderer.outputBuffer = buffer;
60 gbcore->renderer.outputBufferStride = stride;
61}
62
63static bool _GBCoreLoadROM(struct mCore* core, struct VFile* vf, struct VFile* save, const char* fname) {
64 return GBLoadROM(core->board, vf, save, fname);
65}
66
67static bool _GBCoreIsROM(struct mCore* core, struct VFile* vf) {
68 UNUSED(core);
69 return GBIsROM(vf);
70}
71
72static void _GBCoreUnloadROM(struct mCore* core) {
73 return GBUnloadROM(core->board);
74}
75
76static void _GBCoreReset(struct mCore* core) {
77 LR35902Reset(core->cpu);
78}
79
80static void _GBCoreRunFrame(struct mCore* core) {
81 struct GB* gb = core->board;
82 int32_t frameCounter = gb->video.frameCounter;
83 while (gb->video.frameCounter == frameCounter) {
84 LR35902Run(core->cpu);
85 }
86}
87
88static void _GBCoreRunLoop(struct mCore* core) {
89 LR35902Run(core->cpu);
90}
91
92static void _GBCoreStep(struct mCore* core) {
93 LR35902Tick(core->cpu);
94}
95
96static void _GBCoreSetKeys(struct mCore* core, uint32_t keys) {
97 struct GBCore* gbcore = (struct GBCore*) core;
98 gbcore->keys = keys;
99}
100
101struct mCore* GBCoreCreate(void) {
102 struct GBCore* gbcore = malloc(sizeof(*gbcore));
103 struct mCore* core = &gbcore->d;
104 core->cpu = 0;
105 core->board = 0;
106 core->init = _GBCoreInit;
107 core->deinit = _GBCoreDeinit;
108 core->desiredVideoDimensions = _GBCoreDesiredVideoDimensions;
109 core->setVideoBuffer = _GBCoreSetVideoBuffer;
110 core->isROM = _GBCoreIsROM;
111 core->loadROM = _GBCoreLoadROM;
112 core->unloadROM = _GBCoreUnloadROM;
113 core->reset = _GBCoreReset;
114 core->runFrame = _GBCoreRunFrame;
115 core->runLoop = _GBCoreRunLoop;
116 core->step = _GBCoreStep;
117 core->setKeys = _GBCoreSetKeys;
118 return core;
119}