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