1 /***************************************************************************
2 
3 						  -= Power Instinct =-
4 							(C) 1993 Atlus
5 
6 				driver by	Luca Elia (l.elia@tin.it)
7 
8 
9 Note:	if MAME_DEBUG is defined, pressing Z with:
10 
11 		Q			shows layer 1
12 		W			shows layer 2
13 		A			shows the sprites
14 
15 		Keys can be used togheter!
16 
17 		[ 2 Scrolling Layers ]
18 
19 		Each Layer is made of various pages of 256x256 pixels.
20 
21 			[Layer 0]
22 				Pages:				16x2
23 				Tiles:				16x16x4
24 				Scroll:				X,Y
25 
26 			[Layer 1]
27 				Pages:				2x1
28 				Tiles:				8x8x4
29 				Scroll:				No
30 
31 		[ 256 Sprites ]
32 
33 		Each sprite is made of a variable amount of 16x16 tiles.
34 		Size can therefore vary from 16x16 (1 tile) to 256x256
35 		(16x16 tiles)
36 
37 
38 **************************************************************************/
39 #include "vidhrdw/generic.h"
40 
41 /* Variables that driver has access to: */
42 data16_t *powerins_vram_0, *powerins_vctrl_0;
43 data16_t *powerins_vram_1, *powerins_vctrl_1;
44 data16_t *powerins_vregs;
45 
46 /* Variables only used here: */
47 static struct tilemap *tilemap_0, *tilemap_1;
48 static int tile_bank;
49 
50 
51 
52 /***************************************************************************
53 
54 						Hardware registers access
55 
56 ***************************************************************************/
57 
58 
WRITE16_HANDLER(powerins_flipscreen_w)59 WRITE16_HANDLER( powerins_flipscreen_w )
60 {
61 	if (ACCESSING_LSB)	flip_screen_set( data & 1 );
62 }
63 
WRITE16_HANDLER(powerins_tilebank_w)64 WRITE16_HANDLER( powerins_tilebank_w )
65 {
66 	if (ACCESSING_LSB)
67 	{
68 		if (data != tile_bank)
69 		{
70 			tile_bank = data;		// Tiles Bank (VRAM 0)
71 			tilemap_mark_all_tiles_dirty(tilemap_0);
72 		}
73 	}
74 }
75 
76 
77 
78 /***************************************************************************
79 
80 									Palette
81 
82 ***************************************************************************/
83 
84 
WRITE16_HANDLER(powerins_paletteram16_w)85 WRITE16_HANDLER( powerins_paletteram16_w )
86 {
87 	/*	byte 0    byte 1	*/
88 	/*	RRRR GGGG BBBB RGBx	*/
89 	/*	4321 4321 4321 000x	*/
90 
91 	data16_t newword = COMBINE_DATA(&paletteram16[offset]);
92 
93 	int r = ((newword >> 8) & 0xF0 ) | ((newword << 0) & 0x08);
94 	int g = ((newword >> 4) & 0xF0 ) | ((newword << 1) & 0x08);
95 	int b = ((newword >> 0) & 0xF0 ) | ((newword << 2) & 0x08);
96 
97 	palette_set_color( offset, r,g,b );
98 }
99 
100 
101 /***************************************************************************
102 
103 						Callbacks for the TileMap code
104 
105 ***************************************************************************/
106 
107 
108 /***************************************************************************
109 						  [ Tiles Format VRAM 0]
110 
111 Offset:
112 
113 0.w		fedc ---- ---- ----		Color Low  Bits
114 		---- b--- ---- ----		Color High Bit
115 		---- -a98 7654 3210		Code (Banked)
116 
117 
118 ***************************************************************************/
119 
120 /* Layers are made of 256x256 pixel pages */
121 #define TILES_PER_PAGE_X	(0x10)
122 #define TILES_PER_PAGE_Y	(0x10)
123 #define TILES_PER_PAGE		(TILES_PER_PAGE_X * TILES_PER_PAGE_Y)
124 
125 #define DIM_NX_0			(0x100)
126 #define DIM_NY_0			(0x20)
127 
128 
get_tile_info_0(int tile_index)129 static void get_tile_info_0( int tile_index )
130 {
131 	data16_t code = powerins_vram_0[tile_index];
132 	SET_TILE_INFO(
133 			0,
134 			(code & 0x07ff) + (tile_bank*0x800),
135 			((code & 0xf000) >> (16-4)) + ((code & 0x0800) >> (11-4)),
136 			0)
137 }
138 
WRITE16_HANDLER(powerins_vram_0_w)139 WRITE16_HANDLER( powerins_vram_0_w )
140 {
141 	data16_t oldword = powerins_vram_0[offset];
142 	data16_t newword = COMBINE_DATA(&powerins_vram_0[offset]);
143 	if (oldword != newword)
144 		tilemap_mark_tile_dirty(tilemap_0, offset);
145 }
146 
powerins_get_memory_offset_0(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)147 UINT32 powerins_get_memory_offset_0(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)
148 {
149 	return 	(col * TILES_PER_PAGE_Y) +
150 
151 			(row % TILES_PER_PAGE_Y) +
152 			(row / TILES_PER_PAGE_Y) * (TILES_PER_PAGE * 16);
153 }
154 
155 
156 
157 /***************************************************************************
158 						  [ Tiles Format VRAM 1]
159 
160 Offset:
161 
162 0.w		fedc ---- ---- ----		Color
163 		---- ba98 7654 3210		Code
164 
165 
166 ***************************************************************************/
167 
168 #define DIM_NX_1	(0x40)
169 #define DIM_NY_1	(0x20)
170 
get_tile_info_1(int tile_index)171 static void get_tile_info_1( int tile_index )
172 {
173 	data16_t code = powerins_vram_1[tile_index];
174 	SET_TILE_INFO(
175 			1,
176 			code & 0x0fff,
177 			(code & 0xf000) >> (16-4),
178 			0)
179 }
180 
WRITE16_HANDLER(powerins_vram_1_w)181 WRITE16_HANDLER( powerins_vram_1_w )
182 {
183 	data16_t oldword = powerins_vram_1[offset];
184 	data16_t newword = COMBINE_DATA(&powerins_vram_1[offset]);
185 	if (oldword != newword)
186 		tilemap_mark_tile_dirty(tilemap_1, offset);
187 }
188 
189 
190 
191 
192 
193 /***************************************************************************
194 
195 
196 								Vh_Start
197 
198 
199 ***************************************************************************/
200 
VIDEO_START(powerins)201 VIDEO_START( powerins )
202 {
203 	tilemap_0 = tilemap_create(	get_tile_info_0,
204 								powerins_get_memory_offset_0,
205 								TILEMAP_OPAQUE,
206 								16,16,
207 								DIM_NX_0, DIM_NY_0 );
208 
209 	tilemap_1 = tilemap_create(	get_tile_info_1,
210 								tilemap_scan_cols,
211 								TILEMAP_TRANSPARENT,
212 								8,8,
213 								DIM_NX_1, DIM_NY_1 );
214 
215 	if (tilemap_0 && tilemap_1)
216 	{
217 		tilemap_set_scroll_rows(tilemap_0,1);
218 		tilemap_set_scroll_cols(tilemap_0,1);
219 		tilemap_set_transparent_pen(tilemap_0,15);
220 
221 		tilemap_set_scroll_rows(tilemap_1,1);
222 		tilemap_set_scroll_cols(tilemap_1,1);
223 		tilemap_set_transparent_pen(tilemap_1,15);
224 
225 		return 0;
226 	}
227 	else return 1;
228 }
229 
230 
231 
232 
233 
234 
235 /***************************************************************************
236 
237 
238 								Sprites Drawing
239 
240 
241 ***************************************************************************/
242 
243 
244 
245 /* --------------------------[ Sprites Format ]----------------------------
246 
247 Offset:		Format:					Value:
248 
249 	00 		fedc ba98 7654 321-		-
250 	 		---- ---- ---- ---0		Display this sprite
251 
252 	02 		fed- ---- ---- ----		-
253 	 		---c ---- ---- ----		Flip X
254 	 		---- ba9- ---- ----		-
255 	 		---- ---8 ---- ----		Code High Bit
256 			---- ---- 7654 ----		Number of tiles along Y, minus 1 (1-16)
257 			---- ---- ---- 3210		Number of tiles along X, minus 1 (1-16)
258 
259 	04 								Unused?
260 
261 	06		f--- ---- ---- ----		-
262 			-edc ba98 7654 3210		Code Low Bits
263 
264 	08 								X
265 
266 	0A 								Unused?
267 
268 	0C								Y
269 
270 	0E		fedc ba98 76-- ----		-
271 			---- ---- --54 3210		Color
272 
273 
274 ------------------------------------------------------------------------ */
275 
276 #define SIGN_EXTEND_POS(_var_)	{_var_ &= 0x3ff; if (_var_ > 0x1ff) _var_ -= 0x400;}
277 
278 
powerins_draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect)279 static void powerins_draw_sprites(struct mame_bitmap *bitmap,const struct rectangle *cliprect)
280 {
281 	data16_t *source = spriteram16 + 0x8000/2;
282 	data16_t *finish = spriteram16 + 0x9000/2;
283 
284 	int screen_w	=	Machine->drv->screen_width;
285 	int screen_h	=	Machine->drv->screen_height;
286 
287 	for ( ; source < finish; source += 16/2 )
288 	{
289 		int x,y,inc;
290 
291 		int	attr	=	source[ 0x0/2 ];
292 		int	size	=	source[ 0x2/2 ];
293 		int	code	=	source[ 0x6/2 ];
294 		int	sx		=	source[ 0x8/2 ];
295 		int	sy		=	source[ 0xc/2 ];
296 		int	color	=	source[ 0xe/2 ];
297 
298 		int	flipx	=	size & 0x1000;
299 		int	flipy	=	0;	// ??
300 
301 		int	dimx	=	((size >> 0) & 0xf ) + 1;
302 		int	dimy	=	((size >> 4) & 0xf ) + 1;
303 
304 		if (!(attr&1)) continue;
305 
306 		SIGN_EXTEND_POS(sx)
307 		SIGN_EXTEND_POS(sy)
308 
309 		/* Handle flip_screen. Apply a global offset of 32 pixels along x too */
310 
311 		if (flip_screen)
312 		{	sx = screen_w - sx - dimx*16 - 32;	flipx = !flipx;
313 			sy = screen_h - sy - dimy*16;		flipy = !flipy;
314 			code += dimx*dimy-1;			inc = -1;	}
315 		else
316 		{	sx += 32;						inc = +1;	}
317 
318 		code = (code & 0x7fff) + ( (size & 0x0100) << 7 );
319 
320 		for (x = 0 ; x < dimx ; x++)
321 		{
322 			for (y = 0 ; y < dimy ; y++)
323 			{
324 				drawgfx(bitmap,Machine->gfx[2],
325 						code,
326 						color,
327 						flipx, flipy,
328 						sx + x*16,
329 						sy + y*16,
330 						cliprect,TRANSPARENCY_PEN,15);
331 
332 				code += inc;
333 			}
334 		}
335 
336 
337 	}
338 }
339 
340 
341 
342 
343 /***************************************************************************
344 
345 
346 								Screen Drawing
347 
348 
349 ***************************************************************************/
350 
351 
VIDEO_UPDATE(powerins)352 VIDEO_UPDATE( powerins )
353 {
354 	int layers_ctrl = -1;
355 
356 	int scrollx = (powerins_vctrl_0[2/2]&0xff) + (powerins_vctrl_0[0/2]&0xff)*256;
357 	int scrolly = (powerins_vctrl_0[6/2]&0xff) + (powerins_vctrl_0[4/2]&0xff)*256;
358 
359 	tilemap_set_scrollx( tilemap_0, 0, scrollx - 0x20);
360 	tilemap_set_scrolly( tilemap_0, 0, scrolly );
361 
362 	tilemap_set_scrollx( tilemap_1, 0, -0x20);	// fixed offset
363 	tilemap_set_scrolly( tilemap_1, 0,  0x00);
364 
365 #ifdef MAME_DEBUG
366 if (keyboard_pressed(KEYCODE_Z))
367 {
368 	int msk = 0;
369 
370 	if (keyboard_pressed(KEYCODE_Q))	msk |= 1;
371 	if (keyboard_pressed(KEYCODE_W))	msk |= 2;
372 //	if (keyboard_pressed(KEYCODE_E))	msk |= 4;
373 	if (keyboard_pressed(KEYCODE_A))	msk |= 8;
374 	if (msk != 0) layers_ctrl &= msk;
375 }
376 #endif
377 
378 	if (layers_ctrl&1)		tilemap_draw(bitmap,cliprect, tilemap_0, 0, 0);
379 	else					fillbitmap(bitmap,Machine->pens[0],cliprect);
380 	if (layers_ctrl&8)		powerins_draw_sprites(bitmap,cliprect);
381 	if (layers_ctrl&2)		tilemap_draw(bitmap,cliprect, tilemap_1, 0, 0);
382 }
383