1 // license:BSD-3-Clause
2 // copyright-holders:Luca Elia
3 /***************************************************************************
4 
5                             -= Gal's Panic II =-
6 
7                     driver by   Luca Elia (l.elia@tin.it)
8 
9 
10 ***************************************************************************/
11 
12 #include "emu.h"
13 #include "includes/galpani2.h"
14 #include "screen.h"
15 
16 /*
17 304000:0040 0000 0100 0000-0000 0000 0000 0000      (Sprites regs)
18 304010:16C0 0200 16C0 0200-16C0 0200 16C0 0200
19 */
20 
21 /***************************************************************************
22 
23 
24                         Palettized Background Layers
25 
26 
27 ***************************************************************************/
28 
29 
30 #ifdef UNUSED_DEFINITION
galpani2_bg8_regs_r(offs_t offset,int n)31 inline uint16_t galpani2_state::galpani2_bg8_regs_r(offs_t offset, int n)
32 {
33 	switch (offset * 2)
34 	{
35 		case 0x16:  return machine().rand() & 1;
36 		default:
37 			logerror("%s: Warning, bg8 #%d screen reg %04X read\n",machine().describe_context(),_n_,offset*2);
38 	}
39 	return m_bg8_regs[_n_][offset];
40 }
41 
42 /*
43     000-3ff     row? scroll
44     400         ?
45     800-bff     col? scroll
46     c04         0003 flip, 0300 flip?
47     c1c/e       01ff scroll, 3000 ?
48 */
galpani2_bg8_regs_w(offs_t offset,uint16_t data,uint16_t mem_mask,int _n_)49 inline void galpani2_state::galpani2_bg8_regs_w(offs_t offset, uint16_t data, uint16_t mem_mask, int _n_)
50 {
51 	COMBINE_DATA(&m_bg8_regs[_n_][offset]);
52 }
53 
galpani2_bg8_regs_0_r(offs_t offset)54 uint16_t galpani2_state::galpani2_bg8_regs_0_r(offs_t offset) { return galpani2_bg8_regs_r(offset, 0); }
galpani2_bg8_regs_1_r(offs_t offset)55 uint16_t galpani2_state::galpani2_bg8_regs_1_r(offs_t offset) { return galpani2_bg8_regs_r(offset, 1); }
56 
galpani2_bg8_regs_0_w(offs_t offset,uint16_t data,uint16_t mem_mask)57 void galpani2_state::galpani2_bg8_regs_0_w(offs_t offset, uint16_t data, uint16_t mem_mask) { galpani2_bg8_regs_w(offset, data, mem_mask, 0); }
galpani2_bg8_regs_1_w(offs_t offset,uint16_t data,uint16_t mem_mask)58 void galpani2_state::galpani2_bg8_regs_1_w(offs_t offset, uint16_t data, uint16_t mem_mask) { galpani2_bg8_regs_w(offset, data, mem_mask, 1); }
59 #endif
60 
61 
62 
63 /***************************************************************************
64 
65 
66                                 Screen Drawing
67 
68 
69 ***************************************************************************/
70 
71 // based on videos these 8-bit layers actually get *blended* against the RGB555 layer
72 // it should be noted that in the layer at 0x500000 the upper 8 bits are set too, this could be related
73 
74 // scrolling is based on sync between sprite and this layer during the 'keyhole viewer' between rounds (use cheats)
copybg8(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect,int layer)75 void galpani2_state::copybg8(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int layer)
76 {
77 	int x = + ( *m_bg8_scrollx[layer] + 0x200 - 0x1be );
78 	int y = + ( *m_bg8_scrolly[layer] + 0x200 - 0x0f5 );
79 	uint16_t* ram = m_bg8[layer];
80 
81 	pen_t const *const clut = &m_bg8palette->pen(0);
82 	for (int xx = 0; xx < 320; xx++)
83 	{
84 		for (int yy = 0; yy < 240; yy++)
85 		{
86 			uint16_t pen = ram[(((y + yy) & 0xff) * 512) + ((x + xx) & 0x1ff)];
87 			if (pen) bitmap.pix(yy, xx) = clut[pen & 0xff];
88 		}
89 	}
90 }
91 
92 // this seems to be 256x256 pages (arranged as 1024*256), but the game resolution is 320x240
93 // https://www.youtube.com/watch?v=2b2SLFtC0uA is a video of the galpanic2j set, and shows the RGB pattern at
94 // startup covering all screen lines - is the hardware mixing bitmaps of different resolutions or is there a
95 // line select somewhere?  I should find the gal images and find what resolution they're stored at too.
96 // (or is this just wrong format / layout due to protection?)
copybg15(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)97 void galpani2_state::copybg15(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
98 {
99 	uint16_t* ram = m_bg15 + 0x40000/2;
100 
101 	//int x = 0;
102 	//int y = 0;
103 
104 	pen_t const *const clut = &m_bg15palette->pen(0);
105 	for (int xx = 0; xx < 320; xx++)
106 	{
107 		for (int yy = 0; yy < 240; yy++)
108 		{
109 			uint16_t pen = ram[(xx * 0x800) + yy];
110 			bitmap.pix(yy, xx) = clut[pen & 0x7fff];
111 		}
112 	}
113 }
114 
screen_update_galpani2(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)115 uint32_t galpani2_state::screen_update_galpani2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
116 {
117 	int layers_ctrl = -1;
118 
119 #if 1 // MAME_DEBUG
120 if (machine().input().code_pressed(KEYCODE_Z))
121 {
122 	int msk = 0;
123 	if (machine().input().code_pressed(KEYCODE_Q))  msk |= 1;
124 	if (machine().input().code_pressed(KEYCODE_W))  msk |= 2;
125 	if (machine().input().code_pressed(KEYCODE_E))  msk |= 4;
126 	if (machine().input().code_pressed(KEYCODE_A))  msk |= 8;
127 	if (msk != 0) layers_ctrl &= msk;
128 }
129 #endif
130 
131 	bitmap.fill(0, cliprect);
132 	screen.priority().fill(0, cliprect);
133 
134 /*  test mode:
135     304000:0040 0000 0100 0000-0000 0000 0000 0000      (Sprite regs)
136     304010:16C0 0200 16C0 0200-16C0 0200 16C0 0200
137     16c0/40 = 5b        200/40 = 8
138     scrollx = f5, on screen x should be 0 (f5+5b = 150) */
139 
140 	if (layers_ctrl & 0x1) copybg15(screen, bitmap, cliprect);
141 	if (layers_ctrl & 0x2) copybg8(screen, bitmap, cliprect, 0);
142 	if (layers_ctrl & 0x4) copybg8(screen, bitmap, cliprect, 1);
143 	if (layers_ctrl & 0x8)
144 	{
145 		m_kaneko_spr->render_sprites(cliprect, m_spriteram, m_spriteram.bytes());
146 		m_kaneko_spr->copybitmap(bitmap, cliprect, screen.priority());
147 	}
148 	return 0;
149 }
150