src/gba/gba-video.h (view raw)
1#ifndef GBA_VIDEO_H
2#define GBA_VIDEO_H
3
4#include "gba-memory.h"
5
6#include <stdint.h>
7
8enum {
9 VIDEO_CYCLES_PER_PIXEL = 4,
10
11 VIDEO_HORIZONTAL_PIXELS = 240,
12 VIDEO_HBLANK_PIXELS = 68,
13 VIDEO_HDRAW_LENGTH = 1006,
14 VIDEO_HBLANK_LENGTH = 226,
15 VIDEO_HORIZONTAL_LENGTH = 1232,
16
17 VIDEO_VERTICAL_PIXELS = 160,
18 VIDEO_VBLANK_PIXELS = 68,
19 VIDEO_VERTICAL_TOTAL_PIXELS = 228,
20
21 VIDEO_TOTAL_LENGTH = 280896,
22
23 REG_DISPSTAT_MASK = 0xFF38
24};
25
26enum ObjMode {
27 OBJ_MODE_NORMAL = 0,
28 OBJ_MODE_SEMITRANSPARENT = 1,
29 OBJ_MODE_OBJWIN = 2
30};
31
32enum ObjShape {
33 OBJ_SHAPE_SQUARE = 0,
34 OBJ_SHAPE_HORIZONTAL = 1,
35 OBJ_SHAPE_VERTICAL = 2
36};
37
38union GBAColor {
39 struct {
40 unsigned r : 5;
41 unsigned g : 5;
42 unsigned b : 5;
43 };
44 uint16_t packed;
45};
46
47union GBAOAM {
48 struct {
49 int y : 8;
50 unsigned transformed : 1;
51 union {
52 unsigned doublesize : 1;
53 unsigned disable : 1;
54 };
55 enum ObjMode mode : 2;
56 unsigned mosaic : 1;
57 unsigned multipalette : 1;
58 enum ObjShape shape : 2;
59
60 int x : 9;
61 union {
62 unsigned matIndex : 5;
63 struct {
64 int : 3;
65 unsigned hflip : 1;
66 unsigned vflip : 1;
67 };
68 };
69 unsigned size : 2;
70
71 unsigned tile : 10;
72 unsigned priority : 2;
73 unsigned palette : 4;
74
75 int : 16;
76 } obj[128];
77
78 struct {
79 int : 16;
80 int : 16;
81 int : 16;
82 int a : 16;
83 int : 16;
84 int : 16;
85 int : 16;
86 int b : 16;
87 int : 16;
88 int : 16;
89 int : 16;
90 int c : 16;
91 int : 16;
92 int : 16;
93 int : 16;
94 int d : 16;
95 } mat[32];
96
97 uint16_t raw[512];
98};
99
100union GBATextMapData {
101 struct {
102 unsigned tile : 10;
103 unsigned hflip : 1;
104 unsigned vflip : 1;
105 unsigned palette : 4;
106 };
107 uint16_t packed;
108};
109
110union GBARegisterDISPCNT {
111 struct {
112 unsigned mode : 3;
113 unsigned cgb : 1;
114 unsigned frameSelect : 1;
115 unsigned hblankIntervalFree : 1;
116 unsigned objCharacterMapping : 1;
117 unsigned forcedBlank : 1;
118 unsigned bg0Enable : 1;
119 unsigned bg1Enable : 1;
120 unsigned bg2Enable : 1;
121 unsigned bg3Enable : 1;
122 unsigned objEnable : 1;
123 unsigned win0Enable : 1;
124 unsigned win1Enable : 1;
125 unsigned objwinEnable : 1;
126 };
127 uint16_t packed;
128};
129
130union GBARegisterBGCNT {
131 struct {
132 unsigned priority : 2;
133 unsigned charBase : 2;
134 unsigned : 2;
135 unsigned mosaic : 1;
136 unsigned multipalette : 1;
137 unsigned screenBase : 5;
138 unsigned overflow : 1;
139 unsigned size : 2;
140 };
141 uint16_t packed;
142};
143
144struct GBAVideoRenderer {
145 void (*init)(struct GBAVideoRenderer* renderer);
146 void (*deinit)(struct GBAVideoRenderer* renderer);
147
148 uint16_t (*writeVideoRegister)(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value);
149 void (*drawScanline)(struct GBAVideoRenderer* renderer, int y);
150 void (*finishFrame)(struct GBAVideoRenderer* renderer);
151
152 uint16_t* palette;
153 uint16_t* vram;
154 union GBAOAM* oam;
155
156 int framesPending;
157 int turbo;
158};
159
160struct GBAVideo {
161 struct GBA* p;
162 struct GBAVideoRenderer* renderer;
163
164 // DISPSTAT
165 int inHblank;
166 int inVblank;
167 int vcounter;
168 int vblankIRQ;
169 int hblankIRQ;
170 int vcounterIRQ;
171 int vcountSetting;
172
173 // VCOUNT
174 int vcount;
175
176 int32_t lastHblank;
177 int32_t nextHblank;
178 int32_t nextEvent;
179 int32_t eventDiff;
180
181 int32_t nextHblankIRQ;
182 int32_t nextVblankIRQ;
183 int32_t nextVcounterIRQ;
184
185 uint16_t palette[SIZE_PALETTE_RAM >> 1];
186 uint16_t vram[SIZE_VRAM >> 1];
187 union GBAOAM oam;
188};
189
190void GBAVideoInit(struct GBAVideo* video);
191void GBAVideoAssociateRenderer(struct GBAVideo* video, struct GBAVideoRenderer* renderer);
192int32_t GBAVideoProcessEvents(struct GBAVideo* video, int32_t cycles);
193
194void GBAVideoWriteDISPSTAT(struct GBAVideo* video, uint16_t value);
195uint16_t GBAVideoReadDISPSTAT(struct GBAVideo* video);
196
197#endif