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