1 // license:BSD-3-Clause
2 // copyright-holders:Ernesto Corvi,Tim Lindquist,Carlos A. Lozano,Bryan McPhail,Jarek Parchanski,Nicola Salmoria,Tomasz Slanina,Phil Stroffolino,Acho A. Tang,Victor Trucco
3 // thanks-to:Marco Cassili
4 #include "emu.h"
5 #include "includes/snk.h"
6
7 /*******************************************************************************
8 Shadow Handling Notes
9 ********************************************************************************
10 Shadows are handled by changing palette bank.
11
12 Games Not Using Shadows
13
14 those using gwar_vh_screenrefresh (gwar, bermudat, psychos, chopper1)
15 (0-15 , 15 is transparent)
16
17 Games Using Shadows
18
19 those using tnk3_vh_screenrefresh (tnk3, athena, fitegolf) sgladiat is similar
20 (0-7 , 6 is shadow, 7 is transparent) * these are using aso colour prom convert *
21 those using ikari_vh_screenrefresh (ikari, victroad)
22 (0-7 , 6 is shadow, 7 is transparent)
23 those using tdfever_vh_screenrefresh (tdfever, fsoccer)
24 (0-15 , 14 is shadow, 15 is transparent)
25
26 *******************************************************************************/
27
28
29 /**************************************************************************************/
30
tnk3_palette(palette_device & palette) const31 void snk_state::tnk3_palette(palette_device &palette) const
32 {
33 uint8_t const *const color_prom = memregion("proms")->base();
34 constexpr int num_colors = 0x400;
35
36 for (int i = 0; i < num_colors; i++)
37 {
38 int bit0, bit1, bit2, bit3;
39
40 bit0 = BIT(color_prom[i + 2*num_colors], 3);
41 bit1 = BIT(color_prom[i], 1);
42 bit2 = BIT(color_prom[i], 2);
43 bit3 = BIT(color_prom[i], 3);
44 int const r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
45
46 bit0 = BIT(color_prom[i + 2*num_colors], 2);
47 bit1 = BIT(color_prom[i + num_colors], 2);
48 bit2 = BIT(color_prom[i + num_colors], 3);
49 bit3 = BIT(color_prom[i], 0);
50 int const g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
51
52 bit0 = BIT(color_prom[i + 2*num_colors], 0);
53 bit1 = BIT(color_prom[i + 2*num_colors], 1);
54 bit2 = BIT(color_prom[i + num_colors], 0);
55 bit3 = BIT(color_prom[i + num_colors], 1);
56 int const b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
57
58 palette.set_pen_color(i, rgb_t(r, g, b));
59 }
60 }
61
62 /**************************************************************************************/
63
TILEMAP_MAPPER_MEMBER(snk_state::marvins_tx_scan_cols)64 TILEMAP_MAPPER_MEMBER(snk_state::marvins_tx_scan_cols)
65 {
66 // tilemap is 36x28, the central part is from the first RAM page and the
67 // extra 4 columns are from the second page
68 col -= 2;
69 if (col & 0x20)
70 return 0x400 + row + ((col & 0x1f) << 5);
71 else
72 return row + (col << 5);
73 }
74
TILE_GET_INFO_MEMBER(snk_state::marvins_get_tx_tile_info)75 TILE_GET_INFO_MEMBER(snk_state::marvins_get_tx_tile_info)
76 {
77 int code = m_tx_videoram[tile_index];
78 int color = code >> 5;
79
80 tileinfo.set(0,
81 m_tx_tile_offset + code,
82 color,
83 tile_index & 0x400 ? TILE_FORCE_LAYER0 : 0);
84 }
85
TILE_GET_INFO_MEMBER(snk_state::ikari_get_tx_tile_info)86 TILE_GET_INFO_MEMBER(snk_state::ikari_get_tx_tile_info)
87 {
88 int code = m_tx_videoram[tile_index];
89
90 tileinfo.set(0,
91 m_tx_tile_offset + code,
92 0,
93 tile_index & 0x400 ? TILE_FORCE_LAYER0 : 0);
94 }
95
TILE_GET_INFO_MEMBER(snk_state::gwar_get_tx_tile_info)96 TILE_GET_INFO_MEMBER(snk_state::gwar_get_tx_tile_info)
97 {
98 int code = m_tx_videoram[tile_index];
99
100 tileinfo.set(0,
101 m_tx_tile_offset + code,
102 0,
103 0);
104 }
105
106
TILE_GET_INFO_MEMBER(snk_state::marvins_get_fg_tile_info)107 TILE_GET_INFO_MEMBER(snk_state::marvins_get_fg_tile_info)
108 {
109 int code = m_fg_videoram[tile_index];
110
111 tileinfo.set(1,
112 code,
113 0,
114 0);
115 }
116
TILE_GET_INFO_MEMBER(snk_state::marvins_get_bg_tile_info)117 TILE_GET_INFO_MEMBER(snk_state::marvins_get_bg_tile_info)
118 {
119 int code = m_bg_videoram[tile_index];
120
121 tileinfo.set(2,
122 code,
123 0,
124 0);
125 }
126
127
TILE_GET_INFO_MEMBER(snk_state::aso_get_bg_tile_info)128 TILE_GET_INFO_MEMBER(snk_state::aso_get_bg_tile_info)
129 {
130 int code = m_bg_videoram[tile_index];
131
132 tileinfo.set(1,
133 m_bg_tile_offset + code,
134 0,
135 0);
136 }
137
TILE_GET_INFO_MEMBER(snk_state::tnk3_get_bg_tile_info)138 TILE_GET_INFO_MEMBER(snk_state::tnk3_get_bg_tile_info)
139 {
140 int attr = m_bg_videoram[2*tile_index+1];
141 int code = m_bg_videoram[2*tile_index] | ((attr & 0x30) << 4);
142 int color = (attr & 0xf) ^ 8;
143
144 tileinfo.set(1,
145 code,
146 color,
147 0);
148 }
149
TILE_GET_INFO_MEMBER(snk_state::ikari_get_bg_tile_info)150 TILE_GET_INFO_MEMBER(snk_state::ikari_get_bg_tile_info)
151 {
152 int attr = m_bg_videoram[2*tile_index+1];
153 int code = m_bg_videoram[2*tile_index] | ((attr & 0x03) << 8);
154 int color = (attr & 0x70) >> 4;
155
156 tileinfo.set(1,
157 code,
158 color,
159 0);
160 }
161
TILE_GET_INFO_MEMBER(snk_state::gwar_get_bg_tile_info)162 TILE_GET_INFO_MEMBER(snk_state::gwar_get_bg_tile_info)
163 {
164 int attr = m_bg_videoram[2*tile_index+1];
165 int code = m_bg_videoram[2*tile_index] | ((attr & 0x0f) << 8);
166 int color = (attr & 0xf0) >> 4;
167
168 if (m_is_psychos) // psychos has a separate palette bank bit
169 color &= 7;
170
171 tileinfo.set(1,
172 code,
173 color,
174 0);
175
176 // bermudat, tdfever use FFFF to blank the background.
177 // (still call tileinfo.set, otherwise problems might occur on boot when
178 // the tile data hasn't been initialised)
179 if (code >= m_gfxdecode->gfx(1)->elements())
180 tileinfo.pen_data = m_empty_tile;
181 }
182
183
184 /**************************************************************************************/
185
VIDEO_START_MEMBER(snk_state,snk_3bpp_shadow)186 VIDEO_START_MEMBER(snk_state,snk_3bpp_shadow)
187 {
188 int i;
189
190 if(!(m_palette->shadows_enabled()))
191 fatalerror("driver should use VIDEO_HAS_SHADOWS\n");
192
193 /* prepare shadow draw table */
194 for(i = 0; i <= 5; i++) m_drawmode_table[i] = DRAWMODE_SOURCE;
195 m_drawmode_table[6] = (m_palette->shadows_enabled()) ? DRAWMODE_SHADOW : DRAWMODE_SOURCE;
196 m_drawmode_table[7] = DRAWMODE_NONE;
197
198 for (i = 0x000;i < 0x400;i++)
199 m_palette->shadow_table()[i] = i | 0x200;
200 }
201
VIDEO_START_MEMBER(snk_state,snk_4bpp_shadow)202 VIDEO_START_MEMBER(snk_state,snk_4bpp_shadow)
203 {
204 int i;
205
206 if(!(m_palette->shadows_enabled()))
207 fatalerror("driver should use VIDEO_HAS_SHADOWS\n");
208
209 /* prepare shadow draw table */
210 for(i = 0; i <= 13; i++) m_drawmode_table[i] = DRAWMODE_SOURCE;
211 m_drawmode_table[14] = DRAWMODE_SHADOW;
212 m_drawmode_table[15] = DRAWMODE_NONE;
213
214 /* all palette entries are not affected by shadow sprites... */
215 for (i = 0x000;i < 0x400;i++)
216 m_palette->shadow_table()[i] = i;
217 /* ... except for tilemap colors */
218 for (i = 0x200;i < 0x300;i++)
219 m_palette->shadow_table()[i] = i + 0x100;
220 }
221
222
VIDEO_START_MEMBER(snk_state,marvins)223 VIDEO_START_MEMBER(snk_state,marvins)
224 {
225 VIDEO_START_CALL_MEMBER(snk_3bpp_shadow);
226
227 m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(snk_state::marvins_get_tx_tile_info)), tilemap_mapper_delegate(*this, FUNC(snk_state::marvins_tx_scan_cols)), 8, 8, 36, 28);
228 m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(snk_state::marvins_get_fg_tile_info)), TILEMAP_SCAN_COLS, 8, 8, 64, 32);
229 m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(snk_state::marvins_get_bg_tile_info)), TILEMAP_SCAN_COLS, 8, 8, 64, 32);
230
231 m_tx_tilemap->set_transparent_pen(15);
232 m_tx_tilemap->set_scrolldy(8, 8);
233
234 m_fg_tilemap->set_transparent_pen(15);
235 m_fg_tilemap->set_scrolldx(15, 31);
236 m_fg_tilemap->set_scrolldy(8, -32);
237
238 m_bg_tilemap->set_scrolldx(15, 31);
239 m_bg_tilemap->set_scrolldy(8, -32);
240
241 m_tx_tile_offset = 0;
242 }
243
VIDEO_START_MEMBER(snk_state,jcross)244 VIDEO_START_MEMBER(snk_state,jcross)
245 {
246 VIDEO_START_CALL_MEMBER(snk_3bpp_shadow);
247
248 m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(snk_state::marvins_get_tx_tile_info)), tilemap_mapper_delegate(*this, FUNC(snk_state::marvins_tx_scan_cols)), 8, 8, 36, 28);
249 m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(snk_state::aso_get_bg_tile_info)), TILEMAP_SCAN_COLS, 8, 8, 64, 64);
250
251 m_tx_tilemap->set_transparent_pen(15);
252 m_tx_tilemap->set_scrolldy(8, 8);
253
254 m_bg_tilemap->set_scrolldx(15, 24);
255 m_bg_tilemap->set_scrolldy(8, -32);
256
257 m_num_sprites = 25;
258 m_yscroll_mask = 0x1ff;
259 m_bg_tile_offset = 0;
260 m_tx_tile_offset = 0;
261 }
262
VIDEO_START_MEMBER(snk_state,sgladiat)263 VIDEO_START_MEMBER(snk_state,sgladiat)
264 {
265 VIDEO_START_CALL_MEMBER(snk_3bpp_shadow);
266
267 m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(snk_state::marvins_get_tx_tile_info)), tilemap_mapper_delegate(*this, FUNC(snk_state::marvins_tx_scan_cols)), 8, 8, 36, 28);
268 m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(snk_state::aso_get_bg_tile_info)), TILEMAP_SCAN_COLS, 8, 8, 64, 32);
269
270 m_tx_tilemap->set_transparent_pen(15);
271 m_tx_tilemap->set_scrolldy(8, 8);
272
273 m_bg_tilemap->set_scrolldx(15, 24);
274 m_bg_tilemap->set_scrolldy(8, -32);
275
276 m_num_sprites = 25;
277 m_yscroll_mask = 0x0ff;
278 m_bg_tile_offset = 0;
279 m_tx_tile_offset = 0;
280 }
281
VIDEO_START_MEMBER(snk_state,hal21)282 VIDEO_START_MEMBER(snk_state,hal21)
283 {
284 VIDEO_START_CALL_MEMBER(jcross);
285
286 m_bg_tilemap->set_scrolldy(8, -32+256);
287
288 m_num_sprites = 50;
289 m_yscroll_mask = 0x1ff;
290 }
291
VIDEO_START_MEMBER(snk_state,aso)292 VIDEO_START_MEMBER(snk_state,aso)
293 {
294 VIDEO_START_CALL_MEMBER(jcross);
295
296 m_bg_tilemap->set_scrolldx(15+256, 24+256);
297
298 m_num_sprites = 50;
299 m_yscroll_mask = 0x1ff;
300 }
301
302
VIDEO_START_MEMBER(snk_state,tnk3)303 VIDEO_START_MEMBER(snk_state,tnk3)
304 {
305 VIDEO_START_CALL_MEMBER(snk_3bpp_shadow);
306
307 m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(snk_state::marvins_get_tx_tile_info)), tilemap_mapper_delegate(*this, FUNC(snk_state::marvins_tx_scan_cols)), 8, 8, 36, 28);
308 m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(snk_state::tnk3_get_bg_tile_info)), TILEMAP_SCAN_COLS, 8, 8, 64, 64);
309
310 m_tx_tilemap->set_transparent_pen(15);
311 m_tx_tilemap->set_scrolldy(8, 8);
312
313 m_bg_tilemap->set_scrolldx(15, 24);
314 m_bg_tilemap->set_scrolldy(8, -32);
315
316 m_num_sprites = 50;
317 m_yscroll_mask = 0x1ff;
318 m_tx_tile_offset = 0;
319 }
320
VIDEO_START_MEMBER(snk_state,ikari)321 VIDEO_START_MEMBER(snk_state,ikari)
322 {
323 VIDEO_START_CALL_MEMBER(snk_3bpp_shadow);
324
325 m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(snk_state::ikari_get_tx_tile_info)), tilemap_mapper_delegate(*this, FUNC(snk_state::marvins_tx_scan_cols)), 8, 8, 36, 28);
326 m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(snk_state::ikari_get_bg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 32, 32);
327
328 m_tx_tilemap->set_transparent_pen(15);
329 m_tx_tilemap->set_scrolldy(8, 8);
330
331 m_bg_tilemap->set_scrolldx(15, 24);
332 m_bg_tilemap->set_scrolldy(8, -32);
333
334 m_tx_tile_offset = 0;
335 }
336
VIDEO_START_MEMBER(snk_state,gwar)337 VIDEO_START_MEMBER(snk_state,gwar)
338 {
339 int i;
340
341 /* prepare drawmode table */
342 for(i = 0; i <= 14; i++) m_drawmode_table[i] = DRAWMODE_SOURCE;
343 m_drawmode_table[15] = DRAWMODE_NONE;
344
345 memset(m_empty_tile, 0xf, sizeof(m_empty_tile));
346
347 m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(snk_state::gwar_get_tx_tile_info)), TILEMAP_SCAN_COLS, 8, 8, 50, 32);
348 m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(snk_state::gwar_get_bg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 32, 32);
349
350 m_tx_tilemap->set_transparent_pen(15);
351
352 m_bg_tilemap->set_scrolldx(16, 143);
353 m_bg_tilemap->set_scrolldy(0, -32);
354
355 m_tx_tile_offset = 0;
356
357 m_is_psychos = 0;
358 }
359
VIDEO_START_MEMBER(snk_state,psychos)360 VIDEO_START_MEMBER(snk_state,psychos)
361 {
362 VIDEO_START_CALL_MEMBER(gwar);
363 m_is_psychos = 1;
364 }
365
VIDEO_START_MEMBER(snk_state,tdfever)366 VIDEO_START_MEMBER(snk_state,tdfever)
367 {
368 VIDEO_START_CALL_MEMBER(gwar);
369 VIDEO_START_CALL_MEMBER(snk_4bpp_shadow);
370 }
371
372 /**************************************************************************************/
373
snk_tx_videoram_w(offs_t offset,uint8_t data)374 void snk_state::snk_tx_videoram_w(offs_t offset, uint8_t data)
375 {
376 m_tx_videoram[offset] = data;
377 m_tx_tilemap->mark_tile_dirty(offset);
378 }
379
marvins_fg_videoram_w(offs_t offset,uint8_t data)380 void snk_state::marvins_fg_videoram_w(offs_t offset, uint8_t data)
381 {
382 m_fg_videoram[offset] = data;
383 m_fg_tilemap->mark_tile_dirty(offset);
384 }
385
marvins_bg_videoram_w(offs_t offset,uint8_t data)386 void snk_state::marvins_bg_videoram_w(offs_t offset, uint8_t data)
387 {
388 m_bg_videoram[offset] = data;
389 m_bg_tilemap->mark_tile_dirty(offset);
390 }
391
snk_bg_videoram_w(offs_t offset,uint8_t data)392 void snk_state::snk_bg_videoram_w(offs_t offset, uint8_t data)
393 {
394 m_bg_videoram[offset] = data;
395 m_bg_tilemap->mark_tile_dirty(offset >> 1);
396 }
397
398
snk_fg_scrollx_w(uint8_t data)399 void snk_state::snk_fg_scrollx_w(uint8_t data)
400 {
401 m_fg_scrollx = (m_fg_scrollx & ~0xff) | data;
402 }
403
snk_fg_scrolly_w(uint8_t data)404 void snk_state::snk_fg_scrolly_w(uint8_t data)
405 {
406 m_fg_scrolly = (m_fg_scrolly & ~0xff) | data;
407 }
408
snk_bg_scrollx_w(uint8_t data)409 void snk_state::snk_bg_scrollx_w(uint8_t data)
410 {
411 m_bg_scrollx = (m_bg_scrollx & ~0xff) | data;
412 }
413
snk_bg_scrolly_w(uint8_t data)414 void snk_state::snk_bg_scrolly_w(uint8_t data)
415 {
416 m_bg_scrolly = (m_bg_scrolly & ~0xff) | data;
417 }
418
snk_sp16_scrollx_w(uint8_t data)419 void snk_state::snk_sp16_scrollx_w(uint8_t data)
420 {
421 m_sp16_scrollx = (m_sp16_scrollx & ~0xff) | data;
422 }
423
snk_sp16_scrolly_w(uint8_t data)424 void snk_state::snk_sp16_scrolly_w(uint8_t data)
425 {
426 m_sp16_scrolly = (m_sp16_scrolly & ~0xff) | data;
427 }
428
snk_sp32_scrollx_w(uint8_t data)429 void snk_state::snk_sp32_scrollx_w(uint8_t data)
430 {
431 m_sp32_scrollx = (m_sp32_scrollx & ~0xff) | data;
432 }
433
snk_sp32_scrolly_w(uint8_t data)434 void snk_state::snk_sp32_scrolly_w(uint8_t data)
435 {
436 m_sp32_scrolly = (m_sp32_scrolly & ~0xff) | data;
437 }
438
snk_sprite_split_point_w(uint8_t data)439 void snk_state::snk_sprite_split_point_w(uint8_t data)
440 {
441 m_sprite_split_point = data;
442 }
443
444
marvins_palette_bank_w(uint8_t data)445 void snk_state::marvins_palette_bank_w(uint8_t data)
446 {
447 m_bg_tilemap->set_palette_offset(data & 0x70);
448 m_fg_tilemap->set_palette_offset((data & 0x07) << 4);
449 }
450
marvins_flipscreen_w(uint8_t data)451 void snk_state::marvins_flipscreen_w(uint8_t data)
452 {
453 flip_screen_set(data & 0x80);
454
455 // other bits unknown
456 }
457
sgladiat_flipscreen_w(uint8_t data)458 void snk_state::sgladiat_flipscreen_w(uint8_t data)
459 {
460 flip_screen_set(data & 0x80);
461
462 m_bg_tilemap->set_palette_offset(((data & 0xf) ^ 8) << 4);
463
464 // other bits unknown
465 }
466
hal21_flipscreen_w(uint8_t data)467 void snk_state::hal21_flipscreen_w(uint8_t data)
468 {
469 flip_screen_set(data & 0x80);
470
471 m_bg_tilemap->set_palette_offset(((data & 0xf) ^ 8) << 4);
472 if (m_bg_tile_offset != ((data & 0x20) << 3))
473 {
474 m_bg_tile_offset = (data & 0x20) << 3;
475 m_bg_tilemap->mark_all_dirty();
476 }
477
478 // other bits unknown
479 }
480
marvins_scroll_msb_w(uint8_t data)481 void snk_state::marvins_scroll_msb_w(uint8_t data)
482 {
483 m_bg_scrollx = (m_bg_scrollx & 0xff) | ((data & 0x04) << 6);
484 m_fg_scrollx = (m_fg_scrollx & 0xff) | ((data & 0x02) << 7);
485 m_sp16_scrollx = (m_sp16_scrollx & 0xff) | ((data & 0x01) << 8);
486 }
487
jcross_scroll_msb_w(uint8_t data)488 void snk_state::jcross_scroll_msb_w(uint8_t data)
489 {
490 m_bg_scrolly = (m_bg_scrolly & 0xff) | ((data & 0x10) << 4);
491 m_sp16_scrolly = (m_sp16_scrolly & 0xff) | ((data & 0x08) << 5);
492 m_bg_scrollx = (m_bg_scrollx & 0xff) | ((data & 0x02) << 7);
493 m_sp16_scrollx = (m_sp16_scrollx & 0xff) | ((data & 0x01) << 8);
494 }
495
sgladiat_scroll_msb_w(uint8_t data)496 void snk_state::sgladiat_scroll_msb_w(uint8_t data)
497 {
498 m_bg_scrollx = (m_bg_scrollx & 0xff) | ((data & 0x02) << 7);
499 m_sp16_scrollx = (m_sp16_scrollx & 0xff) | ((data & 0x01) << 8);
500 }
501
aso_videoattrs_w(uint8_t data)502 void snk_state::aso_videoattrs_w(uint8_t data)
503 {
504 /*
505 video attributes:
506 X-------
507 -X------
508 --X----- flip screen
509 ---X---- scrolly MSB (background)
510 ----X--- scrolly MSB (sprites)
511 -----X--
512 ------X- scrollx MSB (background)
513 -------X scrollx MSB (sprites)
514 */
515
516
517 flip_screen_set(data & 0x20);
518
519 m_bg_scrolly = (m_bg_scrolly & 0xff) | ((data & 0x10) << 4);
520 m_sp16_scrolly = (m_sp16_scrolly & 0xff) | ((data & 0x08) << 5);
521 m_bg_scrollx = (m_bg_scrollx & 0xff) | ((data & 0x02) << 7);
522 m_sp16_scrollx = (m_sp16_scrollx & 0xff) | ((data & 0x01) << 8);
523 }
524
tnk3_videoattrs_w(uint8_t data)525 void snk_state::tnk3_videoattrs_w(uint8_t data)
526 {
527 /*
528 video attributes:
529 X------- flip screen
530 -X------ character bank (for text layer)
531 --X-----
532 ---X---- scrolly MSB (background)
533 ----X--- scrolly MSB (sprites)
534 -----X--
535 ------X- scrollx MSB (background)
536 -------X scrollx MSB (sprites)
537 */
538
539
540 flip_screen_set(data & 0x80);
541
542 if (m_tx_tile_offset != ((data & 0x40) << 2))
543 {
544 m_tx_tile_offset = (data & 0x40) << 2;
545 m_tx_tilemap->mark_all_dirty();
546 }
547
548 m_bg_scrolly = (m_bg_scrolly & 0xff) | ((data & 0x10) << 4);
549 m_sp16_scrolly = (m_sp16_scrolly & 0xff) | ((data & 0x08) << 5);
550 m_bg_scrollx = (m_bg_scrollx & 0xff) | ((data & 0x02) << 7);
551 m_sp16_scrollx = (m_sp16_scrollx & 0xff) | ((data & 0x01) << 8);
552 }
553
aso_bg_bank_w(uint8_t data)554 void snk_state::aso_bg_bank_w(uint8_t data)
555 {
556 m_bg_tilemap->set_palette_offset(((data & 0xf) ^ 8) << 4);
557 if (m_bg_tile_offset != ((data & 0x30) << 4))
558 {
559 m_bg_tile_offset = (data & 0x30) << 4;
560 m_bg_tilemap->mark_all_dirty();
561 }
562 }
563
ikari_bg_scroll_msb_w(uint8_t data)564 void snk_state::ikari_bg_scroll_msb_w(uint8_t data)
565 {
566 m_bg_scrollx = (m_bg_scrollx & 0xff) | ((data & 0x02) << 7);
567 m_bg_scrolly = (m_bg_scrolly & 0xff) | ((data & 0x01) << 8);
568 }
569
ikari_sp_scroll_msb_w(uint8_t data)570 void snk_state::ikari_sp_scroll_msb_w(uint8_t data)
571 {
572 m_sp32_scrollx = (m_sp32_scrollx & 0xff) | ((data & 0x20) << 3);
573 m_sp16_scrollx = (m_sp16_scrollx & 0xff) | ((data & 0x10) << 4);
574 m_sp32_scrolly = (m_sp32_scrolly & 0xff) | ((data & 0x08) << 5);
575 m_sp16_scrolly = (m_sp16_scrolly & 0xff) | ((data & 0x04) << 6);
576 }
577
ikari_unknown_video_w(uint8_t data)578 void snk_state::ikari_unknown_video_w(uint8_t data)
579 {
580 /* meaning of 0xc980 uncertain.
581 Normally 0x20, ikaria/ikarijp sets it to 0x31 during test mode.
582 Changing char bank is necessary to fix the display during the
583 hard flags test and the test grid.
584 Changing palette bank is necessary to fix colors in test mode. */
585
586
587 if (data != 0x20 && // normal
588 data != 0x31 && // ikari test
589 data != 0xaa) // victroad spurious during boot
590 popmessage("attrs %02x contact MAMEDEV", data);
591
592 m_tx_tilemap->set_palette_offset((data & 0x01) << 4);
593 if (m_tx_tile_offset != ((data & 0x10) << 4))
594 {
595 m_tx_tile_offset = (data & 0x10) << 4;
596 m_tx_tilemap->mark_all_dirty();
597 }
598 }
599
gwar_tx_bank_w(uint8_t data)600 void snk_state::gwar_tx_bank_w(uint8_t data)
601 {
602 m_tx_tilemap->set_palette_offset((data & 0xf) << 4);
603 if (m_tx_tile_offset != ((data & 0x30) << 4))
604 {
605 m_tx_tile_offset = (data & 0x30) << 4;
606 m_tx_tilemap->mark_all_dirty();
607 }
608
609 if (m_is_psychos)
610 m_bg_tilemap->set_palette_offset((data & 0x80));
611 }
612
gwar_videoattrs_w(uint8_t data)613 void snk_state::gwar_videoattrs_w(uint8_t data)
614 {
615 flip_screen_set(data & 0x04);
616
617 m_sp32_scrollx = (m_sp32_scrollx & 0xff) | ((data & 0x80) << 1);
618 m_sp16_scrollx = (m_sp16_scrollx & 0xff) | ((data & 0x40) << 2);
619 m_sp32_scrolly = (m_sp32_scrolly & 0xff) | ((data & 0x20) << 3);
620 m_sp16_scrolly = (m_sp16_scrolly & 0xff) | ((data & 0x10) << 4);
621 m_bg_scrollx = (m_bg_scrollx & 0xff) | ((data & 0x02) << 7);
622 m_bg_scrolly = (m_bg_scrolly & 0xff) | ((data & 0x01) << 8);
623 }
624
gwara_videoattrs_w(uint8_t data)625 void snk_state::gwara_videoattrs_w(uint8_t data)
626 {
627 flip_screen_set(data & 0x10);
628
629 m_bg_scrollx = (m_bg_scrollx & 0xff) | ((data & 0x02) << 7);
630 m_bg_scrolly = (m_bg_scrolly & 0xff) | ((data & 0x01) << 8);
631 }
632
gwara_sp_scroll_msb_w(uint8_t data)633 void snk_state::gwara_sp_scroll_msb_w(uint8_t data)
634 {
635 m_sp32_scrollx = (m_sp32_scrollx & 0xff) | ((data & 0x20) << 3);
636 m_sp16_scrollx = (m_sp16_scrollx & 0xff) | ((data & 0x10) << 4);
637 m_sp32_scrolly = (m_sp32_scrolly & 0xff) | ((data & 0x08) << 5);
638 m_sp16_scrolly = (m_sp16_scrolly & 0xff) | ((data & 0x04) << 6);
639 }
640
tdfever_sp_scroll_msb_w(uint8_t data)641 void snk_state::tdfever_sp_scroll_msb_w(uint8_t data)
642 {
643 m_sp32_scrolly = (m_sp32_scrolly & 0xff) | ((data & 0x80) << 1);
644 m_sp32_scrollx = (m_sp32_scrollx & 0xff) | ((data & 0x40) << 2);
645 }
646
tdfever_spriteram_w(offs_t offset,uint8_t data)647 void snk_state::tdfever_spriteram_w(offs_t offset, uint8_t data)
648 {
649 /* partial updates avoid flickers in the fsoccer radar. */
650 if (offset < 0x80 && m_spriteram[offset] != data)
651 {
652 int vpos = m_screen->vpos();
653
654 if (vpos > 0)
655 m_screen->update_partial(vpos - 1);
656 }
657
658 m_spriteram[offset] = data;
659 }
660
661 /**************************************************************************************/
662
marvins_draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect,const int scrollx,const int scrolly,const int from,const int to)663 void snk_state::marvins_draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, const int scrollx, const int scrolly, const int from, const int to)
664 {
665 gfx_element *gfx = m_gfxdecode->gfx(3);
666 const uint8_t *source, *finish;
667
668 source = m_spriteram + from*4;
669 finish = m_spriteram + to*4;
670
671 while( source<finish )
672 {
673 int attributes = source[3]; /* Y?F? CCCC */
674 int tile_number = source[1];
675 int sx = scrollx + 301 - 15 - source[2] + ((attributes&0x80)?256:0);
676 int sy = -scrolly - 8 + source[0];
677 int color = attributes&0xf;
678 int flipy = (attributes&0x20);
679 int flipx = 0;
680
681 if (flip_screen())
682 {
683 sx = 89 - 16 - sx;
684 sy = 262 - 16 - sy;
685 flipx = !flipx;
686 flipy = !flipy;
687 }
688
689 sx &= 0x1ff;
690 sy &= 0xff;
691 if (sx > 512-16) sx -= 512;
692 if (sy > 256-16) sy -= 256;
693
694 gfx->transtable(bitmap,cliprect,
695 tile_number,
696 color,
697 flipx, flipy,
698 sx, sy,
699 m_drawmode_table);
700
701 source+=4;
702 }
703 }
704
705
tnk3_draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect,const int xscroll,const int yscroll)706 void snk_state::tnk3_draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, const int xscroll, const int yscroll)
707 {
708 uint8_t *spriteram = m_spriteram;
709 gfx_element *gfx = m_gfxdecode->gfx(2);
710 const int size = gfx->width();
711 int tile_number, attributes, color, sx, sy;
712 int xflip,yflip;
713 int offs;
714
715 /* jcross and sgladiat have only 25 sprites, the others 50 */
716
717 /* jcross has 256 tiles, attribute bit 6 is unused and bit 5 is y-flip */
718 /* sgladiat and tnk3 have 512 tiles, bit 6 is bank and bit 5 is y-flip */
719 /* athena has 1024 tiles, bit 6 and bit 5 are bank */
720
721 for (offs = 0; offs < m_num_sprites*4; offs += 4)
722 {
723 tile_number = spriteram[offs+1];
724 attributes = spriteram[offs+3];
725 color = attributes & 0xf;
726 sx = xscroll + 301 - size - spriteram[offs+2];
727 sy = -yscroll + 7 - size + spriteram[offs];
728 sx += (attributes & 0x80) << 1;
729 sy += (attributes & 0x10) << 4;
730 xflip = 0;
731 yflip = 0;
732
733 if (gfx->elements() > 256) // all except jcross
734 {
735 tile_number |= (attributes & 0x40) << 2;
736 }
737
738 if (gfx->elements() > 512) // athena
739 {
740 tile_number |= (attributes & 0x20) << 4;
741 }
742 else // all others
743 {
744 yflip = attributes & 0x20;
745 }
746
747 if (flip_screen())
748 {
749 sx = 89 - size - sx; // this causes slight misalignment in tnk3 but is correct for athena and fitegolf
750 sy = 262 - size - sy;
751 xflip = !xflip;
752 yflip = !yflip;
753 }
754
755 sx &= 0x1ff;
756 sy &= m_yscroll_mask; // sgladiat apparently has only 256 pixels of vertical scrolling range
757 if (sx > 512-size) sx -= 512;
758 if (sy > (m_yscroll_mask+1)-size) sy -= (m_yscroll_mask+1);
759
760 gfx->transtable(bitmap,cliprect,
761 tile_number,
762 color,
763 xflip,yflip,
764 sx,sy,
765 m_drawmode_table);
766 }
767 }
768
769
ikari_draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect,const int start,const int xscroll,const int yscroll,const uint8_t * source,const int gfxnum)770 void snk_state::ikari_draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, const int start, const int xscroll, const int yscroll, const uint8_t *source, const int gfxnum )
771 {
772 gfx_element *gfx = m_gfxdecode->gfx(gfxnum);
773 const int size = gfx->width();
774 int tile_number, attributes, color, sx, sy;
775 int which, finish;
776
777 finish = (start+25)*4;
778
779 for (which = start*4; which < finish; which += 4)
780 {
781 tile_number = source[which+1];
782 attributes = source[which+3];
783 color = attributes & 0xf;
784 sx = xscroll + 300 - size - source[which+2];
785 sy = -yscroll + 7 - size + source[which];
786 sx += (attributes & 0x80) << 1;
787 sy += (attributes & 0x10) << 4;
788
789 switch (size)
790 {
791 case 16:
792 tile_number |= (attributes & 0x60) << 3;
793 break;
794
795 case 32:
796 tile_number |= (attributes & 0x40) << 2;
797 break;
798 }
799
800 sx &= 0x1ff;
801 sy &= 0x1ff;
802 if (sx > 512-size) sx -= 512;
803 if (sy > 512-size) sy -= 512;
804
805 gfx->transtable(bitmap,cliprect,
806 tile_number,
807 color,
808 0,0,
809 sx,sy,
810 m_drawmode_table);
811 }
812 }
813
814 /**************************************************************/
815
816 /*
817 Sprite Format
818 -------------
819 byte0: y offset
820 byte1: tile number
821 byte2: x offset
822 byte3: attributes
823
824 32x32 attributes:
825
826 76543210
827 ----xxxx (color)
828 ---x---- (y offset bit8)
829 -xx----- (bank number)
830 x------- (x offset bit8)
831
832 16x16 attributes:
833
834 76543210
835 -----xxx (color)
836 ---x---- (y offset bit8)
837 -xx-x--- (bank number)
838 x------- (x offset bit8)
839 */
tdfever_draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect,const int xscroll,const int yscroll,const uint8_t * source,const int gfxnum,const int hw_xflip,const int from,const int to)840 void snk_state::tdfever_draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, const int xscroll, const int yscroll, const uint8_t *source, const int gfxnum,
841 const int hw_xflip, const int from, const int to)
842 {
843 gfx_element *gfx = m_gfxdecode->gfx(gfxnum);
844 const int size = gfx->width();
845 int tile_number, attributes, sx, sy, color;
846 int which;
847 int flipx, flipy;
848
849 for(which = from*4; which < to*4; which+=4)
850 {
851 tile_number = source[which+1];
852 attributes = source[which+3];
853 color = attributes & 0x0f;
854 sx = -xscroll - 9 + source[which+2];
855 sy = -yscroll + 1 - size + source[which];
856 sx += (attributes & 0x80) << 1;
857 sy += (attributes & 0x10) << 4;
858
859 switch (size)
860 {
861 case 16:
862 tile_number |= ((attributes & 0x08) << 5) | ((attributes & 0x60) << 4);
863 color &= 7; // attribute bit 3 is used for bank select
864 if (from == 0)
865 color |= 8; // low priority sprites use the other palette bank
866 break;
867
868 case 32:
869 tile_number |= (attributes & 0x60) << 3;
870 break;
871 }
872
873 flipx = hw_xflip;
874 flipy = 0;
875
876 if (hw_xflip)
877 sx = 495 - size - sx;
878
879 if (flip_screen())
880 {
881 sx = 495 - size - sx;
882 sy = 258 - size - sy;
883 flipx = !flipx;
884 flipy = !flipy;
885 }
886
887 sx &= 0x1ff;
888 sy &= 0x1ff;
889 if (sx > 512-size) sx -= 512;
890 if (sy > 512-size) sy -= 512;
891
892 gfx->transtable(bitmap,cliprect,
893 tile_number,
894 color,
895 flipx,flipy,
896 sx,sy,
897 m_drawmode_table);
898 }
899 }
900
901 /**************************************************************/
902
screen_update_marvins(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)903 uint32_t snk_state::screen_update_marvins(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
904 {
905 m_bg_tilemap->set_scrollx(0, m_bg_scrollx);
906 m_bg_tilemap->set_scrolly(0, m_bg_scrolly);
907 m_fg_tilemap->set_scrollx(0, m_fg_scrollx);
908 m_fg_tilemap->set_scrolly(0, m_fg_scrolly);
909
910 m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
911 marvins_draw_sprites(bitmap, cliprect, m_sp16_scrollx, m_sp16_scrolly, 0, m_sprite_split_point>>2);
912 m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
913 marvins_draw_sprites(bitmap, cliprect, m_sp16_scrollx, m_sp16_scrolly, m_sprite_split_point>>2, 25);
914 m_tx_tilemap->draw(screen, bitmap, cliprect, 0, 0);
915
916 return 0;
917 }
918
919
screen_update_tnk3(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)920 uint32_t snk_state::screen_update_tnk3(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
921 {
922 m_bg_tilemap->set_scrollx(0, m_bg_scrollx);
923 m_bg_tilemap->set_scrolly(0, m_bg_scrolly);
924
925 m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
926 tnk3_draw_sprites(bitmap, cliprect, m_sp16_scrollx, m_sp16_scrolly);
927 m_tx_tilemap->draw(screen, bitmap, cliprect, 0, 0);
928
929 return 0;
930 }
931
screen_update_fitegolf2(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)932 uint32_t snk_state::screen_update_fitegolf2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
933 {
934 m_bg_tilemap->set_scrollx(0, m_bg_scrollx);
935 m_bg_tilemap->set_scrolly(0, m_bg_scrolly);
936
937 m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
938 tnk3_draw_sprites(bitmap, cliprect, m_sp16_scrollx+1, m_sp16_scrolly); // needs an extra offset?? neither this or fitegolf actually write to sprite offset registers tho?
939 m_tx_tilemap->draw(screen, bitmap, cliprect, 0, 0);
940
941 return 0;
942 }
943
944
945
screen_update_ikari(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)946 uint32_t snk_state::screen_update_ikari(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
947 {
948 m_bg_tilemap->set_scrollx(0, m_bg_scrollx);
949 m_bg_tilemap->set_scrolly(0, m_bg_scrolly);
950
951 m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
952
953 ikari_draw_sprites(bitmap, cliprect, 0, m_sp16_scrollx, m_sp16_scrolly, m_spriteram + 0x800, 2 );
954 ikari_draw_sprites(bitmap, cliprect, 0, m_sp32_scrollx, m_sp32_scrolly, m_spriteram, 3 );
955 ikari_draw_sprites(bitmap, cliprect, 25, m_sp16_scrollx, m_sp16_scrolly, m_spriteram + 0x800, 2 );
956
957 m_tx_tilemap->draw(screen, bitmap, cliprect, 0, 0);
958 return 0;
959 }
960
961
screen_update_gwar(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)962 uint32_t snk_state::screen_update_gwar(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
963 {
964 m_bg_tilemap->set_scrollx(0, m_bg_scrollx);
965 m_bg_tilemap->set_scrolly(0, m_bg_scrolly);
966
967 m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
968
969 tdfever_draw_sprites(bitmap, cliprect, m_sp16_scrollx, m_sp16_scrolly, m_spriteram + 0x800, 2, 0, 0, m_sprite_split_point );
970 tdfever_draw_sprites(bitmap, cliprect, m_sp32_scrollx, m_sp32_scrolly, m_spriteram, 3, 0, 0, 32 );
971 tdfever_draw_sprites(bitmap, cliprect, m_sp16_scrollx, m_sp16_scrolly, m_spriteram + 0x800, 2, 0, m_sprite_split_point, 64 );
972
973 m_tx_tilemap->draw(screen, bitmap, cliprect, 0, 0);
974
975 return 0;
976 }
977
978
screen_update_tdfever(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)979 uint32_t snk_state::screen_update_tdfever(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
980 {
981 m_bg_tilemap->set_scrollx(0, m_bg_scrollx);
982 m_bg_tilemap->set_scrolly(0, m_bg_scrolly);
983
984 m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
985
986 tdfever_draw_sprites(bitmap, cliprect, m_sp32_scrollx, m_sp32_scrolly, m_spriteram, 2, 1, 0, 32 );
987
988 m_tx_tilemap->draw(screen, bitmap, cliprect, 0, 0);
989
990 return 0;
991 }
992