1 // license:BSD-3-Clause
2 // copyright-holders:Mirko Buffoni
3 /***************************************************************************
4
5 video.c
6
7 Functions to emulate the video hardware of the machine.
8
9 ***************************************************************************/
10
11 #include "emu.h"
12 #include "includes/senjyo.h"
13
14
15 /***************************************************************************
16
17 Callbacks for the TileMap code
18
19 ***************************************************************************/
20
TILE_GET_INFO_MEMBER(senjyo_state::get_fg_tile_info)21 TILE_GET_INFO_MEMBER(senjyo_state::get_fg_tile_info)
22 {
23 uint8_t attr = m_fgcolorram[tile_index];
24 int flags = (attr & 0x80) ? TILE_FLIPY : 0;
25
26 if (m_is_senjyo && (tile_index & 0x1f) >= 32-8)
27 flags |= TILE_FORCE_LAYER0;
28
29 tileinfo.set(0,
30 m_fgvideoram[tile_index] + ((attr & 0x10) << 4),
31 attr & 0x07,
32 flags);
33 }
34
TILE_GET_INFO_MEMBER(senjyo_state::senjyo_bg1_tile_info)35 TILE_GET_INFO_MEMBER(senjyo_state::senjyo_bg1_tile_info)
36 {
37 uint8_t code = m_bg1videoram[tile_index];
38
39 tileinfo.set(1,
40 code,
41 (code & 0x70) >> 4,
42 0);
43 }
44
TILE_GET_INFO_MEMBER(senjyo_state::starforc_bg1_tile_info)45 TILE_GET_INFO_MEMBER(senjyo_state::starforc_bg1_tile_info)
46 {
47 /* Star Force has more tiles in bg1, so to get a uniform color code spread */
48 /* they wired bit 7 of the tile code in place of bit 4 to get the color code */
49 uint8_t code = m_bg1videoram[tile_index];
50
51 tileinfo.set(1,
52 code,
53 bitswap<3>(((code & 0xe0) >> 5), 1, 0, 2),
54 0);
55 }
56
TILE_GET_INFO_MEMBER(senjyo_state::get_bg2_tile_info)57 TILE_GET_INFO_MEMBER(senjyo_state::get_bg2_tile_info)
58 {
59 uint8_t code = m_bg2videoram[tile_index];
60
61 tileinfo.set(2,
62 code,
63 (code & 0xe0) >> 5,
64 0);
65 }
66
TILE_GET_INFO_MEMBER(senjyo_state::get_bg3_tile_info)67 TILE_GET_INFO_MEMBER(senjyo_state::get_bg3_tile_info)
68 {
69 uint8_t code = m_bg3videoram[tile_index];
70
71 tileinfo.set(3,
72 code,
73 (code & 0xe0) >> 5,
74 0);
75 }
76
77
78
79 /***************************************************************************
80
81 Start the video hardware emulation.
82
83 ***************************************************************************/
84
video_start()85 void senjyo_state::video_start()
86 {
87 m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(senjyo_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
88
89 if (m_is_senjyo)
90 {
91 m_bg1_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(senjyo_state::senjyo_bg1_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 16, 32);
92 m_bg2_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(senjyo_state::get_bg2_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 16, 48); // only 16x32 used by Star Force
93 m_bg3_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(senjyo_state::get_bg3_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 16, 56); // only 16x32 used by Star Force
94 }
95 else
96 {
97 m_bg1_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(senjyo_state::starforc_bg1_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 16, 32);
98 m_bg2_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(senjyo_state::get_bg2_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 16, 32); // only 16x32 used by Star Force
99 m_bg3_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(senjyo_state::get_bg3_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 16, 32); // only 16x32 used by Star Force
100 }
101
102 m_fg_tilemap->set_transparent_pen(0);
103 m_bg1_tilemap->set_transparent_pen(0);
104 m_bg2_tilemap->set_transparent_pen(0);
105 m_bg3_tilemap->set_transparent_pen(0);
106 m_fg_tilemap->set_scroll_cols(32);
107 }
108
IIBBGGRR(uint32_t raw)109 rgb_t senjyo_state::IIBBGGRR(uint32_t raw)
110 {
111 uint8_t const i = (raw >> 6) & 0x03;
112 uint8_t const r = (raw << 2) & 0x0c;
113 uint8_t const g = (raw ) & 0x0c;
114 uint8_t const b = (raw >> 2) & 0x0c;
115
116 return rgb_t(pal4bit(r ? (r | i) : 0), pal4bit(g ? (g | i) : 0), pal4bit(b ? (b | i) : 0));
117 }
118
radar_palette(palette_device & palette) const119 void senjyo_state::radar_palette(palette_device &palette) const
120 {
121 // two colors for the radar dots (verified on the real board)
122 palette.set_pen_color(0, rgb_t(0xff, 0x00, 0x00)); // red for enemies
123 palette.set_pen_color(1, rgb_t(0xff, 0xff, 0x00)); // yellow for player
124 }
125
126
127 /***************************************************************************
128
129 Memory handlers
130
131 ***************************************************************************/
132
fgvideoram_w(offs_t offset,uint8_t data)133 void senjyo_state::fgvideoram_w(offs_t offset, uint8_t data)
134 {
135 m_fgvideoram[offset] = data;
136 m_fg_tilemap->mark_tile_dirty(offset);
137 }
fgcolorram_w(offs_t offset,uint8_t data)138 void senjyo_state::fgcolorram_w(offs_t offset, uint8_t data)
139 {
140 m_fgcolorram[offset] = data;
141 m_fg_tilemap->mark_tile_dirty(offset);
142 }
bg1videoram_w(offs_t offset,uint8_t data)143 void senjyo_state::bg1videoram_w(offs_t offset, uint8_t data)
144 {
145 m_bg1videoram[offset] = data;
146 m_bg1_tilemap->mark_tile_dirty(offset);
147 }
bg2videoram_w(offs_t offset,uint8_t data)148 void senjyo_state::bg2videoram_w(offs_t offset, uint8_t data)
149 {
150 m_bg2videoram[offset] = data;
151 m_bg2_tilemap->mark_tile_dirty(offset);
152 }
bg3videoram_w(offs_t offset,uint8_t data)153 void senjyo_state::bg3videoram_w(offs_t offset, uint8_t data)
154 {
155 m_bg3videoram[offset] = data;
156 m_bg3_tilemap->mark_tile_dirty(offset);
157 }
158
159 /***************************************************************************
160
161 Display refresh
162
163 ***************************************************************************/
164
draw_bgbitmap(bitmap_rgb32 & bitmap,const rectangle & cliprect)165 void senjyo_state::draw_bgbitmap(bitmap_rgb32 &bitmap, const rectangle &cliprect)
166 {
167 // assume +1 from disabling layer being 0xff
168 uint8_t stripe_width = m_bgstripesram[0]+1;
169 if (stripe_width == 0)
170 bitmap.fill(m_palette->pen_color(0), cliprect);
171 else
172 {
173 int flip = flip_screen();
174
175 int pen = 0;
176 int count = 0;
177 int strwid = stripe_width;
178 if (strwid == 0) strwid = 0x100;
179 if (flip) strwid ^= 0xff;
180
181 for (int x = 0;x < 256;x++)
182 {
183 if (flip)
184 for (int y = 0;y < 256;y++)
185 bitmap.pix(y, 255 - x) = m_palette->pen_color(384 + pen);
186 else
187 for (int y = 0;y < 256;y++)
188 bitmap.pix(y, x) = m_palette->pen_color(384 + pen);
189
190 count += 0x10;
191 if (count >= strwid)
192 {
193 pen = (pen + 1) & 0x0f;
194 count -= strwid;
195 }
196 }
197 }
198 }
199
draw_radar(bitmap_rgb32 & bitmap,const rectangle & cliprect)200 void senjyo_state::draw_radar(bitmap_rgb32 &bitmap, const rectangle &cliprect)
201 {
202 for (int offs = 0;offs < 0x400;offs++)
203 for (int x = 0;x < 8;x++)
204 if (m_radarram[offs] & (1 << x))
205 {
206 int sx, sy;
207
208 sx = (8 * (offs % 8) + x) + 256-64;
209 sy = ((offs & 0x1ff) / 8) + 96;
210
211 if (flip_screen())
212 {
213 sx = 255 - sx;
214 sy = 255 - sy;
215 }
216
217 if (cliprect.contains(sx, sy))
218 bitmap.pix(sy, sx) = m_radar_palette->pen_color(offs < 0x200 ? 0 : 1);
219 }
220 }
221
draw_sprites(bitmap_rgb32 & bitmap,const rectangle & cliprect,int priority)222 void senjyo_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, int priority)
223 {
224 for (int offs = m_spriteram.bytes() - 4; offs >= 0; offs -= 4)
225 {
226 int big,sx,sy,flipx,flipy;
227
228 if (((m_spriteram[offs+1] & 0x30) >> 4) == priority)
229 {
230 if (m_is_senjyo) /* Senjyo */
231 big = (m_spriteram[offs] & 0x80);
232 else /* Star Force */
233 big = ((m_spriteram[offs] & 0xc0) == 0xc0);
234 sx = m_spriteram[offs+3];
235 if (big)
236 sy = 224-m_spriteram[offs+2];
237 else
238 sy = 240-m_spriteram[offs+2];
239 flipx = m_spriteram[offs+1] & 0x40;
240 flipy = m_spriteram[offs+1] & 0x80;
241
242 if (flip_screen())
243 {
244 flipx = !flipx;
245 flipy = !flipy;
246
247 if (big)
248 {
249 sx = 224 - sx;
250 sy = 226 - sy;
251 }
252 else
253 {
254 sx = 240 - sx;
255 sy = 242 - sy;
256 }
257 }
258
259
260 m_gfxdecode->gfx(big ? 5 : 4)->transpen(bitmap,cliprect,
261 m_spriteram[offs],
262 m_spriteram[offs + 1] & 0x07,
263 flipx,flipy,
264 sx,sy,0);
265 }
266 }
267 }
268
screen_update(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)269 uint32_t senjyo_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
270 {
271 int flip = flip_screen();
272
273 for (int i = 0;i < 32;i++)
274 m_fg_tilemap->set_scrolly(i, m_fgscroll[i]);
275
276 int scrollx = m_scrollx1[0];
277 int scrolly = m_scrolly1[0] + 256 * m_scrolly1[1];
278 if (flip)
279 scrollx = -scrollx;
280 m_bg1_tilemap->set_scrollx(0, scrollx);
281 m_bg1_tilemap->set_scrolly(0, scrolly);
282
283 scrollx = m_scrollx2[0];
284 scrolly = m_scrolly2[0] + 256 * m_scrolly2[1];
285 if (m_scrollhack) /* Star Force, but NOT the encrypted version */
286 {
287 scrollx = m_scrollx1[0];
288 scrolly = m_scrolly1[0] + 256 * m_scrolly1[1];
289 }
290 if (flip)
291 scrollx = -scrollx;
292 m_bg2_tilemap->set_scrollx(0, scrollx);
293 m_bg2_tilemap->set_scrolly(0, scrolly);
294
295 scrollx = m_scrollx3[0];
296 scrolly = m_scrolly3[0] + 256 * m_scrolly3[1];
297 if (flip)
298 scrollx = -scrollx;
299 m_bg3_tilemap->set_scrollx(0, scrollx);
300 m_bg3_tilemap->set_scrolly(0, scrolly);
301
302 draw_bgbitmap(bitmap, cliprect);
303 draw_sprites(bitmap, cliprect, 0);
304 m_bg3_tilemap->draw(screen, bitmap, cliprect, 0, 0);
305 draw_sprites(bitmap, cliprect, 1);
306 m_bg2_tilemap->draw(screen, bitmap, cliprect, 0, 0);
307 draw_sprites(bitmap, cliprect, 2);
308 m_bg1_tilemap->draw(screen, bitmap, cliprect, 0, 0);
309 draw_sprites(bitmap, cliprect, 3);
310 m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
311 draw_radar(bitmap, cliprect);
312
313 #if 0
314 {
315 char baf[80];
316 uint8_t *senjyo_scrolly3 = m_scrolly3;
317
318 sprintf(baf,"%02x %02x %02x %02x %02x %02x %02x %02x",
319 senjyo_scrolly3[0x00],
320 senjyo_scrolly3[0x01],
321 senjyo_scrolly3[0x02],
322 senjyo_scrolly3[0x03],
323 senjyo_scrolly3[0x04],
324 senjyo_scrolly3[0x05],
325 senjyo_scrolly3[0x06],
326 senjyo_scrolly3[0x07]);
327 ui_draw_text(baf,0,0);
328 sprintf(baf,"%02x %02x %02x %02x %02x %02x %02x %02x",
329 senjyo_scrolly3[0x08],
330 senjyo_scrolly3[0x09],
331 senjyo_scrolly3[0x0a],
332 senjyo_scrolly3[0x0b],
333 senjyo_scrolly3[0x0c],
334 senjyo_scrolly3[0x0d],
335 senjyo_scrolly3[0x0e],
336 senjyo_scrolly3[0x0f]);
337 ui_draw_text(baf,0,10);
338 sprintf(baf,"%02x %02x %02x %02x %02x %02x %02x %02x",
339 senjyo_scrolly3[0x10],
340 senjyo_scrolly3[0x11],
341 senjyo_scrolly3[0x12],
342 senjyo_scrolly3[0x13],
343 senjyo_scrolly3[0x14],
344 senjyo_scrolly3[0x15],
345 senjyo_scrolly3[0x16],
346 senjyo_scrolly3[0x17]);
347 ui_draw_text(baf,0,20);
348 sprintf(baf,"%02x %02x %02x %02x %02x %02x %02x %02x",
349 senjyo_scrolly3[0x18],
350 senjyo_scrolly3[0x19],
351 senjyo_scrolly3[0x1a],
352 senjyo_scrolly3[0x1b],
353 senjyo_scrolly3[0x1c],
354 senjyo_scrolly3[0x1d],
355 senjyo_scrolly3[0x1e],
356 senjyo_scrolly3[0x1f]);
357 ui_draw_text(baf,0,30);
358 }
359 #endif
360 return 0;
361 }
362