// license:BSD-3-Clause // copyright-holders:Nicola Salmoria /*************************************************************************** cclimber.cpp Functions to emulate the video hardware of the machine. ***************************************************************************/ #include "emu.h" #include "video/resnet.h" #include "includes/cclimber.h" #define CCLIMBER_BG_PEN (0) #define SWIMMER_SIDE_BG_PEN (0x120) #define SWIMMER_BG_SPLIT (0x18 * 8) #define YAMATO_SKY_PEN_BASE (0x60) /*************************************************************************** Convert the color PROMs into a more useable format. Crazy Climber has three 32x8 palette PROMs. The palette PROMs are connected to the RGB output this way: bit 7 -- 220 ohm resistor -- BLUE -- 470 ohm resistor -- BLUE -- 220 ohm resistor -- GREEN -- 470 ohm resistor -- GREEN -- 1 kohm resistor -- GREEN -- 220 ohm resistor -- RED -- 470 ohm resistor -- RED bit 0 -- 1 kohm resistor -- RED ***************************************************************************/ void cclimber_state::cclimber_palette(palette_device &palette) const { const uint8_t *color_prom = memregion("proms")->base(); static constexpr int resistances_rg[3] = { 1000, 470, 220 }; static constexpr int resistances_b [2] = { 470, 220 }; // compute the color output resistor weights double weights_rg[3], weights_b[2]; compute_resistor_weights(0, 255, -1.0, 3, resistances_rg, weights_rg, 0, 0, 2, resistances_b, weights_b, 0, 0, 0, nullptr, nullptr, 0, 0); for (int i = 0;i < palette.entries(); i++) { int bit0, bit1, bit2; // red component bit0 = BIT(color_prom[i], 0); bit1 = BIT(color_prom[i], 1); bit2 = BIT(color_prom[i], 2); int const r = combine_weights(weights_rg, bit0, bit1, bit2); // green component bit0 = BIT(color_prom[i], 3); bit1 = BIT(color_prom[i], 4); bit2 = BIT(color_prom[i], 5); int const g = combine_weights(weights_rg, bit0, bit1, bit2); // blue component bit0 = BIT(color_prom[i], 6); bit1 = BIT(color_prom[i], 7); int const b = combine_weights(weights_b, bit0, bit1); palette.set_pen_color(i, rgb_t(r, g, b)); } } /*************************************************************************** Convert the color PROMs into a more useable format. Swimmer has two 256x4 char/sprite palette PROMs and one 32x8 big sprite palette PROM. The palette PROMs are connected to the RGB output this way: (the 500 and 250 ohm resistors are made of 1 kohm resistors in parallel) bit 3 -- 250 ohm resistor -- BLUE -- 500 ohm resistor -- BLUE -- 250 ohm resistor -- GREEN bit 0 -- 500 ohm resistor -- GREEN bit 3 -- 1 kohm resistor -- GREEN -- 250 ohm resistor -- RED -- 500 ohm resistor -- RED bit 0 -- 1 kohm resistor -- RED bit 7 -- 250 ohm resistor -- BLUE -- 500 ohm resistor -- BLUE -- 250 ohm resistor -- GREEN -- 500 ohm resistor -- GREEN -- 1 kohm resistor -- GREEN -- 250 ohm resistor -- RED -- 500 ohm resistor -- RED bit 0 -- 1 kohm resistor -- RED Additionally, the background color of the score panel is determined by these resistors: /--- tri-state -- 470 -- BLUE +5V -- 1kohm ------- tri-state -- 390 -- GREEN \--- tri-state -- 1000 -- RED ***************************************************************************/ void cclimber_state::swimmer_palette(palette_device &palette) const { const uint8_t *color_prom = memregion("proms")->base(); for (int i = 0; i < 0x100; i++) { int bit0, bit1, bit2; // red component bit0 = BIT(color_prom[i + 0x000], 0); bit1 = BIT(color_prom[i + 0x000], 1); bit2 = BIT(color_prom[i + 0x000], 2); int const r = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2; // green component bit0 = BIT(color_prom[i + 0x000], 3); bit1 = BIT(color_prom[i + 0x100], 0); bit2 = BIT(color_prom[i + 0x100], 1); int const g = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2; // blue component bit0 = 0; bit1 = BIT(color_prom[i + 0x100], 2); bit2 = BIT(color_prom[i + 0x100], 3); int const b = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2; palette.set_pen_color(i, rgb_t(r, g, b)); } color_prom += 0x200; // big sprite for (int i = 0; i < 0x20; i++) { int bit0, bit1, bit2; // red component bit0 = BIT(color_prom[i], 0); bit1 = BIT(color_prom[i], 1); bit2 = BIT(color_prom[i], 2); int const r = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2; // green component bit0 = BIT(color_prom[i], 3); bit1 = BIT(color_prom[i], 4); bit2 = BIT(color_prom[i], 5); int const g = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2; // blue component bit0 = 0; bit1 = BIT(color_prom[i], 6); bit2 = BIT(color_prom[i], 7); int const b = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2; palette.set_pen_color(i + 0x100, rgb_t(r, g, b)); } // side panel backgrond pen #if 0 // values calculated from the resistors don't seem to match the real board palette.set_pen_color(SWIMMER_SIDE_BG_PEN, rgb_t(0x24, 0x5d, 0x4e)); #endif palette.set_pen_color(SWIMMER_SIDE_BG_PEN, rgb_t(0x20, 0x98, 0x79)); } void cclimber_state::yamato_palette(palette_device &palette) const { uint8_t const *const color_prom = memregion("proms")->base(); // chars - 12 bits RGB for (int i = 0; i < 0x40; i++) { int bit0, bit1, bit2, bit3; // red component bit0 = BIT(color_prom[i + 0x00], 0); bit1 = BIT(color_prom[i + 0x00], 1); bit2 = BIT(color_prom[i + 0x00], 2); bit3 = BIT(color_prom[i + 0x00], 3); int const r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; // green component bit0 = BIT(color_prom[i + 0x00], 4); bit1 = BIT(color_prom[i + 0x00], 5); bit2 = BIT(color_prom[i + 0x00], 6); bit3 = BIT(color_prom[i + 0x00], 7); int const g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; // blue component bit0 = BIT(color_prom[i + 0x40], 0); bit1 = BIT(color_prom[i + 0x40], 1); bit2 = BIT(color_prom[i + 0x40], 2); bit3 = BIT(color_prom[i + 0x40], 3); int const b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; palette.set_pen_color(i, rgb_t(r, g, b)); } // big sprite - 8 bits RGB for (int i = 0; i < 0x20; i++) { int bit0, bit1, bit2; // red component bit0 = BIT(color_prom[i + 0x80], 0); bit1 = BIT(color_prom[i + 0x80], 1); bit2 = BIT(color_prom[i + 0x80], 2); int const r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; // green component bit0 = BIT(color_prom[i + 0x80], 3); bit1 = BIT(color_prom[i + 0x80], 4); bit2 = BIT(color_prom[i + 0x80], 5); int const g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; // blue component bit0 = 0; bit1 = BIT(color_prom[i + 0x80], 6); bit2 = BIT(color_prom[i + 0x80], 7); int const b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; palette.set_pen_color(i + 0x40, rgb_t(r, g, b)); } // fake colors for bg gradient for (int i = 0; i < 0x100; i++) palette.set_pen_color(YAMATO_SKY_PEN_BASE + i, rgb_t(0, 0, i)); } void cclimber_state::toprollr_palette(palette_device &palette) const { uint8_t const *const color_prom = memregion("proms")->base(); for (int i = 0; i < 0xa0; i++) { int bit0, bit1, bit2; // red component bit0 = BIT(color_prom[i], 0); bit1 = BIT(color_prom[i], 1); bit2 = BIT(color_prom[i], 2); int const r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; // green component bit0 = BIT(color_prom[i], 3); bit1 = BIT(color_prom[i], 4); bit2 = BIT(color_prom[i], 5); int const g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; // blue component bit0 = 0; bit1 = BIT(color_prom[i], 6); bit2 = BIT(color_prom[i], 7); int const b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; palette.set_pen_color(i, rgb_t(r, g, b)); } } /*************************************************************************** Swimmer can directly set the background color. The latch is connected to the RGB output this way: (the 500 and 250 ohm resistors are made of 1 kohm resistors in parallel) bit 7 -- 250 ohm resistor -- RED -- 500 ohm resistor -- RED -- 250 ohm resistor -- GREEN -- 500 ohm resistor -- GREEN -- 1 kohm resistor -- GREEN -- 250 ohm resistor -- BLUE -- 500 ohm resistor -- BLUE bit 0 -- 1 kohm resistor -- BLUE ***************************************************************************/ void cclimber_state::swimmer_set_background_pen() { int bit0, bit1, bit2; int r, g, b; /* red component */ bit0 = 0; bit1 = (*m_swimmer_background_color >> 6) & 0x01; bit2 = (*m_swimmer_background_color >> 7) & 0x01; r = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2; /* green component */ bit0 = (*m_swimmer_background_color >> 3) & 0x01; bit1 = (*m_swimmer_background_color >> 4) & 0x01; bit2 = (*m_swimmer_background_color >> 5) & 0x01; g = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2; /* blue component */ bit0 = (*m_swimmer_background_color >> 0) & 0x01; bit1 = (*m_swimmer_background_color >> 1) & 0x01; bit2 = (*m_swimmer_background_color >> 2) & 0x01; b = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2; m_palette->set_pen_color(CCLIMBER_BG_PEN, rgb_t(r, g, b)); } WRITE8_MEMBER(cclimber_state::cclimber_colorram_w) { /* A5 is not connected, there is only 0x200 bytes of RAM */ m_colorram[offset & ~0x20] = data; m_colorram[offset | 0x20] = data; } WRITE_LINE_MEMBER(cclimber_state::flip_screen_x_w) { m_flip_x = state; } WRITE_LINE_MEMBER(cclimber_state::flip_screen_y_w) { m_flip_y = state; } WRITE_LINE_MEMBER(cclimber_state::sidebg_enable_w) { m_swimmer_side_background_enabled = state; } WRITE_LINE_MEMBER(cclimber_state::palette_bank_w) { m_swimmer_palettebank = state; } TILE_GET_INFO_MEMBER(cclimber_state::cclimber_get_pf_tile_info) { int code, color; int flags = TILE_FLIPYX(m_colorram[tile_index] >> 6); /* vertical flipping flips two adjacent characters */ if (flags & 0x02) tile_index = tile_index ^ 0x20; code = ((m_colorram[tile_index] & 0x10) << 5) | ((m_colorram[tile_index] & 0x20) << 3) | m_videoram[tile_index]; color = m_colorram[tile_index] & 0x0f; SET_TILE_INFO_MEMBER(0, code, color, flags); } TILE_GET_INFO_MEMBER(cclimber_state::swimmer_get_pf_tile_info) { int code, color; int flags = TILE_FLIPYX(m_colorram[tile_index] >> 6); /* vertical flipping flips two adjacent characters */ if (flags & 0x02) tile_index = tile_index ^ 0x20; code = ((m_colorram[tile_index] & 0x10) << 4) | m_videoram[tile_index]; color = (m_swimmer_palettebank << 4) | (m_colorram[tile_index] & 0x0f); SET_TILE_INFO_MEMBER(0, code, color, flags); } TILE_GET_INFO_MEMBER(cclimber_state::toprollr_get_pf_tile_info) { int code, attr, color; attr = tile_index & 0x10 ? m_colorram[tile_index & ~0x20] : m_colorram[tile_index]; code = ((attr & 0x30) << 4) | m_videoram[tile_index]; color = attr & 0x0f; SET_TILE_INFO_MEMBER(0, code, color, 0); } TILE_GET_INFO_MEMBER(cclimber_state::cclimber_get_bs_tile_info) { int code, color; /* only the lower right is visible */ tileinfo.group = ((tile_index & 0x210) == 0x210) ? 0 : 1; /* the address doesn't use A4 of the coordinates, giving a 16x16 map */ tile_index = ((tile_index & 0x1e0) >> 1) | (tile_index & 0x0f); code = ((m_bigsprite_control[1] & 0x08) << 5) | m_bigsprite_videoram[tile_index]; color = m_bigsprite_control[1] & 0x07; SET_TILE_INFO_MEMBER(2, code, color, 0); } TILE_GET_INFO_MEMBER(cclimber_state::toprollr_get_bs_tile_info) { int code, color; /* only the lower right is visible */ tileinfo.group = ((tile_index & 0x210) == 0x210) ? 0 : 1; /* the address doesn't use A4 of the coordinates, giving a 16x16 map */ tile_index = ((tile_index & 0x1e0) >> 1) | (tile_index & 0x0f); code = ((m_bigsprite_control[1] & 0x18) << 5) | m_bigsprite_videoram[tile_index]; color = m_bigsprite_control[1] & 0x07; SET_TILE_INFO_MEMBER(2, code, color, 0); } TILE_GET_INFO_MEMBER(cclimber_state::toproller_get_bg_tile_info) { int code = ((m_toprollr_bg_coloram[tile_index] & 0x40) << 2) | m_toprollr_bg_videoram[tile_index]; int color = m_toprollr_bg_coloram[tile_index] & 0x0f; SET_TILE_INFO_MEMBER(3, code, color, TILE_FLIPX); } VIDEO_START_MEMBER(cclimber_state,cclimber) { 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); m_pf_tilemap->set_transparent_pen(0); m_pf_tilemap->set_scroll_cols(32); 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); m_bs_tilemap->set_scroll_cols(1); m_bs_tilemap->set_scroll_rows(1); m_bs_tilemap->set_transmask(0, 0x01, 0); /* pen 0 is transaprent */ m_bs_tilemap->set_transmask(1, 0x0f, 0); /* all 4 pens are transparent */ save_item(NAME(m_flip_x)); save_item(NAME(m_flip_y)); } VIDEO_START_MEMBER(cclimber_state,swimmer) { 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); m_pf_tilemap->set_transparent_pen(0); m_pf_tilemap->set_scroll_cols(32); 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); m_bs_tilemap->set_scroll_cols(1); m_bs_tilemap->set_scroll_rows(1); m_bs_tilemap->set_transmask(0, 0x01, 0); /* pen 0 is transaprent */ m_bs_tilemap->set_transmask(1, 0xff, 0); /* all 8 pens are transparent */ save_item(NAME(m_flip_x)); save_item(NAME(m_flip_y)); save_item(NAME(m_swimmer_side_background_enabled)); save_item(NAME(m_swimmer_palettebank)); } VIDEO_START_MEMBER(cclimber_state,toprollr) { 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); m_pf_tilemap->set_transparent_pen(0); 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); m_toproller_bg_tilemap->set_scroll_rows(1); 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); m_bs_tilemap->set_scroll_cols(1); m_bs_tilemap->set_scroll_rows(1); m_bs_tilemap->set_transmask(0, 0x01, 0); /* pen 0 is transaprent */ m_bs_tilemap->set_transmask(1, 0x0f, 0); /* all 4 pens are transparent */ save_item(NAME(m_flip_x)); save_item(NAME(m_flip_y)); } void cclimber_state::draw_playfield(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int i; m_pf_tilemap->mark_all_dirty(); m_pf_tilemap->set_flip((m_flip_x ? TILEMAP_FLIPX : 0) | (m_flip_y ? TILEMAP_FLIPY : 0)); for (i = 0; i < 32; i++) m_pf_tilemap->set_scrolly(i, m_column_scroll[i]); m_pf_tilemap->draw(screen, bitmap, cliprect, 0, 0); } void cclimber_state::cclimber_draw_bigsprite(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { uint8_t x = m_bigsprite_control[3] - 8; uint8_t y = m_bigsprite_control[2]; int bigsprite_flip_x = (m_bigsprite_control[1] & 0x10) >> 4; int bigsprite_flip_y = (m_bigsprite_control[1] & 0x20) >> 5; if (bigsprite_flip_x) x = 0x80 - x; if (bigsprite_flip_y) y = 0x80 - y; m_bs_tilemap->mark_all_dirty(); m_bs_tilemap->set_flip((bigsprite_flip_x ? TILEMAP_FLIPX : 0) | (m_flip_y ^ bigsprite_flip_y ? TILEMAP_FLIPY : 0)); m_bs_tilemap->set_scrollx(0, x); m_bs_tilemap->set_scrolly(0, y); m_bs_tilemap->draw(screen, bitmap, cliprect, 0, 0); } void cclimber_state::toprollr_draw_bigsprite(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { uint8_t x = m_bigsprite_control[3] - 8; uint8_t y = m_bigsprite_control[2]; m_bs_tilemap->mark_all_dirty(); m_bs_tilemap->set_flip(m_flip_y ? TILEMAP_FLIPY : 0); m_bs_tilemap->set_scrollx(0, x); m_bs_tilemap->set_scrolly(0, y); m_bs_tilemap->draw(screen, bitmap, cliprect, 0, 0); } void cclimber_state::cclimber_draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx) { int offs; /* draw the sprites -- note that it is important to draw them exactly in this order, to have the correct priorities. */ for (offs = 0x1c; offs >= 0; offs -= 4) { int x = m_spriteram[offs + 3] + 1; /* x + 1 is evident in cclimber and ckong. It looks worse, but it has been confirmed on several PCBs. */ int y = 240 - m_spriteram[offs + 2]; int code = ((m_spriteram[offs + 1] & 0x10) << 3) | ((m_spriteram[offs + 1] & 0x20) << 1) | ( m_spriteram[offs + 0] & 0x3f); int color = m_spriteram[offs + 1] & 0x0f; int flipx = m_spriteram[offs + 0] & 0x40; int flipy = m_spriteram[offs + 0] & 0x80; if (m_flip_x) { x = 242 - x; flipx = !flipx; } if (m_flip_y) { y = 240 - y; flipy = !flipy; } gfx->transpen(bitmap,cliprect, code, color, flipx, flipy, x, y, 0); } } void cclimber_state::toprollr_draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx) { int offs; /* draw the sprites -- note that it is important to draw them exactly in this order, to have the correct priorities. */ for (offs = m_spriteram.bytes() - 4; offs >= 0; offs -= 4) { int x = m_spriteram[offs + 3]; int y = 240 - m_spriteram[offs + 2]; int code = ((m_spriteram[offs + 1] & 0x10) << 3) | ((m_spriteram[offs + 1] & 0x20) << 1) | ( m_spriteram[offs + 0] & 0x3f); int color = m_spriteram[offs + 1] & 0x0f; int flipx = m_spriteram[offs + 0] & 0x40; int flipy = m_spriteram[offs + 0] & 0x80; if (m_flip_x) { x = 240 - x; flipx = !flipx; } if (m_flip_y) { y = 240 - y; flipy = !flipy; } gfx->transpen(bitmap,cliprect, code, color, flipx, flipy, x, y, 0); } } void cclimber_state::swimmer_draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx) { int offs; /* draw the sprites -- note that it is important to draw them exactly in this order, to have the correct priorities. */ for (offs = 0x1c; offs >= 0; offs -= 4) { int x = m_spriteram[offs + 3]; int y = 240 - m_spriteram[offs + 2]; int code = ((m_spriteram[offs + 1] & 0x10) << 2) | (m_spriteram[offs + 0] & 0x3f); int color = (m_swimmer_palettebank << 4) | (m_spriteram[offs + 1] & 0x0f); int flipx = m_spriteram[offs + 0] & 0x40; int flipy = m_spriteram[offs + 0] & 0x80; if (m_flip_x) { x = 240 - x; flipx = !flipx; } if (m_flip_y) { y = 240 - y; flipy = !flipy; } gfx->transpen(bitmap,cliprect, code, color, flipx, flipy, x, y, 0); } } uint32_t cclimber_state::screen_update_cclimber(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { bitmap.fill(CCLIMBER_BG_PEN, cliprect); draw_playfield(screen, bitmap, cliprect); /* draw the "big sprite" under the regular sprites */ if ((m_bigsprite_control[0] & 0x01)) { cclimber_draw_bigsprite(screen, bitmap, cliprect); cclimber_draw_sprites(bitmap, cliprect, m_gfxdecode->gfx(1)); } /* draw the "big sprite" over the regular sprites */ else { cclimber_draw_sprites(bitmap, cliprect, m_gfxdecode->gfx(1)); cclimber_draw_bigsprite(screen, bitmap, cliprect); } return 0; } uint32_t cclimber_state::screen_update_yamato(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int i; uint8_t *sky_rom = memregion("user1")->base() + 0x1200; for (i = 0; i < 0x100; i++) { int j; pen_t pen = YAMATO_SKY_PEN_BASE + sky_rom[(m_flip_x ? 0x80 : 0) + (i >> 1)]; for (j = 0; j < 0x100; j++) bitmap.pix16(j, (i - 8) & 0xff) = pen; } draw_playfield(screen, bitmap, cliprect); /* draw the "big sprite" under the regular sprites */ if ((m_bigsprite_control[0] & 0x01)) { cclimber_draw_bigsprite(screen, bitmap, cliprect); toprollr_draw_sprites(bitmap, cliprect, m_gfxdecode->gfx(1)); } /* draw the "big sprite" over the regular sprites */ else { toprollr_draw_sprites(bitmap, cliprect, m_gfxdecode->gfx(1)); cclimber_draw_bigsprite(screen, bitmap, cliprect); } return 0; } uint32_t cclimber_state::screen_update_swimmer(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { swimmer_set_background_pen(); if (m_swimmer_side_background_enabled) { if (m_flip_x) { rectangle split_rect_left(0, 0xff - SWIMMER_BG_SPLIT, 0, 0xff); rectangle split_rect_right(0x100 - SWIMMER_BG_SPLIT, 0xff, 0, 0xff); split_rect_left &= cliprect; bitmap.fill(SWIMMER_SIDE_BG_PEN, split_rect_left); split_rect_right &= cliprect; bitmap.fill(CCLIMBER_BG_PEN, split_rect_right); } else { rectangle split_rect_left(0, SWIMMER_BG_SPLIT - 1, 0, 0xff); rectangle split_rect_right(SWIMMER_BG_SPLIT, 0xff, 0, 0xff); split_rect_left &= cliprect; bitmap.fill(CCLIMBER_BG_PEN, split_rect_left); split_rect_right &= cliprect; bitmap.fill(SWIMMER_SIDE_BG_PEN, split_rect_right); } } else bitmap.fill(CCLIMBER_BG_PEN, cliprect); draw_playfield(screen, bitmap, cliprect); /* draw the "big sprite" under the regular sprites */ if ((m_bigsprite_control[0] & 0x01)) { cclimber_draw_bigsprite(screen, bitmap, cliprect); swimmer_draw_sprites(bitmap, cliprect, m_gfxdecode->gfx(1)); } /* draw the "big sprite" over the regular sprites */ else { swimmer_draw_sprites(bitmap, cliprect, m_gfxdecode->gfx(1)); cclimber_draw_bigsprite(screen, bitmap, cliprect); } return 0; } uint32_t cclimber_state::screen_update_toprollr(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { rectangle scroll_area_clip = cliprect; scroll_area_clip.min_x = 4*8; scroll_area_clip.max_x = 29*8-1; bitmap.fill(CCLIMBER_BG_PEN, cliprect); m_toproller_bg_tilemap->set_scrollx(0, m_toprollr_bg_videoram[0]); m_toproller_bg_tilemap->set_flip((m_flip_x ? TILEMAP_FLIPX : 0) | (m_flip_y ? TILEMAP_FLIPY : 0)); m_toproller_bg_tilemap->mark_all_dirty(); m_toproller_bg_tilemap->draw(screen, bitmap, scroll_area_clip, 0, 0); /* draw the "big sprite" over the regular sprites */ if ((m_bigsprite_control[1] & 0x20)) { toprollr_draw_sprites(bitmap, scroll_area_clip, m_gfxdecode->gfx(1)); toprollr_draw_bigsprite(screen, bitmap, scroll_area_clip); } /* draw the "big sprite" under the regular sprites */ else { toprollr_draw_bigsprite(screen, bitmap, scroll_area_clip); toprollr_draw_sprites(bitmap, scroll_area_clip, m_gfxdecode->gfx(1)); } m_pf_tilemap->mark_all_dirty(); m_pf_tilemap->set_flip((m_flip_x ? TILEMAP_FLIPX : 0) | (m_flip_y ? TILEMAP_FLIPY : 0)); m_pf_tilemap->draw(screen, bitmap, cliprect, 0, 0); return 0; }