1 // license:BSD-3-Clause
2 // copyright-holders:Bryan McPhail
3 /***************************************************************************
4
5 video.c
6
7 Functions to emulate the video hardware of the machine.
8
9 ***************************************************************************/
10
11 #include "emu.h"
12 #include "includes/lastduel.h"
13
14
15 /***************************************************************************
16
17 Callbacks for the TileMap code
18
19 ***************************************************************************/
20
TILE_GET_INFO_MEMBER(lastduel_state::ld_get_bg_tile_info)21 TILE_GET_INFO_MEMBER(lastduel_state::ld_get_bg_tile_info)
22 {
23 int const tile = m_vram[1][2 * tile_index] & 0x1fff;
24 int const color = m_vram[1][2 * tile_index + 1];
25 tileinfo.set(2,
26 tile,color & 0xf,
27 TILE_FLIPYX((color & 0x60) >> 5));
28 }
29
TILE_GET_INFO_MEMBER(lastduel_state::ld_get_fg_tile_info)30 TILE_GET_INFO_MEMBER(lastduel_state::ld_get_fg_tile_info)
31 {
32 int const tile = m_vram[0][2 * tile_index] & 0x1fff;
33 int const color = m_vram[0][2 * tile_index + 1];
34 tileinfo.set(3,
35 tile,
36 color & 0xf,
37 TILE_FLIPYX((color & 0x60) >> 5));
38 tileinfo.group = (color & 0x80) >> 7;
39 }
40
TILE_GET_INFO_MEMBER(lastduel_state::get_bg_tile_info)41 TILE_GET_INFO_MEMBER(lastduel_state::get_bg_tile_info)
42 {
43 int const tile = m_vram[1][tile_index] & 0x1fff;
44 int const color = m_vram[1][tile_index + 0x0800];
45 tileinfo.set(2,
46 tile,
47 color & 0xf,
48 TILE_FLIPYX((color & 0x60) >> 5));
49 }
50
TILE_GET_INFO_MEMBER(lastduel_state::get_fg_tile_info)51 TILE_GET_INFO_MEMBER(lastduel_state::get_fg_tile_info)
52 {
53 int const tile = m_vram[0][tile_index] & 0x1fff;
54 int const color = m_vram[0][tile_index + 0x0800];
55 tileinfo.set(3,
56 tile,
57 color & 0xf,
58 TILE_FLIPYX((color & 0x60) >> 5));
59 tileinfo.group = (color & 0x10) >> 4;
60 }
61
TILE_GET_INFO_MEMBER(lastduel_state::get_fix_info)62 TILE_GET_INFO_MEMBER(lastduel_state::get_fix_info)
63 {
64 int const tile = m_txram[tile_index];
65 tileinfo.set(1,
66 tile & 0x7ff,
67 tile>>12,
68 (tile & 0x800) ? TILE_FLIPY : 0);
69 }
70
71
72
73 /***************************************************************************
74
75 Start the video hardware emulation.
76
77 ***************************************************************************/
78
VIDEO_START_MEMBER(lastduel_state,lastduel)79 VIDEO_START_MEMBER(lastduel_state,lastduel)
80 {
81 m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lastduel_state::ld_get_bg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 64, 64);
82 m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lastduel_state::ld_get_fg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 64, 64);
83 m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lastduel_state::get_fix_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
84
85 m_tilemap[0]->set_transmask(0, 0xffff, 0x0001);
86 m_tilemap[0]->set_transmask(1, 0xf07f, 0x0f81);
87 m_tx_tilemap->set_transparent_pen(3);
88
89 m_sprite_flipy_mask = 0x40;
90 m_sprite_pri_mask = 0x00;
91 m_tilemap_priority = 0;
92 }
93
VIDEO_START_MEMBER(lastduel_state,madgear)94 VIDEO_START_MEMBER(lastduel_state,madgear)
95 {
96 m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lastduel_state::get_bg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 64, 32);
97 m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lastduel_state::get_fg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 64, 32);
98 m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lastduel_state::get_fix_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
99
100 m_tilemap[0]->set_transmask(0, 0xffff, 0x8000);
101 m_tilemap[0]->set_transmask(1, 0x80ff, 0xff00);
102 m_tx_tilemap->set_transparent_pen(3);
103 m_tilemap[1]->set_transparent_pen(15);
104
105 m_sprite_flipy_mask = 0x80;
106 m_sprite_pri_mask = 0x10;
107 }
108
109
110
111 /***************************************************************************
112
113 Memory handlers
114
115 ***************************************************************************/
116
flip_w(uint8_t data)117 void lastduel_state::flip_w(uint8_t data)
118 {
119 flip_screen_set(data & 0x01);
120
121 machine().bookkeeping().coin_lockout_w(0, ~data & 0x10);
122 machine().bookkeeping().coin_lockout_w(1, ~data & 0x20);
123 machine().bookkeeping().coin_counter_w(0, data & 0x40);
124 machine().bookkeeping().coin_counter_w(1, data & 0x80);
125 }
126
vctrl_w(offs_t offset,uint16_t data,uint16_t mem_mask)127 void lastduel_state::vctrl_w(offs_t offset, uint16_t data, uint16_t mem_mask)
128 {
129 data = COMBINE_DATA(&m_vctrl[offset]);
130 switch (offset)
131 {
132 case 0: m_tilemap[0]->set_scrolly(0, data); break;
133 case 1: m_tilemap[0]->set_scrollx(0, data); break;
134 case 2: m_tilemap[1]->set_scrolly(0, data); break;
135 case 3: m_tilemap[1]->set_scrollx(0, data); break;
136 case 7: m_tilemap_priority = data; break;
137 default:
138 logerror("Unmapped video write %d %04x\n", offset, data);
139 break;
140 }
141 }
142
txram_w(offs_t offset,uint16_t data,uint16_t mem_mask)143 void lastduel_state::txram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
144 {
145 COMBINE_DATA(&m_txram[offset]);
146 m_tx_tilemap->mark_tile_dirty(offset);
147 }
148
lastduel_RRRRGGGGBBBBIIII(uint32_t raw)149 rgb_t lastduel_state::lastduel_RRRRGGGGBBBBIIII(uint32_t raw)
150 {
151 // Brightness parameter interpreted same way as CPS1
152 int const bright = 0x10 + (raw & 0x0f);
153
154 int const red = ((raw >> 12) & 0x0f) * bright * 0x11 / 0x1f;
155 int const green = ((raw >> 8) & 0x0f) * bright * 0x11 / 0x1f;
156 int const blue = ((raw >> 4) & 0x0f) * bright * 0x11 / 0x1f;
157
158 return rgb_t(red, green, blue);
159 }
160
161 /***************************************************************************
162
163 Display refresh
164
165 ***************************************************************************/
166
draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect,int pri)167 void lastduel_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect, int pri )
168 {
169 const uint16_t *buffered_spriteram16 = m_spriteram->buffer();
170 int offs;
171
172 if (!m_sprite_pri_mask)
173 if (pri == 1)
174 return; /* only low priority sprites in lastduel */
175
176 for (offs = 0x400 - 4; offs >= 0; offs -= 4)
177 {
178 int attr, sy, sx, flipx, flipy, code, color;
179
180 attr = buffered_spriteram16[offs + 1];
181 if (m_sprite_pri_mask) /* only madgear seems to have this */
182 {
183 if (pri == 1 && (attr & m_sprite_pri_mask))
184 continue;
185 if (pri == 0 && !(attr & m_sprite_pri_mask))
186 continue;
187 }
188
189 code = buffered_spriteram16[offs];
190 sx = buffered_spriteram16[offs + 3] & 0x1ff;
191 sy = buffered_spriteram16[offs + 2] & 0x1ff;
192 if (sy > 0x100)
193 sy -= 0x200;
194
195 flipx = attr & 0x20;
196 flipy = attr & m_sprite_flipy_mask; /* 0x40 for lastduel, 0x80 for madgear */
197 color = attr & 0x0f;
198
199 if (flip_screen())
200 {
201 sx = 496 - sx;
202 sy = 240 - sy;
203 flipx = !flipx;
204 flipy = !flipy;
205 }
206
207 m_gfxdecode->gfx(0)->transpen(bitmap,cliprect,
208 code,
209 color,
210 flipx,flipy,
211 sx,sy,15);
212 }
213 }
214
screen_update_lastduel(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)215 uint32_t lastduel_state::screen_update_lastduel(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
216 {
217 m_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
218 m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1, 0);
219 draw_sprites(bitmap, cliprect, 0);
220 m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0, 0);
221 draw_sprites(bitmap, cliprect, 1);
222 m_tx_tilemap->draw(screen, bitmap, cliprect, 0, 0);
223 return 0;
224 }
225
screen_update_madgear(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)226 uint32_t lastduel_state::screen_update_madgear(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
227 {
228 if (m_tilemap_priority)
229 {
230 m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | TILEMAP_DRAW_OPAQUE, 0);
231 draw_sprites(bitmap, cliprect, 0);
232 m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0, 0);
233 m_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
234 draw_sprites(bitmap, cliprect, 1);
235 }
236 else
237 {
238 m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
239 m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1, 0);
240 draw_sprites(bitmap, cliprect, 0);
241 m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0, 0);
242 draw_sprites(bitmap, cliprect, 1);
243 }
244 m_tx_tilemap->draw(screen, bitmap, cliprect, 0, 0);
245 return 0;
246 }
247