refactor seta2.cpp in preparation for adding zooming (nw)

This commit is contained in:
DavidHaywood 2020-05-08 21:40:17 +01:00
parent 0d5266c1d9
commit fa46c10a4d
3 changed files with 161 additions and 110 deletions

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:Luca Elia
// copyright-holders:Luca Elia, David Haywood
/***************************************************************************
-= Newer Seta Hardware =-
@ -4400,20 +4400,32 @@ ROM_START( telpacfl )
ROM_END
GAME( 1994, gundamex, 0, gundamex, gundamex, seta2_state, empty_init, ROT0, "Banpresto", "Mobile Suit Gundam EX Revue", 0 )
GAME( 1995, grdians, 0, grdians, grdians, seta2_state, empty_init, ROT0, "Winkysoft (Banpresto license)", "Guardians / Denjin Makai II (P-FG01-1 PCB)", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1995, grdiansa, grdians, grdians, grdians, seta2_state, empty_init, ROT0, "Winkysoft (Banpresto license)", "Guardians / Denjin Makai II (P0-113A PCB)", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1996, mj4simai, 0, seta2, mj4simai, mj4simai_state, empty_init, ROT0, "Maboroshi Ware", "Wakakusamonogatari Mahjong Yonshimai (Japan)", MACHINE_NO_COCKTAIL )
GAME( 1996, myangel, 0, myangel, myangel, seta2_state, empty_init, ROT0, "MOSS / Namco", "Kosodate Quiz My Angel (Japan)", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1997, myangel2, 0, myangel2, myangel2, seta2_state, empty_init, ROT0, "MOSS / Namco", "Kosodate Quiz My Angel 2 (Japan)", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1996, telpacfl, 0, telpacfl, telpacfl, seta2_state, empty_init, ROT270, "Sunsoft", "TelePachi Fever Lion (V1.0)", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1997, reelquak, 0, reelquak, reelquak, seta2_state, empty_init, ROT0, "<unknown>", "Reel'N Quake! (Version 1.05)", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
GAME( 199?, endrichs, 0, reelquak, endrichs, seta2_state, empty_init, ROT0, "E.N.Tiger", "Endless Riches (Ver 1.20)", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1997, staraudi, 0, staraudi, staraudi, staraudi_state, empty_init, ROT0, "Namco", "Star Audition", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1999, pzlbowl, 0, pzlbowl, pzlbowl, seta2_state, empty_init, ROT0, "MOSS / Nihon System", "Puzzle De Bowling (Japan)", MACHINE_NO_COCKTAIL )
GAME( 2000, penbros, 0, penbros, penbros, seta2_state, empty_init, ROT0, "Subsino", "Penguin Brothers (Japan)", MACHINE_NO_COCKTAIL )
GAME( 2000, ablast, penbros, penbros, penbros, seta2_state, empty_init, ROT0, "Subsino", "Hong Tian Lei (A-Blast) (Japan)", MACHINE_NO_COCKTAIL ) // 轟天雷/Hōng tiān léi
GAME( 2000, ablastb, penbros, ablastb, penbros, seta2_state, empty_init, ROT0, "bootleg", "Hong Tian Lei (A-Blast) (bootleg)", MACHINE_NO_COCKTAIL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) // at least "tilemap sprite" scrolly flag differs, FPGA instead of x1-010
GAME( 2000, namcostr, 0, namcostr, funcube, seta2_state, init_namcostr, ROT0, "Namco", "Namco Stars", MACHINE_NO_COCKTAIL | MACHINE_NOT_WORKING )
GAME( 2000, deerhunt, 0, samshoot, deerhunt, seta2_state, empty_init, ROT0, "Sammy USA Corporation", "Deer Hunting USA V4.3", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
GAME( 2000, deerhunta, deerhunt, samshoot, deerhunt, seta2_state, empty_init, ROT0, "Sammy USA Corporation", "Deer Hunting USA V4.2", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
GAME( 2000, deerhuntb, deerhunt, samshoot, deerhunt, seta2_state, empty_init, ROT0, "Sammy USA Corporation", "Deer Hunting USA V4.0", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
@ -4421,14 +4433,22 @@ GAME( 2000, deerhuntc, deerhunt, samshoot, deerhunt, seta2_state, empty_init,
GAME( 2000, deerhuntd, deerhunt, samshoot, deerhunt, seta2_state, empty_init, ROT0, "Sammy USA Corporation", "Deer Hunting USA V2", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
GAME( 2000, deerhunte, deerhunt, samshoot, deerhunt, seta2_state, empty_init, ROT0, "Sammy USA Corporation", "Deer Hunting USA V1", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
GAME( 2000, deerhuntj, deerhunt, samshoot, deerhunt, seta2_state, empty_init, ROT0, "Sammy USA Corporation", "Deer Hunting USA V4.4.1 (Japan)", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
GAME( 2001, turkhunt, 0, samshoot, turkhunt, seta2_state, empty_init, ROT0, "Sammy USA Corporation", "Turkey Hunting USA V1.00", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
GAME( 2001, wschamp, 0, samshoot, wschamp, seta2_state, empty_init, ROT0, "Sammy USA Corporation", "Wing Shooting Championship V2.00", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
GAME( 2001, wschampa, wschamp, samshoot, wschamp, seta2_state, empty_init, ROT0, "Sammy USA Corporation", "Wing Shooting Championship V1.01", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
GAME( 2001, wschampb, wschamp, samshoot, wschamp, seta2_state, empty_init, ROT0, "Sammy USA Corporation", "Wing Shooting Championship V1.00", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
GAME( 2002, trophyh, 0, samshoot, trophyh, seta2_state, empty_init, ROT0, "Sammy USA Corporation", "Trophy Hunting - Bear & Moose V1.00", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
GAME( 2002, trophyht, trophyh, samshoot, trophyht, seta2_state, empty_init, ROT0, "Sammy USA Corporation", "Trophy Hunting - Bear & Moose V1.00 (location test)", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS )
GAME( 2000, funcube, 0, funcube, funcube, funcube_state, init_funcube, ROT0, "Namco", "Funcube (v1.5)", MACHINE_NO_COCKTAIL )
GAME( 2001, funcube2, 0, funcube2, funcube, funcube_state, init_funcube2, ROT0, "Namco", "Funcube 2 (v1.1)", MACHINE_NO_COCKTAIL )
GAME( 2001, funcube3, 0, funcube3, funcube, funcube_state, init_funcube3, ROT0, "Namco", "Funcube 3 (v1.1)", MACHINE_NO_COCKTAIL )
GAME( 2001, funcube4, 0, funcube2, funcube, funcube_state, init_funcube2, ROT0, "Namco", "Funcube 4 (v1.0)", MACHINE_NO_COCKTAIL )
GAME( 2002, funcube5, 0, funcube2, funcube, funcube_state, init_funcube2, ROT0, "Namco", "Funcube 5 (v1.0)", MACHINE_NO_COCKTAIL )

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:Luca Elia
// copyright-holders:Luca Elia, David Haywood
#ifndef MAME_INCLUDES_SETA2_H
#define MAME_INCLUDES_SETA2_H
@ -84,6 +84,9 @@ protected:
DECLARE_READ16_MEMBER(spriteram_r);
DECLARE_WRITE16_MEMBER(spriteram_w);
int calculate_global_xoffset(int special);
int calculate_global_yoffset(int special);
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int scanline);
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
@ -135,7 +138,7 @@ protected:
std::unique_ptr<uint16_t[]> m_private_spriteram;
private:
void drawgfx_line(bitmap_ind16 &bitmap, const rectangle &cliprect, int gfx, const uint8_t* const addr, const uint32_t realcolor, int flipx, int flipy, int base_sx, int shadow, int realline, int line, int opaque);
void drawgfx_line(bitmap_ind16 &bitmap, const rectangle &cliprect, int gfx, const uint8_t* const addr, const uint32_t realcolor, int flipx, int flipy, int base_sx, int shadow, int screenline, int line, int opaque);
inline void get_tile(uint16_t* spriteram, int is_16x16, int x, int y, int page, int& code, int& attr, int& flipx, int& flipy, int& color);
std::unique_ptr<uint32_t[]> m_realtilenumber;

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:Luca Elia
// copyright-holders:Luca Elia, David Haywood
/***************************************************************************
-= Newer Seta Hardware =-
@ -75,6 +75,15 @@
The low bits of the pens from a "shadowing" tile (regardless of color code)
substitute the top bits of the color index (0-7fff) in the frame buffer.
Note:
Based on raster effect usage in Guardians it would appear this list is
transformed into an alt format by the hardware. It is unknown if this
alt format is visible to the CPU for reading, or only writing the updated
scroll positions. We could do with attempting a RAM capture to see what
this format really looks like if it is CPU visible as the current
implementation of this copy / reformat operation is pure guesswork
***************************************************************************/
#include "emu.h"
@ -282,7 +291,7 @@ WRITE16_MEMBER(seta2_state::spriteram_w)
***************************************************************************/
inline void seta2_state::drawgfx_line(bitmap_ind16 &bitmap, const rectangle &cliprect, int which_gfx, const uint8_t* const addr, const uint32_t realcolor, int flipx, int flipy, int base_sx, int use_shadow, int realline, int line, int opaque)
inline void seta2_state::drawgfx_line(bitmap_ind16 &bitmap, const rectangle &cliprect, int which_gfx, const uint8_t* const addr, const uint32_t realcolor, int flipx, int flipy, int base_sx, int use_shadow, int screenline, int line, int opaque)
{
struct drawmodes
{
@ -313,7 +322,7 @@ inline void seta2_state::drawgfx_line(bitmap_ind16 &bitmap, const rectangle &cli
const uint8_t* const source = flipy ? addr + (7 - line) * 8 : addr + line * 8;
uint16_t* dest = &bitmap.pix16(realline);
uint16_t* dest = &bitmap.pix16(screenline);
const int x0 = flipx ? (base_sx + 8 - 1) : (base_sx);
const int x1 = flipx ? (base_sx - 1) : (x0 + 8);
@ -395,19 +404,8 @@ inline void seta2_state::get_tile(uint16_t* spriteram, int is_16x16, int x, int
}
}
void seta2_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
int seta2_state::calculate_global_xoffset(int special)
{
if (!m_vregs.found())
return; // ablastb (bootleg) doesn't have obvious video registers, so just abandon, probably needs a different driver
// Sprites list
uint16_t *spriteram = m_spriteram;
int global_yoffset = (m_vregs[0x1a/2] & 0x7ff); // and 0x18/2 for low bits
if (global_yoffset & 0x400)
global_yoffset -= 0x800;
global_yoffset += 1; // +2 for myangel / myangel2?
int global_xoffset = (m_vregs[0x12/2] & 0x7ff); // and 0x10/2 for low bits
if (global_xoffset & 0x400)
global_xoffset -= 0x800;
@ -424,6 +422,35 @@ void seta2_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
global_xoffset -= 0x14f;
}
if (special)
global_xoffset = 0x80;
return global_xoffset;
}
int seta2_state::calculate_global_yoffset(int special)
{
// Sprites list
int global_yoffset = (m_vregs[0x1a / 2] & 0x7ff); // and 0x18/2 for low bits
if (global_yoffset & 0x400)
global_yoffset -= 0x800;
global_yoffset += 1; // +2 for myangel / myangel2?
if (special)
global_yoffset = -0x90;
return global_yoffset;
}
void seta2_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int scanline)
{
if (!m_vregs.found())
return; // ablastb (bootleg) doesn't have obvious video registers, so just abandon, probably needs a different driver
uint16_t* spriteram = m_spriteram;
uint16_t *s1 = m_private_spriteram.get();
for (; s1 < &m_private_spriteram[0x1000 / 2]; s1 += 4)
@ -451,12 +478,12 @@ void seta2_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
xoffs &= 0x3ff;
yoffs &= 0x3ff;
int global_xoffset = calculate_global_xoffset(special);
int global_yoffset = calculate_global_yoffset(special);
if (special)
{
use_shadow = 0;
// which_gfx = 4 << 8;
global_yoffset = -0x90;
global_xoffset = 0x80;
}
// Number of single-sprites
@ -471,108 +498,85 @@ void seta2_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
if (sprite & 0x8000)
{
// "floating tilemap" sprite
// the 'floating tilemap sprites' are just a window into the tilemap, the position of the sprite does not change the scroll values
int sx = s2[0];
// get everything we need to calculate if sprite covers this scanline
int sy = s2[1];
int scrollx = s2[2];
int scrolly = s2[3];
int is_16x16 = (scrollx & 0x8000) >> 15;
int page = (scrollx & 0x7c00) >> 10;
int local_sizex = sx & 0xfc00;
int local_sizey = sy & 0xfc00;
sx &= 0x3ff;
sy += global_yoffset;
sy &= 0x1ff;
if (sy & 0x100)
sy -= 0x200;
int height = use_global_size ? global_sizey : local_sizey;
height = ((height & 0xfc00) >> 10) + 1;
int firstline = (sy + yoffs) & 0x1ff;
if (firstline & 0x100) firstline -= 0x200;
int endline = firstline + height * 0x10 - 1;
// if the sprite doesn't cover this scanline, bail now
if (firstline > scanline) continue;
if (endline < scanline) continue;
// get everything we need to calculate if sprite is actually within the x co-ordinates of the screen
int sx = s2[0];
int local_sizex = sx & 0xfc00;
sx &= 0x3ff;
sx -= global_xoffset;
int width = use_global_size ? global_sizex : local_sizex;
int height = use_global_size ? global_sizey : local_sizey;
height = ((height & 0xfc00) >> 10) + 1;
width = ((width & 0xfc00) >> 10)/* + 1*/; // reelquak reels
if (!width)
continue;
scrollx &= 0x3ff;
int firstcolumn = (sx + xoffs);
firstcolumn = (firstcolumn & 0x1ff) - (firstcolumn & 0x200);
int lastcolumn = firstcolumn + width * 0x10 - 1;
// if the sprite isn't within the x-coordinates of the screen, bail
if (firstcolumn > cliprect.max_x) continue;
if (lastcolumn < cliprect.min_x) continue;
// otherwise get the rest of the things we need to draw
int scrolly = s2[3];
scrolly &= 0x1ff;
scrolly += global_yoffset;
int sourceline = (scanline - scrolly) & 0x1ff;
rectangle clip;
// sprite clipping region (x)
clip.min_x = (sx + xoffs);
clip.min_x = (clip.min_x & 0x1ff) - (clip.min_x & 0x200);
clip.max_x = clip.min_x + width * 0x10 - 1;
int scrollx = s2[2];
int is_16x16 = (scrollx & 0x8000) >> 15;
int page = (scrollx & 0x7c00) >> 10;
scrollx &= 0x3ff;
if (clip.min_x > cliprect.max_x) continue;
if (clip.max_x < cliprect.min_x) continue;
if (clip.min_x < cliprect.min_x) clip.min_x = cliprect.min_x;
if (clip.max_x > cliprect.max_x) clip.max_x = cliprect.max_x;
// sprite clipping region (y)
int basey = (sy + yoffs) & 0x1ff;
if (basey & 0x100) basey -= 0x200;
clip.min_y = basey;
clip.max_y = clip.min_y + height * 0x10 - 1;
if (clip.min_y > cliprect.max_y) continue;
if (clip.max_y < cliprect.min_y) continue;
if (clip.min_y < cliprect.min_y) clip.min_y = cliprect.min_y;
if (clip.max_y > cliprect.max_y) clip.max_y = cliprect.max_y;
for (int realline = clip.min_y; realline <= clip.max_y; realline++)
// we treat 16x16 tiles as 4 8x8 tiles, so while the tilemap is 0x40 tiles wide in memory, that becomes 0x80 tiles in 16x16 mode, with the data wrapping in 8x8 mode
for (int x = 0; x < 0x80; x++)
{
int sourceline = (realline - scrolly) & 0x1ff;
int code, attr, flipx, flipy, color;
// tilemap data is NOT buffered?
get_tile(spriteram, is_16x16, x * 8, sourceline, page, code, attr, flipx, flipy, color);
// we treat 16x16 tiles as 4 8x8 tiles, so while the tilemap is 0x40 tiles wide in memory, that becomes 0x80 tiles in 16x16 mode, with the data wrapping in 8x8 mode
for (int x = 0; x < 0x80; x++)
int tileline = sourceline & 0x07;
int dx = sx + (scrollx & 0x3ff) + xoffs + 0x10;
int px = (((dx + x * 8) + 0x10) & 0x3ff) - 0x10;
int dst_x = px & 0x3ff;
dst_x = (dst_x & 0x1ff) - (dst_x & 0x200);
if ((dst_x >= firstcolumn - 8) && (dst_x <= lastcolumn)) // reelnquak reels are heavily glitched without this check
{
int code, attr, flipx, flipy, color;
// tilemap data is NOT buffered?
get_tile(spriteram, is_16x16, x * 8, sourceline, page, code, attr, flipx, flipy, color);
int tileline = sourceline & 0x07;
int dx = sx + (scrollx & 0x3ff) + xoffs + 0x10;
int px = (((dx + x * 8) + 0x10) & 0x3ff) - 0x10;
int dst_x = px & 0x3ff;
dst_x = (dst_x & 0x1ff) - (dst_x & 0x200);
if ((dst_x >= clip.min_x - 8) && (dst_x <= clip.max_x))
{
drawgfx_line(bitmap, clip, which_gfx, m_spritegfx->get_data(m_realtilenumber[code]), color << 4, flipx, flipy, dst_x, use_shadow, realline, tileline, opaque);
}
drawgfx_line(bitmap, cliprect, which_gfx, m_spritegfx->get_data(m_realtilenumber[code]), color << 4, flipx, flipy, dst_x, use_shadow, scanline, tileline, opaque);
}
}
}
else
{
// "normal" sprite
int sx = s2[0];
int sy = s2[1];
int attr = s2[2];
int code = s2[3] + ((attr & 0x0007) << 16);
int flipx = (attr & 0x0010);
int flipy = (attr & 0x0008);
int color = (attr & 0xffe0) >> 5;
int sizex = use_global_size ? global_sizex : sx;
int sizey = use_global_size ? global_sizey : sy;
sizex = (1 << ((sizex & 0x0c00) >> 10)) - 1;
sizey = (1 << ((sizey & 0x0c00) >> 10)) - 1;
sx += xoffs;
sx = (sx & 0x1ff) - (sx & 0x200);
sx -= global_xoffset;
sizey = (1 << ((sizey & 0x0c00) >> 10)) - 1;
sy += yoffs;
sy += global_yoffset;
@ -582,35 +586,47 @@ void seta2_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
if (sy & 0x100)
sy -= 0x200;
int basecode = code &= ~((sizex + 1) * (sizey + 1) - 1); // see myangel, myangel2 and grdians
int firstline = sy;
int endline = (sy + (sizey + 1) * 8) - 1;
int realfirstline = firstline;
// if the sprite doesn't cover this scanline, bail now
if (firstline > scanline) continue;
if (endline < scanline) continue;
if (firstline < cliprect.min_y) realfirstline = cliprect.min_y;
if (endline > cliprect.max_y) endline = cliprect.max_y;
// otherwise get the rest of the things we need to draw
int attr = s2[2];
int code = s2[3] + ((attr & 0x0007) << 16);
int flipx = (attr & 0x0010);
int flipy = (attr & 0x0008);
int color = (attr & 0xffe0) >> 5;
for (int realline = realfirstline; realline <= endline; realline++)
int sx = s2[0];
int sizex = use_global_size ? global_sizex : sx;
sizex = (1 << ((sizex & 0x0c00) >> 10)) - 1;
sx += xoffs;
sx = (sx & 0x1ff) - (sx & 0x200);
sx -= global_xoffset;
int basecode = code &= ~((sizex + 1) * (sizey + 1) - 1); // see myangel, myangel2 and grdians
int line = scanline - firstline;
int y = (line >> 3);
line &= 0x7;
if (special)
{
int line = realline - firstline;
int y = (line >> 3);
line &= 0x7;
if (special)
{
// grdians map...
color = 0x7ff;
}
for (int x = 0; x <= sizex; x++)
{
int realcode = (basecode + (flipy ? sizey - y : y)*(sizex + 1)) + (flipx ? sizex - x : x);
drawgfx_line(bitmap, cliprect, which_gfx, m_spritegfx->get_data(m_realtilenumber[realcode]), color << 4, flipx, flipy, sx + x * 8, use_shadow, realline, line, opaque);
}
// grdians map...
color = 0x7ff;
}
for (int x = 0; x <= sizex; x++)
{
int realcode = (basecode + (flipy ? sizey - y : y)*(sizex + 1)) + (flipx ? sizex - x : x);
drawgfx_line(bitmap, cliprect, which_gfx, m_spritegfx->get_data(m_realtilenumber[realcode]), color << 4, flipx, flipy, sx + x * 8, use_shadow, scanline, line, opaque);
}
}
}
}
@ -634,6 +650,18 @@ TIMER_CALLBACK_MEMBER(seta2_state::raster_timer_done)
}
void seta2_state::draw_sprites(bitmap_ind16& bitmap, const rectangle& cliprect)
{
for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
rectangle tempcliprect(cliprect);
tempcliprect.sety(y,y);
draw_sprites(bitmap, tempcliprect, y);
}
}
/***************************************************************************