src/mess/machine/sms.c
| r9563 | r9564 | |
| 40 | 40 | UINT8 input_port0; |
| 41 | 41 | UINT8 input_port1; |
| 42 | 42 | |
| 43 | bitmap_t *tmp_bitmap; |
| 44 | bitmap_t *prev_bitmap; |
| 45 | |
| 43 | 46 | /* Model identifiers */ |
| 44 | 47 | UINT8 is_gamegear; |
| 45 | 48 | UINT8 is_region_japan; |
| r9563 | r9564 | |
| 1305 | 1308 | sms_state.current_cartridge = 0; |
| 1306 | 1309 | |
| 1307 | 1310 | sms_state.bios_port = (IO_EXPANSION | IO_CARTRIDGE | IO_CARD); |
| 1308 | | if (!sms_state.is_gamegear && ! sms_state.has_bios) |
| 1311 | if (!sms_state.is_gamegear && !sms_state.has_bios) |
| 1309 | 1312 | { |
| 1310 | 1313 | sms_state.bios_port &= ~(IO_CARTRIDGE); |
| 1311 | 1314 | sms_state.bios_port |= IO_BIOS_ROM; |
| r9563 | r9564 | |
| 1780 | 1783 | |
| 1781 | 1784 | |
| 1782 | 1785 | /* This needs to be here to check if segascope has been enabled */ |
| 1786 | static void sms_black_bitmap( const screen_device *screen, bitmap_t *bitmap ) |
| 1787 | { |
| 1788 | const int width = screen->width(); |
| 1789 | const int height = screen->height(); |
| 1790 | int x, y; |
| 1791 | |
| 1792 | for (y = 0; y < height; y++) |
| 1793 | for (x = 0; x < width; x++) |
| 1794 | *BITMAP_ADDR32(bitmap, y, x) = MAKE_RGB(0,0,0); |
| 1795 | } |
| 1796 | |
| 1783 | 1797 | VIDEO_UPDATE( sms1 ) |
| 1784 | 1798 | { |
| 1785 | 1799 | running_device *main_scr = screen->machine->device("screen"); |
| r9563 | r9564 | |
| 1794 | 1808 | } |
| 1795 | 1809 | else if (screen == left_lcd) |
| 1796 | 1810 | { |
| 1797 | | int width = screen->width(); |
| 1798 | | int height = screen->height(); |
| 1799 | | int x, y; |
| 1800 | | |
| 1801 | | if (segascope) |
| 1802 | | { |
| 1803 | | if (sms_state.sscope_state & 0x01) /* 1 = left screen ON, right screen OFF */ |
| 1804 | | sms_vdp_update(smsvdp, bitmap, cliprect); |
| 1805 | | else /* 0 = left screen OFF, right screen ON */ |
| 1806 | | { |
| 1807 | | for (y = 0; y < height; y++) |
| 1808 | | for (x = 0; x < width; x++) |
| 1809 | | *BITMAP_ADDR32(bitmap, y, x) = MAKE_RGB(0,0,0); |
| 1810 | | } |
| 1811 | | } |
| 1812 | | else /* We only use the second screen for SegaScope, if it not selected return a black screen */ |
| 1813 | | { |
| 1814 | | for (y = 0; y < height; y++) |
| 1815 | | for (x = 0; x < width; x++) |
| 1816 | | *BITMAP_ADDR32(bitmap, y, x) = MAKE_RGB(0,0,0); |
| 1817 | | } |
| 1811 | /* We only need 2nd screen for SegaScope: if it's not selected return a black screen */ |
| 1812 | if (segascope && (sms_state.sscope_state & 0x01)) |
| 1813 | sms_vdp_update(smsvdp, bitmap, cliprect); /* sscope_state 1 = left screen ON, right screen OFF */ |
| 1814 | else |
| 1815 | sms_black_bitmap(screen, bitmap); /* sscope_state 0 = left screen OFF, right screen ON */ |
| 1818 | 1816 | } |
| 1819 | 1817 | else if (screen == right_lcd) |
| 1820 | 1818 | { |
| 1821 | | int width = screen->width(); |
| 1822 | | int height = screen->height(); |
| 1823 | | int x, y; |
| 1824 | | |
| 1825 | | if (segascope) |
| 1826 | | { |
| 1827 | | if (sms_state.sscope_state & 0x01) /* 1 = left screen ON, right screen OFF */ |
| 1828 | | { |
| 1829 | | for (y = 0; y < height; y++) |
| 1830 | | for (x = 0; x < width; x++) |
| 1831 | | *BITMAP_ADDR32(bitmap, y, x) = MAKE_RGB(0,0,0); |
| 1832 | | } |
| 1833 | | else /* 0 = left screen OFF, right screen ON */ |
| 1834 | | sms_vdp_update(smsvdp, bitmap, cliprect); |
| 1835 | | } |
| 1836 | | else /* We only use the third screen for SegaScope, if it not selected return a black screen */ |
| 1837 | | { |
| 1838 | | for (y = 0; y < height; y++) |
| 1839 | | for (x = 0; x < width; x++) |
| 1840 | | *BITMAP_ADDR32(bitmap, y, x) = MAKE_RGB(0,0,0); |
| 1841 | | } |
| 1819 | /* We only need 3rd screen for SegaScope: if it's not selected return a black screen */ |
| 1820 | if (!segascope || (sms_state.sscope_state & 0x01)) |
| 1821 | sms_black_bitmap(screen, bitmap); /* sscope_state 1 = left screen ON, right screen OFF */ |
| 1822 | else |
| 1823 | sms_vdp_update(smsvdp, bitmap, cliprect); /* sscope_state 0 = left screen OFF, right screen ON */ |
| 1842 | 1824 | } |
| 1843 | 1825 | |
| 1844 | 1826 | return 0; |
| r9563 | r9564 | |
| 1851 | 1833 | |
| 1852 | 1834 | return 0; |
| 1853 | 1835 | } |
| 1836 | |
| 1837 | VIDEO_START( gamegear ) |
| 1838 | { |
| 1839 | screen_device *screen = screen_first(*machine); |
| 1840 | int width = screen->width(); |
| 1841 | int height = screen->height(); |
| 1842 | |
| 1843 | sms_state.prev_bitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED32); |
| 1844 | sms_state.tmp_bitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED32); |
| 1845 | state_save_register_global_bitmap(machine, sms_state.tmp_bitmap); |
| 1846 | } |
| 1847 | |
| 1848 | VIDEO_UPDATE( gamegear ) |
| 1849 | { |
| 1850 | running_device *smsvdp = screen->machine->device("sms_vdp"); |
| 1851 | int width = screen->width(); |
| 1852 | int height = screen->height(); |
| 1853 | int x, y; |
| 1854 | |
| 1855 | sms_vdp_update(smsvdp, sms_state.tmp_bitmap, cliprect); |
| 1856 | |
| 1857 | // HACK: fake LCD persistence effect |
| 1858 | // (it would be better to generalized this in the core, to be used for all LCD systems) |
| 1859 | for (y = 0; y < height; y++) |
| 1860 | { |
| 1861 | UINT32 *line0 = BITMAP_ADDR32(sms_state.tmp_bitmap, y, 0); |
| 1862 | UINT32 *line1 = BITMAP_ADDR32(sms_state.prev_bitmap, y, 0); |
| 1863 | for (x = 0; x < width; x++) |
| 1864 | { |
| 1865 | UINT32 color0 = line0[x]; |
| 1866 | UINT32 color1 = line1[x]; |
| 1867 | UINT16 r0 = (color0 >> 16) & 0x000000ff; |
| 1868 | UINT16 g0 = (color0 >> 8) & 0x000000ff; |
| 1869 | UINT16 b0 = (color0 >> 0) & 0x000000ff; |
| 1870 | UINT16 r1 = (color1 >> 16) & 0x000000ff; |
| 1871 | UINT16 g1 = (color1 >> 8) & 0x000000ff; |
| 1872 | UINT16 b1 = (color1 >> 0) & 0x000000ff; |
| 1873 | UINT8 r = (UINT8)((r0 + r1) >> 1); |
| 1874 | UINT8 g = (UINT8)((g0 + g1) >> 1); |
| 1875 | UINT8 b = (UINT8)((b0 + b1) >> 1); |
| 1876 | *BITMAP_ADDR32(bitmap, y, x) = (r << 16) | (g << 8) | b; |
| 1877 | } |
| 1878 | } |
| 1879 | copybitmap(sms_state.prev_bitmap, sms_state.tmp_bitmap, 0, 0, 0, 0, cliprect); |
| 1880 | |
| 1881 | return 0; |
| 1882 | } |
src/mess/video/smsvdp.c
| r9563 | r9564 | |
| 116 | 116 | region_info *VRAM; /* Pointer to VRAM */ |
| 117 | 117 | region_info *CRAM; /* Pointer to CRAM */ |
| 118 | 118 | const UINT8 *sms_frame_timing; |
| 119 | | bitmap_t *prev_bitmap; |
| 120 | 119 | bitmap_t *tmpbitmap; |
| 121 | | int prev_bitmap_saved; |
| 122 | 120 | UINT8 *collision_buffer; |
| 123 | 121 | |
| 124 | 122 | /* line_buffer will be used to hold 5 lines of line data. Line #0 is the regular blitting area. |
| r9563 | r9564 | |
| 1444 | 1442 | UINT32 sms_vdp_update( running_device *device, bitmap_t *bitmap, const rectangle *cliprect ) |
| 1445 | 1443 | { |
| 1446 | 1444 | smsvdp_t *smsvdp = get_safe_token(device); |
| 1447 | | screen_device *screen = screen_first(*device->machine); |
| 1448 | | int width = screen->width(); |
| 1449 | | int height = screen->height(); |
| 1450 | | int x, y; |
| 1451 | | |
| 1452 | | if (IS_GAMEGEAR_VDP) |
| 1453 | | { |
| 1454 | | for (y = 0; y < height; y++) |
| 1455 | | { |
| 1456 | | UINT32 *line0 = BITMAP_ADDR32(smsvdp->tmpbitmap, y, 0); |
| 1457 | | UINT32 *line1 = BITMAP_ADDR32(smsvdp->prev_bitmap, y, 0); |
| 1458 | | for (x = 0; x < width; x++) |
| 1459 | | { |
| 1460 | | UINT32 color0 = line0[x]; |
| 1461 | | UINT32 color1 = line1[x]; |
| 1462 | | UINT16 r0 = (color0 >> 16) & 0x000000ff; |
| 1463 | | UINT16 g0 = (color0 >> 8) & 0x000000ff; |
| 1464 | | UINT16 b0 = (color0 >> 0) & 0x000000ff; |
| 1465 | | UINT16 r1 = (color1 >> 16) & 0x000000ff; |
| 1466 | | UINT16 g1 = (color1 >> 8) & 0x000000ff; |
| 1467 | | UINT16 b1 = (color1 >> 0) & 0x000000ff; |
| 1468 | | UINT8 r = (UINT8)((r0 + r1) >> 1); |
| 1469 | | UINT8 g = (UINT8)((g0 + g1) >> 1); |
| 1470 | | UINT8 b = (UINT8)((b0 + b1) >> 1); |
| 1471 | | *BITMAP_ADDR32(bitmap, y, x) = (r << 16) | (g << 8) | b; |
| 1472 | | } |
| 1473 | | } |
| 1474 | | |
| 1475 | | copybitmap(smsvdp->prev_bitmap, smsvdp->tmpbitmap, 0, 0, 0, 0, cliprect); |
| 1476 | | } |
| 1477 | | else |
| 1478 | | { |
| 1479 | | copybitmap(bitmap, smsvdp->tmpbitmap, 0, 0, 0, 0, cliprect); |
| 1480 | | } |
| 1481 | | |
| 1445 | copybitmap(bitmap, smsvdp->tmpbitmap, 0, 0, 0, 0, cliprect); |
| 1482 | 1446 | return 0; |
| 1483 | 1447 | } |
| 1484 | 1448 | |
| r9563 | r9564 | |
| 1510 | 1474 | |
| 1511 | 1475 | /* Make temp bitmap for rendering */ |
| 1512 | 1476 | smsvdp->tmpbitmap = auto_bitmap_alloc(device->machine, width, height, BITMAP_FORMAT_INDEXED32); |
| 1513 | | smsvdp->prev_bitmap = auto_bitmap_alloc(device->machine, width, height, BITMAP_FORMAT_INDEXED32); |
| 1514 | 1477 | |
| 1515 | 1478 | smsvdp->smsvdp_display_timer = timer_alloc(device->machine, smsvdp_display_callback, smsvdp); |
| 1516 | 1479 | timer_adjust_periodic(smsvdp->smsvdp_display_timer, screen->time_until_pos(0, DISPLAY_CB_HPOS), 0, screen->scan_period()); |
| r9563 | r9564 | |
| 1529 | 1492 | state_save_register_device_item(device, 0, smsvdp->y_pixels); |
| 1530 | 1493 | state_save_register_device_item(device, 0, smsvdp->line_counter); |
| 1531 | 1494 | state_save_register_device_item(device, 0, smsvdp->hcounter); |
| 1532 | | state_save_register_device_item(device, 0, smsvdp->prev_bitmap_saved); |
| 1533 | 1495 | state_save_register_device_item_array(device, 0, smsvdp->reg); |
| 1534 | 1496 | state_save_register_device_item_array(device, 0, smsvdp->current_palette); |
| 1535 | 1497 | state_save_register_device_item_pointer(device, 0, smsvdp->line_buffer, 256 * 5); |
| 1536 | 1498 | state_save_register_device_item_pointer(device, 0, smsvdp->collision_buffer, SMS_X_PIXELS); |
| 1537 | 1499 | state_save_register_device_item_bitmap(device, 0, smsvdp->tmpbitmap); |
| 1538 | | state_save_register_device_item_bitmap(device, 0, smsvdp->prev_bitmap); |
| 1539 | 1500 | } |
| 1540 | 1501 | |
| 1541 | 1502 | static DEVICE_RESET( smsvdp ) |
| r9563 | r9564 | |
| 1561 | 1522 | smsvdp->buffer = 0; |
| 1562 | 1523 | smsvdp->irq_state = 0; |
| 1563 | 1524 | smsvdp->line_counter = 0; |
| 1564 | | smsvdp->prev_bitmap_saved = 0; |
| 1565 | 1525 | |
| 1566 | 1526 | /* for light gun input with "Hang-On & Safari Hunt", hcounter seems to |
| 1567 | 1527 | need initialization to some value */ |