/*************************************************************************** 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 "driver.h" #include "includes/dynax.h" // Log Blitter #define VERBOSE 0 /* 0 B01234 G01234 R01234 */ PALETTE_INIT( sprtmtch ) { int i; for (i = 0;i < machine->drv->total_colors;i++) { int x = (color_prom[i]<<8) + color_prom[0x200+i]; /* The bits are in reverse order! */ int r = BITSWAP8((x >> 0) & 0x1f, 7,6,5, 0,1,2,3,4 ); int g = BITSWAP8((x >> 5) & 0x1f, 7,6,5, 0,1,2,3,4 ); int b = BITSWAP8((x >> 10) & 0x1f, 7,6,5, 0,1,2,3,4 ); palette_set_color_rgb(machine,i,pal5bit(r),pal5bit(g),pal5bit(b)); } } /*************************************************************************** Video Blitter(s) ***************************************************************************/ static int dynax_blit_scroll_x, dynax_blit2_scroll_x; static int dynax_blit_scroll_y, dynax_blit2_scroll_y; static int dynax_blit_wrap_enable, dynax_blit2_wrap_enable; static int blit_x,blit_y, blit2_x,blit2_y; static int blit_src, blit2_src; static int dynax_blit_romregion, dynax_blit2_romregion; static int dynax_blit_dest, dynax_blit2_dest; static int dynax_blit_pen, dynax_blit2_pen; static int dynax_blit_palbank, dynax_blit2_palbank; static int dynax_blit_palettes, dynax_blit2_palettes; static int dynax_layer_enable; static int dynax_blit_backpen; static int hanamai_layer_half; static int hnoridur_layer_half2; static int extra_scroll_x,extra_scroll_y; static int flipscreen; #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) static int layer_layout; static void (*update_irq_func)(void); // some games trigger IRQ at blitter end, some don't // up to 8 layers, 2 images per layer (interleaved on screen) static UINT8 *dynax_pixmap[8][2]; WRITE8_HANDLER( dynax_extra_scrollx_w ) { extra_scroll_x = data; } WRITE8_HANDLER( dynax_extra_scrolly_w ) { extra_scroll_y = data; } /* Destination Pen */ WRITE8_HANDLER( dynax_blit_pen_w ) { dynax_blit_pen = data; #if VERBOSE logerror("P=%02X ",data); #endif } WRITE8_HANDLER( dynax_blit2_pen_w ) { dynax_blit2_pen = data; #if VERBOSE logerror("P'=%02X ",data); #endif } /* Destination Layers */ WRITE8_HANDLER( dynax_blit_dest_w ) { dynax_blit_dest = data; if (layer_layout == LAYOUT_HNORIDUR) dynax_blit_dest = BITSWAP8(dynax_blit_dest ^ 0x0f, 7,6,5,4, 0,1,2,3); #if VERBOSE logerror("D=%02X ",data); #endif } WRITE8_HANDLER( dynax_blit2_dest_w ) { dynax_blit2_dest = data; #if VERBOSE logerror("D'=%02X ",data); #endif } WRITE8_HANDLER( tenkai_blit_dest_w ) { dynax_blit_dest_w(0, BITSWAP8(data, 7,6,5,4, 0,1,2,3)); } /* Background Color */ WRITE8_HANDLER( dynax_blit_backpen_w ) { dynax_blit_backpen = data; #if VERBOSE logerror("B=%02X ",data); #endif } /* Layers 0&1 Palettes (Low Bits) */ WRITE8_HANDLER( dynax_blit_palette01_w ) { if (layer_layout == LAYOUT_HNORIDUR) dynax_blit_palettes = (dynax_blit_palettes & 0x00ff) | ((data&0x0f)<<12) | ((data&0xf0)<<4); else dynax_blit_palettes = (dynax_blit_palettes & 0xff00) | data; #if VERBOSE logerror("P01=%02X ",data); #endif } WRITE8_HANDLER( tenkai_blit_palette01_w ) { dynax_blit_palettes = (dynax_blit_palettes & 0xff00) | data; #if VERBOSE logerror("P01=%02X ",data); #endif } /* Layers 4&5 Palettes (Low Bits) */ WRITE8_HANDLER( dynax_blit_palette45_w ) { if (layer_layout == LAYOUT_HNORIDUR) dynax_blit2_palettes = (dynax_blit2_palettes & 0x00ff) | ((data&0x0f)<<12) | ((data&0xf0)<<4); else dynax_blit2_palettes = (dynax_blit2_palettes & 0xff00) | data; #if VERBOSE logerror("P45=%02X ",data); #endif } /* Layer 2&3 Palettes (Low Bits) */ WRITE8_HANDLER( dynax_blit_palette23_w ) { if (layer_layout == LAYOUT_HNORIDUR) dynax_blit_palettes = (dynax_blit_palettes & 0xff00) | ((data&0x0f)<<4) | ((data&0xf0)>>4); else dynax_blit_palettes = (dynax_blit_palettes & 0x00ff) | (data<<8); #if VERBOSE logerror("P23=%02X ",data); #endif } WRITE8_HANDLER( tenkai_blit_palette23_w ) { dynax_blit_palettes = (dynax_blit_palettes & 0x00ff) | ((data&0x0f)<<12) | ((data&0xf0)<<4); #if VERBOSE logerror("P23=%02X ",data); #endif } /* Layer 6&7 Palettes (Low Bits) */ WRITE8_HANDLER( dynax_blit_palette67_w ) { if (layer_layout == LAYOUT_HNORIDUR) dynax_blit2_palettes = (dynax_blit2_palettes & 0xff00) | ((data&0x0f)<<4) | ((data&0xf0)>>4); else dynax_blit2_palettes = (dynax_blit2_palettes & 0x00ff) | (data<<8); #if VERBOSE logerror("P67=%02X ",data); #endif } /* Layers Palettes (High Bits) */ WRITE8_HANDLER( dynax_blit_palbank_w ) { dynax_blit_palbank = data; #if VERBOSE logerror("PB=%02X ",data); #endif } WRITE8_HANDLER( dynax_blit2_palbank_w ) { dynax_blit2_palbank = data; #if VERBOSE logerror("PB'=%02X ",data); #endif } /* Which half of the layers to write two (interleaved games only) */ WRITE8_HANDLER( hanamai_layer_half_w ) { hanamai_layer_half = (~data) & 1; #if VERBOSE logerror("H=%02X ",data); #endif } /* Write to both halves of the layers (interleaved games only) */ WRITE8_HANDLER( hnoridur_layer_half2_w ) { hnoridur_layer_half2 = (~data) & 1; #if VERBOSE logerror("H2=%02X ",data); #endif } WRITE8_HANDLER( mjdialq2_blit_dest_w ) { int mask = (2 >> offset); /* 1 or 2 */ dynax_blit_dest &= ~mask; if (~data & 1) dynax_blit_dest |= mask; } /* Layers Enable */ WRITE8_HANDLER( dynax_layer_enable_w ) { dynax_layer_enable = data; #if VERBOSE logerror("E=%02X ",data); #endif } WRITE8_HANDLER( jantouki_layer_enable_w ) { int mask = 1 << (7-offset); dynax_layer_enable = (dynax_layer_enable & ~mask) | ((data & 1) ? mask : 0); dynax_layer_enable |= 1; } WRITE8_HANDLER( mjdialq2_layer_enable_w ) { int mask = (2 >> offset); /* 1 or 2 */ dynax_layer_enable &= ~mask; if (~data & 1) dynax_layer_enable |= mask; } WRITE8_HANDLER( dynax_flipscreen_w ) { flipscreen = data & 1; if (data & ~1) logerror("CPU#0 PC %06X: Warning, flip screen <- %02X\n", activecpu_get_pc(), data); #if VERBOSE logerror("F=%02X ",data); #endif } WRITE8_HANDLER( dynax_blit_romregion_w ) { dynax_blit_romregion = REGION_GFX1 + data; #if VERBOSE logerror("GFX%X ",data+1); #endif } WRITE8_HANDLER( dynax_blit2_romregion_w ) { dynax_blit2_romregion = REGION_GFX2 + data; #if VERBOSE logerror("GFX%X' ",data+2); #endif } /*************************************************************************** Blitter Data Format The blitter reads its commands from the gfx ROMs. They are instructions to draw an image pixel by pixel (in a compressed form) in a frame buffer. Fetch 1 Byte from the ROM: 7654 ---- Pen to draw with ---- 3210 Command Other bytes may follow, depending on the command Commands: 0 Stop. 1-b Draw 1-b pixels along X. c Followed by 1 byte (N): draw N pixels along X. d Followed by 2 bytes (X,N): skip X pixels, draw N pixels along X. e ? unused f Increment Y ***************************************************************************/ /* Plot a pixel (in the pixmaps specified by dynax_blit_dest) */ INLINE void blitter_plot_pixel(int layer,int mask, int x, int y, int pen, int wrap, int flags) { int addr; if ( (y > 0xff) && (!(wrap & 2)) ) return; // fixes mjdialq2 & mjangels title screens if ( (x > 0xff) && (!(wrap & 1)) ) return; x &= 0xff; // confirmed by some mjdialq2 gfx and especially by mjfriday, which // uses the front layer to mask out the right side of the screen as // it draws stuff on the left, when it shows the girls scrolling // horizontally after you win. y &= 0xff; // seems confirmed by mjdialq2 last picture of gal 6, but it breaks // mjdialq2 title screen so there's something we are missing. /* "Flip Screen" just means complement the coordinates to 255 */ if (flipscreen) { x ^= 0xff; y ^= 0xff; } /* Rotate: rotation = SWAPXY + FLIPY */ if (flags & 0x08) { int t = x; x = y; y = t; } addr = x + (y<<8); switch (layer_layout) { case LAYOUT_HANAMAI: if (mask & 0x01) dynax_pixmap[layer+0][hanamai_layer_half^flipscreen][addr] = pen; if (mask & 0x02) dynax_pixmap[layer+1][hanamai_layer_half^flipscreen][addr] = pen; if (mask & 0x04) dynax_pixmap[layer+2][hanamai_layer_half^flipscreen][addr] = pen; if (mask & 0x08) dynax_pixmap[layer+3][hanamai_layer_half^flipscreen][addr] = pen; break; case LAYOUT_HNORIDUR: if (mask & 0x01) dynax_pixmap[layer+0][hanamai_layer_half^flipscreen][addr] = pen; if (mask & 0x02) dynax_pixmap[layer+1][hanamai_layer_half^flipscreen][addr] = pen; if (mask & 0x04) dynax_pixmap[layer+2][hanamai_layer_half^flipscreen][addr] = pen; if (mask & 0x08) dynax_pixmap[layer+3][hanamai_layer_half^flipscreen][addr] = pen; if (!hnoridur_layer_half2) break; if (mask & 0x01) dynax_pixmap[layer+0][1^hanamai_layer_half^flipscreen][addr] = pen; if (mask & 0x02) dynax_pixmap[layer+1][1^hanamai_layer_half^flipscreen][addr] = pen; if (mask & 0x04) dynax_pixmap[layer+2][1^hanamai_layer_half^flipscreen][addr] = pen; if (mask & 0x08) dynax_pixmap[layer+3][1^hanamai_layer_half^flipscreen][addr] = pen; break; case LAYOUT_JANTOUKI: if (mask & 0x80) dynax_pixmap[layer+3][1^flipscreen][addr] = pen; if (mask & 0x40) dynax_pixmap[layer+3][0^flipscreen][addr] = pen; case LAYOUT_DRGPUNCH: if (mask & 0x20) dynax_pixmap[layer+2][1^flipscreen][addr] = pen; if (mask & 0x10) dynax_pixmap[layer+2][0^flipscreen][addr] = pen; if (mask & 0x08) dynax_pixmap[layer+1][1^flipscreen][addr] = pen; if (mask & 0x04) dynax_pixmap[layer+1][0^flipscreen][addr] = pen; if (mask & 0x02) dynax_pixmap[layer+0][1^flipscreen][addr] = pen; if (mask & 0x01) dynax_pixmap[layer+0][0^flipscreen][addr] = pen; break; case LAYOUT_MJDIALQ2: if (mask & 0x01) dynax_pixmap[layer+0][0][addr] = pen; if (mask & 0x02) dynax_pixmap[layer+1][0][addr] = pen; break; } } static int blitter_drawgfx( int layer, int mask, int gfx, int src, int pen, int x, int y, int wrap, int flags ) { UINT8 cmd; UINT8 *ROM = memory_region( gfx ); size_t ROM_size = memory_region_length( gfx ); int sx; if (layer_layout == LAYOUT_HNORIDUR) // e.g. yarunara pen = ((pen >> 4) & 0xf) | ( (mask & 0x10) ? ((pen & 0x08) << 1) : 0 ); else pen = (pen >> 4) & 0xf; if (flags & 0xf4) popmessage("flags %02x",flags); if ( flags & 1 ) { int start,len; /* Clear the buffer(s) starting from the given scanline and exit */ int addr = x + (y<<8); if (flipscreen) start = 0; else start = addr; len = 0x10000 - addr; switch (layer_layout) { case LAYOUT_HANAMAI: if (mask & 0x01) memset(&dynax_pixmap[layer+0][0][start],pen,len); if (mask & 0x01) memset(&dynax_pixmap[layer+0][1][start],pen,len); if (mask & 0x02) memset(&dynax_pixmap[layer+1][0][start],pen,len); if (mask & 0x02) memset(&dynax_pixmap[layer+1][1][start],pen,len); if (mask & 0x04) memset(&dynax_pixmap[layer+2][0][start],pen,len); if (mask & 0x04) memset(&dynax_pixmap[layer+2][1][start],pen,len); if (mask & 0x08) memset(&dynax_pixmap[layer+3][0][start],pen,len); if (mask & 0x08) memset(&dynax_pixmap[layer+3][1][start],pen,len); break; case LAYOUT_HNORIDUR: if (mask & 0x01) memset(&dynax_pixmap[layer+0][hanamai_layer_half][start],pen,len); if (mask & 0x02) memset(&dynax_pixmap[layer+1][hanamai_layer_half][start],pen,len); if (mask & 0x04) memset(&dynax_pixmap[layer+2][hanamai_layer_half][start],pen,len); if (mask & 0x08) memset(&dynax_pixmap[layer+3][hanamai_layer_half][start],pen,len); if (!hnoridur_layer_half2) break; if (mask & 0x01) memset(&dynax_pixmap[layer+0][1-hanamai_layer_half][start],pen,len); if (mask & 0x02) memset(&dynax_pixmap[layer+1][1-hanamai_layer_half][start],pen,len); if (mask & 0x04) memset(&dynax_pixmap[layer+2][1-hanamai_layer_half][start],pen,len); if (mask & 0x08) memset(&dynax_pixmap[layer+3][1-hanamai_layer_half][start],pen,len); break; case LAYOUT_JANTOUKI: if (mask & 0x80) memset(&dynax_pixmap[layer+3][1][start],pen,len); if (mask & 0x40) memset(&dynax_pixmap[layer+3][0][start],pen,len); case LAYOUT_DRGPUNCH: if (mask & 0x20) memset(&dynax_pixmap[layer+2][1][start],pen,len); if (mask & 0x10) memset(&dynax_pixmap[layer+2][0][start],pen,len); if (mask & 0x08) memset(&dynax_pixmap[layer+1][1][start],pen,len); if (mask & 0x04) memset(&dynax_pixmap[layer+1][0][start],pen,len); if (mask & 0x02) memset(&dynax_pixmap[layer+0][1][start],pen,len); if (mask & 0x01) memset(&dynax_pixmap[layer+0][0][start],pen,len); break; case LAYOUT_MJDIALQ2: if (mask & 0x01) memset(&dynax_pixmap[layer+0][0][start],pen,len); if (mask & 0x02) memset(&dynax_pixmap[layer+1][0][start],pen,len); break; } return src; } sx = x; src &= 0xfffff; for ( ;; ) { if (src >= ROM_size) { popmessage("GFXROM OVER %08x",src); return src; } cmd = ROM[src++]; src &= 0xfffff; if (!(flags & 0x02)) // Ignore the pens specified in ROM, draw everything with the pen supplied as parameter pen = (pen & 0xf0) | ((cmd & 0xf0)>>4); cmd = (cmd & 0x0f); switch (cmd) { case 0xf: // Increment Y /* Rotate: rotation = SWAPXY + FLIPY */ if (flags & 0x08) y--; else y++; x = sx; break; case 0xe: // unused ? was "change dest mask" in the "rev1" blitter popmessage("Blitter unknown command %06X: %02X\n", src-1, cmd); case 0xd: // Skip X pixels if (src >= ROM_size) { popmessage("GFXROM OVER %08x",src); return src; } x = sx + ROM[src++]; src &= 0xfffff; /* fall through into next case */ case 0xc: // Draw N pixels if (src >= ROM_size) { popmessage("GFXROM OVER %08x",src); return src; } cmd = ROM[src++]; src &= 0xfffff; /* fall through into next case */ case 0xb: case 0xa: case 0x9: case 0x8: case 0x7: case 0x6: case 0x5: case 0x4: case 0x3: case 0x2: case 0x1: // Draw N pixels while (cmd--) blitter_plot_pixel(layer, mask, x++, y, pen, wrap, flags); break; case 0x0: // Stop return src; } } } static void dynax_blitter_start(int flags) { int blit_newsrc; #if VERBOSE logerror("XY=%X,%X SRC=%X BLIT=%X\n",blit_x,blit_y,blit_src,flags); #endif blit_newsrc = blitter_drawgfx( 0, // layer dynax_blit_dest, // layer mask dynax_blit_romregion, // rom region blit_src, // rom address dynax_blit_pen, // pen blit_x, blit_y, // x,y dynax_blit_wrap_enable, // wrap around flags // flags ); blit_src = (blit_src & ~0x0fffff) | (blit_newsrc & 0x0fffff) ; /* Generate an IRQ */ if (update_irq_func) { dynax_blitter_irq = 1; update_irq_func(); } } static void jantouki_blitter_start(int flags) { int blit_newsrc; #if VERBOSE logerror("XY=%X,%X SRC=%X BLIT=%X\n",blit_x,blit_y,blit_src,flags); #endif blit_newsrc = blitter_drawgfx( 0, // layer dynax_blit_dest, // layer mask dynax_blit_romregion, // rom region blit_src, // rom address dynax_blit_pen, // pen blit_x, blit_y, // x,y dynax_blit_wrap_enable, // wrap around flags // flags ); blit_src = (blit_src & ~0x0fffff) | (blit_newsrc & 0x0fffff) ; /* Generate an IRQ */ if (update_irq_func) { dynax_blitter_irq = 1; update_irq_func(); } } static void jantouki_blitter2_start(int flags) { int blit2_newsrc; #if VERBOSE logerror("XY'=%X,%X SRC'=%X BLIT'=%02X\n",blit2_x,blit2_y,blit2_src,flags); #endif blit2_newsrc = blitter_drawgfx( 4, // layer dynax_blit2_dest, // layer mask dynax_blit2_romregion, // rom region blit2_src, // rom address dynax_blit2_pen, // pen blit2_x, blit2_y, // x,y dynax_blit2_wrap_enable, // wrap around flags // flags ); blit2_src = (blit2_src & ~0x0fffff) | (blit2_newsrc & 0x0fffff) ; /* Generate an IRQ */ if (update_irq_func) { dynax_blitter2_irq = 1; update_irq_func(); } } static WRITE8_HANDLER( dynax_blit_scroll_w ) { switch( blit_src & 0xc00000 ) { case 0x000000: dynax_blit_scroll_x = data; #if VERBOSE logerror("SX=%02X ",data); #endif break; case 0x400000: dynax_blit_scroll_y = data; #if VERBOSE logerror("SY=%02X ",data); #endif break; case 0x800000: case 0xc00000: dynax_blit_wrap_enable = data; #if VERBOSE logerror("WE=%02X ",data); #endif break; } } // inverted scroll values static WRITE8_HANDLER( tenkai_blit_scroll_w ) { switch( blit_src & 0xc00000 ) { case 0x000000: dynax_blit_scroll_x = ((data ^ 0xff) + 1) & 0xff; #if VERBOSE logerror("SX=%02X ",data); #endif break; case 0x400000: dynax_blit_scroll_y = data ^ 0xff; #if VERBOSE logerror("SY=%02X ",data); #endif break; case 0x800000: case 0xc00000: dynax_blit_wrap_enable = data; #if VERBOSE logerror("WE=%02X ",data); #endif break; } } static WRITE8_HANDLER( dynax_blit2_scroll_w ) { switch( blit2_src & 0xc00000 ) { case 0x000000: dynax_blit2_scroll_x = data; #if VERBOSE logerror("SX'=%02X ",data); #endif break; case 0x400000: dynax_blit2_scroll_y = data; #if VERBOSE logerror("SY'=%02X ",data); #endif break; case 0x800000: case 0xc00000: dynax_blit2_wrap_enable = data; #if VERBOSE logerror("WE'=%02X ",data); #endif break; } } WRITE8_HANDLER( dynax_blitter_rev2_w ) { switch (offset) { case 0: dynax_blitter_start(data); break; case 1: blit_x = data; break; case 2: blit_y = data; break; case 3: blit_src = (blit_src & 0xffff00) | (data << 0); break; case 4: blit_src = (blit_src & 0xff00ff) | (data << 8); break; case 5: blit_src = (blit_src & 0x00ffff) | (data <<16); break; case 6: dynax_blit_scroll_w(0,data); break; } } // different scroll_w WRITE8_HANDLER( tenkai_blitter_rev2_w ) { switch (offset) { case 0: dynax_blitter_start(data); break; case 1: blit_x = data; break; case 2: blit_y = data; break; case 3: blit_src = (blit_src & 0xffff00) | (data << 0); break; case 4: blit_src = (blit_src & 0xff00ff) | (data << 8); break; case 5: blit_src = (blit_src & 0x00ffff) | (data <<16); break; case 6: tenkai_blit_scroll_w(0,data); break; } } WRITE8_HANDLER( jantouki_blitter_rev2_w ) { switch (offset) { case 0: jantouki_blitter_start(data); break; case 1: blit_x = data; break; case 2: blit_y = data; break; case 3: blit_src = (blit_src & 0xffff00) | (data << 0); break; case 4: blit_src = (blit_src & 0xff00ff) | (data << 8); break; case 5: blit_src = (blit_src & 0x00ffff) | (data <<16); break; case 6: dynax_blit_scroll_w(0,data); break; } } WRITE8_HANDLER( jantouki_blitter2_rev2_w ) { switch (offset) { case 0: jantouki_blitter2_start(data); break; case 1: blit2_x = data; break; case 2: blit2_y = data; break; case 3: blit2_src = (blit2_src & 0xffff00) | (data << 0); break; case 4: blit2_src = (blit2_src & 0xff00ff) | (data << 8); break; case 5: blit2_src = (blit2_src & 0x00ffff) | (data <<16); break; case 6: dynax_blit2_scroll_w(0,data); break; } } /*************************************************************************** Video Init ***************************************************************************/ static const int *priority_table; // 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 void Video_Reset(void) { dynax_blit_romregion = REGION_GFX1; dynax_blit2_romregion = REGION_GFX1; dynax_blit_dest = -1; dynax_blit2_dest = -1; dynax_blit_pen = 0x7; dynax_blit2_pen = 0x7; dynax_blit_palbank = 0; dynax_blit2_palbank = 0; dynax_blit_palettes = 0; dynax_blit2_palettes = 0; dynax_layer_enable = -1; dynax_blit_backpen = 0; extra_scroll_x = 0; extra_scroll_y = 0; hnoridur_layer_half2 = 0; update_irq_func = sprtmtch_update_irq; } VIDEO_START( hanamai ) { dynax_pixmap[0][0] = auto_malloc(256*256); dynax_pixmap[0][1] = auto_malloc(256*256); dynax_pixmap[1][0] = auto_malloc(256*256); dynax_pixmap[1][1] = auto_malloc(256*256); dynax_pixmap[2][0] = auto_malloc(256*256); dynax_pixmap[2][1] = auto_malloc(256*256); dynax_pixmap[3][0] = auto_malloc(256*256); dynax_pixmap[3][1] = auto_malloc(256*256); Video_Reset(); layer_layout = LAYOUT_HANAMAI; } VIDEO_START( hnoridur ) { dynax_pixmap[0][0] = auto_malloc(256*256); dynax_pixmap[0][1] = auto_malloc(256*256); dynax_pixmap[1][0] = auto_malloc(256*256); dynax_pixmap[1][1] = auto_malloc(256*256); dynax_pixmap[2][0] = auto_malloc(256*256); dynax_pixmap[2][1] = auto_malloc(256*256); dynax_pixmap[3][0] = auto_malloc(256*256); dynax_pixmap[3][1] = auto_malloc(256*256); Video_Reset(); layer_layout = LAYOUT_HNORIDUR; priority_table = priority_hnoridur; } VIDEO_START( mcnpshnt ) { video_start_hnoridur(machine); priority_table = priority_mcnpshnt; } VIDEO_START( sprtmtch ) { dynax_pixmap[0][0] = auto_malloc(256*256); dynax_pixmap[0][1] = auto_malloc(256*256); dynax_pixmap[1][0] = auto_malloc(256*256); dynax_pixmap[1][1] = auto_malloc(256*256); dynax_pixmap[2][0] = auto_malloc(256*256); dynax_pixmap[2][1] = auto_malloc(256*256); Video_Reset(); layer_layout = LAYOUT_DRGPUNCH; } VIDEO_START( jantouki ) { dynax_pixmap[0][0] = auto_malloc(256*256); dynax_pixmap[0][1] = auto_malloc(256*256); dynax_pixmap[1][0] = auto_malloc(256*256); dynax_pixmap[1][1] = auto_malloc(256*256); dynax_pixmap[2][0] = auto_malloc(256*256); dynax_pixmap[2][1] = auto_malloc(256*256); dynax_pixmap[3][0] = auto_malloc(256*256); dynax_pixmap[3][1] = auto_malloc(256*256); dynax_pixmap[4][0] = auto_malloc(256*256); dynax_pixmap[4][1] = auto_malloc(256*256); dynax_pixmap[5][0] = auto_malloc(256*256); dynax_pixmap[5][1] = auto_malloc(256*256); dynax_pixmap[6][0] = auto_malloc(256*256); dynax_pixmap[6][1] = auto_malloc(256*256); dynax_pixmap[7][0] = auto_malloc(256*256); dynax_pixmap[7][1] = auto_malloc(256*256); Video_Reset(); layer_layout = LAYOUT_JANTOUKI; update_irq_func = jantouki_update_irq; } VIDEO_START( mjdialq2 ) { dynax_pixmap[0][0] = auto_malloc(256*256); dynax_pixmap[1][0] = auto_malloc(256*256); Video_Reset(); layer_layout = LAYOUT_MJDIALQ2; update_irq_func = 0; } VIDEO_START( mjelctrn ) { video_start_hnoridur(machine); priority_table = priority_mjelctrn; update_irq_func = mjelctrn_update_irq; } VIDEO_START( neruton ) { video_start_hnoridur(machine); // priority_table = priority_mjelctrn; update_irq_func = neruton_update_irq; } /*************************************************************************** Screen Drawing ***************************************************************************/ static void hanamai_copylayer(mame_bitmap *bitmap,const rectangle *cliprect,int i) { int color; int scrollx,scrolly; switch ( i ) { case 0: color = (dynax_blit_palettes >> 0) & 0xf; break; case 1: color = (dynax_blit_palettes >> 4) & 0xf; break; case 2: color = (dynax_blit_palettes >> 8) & 0xf; break; case 3: color = (dynax_blit_palettes >> 12) & 0xf; break; default: return; } color += (dynax_blit_palbank & 0x0f) * 16; scrollx = dynax_blit_scroll_x; scrolly = dynax_blit_scroll_y; if ( (layer_layout == LAYOUT_HANAMAI && i == 1) || (layer_layout == LAYOUT_HNORIDUR && i == 1) ) { scrollx = extra_scroll_x; scrolly = extra_scroll_y; } { int dy,length,pen,offs; UINT8 *src1 = dynax_pixmap[i][1]; UINT8 *src2 = dynax_pixmap[i][0]; int palbase = 16*color; offs = 0; for (dy = 0; dy < 256; dy++) { UINT16 *dst; UINT16 *dstbase = BITMAP_ADDR16(bitmap, (dy - scrolly) & 0xff, 0); 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; } } } } static void jantouki_copylayer(mame_bitmap *bitmap,const rectangle *cliprect,int i, int y) { int color,scrollx,scrolly,palettes,palbank; if (i < 4) { scrollx = dynax_blit_scroll_x; scrolly = dynax_blit_scroll_y; palettes = dynax_blit_palettes; palbank = dynax_blit_palbank; } else { scrollx = dynax_blit2_scroll_x; scrolly = dynax_blit2_scroll_y; palettes = dynax_blit2_palettes; palbank = dynax_blit2_palbank; } switch ( i % 4 ) { case 0: color = ((palettes >> 12) & 0xf) + ((palbank & 1) << 4); break; case 1: color = ((palettes >> 8) & 0xf) + ((palbank & 1) << 4); break; case 2: color = ((palettes >> 4) & 0xf) + ((palbank & 1) << 4); break; case 3: color = ((palettes >> 0) & 0xf) + ((palbank & 1) << 4); break; default: return; } { int dy,length,pen,offs; UINT8 *src1 = dynax_pixmap[i][1]; UINT8 *src2 = dynax_pixmap[i][0]; int palbase = 16*color; offs = 0; for (dy = 0; dy < 256; dy++) { int sy = ((dy - scrolly) & 0xff) + y; UINT16 *dst; UINT16 *dstbase = BITMAP_ADDR16(bitmap, sy, 0); 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; } } } } static void mjdialq2_copylayer(mame_bitmap *bitmap,const rectangle *cliprect,int i) { int color; int scrollx,scrolly; switch ( i ) { case 0: color = (dynax_blit_palettes >> 4) & 0xf; break; case 1: color = (dynax_blit_palettes >> 0) & 0xf; break; default: return; } color += (dynax_blit_palbank & 1) * 16; scrollx = dynax_blit_scroll_x; scrolly = dynax_blit_scroll_y; { int dy,length,pen,offs; UINT8 *src = dynax_pixmap[i][0]; int palbase = 16*color; offs = 0; for (dy = 0; dy < 256; dy++) { UINT16 *dst; UINT16 *dstbase = BITMAP_ADDR16(bitmap, (dy - scrolly) & 0xff, 0); 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++; } } } } static int hanamai_priority; WRITE8_HANDLER( hanamai_priority_w ) { hanamai_priority = data; } WRITE8_HANDLER( tenkai_priority_w ) { hanamai_priority = BITSWAP8(data, 3,2,1,0, 4,7,5,6); } static int debug_mask(void) { #ifdef MAME_DEBUG int msk = 0; if (input_code_pressed(KEYCODE_Z)) { if (input_code_pressed(KEYCODE_Q)) msk |= 0x01; // layer 0 if (input_code_pressed(KEYCODE_W)) msk |= 0x02; // layer 1 if (input_code_pressed(KEYCODE_E)) msk |= 0x04; // layer 2 if (input_code_pressed(KEYCODE_R)) msk |= 0x08; // layer 3 if (input_code_pressed(KEYCODE_A)) msk |= 0x10; // layer 4 if (input_code_pressed(KEYCODE_S)) msk |= 0x20; // layer 5 if (input_code_pressed(KEYCODE_D)) msk |= 0x40; // layer 6 if (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 */ static int debug_viewer(running_machine *machine, mame_bitmap *bitmap,const rectangle *cliprect) { #ifdef MAME_DEBUG static int toggle; if (input_code_pressed_once(KEYCODE_T)) toggle = 1-toggle; if (toggle) { UINT8 *RAM = memory_region( REGION_GFX1 ); size_t size = memory_region_length( REGION_GFX1 ); static int i = 0, c = 0, r = 0; if (input_code_pressed_once(KEYCODE_I)) c = (c-1) & 0x1f; if (input_code_pressed_once(KEYCODE_O)) c = (c+1) & 0x1f; if (input_code_pressed_once(KEYCODE_R)) { r = (r+1) & 0x7; i = size/8 * r; } if (input_code_pressed(KEYCODE_M) | input_code_pressed_once(KEYCODE_K)) { while( i < size && RAM[i] ) i++; while( i < size && !RAM[i] ) i++; } if (input_code_pressed(KEYCODE_N) | input_code_pressed_once(KEYCODE_J)) { if (i >= 2) i-=2; while( i > 0 && RAM[i] ) i--; i++; } dynax_blit_palettes = (c & 0xf) * 0x111; dynax_blit_palbank = (c >> 4) & 1; fillbitmap(bitmap,machine->pens[0],cliprect); memset(dynax_pixmap[0][0],0,sizeof(UINT8)*0x100*0x100); if (layer_layout != LAYOUT_MJDIALQ2) memset(dynax_pixmap[0][1],0,sizeof(UINT8)*0x100*0x100); for (hanamai_layer_half = 0; hanamai_layer_half < 2; hanamai_layer_half++) blitter_drawgfx(0,1,REGION_GFX1,i,0,cliprect->min_x,cliprect->min_y,3,0); if (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; } VIDEO_UPDATE( hanamai ) { int layers_ctrl = ~dynax_layer_enable; int lay[4]; if (debug_viewer(machine,bitmap,cliprect)) return 0; layers_ctrl &= debug_mask(); fillbitmap( bitmap, machine->pens[(dynax_blit_backpen & 0xff) + (dynax_blit_palbank & 1) * 256], cliprect); /* bit 4 = display enable? */ if (!(hanamai_priority & 0x10)) return 0; switch (hanamai_priority) { default: popmessage("unknown priority %02x",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 (layers_ctrl & (1 << lay[0])) hanamai_copylayer( bitmap, cliprect, lay[0] ); if (layers_ctrl & (1 << lay[1])) hanamai_copylayer( bitmap, cliprect, lay[1] ); if (layers_ctrl & (1 << lay[2])) hanamai_copylayer( bitmap, cliprect, lay[2] ); if (layers_ctrl & (1 << lay[3])) hanamai_copylayer( bitmap, cliprect, lay[3] ); return 0; } VIDEO_UPDATE( hnoridur ) { int layers_ctrl = ~BITSWAP8(hanamai_priority, 7,6,5,4, 0,1,2,3); int lay[4]; int pri; if (debug_viewer(machine,bitmap,cliprect)) return 0; layers_ctrl &= debug_mask(); fillbitmap( bitmap, machine->pens[(dynax_blit_backpen & 0xff) + (dynax_blit_palbank & 0x0f) * 256], cliprect); pri = hanamai_priority >> 4; if (pri > 7) { popmessage("unknown priority %02x",hanamai_priority); pri = 0; } pri = priority_table[pri]; lay[0] = (pri >> 12) & 3; lay[1] = (pri >> 8) & 3; lay[2] = (pri >> 4) & 3; lay[3] = (pri >> 0) & 3; if (layers_ctrl & (1 << lay[0])) hanamai_copylayer( bitmap, cliprect, lay[0] ); if (layers_ctrl & (1 << lay[1])) hanamai_copylayer( bitmap, cliprect, lay[1] ); if (layers_ctrl & (1 << lay[2])) hanamai_copylayer( bitmap, cliprect, lay[2] ); if (layers_ctrl & (1 << lay[3])) hanamai_copylayer( bitmap, cliprect, lay[3] ); return 0; } VIDEO_UPDATE( sprtmtch ) { int layers_ctrl = ~dynax_layer_enable; if (debug_viewer(machine,bitmap,cliprect)) return 0; layers_ctrl &= debug_mask(); fillbitmap( bitmap, machine->pens[(dynax_blit_backpen & 0xff) + (dynax_blit_palbank & 1) * 256], cliprect); if (layers_ctrl & 1) hanamai_copylayer( bitmap, cliprect, 0 ); if (layers_ctrl & 2) hanamai_copylayer( bitmap, cliprect, 1 ); if (layers_ctrl & 4) hanamai_copylayer( bitmap, cliprect, 2 ); return 0; } VIDEO_UPDATE( jantouki ) { int layers_ctrl = dynax_layer_enable; if (debug_viewer(machine,bitmap,cliprect)) return 0; layers_ctrl &= debug_mask(); fillbitmap( bitmap, machine->pens[(dynax_blit_backpen & 0xff) + (dynax_blit_palbank & 1) * 256], cliprect); if (screen==0) { // if (layers_ctrl & 0x01) jantouki_copylayer( bitmap, cliprect, 3, 0 ); if (layers_ctrl & 0x02) jantouki_copylayer( bitmap, cliprect, 2, 0 ); if (layers_ctrl & 0x04) jantouki_copylayer( bitmap, cliprect, 1, 0 ); if (layers_ctrl & 0x08) jantouki_copylayer( bitmap, cliprect, 0, 0 ); } else if (screen==1) { if (layers_ctrl & 0x01) jantouki_copylayer( bitmap, cliprect, 3, 0 ); if (layers_ctrl & 0x10) jantouki_copylayer( bitmap, cliprect, 7, 0 ); if (layers_ctrl & 0x20) jantouki_copylayer( bitmap, cliprect, 6, 0 ); if (layers_ctrl & 0x40) jantouki_copylayer( bitmap, cliprect, 5, 0 ); if (layers_ctrl & 0x80) jantouki_copylayer( bitmap, cliprect, 4, 0 ); } return 0; } VIDEO_UPDATE( mjdialq2 ) { int layers_ctrl = ~dynax_layer_enable; if (debug_viewer(machine,bitmap,cliprect)) return 0; layers_ctrl &= debug_mask(); fillbitmap( bitmap, machine->pens[(dynax_blit_backpen & 0xff) + (dynax_blit_palbank & 1) * 256], cliprect); if (layers_ctrl & 1) mjdialq2_copylayer( bitmap, cliprect, 0 ); if (layers_ctrl & 2) mjdialq2_copylayer( bitmap, cliprect, 1 ); return 0; } // htengoku uses the mixer chip from ddenlovr static mame_bitmap *framebuffer; VIDEO_START(htengoku) { video_start_ddenlovr(machine); video_start_hnoridur(machine); framebuffer = auto_bitmap_alloc(machine->screen[0].width,machine->screen[0].height,machine->screen[0].format); } VIDEO_EOF(htengoku) { int layer,x,y; // render the layers, one by one, "dynax.c" style. Then convert the pixmaps to "ddenlovr.c" // format and let video_eof_ddenlovr do the final compositing (priorities + palettes) for (layer = 0; layer < 4; layer++) { fillbitmap(framebuffer,0,&machine->screen[0].visarea); hanamai_copylayer( framebuffer, &machine->screen[0].visarea, layer ); for (y=0; y < 256; y++) for (x=0; x < 512; x++) ddenlovr_pixmap[3-layer][y*512+x] = (UINT8)(*BITMAP_ADDR16(framebuffer, y,x)); } video_eof_ddenlovr(machine); }