1 /* vidhrdw/namconb1.c */
2
3 #include "driver.h"
4 #include "vidhrdw/generic.h"
5 #include "namconb1.h"
6 #include "namcoic.h"
7 #include "namcos2.h"
8
9
10 /* tilemap_palette_bank is used to cache tilemap color, so that we can
11 * mark whole tilemaps dirty only when necessary.
12 */
13 static int tilemap_palette_bank[6];
14 static UINT8 *mpMaskData;
15 static struct tilemap *background[6];
16
17 /* nth_word32 is a general-purpose utility function, which allows us to
18 * read from 32-bit aligned memory as if it were an array of 16 bit words.
19 */
nth_word32(const data32_t * source,int which)20 static INLINE data16_t nth_word32( const data32_t *source, int which )
21 {
22 source += which/2;
23 if( which&1 )
24 {
25 return (*source)&0xffff;
26 }
27 else
28 {
29 return (*source)>>16;
30 }
31 }
32
33 /* nth_byte32 is a general-purpose utility function, which allows us to
34 * read from 32-bit aligned memory as if it were an array of bytes.
35 */
36 static INLINE data8_t
nth_byte32(const data32_t * pSource,int which)37 nth_byte32( const data32_t *pSource, int which )
38 {
39 data32_t data = pSource[which/4];
40 switch( which&3 )
41 {
42 case 0: return data>>24;
43 case 1: return (data>>16)&0xff;
44 case 2: return (data>>8)&0xff;
45 default: return data&0xff;
46 }
47 } /* nth_byte32 */
48
tilemapNB1_get_info(int tile_index,int tilemap_color,const data32_t * tilemap_videoram)49 static INLINE void tilemapNB1_get_info(int tile_index,int tilemap_color,const data32_t *tilemap_videoram)
50 {
51 data16_t tile = nth_word32( tilemap_videoram, tile_index );
52 SET_TILE_INFO(
53 NAMCONB1_TILEGFX,
54 tile,
55 tilemap_color,
56 0)
57 tile_info.mask_data = 8*tile + mpMaskData;
58 }
59
tilemapNB1_get_info0(int tile_index)60 static void tilemapNB1_get_info0(int tile_index) { tilemapNB1_get_info(tile_index,tilemap_palette_bank[0],&videoram32[0x0000]); }
tilemapNB1_get_info1(int tile_index)61 static void tilemapNB1_get_info1(int tile_index) { tilemapNB1_get_info(tile_index,tilemap_palette_bank[1],&videoram32[0x0800]); }
tilemapNB1_get_info2(int tile_index)62 static void tilemapNB1_get_info2(int tile_index) { tilemapNB1_get_info(tile_index,tilemap_palette_bank[2],&videoram32[0x1000]); }
tilemapNB1_get_info3(int tile_index)63 static void tilemapNB1_get_info3(int tile_index) { tilemapNB1_get_info(tile_index,tilemap_palette_bank[3],&videoram32[0x1800]); }
tilemapNB1_get_info4(int tile_index)64 static void tilemapNB1_get_info4(int tile_index) { tilemapNB1_get_info(tile_index,tilemap_palette_bank[4],&videoram32[NAMCONB1_FG1BASE/2]); }
tilemapNB1_get_info5(int tile_index)65 static void tilemapNB1_get_info5(int tile_index) { tilemapNB1_get_info(tile_index,tilemap_palette_bank[5],&videoram32[NAMCONB1_FG2BASE/2]); }
66
WRITE32_HANDLER(namconb1_videoram_w)67 WRITE32_HANDLER( namconb1_videoram_w )
68 {
69 int layer;
70 data32_t old_data;
71
72 old_data = videoram32[offset];
73 COMBINE_DATA( &videoram32[offset] );
74 if( videoram32[offset]!=old_data )
75 {
76 offset*=2; /* convert dword offset to word offset */
77 layer = offset/(64*64);
78 if( layer<4 )
79 {
80 offset &= 0xfff;
81 tilemap_mark_tile_dirty( background[layer], offset );
82 tilemap_mark_tile_dirty( background[layer], offset+1 );
83 }
84 else
85 {
86 if( offset >= NAMCONB1_FG1BASE &&
87 offset<NAMCONB1_FG1BASE+NAMCONB1_COLS*NAMCONB1_ROWS )
88 {
89 offset -= NAMCONB1_FG1BASE;
90 tilemap_mark_tile_dirty( background[4], offset );
91 tilemap_mark_tile_dirty( background[4], offset+1 );
92 }
93 else if( offset >= NAMCONB1_FG2BASE &&
94 offset<NAMCONB1_FG2BASE+NAMCONB1_COLS*NAMCONB1_ROWS )
95 {
96 offset -= NAMCONB1_FG2BASE;
97 tilemap_mark_tile_dirty( background[5], offset );
98 tilemap_mark_tile_dirty( background[5], offset+1 );
99 }
100 }
101 }
102 }
103
namconb1_install_palette(void)104 static void namconb1_install_palette( void )
105 {
106 int pen, page, dword_offset, byte_offset;
107 data32_t r,g,b;
108 data32_t *pSource;
109
110 /* this is unnecessarily expensive. Better would be to mark palette entries dirty as
111 * they are modified, and only process those that have changed.
112 */
113 pen = 0;
114 for( page=0; page<4; page++ )
115 {
116 pSource = &paletteram32[page*0x2000/4];
117 for( dword_offset=0; dword_offset<0x800/4; dword_offset++ )
118 {
119 r = pSource[dword_offset+0x0000/4];
120 g = pSource[dword_offset+0x0800/4];
121 b = pSource[dword_offset+0x1000/4];
122
123 for( byte_offset=0; byte_offset<4; byte_offset++ )
124 {
125 palette_set_color( pen++, r>>24, g>>24, b>>24 );
126 r<<=8; g<<=8; b<<=8;
127 }
128 }
129 }
130 }
131
132 /**
133 * MCU simulation. It manages coinage, input ports, and presumably
134 * communication with the sound CPU.
135 */
136 static void
handle_mcu(void)137 handle_mcu( void )
138 {
139 static int toggle;
140 static data16_t credits;
141 static int old_coin_state;
142 static int old_p1;
143 static int old_p2;
144 static int old_p3;
145 static int old_p4;
146 int new_coin_state = readinputport(0)&0x3; /* coin1,2 */
147 unsigned dsw = readinputport(1)<<16;
148 unsigned p1 = readinputport(2);
149 unsigned p2 = readinputport(3);
150 unsigned p3;
151 unsigned p4;
152 toggle = !toggle;
153 if( toggle ) dsw &= ~(0x80<<16);
154 if( namcos2_gametype == NAMCONB2_MACH_BREAKERS )
155 {
156 p3 = readinputport(4);
157 p4 = readinputport(5);
158 }
159 else
160 {
161 p3 = 0;
162 p4 = 0;
163 }
164
165 p1 = (p1&(~old_p1))|(p1<<8);
166 p2 = (p2&(~old_p2))|(p2<<8);
167 p3 = (p3&(~old_p3))|(p3<<8);
168 p4 = (p4&(~old_p4))|(p4<<8);
169
170 old_p1 = p1;
171 old_p2 = p2;
172 old_p3 = p3;
173 old_p4 = p4;
174
175 namconb1_workram32[0x6000/4] = dsw|p1;
176 namconb1_workram32[0x6004/4] = (p2<<16)|p3;
177 namconb1_workram32[0x6008/4] = p4<<16;
178
179 if( new_coin_state && !old_coin_state )
180 {
181 credits++;
182 }
183 old_coin_state = new_coin_state;
184 namconb1_workram32[0x601e/4] &= 0xffff0000;
185 namconb1_workram32[0x601e/4] |= credits;
186 } /* handle_mcu */
187
188 static void
video_update_common(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int bROZ)189 video_update_common( struct mame_bitmap *bitmap, const struct rectangle *cliprect, int bROZ )
190 {
191 const int xadjust[4] = { 0,2,3,4 };
192 int i,pri;
193
194 handle_mcu();
195 namconb1_install_palette();
196 fillbitmap(priority_bitmap,0,NULL); /* not actually used (yet) */
197
198 /* I have no idea what the background color should be, but I doubt it ever pokes through. */
199 fillbitmap( bitmap, 0, 0 );
200
201 for( i=0; i<6; i++ )
202 {
203 int tilemap_color = nth_word32( &namconb1_scrollram32[0x30/4], i )&7;
204 if( tilemap_palette_bank[i]!= tilemap_color )
205 {
206 tilemap_palette_bank[i] = tilemap_color;
207 tilemap_mark_all_tiles_dirty( background[i] );
208 }
209 if( i<4 )
210 {
211 tilemap_set_scrollx( background[i],0,namconb1_scrollram32[i*2]+48-xadjust[i] );
212 tilemap_set_scrolly( background[i],0,namconb1_scrollram32[i*2+1]+24 );
213 }
214 }
215
216 for( pri=0; pri<8; pri++ )
217 {
218 if( bROZ )
219 {
220 namco_roz_draw( bitmap,cliprect,pri );
221 }
222
223 for( i=0; i<6; i++ )
224 {
225 if( nth_word32( &namconb1_scrollram32[0x20/4],i ) == pri )
226 {
227 tilemap_draw( bitmap,cliprect,background[i],0,0/*1<<pri*/ );
228 }
229 }
230 namco_obj_draw( bitmap, cliprect, pri );
231 }
232 } /* video_update_common */
233
234 /************************************************************************************************/
235
VIDEO_UPDATE(namconb1)236 VIDEO_UPDATE( namconb1 )
237 {
238 int beamx,beamy;
239
240 video_update_common( bitmap, cliprect, 0 );
241
242 if( namcos2_gametype == NAMCONB1_GUNBULET )
243 {
244 beamx = ((readinputport(4))*288)/256;
245 beamy = ((readinputport(5))*224)/256;
246 draw_crosshair( bitmap, beamx, beamy, cliprect );
247
248 beamx = ((readinputport(6))*288)/256;
249 beamy = ((readinputport(7))*224)/256;
250 draw_crosshair( bitmap, beamx, beamy, cliprect );
251 }
252 }
253
NB1objcode2tile(int code)254 static int NB1objcode2tile( int code )
255 {
256 int bank;
257 bank = nth_word32( namconb1_spritebank32, code>>11 );
258 return (code&0x7ff) + bank*0x800;
259 }
260
VIDEO_START(namconb1)261 VIDEO_START( namconb1 )
262 {
263 int i;
264 static void (*get_info[6])(int tile_index) =
265 {
266 tilemapNB1_get_info0, tilemapNB1_get_info1, tilemapNB1_get_info2,
267 tilemapNB1_get_info3, tilemapNB1_get_info4, tilemapNB1_get_info5
268 };
269
270 namco_obj_init(NAMCONB1_SPRITEGFX,0x0,NB1objcode2tile);
271 mpMaskData = (UINT8 *)memory_region( NAMCONB1_TILEMASKREGION );
272 for( i=0; i<6; i++ )
273 {
274 if( i<4 )
275 {
276 background[i] = tilemap_create(
277 get_info[i],
278 tilemap_scan_rows,
279 TILEMAP_BITMASK,8,8,64,64 );
280 }
281 else
282 {
283 background[i] = tilemap_create(
284 get_info[i],
285 tilemap_scan_rows,
286 TILEMAP_BITMASK,8,8,NAMCONB1_COLS,NAMCONB1_ROWS );
287 }
288
289 if( background[i]==NULL ) return 1; /* error */
290
291 tilemap_palette_bank[i] = -1;
292 }
293 return 0; /* no error */
294 }
295
296 /****************************************************************************************************/
297
298 static INLINE void
tilemapNB2_get_info(int tile_index,int which,const data32_t * tilemap_videoram)299 tilemapNB2_get_info(int tile_index,int which,const data32_t *tilemap_videoram)
300 {
301 data16_t tile = nth_word32( tilemap_videoram, tile_index );
302 int mangle;
303
304 if( namcos2_gametype == NAMCONB2_MACH_BREAKERS )
305 {
306 mangle = tile;
307 }
308 else
309 {
310 /* the pixmap index is mangled, the transparency bitmask index is not */
311 mangle = tile&~(0x140);
312 if( tile&0x100 ) mangle |= 0x040;
313 if( tile&0x040 ) mangle |= 0x100;
314 }
315 SET_TILE_INFO( NAMCONB1_TILEGFX,mangle,tilemap_palette_bank[which],0)
316 tile_info.mask_data = 8*tile + mpMaskData;
317 } /* tilemapNB2_get_info */
318
tilemapNB2_get_info0(int tile_index)319 static void tilemapNB2_get_info0(int tile_index) { tilemapNB2_get_info(tile_index,0,&videoram32[0x0000/4]); }
tilemapNB2_get_info1(int tile_index)320 static void tilemapNB2_get_info1(int tile_index) { tilemapNB2_get_info(tile_index,1,&videoram32[0x2000/4]); }
tilemapNB2_get_info2(int tile_index)321 static void tilemapNB2_get_info2(int tile_index) { tilemapNB2_get_info(tile_index,2,&videoram32[0x4000/4]); }
tilemapNB2_get_info3(int tile_index)322 static void tilemapNB2_get_info3(int tile_index) { tilemapNB2_get_info(tile_index,3,&videoram32[0x6000/4]); }
tilemapNB2_get_info4(int tile_index)323 static void tilemapNB2_get_info4(int tile_index) { tilemapNB2_get_info(tile_index,4,&videoram32[NAMCONB1_FG1BASE/2]); }
tilemapNB2_get_info5(int tile_index)324 static void tilemapNB2_get_info5(int tile_index) { tilemapNB2_get_info(tile_index,5,&videoram32[NAMCONB1_FG2BASE/2]); }
325
VIDEO_UPDATE(namconb2)326 VIDEO_UPDATE( namconb2 )
327 {
328 video_update_common( bitmap, cliprect, 1 );
329 } /* namconb2_vh_screenrefresh */
330
NB2objcode2tile(int code)331 static int NB2objcode2tile( int code )
332 {
333 int bank;
334 bank = nth_byte32( namconb1_spritebank32, (code>>11)&0xf );
335 code &= 0x7ff;
336 if( namcos2_gametype == NAMCONB2_MACH_BREAKERS )
337 {
338 if( bank&0x01 ) code |= 0x01*0x800;
339 if( bank&0x02 ) code |= 0x02*0x800;
340 if( bank&0x04 ) code |= 0x04*0x800;
341 if( bank&0x08 ) code |= 0x08*0x800;
342 if( bank&0x10 ) code |= 0x10*0x800;
343 if( bank&0x40 ) code |= 0x20*0x800;
344 }
345 else
346 {
347 if( bank&0x01 ) code |= 0x01*0x800;
348 if( bank&0x02 ) code |= 0x04*0x800;
349 if( bank&0x04 ) code |= 0x02*0x800;
350 if( bank&0x08 ) code |= 0x08*0x800;
351 if( bank&0x10 ) code |= 0x10*0x800;
352 if( bank&0x40 ) code |= 0x20*0x800;
353 }
354 return code;
355 }
356
VIDEO_START(namconb2)357 VIDEO_START( namconb2 )
358 {
359 int i;
360 static void (*get_info[6])(int tile_index) =
361 { tilemapNB2_get_info0, tilemapNB2_get_info1, tilemapNB2_get_info2,
362 tilemapNB2_get_info3, tilemapNB2_get_info4, tilemapNB2_get_info5 };
363
364 namco_obj_init(NAMCONB1_SPRITEGFX,0x0,NB2objcode2tile);
365
366 if( namco_roz_init(NAMCONB1_ROTGFX,NAMCONB1_ROTMASKREGION)!=0 ) return 1;
367
368 mpMaskData = (UINT8 *)memory_region( NAMCONB1_TILEMASKREGION );
369 for( i=0; i<6; i++ )
370 {
371 if( i<4 )
372 {
373 background[i] = tilemap_create(
374 get_info[i],
375 tilemap_scan_rows,
376 TILEMAP_BITMASK,8,8,64,64 );
377 }
378 else
379 {
380 background[i] = tilemap_create(
381 get_info[i],
382 tilemap_scan_rows,
383 TILEMAP_BITMASK,8,8,NAMCONB1_COLS,NAMCONB1_ROWS );
384 }
385
386 if( background[i]==NULL ) return 1; /* error */
387 }
388
389 return 0;
390 } /* namconb2_vh_start */
391