1 // license:BSD-3-Clause
2 // copyright-holders:Paul Leaman
3 #include "emu.h"
4 #include "includes/blktiger.h"
5 
6 
7 #define BGRAM_BANK_SIZE 0x1000
8 #define BGRAM_BANKS 4
9 
10 
11 /***************************************************************************
12 
13   Callbacks for the TileMap code
14 
15 ***************************************************************************/
16 
TILEMAP_MAPPER_MEMBER(blktiger_state::bg8x4_scan)17 TILEMAP_MAPPER_MEMBER(blktiger_state::bg8x4_scan)
18 {
19 	/* logical (col,row) -> memory offset */
20 	return (col & 0x0f) + ((row & 0x0f) << 4) + ((col & 0x70) << 4) + ((row & 0x30) << 7);
21 }
22 
TILEMAP_MAPPER_MEMBER(blktiger_state::bg4x8_scan)23 TILEMAP_MAPPER_MEMBER(blktiger_state::bg4x8_scan)
24 {
25 	/* logical (col,row) -> memory offset */
26 	return (col & 0x0f) + ((row & 0x0f) << 4) + ((col & 0x30) << 4) + ((row & 0x70) << 6);
27 }
28 
TILE_GET_INFO_MEMBER(blktiger_state::get_bg_tile_info)29 TILE_GET_INFO_MEMBER(blktiger_state::get_bg_tile_info)
30 {
31 	/* the tile priority table is a guess compiled by looking at the game. It
32 	   was not derived from a PROM so it could be wrong. */
33 	static const uint8_t split_table[16] =
34 	{
35 		3,3,2,2,
36 		1,1,0,0,
37 		0,0,0,0,
38 		0,0,0,0
39 	};
40 	uint8_t attr = m_scroll_ram[2 * tile_index + 1];
41 	int color = (attr & 0x78) >> 3;
42 	tileinfo.set(1,
43 			m_scroll_ram[2 * tile_index] + ((attr & 0x07) << 8),
44 			color,
45 			(attr & 0x80) ? TILE_FLIPX : 0);
46 	tileinfo.group = split_table[color];
47 }
48 
TILE_GET_INFO_MEMBER(blktiger_state::get_tx_tile_info)49 TILE_GET_INFO_MEMBER(blktiger_state::get_tx_tile_info)
50 {
51 	uint8_t attr = m_txvideoram[tile_index + 0x400];
52 	tileinfo.set(0,
53 			m_txvideoram[tile_index] + ((attr & 0xe0) << 3),
54 			attr & 0x1f,
55 			0);
56 }
57 
58 
59 /***************************************************************************
60 
61   Start the video hardware emulation.
62 
63 ***************************************************************************/
64 
video_start()65 void blktiger_state::video_start()
66 {
67 	m_chon = 1;
68 	m_bgon = 1;
69 	m_objon = 1;
70 	m_screen_layout = 0;
71 
72 	m_scroll_ram = std::make_unique<uint8_t[]>(BGRAM_BANK_SIZE * BGRAM_BANKS);
73 
74 	m_tx_tilemap =    &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(blktiger_state::get_tx_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
75 	m_bg_tilemap8x4 = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(blktiger_state::get_bg_tile_info)), tilemap_mapper_delegate(*this, FUNC(blktiger_state::bg8x4_scan)), 16, 16, 128, 64);
76 	m_bg_tilemap4x8 = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(blktiger_state::get_bg_tile_info)), tilemap_mapper_delegate(*this, FUNC(blktiger_state::bg4x8_scan)), 16, 16, 64, 128);
77 
78 	m_tx_tilemap->set_transparent_pen(3);
79 
80 	m_bg_tilemap8x4->set_transmask(0, 0xffff, 0x8000);  /* split type 0 is totally transparent in front half */
81 	m_bg_tilemap8x4->set_transmask(1, 0xfff0, 0x800f);  /* split type 1 has pens 4-15 transparent in front half */
82 	m_bg_tilemap8x4->set_transmask(2, 0xff00, 0x80ff);  /* split type 1 has pens 8-15 transparent in front half */
83 	m_bg_tilemap8x4->set_transmask(3, 0xf000, 0x8fff);  /* split type 1 has pens 12-15 transparent in front half */
84 	m_bg_tilemap4x8->set_transmask(0, 0xffff, 0x8000);
85 	m_bg_tilemap4x8->set_transmask(1, 0xfff0, 0x800f);
86 	m_bg_tilemap4x8->set_transmask(2, 0xff00, 0x80ff);
87 	m_bg_tilemap4x8->set_transmask(3, 0xf000, 0x8fff);
88 
89 	save_pointer(NAME(m_scroll_ram), BGRAM_BANK_SIZE * BGRAM_BANKS);
90 }
91 
92 
93 
94 /***************************************************************************
95 
96   Memory handlers
97 
98 ***************************************************************************/
99 
blktiger_txvideoram_w(offs_t offset,uint8_t data)100 void blktiger_state::blktiger_txvideoram_w(offs_t offset, uint8_t data)
101 {
102 	m_txvideoram[offset] = data;
103 	m_tx_tilemap->mark_tile_dirty(offset & 0x3ff);
104 }
105 
blktiger_bgvideoram_r(offs_t offset)106 uint8_t blktiger_state::blktiger_bgvideoram_r(offs_t offset)
107 {
108 	return m_scroll_ram[offset + m_scroll_bank];
109 }
110 
blktiger_bgvideoram_w(offs_t offset,uint8_t data)111 void blktiger_state::blktiger_bgvideoram_w(offs_t offset, uint8_t data)
112 {
113 	offset += m_scroll_bank;
114 
115 	m_scroll_ram[offset] = data;
116 	m_bg_tilemap8x4->mark_tile_dirty(offset / 2);
117 	m_bg_tilemap4x8->mark_tile_dirty(offset / 2);
118 }
119 
blktiger_bgvideoram_bank_w(uint8_t data)120 void blktiger_state::blktiger_bgvideoram_bank_w(uint8_t data)
121 {
122 	m_scroll_bank = (data % BGRAM_BANKS) * BGRAM_BANK_SIZE;
123 }
124 
125 
blktiger_scrolly_w(offs_t offset,uint8_t data)126 void blktiger_state::blktiger_scrolly_w(offs_t offset, uint8_t data)
127 {
128 	m_scroll_y[offset] = data;
129 	int scrolly = m_scroll_y[0] | (m_scroll_y[1] << 8);
130 	m_bg_tilemap8x4->set_scrolly(0, scrolly);
131 	m_bg_tilemap4x8->set_scrolly(0, scrolly);
132 }
133 
blktiger_scrollx_w(offs_t offset,uint8_t data)134 void blktiger_state::blktiger_scrollx_w(offs_t offset, uint8_t data)
135 {
136 	m_scroll_x[offset] = data;
137 	int scrollx = m_scroll_x[0] | (m_scroll_x[1] << 8);
138 	m_bg_tilemap8x4->set_scrollx(0, scrollx);
139 	m_bg_tilemap4x8->set_scrollx(0, scrollx);
140 }
141 
142 
blktiger_video_control_w(uint8_t data)143 void blktiger_state::blktiger_video_control_w(uint8_t data)
144 {
145 	/* bits 0 and 1 are coin counters */
146 	machine().bookkeeping().coin_counter_w(0,data & 1);
147 	machine().bookkeeping().coin_counter_w(1,data & 2);
148 
149 	/* bit 5 resets the sound CPU */
150 	m_audiocpu->set_input_line(INPUT_LINE_RESET, (data & 0x20) ? ASSERT_LINE : CLEAR_LINE);
151 
152 	/* bit 6 flips screen */
153 	flip_screen_set(data & 0x40);
154 
155 	/* bit 7 enables characters? Just a guess */
156 	m_chon = ~data & 0x80;
157 }
158 
blktiger_video_enable_w(uint8_t data)159 void blktiger_state::blktiger_video_enable_w(uint8_t data)
160 {
161 	/* not sure which is which, but I think that bit 1 and 2 enable background and sprites */
162 	/* bit 1 enables bg ? */
163 	m_bgon = ~data & 0x02;
164 
165 	/* bit 2 enables sprites ? */
166 	m_objon = ~data & 0x04;
167 }
168 
blktiger_screen_layout_w(uint8_t data)169 void blktiger_state::blktiger_screen_layout_w(uint8_t data)
170 {
171 	m_screen_layout = data;
172 	m_bg_tilemap8x4->enable(m_screen_layout);
173 	m_bg_tilemap4x8->enable(!m_screen_layout);
174 }
175 
176 
177 
178 /***************************************************************************
179 
180   Display refresh
181 
182 ***************************************************************************/
183 
draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect)184 void blktiger_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect )
185 {
186 	uint8_t *buffered_spriteram = m_spriteram->buffer();
187 	int offs;
188 
189 	/* Draw the sprites. */
190 	for (offs = m_spriteram->bytes() - 4;offs >= 0;offs -= 4)
191 	{
192 		int attr = buffered_spriteram[offs+1];
193 		int sx = buffered_spriteram[offs + 3] - ((attr & 0x10) << 4);
194 		int sy = buffered_spriteram[offs + 2];
195 		int code = buffered_spriteram[offs] | ((attr & 0xe0) << 3);
196 		int color = attr & 0x07;
197 		int flipx = attr & 0x08;
198 
199 		if (flip_screen())
200 		{
201 			sx = 240 - sx;
202 			sy = 240 - sy;
203 			flipx = !flipx;
204 		}
205 
206 		m_gfxdecode->gfx(2)->transpen(bitmap,cliprect,
207 				code,
208 				color,
209 				flipx,flip_screen(),
210 				sx,sy,15);
211 	}
212 }
213 
screen_update_blktiger(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)214 uint32_t blktiger_state::screen_update_blktiger(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
215 {
216 	bitmap.fill(1023, cliprect);
217 
218 	if (m_bgon)
219 		(m_screen_layout ? m_bg_tilemap8x4 : m_bg_tilemap4x8)->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1, 0);
220 
221 	if (m_objon)
222 		draw_sprites(bitmap, cliprect);
223 
224 	if (m_bgon)
225 		(m_screen_layout ? m_bg_tilemap8x4 : m_bg_tilemap4x8)->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0, 0);
226 
227 	if (m_chon)
228 		m_tx_tilemap->draw(screen, bitmap, cliprect, 0, 0);
229 
230 	return 0;
231 }
232