summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/ddragon3.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/ddragon3.c')
-rw-r--r--src/mame/video/ddragon3.c224
1 files changed, 224 insertions, 0 deletions
diff --git a/src/mame/video/ddragon3.c b/src/mame/video/ddragon3.c
new file mode 100644
index 00000000000..7867797c2eb
--- /dev/null
+++ b/src/mame/video/ddragon3.c
@@ -0,0 +1,224 @@
+/***************************************************************************
+
+ Video Hardware for Double Dragon 3
+
+***************************************************************************/
+
+#include "driver.h"
+
+UINT16 *ddragon3_bg_videoram16;
+UINT16 *ddragon3_fg_videoram16;
+UINT16 ddragon3_vreg;
+
+static UINT16 ddragon3_bg_scrollx;
+static UINT16 ddragon3_bg_scrolly;
+static UINT16 ddragon3_fg_scrollx;
+static UINT16 ddragon3_fg_scrolly;
+static UINT16 ddragon3_bg_tilebase;
+
+static tilemap *bg_tilemap, *fg_tilemap;
+
+
+WRITE16_HANDLER( ddragon3_scroll16_w )
+{
+ switch (offset)
+ {
+ case 0: COMBINE_DATA(&ddragon3_fg_scrollx); break; // Scroll X, BG1
+ case 1: COMBINE_DATA(&ddragon3_fg_scrolly); break; // Scroll Y, BG1
+ case 2: COMBINE_DATA(&ddragon3_bg_scrollx); break; // Scroll X, BG0
+ case 3: COMBINE_DATA(&ddragon3_bg_scrolly); break; // Scroll Y, BG0
+ case 4: break; // Unknown write
+ case 5: flip_screen_set(data & 0x01); break; // Flip Screen
+ case 6:
+ COMBINE_DATA(&ddragon3_bg_tilebase); // BG Tile Base
+ ddragon3_bg_tilebase &= 0x1ff;
+ tilemap_mark_all_tiles_dirty(bg_tilemap);
+ break;
+ }
+}
+
+READ16_HANDLER( ddragon3_scroll16_r )
+{
+ switch (offset)
+ {
+ case 0: return ddragon3_fg_scrollx;
+ case 1: return ddragon3_fg_scrolly;
+ case 2: return ddragon3_bg_scrollx;
+ case 3: return ddragon3_bg_scrolly;
+ case 5: return flip_screen;
+ case 6: return ddragon3_bg_tilebase;
+ }
+
+ return 0;
+}
+
+WRITE16_HANDLER( ddragon3_bg_videoram16_w )
+{
+ COMBINE_DATA(&ddragon3_bg_videoram16[offset]);
+ tilemap_mark_tile_dirty(bg_tilemap, offset);
+}
+
+WRITE16_HANDLER( ddragon3_fg_videoram16_w )
+{
+ COMBINE_DATA(&ddragon3_fg_videoram16[offset]);
+ tilemap_mark_tile_dirty(fg_tilemap, offset / 2);
+}
+
+static TILE_GET_INFO( get_bg_tile_info )
+{
+ UINT16 attr = ddragon3_bg_videoram16[tile_index];
+ int code = (attr & 0x0fff) | ((ddragon3_bg_tilebase & 0x01) << 12);
+ int color = ((attr & 0xf000) >> 12) + 16;
+
+ SET_TILE_INFO(0, code, color, 0);
+}
+
+static TILE_GET_INFO( get_fg_tile_info )
+{
+ int offs = tile_index * 2;
+ UINT16 attr = ddragon3_fg_videoram16[offs];
+ int code = ddragon3_fg_videoram16[offs + 1] & 0x1fff;
+ int color = attr & 0xf;
+ int flags = (attr & 0x40) ? TILE_FLIPX : 0;
+
+ SET_TILE_INFO(0, code, color, flags);
+}
+
+VIDEO_START( ddragon3 )
+{
+ state_save_register_global(ddragon3_vreg);
+ state_save_register_global(ddragon3_bg_scrollx);
+ state_save_register_global(ddragon3_bg_scrolly);
+ state_save_register_global(ddragon3_fg_scrollx);
+ state_save_register_global(ddragon3_fg_scrolly);
+ state_save_register_global(ddragon3_bg_tilebase);
+
+ bg_tilemap = tilemap_create(get_bg_tile_info, tilemap_scan_rows,
+ TILEMAP_TYPE_PEN, 16, 16, 32, 32);
+
+ fg_tilemap = tilemap_create(get_fg_tile_info, tilemap_scan_rows,
+ TILEMAP_TYPE_PEN, 16, 16, 32, 32);
+
+ tilemap_set_transparent_pen(bg_tilemap, 0);
+ tilemap_set_transparent_pen(fg_tilemap, 0);
+}
+
+/*
+ * Sprite Format
+ * ----------------------------------
+ *
+ * Word | Bit(s) | Use
+ * -----+-fedcba9876543210-+----------------
+ * 0 | --------xxxxxxxx | ypos (signed)
+ * -----+------------------+
+ * 1 | --------xxx----- | height
+ * 1 | -----------xx--- | yflip, xflip
+ * 1 | -------------x-- | msb x
+ * 1 | --------------x- | msb y?
+ * 1 | ---------------x | enable
+ * -----+------------------+
+ * 2 | --------xxxxxxxx | tile number
+ * -----+------------------+
+ * 3 | --------xxxxxxxx | bank
+ * -----+------------------+
+ * 4 | ------------xxxx |color
+ * -----+------------------+
+ * 5 | --------xxxxxxxx | xpos
+ * -----+------------------+
+ * 6,7| unused
+ */
+
+static void draw_sprites(running_machine* machine, mame_bitmap *bitmap, const rectangle *cliprect)
+{
+ UINT16 *source = spriteram16;
+ UINT16 *finish = source + 0x800;
+
+ while (source < finish)
+ {
+ UINT16 attr = source[1];
+
+ if (attr & 0x01) /* enable */
+ {
+ int i;
+ int bank = source[3] & 0xff;
+ int code = (source[2] & 0xff) + (bank * 256);
+ int color = source[4] & 0xf;
+ int flipx = attr & 0x10;
+ int flipy = attr & 0x08;
+ int sx = source[5] & 0xff;
+ int sy = source[0] & 0xff;
+ int height = (attr >> 5) & 0x07;
+
+ if (attr & 0x04) sx |= 0x100;
+ if (attr & 0x02) sy = 239 + (0x100 - sy); else sy = 240 - sy;
+ if (sx > 0x17f) sx = 0 - (0x200 - sx);
+
+ if (flip_screen)
+ {
+ sx = 304 - sx;
+ sy = 224 - sy;
+ flipx = !flipx;
+ flipy = !flipy;
+ }
+
+ for (i = 0; i <= height; i++)
+ {
+ drawgfx(bitmap, machine->gfx[1], code + i, color, flipx, flipy,
+ sx, sy + (flip_screen ? (i * 16) : (-i * 16)), cliprect,
+ TRANSPARENCY_PEN, 0);
+ }
+ }
+
+ source += 8;
+ }
+}
+
+VIDEO_UPDATE( ddragon3 )
+{
+ tilemap_set_scrollx(bg_tilemap, 0, ddragon3_bg_scrollx);
+ tilemap_set_scrolly(bg_tilemap, 0, ddragon3_bg_scrolly);
+ tilemap_set_scrollx(fg_tilemap, 0, ddragon3_fg_scrollx);
+ tilemap_set_scrolly(fg_tilemap, 0, ddragon3_fg_scrolly);
+
+ if ((ddragon3_vreg & 0x60) == 0x40)
+ {
+ tilemap_draw(bitmap, cliprect, bg_tilemap, TILEMAP_DRAW_OPAQUE, 0);
+ tilemap_draw(bitmap, cliprect, fg_tilemap, 0, 0);
+ draw_sprites(machine, bitmap, cliprect);
+ }
+ else if ((ddragon3_vreg & 0x60) == 0x60)
+ {
+ tilemap_draw(bitmap, cliprect, fg_tilemap, TILEMAP_DRAW_OPAQUE, 0);
+ tilemap_draw(bitmap, cliprect, bg_tilemap, 0, 0);
+ draw_sprites(machine, bitmap, cliprect);
+ }
+ else
+ {
+ tilemap_draw(bitmap, cliprect, bg_tilemap, TILEMAP_DRAW_OPAQUE, 0);
+ draw_sprites(machine, bitmap, cliprect);
+ tilemap_draw(bitmap, cliprect, fg_tilemap, 0, 0);
+ }
+ return 0;
+}
+
+VIDEO_UPDATE( ctribe )
+{
+ tilemap_set_scrollx( bg_tilemap, 0, ddragon3_bg_scrollx );
+ tilemap_set_scrolly( bg_tilemap, 0, ddragon3_bg_scrolly );
+ tilemap_set_scrollx( fg_tilemap, 0, ddragon3_fg_scrollx );
+ tilemap_set_scrolly( fg_tilemap, 0, ddragon3_fg_scrolly );
+
+ if(ddragon3_vreg & 8)
+ {
+ tilemap_draw(bitmap, cliprect, fg_tilemap, TILEMAP_DRAW_OPAQUE, 0);
+ draw_sprites(machine, bitmap, cliprect);
+ tilemap_draw(bitmap, cliprect, bg_tilemap, 0, 0);
+ }
+ else
+ {
+ tilemap_draw(bitmap, cliprect, bg_tilemap, TILEMAP_DRAW_OPAQUE, 0);
+ tilemap_draw(bitmap, cliprect, fg_tilemap, 0, 0);
+ draw_sprites(machine, bitmap, cliprect);
+ }
+ return 0;
+}