1 // license:BSD-3-Clause
2 // copyright-holders:Nicola Salmoria, David Haywood
3 // Video System Sprites (type 2)
4 // todo:
5 // move various vsystem sprite functions here
6 // unify common ones + convert to device
7
8 // this is probably the VS 8904/8905 combo
9
10 // Spinal Breakers
11 // Power Spikes
12 // Karate Blazers
13 // Turbo Force
14 // Aero Fighters (older hardware types)
15 // World Beach Championships 97 (modern Power Spikes bootleg, not original hw)
16 // Welltris
17 // Formula 1 Grand Prix (1)
18 // Pipe Dream
19
20 // there were lots of comments saying drivers using the
21 // static const uint8_t zoomtable[16] = { 0,7,14,20,25,30,34,38,42,46,49,52,54,57,59,61 };
22 // table for zooming needed upgrading, are we sure this isn't one of the
23 // differences between this sprite chip and the one in vsystem_spr.c, pspikes zooming is very rough
24
25
26 #include "emu.h"
27 #include "vsystem_spr2.h"
28
29
30 DEFINE_DEVICE_TYPE(VSYSTEM_SPR2, vsystem_spr2_device, "vsystem2_spr", "Video System VS8904/VS8905 Sprites")
31
vsystem_spr2_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)32 vsystem_spr2_device::vsystem_spr2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
33 : device_t(mconfig, VSYSTEM_SPR2, tag, owner, clock)
34 , m_newtilecb(*this, DEVICE_SELF, FUNC(vsystem_spr2_device::tile_callback_noindirect))
35 , m_pritype(0) // hack until we have better handling
36 , m_gfx_region(0)
37 , m_xoffs(0)
38 , m_yoffs(0)
39 , m_curr_sprite()
40 , m_gfxdecode(*this, finder_base::DUMMY_TAG)
41 {
42 }
43
tile_callback_noindirect(uint32_t tile)44 uint32_t vsystem_spr2_device::tile_callback_noindirect(uint32_t tile)
45 {
46 return tile;
47 }
48
49
device_start()50 void vsystem_spr2_device::device_start()
51 {
52 // bind our handler
53 m_newtilecb.resolve();
54 }
55
device_reset()56 void vsystem_spr2_device::device_reset()
57 {
58 }
59
60
get(uint16_t const * ram)61 bool vsystem_spr2_device::sprite_attributes::get(uint16_t const *ram)
62 {
63 // sprite is disabled
64 if (!(ram[2] & 0x0080))
65 return false;
66
67 oy = (ram[0] & 0x01ff);
68 zoomy = (ram[0] & 0xf000) >> 12;
69
70 ox = (ram[1] & 0x01ff);
71 zoomx = (ram[1] & 0xf000) >> 12;
72
73 xsize = (ram[2] & 0x0700) >> 8;
74 flipx = (ram[2] & 0x0800);
75
76 ysize = (ram[2] & 0x7000) >> 12;
77 flipy = (ram[2] & 0x8000);
78
79 color = (ram[2] & 0x000f);
80 pri = (ram[2] & 0x0010);
81
82 map = (ram[3]);
83
84 return true;
85 }
86
handle_xsize_map_inc()87 void vsystem_spr2_device::sprite_attributes::handle_xsize_map_inc()
88 {
89 if (xsize == 2) map += 1;
90 if (xsize == 4) map += 3;
91 if (xsize == 5) map += 2;
92 if (xsize == 6) map += 1;
93 }
94
95 template<class BitmapClass>
turbofrc_draw_sprites_common(uint16_t const * spriteram3,int spriteram3_bytes,int spritepalettebank,BitmapClass & bitmap,const rectangle & cliprect,bitmap_ind8 & priority_bitmap,int pri_param,bool flip_screen)96 void vsystem_spr2_device::turbofrc_draw_sprites_common(uint16_t const *spriteram3, int spriteram3_bytes, int spritepalettebank, BitmapClass &bitmap, const rectangle &cliprect, bitmap_ind8 &priority_bitmap, int pri_param, bool flip_screen)
97 {
98 int attr_start, first;
99 first = 4 * spriteram3[0x1fe];
100
101 first &= 0x1ff;
102 if (first>0x200-4)
103 first = 0x200-4;
104
105 int start,end,inc;
106
107 if (m_pritype == 0 || m_pritype == 1 || m_pritype == 2) // prdrawgfx cases
108 {
109 start = 0x200 - 8;
110 end = first-4;
111 inc = -4;
112 }
113 else // drawgfx cases
114 {
115 start = first;
116 end = 0x200 -4;
117 inc = 4;
118 }
119
120 for (attr_start = start; attr_start != end; attr_start += inc)
121 {
122 int x, y;
123
124 if (!m_curr_sprite.get(&spriteram3[attr_start]))
125 continue;
126
127 // pipedrm
128 m_curr_sprite.ox += m_xoffs;
129 m_curr_sprite.oy += m_yoffs;
130
131 int usepri = 0;
132
133 // these are still calling the function multiple times to filter out priorities, even if some are also using pdrawgfx(!)
134 if (m_pritype == 0 || m_pritype == 1 || m_pritype == 3) // turbo force, spinlbrk, pipedrm etc.
135 {
136 if ((m_curr_sprite.pri>>4) != pri_param)
137 continue;
138 }
139
140
141 if (m_pritype == 0) // turbo force etc.
142 {
143 usepri = m_curr_sprite.pri ? 0 : 2;
144 }
145 else if (m_pritype == 1) // spinlbrk
146 {
147 usepri = m_curr_sprite.pri ? 2 : 0;
148 }
149 else if (m_pritype == 2) // f1gp
150 {
151 usepri = pri_param;
152 }
153
154 bool fx = m_curr_sprite.flipx != 0;
155 bool fy = m_curr_sprite.flipy != 0;
156 if (flip_screen)
157 {
158 m_curr_sprite.ox = 308 - m_curr_sprite.ox;
159 m_curr_sprite.oy = 208 - m_curr_sprite.oy;
160 fx = !fx;
161 fy = !fy;
162 }
163
164 m_curr_sprite.color += 16 * spritepalettebank;
165
166 m_curr_sprite.zoomx = 32 - m_curr_sprite.zoomx;
167 m_curr_sprite.zoomy = 32 - m_curr_sprite.zoomy;
168
169 for (y = 0; y <= m_curr_sprite.ysize; y++)
170 {
171 int cy = m_curr_sprite.flipy ? (m_curr_sprite.ysize - y) : y;
172 int sy = ((m_curr_sprite.oy + m_curr_sprite.zoomy * (flip_screen ? -cy : cy) / 2 + 16) & 0x1ff) - 16;
173
174 for (x = 0; x <= m_curr_sprite.xsize; x++)
175 {
176 int cx = m_curr_sprite.flipx ? (m_curr_sprite.xsize - x) : x;
177 int sx = ((m_curr_sprite.ox + m_curr_sprite.zoomx * (flip_screen ? -cx : cx) / 2 + 16) & 0x1ff) - 16;
178
179 int curr = m_newtilecb(m_curr_sprite.map++);
180
181 if (m_pritype == 0 || m_pritype == 1 || m_pritype == 2) // pdrawgfx cases
182 {
183 m_gfxdecode->gfx(m_gfx_region)->prio_zoom_transpen(bitmap,cliprect, curr, m_curr_sprite.color, fx, fy, sx-0x000,sy-0x000, m_curr_sprite.zoomx << 11, m_curr_sprite.zoomy << 11, priority_bitmap,usepri,15);
184 m_gfxdecode->gfx(m_gfx_region)->prio_zoom_transpen(bitmap,cliprect, curr, m_curr_sprite.color, fx, fy, sx-0x200,sy-0x000, m_curr_sprite.zoomx << 11, m_curr_sprite.zoomy << 11, priority_bitmap,usepri,15);
185 m_gfxdecode->gfx(m_gfx_region)->prio_zoom_transpen(bitmap,cliprect, curr, m_curr_sprite.color, fx, fy, sx-0x000,sy-0x200, m_curr_sprite.zoomx << 11, m_curr_sprite.zoomy << 11, priority_bitmap,usepri,15);
186 m_gfxdecode->gfx(m_gfx_region)->prio_zoom_transpen(bitmap,cliprect, curr, m_curr_sprite.color, fx, fy, sx-0x200,sy-0x200, m_curr_sprite.zoomx << 11, m_curr_sprite.zoomy << 11, priority_bitmap,usepri,15);
187 }
188 else // drawgfx cases (welltris, pipedrm)
189 {
190 m_gfxdecode->gfx(m_gfx_region)->zoom_transpen(bitmap,cliprect, curr, m_curr_sprite.color, fx, fy, sx-0x000,sy-0x000, m_curr_sprite.zoomx << 11, m_curr_sprite.zoomy << 11,15);
191 m_gfxdecode->gfx(m_gfx_region)->zoom_transpen(bitmap,cliprect, curr, m_curr_sprite.color, fx, fy, sx-0x200,sy-0x000, m_curr_sprite.zoomx << 11, m_curr_sprite.zoomy << 11,15);
192 m_gfxdecode->gfx(m_gfx_region)->zoom_transpen(bitmap,cliprect, curr, m_curr_sprite.color, fx, fy, sx-0x000,sy-0x200, m_curr_sprite.zoomx << 11, m_curr_sprite.zoomy << 11,15);
193 m_gfxdecode->gfx(m_gfx_region)->zoom_transpen(bitmap,cliprect, curr, m_curr_sprite.color, fx, fy, sx-0x200,sy-0x200, m_curr_sprite.zoomx << 11, m_curr_sprite.zoomy << 11,15);
194 }
195
196 }
197 m_curr_sprite.handle_xsize_map_inc();
198 }
199 }
200 }
201
turbofrc_draw_sprites(uint16_t const * spriteram3,int spriteram3_bytes,int spritepalettebank,bitmap_ind16 & bitmap,const rectangle & cliprect,bitmap_ind8 & priority_bitmap,int pri_param,bool flip_screen)202 void vsystem_spr2_device::turbofrc_draw_sprites(uint16_t const *spriteram3, int spriteram3_bytes, int spritepalettebank, bitmap_ind16 &bitmap, const rectangle &cliprect, bitmap_ind8 &priority_bitmap, int pri_param, bool flip_screen)
203 {
204 turbofrc_draw_sprites_common(spriteram3, spriteram3_bytes, spritepalettebank, bitmap, cliprect, priority_bitmap, pri_param, flip_screen);
205 }
206
turbofrc_draw_sprites(uint16_t const * spriteram3,int spriteram3_bytes,int spritepalettebank,bitmap_rgb32 & bitmap,const rectangle & cliprect,bitmap_ind8 & priority_bitmap,int pri_param,bool flip_screen)207 void vsystem_spr2_device::turbofrc_draw_sprites(uint16_t const *spriteram3, int spriteram3_bytes, int spritepalettebank, bitmap_rgb32 &bitmap, const rectangle &cliprect, bitmap_ind8 &priority_bitmap, int pri_param, bool flip_screen)
208 {
209 turbofrc_draw_sprites_common(spriteram3, spriteram3_bytes, spritepalettebank, bitmap, cliprect, priority_bitmap, pri_param, flip_screen);
210 }
211