all repos — mgba @ b4d90e7e8455ecc29ea7380718b007ada083e7ee

mGBA Game Boy Advance Emulator

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
 46union GBAColor {
 47	struct {
 48		unsigned r : 5;
 49		unsigned g : 5;
 50		unsigned b : 5;
 51	};
 52	uint16_t packed;
 53};
 54
 55struct GBAObj {
 56	unsigned y : 8;
 57	unsigned transformed : 1;
 58	unsigned disable : 1;
 59	enum ObjMode mode : 2;
 60	unsigned mosaic : 1;
 61	unsigned multipalette : 1;
 62	enum ObjShape shape : 2;
 63
 64	int x : 9;
 65	int : 3;
 66	unsigned hflip : 1;
 67	unsigned vflip : 1;
 68	unsigned size : 2;
 69
 70	unsigned tile : 10;
 71	unsigned priority : 2;
 72	unsigned palette : 4;
 73
 74	int : 16;
 75};
 76
 77struct GBATransformedObj {
 78	unsigned y : 8;
 79	unsigned transformed : 1;
 80	unsigned doublesize : 1;
 81	enum ObjMode mode : 2;
 82	unsigned mosaic : 1;
 83	unsigned multipalette : 1;
 84	enum ObjShape shape : 2;
 85
 86	int x : 9;
 87	unsigned matIndex : 5;
 88	unsigned size : 2;
 89
 90	unsigned tile : 10;
 91	unsigned priority : 2;
 92	unsigned palette : 4;
 93
 94	int : 16;
 95};
 96
 97union GBAOAM {
 98	struct GBAObj obj[128];
 99	struct GBATransformedObj tobj[128];
100
101	struct GBAOAMMatrix {
102		int : 16;
103		int : 16;
104		int : 16;
105		int a : 16;
106		int : 16;
107		int : 16;
108		int : 16;
109		int b : 16;
110		int : 16;
111		int : 16;
112		int : 16;
113		int c : 16;
114		int : 16;
115		int : 16;
116		int : 16;
117		int d : 16;
118	} mat[32];
119
120	uint16_t raw[512];
121};
122
123#define GBA_TEXT_MAP_TILE(MAP) ((MAP) & 0x03FF)
124#define GBA_TEXT_MAP_HFLIP(MAP) ((MAP) & 0x0400)
125#define GBA_TEXT_MAP_VFLIP(MAP) ((MAP) & 0x0800)
126#define GBA_TEXT_MAP_PALETTE(MAP) (((MAP) & 0xF000) >> 12)
127
128union GBARegisterDISPCNT {
129	struct {
130		unsigned mode : 3;
131		unsigned cgb : 1;
132		unsigned frameSelect : 1;
133		unsigned hblankIntervalFree : 1;
134		unsigned objCharacterMapping : 1;
135		unsigned forcedBlank : 1;
136		unsigned bg0Enable : 1;
137		unsigned bg1Enable : 1;
138		unsigned bg2Enable : 1;
139		unsigned bg3Enable : 1;
140		unsigned objEnable : 1;
141		unsigned win0Enable : 1;
142		unsigned win1Enable : 1;
143		unsigned objwinEnable : 1;
144	};
145	uint16_t packed;
146};
147
148union GBARegisterDISPSTAT {
149	struct {
150		unsigned inVblank : 1;
151		unsigned inHblank : 1;
152		unsigned vcounter : 1;
153		unsigned vblankIRQ : 1;
154		unsigned hblankIRQ : 1;
155		unsigned vcounterIRQ : 1;
156		unsigned : 2;
157		unsigned vcountSetting : 8;
158	};
159	uint32_t packed;
160};
161
162union GBARegisterBGCNT {
163	struct {
164		unsigned priority : 2;
165		unsigned charBase : 2;
166		unsigned : 2;
167		unsigned mosaic : 1;
168		unsigned multipalette : 1;
169		unsigned screenBase : 5;
170		unsigned overflow : 1;
171		unsigned size : 2;
172	};
173	uint16_t packed;
174};
175
176struct GBAVideoRenderer {
177	void (*init)(struct GBAVideoRenderer* renderer);
178	void (*reset)(struct GBAVideoRenderer* renderer);
179	void (*deinit)(struct GBAVideoRenderer* renderer);
180
181	uint16_t (*writeVideoRegister)(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value);
182	void (*writePalette)(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value);
183	void (*writeOAM)(struct GBAVideoRenderer* renderer, uint32_t oam);
184	void (*drawScanline)(struct GBAVideoRenderer* renderer, int y);
185	void (*finishFrame)(struct GBAVideoRenderer* renderer);
186
187	void (*getPixels)(struct GBAVideoRenderer* renderer, unsigned* stride, void** pixels);
188	void (*putPixels)(struct GBAVideoRenderer* renderer, unsigned stride, void* pixels);
189
190	uint16_t* palette;
191	uint16_t* vram;
192	union GBAOAM* oam;
193};
194
195struct GBAVideo {
196	struct GBA* p;
197	struct GBAVideoRenderer* renderer;
198
199	// DISPSTAT
200	int inHblank;
201	int inVblank;
202	int vcounter;
203	int vblankIRQ;
204	int hblankIRQ;
205	int vcounterIRQ;
206	int vcountSetting;
207
208	// VCOUNT
209	int vcount;
210
211	int32_t lastHblank;
212	int32_t nextHblank;
213	int32_t nextEvent;
214	int32_t eventDiff;
215
216	int32_t nextHblankIRQ;
217	int32_t nextVblankIRQ;
218	int32_t nextVcounterIRQ;
219
220	uint16_t palette[SIZE_PALETTE_RAM >> 1];
221	uint16_t* vram;
222	union GBAOAM oam;
223};
224
225void GBAVideoInit(struct GBAVideo* video);
226void GBAVideoReset(struct GBAVideo* video);
227void GBAVideoDeinit(struct GBAVideo* video);
228void GBAVideoAssociateRenderer(struct GBAVideo* video, struct GBAVideoRenderer* renderer);
229int32_t GBAVideoProcessEvents(struct GBAVideo* video, int32_t cycles);
230
231void GBAVideoWriteDISPSTAT(struct GBAVideo* video, uint16_t value);
232
233struct GBASerializedState;
234void GBAVideoSerialize(struct GBAVideo* video, struct GBASerializedState* state);
235void GBAVideoDeserialize(struct GBAVideo* video, struct GBASerializedState* state);
236
237#endif