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
135DECL_BITFIELD(GBARegisterDISPSTAT, uint16_t);
136DECL_BIT(GBARegisterDISPSTAT, InVblank, 0);
137DECL_BIT(GBARegisterDISPSTAT, InHblank, 1);
138DECL_BIT(GBARegisterDISPSTAT, Vcounter, 2);
139DECL_BIT(GBARegisterDISPSTAT, VblankIRQ, 3);
140DECL_BIT(GBARegisterDISPSTAT, HblankIRQ, 4);
141DECL_BIT(GBARegisterDISPSTAT, VcounterIRQ, 5);
142DECL_BITS(GBARegisterDISPSTAT, VcountSetting, 8, 8);
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 (*reset)(struct GBAVideoRenderer* renderer);
161 void (*deinit)(struct GBAVideoRenderer* renderer);
162
163 uint16_t (*writeVideoRegister)(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value);
164 void (*writePalette)(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value);
165 void (*writeOAM)(struct GBAVideoRenderer* renderer, uint32_t oam);
166 void (*drawScanline)(struct GBAVideoRenderer* renderer, int y);
167 void (*finishFrame)(struct GBAVideoRenderer* renderer);
168
169 void (*getPixels)(struct GBAVideoRenderer* renderer, unsigned* stride, void** pixels);
170 void (*putPixels)(struct GBAVideoRenderer* renderer, unsigned stride, void* pixels);
171
172 uint16_t* palette;
173 uint16_t* vram;
174 union GBAOAM* oam;
175};
176
177struct GBAVideo {
178 struct GBA* p;
179 struct GBAVideoRenderer* renderer;
180
181 GBARegisterDISPSTAT dispstat;
182
183 // VCOUNT
184 int vcount;
185
186 int32_t lastHblank;
187 int32_t nextHblank;
188 int32_t nextEvent;
189 int32_t eventDiff;
190
191 int32_t nextHblankIRQ;
192 int32_t nextVblankIRQ;
193 int32_t nextVcounterIRQ;
194
195 uint16_t palette[SIZE_PALETTE_RAM >> 1];
196 uint16_t* vram;
197 union GBAOAM oam;
198};
199
200void GBAVideoInit(struct GBAVideo* video);
201void GBAVideoReset(struct GBAVideo* video);
202void GBAVideoDeinit(struct GBAVideo* video);
203void GBAVideoAssociateRenderer(struct GBAVideo* video, struct GBAVideoRenderer* renderer);
204int32_t GBAVideoProcessEvents(struct GBAVideo* video, int32_t cycles);
205
206void GBAVideoWriteDISPSTAT(struct GBAVideo* video, uint16_t value);
207
208struct GBASerializedState;
209void GBAVideoSerialize(struct GBAVideo* video, struct GBASerializedState* state);
210void GBAVideoDeserialize(struct GBAVideo* video, struct GBASerializedState* state);
211
212#endif