1 // license:BSD-3-Clause
2 // copyright-holders:Nicola Salmoria
3 #include "emu.h"
4 #include "includes/xmen.h"
5 
6 
7 /***************************************************************************
8 
9   Callbacks for the K052109
10 
11 ***************************************************************************/
12 
K052109_CB_MEMBER(xmen_state::tile_callback)13 K052109_CB_MEMBER(xmen_state::tile_callback)
14 {
15 	/* (color & 0x02) is flip y handled internally by the 052109 */
16 	if (layer == 0)
17 		*color = m_layer_colorbase[layer] + ((*color & 0xf0) >> 4);
18 	else
19 		*color = m_layer_colorbase[layer] + ((*color & 0x7c) >> 2);
20 }
21 
22 /***************************************************************************
23 
24   Callbacks for the K053247
25 
26 ***************************************************************************/
27 
K053246_CB_MEMBER(xmen_state::sprite_callback)28 K053246_CB_MEMBER(xmen_state::sprite_callback)
29 {
30 	int pri = (*color & 0x00e0) >> 4;   /* ??????? */
31 
32 	if (pri <= m_layerpri[2])
33 		*priority_mask = 0;
34 	else if (pri > m_layerpri[2] && pri <= m_layerpri[1])
35 		*priority_mask = 0xf0;
36 	else if (pri > m_layerpri[1] && pri <= m_layerpri[0])
37 		*priority_mask = 0xf0 | 0xcc;
38 	else
39 		*priority_mask = 0xf0 | 0xcc | 0xaa;
40 
41 	*color = m_sprite_colorbase + (*color & 0x001f);
42 }
43 
44 
45 
46 /***************************************************************************
47 
48   Start the video hardware emulation.
49 
50 ***************************************************************************/
51 
VIDEO_START_MEMBER(xmen_state,xmen6p)52 VIDEO_START_MEMBER(xmen_state,xmen6p)
53 {
54 	m_k053246->k053247_get_ram( &m_k053247_ram);
55 
56 	m_screen_left  = std::make_unique<bitmap_ind16>(64 * 8, 32 * 8);
57 	m_screen_right = std::make_unique<bitmap_ind16>(64 * 8, 32 * 8);
58 
59 	save_item(NAME(*m_screen_left));
60 	save_item(NAME(*m_screen_right));
61 }
62 
63 
64 /***************************************************************************
65 
66   Display refresh
67 
68 ***************************************************************************/
69 
screen_update_xmen(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)70 uint32_t xmen_state::screen_update_xmen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
71 {
72 	int layer[3], bg_colorbase;
73 
74 	bg_colorbase = m_k053251->get_palette_index(k053251_device::CI4);
75 	m_sprite_colorbase = m_k053251->get_palette_index(k053251_device::CI1);
76 	m_layer_colorbase[0] = m_k053251->get_palette_index(k053251_device::CI3);
77 	m_layer_colorbase[1] = m_k053251->get_palette_index(k053251_device::CI0);
78 	m_layer_colorbase[2] = m_k053251->get_palette_index(k053251_device::CI2);
79 
80 	m_k052109->tilemap_update();
81 
82 	layer[0] = 0;
83 	m_layerpri[0] = m_k053251->get_priority(k053251_device::CI3);
84 	layer[1] = 1;
85 	m_layerpri[1] = m_k053251->get_priority(k053251_device::CI0);
86 	layer[2] = 2;
87 	m_layerpri[2] = m_k053251->get_priority(k053251_device::CI2);
88 
89 	konami_sortlayers3(layer, m_layerpri);
90 
91 	screen.priority().fill(0, cliprect);
92 	/* note the '+1' in the background color!!! */
93 	bitmap.fill(16 * bg_colorbase + 1, cliprect);
94 	m_k052109->tilemap_draw(screen, bitmap, cliprect, layer[0], 0, 1);
95 	m_k052109->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 2);
96 	m_k052109->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 4);
97 
98 	/* this isn't supported anymore and it is unsure if still needed; keeping here for reference
99 	pdrawgfx_shadow_lowpri = 1; fix shadows of boulders in front of feet */
100 	m_k053246->k053247_sprites_draw( bitmap, cliprect);
101 	return 0;
102 }
103 
104 
screen_update_xmen6p_left(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)105 uint32_t xmen_state::screen_update_xmen6p_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
106 {
107 	for(int y = 0; y < 32 * 8; y++)
108 	{
109 		uint16_t *const line_dest = &bitmap.pix(y);
110 		uint16_t const *const line_src = &m_screen_left->pix(y);
111 
112 		for (int x = 12 * 8; x < 52 * 8; x++)
113 			line_dest[x] = line_src[x];
114 	}
115 
116 	return 0;
117 }
118 
screen_update_xmen6p_right(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)119 uint32_t xmen_state::screen_update_xmen6p_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
120 {
121 	for(int y = 0; y < 32 * 8; y++)
122 	{
123 		uint16_t *const line_dest = &bitmap.pix(y);
124 		uint16_t const *const line_src = &m_screen_right->pix(y);
125 
126 		for (int x = 12 * 8; x < 52 * 8; x++)
127 			line_dest[x] = line_src[x];
128 	}
129 
130 	return 0;
131 }
132 
133 /* my lefts and rights are mixed up in several places.. */
WRITE_LINE_MEMBER(xmen_state::screen_vblank_xmen6p)134 WRITE_LINE_MEMBER(xmen_state::screen_vblank_xmen6p)
135 {
136 	// rising edge
137 	if (state)
138 	{
139 		int layer[3], bg_colorbase;
140 		bitmap_ind16 * renderbitmap;
141 		rectangle cliprect;
142 
143 		// const rectangle *visarea = m_screen->visible_area();
144 		// cliprect = *visarea;
145 		cliprect.set(0, 64 * 8 - 1, 2 * 8, 30 * 8 - 1);
146 
147 		int index = m_screen->frame_number() & 1;
148 		renderbitmap = index ? m_screen_right.get() : m_screen_left.get();
149 
150 		/* copy the desired spritelist to the chip */
151 		memcpy(m_k053247_ram, m_xmen6p_spriteram[index], 0x1000);
152 
153 		/* we write the entire content of the tileram to the chip to ensure
154 		   everything gets marked as dirty and the desired tilemap is rendered
155 		   this is not very efficient!
156 		*/
157 		index += m_xmen6p_tilemap_select ? 2 : 0;
158 		for (int offset = 0; offset < (0xc000 / 2); offset++)
159 		{
160 			if (index == 0 || (offset != 0x1c80 && offset != 0x1e80))
161 				m_k052109->write(offset, m_xmen6p_tilemap[index][offset] & 0x00ff);
162 		}
163 
164 		bg_colorbase = m_k053251->get_palette_index(k053251_device::CI4);
165 		m_sprite_colorbase = m_k053251->get_palette_index(k053251_device::CI1);
166 		m_layer_colorbase[0] = m_k053251->get_palette_index(k053251_device::CI3);
167 		m_layer_colorbase[1] = m_k053251->get_palette_index(k053251_device::CI0);
168 		m_layer_colorbase[2] = m_k053251->get_palette_index(k053251_device::CI2);
169 
170 		m_k052109->tilemap_update();
171 
172 		layer[0] = 0;
173 		m_layerpri[0] = m_k053251->get_priority(k053251_device::CI3);
174 		layer[1] = 1;
175 		m_layerpri[1] = m_k053251->get_priority(k053251_device::CI0);
176 		layer[2] = 2;
177 		m_layerpri[2] = m_k053251->get_priority(k053251_device::CI2);
178 
179 		konami_sortlayers3(layer, m_layerpri);
180 
181 		m_screen->priority().fill(0, cliprect);
182 		/* note the '+1' in the background color!!! */
183 		renderbitmap->fill(16 * bg_colorbase + 1, cliprect);
184 		m_k052109->tilemap_draw(*m_screen, *renderbitmap, cliprect, layer[0], 0, 1);
185 		m_k052109->tilemap_draw(*m_screen, *renderbitmap, cliprect, layer[1], 0, 2);
186 		m_k052109->tilemap_draw(*m_screen, *renderbitmap, cliprect, layer[2], 0, 4);
187 
188 		/* this isn't supported anymore and it is unsure if still needed; keeping here for reference
189 		pdrawgfx_shadow_lowpri = 1; fix shadows of boulders in front of feet */
190 		m_k053246->k053247_sprites_draw(*renderbitmap, cliprect);
191 	}
192 }
193