diff options
Diffstat (limited to 'src/mame/video/namconb1.c')
-rw-r--r-- | src/mame/video/namconb1.c | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/src/mame/video/namconb1.c b/src/mame/video/namconb1.c new file mode 100644 index 00000000000..e3e4c8bc693 --- /dev/null +++ b/src/mame/video/namconb1.c @@ -0,0 +1,289 @@ +/* video/namconb1.c */ + +#include "driver.h" +#include "namconb1.h" +#include "namcoic.h" +#include "namcos2.h" + +static UINT32 tilemap_tile_bank[4]; + +/* nth_word32 is a general-purpose utility function, which allows us to + * read from 32-bit aligned memory as if it were an array of 16 bit words. + */ +INLINE UINT16 +nth_word32( const UINT32 *source, int which ) +{ + source += which/2; + if( which&1 ) + { + return (*source)&0xffff; + } + else + { + return (*source)>>16; + } +} + +/* nth_byte32 is a general-purpose utility function, which allows us to + * read from 32-bit aligned memory as if it were an array of bytes. + */ +INLINE UINT8 +nth_byte32( const UINT32 *pSource, int which ) +{ + UINT32 data = pSource[which/4]; + switch( which&3 ) + { + case 0: return data>>24; + case 1: return (data>>16)&0xff; + case 2: return (data>>8)&0xff; + default: return data&0xff; + } +} /* nth_byte32 */ + +static void +NB1TilemapCB(UINT16 code, int *tile, int *mask ) +{ + *tile = code; + *mask = code; +} /* NB1TilemapCB */ + +static void +NB2TilemapCB(UINT16 code, int *tile, int *mask ) +{ + int mangle; + + if( namcos2_gametype == NAMCONB2_MACH_BREAKERS ) + { + /* 00010203 04050607 00010203 04050607 (normal) */ + /* 00010718 191a1b07 00010708 090a0b07 (alt bank) */ + int bank = nth_byte32( namconb1_tilebank32, (code>>13)+8 ); + mangle = (code&0x1fff) + bank*0x2000; + *tile = mangle; + *mask = mangle; + } + else + { + /* the pixmap index is mangled, the transparency bitmask index is not */ + mangle = code&~(0x140); + if( code&0x100 ) mangle |= 0x040; + if( code&0x040 ) mangle |= 0x100; + *tile = mangle; + *mask = code; + } +} /* NB2TilemapCB */ + +static void namconb1_install_palette(running_machine *machine) +{ + int pen, page, dword_offset, byte_offset; + UINT32 r,g,b; + UINT32 *pSource; + + /** + * This is unnecessarily expensive. Better would be to mark palette entries dirty as + * they are modified, and only process those that have changed. + */ + pen = 0; + for( page=0; page<4; page++ ) + { + pSource = &paletteram32[page*0x2000/4]; + for( dword_offset=0; dword_offset<0x800/4; dword_offset++ ) + { + r = pSource[dword_offset+0x0000/4]; + g = pSource[dword_offset+0x0800/4]; + b = pSource[dword_offset+0x1000/4]; + + for( byte_offset=0; byte_offset<4; byte_offset++ ) + { + palette_set_color_rgb( machine, pen++, r>>24, g>>24, b>>24 ); + r<<=8; g<<=8; b<<=8; + } + } + } +} /* namconb1_install_palette */ + +/** + * MCU simulation. It manages coinage, input ports, and presumably + * communication with the sound CPU. + */ +static void +handle_mcu( void ) +{ + static int toggle; + static UINT16 credits; + static int old_coin_state; + static int old_p1; + static int old_p2; + static int old_p3; + static int old_p4; + int new_coin_state = readinputport(0)&0x3; /* coin1,2 */ + unsigned dsw = readinputport(1)<<16; + unsigned p1 = readinputport(2); + unsigned p2 = readinputport(3); + unsigned p3; + unsigned p4; + toggle = !toggle; + if( toggle ) dsw &= ~(0x80<<16); + if( namcos2_gametype == NAMCONB2_MACH_BREAKERS ) + { + p3 = readinputport(4); + p4 = readinputport(5); + } + else + { + p3 = 0; + p4 = 0; + } + + p1 = (p1&(~old_p1))|(p1<<8); + p2 = (p2&(~old_p2))|(p2<<8); + p3 = (p3&(~old_p3))|(p3<<8); + p4 = (p4&(~old_p4))|(p4<<8); + + old_p1 = p1; + old_p2 = p2; + old_p3 = p3; + old_p4 = p4; + + namconb1_workram32[0x6000/4] = dsw|p1; + namconb1_workram32[0x6004/4] = (p2<<16)|p3; + namconb1_workram32[0x6008/4] = p4<<16; + + if( new_coin_state && !old_coin_state ) + { + credits++; + } + old_coin_state = new_coin_state; + namconb1_workram32[0x601e/4] &= 0xffff0000; + namconb1_workram32[0x601e/4] |= credits; +} /* handle_mcu */ + +static void +video_update_common(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect, int bROZ ) +{ + int pri; + handle_mcu(); + namconb1_install_palette(machine); + + if( bROZ ) + { + for( pri=0; pri<16; pri++ ) + { + namco_roz_draw( bitmap,cliprect,pri ); + if( (pri&1)==0 ) + { + namco_tilemap_draw( bitmap, cliprect, pri/2 ); + } + namco_obj_draw(machine, bitmap, cliprect, pri ); + } + } + else + { + for( pri=0; pri<8; pri++ ) + { + namco_tilemap_draw( bitmap, cliprect, pri ); + namco_obj_draw(machine, bitmap, cliprect, pri ); + } + } +} /* video_update_common */ + +/************************************************************************************************/ + +VIDEO_UPDATE( namconb1 ) +{ + /* compute window for custom screen blanking */ + rectangle clip; + //004a 016a 0021 0101 0144 0020 (nebulas ray) + UINT32 xclip = paletteram32[0x1800/4]; + UINT32 yclip = paletteram32[0x1804/4]; + clip.min_x = (xclip>>16) - 0x4a; + clip.max_x = (xclip&0xffff) - 0x4a - 1; + clip.min_y = (yclip>>16) - 0x21; + clip.max_y = (yclip&0xffff) - 0x21 - 1; + /* intersect with master clip rectangle */ + if( clip.min_x < cliprect->min_x ){ clip.min_x = cliprect->min_x; } + if( clip.min_y < cliprect->min_y ){ clip.min_y = cliprect->min_y; } + if( clip.max_x > cliprect->max_x ){ clip.max_x = cliprect->max_x; } + if( clip.max_y > cliprect->max_y ){ clip.max_y = cliprect->max_y; } + + fillbitmap( bitmap, get_black_pen(machine), cliprect ); + + video_update_common( machine, bitmap, &clip, 0 ); + + return 0; +} + +static int +NB1objcode2tile( int code ) +{ + int bank = nth_word32( namconb1_spritebank32, code>>11 ); + return (code&0x7ff) + bank*0x800; +} + +VIDEO_START( namconb1 ) +{ + namco_tilemap_init( NAMCONB1_TILEGFX, memory_region(NAMCONB1_TILEMASKREGION), NB1TilemapCB ); + namco_obj_init(NAMCONB1_SPRITEGFX,0x0,NB1objcode2tile); +} /* namconb1 */ + +/****************************************************************************************************/ + +VIDEO_UPDATE( namconb2 ) +{ + /* compute window for custom screen blanking */ + rectangle clip; + //004a016a 00210101 01440020 + UINT32 xclip = paletteram32[0x1800/4]; + UINT32 yclip = paletteram32[0x1804/4]; + clip.min_x = (xclip>>16) - 0x4b; + clip.max_x = (xclip&0xffff) - 0x4b - 1; + clip.min_y = (yclip>>16) - 0x21; + clip.max_y = (yclip&0xffff) - 0x21 - 1; + /* intersect with master clip rectangle */ + if( clip.min_x < cliprect->min_x ){ clip.min_x = cliprect->min_x; } + if( clip.min_y < cliprect->min_y ){ clip.min_y = cliprect->min_y; } + if( clip.max_x > cliprect->max_x ){ clip.max_x = cliprect->max_x; } + if( clip.max_y > cliprect->max_y ){ clip.max_y = cliprect->max_y; } + + fillbitmap( bitmap, get_black_pen(machine), cliprect ); + + if( memcmp(tilemap_tile_bank,namconb1_tilebank32,sizeof(tilemap_tile_bank))!=0 ) + { + namco_tilemap_invalidate(); + memcpy(tilemap_tile_bank,namconb1_tilebank32,sizeof(tilemap_tile_bank)); + } + video_update_common( machine, bitmap, &clip, 1 ); + return 0; +} + +static int +NB2objcode2tile( int code ) +{ + int bank = nth_byte32( namconb1_spritebank32, (code>>11)&0xf ); + code &= 0x7ff; + if( namcos2_gametype == NAMCONB2_MACH_BREAKERS ) + { + if( bank&0x01 ) code |= 0x01*0x800; + if( bank&0x02 ) code |= 0x02*0x800; + if( bank&0x04 ) code |= 0x04*0x800; + if( bank&0x08 ) code |= 0x08*0x800; + if( bank&0x10 ) code |= 0x10*0x800; + if( bank&0x40 ) code |= 0x20*0x800; + } + else + { + if( bank&0x01 ) code |= 0x01*0x800; + if( bank&0x02 ) code |= 0x04*0x800; + if( bank&0x04 ) code |= 0x02*0x800; + if( bank&0x08 ) code |= 0x08*0x800; + if( bank&0x10 ) code |= 0x10*0x800; + if( bank&0x40 ) code |= 0x20*0x800; + } + return code; +} /* NB2objcode2tile */ + +VIDEO_START( namconb2 ) +{ + namco_tilemap_init(NAMCONB1_TILEGFX, memory_region(NAMCONB1_TILEMASKREGION), NB2TilemapCB ); + namco_obj_init(NAMCONB1_SPRITEGFX,0x0,NB2objcode2tile); + namco_roz_init(NAMCONB1_ROTGFX,NAMCONB1_ROTMASKREGION); +} /* namconb2_vh_start */ |