// license:BSD-3-Clause // copyright-holders:David Haywood, Nicola Salmoria, Tomasz Slanina #include "emu.h" #include "includes/darkmist.h" /* vis. flags */ #define DISPLAY_SPR 1 #define DISPLAY_FG 2 /* 2 or 8 */ #define DISPLAY_BG 4 #define DISPLAY_TXT 16 TILE_GET_INFO_MEMBER(darkmist_state::get_bgtile_info) { int code,attr,pal; code=memregion("bg_map")->base()[tile_index*2]; /* TTTTTTTT */ attr=memregion("bg_map")->base()[(tile_index*2)+1]; /* -PPP--TT - FIXED BITS (0xxx00xx) */ code+=(attr&3)<<8; pal=(attr>>4) & 0xf; SET_TILE_INFO_MEMBER(1, code, pal, 0); } TILE_GET_INFO_MEMBER(darkmist_state::get_fgtile_info) { int code,attr,pal; code = memregion("fg_map")->base()[tile_index*2]; /* TTTTTTTT */ attr = memregion("fg_map")->base()[(tile_index*2)+1]; /* -PPP--TT - FIXED BITS (0xxx00xx) */ code+=(attr&3)<<8; pal=(attr>>4) & 0xf; SET_TILE_INFO_MEMBER(2, code, pal, 0); } TILE_GET_INFO_MEMBER(darkmist_state::get_txttile_info) { int code,attr,pal; code=m_videoram[tile_index]; attr=m_videoram[tile_index+0x400]; pal=(attr>>1); code+=(attr&1)<<8; SET_TILE_INFO_MEMBER(0, code, pal & 0xf, 0); } PALETTE_INIT_MEMBER(darkmist_state, darkmist) { // palette.set_indirect_color(0x100, rgb_t::black()); for (int i = 0; i < 0x400; i++) { int ctabentry; uint8_t clut = 0; switch (i & 0x300) { case 0x000: clut = m_bg_clut[i&0xff]; break; case 0x100: clut = m_fg_clut[i&0xff]; break; case 0x200: clut = m_spr_clut[i&0xff]; break; case 0x300: clut = m_tx_clut[i&0xff]; break; } // if (clut & 0x40) // 0x40 indicates transparent pen // ctabentry = 0x100; // else { ctabentry = (clut & 0x3f); switch (i & 0x300) { case 0x000: ctabentry = ctabentry | 0x80; break; case 0x100: ctabentry = ctabentry | 0x00; break; case 0x200: ctabentry = ctabentry | 0x40; break; case 0x300: ctabentry = ctabentry | 0xc0; break; } } palette.set_pen_indirect(i, ctabentry); } } void darkmist_state::video_start() { m_bgtilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(darkmist_state::get_bgtile_info),this),TILEMAP_SCAN_ROWS,16,16,512,64 ); m_fgtilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(darkmist_state::get_fgtile_info),this),TILEMAP_SCAN_ROWS,16,16,64,256 ); m_txtilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(darkmist_state::get_txttile_info),this),TILEMAP_SCAN_ROWS,8,8,32,32 ); // m_fgtilemap->set_transparent_pen(0); // m_txtilemap->set_transparent_pen(0); save_item(NAME(m_hw)); m_screen->register_screen_bitmap(m_temp_bitmap); } // TODO: move this code into framework or substitute with a valid alternative void darkmist_state::mix_layer(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, uint8_t* clut) { for (int y = cliprect.min_y; y <= cliprect.max_y; y++) { uint16_t *dest = &bitmap.pix16(y); uint16_t *src = &m_temp_bitmap.pix16(y); for (int x = cliprect.min_x; x <= cliprect.max_x; x++) { uint16_t pix = (src[x] & 0xff); uint16_t real = clut[pix]; if (!(real & 0x40)) dest[x] = src[x]; } } } /* Sprites 76543210 0 - TTTT TTTT - tile 1 - xyBP PPP? - palette (P), flips (x,y), B - use spritebank, ? - unknown, according to gamecode top bit of one of coords(y/x) 2 - YYYY YYYY - y coord 3 - XXXX XXXX - x coord */ void darkmist_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect) { int i,fx,fy,tile,palette; // fetch from top to bottom for(i=m_spriteram.bytes()-32;i>=0;i-=32) { fy=m_spriteram[i+1]&0x40; fx=m_spriteram[i+1]&0x80; tile=m_spriteram[i+0]; if(m_spriteram[i+1]&0x20) tile += (*m_spritebank << 8); palette=((m_spriteram[i+1])>>1)&0xf; if(m_spriteram[i+1]&0x1) palette=machine().rand()&15; m_gfxdecode->gfx(3)->transpen( bitmap,cliprect, tile, palette, fx,fy, m_spriteram[i+3],m_spriteram[i+2],0 ); } } uint32_t darkmist_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { #define DM_GETSCROLL(n) (((m_scroll[(n)]<<1)&0xff) + ((m_scroll[(n)]&0x80)?1:0) +( ((m_scroll[(n)-1]<<4) | (m_scroll[(n)-1]<<12) )&0xff00)) m_bgtilemap->set_scrollx(0, DM_GETSCROLL(0x2)); m_bgtilemap->set_scrolly(0, DM_GETSCROLL(0x6)); m_fgtilemap->set_scrollx(0, DM_GETSCROLL(0xa)); m_fgtilemap->set_scrolly(0, DM_GETSCROLL(0xe)); m_temp_bitmap.fill(0,cliprect); bitmap.fill(m_palette->black_pen(), cliprect); if(m_hw & DISPLAY_BG) { m_bgtilemap->draw(screen, m_temp_bitmap, cliprect, 0,0); mix_layer(screen, bitmap, cliprect, m_bg_clut); } if(m_hw & DISPLAY_FG) { m_fgtilemap->draw(screen, m_temp_bitmap, cliprect, 0,0); mix_layer(screen, bitmap, cliprect, m_fg_clut); } if(m_hw & DISPLAY_SPR) { draw_sprites(m_temp_bitmap,cliprect); mix_layer(screen, bitmap, cliprect, m_spr_clut); } if(m_hw & DISPLAY_TXT) { m_txtilemap->draw(screen, m_temp_bitmap, cliprect, 0,0); mix_layer(screen, bitmap, cliprect, m_tx_clut); } return 0; } WRITE8_MEMBER(darkmist_state::tx_vram_w) { m_videoram[offset] = data; m_txtilemap->mark_tile_dirty(offset & 0x3ff); }