summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/namcona1.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/namcona1.cpp')
-rw-r--r--src/mame/video/namcona1.cpp623
1 files changed, 0 insertions, 623 deletions
diff --git a/src/mame/video/namcona1.cpp b/src/mame/video/namcona1.cpp
deleted file mode 100644
index 34f3d89e0a2..00000000000
--- a/src/mame/video/namcona1.cpp
+++ /dev/null
@@ -1,623 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Phil Stroffolino
-/* Namco System NA1/2 Video Hardware */
-
-/*
-Notes:
-- fa/fghtatck: Global screen window effect cut one line from top/bottom of screen, especially noticeable with credit display.
- It's a btanb according to a PCB video I've seen -AS.
-
-TODO:
-- background color currently follows what xday2 tries to set up, it's not sure if this is correct for everything else.
- Maybe there's a setting that actually switches between that and black pen?
-- non-shadow pixels for sprites flagged to enable shadows have bad colors
-- xday2: after choosing life (right) mode and set up date of birth, a joystick screen shows up.
- Bottom yellow frame doesn't show up correctly.
-- xday2: at the end of life event, there's an unemulated screen shutdown event (might be posirq?)
-
-*/
-
-#include "emu.h"
-#include "includes/namcona1.h"
-
-
-void namcona1_state::tilemap_get_info(
- tile_data &tileinfo,
- int tile_index,
- const u16 *tilemap_videoram,
- bool use_4bpp_gfx)
-{
- const u16 data = tilemap_videoram[tile_index];
- const u32 tile = data & 0xfff;
- const u8 gfx = use_4bpp_gfx ? 1 : 0;
- const u32 color = use_4bpp_gfx ? (data & 0x7000) >> 12 : 0;
-
- if (data & 0x8000)
- {
- SET_TILE_INFO_MEMBER(gfx, tile, color, TILE_FORCE_LAYER0);
- }
- else
- {
- SET_TILE_INFO_MEMBER(gfx, tile, color, 0);
- tileinfo.mask_data = &m_shaperam[tile << 3];
- }
-} /* tilemap_get_info */
-
-TILE_GET_INFO_MEMBER(namcona1_state::tilemap_get_info0)
-{
- tilemap_get_info(tileinfo, tile_index, 0 * 0x1000 + m_videoram, m_vreg[0xbc / 2] & 0x1);
-}
-
-TILE_GET_INFO_MEMBER(namcona1_state::tilemap_get_info1)
-{
- tilemap_get_info(tileinfo, tile_index, 1 * 0x1000 + m_videoram, m_vreg[0xbc / 2] & 0x2);
-}
-
-TILE_GET_INFO_MEMBER(namcona1_state::tilemap_get_info2)
-{
- tilemap_get_info(tileinfo, tile_index, 2 * 0x1000 + m_videoram, m_vreg[0xbc / 2] & 0x4);
-}
-
-TILE_GET_INFO_MEMBER(namcona1_state::tilemap_get_info3)
-{
- tilemap_get_info(tileinfo, tile_index, 3 * 0x1000 + m_videoram, m_vreg[0xbc / 2] & 0x8);
-}
-
-TILE_GET_INFO_MEMBER(namcona1_state::roz_get_info)
-{
- /* each logical tile is constructed from 4*4 normal tiles */
- const bool use_4bpp_gfx = m_vreg[0xbc / 2] & 0x10; /* ? */
- const u16 c = tile_index & 0x3f;
- const u16 r = tile_index >> 6;
- const u16 data = m_videoram[0x8000 / 2 + ((r >> 2) << 6) + (c >> 2)];
- const u32 tile = ((data & 0xfbf) + (c & 3) + ((r & 3) << 6)) & 0xfff; /* mask out bit 0x40 - patch for Emeraldia Japan */
- const u8 gfx = use_4bpp_gfx ? 1 : 0;
- const u32 color = use_4bpp_gfx ? (data & 0x7000) >> 12 : 0;
-
- if (data & 0x8000)
- {
- SET_TILE_INFO_MEMBER(gfx, tile, color, TILE_FORCE_LAYER0);
- }
- else
- {
- SET_TILE_INFO_MEMBER(gfx, tile, color, 0);
- tileinfo.mask_data = &m_shaperam[tile << 3];
- }
-} /* roz_get_info */
-
-/*************************************************************************/
-
-void namcona1_state::videoram_w(offs_t offset, u16 data, u16 mem_mask)
-{
- COMBINE_DATA(&m_videoram[offset]);
- if (offset < 0x8000 / 2)
- {
- m_bg_tilemap[offset >> 12]->mark_tile_dirty(offset & 0xfff);
- }
- else if (offset < 0x8800 / 2)
- {
- if (offset & ~0x30)
- {
- for (int i = 0; i < 4; i++)
- {
- m_bg_tilemap[4]->mark_tile_dirty(((offset & 0x3cf) << 2) + i);
- m_bg_tilemap[4]->mark_tile_dirty(((offset & 0x3cf) << 2) + 0x40 + i);
- m_bg_tilemap[4]->mark_tile_dirty(((offset & 0x3cf) << 2) + 0x80 + i);
- m_bg_tilemap[4]->mark_tile_dirty(((offset & 0x3cf) << 2) + 0xc0 + i);
- }
- }
- }
-} /* videoram_w */
-
-/*************************************************************************/
-
-void namcona1_state::UpdatePalette(int offset)
-{
- const u16 data = m_paletteram[offset]; /* -RRRRRGG GGGBBBBB */
- /**
- * sprites can be configured to use an alternate interpretation of palette ram
- * (used in-game in Emeraldia)
- *
- * RRRGGGBB RRRGGGBB
- */
- int r = (((data & 0x00e0) >> 5) + ((data & 0xe000) >> 13) * 2) * 0xff / (0x7 * 3);
- int g = (((data & 0x001c) >> 2) + ((data & 0x1c00) >> 10) * 2) * 0xff / (0x7 * 3);
- int b = (((data & 0x0003) >> 0) + ((data & 0x0300) >> 8) * 2) * 0xff / (0x3 * 3);
- m_palette->set_pen_color(offset + 0x1000, r, g, b);
-
- m_palette->set_pen_color(offset, pal5bit(data >> 10), pal5bit(data >> 5), pal5bit(data >> 0));
-}
-
-void namcona1_state::paletteram_w(offs_t offset, u16 data, u16 mem_mask)
-{
- COMBINE_DATA(&m_paletteram[offset]);
- if (m_vreg[0x8e / 2])
- { /* graphics enabled; update palette immediately */
- UpdatePalette(offset);
- }
- else
- {
- m_palette_is_dirty = 1;
- }
-}
-
-
-u16 namcona1_state::gfxram_r(offs_t offset)
-{
- const u16 type = m_vreg[0x0c / 2];
- if (type == 0x03)
- {
- if (offset < 0x4000)
- {
- offset *= 2;
- return (m_shaperam[offset] << 8) | m_shaperam[offset+1];
- }
- }
- else if (type == 0x02)
- {
- return m_cgram[offset];
- }
- return 0x0000;
-} /* gfxram_r */
-
-void namcona1_state::gfxram_w(offs_t offset, u16 data, u16 mem_mask)
-{
- const u16 type = m_vreg[0x0c / 2];
-
- if (type == 0x03)
- {
- if (offset < 0x4000)
- {
- offset *= 2;
- if (ACCESSING_BITS_8_15)
- m_shaperam[offset] = data >> 8;
- if (ACCESSING_BITS_0_7)
- m_shaperam[offset + 1] = data;
- m_gfxdecode->gfx(2)->mark_dirty(offset >> 3);
- }
- }
- else if (type == 0x02)
- {
- const u16 old_word = m_cgram[offset];
- COMBINE_DATA(&m_cgram[offset]);
- if (m_cgram[offset] != old_word)
- {
- m_gfxdecode->gfx(0)->mark_dirty(offset >> 5);
- m_gfxdecode->gfx(1)->mark_dirty(offset >> 5);
- }
- }
-} /* gfxram_w */
-
-void namcona1_state::video_start()
-{
- // normal tilemaps
- m_bg_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(namcona1_state::tilemap_get_info0),this), TILEMAP_SCAN_ROWS, 8,8,64,64);
- m_bg_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(namcona1_state::tilemap_get_info1),this), TILEMAP_SCAN_ROWS, 8,8,64,64);
- m_bg_tilemap[2] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(namcona1_state::tilemap_get_info2),this), TILEMAP_SCAN_ROWS, 8,8,64,64);
- m_bg_tilemap[3] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(namcona1_state::tilemap_get_info3),this), TILEMAP_SCAN_ROWS, 8,8,64,64);
-
- // roz tilemap
- m_bg_tilemap[4] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(namcona1_state::roz_get_info),this), TILEMAP_SCAN_ROWS, 8,8,64,64);
-
- m_shaperam.resize(0x8000);
-
- m_gfxdecode->gfx(2)->set_source(&m_shaperam[0]);
-
- save_item(NAME(m_shaperam));
- save_item(NAME(m_palette_is_dirty));
-} /* video_start */
-
-void namcona1_state::device_post_load()
-{
- for (int i = 0; i < 3; i++)
- m_gfxdecode->gfx(i)->mark_all_dirty();
-}
-
-
-/*************************************************************************/
-
-void namcona1_state::pdraw_tile(
- screen_device &screen,
- bitmap_ind16 &dest_bmp,
- const rectangle &clip,
- u32 code,
- u32 color,
- int sx, int sy,
- bool flipx, bool flipy,
- u8 priority,
- bool bShadow,
- bool bOpaque,
- u8 gfx_region)
-{
- gfx_element *gfx = m_gfxdecode->gfx(gfx_region);
- gfx_element *mask = m_gfxdecode->gfx(2);
-
- const u16 pal_base = gfx->colorbase() + gfx->granularity() * (color % gfx->colors());
- const u8 *source_base = gfx->get_data((code % gfx->elements()));
- const u8 *mask_base = mask->get_data((code % mask->elements()));
-
- /* compute sprite increment per screen pixel */
- int dx, dy;
-
- int ex = sx + gfx->width();
- int ey = sy + gfx->height();
-
- int x_index_base;
- int y_index;
-
- if (flipx)
- {
- x_index_base = gfx->width() - 1;
- dx = -1;
- }
- else
- {
- x_index_base = 0;
- dx = 1;
- }
-
- if (flipy)
- {
- y_index = gfx->height() - 1;
- dy = -1;
- }
- else
- {
- y_index = 0;
- dy = 1;
- }
-
- if (sx < clip.min_x)
- { /* clip left */
- int pixels = clip.min_x - sx;
- sx += pixels;
- x_index_base += pixels * dx;
- }
- if (sy < clip.min_y)
- { /* clip top */
- int pixels = clip.min_y - sy;
- sy += pixels;
- y_index += pixels * dy;
- }
- /* NS 980211 - fixed incorrect clipping */
- if (ex > clip.max_x + 1)
- { /* clip right */
- int pixels = ex - clip.max_x - 1;
- ex -= pixels;
- }
- if (ey > clip.max_y + 1)
- { /* clip bottom */
- int pixels = ey - clip.max_y - 1;
- ey -= pixels;
- }
-
- if (ex > sx)
- { /* skip if inner loop doesn't draw anything */
- for (int y = sy; y < ey; y++)
- {
- const u8 *source = source_base + y_index * gfx->rowbytes();
- const u8 *mask_addr = mask_base + y_index * mask->rowbytes();
- u16 *dest = &dest_bmp.pix16(y);
- u8 *pri = &screen.priority().pix8(y);
-
- int x_index = x_index_base;
- for (int x = sx; x < ex; x++)
- {
- if (bOpaque)
- {
- if (pri[x] <= priority)
- {
- const u8 c = source[x_index];
- dest[x] = pal_base + c;
- }
- pri[x] = 0xff;
- }
- else
- {
- /* sprite pixel is opaque */
- if (mask_addr[x_index] != 0)
- {
- if (pri[x] <= priority)
- {
- const u8 c = source[x_index];
-
- /* render a shadow only if the sprites color is $F (8bpp) or $FF (4bpp) */
- if (bShadow)
- {
- if ((gfx_region == 0 && color == 0x0f) ||
- (gfx_region == 1 && color == 0xff))
- {
- pen_t *palette_shadow_table = m_palette->shadow_table();
- dest[x] = palette_shadow_table[dest[x]];
- }
- else
- {
- dest[x] = pal_base + c + 0x1000;
- }
- }
- else
- {
- dest[x] = pal_base + c;
- }
- }
- pri[x] = 0xff;
- }
- }
- x_index += dx;
- }
- y_index += dy;
- }
- }
-} /* pdraw_tile */
-
-void namcona1_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- const u16 *source = m_spriteram;
-
- const u16 sprite_control = m_vreg[0x22 / 2];
- if (sprite_control & 1) source += 0x400; /* alternate spriteram bank */
-
- for (int which = 0; which < 0x100; which++)
- { /* max 256 sprites */
- int bpp4,palbase;
- const u16 ypos = source[0]; /* FHHH---Y YYYYYYYY flipy, height, ypos */
- const u16 tile = source[1]; /* O???TTTT TTTTTTTT opaque tile */
- const u16 color = source[2]; /* FSWWOOOO CCCCBPPP flipx, shadow, width, color offset for 4bpp, color, 4bbp - 8bpp mode, pri*/
- const u16 xpos = source[3]; /* -------X XXXXXXXX xpos */
-
- const u8 priority = color & 0x7;
- const u16 width = ((color >> 12) & 0x3) + 1;
- const u16 height = ((ypos >> 12) & 0x7) + 1;
- bool flipy = ypos & 0x8000;
- bool flipx = color & 0x8000;
-
- if (color & 8)
- {
- palbase = (color & 0xf0) | ((color & 0xf00) >> 8);
- bpp4 = 1;
- }
- else
- {
- palbase = (color & 0xf0) >> 4;
- bpp4 = 0;
- }
-
- for (int row = 0; row < height; row++)
- {
- int sy = (ypos & 0x1ff) - 30 + 32;
- if (flipy)
- {
- sy += (height - 1 - row) << 3;
- }
- else
- {
- sy += row << 3;
- }
- sy = ((sy + 8) & 0x1ff) - 8;
-
- for (int col = 0; col < width; col++)
- {
- int sx = (xpos & 0x1ff) - 10;
- if (flipx)
- {
- sx += (width - 1 - col) << 3;
- }
- else
- {
- sx += col << 3;
- }
- sx = ((sx + 16) & 0x1ff) - 8;
-
- pdraw_tile(screen,
- bitmap,
- cliprect,
- (tile & 0xfff) + (row << 6) + col,
- palbase,
- sx,sy,flipx,flipy,
- priority,
- color & 0x4000, /* shadow */
- tile & 0x8000, /* opaque */
- bpp4);
-
- } /* next col */
- } /* next row */
- source += 4;
- }
-} /* draw_sprites */
-
-void namcona1_state::draw_pixel_line(const rectangle &cliprect, u16 *pDest, u8 *pPri, u16 *pSource, const pen_t *paldata)
-{
- for (int x = 0; x < 38 << 3; x += 2)
- {
- u16 data = *pSource++;
- pPri[x + 0] = 0xff;
- pPri[x + 1] = 0xff;
- if (x >= cliprect.min_x && x <= cliprect.max_x)
- pDest[x+0] = paldata[data>>8];
- if (x+1 >= cliprect.min_x && x+1 <= cliprect.max_x)
- pDest[x+1] = paldata[data&0xff];
- } /* next x */
-} /* draw_pixel_line */
-
-void namcona1_state::draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int which, int primask)
-{
- if (which == 4)
- {
- /* draw the roz tilemap all at once */
- int incxx = ((s16)m_vreg[0xc0 / 2])<<8;
- int incxy = ((s16)m_vreg[0xc2 / 2])<<8;
- int incyx = ((s16)m_vreg[0xc4 / 2])<<8;
- int incyy = ((s16)m_vreg[0xc6 / 2])<<8;
- s16 xoffset = m_vreg[0xc8 / 2];
- s16 yoffset = m_vreg[0xca / 2];
- int dx = 46; /* horizontal adjust */
- int dy = -8; /* vertical adjust */
- u32 startx = (xoffset<<12) + incxx * dx + incyx * dy;
- u32 starty = (yoffset<<12) + incxy * dx + incyy * dy;
- m_bg_tilemap[4]->draw_roz(screen, bitmap, cliprect,
- startx, starty, incxx, incxy, incyx, incyy, 0, 0, primask, 0);
- }
- else
- {
- /* draw one scanline at a time */
- /* scrollx lineselect
- * tmap0 ffe000 ffe200
- * tmap1 ffe400 ffe600
- * tmap2 ffe800 ffea00
- * tmap3 ffec00 ffee00
- */
- const u16 *scroll = &m_scroll[which * 0x400 / 2];
- rectangle clip = cliprect;
- int xadjust = 0x3a - which*2;
- int scrollx = xadjust;
- int scrolly = 0;
-
- for (int line = 0; line < 256; line++)
- {
- clip.min_y = line;
- clip.max_y = line;
- int xdata = scroll[line];
- int ydata = scroll[line + 0x200 / 2];
-
- if (xdata)
- {
- /* screenwise linescroll */
- if (xdata & 0x4000) // resets current xscroll value (knuckle head)
- scrollx = xadjust + xdata;
- else
- scrollx += xdata & 0x1ff;
- }
-
- if (ydata & 0x4000)
- {
- /* line select: dword offset from 0xff000 or tilemap source line */
- scrolly = (ydata - line) & 0x1ff;
- }
-
- if (line >= cliprect.min_y && line <= cliprect.max_y)
- {
- // TODO: not convinced about this trigger
- if (xdata == 0xc001)
- {
- /* This is a simplification, but produces the correct behavior for the only game that uses this
- * feature, Numan Athletics.
- */
- // TODO: with this it breaks colors in VS Express event, likely pal bank is somewhere else in this mode, assuming it has one anyway?
- //const pen_t *paldata = &m_palette->pen(m_bg_tilemap[which]->palette_offset());
- const pen_t *paldata = &m_palette->pen(0);
-
- draw_pixel_line(cliprect, &bitmap.pix16(line),
- &screen.priority().pix8(line),
- m_videoram + ydata + 25,
- paldata);
- }
- else
- {
- m_bg_tilemap[which]->set_scrollx(0, scrollx);
- m_bg_tilemap[which]->set_scrolly(0, scrolly);
- m_bg_tilemap[which]->draw(screen, bitmap, clip, 0, primask, 0);
- }
- }
- }
- }
-} /* draw_background */
-
-// CRTC safety checks
-bool namcona1_state::screen_enabled(const rectangle &cliprect)
-{
- if (cliprect.min_x < 0)
- return false;
-
- if (cliprect.max_x < 0)
- return false;
-
- if (cliprect.min_x > cliprect.max_x)
- return false;
-
- if (cliprect.min_y > cliprect.max_y)
- return false;
-
- return true;
-}
-
-u32 namcona1_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- // CRTC visible area parameters
- // (used mostly by Numan Athletics for global screen window effects, cfr. start of events/title screen to demo mode transitions)
- rectangle display_rect;
- display_rect.min_x = m_vreg[0x80 / 2]-0x48;
- display_rect.max_x = m_vreg[0x82 / 2]-0x48-1;
- display_rect.min_y = std::max((int)m_vreg[0x84 / 2], cliprect.min_y);
- display_rect.max_y = std::min((int)m_vreg[0x86 / 2] - 1, cliprect.max_y);
-
- /* int flipscreen = m_vreg[0x98 / 2]; (TBA) */
-
- screen.priority().fill(0, cliprect);
-
- // guess for X-Day 2 (flames in attract), seems wrong for Emeraldia but unsure
-// bitmap.fill(0xff, cliprect); /* background color? */
- bitmap.fill((m_vreg[0xba / 2] & 0xf) << 8, cliprect);
-
- if (m_vreg[0x8e / 2] && screen_enabled(display_rect) == true)
- {
- /* gfx enabled */
- if (m_palette_is_dirty)
- {
- /* palette updates are delayed when graphics are disabled */
- for (int which = 0; which < 0x1000; which++)
- {
- UpdatePalette(which);
- }
- m_palette_is_dirty = 0;
- }
-
- for (int priority = 0; priority < 8; priority++)
- {
- for (int which = 4; which >= 0; which--)
- {
- int pri;
- if (which == 4)
- {
- pri = m_vreg[0xa0 / 2 + 5] & 0x7;
- }
- else
- {
- pri = m_vreg[0xa0 / 2 + which] & 0x7;
- }
- if (pri == priority)
- {
- draw_background(screen, bitmap, display_rect, which, priority);
- }
- } /* next tilemap */
- } /* next priority level */
-
- draw_sprites(screen, bitmap, display_rect);
- } /* gfx enabled */
- return 0;
-}
-
-/*
-roz bad in emeraldaj - blit param?
-
-$efff20: sprite control: 0x3a,0x3e,0x3f
- bit 0x01 selects spriteram bank
-
- 0 2 4 6 8 a c e
-$efff00: src0 src1 src2 dst0 dst1 dst2 BANK [src
-$efff10: src] [dst dst] #BYT BLIT eINT 001f 0001
-$efff20: 003f 003f IACK ---- ---- ---- ---- ----
-...
-$efff80: 0050 0170 0020 0100 0170 POS? 0000 GFXE
-$efff90: 0000 0001 0002 0003 FLIP ---- ---- ----
-$efffa0: PRI PRI PRI PRI ???? PRI 00c0 ---- priority (0..7)
-$efffb0: CLR CLR CLR CLR 0001 CLR BPP ---- color (0..f), bpp flag per layer
-$efffc0: RZXX RZXY RZYX RZYY RZX0 RZY0 0044 ---- ROZ
-
-
-Emeralda: 0048 0177 0020 0100 0000 00f0 0000 0001 in-game
- 0050 0170 0020 0100 0000 00f0 0000 0001 self test
-
-NumanAth: 0050 0170 0020 0100 0170 00d8 0000 0001 in-game
-
-
-*/