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