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