// license:BSD-3-Clause
// copyright-holders:Luca Elia
/***************************************************************************
-= Gal's Panic II =-
driver by Luca Elia (l.elia@tin.it)
***************************************************************************/
#include "emu.h"
#include "includes/galpani2.h"
#include "screen.h"
/*
304000:0040 0000 0100 0000-0000 0000 0000 0000 (Sprites regs)
304010:16C0 0200 16C0 0200-16C0 0200 16C0 0200
*/
/***************************************************************************
Palettized Background Layers
***************************************************************************/
#ifdef UNUSED_DEFINITION
inline uint16_t galpani2_state::galpani2_bg8_regs_r(address_space &space, offs_t offset, int n)
{
switch (offset * 2)
{
case 0x16: return machine().rand() & 1;
default:
logerror("%s: Warning, bg8 #%d screen reg %04X read\n",machine().describe_context(),_n_,offset*2);
}
return m_bg8_regs[_n_][offset];
}
/*
000-3ff row? scroll
400 ?
800-bff col? scroll
c04 0003 flip, 0300 flip?
c1c/e 01ff scroll, 3000 ?
*/
inline void galpani2_state::galpani2_bg8_regs_w(address_space &space, offs_t offset, uint16_t data, uint16_t mem_mask, int _n_)
{
COMBINE_DATA(&m_bg8_regs[_n_][offset]);
}
READ16_MEMBER( galpani2_bg8_regs_0_r ) { return galpani2_bg8_regs_r(space, offset, 0); }
READ16_MEMBER( galpani2_bg8_regs_1_r ) { return galpani2_bg8_regs_r(space, offset, 1); }
WRITE16_MEMBER( galpani2_bg8_regs_0_w ) { galpani2_bg8_regs_w(space, offset, data, mem_mask, 0); }
WRITE16_MEMBER( galpani2_bg8_regs_1_w ) { galpani2_bg8_regs_w(space, offset, data, mem_mask, 1); }
#endif
/***************************************************************************
Screen Drawing
***************************************************************************/
// based on videos these 8-bit layers actually get *blended* against the RGB555 layer
// it should be noted that in the layer at 0x500000 the upper 8 bits are set too, this could be related
// scrolling is based on sync between sprite and this layer during the 'keyhole viewer' between rounds (use cheats)
void galpani2_state::copybg8(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int layer)
{
int x = + ( *m_bg8_scrollx[layer] + 0x200 - 0x1be );
int y = + ( *m_bg8_scrolly[layer] + 0x200 - 0x0f5 );
uint16_t* ram = m_bg8[layer];
const pen_t *clut = &m_bg8palette->pen(0);
for (int xx = 0; xx < 320; xx++)
{
for (int yy = 0; yy < 240; yy++)
{
uint16_t pen = ram[(((y + yy) & 0xff) * 512) + ((x + xx) & 0x1ff)];
if (pen) bitmap.pix32(yy, xx) = clut[pen & 0xff];
}
}
}
// this seems to be 256x256 pages (arranged as 1024*256), but the game resolution is 320x240
// https://www.youtube.com/watch?v=2b2SLFtC0uA is a video of the galpanic2j set, and shows the RGB pattern at
// startup covering all screen lines - is the hardware mixing bitmaps of different resolutions or is there a
// line select somewhere? I should find the gal images and find what resolution they're stored at too.
// (or is this just wrong format / layout due to protection?)
void galpani2_state::copybg15(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
uint16_t* ram = m_bg15 + 0x40000/2;
//int x = 0;
//int y = 0;
const pen_t *clut = &m_bg15palette->pen(0);
for (int xx = 0; xx < 320; xx++)
{
for (int yy = 0; yy < 240; yy++)
{
uint16_t pen = ram[(xx * 0x800) + yy];
bitmap.pix32(yy, xx) = clut[pen & 0x7fff];
}
}
}
uint32_t galpani2_state::screen_update_galpani2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
int layers_ctrl = -1;
#if 1 // MAME_DEBUG
if (machine().input().code_pressed(KEYCODE_Z))
{
int msk = 0;
if (machine().input().code_pressed(KEYCODE_Q)) msk |= 1;
if (machine().input().code_pressed(KEYCODE_W)) msk |= 2;
if (machine().input().code_pressed(KEYCODE_E)) msk |= 4;
if (machine().input().code_pressed(KEYCODE_A)) msk |= 8;
if (msk != 0) layers_ctrl &= msk;
}
#endif
bitmap.fill(0, cliprect);
screen.priority().fill(0, cliprect);
/* test mode:
304000:0040 0000 0100 0000-0000 0000 0000 0000 (Sprite regs)
304010:16C0 0200 16C0 0200-16C0 0200 16C0 0200
16c0/40 = 5b 200/40 = 8
scrollx = f5, on screen x should be 0 (f5+5b = 150) */
if (layers_ctrl & 0x1) copybg15(screen, bitmap, cliprect);
if (layers_ctrl & 0x2) copybg8(screen, bitmap, cliprect, 0);
if (layers_ctrl & 0x4) copybg8(screen, bitmap, cliprect, 1);
if (layers_ctrl & 0x8) m_kaneko_spr->render_sprites(bitmap, cliprect, screen.priority(), m_spriteram, m_spriteram.bytes());
return 0;
}