// license:BSD-3-Clause // copyright-holders:Luca Elia, Nicola Salmoria /*************************************************************************** The CPU controls a video blitter that can read data from the ROMs (instructions to draw pixel by pixel, in a compressed form) and write to up to 8 frame buffers. hanamai: There are four scrolling layers. Each layer consists of 2 frame buffers. The 2 images are interleaved to form the final picture sent to the screen. drgpunch: There are three scrolling layers. Each layer consists of 2 frame buffers. The 2 images are interleaved to form the final picture sent to the screen. mjdialq2: Two scrolling layers. ***************************************************************************/ #include "emu.h" #include "includes/dynax.h" // Log Blitter #define VERBOSE 0 #define LOG(x) do { if (VERBOSE) logerror x; } while (0) /* x B01234 G01234 R01234 */ PALETTE_INIT_MEMBER(dynax_state,sprtmtch) { const uint8_t *color_prom = memregion("proms")->base(); if (!color_prom) return; for (int i = 0; i < palette.entries(); i++) { int x = (color_prom[i] << 8) + color_prom[0x200 + i]; /* The bits are in reverse order! */ int r = bitswap<8>((x >> 0) & 0x1f, 7, 6, 5, 0, 1, 2, 3, 4); int g = bitswap<8>((x >> 5) & 0x1f, 7, 6, 5, 0, 1, 2, 3, 4); int b = bitswap<8>((x >> 10) & 0x1f, 7, 6, 5, 0, 1, 2, 3, 4); palette.set_pen_color(i, pal5bit(r), pal5bit(g), pal5bit(b)); } } /* x xB0123 xG0123 xR0123 */ PALETTE_INIT_MEMBER(dynax_state,janyuki) { const uint8_t *color_prom = memregion("proms")->base(); if (!color_prom) return; for (int i = 0; i < palette.entries(); i++) { int x = (color_prom[i] << 8) + color_prom[0x200 + i]; /* The bits are in reverse order! */ int r = bitswap<8>((x >> 0) & 0x0f, 7, 6, 5, 4, 0, 1, 2, 3); int g = bitswap<8>((x >> 5) & 0x0f, 7, 6, 5, 4, 0, 1, 2, 3); int b = bitswap<8>((x >> 10) & 0x0f, 7, 6, 5, 4, 0, 1, 2, 3); palette.set_pen_color(i, pal4bit(r), pal4bit(g), pal4bit(b)); } } /*************************************************************************** Video Blitter(s) ***************************************************************************/ #define LAYOUT_HANAMAI 0 // 4 layers, interleaved #define LAYOUT_HNORIDUR 1 // same as hanamai but some bits are inverted and layer order is reversed #define LAYOUT_DRGPUNCH 2 // 3 couples of layers, interleaved #define LAYOUT_MJDIALQ2 3 // 2 layers #define LAYOUT_JANTOUKI 4 // 2 x (4 couples of layers, interleaved) WRITE8_MEMBER(dynax_state::dynax_extra_scrollx_w) { m_extra_scroll_x = data; } WRITE8_MEMBER(dynax_state::dynax_extra_scrolly_w) { m_extra_scroll_y = data; } /* Destination Layers */ WRITE8_MEMBER(dynax_state::dynax_blit_dest_w) { m_blit_dest = data; if (m_layer_layout == LAYOUT_HNORIDUR) m_blit_dest = bitswap<8>(m_blit_dest ^ 0x0f, 7, 6, 5, 4, 0, 1, 2, 3); LOG(("D=%02X ", data)); } WRITE8_MEMBER(dynax_state::dynax_blit2_dest_w) { m_blit2_dest = data; LOG(("D'=%02X ", data)); } WRITE8_MEMBER(dynax_state::tenkai_blit_dest_w) { dynax_blit_dest_w(space, 0, bitswap<8>(data, 7, 6, 5, 4, 0, 1, 2, 3)); } /* mjelctrn: 7 d e -> 1 - 4 8 mjembase: b d e -> - 2 4 8 */ WRITE8_MEMBER(dynax_state::mjembase_blit_dest_w) { dynax_blit_dest_w(space, 0, bitswap<8>(data, 7, 6, 5, 4, 2, 3, 1, 0)); } /* Background Color */ WRITE8_MEMBER(dynax_state::dynax_blit_backpen_w) { m_blit_backpen = data; LOG(("B=%02X ", data)); } /* Layers 0&1 Palettes (Low Bits) */ WRITE8_MEMBER(dynax_state::dynax_blit_palette01_w) { if (m_layer_layout == LAYOUT_HNORIDUR) m_blit_palettes = (m_blit_palettes & 0x00ff) | ((data & 0x0f) << 12) | ((data & 0xf0) << 4); else m_blit_palettes = (m_blit_palettes & 0xff00) | data; LOG(("P01=%02X ", data)); } WRITE8_MEMBER(dynax_state::tenkai_blit_palette01_w) { m_blit_palettes = (m_blit_palettes & 0xff00) | data; LOG(("P01=%02X ", data)); } /* Layers 4&5 Palettes (Low Bits) */ WRITE8_MEMBER(dynax_state::dynax_blit_palette45_w) { if (m_layer_layout == LAYOUT_HNORIDUR) m_blit2_palettes = (m_blit2_palettes & 0x00ff) | ((data & 0x0f) << 12) | ((data & 0xf0) << 4); else m_blit2_palettes = (m_blit2_palettes & 0xff00) | data; LOG(("P45=%02X ", data)); } /* Layer 2&3 Palettes (Low Bits) */ WRITE8_MEMBER(dynax_state::dynax_blit_palette23_w) { if (m_layer_layout == LAYOUT_HNORIDUR) m_blit_palettes = (m_blit_palettes & 0xff00) | ((data & 0x0f) << 4) | ((data & 0xf0) >> 4); else m_blit_palettes = (m_blit_palettes & 0x00ff) | (data << 8); LOG(("P23=%02X ", data)); } WRITE8_MEMBER(dynax_state::tenkai_blit_palette23_w) { m_blit_palettes = (m_blit_palettes & 0x00ff) | ((data & 0x0f) << 12) | ((data & 0xf0) << 4); LOG(("P23=%02X ", data)); } WRITE8_MEMBER(dynax_state::mjembase_blit_palette23_w) { dynax_blit_palette23_w(space, offset, bitswap<8>(data, 3, 2, 1, 0, 7, 6, 5, 4), mem_mask); } /* Layer 6&7 Palettes (Low Bits) */ WRITE8_MEMBER(dynax_state::dynax_blit_palette67_w) { if (m_layer_layout == LAYOUT_HNORIDUR) m_blit2_palettes = (m_blit2_palettes & 0xff00) | ((data & 0x0f) << 4) | ((data & 0xf0) >> 4); else m_blit2_palettes = (m_blit2_palettes & 0x00ff) | (data << 8); LOG(("P67=%02X ", data)); } /* Layers Palettes (High Bits) */ WRITE_LINE_MEMBER(dynax_state::blit_palbank_w) { m_blit_palbank = state; LOG(("PB=%d ", state)); } WRITE_LINE_MEMBER(dynax_state::blit2_palbank_w) { m_blit2_palbank = state; LOG(("PB'=%d ", state)); } WRITE8_MEMBER(dynax_state::hnoridur_palbank_w) { m_palbank = data & 0x0f; m_blit_palbank = data; // ??? } /* Which half of the layers to write to (interleaved games only) */ WRITE_LINE_MEMBER(dynax_state::layer_half_w) { m_hanamai_layer_half = !state; LOG(("H=%d ", state)); } /* Write to both halves of the layers (interleaved games only) */ WRITE_LINE_MEMBER(dynax_state::layer_half2_w) { m_hnoridur_layer_half2 = !state; LOG(("H2=%d ", state)); } WRITE_LINE_MEMBER(dynax_state::mjdialq2_blit_dest0_w) { m_blit_dest &= ~1; if (!state) m_blit_dest |= 1; } WRITE_LINE_MEMBER(dynax_state::mjdialq2_blit_dest1_w) { m_blit_dest &= ~2; if (!state) m_blit_dest |= 2; } /* Layers Enable */ WRITE8_MEMBER(dynax_state::dynax_layer_enable_w) { m_layer_enable = data; LOG(("E=%02X ", data)); } WRITE8_MEMBER(dynax_state::jantouki_layer_enable_w) { int mask = 1 << (7 - offset); m_layer_enable = (m_layer_enable & ~mask) | ((data & 1) ? mask : 0); m_layer_enable |= 1; } WRITE_LINE_MEMBER(dynax_state::mjdialq2_layer0_enable_w) { m_layer_enable &= ~1; if (!state) m_layer_enable |= 1; } WRITE_LINE_MEMBER(dynax_state::mjdialq2_layer1_enable_w) { m_layer_enable &= ~2; if (!state) m_layer_enable |= 2; } WRITE_LINE_MEMBER(dynax_state::flipscreen_w) { m_flipscreen = state; LOG(("F=%d ", state)); } WRITE8_MEMBER(dynax_state::dynax_blit_romregion_w) { if (data < 8) m_blitter->set_rom_bank(data); LOG(("GFX%X ", data + 1)); } WRITE8_MEMBER(dynax_state::dynax_blit2_romregion_w) { if (data + 1 < 8) m_blitter2->set_rom_bank(data); LOG(("GFX%X' ", data + 2)); } WRITE8_MEMBER(dynax_state::hanamai_blit_pixel_w) { if (m_flipscreen) offset ^= 0xffff; for (int layer = 0; layer < 4; layer++) { if (BIT(m_blit_dest, layer)) { if (BIT(m_hanamai_priority, 4)) m_pixmap[layer][m_hanamai_layer_half ^ m_flipscreen][offset] = data; else m_pixmap[layer][0][offset] = m_pixmap[layer][1][offset] = data; } } } WRITE8_MEMBER(dynax_state::cdracula_blit_pixel_w) { if (m_flipscreen) offset ^= 0xffff; for (int layer = 0; layer < 4; layer++) { if (BIT(m_blit_dest, layer + 4)) m_pixmap[layer][1 ^ m_flipscreen][offset] = data; if (BIT(m_blit_dest, layer)) m_pixmap[layer][0 ^ m_flipscreen][offset] = data; } } WRITE8_MEMBER(dynax_state::hnoridur_blit_pixel_w) { if (m_flipscreen) offset ^= 0xffff; if (BIT(m_blit_dest, 4)) data |= (m_blitter->blit_pen() & 0x08) << 1; for (int layer = 0; layer < 4; layer++) { if (BIT(m_blit_dest, layer)) { m_pixmap[layer][m_hanamai_layer_half ^ m_flipscreen][offset] = data; if (m_hnoridur_layer_half2) m_pixmap[layer][1 ^ m_hanamai_layer_half ^ m_flipscreen][offset] = data; } } } WRITE8_MEMBER(dynax_state::drgpunch_blit_pixel_w) { if (m_flipscreen) offset ^= 0xffff; for (int layer = 2; layer >= 0; layer--) { if (BIT(m_blit_dest, 2 * layer + 1)) m_pixmap[layer][1 ^ m_flipscreen][offset] = data; if (BIT(m_blit_dest, 2 * layer)) m_pixmap[layer][0 ^ m_flipscreen][offset] = data; } } // two blitters/screens WRITE8_MEMBER(dynax_state::jantouki_blit_pixel_w) { if (m_flipscreen) offset ^= 0xffff; for (int layer = 3; layer >= 0; layer--) { if (BIT(m_blit_dest, 2 * layer + 1)) m_pixmap[layer][1 ^ m_flipscreen][offset] = data; if (BIT(m_blit_dest, 2 * layer)) m_pixmap[layer][0 ^ m_flipscreen][offset] = data; } } WRITE8_MEMBER(dynax_state::jantouki_blit2_pixel_w) { if (m_flipscreen) offset ^= 0xffff; for (int layer = 3; layer >= 0; layer--) { if (BIT(m_blit2_dest, 2 * layer + 1)) m_pixmap[layer + 4][1 ^ m_flipscreen][offset] = data; if (BIT(m_blit2_dest, 2 * layer)) m_pixmap[layer + 4][0 ^ m_flipscreen][offset] = data; } } WRITE8_MEMBER(dynax_state::mjdialq2_blit_pixel_w) { if (m_flipscreen) offset ^= 0xffff; for (int layer = 0; layer < 2; layer++) if (BIT(m_blit_dest, layer)) m_pixmap[layer][0][offset] = data; } WRITE8_MEMBER(dynax_state::dynax_blit_scrollx_w) { m_blit_scroll_x = data; } WRITE8_MEMBER(dynax_state::dynax_blit_scrolly_w) { m_blit_scroll_y = data; } WRITE8_MEMBER(dynax_state::dynax_blit2_scrollx_w) { m_blit2_scroll_x = data; } WRITE8_MEMBER(dynax_state::dynax_blit2_scrolly_w) { m_blit2_scroll_y = data; } // inverted scroll values WRITE8_MEMBER(dynax_state::tenkai_blit_scrollx_w) { m_blit_scroll_x = ((data ^ 0xff) + 1) & 0xff; } WRITE8_MEMBER(dynax_state::tenkai_blit_scrolly_w) { m_blit_scroll_y = data ^ 0xff; } /*************************************************************************** Video Init ***************************************************************************/ // 0 1 2 3 4 5 6 7 static const int priority_hnoridur[8] = { 0x0231, 0x2103, 0x3102, 0x2031, 0x3021, 0x1302, 0x2310, 0x1023 }; static const int priority_mcnpshnt[8] = { 0x3210, 0x2103, 0x3102, 0x2031, 0x3021, 0x1302, 0x2310, 0x1023 }; static const int priority_mjelctrn[8] = { 0x0231, 0x0321, 0x2031, 0x2301, 0x3021, 0x3201 ,0x0000, 0x0000 }; // this game doesn't use (hasn't?) layer 1 static const int priority_mjembase[8] = { 0x0231, 0x2031, 0x0321, 0x3021, 0x2301, 0x3201 ,0x0000, 0x0000 }; // this game doesn't use (hasn't?) layer 1 void dynax_state::dynax_common_reset() { m_blit_dest = -1; m_blit2_dest = -1; m_blit_palbank = 0; m_blit2_palbank = 0; m_blit_palettes = 0; m_blit2_palettes = 0; m_layer_enable = -1; m_blit_backpen = 0; m_extra_scroll_x = 0; m_extra_scroll_y = 0; m_hnoridur_layer_half2 = 0; m_blit_scroll_x = 0; m_blit2_scroll_x = 0; m_blit_scroll_y = 0; m_blit2_scroll_y = 0; m_hanamai_layer_half = 0; m_flipscreen = 0; m_hanamai_priority = 0; save_item(NAME(m_blit_dest)); save_item(NAME(m_blit2_dest)); save_item(NAME(m_blit_palbank)); save_item(NAME(m_blit2_palbank)); save_item(NAME(m_blit_palettes)); save_item(NAME(m_blit2_palettes)); save_item(NAME(m_layer_enable)); save_item(NAME(m_blit_backpen)); save_item(NAME(m_extra_scroll_x)); save_item(NAME(m_extra_scroll_y)); save_item(NAME(m_hnoridur_layer_half2)); save_item(NAME(m_blit_scroll_x)); save_item(NAME(m_blit2_scroll_x)); save_item(NAME(m_blit_scroll_y)); save_item(NAME(m_blit2_scroll_y)); save_item(NAME(m_hanamai_layer_half)); save_item(NAME(m_flipscreen)); save_item(NAME(m_hanamai_priority)); } VIDEO_START_MEMBER(dynax_state,hanamai) { m_pixmap[0][0] = std::make_unique(256 * 256); m_pixmap[0][1] = std::make_unique(256 * 256); m_pixmap[1][0] = std::make_unique(256 * 256); m_pixmap[1][1] = std::make_unique(256 * 256); m_pixmap[2][0] = std::make_unique(256 * 256); m_pixmap[2][1] = std::make_unique(256 * 256); m_pixmap[3][0] = std::make_unique(256 * 256); m_pixmap[3][1] = std::make_unique(256 * 256); dynax_common_reset(); m_layer_layout = LAYOUT_HANAMAI; save_pointer(NAME(m_pixmap[0][0]), 256 * 256); save_pointer(NAME(m_pixmap[0][1]), 256 * 256); save_pointer(NAME(m_pixmap[1][0]), 256 * 256); save_pointer(NAME(m_pixmap[1][1]), 256 * 256); save_pointer(NAME(m_pixmap[2][0]), 256 * 256); save_pointer(NAME(m_pixmap[2][1]), 256 * 256); save_pointer(NAME(m_pixmap[3][0]), 256 * 256); save_pointer(NAME(m_pixmap[3][1]), 256 * 256); } VIDEO_START_MEMBER(dynax_state,hnoridur) { m_pixmap[0][0] = std::make_unique(256 * 256); m_pixmap[0][1] = std::make_unique(256 * 256); m_pixmap[1][0] = std::make_unique(256 * 256); m_pixmap[1][1] = std::make_unique(256 * 256); m_pixmap[2][0] = std::make_unique(256 * 256); m_pixmap[2][1] = std::make_unique(256 * 256); m_pixmap[3][0] = std::make_unique(256 * 256); m_pixmap[3][1] = std::make_unique(256 * 256); dynax_common_reset(); m_layer_layout = LAYOUT_HNORIDUR; m_priority_table = priority_hnoridur; save_pointer(NAME(m_pixmap[0][0]), 256 * 256); save_pointer(NAME(m_pixmap[0][1]), 256 * 256); save_pointer(NAME(m_pixmap[1][0]), 256 * 256); save_pointer(NAME(m_pixmap[1][1]), 256 * 256); save_pointer(NAME(m_pixmap[2][0]), 256 * 256); save_pointer(NAME(m_pixmap[2][1]), 256 * 256); save_pointer(NAME(m_pixmap[3][0]), 256 * 256); save_pointer(NAME(m_pixmap[3][1]), 256 * 256); } VIDEO_START_MEMBER(dynax_state,mcnpshnt) { VIDEO_START_CALL_MEMBER(hnoridur); m_priority_table = priority_mcnpshnt; } VIDEO_START_MEMBER(dynax_state,sprtmtch) { m_pixmap[0][0] = std::make_unique(256 * 256); m_pixmap[0][1] = std::make_unique(256 * 256); m_pixmap[1][0] = std::make_unique(256 * 256); m_pixmap[1][1] = std::make_unique(256 * 256); m_pixmap[2][0] = std::make_unique(256 * 256); m_pixmap[2][1] = std::make_unique(256 * 256); dynax_common_reset(); m_layer_layout = LAYOUT_DRGPUNCH; save_pointer(NAME(m_pixmap[0][0]), 256 * 256); save_pointer(NAME(m_pixmap[0][1]), 256 * 256); save_pointer(NAME(m_pixmap[1][0]), 256 * 256); save_pointer(NAME(m_pixmap[1][1]), 256 * 256); save_pointer(NAME(m_pixmap[2][0]), 256 * 256); save_pointer(NAME(m_pixmap[2][1]), 256 * 256); } VIDEO_START_MEMBER(dynax_state,jantouki) { m_pixmap[0][0] = std::make_unique(256 * 256); m_pixmap[0][1] = std::make_unique(256 * 256); m_pixmap[1][0] = std::make_unique(256 * 256); m_pixmap[1][1] = std::make_unique(256 * 256); m_pixmap[2][0] = std::make_unique(256 * 256); m_pixmap[2][1] = std::make_unique(256 * 256); m_pixmap[3][0] = std::make_unique(256 * 256); m_pixmap[3][1] = std::make_unique(256 * 256); m_pixmap[4][0] = std::make_unique(256 * 256); m_pixmap[4][1] = std::make_unique(256 * 256); m_pixmap[5][0] = std::make_unique(256 * 256); m_pixmap[5][1] = std::make_unique(256 * 256); m_pixmap[6][0] = std::make_unique(256 * 256); m_pixmap[6][1] = std::make_unique(256 * 256); m_pixmap[7][0] = std::make_unique(256 * 256); m_pixmap[7][1] = std::make_unique(256 * 256); dynax_common_reset(); m_layer_layout = LAYOUT_JANTOUKI; save_pointer(NAME(m_pixmap[0][0]), 256 * 256); save_pointer(NAME(m_pixmap[0][1]), 256 * 256); save_pointer(NAME(m_pixmap[1][0]), 256 * 256); save_pointer(NAME(m_pixmap[1][1]), 256 * 256); save_pointer(NAME(m_pixmap[2][0]), 256 * 256); save_pointer(NAME(m_pixmap[2][1]), 256 * 256); save_pointer(NAME(m_pixmap[3][0]), 256 * 256); save_pointer(NAME(m_pixmap[3][1]), 256 * 256); save_pointer(NAME(m_pixmap[4][0]), 256 * 256); save_pointer(NAME(m_pixmap[4][1]), 256 * 256); save_pointer(NAME(m_pixmap[5][0]), 256 * 256); save_pointer(NAME(m_pixmap[5][1]), 256 * 256); save_pointer(NAME(m_pixmap[6][0]), 256 * 256); save_pointer(NAME(m_pixmap[6][1]), 256 * 256); save_pointer(NAME(m_pixmap[7][0]), 256 * 256); save_pointer(NAME(m_pixmap[7][1]), 256 * 256); } VIDEO_START_MEMBER(dynax_state,mjdialq2) { m_pixmap[0][0] = std::make_unique(256 * 256); m_pixmap[1][0] = std::make_unique(256 * 256); dynax_common_reset(); m_layer_layout = LAYOUT_MJDIALQ2; save_pointer(NAME(m_pixmap[0][0]), 256 * 256); save_pointer(NAME(m_pixmap[1][0]), 256 * 256); } VIDEO_START_MEMBER(dynax_state,mjelctrn) { VIDEO_START_CALL_MEMBER(hnoridur); m_priority_table = priority_mjelctrn; } VIDEO_START_MEMBER(dynax_state,mjembase) { VIDEO_START_CALL_MEMBER(hnoridur); m_priority_table = priority_mjembase; } VIDEO_START_MEMBER(dynax_state,neruton) { VIDEO_START_CALL_MEMBER(hnoridur); // m_priority_table = priority_mjelctrn; } /*************************************************************************** Screen Drawing ***************************************************************************/ void dynax_state::hanamai_copylayer(bitmap_ind16 &bitmap, const rectangle &cliprect, int i ) { int color; int scrollx, scrolly; switch (i) { case 0: color = (m_blit_palettes >> 0) & 0x0f; break; case 1: color = (m_blit_palettes >> 4) & 0x0f; break; case 2: color = (m_blit_palettes >> 8) & 0x0f; break; case 3: color = (m_blit_palettes >> 12) & 0x0f; break; default: return; } color += (m_blit_palbank & 0x0f) * 16; scrollx = m_blit_scroll_x; scrolly = m_blit_scroll_y; if (i == 1 && (m_layer_layout == LAYOUT_HANAMAI || m_layer_layout == LAYOUT_HNORIDUR)) { scrollx = m_extra_scroll_x; scrolly = m_extra_scroll_y; } { int dy, length, pen; uint8_t *src1 = m_pixmap[i][1].get(); uint8_t *src2 = m_pixmap[i][0].get(); int palbase = 16 * color; for (dy = 0; dy < 256; dy++) { uint16_t *dst; uint16_t *dstbase = &bitmap.pix16((dy - scrolly) & 0xff); length = scrollx; dst = dstbase + 2 * (256 - length); while (length--) { pen = *(src1++); if (pen) *dst = palbase + pen; pen = *(src2++); if (pen) *(dst + 1) = palbase + pen; dst += 2; } length = 256 - scrollx; dst = dstbase; while (length--) { pen = *(src1++); if (pen) *dst = palbase + pen; pen = *(src2++); if (pen) *(dst + 1) = palbase + pen; dst += 2; } } } } void dynax_state::jantouki_copylayer( bitmap_ind16 &bitmap, const rectangle &cliprect, int i, int y ) { int color, scrollx, scrolly, palettes, palbank; if (i < 4) { scrollx = m_blit_scroll_x; scrolly = m_blit_scroll_y; palettes = m_blit_palettes; palbank = m_blit_palbank; } else { scrollx = m_blit2_scroll_x; scrolly = m_blit2_scroll_y; palettes = m_blit2_palettes; palbank = m_blit2_palbank; } switch (i % 4) { case 0: color = ((palettes >> 12) & 0x0f) + ((palbank & 1) << 4); break; case 1: color = ((palettes >> 8) & 0x0f) + ((palbank & 1) << 4); break; case 2: color = ((palettes >> 4) & 0x0f) + ((palbank & 1) << 4); break; case 3: color = ((palettes >> 0) & 0x0f) + ((palbank & 1) << 4); break; default: return; } { int dy, length, pen; uint8_t *src1 = m_pixmap[i][1].get(); uint8_t *src2 = m_pixmap[i][0].get(); int palbase = 16 * color; for (dy = 0; dy < 256; dy++) { int sy = ((dy - scrolly) & 0xff) + y; uint16_t *dst; uint16_t *dstbase = &bitmap.pix16(sy); if ((sy < cliprect.min_y) || (sy > cliprect.max_y)) { src1 += 256; src2 += 256; continue; } length = scrollx; dst = dstbase + 2 * (256 - length); while (length--) { pen = *(src1++); if (pen) *dst = palbase + pen; pen = *(src2++); if (pen) *(dst + 1) = palbase + pen; dst += 2; } length = 256 - scrollx; dst = dstbase; while (length--) { pen = *(src1++); if (pen) *dst = palbase + pen; pen = *(src2++); if (pen) *(dst + 1) = palbase + pen; dst += 2; } } } } void dynax_state::mjdialq2_copylayer( bitmap_ind16 &bitmap, const rectangle &cliprect, int i ) { int color; int scrollx, scrolly; switch (i) { case 0: color = (m_blit_palettes >> 4) & 0x0f; break; case 1: color = (m_blit_palettes >> 0) & 0x0f; break; default: return; } color += (m_blit_palbank & 1) * 16; scrollx = m_blit_scroll_x; scrolly = m_blit_scroll_y; { int dy, length, pen; uint8_t *src = m_pixmap[i][0].get(); int palbase = 16 * color; for (dy = 0; dy < 256; dy++) { uint16_t *dst; uint16_t *dstbase = &bitmap.pix16((dy - scrolly) & 0xff); length = scrollx; dst = dstbase + 256 - length; while (length--) { pen = *(src++); if (pen) *dst = palbase + pen; dst++; } length = 256 - scrollx; dst = dstbase; while (length--) { pen = *(src++); if (pen) *dst = palbase + pen; dst++; } } } } WRITE8_MEMBER(dynax_state::hanamai_priority_w) { m_hanamai_priority = data; } WRITE8_MEMBER(dynax_state::tenkai_priority_w) { m_hanamai_priority = bitswap<8>(data, 3, 2, 1, 0, 4, 7, 5, 6); } /* mjembase: priority: 00 08 10 18 20 28; enable: 1,2,4 Convert to: mjelctrn: priority: 00 20 10 40 30 50; enable: 1,2,8 */ WRITE8_MEMBER(dynax_state::mjembase_priority_w) { m_hanamai_priority = bitswap<8>(data, 6, 5, 4, 3, 2, 7, 1, 0); } int dynax_state::debug_mask() { #ifdef MAME_DEBUG int msk = 0; if (machine().input().code_pressed(KEYCODE_Z)) { if (machine().input().code_pressed(KEYCODE_Q)) msk |= 0x01; // layer 0 if (machine().input().code_pressed(KEYCODE_W)) msk |= 0x02; // layer 1 if (machine().input().code_pressed(KEYCODE_E)) msk |= 0x04; // layer 2 if (machine().input().code_pressed(KEYCODE_R)) msk |= 0x08; // layer 3 if (machine().input().code_pressed(KEYCODE_A)) msk |= 0x10; // layer 4 if (machine().input().code_pressed(KEYCODE_S)) msk |= 0x20; // layer 5 if (machine().input().code_pressed(KEYCODE_D)) msk |= 0x40; // layer 6 if (machine().input().code_pressed(KEYCODE_F)) msk |= 0x80; // layer 7 if (msk != 0) return msk; } #endif return -1; } /* A primitive gfx viewer: T - Toggle viewer I,O - Change palette (-,+) J,K & N,M - Change "tile" (-,+, slow & fast) R - move "tile" to the next 1/8th of the gfx */ int dynax_state::debug_viewer(bitmap_ind16 &bitmap, const rectangle &cliprect ) { #if 0 // needs rewrite static int toggle; if (machine().input().code_pressed_once(KEYCODE_T)) toggle = 1 - toggle; if (m_blitter_gfx.found() && toggle) { uint8_t *RAM = &m_blitter_gfx[0]; size_t size = m_blitter_gfx.bytes(); static int i = 0, c = 0, r = 0; if (machine().input().code_pressed_once(KEYCODE_I)) c = (c - 1) & 0x1f; if (machine().input().code_pressed_once(KEYCODE_O)) c = (c + 1) & 0x1f; if (machine().input().code_pressed_once(KEYCODE_R)) { r = (r + 1) & 0x7; i = size / 8 * r; } if (machine().input().code_pressed(KEYCODE_M) | machine().input().code_pressed_once(KEYCODE_K)) { while (i < size && RAM[i]) i++; while (i < size && !RAM[i]) i++; } if (machine().input().code_pressed(KEYCODE_N) | machine().input().code_pressed_once(KEYCODE_J)) { if (i >= 2) i -= 2; while (i > 0 && RAM[i]) i--; i++; } m_blit_palettes = (c & 0xf) * 0x111; m_blit_palbank = (c >> 4) & 1; bitmap.fill(0, cliprect); memset(m_pixmap[0][0].get(), 0, sizeof(uint8_t) * 0x100 * 0x100); if (m_layer_layout != LAYOUT_MJDIALQ2) memset(m_pixmap[0][1].get(), 0, sizeof(uint8_t) * 0x100 * 0x100); for (m_hanamai_layer_half = 0; m_hanamai_layer_half < 2; m_hanamai_layer_half++) blitter_drawgfx(0, 1, m_blitter_gfx, i, 0, cliprect.min_x, cliprect.min_y, 3, 0); if (m_layer_layout != LAYOUT_MJDIALQ2) hanamai_copylayer(bitmap, cliprect, 0); else mjdialq2_copylayer(bitmap, cliprect, 0); popmessage("%06X C%02X", i, c); return 1; } #endif return 0; } uint32_t dynax_state::screen_update_hanamai(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int layers_ctrl = ~m_layer_enable; int lay[4]; if (debug_viewer(bitmap, cliprect)) return 0; layers_ctrl &= debug_mask(); bitmap.fill((m_blit_backpen & 0xff) + (m_blit_palbank & 1) * 256, cliprect); /* bit 4 = display enable? */ if (!(m_hanamai_priority & 0x10)) return 0; switch (m_hanamai_priority) { default: popmessage("unknown priority %02x", m_hanamai_priority); case 0x10: lay[0] = 0; lay[1] = 1; lay[2] = 2; lay[3] = 3; break; case 0x11: lay[0] = 0; lay[1] = 3; lay[2] = 2; lay[3] = 1; break; case 0x12: lay[0] = 0; lay[1] = 1; lay[2] = 3; lay[3] = 2; break; case 0x13: lay[0] = 0; lay[1] = 3; lay[2] = 1; lay[3] = 2; break; case 0x14: lay[0] = 0; lay[1] = 2; lay[2] = 1; lay[3] = 3; break; case 0x15: lay[0] = 0; lay[1] = 2; lay[2] = 3; lay[3] = 1; break; } if (BIT(layers_ctrl, lay[0])) hanamai_copylayer(bitmap, cliprect, lay[0]); if (BIT(layers_ctrl, lay[1])) hanamai_copylayer(bitmap, cliprect, lay[1]); if (BIT(layers_ctrl, lay[2])) hanamai_copylayer(bitmap, cliprect, lay[2]); if (BIT(layers_ctrl, lay[3])) hanamai_copylayer(bitmap, cliprect, lay[3]); return 0; } uint32_t dynax_state::screen_update_hnoridur(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int layers_ctrl = ~bitswap<8>(m_hanamai_priority, 7, 6, 5, 4, 0, 1, 2, 3); int lay[4]; int pri; if (debug_viewer(bitmap, cliprect)) return 0; layers_ctrl &= debug_mask(); bitmap.fill((m_blit_backpen & 0xff) + (m_blit_palbank & 0x0f) * 256, cliprect); pri = m_hanamai_priority >> 4; if (pri > 7) { popmessage("unknown priority %02x", m_hanamai_priority); pri = 0; } pri = m_priority_table[pri]; lay[0] = (pri >> 12) & 3; lay[1] = (pri >> 8) & 3; lay[2] = (pri >> 4) & 3; lay[3] = (pri >> 0) & 3; if (BIT(layers_ctrl, lay[0])) hanamai_copylayer(bitmap, cliprect, lay[0]); if (BIT(layers_ctrl, lay[1])) hanamai_copylayer(bitmap, cliprect, lay[1]); if (BIT(layers_ctrl, lay[2])) hanamai_copylayer(bitmap, cliprect, lay[2]); if (BIT(layers_ctrl, lay[3])) hanamai_copylayer(bitmap, cliprect, lay[3]); return 0; } uint32_t dynax_state::screen_update_sprtmtch(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int layers_ctrl = ~m_layer_enable; if (debug_viewer(bitmap,cliprect)) return 0; layers_ctrl &= debug_mask(); bitmap.fill((m_blit_backpen & 0xff) + (m_blit_palbank & 1) * 256, cliprect); if (BIT(layers_ctrl, 0)) hanamai_copylayer(bitmap, cliprect, 0); if (BIT(layers_ctrl, 1)) hanamai_copylayer(bitmap, cliprect, 1); if (BIT(layers_ctrl, 2)) hanamai_copylayer(bitmap, cliprect, 2); return 0; } uint32_t dynax_state::screen_update_jantouki_top(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int layers_ctrl = m_layer_enable; if (debug_viewer(bitmap, cliprect)) return 0; layers_ctrl &= debug_mask(); bitmap.fill((m_blit_backpen & 0xff) + (m_blit_palbank & 1) * 256, cliprect); // if (BIT(layers_ctrl, 0)) jantouki_copylayer(bitmap, cliprect, 3, 0); if (BIT(layers_ctrl, 1)) jantouki_copylayer(bitmap, cliprect, 2, 0); if (BIT(layers_ctrl, 2)) jantouki_copylayer(bitmap, cliprect, 1, 0); if (BIT(layers_ctrl, 3)) jantouki_copylayer(bitmap, cliprect, 0, 0); return 0; } uint32_t dynax_state::screen_update_jantouki_bottom(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int layers_ctrl = m_layer_enable; if (debug_viewer(bitmap, cliprect)) return 0; layers_ctrl &= debug_mask(); bitmap.fill((m_blit_backpen & 0xff) + (m_blit_palbank & 1) * 256, cliprect); if (BIT(layers_ctrl, 0)) jantouki_copylayer(bitmap, cliprect, 3, 0); if (BIT(layers_ctrl, 4)) jantouki_copylayer(bitmap, cliprect, 7, 0); if (BIT(layers_ctrl, 5)) jantouki_copylayer(bitmap, cliprect, 6, 0); if (BIT(layers_ctrl, 6)) jantouki_copylayer(bitmap, cliprect, 5, 0); if (BIT(layers_ctrl, 7)) jantouki_copylayer(bitmap, cliprect, 4, 0); return 0; } uint32_t dynax_state::screen_update_mjdialq2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int layers_ctrl = ~m_layer_enable; if (debug_viewer(bitmap, cliprect)) return 0; layers_ctrl &= debug_mask(); bitmap.fill((m_blit_backpen & 0xff) + (m_blit_palbank & 1) * 256, cliprect); if (BIT(layers_ctrl, 0)) mjdialq2_copylayer(bitmap, cliprect, 0); if (BIT(layers_ctrl, 1)) mjdialq2_copylayer(bitmap, cliprect, 1); return 0; } uint32_t dynax_state::screen_update_cdracula(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int layers_ctrl = ~m_layer_enable; if (debug_viewer(bitmap,cliprect)) return 0; layers_ctrl &= debug_mask(); bitmap.fill((m_blit_backpen & 0xff) + (m_blit_palbank & 1) * 256, cliprect); m_extra_scroll_y = -8; if (BIT(layers_ctrl, 3)) hanamai_copylayer(bitmap, cliprect, 3); if (BIT(layers_ctrl, 1)) hanamai_copylayer(bitmap, cliprect, 1); if (BIT(layers_ctrl, 2)) hanamai_copylayer(bitmap, cliprect, 2); if (BIT(layers_ctrl, 0)) hanamai_copylayer(bitmap, cliprect, 0); return 0; }