1 // license:BSD-3-Clause
2 // copyright-holders:Acho A. Tang, Alex W. Jackson
3 /*****************************************************************************
4 
5 B-Wings  (c) 1984 Data East Corporation
6 Zaviga   (c) 1984 Data East Corporation
7 
8 drivers by Acho A. Tang
9 revised by Alex W. Jackson
10 
11 *****************************************************************************/
12 // Directives
13 
14 #include "emu.h"
15 #include "includes/bwing.h"
16 
17 
18 //****************************************************************************
19 // Exports
20 
21 
videoram_w(offs_t offset,uint8_t data)22 void bwing_state::videoram_w(offs_t offset, uint8_t data)
23 {
24 	m_videoram[offset] = data;
25 	m_charmap->mark_tile_dirty(offset);
26 }
27 
28 
fgscrollram_w(offs_t offset,uint8_t data)29 void bwing_state::fgscrollram_w(offs_t offset, uint8_t data)
30 {
31 	m_fgscrollram[offset] = data;
32 	m_fgmap->mark_tile_dirty(offset);
33 }
34 
35 
bgscrollram_w(offs_t offset,uint8_t data)36 void bwing_state::bgscrollram_w(offs_t offset, uint8_t data)
37 {
38 	m_bgscrollram[offset] = data;
39 	m_bgmap->mark_tile_dirty(offset);
40 }
41 
42 
gfxram_w(offs_t offset,uint8_t data)43 void bwing_state::gfxram_w(offs_t offset, uint8_t data)
44 {
45 	m_gfxram[offset] = data;
46 	int whichgfx = (offset & 0x1000) ? 3 : 2;
47 	m_gfxdecode->gfx(whichgfx)->mark_dirty((offset & 0xfff) / 32);
48 }
49 
50 
scrollreg_w(offs_t offset,uint8_t data)51 void bwing_state::scrollreg_w(offs_t offset, uint8_t data)
52 {
53 	m_sreg[offset] = data;
54 
55 	switch (offset)
56 	{
57 		case 6: m_palatch = data; break; // one of the palette components is latched through I/O(yike)
58 
59 		case 7:
60 			m_mapmask = data;
61 			m_vrambank->set_bank(data >> 6);
62 		break;
63 	}
64 }
65 
66 
paletteram_w(offs_t offset,uint8_t data)67 void bwing_state::paletteram_w(offs_t offset, uint8_t data)
68 {
69 	static const float rgb[4][3] = {
70 		{0.85f, 0.95f, 1.00f},
71 		{0.90f, 1.00f, 1.00f},
72 		{0.80f, 1.00f, 1.00f},
73 		{0.75f, 0.90f, 1.10f}
74 	};
75 	int r, g, b, i;
76 
77 	m_paletteram[offset] = data;
78 
79 	r = ~data & 7;
80 	g = ~(data >> 4) & 7;
81 	b = ~m_palatch & 7;
82 
83 	r = ((r << 5) + (r << 2) + (r >> 1));
84 	g = ((g << 5) + (g << 2) + (g >> 1));
85 	b = ((b << 5) + (b << 2) + (b >> 1));
86 
87 	if ((i = ioport("EXTRA")->read()) < 4)
88 	{
89 		r = (float)r * rgb[i][0];
90 		g = (float)g * rgb[i][1];
91 		b = (float)b * rgb[i][2];
92 		if (r > 0xff) r = 0xff;
93 		if (g > 0xff) g = 0xff;
94 		if (b > 0xff) b = 0xff;
95 	}
96 
97 	m_palette->set_pen_color(offset, rgb_t(r, g, b));
98 }
99 
100 //****************************************************************************
101 // Initializations
102 
TILE_GET_INFO_MEMBER(bwing_state::get_fgtileinfo)103 TILE_GET_INFO_MEMBER(bwing_state::get_fgtileinfo)
104 {
105 	tileinfo.set(2, m_fgscrollram[tile_index] & 0x7f, m_fgscrollram[tile_index] >> 7, 0);
106 }
107 
TILE_GET_INFO_MEMBER(bwing_state::get_bgtileinfo)108 TILE_GET_INFO_MEMBER(bwing_state::get_bgtileinfo)
109 {
110 	tileinfo.set(3, m_bgscrollram[tile_index] & 0x7f, m_bgscrollram[tile_index] >> 7, 0);
111 }
112 
TILE_GET_INFO_MEMBER(bwing_state::get_charinfo)113 TILE_GET_INFO_MEMBER(bwing_state::get_charinfo)
114 {
115 	tileinfo.set(0, m_videoram[tile_index], 0, 0);
116 }
117 
TILEMAP_MAPPER_MEMBER(bwing_state::scan_cols)118 TILEMAP_MAPPER_MEMBER(bwing_state::scan_cols)
119 {
120 	return (row & 0xf) | ((col & 0xf) << 4) | ((row & 0x30) << 4) | ((col & 0x30) << 6);
121 }
122 
123 
video_start()124 void bwing_state::video_start()
125 {
126 	int i;
127 
128 	m_charmap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(bwing_state::get_charinfo)), TILEMAP_SCAN_COLS, 8, 8, 32, 32);
129 	m_fgmap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(bwing_state::get_fgtileinfo)), tilemap_mapper_delegate(*this, FUNC(bwing_state::scan_cols)), 16, 16, 64, 64);
130 	m_bgmap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(bwing_state::get_bgtileinfo)), tilemap_mapper_delegate(*this, FUNC(bwing_state::scan_cols)), 16, 16, 64, 64);
131 
132 	m_charmap->set_transparent_pen(0);
133 	m_fgmap->set_transparent_pen(0);
134 
135 	for (i = 0; i < 8; i++)
136 		m_sreg[i] = 0;
137 }
138 
139 //****************************************************************************
140 // Realtime
141 
draw_sprites(bitmap_ind16 & bmp,const rectangle & clip,uint8_t * ram,int pri)142 void bwing_state::draw_sprites( bitmap_ind16 &bmp, const rectangle &clip, uint8_t *ram, int pri )
143 {
144 	int attrib, fx, fy, code, x, y, color, i;
145 	gfx_element *gfx = m_gfxdecode->gfx(1);
146 
147 	for (i = 0; i < 0x200; i += 4)
148 	{
149 		attrib = ram[i];
150 		code   = ram[i + 1];
151 		y      = ram[i + 2];
152 		x      = ram[i + 3];
153 		color  = (attrib >> 3) & 1;
154 
155 		if (!(attrib & 1) || color != pri)
156 			continue;
157 
158 		code += (attrib << 3) & 0x100;
159 		y -= (attrib << 1) & 0x100;
160 		x -= (attrib << 2) & 0x100;
161 
162 		fx = attrib & 0x04;
163 		fy = ~attrib & 0x02;
164 
165 		// normal/cocktail
166 		if (m_mapmask & 0x20)
167 		{
168 			fx = !fx;
169 			fy = !fy;
170 			x = 240 - x;
171 			y = 240 - y;
172 		}
173 
174 		// single/double
175 		if (!(attrib & 0x10))
176 				gfx->transpen(bmp,clip, code, color, fx, fy, x, y, 0);
177 		else
178 				gfx->zoom_transpen(bmp,clip, code, color, fx, fy, x, y, 1<<16, 2<<16, 0);
179 	}
180 }
181 
182 
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)183 uint32_t bwing_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
184 {
185 	unsigned flip, x, y, shiftx;
186 
187 	if (m_mapmask & 0x20)
188 	{
189 		flip = TILEMAP_FLIPX;
190 		shiftx = -8;
191 	}
192 	else
193 	{
194 		flip = TILEMAP_FLIPY;
195 		shiftx = 8;
196 	}
197 
198 	// draw background
199 	if (!(m_mapmask & 1))
200 	{
201 		m_bgmap->set_flip(flip);
202 		x = ((m_sreg[1]<<2 & 0x300) + m_sreg[2] + shiftx) & 0x3ff;
203 		m_bgmap->set_scrollx(0, x);
204 		y = (m_sreg[1]<<4 & 0x300) + m_sreg[3];
205 		m_bgmap->set_scrolly(0, y);
206 		m_bgmap->draw(screen, bitmap, cliprect, 0, 0);
207 	}
208 	else
209 		bitmap.fill(m_palette->black_pen(), cliprect);
210 
211 	// draw low priority sprites
212 	draw_sprites(bitmap, cliprect, m_spriteram, 0);
213 
214 	// draw foreground
215 	if (!(m_mapmask & 2))
216 	{
217 		m_fgmap->set_flip(flip);
218 		x = ((m_sreg[1] << 6 & 0x300) + m_sreg[4] + shiftx) & 0x3ff;
219 		m_fgmap->set_scrollx(0, x);
220 		y = (m_sreg[1] << 8 & 0x300) + m_sreg[5];
221 		m_fgmap->set_scrolly(0, y);
222 		m_fgmap->draw(screen, bitmap, cliprect, 0, 0);
223 	}
224 
225 	// draw high priority sprites
226 	draw_sprites(bitmap, cliprect, m_spriteram, 1);
227 
228 	// draw text layer
229 //  if (m_mapmask & 4)
230 	{
231 		m_charmap->set_flip(flip);
232 		m_charmap->draw(screen, bitmap, cliprect, 0, 0);
233 	}
234 	return 0;
235 }
236