1 // license:BSD-3-Clause
2 // copyright-holders:Nicola Salmoria
3 /***************************************************************************
4 
5   Galaxian hardware family
6 
7 ***************************************************************************/
8 
9 #include "emu.h"
10 #include "includes/galaxold.h"
11 
12 #define STARS_COLOR_BASE        (memregion("proms")->bytes())
13 #define BULLETS_COLOR_BASE      (STARS_COLOR_BASE + 64)
14 #define BACKGROUND_COLOR_BASE   (BULLETS_COLOR_BASE + 2)
15 
16 /***************************************************************************
17 
18   Convert the color PROMs into a more useable format.
19 
20   Galaxian has one 32 bytes palette PROM, connected to the RGB output this way:
21 
22   bit 7 -- 220 ohm resistor  -- BLUE
23         -- 470 ohm resistor  -- BLUE
24         -- 220 ohm resistor  -- GREEN
25         -- 470 ohm resistor  -- GREEN
26         -- 1  kohm resistor  -- GREEN
27         -- 220 ohm resistor  -- RED
28         -- 470 ohm resistor  -- RED
29   bit 0 -- 1  kohm resistor  -- RED
30 
31   The output of the background star generator is connected this way:
32 
33   bit 5 -- 100 ohm resistor  -- BLUE
34         -- 150 ohm resistor  -- BLUE
35         -- 100 ohm resistor  -- GREEN
36         -- 150 ohm resistor  -- GREEN
37         -- 100 ohm resistor  -- RED
38   bit 0 -- 150 ohm resistor  -- RED
39 
40   The blue background in Scramble and other games goes through a 390 ohm
41   resistor.
42 
43   The bullet RGB outputs go through 100 ohm resistors.
44 
45   The RGB outputs have a 470 ohm pull-down each.
46 
47 ***************************************************************************/
galaxold_palette(palette_device & palette)48 void galaxold_state::galaxold_palette(palette_device &palette)
49 {
50 	const uint8_t *color_prom = memregion("proms")->base();
51 
52 	// first, the character/sprite palette
53 	int const len = memregion("proms")->bytes();
54 	for (int i = 0; i < len; i++)
55 	{
56 		int bit0, bit1, bit2;
57 
58 		// red component
59 		bit0 = BIT(*color_prom, 0);
60 		bit1 = BIT(*color_prom, 1);
61 		bit2 = BIT(*color_prom, 2);
62 		int const r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
63 		// green component
64 		bit0 = BIT(*color_prom, 3);
65 		bit1 = BIT(*color_prom, 4);
66 		bit2 = BIT(*color_prom, 5);
67 		int const g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
68 		// blue component
69 		bit0 = BIT(*color_prom, 6);
70 		bit1 = BIT(*color_prom, 7);
71 		int const b = 0x4f * bit0 + 0xa8 * bit1;
72 
73 		palette.set_pen_color(i, r, g, b);
74 		color_prom++;
75 	}
76 
77 	galaxold_init_stars(STARS_COLOR_BASE);
78 
79 	// bullets - yellow and white
80 	palette.set_pen_color(BULLETS_COLOR_BASE + 0, rgb_t(0xef, 0xef, 0x00));
81 	palette.set_pen_color(BULLETS_COLOR_BASE + 1, rgb_t(0xef, 0xef, 0xef));
82 }
83 
scrambold_palette(palette_device & palette)84 void galaxold_state::scrambold_palette(palette_device &palette)
85 {
86 	galaxold_palette(palette);
87 
88 	// blue background - 390 ohm resistor
89 	palette.set_pen_color(BACKGROUND_COLOR_BASE, rgb_t(0, 0, 0x56));
90 }
91 
92 
93 
stratgyx_palette(palette_device & palette)94 void galaxold_state::stratgyx_palette(palette_device &palette)
95 {
96 	galaxold_palette(palette);
97 
98 	/*  The background color generator is connected this way:
99 
100 	    RED   - 270 ohm resistor
101 	    GREEN - 560 ohm resistor
102 	    BLUE  - 470 ohm resistor */
103 
104 	for (int i = 0; i < 8; i++)
105 	{
106 		int const r = BIT(i, 0) * 0x7c;
107 		int const g = BIT(i, 1) * 0x3c;
108 		int const b = BIT(i, 2) * 0x47;
109 
110 		palette.set_pen_color(BACKGROUND_COLOR_BASE + i, r, g, b);
111 	}
112 }
113 
rockclim_palette(palette_device & palette) const114 void galaxold_state::rockclim_palette(palette_device &palette) const
115 {
116 	const uint8_t *color_prom = memregion("proms")->base();
117 
118 	// first, the character/sprite palette
119 	int const len = memregion("proms")->bytes();
120 	for (int i = 0; i < len; i++)
121 	{
122 		int bit0, bit1, bit2;
123 
124 		// red component
125 		bit0 = BIT(*color_prom, 0);
126 		bit1 = BIT(*color_prom, 1);
127 		bit2 = BIT(*color_prom, 2);
128 		int const r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
129 		// green component
130 		bit0 = BIT(*color_prom, 3);
131 		bit1 = BIT(*color_prom, 4);
132 		bit2 = BIT(*color_prom, 5);
133 		int const g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
134 		// blue component
135 		bit0 = BIT(*color_prom, 6);
136 		bit1 = BIT(*color_prom, 7);
137 		int const b = 0x4f * bit0 + 0xa8 * bit1;
138 
139 		palette.set_pen_color(i, r, g, b);
140 		color_prom++;
141 	}
142 }
143 
144 /***************************************************************************
145 
146   Convert the color PROMs into a more useable format.
147 
148   Dark Planet has one 32 bytes palette PROM, connected to the RGB output this way:
149 
150   bit 5 -- 220 ohm resistor  -- BLUE
151         -- 470 ohm resistor  -- BLUE
152         -- 1  kohm resistor  -- BLUE
153         -- 220 ohm resistor  -- RED
154         -- 470 ohm resistor  -- RED
155   bit 0 -- 1  kohm resistor  -- RED
156 
157   The bullet RGB outputs go through 100 ohm resistors.
158 
159   The RGB outputs have a 470 ohm pull-down each.
160 
161 ***************************************************************************/
darkplnt_palette(palette_device & palette) const162 void galaxold_state::darkplnt_palette(palette_device &palette) const
163 {
164 	const uint8_t *color_prom = memregion("proms")->base();
165 
166 	// first, the character/sprite palette
167 	for (int i = 0; i < 32; i++)
168 	{
169 		int bit0, bit1, bit2;
170 
171 		// red component
172 		bit0 = BIT(*color_prom, 0);
173 		bit1 = BIT(*color_prom, 1);
174 		bit2 = BIT(*color_prom, 2);
175 		int const r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
176 		// green component
177 		int const g = 0x00;
178 		// blue component
179 		bit0 = BIT(*color_prom, 3);
180 		bit1 = BIT(*color_prom, 4);
181 		bit2 = BIT(*color_prom, 5);
182 		int const b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
183 
184 		palette.set_pen_color(i, r, g, b);
185 		color_prom++;
186 	}
187 
188 	// bullets - red and blue
189 	palette.set_pen_color(BULLETS_COLOR_BASE + 0, rgb_t(0xef, 0x00, 0x00));
190 	palette.set_pen_color(BULLETS_COLOR_BASE + 1, rgb_t(0x00, 0x00, 0xef));
191 }
192 
minefld_palette(palette_device & palette)193 void galaxold_state::minefld_palette(palette_device &palette)
194 {
195 	galaxold_palette(palette);
196 
197 	// set up background colors
198 
199 	// graduated blue
200 
201 	for (int i = 0; i < 128; i++)
202 	{
203 		int const r = 0;
204 		int const g = i;
205 		int const b = i * 2;
206 		palette.set_pen_color(BACKGROUND_COLOR_BASE + i, r, g, b);
207 	}
208 
209 	// graduated brown
210 
211 	for (int i = 0; i < 128; i++)
212 	{
213 		int const r = i * 1.5;
214 		int const g = i * 0.75;
215 		int const b = i / 2;
216 		palette.set_pen_color(BACKGROUND_COLOR_BASE + 128 + i, r, g, b);
217 	}
218 }
219 
rescue_palette(palette_device & palette)220 void galaxold_state::rescue_palette(palette_device &palette)
221 {
222 	galaxold_palette(palette);
223 
224 	// set up background colors
225 
226 	// graduated blue
227 
228 	for (int i = 0; i < 128; i++)
229 	{
230 		int const r = 0;
231 		int const g = i;
232 		int const b = i * 2;
233 		palette.set_pen_color(BACKGROUND_COLOR_BASE + i, r, g, b);
234 	}
235 }
236 
mariner_palette(palette_device & palette)237 void galaxold_state::mariner_palette(palette_device &palette)
238 {
239 	galaxold_palette(palette);
240 
241 	/* set up background colors */
242 
243 	/* 16 shades of blue - the 4 bits are connected to the following resistors:
244 
245 	    bit 0 -- 4.7 kohm resistor
246 	          -- 2.2 kohm resistor
247 	          -- 1   kohm resistor
248 	    bit 0 -- .47 kohm resistor */
249 
250 	for (int i = 0; i < 16; i++)
251 	{
252 		int const r = 0;
253 		int const g = 0;
254 		int const b = 0x0e * BIT(i, 0) + 0x1f * BIT(i, 1) + 0x43 * BIT(i, 2) + 0x8f * BIT(i, 3);
255 
256 		palette.set_pen_color(BACKGROUND_COLOR_BASE + i, r, g, b);
257 	}
258 }
259 
260 // swapped r/g/b hook-up
dambustr_palette(palette_device & palette)261 void galaxold_state::dambustr_palette(palette_device &palette)
262 {
263 	const uint8_t *color_prom = memregion("proms")->base();
264 
265 	// first, the character/sprite palette
266 	int const len = memregion("proms")->bytes();
267 	for (int i = 0; i < len; i++)
268 	{
269 		int bit0, bit1, bit2;
270 
271 		// red component
272 		bit0 = BIT(*color_prom, 0);
273 		bit1 = BIT(*color_prom, 1);
274 		bit2 = BIT(*color_prom, 2);
275 		int const b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
276 		// green component
277 		bit0 = BIT(*color_prom, 3);
278 		bit1 = BIT(*color_prom, 4);
279 		bit2 = BIT(*color_prom, 5);
280 		int const r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
281 		// blue component
282 		bit0 = BIT(*color_prom, 6);
283 		bit1 = BIT(*color_prom, 7);
284 		int const g = 0x4f * bit0 + 0xa8 * bit1;
285 
286 		palette.set_pen_color(i, r, g, b);
287 		color_prom++;
288 	}
289 
290 	galaxold_init_stars(STARS_COLOR_BASE);
291 
292 	// bullets - yellow and white
293 	palette.set_pen_color(BULLETS_COLOR_BASE + 0, rgb_t(0xef, 0xef, 0x00));
294 	palette.set_pen_color(BULLETS_COLOR_BASE + 1, rgb_t(0xef, 0xef, 0xef));
295 
296 	/*
297 	Assumption (not clear from the schematics):
298 	The background color generator is connected this way:
299 
300 	    RED   - 470 ohm resistor
301 	    GREEN - 470 ohm resistor
302 	    BLUE  - 470 ohm resistor */
303 
304 	for (int i = 0; i < 8; i++)
305 	{
306 		int const r = BIT(i, 0) * 0x47;
307 		int const g = BIT(i, 1) * 0x47;
308 		int const b = BIT(i, 2) * 0x4f;
309 		palette.set_pen_color(BACKGROUND_COLOR_BASE + i, r, g, b);
310 	}
311 }
312 
313 
turtles_palette(palette_device & palette)314 void galaxold_state::turtles_palette(palette_device &palette)
315 {
316 	galaxold_palette(palette);
317 
318 	/*  The background color generator is connected this way:
319 
320 	    RED   - 390 ohm resistor
321 	    GREEN - 470 ohm resistor
322 	    BLUE  - 390 ohm resistor */
323 
324 	for (int i = 0; i < 8; i++)
325 	{
326 		int const r = BIT(i, 0) * 0x55;
327 		int const g = BIT(i, 1) * 0x47;
328 		int const b = BIT(i, 2) * 0x55;
329 
330 		palette.set_pen_color(BACKGROUND_COLOR_BASE + i, r, g, b);
331 	}
332 }
333 
334 
335 /***************************************************************************
336 
337   Start the video hardware emulation.
338 
339 ***************************************************************************/
340 
state_save_register()341 void galaxold_state::state_save_register()
342 {
343 	save_item(NAME(m_gfxbank));
344 	save_item(NAME(m_flipscreen_x));
345 	save_item(NAME(m_flipscreen_y));
346 
347 	save_item(NAME(m_stars_on));
348 	save_item(NAME(m_stars_scrollpos));
349 	save_item(NAME(m_stars_blink_state));
350 	save_item(NAME(m_timer_adjusted));
351 
352 	save_item(NAME(m_darkplnt_bullet_color));
353 
354 	save_item(NAME(m_background_enable));
355 	save_item(NAME(m_background_red));
356 	save_item(NAME(m_background_green));
357 	save_item(NAME(m_background_blue));
358 }
359 
video_start_common()360 void galaxold_state::video_start_common()
361 {
362 	m_modify_charcode = nullptr;
363 	m_modify_spritecode = nullptr;
364 	m_modify_color = nullptr;
365 	m_modify_ypos = nullptr;
366 
367 	m_draw_bullets = nullptr;
368 
369 	m_draw_background = &galaxold_state::galaxold_draw_background;
370 	m_background_enable = 0;
371 	m_background_blue = 0;
372 	m_background_red = 0;
373 	m_background_green = 0;
374 
375 	m_draw_stars = &galaxold_state::noop_draw_stars;
376 
377 	m_flipscreen_x = 0;
378 	m_flipscreen_y = 0;
379 
380 	m_spriteram2_present = 0;
381 
382 	state_save_register();
383 }
384 
VIDEO_START_MEMBER(galaxold_state,galaxold_plain)385 VIDEO_START_MEMBER(galaxold_state,galaxold_plain)
386 {
387 	video_start_common();
388 	m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(galaxold_state::get_tile_info)), TILEMAP_SCAN_ROWS,8,8,32,32);
389 	m_bg_tilemap->set_transparent_pen(0);
390 
391 	m_bg_tilemap->set_scroll_cols(32);
392 
393 	m_color_mask = (m_gfxdecode->gfx(0)->granularity() == 4) ? 7 : 3;
394 }
395 
VIDEO_START_MEMBER(galaxold_state,galaxold)396 VIDEO_START_MEMBER(galaxold_state,galaxold)
397 {
398 	VIDEO_START_CALL_MEMBER(galaxold_plain);
399 
400 	m_draw_stars = &galaxold_state::galaxold_draw_stars;
401 
402 	m_draw_bullets = &galaxold_state::galaxold_draw_bullets;
403 }
404 
VIDEO_START_MEMBER(galaxold_state,scrambold)405 VIDEO_START_MEMBER(galaxold_state,scrambold)
406 {
407 	VIDEO_START_CALL_MEMBER(galaxold_plain);
408 
409 	/* FIXME: This most probably needs to be adjusted
410 	 * again when RAW video params are added to scramble
411 	 */
412 	m_bg_tilemap->set_scrolldx(0, 0);
413 
414 	m_draw_stars = &galaxold_state::scrambold_draw_stars;
415 
416 	m_draw_bullets = &galaxold_state::scrambold_draw_bullets;
417 
418 	m_draw_background = &galaxold_state::scrambold_draw_background;
419 }
420 
VIDEO_START_MEMBER(galaxold_state,newsin7)421 VIDEO_START_MEMBER(galaxold_state, newsin7)
422 {
423 	VIDEO_START_CALL_MEMBER(scrambold);
424 
425 	m_leftclip = 0;
426 }
427 
428 
VIDEO_START_MEMBER(galaxold_state,darkplnt)429 VIDEO_START_MEMBER(galaxold_state,darkplnt)
430 {
431 	VIDEO_START_CALL_MEMBER(galaxold_plain);
432 
433 	m_bg_tilemap->set_scrolldx(0, 0);
434 	m_draw_bullets = &galaxold_state::darkplnt_draw_bullets;
435 }
436 
VIDEO_START_MEMBER(galaxold_state,rescue)437 VIDEO_START_MEMBER(galaxold_state,rescue)
438 {
439 	VIDEO_START_CALL_MEMBER(scrambold);
440 
441 	m_draw_stars = &galaxold_state::rescue_draw_stars;
442 
443 	m_draw_background = &galaxold_state::rescue_draw_background;
444 }
445 
VIDEO_START_MEMBER(galaxold_state,minefld)446 VIDEO_START_MEMBER(galaxold_state,minefld)
447 {
448 	VIDEO_START_CALL_MEMBER(scrambold);
449 
450 	m_draw_stars = &galaxold_state::rescue_draw_stars;
451 
452 	m_draw_background = &galaxold_state::minefld_draw_background;
453 }
454 
VIDEO_START_MEMBER(galaxold_state,stratgyx)455 VIDEO_START_MEMBER(galaxold_state,stratgyx)
456 {
457 	VIDEO_START_CALL_MEMBER(galaxold_plain);
458 
459 	m_draw_background = &galaxold_state::stratgyx_draw_background;
460 
461 	// level 3 tank bullets
462 	m_draw_bullets = &galaxold_state::scrambold_draw_bullets;
463 }
464 
VIDEO_START_MEMBER(galaxold_state,ckongs)465 VIDEO_START_MEMBER(galaxold_state,ckongs)
466 {
467 	VIDEO_START_CALL_MEMBER(scrambold);
468 
469 	m_modify_spritecode = &galaxold_state::mshuttle_modify_spritecode;
470 }
471 
VIDEO_START_MEMBER(galaxold_state,mariner)472 VIDEO_START_MEMBER(galaxold_state,mariner)
473 {
474 	VIDEO_START_CALL_MEMBER(galaxold_plain);
475 
476 	m_draw_stars = &galaxold_state::mariner_draw_stars;
477 
478 	m_draw_bullets = &galaxold_state::scrambold_draw_bullets;
479 
480 	m_draw_background = &galaxold_state::mariner_draw_background;
481 
482 	m_modify_charcode = &galaxold_state::mariner_modify_charcode;
483 }
484 
VIDEO_START_MEMBER(galaxold_state,mimonkey)485 VIDEO_START_MEMBER(galaxold_state,mimonkey)
486 {
487 	VIDEO_START_CALL_MEMBER(scrambold);
488 
489 	m_modify_charcode   = &galaxold_state::mimonkey_modify_charcode;
490 	m_modify_spritecode = &galaxold_state::mimonkey_modify_spritecode;
491 }
492 
VIDEO_START_MEMBER(galaxold_state,dkongjrm)493 VIDEO_START_MEMBER(galaxold_state,dkongjrm)
494 {
495 	VIDEO_START_CALL_MEMBER(galaxold_plain);
496 
497 	m_modify_charcode   = &galaxold_state::pisces_modify_charcode;
498 	m_modify_spritecode = &galaxold_state::dkongjrm_modify_spritecode;
499 
500 	m_spriteram2_present= 1;
501 }
502 
VIDEO_START_MEMBER(galaxold_state,dkongjrmc)503 VIDEO_START_MEMBER(galaxold_state,dkongjrmc)
504 {
505 	VIDEO_START_CALL_MEMBER(galaxold_plain);
506 
507 	m_modify_charcode   = &galaxold_state::pisces_modify_charcode;
508 	m_modify_spritecode = &galaxold_state::dkongjrmc_modify_spritecode;
509 }
510 
VIDEO_START_MEMBER(galaxold_state,scorpion)511 VIDEO_START_MEMBER(galaxold_state,scorpion)
512 {
513 	VIDEO_START_CALL_MEMBER(scrambold);
514 
515 	m_modify_spritecode = &galaxold_state::batman2_modify_spritecode;
516 }
517 
pisces_modify_spritecode(uint8_t * spriteram,int * code,int * flipx,int * flipy,int offs)518 void galaxold_state::pisces_modify_spritecode(uint8_t *spriteram, int *code, int *flipx, int *flipy, int offs)
519 {
520 	*code |= (m_gfxbank[0] << 6);
521 }
522 
VIDEO_START_MEMBER(galaxold_state,pisces)523 VIDEO_START_MEMBER(galaxold_state,pisces)
524 {
525 	VIDEO_START_CALL_MEMBER(galaxold);
526 
527 	m_modify_charcode   = &galaxold_state::pisces_modify_charcode;
528 	m_modify_spritecode = &galaxold_state::pisces_modify_spritecode;
529 }
530 
531 #ifdef UNUSED_FUNCTION
theend_draw_bullets(bitmap_ind16 & bitmap,const rectangle & cliprect,int offs,int x,int y)532 void galaxold_state::theend_draw_bullets(bitmap_ind16 &bitmap, const rectangle &cliprect, int offs, int x, int y)
533 {
534 	/* same as Galaxian, but all bullets are yellow */
535 	for (int i = 0; i < 4; i++)
536 	{
537 		x--;
538 
539 		if (cliprect.contains(x, y))
540 			bitmap.pix(y, x) = BULLETS_COLOR_BASE;
541 	}
542 }
543 
VIDEO_START_MEMBER(galaxold_state,theend)544 VIDEO_START_MEMBER(galaxold_state,theend)
545 {
546 	VIDEO_START_CALL_MEMBER(galaxold);
547 
548 	m_draw_bullets = &galaxold_state::theend_draw_bullets;
549 }
550 #endif
551 
mooncrst_modify_spritecode(uint8_t * spriteram,int * code,int * flipx,int * flipy,int offs)552 void galaxold_state::mooncrst_modify_spritecode(uint8_t *spriteram, int *code, int *flipx, int *flipy, int offs)
553 {
554 	if (m_gfxbank[2] && ((*code & 0x30) == 0x20))
555 	{
556 		*code = (*code & 0x0f) | (m_gfxbank[0] << 4) | (m_gfxbank[1] << 5) | 0x40;
557 	}
558 }
559 
VIDEO_START_MEMBER(galaxold_state,mooncrst)560 VIDEO_START_MEMBER(galaxold_state,mooncrst)
561 {
562 	VIDEO_START_CALL_MEMBER(galaxold);
563 
564 	m_modify_charcode   = &galaxold_state::mooncrst_modify_charcode;
565 	m_modify_spritecode = &galaxold_state::mooncrst_modify_spritecode;
566 }
567 
rockclim_draw_background(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)568 void galaxold_state::rockclim_draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
569 {
570 	m_rockclim_tilemap->draw(screen, bitmap, cliprect, 0,0);
571 }
572 
rockclim_modify_spritecode(uint8_t * spriteram,int * code,int * flipx,int * flipy,int offs)573 void galaxold_state::rockclim_modify_spritecode(uint8_t *spriteram, int *code, int *flipx, int *flipy, int offs)
574 {
575 	if (m_gfxbank[2])    *code|=0x40;
576 }
577 
VIDEO_START_MEMBER(galaxold_state,rockclim)578 VIDEO_START_MEMBER(galaxold_state,rockclim)
579 {
580 	VIDEO_START_CALL_MEMBER(galaxold);
581 	m_rockclim_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(galaxold_state::rockclim_get_tile_info)), TILEMAP_SCAN_ROWS,8,8,64,32);
582 
583 	m_draw_background = &galaxold_state::rockclim_draw_background;
584 	m_modify_charcode = &galaxold_state::mooncrst_modify_charcode;
585 	m_modify_spritecode = &galaxold_state::rockclim_modify_spritecode;
586 
587 	m_rockclim_v = m_rockclim_h = 0;
588 	save_item(NAME(m_rockclim_v));
589 	save_item(NAME(m_rockclim_h));
590 }
591 
TILE_GET_INFO_MEMBER(galaxold_state::drivfrcg_get_tile_info)592 TILE_GET_INFO_MEMBER(galaxold_state::drivfrcg_get_tile_info)
593 {
594 	int code = m_videoram[tile_index];
595 	uint8_t x = tile_index & 0x1f;
596 	uint8_t color = m_attributesram[(x << 1) | 1] & 7;
597 	uint8_t bank = m_attributesram[(x << 1) | 1] & 0x30;
598 
599 	code |= (bank << 4);
600 	color |= ((m_attributesram[(x << 1) | 1] & 0x40) >> 3);
601 
602 	tileinfo.set(0, code, color, 0);
603 }
604 
VIDEO_START_MEMBER(galaxold_state,drivfrcg)605 VIDEO_START_MEMBER(galaxold_state,drivfrcg)
606 {
607 	video_start_common();
608 	m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(galaxold_state::drivfrcg_get_tile_info)), TILEMAP_SCAN_ROWS,8,8,32,32);
609 
610 	m_bg_tilemap->set_transparent_pen(0);
611 	m_bg_tilemap->set_scroll_cols(32);
612 
613 	m_modify_spritecode = &galaxold_state::mshuttle_modify_spritecode;
614 	m_modify_color = &galaxold_state::drivfrcg_modify_color;
615 
616 	m_color_mask = 0xff;
617 }
618 
VIDEO_START_MEMBER(galaxold_state,ad2083)619 VIDEO_START_MEMBER(galaxold_state,ad2083)
620 {
621 	video_start_common();
622 	m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(galaxold_state::drivfrcg_get_tile_info)), TILEMAP_SCAN_ROWS,8,8,32,32);
623 
624 	m_bg_tilemap->set_transparent_pen(0);
625 	m_bg_tilemap->set_scroll_cols(32);
626 
627 	m_modify_spritecode = &galaxold_state::ad2083_modify_spritecode;
628 
629 	m_draw_bullets = &galaxold_state::scrambold_draw_bullets;
630 
631 	m_draw_background = &galaxold_state::ad2083_draw_background;
632 
633 	m_color_mask = 7;
634 }
635 
636 
racknrol_tiles_bank_w(offs_t offset,uint8_t data)637 void galaxold_state::racknrol_tiles_bank_w(offs_t offset, uint8_t data)
638 {
639 	m_racknrol_tiles_bank[offset] = data;
640 	m_bg_tilemap->mark_all_dirty();
641 }
642 
TILE_GET_INFO_MEMBER(galaxold_state::racknrol_get_tile_info)643 TILE_GET_INFO_MEMBER(galaxold_state::racknrol_get_tile_info)
644 {
645 	int code = m_videoram[tile_index];
646 	uint8_t x = tile_index & 0x1f;
647 	uint8_t color = m_attributesram[(x << 1) | 1] & 7;
648 	uint8_t bank = m_racknrol_tiles_bank[x] & 7;
649 
650 	code |= (bank << 8);
651 
652 	tileinfo.set(0, code, color, 0);
653 }
654 
VIDEO_START_MEMBER(galaxold_state,racknrol)655 VIDEO_START_MEMBER(galaxold_state,racknrol)
656 {
657 	video_start_common();
658 	m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(galaxold_state::racknrol_get_tile_info)), TILEMAP_SCAN_ROWS,8,8,32,32);
659 
660 	m_bg_tilemap->set_transparent_pen(0);
661 	m_bg_tilemap->set_scroll_cols(32);
662 
663 	m_color_mask = 0xff;
664 }
665 
666 
667 // Harem
668 
TILE_GET_INFO_MEMBER(galaxold_state::harem_get_tile_info)669 TILE_GET_INFO_MEMBER(galaxold_state::harem_get_tile_info)
670 {
671 	int code = m_videoram[tile_index];
672 	uint8_t x = tile_index & 0x1f;
673 	uint8_t color = m_attributesram[(x << 1) | 1] & 7;
674 	uint8_t bank = BIT(m_racknrol_tiles_bank[0], x/4);    // 1 bit every 4 columns
675 
676 	code  |= bank * 0x200;
677 
678 	tileinfo.set(0, code, color, 0);
679 }
680 
harem_modify_spritecode(uint8_t * spriteram,int * code,int * flipx,int * flipy,int offs)681 void galaxold_state::harem_modify_spritecode(uint8_t *spriteram, int *code, int *flipx, int *flipy, int offs)
682 {
683 	*code |= (m_gfxbank[0] << 7) | 0x40;
684 }
685 
VIDEO_START_MEMBER(galaxold_state,harem)686 VIDEO_START_MEMBER(galaxold_state,harem)
687 {
688 	video_start_common();
689 	m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(galaxold_state::harem_get_tile_info)), TILEMAP_SCAN_ROWS,8,8,32,32);
690 //  m_bg_tilemap->set_transparent_pen(0);   // opaque tilemap to get sky and sand colors
691 
692 	m_bg_tilemap->set_scroll_cols(32);
693 
694 	m_color_mask = (m_gfxdecode->gfx(0)->granularity() == 4) ? 7 : 3;
695 
696 	m_modify_spritecode = &galaxold_state::harem_modify_spritecode;
697 }
698 
VIDEO_START_MEMBER(galaxold_state,ozon1)699 VIDEO_START_MEMBER(galaxold_state,ozon1)
700 {
701 	VIDEO_START_CALL_MEMBER(galaxold_plain);
702 
703 	m_bg_tilemap->set_scrolldx(0, 384-256);
704 }
705 
VIDEO_START_MEMBER(galaxold_state,bongo)706 VIDEO_START_MEMBER(galaxold_state,bongo)
707 {
708 	VIDEO_START_CALL_MEMBER(galaxold_plain);
709 
710 	m_bg_tilemap->set_scrolldx(0, 384-256);
711 
712 	m_modify_spritecode = &galaxold_state::batman2_modify_spritecode;
713 }
714 
TILE_GET_INFO_MEMBER(galaxold_state::dambustr_get_tile_info2)715 TILE_GET_INFO_MEMBER(galaxold_state::dambustr_get_tile_info2)
716 {
717 	uint8_t x = tile_index & 0x1f;
718 
719 	uint16_t code = m_dambustr_videoram2[tile_index];
720 	uint8_t color = m_attributesram[(x << 1) | 1] & m_color_mask;
721 
722 	if (m_modify_charcode)
723 	{
724 		(this->*m_modify_charcode)(&code, x);
725 	}
726 
727 	if (m_modify_color)
728 	{
729 		(this->*m_modify_color)(&color);
730 	}
731 
732 	tileinfo.set(0, code, color, 0);
733 }
734 
VIDEO_START_MEMBER(galaxold_state,dambustr)735 VIDEO_START_MEMBER(galaxold_state,dambustr)
736 {
737 	VIDEO_START_CALL_MEMBER(galaxold);
738 
739 	m_dambustr_bg_split_line = 0;
740 	m_dambustr_bg_color_1 = 0;
741 	m_dambustr_bg_color_2 = 0;
742 	m_dambustr_bg_priority = 0;
743 	m_dambustr_char_bank = 0;
744 
745 	m_draw_background = &galaxold_state::dambustr_draw_background;
746 
747 	m_modify_charcode   = &galaxold_state::dambustr_modify_charcode;
748 	m_modify_spritecode = &galaxold_state::dambustr_modify_spritecode;
749 
750 	m_draw_bullets = &galaxold_state::dambustr_draw_bullets;
751 
752 	/* allocate the temporary bitmap for the background priority */
753 	m_dambustr_tmpbitmap = std::make_unique<bitmap_ind16>(m_screen->width(), m_screen->height());
754 
755 	/* make a copy of the tilemap to emulate background priority */
756 	m_dambustr_videoram2 = std::make_unique<uint8_t[]>(0x0400);
757 	m_dambustr_tilemap2 = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(galaxold_state::dambustr_get_tile_info2)), TILEMAP_SCAN_ROWS,8,8,32,32);
758 
759 	m_dambustr_tilemap2->set_transparent_pen(0);
760 }
761 
762 
galaxold_videoram_w(offs_t offset,uint8_t data)763 void galaxold_state::galaxold_videoram_w(offs_t offset, uint8_t data)
764 {
765 	m_videoram[offset] = data;
766 	m_bg_tilemap->mark_tile_dirty(offset);
767 }
768 
galaxold_videoram_r(offs_t offset)769 uint8_t galaxold_state::galaxold_videoram_r(offs_t offset)
770 {
771 	return m_videoram[offset];
772 }
773 
774 
galaxold_attributesram_w(offs_t offset,uint8_t data)775 void galaxold_state::galaxold_attributesram_w(offs_t offset, uint8_t data)
776 {
777 	if (m_attributesram[offset] != data)
778 	{
779 		if (offset & 0x01)
780 		{
781 			/* color change */
782 			int i;
783 
784 			for (i = offset >> 1; i < 0x0400; i += 32)
785 				m_bg_tilemap->mark_tile_dirty(i);
786 		}
787 		else
788 		{
789 			if (m_modify_ypos)
790 			{
791 				(this->*m_modify_ypos)(&data);
792 			}
793 
794 			m_bg_tilemap->set_scrolly(offset >> 1, data);
795 		}
796 
797 		m_attributesram[offset] = data;
798 	}
799 }
800 
801 
galaxold_flip_screen_x_w(uint8_t data)802 void galaxold_state::galaxold_flip_screen_x_w(uint8_t data)
803 {
804 	if (m_flipscreen_x != (data & 0x01))
805 	{
806 		m_flipscreen_x = data & 0x01;
807 
808 		m_bg_tilemap->set_flip((m_flipscreen_x ? TILEMAP_FLIPX : 0) | (m_flipscreen_y ? TILEMAP_FLIPY : 0));
809 	}
810 }
811 
galaxold_flip_screen_y_w(uint8_t data)812 void galaxold_state::galaxold_flip_screen_y_w(uint8_t data)
813 {
814 	if (m_flipscreen_y != (data & 0x01))
815 	{
816 		m_flipscreen_y = data & 0x01;
817 
818 		m_bg_tilemap->set_flip((m_flipscreen_x ? TILEMAP_FLIPX : 0) | (m_flipscreen_y ? TILEMAP_FLIPY : 0));
819 	}
820 }
821 
822 
823 #ifdef UNUSED_FUNCTION
gteikob2_flip_screen_x_w(uint8_t data)824 void galaxold_state::gteikob2_flip_screen_x_w(uint8_t data)
825 {
826 	galaxold_flip_screen_x_w(~data);
827 }
828 
gteikob2_flip_screen_y_w(uint8_t data)829 void galaxold_state::gteikob2_flip_screen_y_w(uint8_t data)
830 {
831 	galaxold_flip_screen_y_w(~data);
832 }
833 #endif
834 
835 
hotshock_flip_screen_w(uint8_t data)836 void galaxold_state::hotshock_flip_screen_w(uint8_t data)
837 {
838 	galaxold_flip_screen_x_w(data);
839 	galaxold_flip_screen_y_w(data);
840 }
841 
842 
scrambold_background_enable_w(uint8_t data)843 void galaxold_state::scrambold_background_enable_w(uint8_t data)
844 {
845 	m_background_enable = data & 0x01;
846 }
847 
scrambold_background_red_w(uint8_t data)848 void galaxold_state::scrambold_background_red_w(uint8_t data)
849 {
850 	m_background_red = data & 0x01;
851 }
852 
scrambold_background_green_w(uint8_t data)853 void galaxold_state::scrambold_background_green_w(uint8_t data)
854 {
855 	m_background_green = data & 0x01;
856 }
857 
scrambold_background_blue_w(uint8_t data)858 void galaxold_state::scrambold_background_blue_w(uint8_t data)
859 {
860 	m_background_blue = data & 0x01;
861 }
862 
863 
galaxold_stars_enable_w(uint8_t data)864 void galaxold_state::galaxold_stars_enable_w(uint8_t data)
865 {
866 	m_stars_on = data & 0x01;
867 
868 	if (!m_stars_on)
869 	{
870 		m_stars_scrollpos = 0;
871 	}
872 }
873 
874 
darkplnt_bullet_color_w(uint8_t data)875 void galaxold_state::darkplnt_bullet_color_w(uint8_t data)
876 {
877 	m_darkplnt_bullet_color = data & 0x01;
878 }
879 
880 
881 
galaxold_gfxbank_w(offs_t offset,uint8_t data)882 void galaxold_state::galaxold_gfxbank_w(offs_t offset, uint8_t data)
883 {
884 	if (m_gfxbank[offset] != data)
885 	{
886 		m_gfxbank[offset] = data;
887 
888 		m_bg_tilemap->mark_all_dirty();
889 	}
890 }
891 
rockclim_videoram_w(offs_t offset,uint8_t data)892 void galaxold_state::rockclim_videoram_w(offs_t offset, uint8_t data)
893 {
894 	m_rockclim_videoram[offset] = data;
895 	m_rockclim_tilemap->mark_tile_dirty(offset);
896 }
897 
rockclim_scroll_w(offs_t offset,uint8_t data)898 void galaxold_state::rockclim_scroll_w(offs_t offset, uint8_t data)
899 {
900 	switch(offset&3)
901 	{
902 		case 0: m_rockclim_h=(m_rockclim_h&0xff00)|data;m_rockclim_tilemap ->set_scrollx(0, m_rockclim_h );break;
903 		case 1: m_rockclim_h=(m_rockclim_h&0xff)|(data<<8);m_rockclim_tilemap ->set_scrollx(0, m_rockclim_h );break;
904 		case 2: m_rockclim_v=(m_rockclim_v&0xff00)|data;m_rockclim_tilemap ->set_scrolly(0, m_rockclim_v );break;
905 		case 3: m_rockclim_v=(m_rockclim_v&0xff)|(data<<8);m_rockclim_tilemap ->set_scrolly(0, m_rockclim_v );break;
906 	}
907 
908 }
909 
910 
rockclim_videoram_r(offs_t offset)911 uint8_t galaxold_state::rockclim_videoram_r(offs_t offset)
912 {
913 	return m_rockclim_videoram[offset];
914 }
915 
916 
dambustr_bg_split_line_w(uint8_t data)917 void galaxold_state::dambustr_bg_split_line_w(uint8_t data)
918 {
919 	m_dambustr_bg_split_line = data;
920 }
921 
922 
dambustr_bg_color_w(uint8_t data)923 void galaxold_state::dambustr_bg_color_w(uint8_t data)
924 {
925 	m_dambustr_bg_color_1 = (BIT(data,2)<<2) | (BIT(data,1)<<1) | BIT(data,0);
926 	m_dambustr_bg_color_2 = (BIT(data,6)<<2) | (BIT(data,5)<<1) | BIT(data,4);
927 	m_dambustr_bg_priority = BIT(data,3);
928 	m_dambustr_char_bank = BIT(data,7);
929 	m_bg_tilemap->mark_all_dirty();
930 }
931 
932 
933 
934 /* character banking functions */
935 
mooncrst_modify_charcode(uint16_t * code,uint8_t x)936 void galaxold_state::mooncrst_modify_charcode(uint16_t *code, uint8_t x)
937 {
938 	if (m_gfxbank[2] && ((*code & 0xc0) == 0x80))
939 	{
940 		*code = (*code & 0x3f) | (m_gfxbank[0] << 6) | (m_gfxbank[1] << 7) | 0x0100;
941 	}
942 }
943 
pisces_modify_charcode(uint16_t * code,uint8_t x)944 void galaxold_state::pisces_modify_charcode(uint16_t *code, uint8_t x)
945 {
946 	*code |= (m_gfxbank[0] << 8);
947 }
948 
mimonkey_modify_charcode(uint16_t * code,uint8_t x)949 void galaxold_state::mimonkey_modify_charcode(uint16_t *code, uint8_t x)
950 {
951 	*code |= (m_gfxbank[0] << 8) | (m_gfxbank[2] << 9);
952 }
953 
mariner_modify_charcode(uint16_t * code,uint8_t x)954 void galaxold_state::mariner_modify_charcode(uint16_t *code, uint8_t x)
955 {
956 	uint8_t *prom;
957 
958 
959 	/* bit 0 of the PROM controls character banking */
960 
961 	prom = memregion("user2")->base();
962 
963 	*code |= ((prom[x] & 0x01) << 8);
964 }
965 
dambustr_modify_charcode(uint16_t * code,uint8_t x)966 void galaxold_state::dambustr_modify_charcode(uint16_t *code, uint8_t x)
967 {
968 	if (m_dambustr_char_bank == 0) { // text mode
969 		*code |= 0x0300;
970 	}
971 	else {              // graphics mode
972 		if (x == 28)        // only line #28 stays in text mode
973 			*code |= 0x0300;
974 		else
975 			*code &= 0x00ff;
976 	};
977 }
978 
979 
980 
981 /* sprite banking functions */
982 
mshuttle_modify_spritecode(uint8_t * spriteram,int * code,int * flipx,int * flipy,int offs)983 void galaxold_state::mshuttle_modify_spritecode(uint8_t *spriteram, int *code, int *flipx, int *flipy, int offs)
984 {
985 	*code |= ((spriteram[offs + 2] & 0x30) << 2);
986 }
987 
988 
mimonkey_modify_spritecode(uint8_t * spriteram,int * code,int * flipx,int * flipy,int offs)989 void galaxold_state::mimonkey_modify_spritecode(uint8_t *spriteram, int *code, int *flipx, int *flipy, int offs)
990 {
991 	*code |= (m_gfxbank[0] << 6) | (m_gfxbank[2] << 7);
992 }
993 
batman2_modify_spritecode(uint8_t * spriteram,int * code,int * flipx,int * flipy,int offs)994 void galaxold_state::batman2_modify_spritecode(uint8_t *spriteram, int *code, int *flipx, int *flipy, int offs)
995 {
996 	/* only the upper 64 sprites are used */
997 	*code |= 0x40;
998 }
999 
dkongjrm_modify_spritecode(uint8_t * spriteram,int * code,int * flipx,int * flipy,int offs)1000 void galaxold_state::dkongjrm_modify_spritecode(uint8_t *spriteram, int *code, int *flipx, int *flipy, int offs)
1001 {
1002 	/* No x flip */
1003 	*code = (spriteram[offs + 1] & 0x7f) | 0x80;
1004 	*flipx = 0;
1005 }
1006 
dkongjrmc_modify_spritecode(uint8_t * spriteram,int * code,int * flipx,int * flipy,int offs)1007 void galaxold_state::dkongjrmc_modify_spritecode(uint8_t *spriteram, int *code, int *flipx, int *flipy, int offs)
1008 {
1009 	*code = (spriteram[offs + 1] & 0x7f) | 0x80; // bit 6 is also X flip
1010 }
1011 
ad2083_modify_spritecode(uint8_t * spriteram,int * code,int * flipx,int * flipy,int offs)1012 void galaxold_state::ad2083_modify_spritecode(uint8_t *spriteram, int *code, int *flipx, int *flipy, int offs)
1013 {
1014 	/* No x flip */
1015 	*code = (spriteram[offs + 1] & 0x7f) | ((spriteram[offs + 2] & 0x30) << 2);
1016 	*flipx = 0;
1017 }
1018 
dambustr_modify_spritecode(uint8_t * spriteram,int * code,int * flipx,int * flipy,int offs)1019 void galaxold_state::dambustr_modify_spritecode(uint8_t *spriteram, int *code, int *flipx, int *flipy, int offs)
1020 {
1021 	*code += 0x40;
1022 }
1023 
1024 
1025 /* color PROM mapping functions */
1026 
drivfrcg_modify_color(uint8_t * color)1027 void galaxold_state::drivfrcg_modify_color(uint8_t *color)
1028 {
1029 	*color = ((*color & 0x40) >> 3) | (*color & 7);
1030 }
1031 
1032 
1033 /* y position mapping functions */
1034 
1035 
1036 /* bullet drawing functions */
1037 
galaxold_draw_bullets(bitmap_ind16 & bitmap,const rectangle & cliprect,int offs,int x,int y)1038 void galaxold_state::galaxold_draw_bullets(bitmap_ind16 &bitmap, const rectangle &cliprect, int offs, int x, int y)
1039 {
1040 	for (int i = 0; i < 4; i++)
1041 	{
1042 		x--;
1043 
1044 		if (cliprect.contains(x, y))
1045 		{
1046 			/* yellow missile, white shells (this is the terminology on the schematics) */
1047 			int const color = ((offs == 7*4) ? BULLETS_COLOR_BASE : BULLETS_COLOR_BASE + 1);
1048 
1049 			bitmap.pix(y, x) = color;
1050 		}
1051 	}
1052 }
1053 
scrambold_draw_bullets(bitmap_ind16 & bitmap,const rectangle & cliprect,int offs,int x,int y)1054 void galaxold_state::scrambold_draw_bullets(bitmap_ind16 &bitmap, const rectangle &cliprect, int offs, int x, int y)
1055 {
1056 	if (m_flipscreen_x)  x++;
1057 
1058 	x = x - 6;
1059 
1060 	if (cliprect.contains(x, y))
1061 		/* yellow bullets */
1062 		bitmap.pix(y, x) = BULLETS_COLOR_BASE;
1063 }
1064 
darkplnt_draw_bullets(bitmap_ind16 & bitmap,const rectangle & cliprect,int offs,int x,int y)1065 void galaxold_state::darkplnt_draw_bullets(bitmap_ind16 &bitmap, const rectangle &cliprect, int offs, int x, int y)
1066 {
1067 	if (m_flipscreen_x)  x++;
1068 
1069 	x = x - 6;
1070 
1071 	if (cliprect.contains(x, y))
1072 		bitmap.pix(y, x) = 32 + m_darkplnt_bullet_color;
1073 }
1074 
dambustr_draw_bullets(bitmap_ind16 & bitmap,const rectangle & cliprect,int offs,int x,int y)1075 void galaxold_state::dambustr_draw_bullets(bitmap_ind16 &bitmap, const rectangle &cliprect, int offs, int x, int y)
1076 {
1077 	if (flip_screen_x())  x++;
1078 
1079 	x = x - 6;
1080 
1081 	/* bullets are 2 pixels wide */
1082 	for (int i = 0; i < 2; i++)
1083 	{
1084 		int color;
1085 		if (offs < 4*4)
1086 		{
1087 			color = BULLETS_COLOR_BASE;
1088 			y--;
1089 		}
1090 		else
1091 		{
1092 			color = BULLETS_COLOR_BASE + 1;
1093 			x--;
1094 		}
1095 
1096 		if (cliprect.contains(x, y))
1097 			bitmap.pix(y, x) = color;
1098 	}
1099 }
1100 
1101 
1102 
1103 /* background drawing functions */
1104 
galaxold_draw_background(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)1105 void galaxold_state::galaxold_draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
1106 {
1107 	/* plain black background */
1108 	bitmap.fill(0, cliprect);
1109 }
1110 
scrambold_draw_background(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)1111 void galaxold_state::scrambold_draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
1112 {
1113 	if (m_background_enable)
1114 		bitmap.fill(BACKGROUND_COLOR_BASE, cliprect);
1115 	else
1116 		bitmap.fill(0, cliprect);
1117 }
1118 
ad2083_draw_background(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)1119 void galaxold_state::ad2083_draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
1120 {
1121 	int color = (m_background_blue << 2) | (m_background_green << 1) | m_background_red;
1122 
1123 	bitmap.fill(BACKGROUND_COLOR_BASE + color, cliprect);
1124 }
1125 
stratgyx_draw_background(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)1126 void galaxold_state::stratgyx_draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
1127 {
1128 	uint8_t x;
1129 	uint8_t *prom;
1130 	int base = BACKGROUND_COLOR_BASE;
1131 
1132 
1133 	/* the background PROM is connected the following way:
1134 
1135 	   bit 0 = 0 enables the blue gun if BCB is asserted
1136 	   bit 1 = 0 enables the red gun if BCR is asserted and
1137 	             the green gun if BCG is asserted
1138 	   bits 2-7 are unconnected */
1139 
1140 	prom = memregion("user1")->base();
1141 
1142 	for (x = 0; x < 32; x++)
1143 	{
1144 		int sx,color;
1145 
1146 
1147 		color = 0;
1148 
1149 		if ((~prom[x] & 0x02) && m_background_red)   color |= 0x01;
1150 		if ((~prom[x] & 0x02) && m_background_green) color |= 0x02;
1151 		if ((~prom[x] & 0x01) && m_background_blue)  color |= 0x04;
1152 
1153 		if (m_flipscreen_x)
1154 			sx = 8 * (31 - x);
1155 		else
1156 			sx = 8 * x;
1157 
1158 		bitmap.plot_box(sx, 0, 8, 256, base + color);
1159 	}
1160 }
1161 
minefld_draw_background(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)1162 void galaxold_state::minefld_draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
1163 {
1164 	if (m_background_enable)
1165 	{
1166 		int base = BACKGROUND_COLOR_BASE;
1167 		int x;
1168 
1169 
1170 		for (x = 0; x < 128; x++)
1171 			bitmap.plot_box(x,       0, 1, 256, base + x);
1172 
1173 		for (x = 0; x < 120; x++)
1174 			bitmap.plot_box(x + 128, 0, 1, 256, base + x + 128);
1175 
1176 		bitmap.plot_box(248, 0, 16, 256, base);
1177 	}
1178 	else
1179 		bitmap.fill(0, cliprect);
1180 }
1181 
rescue_draw_background(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)1182 void galaxold_state::rescue_draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
1183 {
1184 	if (m_background_enable)
1185 	{
1186 		int base = BACKGROUND_COLOR_BASE;
1187 		int x;
1188 
1189 		for (x = 0; x < 128; x++)
1190 			bitmap.plot_box(x,       0, 1, 256, base + x);
1191 
1192 		for (x = 0; x < 120; x++)
1193 			bitmap.plot_box(x + 128, 0, 1, 256, base + x + 8);
1194 
1195 		bitmap.plot_box(248, 0, 16, 256, base);
1196 	}
1197 	else
1198 		bitmap.fill(0, cliprect);
1199 }
1200 
mariner_draw_background(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)1201 void galaxold_state::mariner_draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
1202 {
1203 	int base = BACKGROUND_COLOR_BASE;
1204 	uint8_t x;
1205 	uint8_t *prom;
1206 
1207 
1208 	/* the background PROM contains the color codes for each 8 pixel
1209 	   line (column) of the screen.  The first 0x20 bytes for unflipped,
1210 	   and the 2nd 0x20 bytes for flipped screen. */
1211 
1212 	prom = memregion("user1")->base();
1213 
1214 	if (m_flipscreen_x)
1215 	{
1216 		for (x = 0; x < 32; x++)
1217 		{
1218 			int color;
1219 
1220 			if (x == 0)
1221 				color = 0;
1222 			else
1223 				color = prom[0x20 + x - 1];
1224 
1225 			bitmap.plot_box(8 * (31 - x), 0, 8, 256, base + color);
1226 		}
1227 	}
1228 	else
1229 	{
1230 		for (x = 0; x < 32; x++)
1231 		{
1232 			int color;
1233 
1234 			if (x == 31)
1235 				color = 0;
1236 			else
1237 				color = prom[x + 1];
1238 
1239 			bitmap.plot_box(8 * x, 0, 8, 256, base + color);
1240 		}
1241 	}
1242 }
1243 
dambustr_draw_background(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)1244 void galaxold_state::dambustr_draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
1245 {
1246 	int base = BACKGROUND_COLOR_BASE;
1247 	int col1 = base + m_dambustr_bg_color_1;
1248 	int col2 = base + m_dambustr_bg_color_2;
1249 
1250 	if (flip_screen_x())
1251 	{
1252 		bitmap.plot_box(  0, 0, 256-m_dambustr_bg_split_line, 256, col2);
1253 		bitmap.plot_box(256-m_dambustr_bg_split_line, 0, m_dambustr_bg_split_line, 256, col1);
1254 	}
1255 	else
1256 	{
1257 		bitmap.plot_box(  0, 0, 256-m_dambustr_bg_split_line, 256, col1);
1258 		bitmap.plot_box(256-m_dambustr_bg_split_line, 0, m_dambustr_bg_split_line, 256, col2);
1259 	}
1260 
1261 }
1262 
dambustr_draw_upper_background(bitmap_ind16 & bitmap,const rectangle & cliprect)1263 void galaxold_state::dambustr_draw_upper_background(bitmap_ind16 &bitmap, const rectangle &cliprect)
1264 {
1265 	if (flip_screen_x())
1266 	{
1267 		rectangle clip(254 - m_dambustr_bg_split_line, m_dambustr_bg_split_line, 0, 255);
1268 		copybitmap(bitmap, *m_dambustr_tmpbitmap, 0, 0, 0, 0, clip);
1269 	}
1270 	else
1271 	{
1272 		rectangle clip(0, 254 - m_dambustr_bg_split_line, 0, 255);
1273 		copybitmap(bitmap, *m_dambustr_tmpbitmap, 0, 0, 0, 0, clip);
1274 	}
1275 }
1276 
1277 
1278 
1279 /* star drawing functions */
1280 
galaxold_init_stars(int colors_offset)1281 void galaxold_state::galaxold_init_stars(int colors_offset)
1282 {
1283 	struct star_gold *stars = m_stars;
1284 	int i;
1285 	int total_stars;
1286 	uint32_t generator;
1287 	int x,y;
1288 
1289 
1290 	m_stars_on = 0;
1291 	m_stars_blink_state = 0;
1292 	m_stars_blink_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(galaxold_state::stars_blink_callback),this));
1293 	m_stars_scroll_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(galaxold_state::stars_scroll_callback),this));
1294 	m_timer_adjusted = 0;
1295 	m_stars_colors_start = colors_offset;
1296 
1297 	for (i = 0;i < 64;i++)
1298 	{
1299 		int bits,r,g,b;
1300 		static const int map[4] = { 0x00, 0x88, 0xcc, 0xff };
1301 
1302 
1303 		bits = (i >> 0) & 0x03;
1304 		r = map[bits];
1305 		bits = (i >> 2) & 0x03;
1306 		g = map[bits];
1307 		bits = (i >> 4) & 0x03;
1308 		b = map[bits];
1309 		m_palette->set_pen_color(colors_offset+i,r,g,b);
1310 	}
1311 
1312 
1313 	/* precalculate the star background */
1314 
1315 	total_stars = 0;
1316 	generator = 0;
1317 
1318 	for (y = 0;y < 256;y++)
1319 	{
1320 		for (x = 0;x < 512;x++)
1321 		{
1322 			uint32_t bit0;
1323 
1324 
1325 			bit0 = ((~generator >> 16) & 0x01) ^ ((generator >> 4) & 0x01);
1326 
1327 			generator = (generator << 1) | bit0;
1328 
1329 			if (((~generator >> 16) & 0x01) && (generator & 0xff) == 0xff)
1330 			{
1331 				int color;
1332 
1333 
1334 				color = (~(generator >> 8)) & 0x3f;
1335 				if (color)
1336 				{
1337 					stars[total_stars].x = x;
1338 					stars[total_stars].y = y;
1339 					stars[total_stars].color = color;
1340 
1341 					total_stars++;
1342 				}
1343 			}
1344 		}
1345 	}
1346 
1347 	if (total_stars != STAR_COUNT)
1348 	{
1349 		fatalerror("total_stars = %d, STAR_COUNT = %d\n",total_stars,STAR_COUNT);
1350 	}
1351 }
1352 
plot_star(bitmap_ind16 & bitmap,int x,int y,int color,const rectangle & cliprect)1353 void galaxold_state::plot_star(bitmap_ind16 &bitmap, int x, int y, int color, const rectangle &cliprect)
1354 {
1355 	if (m_flipscreen_x)
1356 		x = 255 - x;
1357 
1358 	if (m_flipscreen_y)
1359 		y = 255 - y;
1360 
1361 	if (cliprect.contains(x, y))
1362 		bitmap.pix(y, x) = m_stars_colors_start + color;
1363 }
1364 
noop_draw_stars(bitmap_ind16 & bitmap,const rectangle & cliprect)1365 void galaxold_state::noop_draw_stars(bitmap_ind16 &bitmap, const rectangle &cliprect)
1366 {
1367 }
1368 
galaxold_draw_stars(bitmap_ind16 & bitmap,const rectangle & cliprect)1369 void galaxold_state::galaxold_draw_stars(bitmap_ind16 &bitmap, const rectangle &cliprect)
1370 {
1371 	struct star_gold *stars = m_stars;
1372 	int offs;
1373 
1374 
1375 	if (!m_timer_adjusted)
1376 	{
1377 		start_stars_scroll_timer();
1378 		m_timer_adjusted = 1;
1379 	}
1380 
1381 
1382 	for (offs = 0;offs < STAR_COUNT;offs++)
1383 	{
1384 		int x,y;
1385 
1386 
1387 		x = ((stars[offs].x +   m_stars_scrollpos) & 0x01ff) >> 1;
1388 		y = ( stars[offs].y + ((m_stars_scrollpos + stars[offs].x) >> 9)) & 0xff;
1389 
1390 		if ((y & 0x01) ^ ((x >> 3) & 0x01))
1391 		{
1392 			plot_star(bitmap, x, y, stars[offs].color, cliprect);
1393 		}
1394 	}
1395 }
1396 
scrambold_draw_stars(bitmap_ind16 & bitmap,const rectangle & cliprect)1397 void galaxold_state::scrambold_draw_stars(bitmap_ind16 &bitmap, const rectangle &cliprect)
1398 {
1399 	struct star_gold *stars = m_stars;
1400 	int offs;
1401 
1402 
1403 	if (!m_timer_adjusted)
1404 	{
1405 		start_stars_blink_timer(100000, 10000, 0.00001);
1406 		m_timer_adjusted = 1;
1407 	}
1408 
1409 
1410 	for (offs = 0;offs < STAR_COUNT;offs++)
1411 	{
1412 		int x,y;
1413 
1414 
1415 		x = stars[offs].x >> 1;
1416 		y = stars[offs].y;
1417 
1418 		if ((y & 0x01) ^ ((x >> 3) & 0x01))
1419 		{
1420 			/* determine when to skip plotting */
1421 			switch (m_stars_blink_state & 0x03)
1422 			{
1423 			case 0:
1424 				if (!(stars[offs].color & 0x01))  continue;
1425 				break;
1426 			case 1:
1427 				if (!(stars[offs].color & 0x04))  continue;
1428 				break;
1429 			case 2:
1430 				if (!(stars[offs].y & 0x02))  continue;
1431 				break;
1432 			case 3:
1433 				/* always plot */
1434 				break;
1435 			}
1436 
1437 			plot_star(bitmap, x, y, stars[offs].color, cliprect);
1438 		}
1439 	}
1440 }
1441 
rescue_draw_stars(bitmap_ind16 & bitmap,const rectangle & cliprect)1442 void galaxold_state::rescue_draw_stars(bitmap_ind16 &bitmap, const rectangle &cliprect)
1443 {
1444 	struct star_gold *stars = m_stars;
1445 	int offs;
1446 
1447 
1448 	/* same as Scramble, but only top (left) half of screen */
1449 
1450 	if (!m_timer_adjusted)
1451 	{
1452 		start_stars_blink_timer(100000, 10000, 0.00001);
1453 		m_timer_adjusted = 1;
1454 	}
1455 
1456 
1457 	for (offs = 0;offs < STAR_COUNT;offs++)
1458 	{
1459 		int x,y;
1460 
1461 
1462 		x = stars[offs].x >> 1;
1463 		y = stars[offs].y;
1464 
1465 		if ((x < 128) && ((y & 0x01) ^ ((x >> 3) & 0x01)))
1466 		{
1467 			/* determine when to skip plotting */
1468 			switch (m_stars_blink_state & 0x03)
1469 			{
1470 			case 0:
1471 				if (!(stars[offs].color & 0x01))  continue;
1472 				break;
1473 			case 1:
1474 				if (!(stars[offs].color & 0x04))  continue;
1475 				break;
1476 			case 2:
1477 				if (!(stars[offs].y & 0x02))  continue;
1478 				break;
1479 			case 3:
1480 				/* always plot */
1481 				break;
1482 			}
1483 
1484 			plot_star(bitmap, x, y, stars[offs].color, cliprect);
1485 		}
1486 	}
1487 }
1488 
mariner_draw_stars(bitmap_ind16 & bitmap,const rectangle & cliprect)1489 void galaxold_state::mariner_draw_stars(bitmap_ind16 &bitmap, const rectangle &cliprect)
1490 {
1491 	struct star_gold *stars = m_stars;
1492 	int offs;
1493 	uint8_t *prom;
1494 
1495 
1496 	if (!m_timer_adjusted)
1497 	{
1498 		start_stars_scroll_timer();
1499 		m_timer_adjusted = 1;
1500 	}
1501 
1502 
1503 	/* bit 2 of the PROM controls star visibility */
1504 
1505 	prom = memregion("user2")->base();
1506 
1507 	for (offs = 0;offs < STAR_COUNT;offs++)
1508 	{
1509 		int x,y;
1510 
1511 
1512 		x = ((stars[offs].x +   -m_stars_scrollpos) & 0x01ff) >> 1;
1513 		y = ( stars[offs].y + ((-m_stars_scrollpos + stars[offs].x) >> 9)) & 0xff;
1514 
1515 		if ((y & 0x01) ^ ((x >> 3) & 0x01))
1516 		{
1517 			if (prom[(x/8 + 1) & 0x1f] & 0x04)
1518 			{
1519 				plot_star(bitmap, x, y, stars[offs].color, cliprect);
1520 			}
1521 		}
1522 	}
1523 }
1524 
TIMER_CALLBACK_MEMBER(galaxold_state::stars_blink_callback)1525 TIMER_CALLBACK_MEMBER(galaxold_state::stars_blink_callback)
1526 {
1527 	m_stars_blink_state++;
1528 }
1529 
start_stars_blink_timer(double ra,double rb,double c)1530 void galaxold_state::start_stars_blink_timer(double ra, double rb, double c)
1531 {
1532 	/* calculate the period using the formula given in the 555 datasheet */
1533 
1534 	int period_in_ms = 693 * (ra + 2.0 * rb) * c;
1535 
1536 	m_stars_blink_timer->adjust(attotime::from_msec(period_in_ms), 0, attotime::from_msec(period_in_ms));
1537 }
1538 
1539 
TIMER_CALLBACK_MEMBER(galaxold_state::stars_scroll_callback)1540 TIMER_CALLBACK_MEMBER(galaxold_state::stars_scroll_callback)
1541 {
1542 	if (m_stars_on)
1543 	{
1544 		m_stars_scrollpos++;
1545 	}
1546 }
1547 
start_stars_scroll_timer()1548 void galaxold_state::start_stars_scroll_timer()
1549 {
1550 	m_stars_scroll_timer->adjust(m_screen->frame_period(), 0, m_screen->frame_period());
1551 }
1552 
1553 
1554 
TILE_GET_INFO_MEMBER(galaxold_state::get_tile_info)1555 TILE_GET_INFO_MEMBER(galaxold_state::get_tile_info)
1556 {
1557 	uint8_t x = tile_index & 0x1f;
1558 
1559 	uint16_t code = m_videoram[tile_index];
1560 	uint8_t color = m_attributesram[(x << 1) | 1] & m_color_mask;
1561 
1562 	if (m_modify_charcode)
1563 	{
1564 		(this->*m_modify_charcode)(&code, x);
1565 	}
1566 
1567 	if (m_modify_color)
1568 	{
1569 		(this->*m_modify_color)(&color);
1570 	}
1571 
1572 	tileinfo.set(0, code, color, 0);
1573 }
1574 
TILE_GET_INFO_MEMBER(galaxold_state::rockclim_get_tile_info)1575 TILE_GET_INFO_MEMBER(galaxold_state::rockclim_get_tile_info)
1576 {
1577 	uint16_t code = m_rockclim_videoram[tile_index];
1578 	tileinfo.set(2, code, 0, 0);
1579 }
1580 
draw_bullets_common(bitmap_ind16 & bitmap,const rectangle & cliprect)1581 void galaxold_state::draw_bullets_common(bitmap_ind16 &bitmap, const rectangle &cliprect)
1582 {
1583 	int offs;
1584 
1585 
1586 	for (offs = 0;offs < m_bulletsram.bytes();offs += 4)
1587 	{
1588 		uint8_t sx,sy;
1589 
1590 		sy = 255 - m_bulletsram[offs + 1];
1591 		sx = 255 - m_bulletsram[offs + 3];
1592 
1593 		if (m_flipscreen_y)  sy = 255 - sy;
1594 
1595 		(this->*m_draw_bullets)(bitmap, cliprect, offs, sx, sy);
1596 	}
1597 }
1598 
1599 
draw_sprites(bitmap_ind16 & bitmap,uint8_t * spriteram,size_t spriteram_size)1600 void galaxold_state::draw_sprites(bitmap_ind16 &bitmap, uint8_t *spriteram, size_t spriteram_size)
1601 {
1602 	const rectangle spritevisiblearea((0+m_leftclip)*8+1, 32*8-1, 2*8,   30*8-1);
1603 	const rectangle spritevisibleareaflipx(0*8, (32-m_leftclip)*8-2, 2*8, 30*8-1);
1604 
1605 	int offs;
1606 
1607 
1608 	for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
1609 	{
1610 		uint8_t sx,sy,color;
1611 		int flipx,flipy,code;
1612 
1613 
1614 		sx = spriteram[offs + 3] + 1;   /* the existence of +1 is supported by a LOT of games */
1615 		sy = spriteram[offs];           /* Anteater, Mariner, for example */
1616 		flipx = spriteram[offs + 1] & 0x40;
1617 		flipy = spriteram[offs + 1] & 0x80;
1618 		code = spriteram[offs + 1] & 0x3f;
1619 		color = spriteram[offs + 2] & m_color_mask;
1620 
1621 		if (m_modify_spritecode)
1622 		{
1623 			(this->*m_modify_spritecode)(spriteram, &code, &flipx, &flipy, offs);
1624 		}
1625 
1626 		if (m_modify_color)
1627 		{
1628 			(this->*m_modify_color)(&color);
1629 		}
1630 
1631 		if (m_modify_ypos)
1632 		{
1633 			(this->*m_modify_ypos)(&sy);
1634 		}
1635 
1636 		if (m_flipscreen_x)
1637 		{
1638 			sx = 240 - sx;
1639 			flipx = !flipx;
1640 		}
1641 
1642 		if (m_flipscreen_y)
1643 		{
1644 			flipy = !flipy;
1645 		}
1646 		else
1647 		{
1648 			sy = 240 - sy;
1649 		}
1650 
1651 
1652 		/* In at least Amidar Turtles, sprites #0, #1 and #2 need to be moved */
1653 		/* down (left) one pixel to be positioned correctly. */
1654 		/* Note that the adjustment must be done AFTER handling flipscreen, thus */
1655 		/* proving that this is a hardware related "feature" */
1656 
1657 		if (offs < 3*4)  sy++;
1658 
1659 
1660 		m_gfxdecode->gfx(1)->transpen(bitmap,m_flipscreen_x ? spritevisibleareaflipx : spritevisiblearea,
1661 				code,color,
1662 				flipx,flipy,
1663 				sx,sy,0);
1664 	}
1665 }
1666 
1667 
screen_update_galaxold(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)1668 uint32_t galaxold_state::screen_update_galaxold(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
1669 {
1670 	(this->*m_draw_background)(screen, bitmap, cliprect);
1671 
1672 	if (m_stars_on)
1673 	{
1674 		(this->*m_draw_stars)(bitmap, cliprect);
1675 	}
1676 
1677 
1678 	m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
1679 
1680 	if (m_draw_bullets)
1681 	{
1682 		draw_bullets_common(bitmap, cliprect);
1683 	}
1684 
1685 
1686 	draw_sprites(bitmap, m_spriteram, m_spriteram.bytes());
1687 
1688 	if (m_spriteram2_present)
1689 	{
1690 		draw_sprites(bitmap, m_spriteram2, m_spriteram2.bytes());
1691 	}
1692 	return 0;
1693 }
1694 
1695 
screen_update_dambustr(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)1696 uint32_t galaxold_state::screen_update_dambustr(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
1697 {
1698 	int i, j;
1699 	uint8_t color;
1700 
1701 	(this->*m_draw_background)(screen, bitmap, cliprect);
1702 
1703 	if (m_stars_on)
1704 	{
1705 		(this->*m_draw_stars)(bitmap, cliprect);
1706 	}
1707 
1708 	/* save the background for drawing it again later, if background has priority over characters */
1709 	copybitmap(*m_dambustr_tmpbitmap, bitmap, 0, 0, 0, 0, m_dambustr_tmpbitmap->cliprect());
1710 
1711 	m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
1712 
1713 	if (m_draw_bullets)
1714 	{
1715 		draw_bullets_common(bitmap, cliprect);
1716 	}
1717 
1718 	draw_sprites(bitmap, m_spriteram, m_spriteram.bytes());
1719 
1720 	if (m_dambustr_bg_priority)
1721 	{
1722 		/* draw the upper part of the background, as it has priority */
1723 		dambustr_draw_upper_background(bitmap, cliprect);
1724 
1725 		/* only rows with color code > 3 are stronger than the background */
1726 		memset(m_dambustr_videoram2.get(), 0x20, 0x0400);
1727 		for (i=0; i<32; i++) {
1728 			color = m_attributesram[(i << 1) | 1] & m_color_mask;
1729 			if (color > 3) {
1730 				for (j=0; j<32; j++)
1731 					m_dambustr_videoram2[32*j+i] = m_videoram[32*j+i];
1732 			};
1733 		};
1734 		m_dambustr_tilemap2->mark_all_dirty();
1735 		m_dambustr_tilemap2->draw(screen, bitmap, cliprect, 0, 0);
1736 	};
1737 
1738 	return 0;
1739 }
1740 
bagmanmc_modify_charcode(uint16_t * code,uint8_t x)1741 void galaxold_state::bagmanmc_modify_charcode(uint16_t *code, uint8_t x)
1742 {
1743 	*code |= (m_gfxbank[0] << 9);
1744 }
1745 
bagmanmc_modify_spritecode(uint8_t * spriteram,int * code,int * flipx,int * flipy,int offs)1746 void galaxold_state::bagmanmc_modify_spritecode(uint8_t *spriteram, int *code, int *flipx, int *flipy, int offs)
1747 {
1748 	*code |= (m_gfxbank[0] << 7) | 0x40;
1749 }
1750 
VIDEO_START_MEMBER(galaxold_state,bagmanmc)1751 VIDEO_START_MEMBER(galaxold_state,bagmanmc)
1752 {
1753 	VIDEO_START_CALL_MEMBER(galaxold);
1754 
1755 	m_modify_charcode = &galaxold_state::bagmanmc_modify_charcode;
1756 	m_modify_spritecode = &galaxold_state::bagmanmc_modify_spritecode;
1757 }
1758