Mercurial > repos > blastem
comparison vdp.c @ 1652:d0a69348add8
Optimized render_map_output a bit
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 27 Dec 2018 09:23:51 -0800 |
parents | b500e971da75 |
children | 858d52140375 |
comparison
equal
deleted
inserted
replaced
1651:9b8fe6729877 | 1652:d0a69348add8 |
---|---|
768 #define BG_START_SLOT 6 | 768 #define BG_START_SLOT 6 |
769 | 769 |
770 static void update_color_map(vdp_context *context, uint16_t index, uint16_t value) | 770 static void update_color_map(vdp_context *context, uint16_t index, uint16_t value) |
771 { | 771 { |
772 context->colors[index] = color_map[value & CRAM_BITS]; | 772 context->colors[index] = color_map[value & CRAM_BITS]; |
773 context->colors[index + CRAM_SIZE] = color_map[(value & CRAM_BITS) | FBUF_SHADOW]; | 773 context->colors[index + SHADOW_OFFSET] = color_map[(value & CRAM_BITS) | FBUF_SHADOW]; |
774 context->colors[index + CRAM_SIZE*2] = color_map[(value & CRAM_BITS) | FBUF_HILIGHT]; | 774 context->colors[index + HIGHLIGHT_OFFSET] = color_map[(value & CRAM_BITS) | FBUF_HILIGHT]; |
775 context->colors[index + CRAM_SIZE*3] = color_map[(value & CRAM_BITS) | FBUF_MODE4]; | 775 context->colors[index + MODE4_OFFSET] = color_map[(value & CRAM_BITS) | FBUF_MODE4]; |
776 } | 776 } |
777 | 777 |
778 void write_cram_internal(vdp_context * context, uint16_t addr, uint16_t value) | 778 void write_cram_internal(vdp_context * context, uint16_t addr, uint16_t value) |
779 { | 779 { |
780 context->cram[addr] = value; | 780 context->cram[addr] = value; |
796 context->vcounter < context->inactive_start + context->border_bot | 796 context->vcounter < context->inactive_start + context->border_bot |
797 || context->vcounter > 0x200 - context->border_top | 797 || context->vcounter > 0x200 - context->border_top |
798 )) { | 798 )) { |
799 uint8_t bg_end_slot = BG_START_SLOT + (context->regs[REG_MODE_4] & BIT_H40) ? LINEBUF_SIZE/2 : (256+HORIZ_BORDER)/2; | 799 uint8_t bg_end_slot = BG_START_SLOT + (context->regs[REG_MODE_4] & BIT_H40) ? LINEBUF_SIZE/2 : (256+HORIZ_BORDER)/2; |
800 if (context->hslot < bg_end_slot) { | 800 if (context->hslot < bg_end_slot) { |
801 uint32_t color = (context->regs[REG_MODE_2] & BIT_MODE_5) ? context->colors[addr] : context->colors[addr + CRAM_SIZE*3]; | 801 uint32_t color = (context->regs[REG_MODE_2] & BIT_MODE_5) ? context->colors[addr] : context->colors[addr + MODE4_OFFSET]; |
802 context->output[(context->hslot - BG_START_SLOT)*2 + 1] = color; | 802 context->output[(context->hslot - BG_START_SLOT)*2 + 1] = color; |
803 } | 803 } |
804 } | 804 } |
805 } | 805 } |
806 | 806 |
1261 uint32_t address = mode4_address_map[((context->col_1 & 0x1FF) * 32) + vscroll * 4]; | 1261 uint32_t address = mode4_address_map[((context->col_1 & 0x1FF) * 32) + vscroll * 4]; |
1262 context->fetch_tmp[0] = context->vdpmem[address]; | 1262 context->fetch_tmp[0] = context->vdpmem[address]; |
1263 context->fetch_tmp[1] = context->vdpmem[address+1]; | 1263 context->fetch_tmp[1] = context->vdpmem[address+1]; |
1264 } | 1264 } |
1265 | 1265 |
1266 static uint8_t composite_normal(vdp_context *context, uint8_t *debug_dst, uint8_t sprite, uint8_t plane_a, uint8_t plane_b, uint8_t bg_index) | |
1267 { | |
1268 uint8_t pixel = bg_index; | |
1269 uint8_t src = DBG_SRC_BG; | |
1270 if (plane_b & 0xF) { | |
1271 pixel = plane_b; | |
1272 src = DBG_SRC_B; | |
1273 } | |
1274 if (plane_a & 0xF && (plane_a & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) { | |
1275 pixel = plane_a; | |
1276 src = DBG_SRC_A; | |
1277 } | |
1278 if (sprite & 0xF && (sprite & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) { | |
1279 pixel = sprite; | |
1280 src = DBG_SRC_S; | |
1281 } | |
1282 *debug_dst = src; | |
1283 return pixel; | |
1284 } | |
1285 typedef struct { | |
1286 uint8_t index, intensity; | |
1287 } sh_pixel; | |
1288 | |
1289 static sh_pixel composite_highlight(vdp_context *context, uint8_t *debug_dst, uint8_t sprite, uint8_t plane_a, uint8_t plane_b, uint8_t bg_index) | |
1290 { | |
1291 uint8_t pixel = bg_index; | |
1292 uint8_t src = DBG_SRC_BG; | |
1293 uint8_t intensity = 0; | |
1294 if (plane_b & 0xF) { | |
1295 pixel = plane_b; | |
1296 src = DBG_SRC_B; | |
1297 } | |
1298 intensity = plane_b & BUF_BIT_PRIORITY; | |
1299 if (plane_a & 0xF && (plane_a & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) { | |
1300 pixel = plane_a; | |
1301 src = DBG_SRC_A; | |
1302 } | |
1303 intensity |= plane_a & BUF_BIT_PRIORITY; | |
1304 if (sprite & 0xF && (sprite & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) { | |
1305 if ((sprite & 0x3F) == 0x3E) { | |
1306 intensity += BUF_BIT_PRIORITY; | |
1307 } else if ((sprite & 0x3F) == 0x3F) { | |
1308 intensity = 0; | |
1309 } else { | |
1310 pixel = sprite; | |
1311 src = DBG_SRC_S; | |
1312 if ((pixel & 0xF) == 0xE) { | |
1313 intensity = BUF_BIT_PRIORITY; | |
1314 } else { | |
1315 intensity |= pixel & BUF_BIT_PRIORITY; | |
1316 } | |
1317 } | |
1318 } | |
1319 *debug_dst = src; | |
1320 return (sh_pixel){.index = pixel, .intensity = intensity}; | |
1321 } | |
1322 | |
1323 static void render_normal(vdp_context *context, int32_t col, uint32_t *dst, uint8_t *debug_dst, int plane_a_off, int plane_b_off) | |
1324 { | |
1325 int start = 0; | |
1326 if (!col && (context->regs[REG_MODE_1] & BIT_COL0_MASK)) { | |
1327 uint32_t bgcolor = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; | |
1328 for (int i = 0; i < 8; ++i) | |
1329 { | |
1330 *(dst++) = bgcolor; | |
1331 *(debug_dst++) = DBG_SRC_BG; | |
1332 } | |
1333 start = 8; | |
1334 } | |
1335 uint8_t *sprite_buf = context->linebuf + col * 8 + start; | |
1336 for (int i = start; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) | |
1337 { | |
1338 uint8_t sprite, plane_a, plane_b; | |
1339 plane_a = context->tmp_buf_a[plane_a_off & SCROLL_BUFFER_MASK]; | |
1340 plane_b = context->tmp_buf_b[plane_b_off & SCROLL_BUFFER_MASK]; | |
1341 sprite = *sprite_buf; | |
1342 uint8_t pixel = composite_normal(context, debug_dst, sprite, plane_a, plane_b, context->regs[REG_BG_COLOR]); | |
1343 debug_dst++; | |
1344 *(dst++) = context->colors[pixel & 0x3F]; | |
1345 } | |
1346 } | |
1347 | |
1348 static void render_highlight(vdp_context *context, int32_t col, uint32_t *dst, uint8_t *debug_dst, int plane_a_off, int plane_b_off) | |
1349 { | |
1350 int start = 0; | |
1351 if (!col && (context->regs[REG_MODE_1] & BIT_COL0_MASK)) { | |
1352 uint32_t bgcolor = context->colors[SHADOW_OFFSET + (context->regs[REG_BG_COLOR] & 0x3F)]; | |
1353 for (int i = 0; i < 8; ++i) | |
1354 { | |
1355 *(dst++) = bgcolor; | |
1356 *(debug_dst++) = DBG_SRC_BG | DBG_SHADOW; | |
1357 } | |
1358 start = 8; | |
1359 } | |
1360 uint8_t *sprite_buf = context->linebuf + col * 8 + start; | |
1361 for (int i = start; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) | |
1362 { | |
1363 uint8_t sprite, plane_a, plane_b; | |
1364 plane_a = context->tmp_buf_a[plane_a_off & SCROLL_BUFFER_MASK]; | |
1365 plane_b = context->tmp_buf_b[plane_b_off & SCROLL_BUFFER_MASK]; | |
1366 sprite = *sprite_buf; | |
1367 sh_pixel pixel = composite_highlight(context, debug_dst, sprite, plane_a, plane_b, context->regs[REG_BG_COLOR]); | |
1368 uint32_t *colors; | |
1369 if (pixel.intensity == BUF_BIT_PRIORITY << 1) { | |
1370 colors = context->colors + HIGHLIGHT_OFFSET; | |
1371 } else if (pixel.intensity) { | |
1372 colors = context->colors; | |
1373 } else { | |
1374 colors = context->colors + SHADOW_OFFSET; | |
1375 } | |
1376 debug_dst++; | |
1377 *(dst++) = colors[pixel.index & 0x3F]; | |
1378 } | |
1379 } | |
1380 | |
1381 static void render_testreg(vdp_context *context, int32_t col, uint32_t *dst, uint8_t *debug_dst, int plane_a_off, int plane_b_off, uint8_t output_disabled, uint8_t test_layer) | |
1382 { | |
1383 if (output_disabled) { | |
1384 switch (test_layer) | |
1385 { | |
1386 case 0: | |
1387 for (int i = 0; i < 16; i++) | |
1388 { | |
1389 *(dst++) = 0x3F; //TODO: confirm this on hardware | |
1390 *(debug_dst++) = DBG_SRC_BG; | |
1391 } | |
1392 break; | |
1393 case 1: { | |
1394 uint8_t *sprite_buf = context->linebuf + col * 8; | |
1395 for (int i = 0; i < 16; i++) | |
1396 { | |
1397 *(dst++) = *(sprite_buf++); | |
1398 *(debug_dst++) = DBG_SRC_S; | |
1399 } | |
1400 break; | |
1401 } | |
1402 case 2: | |
1403 for (int i = 0; i < 16; i++) | |
1404 { | |
1405 *(dst++) = context->tmp_buf_a[(plane_a_off++) & SCROLL_BUFFER_MASK]; | |
1406 *(debug_dst++) = DBG_SRC_A; | |
1407 } | |
1408 break; | |
1409 case 3: | |
1410 for (int i = 0; i < 16; i++) | |
1411 { | |
1412 *(dst++) = context->tmp_buf_a[(plane_a_off++) & SCROLL_BUFFER_MASK]; | |
1413 *(debug_dst++) = DBG_SRC_B; | |
1414 } | |
1415 break; | |
1416 } | |
1417 } else { | |
1418 int start = 0; | |
1419 uint8_t *sprite_buf = context->linebuf + col * 8; | |
1420 if (!col && (context->regs[REG_MODE_1] & BIT_COL0_MASK)) { | |
1421 //TODO: Confirm how test register interacts with column 0 blanking | |
1422 uint8_t pixel = context->regs[REG_BG_COLOR] & 0x3F; | |
1423 uint8_t src = DBG_SRC_BG; | |
1424 for (int i = 0; i < 8; ++i) | |
1425 { | |
1426 switch (test_layer) | |
1427 { | |
1428 case 1: | |
1429 pixel &= sprite_buf[i]; | |
1430 if (pixel) { | |
1431 src = DBG_SRC_S; | |
1432 } | |
1433 break; | |
1434 case 2: | |
1435 pixel &= context->tmp_buf_a[(plane_a_off + i) & SCROLL_BUFFER_MASK]; | |
1436 if (pixel) { | |
1437 src = DBG_SRC_A; | |
1438 } | |
1439 break; | |
1440 case 3: | |
1441 pixel &= context->tmp_buf_b[(plane_b_off + i) & SCROLL_BUFFER_MASK]; | |
1442 if (pixel) { | |
1443 src = DBG_SRC_B; | |
1444 } | |
1445 break; | |
1446 } | |
1447 | |
1448 *(dst++) = context->colors[pixel & 0x3F]; | |
1449 *(debug_dst++) = src; | |
1450 } | |
1451 plane_a_off += 8; | |
1452 plane_b_off += 8; | |
1453 sprite_buf += 8; | |
1454 start = 8; | |
1455 } | |
1456 for (int i = start; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) | |
1457 { | |
1458 uint8_t sprite, plane_a, plane_b; | |
1459 plane_a = context->tmp_buf_a[plane_a_off & SCROLL_BUFFER_MASK]; | |
1460 plane_b = context->tmp_buf_b[plane_b_off & SCROLL_BUFFER_MASK]; | |
1461 sprite = *sprite_buf; | |
1462 uint8_t pixel = composite_normal(context, debug_dst, sprite, plane_a, plane_b, 0x3F); | |
1463 switch (test_layer) | |
1464 { | |
1465 case 1: | |
1466 pixel &= sprite; | |
1467 if (pixel) { | |
1468 *debug_dst = DBG_SRC_S; | |
1469 } | |
1470 break; | |
1471 case 2: | |
1472 pixel &= plane_a; | |
1473 if (pixel) { | |
1474 *debug_dst = DBG_SRC_A; | |
1475 } | |
1476 break; | |
1477 case 3: | |
1478 pixel &= plane_b; | |
1479 if (pixel) { | |
1480 *debug_dst = DBG_SRC_B; | |
1481 } | |
1482 break; | |
1483 } | |
1484 debug_dst++; | |
1485 *(dst++) = context->colors[pixel & 0x3F]; | |
1486 } | |
1487 } | |
1488 } | |
1489 | |
1490 static void render_testreg_highlight(vdp_context *context, int32_t col, uint32_t *dst, uint8_t *debug_dst, int plane_a_off, int plane_b_off, uint8_t output_disabled, uint8_t test_layer) | |
1491 { | |
1492 if (output_disabled) { | |
1493 //TODO: confirm how this behaves when shadow/highlight is enabled | |
1494 switch (test_layer) | |
1495 { | |
1496 case 0: | |
1497 for (int i = 0; i < 16; i++) | |
1498 { | |
1499 *(dst++) = 0x3F; //TODO: confirm this on hardware | |
1500 *(debug_dst++) = DBG_SRC_BG; | |
1501 } | |
1502 break; | |
1503 case 1: { | |
1504 uint8_t *sprite_buf = context->linebuf + col * 8; | |
1505 for (int i = 0; i < 16; i++) | |
1506 { | |
1507 *(dst++) = *(sprite_buf++); | |
1508 *(debug_dst++) = DBG_SRC_S; | |
1509 } | |
1510 break; | |
1511 } | |
1512 case 2: | |
1513 for (int i = 0; i < 16; i++) | |
1514 { | |
1515 *(dst++) = context->tmp_buf_a[(plane_a_off++) & SCROLL_BUFFER_MASK]; | |
1516 *(debug_dst++) = DBG_SRC_A; | |
1517 } | |
1518 break; | |
1519 case 3: | |
1520 for (int i = 0; i < 16; i++) | |
1521 { | |
1522 *(dst++) = context->tmp_buf_a[(plane_a_off++) & SCROLL_BUFFER_MASK]; | |
1523 *(debug_dst++) = DBG_SRC_B; | |
1524 } | |
1525 break; | |
1526 } | |
1527 } else { | |
1528 int start = 0; | |
1529 uint8_t *sprite_buf = context->linebuf + col * 8; | |
1530 if (!col && (context->regs[REG_MODE_1] & BIT_COL0_MASK)) { | |
1531 //TODO: Confirm how test register interacts with column 0 blanking | |
1532 uint8_t pixel = context->regs[REG_BG_COLOR] & 0x3F; | |
1533 uint8_t src = DBG_SRC_BG | DBG_SHADOW; | |
1534 for (int i = 0; i < 8; ++i) | |
1535 { | |
1536 switch (test_layer) | |
1537 { | |
1538 case 1: | |
1539 pixel &= sprite_buf[i]; | |
1540 if (pixel) { | |
1541 src = DBG_SRC_S | DBG_SHADOW; | |
1542 } | |
1543 break; | |
1544 case 2: | |
1545 pixel &= context->tmp_buf_a[(plane_a_off + i) & SCROLL_BUFFER_MASK]; | |
1546 if (pixel) { | |
1547 src = DBG_SRC_A | DBG_SHADOW; | |
1548 } | |
1549 break; | |
1550 case 3: | |
1551 pixel &= context->tmp_buf_b[(plane_b_off + i) & SCROLL_BUFFER_MASK]; | |
1552 if (pixel) { | |
1553 src = DBG_SRC_B | DBG_SHADOW; | |
1554 } | |
1555 break; | |
1556 } | |
1557 | |
1558 *(dst++) = context->colors[SHADOW_OFFSET + (pixel & 0x3F)]; | |
1559 *(debug_dst++) = src; | |
1560 } | |
1561 plane_a_off += 8; | |
1562 plane_b_off += 8; | |
1563 sprite_buf += 8; | |
1564 start = 8; | |
1565 } | |
1566 for (int i = start; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) | |
1567 { | |
1568 uint8_t sprite, plane_a, plane_b; | |
1569 plane_a = context->tmp_buf_a[plane_a_off & SCROLL_BUFFER_MASK]; | |
1570 plane_b = context->tmp_buf_b[plane_b_off & SCROLL_BUFFER_MASK]; | |
1571 sprite = *sprite_buf; | |
1572 sh_pixel pixel = composite_highlight(context, debug_dst, sprite, plane_a, plane_b, 0x3F); | |
1573 uint32_t *colors; | |
1574 if (pixel.intensity == BUF_BIT_PRIORITY << 1) { | |
1575 colors = context->colors + HIGHLIGHT_OFFSET; | |
1576 } else if (pixel.intensity) { | |
1577 colors = context->colors; | |
1578 } else { | |
1579 colors = context->colors + SHADOW_OFFSET; | |
1580 } | |
1581 switch (test_layer) | |
1582 { | |
1583 case 1: | |
1584 pixel.index &= sprite; | |
1585 if (pixel.index) { | |
1586 *debug_dst = DBG_SRC_S; | |
1587 } | |
1588 break; | |
1589 case 2: | |
1590 pixel.index &= plane_a; | |
1591 if (pixel.index) { | |
1592 *debug_dst = DBG_SRC_A; | |
1593 } | |
1594 break; | |
1595 case 3: | |
1596 pixel.index &= plane_b; | |
1597 if (pixel.index) { | |
1598 *debug_dst = DBG_SRC_B; | |
1599 } | |
1600 break; | |
1601 } | |
1602 debug_dst++; | |
1603 *(dst++) = colors[pixel.index & 0x3F]; | |
1604 } | |
1605 } | |
1606 } | |
1607 | |
1266 static void render_map_output(uint32_t line, int32_t col, vdp_context * context) | 1608 static void render_map_output(uint32_t line, int32_t col, vdp_context * context) |
1267 { | 1609 { |
1268 uint32_t *dst; | 1610 uint32_t *dst; |
1269 uint8_t *debug_dst; | 1611 uint8_t *debug_dst; |
1270 uint8_t output_disabled = (context->test_port & TEST_BIT_DISABLE) != 0; | 1612 uint8_t output_disabled = (context->test_port & TEST_BIT_DISABLE) != 0; |
1291 context->done_output = dst; | 1633 context->done_output = dst; |
1292 return; | 1634 return; |
1293 } | 1635 } |
1294 line &= 0xFF; | 1636 line &= 0xFF; |
1295 render_map(context->col_2, context->tmp_buf_b, context->buf_b_off+8, context); | 1637 render_map(context->col_2, context->tmp_buf_b, context->buf_b_off+8, context); |
1296 uint8_t *sprite_buf, *plane_a, *plane_b; | 1638 uint8_t *sprite_buf; |
1639 uint8_t sprite, plane_a, plane_b; | |
1297 int plane_a_off, plane_b_off; | 1640 int plane_a_off, plane_b_off; |
1298 if (col) | 1641 if (col) |
1299 { | 1642 { |
1300 col-=2; | 1643 col-=2; |
1301 dst = context->output + BORDER_LEFT + col * 8; | 1644 dst = context->output + BORDER_LEFT + col * 8; |
1302 debug_dst = context->layer_debug_buf + BORDER_LEFT + col * 8; | 1645 debug_dst = context->layer_debug_buf + BORDER_LEFT + col * 8; |
1303 | 1646 |
1304 sprite_buf = context->linebuf + col * 8; | 1647 |
1305 uint8_t a_src, src; | 1648 uint8_t a_src, src; |
1306 if (context->flags & FLAG_WINDOW) { | 1649 if (context->flags & FLAG_WINDOW) { |
1307 plane_a_off = context->buf_a_off; | 1650 plane_a_off = context->buf_a_off; |
1308 a_src = DBG_SRC_W; | 1651 a_src = DBG_SRC_W; |
1309 } else { | 1652 } else { |
1312 } | 1655 } |
1313 plane_b_off = context->buf_b_off - (context->hscroll_b & 0xF); | 1656 plane_b_off = context->buf_b_off - (context->hscroll_b & 0xF); |
1314 //printf("A | tmp_buf offset: %d\n", 8 - (context->hscroll_a & 0x7)); | 1657 //printf("A | tmp_buf offset: %d\n", 8 - (context->hscroll_a & 0x7)); |
1315 | 1658 |
1316 if (context->regs[REG_MODE_4] & BIT_HILIGHT) { | 1659 if (context->regs[REG_MODE_4] & BIT_HILIGHT) { |
1317 for (int i = 0; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) { | 1660 if (output_disabled || test_layer) { |
1318 plane_a = context->tmp_buf_a + (plane_a_off & SCROLL_BUFFER_MASK); | 1661 render_testreg_highlight(context, col, dst, debug_dst, plane_a_off, plane_b_off, output_disabled, test_layer); |
1319 plane_b = context->tmp_buf_b + (plane_b_off & SCROLL_BUFFER_MASK); | 1662 } else { |
1320 uint8_t pixel = context->regs[REG_BG_COLOR]; | 1663 render_highlight(context, col, dst, debug_dst, plane_a_off, plane_b_off); |
1321 uint32_t *colors = context->colors; | 1664 } |
1322 src = DBG_SRC_BG; | 1665 } else { |
1323 uint8_t intensity = 0; | 1666 if (output_disabled || test_layer) { |
1324 if (col || !(context->regs[REG_MODE_1] & BIT_COL0_MASK) || i >= 8) { | 1667 render_testreg(context, col, dst, debug_dst, plane_a_off, plane_b_off, output_disabled, test_layer); |
1325 if (*plane_b & 0xF) { | 1668 } else { |
1326 pixel = *plane_b; | 1669 render_normal(context, col, dst, debug_dst, plane_a_off, plane_b_off); |
1327 src = DBG_SRC_B; | |
1328 } | |
1329 intensity = *plane_b & BUF_BIT_PRIORITY; | |
1330 if (*plane_a & 0xF && (*plane_a & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) { | |
1331 pixel = *plane_a; | |
1332 src = a_src; | |
1333 } | |
1334 intensity |= *plane_a & BUF_BIT_PRIORITY; | |
1335 if (*sprite_buf & 0xF && (*sprite_buf & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) { | |
1336 if ((*sprite_buf & 0x3F) == 0x3E) { | |
1337 intensity += BUF_BIT_PRIORITY; | |
1338 } else if ((*sprite_buf & 0x3F) == 0x3F) { | |
1339 intensity = 0; | |
1340 } else { | |
1341 pixel = *sprite_buf; | |
1342 src = DBG_SRC_S; | |
1343 if ((pixel & 0xF) == 0xE) { | |
1344 intensity = BUF_BIT_PRIORITY; | |
1345 } else { | |
1346 intensity |= pixel & BUF_BIT_PRIORITY; | |
1347 } | |
1348 } | |
1349 } | |
1350 } | |
1351 if (output_disabled) { | |
1352 pixel = 0x3F; | |
1353 } | |
1354 if (!intensity) { | |
1355 src |= DBG_SHADOW; | |
1356 colors += CRAM_SIZE; | |
1357 } else if (intensity == BUF_BIT_PRIORITY*2) { | |
1358 src |= DBG_HILIGHT; | |
1359 colors += CRAM_SIZE*2; | |
1360 } | |
1361 //TODO: Verify how test register stuff interacts with shadow/highlight | |
1362 //TODO: Simulate CRAM corruption from bus fight | |
1363 switch (test_layer) | |
1364 { | |
1365 case 1: | |
1366 pixel &= *sprite_buf; | |
1367 if (output_disabled && pixel) { | |
1368 src = DBG_SRC_S; | |
1369 } | |
1370 break; | |
1371 case 2: | |
1372 pixel &= *plane_a; | |
1373 if (output_disabled && pixel) { | |
1374 src = DBG_SRC_A; | |
1375 } | |
1376 break; | |
1377 case 3: | |
1378 pixel &= *plane_b; | |
1379 if (output_disabled && pixel) { | |
1380 src = DBG_SRC_B; | |
1381 } | |
1382 break; | |
1383 } | |
1384 *(debug_dst++) = src; | |
1385 *(dst++) = colors[pixel & 0x3F]; | |
1386 } | |
1387 } else { | |
1388 for (int i = 0; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) { | |
1389 plane_a = context->tmp_buf_a + (plane_a_off & SCROLL_BUFFER_MASK); | |
1390 plane_b = context->tmp_buf_b + (plane_b_off & SCROLL_BUFFER_MASK); | |
1391 uint8_t pixel = context->regs[REG_BG_COLOR]; | |
1392 src = DBG_SRC_BG; | |
1393 if (output_disabled) { | |
1394 pixel = 0x3F; | |
1395 } else { | |
1396 if (col || !(context->regs[REG_MODE_1] & BIT_COL0_MASK) || i >= 8) { | |
1397 if (*plane_b & 0xF) { | |
1398 pixel = *plane_b; | |
1399 src = DBG_SRC_B; | |
1400 } | |
1401 if (*plane_a & 0xF && (*plane_a & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) { | |
1402 pixel = *plane_a; | |
1403 src = a_src; | |
1404 } | |
1405 if (*sprite_buf & 0xF && (*sprite_buf & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) { | |
1406 pixel = *sprite_buf; | |
1407 src = DBG_SRC_S; | |
1408 } | |
1409 } | |
1410 } | |
1411 //TODO: Simulate CRAM corruption from bus fight | |
1412 switch (test_layer) | |
1413 { | |
1414 case 1: | |
1415 pixel &= *sprite_buf; | |
1416 if (output_disabled && pixel) { | |
1417 src = DBG_SRC_S; | |
1418 } | |
1419 break; | |
1420 case 2: | |
1421 pixel &= *plane_a; | |
1422 if (output_disabled && pixel) { | |
1423 src = DBG_SRC_A; | |
1424 } | |
1425 break; | |
1426 case 3: | |
1427 pixel &= *plane_b; | |
1428 if (output_disabled && pixel) { | |
1429 src = DBG_SRC_B; | |
1430 } | |
1431 break; | |
1432 } | |
1433 *(dst++) = context->colors[pixel & 0x3F]; | |
1434 *(debug_dst++) = src; | |
1435 } | 1670 } |
1436 } | 1671 } |
1437 } else { | 1672 } else { |
1438 dst = context->output; | 1673 dst = context->output; |
1439 debug_dst = context->layer_debug_buf; | 1674 debug_dst = context->layer_debug_buf; |
1488 *dst = bg_color; | 1723 *dst = bg_color; |
1489 *debug_dst = DBG_SRC_BG; | 1724 *debug_dst = DBG_SRC_BG; |
1490 } | 1725 } |
1491 } | 1726 } |
1492 } | 1727 } |
1493 context->done_output = dst; | 1728 context->done_output = dst + 16; |
1494 context->buf_a_off = (context->buf_a_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK; | 1729 context->buf_a_off = (context->buf_a_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK; |
1495 context->buf_b_off = (context->buf_b_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK; | 1730 context->buf_b_off = (context->buf_b_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK; |
1496 } | 1731 } |
1497 | 1732 |
1498 static void render_map_mode4(uint32_t line, int32_t col, vdp_context * context) | 1733 static void render_map_mode4(uint32_t line, int32_t col, vdp_context * context) |
1533 { | 1768 { |
1534 *dst = (pixels >> i & 0xF) | pal_priority; | 1769 *dst = (pixels >> i & 0xF) | pal_priority; |
1535 } | 1770 } |
1536 context->buf_a_off = (context->buf_a_off + 8) & 15; | 1771 context->buf_a_off = (context->buf_a_off + 8) & 15; |
1537 | 1772 |
1538 uint8_t bgcolor = 0x10 | (context->regs[REG_BG_COLOR] & 0xF) + CRAM_SIZE*3; | 1773 uint8_t bgcolor = 0x10 | (context->regs[REG_BG_COLOR] & 0xF) + MODE4_OFFSET; |
1539 uint32_t *dst = context->output + col * 8 + BORDER_LEFT; | 1774 uint32_t *dst = context->output + col * 8 + BORDER_LEFT; |
1540 uint8_t *debug_dst = context->layer_debug_buf + col * 8 + BORDER_LEFT; | 1775 uint8_t *debug_dst = context->layer_debug_buf + col * 8 + BORDER_LEFT; |
1541 if (context->state == PREPARING) { | 1776 if (context->state == PREPARING) { |
1542 for (int i = 0; i < 16; i++) | 1777 for (int i = 0; i < 16; i++) |
1543 { | 1778 { |
1555 for (int i = 0; i < 8; i++, sprite_src++) | 1790 for (int i = 0; i < 8; i++, sprite_src++) |
1556 { | 1791 { |
1557 uint8_t *bg_src = context->tmp_buf_a + ((8 + i + col * 8 - (context->hscroll_a & 0x7)) & 15); | 1792 uint8_t *bg_src = context->tmp_buf_a + ((8 + i + col * 8 - (context->hscroll_a & 0x7)) & 15); |
1558 if ((*bg_src & 0x4F) > 0x40 || !*sprite_src) { | 1793 if ((*bg_src & 0x4F) > 0x40 || !*sprite_src) { |
1559 //background plane has priority and is opaque or sprite layer is transparent | 1794 //background plane has priority and is opaque or sprite layer is transparent |
1560 *(dst++) = context->colors[(*bg_src & 0x1F) + CRAM_SIZE*3]; | 1795 *(dst++) = context->colors[(*bg_src & 0x1F) + MODE4_OFFSET]; |
1561 *(debug_dst++) = DBG_SRC_A; | 1796 *(debug_dst++) = DBG_SRC_A; |
1562 } else { | 1797 } else { |
1563 //sprite layer is opaque and not covered by high priority BG pixels | 1798 //sprite layer is opaque and not covered by high priority BG pixels |
1564 *(dst++) = context->colors[*sprite_src | 0x10 + CRAM_SIZE*3]; | 1799 *(dst++) = context->colors[*sprite_src | 0x10 + MODE4_OFFSET]; |
1565 *(debug_dst++) = DBG_SRC_S; | 1800 *(debug_dst++) = DBG_SRC_S; |
1566 } | 1801 } |
1567 } | 1802 } |
1568 } else { | 1803 } else { |
1569 for (int i = 0; i < 8; i++) | 1804 for (int i = 0; i < 8; i++) |
2178 fetch_sprite_cells_mode4(context);\ | 2413 fetch_sprite_cells_mode4(context);\ |
2179 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 2))\ | 2414 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 2))\ |
2180 case CALC_SLOT(slot, 3):\ | 2415 case CALC_SLOT(slot, 3):\ |
2181 if ((slot + 3) == 140) {\ | 2416 if ((slot + 3) == 140) {\ |
2182 uint32_t *dst = context->output + BORDER_LEFT + 256 + 8;\ | 2417 uint32_t *dst = context->output + BORDER_LEFT + 256 + 8;\ |
2183 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + CRAM_SIZE*3];\ | 2418 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + MODE4_OFFSET];\ |
2184 for (int i = 0; i < BORDER_RIGHT-8; i++, dst++)\ | 2419 for (int i = 0; i < BORDER_RIGHT-8; i++, dst++)\ |
2185 {\ | 2420 {\ |
2186 *dst = bgcolor;\ | 2421 *dst = bgcolor;\ |
2187 }\ | 2422 }\ |
2188 context->done_output = dst;\ | 2423 context->done_output = dst;\ |
2698 scan_sprite_table_mode4(context); | 2933 scan_sprite_table_mode4(context); |
2699 CHECK_LIMIT | 2934 CHECK_LIMIT |
2700 case 0: { | 2935 case 0: { |
2701 scan_sprite_table_mode4(context); | 2936 scan_sprite_table_mode4(context); |
2702 uint32_t *dst = context->output;; | 2937 uint32_t *dst = context->output;; |
2703 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + CRAM_SIZE*3]; | 2938 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + MODE4_OFFSET]; |
2704 for (int i = 0; i < BORDER_LEFT-8; i++, dst++) | 2939 for (int i = 0; i < BORDER_LEFT-8; i++, dst++) |
2705 { | 2940 { |
2706 *dst = bgcolor; | 2941 *dst = bgcolor; |
2707 } | 2942 } |
2708 context->done_output = dst; | 2943 context->done_output = dst; |
2720 case 4: { | 2955 case 4: { |
2721 scan_sprite_table_mode4(context); | 2956 scan_sprite_table_mode4(context); |
2722 context->buf_a_off = 8; | 2957 context->buf_a_off = 8; |
2723 memset(context->tmp_buf_a, 0, 8); | 2958 memset(context->tmp_buf_a, 0, 8); |
2724 uint32_t *dst = context->output + BORDER_LEFT - 8; | 2959 uint32_t *dst = context->output + BORDER_LEFT - 8; |
2725 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + CRAM_SIZE*3]; | 2960 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + MODE4_OFFSET]; |
2726 for (int i = 0; i < 8; i++, dst++) | 2961 for (int i = 0; i < 8; i++, dst++) |
2727 { | 2962 { |
2728 *dst = bgcolor; | 2963 *dst = bgcolor; |
2729 } | 2964 } |
2730 context->done_output = dst; | 2965 context->done_output = dst; |
2776 //set things up for sprite rendering in the next slot | 3011 //set things up for sprite rendering in the next slot |
2777 memset(context->linebuf, 0, LINEBUF_SIZE); | 3012 memset(context->linebuf, 0, LINEBUF_SIZE); |
2778 context->cur_slot = context->sprite_index = MAX_DRAWS_H32_MODE4-1; | 3013 context->cur_slot = context->sprite_index = MAX_DRAWS_H32_MODE4-1; |
2779 context->sprite_draws = MAX_DRAWS_H32_MODE4; | 3014 context->sprite_draws = MAX_DRAWS_H32_MODE4; |
2780 uint32_t *dst = context->output + BORDER_LEFT + 256; | 3015 uint32_t *dst = context->output + BORDER_LEFT + 256; |
2781 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + CRAM_SIZE*3]; | 3016 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + MODE4_OFFSET]; |
2782 for (int i = 0; i < 8; i++, dst++) | 3017 for (int i = 0; i < 8; i++, dst++) |
2783 { | 3018 { |
2784 *dst = bgcolor; | 3019 *dst = bgcolor; |
2785 } | 3020 } |
2786 context->done_output = dst; | 3021 context->done_output = dst; |
2991 | 3226 |
2992 if (dst) { | 3227 if (dst) { |
2993 if (mode_5) { | 3228 if (mode_5) { |
2994 bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; | 3229 bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; |
2995 } else if (context->regs[REG_MODE_1] & BIT_MODE_4) { | 3230 } else if (context->regs[REG_MODE_1] & BIT_MODE_4) { |
2996 bg_color = context->colors[CRAM_SIZE * 3 + 0x10 + (context->regs[REG_BG_COLOR] & 0xF)]; | 3231 bg_color = context->colors[MODE4_OFFSET + 0x10 + (context->regs[REG_BG_COLOR] & 0xF)]; |
2997 } | 3232 } |
2998 if (dst >= context->done_output) { | 3233 if (dst >= context->done_output) { |
2999 *(dst++) = bg_color; | 3234 *(dst++) = bg_color; |
3000 *(debug_dst++) = DBG_SRC_BG; | 3235 *(debug_dst++) = DBG_SRC_BG; |
3001 } else { | 3236 } else { |