1 /*******************************************************************************
2 
3 	actfancr - Bryan McPhail, mish@tendril.co.uk
4 
5 *******************************************************************************/
6 
7 #include "driver.h"
8 #include "vidhrdw/generic.h"
9 #include "state.h"
10 
11 
12 static UINT8 actfancr_control_1[0x20],actfancr_control_2[0x20];
13 unsigned char *actfancr_pf1_data,*actfancr_pf2_data,*actfancr_pf1_rowscroll_data;
14 static struct tilemap *pf1_tilemap,*pf1_alt_tilemap,*pf2_tilemap;
15 static int flipscreen;
16 
actfancr_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)17 static UINT32 actfancr_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)
18 {
19 	/* logical (col,row) -> memory offset */
20 	return (col & 0x0f) + ((row & 0x0f) << 4) + ((col & 0xf0) << 4);
21 }
22 
actfancr_scan2(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)23 static UINT32 actfancr_scan2(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)
24 {
25 	/* logical (col,row) -> memory offset */
26 	return (col & 0x0f) + ((row & 0x0f) << 4) + ((row & 0x10) << 4) + ((col & 0x70) << 5);
27 }
28 
get_tile_info(int tile_index)29 static void get_tile_info(int tile_index)
30 {
31 	int tile,color;
32 
33 	tile=actfancr_pf1_data[2*tile_index]+(actfancr_pf1_data[2*tile_index+1]<<8);
34 	color=tile >> 12;
35 	tile=tile&0xfff;
36 
37 	SET_TILE_INFO(
38 			2,
39 			tile,
40 			color,
41 			0)
42 }
43 
triothep_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)44 static UINT32 triothep_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)
45 {
46 	/* logical (col,row) -> memory offset */
47 	return (col & 0x0f) + ((row & 0x0f) << 4) + ((row & 0x10) << 4) + ((col & 0x10) << 5);
48 }
49 
get_trio_tile_info(int tile_index)50 static void get_trio_tile_info(int tile_index)
51 {
52 	int tile,color;
53 
54 	tile=actfancr_pf1_data[2*tile_index]+(actfancr_pf1_data[2*tile_index+1]<<8);
55 	color=tile >> 12;
56 	tile=tile&0xfff;
57 
58 	SET_TILE_INFO(
59 			2,
60 			tile,
61 			color,
62 			0)
63 }
64 
get_pf2_tile_info(int tile_index)65 static void get_pf2_tile_info(int tile_index)
66 {
67 	int tile,color;
68 
69 	tile=actfancr_pf2_data[2*tile_index]+(actfancr_pf2_data[2*tile_index+1]<<8);
70 	color=tile>>12;
71 
72 	tile=tile&0xfff;
73 
74 	SET_TILE_INFO(
75 				0,
76 				tile,
77 				color,
78 				0)
79 }
80 
81 /******************************************************************************/
82 
register_savestate(void)83 static void register_savestate(void)
84 {
85 	state_save_register_UINT8("video", 0, "control_1", actfancr_control_1, 0x20);
86 	state_save_register_UINT8("video", 0, "control_2", actfancr_control_2, 0x20);
87 }
88 
VIDEO_START(actfancr)89 VIDEO_START( actfancr )
90 {
91 	pf1_tilemap = tilemap_create(get_tile_info,actfancr_scan,TILEMAP_OPAQUE,16,16,256,16);
92 	pf1_alt_tilemap = tilemap_create(get_tile_info,actfancr_scan2,TILEMAP_OPAQUE,16,16,128,32);
93 	pf2_tilemap = tilemap_create(get_pf2_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,32,32);
94 
95 	if (!pf1_tilemap || !pf1_alt_tilemap || !pf2_tilemap)
96 		return 1;
97 
98 	tilemap_set_transparent_pen(pf2_tilemap,0);
99 
100 	register_savestate();
101 
102 	return 0;
103 }
104 
VIDEO_START(triothep)105 VIDEO_START( triothep )
106 {
107 	pf1_tilemap = tilemap_create(get_trio_tile_info,triothep_scan,TILEMAP_OPAQUE,16,16,32,32);
108 	pf2_tilemap = tilemap_create(get_pf2_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,32,32);
109 
110 	if (!pf1_tilemap || !pf2_tilemap)
111 		return 1;
112 
113 	tilemap_set_transparent_pen(pf2_tilemap,0);
114 
115 	pf1_alt_tilemap=NULL;
116 
117 	register_savestate();
118 
119 	return 0;
120 }
121 
122 /******************************************************************************/
123 
WRITE_HANDLER(actfancr_pf1_control_w)124 WRITE_HANDLER( actfancr_pf1_control_w )
125 {
126 	actfancr_control_1[offset]=data;
127 }
128 
WRITE_HANDLER(actfancr_pf2_control_w)129 WRITE_HANDLER( actfancr_pf2_control_w )
130 {
131 	actfancr_control_2[offset]=data;
132 }
133 
WRITE_HANDLER(actfancr_pf1_data_w)134 WRITE_HANDLER( actfancr_pf1_data_w )
135 {
136 	actfancr_pf1_data[offset]=data;
137 	tilemap_mark_tile_dirty(pf1_tilemap,offset/2);
138 	if (pf1_alt_tilemap) tilemap_mark_tile_dirty(pf1_alt_tilemap,offset/2);
139 }
140 
READ_HANDLER(actfancr_pf1_data_r)141 READ_HANDLER( actfancr_pf1_data_r )
142 {
143 	return actfancr_pf1_data[offset];
144 }
145 
WRITE_HANDLER(actfancr_pf2_data_w)146 WRITE_HANDLER( actfancr_pf2_data_w )
147 {
148 	actfancr_pf2_data[offset]=data;
149 	tilemap_mark_tile_dirty(pf2_tilemap,offset/2);
150 }
151 
READ_HANDLER(actfancr_pf2_data_r)152 READ_HANDLER( actfancr_pf2_data_r )
153 {
154 	return actfancr_pf2_data[offset];
155 }
156 
157 /******************************************************************************/
158 
VIDEO_UPDATE(actfancr)159 VIDEO_UPDATE( actfancr )
160 {
161 	int offs,mult;
162 	int scrollx=(actfancr_control_1[0x10]+(actfancr_control_1[0x11]<<8));
163 	int scrolly=(actfancr_control_1[0x12]+(actfancr_control_1[0x13]<<8));
164 
165 	/* Draw playfield */
166 	flipscreen=actfancr_control_2[0]&0x80;
167 	tilemap_set_flip(ALL_TILEMAPS,flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
168 
169 	tilemap_set_scrollx( pf1_tilemap,0, scrollx );
170 	tilemap_set_scrolly( pf1_tilemap,0, scrolly );
171 	tilemap_set_scrollx( pf1_alt_tilemap,0, scrollx );
172 	tilemap_set_scrolly( pf1_alt_tilemap,0, scrolly );
173 
174 	if (actfancr_control_1[6]==1)
175 		tilemap_draw(bitmap,cliprect,pf1_alt_tilemap,0,0);
176 	else
177 		tilemap_draw(bitmap,cliprect,pf1_tilemap,0,0);
178 
179 	/* Sprites */
180 	for (offs = 0;offs < 0x800;offs += 8)
181 	{
182 		int x,y,sprite,colour,multi,fx,fy,inc,flash;
183 
184 		y=buffered_spriteram[offs]+(buffered_spriteram[offs+1]<<8);
185  		if ((y&0x8000) == 0) continue;
186 		x = buffered_spriteram[offs+4]+(buffered_spriteram[offs+5]<<8);
187 		colour = ((x & 0xf000) >> 12);
188 		flash=x&0x800;
189 		if (flash && (cpu_getcurrentframe() & 1)) continue;
190 
191 		fx = y & 0x2000;
192 		fy = y & 0x4000;
193 		multi = (1 << ((y & 0x1800) >> 11)) - 1;	/* 1x, 2x, 4x, 8x height */
194 
195 											/* multi = 0   1   3   7 */
196 		sprite = buffered_spriteram[offs+2]+(buffered_spriteram[offs+3]<<8);
197 		sprite &= 0x0fff;
198 
199 		x = x & 0x01ff;
200 		y = y & 0x01ff;
201 		if (x >= 256) x -= 512;
202 		if (y >= 256) y -= 512;
203 		x = 240 - x;
204 		y = 240 - y;
205 
206 		sprite &= ~multi;
207 		if (fy)
208 			inc = -1;
209 		else
210 		{
211 			sprite += multi;
212 			inc = 1;
213 		}
214 
215 		if (flipscreen) {
216 			y=240-y;
217 			x=240-x;
218 			if (fx) fx=0; else fx=1;
219 			if (fy) fy=0; else fy=1;
220 			mult=16;
221 		}
222 		else mult=-16;
223 
224 		while (multi >= 0)
225 		{
226 			drawgfx(bitmap,Machine->gfx[1],
227 					sprite - multi * inc,
228 					colour,
229 					fx,fy,
230 					x,y + mult * multi,
231 					cliprect,TRANSPARENCY_PEN,0);
232 			multi--;
233 		}
234 	}
235 
236 	tilemap_draw(bitmap,cliprect,pf2_tilemap,0,0);
237 }
238 
VIDEO_UPDATE(triothep)239 VIDEO_UPDATE( triothep )
240 {
241 	int offs,i,mult;
242 	int scrollx=(actfancr_control_1[0x10]+(actfancr_control_1[0x11]<<8));
243 	int scrolly=(actfancr_control_1[0x12]+(actfancr_control_1[0x13]<<8));
244 
245 	/* Draw playfield */
246 	flipscreen=actfancr_control_2[0]&0x80;
247 	tilemap_set_flip(ALL_TILEMAPS,flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
248 
249 	if (actfancr_control_2[0]&0x4) {
250 		tilemap_set_scroll_rows(pf1_tilemap,32);
251 		tilemap_set_scrolly( pf1_tilemap,0, scrolly );
252 		for (i=0; i<32; i++)
253 			tilemap_set_scrollx( pf1_tilemap,i, scrollx+(actfancr_pf1_rowscroll_data[i*2] | actfancr_pf1_rowscroll_data[i*2+1]<<8) );
254 	}
255 	else {
256 		tilemap_set_scroll_rows(pf1_tilemap,1);
257 		tilemap_set_scrollx( pf1_tilemap,0, scrollx );
258 		tilemap_set_scrolly( pf1_tilemap,0, scrolly );
259 	}
260 
261 	tilemap_draw(bitmap,cliprect,pf1_tilemap,0,0);
262 
263 	/* Sprites */
264 	for (offs = 0;offs < 0x800;offs += 8)
265 	{
266 		int x,y,sprite,colour,multi,fx,fy,inc,flash;
267 
268 		y=buffered_spriteram[offs]+(buffered_spriteram[offs+1]<<8);
269  		if ((y&0x8000) == 0) continue;
270 		x = buffered_spriteram[offs+4]+(buffered_spriteram[offs+5]<<8);
271 		colour = ((x & 0xf000) >> 12);
272 		flash=x&0x800;
273 		if (flash && (cpu_getcurrentframe() & 1)) continue;
274 
275 		fx = y & 0x2000;
276 		fy = y & 0x4000;
277 		multi = (1 << ((y & 0x1800) >> 11)) - 1;	/* 1x, 2x, 4x, 8x height */
278 
279 											/* multi = 0   1   3   7 */
280 		sprite = buffered_spriteram[offs+2]+(buffered_spriteram[offs+3]<<8);
281 		sprite &= 0x0fff;
282 
283 		x = x & 0x01ff;
284 		y = y & 0x01ff;
285 		if (x >= 256) x -= 512;
286 		if (y >= 256) y -= 512;
287 		x = 240 - x;
288 		y = 240 - y;
289 
290 		sprite &= ~multi;
291 		if (fy)
292 			inc = -1;
293 		else
294 		{
295 			sprite += multi;
296 			inc = 1;
297 		}
298 
299 		if (flipscreen) {
300 			y=240-y;
301 			x=240-x;
302 			if (fx) fx=0; else fx=1;
303 			if (fy) fy=0; else fy=1;
304 			mult=16;
305 		}
306 		else mult=-16;
307 
308 		while (multi >= 0)
309 		{
310 			drawgfx(bitmap,Machine->gfx[1],
311 					sprite - multi * inc,
312 					colour,
313 					fx,fy,
314 					x,y + mult * multi,
315 					cliprect,TRANSPARENCY_PEN,0);
316 			multi--;
317 		}
318 	}
319 
320 	tilemap_draw(bitmap,cliprect,pf2_tilemap,0,0);
321 }
322