1 /* Copyright (c) 2013-2015 Jeffrey Pfau
2  *
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef CORE_INTERFACE_H
7 #define CORE_INTERFACE_H
8 
9 #include <mgba-util/common.h>
10 
11 CXX_GUARD_START
12 
13 #include <mgba-util/vector.h>
14 
15 struct mCore;
16 struct mStateExtdataItem;
17 
18 #ifdef COLOR_16_BIT
19 typedef uint16_t color_t;
20 #define BYTES_PER_PIXEL 2
21 #else
22 typedef uint32_t color_t;
23 #define BYTES_PER_PIXEL 4
24 #endif
25 
26 #define M_R5(X) ((X) & 0x1F)
27 #define M_G5(X) (((X) >> 5) & 0x1F)
28 #define M_B5(X) (((X) >> 10) & 0x1F)
29 
30 #define M_R8(X) (((((X) << 3) & 0xF8) * 0x21) >> 5)
31 #define M_G8(X) (((((X) >> 2) & 0xF8) * 0x21) >> 5)
32 #define M_B8(X) (((((X) >> 7) & 0xF8) * 0x21) >> 5)
33 
34 #define M_RGB5_TO_BGR8(X) ((M_R5(X) << 3) | (M_G5(X) << 11) | (M_B5(X) << 19))
35 #define M_RGB5_TO_RGB8(X) ((M_R5(X) << 19) | (M_G5(X) << 11) | (M_B5(X) << 3))
36 #define M_RGB8_TO_BGR5(X) ((((X) & 0xF8) >> 3) | (((X) & 0xF800) >> 6) | (((X) & 0xF80000) >> 9))
37 #define M_RGB8_TO_RGB5(X) ((((X) & 0xF8) << 7) | (((X) & 0xF800) >> 6) | (((X) & 0xF80000) >> 19))
38 
39 #ifndef COLOR_16_BIT
40 #define M_COLOR_RED   0x000000FF
41 #define M_COLOR_GREEN 0x0000FF00
42 #define M_COLOR_BLUE  0x00FF0000
43 #define M_COLOR_ALPHA 0xFF000000
44 #define M_COLOR_WHITE 0x00FFFFFF
45 
46 #define M_RGB8_TO_NATIVE(X) (((X) & 0x00FF00) | (((X) & 0x0000FF) << 16) | (((X) & 0xFF0000) >> 16))
47 #elif defined(COLOR_5_6_5)
48 #define M_COLOR_RED   0x001F
49 #define M_COLOR_GREEN 0x07E0
50 #define M_COLOR_BLUE  0xF800
51 #define M_COLOR_ALPHA 0x0000
52 #define M_COLOR_WHITE 0xFFDF
53 
54 #define M_RGB8_TO_NATIVE(X) ((((X) & 0xF8) << 8) | (((X) & 0xFC00) >> 5) | (((X) & 0xF80000) >> 19))
55 #else
56 #define M_COLOR_RED   0x001F
57 #define M_COLOR_GREEN 0x03E0
58 #define M_COLOR_BLUE  0x7C00
59 #define M_COLOR_ALPHA 0x1000
60 #define M_COLOR_WHITE 0x7FFF
61 
62 #define M_RGB8_TO_NATIVE(X) M_RGB8_TO_BGR5(X)
63 #endif
64 
65 #ifndef PYCPARSE
mColorFrom555(uint16_t value)66 static inline color_t mColorFrom555(uint16_t value) {
67 #ifdef COLOR_16_BIT
68 #ifdef COLOR_5_6_5
69 	color_t color = 0;
70 	color |= (value & 0x001F) << 11;
71 	color |= (value & 0x03E0) << 1;
72 	color |= (value & 0x7C00) >> 10;
73 #else
74 	color_t color = value;
75 #endif
76 #else
77 	color_t color = M_RGB5_TO_BGR8(value);
78 	color |= (color >> 5) & 0x070707;
79 #endif
80 	return color;
81 }
82 
mColorMix5Bit(int weightA,unsigned colorA,int weightB,unsigned colorB)83 ATTRIBUTE_UNUSED static unsigned mColorMix5Bit(int weightA, unsigned colorA, int weightB, unsigned colorB) {
84 	unsigned c = 0;
85 	unsigned a, b;
86 #ifdef COLOR_16_BIT
87 #ifdef COLOR_5_6_5
88 	a = colorA & 0xF81F;
89 	b = colorB & 0xF81F;
90 	a |= (colorA & 0x7C0) << 16;
91 	b |= (colorB & 0x7C0) << 16;
92 	c = ((a * weightA + b * weightB) / 16);
93 	if (c & 0x08000000) {
94 		c = (c & ~0x0FC00000) | 0x07C00000;
95 	}
96 	if (c & 0x0020) {
97 		c = (c & ~0x003F) | 0x001F;
98 	}
99 	if (c & 0x10000) {
100 		c = (c & ~0x1F800) | 0xF800;
101 	}
102 	c = (c & 0xF81F) | ((c >> 16) & 0x07C0);
103 #else
104 	a = colorA & 0x7C1F;
105 	b = colorB & 0x7C1F;
106 	a |= (colorA & 0x3E0) << 16;
107 	b |= (colorB & 0x3E0) << 16;
108 	c = ((a * weightA + b * weightB) / 16);
109 	if (c & 0x04000000) {
110 		c = (c & ~0x07E00000) | 0x03E00000;
111 	}
112 	if (c & 0x0020) {
113 		c = (c & ~0x003F) | 0x001F;
114 	}
115 	if (c & 0x8000) {
116 		c = (c & ~0xF800) | 0x7C00;
117 	}
118 	c = (c & 0x7C1F) | ((c >> 16) & 0x03E0);
119 #endif
120 #else
121 	a = colorA & 0xFF;
122 	b = colorB & 0xFF;
123 	c |= ((a * weightA + b * weightB) / 16) & 0x1FF;
124 	if (c & 0x00000100) {
125 		c = 0x000000FF;
126 	}
127 
128 	a = colorA & 0xFF00;
129 	b = colorB & 0xFF00;
130 	c |= ((a * weightA + b * weightB) / 16) & 0x1FF00;
131 	if (c & 0x00010000) {
132 		c = (c & 0x000000FF) | 0x0000FF00;
133 	}
134 
135 	a = colorA & 0xFF0000;
136 	b = colorB & 0xFF0000;
137 	c |= ((a * weightA + b * weightB) / 16) & 0x1FF0000;
138 	if (c & 0x01000000) {
139 		c = (c & 0x0000FFFF) | 0x00FF0000;
140 	}
141 #endif
142 	return c;
143 }
144 #endif
145 
146 struct blip_t;
147 
148 enum mColorFormat {
149 	mCOLOR_XBGR8  = 0x00001,
150 	mCOLOR_XRGB8  = 0x00002,
151 	mCOLOR_BGRX8  = 0x00004,
152 	mCOLOR_RGBX8  = 0x00008,
153 	mCOLOR_ABGR8  = 0x00010,
154 	mCOLOR_ARGB8  = 0x00020,
155 	mCOLOR_BGRA8  = 0x00040,
156 	mCOLOR_RGBA8  = 0x00080,
157 	mCOLOR_RGB5   = 0x00100,
158 	mCOLOR_BGR5   = 0x00200,
159 	mCOLOR_RGB565 = 0x00400,
160 	mCOLOR_BGR565 = 0x00800,
161 	mCOLOR_ARGB5  = 0x01000,
162 	mCOLOR_ABGR5  = 0x02000,
163 	mCOLOR_RGBA5  = 0x04000,
164 	mCOLOR_BGRA5  = 0x08000,
165 	mCOLOR_RGB8   = 0x10000,
166 	mCOLOR_BGR8   = 0x20000,
167 
168 	mCOLOR_ANY    = -1
169 };
170 
171 enum mCoreFeature {
172 	mCORE_FEATURE_OPENGL = 1,
173 };
174 
175 struct mCoreCallbacks {
176 	void* context;
177 	void (*videoFrameStarted)(void* context);
178 	void (*videoFrameEnded)(void* context);
179 	void (*coreCrashed)(void* context);
180 	void (*sleep)(void* context);
181 	void (*shutdown)(void* context);
182 	void (*keysRead)(void* context);
183 	void (*savedataUpdated)(void* context);
184 };
185 
186 DECLARE_VECTOR(mCoreCallbacksList, struct mCoreCallbacks);
187 
188 struct mAVStream {
189 	void (*videoDimensionsChanged)(struct mAVStream*, unsigned width, unsigned height);
190 	void (*postVideoFrame)(struct mAVStream*, const color_t* buffer, size_t stride);
191 	void (*postAudioFrame)(struct mAVStream*, int16_t left, int16_t right);
192 	void (*postAudioBuffer)(struct mAVStream*, struct blip_t* left, struct blip_t* right);
193 };
194 
195 struct mKeyCallback {
196 	uint16_t (*readKeys)(struct mKeyCallback*);
197 };
198 
199 enum mPeripheral {
200 	mPERIPH_ROTATION = 1,
201 	mPERIPH_RUMBLE,
202 	mPERIPH_IMAGE_SOURCE,
203 	mPERIPH_CUSTOM = 0x1000
204 };
205 
206 struct mRotationSource {
207 	void (*sample)(struct mRotationSource*);
208 
209 	int32_t (*readTiltX)(struct mRotationSource*);
210 	int32_t (*readTiltY)(struct mRotationSource*);
211 
212 	int32_t (*readGyroZ)(struct mRotationSource*);
213 };
214 
215 struct mRTCSource {
216 	void (*sample)(struct mRTCSource*);
217 
218 	time_t (*unixTime)(struct mRTCSource*);
219 
220 	void (*serialize)(struct mRTCSource*, struct mStateExtdataItem*);
221 	bool (*deserialize)(struct mRTCSource*, const struct mStateExtdataItem*);
222 };
223 
224 struct mImageSource {
225 	void (*startRequestImage)(struct mImageSource*, unsigned w, unsigned h, int colorFormats);
226 	void (*stopRequestImage)(struct mImageSource*);
227 	void (*requestImage)(struct mImageSource*, const void** buffer, size_t* stride, enum mColorFormat* colorFormat);
228 };
229 
230 enum mRTCGenericType {
231 	RTC_NO_OVERRIDE,
232 	RTC_FIXED,
233 	RTC_FAKE_EPOCH,
234 	RTC_CUSTOM_START = 0x1000
235 };
236 
237 struct mRTCGenericSource {
238 	struct mRTCSource d;
239 	struct mCore* p;
240 	enum mRTCGenericType override;
241 	int64_t value;
242 	struct mRTCSource* custom;
243 };
244 
245 struct mRTCGenericState {
246 	int32_t type;
247 	int32_t padding;
248 	int64_t value;
249 };
250 
251 void mRTCGenericSourceInit(struct mRTCGenericSource* rtc, struct mCore* core);
252 
253 struct mRumble {
254 	void (*setRumble)(struct mRumble*, int enable);
255 };
256 
257 struct mCoreChannelInfo {
258 	size_t id;
259 	const char* internalName;
260 	const char* visibleName;
261 	const char* visibleType;
262 };
263 
264 enum mCoreMemoryBlockFlags {
265 	mCORE_MEMORY_READ = 0x01,
266 	mCORE_MEMORY_WRITE = 0x02,
267 	mCORE_MEMORY_RW = 0x03,
268 	mCORE_MEMORY_WORM = 0x04,
269 	mCORE_MEMORY_MAPPED = 0x10,
270 	mCORE_MEMORY_VIRTUAL = 0x20,
271 };
272 
273 struct mCoreMemoryBlock {
274 	size_t id;
275 	const char* internalName;
276 	const char* shortName;
277 	const char* longName;
278 	uint32_t start;
279 	uint32_t end;
280 	uint32_t size;
281 	uint32_t flags;
282 	uint16_t maxSegment;
283 	uint32_t segmentStart;
284 };
285 
286 CXX_GUARD_END
287 
288 #endif
289