1 // license:BSD-3-Clause
2 // copyright-holders:Ernesto Corvi
3 #include "emu.h"
4 #include "includes/wc90b.h"
5 
6 
7 /***************************************************************************
8 
9   Callbacks for the TileMap code
10 
11 ***************************************************************************/
12 
TILE_GET_INFO_MEMBER(wc90b_state::get_bg_tile_info)13 TILE_GET_INFO_MEMBER(wc90b_state::get_bg_tile_info)
14 {
15 	int attr = m_bgvideoram[tile_index];
16 	int tile = m_bgvideoram[tile_index + 0x800];
17 	tileinfo.set(1,
18 			 ((((attr & 3) + ((attr >> 1) & 4)))<<8) | tile | 0x800,
19 			(attr >> 4) | 0x10,
20 			0);
21 }
22 
TILE_GET_INFO_MEMBER(wc90b_state::get_fg_tile_info)23 TILE_GET_INFO_MEMBER(wc90b_state::get_fg_tile_info)
24 {
25 	int attr = m_fgvideoram[tile_index];
26 	int tile = m_fgvideoram[tile_index + 0x800];
27 	tileinfo.set(1,
28 			((((attr & 3) + ((attr >> 1) & 4)))<<8) | tile,
29 			attr >> 4,
30 			0);
31 }
32 
TILE_GET_INFO_MEMBER(wc90b_state::get_tx_tile_info)33 TILE_GET_INFO_MEMBER(wc90b_state::get_tx_tile_info)
34 {
35 	tileinfo.set(0,
36 			m_txvideoram[tile_index + 0x800] + ((m_txvideoram[tile_index] & 0x07) << 8),
37 			m_txvideoram[tile_index] >> 4,
38 			0);
39 }
40 
41 
42 
43 /***************************************************************************
44 
45   Start the video hardware emulation.
46 
47 ***************************************************************************/
48 
video_start()49 void wc90b_state::video_start()
50 {
51 	m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(wc90b_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 64, 32);
52 	m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(wc90b_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 64, 32);
53 	m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(wc90b_state::get_tx_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
54 
55 	m_fg_tilemap->set_transparent_pen(15);
56 	m_tx_tilemap->set_transparent_pen(15);
57 }
58 
59 
60 
61 /***************************************************************************
62 
63   Memory handlers
64 
65 ***************************************************************************/
66 
bgvideoram_w(offs_t offset,uint8_t data)67 void wc90b_state::bgvideoram_w(offs_t offset, uint8_t data)
68 {
69 	m_bgvideoram[offset] = data;
70 	m_bg_tilemap->mark_tile_dirty(offset & 0x7ff);
71 }
72 
fgvideoram_w(offs_t offset,uint8_t data)73 void wc90b_state::fgvideoram_w(offs_t offset, uint8_t data)
74 {
75 	m_fgvideoram[offset] = data;
76 	m_fg_tilemap->mark_tile_dirty(offset & 0x7ff);
77 }
78 
txvideoram_w(offs_t offset,uint8_t data)79 void wc90b_state::txvideoram_w(offs_t offset, uint8_t data)
80 {
81 	m_txvideoram[offset] = data;
82 	m_tx_tilemap->mark_tile_dirty(offset & 0x7ff);
83 }
84 
85 
86 
87 /***************************************************************************
88 
89   Display refresh
90 
91 ***************************************************************************/
92 
draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect,int priority)93 void wc90b_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int priority )
94 {
95 	/* draw all visible sprites of specified priority */
96 	for ( int offs = m_spriteram.bytes() - 8 ; offs >= 0 ; offs -= 8 )
97 	{
98 		if ( ( ~( m_spriteram[offs+3] >> 7 ) & 1 ) == priority )
99 		{
100 
101 			// 0   bbbb bbff   b = tile lower , f = flip bits
102 			// 1   yyyy yyyy
103 			// 2   xxxx xxxx
104 			// 3   PXcc cccc   P = priority X = x high, c = tile upper
105 			// 4   pppp ----   palette
106 
107 			int tilehigh = ( m_spriteram[offs + 3] & 0x3f ) << 6;
108 			int tilelow = m_spriteram[offs + 0];
109 			int flags = m_spriteram[offs + 4];
110 
111 			tilehigh += ( tilelow & 0xfc ) >> 2;
112 
113 			int sx = m_spriteram[offs + 2];
114 			if (!(m_spriteram[offs + 3] & 0x40)) sx -= 0x0100;
115 
116 			int sy = 240 - m_spriteram[offs + 1];
117 
118 			m_gfxdecode->gfx(2)->transpen(bitmap,cliprect, tilehigh,
119 					flags >> 4, /* color */
120 					tilelow & 1,   /* flipx */
121 					tilelow & 2,   /* flipy */
122 					sx,
123 					sy,15 );
124 		}
125 	}
126 }
127 
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)128 uint32_t wc90b_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
129 {
130 	m_bg_tilemap->set_scrollx(0,8 * (m_scroll2x[0] & 0x7f) + 256 - 4 + (m_scroll_x_lo[0] & 0x07));
131 	m_bg_tilemap->set_scrolly(0,m_scroll2y[0] + 1 + ((m_scroll2x[0] & 0x80) ? 256 : 0));
132 	m_fg_tilemap->set_scrollx(0,8 * (m_scroll1x[0] & 0x7f) + 256 - 6 + ((m_scroll_x_lo[0] & 0x38) >> 3));
133 	m_fg_tilemap->set_scrolly(0,m_scroll1y[0] + 1 + ((m_scroll1x[0] & 0x80) ? 256 : 0));
134 
135 	m_bg_tilemap->draw(screen, bitmap, cliprect, 0,0);
136 	draw_sprites(bitmap,cliprect, 1 );
137 	m_fg_tilemap->draw(screen, bitmap, cliprect, 0,0);
138 	m_tx_tilemap->draw(screen, bitmap, cliprect, 0,0);
139 	// TODO: if scoring on same Y as GOAL message, ball will be above it. Might be a btanb (or needs single pass draw + mix?)
140 	draw_sprites(bitmap,cliprect, 0 );
141 	return 0;
142 }
143 
draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect,int priority)144 void eurogael_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int priority )
145 {
146 	/* draw all visible sprites of specified priority */
147 
148 	// entry at start of RAM might not be a sprite
149 	for ( int offs = 0x200 - 4 ; offs >= 4 ; offs -= 4 )
150 	{
151 		if ( ( ( m_spriteram[offs+3] >> 4 ) & 1 ) == priority )
152 		{
153 			// this is wrong
154 
155 			// 0      bbbb bbbb   b = tile lower
156 			// 1      yyyy yyyy
157 			// 2      xxxx xxxx
158 			// 3      ffXP cccc   f = flip bits, P = priority (inverted vs. other bootlegs) X = X high?, c = tile upper
159 			// 0x200  ---- -ppp   p = palette
160 
161 			int tilehigh = ( m_spriteram[offs + 3] & 0x0f ) << 8;
162 			int attr = ( m_spriteram[offs + 3] & 0xf0 ) >> 4;
163 
164 			int tilelow = m_spriteram[offs + 0];
165 			int flags = m_spriteram[offs + 0x200];
166 
167 			tilehigh += tilelow;
168 
169 			int sx = m_spriteram[offs + 2];
170 			if (!(attr & 0x02)) sx -= 0x0100;
171 
172 			int sy = 240 - m_spriteram[offs + 1];
173 
174 			m_gfxdecode->gfx(2)->transpen(bitmap,cliprect, tilehigh,
175 					(flags & 0x7) | 8, /* color - palettes 0x0 - 0x7 never written? */
176 					attr & 4,   /* flipx */
177 					attr & 8,   /* flipy */
178 					sx,
179 					sy,15 );
180 		}
181 	}
182 }
183 
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)184 uint32_t eurogael_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
185 {
186 	// the code to write / clear tilemaps for fb and tx layers has been specifically modified to avoid writing to the last 4 bytes
187 	// and the game instead writes scroll values there instead, there is no code to copy from there, so it looks like these are the scroll regs
188 
189 	// each of the 3 layer has its own PCB, all PCBs look identical, so why does handling differ slightly?
190 
191 	int fg_scrollx = ((m_fgvideoram[0xffc]) | (m_fgvideoram[0xffd]<<8)) + 33;
192 	int fg_scrolly = ((m_fgvideoram[0xffe]) | (m_fgvideoram[0xfff]<<8)) + 1;
193 	int bg_scrollx = ((m_bgscroll[0xf00]) | (m_bgscroll[0xf01]<<8)) + 33;
194 	int bg_scrolly = ((m_bgscroll[0xf02]) | (m_bgscroll[0xf03]<<8)) + 1;
195 	int tx_scrollx = ((m_txvideoram[0xffc]) | (m_txvideoram[0xffd]<<8)) + 33;
196 	int tx_scrolly = ((m_txvideoram[0xffe]) | (m_txvideoram[0xfff]<<8)) + 1;
197 
198 	m_bg_tilemap->set_scrollx(0, bg_scrollx);
199 	m_bg_tilemap->set_scrolly(0, bg_scrolly);
200 	m_fg_tilemap->set_scrollx(0, fg_scrollx);
201 	m_fg_tilemap->set_scrolly(0, fg_scrolly);
202 	m_tx_tilemap->set_scrollx(0, tx_scrollx);
203 	m_tx_tilemap->set_scrolly(0, tx_scrolly);
204 
205 	m_bg_tilemap->draw(screen, bitmap, cliprect, 0,0);
206 	draw_sprites(bitmap,cliprect, 1 );
207 	m_fg_tilemap->draw(screen, bitmap, cliprect, 0,0);
208 	m_tx_tilemap->draw(screen, bitmap, cliprect, 0,0);
209 	draw_sprites(bitmap,cliprect, 0 );
210 	return 0;
211 }
212