src/gba/gba-video.h (view raw)
1#ifndef GBA_VIDEO_H
2#define GBA_VIDEO_H
3
4#include "common.h"
5
6#include "gba-memory.h"
7
8#ifdef COLOR_16_BIT
9#define BYTES_PER_PIXEL 2
10#else
11#define BYTES_PER_PIXEL 4
12#endif
13
14enum {
15 VIDEO_CYCLES_PER_PIXEL = 4,
16
17 VIDEO_HORIZONTAL_PIXELS = 240,
18 VIDEO_HBLANK_PIXELS = 68,
19 VIDEO_HDRAW_LENGTH = 1006,
20 VIDEO_HBLANK_LENGTH = 226,
21 VIDEO_HORIZONTAL_LENGTH = 1232,
22
23 VIDEO_VERTICAL_PIXELS = 160,
24 VIDEO_VBLANK_PIXELS = 68,
25 VIDEO_VERTICAL_TOTAL_PIXELS = 228,
26
27 VIDEO_TOTAL_LENGTH = 280896,
28
29 REG_DISPSTAT_MASK = 0xFF38,
30
31 BASE_TILE = 0x00010000
32};
33
34enum ObjMode {
35 OBJ_MODE_NORMAL = 0,
36 OBJ_MODE_SEMITRANSPARENT = 1,
37 OBJ_MODE_OBJWIN = 2
38};
39
40enum ObjShape {
41 OBJ_SHAPE_SQUARE = 0,
42 OBJ_SHAPE_HORIZONTAL = 1,
43 OBJ_SHAPE_VERTICAL = 2
44};
45
46struct GBAObj {
47 unsigned y : 8;
48 unsigned transformed : 1;
49 unsigned disable : 1;
50 enum ObjMode mode : 2;
51 unsigned mosaic : 1;
52 unsigned multipalette : 1;
53 enum ObjShape shape : 2;
54
55 int x : 9;
56 int : 3;
57 unsigned hflip : 1;
58 unsigned vflip : 1;
59 unsigned size : 2;
60
61 unsigned tile : 10;
62 unsigned priority : 2;
63 unsigned palette : 4;
64
65 int : 16;
66};
67
68struct GBATransformedObj {
69 unsigned y : 8;
70 unsigned transformed : 1;
71 unsigned doublesize : 1;
72 enum ObjMode mode : 2;
73 unsigned mosaic : 1;
74 unsigned multipalette : 1;
75 enum ObjShape shape : 2;
76
77 int x : 9;
78 unsigned matIndex : 5;
79 unsigned size : 2;
80
81 unsigned tile : 10;
82 unsigned priority : 2;
83 unsigned palette : 4;
84
85 int : 16;
86};
87
88union GBAOAM {
89 struct GBAObj obj[128];
90 struct GBATransformedObj tobj[128];
91
92 struct GBAOAMMatrix {
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
114#define GBA_TEXT_MAP_TILE(MAP) ((MAP) & 0x03FF)
115#define GBA_TEXT_MAP_HFLIP(MAP) ((MAP) & 0x0400)
116#define GBA_TEXT_MAP_VFLIP(MAP) ((MAP) & 0x0800)
117#define GBA_TEXT_MAP_PALETTE(MAP) (((MAP) & 0xF000) >> 12)
118
119DECL_BITFIELD(GBARegisterDISPCNT, uint16_t);
120DECL_BITS(GBARegisterDISPCNT, Mode, 0, 3);
121DECL_BIT(GBARegisterDISPCNT, Cgb, 3);
122DECL_BIT(GBARegisterDISPCNT, FrameSelect, 4);
123DECL_BIT(GBARegisterDISPCNT, HblankIntervalFree, 5);
124DECL_BIT(GBARegisterDISPCNT, ObjCharacterMapping, 6);
125DECL_BIT(GBARegisterDISPCNT, ForcedBlank, 7);
126DECL_BIT(GBARegisterDISPCNT, Bg0Enable, 8);
127DECL_BIT(GBARegisterDISPCNT, Bg1Enable, 9);
128DECL_BIT(GBARegisterDISPCNT, Bg2Enable, 10);
129DECL_BIT(GBARegisterDISPCNT, Bg3Enable, 11);
130DECL_BIT(GBARegisterDISPCNT, ObjEnable, 12);
131DECL_BIT(GBARegisterDISPCNT, Win0Enable, 13);
132DECL_BIT(GBARegisterDISPCNT, Win1Enable, 14);
133DECL_BIT(GBARegisterDISPCNT, ObjwinEnable, 15);
134
135union GBARegisterDISPSTAT {
136 struct {
137 unsigned inVblank : 1;
138 unsigned inHblank : 1;
139 unsigned vcounter : 1;
140 unsigned vblankIRQ : 1;
141 unsigned hblankIRQ : 1;
142 unsigned vcounterIRQ : 1;
143 unsigned : 2;
144 unsigned vcountSetting : 8;
145 };
146 uint32_t packed;
147};
148
149union GBARegisterBGCNT {
150 struct {
151 unsigned priority : 2;
152 unsigned charBase : 2;
153 unsigned : 2;
154 unsigned mosaic : 1;
155 unsigned multipalette : 1;
156 unsigned screenBase : 5;
157 unsigned overflow : 1;
158 unsigned size : 2;
159 };
160 uint16_t packed;
161};
162
163struct GBAVideoRenderer {
164 void (*init)(struct GBAVideoRenderer* renderer);
165 void (*reset)(struct GBAVideoRenderer* renderer);
166 void (*deinit)(struct GBAVideoRenderer* renderer);
167
168 uint16_t (*writeVideoRegister)(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value);
169 void (*writePalette)(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value);
170 void (*writeOAM)(struct GBAVideoRenderer* renderer, uint32_t oam);
171 void (*drawScanline)(struct GBAVideoRenderer* renderer, int y);
172 void (*finishFrame)(struct GBAVideoRenderer* renderer);
173
174 void (*getPixels)(struct GBAVideoRenderer* renderer, unsigned* stride, void** pixels);
175 void (*putPixels)(struct GBAVideoRenderer* renderer, unsigned stride, void* pixels);
176
177 uint16_t* palette;
178 uint16_t* vram;
179 union GBAOAM* oam;
180};
181
182struct GBAVideo {
183 struct GBA* p;
184 struct GBAVideoRenderer* renderer;
185
186 // DISPSTAT
187 int inHblank;
188 int inVblank;
189 int vcounter;
190 int vblankIRQ;
191 int hblankIRQ;
192 int vcounterIRQ;
193 int vcountSetting;
194
195 // VCOUNT
196 int vcount;
197
198 int32_t lastHblank;
199 int32_t nextHblank;
200 int32_t nextEvent;
201 int32_t eventDiff;
202
203 int32_t nextHblankIRQ;
204 int32_t nextVblankIRQ;
205 int32_t nextVcounterIRQ;
206
207 uint16_t palette[SIZE_PALETTE_RAM >> 1];
208 uint16_t* vram;
209 union GBAOAM oam;
210};
211
212void GBAVideoInit(struct GBAVideo* video);
213void GBAVideoReset(struct GBAVideo* video);
214void GBAVideoDeinit(struct GBAVideo* video);
215void GBAVideoAssociateRenderer(struct GBAVideo* video, struct GBAVideoRenderer* renderer);
216int32_t GBAVideoProcessEvents(struct GBAVideo* video, int32_t cycles);
217
218void GBAVideoWriteDISPSTAT(struct GBAVideo* video, uint16_t value);
219
220struct GBASerializedState;
221void GBAVideoSerialize(struct GBAVideo* video, struct GBASerializedState* state);
222void GBAVideoDeserialize(struct GBAVideo* video, struct GBASerializedState* state);
223
224#endif