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