rlm@1
|
1 #include <cstdlib>
|
rlm@1
|
2 #include <cstring>
|
rlm@1
|
3
|
rlm@1
|
4 #include "../common/System.h"
|
rlm@1
|
5 #include "../common/Util.h"
|
rlm@1
|
6 #include "GB.h"
|
rlm@1
|
7 #include "gbGlobals.h"
|
rlm@1
|
8 #include "../common/movie.h"
|
rlm@1
|
9
|
rlm@1
|
10 extern u8 * pix;
|
rlm@1
|
11
|
rlm@1
|
12 #define GBSGB_NONE 0
|
rlm@1
|
13 #define GBSGB_RESET 1
|
rlm@1
|
14 #define GBSGB_PACKET_TRANSMIT 2
|
rlm@1
|
15
|
rlm@1
|
16 u8 gbSgbBorderChar [32 * 256];
|
rlm@1
|
17 u8 gbSgbBorder [2048];
|
rlm@1
|
18
|
rlm@1
|
19 int32 gbSgbCGBSupport = 0;
|
rlm@1
|
20 int32 gbSgbMask = 0;
|
rlm@1
|
21 int32 gbSgbMode = 0;
|
rlm@1
|
22 int32 gbSgbPacketState = GBSGB_NONE;
|
rlm@1
|
23 int32 gbSgbBit = 0;
|
rlm@1
|
24 int32 gbSgbPacketTimeout = 0;
|
rlm@1
|
25 int32 GBSGB_PACKET_TIMEOUT = 66666;
|
rlm@1
|
26 u8 gbSgbPacket[16 * 7];
|
rlm@1
|
27 int32 gbSgbPacketNBits = 0;
|
rlm@1
|
28 int32 gbSgbPacketByte = 0;
|
rlm@1
|
29 int32 gbSgbPacketNumber = 0;
|
rlm@1
|
30 int32 gbSgbMultiplayer = 0;
|
rlm@1
|
31 int32 gbSgbFourPlayers = 0;
|
rlm@1
|
32 u8 gbSgbNextController = 0x0f;
|
rlm@1
|
33 u8 gbSgbReadingController = 0;
|
rlm@1
|
34 u16 gbSgbSCPPalette[4 * 512];
|
rlm@1
|
35 u8 gbSgbATF[20 * 18];
|
rlm@1
|
36 u8 gbSgbATFList[45 * 20 * 18];
|
rlm@1
|
37 u8 gbSgbScreenBuffer[4160];
|
rlm@1
|
38
|
rlm@1
|
39 inline void gbSgbDraw24Bit(u8 *p, u16 v)
|
rlm@1
|
40 {
|
rlm@1
|
41 *((u32 *) p) = systemColorMap32[v];
|
rlm@1
|
42 }
|
rlm@1
|
43
|
rlm@1
|
44 inline void gbSgbDraw32Bit(u32 *p, u16 v)
|
rlm@1
|
45 {
|
rlm@1
|
46 *p = systemColorMap32[v];
|
rlm@1
|
47 }
|
rlm@1
|
48
|
rlm@1
|
49 inline void gbSgbDraw16Bit(u16 *p, u16 v)
|
rlm@1
|
50 {
|
rlm@1
|
51 *p = systemColorMap16[v];
|
rlm@1
|
52 }
|
rlm@1
|
53
|
rlm@1
|
54 void gbSgbReset()
|
rlm@1
|
55 {
|
rlm@1
|
56 gbSgbPacketTimeout = 0;
|
rlm@1
|
57 gbSgbCGBSupport = 0;
|
rlm@1
|
58 gbSgbMask = 0;
|
rlm@1
|
59 gbSgbPacketState = GBSGB_NONE;
|
rlm@1
|
60 gbSgbBit = 0;
|
rlm@1
|
61 gbSgbPacketNBits = 0;
|
rlm@1
|
62 gbSgbPacketNumber = 0;
|
rlm@1
|
63 gbSgbMultiplayer = 0;
|
rlm@1
|
64 gbSgbFourPlayers = 0;
|
rlm@1
|
65 gbSgbNextController = 0x0f;
|
rlm@1
|
66 gbSgbReadingController = 0;
|
rlm@1
|
67
|
rlm@1
|
68 memset(gbSgbSCPPalette, 0, 512 * 4);
|
rlm@1
|
69 memset(gbSgbATF, 0, 20 * 18);
|
rlm@1
|
70 memset(gbSgbATFList, 0, 45 * 20 * 18);
|
rlm@1
|
71 memset(gbSgbPacket, 0, 16 * 7);
|
rlm@1
|
72 memset(gbSgbBorderChar, 0, 32 * 256);
|
rlm@1
|
73 memset(gbSgbBorder, 0, 2048);
|
rlm@1
|
74
|
rlm@1
|
75 int i;
|
rlm@1
|
76 for (i = 1; i < 2048; i += 2)
|
rlm@1
|
77 {
|
rlm@1
|
78 gbSgbBorder[i] = 1 << 2;
|
rlm@1
|
79 }
|
rlm@1
|
80
|
rlm@1
|
81 for (i = 0; i < 4; i++)
|
rlm@1
|
82 {
|
rlm@1
|
83 gbPalette[i * 4] = (0x1f) | (0x1f << 5) | (0x1f << 10);
|
rlm@1
|
84 gbPalette[i * 4 + 1] = (0x15) | (0x15 << 5) | (0x15 << 10);
|
rlm@1
|
85 gbPalette[i * 4 + 2] = (0x0c) | (0x0c << 5) | (0x0c << 10);
|
rlm@1
|
86 gbPalette[i * 4 + 3] = 0;
|
rlm@1
|
87 }
|
rlm@1
|
88 }
|
rlm@1
|
89
|
rlm@1
|
90 void gbSgbInit()
|
rlm@1
|
91 {
|
rlm@1
|
92 gbSgbReset();
|
rlm@1
|
93 }
|
rlm@1
|
94
|
rlm@1
|
95 void gbSgbShutdown()
|
rlm@1
|
96 {
|
rlm@1
|
97 memset(gbSgbBorderChar, 0, 32 * 256);
|
rlm@1
|
98 memset(gbSgbBorder, 0, 2048);
|
rlm@1
|
99 }
|
rlm@1
|
100
|
rlm@1
|
101 void gbSgbFillScreen(u16 color)
|
rlm@1
|
102 {
|
rlm@1
|
103 switch (systemColorDepth)
|
rlm@1
|
104 {
|
rlm@1
|
105 case 16:
|
rlm@1
|
106 {
|
rlm@1
|
107 for (int y = 0; y < 144; y++)
|
rlm@1
|
108 {
|
rlm@1
|
109 int yLine = (y + gbBorderRowSkip + 1) * (gbBorderLineSkip + 2) +
|
rlm@1
|
110 gbBorderColumnSkip;
|
rlm@1
|
111 u16 *dest = (u16 *)pix + yLine;
|
rlm@1
|
112 for (register int x = 0; x < 160; x++)
|
rlm@1
|
113 gbSgbDraw16Bit(dest++, color);
|
rlm@1
|
114 }
|
rlm@1
|
115 }
|
rlm@1
|
116 break;
|
rlm@1
|
117 case 24:
|
rlm@1
|
118 {
|
rlm@1
|
119 for (int y = 0; y < 144; y++)
|
rlm@1
|
120 {
|
rlm@1
|
121 int yLine = (y + gbBorderRowSkip) * gbBorderLineSkip + gbBorderColumnSkip;
|
rlm@1
|
122 u8 *dest = (u8 *)pix + yLine * 3;
|
rlm@1
|
123 for (register int x = 0; x < 160; x++)
|
rlm@1
|
124 {
|
rlm@1
|
125 gbSgbDraw24Bit(dest, color);
|
rlm@1
|
126 dest += 3;
|
rlm@1
|
127 }
|
rlm@1
|
128 }
|
rlm@1
|
129 }
|
rlm@1
|
130 break;
|
rlm@1
|
131 case 32:
|
rlm@1
|
132 {
|
rlm@1
|
133 for (int y = 0; y < 144; y++)
|
rlm@1
|
134 {
|
rlm@1
|
135 int yLine = (y + gbBorderRowSkip + 1) * (gbBorderLineSkip + 1) + gbBorderColumnSkip;
|
rlm@1
|
136 u32 *dest = (u32 *)pix + yLine;
|
rlm@1
|
137 for (register int x = 0; x < 160; x++)
|
rlm@1
|
138 {
|
rlm@1
|
139 gbSgbDraw32Bit(dest++, color);
|
rlm@1
|
140 }
|
rlm@1
|
141 }
|
rlm@1
|
142 }
|
rlm@1
|
143 break;
|
rlm@1
|
144 }
|
rlm@1
|
145 }
|
rlm@1
|
146
|
rlm@1
|
147 void gbSgbRenderScreenToBuffer()
|
rlm@1
|
148 {
|
rlm@1
|
149 u16 mapAddress = 0x9800;
|
rlm@1
|
150
|
rlm@1
|
151 if (register_LCDC & 0x08)
|
rlm@1
|
152 mapAddress = 0x9c00;
|
rlm@1
|
153
|
rlm@1
|
154 u16 patternAddress = 0x8800;
|
rlm@1
|
155
|
rlm@1
|
156 int flag = 1;
|
rlm@1
|
157
|
rlm@1
|
158 if (register_LCDC & 0x10)
|
rlm@1
|
159 {
|
rlm@1
|
160 patternAddress = 0x8000;
|
rlm@1
|
161 flag = 0;
|
rlm@1
|
162 }
|
rlm@1
|
163
|
rlm@1
|
164 u8 *toAddress = gbSgbScreenBuffer;
|
rlm@1
|
165
|
rlm@1
|
166 for (int i = 0; i < 13; i++)
|
rlm@1
|
167 {
|
rlm@1
|
168 for (int j = 0; j < 20; j++)
|
rlm@1
|
169 {
|
rlm@1
|
170 int tile = gbReadMemoryQuick(mapAddress);
|
rlm@1
|
171 mapAddress++;
|
rlm@1
|
172
|
rlm@1
|
173 if (flag)
|
rlm@1
|
174 {
|
rlm@1
|
175 if (tile > 127)
|
rlm@1
|
176 tile -= 128;
|
rlm@1
|
177 else
|
rlm@1
|
178 tile += 128;
|
rlm@1
|
179 }
|
rlm@1
|
180 for (int k = 0; k < 16; k++)
|
rlm@1
|
181 *toAddress++ = gbReadMemoryQuick(patternAddress + tile * 16 + k);
|
rlm@1
|
182 }
|
rlm@1
|
183 mapAddress += 12;
|
rlm@1
|
184 }
|
rlm@1
|
185 }
|
rlm@1
|
186
|
rlm@1
|
187 void gbSgbDrawBorderTile(int x, int y, int tile, int attr)
|
rlm@1
|
188 {
|
rlm@1
|
189 u16 *dest = (u16 *)pix + ((y + 1) * (256 + 2)) + x;
|
rlm@1
|
190 u8 * dest8 = (u8 *)pix + ((y * 256) + x) * 3;
|
rlm@1
|
191 u32 *dest32 = (u32 *)pix + ((y + 1) * 257) + x;
|
rlm@1
|
192
|
rlm@1
|
193 u8 *tileAddress = &gbSgbBorderChar[tile * 32];
|
rlm@1
|
194 u8 *tileAddress2 = &gbSgbBorderChar[tile * 32 + 16];
|
rlm@1
|
195
|
rlm@1
|
196 u8 l = 8;
|
rlm@1
|
197
|
rlm@1
|
198 u8 palette = ((attr >> 2) & 7);
|
rlm@1
|
199
|
rlm@1
|
200 if (palette < 4)
|
rlm@1
|
201 palette += 4;
|
rlm@1
|
202
|
rlm@1
|
203 palette *= 16;
|
rlm@1
|
204
|
rlm@1
|
205 u8 xx = 0;
|
rlm@1
|
206 u8 yy = 0;
|
rlm@1
|
207
|
rlm@1
|
208 int flipX = attr & 0x40;
|
rlm@1
|
209 int flipY = attr & 0x80;
|
rlm@1
|
210
|
rlm@1
|
211 while (l > 0)
|
rlm@1
|
212 {
|
rlm@1
|
213 u8 mask = 0x80;
|
rlm@1
|
214 u8 a = *tileAddress++;
|
rlm@1
|
215 u8 b = *tileAddress++;
|
rlm@1
|
216 u8 c = *tileAddress2++;
|
rlm@1
|
217 u8 d = *tileAddress2++;
|
rlm@1
|
218
|
rlm@1
|
219 while (mask > 0)
|
rlm@1
|
220 {
|
rlm@1
|
221 u8 color = 0;
|
rlm@1
|
222 if (a & mask)
|
rlm@1
|
223 color++;
|
rlm@1
|
224 if (b & mask)
|
rlm@1
|
225 color += 2;
|
rlm@1
|
226 if (c & mask)
|
rlm@1
|
227 color += 4;
|
rlm@1
|
228 if (d & mask)
|
rlm@1
|
229 color += 8;
|
rlm@1
|
230
|
rlm@1
|
231 u8 xxx = xx;
|
rlm@1
|
232 u8 yyy = yy;
|
rlm@1
|
233
|
rlm@1
|
234 if (flipX)
|
rlm@1
|
235 xxx = 7 - xx;
|
rlm@1
|
236 if (flipY)
|
rlm@1
|
237 yyy = 7 - yy;
|
rlm@1
|
238
|
rlm@1
|
239 u8 realx = x + xxx;
|
rlm@1
|
240 u8 realy = y + yyy;
|
rlm@1
|
241
|
rlm@1
|
242 u16 c = gbPalette[palette + color];
|
rlm@1
|
243 if (!color)
|
rlm@1
|
244 c = gbPalette[0];
|
rlm@1
|
245 if ((realy < 40 || realy >= 184) || (realx < 48 || realx >= 208))
|
rlm@1
|
246 {
|
rlm@1
|
247 switch (systemColorDepth)
|
rlm@1
|
248 {
|
rlm@1
|
249 case 16:
|
rlm@1
|
250 gbSgbDraw16Bit(dest + yyy * (256 + 2) + xxx, c);
|
rlm@1
|
251 break;
|
rlm@1
|
252 case 24:
|
rlm@1
|
253 gbSgbDraw24Bit(dest8 + (yyy * 256 + xxx) * 3, c);
|
rlm@1
|
254 break;
|
rlm@1
|
255 case 32:
|
rlm@1
|
256 gbSgbDraw32Bit(dest32 + yyy * (256 + 1) + xxx, c);
|
rlm@1
|
257 break;
|
rlm@1
|
258 }
|
rlm@1
|
259 }
|
rlm@1
|
260
|
rlm@1
|
261 mask >>= 1;
|
rlm@1
|
262
|
rlm@1
|
263 xx++;
|
rlm@1
|
264 }
|
rlm@1
|
265 yy++;
|
rlm@1
|
266 xx = 0;
|
rlm@1
|
267 l--;
|
rlm@1
|
268 mask = 0x80;
|
rlm@1
|
269 }
|
rlm@1
|
270 }
|
rlm@1
|
271
|
rlm@1
|
272 void gbSgbRenderBorder()
|
rlm@1
|
273 {
|
rlm@1
|
274 if (gbBorderOn)
|
rlm@1
|
275 {
|
rlm@1
|
276 u8 *fromAddress = gbSgbBorder;
|
rlm@1
|
277
|
rlm@1
|
278 for (u8 y = 0; y < 28; y++)
|
rlm@1
|
279 {
|
rlm@1
|
280 for (u8 x = 0; x < 32; x++)
|
rlm@1
|
281 {
|
rlm@1
|
282 u8 tile = *fromAddress++;
|
rlm@1
|
283 u8 attr = *fromAddress++;
|
rlm@1
|
284
|
rlm@1
|
285 gbSgbDrawBorderTile(x * 8, y * 8, tile, attr);
|
rlm@1
|
286 }
|
rlm@1
|
287 }
|
rlm@1
|
288 }
|
rlm@1
|
289 }
|
rlm@1
|
290
|
rlm@1
|
291 void gbSgbPicture()
|
rlm@1
|
292 {
|
rlm@1
|
293 gbSgbRenderScreenToBuffer();
|
rlm@1
|
294
|
rlm@1
|
295 memcpy(gbSgbBorder, gbSgbScreenBuffer, 2048);
|
rlm@1
|
296
|
rlm@1
|
297 u16 *paletteAddr = (u16 *)&gbSgbScreenBuffer[2048];
|
rlm@1
|
298
|
rlm@1
|
299 for (int i = 64; i < 128; i++)
|
rlm@1
|
300 {
|
rlm@1
|
301 gbPalette[i] = READ16LE(paletteAddr++);
|
rlm@1
|
302 }
|
rlm@1
|
303
|
rlm@1
|
304 gbSgbCGBSupport |= 4;
|
rlm@1
|
305
|
rlm@1
|
306 if (gbBorderAutomatic && !gbBorderOn && gbSgbCGBSupport > 4)
|
rlm@1
|
307 {
|
rlm@1
|
308 gbBorderOn = 1;
|
rlm@1
|
309 systemGbBorderOn();
|
rlm@1
|
310 }
|
rlm@1
|
311
|
rlm@1
|
312 if (gbBorderOn && !gbSgbMask)
|
rlm@1
|
313 gbSgbRenderBorder();
|
rlm@1
|
314
|
rlm@1
|
315 if (gbSgbMode && gbCgbMode && gbSgbCGBSupport > 4)
|
rlm@1
|
316 {
|
rlm@1
|
317 gbSgbCGBSupport = 0;
|
rlm@1
|
318 gbSgbMode = 2;
|
rlm@1
|
319 gbSgbMask = 0;
|
rlm@1
|
320 gbSgbRenderBorder();
|
rlm@1
|
321 gbReset();
|
rlm@1
|
322 }
|
rlm@1
|
323
|
rlm@1
|
324 if (gbSgbCGBSupport > 4)
|
rlm@1
|
325 gbSgbCGBSupport = 0;
|
rlm@1
|
326 }
|
rlm@1
|
327
|
rlm@1
|
328 void gbSgbSetPalette(int a, int b, u16 *p)
|
rlm@1
|
329 {
|
rlm@1
|
330 u16 bit00 = READ16LE(p++);
|
rlm@1
|
331 int i;
|
rlm@1
|
332
|
rlm@1
|
333 for (i = 1; i < 4; i++)
|
rlm@1
|
334 {
|
rlm@1
|
335 gbPalette[a * 4 + i] = READ16LE(p++);
|
rlm@1
|
336 }
|
rlm@1
|
337
|
rlm@1
|
338 for (i = 1; i < 4; i++)
|
rlm@1
|
339 {
|
rlm@1
|
340 gbPalette[b * 4 + i] = READ16LE(p++);
|
rlm@1
|
341 }
|
rlm@1
|
342
|
rlm@1
|
343 gbPalette[0] = gbPalette[4] = gbPalette[8] = gbPalette[12] = bit00;
|
rlm@1
|
344 if (gbBorderOn && !gbSgbMask)
|
rlm@1
|
345 gbSgbRenderBorder();
|
rlm@1
|
346 }
|
rlm@1
|
347
|
rlm@1
|
348 void gbSgbScpPalette()
|
rlm@1
|
349 {
|
rlm@1
|
350 gbSgbRenderScreenToBuffer();
|
rlm@1
|
351
|
rlm@1
|
352 u16 *fromAddress = (u16 *)gbSgbScreenBuffer;
|
rlm@1
|
353
|
rlm@1
|
354 for (int i = 0; i < 512 * 4; i++)
|
rlm@1
|
355 {
|
rlm@1
|
356 gbSgbSCPPalette[i] = READ16LE(fromAddress++);
|
rlm@1
|
357 }
|
rlm@1
|
358 }
|
rlm@1
|
359
|
rlm@1
|
360 void gbSgbSetATF(int n)
|
rlm@1
|
361 {
|
rlm@1
|
362 if (n < 0)
|
rlm@1
|
363 n = 0;
|
rlm@1
|
364 if (n > 44)
|
rlm@1
|
365 n = 44;
|
rlm@1
|
366 memcpy(gbSgbATF, &gbSgbATFList[n * 20 * 18], 20 * 18);
|
rlm@1
|
367
|
rlm@1
|
368 if (gbSgbPacket[1] & 0x40)
|
rlm@1
|
369 {
|
rlm@1
|
370 gbSgbMask = 0;
|
rlm@1
|
371 if (gbBorderOn)
|
rlm@1
|
372 gbSgbRenderBorder();
|
rlm@1
|
373 }
|
rlm@1
|
374 }
|
rlm@1
|
375
|
rlm@1
|
376 void gbSgbSetPalette()
|
rlm@1
|
377 {
|
rlm@1
|
378 u16 pal = READ16LE((((u16 *)&gbSgbPacket[1]))) & 511;
|
rlm@1
|
379 memcpy(&gbPalette[0], &gbSgbSCPPalette[pal * 4], 4 * sizeof(u16));
|
rlm@1
|
380
|
rlm@1
|
381 pal = READ16LE((((u16 *)&gbSgbPacket[3]))) & 511;
|
rlm@1
|
382 memcpy(&gbPalette[4], &gbSgbSCPPalette[pal * 4], 4 * sizeof(u16));
|
rlm@1
|
383
|
rlm@1
|
384 pal = READ16LE((((u16 *)&gbSgbPacket[5]))) & 511;
|
rlm@1
|
385 memcpy(&gbPalette[8], &gbSgbSCPPalette[pal * 4], 4 * sizeof(u16));
|
rlm@1
|
386
|
rlm@1
|
387 pal = READ16LE((((u16 *)&gbSgbPacket[7]))) & 511;
|
rlm@1
|
388 memcpy(&gbPalette[12], &gbSgbSCPPalette[pal * 4], 4 * sizeof(u16));
|
rlm@1
|
389
|
rlm@1
|
390 u8 atf = gbSgbPacket[9];
|
rlm@1
|
391
|
rlm@1
|
392 if (atf & 0x80)
|
rlm@1
|
393 {
|
rlm@1
|
394 gbSgbSetATF(atf & 0x3f);
|
rlm@1
|
395 }
|
rlm@1
|
396
|
rlm@1
|
397 if (atf & 0x40)
|
rlm@1
|
398 {
|
rlm@1
|
399 gbSgbMask = 0;
|
rlm@1
|
400 if (gbBorderOn)
|
rlm@1
|
401 gbSgbRenderBorder();
|
rlm@1
|
402 }
|
rlm@1
|
403 }
|
rlm@1
|
404
|
rlm@1
|
405 void gbSgbAttributeBlock()
|
rlm@1
|
406 {
|
rlm@1
|
407 u8 *fromAddress = &gbSgbPacket[1];
|
rlm@1
|
408
|
rlm@1
|
409 u8 nDataSet = *fromAddress++;
|
rlm@1
|
410 if (nDataSet > 12)
|
rlm@1
|
411 nDataSet = 12;
|
rlm@1
|
412 if (nDataSet == 0)
|
rlm@1
|
413 nDataSet = 1;
|
rlm@1
|
414
|
rlm@1
|
415 while (nDataSet)
|
rlm@1
|
416 {
|
rlm@1
|
417 u8 controlCode = (*fromAddress++) & 7;
|
rlm@1
|
418 u8 paletteDesignation = (*fromAddress++) & 0x3f;
|
rlm@1
|
419 u8 startH = (*fromAddress++) & 0x1f;
|
rlm@1
|
420 u8 startV = (*fromAddress++) & 0x1f;
|
rlm@1
|
421 u8 endH = (*fromAddress++) & 0x1f;
|
rlm@1
|
422 u8 endV = (*fromAddress++) & 0x1f;
|
rlm@1
|
423
|
rlm@1
|
424 u8 *toAddress = gbSgbATF;
|
rlm@1
|
425
|
rlm@1
|
426 for (u8 y = 0; y < 18; y++)
|
rlm@1
|
427 {
|
rlm@1
|
428 for (u8 x = 0; x < 20; x++)
|
rlm@1
|
429 {
|
rlm@1
|
430 if (x < startH || y < startV ||
|
rlm@1
|
431 x > endH || y > endV)
|
rlm@1
|
432 {
|
rlm@1
|
433 // outside
|
rlm@1
|
434 if (controlCode & 0x04)
|
rlm@1
|
435 *toAddress = (paletteDesignation >> 4) & 0x03;
|
rlm@1
|
436 }
|
rlm@1
|
437 else if (x > startH && x < endH &&
|
rlm@1
|
438 y > startV && y < endV)
|
rlm@1
|
439 {
|
rlm@1
|
440 // inside
|
rlm@1
|
441 if (controlCode & 0x01)
|
rlm@1
|
442 *toAddress = paletteDesignation & 0x03;
|
rlm@1
|
443 }
|
rlm@1
|
444 else
|
rlm@1
|
445 {
|
rlm@1
|
446 // surrounding line
|
rlm@1
|
447 if (controlCode & 0x02)
|
rlm@1
|
448 *toAddress = (paletteDesignation >> 2) & 0x03;
|
rlm@1
|
449 else if (controlCode == 0x01)
|
rlm@1
|
450 *toAddress = paletteDesignation & 0x03;
|
rlm@1
|
451 }
|
rlm@1
|
452 toAddress++;
|
rlm@1
|
453 }
|
rlm@1
|
454 }
|
rlm@1
|
455 nDataSet--;
|
rlm@1
|
456 }
|
rlm@1
|
457 }
|
rlm@1
|
458
|
rlm@1
|
459 void gbSgbSetColumnPalette(u8 col, u8 p)
|
rlm@1
|
460 {
|
rlm@1
|
461 // if(col < 0)
|
rlm@1
|
462 // col = 0;
|
rlm@1
|
463 if (col > 19)
|
rlm@1
|
464 col = 19;
|
rlm@1
|
465
|
rlm@1
|
466 p &= 3;
|
rlm@1
|
467
|
rlm@1
|
468 u8 *toAddress = &gbSgbATF[col];
|
rlm@1
|
469
|
rlm@1
|
470 for (u8 y = 0; y < 18; y++)
|
rlm@1
|
471 {
|
rlm@1
|
472 *toAddress = p;
|
rlm@1
|
473 toAddress += 20;
|
rlm@1
|
474 }
|
rlm@1
|
475 }
|
rlm@1
|
476
|
rlm@1
|
477 void gbSgbSetRowPalette(u8 row, u8 p)
|
rlm@1
|
478 {
|
rlm@1
|
479 // if(row < 0)
|
rlm@1
|
480 // row = 0;
|
rlm@1
|
481 if (row > 17)
|
rlm@1
|
482 row = 17;
|
rlm@1
|
483
|
rlm@1
|
484 p &= 3;
|
rlm@1
|
485
|
rlm@1
|
486 u8 *toAddress = &gbSgbATF[row * 20];
|
rlm@1
|
487
|
rlm@1
|
488 for (u8 x = 0; x < 20; x++)
|
rlm@1
|
489 {
|
rlm@1
|
490 *toAddress++ = p;
|
rlm@1
|
491 }
|
rlm@1
|
492 }
|
rlm@1
|
493
|
rlm@1
|
494 void gbSgbAttributeDivide()
|
rlm@1
|
495 {
|
rlm@1
|
496 u8 control = gbSgbPacket[1];
|
rlm@1
|
497 u8 coord = gbSgbPacket[2];
|
rlm@1
|
498 u8 colorBR = control & 3;
|
rlm@1
|
499 u8 colorAL = (control >> 2) & 3;
|
rlm@1
|
500 u8 colorOL = (control >> 4) & 3;
|
rlm@1
|
501
|
rlm@1
|
502 if (control & 0x40)
|
rlm@1
|
503 {
|
rlm@1
|
504 if (coord > 17)
|
rlm@1
|
505 coord = 17;
|
rlm@1
|
506
|
rlm@1
|
507 for (u8 i = 0; i < 18; i++)
|
rlm@1
|
508 {
|
rlm@1
|
509 if (i < coord)
|
rlm@1
|
510 gbSgbSetRowPalette(i, colorAL);
|
rlm@1
|
511 else if (i > coord)
|
rlm@1
|
512 gbSgbSetRowPalette(i, colorBR);
|
rlm@1
|
513 else
|
rlm@1
|
514 gbSgbSetRowPalette(i, colorOL);
|
rlm@1
|
515 }
|
rlm@1
|
516 }
|
rlm@1
|
517 else
|
rlm@1
|
518 {
|
rlm@1
|
519 if (coord > 19)
|
rlm@1
|
520 coord = 19;
|
rlm@1
|
521
|
rlm@1
|
522 for (u8 i = 0; i < 20; i++)
|
rlm@1
|
523 {
|
rlm@1
|
524 if (i < coord)
|
rlm@1
|
525 gbSgbSetColumnPalette(i, colorAL);
|
rlm@1
|
526 else if (i > coord)
|
rlm@1
|
527 gbSgbSetColumnPalette(i, colorBR);
|
rlm@1
|
528 else
|
rlm@1
|
529 gbSgbSetColumnPalette(i, colorOL);
|
rlm@1
|
530 }
|
rlm@1
|
531 }
|
rlm@1
|
532 }
|
rlm@1
|
533
|
rlm@1
|
534 void gbSgbAttributeLine()
|
rlm@1
|
535 {
|
rlm@1
|
536 u8 *fromAddress = &gbSgbPacket[1];
|
rlm@1
|
537
|
rlm@1
|
538 u8 nDataSet = *fromAddress++;
|
rlm@1
|
539
|
rlm@1
|
540 if (nDataSet > 0x6e)
|
rlm@1
|
541 nDataSet = 0x6e;
|
rlm@1
|
542
|
rlm@1
|
543 while (nDataSet)
|
rlm@1
|
544 {
|
rlm@1
|
545 u8 line = *fromAddress++;
|
rlm@1
|
546 u8 num = line & 0x1f;
|
rlm@1
|
547 u8 pal = (line >> 5) & 0x03;
|
rlm@1
|
548 if (line & 0x80)
|
rlm@1
|
549 {
|
rlm@1
|
550 if (num > 17)
|
rlm@1
|
551 num = 17;
|
rlm@1
|
552 gbSgbSetRowPalette(num, pal);
|
rlm@1
|
553 }
|
rlm@1
|
554 else
|
rlm@1
|
555 {
|
rlm@1
|
556 if (num > 19)
|
rlm@1
|
557 num = 19;
|
rlm@1
|
558 gbSgbSetColumnPalette(num, pal);
|
rlm@1
|
559 }
|
rlm@1
|
560 nDataSet--;
|
rlm@1
|
561 }
|
rlm@1
|
562 }
|
rlm@1
|
563
|
rlm@1
|
564 void gbSgbAttributeCharacter()
|
rlm@1
|
565 {
|
rlm@1
|
566 u8 startH = gbSgbPacket[1] & 0x1f;
|
rlm@1
|
567 u8 startV = gbSgbPacket[2] & 0x1f;
|
rlm@1
|
568 int nDataSet = READ16LE(((u16 *)&gbSgbPacket[3]));
|
rlm@1
|
569 int style = gbSgbPacket[5] & 1;
|
rlm@1
|
570 if (startH > 19)
|
rlm@1
|
571 startH = 19;
|
rlm@1
|
572 if (startV > 17)
|
rlm@1
|
573 startV = 17;
|
rlm@1
|
574
|
rlm@1
|
575 u8 s = 6;
|
rlm@1
|
576 u8 *fromAddress = &gbSgbPacket[6];
|
rlm@1
|
577 u8 v = *fromAddress++;
|
rlm@1
|
578
|
rlm@1
|
579 if (style)
|
rlm@1
|
580 {
|
rlm@1
|
581 while (nDataSet)
|
rlm@1
|
582 {
|
rlm@1
|
583 u8 p = (v >> s) & 3;
|
rlm@1
|
584 gbSgbATF[startV * 20 + startH] = p;
|
rlm@1
|
585 startV++;
|
rlm@1
|
586 if (startV == 18)
|
rlm@1
|
587 {
|
rlm@1
|
588 startV = 0;
|
rlm@1
|
589 startH++;
|
rlm@1
|
590 if (startH == 20)
|
rlm@1
|
591 break;
|
rlm@1
|
592 }
|
rlm@1
|
593
|
rlm@1
|
594 if (s)
|
rlm@1
|
595 s -= 2;
|
rlm@1
|
596 else
|
rlm@1
|
597 {
|
rlm@1
|
598 s = 6;
|
rlm@1
|
599 v = *fromAddress++;
|
rlm@1
|
600 nDataSet--;
|
rlm@1
|
601 }
|
rlm@1
|
602 }
|
rlm@1
|
603 }
|
rlm@1
|
604 else
|
rlm@1
|
605 {
|
rlm@1
|
606 while (nDataSet)
|
rlm@1
|
607 {
|
rlm@1
|
608 u8 p = (v >> s) & 3;
|
rlm@1
|
609 gbSgbATF[startV * 20 + startH] = p;
|
rlm@1
|
610 startH++;
|
rlm@1
|
611 if (startH == 20)
|
rlm@1
|
612 {
|
rlm@1
|
613 startH = 0;
|
rlm@1
|
614 startV++;
|
rlm@1
|
615 if (startV == 18)
|
rlm@1
|
616 break;
|
rlm@1
|
617 }
|
rlm@1
|
618
|
rlm@1
|
619 if (s)
|
rlm@1
|
620 s -= 2;
|
rlm@1
|
621 else
|
rlm@1
|
622 {
|
rlm@1
|
623 s = 6;
|
rlm@1
|
624 v = *fromAddress++;
|
rlm@1
|
625 nDataSet--;
|
rlm@1
|
626 }
|
rlm@1
|
627 }
|
rlm@1
|
628 }
|
rlm@1
|
629 }
|
rlm@1
|
630
|
rlm@1
|
631 void gbSgbSetATFList()
|
rlm@1
|
632 {
|
rlm@1
|
633 gbSgbRenderScreenToBuffer();
|
rlm@1
|
634
|
rlm@1
|
635 u8 *fromAddress = gbSgbScreenBuffer;
|
rlm@1
|
636 u8 *toAddress = gbSgbATFList;
|
rlm@1
|
637
|
rlm@1
|
638 for (int i = 0; i < 45; i++)
|
rlm@1
|
639 {
|
rlm@1
|
640 for (int j = 0; j < 90; j++)
|
rlm@1
|
641 {
|
rlm@1
|
642 u8 v = *fromAddress++;
|
rlm@1
|
643 u8 s = 6;
|
rlm@1
|
644 if (i == 2)
|
rlm@1
|
645 s = 6;
|
rlm@1
|
646 for (int k = 0; k < 4; k++)
|
rlm@1
|
647 {
|
rlm@1
|
648 *toAddress++ = (v >> s) & 0x03;
|
rlm@1
|
649 s -= 2;
|
rlm@1
|
650 }
|
rlm@1
|
651 }
|
rlm@1
|
652 }
|
rlm@1
|
653 }
|
rlm@1
|
654
|
rlm@1
|
655 void gbSgbMaskEnable()
|
rlm@1
|
656 {
|
rlm@1
|
657 int gbSgbMaskFlag = gbSgbPacket[1] & 3;
|
rlm@1
|
658
|
rlm@1
|
659 gbSgbMask = gbSgbMaskFlag;
|
rlm@1
|
660
|
rlm@1
|
661 switch (gbSgbMaskFlag)
|
rlm@1
|
662 {
|
rlm@1
|
663 case 1:
|
rlm@1
|
664 break;
|
rlm@1
|
665 case 2:
|
rlm@1
|
666 gbSgbFillScreen(0x0000);
|
rlm@1
|
667 // memset(&gbPalette[0], 0, 128*sizeof(u16));
|
rlm@1
|
668 break;
|
rlm@1
|
669 case 3:
|
rlm@1
|
670 gbSgbFillScreen(gbPalette[0]);
|
rlm@1
|
671 break;
|
rlm@1
|
672 }
|
rlm@1
|
673 if (!gbSgbMask)
|
rlm@1
|
674 {
|
rlm@1
|
675 if (gbBorderOn)
|
rlm@1
|
676 gbSgbRenderBorder();
|
rlm@1
|
677 }
|
rlm@1
|
678 }
|
rlm@1
|
679
|
rlm@1
|
680 void gbSgbChrTransfer()
|
rlm@1
|
681 {
|
rlm@1
|
682 gbSgbRenderScreenToBuffer();
|
rlm@1
|
683
|
rlm@1
|
684 int address = (gbSgbPacket[1] & 1) * (128 * 32);
|
rlm@1
|
685
|
rlm@1
|
686 if (gbSgbPacket[1] & 1)
|
rlm@1
|
687 gbSgbCGBSupport |= 2;
|
rlm@1
|
688 else
|
rlm@1
|
689 gbSgbCGBSupport |= 1;
|
rlm@1
|
690
|
rlm@1
|
691 memcpy(&gbSgbBorderChar[address], gbSgbScreenBuffer, 128 * 32);
|
rlm@1
|
692
|
rlm@1
|
693 if (gbBorderAutomatic && !gbBorderOn && gbSgbCGBSupport > 4)
|
rlm@1
|
694 {
|
rlm@1
|
695 gbBorderOn = 1;
|
rlm@1
|
696 systemGbBorderOn();
|
rlm@1
|
697 }
|
rlm@1
|
698
|
rlm@1
|
699 if (gbBorderOn && !gbSgbMask)
|
rlm@1
|
700 gbSgbRenderBorder();
|
rlm@1
|
701
|
rlm@1
|
702 if (gbSgbMode && gbCgbMode && gbSgbCGBSupport == 7)
|
rlm@1
|
703 {
|
rlm@1
|
704 gbSgbCGBSupport = 0;
|
rlm@1
|
705 gbSgbMode = 2;
|
rlm@1
|
706 gbSgbMask = 0;
|
rlm@1
|
707 gbSgbRenderBorder();
|
rlm@1
|
708 gbReset();
|
rlm@1
|
709 }
|
rlm@1
|
710
|
rlm@1
|
711 if (gbSgbCGBSupport > 4)
|
rlm@1
|
712 gbSgbCGBSupport = 0;
|
rlm@1
|
713 }
|
rlm@1
|
714
|
rlm@1
|
715 void gbSgbMultiRequest()
|
rlm@1
|
716 {
|
rlm@1
|
717 if (gbSgbPacket[1] & 1)
|
rlm@1
|
718 {
|
rlm@1
|
719 gbSgbMultiplayer = 1;
|
rlm@1
|
720 if (gbSgbPacket[1] & 2)
|
rlm@1
|
721 gbSgbFourPlayers = 1;
|
rlm@1
|
722 else
|
rlm@1
|
723 gbSgbFourPlayers = 0;
|
rlm@1
|
724 gbSgbNextController = 0x0e;
|
rlm@1
|
725 }
|
rlm@1
|
726 else
|
rlm@1
|
727 {
|
rlm@1
|
728 gbSgbFourPlayers = 0;
|
rlm@1
|
729 gbSgbMultiplayer = 0;
|
rlm@1
|
730 gbSgbNextController = 0x0f;
|
rlm@1
|
731 }
|
rlm@1
|
732 }
|
rlm@1
|
733
|
rlm@1
|
734 void gbSgbCommand()
|
rlm@1
|
735 {
|
rlm@1
|
736 int command = gbSgbPacket[0] >> 3;
|
rlm@1
|
737 // int nPacket = gbSgbPacket[0] & 7;
|
rlm@1
|
738
|
rlm@1
|
739 switch (command)
|
rlm@1
|
740 {
|
rlm@1
|
741 case 0x00:
|
rlm@1
|
742 gbSgbSetPalette(0, 1, (u16 *)&gbSgbPacket[1]);
|
rlm@1
|
743 break;
|
rlm@1
|
744 case 0x01:
|
rlm@1
|
745 gbSgbSetPalette(2, 3, (u16 *)&gbSgbPacket[1]);
|
rlm@1
|
746 break;
|
rlm@1
|
747 case 0x02:
|
rlm@1
|
748 gbSgbSetPalette(0, 3, (u16 *)&gbSgbPacket[1]);
|
rlm@1
|
749 break;
|
rlm@1
|
750 case 0x03:
|
rlm@1
|
751 gbSgbSetPalette(1, 2, (u16 *)&gbSgbPacket[1]);
|
rlm@1
|
752 break;
|
rlm@1
|
753 case 0x04:
|
rlm@1
|
754 gbSgbAttributeBlock();
|
rlm@1
|
755 break;
|
rlm@1
|
756 case 0x05:
|
rlm@1
|
757 gbSgbAttributeLine();
|
rlm@1
|
758 break;
|
rlm@1
|
759 case 0x06:
|
rlm@1
|
760 gbSgbAttributeDivide();
|
rlm@1
|
761 break;
|
rlm@1
|
762 case 0x07:
|
rlm@1
|
763 gbSgbAttributeCharacter();
|
rlm@1
|
764 break;
|
rlm@1
|
765 case 0x0a:
|
rlm@1
|
766 gbSgbSetPalette();
|
rlm@1
|
767 break;
|
rlm@1
|
768 case 0x0b:
|
rlm@1
|
769 gbSgbScpPalette();
|
rlm@1
|
770 break;
|
rlm@1
|
771 case 0x11:
|
rlm@1
|
772 gbSgbMultiRequest();
|
rlm@1
|
773 break;
|
rlm@1
|
774 case 0x13:
|
rlm@1
|
775 gbSgbChrTransfer();
|
rlm@1
|
776 break;
|
rlm@1
|
777 case 0x14:
|
rlm@1
|
778 gbSgbPicture();
|
rlm@1
|
779 break;
|
rlm@1
|
780 case 0x15:
|
rlm@1
|
781 gbSgbSetATFList();
|
rlm@1
|
782 break;
|
rlm@1
|
783 case 0x16:
|
rlm@1
|
784 gbSgbSetATF(gbSgbPacket[1] & 0x3f);
|
rlm@1
|
785 break;
|
rlm@1
|
786 case 0x17:
|
rlm@1
|
787 gbSgbMaskEnable();
|
rlm@1
|
788 break;
|
rlm@1
|
789 }
|
rlm@1
|
790 }
|
rlm@1
|
791
|
rlm@1
|
792 void gbSgbResetPacketState()
|
rlm@1
|
793 {
|
rlm@1
|
794 gbSgbPacketState = GBSGB_NONE;
|
rlm@1
|
795 gbSgbPacketTimeout = 0;
|
rlm@1
|
796 }
|
rlm@1
|
797
|
rlm@1
|
798 void gbSgbDoBitTransfer(u8 value)
|
rlm@1
|
799 {
|
rlm@1
|
800 value = value & 0x30;
|
rlm@1
|
801 switch (gbSgbPacketState)
|
rlm@1
|
802 {
|
rlm@1
|
803 case GBSGB_NONE:
|
rlm@1
|
804 if (value == 0)
|
rlm@1
|
805 {
|
rlm@1
|
806 gbSgbPacketState = GBSGB_RESET;
|
rlm@1
|
807 gbSgbPacketTimeout = GBSGB_PACKET_TIMEOUT;
|
rlm@1
|
808 }
|
rlm@1
|
809 else if (value == 0x30)
|
rlm@1
|
810 {
|
rlm@1
|
811 if (gbSgbMultiplayer)
|
rlm@1
|
812 {
|
rlm@1
|
813 if ((gbSgbReadingController & 7) == 7)
|
rlm@1
|
814 {
|
rlm@1
|
815 gbSgbReadingController = 0;
|
rlm@1
|
816 if (gbSgbMultiplayer)
|
rlm@1
|
817 {
|
rlm@1
|
818 gbSgbNextController--;
|
rlm@1
|
819 if (gbSgbFourPlayers)
|
rlm@1
|
820 {
|
rlm@1
|
821 if (gbSgbNextController == 0x0b)
|
rlm@1
|
822 gbSgbNextController = 0x0f;
|
rlm@1
|
823 }
|
rlm@1
|
824 else
|
rlm@1
|
825 {
|
rlm@1
|
826 if (gbSgbNextController == 0x0d)
|
rlm@1
|
827 gbSgbNextController = 0x0f;
|
rlm@1
|
828 }
|
rlm@1
|
829 }
|
rlm@1
|
830 }
|
rlm@1
|
831 else
|
rlm@1
|
832 {
|
rlm@1
|
833 gbSgbReadingController &= 3;
|
rlm@1
|
834 }
|
rlm@1
|
835 }
|
rlm@1
|
836 gbSgbPacketTimeout = 0;
|
rlm@1
|
837 }
|
rlm@1
|
838 else
|
rlm@1
|
839 {
|
rlm@1
|
840 if (value == 0x10)
|
rlm@1
|
841 gbSgbReadingController |= 0x2;
|
rlm@1
|
842 else if (value == 0x20)
|
rlm@1
|
843 gbSgbReadingController |= 0x01;
|
rlm@1
|
844 gbSgbPacketTimeout = 0;
|
rlm@1
|
845 }
|
rlm@1
|
846 gbSgbPacketTimeout = 0;
|
rlm@1
|
847 break;
|
rlm@1
|
848 case GBSGB_RESET:
|
rlm@1
|
849 if (value == 0x30)
|
rlm@1
|
850 {
|
rlm@1
|
851 gbSgbPacketState = GBSGB_PACKET_TRANSMIT;
|
rlm@1
|
852 gbSgbPacketByte = 0;
|
rlm@1
|
853 gbSgbPacketNBits = 0;
|
rlm@1
|
854 gbSgbPacketTimeout = GBSGB_PACKET_TIMEOUT;
|
rlm@1
|
855 }
|
rlm@1
|
856 else if (value == 0x00)
|
rlm@1
|
857 {
|
rlm@1
|
858 gbSgbPacketTimeout = GBSGB_PACKET_TIMEOUT;
|
rlm@1
|
859 gbSgbPacketState = GBSGB_RESET;
|
rlm@1
|
860 }
|
rlm@1
|
861 else
|
rlm@1
|
862 {
|
rlm@1
|
863 gbSgbPacketState = GBSGB_NONE;
|
rlm@1
|
864 gbSgbPacketTimeout = 0;
|
rlm@1
|
865 }
|
rlm@1
|
866 break;
|
rlm@1
|
867 case GBSGB_PACKET_TRANSMIT:
|
rlm@1
|
868 if (value == 0)
|
rlm@1
|
869 {
|
rlm@1
|
870 gbSgbPacketState = GBSGB_RESET;
|
rlm@1
|
871 gbSgbPacketTimeout = 0;
|
rlm@1
|
872 }
|
rlm@1
|
873 else if (value == 0x30)
|
rlm@1
|
874 {
|
rlm@1
|
875 if (gbSgbPacketNBits == 128)
|
rlm@1
|
876 {
|
rlm@1
|
877 gbSgbPacketNBits = 0;
|
rlm@1
|
878 gbSgbPacketByte = 0;
|
rlm@1
|
879 gbSgbPacketNumber++;
|
rlm@1
|
880 gbSgbPacketTimeout = 0;
|
rlm@1
|
881 if (gbSgbPacketNumber == (gbSgbPacket[0] & 7))
|
rlm@1
|
882 {
|
rlm@1
|
883 gbSgbCommand();
|
rlm@1
|
884 gbSgbPacketNumber = 0;
|
rlm@1
|
885 gbSgbPacketState = GBSGB_NONE;
|
rlm@1
|
886 gbSgbPacketTimeout = 0;
|
rlm@1
|
887 }
|
rlm@1
|
888 }
|
rlm@1
|
889 else
|
rlm@1
|
890 {
|
rlm@1
|
891 if (gbSgbPacketNBits < 128)
|
rlm@1
|
892 {
|
rlm@1
|
893 gbSgbPacket[gbSgbPacketNumber * 16 + gbSgbPacketByte] >>= 1;
|
rlm@1
|
894 gbSgbPacket[gbSgbPacketNumber * 16 + gbSgbPacketByte] |= gbSgbBit;
|
rlm@1
|
895 gbSgbPacketNBits++;
|
rlm@1
|
896 if (!(gbSgbPacketNBits & 7))
|
rlm@1
|
897 {
|
rlm@1
|
898 gbSgbPacketByte++;
|
rlm@1
|
899 }
|
rlm@1
|
900 gbSgbPacketTimeout = GBSGB_PACKET_TIMEOUT;
|
rlm@1
|
901 }
|
rlm@1
|
902 }
|
rlm@1
|
903 }
|
rlm@1
|
904 else
|
rlm@1
|
905 {
|
rlm@1
|
906 if (value == 0x20)
|
rlm@1
|
907 gbSgbBit = 0x00;
|
rlm@1
|
908 else
|
rlm@1
|
909 gbSgbBit = 0x80;
|
rlm@1
|
910 gbSgbPacketTimeout = GBSGB_PACKET_TIMEOUT;
|
rlm@1
|
911 }
|
rlm@1
|
912 gbSgbReadingController = 0;
|
rlm@1
|
913 break;
|
rlm@1
|
914 default:
|
rlm@1
|
915 gbSgbPacketState = GBSGB_NONE;
|
rlm@1
|
916 gbSgbPacketTimeout = 0;
|
rlm@1
|
917 break;
|
rlm@1
|
918 }
|
rlm@1
|
919 }
|
rlm@1
|
920
|
rlm@1
|
921 variable_desc gbSgbSaveStruct[] = {
|
rlm@1
|
922 { &gbSgbMask, sizeof(int32) },
|
rlm@1
|
923 { &gbSgbPacketState, sizeof(int32) },
|
rlm@1
|
924 { &gbSgbBit, sizeof(int32) },
|
rlm@1
|
925 { &gbSgbPacketNBits, sizeof(int32) },
|
rlm@1
|
926 { &gbSgbPacketByte, sizeof(int32) },
|
rlm@1
|
927 { &gbSgbPacketNumber, sizeof(int32) },
|
rlm@1
|
928 { &gbSgbMultiplayer, sizeof(int32) },
|
rlm@1
|
929 { &gbSgbNextController, sizeof(u8) },
|
rlm@1
|
930 { &gbSgbReadingController, sizeof(u8) },
|
rlm@1
|
931 { NULL, 0 }
|
rlm@1
|
932 };
|
rlm@1
|
933
|
rlm@1
|
934 variable_desc gbSgbSaveStructV3[] = {
|
rlm@1
|
935 { &gbSgbMask, sizeof(int32) },
|
rlm@1
|
936 { &gbSgbPacketState, sizeof(int32) },
|
rlm@1
|
937 { &gbSgbBit, sizeof(int32) },
|
rlm@1
|
938 { &gbSgbPacketNBits, sizeof(int32) },
|
rlm@1
|
939 { &gbSgbPacketByte, sizeof(int32) },
|
rlm@1
|
940 { &gbSgbPacketNumber, sizeof(int32) },
|
rlm@1
|
941 { &gbSgbMultiplayer, sizeof(int32) },
|
rlm@1
|
942 { &gbSgbNextController, sizeof(u8) },
|
rlm@1
|
943 { &gbSgbReadingController, sizeof(u8) },
|
rlm@1
|
944 { &gbSgbFourPlayers, sizeof(int32) },
|
rlm@1
|
945 { NULL, 0 }
|
rlm@1
|
946 };
|
rlm@1
|
947
|
rlm@1
|
948 void gbSgbSaveGame(gzFile gzFile)
|
rlm@1
|
949 {
|
rlm@1
|
950 utilWriteData(gzFile, gbSgbSaveStructV3);
|
rlm@1
|
951
|
rlm@1
|
952 utilGzWrite(gzFile, gbSgbBorder, 2048);
|
rlm@1
|
953 utilGzWrite(gzFile, gbSgbBorderChar, 32 * 256);
|
rlm@1
|
954
|
rlm@1
|
955 utilGzWrite(gzFile, gbSgbPacket, 16 * 7);
|
rlm@1
|
956
|
rlm@1
|
957 utilGzWrite(gzFile, gbSgbSCPPalette, 4 * 512 * sizeof(u16));
|
rlm@1
|
958 utilGzWrite(gzFile, gbSgbATF, 20 * 18);
|
rlm@1
|
959 utilGzWrite(gzFile, gbSgbATFList, 45 * 20 * 18);
|
rlm@1
|
960
|
rlm@1
|
961 utilGzWrite(gzFile, gbSgbScreenBuffer, 4160);
|
rlm@1
|
962 utilGzWrite(gzFile, &gbSgbMode, sizeof(gbSgbMode));
|
rlm@1
|
963 utilGzWrite(gzFile, &gbSgbCGBSupport, sizeof(gbSgbCGBSupport));
|
rlm@1
|
964 utilGzWrite(gzFile, &gbSgbPacketTimeout, sizeof(gbSgbPacketTimeout));
|
rlm@1
|
965 }
|
rlm@1
|
966
|
rlm@1
|
967 void gbSgbReadGame(gzFile gzFile, int version)
|
rlm@1
|
968 {
|
rlm@1
|
969 if (version >= 3)
|
rlm@1
|
970 utilReadData(gzFile, gbSgbSaveStructV3);
|
rlm@1
|
971 else
|
rlm@1
|
972 {
|
rlm@1
|
973 utilReadData(gzFile, gbSgbSaveStruct);
|
rlm@1
|
974 gbSgbFourPlayers = 0;
|
rlm@1
|
975 }
|
rlm@1
|
976
|
rlm@1
|
977 if (version >= 8)
|
rlm@1
|
978 {
|
rlm@1
|
979 utilGzRead(gzFile, gbSgbBorder, 2048);
|
rlm@1
|
980 utilGzRead(gzFile, gbSgbBorderChar, 32 * 256);
|
rlm@1
|
981 }
|
rlm@1
|
982
|
rlm@1
|
983 utilGzRead(gzFile, gbSgbPacket, 16 * 7);
|
rlm@1
|
984
|
rlm@1
|
985 utilGzRead(gzFile, gbSgbSCPPalette, 4 * 512 * sizeof(u16));
|
rlm@1
|
986 utilGzRead(gzFile, gbSgbATF, 20 * 18);
|
rlm@1
|
987 utilGzRead(gzFile, gbSgbATFList, 45 * 20 * 18);
|
rlm@1
|
988
|
rlm@1
|
989 if (version >= 11)
|
rlm@1
|
990 {
|
rlm@1
|
991 utilGzRead(gzFile, gbSgbScreenBuffer, 4160);
|
rlm@1
|
992 utilGzRead(gzFile, &gbSgbMode, sizeof(gbSgbMode));
|
rlm@1
|
993 utilGzRead(gzFile, &gbSgbCGBSupport, sizeof(gbSgbCGBSupport));
|
rlm@1
|
994 utilGzRead(gzFile, &gbSgbPacketTimeout, sizeof(gbSgbPacketTimeout));
|
rlm@1
|
995 }
|
rlm@1
|
996 }
|
rlm@1
|
997
|