1 // license:BSD-3-Clause
2 // copyright-holders:Nicola Salmoria
3 /***************************************************************************
4
5 cclimber.cpp
6
7 Functions to emulate the video hardware of the machine.
8
9 ***************************************************************************/
10
11 #include "emu.h"
12 #include "video/resnet.h"
13 #include "includes/cclimber.h"
14
15
16 #define CCLIMBER_BG_PEN (0)
17 #define SWIMMER_SIDE_BG_PEN (0x120)
18 #define SWIMMER_BG_SPLIT (0x18 * 8)
19 #define YAMATO_SKY_PEN_BASE (0x60)
20
21
22 /***************************************************************************
23
24 Convert the color PROMs into a more useable format.
25
26 Crazy Climber has three 32x8 palette PROMs.
27 The palette PROMs are connected to the RGB output this way:
28
29 bit 7 -- 220 ohm resistor -- BLUE
30 -- 470 ohm resistor -- BLUE
31 -- 220 ohm resistor -- GREEN
32 -- 470 ohm resistor -- GREEN
33 -- 1 kohm resistor -- GREEN
34 -- 220 ohm resistor -- RED
35 -- 470 ohm resistor -- RED
36 bit 0 -- 1 kohm resistor -- RED
37
38 ***************************************************************************/
cclimber_palette(palette_device & palette) const39 void cclimber_state::cclimber_palette(palette_device &palette) const
40 {
41 const uint8_t *color_prom = memregion("proms")->base();
42 static constexpr int resistances_rg[3] = { 1000, 470, 220 };
43 static constexpr int resistances_b [2] = { 470, 220 };
44
45 // compute the color output resistor weights
46 double weights_rg[3], weights_b[2];
47 compute_resistor_weights(0, 255, -1.0,
48 3, resistances_rg, weights_rg, 0, 0,
49 2, resistances_b, weights_b, 0, 0,
50 0, nullptr, nullptr, 0, 0);
51
52 for (int i = 0;i < palette.entries(); i++)
53 {
54 int bit0, bit1, bit2;
55
56 // red component
57 bit0 = BIT(color_prom[i], 0);
58 bit1 = BIT(color_prom[i], 1);
59 bit2 = BIT(color_prom[i], 2);
60 int const r = combine_weights(weights_rg, bit0, bit1, bit2);
61
62 // green component
63 bit0 = BIT(color_prom[i], 3);
64 bit1 = BIT(color_prom[i], 4);
65 bit2 = BIT(color_prom[i], 5);
66 int const g = combine_weights(weights_rg, bit0, bit1, bit2);
67
68 // blue component
69 bit0 = BIT(color_prom[i], 6);
70 bit1 = BIT(color_prom[i], 7);
71 int const b = combine_weights(weights_b, bit0, bit1);
72
73 palette.set_pen_color(i, rgb_t(r, g, b));
74 }
75 }
76
77
78 /***************************************************************************
79
80 Convert the color PROMs into a more useable format.
81
82 Swimmer has two 256x4 char/sprite palette PROMs and one 32x8 big sprite
83 palette PROM.
84 The palette PROMs are connected to the RGB output this way:
85 (the 500 and 250 ohm resistors are made of 1 kohm resistors in parallel)
86
87 bit 3 -- 250 ohm resistor -- BLUE
88 -- 500 ohm resistor -- BLUE
89 -- 250 ohm resistor -- GREEN
90 bit 0 -- 500 ohm resistor -- GREEN
91 bit 3 -- 1 kohm resistor -- GREEN
92 -- 250 ohm resistor -- RED
93 -- 500 ohm resistor -- RED
94 bit 0 -- 1 kohm resistor -- RED
95
96 bit 7 -- 250 ohm resistor -- BLUE
97 -- 500 ohm resistor -- BLUE
98 -- 250 ohm resistor -- GREEN
99 -- 500 ohm resistor -- GREEN
100 -- 1 kohm resistor -- GREEN
101 -- 250 ohm resistor -- RED
102 -- 500 ohm resistor -- RED
103 bit 0 -- 1 kohm resistor -- RED
104
105 Additionally, the background color of the score panel is determined by
106 these resistors:
107
108 /--- tri-state -- 470 -- BLUE
109 +5V -- 1kohm ------- tri-state -- 390 -- GREEN
110 \--- tri-state -- 1000 -- RED
111
112 ***************************************************************************/
113
swimmer_palette(palette_device & palette) const114 void cclimber_state::swimmer_palette(palette_device &palette) const
115 {
116 const uint8_t *color_prom = memregion("proms")->base();
117
118 for (int i = 0; i < 0x100; i++)
119 {
120 int bit0, bit1, bit2;
121
122 // red component
123 bit0 = BIT(color_prom[i + 0x000], 0);
124 bit1 = BIT(color_prom[i + 0x000], 1);
125 bit2 = BIT(color_prom[i + 0x000], 2);
126 int const r = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
127
128 // green component
129 bit0 = BIT(color_prom[i + 0x000], 3);
130 bit1 = BIT(color_prom[i + 0x100], 0);
131 bit2 = BIT(color_prom[i + 0x100], 1);
132 int const g = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
133
134 // blue component
135 bit0 = 0;
136 bit1 = BIT(color_prom[i + 0x100], 2);
137 bit2 = BIT(color_prom[i + 0x100], 3);
138 int const b = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
139
140 palette.set_pen_color(i, rgb_t(r, g, b));
141 }
142
143 color_prom += 0x200;
144
145 // big sprite
146 for (int i = 0; i < 0x20; i++)
147 {
148 int bit0, bit1, bit2;
149
150 // red component
151 bit0 = BIT(color_prom[i], 0);
152 bit1 = BIT(color_prom[i], 1);
153 bit2 = BIT(color_prom[i], 2);
154 int const r = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
155
156 // green component
157 bit0 = BIT(color_prom[i], 3);
158 bit1 = BIT(color_prom[i], 4);
159 bit2 = BIT(color_prom[i], 5);
160 int const g = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
161
162 // blue component
163 bit0 = 0;
164 bit1 = BIT(color_prom[i], 6);
165 bit2 = BIT(color_prom[i], 7);
166 int const b = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
167
168 palette.set_pen_color(i + 0x100, rgb_t(r, g, b));
169 }
170
171 // side panel backgrond pen
172 #if 0
173 // values calculated from the resistors don't seem to match the real board
174 palette.set_pen_color(SWIMMER_SIDE_BG_PEN, rgb_t(0x24, 0x5d, 0x4e));
175 #endif
176 palette.set_pen_color(SWIMMER_SIDE_BG_PEN, rgb_t(0x20, 0x98, 0x79));
177 }
178
179
yamato_palette(palette_device & palette) const180 void cclimber_state::yamato_palette(palette_device &palette) const
181 {
182 uint8_t const *const color_prom = memregion("proms")->base();
183
184 // chars - 12 bits RGB
185 for (int i = 0; i < 0x40; i++)
186 {
187 int bit0, bit1, bit2, bit3;
188
189 // red component
190 bit0 = BIT(color_prom[i + 0x00], 0);
191 bit1 = BIT(color_prom[i + 0x00], 1);
192 bit2 = BIT(color_prom[i + 0x00], 2);
193 bit3 = BIT(color_prom[i + 0x00], 3);
194 int const r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
195
196 // green component
197 bit0 = BIT(color_prom[i + 0x00], 4);
198 bit1 = BIT(color_prom[i + 0x00], 5);
199 bit2 = BIT(color_prom[i + 0x00], 6);
200 bit3 = BIT(color_prom[i + 0x00], 7);
201 int const g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
202
203 // blue component
204 bit0 = BIT(color_prom[i + 0x40], 0);
205 bit1 = BIT(color_prom[i + 0x40], 1);
206 bit2 = BIT(color_prom[i + 0x40], 2);
207 bit3 = BIT(color_prom[i + 0x40], 3);
208 int const b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
209
210 palette.set_pen_color(i, rgb_t(r, g, b));
211 }
212
213 // big sprite - 8 bits RGB
214 for (int i = 0; i < 0x20; i++)
215 {
216 int bit0, bit1, bit2;
217
218 // red component
219 bit0 = BIT(color_prom[i + 0x80], 0);
220 bit1 = BIT(color_prom[i + 0x80], 1);
221 bit2 = BIT(color_prom[i + 0x80], 2);
222 int const r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
223
224 // green component
225 bit0 = BIT(color_prom[i + 0x80], 3);
226 bit1 = BIT(color_prom[i + 0x80], 4);
227 bit2 = BIT(color_prom[i + 0x80], 5);
228 int const g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
229
230 // blue component
231 bit0 = 0;
232 bit1 = BIT(color_prom[i + 0x80], 6);
233 bit2 = BIT(color_prom[i + 0x80], 7);
234 int const b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
235
236 palette.set_pen_color(i + 0x40, rgb_t(r, g, b));
237 }
238
239 // fake colors for bg gradient
240 for (int i = 0; i < 0x100; i++)
241 palette.set_pen_color(YAMATO_SKY_PEN_BASE + i, rgb_t(0, 0, i));
242 }
243
244
toprollr_palette(palette_device & palette) const245 void cclimber_state::toprollr_palette(palette_device &palette) const
246 {
247 uint8_t const *const color_prom = memregion("proms")->base();
248
249 for (int i = 0; i < 0xa0; i++)
250 {
251 int bit0, bit1, bit2;
252
253 // red component
254 bit0 = BIT(color_prom[i], 0);
255 bit1 = BIT(color_prom[i], 1);
256 bit2 = BIT(color_prom[i], 2);
257 int const r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
258
259 // green component
260 bit0 = BIT(color_prom[i], 3);
261 bit1 = BIT(color_prom[i], 4);
262 bit2 = BIT(color_prom[i], 5);
263 int const g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
264
265 // blue component
266 bit0 = 0;
267 bit1 = BIT(color_prom[i], 6);
268 bit2 = BIT(color_prom[i], 7);
269 int const b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
270
271 palette.set_pen_color(i, rgb_t(r, g, b));
272 }
273 }
274
275
276 /***************************************************************************
277
278 Swimmer can directly set the background color.
279 The latch is connected to the RGB output this way:
280 (the 500 and 250 ohm resistors are made of 1 kohm resistors in parallel)
281
282 bit 7 -- 250 ohm resistor -- RED
283 -- 500 ohm resistor -- RED
284 -- 250 ohm resistor -- GREEN
285 -- 500 ohm resistor -- GREEN
286 -- 1 kohm resistor -- GREEN
287 -- 250 ohm resistor -- BLUE
288 -- 500 ohm resistor -- BLUE
289 bit 0 -- 1 kohm resistor -- BLUE
290
291 ***************************************************************************/
292
swimmer_set_background_pen()293 void cclimber_state::swimmer_set_background_pen()
294 {
295 int bit0, bit1, bit2;
296 int r, g, b;
297
298 /* red component */
299 bit0 = 0;
300 bit1 = (*m_swimmer_background_color >> 6) & 0x01;
301 bit2 = (*m_swimmer_background_color >> 7) & 0x01;
302 r = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
303
304 /* green component */
305 bit0 = (*m_swimmer_background_color >> 3) & 0x01;
306 bit1 = (*m_swimmer_background_color >> 4) & 0x01;
307 bit2 = (*m_swimmer_background_color >> 5) & 0x01;
308 g = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
309
310 /* blue component */
311 bit0 = (*m_swimmer_background_color >> 0) & 0x01;
312 bit1 = (*m_swimmer_background_color >> 1) & 0x01;
313 bit2 = (*m_swimmer_background_color >> 2) & 0x01;
314 b = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
315
316 m_palette->set_pen_color(CCLIMBER_BG_PEN, rgb_t(r, g, b));
317 }
318
319
320
cclimber_colorram_w(offs_t offset,uint8_t data)321 void cclimber_state::cclimber_colorram_w(offs_t offset, uint8_t data)
322 {
323 /* A5 is not connected, there is only 0x200 bytes of RAM */
324 m_colorram[offset & ~0x20] = data;
325 m_colorram[offset | 0x20] = data;
326 }
327
328
flip_screen_x_w(int state)329 void cclimber_state::flip_screen_x_w(int state)
330 {
331 m_flip_x = state;
332 }
333
334
flip_screen_y_w(int state)335 void cclimber_state::flip_screen_y_w(int state)
336 {
337 m_flip_y = state;
338 }
339
340
sidebg_enable_w(int state)341 void cclimber_state::sidebg_enable_w(int state)
342 {
343 m_swimmer_side_background_enabled = state;
344 }
345
346
palette_bank_w(int state)347 void cclimber_state::palette_bank_w(int state)
348 {
349 m_swimmer_palettebank = state;
350 }
351
352
TILE_GET_INFO_MEMBER(cclimber_state::cclimber_get_pf_tile_info)353 TILE_GET_INFO_MEMBER(cclimber_state::cclimber_get_pf_tile_info)
354 {
355 int code, color;
356
357 int flags = TILE_FLIPYX(m_colorram[tile_index] >> 6);
358
359 /* vertical flipping flips two adjacent characters */
360 if (flags & 0x02)
361 tile_index = tile_index ^ 0x20;
362
363 code = ((m_colorram[tile_index] & 0x10) << 5) |
364 ((m_colorram[tile_index] & 0x20) << 3) |
365 m_videoram[tile_index];
366
367 color = m_colorram[tile_index] & 0x0f;
368
369 tileinfo.set(0, code, color, flags);
370 }
371
372
TILE_GET_INFO_MEMBER(cclimber_state::swimmer_get_pf_tile_info)373 TILE_GET_INFO_MEMBER(cclimber_state::swimmer_get_pf_tile_info)
374 {
375 int code, color;
376
377 int flags = TILE_FLIPYX(m_colorram[tile_index] >> 6);
378
379 /* vertical flipping flips two adjacent characters */
380 if (flags & 0x02)
381 tile_index = tile_index ^ 0x20;
382
383 code = ((m_colorram[tile_index] & 0x10) << 4) | m_videoram[tile_index];
384 color = (m_swimmer_palettebank << 4) | (m_colorram[tile_index] & 0x0f);
385
386 tileinfo.set(0, code, color, flags);
387 }
388
389
TILE_GET_INFO_MEMBER(cclimber_state::toprollr_get_pf_tile_info)390 TILE_GET_INFO_MEMBER(cclimber_state::toprollr_get_pf_tile_info)
391 {
392 int code, attr, color;
393
394 attr = tile_index & 0x10 ? m_colorram[tile_index & ~0x20] : m_colorram[tile_index];
395 code = ((attr & 0x30) << 4) | m_videoram[tile_index];
396 color = attr & 0x0f;
397
398 tileinfo.set(0, code, color, 0);
399 }
400
401
TILE_GET_INFO_MEMBER(cclimber_state::cclimber_get_bs_tile_info)402 TILE_GET_INFO_MEMBER(cclimber_state::cclimber_get_bs_tile_info)
403 {
404 int code, color;
405
406 /* only the lower right is visible */
407 tileinfo.group = ((tile_index & 0x210) == 0x210) ? 0 : 1;
408
409 /* the address doesn't use A4 of the coordinates, giving a 16x16 map */
410 tile_index = ((tile_index & 0x1e0) >> 1) | (tile_index & 0x0f);
411
412 code = ((m_bigsprite_control[1] & 0x08) << 5) | m_bigsprite_videoram[tile_index];
413 color = m_bigsprite_control[1] & 0x07;
414
415 tileinfo.set(2, code, color, 0);
416 }
417
418
TILE_GET_INFO_MEMBER(cclimber_state::toprollr_get_bs_tile_info)419 TILE_GET_INFO_MEMBER(cclimber_state::toprollr_get_bs_tile_info)
420 {
421 int code, color;
422
423 /* only the lower right is visible */
424 tileinfo.group = ((tile_index & 0x210) == 0x210) ? 0 : 1;
425
426 /* the address doesn't use A4 of the coordinates, giving a 16x16 map */
427 tile_index = ((tile_index & 0x1e0) >> 1) | (tile_index & 0x0f);
428
429 code = ((m_bigsprite_control[1] & 0x18) << 5) | m_bigsprite_videoram[tile_index];
430 color = m_bigsprite_control[1] & 0x07;
431
432 tileinfo.set(2, code, color, 0);
433 }
434
435
TILE_GET_INFO_MEMBER(cclimber_state::toproller_get_bg_tile_info)436 TILE_GET_INFO_MEMBER(cclimber_state::toproller_get_bg_tile_info)
437 {
438 int code = ((m_toprollr_bg_coloram[tile_index] & 0x40) << 2) | m_toprollr_bg_videoram[tile_index];
439 int color = m_toprollr_bg_coloram[tile_index] & 0x0f;
440
441 tileinfo.set(3, code, color, TILE_FLIPX);
442 }
443
444
VIDEO_START_MEMBER(cclimber_state,cclimber)445 VIDEO_START_MEMBER(cclimber_state,cclimber)
446 {
447 m_pf_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(cclimber_state::cclimber_get_pf_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
448 m_pf_tilemap->set_transparent_pen(0);
449 m_pf_tilemap->set_scroll_cols(32);
450
451 m_bs_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(cclimber_state::cclimber_get_bs_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
452 m_bs_tilemap->set_scroll_cols(1);
453 m_bs_tilemap->set_scroll_rows(1);
454 m_bs_tilemap->set_transmask(0, 0x01, 0); /* pen 0 is transaprent */
455 m_bs_tilemap->set_transmask(1, 0x0f, 0); /* all 4 pens are transparent */
456
457 save_item(NAME(m_flip_x));
458 save_item(NAME(m_flip_y));
459 }
460
461
VIDEO_START_MEMBER(cclimber_state,swimmer)462 VIDEO_START_MEMBER(cclimber_state,swimmer)
463 {
464 m_pf_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(cclimber_state::swimmer_get_pf_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
465 m_pf_tilemap->set_transparent_pen(0);
466 m_pf_tilemap->set_scroll_cols(32);
467
468 m_bs_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(cclimber_state::cclimber_get_bs_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
469 m_bs_tilemap->set_scroll_cols(1);
470 m_bs_tilemap->set_scroll_rows(1);
471 m_bs_tilemap->set_transmask(0, 0x01, 0); /* pen 0 is transaprent */
472 m_bs_tilemap->set_transmask(1, 0xff, 0); /* all 8 pens are transparent */
473
474 save_item(NAME(m_flip_x));
475 save_item(NAME(m_flip_y));
476 save_item(NAME(m_swimmer_side_background_enabled));
477 save_item(NAME(m_swimmer_palettebank));
478 }
479
480
VIDEO_START_MEMBER(cclimber_state,toprollr)481 VIDEO_START_MEMBER(cclimber_state,toprollr)
482 {
483 m_pf_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(cclimber_state::toprollr_get_pf_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
484 m_pf_tilemap->set_transparent_pen(0);
485
486 m_toproller_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(cclimber_state::toproller_get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
487 m_toproller_bg_tilemap->set_scroll_rows(1);
488
489 m_bs_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(cclimber_state::toprollr_get_bs_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
490 m_bs_tilemap->set_scroll_cols(1);
491 m_bs_tilemap->set_scroll_rows(1);
492 m_bs_tilemap->set_transmask(0, 0x01, 0); /* pen 0 is transaprent */
493 m_bs_tilemap->set_transmask(1, 0x0f, 0); /* all 4 pens are transparent */
494
495 save_item(NAME(m_flip_x));
496 save_item(NAME(m_flip_y));
497 }
498
499
draw_playfield(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)500 void cclimber_state::draw_playfield(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
501 {
502 int i;
503
504 m_pf_tilemap->mark_all_dirty();
505 m_pf_tilemap->set_flip((m_flip_x ? TILEMAP_FLIPX : 0) |
506 (m_flip_y ? TILEMAP_FLIPY : 0));
507 for (i = 0; i < 32; i++)
508 m_pf_tilemap->set_scrolly(i, m_column_scroll[i]);
509
510 m_pf_tilemap->draw(screen, bitmap, cliprect, 0, 0);
511 }
512
513
cclimber_draw_bigsprite(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)514 void cclimber_state::cclimber_draw_bigsprite(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
515 {
516 uint8_t x = m_bigsprite_control[3] - 8;
517 uint8_t y = m_bigsprite_control[2];
518 int bigsprite_flip_x = (m_bigsprite_control[1] & 0x10) >> 4;
519 int bigsprite_flip_y = (m_bigsprite_control[1] & 0x20) >> 5;
520
521 if (bigsprite_flip_x)
522 x = 0x80 - x;
523
524 if (bigsprite_flip_y)
525 y = 0x80 - y;
526
527 m_bs_tilemap->mark_all_dirty();
528
529 m_bs_tilemap->set_flip((bigsprite_flip_x ? TILEMAP_FLIPX : 0) |
530 (m_flip_y ^ bigsprite_flip_y ? TILEMAP_FLIPY : 0));
531
532 m_bs_tilemap->set_scrollx(0, x);
533 m_bs_tilemap->set_scrolly(0, y);
534
535 m_bs_tilemap->draw(screen, bitmap, cliprect, 0, 0);
536 }
537
538
toprollr_draw_bigsprite(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)539 void cclimber_state::toprollr_draw_bigsprite(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
540 {
541 uint8_t x = m_bigsprite_control[3] - 8;
542 uint8_t y = m_bigsprite_control[2];
543
544 m_bs_tilemap->mark_all_dirty();
545
546 m_bs_tilemap->set_flip(m_flip_y ? TILEMAP_FLIPY : 0);
547
548 m_bs_tilemap->set_scrollx(0, x);
549 m_bs_tilemap->set_scrolly(0, y);
550
551 m_bs_tilemap->draw(screen, bitmap, cliprect, 0, 0);
552 }
553
554
cclimber_draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect,gfx_element * gfx)555 void cclimber_state::cclimber_draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx)
556 {
557 int offs;
558
559 /* draw the sprites -- note that it is important to draw them exactly in this
560 order, to have the correct priorities. */
561 for (offs = 0x1c; offs >= 0; offs -= 4)
562 {
563 int x = m_spriteram[offs + 3] + 1;
564 /* x + 1 is evident in cclimber and ckong. It looks worse,
565 but it has been confirmed on several PCBs. */
566
567 int y = 240 - m_spriteram[offs + 2];
568
569 int code = ((m_spriteram[offs + 1] & 0x10) << 3) |
570 ((m_spriteram[offs + 1] & 0x20) << 1) |
571 ( m_spriteram[offs + 0] & 0x3f);
572
573 int color = m_spriteram[offs + 1] & 0x0f;
574
575 int flipx = m_spriteram[offs + 0] & 0x40;
576 int flipy = m_spriteram[offs + 0] & 0x80;
577
578 if (m_flip_x)
579 {
580 x = 242 - x;
581 flipx = !flipx;
582 }
583
584 if (m_flip_y)
585 {
586 y = 240 - y;
587 flipy = !flipy;
588 }
589
590 gfx->transpen(bitmap,cliprect, code, color, flipx, flipy, x, y, 0);
591 }
592 }
593
594
toprollr_draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect,gfx_element * gfx)595 void cclimber_state::toprollr_draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx)
596 {
597 int offs;
598
599 /* draw the sprites -- note that it is important to draw them exactly in this
600 order, to have the correct priorities. */
601 for (offs = m_spriteram.bytes() - 4; offs >= 0; offs -= 4)
602 {
603 int x = m_spriteram[offs + 3];
604 int y = 240 - m_spriteram[offs + 2];
605
606 int code = ((m_spriteram[offs + 1] & 0x10) << 3) |
607 ((m_spriteram[offs + 1] & 0x20) << 1) |
608 ( m_spriteram[offs + 0] & 0x3f);
609
610 int color = m_spriteram[offs + 1] & 0x0f;
611
612 int flipx = m_spriteram[offs + 0] & 0x40;
613 int flipy = m_spriteram[offs + 0] & 0x80;
614
615 if (m_flip_x)
616 {
617 x = 240 - x;
618 flipx = !flipx;
619 }
620
621 if (m_flip_y)
622 {
623 y = 240 - y;
624 flipy = !flipy;
625 }
626
627 gfx->transpen(bitmap,cliprect, code, color, flipx, flipy, x, y, 0);
628 }
629 }
630
631
swimmer_draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect,gfx_element * gfx)632 void cclimber_state::swimmer_draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx)
633 {
634 int offs;
635
636 /* draw the sprites -- note that it is important to draw them exactly in this
637 order, to have the correct priorities. */
638 for (offs = 0x1c; offs >= 0; offs -= 4)
639 {
640 int x = m_spriteram[offs + 3];
641 int y = 240 - m_spriteram[offs + 2];
642
643 int code = ((m_spriteram[offs + 1] & 0x10) << 2) |
644 (m_spriteram[offs + 0] & 0x3f);
645
646 int color = (m_swimmer_palettebank << 4) |
647 (m_spriteram[offs + 1] & 0x0f);
648
649 int flipx = m_spriteram[offs + 0] & 0x40;
650 int flipy = m_spriteram[offs + 0] & 0x80;
651
652 if (m_flip_x)
653 {
654 x = 240 - x;
655 flipx = !flipx;
656 }
657
658 if (m_flip_y)
659 {
660 y = 240 - y;
661 flipy = !flipy;
662 }
663
664 gfx->transpen(bitmap,cliprect, code, color, flipx, flipy, x, y, 0);
665 }
666 }
667
668
screen_update_cclimber(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)669 uint32_t cclimber_state::screen_update_cclimber(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
670 {
671 bitmap.fill(CCLIMBER_BG_PEN, cliprect);
672 draw_playfield(screen, bitmap, cliprect);
673
674 /* draw the "big sprite" under the regular sprites */
675 if ((m_bigsprite_control[0] & 0x01))
676 {
677 cclimber_draw_bigsprite(screen, bitmap, cliprect);
678 cclimber_draw_sprites(bitmap, cliprect, m_gfxdecode->gfx(1));
679 }
680
681 /* draw the "big sprite" over the regular sprites */
682 else
683 {
684 cclimber_draw_sprites(bitmap, cliprect, m_gfxdecode->gfx(1));
685 cclimber_draw_bigsprite(screen, bitmap, cliprect);
686 }
687
688 return 0;
689 }
690
691
screen_update_yamato(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)692 uint32_t cclimber_state::screen_update_yamato(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
693 {
694 uint8_t const *const sky_rom = memregion("user1")->base() + 0x1200;
695
696 for (int i = 0; i < 0x100; i++)
697 {
698 pen_t pen = YAMATO_SKY_PEN_BASE + sky_rom[(m_flip_x ? 0x80 : 0) + (i >> 1)];
699
700 for (int j = 0; j < 0x100; j++)
701 bitmap.pix(j, (i - 8) & 0xff) = pen;
702 }
703
704 draw_playfield(screen, bitmap, cliprect);
705
706 /* draw the "big sprite" under the regular sprites */
707 if ((m_bigsprite_control[0] & 0x01))
708 {
709 cclimber_draw_bigsprite(screen, bitmap, cliprect);
710 toprollr_draw_sprites(bitmap, cliprect, m_gfxdecode->gfx(1));
711 }
712
713 /* draw the "big sprite" over the regular sprites */
714 else
715 {
716 toprollr_draw_sprites(bitmap, cliprect, m_gfxdecode->gfx(1));
717 cclimber_draw_bigsprite(screen, bitmap, cliprect);
718 }
719
720 return 0;
721 }
722
723
screen_update_swimmer(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)724 uint32_t cclimber_state::screen_update_swimmer(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
725 {
726 swimmer_set_background_pen();
727
728 if (m_swimmer_side_background_enabled)
729 {
730 if (m_flip_x)
731 {
732 rectangle split_rect_left(0, 0xff - SWIMMER_BG_SPLIT, 0, 0xff);
733 rectangle split_rect_right(0x100 - SWIMMER_BG_SPLIT, 0xff, 0, 0xff);
734
735 split_rect_left &= cliprect;
736 bitmap.fill(SWIMMER_SIDE_BG_PEN, split_rect_left);
737
738 split_rect_right &= cliprect;
739 bitmap.fill(CCLIMBER_BG_PEN, split_rect_right);
740 }
741 else
742 {
743 rectangle split_rect_left(0, SWIMMER_BG_SPLIT - 1, 0, 0xff);
744 rectangle split_rect_right(SWIMMER_BG_SPLIT, 0xff, 0, 0xff);
745
746 split_rect_left &= cliprect;
747 bitmap.fill(CCLIMBER_BG_PEN, split_rect_left);
748
749 split_rect_right &= cliprect;
750 bitmap.fill(SWIMMER_SIDE_BG_PEN, split_rect_right);
751 }
752 }
753 else
754 bitmap.fill(CCLIMBER_BG_PEN, cliprect);
755
756 draw_playfield(screen, bitmap, cliprect);
757
758 /* draw the "big sprite" under the regular sprites */
759 if ((m_bigsprite_control[0] & 0x01))
760 {
761 cclimber_draw_bigsprite(screen, bitmap, cliprect);
762 swimmer_draw_sprites(bitmap, cliprect, m_gfxdecode->gfx(1));
763 }
764
765 /* draw the "big sprite" over the regular sprites */
766 else
767 {
768 swimmer_draw_sprites(bitmap, cliprect, m_gfxdecode->gfx(1));
769 cclimber_draw_bigsprite(screen, bitmap, cliprect);
770 }
771
772 return 0;
773 }
774
775
screen_update_toprollr(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)776 uint32_t cclimber_state::screen_update_toprollr(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
777 {
778 rectangle scroll_area_clip = cliprect;
779 scroll_area_clip.min_x = 4*8;
780 scroll_area_clip.max_x = 29*8-1;
781
782 bitmap.fill(CCLIMBER_BG_PEN, cliprect);
783
784 m_toproller_bg_tilemap->set_scrollx(0, m_toprollr_bg_videoram[0]);
785 m_toproller_bg_tilemap->set_flip((m_flip_x ? TILEMAP_FLIPX : 0) |
786 (m_flip_y ? TILEMAP_FLIPY : 0));
787 m_toproller_bg_tilemap->mark_all_dirty();
788 m_toproller_bg_tilemap->draw(screen, bitmap, scroll_area_clip, 0, 0);
789
790 /* draw the "big sprite" over the regular sprites */
791 if ((m_bigsprite_control[1] & 0x20))
792 {
793 toprollr_draw_sprites(bitmap, scroll_area_clip, m_gfxdecode->gfx(1));
794 toprollr_draw_bigsprite(screen, bitmap, scroll_area_clip);
795 }
796
797 /* draw the "big sprite" under the regular sprites */
798 else
799 {
800 toprollr_draw_bigsprite(screen, bitmap, scroll_area_clip);
801 toprollr_draw_sprites(bitmap, scroll_area_clip, m_gfxdecode->gfx(1));
802 }
803
804 m_pf_tilemap->mark_all_dirty();
805 m_pf_tilemap->set_flip((m_flip_x ? TILEMAP_FLIPX : 0) |
806 (m_flip_y ? TILEMAP_FLIPY : 0));
807 m_pf_tilemap->draw(screen, bitmap, cliprect, 0, 0);
808
809 return 0;
810 }
811