1 // license:BSD-3-Clause
2 // copyright-holders:David Haywood, Nicola Salmoria, Tomasz Slanina
3 #include "emu.h"
4 #include "includes/darkmist.h"
5
6
7
8 /* vis. flags */
9
10 #define DISPLAY_SPR 1
11 #define DISPLAY_FG 2 /* 2 or 8 */
12 #define DISPLAY_BG 4
13 #define DISPLAY_TXT 16
14
15
TILE_GET_INFO_MEMBER(darkmist_state::get_bgtile_info)16 TILE_GET_INFO_MEMBER(darkmist_state::get_bgtile_info)
17 {
18 int code,attr,pal;
19
20 code=memregion("bg_map")->base()[tile_index*2]; /* TTTTTTTT */
21 attr=memregion("bg_map")->base()[(tile_index*2)+1]; /* -PPP--TT - FIXED BITS (0xxx00xx) */
22
23 code+=(attr&3)<<8;
24 pal=(attr>>4) & 0xf;
25
26 tileinfo.set(1,
27 code,
28 pal,
29 0);
30 }
31
TILE_GET_INFO_MEMBER(darkmist_state::get_fgtile_info)32 TILE_GET_INFO_MEMBER(darkmist_state::get_fgtile_info)
33 {
34 int code,attr,pal;
35
36 code = memregion("fg_map")->base()[tile_index*2]; /* TTTTTTTT */
37 attr = memregion("fg_map")->base()[(tile_index*2)+1]; /* -PPP--TT - FIXED BITS (0xxx00xx) */
38
39 code+=(attr&3)<<8;
40 pal=(attr>>4) & 0xf;
41
42 tileinfo.set(2,
43 code,
44 pal,
45 0);
46 }
47
TILE_GET_INFO_MEMBER(darkmist_state::get_txttile_info)48 TILE_GET_INFO_MEMBER(darkmist_state::get_txttile_info)
49 {
50 int code,attr,pal;
51
52 code=m_videoram[tile_index];
53 attr=m_videoram[tile_index+0x400];
54 pal=(attr>>1);
55
56 code+=(attr&1)<<8;
57
58 tileinfo.set(0,
59 code,
60 pal & 0xf,
61 0);
62 }
63
darkmist_palette(palette_device & palette) const64 void darkmist_state::darkmist_palette(palette_device &palette) const
65 {
66 //palette.set_indirect_color(0x100, rgb_t::black());
67
68 std::pair<uint8_t const *, uint8_t> const planes[4]{
69 { &m_bg_clut[0], 0x80 },
70 { &m_fg_clut[0], 0x00 },
71 { &m_spr_clut[0], 0x40 },
72 { &m_tx_clut[0], 0xc0 } };
73
74 for (unsigned plane = 0; ARRAY_LENGTH(planes) > plane; ++plane)
75 {
76 for (unsigned i = 0; 0x100 > i; ++i)
77 {
78 uint8_t const clut = planes[plane].first[i];
79 // if (clut & 0x40) // 0x40 indicates transparent pen
80 // ctabentry = 0x100;
81 // else
82 int const ctabentry = (clut & 0x3f) | planes[plane].second;
83 palette.set_pen_indirect((plane << 8) | i, ctabentry);
84 }
85 }
86 }
87
88
video_start()89 void darkmist_state::video_start()
90 {
91 m_bgtilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(darkmist_state::get_bgtile_info)), TILEMAP_SCAN_ROWS, 16, 16, 512, 64);
92 m_fgtilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(darkmist_state::get_fgtile_info)), TILEMAP_SCAN_ROWS, 16, 16, 64, 256);
93 m_txtilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(darkmist_state::get_txttile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
94 // m_fgtilemap->set_transparent_pen(0);
95 // m_txtilemap->set_transparent_pen(0);
96
97 save_item(NAME(m_hw));
98 m_screen->register_screen_bitmap(m_temp_bitmap);
99 }
100
101 // TODO: move this code into framework or substitute with a valid alternative
mix_layer(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect,uint8_t * clut)102 void darkmist_state::mix_layer(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, uint8_t* clut)
103 {
104 for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
105 {
106 uint16_t *const dest = &bitmap.pix(y);
107 uint16_t const *const src = &m_temp_bitmap.pix(y);
108 for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
109 {
110 uint16_t const pix = (src[x] & 0xff);
111 uint16_t const real = clut[pix];
112
113 if (!(real & 0x40))
114 dest[x] = src[x];
115 }
116 }
117 }
118
119 /*
120 Sprites
121
122 76543210
123 0 - TTTT TTTT - tile
124 1 - xyBP PPP? - palette (P), flips (x,y), B - use spritebank,
125 ? - unknown, according to gamecode top bit of one of coords(y/x)
126 2 - YYYY YYYY - y coord
127 3 - XXXX XXXX - x coord
128
129 */
draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect)130 void darkmist_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
131 {
132 int i,fx,fy,tile,palette;
133 // fetch from top to bottom
134 for(i=m_spriteram.bytes()-32;i>=0;i-=32)
135 {
136 fy=m_spriteram[i+1]&0x40;
137 fx=m_spriteram[i+1]&0x80;
138
139 tile=m_spriteram[i+0];
140
141 if(m_spriteram[i+1]&0x20)
142 tile += (*m_spritebank << 8);
143
144 palette=((m_spriteram[i+1])>>1)&0xf;
145
146 if(m_spriteram[i+1]&0x1)
147 palette=machine().rand()&15;
148
149 m_gfxdecode->gfx(3)->transpen(
150 bitmap,cliprect,
151 tile,
152 palette,
153 fx,fy,
154 m_spriteram[i+3],m_spriteram[i+2],0 );
155 }
156 }
157
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)158 uint32_t darkmist_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
159 {
160 #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))
161
162 m_bgtilemap->set_scrollx(0, DM_GETSCROLL(0x2));
163 m_bgtilemap->set_scrolly(0, DM_GETSCROLL(0x6));
164 m_fgtilemap->set_scrollx(0, DM_GETSCROLL(0xa));
165 m_fgtilemap->set_scrolly(0, DM_GETSCROLL(0xe));
166
167 m_temp_bitmap.fill(0,cliprect);
168 bitmap.fill(m_palette->black_pen(), cliprect);
169
170 if(m_hw & DISPLAY_BG)
171 {
172 m_bgtilemap->draw(screen, m_temp_bitmap, cliprect, 0,0);
173 mix_layer(screen, bitmap, cliprect, m_bg_clut);
174 }
175
176 if(m_hw & DISPLAY_FG)
177 {
178 m_fgtilemap->draw(screen, m_temp_bitmap, cliprect, 0,0);
179 mix_layer(screen, bitmap, cliprect, m_fg_clut);
180 }
181
182 if(m_hw & DISPLAY_SPR)
183 {
184 draw_sprites(m_temp_bitmap,cliprect);
185 mix_layer(screen, bitmap, cliprect, m_spr_clut);
186 }
187
188 if(m_hw & DISPLAY_TXT)
189 {
190 m_txtilemap->draw(screen, m_temp_bitmap, cliprect, 0,0);
191 mix_layer(screen, bitmap, cliprect, m_tx_clut);
192 }
193
194 return 0;
195 }
196
tx_vram_w(offs_t offset,uint8_t data)197 void darkmist_state::tx_vram_w(offs_t offset, uint8_t data)
198 {
199 m_videoram[offset] = data;
200 m_txtilemap->mark_tile_dirty(offset & 0x3ff);
201 }
202