seta2.cpp - further work on zooming (nw)

This commit is contained in:
David Haywood 2020-05-11 15:50:38 +01:00 committed by GitHub
parent 2029bb43b4
commit 216b2a106f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 46 deletions

View File

@ -4416,7 +4416,7 @@ GAME( 1997, reelquak, 0, reelquak, reelquak, seta2_state, empty_init,
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( 1997, staraudi, 0, staraudi, staraudi, staraudi_state, empty_init, ROT0, "Namco", "Star Audition", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING ) // needs flipscreen hooking up properly with new code to function at all
GAME( 1999, pzlbowl, 0, pzlbowl, pzlbowl, seta2_state, empty_init, ROT0, "MOSS / Nihon System", "Puzzle De Bowling (Japan)", MACHINE_NO_COCKTAIL )

View File

@ -84,9 +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, int realscanline);
int calculate_global_xoffset(int nozoom_fixedpalette_fixedposition);
int calculate_global_yoffset(int nozoom_fixedpalette_fixedposition);
void draw_sprites_line(bitmap_ind16 &bitmap, const rectangle &cliprect, int scanline, int realscanline, int xoffset, uint32_t xzoom, bool xzoominverted);
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
@ -138,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 screenline, 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, uint32_t xzoom, 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

@ -290,7 +290,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 screenline, 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, uint32_t xzoom, int use_shadow, int screenline, int line, int opaque)
{
struct drawmodes
{
@ -323,28 +323,35 @@ inline void seta2_state::drawgfx_line(bitmap_ind16 &bitmap, const rectangle &cli
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);
const int dx = flipx ? (-1) : (1);
int x0 = flipx ? (base_sx + (8*xzoom) - xzoom) : (base_sx);
int x1 = flipx ? (base_sx - xzoom) : (x0 + (8*xzoom));
const int dx = flipx ? (-xzoom) : (xzoom);
int column = 0;
int minx = cliprect.min_x << 16;
int maxx = cliprect.max_x << 16;
for (int sx = x0; sx != x1; sx += dx)
{
uint8_t pen = (source[column++] & gfx_mask) >> gfx_shift;
if (sx >= cliprect.min_x && sx <= cliprect.max_x)
if (sx >= minx && sx <= maxx)
{
int realsx = sx >> 16;
if (pen || opaque)
{
if (!shadow)
{
dest[sx] = (realcolor + pen) & 0x7fff;
dest[realsx] = (realcolor + pen) & 0x7fff;
}
else
{
int pen_shift = 15 - shadow;
int pen_mask = (1 << pen_shift) - 1;
dest[sx] = ((dest[sx] & pen_mask) | (pen << pen_shift)) & 0x7fff;
dest[realsx] = ((dest[realsx] & pen_mask) | (pen << pen_shift)) & 0x7fff;
}
}
}
@ -403,8 +410,9 @@ inline void seta2_state::get_tile(uint16_t* spriteram, int is_16x16, int x, int
}
}
int seta2_state::calculate_global_xoffset(int special)
int seta2_state::calculate_global_xoffset(int nozoom_fixedpalette_fixedposition)
{
/*
int global_xoffset = (m_vregs[0x12/2] & 0x7ff); // and 0x10/2 for low bits
if (global_xoffset & 0x400)
global_xoffset -= 0x800;
@ -420,14 +428,17 @@ int seta2_state::calculate_global_xoffset(int special)
{
global_xoffset -= 0x14f;
}
*/
if (special)
int global_xoffset = 0;
if (nozoom_fixedpalette_fixedposition)
global_xoffset = 0x80;
return global_xoffset;
}
int seta2_state::calculate_global_yoffset(int special)
int seta2_state::calculate_global_yoffset(int nozoom_fixedpalette_fixedposition)
{
// Sprites list
//int global_yoffset = (m_vregs[0x1a / 2] & 0x7ff); // and 0x18/2 for low bits
@ -437,18 +448,15 @@ int seta2_state::calculate_global_yoffset(int special)
//global_yoffset += 1; // +2 for myangel / myangel2?
int global_yoffset = 0;
if (special)
if (nozoom_fixedpalette_fixedposition)
global_yoffset = -0x90;
return global_yoffset;
}
void seta2_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int scanline, int realscanline)
void seta2_state::draw_sprites_line(bitmap_ind16 &bitmap, const rectangle &cliprect, int scanline, int realscanline, int xoffset, uint32_t xzoom, bool xzoominverted)
{
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();
@ -472,7 +480,7 @@ void seta2_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect,
int global_sizey = yoffs & 0xfc00;
int special = num & 0x4000; // ignore various things including global offsets, zoom. different palette selection too?
int nozoom_fixedpalette_fixedposition = num & 0x4000; // ignore various things including global offsets, zoom. different palette selection too?
bool opaque = num & 0x2000;
int use_global_size = num & 0x1000;
int use_shadow = num & 0x0800;
@ -485,18 +493,25 @@ void seta2_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect,
if (yoffs & 0x200)
yoffs -= 0x400;
int global_xoffset = calculate_global_xoffset(special);
int global_yoffset = calculate_global_yoffset(special);
int global_xoffset = calculate_global_xoffset(nozoom_fixedpalette_fixedposition);
int global_yoffset = calculate_global_yoffset(nozoom_fixedpalette_fixedposition);
int usedscanline;
if (special)
int usedxoffset;
uint32_t usedxzoom;
if (nozoom_fixedpalette_fixedposition)
{
use_shadow = 0;
// which_gfx = 4 << 8;
usedscanline = realscanline; // no zooming?
usedxzoom = 0x10000;
usedxoffset = 0;
}
else
{
usedscanline = scanline;
usedxzoom = xzoom;
usedxoffset = xoffset;
}
// Number of single-sprites
@ -597,7 +612,10 @@ void seta2_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect,
if ((dst_x >= firstcolumn - 8) && (dst_x <= lastcolumn)) // reelnquak reels are heavily glitched without this check
{
drawgfx_line(bitmap, cliprect, which_gfx, m_spritegfx->get_data(m_realtilenumber[code]), color << 4, flipx, flipy, dst_x, use_shadow, realscanline, tileline, opaque);
uint32_t realsx = dst_x;
realsx -= usedxoffset>>16; // need to refactor, this causes loss of lower 16 bits of offset which are important in zoomed cases for precision
realsx = realsx * usedxzoom;
drawgfx_line(bitmap, cliprect, which_gfx, m_spritegfx->get_data(m_realtilenumber[code]), color << 4, flipx, flipy, realsx, usedxzoom, use_shadow, realscanline, tileline, opaque);
}
}
}
@ -670,7 +688,7 @@ void seta2_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect,
int y = (line >> 3);
line &= 0x7;
if (special)
if (nozoom_fixedpalette_fixedposition)
{
// grdians map...
color = 0x7ff;
@ -679,7 +697,10 @@ void seta2_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect,
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, realscanline, line, opaque);
uint32_t realsx = (sx + x * 8);
realsx -= usedxoffset>>16; // need to refactor, this causes loss of lower 16 bits of offset which are important in zoomed cases for precision
realsx = realsx * usedxzoom;
drawgfx_line(bitmap, cliprect, which_gfx, m_spritegfx->get_data(m_realtilenumber[realcode]), color << 4, flipx, flipy, realsx, usedxzoom, use_shadow, realscanline, line, opaque);
}
}
@ -707,16 +728,11 @@ 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);
if (!m_vregs.found())
return; // ablastb (bootleg) doesn't have obvious video registers, so just abandon, probably needs a different driver
//printf("yoffset: %04x%04x yzoom: %04x%04x | xoffset: %04x%04x xzoom: %04x%04x \n", m_vregs[0x1a/2], m_vregs[0x18/2], m_vregs[0x1e/2], m_vregs[0x1c/2] , m_vregs[0x12/2], m_vregs[0x10/2], m_vregs[0x16/2], m_vregs[0x14/2]);
// TODO the global yscroll should be applied here too as it can be sub-pixel for precision in zoomed cases
uint32_t yoffset = (m_vregs[0x1a / 2] << 16) | m_vregs[0x18 / 2];
yoffset &= 0x07ffffff;
yoffset = 0x07ffffff - yoffset;
@ -724,6 +740,7 @@ void seta2_state::draw_sprites(bitmap_ind16& bitmap, const rectangle& cliprect)
uint32_t yzoom = (m_vregs[0x1e / 2] << 16) | m_vregs[0x1c / 2];
yzoom &= 0x07ffffff;
bool yzoominverted = false;
bool xzoominverted = false;
if (yzoom & 0x04000000)
{
@ -731,6 +748,39 @@ void seta2_state::draw_sprites(bitmap_ind16& bitmap, const rectangle& cliprect)
yzoominverted = true;
}
int xoffset = (m_vregs[0x12 / 2] << 16) | m_vregs[0x10 / 2];
xoffset &= 0x07ffffff;
if (xoffset & 0x04000000)
xoffset -= 0x08000000;
//xoffset = 0x07ffffff - xoffset;
uint32_t xzoom = (m_vregs[0x16 / 2] << 16) | m_vregs[0x14 / 2];
if (xzoom & 0x04000000)
{
xzoom = 0x8000000 - xzoom;
xzoominverted = true;
}
if (!xzoom)
return;
uint64_t inc = 0x100000000ULL;
uint32_t inc2 = inc / xzoom;
//printf("xinc is %04x xoom %04x xoffset is %4x\n", inc2, xzoom, xoffset);
for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
rectangle tempcliprect(cliprect);
tempcliprect.sety(y, y);
int yy;
if (!yzoominverted)
@ -751,7 +801,7 @@ void seta2_state::draw_sprites(bitmap_ind16& bitmap, const rectangle& cliprect)
}
draw_sprites(bitmap, tempcliprect, yy, y);
draw_sprites_line(bitmap, tempcliprect, yy, y, xoffset, inc2, xzoominverted);
}
}