all repos — mgba @ 5122a236e0cb6ed73a274584b94d0639bf0157f3

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 "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