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