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