1 // license:BSD-3-Clause
2 // copyright-holders:Zsolt Vasvari
3 /***************************************************************************
4 
5   Seibu Stinger/Wiz hardware
6 
7   Functions to emulate the video hardware of the machine.
8 
9 ***************************************************************************/
10 
11 #include "emu.h"
12 #include "includes/wiz.h"
13 
14 #include "video/resnet.h"
15 
16 
17 /***************************************************************************
18 
19   Convert the color PROMs into a more useable format.
20 
21   Stinger has three 256x4 palette PROMs (one per gun).
22   The palette PROMs are connected to the RGB output this way:
23 
24   bit 3 -- 100 ohm resistor  -- RED/GREEN/BLUE
25         -- 220 ohm resistor  -- RED/GREEN/BLUE
26         -- 470 ohm resistor  -- RED/GREEN/BLUE
27   bit 0 -- 1  kohm resistor  -- RED/GREEN/BLUE
28 
29 ***************************************************************************/
30 
wiz_palette(palette_device & palette) const31 void wiz_state::wiz_palette(palette_device &palette) const
32 {
33 	uint8_t const *const color_prom = memregion("proms")->base();
34 	static constexpr int resistances[4] = { 1000, 470, 220, 100 };
35 
36 	// compute the color output resistor weights
37 	double rweights[4], gweights[4], bweights[4];
38 	compute_resistor_weights(0, 255, -1.0,
39 			4, resistances, rweights, 470, 0,
40 			4, resistances, gweights, 470, 0,
41 			4, resistances, bweights, 470, 0);
42 
43 	// initialize the palette with these colors
44 	for (int i = 0; i < 0x100; i++)
45 	{
46 		int bit0, bit1, bit2, bit3;
47 
48 		// red component
49 		bit0 = BIT(color_prom[i + 0x000], 0);
50 		bit1 = BIT(color_prom[i + 0x000], 1);
51 		bit2 = BIT(color_prom[i + 0x000], 2);
52 		bit3 = BIT(color_prom[i + 0x000], 3);
53 		int const r = combine_weights(rweights, bit0, bit1, bit2, bit3);
54 
55 		// green component
56 		bit0 = BIT(color_prom[i + 0x100], 0);
57 		bit1 = BIT(color_prom[i + 0x100], 1);
58 		bit2 = BIT(color_prom[i + 0x100], 2);
59 		bit3 = BIT(color_prom[i + 0x100], 3);
60 		int const g = combine_weights(gweights, bit0, bit1, bit2, bit3);
61 
62 		// blue component
63 		bit0 = BIT(color_prom[i + 0x200], 0);
64 		bit1 = BIT(color_prom[i + 0x200], 1);
65 		bit2 = BIT(color_prom[i + 0x200], 2);
66 		bit3 = BIT(color_prom[i + 0x200], 3);
67 		int const b = combine_weights(bweights, bit0, bit1, bit2, bit3);
68 
69 		m_palette->set_pen_color(i, rgb_t(r, g, b));
70 	}
71 }
72 
73 
74 
75 /***************************************************************************
76 
77   I/O
78 
79 ***************************************************************************/
80 
wiz_palette_bank_w(offs_t offset,uint8_t data)81 void wiz_state::wiz_palette_bank_w(offs_t offset, uint8_t data)
82 {
83 	m_palbank[offset] = data & 1;
84 }
85 
wiz_char_bank_w(offs_t offset,uint8_t data)86 void wiz_state::wiz_char_bank_w(offs_t offset, uint8_t data)
87 {
88 	m_charbank[offset] = data & 1;
89 }
90 
wiz_sprite_bank_w(uint8_t data)91 void wiz_state::wiz_sprite_bank_w(uint8_t data)
92 {
93 	m_sprite_bank = data & 1;
94 }
95 
wiz_bgcolor_w(uint8_t data)96 void wiz_state::wiz_bgcolor_w(uint8_t data)
97 {
98 	m_bgcolor = data;
99 }
100 
wiz_flipx_w(uint8_t data)101 void wiz_state::wiz_flipx_w(uint8_t data)
102 {
103 	m_flipx = data & 1;
104 }
105 
wiz_flipy_w(uint8_t data)106 void wiz_state::wiz_flipy_w(uint8_t data)
107 {
108 	m_flipy = data & 1;
109 }
110 
111 
112 
113 /***************************************************************************
114 
115   Screen Update
116 
117 ***************************************************************************/
118 
draw_tiles(bitmap_ind16 & bitmap,const rectangle & cliprect,int layer,int charbank,int colortype)119 void wiz_state::draw_tiles(bitmap_ind16 &bitmap, const rectangle &cliprect, int layer, int charbank, int colortype)
120 {
121 	uint8_t *vram = layer ? m_videoram2 : m_videoram;
122 	uint8_t *aram = layer ? m_attrram2 : m_attrram;
123 	uint8_t *cram = layer ? m_colorram2 : m_colorram;
124 	gfx_element *gfx = m_gfxdecode->gfx(charbank);
125 	int palbank = m_palbank[1] << 4 | m_palbank[0] << 3;
126 
127 	/* draw the tiles. They are characters, but draw them as sprites. */
128 	for (int offs = 0x400-1; offs >= 0; offs--)
129 	{
130 		int code = vram[offs];
131 		int sx = offs & 0x1f;
132 		int sy = offs >> 5;
133 		int color = aram[sx << 1 | 1] & 7;
134 
135 		// wiz/kungfut hw allows more color variety on screen
136 		if (colortype)
137 			color = layer ? (cram[offs] & 7) : ((color & 4) | (code & 3));
138 
139 		int scroll = (8*sy + 256 - aram[sx << 1]) & 0xff;
140 		if (m_flipy)
141 			scroll = (248 - scroll) & 0xff;
142 		if (m_flipx)
143 			sx = 31 - sx;
144 
145 		gfx->transpen(bitmap,cliprect,
146 			code,
147 			palbank | color,
148 			m_flipx,m_flipy,
149 			8*sx,scroll,0);
150 	}
151 }
152 
153 
draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect,int set,int charbank)154 void wiz_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int set, int charbank)
155 {
156 	uint8_t *sram = set ? m_spriteram2 : m_spriteram;
157 	gfx_element *gfx = m_gfxdecode->gfx(charbank);
158 	int palbank = m_palbank[1] << 4 | m_palbank[0] << 3;
159 
160 	for (int offs = 0x20-4; offs >= 0; offs -= 4)
161 	{
162 		int code = sram[offs + 1];
163 		int sx = sram[offs + 3];
164 		int sy = sram[offs];
165 		int color = sram[offs + 2] & 7; // high bits unused
166 
167 		if (!sx || !sy) continue;
168 
169 		// like on galaxian hw, the first three sprites match against y-1 (not on m_spriteram2)
170 		if (set == 0 && offs <= 8)
171 			sy += (m_flipy) ? 1 : -1;
172 
173 		if ( m_flipx) sx = 240 - sx;
174 		if (!m_flipy) sy = 240 - sy;
175 
176 		gfx->transpen(bitmap,cliprect,
177 			code,
178 			palbank | color,
179 			m_flipx,m_flipy,
180 			sx,sy,0);
181 	}
182 }
183 
184 
185 /**************************************************************************/
186 
screen_update_kungfut(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)187 uint32_t wiz_state::screen_update_kungfut(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
188 {
189 	bitmap.fill(m_bgcolor, cliprect);
190 	draw_tiles(bitmap, cliprect, 0, 2 + m_charbank[0], 1);
191 	draw_tiles(bitmap, cliprect, 1, m_charbank[1], 1);
192 	draw_sprites(bitmap, cliprect, 1, 4);
193 	draw_sprites(bitmap, cliprect, 0, 5);
194 	return 0;
195 }
196 
screen_update_wiz(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)197 uint32_t wiz_state::screen_update_wiz(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
198 {
199 	bitmap.fill(m_bgcolor, cliprect);
200 	draw_tiles(bitmap, cliprect, 0, 2 + ((m_charbank[0] << 1) | m_charbank[1]), 1);
201 	draw_tiles(bitmap, cliprect, 1, m_charbank[1], 1);
202 
203 	const rectangle spritevisiblearea(2*8, 32*8-1, 2*8, 30*8-1);
204 	const rectangle spritevisibleareaflipx(0*8, 30*8-1, 2*8, 30*8-1);
205 	const rectangle &visible_area = m_flipx ? spritevisibleareaflipx : spritevisiblearea;
206 
207 	draw_sprites(bitmap, visible_area, 1, 6);
208 	draw_sprites(bitmap, visible_area, 0, 7 + m_sprite_bank);
209 	return 0;
210 }
211 
212 
screen_update_stinger(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)213 uint32_t wiz_state::screen_update_stinger(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
214 {
215 	bitmap.fill(m_bgcolor, cliprect);
216 	draw_tiles(bitmap, cliprect, 0, 2 + m_charbank[0], 0);
217 	draw_tiles(bitmap, cliprect, 1, m_charbank[1], 0);
218 	draw_sprites(bitmap, cliprect, 1, 4);
219 	draw_sprites(bitmap, cliprect, 0, 5);
220 	return 0;
221 }
222