1 /***************************************************************************
2
3 vidhrdw.c
4
5 Functions to emulate the video hardware of the machine.
6
7 ***************************************************************************/
8
9 #include "driver.h"
10 #include "machine/segacrpt.h"
11 #include "vidhrdw/generic.h"
12
13
14
15 extern unsigned char *spriteram;
16 extern size_t spriteram_size;
17
18 UINT8 *senjyo_fgscroll;
19 UINT8 *senjyo_scrollx1,*senjyo_scrolly1;
20 UINT8 *senjyo_scrollx2,*senjyo_scrolly2;
21 UINT8 *senjyo_scrollx3,*senjyo_scrolly3;
22 UINT8 *senjyo_fgvideoram,*senjyo_fgcolorram;
23 UINT8 *senjyo_bg1videoram,*senjyo_bg2videoram,*senjyo_bg3videoram;
24 UINT8 *senjyo_radarram;
25 UINT8 *senjyo_bgstripesram;
26
27 static struct tilemap *fg_tilemap,*bg1_tilemap,*bg2_tilemap,*bg3_tilemap;
28
29 static int senjyo, scrollhack;
30 static int senjyo_bgstripes;
31
32 static struct mame_bitmap *bgbitmap;
33
34
DRIVER_INIT(starforc)35 DRIVER_INIT( starforc )
36 {
37 senjyo = 0;
38 scrollhack = 1;
39 }
DRIVER_INIT(starfore)40 DRIVER_INIT( starfore )
41 {
42 /* encrypted CPU */
43 suprloco_decode();
44
45 senjyo = 0;
46 scrollhack = 0;
47 }
DRIVER_INIT(senjyo)48 DRIVER_INIT( senjyo )
49 {
50 senjyo = 1;
51 scrollhack = 0;
52 }
53
54
55 /***************************************************************************
56
57 Callbacks for the TileMap code
58
59 ***************************************************************************/
60
get_fg_tile_info(int tile_index)61 static void get_fg_tile_info(int tile_index)
62 {
63 unsigned char attr = senjyo_fgcolorram[tile_index];
64 SET_TILE_INFO(
65 0,
66 senjyo_fgvideoram[tile_index] + ((attr & 0x10) << 4),
67 attr & 0x07,
68 (attr & 0x80) ? TILE_FLIPY : 0)
69 if (senjyo && (tile_index & 0x1f) >= 32-8)
70 tile_info.flags |= TILE_IGNORE_TRANSPARENCY;
71 }
72
senjyo_bg1_tile_info(int tile_index)73 static void senjyo_bg1_tile_info(int tile_index)
74 {
75 unsigned char code = senjyo_bg1videoram[tile_index];
76 SET_TILE_INFO(
77 1,
78 code,
79 (code & 0x70) >> 4,
80 0)
81 }
82
starforc_bg1_tile_info(int tile_index)83 static void starforc_bg1_tile_info(int tile_index)
84 {
85 /* Star Force has more tiles in bg1, so to get a uniform color code spread */
86 /* they wired bit 7 of the tile code in place of bit 4 to get the color code */
87 static int colormap[8] = { 0,2,4,6,1,3,5,7 };
88 unsigned char code = senjyo_bg1videoram[tile_index];
89 SET_TILE_INFO(
90 1,
91 code,
92 colormap[(code & 0xe0) >> 5],
93 0)
94 }
95
get_bg2_tile_info(int tile_index)96 static void get_bg2_tile_info(int tile_index)
97 {
98 unsigned char code = senjyo_bg2videoram[tile_index];
99 SET_TILE_INFO(
100 2,
101 code,
102 (code & 0xe0) >> 5,
103 0)
104 }
105
get_bg3_tile_info(int tile_index)106 static void get_bg3_tile_info(int tile_index)
107 {
108 unsigned char code = senjyo_bg3videoram[tile_index];
109 SET_TILE_INFO(
110 3,
111 code,
112 (code & 0xe0) >> 5,
113 0)
114 }
115
116
117
118 /***************************************************************************
119
120 Start the video hardware emulation.
121
122 ***************************************************************************/
123
VIDEO_START(senjyo)124 VIDEO_START( senjyo )
125 {
126 bgbitmap = auto_bitmap_alloc(256,256);
127 if (!bgbitmap)
128 return 1;
129
130 fg_tilemap = tilemap_create(get_fg_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,32,32);
131 if (senjyo)
132 {
133 bg1_tilemap = tilemap_create(senjyo_bg1_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,16,32);
134 bg2_tilemap = tilemap_create(get_bg2_tile_info, tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,16,48); /* only 16x32 used by Star Force */
135 bg3_tilemap = tilemap_create(get_bg3_tile_info, tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,16,56); /* only 16x32 used by Star Force */
136 }
137 else
138 {
139 bg1_tilemap = tilemap_create(starforc_bg1_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,16,32);
140 bg2_tilemap = tilemap_create(get_bg2_tile_info, tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,16,32); /* only 16x32 used by Star Force */
141 bg3_tilemap = tilemap_create(get_bg3_tile_info, tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,16,32); /* only 16x32 used by Star Force */
142 }
143
144
145 if (!fg_tilemap || !bg1_tilemap || !bg2_tilemap || !bg3_tilemap)
146 return 1;
147
148 tilemap_set_transparent_pen(fg_tilemap,0);
149 tilemap_set_transparent_pen(bg1_tilemap,0);
150 tilemap_set_transparent_pen(bg2_tilemap,0);
151 tilemap_set_transparent_pen(bg3_tilemap,0);
152 tilemap_set_scroll_cols(fg_tilemap,32);
153
154 set_vh_global_attribute(NULL,0);
155
156 return 0;
157 }
158
159
160
161 /***************************************************************************
162
163 Memory handlers
164
165 ***************************************************************************/
166
WRITE_HANDLER(senjyo_fgvideoram_w)167 WRITE_HANDLER( senjyo_fgvideoram_w )
168 {
169 if (senjyo_fgvideoram[offset] != data)
170 {
171 senjyo_fgvideoram[offset] = data;
172 tilemap_mark_tile_dirty(fg_tilemap,offset);
173 }
174 }
WRITE_HANDLER(senjyo_fgcolorram_w)175 WRITE_HANDLER( senjyo_fgcolorram_w )
176 {
177 if (senjyo_fgcolorram[offset] != data)
178 {
179 senjyo_fgcolorram[offset] = data;
180 tilemap_mark_tile_dirty(fg_tilemap,offset);
181 }
182 }
WRITE_HANDLER(senjyo_bg1videoram_w)183 WRITE_HANDLER( senjyo_bg1videoram_w )
184 {
185 if (senjyo_bg1videoram[offset] != data)
186 {
187 senjyo_bg1videoram[offset] = data;
188 tilemap_mark_tile_dirty(bg1_tilemap,offset);
189 }
190 }
WRITE_HANDLER(senjyo_bg2videoram_w)191 WRITE_HANDLER( senjyo_bg2videoram_w )
192 {
193 if (senjyo_bg2videoram[offset] != data)
194 {
195 senjyo_bg2videoram[offset] = data;
196 tilemap_mark_tile_dirty(bg2_tilemap,offset);
197 }
198 }
WRITE_HANDLER(senjyo_bg3videoram_w)199 WRITE_HANDLER( senjyo_bg3videoram_w )
200 {
201 if (senjyo_bg3videoram[offset] != data)
202 {
203 senjyo_bg3videoram[offset] = data;
204 tilemap_mark_tile_dirty(bg3_tilemap,offset);
205 }
206 }
207
WRITE_HANDLER(senjyo_bgstripes_w)208 WRITE_HANDLER( senjyo_bgstripes_w )
209 {
210 *senjyo_bgstripesram = data;
211 set_vh_global_attribute(&senjyo_bgstripes, data);
212 }
213
214 /***************************************************************************
215
216 Display refresh
217
218 ***************************************************************************/
219
draw_bgbitmap(struct mame_bitmap * bitmap,const struct rectangle * cliprect)220 static void draw_bgbitmap(struct mame_bitmap *bitmap,const struct rectangle *cliprect)
221 {
222 int x,y,pen,strwid,count;
223
224
225 if (senjyo_bgstripes == 0xff) /* off */
226 {
227 fillbitmap(bitmap,Machine->pens[0],cliprect);
228 return;
229 }
230
231 if (get_vh_global_attribute_changed())
232 {
233 pen = 0;
234 count = 0;
235 strwid = senjyo_bgstripes;
236 if (strwid == 0) strwid = 0x100;
237 if (flip_screen) strwid ^= 0xff;
238
239 for (x = 0;x < 256;x++)
240 {
241 if (flip_screen)
242 {
243 for (y = 0;y < 256;y++)
244 {
245 plot_pixel(bgbitmap, 255 - x, y, Machine->pens[384 + pen]);
246 }
247 }
248 else
249 {
250 for (y = 0;y < 256;y++)
251 {
252 plot_pixel(bgbitmap, x, y, Machine->pens[384 + pen]);
253 }
254 }
255
256 count += 0x10;
257 if (count >= strwid)
258 {
259 pen = (pen + 1) & 0x0f;
260 count -= strwid;
261 }
262 }
263 }
264
265 copybitmap(bitmap,bgbitmap,0,0,0,0,cliprect,TRANSPARENCY_NONE,0);
266 }
267
draw_radar(struct mame_bitmap * bitmap,const struct rectangle * cliprect)268 static void draw_radar(struct mame_bitmap *bitmap,const struct rectangle *cliprect)
269 {
270 int offs,x;
271
272 for (offs = 0;offs < 0x400;offs++)
273 {
274 if (senjyo_radarram[offs])
275 {
276 for (x = 0;x < 8;x++)
277 {
278 if (senjyo_radarram[offs] & (1 << x))
279 {
280 int sx, sy;
281
282 sx = (8 * (offs % 8) + x) + 256-64;
283 sy = ((offs & 0x1ff) / 8) + 96;
284
285 if (flip_screen)
286 {
287 sx = 255 - sx;
288 sy = 255 - sy;
289 }
290
291 if (sy >= cliprect->min_y && sy <= cliprect->max_y &&
292 sx >= cliprect->min_x && sx <= cliprect->max_x)
293 plot_pixel(bitmap,
294 sx, sy,
295 Machine->pens[offs < 0x200 ? 400 : 401]);
296 }
297 }
298 }
299 }
300 }
301
draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int priority)302 static void draw_sprites(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int priority)
303 {
304 int offs;
305
306
307 for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
308 {
309 int big,sx,sy,flipx,flipy;
310
311 if (((spriteram[offs+1] & 0x30) >> 4) == priority)
312 {
313 if (senjyo) /* Senjyo */
314 big = (spriteram[offs] & 0x80);
315 else /* Star Force */
316 big = ((spriteram[offs] & 0xc0) == 0xc0);
317 sx = spriteram[offs+3];
318 if (big)
319 sy = 224-spriteram[offs+2];
320 else
321 sy = 240-spriteram[offs+2];
322 flipx = spriteram[offs+1] & 0x40;
323 flipy = spriteram[offs+1] & 0x80;
324
325 if (flip_screen)
326 {
327 flipx = !flipx;
328 flipy = !flipy;
329
330 if (big)
331 {
332 sx = 224 - sx;
333 sy = 226 - sy;
334 }
335 else
336 {
337 sx = 240 - sx;
338 sy = 242 - sy;
339 }
340 }
341
342
343 drawgfx(bitmap,Machine->gfx[big ? 5 : 4],
344 spriteram[offs],
345 spriteram[offs + 1] & 0x07,
346 flipx,flipy,
347 sx,sy,
348 cliprect,TRANSPARENCY_PEN,0);
349 }
350 }
351 }
352
VIDEO_UPDATE(senjyo)353 VIDEO_UPDATE( senjyo )
354 {
355 int i;
356
357
358 /* two colors for the radar dots (verified on the real board) */
359 palette_set_color(400,0xff,0x00,0x00); /* red for enemies */
360 palette_set_color(401,0xff,0xff,0x00); /* yellow for player */
361
362 {
363 int scrollx,scrolly;
364
365 for (i = 0;i < 32;i++)
366 tilemap_set_scrolly(fg_tilemap,i,senjyo_fgscroll[i]);
367
368 scrollx = senjyo_scrollx1[0];
369 scrolly = senjyo_scrolly1[0] + 256 * senjyo_scrolly1[1];
370 if (flip_screen)
371 scrollx = -scrollx;
372 tilemap_set_scrollx(bg1_tilemap,0,scrollx);
373 tilemap_set_scrolly(bg1_tilemap,0,scrolly);
374
375 scrollx = senjyo_scrollx2[0];
376 scrolly = senjyo_scrolly2[0] + 256 * senjyo_scrolly2[1];
377 if (scrollhack) /* Star Force, but NOT the encrypted version */
378 {
379 scrollx = senjyo_scrollx1[0];
380 scrolly = senjyo_scrolly1[0] + 256 * senjyo_scrolly1[1];
381 }
382 if (flip_screen)
383 scrollx = -scrollx;
384 tilemap_set_scrollx(bg2_tilemap,0,scrollx);
385 tilemap_set_scrolly(bg2_tilemap,0,scrolly);
386
387 scrollx = senjyo_scrollx3[0];
388 scrolly = senjyo_scrolly3[0] + 256 * senjyo_scrolly3[1];
389 if (flip_screen)
390 scrollx = -scrollx;
391 tilemap_set_scrollx(bg3_tilemap,0,scrollx);
392 tilemap_set_scrolly(bg3_tilemap,0,scrolly);
393 }
394
395 draw_bgbitmap(bitmap,cliprect);
396 draw_sprites(bitmap,cliprect,0);
397 tilemap_draw(bitmap,cliprect,bg3_tilemap,0,0);
398 draw_sprites(bitmap,cliprect,1);
399 tilemap_draw(bitmap,cliprect,bg2_tilemap,0,0);
400 draw_sprites(bitmap,cliprect,2);
401 tilemap_draw(bitmap,cliprect,bg1_tilemap,0,0);
402 draw_sprites(bitmap,cliprect,3);
403 tilemap_draw(bitmap,cliprect,fg_tilemap,0,0);
404 draw_radar(bitmap,cliprect);
405
406 #if 0
407 {
408 char baf[80];
409
410 sprintf(baf,"%02x %02x %02x %02x %02x %02x %02x %02x",
411 senjyo_scrolly3[0x00],
412 senjyo_scrolly3[0x01],
413 senjyo_scrolly3[0x02],
414 senjyo_scrolly3[0x03],
415 senjyo_scrolly3[0x04],
416 senjyo_scrolly3[0x05],
417 senjyo_scrolly3[0x06],
418 senjyo_scrolly3[0x07]);
419 ui_text(baf,0,0);
420 sprintf(baf,"%02x %02x %02x %02x %02x %02x %02x %02x",
421 senjyo_scrolly3[0x08],
422 senjyo_scrolly3[0x09],
423 senjyo_scrolly3[0x0a],
424 senjyo_scrolly3[0x0b],
425 senjyo_scrolly3[0x0c],
426 senjyo_scrolly3[0x0d],
427 senjyo_scrolly3[0x0e],
428 senjyo_scrolly3[0x0f]);
429 ui_text(baf,0,10);
430 sprintf(baf,"%02x %02x %02x %02x %02x %02x %02x %02x",
431 senjyo_scrolly3[0x10],
432 senjyo_scrolly3[0x11],
433 senjyo_scrolly3[0x12],
434 senjyo_scrolly3[0x13],
435 senjyo_scrolly3[0x14],
436 senjyo_scrolly3[0x15],
437 senjyo_scrolly3[0x16],
438 senjyo_scrolly3[0x17]);
439 ui_text(baf,0,20);
440 sprintf(baf,"%02x %02x %02x %02x %02x %02x %02x %02x",
441 senjyo_scrolly3[0x18],
442 senjyo_scrolly3[0x19],
443 senjyo_scrolly3[0x1a],
444 senjyo_scrolly3[0x1b],
445 senjyo_scrolly3[0x1c],
446 senjyo_scrolly3[0x1d],
447 senjyo_scrolly3[0x1e],
448 senjyo_scrolly3[0x1f]);
449 ui_text(baf,0,30);
450 }
451 #endif
452 }
453