1 // license:BSD-3-Clause
2 // copyright-holders:Tomasz Slanina, Pierpaolo Prazzoli
3 /***************************************************************************
4
5 - BG layer 32x128 , 8x8 tiles 4bpp , 2 palettes (2nd is black )
6 - TXT layer 32x32 , 8x8 tiles 4bpp , 2 palettes (2nd is black)
7 - Sprites 16x16 3bpp, 8 palettes (0-3 are black)
8
9 'Special' effects :
10
11 - spotlight - gfx(BG+Sprites) outside spotlight is using black pals
12 spotlight masks are taken from ROM pr8
13 simulated using bitmaps and custom clipping rect
14
15 - lightning - BG color change (darkening ?) - simple analog circ.
16 simulated by additional palette
17
18 In debug build press 'w' for spotlight and 'e' for lightning
19
20 ***************************************************************************/
21 #include "emu.h"
22 #include "includes/pitnrun.h"
23
24
25
TILE_GET_INFO_MEMBER(pitnrun_state::get_tile_info1)26 TILE_GET_INFO_MEMBER(pitnrun_state::get_tile_info1)
27 {
28 int code = m_videoram[tile_index];
29 tileinfo.set(0,
30 code,
31 0,
32 0);
33 }
34
TILE_GET_INFO_MEMBER(pitnrun_state::get_tile_info2)35 TILE_GET_INFO_MEMBER(pitnrun_state::get_tile_info2)
36 {
37 int code = m_videoram2[tile_index];
38 tileinfo.set(1,
39 code + (m_char_bank<<8),
40 m_color_select&1,
41 0);
42 }
43
videoram_w(offs_t offset,uint8_t data)44 void pitnrun_state::videoram_w(offs_t offset, uint8_t data)
45 {
46 m_videoram[offset] = data;
47 m_fg ->mark_all_dirty();
48 }
49
videoram2_w(offs_t offset,uint8_t data)50 void pitnrun_state::videoram2_w(offs_t offset, uint8_t data)
51 {
52 m_videoram2[offset] = data;
53 m_bg ->mark_all_dirty();
54 }
55
WRITE_LINE_MEMBER(pitnrun_state::char_bank_select_w)56 WRITE_LINE_MEMBER(pitnrun_state::char_bank_select_w)
57 {
58 m_char_bank = state;
59 m_bg->mark_all_dirty();
60 }
61
62
scroll_w(offs_t offset,uint8_t data)63 void pitnrun_state::scroll_w(offs_t offset, uint8_t data)
64 {
65 m_scroll = (m_scroll & (0xff<<((offset)?0:8))) |( data<<((offset)?8:0));
66 m_bg->set_scrollx(0, m_scroll);
67 }
68
scroll_y_w(uint8_t data)69 void pitnrun_state::scroll_y_w(uint8_t data)
70 {
71 m_bg->set_scrolly(0, data);
72 }
73
ha_w(uint8_t data)74 void pitnrun_state::ha_w(uint8_t data)
75 {
76 m_ha=data;
77 }
78
h_heed_w(uint8_t data)79 void pitnrun_state::h_heed_w(uint8_t data)
80 {
81 m_h_heed=data;
82 }
83
v_heed_w(uint8_t data)84 void pitnrun_state::v_heed_w(uint8_t data)
85 {
86 m_v_heed=data;
87 }
88
WRITE_LINE_MEMBER(pitnrun_state::color_select_w)89 WRITE_LINE_MEMBER(pitnrun_state::color_select_w)
90 {
91 m_color_select = state;
92 machine().tilemap().mark_all_dirty();
93 }
94
spotlights()95 void pitnrun_state::spotlights()
96 {
97 uint8_t const *const ROM = memregion("spot")->base();
98 for (int i=0; i<4; i++)
99 {
100 for (int y=0; y<128; y++)
101 {
102 for (int x=0; x<16; x++)
103 {
104 int datapix = ROM[128*16*i + x + y*16];
105 for(int b=0; b<8; b++)
106 {
107 m_tmp_bitmap[i]->pix(y, x*8 + (7 - b)) = (datapix & 1);
108 datapix>>=1;
109 }
110 }
111 }
112 }
113 }
114
115
pitnrun_palette(palette_device & palette) const116 void pitnrun_state::pitnrun_palette(palette_device &palette) const
117 {
118 uint8_t const *const color_prom = memregion("proms")->base();
119
120 for (int i = 0; i < 32*3; i++)
121 {
122 int bit0, bit1, bit2;
123
124 bit0 = BIT(color_prom[i], 0);
125 bit1 = BIT(color_prom[i], 1);
126 bit2 = BIT(color_prom[i], 2);
127 int const r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
128
129 bit0 = BIT(color_prom[i], 3);
130 bit1 = BIT(color_prom[i], 4);
131 bit2 = BIT(color_prom[i], 5);
132 int const g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
133
134 bit0 = 0;
135 bit1 = BIT(color_prom[i], 6);
136 bit2 = BIT(color_prom[i], 7);
137 int const b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
138
139 palette.set_pen_color(i, rgb_t(r, g, b));
140 }
141
142 // fake bg palette for lightning effect
143 for (int i = 2*16; i < 2*16 + 16; i++)
144 {
145 int bit0, bit1, bit2;
146
147 bit0 = BIT(color_prom[i], 0);
148 bit1 = BIT(color_prom[i], 1);
149 bit2 = BIT(color_prom[i], 2);
150 int r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
151
152 bit0 = BIT(color_prom[i], 3);
153 bit1 = BIT(color_prom[i], 4);
154 bit2 = BIT(color_prom[i], 5);
155 int g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
156
157 bit0 = 0;
158 bit1 = BIT(color_prom[i], 6);
159 bit2 = BIT(color_prom[i], 7);
160 int b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
161
162 r /= 3;
163 g /= 3;
164 b /= 3;
165
166 palette.set_pen_color(i + 16, (r > 0xff) ? 0xff : r, (g > 0xff) ? 0xff : g, (b > 0xff) ? 0xff : b);
167
168 }
169 }
170
video_start()171 void pitnrun_state::video_start()
172 {
173 m_fg = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(pitnrun_state::get_tile_info1)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
174 m_bg = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(pitnrun_state::get_tile_info2)), TILEMAP_SCAN_ROWS, 8, 8, 32*4, 32);
175 m_fg->set_transparent_pen(0 );
176 m_tmp_bitmap[0] = std::make_unique<bitmap_ind16>(128,128);
177 m_tmp_bitmap[1] = std::make_unique<bitmap_ind16>(128,128);
178 m_tmp_bitmap[2] = std::make_unique<bitmap_ind16>(128,128);
179 m_tmp_bitmap[3] = std::make_unique<bitmap_ind16>(128,128);
180 spotlights();
181
182 save_item(NAME(m_h_heed));
183 save_item(NAME(m_v_heed));
184 save_item(NAME(m_ha));
185 save_item(NAME(m_scroll));
186 save_item(NAME(m_char_bank));
187 save_item(NAME(m_color_select));
188 }
189
draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect)190 void pitnrun_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect )
191 {
192 uint8_t *spriteram = m_spriteram;
193 int sx, sy, flipx, flipy, offs,pal;
194
195 for (offs = 0 ; offs < 0x100; offs+=4)
196 {
197 pal=spriteram[offs+2]&0x3;
198
199 sy = 256-spriteram[offs+0]-16;
200 sx = spriteram[offs+3]+1; // +1 needed to properly align Jump Kun
201 flipy = (spriteram[offs+1]&0x80)>>7;
202 flipx = (spriteram[offs+1]&0x40)>>6;
203
204 if (flip_screen_x())
205 {
206 sx = 256 - sx;
207 flipx = !flipx;
208 }
209 if (flip_screen_y())
210 {
211 sy = 240 - sy;
212 flipy = !flipy;
213 }
214
215 m_gfxdecode->gfx(2)->transpen(bitmap,cliprect,
216 (spriteram[offs+1]&0x3f)+((spriteram[offs+2]&0x80)>>1)+((spriteram[offs+2]&0x40)<<1),
217 pal,
218 flipx,flipy,
219 sx,sy,0);
220 }
221 }
222
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)223 uint32_t pitnrun_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
224 {
225 int dx=0,dy=0;
226 rectangle myclip=cliprect;
227
228 #ifdef MAME_DEBUG
229 if (machine().input().code_pressed_once(KEYCODE_Q))
230 {
231 uint8_t *ROM = memregion("maincpu")->base();
232 ROM[0x84f6]=0; /* lap 0 - normal */
233 }
234
235 if (machine().input().code_pressed_once(KEYCODE_W))
236 {
237 uint8_t *ROM = memregion("maincpu")->base();
238 ROM[0x84f6]=6; /* lap 6 = spotlight */
239 }
240
241 if (machine().input().code_pressed_once(KEYCODE_E))
242 {
243 uint8_t *ROM = memregion("maincpu")->base();
244 ROM[0x84f6]=2; /* lap 3 (trial 2)= lightnings */
245 ROM[0x8102]=1;
246 }
247 #endif
248
249 bitmap.fill(0, cliprect);
250
251 if(!(m_ha&4))
252 m_bg->draw(screen, bitmap, cliprect, 0,0);
253 else
254 {
255 dx=128-m_h_heed+((m_ha&8)<<5)+3;
256 dy=128-m_v_heed+((m_ha&0x10)<<4);
257
258 if (flip_screen_x())
259 dx=128-dx+16;
260
261 if (flip_screen_y())
262 dy=128-dy;
263
264 myclip.set(dx, dx+127, dy, dy+127);
265 myclip &= cliprect;
266
267 m_bg->draw(screen, bitmap, myclip, 0,0);
268 }
269
270 draw_sprites(bitmap,myclip);
271
272 if(m_ha&4)
273 copybitmap_trans(bitmap,*m_tmp_bitmap[m_ha&3],flip_screen_x(),flip_screen_y(),dx,dy,myclip, 1);
274 m_fg->draw(screen, bitmap, cliprect, 0,0);
275 return 0;
276 }
277