diff options
Diffstat (limited to 'src/mame/video/dday.c')
-rw-r--r-- | src/mame/video/dday.c | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/src/mame/video/dday.c b/src/mame/video/dday.c new file mode 100644 index 00000000000..0d6c74b6e9f --- /dev/null +++ b/src/mame/video/dday.c @@ -0,0 +1,379 @@ +/*************************************************************************** + + video.c + + Functions to emulate the video hardware of the machine. + + Convention: "sl" stands for "searchlight" + +***************************************************************************/ + +#include "driver.h" + + +UINT8 *dday_bgvideoram; +UINT8 *dday_fgvideoram; +UINT8 *dday_textvideoram; +UINT8 *dday_colorram; + +static tilemap *fg_tilemap, *bg_tilemap, *text_tilemap, *sl_tilemap; +static mame_bitmap *main_bitmap; +static int control; +static int sl_image; +static int sl_enable; +static int timer_value; + + +/* Note: There seems to be no way to reset this timer via hardware. + The game uses a difference method to reset it to 99. + + Thanks Zwaxy for the timer info. */ + +READ8_HANDLER( dday_countdown_timer_r ) +{ + return ((timer_value / 10) << 4) | (timer_value % 10); +} + +static TIMER_CALLBACK( countdown_timer_callback ) +{ + timer_value--; + + if (timer_value < 0) + { + timer_value = 99; + } +} + +static void start_countdown_timer(void) +{ + timer_value = 0; + + timer_pulse(ATTOTIME_IN_SEC(1), 0, countdown_timer_callback); +} + + +/*************************************************************************** + + Convert the color PROMs into a more useable format. + +***************************************************************************/ + +PALETTE_INIT( dday ) +{ + int i; + + + palette_set_shadow_factor(machine, 1.0/8); /* this matches the previous version of the driver (>>3) */ + + for (i = 0; i < machine->drv->total_colors; i++) + { + int bit0,bit1,bit2,bit3,r,g,b; + + + /* red component */ + bit0 = (color_prom[i] >> 0) & 0x01; + bit1 = (color_prom[i] >> 1) & 0x01; + bit2 = (color_prom[i] >> 2) & 0x01; + bit3 = (color_prom[i] >> 3) & 0x01; + r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + /* green component */ + bit0 = (color_prom[i + machine->drv->total_colors] >> 0) & 0x01; + bit1 = (color_prom[i + machine->drv->total_colors] >> 1) & 0x01; + bit2 = (color_prom[i + machine->drv->total_colors] >> 2) & 0x01; + bit3 = (color_prom[i + machine->drv->total_colors] >> 3) & 0x01; + g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + /* blue component */ + bit0 = (color_prom[i + 2*machine->drv->total_colors] >> 0) & 0x01; + bit1 = (color_prom[i + 2*machine->drv->total_colors] >> 1) & 0x01; + bit2 = (color_prom[i + 2*machine->drv->total_colors] >> 2) & 0x01; + bit3 = (color_prom[i + 2*machine->drv->total_colors] >> 3) & 0x01; + b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + palette_set_color(machine,i,MAKE_RGB(r,g,b)); + } + + + /* HACK!!! This table is handgenerated, but it matches the screenshot. + I have no clue how it really works */ + + colortable[0*8+0] = 0; + colortable[0*8+1] = 1; + colortable[0*8+2] = 21; + colortable[0*8+3] = 2; + colortable[0*8+4+0] = 0; + colortable[0*8+4+1] = 1; + colortable[0*8+4+2] = 21; + colortable[0*8+4+3] = 2; + + colortable[1*8+0] = 4; + colortable[1*8+1] = 5; + colortable[1*8+2] = 3; + colortable[1*8+3] = 7; + colortable[1*8+4+0] = 4; + colortable[1*8+4+1] = 5; + colortable[1*8+4+2] = 3; + colortable[1*8+4+3] = 7; + + colortable[2*8+0] = 8; + colortable[2*8+1] = 21; + colortable[2*8+2] = 10; + colortable[2*8+3] = 3; + colortable[2*8+4+0] = 8; + colortable[2*8+4+1] = 21; + colortable[2*8+4+2] = 10; + colortable[2*8+4+3] = 3; + + colortable[3*8+0] = 8; + colortable[3*8+1] = 21; + colortable[3*8+2] = 10; + colortable[3*8+3] = 3; + colortable[3*8+4+0] = 8; + colortable[3*8+4+1] = 21; + colortable[3*8+4+2] = 10; + colortable[3*8+4+3] = 3; + + colortable[4*8+0] = 16; + colortable[4*8+1] = 17; + colortable[4*8+2] = 18; + colortable[4*8+3] = 7; + colortable[4*8+4+0] = 16; + colortable[4*8+4+1] = 17; + colortable[4*8+4+2] = 18; + colortable[4*8+4+3] = 7; + + colortable[5*8+0] = 29; + colortable[5*8+1] = 21; + colortable[5*8+2] = 22; + colortable[5*8+3] = 27; + colortable[5*8+4+0] = 29; + colortable[5*8+4+1] = 21; + colortable[5*8+4+2] = 22; + colortable[5*8+4+3] = 27; + + colortable[6*8+0] = 29; + colortable[6*8+1] = 21; + colortable[6*8+2] = 26; + colortable[6*8+3] = 27; + colortable[6*8+4+0] = 29; + colortable[6*8+4+1] = 21; + colortable[6*8+4+2] = 26; + colortable[6*8+4+3] = 27; + + colortable[7*8+0] = 29; + colortable[7*8+1] = 2; + colortable[7*8+2] = 4; + colortable[7*8+3] = 27; + colortable[7*8+4+0] = 29; + colortable[7*8+4+1] = 2; + colortable[7*8+4+2] = 4; + colortable[7*8+4+3] = 27; +} + + +/*************************************************************************** + + Callbacks for the TileMap code + +***************************************************************************/ + +static TILE_GET_INFO( get_bg_tile_info ) +{ + int code; + + code = dday_bgvideoram[tile_index]; + SET_TILE_INFO(0, code, code >> 5, 0); +} + +static TILE_GET_INFO( get_fg_tile_info ) +{ + int code, flipx; + + flipx = dday_colorram[tile_index & 0x03e0] & 0x01; + code = dday_fgvideoram[flipx ? tile_index ^ 0x1f : tile_index]; + SET_TILE_INFO(2, code, code >> 5, flipx ? TILE_FLIPX : 0); +} + +static TILE_GET_INFO( get_text_tile_info ) +{ + int code; + + code = dday_textvideoram[tile_index]; + SET_TILE_INFO(1, code, code >> 5, 0); +} + +static TILE_GET_INFO( get_sl_tile_info ) +{ + int code, sl_flipx, flipx; + UINT8* sl_map; + + sl_map = &memory_region(REGION_USER1)[(sl_image & 0x07) * 0x0200]; + + flipx = (tile_index >> 4) & 0x01; + sl_flipx = (sl_image >> 3) & 0x01; + + /* bit 4 is really a flip indicator. Need to shift bits 5-9 to the right by 1 */ + tile_index = ((tile_index & 0x03e0) >> 1) | (tile_index & 0x0f); + + code = sl_map[flipx ? tile_index ^ 0x0f : tile_index]; + + if (sl_flipx != flipx) + { + if (code & 0x80) + { + /* no mirroring, draw dark spot */ + code = 1; + } + } + + SET_TILE_INFO(3, code & 0x3f, 0, flipx ? TILE_FLIPX : 0); +} + + +/*************************************************************************** + + Start the video hardware emulation. + +***************************************************************************/ + +VIDEO_START( dday ) +{ + bg_tilemap = tilemap_create(get_bg_tile_info, tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32); + fg_tilemap = tilemap_create(get_fg_tile_info, tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32); + text_tilemap = tilemap_create(get_text_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32); + sl_tilemap = tilemap_create(get_sl_tile_info, tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32); + + main_bitmap = auto_bitmap_alloc(machine->screen[0].width,machine->screen[0].height,machine->screen[0].format); + + tilemap_set_transmask(bg_tilemap,0,0x00f0,0xff0f); /* pens 0-3 have priority over the foreground layer */ + + tilemap_set_transparent_pen(fg_tilemap, 0); + + tilemap_set_transparent_pen(text_tilemap, 0); + + control = 0; + sl_enable = 0; + sl_image = 0; + + start_countdown_timer(); +} + +WRITE8_HANDLER( dday_bgvideoram_w ) +{ + dday_bgvideoram[offset] = data; + tilemap_mark_tile_dirty(bg_tilemap, offset); +} + +WRITE8_HANDLER( dday_fgvideoram_w ) +{ + dday_fgvideoram[offset] = data; + tilemap_mark_tile_dirty(fg_tilemap, offset); + tilemap_mark_tile_dirty(fg_tilemap, offset ^ 0x1f); /* for flipx case */ +} + +WRITE8_HANDLER( dday_textvideoram_w ) +{ + dday_textvideoram[offset] = data; + tilemap_mark_tile_dirty(text_tilemap, offset); +} + +WRITE8_HANDLER( dday_colorram_w ) +{ + int i; + + + offset &= 0x03e0; + + dday_colorram[offset & 0x3e0] = data; + + for (i = 0; i < 0x20; i++) + { + tilemap_mark_tile_dirty(fg_tilemap, offset + i); + } +} + +READ8_HANDLER( dday_colorram_r ) +{ + return dday_colorram[offset & 0x03e0]; +} + + +WRITE8_HANDLER( dday_sl_control_w ) +{ + if (sl_image != data) + { + sl_image = data; + + tilemap_mark_all_tiles_dirty(sl_tilemap); + } +} + + +WRITE8_HANDLER( dday_control_w ) +{ + //if (data & 0xac) logerror("Control = %02X\n", data & 0xac); + + /* bit 0 is coin counter 1 */ + coin_counter_w(0, data & 0x01); + + /* bit 1 is coin counter 2 */ + coin_counter_w(1, data & 0x02); + + /* bit 4 is sound enable */ + if (!(data & 0x10) && (control & 0x10)) + sndti_reset(SOUND_AY8910, 0); + + sound_global_enable(data & 0x10); + + /* bit 6 is search light enable */ + sl_enable = data & 0x40; + + control = data; +} + +/*************************************************************************** + + Display refresh + +***************************************************************************/ + +VIDEO_UPDATE( dday ) +{ + tilemap_draw(main_bitmap,cliprect,bg_tilemap,TILEMAP_DRAW_LAYER1,0); + tilemap_draw(main_bitmap,cliprect,fg_tilemap,0,0); + tilemap_draw(main_bitmap,cliprect,bg_tilemap,TILEMAP_DRAW_LAYER0,0); + tilemap_draw(main_bitmap,cliprect,text_tilemap,0,0); + + if (sl_enable) + { + /* apply shadow */ + + mame_bitmap *sl_bitmap; + int x, y; + + + sl_bitmap = tilemap_get_pixmap(sl_tilemap); + + for (x = cliprect->min_x; x <= cliprect->max_x; x++) + { + for (y = cliprect->min_y; y <= cliprect->max_y; y++) + { + UINT32 src_pixel; + + + src_pixel = *BITMAP_ADDR16(main_bitmap, y, x); + + if (*BITMAP_ADDR16(sl_bitmap, y, x) == 0xff) + { + src_pixel += machine->drv->total_colors; + } + + *BITMAP_ADDR16(bitmap, y, x) = src_pixel; + } + } + } + else + { + copybitmap(bitmap,main_bitmap,0,0,0,0,cliprect,TRANSPARENCY_NONE,0); + } + return 0; +} |