1 // license:BSD-3-Clause
2 // copyright-holders:Nicola Salmoria
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 "video/resnet.h"
13 #include "includes/zaccaria.h"
14
15
16 /***************************************************************************
17
18 Convert the color PROMs into a more useable format.
19
20
21 Here's the hookup from the proms (82s131) to the r-g-b-outputs
22
23 Prom 9F 74LS374
24 ----------- ____________
25 12 | 3 2 |---680 ohm----| blue out
26 11 | 4 5 |---1k ohm-----| (+ 470 ohm pulldown)
27 10 | 7 6 |---820 ohm-------|
28 9 | 8 9 |---1k ohm--------| green out
29 Prom 9G | | | (+ 390 ohm pulldown)
30 12 | 13 12 |---1.2k ohm------|
31 11 | 14 15 |---820 ohm----------|
32 10 | 17 16 |---1k ohm-----------| red out
33 9 | 18 19 |---1.2k ohm---------| (+ 390 ohm pulldown)
34 |__________|
35
36
37 ***************************************************************************/
zaccaria_palette(palette_device & palette) const38 void zaccaria_state::zaccaria_palette(palette_device &palette) const
39 {
40 uint8_t const *const color_prom = memregion("proms")->base();
41 static constexpr int resistances_rg[] = { 1200, 1000, 820 };
42 static constexpr int resistances_b[] = { 1000, 820 };
43
44 double weights_rg[3], weights_b[2];
45 compute_resistor_weights(0, 0xff, -1.0,
46 3, resistances_rg, weights_rg, 390, 0,
47 2, resistances_b, weights_b, 470, 0,
48 0, nullptr, nullptr, 0, 0);
49
50 for (int i = 0; i < 0x200; i++)
51 {
52 /*
53 TODO: I'm not sure, but I think that pen 0 must always be black, otherwise
54 there's some junk brown background in Jack Rabbit.
55 From the schematics it seems that the background color can be changed, but
56 I'm not sure where it would be taken from; I think the high bits of
57 attributesram, but they are always 0 in these games so they would turn out
58 black anyway.
59 */
60 if (!(i & 0x038))
61 palette.set_indirect_color(i, rgb_t::black());
62 else
63 {
64 int bit0, bit1, bit2;
65
66 // red component
67 bit0 = BIT(color_prom[i + 0x000], 3);
68 bit1 = BIT(color_prom[i + 0x000], 2);
69 bit2 = BIT(color_prom[i + 0x000], 1);
70 int const r = combine_weights(weights_rg, bit0, bit1, bit2);
71
72 // green component
73 bit0 = BIT(color_prom[i + 0x000], 0);
74 bit1 = BIT(color_prom[i + 0x200], 3);
75 bit2 = BIT(color_prom[i + 0x200], 2);
76 int const g = combine_weights(weights_rg, bit0, bit1, bit2);
77
78 // blue component
79 bit0 = BIT(color_prom[i + 0x200], 1);
80 bit1 = BIT(color_prom[i + 0x200], 0);
81 int const b = combine_weights(weights_b, bit0, bit1);
82
83 palette.set_indirect_color(i, rgb_t(r, g, b));
84 }
85 }
86
87 /* There are 512 unique colors, which seem to be organized in 8 blocks */
88 /* of 64. In each block, colors are not in the usual sequential order */
89 /* but in interleaved order, like Phoenix. Additionally, colors for */
90 /* background and sprites are interleaved. */
91 for (int i = 0; i < 8; i++)
92 for (int j = 0; j < 4; j++)
93 for (int k = 0; k < 8; k++)
94 // swap j and k to make the colors sequential
95 palette.set_pen_indirect(0 + 32 * i + 8 * j + k, 64 * i + 8 * k + 2 * j);
96
97 for (int i = 0; i < 8; i++)
98 for (int j = 0; j < 4; j++)
99 for (int k = 0; k < 8; k++)
100 // swap j and k to make the colors sequential
101 palette.set_pen_indirect(256 + 32 * i + 8 * j + k, 64 * i + 8 * k + 2 * j + 1);
102 }
103
104
105
106 /***************************************************************************
107
108 Callbacks for the TileMap code
109
110 ***************************************************************************/
111
TILE_GET_INFO_MEMBER(zaccaria_state::get_tile_info)112 TILE_GET_INFO_MEMBER(zaccaria_state::get_tile_info)
113 {
114 uint8_t attr = m_videoram[tile_index + 0x400];
115 tileinfo.set(0,
116 m_videoram[tile_index] + ((attr & 0x03) << 8),
117 ((attr & 0x0c) >> 2) + ((m_attributesram[2 * (tile_index % 32) + 1] & 0x07) << 2),
118 0);
119 }
120
121
122
123 /***************************************************************************
124
125 Start the video hardware emulation.
126
127 ***************************************************************************/
128
video_start()129 void zaccaria_state::video_start()
130 {
131 m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(zaccaria_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
132
133 m_bg_tilemap->set_scroll_cols(32);
134 }
135
136
137
138 /***************************************************************************
139
140 Memory handlers
141
142 ***************************************************************************/
143
videoram_w(offs_t offset,uint8_t data)144 void zaccaria_state::videoram_w(offs_t offset, uint8_t data)
145 {
146 m_videoram[offset] = data;
147 m_bg_tilemap->mark_tile_dirty(offset & 0x3ff);
148 }
149
attributes_w(offs_t offset,uint8_t data)150 void zaccaria_state::attributes_w(offs_t offset, uint8_t data)
151 {
152 if (offset & 1)
153 {
154 if (m_attributesram[offset] != data)
155 {
156 int i;
157
158 for (i = offset / 2;i < 0x400;i += 32)
159 m_bg_tilemap->mark_tile_dirty(i);
160 }
161 }
162 else
163 m_bg_tilemap->set_scrolly(offset / 2,data);
164
165 m_attributesram[offset] = data;
166 }
167
WRITE_LINE_MEMBER(zaccaria_state::flip_screen_x_w)168 WRITE_LINE_MEMBER(zaccaria_state::flip_screen_x_w)
169 {
170 flip_screen_x_set(state);
171 }
172
WRITE_LINE_MEMBER(zaccaria_state::flip_screen_y_w)173 WRITE_LINE_MEMBER(zaccaria_state::flip_screen_y_w)
174 {
175 flip_screen_y_set(state);
176 }
177
178
179
180 /***************************************************************************
181
182 Display refresh
183
184 ***************************************************************************/
185
186 /* sprite format:
187
188 76543210
189 0 xxxxxxxx x
190 1 x....... flipy
191 .x...... flipx
192 ..xxxxxx code low
193 2 xx...... code high
194 ..xxx... ?
195 .....xxx color
196 3 xxxxxxxx y
197
198 offsets 1 and 2 are swapped if accessed from spriteram2
199
200 */
draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect,uint8_t * spriteram,int color,int section)201 void zaccaria_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect,uint8_t *spriteram,int color,int section)
202 {
203 int offs,o1 = 1,o2 = 2;
204
205 if (section)
206 {
207 o1 = 2;
208 o2 = 1;
209 }
210
211 for (offs = 0;offs < 0x20;offs += 4)
212 {
213 int sx = spriteram[offs + 3] + 1;
214 int sy = 242 - spriteram[offs];
215 int flipx = spriteram[offs + o1] & 0x40;
216 int flipy = spriteram[offs + o1] & 0x80;
217
218 if (sx == 1) continue;
219
220 if (flip_screen_x())
221 {
222 sx = 240 - sx;
223 flipx = !flipx;
224 }
225 if (flip_screen_y())
226 {
227 sy = 240 - sy;
228 flipy = !flipy;
229 }
230
231 m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
232 (spriteram[offs + o1] & 0x3f) + (spriteram[offs + o2] & 0xc0),
233 ((spriteram[offs + o2] & 0x07) << 2) | color,
234 flipx,flipy,sx,sy,0);
235 }
236 }
237
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)238 uint32_t zaccaria_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
239 {
240 m_bg_tilemap->draw(screen, bitmap, cliprect, 0,0);
241
242 // 3 layers of sprites, each with their own palette and priorities
243 // Not perfect yet, does spriteram(1) layer have a priority bit somewhere?
244 draw_sprites(bitmap,cliprect,m_spriteram2,2,1);
245 draw_sprites(bitmap,cliprect,m_spriteram,1,0);
246 draw_sprites(bitmap,cliprect,m_spriteram2+0x20,0,1);
247
248 return 0;
249 }
250