summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/fromance.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/fromance.c')
-rw-r--r--src/mame/video/fromance.c471
1 files changed, 471 insertions, 0 deletions
diff --git a/src/mame/video/fromance.c b/src/mame/video/fromance.c
new file mode 100644
index 00000000000..06ae9541f5c
--- /dev/null
+++ b/src/mame/video/fromance.c
@@ -0,0 +1,471 @@
+/******************************************************************************
+
+ Video Hardware for Video System Mahjong series and Pipe Dream.
+
+ Driver by Takahiro Nogi <nogi@kt.rim.or.jp> 2001/02/04 -
+ and Bryan McPhail, Nicola Salmoria, Aaron Giles
+
+******************************************************************************/
+
+#include "driver.h"
+#include "fromance.h"
+
+
+static UINT8 selected_videoram;
+static UINT8 *local_videoram[2];
+
+static UINT8 selected_paletteram;
+static UINT8 *local_paletteram;
+
+static UINT32 scrollx[2], scrolly[2];
+static UINT8 gfxreg;
+static UINT8 flipscreen;
+static UINT32 scrolly_ofs;
+static UINT32 scrollx_ofs;
+
+static UINT8 crtc_register;
+static UINT8 crtc_data[0x10];
+static emu_timer *crtc_timer;
+
+static UINT8 flipscreen_old = -1;
+
+static tilemap *bg_tilemap, *fg_tilemap;
+
+static TIMER_CALLBACK( crtc_interrupt_gen );
+
+
+/*************************************
+ *
+ * Tilemap callbacks
+ *
+ *************************************/
+
+INLINE void get_fromance_tile_info(running_machine *machine,tile_data *tileinfo,int tile_index,int layer)
+{
+ int tile = ((local_videoram[layer][0x0000 + tile_index] & 0x80) << 9) |
+ (local_videoram[layer][0x1000 + tile_index] << 8) |
+ local_videoram[layer][0x2000 + tile_index];
+ int color = local_videoram[layer][tile_index] & 0x7f;
+
+ SET_TILE_INFO(layer, tile, color, 0);
+}
+
+static TILE_GET_INFO( get_fromance_bg_tile_info ) { get_fromance_tile_info(machine,tileinfo,tile_index, 0); }
+static TILE_GET_INFO( get_fromance_fg_tile_info ) { get_fromance_tile_info(machine,tileinfo,tile_index, 1); }
+
+INLINE void get_nekkyoku_tile_info(running_machine *machine,tile_data *tileinfo,int tile_index,int layer)
+{
+ int tile = (local_videoram[layer][0x0000 + tile_index] << 8) |
+ local_videoram[layer][0x1000 + tile_index];
+ int color = local_videoram[layer][tile_index + 0x2000] & 0x3f;
+
+ SET_TILE_INFO(layer, tile, color, 0);
+}
+
+static TILE_GET_INFO( get_nekkyoku_bg_tile_info ) { get_nekkyoku_tile_info(machine, tileinfo, tile_index, 0); }
+static TILE_GET_INFO( get_nekkyoku_fg_tile_info ) { get_nekkyoku_tile_info(machine, tileinfo, tile_index, 1); }
+
+
+
+/*************************************
+ *
+ * Video system start
+ *
+ *************************************/
+
+VIDEO_START( fromance )
+{
+ /* allocate tilemaps */
+ bg_tilemap = tilemap_create(get_fromance_bg_tile_info, tilemap_scan_rows, TILEMAP_TYPE_PEN, 8,4, 64,64);
+ fg_tilemap = tilemap_create(get_fromance_fg_tile_info, tilemap_scan_rows, TILEMAP_TYPE_PEN, 8,4, 64,64);
+
+ /* allocate local videoram */
+ local_videoram[0] = auto_malloc(0x1000 * 3);
+ local_videoram[1] = auto_malloc(0x1000 * 3);
+
+ /* allocate local palette RAM */
+ local_paletteram = auto_malloc(0x800 * 2);
+
+ /* configure tilemaps */
+ tilemap_set_transparent_pen(fg_tilemap,15);
+
+ /* reset the timer */
+ crtc_timer = timer_alloc(crtc_interrupt_gen);
+
+ scrollx_ofs = 0x159;
+ scrolly_ofs = 0x10;
+
+ /* state save */
+ state_save_register_global(selected_videoram);
+ state_save_register_global_pointer(local_videoram[0], 0x1000 * 3);
+ state_save_register_global_pointer(local_videoram[1], 0x1000 * 3);
+ state_save_register_global(selected_paletteram);
+ state_save_register_global_array(scrollx);
+ state_save_register_global_array(scrolly);
+ state_save_register_global(gfxreg);
+ state_save_register_global(flipscreen);
+ state_save_register_global(flipscreen_old);
+ state_save_register_global(scrollx_ofs);
+ state_save_register_global(scrolly_ofs);
+ state_save_register_global(crtc_register);
+ state_save_register_global_array(crtc_data);
+ state_save_register_global_pointer(local_paletteram, 0x800 * 2);
+}
+
+VIDEO_START( nekkyoku )
+{
+ /* allocate tilemaps */
+ bg_tilemap = tilemap_create(get_nekkyoku_bg_tile_info, tilemap_scan_rows, TILEMAP_TYPE_PEN, 8,4, 64,64);
+ fg_tilemap = tilemap_create(get_nekkyoku_fg_tile_info, tilemap_scan_rows, TILEMAP_TYPE_PEN, 8,4, 64,64);
+
+ /* allocate local videoram */
+ local_videoram[0] = auto_malloc(0x1000 * 3);
+ local_videoram[1] = auto_malloc(0x1000 * 3);
+
+ /* allocate local palette RAM */
+ local_paletteram = auto_malloc(0x800 * 2);
+
+ /* configure tilemaps */
+ tilemap_set_transparent_pen(fg_tilemap,15);
+
+ /* reset the timer */
+ crtc_timer = timer_alloc(crtc_interrupt_gen);
+
+ scrollx_ofs = 0x159;
+ scrolly_ofs = 0x10;
+
+ /* state save */
+ state_save_register_global(selected_videoram);
+ state_save_register_global_pointer(local_videoram[0], 0x1000 * 3);
+ state_save_register_global_pointer(local_videoram[1], 0x1000 * 3);
+ state_save_register_global(selected_paletteram);
+ state_save_register_global_array(scrollx);
+ state_save_register_global_array(scrolly);
+ state_save_register_global(gfxreg);
+ state_save_register_global(flipscreen);
+ state_save_register_global(flipscreen_old);
+ state_save_register_global(scrollx_ofs);
+ state_save_register_global(scrolly_ofs);
+ state_save_register_global(crtc_register);
+ state_save_register_global_array(crtc_data);
+ state_save_register_global_pointer(local_paletteram, 0x800 * 2);
+}
+
+VIDEO_START( pipedrm )
+{
+ video_start_fromance(machine);
+ scrolly_ofs = 0x00;
+}
+
+VIDEO_START( hatris )
+{
+ video_start_fromance(machine);
+ scrollx_ofs = 0xB9;
+ scrolly_ofs = 0x00;
+}
+
+/*************************************
+ *
+ * Graphics control register
+ *
+ *************************************/
+
+WRITE8_HANDLER( fromance_gfxreg_w )
+{
+
+ gfxreg = data;
+ flipscreen = (data & 0x01);
+ selected_videoram = (~data >> 1) & 1;
+ selected_paletteram = (data >> 6) & 1;
+
+ if (flipscreen != flipscreen_old)
+ {
+ flipscreen_old = flipscreen;
+ tilemap_set_flip(ALL_TILEMAPS, flipscreen ? (TILEMAP_FLIPX | TILEMAP_FLIPY) : 0);
+ }
+}
+
+
+
+/*************************************
+ *
+ * Banked palette RAM
+ *
+ *************************************/
+
+READ8_HANDLER( fromance_paletteram_r )
+{
+ /* adjust for banking and read */
+ offset |= selected_paletteram << 11;
+ return local_paletteram[offset];
+}
+
+
+WRITE8_HANDLER( fromance_paletteram_w )
+{
+ int palword;
+
+ /* adjust for banking and modify */
+ offset |= selected_paletteram << 11;
+ local_paletteram[offset] = data;
+
+ /* compute R,G,B */
+ palword = (local_paletteram[offset | 1] << 8) | local_paletteram[offset & ~1];
+ palette_set_color_rgb(Machine, offset / 2, pal5bit(palword >> 10), pal5bit(palword >> 5), pal5bit(palword >> 0));
+}
+
+
+
+/*************************************
+ *
+ * Video RAM read/write
+ *
+ *************************************/
+
+READ8_HANDLER( fromance_videoram_r )
+{
+ return local_videoram[selected_videoram][offset];
+}
+
+
+WRITE8_HANDLER( fromance_videoram_w )
+{
+ local_videoram[selected_videoram][offset] = data;
+ tilemap_mark_tile_dirty(selected_videoram ? fg_tilemap : bg_tilemap, offset & 0x0fff);
+}
+
+
+
+/*************************************
+ *
+ * Scroll registers
+ *
+ *************************************/
+
+WRITE8_HANDLER( fromance_scroll_w )
+{
+ if (flipscreen)
+ {
+ switch (offset)
+ {
+ case 0:
+ scrollx[1] = (data + (((gfxreg & 0x08) >> 3) * 0x100) - scrollx_ofs);
+ break;
+ case 1:
+ scrolly[1] = (data + (((gfxreg & 0x04) >> 2) * 0x100) - scrolly_ofs); // - 0x10
+ break;
+ case 2:
+ scrollx[0] = (data + (((gfxreg & 0x20) >> 5) * 0x100) - scrollx_ofs);
+ break;
+ case 3:
+ scrolly[0] = (data + (((gfxreg & 0x10) >> 4) * 0x100) - scrolly_ofs);
+ break;
+ }
+ }
+ else
+ {
+ switch (offset)
+ {
+ case 0:
+ scrollx[1] = (data + (((gfxreg & 0x08) >> 3) * 0x100) - 0x1f7);
+ break;
+ case 1:
+ scrolly[1] = (data + (((gfxreg & 0x04) >> 2) * 0x100) - 0xf9);
+ break;
+ case 2:
+ scrollx[0] = (data + (((gfxreg & 0x20) >> 5) * 0x100) - 0x1f7);
+ break;
+ case 3:
+ scrolly[0] = (data + (((gfxreg & 0x10) >> 4) * 0x100) - 0xf9);
+ break;
+ }
+ }
+}
+
+
+
+/*************************************
+ *
+ * Fake video controller
+ *
+ *************************************/
+
+static TIMER_CALLBACK( crtc_interrupt_gen )
+{
+ cpunum_set_input_line(1, 0, HOLD_LINE);
+ if (param != 0)
+ timer_adjust(crtc_timer, attotime_make(0, machine->screen[0].refresh / param), 0, attotime_make(0, machine->screen[0].refresh / param));
+}
+
+
+WRITE8_HANDLER( fromance_crtc_data_w )
+{
+ crtc_data[crtc_register] = data;
+
+ switch (crtc_register)
+ {
+ /* only register we know about.... */
+ case 0x0b:
+ timer_adjust(crtc_timer, video_screen_get_time_until_pos(0, Machine->screen[0].visarea.max_y + 1, 0), (data > 0x80) ? 2 : 1, attotime_zero);
+ break;
+
+ default:
+ logerror("CRTC register %02X = %02X\n", crtc_register, data & 0xff);
+ break;
+ }
+}
+
+
+WRITE8_HANDLER( fromance_crtc_register_w )
+{
+ crtc_register = data;
+}
+
+
+
+/*************************************
+ *
+ * Sprite routines (Pipe Dream)
+ *
+ *************************************/
+
+static void draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect, int draw_priority)
+{
+ static const UINT8 zoomtable[16] = { 0,7,14,20,25,30,34,38,42,46,49,52,54,57,59,61 };
+ int offs;
+
+ /* draw the sprites */
+ for (offs = 0; offs < spriteram_size; offs += 8)
+ {
+ int data2 = spriteram[offs + 4] | (spriteram[offs + 5] << 8);
+ int priority = (data2 >> 4) & 1;
+
+ /* turns out the sprites are the same as in aerofgt.c */
+ if ((data2 & 0x80) && priority == draw_priority)
+ {
+ int data0 = spriteram[offs + 0] | (spriteram[offs + 1] << 8);
+ int data1 = spriteram[offs + 2] | (spriteram[offs + 3] << 8);
+ int data3 = spriteram[offs + 6] | (spriteram[offs + 7] << 8);
+ int code = data3 & 0xfff;
+ int color = data2 & 0x0f;
+ int y = (data0 & 0x1ff) - 6;
+ int x = (data1 & 0x1ff) - 13;
+ int yzoom = (data0 >> 12) & 15;
+ int xzoom = (data1 >> 12) & 15;
+ int zoomed = (xzoom | yzoom);
+ int ytiles = ((data2 >> 12) & 7) + 1;
+ int xtiles = ((data2 >> 8) & 7) + 1;
+ int yflip = (data2 >> 15) & 1;
+ int xflip = (data2 >> 11) & 1;
+ int xt, yt;
+
+ /* compute the zoom factor -- stolen from aerofgt.c */
+ xzoom = 16 - zoomtable[xzoom] / 8;
+ yzoom = 16 - zoomtable[yzoom] / 8;
+
+ /* wrap around */
+ if (x > machine->screen[0].visarea.max_x) x -= 0x200;
+ if (y > machine->screen[0].visarea.max_y) y -= 0x200;
+
+ /* flip ? */
+ if (flipscreen)
+ {
+ y = machine->screen[0].visarea.max_y - y - 16 * ytiles - 4;
+ x = machine->screen[0].visarea.max_x - x - 16 * xtiles - 24;
+ xflip=!xflip;
+ yflip=!yflip;
+ }
+
+ /* normal case */
+ if (!xflip && !yflip)
+ {
+ for (yt = 0; yt < ytiles; yt++)
+ for (xt = 0; xt < xtiles; xt++, code++)
+ if (!zoomed)
+ drawgfx(bitmap, machine->gfx[2], code, color, 0, 0,
+ x + xt * 16, y + yt * 16, cliprect, TRANSPARENCY_PEN, 15);
+ else
+ drawgfxzoom(bitmap, machine->gfx[2], code, color, 0, 0,
+ x + xt * xzoom, y + yt * yzoom, cliprect, TRANSPARENCY_PEN, 15,
+ 0x1000 * xzoom, 0x1000 * yzoom);
+ }
+
+ /* xflipped case */
+ else if (xflip && !yflip)
+ {
+ for (yt = 0; yt < ytiles; yt++)
+ for (xt = 0; xt < xtiles; xt++, code++)
+ if (!zoomed)
+ drawgfx(bitmap, machine->gfx[2], code, color, 1, 0,
+ x + (xtiles - 1 - xt) * 16, y + yt * 16, cliprect, TRANSPARENCY_PEN, 15);
+ else
+ drawgfxzoom(bitmap, machine->gfx[2], code, color, 1, 0,
+ x + (xtiles - 1 - xt) * xzoom, y + yt * yzoom, cliprect, TRANSPARENCY_PEN, 15,
+ 0x1000 * xzoom, 0x1000 * yzoom);
+ }
+
+ /* yflipped case */
+ else if (!xflip && yflip)
+ {
+ for (yt = 0; yt < ytiles; yt++)
+ for (xt = 0; xt < xtiles; xt++, code++)
+ if (!zoomed)
+ drawgfx(bitmap, machine->gfx[2], code, color, 0, 1,
+ x + xt * 16, y + (ytiles - 1 - yt) * 16, cliprect, TRANSPARENCY_PEN, 15);
+ else
+ drawgfxzoom(bitmap, machine->gfx[2], code, color, 0, 1,
+ x + xt * xzoom, y + (ytiles - 1 - yt) * yzoom, cliprect, TRANSPARENCY_PEN, 15,
+ 0x1000 * xzoom, 0x1000 * yzoom);
+ }
+
+ /* x & yflipped case */
+ else
+ {
+ for (yt = 0; yt < ytiles; yt++)
+ for (xt = 0; xt < xtiles; xt++, code++)
+ if (!zoomed)
+ drawgfx(bitmap, machine->gfx[2], code, color, 1, 1,
+ x + (xtiles - 1 - xt) * 16, y + (ytiles - 1 - yt) * 16, cliprect, TRANSPARENCY_PEN, 15);
+ else
+ drawgfxzoom(bitmap, machine->gfx[2], code, color, 1, 1,
+ x + (xtiles - 1 - xt) * xzoom, y + (ytiles - 1 - yt) * yzoom, cliprect, TRANSPARENCY_PEN, 15,
+ 0x1000 * xzoom, 0x1000 * yzoom);
+ }
+ }
+ }
+}
+
+
+
+/*************************************
+ *
+ * Main screen refresh
+ *
+ *************************************/
+
+VIDEO_UPDATE( fromance )
+{
+ tilemap_set_scrollx(bg_tilemap, 0, scrollx[0]);
+ tilemap_set_scrolly(bg_tilemap, 0, scrolly[0]);
+ tilemap_set_scrollx(fg_tilemap, 0, scrollx[1]);
+ tilemap_set_scrolly(fg_tilemap, 0, scrolly[1]);
+
+ tilemap_draw(bitmap,cliprect, bg_tilemap, 0, 0);
+ tilemap_draw(bitmap,cliprect, fg_tilemap, 0, 0);
+ return 0;
+}
+
+
+VIDEO_UPDATE( pipedrm )
+{
+ /* there seems to be no logical mapping for the X scroll register -- maybe it's gone */
+ tilemap_set_scrolly(bg_tilemap, 0, scrolly[1]);
+ tilemap_set_scrolly(fg_tilemap, 0, scrolly[0]);
+
+ tilemap_draw(bitmap,cliprect, bg_tilemap, 0, 0);
+ tilemap_draw(bitmap,cliprect, fg_tilemap, 0, 0);
+
+ draw_sprites(machine,bitmap,cliprect, 0);
+ draw_sprites(machine,bitmap,cliprect, 1);
+ return 0;
+}