1 /***************************************************************************
2 
3 Atari Sprint 8 video emulation
4 
5 ***************************************************************************/
6 
7 #include "driver.h"
8 
9 extern void sprint8_collision_callback(int n);
10 
11 UINT8* sprint8_video_ram;
12 UINT8* sprint8_pos_h_ram;
13 UINT8* sprint8_pos_v_ram;
14 UINT8* sprint8_pos_d_ram;
15 
16 static struct tilemap* tilemap1;
17 static struct tilemap* tilemap2;
18 
19 static struct mame_bitmap* helper1;
20 static struct mame_bitmap* helper2;
21 
22 
get_tile_info1(int tile_index)23 static void get_tile_info1(int tile_index)
24 {
25 	UINT8 code = sprint8_video_ram[tile_index];
26 
27 	int color = 0;
28 
29 	if ((code & 0x30) != 0x30) /* ? */
30 	{
31 		color = 17;
32 	}
33 	else
34 	{
35 		if ((tile_index + 1) & 0x010)
36 		{
37 			color |= 1;
38 		}
39 		if (code & 0x80)
40 		{
41 			color |= 2;
42 		}
43 		if (tile_index & 0x200)
44 		{
45 			color |= 4;
46 		}
47 	}
48 
49 	SET_TILE_INFO(code >> 7, code, color, (code & 0x40) ? (TILE_FLIPX | TILE_FLIPY) : 0)
50 }
51 
52 
get_tile_info2(int tile_index)53 static void get_tile_info2(int tile_index)
54 {
55 	UINT8 code = sprint8_video_ram[tile_index];
56 
57 	int color = 0;
58 
59 	if ((code & 0x38) != 0x28)
60 	{
61 		color = 16;
62 	}
63 	else
64 	{
65 		color = 17;
66 	}
67 
68 	SET_TILE_INFO(code >> 7, code, color, (code & 0x40) ? (TILE_FLIPX | TILE_FLIPY) : 0)
69 }
70 
71 
WRITE_HANDLER(sprint8_video_ram_w)72 WRITE_HANDLER( sprint8_video_ram_w )
73 {
74 	if (data != sprint8_video_ram[offset])
75 	{
76 		tilemap_mark_tile_dirty(tilemap1, offset);
77 		tilemap_mark_tile_dirty(tilemap2, offset);
78 	}
79 
80 	sprint8_video_ram[offset] = data;
81 }
82 
83 
VIDEO_START(sprint8)84 VIDEO_START( sprint8 )
85 {
86 	helper1 = auto_bitmap_alloc(Machine->drv->screen_width, Machine->drv->screen_height);
87 	helper2 = auto_bitmap_alloc(Machine->drv->screen_width, Machine->drv->screen_height);
88 
89 	if (helper1 == NULL)
90 	{
91 		return 1;
92 	}
93 	if (helper2 == NULL)
94 	{
95 		return 1;
96 	}
97 
98 	tilemap1 = tilemap_create(get_tile_info1, tilemap_scan_rows, TILEMAP_OPAQUE, 16, 8, 32, 32);
99 	tilemap2 = tilemap_create(get_tile_info2, tilemap_scan_rows, TILEMAP_OPAQUE, 16, 8, 32, 32);
100 
101 	if (tilemap2 == NULL)
102 	{
103 		return 1;
104 	}
105 	if (tilemap1 == NULL)
106 	{
107 		return 1;
108 	}
109 
110 	tilemap_set_scrolly(tilemap1, 0, +24);
111 	tilemap_set_scrolly(tilemap2, 0, +24);
112 
113 	return 0;
114 }
115 
116 
draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * rect)117 static void draw_sprites(struct mame_bitmap* bitmap, const struct rectangle* rect)
118 {
119 	int i;
120 
121 	for (i = 0; i < 16; i++)
122 	{
123 		UINT8 code = sprint8_pos_d_ram[i];
124 
125 		int x = sprint8_pos_h_ram[i];
126 		int y = sprint8_pos_v_ram[i];
127 
128 		if (code & 0x80)
129 		{
130 			x |= 0x100;
131 		}
132 
133 		drawgfx(bitmap, Machine->gfx[2],
134 			code ^ 7,
135 			i,
136 			!(code & 0x10), !(code & 0x08),
137 			496 - x, y - 31,
138 			rect, TRANSPARENCY_PEN, 0);
139 	}
140 }
141 
142 
VIDEO_UPDATE(sprint8)143 VIDEO_UPDATE( sprint8 )
144 {
145 	tilemap_draw(bitmap, cliprect, tilemap1, 0, 0);
146 
147 	draw_sprites(bitmap, cliprect);
148 }
149 
150 
VIDEO_EOF(sprint8)151 VIDEO_EOF( sprint8 )
152 {
153 	int x;
154 	int y;
155 
156 	tilemap_draw(helper2, &Machine->visible_area, tilemap2, 0, 0);
157 
158 	fillbitmap(helper1, 16, &Machine->visible_area);
159 
160 	draw_sprites(helper1, &Machine->visible_area);
161 
162 	for (y = Machine->visible_area.min_y; y <= Machine->visible_area.max_y; y++)
163 	{
164 		const UINT16* p1 = (UINT16*) helper1->line[y];
165 		const UINT16* p2 = (UINT16*) helper2->line[y];
166 
167 		for (x = Machine->visible_area.min_x; x <= Machine->visible_area.max_x; x++)
168 		{
169 			if (p1[x] != 16 && p2[x] != 16)
170 			{
171 				double time = cpu_getscanlinetime(y + 24) + x / 11055000.0;
172 
173 				timer_set(time, p1[x], sprint8_collision_callback);
174 			}
175 		}
176 	}
177 }
178