src/gb/renderers/software.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 "software.h"
7
8#include "util/memory.h"
9
10static void GBVideoSoftwareRendererInit(struct GBVideoRenderer* renderer);
11static void GBVideoSoftwareRendererDeinit(struct GBVideoRenderer* renderer);
12static void GBVideoSoftwareRendererReset(struct GBVideoRenderer* renderer);
13static void GBVideoSoftwareRendererWriteVRAM(struct GBVideoRenderer* renderer, uint16_t address);
14static uint8_t GBVideoSoftwareRendererWriteVideoRegister(struct GBVideoRenderer* renderer, uint16_t address, uint8_t value);
15static void GBVideoSoftwareRendererDrawScanline(struct GBVideoRenderer* renderer, int y);
16static void GBVideoSoftwareRendererFinishFrame(struct GBVideoRenderer* renderer);
17static void GBVideoSoftwareRendererGetPixels(struct GBVideoRenderer* renderer, unsigned* stride, const void** pixels);
18static void GBVideoSoftwareRendererPutPixels(struct GBVideoRenderer* renderer, unsigned stride, void* pixels);
19
20#ifdef COLOR_16_BIT
21#ifdef COLOR_5_6_5
22static const color_t GB_PALETTE[4] = { 0xFFFF, 0x39C7, 0x18C3, 0x0000};
23#else
24static const color_t GB_PALETTE[4] = { 0x7FFF, 0x1DE7, 0x0C63, 0x0000};
25#endif
26#else
27static const color_t GB_PALETTE[4] = { 0xFFFFFF, 0x808080, 0x404040, 0x000000};
28#endif
29
30void GBVideoSoftwareRendererCreate(struct GBVideoSoftwareRenderer* renderer) {
31 renderer->d.init = GBVideoSoftwareRendererInit;
32 renderer->d.reset = GBVideoSoftwareRendererReset;
33 renderer->d.deinit = GBVideoSoftwareRendererDeinit;
34 renderer->d.writeVideoRegister = GBVideoSoftwareRendererWriteVideoRegister;
35 renderer->d.writeVRAM = GBVideoSoftwareRendererWriteVRAM;
36 renderer->d.drawScanline = GBVideoSoftwareRendererDrawScanline;
37 renderer->d.finishFrame = GBVideoSoftwareRendererFinishFrame;
38 renderer->d.getPixels = 0;
39 renderer->d.putPixels = 0;
40
41 renderer->temporaryBuffer = 0;
42}
43
44static void GBVideoSoftwareRendererInit(struct GBVideoRenderer* renderer) {
45 GBVideoSoftwareRendererReset(renderer);
46
47 struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer;
48
49 int y;
50 for (y = 0; y < GB_VIDEO_VERTICAL_PIXELS; ++y) {
51 color_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y];
52 int x;
53 for (x = 0; x < GB_VIDEO_HORIZONTAL_PIXELS; ++x) {
54 row[x] = GB_PALETTE[0];
55 }
56 }
57}
58
59static void GBVideoSoftwareRendererReset(struct GBVideoRenderer* renderer) {
60 struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer;
61 int i;
62
63 // TODO
64}
65
66static void GBVideoSoftwareRendererDeinit(struct GBVideoRenderer* renderer) {
67 struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer;
68 UNUSED(softwareRenderer);
69}
70
71static void GBVideoSoftwareRendererWriteVRAM(struct GBVideoRenderer* renderer, uint16_t address) {
72 struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer;
73 // TODO
74}
75static uint8_t GBVideoSoftwareRendererWriteVideoRegister(struct GBVideoRenderer* renderer, uint16_t address, uint8_t value) {
76 struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer;
77 // TODO
78 return value;
79}
80
81static void GBVideoSoftwareRendererDrawScanline(struct GBVideoRenderer* renderer, int y) {
82 struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer;
83
84 color_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y];
85
86 // TODO
87 size_t x;
88#ifdef COLOR_16_BIT
89#if defined(__ARM_NEON) && !defined(__APPLE__)
90 _to16Bit(row, softwareRenderer->row, GB_VIDEO_HORIZONTAL_PIXELS);
91#else
92 for (x = 0; x < GB_VIDEO_HORIZONTAL_PIXELS; ++x) {
93 row[x] = softwareRenderer->row[x];
94 }
95#endif
96#else
97 memcpy(row, softwareRenderer->row, GB_VIDEO_HORIZONTAL_PIXELS * sizeof(*row));
98#endif
99}
100
101static void GBVideoSoftwareRendererFinishFrame(struct GBVideoRenderer* renderer) {
102 struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer;
103
104 if (softwareRenderer->temporaryBuffer) {
105 mappedMemoryFree(softwareRenderer->temporaryBuffer, GB_VIDEO_HORIZONTAL_PIXELS * GB_VIDEO_VERTICAL_PIXELS * 4);
106 softwareRenderer->temporaryBuffer = 0;
107 }
108}