Mercurial > vba-clojure
diff src/gb/gbSGB.cpp @ 17:75e5bb1e0aa1
going to now integrate the gb src tree since it has no dependencies
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 11:44:47 -0600 |
parents | f9f4f1b99eed |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/gb/gbSGB.cpp Sat Mar 03 11:44:47 2012 -0600 1.3 @@ -0,0 +1,997 @@ 1.4 +#include <cstdlib> 1.5 +#include <cstring> 1.6 + 1.7 +#include "../common/System.h" 1.8 +#include "../common/Util.h" 1.9 +#include "GB.h" 1.10 +#include "gbGlobals.h" 1.11 +#include "../common/movie.h" 1.12 + 1.13 +extern u8 * pix; 1.14 + 1.15 +#define GBSGB_NONE 0 1.16 +#define GBSGB_RESET 1 1.17 +#define GBSGB_PACKET_TRANSMIT 2 1.18 + 1.19 +u8 gbSgbBorderChar [32 * 256]; 1.20 +u8 gbSgbBorder [2048]; 1.21 + 1.22 +int32 gbSgbCGBSupport = 0; 1.23 +int32 gbSgbMask = 0; 1.24 +int32 gbSgbMode = 0; 1.25 +int32 gbSgbPacketState = GBSGB_NONE; 1.26 +int32 gbSgbBit = 0; 1.27 +int32 gbSgbPacketTimeout = 0; 1.28 +int32 GBSGB_PACKET_TIMEOUT = 66666; 1.29 +u8 gbSgbPacket[16 * 7]; 1.30 +int32 gbSgbPacketNBits = 0; 1.31 +int32 gbSgbPacketByte = 0; 1.32 +int32 gbSgbPacketNumber = 0; 1.33 +int32 gbSgbMultiplayer = 0; 1.34 +int32 gbSgbFourPlayers = 0; 1.35 +u8 gbSgbNextController = 0x0f; 1.36 +u8 gbSgbReadingController = 0; 1.37 +u16 gbSgbSCPPalette[4 * 512]; 1.38 +u8 gbSgbATF[20 * 18]; 1.39 +u8 gbSgbATFList[45 * 20 * 18]; 1.40 +u8 gbSgbScreenBuffer[4160]; 1.41 + 1.42 +inline void gbSgbDraw24Bit(u8 *p, u16 v) 1.43 +{ 1.44 + *((u32 *) p) = systemColorMap32[v]; 1.45 +} 1.46 + 1.47 +inline void gbSgbDraw32Bit(u32 *p, u16 v) 1.48 +{ 1.49 + *p = systemColorMap32[v]; 1.50 +} 1.51 + 1.52 +inline void gbSgbDraw16Bit(u16 *p, u16 v) 1.53 +{ 1.54 + *p = systemColorMap16[v]; 1.55 +} 1.56 + 1.57 +void gbSgbReset() 1.58 +{ 1.59 + gbSgbPacketTimeout = 0; 1.60 + gbSgbCGBSupport = 0; 1.61 + gbSgbMask = 0; 1.62 + gbSgbPacketState = GBSGB_NONE; 1.63 + gbSgbBit = 0; 1.64 + gbSgbPacketNBits = 0; 1.65 + gbSgbPacketNumber = 0; 1.66 + gbSgbMultiplayer = 0; 1.67 + gbSgbFourPlayers = 0; 1.68 + gbSgbNextController = 0x0f; 1.69 + gbSgbReadingController = 0; 1.70 + 1.71 + memset(gbSgbSCPPalette, 0, 512 * 4); 1.72 + memset(gbSgbATF, 0, 20 * 18); 1.73 + memset(gbSgbATFList, 0, 45 * 20 * 18); 1.74 + memset(gbSgbPacket, 0, 16 * 7); 1.75 + memset(gbSgbBorderChar, 0, 32 * 256); 1.76 + memset(gbSgbBorder, 0, 2048); 1.77 + 1.78 + int i; 1.79 + for (i = 1; i < 2048; i += 2) 1.80 + { 1.81 + gbSgbBorder[i] = 1 << 2; 1.82 + } 1.83 + 1.84 + for (i = 0; i < 4; i++) 1.85 + { 1.86 + gbPalette[i * 4] = (0x1f) | (0x1f << 5) | (0x1f << 10); 1.87 + gbPalette[i * 4 + 1] = (0x15) | (0x15 << 5) | (0x15 << 10); 1.88 + gbPalette[i * 4 + 2] = (0x0c) | (0x0c << 5) | (0x0c << 10); 1.89 + gbPalette[i * 4 + 3] = 0; 1.90 + } 1.91 +} 1.92 + 1.93 +void gbSgbInit() 1.94 +{ 1.95 + gbSgbReset(); 1.96 +} 1.97 + 1.98 +void gbSgbShutdown() 1.99 +{ 1.100 + memset(gbSgbBorderChar, 0, 32 * 256); 1.101 + memset(gbSgbBorder, 0, 2048); 1.102 +} 1.103 + 1.104 +void gbSgbFillScreen(u16 color) 1.105 +{ 1.106 + switch (systemColorDepth) 1.107 + { 1.108 + case 16: 1.109 + { 1.110 + for (int y = 0; y < 144; y++) 1.111 + { 1.112 + int yLine = (y + gbBorderRowSkip + 1) * (gbBorderLineSkip + 2) + 1.113 + gbBorderColumnSkip; 1.114 + u16 *dest = (u16 *)pix + yLine; 1.115 + for (register int x = 0; x < 160; x++) 1.116 + gbSgbDraw16Bit(dest++, color); 1.117 + } 1.118 + } 1.119 + break; 1.120 + case 24: 1.121 + { 1.122 + for (int y = 0; y < 144; y++) 1.123 + { 1.124 + int yLine = (y + gbBorderRowSkip) * gbBorderLineSkip + gbBorderColumnSkip; 1.125 + u8 *dest = (u8 *)pix + yLine * 3; 1.126 + for (register int x = 0; x < 160; x++) 1.127 + { 1.128 + gbSgbDraw24Bit(dest, color); 1.129 + dest += 3; 1.130 + } 1.131 + } 1.132 + } 1.133 + break; 1.134 + case 32: 1.135 + { 1.136 + for (int y = 0; y < 144; y++) 1.137 + { 1.138 + int yLine = (y + gbBorderRowSkip + 1) * (gbBorderLineSkip + 1) + gbBorderColumnSkip; 1.139 + u32 *dest = (u32 *)pix + yLine; 1.140 + for (register int x = 0; x < 160; x++) 1.141 + { 1.142 + gbSgbDraw32Bit(dest++, color); 1.143 + } 1.144 + } 1.145 + } 1.146 + break; 1.147 + } 1.148 +} 1.149 + 1.150 +void gbSgbRenderScreenToBuffer() 1.151 +{ 1.152 + u16 mapAddress = 0x9800; 1.153 + 1.154 + if (register_LCDC & 0x08) 1.155 + mapAddress = 0x9c00; 1.156 + 1.157 + u16 patternAddress = 0x8800; 1.158 + 1.159 + int flag = 1; 1.160 + 1.161 + if (register_LCDC & 0x10) 1.162 + { 1.163 + patternAddress = 0x8000; 1.164 + flag = 0; 1.165 + } 1.166 + 1.167 + u8 *toAddress = gbSgbScreenBuffer; 1.168 + 1.169 + for (int i = 0; i < 13; i++) 1.170 + { 1.171 + for (int j = 0; j < 20; j++) 1.172 + { 1.173 + int tile = gbReadMemoryQuick(mapAddress); 1.174 + mapAddress++; 1.175 + 1.176 + if (flag) 1.177 + { 1.178 + if (tile > 127) 1.179 + tile -= 128; 1.180 + else 1.181 + tile += 128; 1.182 + } 1.183 + for (int k = 0; k < 16; k++) 1.184 + *toAddress++ = gbReadMemoryQuick(patternAddress + tile * 16 + k); 1.185 + } 1.186 + mapAddress += 12; 1.187 + } 1.188 +} 1.189 + 1.190 +void gbSgbDrawBorderTile(int x, int y, int tile, int attr) 1.191 +{ 1.192 + u16 *dest = (u16 *)pix + ((y + 1) * (256 + 2)) + x; 1.193 + u8 * dest8 = (u8 *)pix + ((y * 256) + x) * 3; 1.194 + u32 *dest32 = (u32 *)pix + ((y + 1) * 257) + x; 1.195 + 1.196 + u8 *tileAddress = &gbSgbBorderChar[tile * 32]; 1.197 + u8 *tileAddress2 = &gbSgbBorderChar[tile * 32 + 16]; 1.198 + 1.199 + u8 l = 8; 1.200 + 1.201 + u8 palette = ((attr >> 2) & 7); 1.202 + 1.203 + if (palette < 4) 1.204 + palette += 4; 1.205 + 1.206 + palette *= 16; 1.207 + 1.208 + u8 xx = 0; 1.209 + u8 yy = 0; 1.210 + 1.211 + int flipX = attr & 0x40; 1.212 + int flipY = attr & 0x80; 1.213 + 1.214 + while (l > 0) 1.215 + { 1.216 + u8 mask = 0x80; 1.217 + u8 a = *tileAddress++; 1.218 + u8 b = *tileAddress++; 1.219 + u8 c = *tileAddress2++; 1.220 + u8 d = *tileAddress2++; 1.221 + 1.222 + while (mask > 0) 1.223 + { 1.224 + u8 color = 0; 1.225 + if (a & mask) 1.226 + color++; 1.227 + if (b & mask) 1.228 + color += 2; 1.229 + if (c & mask) 1.230 + color += 4; 1.231 + if (d & mask) 1.232 + color += 8; 1.233 + 1.234 + u8 xxx = xx; 1.235 + u8 yyy = yy; 1.236 + 1.237 + if (flipX) 1.238 + xxx = 7 - xx; 1.239 + if (flipY) 1.240 + yyy = 7 - yy; 1.241 + 1.242 + u8 realx = x + xxx; 1.243 + u8 realy = y + yyy; 1.244 + 1.245 + u16 c = gbPalette[palette + color]; 1.246 + if (!color) 1.247 + c = gbPalette[0]; 1.248 + if ((realy < 40 || realy >= 184) || (realx < 48 || realx >= 208)) 1.249 + { 1.250 + switch (systemColorDepth) 1.251 + { 1.252 + case 16: 1.253 + gbSgbDraw16Bit(dest + yyy * (256 + 2) + xxx, c); 1.254 + break; 1.255 + case 24: 1.256 + gbSgbDraw24Bit(dest8 + (yyy * 256 + xxx) * 3, c); 1.257 + break; 1.258 + case 32: 1.259 + gbSgbDraw32Bit(dest32 + yyy * (256 + 1) + xxx, c); 1.260 + break; 1.261 + } 1.262 + } 1.263 + 1.264 + mask >>= 1; 1.265 + 1.266 + xx++; 1.267 + } 1.268 + yy++; 1.269 + xx = 0; 1.270 + l--; 1.271 + mask = 0x80; 1.272 + } 1.273 +} 1.274 + 1.275 +void gbSgbRenderBorder() 1.276 +{ 1.277 + if (gbBorderOn) 1.278 + { 1.279 + u8 *fromAddress = gbSgbBorder; 1.280 + 1.281 + for (u8 y = 0; y < 28; y++) 1.282 + { 1.283 + for (u8 x = 0; x < 32; x++) 1.284 + { 1.285 + u8 tile = *fromAddress++; 1.286 + u8 attr = *fromAddress++; 1.287 + 1.288 + gbSgbDrawBorderTile(x * 8, y * 8, tile, attr); 1.289 + } 1.290 + } 1.291 + } 1.292 +} 1.293 + 1.294 +void gbSgbPicture() 1.295 +{ 1.296 + gbSgbRenderScreenToBuffer(); 1.297 + 1.298 + memcpy(gbSgbBorder, gbSgbScreenBuffer, 2048); 1.299 + 1.300 + u16 *paletteAddr = (u16 *)&gbSgbScreenBuffer[2048]; 1.301 + 1.302 + for (int i = 64; i < 128; i++) 1.303 + { 1.304 + gbPalette[i] = READ16LE(paletteAddr++); 1.305 + } 1.306 + 1.307 + gbSgbCGBSupport |= 4; 1.308 + 1.309 + if (gbBorderAutomatic && !gbBorderOn && gbSgbCGBSupport > 4) 1.310 + { 1.311 + gbBorderOn = 1; 1.312 + systemGbBorderOn(); 1.313 + } 1.314 + 1.315 + if (gbBorderOn && !gbSgbMask) 1.316 + gbSgbRenderBorder(); 1.317 + 1.318 + if (gbSgbMode && gbCgbMode && gbSgbCGBSupport > 4) 1.319 + { 1.320 + gbSgbCGBSupport = 0; 1.321 + gbSgbMode = 2; 1.322 + gbSgbMask = 0; 1.323 + gbSgbRenderBorder(); 1.324 + gbReset(); 1.325 + } 1.326 + 1.327 + if (gbSgbCGBSupport > 4) 1.328 + gbSgbCGBSupport = 0; 1.329 +} 1.330 + 1.331 +void gbSgbSetPalette(int a, int b, u16 *p) 1.332 +{ 1.333 + u16 bit00 = READ16LE(p++); 1.334 + int i; 1.335 + 1.336 + for (i = 1; i < 4; i++) 1.337 + { 1.338 + gbPalette[a * 4 + i] = READ16LE(p++); 1.339 + } 1.340 + 1.341 + for (i = 1; i < 4; i++) 1.342 + { 1.343 + gbPalette[b * 4 + i] = READ16LE(p++); 1.344 + } 1.345 + 1.346 + gbPalette[0] = gbPalette[4] = gbPalette[8] = gbPalette[12] = bit00; 1.347 + if (gbBorderOn && !gbSgbMask) 1.348 + gbSgbRenderBorder(); 1.349 +} 1.350 + 1.351 +void gbSgbScpPalette() 1.352 +{ 1.353 + gbSgbRenderScreenToBuffer(); 1.354 + 1.355 + u16 *fromAddress = (u16 *)gbSgbScreenBuffer; 1.356 + 1.357 + for (int i = 0; i < 512 * 4; i++) 1.358 + { 1.359 + gbSgbSCPPalette[i] = READ16LE(fromAddress++); 1.360 + } 1.361 +} 1.362 + 1.363 +void gbSgbSetATF(int n) 1.364 +{ 1.365 + if (n < 0) 1.366 + n = 0; 1.367 + if (n > 44) 1.368 + n = 44; 1.369 + memcpy(gbSgbATF, &gbSgbATFList[n * 20 * 18], 20 * 18); 1.370 + 1.371 + if (gbSgbPacket[1] & 0x40) 1.372 + { 1.373 + gbSgbMask = 0; 1.374 + if (gbBorderOn) 1.375 + gbSgbRenderBorder(); 1.376 + } 1.377 +} 1.378 + 1.379 +void gbSgbSetPalette() 1.380 +{ 1.381 + u16 pal = READ16LE((((u16 *)&gbSgbPacket[1]))) & 511; 1.382 + memcpy(&gbPalette[0], &gbSgbSCPPalette[pal * 4], 4 * sizeof(u16)); 1.383 + 1.384 + pal = READ16LE((((u16 *)&gbSgbPacket[3]))) & 511; 1.385 + memcpy(&gbPalette[4], &gbSgbSCPPalette[pal * 4], 4 * sizeof(u16)); 1.386 + 1.387 + pal = READ16LE((((u16 *)&gbSgbPacket[5]))) & 511; 1.388 + memcpy(&gbPalette[8], &gbSgbSCPPalette[pal * 4], 4 * sizeof(u16)); 1.389 + 1.390 + pal = READ16LE((((u16 *)&gbSgbPacket[7]))) & 511; 1.391 + memcpy(&gbPalette[12], &gbSgbSCPPalette[pal * 4], 4 * sizeof(u16)); 1.392 + 1.393 + u8 atf = gbSgbPacket[9]; 1.394 + 1.395 + if (atf & 0x80) 1.396 + { 1.397 + gbSgbSetATF(atf & 0x3f); 1.398 + } 1.399 + 1.400 + if (atf & 0x40) 1.401 + { 1.402 + gbSgbMask = 0; 1.403 + if (gbBorderOn) 1.404 + gbSgbRenderBorder(); 1.405 + } 1.406 +} 1.407 + 1.408 +void gbSgbAttributeBlock() 1.409 +{ 1.410 + u8 *fromAddress = &gbSgbPacket[1]; 1.411 + 1.412 + u8 nDataSet = *fromAddress++; 1.413 + if (nDataSet > 12) 1.414 + nDataSet = 12; 1.415 + if (nDataSet == 0) 1.416 + nDataSet = 1; 1.417 + 1.418 + while (nDataSet) 1.419 + { 1.420 + u8 controlCode = (*fromAddress++) & 7; 1.421 + u8 paletteDesignation = (*fromAddress++) & 0x3f; 1.422 + u8 startH = (*fromAddress++) & 0x1f; 1.423 + u8 startV = (*fromAddress++) & 0x1f; 1.424 + u8 endH = (*fromAddress++) & 0x1f; 1.425 + u8 endV = (*fromAddress++) & 0x1f; 1.426 + 1.427 + u8 *toAddress = gbSgbATF; 1.428 + 1.429 + for (u8 y = 0; y < 18; y++) 1.430 + { 1.431 + for (u8 x = 0; x < 20; x++) 1.432 + { 1.433 + if (x < startH || y < startV || 1.434 + x > endH || y > endV) 1.435 + { 1.436 + // outside 1.437 + if (controlCode & 0x04) 1.438 + *toAddress = (paletteDesignation >> 4) & 0x03; 1.439 + } 1.440 + else if (x > startH && x < endH && 1.441 + y > startV && y < endV) 1.442 + { 1.443 + // inside 1.444 + if (controlCode & 0x01) 1.445 + *toAddress = paletteDesignation & 0x03; 1.446 + } 1.447 + else 1.448 + { 1.449 + // surrounding line 1.450 + if (controlCode & 0x02) 1.451 + *toAddress = (paletteDesignation >> 2) & 0x03; 1.452 + else if (controlCode == 0x01) 1.453 + *toAddress = paletteDesignation & 0x03; 1.454 + } 1.455 + toAddress++; 1.456 + } 1.457 + } 1.458 + nDataSet--; 1.459 + } 1.460 +} 1.461 + 1.462 +void gbSgbSetColumnPalette(u8 col, u8 p) 1.463 +{ 1.464 + // if(col < 0) 1.465 + // col = 0; 1.466 + if (col > 19) 1.467 + col = 19; 1.468 + 1.469 + p &= 3; 1.470 + 1.471 + u8 *toAddress = &gbSgbATF[col]; 1.472 + 1.473 + for (u8 y = 0; y < 18; y++) 1.474 + { 1.475 + *toAddress = p; 1.476 + toAddress += 20; 1.477 + } 1.478 +} 1.479 + 1.480 +void gbSgbSetRowPalette(u8 row, u8 p) 1.481 +{ 1.482 + // if(row < 0) 1.483 + // row = 0; 1.484 + if (row > 17) 1.485 + row = 17; 1.486 + 1.487 + p &= 3; 1.488 + 1.489 + u8 *toAddress = &gbSgbATF[row * 20]; 1.490 + 1.491 + for (u8 x = 0; x < 20; x++) 1.492 + { 1.493 + *toAddress++ = p; 1.494 + } 1.495 +} 1.496 + 1.497 +void gbSgbAttributeDivide() 1.498 +{ 1.499 + u8 control = gbSgbPacket[1]; 1.500 + u8 coord = gbSgbPacket[2]; 1.501 + u8 colorBR = control & 3; 1.502 + u8 colorAL = (control >> 2) & 3; 1.503 + u8 colorOL = (control >> 4) & 3; 1.504 + 1.505 + if (control & 0x40) 1.506 + { 1.507 + if (coord > 17) 1.508 + coord = 17; 1.509 + 1.510 + for (u8 i = 0; i < 18; i++) 1.511 + { 1.512 + if (i < coord) 1.513 + gbSgbSetRowPalette(i, colorAL); 1.514 + else if (i > coord) 1.515 + gbSgbSetRowPalette(i, colorBR); 1.516 + else 1.517 + gbSgbSetRowPalette(i, colorOL); 1.518 + } 1.519 + } 1.520 + else 1.521 + { 1.522 + if (coord > 19) 1.523 + coord = 19; 1.524 + 1.525 + for (u8 i = 0; i < 20; i++) 1.526 + { 1.527 + if (i < coord) 1.528 + gbSgbSetColumnPalette(i, colorAL); 1.529 + else if (i > coord) 1.530 + gbSgbSetColumnPalette(i, colorBR); 1.531 + else 1.532 + gbSgbSetColumnPalette(i, colorOL); 1.533 + } 1.534 + } 1.535 +} 1.536 + 1.537 +void gbSgbAttributeLine() 1.538 +{ 1.539 + u8 *fromAddress = &gbSgbPacket[1]; 1.540 + 1.541 + u8 nDataSet = *fromAddress++; 1.542 + 1.543 + if (nDataSet > 0x6e) 1.544 + nDataSet = 0x6e; 1.545 + 1.546 + while (nDataSet) 1.547 + { 1.548 + u8 line = *fromAddress++; 1.549 + u8 num = line & 0x1f; 1.550 + u8 pal = (line >> 5) & 0x03; 1.551 + if (line & 0x80) 1.552 + { 1.553 + if (num > 17) 1.554 + num = 17; 1.555 + gbSgbSetRowPalette(num, pal); 1.556 + } 1.557 + else 1.558 + { 1.559 + if (num > 19) 1.560 + num = 19; 1.561 + gbSgbSetColumnPalette(num, pal); 1.562 + } 1.563 + nDataSet--; 1.564 + } 1.565 +} 1.566 + 1.567 +void gbSgbAttributeCharacter() 1.568 +{ 1.569 + u8 startH = gbSgbPacket[1] & 0x1f; 1.570 + u8 startV = gbSgbPacket[2] & 0x1f; 1.571 + int nDataSet = READ16LE(((u16 *)&gbSgbPacket[3])); 1.572 + int style = gbSgbPacket[5] & 1; 1.573 + if (startH > 19) 1.574 + startH = 19; 1.575 + if (startV > 17) 1.576 + startV = 17; 1.577 + 1.578 + u8 s = 6; 1.579 + u8 *fromAddress = &gbSgbPacket[6]; 1.580 + u8 v = *fromAddress++; 1.581 + 1.582 + if (style) 1.583 + { 1.584 + while (nDataSet) 1.585 + { 1.586 + u8 p = (v >> s) & 3; 1.587 + gbSgbATF[startV * 20 + startH] = p; 1.588 + startV++; 1.589 + if (startV == 18) 1.590 + { 1.591 + startV = 0; 1.592 + startH++; 1.593 + if (startH == 20) 1.594 + break; 1.595 + } 1.596 + 1.597 + if (s) 1.598 + s -= 2; 1.599 + else 1.600 + { 1.601 + s = 6; 1.602 + v = *fromAddress++; 1.603 + nDataSet--; 1.604 + } 1.605 + } 1.606 + } 1.607 + else 1.608 + { 1.609 + while (nDataSet) 1.610 + { 1.611 + u8 p = (v >> s) & 3; 1.612 + gbSgbATF[startV * 20 + startH] = p; 1.613 + startH++; 1.614 + if (startH == 20) 1.615 + { 1.616 + startH = 0; 1.617 + startV++; 1.618 + if (startV == 18) 1.619 + break; 1.620 + } 1.621 + 1.622 + if (s) 1.623 + s -= 2; 1.624 + else 1.625 + { 1.626 + s = 6; 1.627 + v = *fromAddress++; 1.628 + nDataSet--; 1.629 + } 1.630 + } 1.631 + } 1.632 +} 1.633 + 1.634 +void gbSgbSetATFList() 1.635 +{ 1.636 + gbSgbRenderScreenToBuffer(); 1.637 + 1.638 + u8 *fromAddress = gbSgbScreenBuffer; 1.639 + u8 *toAddress = gbSgbATFList; 1.640 + 1.641 + for (int i = 0; i < 45; i++) 1.642 + { 1.643 + for (int j = 0; j < 90; j++) 1.644 + { 1.645 + u8 v = *fromAddress++; 1.646 + u8 s = 6; 1.647 + if (i == 2) 1.648 + s = 6; 1.649 + for (int k = 0; k < 4; k++) 1.650 + { 1.651 + *toAddress++ = (v >> s) & 0x03; 1.652 + s -= 2; 1.653 + } 1.654 + } 1.655 + } 1.656 +} 1.657 + 1.658 +void gbSgbMaskEnable() 1.659 +{ 1.660 + int gbSgbMaskFlag = gbSgbPacket[1] & 3; 1.661 + 1.662 + gbSgbMask = gbSgbMaskFlag; 1.663 + 1.664 + switch (gbSgbMaskFlag) 1.665 + { 1.666 + case 1: 1.667 + break; 1.668 + case 2: 1.669 + gbSgbFillScreen(0x0000); 1.670 + // memset(&gbPalette[0], 0, 128*sizeof(u16)); 1.671 + break; 1.672 + case 3: 1.673 + gbSgbFillScreen(gbPalette[0]); 1.674 + break; 1.675 + } 1.676 + if (!gbSgbMask) 1.677 + { 1.678 + if (gbBorderOn) 1.679 + gbSgbRenderBorder(); 1.680 + } 1.681 +} 1.682 + 1.683 +void gbSgbChrTransfer() 1.684 +{ 1.685 + gbSgbRenderScreenToBuffer(); 1.686 + 1.687 + int address = (gbSgbPacket[1] & 1) * (128 * 32); 1.688 + 1.689 + if (gbSgbPacket[1] & 1) 1.690 + gbSgbCGBSupport |= 2; 1.691 + else 1.692 + gbSgbCGBSupport |= 1; 1.693 + 1.694 + memcpy(&gbSgbBorderChar[address], gbSgbScreenBuffer, 128 * 32); 1.695 + 1.696 + if (gbBorderAutomatic && !gbBorderOn && gbSgbCGBSupport > 4) 1.697 + { 1.698 + gbBorderOn = 1; 1.699 + systemGbBorderOn(); 1.700 + } 1.701 + 1.702 + if (gbBorderOn && !gbSgbMask) 1.703 + gbSgbRenderBorder(); 1.704 + 1.705 + if (gbSgbMode && gbCgbMode && gbSgbCGBSupport == 7) 1.706 + { 1.707 + gbSgbCGBSupport = 0; 1.708 + gbSgbMode = 2; 1.709 + gbSgbMask = 0; 1.710 + gbSgbRenderBorder(); 1.711 + gbReset(); 1.712 + } 1.713 + 1.714 + if (gbSgbCGBSupport > 4) 1.715 + gbSgbCGBSupport = 0; 1.716 +} 1.717 + 1.718 +void gbSgbMultiRequest() 1.719 +{ 1.720 + if (gbSgbPacket[1] & 1) 1.721 + { 1.722 + gbSgbMultiplayer = 1; 1.723 + if (gbSgbPacket[1] & 2) 1.724 + gbSgbFourPlayers = 1; 1.725 + else 1.726 + gbSgbFourPlayers = 0; 1.727 + gbSgbNextController = 0x0e; 1.728 + } 1.729 + else 1.730 + { 1.731 + gbSgbFourPlayers = 0; 1.732 + gbSgbMultiplayer = 0; 1.733 + gbSgbNextController = 0x0f; 1.734 + } 1.735 +} 1.736 + 1.737 +void gbSgbCommand() 1.738 +{ 1.739 + int command = gbSgbPacket[0] >> 3; 1.740 + // int nPacket = gbSgbPacket[0] & 7; 1.741 + 1.742 + switch (command) 1.743 + { 1.744 + case 0x00: 1.745 + gbSgbSetPalette(0, 1, (u16 *)&gbSgbPacket[1]); 1.746 + break; 1.747 + case 0x01: 1.748 + gbSgbSetPalette(2, 3, (u16 *)&gbSgbPacket[1]); 1.749 + break; 1.750 + case 0x02: 1.751 + gbSgbSetPalette(0, 3, (u16 *)&gbSgbPacket[1]); 1.752 + break; 1.753 + case 0x03: 1.754 + gbSgbSetPalette(1, 2, (u16 *)&gbSgbPacket[1]); 1.755 + break; 1.756 + case 0x04: 1.757 + gbSgbAttributeBlock(); 1.758 + break; 1.759 + case 0x05: 1.760 + gbSgbAttributeLine(); 1.761 + break; 1.762 + case 0x06: 1.763 + gbSgbAttributeDivide(); 1.764 + break; 1.765 + case 0x07: 1.766 + gbSgbAttributeCharacter(); 1.767 + break; 1.768 + case 0x0a: 1.769 + gbSgbSetPalette(); 1.770 + break; 1.771 + case 0x0b: 1.772 + gbSgbScpPalette(); 1.773 + break; 1.774 + case 0x11: 1.775 + gbSgbMultiRequest(); 1.776 + break; 1.777 + case 0x13: 1.778 + gbSgbChrTransfer(); 1.779 + break; 1.780 + case 0x14: 1.781 + gbSgbPicture(); 1.782 + break; 1.783 + case 0x15: 1.784 + gbSgbSetATFList(); 1.785 + break; 1.786 + case 0x16: 1.787 + gbSgbSetATF(gbSgbPacket[1] & 0x3f); 1.788 + break; 1.789 + case 0x17: 1.790 + gbSgbMaskEnable(); 1.791 + break; 1.792 + } 1.793 +} 1.794 + 1.795 +void gbSgbResetPacketState() 1.796 +{ 1.797 + gbSgbPacketState = GBSGB_NONE; 1.798 + gbSgbPacketTimeout = 0; 1.799 +} 1.800 + 1.801 +void gbSgbDoBitTransfer(u8 value) 1.802 +{ 1.803 + value = value & 0x30; 1.804 + switch (gbSgbPacketState) 1.805 + { 1.806 + case GBSGB_NONE: 1.807 + if (value == 0) 1.808 + { 1.809 + gbSgbPacketState = GBSGB_RESET; 1.810 + gbSgbPacketTimeout = GBSGB_PACKET_TIMEOUT; 1.811 + } 1.812 + else if (value == 0x30) 1.813 + { 1.814 + if (gbSgbMultiplayer) 1.815 + { 1.816 + if ((gbSgbReadingController & 7) == 7) 1.817 + { 1.818 + gbSgbReadingController = 0; 1.819 + if (gbSgbMultiplayer) 1.820 + { 1.821 + gbSgbNextController--; 1.822 + if (gbSgbFourPlayers) 1.823 + { 1.824 + if (gbSgbNextController == 0x0b) 1.825 + gbSgbNextController = 0x0f; 1.826 + } 1.827 + else 1.828 + { 1.829 + if (gbSgbNextController == 0x0d) 1.830 + gbSgbNextController = 0x0f; 1.831 + } 1.832 + } 1.833 + } 1.834 + else 1.835 + { 1.836 + gbSgbReadingController &= 3; 1.837 + } 1.838 + } 1.839 + gbSgbPacketTimeout = 0; 1.840 + } 1.841 + else 1.842 + { 1.843 + if (value == 0x10) 1.844 + gbSgbReadingController |= 0x2; 1.845 + else if (value == 0x20) 1.846 + gbSgbReadingController |= 0x01; 1.847 + gbSgbPacketTimeout = 0; 1.848 + } 1.849 + gbSgbPacketTimeout = 0; 1.850 + break; 1.851 + case GBSGB_RESET: 1.852 + if (value == 0x30) 1.853 + { 1.854 + gbSgbPacketState = GBSGB_PACKET_TRANSMIT; 1.855 + gbSgbPacketByte = 0; 1.856 + gbSgbPacketNBits = 0; 1.857 + gbSgbPacketTimeout = GBSGB_PACKET_TIMEOUT; 1.858 + } 1.859 + else if (value == 0x00) 1.860 + { 1.861 + gbSgbPacketTimeout = GBSGB_PACKET_TIMEOUT; 1.862 + gbSgbPacketState = GBSGB_RESET; 1.863 + } 1.864 + else 1.865 + { 1.866 + gbSgbPacketState = GBSGB_NONE; 1.867 + gbSgbPacketTimeout = 0; 1.868 + } 1.869 + break; 1.870 + case GBSGB_PACKET_TRANSMIT: 1.871 + if (value == 0) 1.872 + { 1.873 + gbSgbPacketState = GBSGB_RESET; 1.874 + gbSgbPacketTimeout = 0; 1.875 + } 1.876 + else if (value == 0x30) 1.877 + { 1.878 + if (gbSgbPacketNBits == 128) 1.879 + { 1.880 + gbSgbPacketNBits = 0; 1.881 + gbSgbPacketByte = 0; 1.882 + gbSgbPacketNumber++; 1.883 + gbSgbPacketTimeout = 0; 1.884 + if (gbSgbPacketNumber == (gbSgbPacket[0] & 7)) 1.885 + { 1.886 + gbSgbCommand(); 1.887 + gbSgbPacketNumber = 0; 1.888 + gbSgbPacketState = GBSGB_NONE; 1.889 + gbSgbPacketTimeout = 0; 1.890 + } 1.891 + } 1.892 + else 1.893 + { 1.894 + if (gbSgbPacketNBits < 128) 1.895 + { 1.896 + gbSgbPacket[gbSgbPacketNumber * 16 + gbSgbPacketByte] >>= 1; 1.897 + gbSgbPacket[gbSgbPacketNumber * 16 + gbSgbPacketByte] |= gbSgbBit; 1.898 + gbSgbPacketNBits++; 1.899 + if (!(gbSgbPacketNBits & 7)) 1.900 + { 1.901 + gbSgbPacketByte++; 1.902 + } 1.903 + gbSgbPacketTimeout = GBSGB_PACKET_TIMEOUT; 1.904 + } 1.905 + } 1.906 + } 1.907 + else 1.908 + { 1.909 + if (value == 0x20) 1.910 + gbSgbBit = 0x00; 1.911 + else 1.912 + gbSgbBit = 0x80; 1.913 + gbSgbPacketTimeout = GBSGB_PACKET_TIMEOUT; 1.914 + } 1.915 + gbSgbReadingController = 0; 1.916 + break; 1.917 + default: 1.918 + gbSgbPacketState = GBSGB_NONE; 1.919 + gbSgbPacketTimeout = 0; 1.920 + break; 1.921 + } 1.922 +} 1.923 + 1.924 +variable_desc gbSgbSaveStruct[] = { 1.925 + { &gbSgbMask, sizeof(int32) }, 1.926 + { &gbSgbPacketState, sizeof(int32) }, 1.927 + { &gbSgbBit, sizeof(int32) }, 1.928 + { &gbSgbPacketNBits, sizeof(int32) }, 1.929 + { &gbSgbPacketByte, sizeof(int32) }, 1.930 + { &gbSgbPacketNumber, sizeof(int32) }, 1.931 + { &gbSgbMultiplayer, sizeof(int32) }, 1.932 + { &gbSgbNextController, sizeof(u8) }, 1.933 + { &gbSgbReadingController, sizeof(u8) }, 1.934 + { NULL, 0 } 1.935 +}; 1.936 + 1.937 +variable_desc gbSgbSaveStructV3[] = { 1.938 + { &gbSgbMask, sizeof(int32) }, 1.939 + { &gbSgbPacketState, sizeof(int32) }, 1.940 + { &gbSgbBit, sizeof(int32) }, 1.941 + { &gbSgbPacketNBits, sizeof(int32) }, 1.942 + { &gbSgbPacketByte, sizeof(int32) }, 1.943 + { &gbSgbPacketNumber, sizeof(int32) }, 1.944 + { &gbSgbMultiplayer, sizeof(int32) }, 1.945 + { &gbSgbNextController, sizeof(u8) }, 1.946 + { &gbSgbReadingController, sizeof(u8) }, 1.947 + { &gbSgbFourPlayers, sizeof(int32) }, 1.948 + { NULL, 0 } 1.949 +}; 1.950 + 1.951 +void gbSgbSaveGame(gzFile gzFile) 1.952 +{ 1.953 + utilWriteData(gzFile, gbSgbSaveStructV3); 1.954 + 1.955 + utilGzWrite(gzFile, gbSgbBorder, 2048); 1.956 + utilGzWrite(gzFile, gbSgbBorderChar, 32 * 256); 1.957 + 1.958 + utilGzWrite(gzFile, gbSgbPacket, 16 * 7); 1.959 + 1.960 + utilGzWrite(gzFile, gbSgbSCPPalette, 4 * 512 * sizeof(u16)); 1.961 + utilGzWrite(gzFile, gbSgbATF, 20 * 18); 1.962 + utilGzWrite(gzFile, gbSgbATFList, 45 * 20 * 18); 1.963 + 1.964 + utilGzWrite(gzFile, gbSgbScreenBuffer, 4160); 1.965 + utilGzWrite(gzFile, &gbSgbMode, sizeof(gbSgbMode)); 1.966 + utilGzWrite(gzFile, &gbSgbCGBSupport, sizeof(gbSgbCGBSupport)); 1.967 + utilGzWrite(gzFile, &gbSgbPacketTimeout, sizeof(gbSgbPacketTimeout)); 1.968 +} 1.969 + 1.970 +void gbSgbReadGame(gzFile gzFile, int version) 1.971 +{ 1.972 + if (version >= 3) 1.973 + utilReadData(gzFile, gbSgbSaveStructV3); 1.974 + else 1.975 + { 1.976 + utilReadData(gzFile, gbSgbSaveStruct); 1.977 + gbSgbFourPlayers = 0; 1.978 + } 1.979 + 1.980 + if (version >= 8) 1.981 + { 1.982 + utilGzRead(gzFile, gbSgbBorder, 2048); 1.983 + utilGzRead(gzFile, gbSgbBorderChar, 32 * 256); 1.984 + } 1.985 + 1.986 + utilGzRead(gzFile, gbSgbPacket, 16 * 7); 1.987 + 1.988 + utilGzRead(gzFile, gbSgbSCPPalette, 4 * 512 * sizeof(u16)); 1.989 + utilGzRead(gzFile, gbSgbATF, 20 * 18); 1.990 + utilGzRead(gzFile, gbSgbATFList, 45 * 20 * 18); 1.991 + 1.992 + if (version >= 11) 1.993 + { 1.994 + utilGzRead(gzFile, gbSgbScreenBuffer, 4160); 1.995 + utilGzRead(gzFile, &gbSgbMode, sizeof(gbSgbMode)); 1.996 + utilGzRead(gzFile, &gbSgbCGBSupport, sizeof(gbSgbCGBSupport)); 1.997 + utilGzRead(gzFile, &gbSgbPacketTimeout, sizeof(gbSgbPacketTimeout)); 1.998 + } 1.999 +} 1.1000 +