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