1 // license:BSD-3-Clause
2 // copyright-holders:Nicola Salmoria
3 #include "emu.h"
4 #include "includes/gberet.h"
5
6
7 /***************************************************************************
8
9 Convert the color PROMs into a more useable format.
10
11 Green Beret has a 32 bytes palette PROM and two 256 bytes color lookup table
12 PROMs (one for sprites, one for characters).
13 The palette PROM is connected to the RGB output, this way:
14
15 bit 7 -- 220 ohm resistor -- BLUE
16 -- 470 ohm resistor -- BLUE
17 -- 220 ohm resistor -- GREEN
18 -- 470 ohm resistor -- GREEN
19 -- 1 kohm resistor -- GREEN
20 -- 220 ohm resistor -- RED
21 -- 470 ohm resistor -- RED
22 bit 0 -- 1 kohm resistor -- RED
23
24 ***************************************************************************/
25
gberet_palette(palette_device & palette) const26 void gberet_state::gberet_palette(palette_device &palette) const
27 {
28 uint8_t const *color_prom = memregion("proms")->base();
29
30 // create a lookup table for the palette
31 for (int i = 0; i < 0x20; i++)
32 {
33 int bit0, bit1, bit2;
34
35 // red component
36 bit0 = BIT(color_prom[i], 0);
37 bit1 = BIT(color_prom[i], 1);
38 bit2 = BIT(color_prom[i], 2);
39 int const r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
40
41 // green component
42 bit0 = BIT(color_prom[i], 3);
43 bit1 = BIT(color_prom[i], 4);
44 bit2 = BIT(color_prom[i], 5);
45 int const g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
46
47 // blue component
48 bit0 = 0;
49 bit1 = BIT(color_prom[i], 6);
50 bit2 = BIT(color_prom[i], 7);
51 int const b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
52
53 palette.set_indirect_color(i, rgb_t(r, g, b));
54 }
55
56 // color_prom now points to the beginning of the lookup table
57 color_prom += 0x20;
58
59 for (int i = 0; i < 0x100; i++)
60 {
61 uint8_t const ctabentry = (color_prom[i] & 0x0f) | 0x10;
62 palette.set_pen_indirect(i, ctabentry);
63 }
64
65 for (int i = 0x100; i < 0x200; i++)
66 {
67 uint8_t const ctabentry = color_prom[i] & 0x0f;
68 palette.set_pen_indirect(i, ctabentry);
69 }
70 }
71
gberet_videoram_w(offs_t offset,uint8_t data)72 void gberet_state::gberet_videoram_w(offs_t offset, uint8_t data)
73 {
74 m_videoram[offset] = data;
75 m_bg_tilemap->mark_tile_dirty(offset);
76 }
77
gberet_colorram_w(offs_t offset,uint8_t data)78 void gberet_state::gberet_colorram_w(offs_t offset, uint8_t data)
79 {
80 m_colorram[offset] = data;
81 m_bg_tilemap->mark_tile_dirty(offset);
82 }
83
gberet_scroll_w(offs_t offset,uint8_t data)84 void gberet_state::gberet_scroll_w(offs_t offset, uint8_t data)
85 {
86 int scroll;
87
88 m_scrollram[offset] = data;
89
90 scroll = m_scrollram[offset & 0x1f] | (m_scrollram[offset | 0x20] << 8);
91 m_bg_tilemap->set_scrollx(offset & 0x1f, scroll);
92 }
93
gberet_sprite_bank_w(uint8_t data)94 void gberet_state::gberet_sprite_bank_w(uint8_t data)
95 {
96 m_spritebank = data;
97 }
98
TILE_GET_INFO_MEMBER(gberet_state::get_bg_tile_info)99 TILE_GET_INFO_MEMBER(gberet_state::get_bg_tile_info)
100 {
101 int attr = m_colorram[tile_index];
102 int code = m_videoram[tile_index] + ((attr & 0x40) << 2);
103 int color = attr & 0x0f;
104 int flags = TILE_FLIPYX((attr & 0x30) >> 4);
105
106 tileinfo.group = color;
107 tileinfo.category = (attr & 0x80) >> 7;
108
109 tileinfo.set(0, code, color, flags);
110 }
111
VIDEO_START_MEMBER(gberet_state,gberet)112 VIDEO_START_MEMBER(gberet_state,gberet)
113 {
114 m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(gberet_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
115 m_bg_tilemap->configure_groups(*m_gfxdecode->gfx(0), 0x10);
116 m_bg_tilemap->set_scroll_rows(32);
117 }
118
gberet_draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect)119 void gberet_state::gberet_draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect )
120 {
121 int offs;
122 uint8_t *sr;
123
124 if (m_spritebank & 0x08)
125 sr = m_spriteram2;
126 else
127 sr = m_spriteram;
128
129 for (offs = 0; offs < 0xc0; offs += 4)
130 {
131 if (sr[offs + 3])
132 {
133 int attr = sr[offs + 1];
134 int code = sr[offs + 0] + ((attr & 0x40) << 2);
135 int color = attr & 0x0f;
136 int sx = sr[offs + 2] - 2 * (attr & 0x80);
137 int sy = sr[offs + 3];
138 int flipx = attr & 0x10;
139 int flipy = attr & 0x20;
140
141 if (flip_screen())
142 {
143 sx = 240 - sx;
144 sy = 240 - sy;
145 flipx = !flipx;
146 flipy = !flipy;
147 }
148
149 m_gfxdecode->gfx(1)->transmask(bitmap,cliprect, code, color, flipx, flipy, sx, sy,
150 m_palette->transpen_mask(*m_gfxdecode->gfx(1), color, 0));
151 }
152 }
153 }
154
screen_update_gberet(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)155 uint32_t gberet_state::screen_update_gberet(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
156 {
157 m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE | TILEMAP_DRAW_ALL_CATEGORIES, 0);
158 gberet_draw_sprites(bitmap, cliprect);
159 m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
160 return 0;
161 }
162
163 /* Green Beret (bootleg) */
164
gberetb_scroll_w(offs_t offset,uint8_t data)165 void gberet_state::gberetb_scroll_w(offs_t offset, uint8_t data)
166 {
167 int scroll = data;
168
169 if (offset)
170 scroll |= 0x100;
171
172 for (offset = 6; offset < 29; offset++)
173 m_bg_tilemap->set_scrollx(offset, scroll + 64 - 8);
174 }
175
gberetb_draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect)176 void gberet_state::gberetb_draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect )
177 {
178 uint8_t *spriteram = m_spriteram;
179 int offs;
180
181 for (offs = m_spriteram.bytes() - 4; offs >= 0; offs -= 4)
182 {
183 if (spriteram[offs + 1])
184 {
185 int attr = spriteram[offs + 3];
186 int code = spriteram[offs] + ((attr & 0x40) << 2);
187 int color = attr & 0x0f;
188 int sx = spriteram[offs + 2] - 2 * (attr & 0x80);
189 int sy = 240 - spriteram[offs + 1];
190 int flipx = attr & 0x10;
191 int flipy = attr & 0x20;
192
193 if (flip_screen())
194 {
195 sx = 240 - sx;
196 sy = 240 - sy;
197 flipx = !flipx;
198 flipy = !flipy;
199 }
200
201 m_gfxdecode->gfx(1)->transmask(bitmap,cliprect, code, color, flipx, flipy, sx, sy,
202 m_palette->transpen_mask(*m_gfxdecode->gfx(1), color, 0));
203 }
204 }
205 }
206
screen_update_gberetb(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)207 uint32_t gberet_state::screen_update_gberetb(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
208 {
209 m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE | TILEMAP_DRAW_ALL_CATEGORIES, 0);
210 gberetb_draw_sprites(bitmap, cliprect);
211 m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
212 return 0;
213 }
214