summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/galaxian.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/galaxian.c')
-rw-r--r--src/mame/video/galaxian.c2243
1 files changed, 2243 insertions, 0 deletions
diff --git a/src/mame/video/galaxian.c b/src/mame/video/galaxian.c
new file mode 100644
index 00000000000..c331bce0c15
--- /dev/null
+++ b/src/mame/video/galaxian.c
@@ -0,0 +1,2243 @@
+/***************************************************************************
+
+ Galaxian hardware family
+
+***************************************************************************/
+
+#include "driver.h"
+#include "includes/galaxian.h"
+
+static rectangle _spritevisiblearea =
+{
+ 2*8+1, 32*8-1,
+ 2*8, 30*8-1
+};
+static rectangle _spritevisibleareaflipx =
+{
+ 0*8, 30*8-2,
+ 2*8, 30*8-1
+};
+
+static rectangle* spritevisiblearea;
+static rectangle* spritevisibleareaflipx;
+
+
+#define STARS_COLOR_BASE (memory_region_length(REGION_PROMS))
+#define BULLETS_COLOR_BASE (STARS_COLOR_BASE + 64)
+#define BACKGROUND_COLOR_BASE (BULLETS_COLOR_BASE + 2)
+
+
+UINT8 *galaxian_videoram;
+UINT8 *galaxian_spriteram;
+UINT8 *galaxian_spriteram2;
+UINT8 *galaxian_attributesram;
+UINT8 *galaxian_bulletsram;
+UINT8 *rockclim_videoram;
+size_t galaxian_spriteram_size;
+size_t galaxian_spriteram2_size;
+size_t galaxian_bulletsram_size;
+
+
+static TILE_GET_INFO( get_tile_info );
+static TILE_GET_INFO( rockclim_get_tile_info );
+static tilemap *bg_tilemap;
+static tilemap *rockclim_tilemap;
+static int mooncrst_gfxextend;
+static int spriteram2_present;
+static UINT8 gfxbank[5];
+static UINT8 flipscreen_x;
+static UINT8 flipscreen_y;
+static UINT8 color_mask;
+static tilemap *dambustr_tilemap2;
+static UINT8 *dambustr_videoram2;
+static void (*modify_charcode)(UINT16 *code,UINT8 x); /* function to call to do character banking */
+static void gmgalax_modify_charcode(UINT16 *code,UINT8 x);
+static void mooncrst_modify_charcode(UINT16 *code,UINT8 x);
+static void mooncrgx_modify_charcode(UINT16 *code,UINT8 x);
+static void moonqsr_modify_charcode(UINT16 *code,UINT8 x);
+static void mshuttle_modify_charcode(UINT16 *code,UINT8 x);
+static void pisces_modify_charcode(UINT16 *code,UINT8 x);
+static void mimonkey_modify_charcode(UINT16 *code,UINT8 x);
+static void batman2_modify_charcode(UINT16 *code,UINT8 x);
+static void mariner_modify_charcode(UINT16 *code,UINT8 x);
+static void jumpbug_modify_charcode(UINT16 *code,UINT8 x);
+static void dambustr_modify_charcode(UINT16 *code,UINT8 x);
+
+static void (*modify_spritecode)(UINT8 *spriteram,int*,int*,int*,int); /* function to call to do sprite banking */
+static void gmgalax_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs);
+static void mooncrst_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs);
+static void mooncrgx_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs);
+static void moonqsr_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs);
+static void mshuttle_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs);
+static void calipso_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs);
+static void pisces_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs);
+static void mimonkey_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs);
+static void batman2_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs);
+static void jumpbug_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs);
+static void dkongjrm_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs);
+static void ad2083_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs);
+static void dambustr_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs);
+
+static void (*modify_color)(UINT8 *color); /* function to call to do modify how the color codes map to the PROM */
+static void frogger_modify_color(UINT8 *color);
+static void gmgalax_modify_color(UINT8 *color);
+static void drivfrcg_modify_color(UINT8 *color);
+
+static void (*modify_ypos)(UINT8*); /* function to call to do modify how vertical positioning bits are connected */
+static void frogger_modify_ypos(UINT8 *sy);
+
+static TIMER_CALLBACK( stars_blink_callback );
+static TIMER_CALLBACK( stars_scroll_callback );
+
+static void (*tilemap_set_scroll)( tilemap *, int col, int value );
+
+/* star circuit */
+#define STAR_COUNT 252
+struct star
+{
+ int x,y,color;
+};
+static struct star stars[STAR_COUNT];
+static int stars_colors_start;
+ UINT8 galaxian_stars_on;
+static INT32 stars_scrollpos;
+static UINT8 stars_blink_state;
+static emu_timer *stars_blink_timer;
+static emu_timer *stars_scroll_timer;
+static UINT8 timer_adjusted;
+ void galaxian_init_stars(running_machine *machine, int colors_offset);
+static void (*draw_stars)(running_machine *, mame_bitmap *); /* function to call to draw the star layer */
+static void noop_draw_stars(running_machine *machine, mame_bitmap *bitmap);
+ void galaxian_draw_stars(running_machine *machine, mame_bitmap *bitmap);
+static void scramble_draw_stars(running_machine *machine, mame_bitmap *bitmap);
+static void rescue_draw_stars(running_machine *machine, mame_bitmap *bitmap);
+static void mariner_draw_stars(running_machine *machine, mame_bitmap *bitmap);
+static void jumpbug_draw_stars(running_machine *machine, mame_bitmap *bitmap);
+static void start_stars_blink_timer(double ra, double rb, double c);
+static void start_stars_scroll_timer(void);
+
+/* bullets circuit */
+static UINT8 darkplnt_bullet_color;
+static void (*draw_bullets)(running_machine *, mame_bitmap *,int,int,int); /* function to call to draw a bullet */
+static void galaxian_draw_bullets(running_machine *machine, mame_bitmap *bitmap, int offs, int x, int y);
+static void gteikob2_draw_bullets(running_machine *machine, mame_bitmap *bitmap, int offs, int x, int y);
+static void scramble_draw_bullets(running_machine *machine, mame_bitmap *bitmap, int offs, int x, int y);
+static void theend_draw_bullets(running_machine *machine, mame_bitmap *bitmap, int offs, int x, int y);
+static void darkplnt_draw_bullets(running_machine *machine, mame_bitmap *bitmap, int offs, int x, int y);
+static void dambustr_draw_bullets(running_machine *machine, mame_bitmap *bitmap, int offs, int x, int y);
+
+/* background circuit */
+static UINT8 background_enable;
+static UINT8 background_red, background_green, background_blue;
+static void (*draw_background)(running_machine *, mame_bitmap *); /* function to call to draw the background */
+static void galaxian_draw_background(running_machine *machine, mame_bitmap *bitmap);
+static void scramble_draw_background(running_machine *machine, mame_bitmap *bitmap);
+static void turtles_draw_background(running_machine *machine, mame_bitmap *bitmap);
+static void mariner_draw_background(running_machine *machine, mame_bitmap *bitmap);
+static void frogger_draw_background(running_machine *machine, mame_bitmap *bitmap);
+static void stratgyx_draw_background(running_machine *machine, mame_bitmap *bitmap);
+static void minefld_draw_background(running_machine *machine, mame_bitmap *bitmap);
+static void rescue_draw_background(running_machine *machine, mame_bitmap *bitmap);
+static void dambustr_draw_background(running_machine *machine, mame_bitmap *bitmap);
+
+static UINT16 rockclim_v;
+static UINT16 rockclim_h;
+static int dambustr_bg_split_line;
+static int dambustr_bg_color_1;
+static int dambustr_bg_color_2;
+static int dambustr_bg_priority;
+static int dambustr_char_bank;
+static mame_bitmap *dambustr_tmpbitmap;
+
+
+
+/***************************************************************************
+
+ Convert the color PROMs into a more useable format.
+
+ Galaxian has one 32 bytes palette PROM, connected to the RGB output this way:
+
+ bit 7 -- 220 ohm resistor -- BLUE
+ -- 470 ohm resistor -- BLUE
+ -- 220 ohm resistor -- GREEN
+ -- 470 ohm resistor -- GREEN
+ -- 1 kohm resistor -- GREEN
+ -- 220 ohm resistor -- RED
+ -- 470 ohm resistor -- RED
+ bit 0 -- 1 kohm resistor -- RED
+
+ The output of the background star generator is connected this way:
+
+ bit 5 -- 100 ohm resistor -- BLUE
+ -- 150 ohm resistor -- BLUE
+ -- 100 ohm resistor -- GREEN
+ -- 150 ohm resistor -- GREEN
+ -- 100 ohm resistor -- RED
+ bit 0 -- 150 ohm resistor -- RED
+
+ The blue background in Scramble and other games goes through a 390 ohm
+ resistor.
+
+ The bullet RGB outputs go through 100 ohm resistors.
+
+ The RGB outputs have a 470 ohm pull-down each.
+
+***************************************************************************/
+PALETTE_INIT( galaxian )
+{
+ int i;
+
+
+ /* first, the character/sprite palette */
+
+ for (i = 0;i < memory_region_length(REGION_PROMS);i++)
+ {
+ int bit0,bit1,bit2,r,g,b;
+
+ /* red component */
+ bit0 = BIT(*color_prom,0);
+ bit1 = BIT(*color_prom,1);
+ bit2 = BIT(*color_prom,2);
+ r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+ /* green component */
+ bit0 = BIT(*color_prom,3);
+ bit1 = BIT(*color_prom,4);
+ bit2 = BIT(*color_prom,5);
+ g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+ /* blue component */
+ bit0 = BIT(*color_prom,6);
+ bit1 = BIT(*color_prom,7);
+ b = 0x4f * bit0 + 0xa8 * bit1;
+
+ palette_set_color_rgb(machine,i,r,g,b);
+ color_prom++;
+ }
+
+
+ galaxian_init_stars(machine, STARS_COLOR_BASE);
+
+
+ /* bullets - yellow and white */
+ palette_set_color(machine,BULLETS_COLOR_BASE+0,MAKE_RGB(0xef,0xef,0x00));
+ palette_set_color(machine,BULLETS_COLOR_BASE+1,MAKE_RGB(0xef,0xef,0xef));
+}
+
+PALETTE_INIT( scramble )
+{
+ palette_init_galaxian(machine, colortable, color_prom);
+
+
+ /* blue background - 390 ohm resistor */
+ palette_set_color(machine,BACKGROUND_COLOR_BASE,MAKE_RGB(0,0,0x56));
+}
+
+PALETTE_INIT( moonwar )
+{
+ palette_init_scramble(machine, colortable, color_prom);
+
+
+ /* wire mod to connect the bullet blue output to the 220 ohm resistor */
+ palette_set_color(machine,BULLETS_COLOR_BASE+0,MAKE_RGB(0xef,0xef,0x97));
+}
+
+PALETTE_INIT( turtles )
+{
+ int i;
+
+
+ palette_init_galaxian(machine, colortable, color_prom);
+
+
+ /* The background color generator is connected this way:
+
+ RED - 390 ohm resistor
+ GREEN - 470 ohm resistor
+ BLUE - 390 ohm resistor */
+
+ for (i = 0; i < 8; i++)
+ {
+ int r = BIT(i,0) * 0x55;
+ int g = BIT(i,1) * 0x47;
+ int b = BIT(i,2) * 0x55;
+
+ palette_set_color_rgb(machine,BACKGROUND_COLOR_BASE+i,r,g,b);
+ }
+}
+
+PALETTE_INIT( stratgyx )
+{
+ int i;
+
+
+ palette_init_galaxian(machine, colortable, color_prom);
+
+
+ /* The background color generator is connected this way:
+
+ RED - 270 ohm resistor
+ GREEN - 560 ohm resistor
+ BLUE - 470 ohm resistor */
+
+ for (i = 0; i < 8; i++)
+ {
+ int r = BIT(i,0) * 0x7c;
+ int g = BIT(i,1) * 0x3c;
+ int b = BIT(i,2) * 0x47;
+
+ palette_set_color_rgb(machine,BACKGROUND_COLOR_BASE+i,r,g,b);
+ }
+}
+
+PALETTE_INIT( frogger )
+{
+ palette_init_galaxian(machine, colortable, color_prom);
+
+
+ /* blue background - 470 ohm resistor */
+ palette_set_color(machine,BACKGROUND_COLOR_BASE,MAKE_RGB(0,0,0x47));
+}
+
+PALETTE_INIT( rockclim )
+{
+ int i;
+
+
+ /* first, the character/sprite palette */
+
+ for (i = 0;i < memory_region_length(REGION_PROMS);i++)
+ {
+ int bit0,bit1,bit2,r,g,b;
+
+ /* red component */
+ bit0 = BIT(*color_prom,0);
+ bit1 = BIT(*color_prom,1);
+ bit2 = BIT(*color_prom,2);
+ r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+ /* green component */
+ bit0 = BIT(*color_prom,3);
+ bit1 = BIT(*color_prom,4);
+ bit2 = BIT(*color_prom,5);
+ g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+ /* blue component */
+ bit0 = BIT(*color_prom,6);
+ bit1 = BIT(*color_prom,7);
+ b = 0x4f * bit0 + 0xa8 * bit1;
+
+ palette_set_color_rgb(machine,i,r,g,b);
+ color_prom++;
+ }
+}
+/***************************************************************************
+
+ Convert the color PROMs into a more useable format.
+
+ Dark Planet has one 32 bytes palette PROM, connected to the RGB output this way:
+
+ bit 5 -- 220 ohm resistor -- BLUE
+ -- 470 ohm resistor -- BLUE
+ -- 1 kohm resistor -- BLUE
+ -- 220 ohm resistor -- RED
+ -- 470 ohm resistor -- RED
+ bit 0 -- 1 kohm resistor -- RED
+
+ The bullet RGB outputs go through 100 ohm resistors.
+
+ The RGB outputs have a 470 ohm pull-down each.
+
+***************************************************************************/
+PALETTE_INIT( darkplnt )
+{
+ int i;
+
+
+ /* first, the character/sprite palette */
+
+ for (i = 0;i < 32;i++)
+ {
+ int bit0,bit1,bit2,r,g,b;
+
+ /* red component */
+ bit0 = BIT(*color_prom,0);
+ bit1 = BIT(*color_prom,1);
+ bit2 = BIT(*color_prom,2);
+ r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+ /* green component */
+ g = 0x00;
+ /* blue component */
+ bit0 = BIT(*color_prom,3);
+ bit1 = BIT(*color_prom,4);
+ bit2 = BIT(*color_prom,5);
+ b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+
+ palette_set_color_rgb(machine,i,r,g,b);
+ color_prom++;
+ }
+
+
+ /* bullets - red and blue */
+ palette_set_color(machine,BULLETS_COLOR_BASE+0,MAKE_RGB(0xef,0x00,0x00));
+ palette_set_color(machine,BULLETS_COLOR_BASE+1,MAKE_RGB(0x00,0x00,0xef));
+}
+
+PALETTE_INIT( minefld )
+{
+ int i;
+
+
+ palette_init_galaxian(machine, colortable, color_prom);
+
+
+ /* set up background colors */
+
+ /* graduated blue */
+
+ for (i = 0; i < 128; i++)
+ {
+ int r = 0;
+ int g = i;
+ int b = i * 2;
+ palette_set_color_rgb(machine,BACKGROUND_COLOR_BASE+i,r,g,b);
+ }
+
+ /* graduated brown */
+
+ for (i = 0; i < 128; i++)
+ {
+ int r = i * 1.5;
+ int g = i * 0.75;
+ int b = i / 2;
+ palette_set_color_rgb(machine,BACKGROUND_COLOR_BASE+128+i,r,g,b);
+ }
+}
+
+PALETTE_INIT( rescue )
+{
+ int i;
+
+
+ palette_init_galaxian(machine, colortable, color_prom);
+
+
+ /* set up background colors */
+
+ /* graduated blue */
+
+ for (i = 0; i < 128; i++)
+ {
+ int r = 0;
+ int g = i;
+ int b = i * 2;
+ palette_set_color_rgb(machine,BACKGROUND_COLOR_BASE+i,r,g,b);
+ }
+}
+
+PALETTE_INIT( mariner )
+{
+ int i;
+
+
+ palette_init_galaxian(machine, colortable, color_prom);
+
+
+ /* set up background colors */
+
+ /* 16 shades of blue - the 4 bits are connected to the following resistors:
+
+ bit 0 -- 4.7 kohm resistor
+ -- 2.2 kohm resistor
+ -- 1 kohm resistor
+ bit 0 -- .47 kohm resistor */
+
+ for (i = 0; i < 16; i++)
+ {
+ int r,g,b;
+
+ r = 0;
+ g = 0;
+ b = 0x0e * BIT(i,0) + 0x1f * BIT(i,1) + 0x43 * BIT(i,2) + 0x8f * BIT(i,3);
+
+ palette_set_color_rgb(machine,BACKGROUND_COLOR_BASE+i,r,g,b);
+ }
+}
+
+
+PALETTE_INIT( dambustr )
+{
+ int i;
+
+ palette_init_galaxian(machine, colortable, color_prom);
+
+
+ /*
+ Assumption (not clear from the schematics):
+ The background color generator is connected this way:
+
+ RED - 470 ohm resistor
+ GREEN - 470 ohm resistor
+ BLUE - 470 ohm resistor */
+
+
+ for (i = 0; i < 8; i++)
+ {
+ int r = BIT(i,0) * 0x47;
+ int g = BIT(i,1) * 0x47;
+ int b = BIT(i,2) * 0x4f;
+ palette_set_color_rgb(machine,BACKGROUND_COLOR_BASE+i,r,g,b);
+ }
+}
+
+
+
+/***************************************************************************
+
+ Start the video hardware emulation.
+
+***************************************************************************/
+
+static void state_save_register(void)
+{
+ state_save_register_global_array(gfxbank);
+ state_save_register_global(flipscreen_x);
+ state_save_register_global(flipscreen_y);
+
+ state_save_register_global(galaxian_stars_on);
+ state_save_register_global(stars_scrollpos);
+ state_save_register_global(stars_blink_state);
+
+ state_save_register_global(darkplnt_bullet_color);
+
+ state_save_register_global(background_enable);
+ state_save_register_global(background_red);
+ state_save_register_global(background_green);
+ state_save_register_global(background_blue);
+}
+
+static void video_start_common(running_machine *machine, tilemap_mapper_callback get_memory_offset)
+{
+ bg_tilemap = tilemap_create(get_tile_info,get_memory_offset,TILEMAP_TYPE_PEN,8,8,32,32);
+ tilemap_set_scrolldx(bg_tilemap, 0, -128);
+
+ tilemap_set_transparent_pen(bg_tilemap,0);
+
+
+ modify_charcode = 0;
+ modify_spritecode = 0;
+ modify_color = 0;
+ modify_ypos = 0;
+
+ mooncrst_gfxextend = 0;
+
+ draw_bullets = 0;
+
+ draw_background = galaxian_draw_background;
+ background_enable = 0;
+ background_blue = 0;
+ background_red = 0;
+ background_green = 0;
+
+ draw_stars = noop_draw_stars;
+
+ flipscreen_x = 0;
+ flipscreen_y = 0;
+
+ spriteram2_present = 0;
+
+ spritevisiblearea = &_spritevisiblearea;
+ spritevisibleareaflipx = &_spritevisibleareaflipx;
+
+ color_mask = (machine->gfx[0]->color_granularity == 4) ? 7 : 3;
+
+ state_save_register();
+}
+
+VIDEO_START( galaxian_plain )
+{
+ video_start_common(machine,tilemap_scan_rows);
+
+ tilemap_set_scroll_cols(bg_tilemap, 32);
+ tilemap_set_scroll = tilemap_set_scrolly;
+}
+
+VIDEO_START( galaxian )
+{
+ video_start_galaxian_plain(machine);
+
+ draw_stars = galaxian_draw_stars;
+
+ draw_bullets = galaxian_draw_bullets;
+}
+
+VIDEO_START( gmgalax )
+{
+ video_start_galaxian(machine);
+
+ modify_charcode = gmgalax_modify_charcode;
+ modify_spritecode = gmgalax_modify_spritecode;
+ modify_color = gmgalax_modify_color;
+}
+
+VIDEO_START( mooncrst )
+{
+ video_start_galaxian(machine);
+
+ modify_charcode = mooncrst_modify_charcode;
+ modify_spritecode = mooncrst_modify_spritecode;
+}
+
+VIDEO_START( mooncrgx )
+{
+ video_start_galaxian(machine);
+
+ modify_charcode = mooncrgx_modify_charcode;
+ modify_spritecode = mooncrgx_modify_spritecode;
+}
+
+VIDEO_START( moonqsr )
+{
+ video_start_galaxian(machine);
+
+ modify_charcode = moonqsr_modify_charcode;
+ modify_spritecode = moonqsr_modify_spritecode;
+}
+
+VIDEO_START( mshuttle )
+{
+ video_start_galaxian(machine);
+
+ modify_charcode = mshuttle_modify_charcode;
+ modify_spritecode = mshuttle_modify_spritecode;
+}
+
+VIDEO_START( pisces )
+{
+ video_start_galaxian(machine);
+
+ modify_charcode = pisces_modify_charcode;
+ modify_spritecode = pisces_modify_spritecode;
+}
+
+VIDEO_START( gteikob2 )
+{
+ video_start_pisces(machine);
+
+ draw_bullets = gteikob2_draw_bullets;
+}
+
+VIDEO_START( batman2 )
+{
+ video_start_galaxian(machine);
+
+ modify_charcode = batman2_modify_charcode;
+ modify_spritecode = batman2_modify_spritecode;
+
+}
+
+VIDEO_START( scramble )
+{
+ video_start_galaxian_plain(machine);
+
+ draw_stars = scramble_draw_stars;
+
+ draw_bullets = scramble_draw_bullets;
+
+ draw_background = scramble_draw_background;
+}
+
+VIDEO_START( sfx )
+{
+ video_start_common(machine,tilemap_scan_cols);
+
+ tilemap_set_scroll_rows(bg_tilemap, 32);
+ tilemap_set_scroll = tilemap_set_scrollx;
+
+ draw_stars = scramble_draw_stars;
+
+ draw_bullets = scramble_draw_bullets;
+
+ draw_background = turtles_draw_background;
+}
+
+VIDEO_START( turtles )
+{
+ video_start_galaxian_plain(machine);
+
+ draw_background = turtles_draw_background;
+}
+
+VIDEO_START( theend )
+{
+ video_start_galaxian(machine);
+
+ draw_bullets = theend_draw_bullets;
+}
+
+VIDEO_START( darkplnt )
+{
+ video_start_galaxian_plain(machine);
+
+ draw_bullets = darkplnt_draw_bullets;
+}
+
+VIDEO_START( rescue )
+{
+ video_start_scramble(machine);
+
+ draw_stars = rescue_draw_stars;
+
+ draw_background = rescue_draw_background;
+}
+
+VIDEO_START( minefld )
+{
+ video_start_scramble(machine);
+
+ draw_stars = rescue_draw_stars;
+
+ draw_background = minefld_draw_background;
+}
+
+VIDEO_START( stratgyx )
+{
+ video_start_galaxian_plain(machine);
+
+ draw_background = stratgyx_draw_background;
+}
+
+VIDEO_START( ckongs )
+{
+ video_start_scramble(machine);
+
+ modify_spritecode = mshuttle_modify_spritecode;
+}
+
+VIDEO_START( calipso )
+{
+ video_start_galaxian_plain(machine);
+
+ draw_bullets = scramble_draw_bullets;
+
+ draw_background = scramble_draw_background;
+
+ modify_spritecode = calipso_modify_spritecode;
+}
+
+VIDEO_START( mariner )
+{
+ video_start_galaxian_plain(machine);
+
+ draw_stars = mariner_draw_stars;
+
+ draw_bullets = scramble_draw_bullets;
+
+ draw_background = mariner_draw_background;
+
+ modify_charcode = mariner_modify_charcode;
+}
+
+VIDEO_START( froggers )
+{
+ video_start_galaxian_plain(machine);
+
+ draw_background = frogger_draw_background;
+ modify_color = frogger_modify_color;
+}
+
+VIDEO_START( frogger )
+{
+ video_start_froggers(machine);
+
+ modify_ypos = frogger_modify_ypos;
+}
+
+VIDEO_START( jumpbug )
+{
+ video_start_scramble(machine);
+
+ draw_stars = jumpbug_draw_stars;
+
+ modify_charcode = jumpbug_modify_charcode;
+ modify_spritecode = jumpbug_modify_spritecode;
+}
+
+VIDEO_START( azurian )
+{
+ video_start_galaxian_plain(machine);
+
+ draw_stars = galaxian_draw_stars;
+ draw_bullets = scramble_draw_bullets; /* Shots are yellow like in Scramble */
+}
+
+VIDEO_START( mimonkey )
+{
+ video_start_scramble(machine);
+
+ modify_charcode = mimonkey_modify_charcode;
+ modify_spritecode = mimonkey_modify_spritecode;
+}
+
+VIDEO_START( dkongjrm )
+{
+ video_start_galaxian_plain(machine);
+
+ modify_charcode = pisces_modify_charcode;
+ modify_spritecode = dkongjrm_modify_spritecode;
+
+ spriteram2_present= 1;
+}
+
+VIDEO_START( newsin7 )
+{
+ video_start_scramble(machine);
+
+ spritevisiblearea = &_spritevisibleareaflipx;
+ spritevisibleareaflipx = &_spritevisiblearea;
+}
+
+VIDEO_START( scorpion )
+{
+ video_start_scramble(machine);
+
+ modify_spritecode = batman2_modify_spritecode;
+}
+
+static void rockclim_draw_background(running_machine *machine, mame_bitmap *bitmap)
+{
+ tilemap_draw(bitmap,0,rockclim_tilemap, 0,0);
+}
+
+static void rockclim_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs)
+{
+ if (gfxbank[2]) *code|=0x40;
+}
+
+VIDEO_START( rockclim )
+{
+ video_start_galaxian(machine);
+ rockclim_tilemap = tilemap_create(rockclim_get_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,64,32);
+ draw_background = rockclim_draw_background;
+ modify_charcode = mooncrst_modify_charcode;
+ modify_spritecode = rockclim_modify_spritecode;
+ rockclim_v = rockclim_h = 0;
+ state_save_register_global(rockclim_v);
+ state_save_register_global(rockclim_h);
+}
+
+static TILE_GET_INFO( drivfrcg_get_tile_info )
+{
+ int code = galaxian_videoram[tile_index];
+ UINT8 x = tile_index & 0x1f;
+ UINT8 color = galaxian_attributesram[(x << 1) | 1] & 7;
+ UINT8 bank = galaxian_attributesram[(x << 1) | 1] & 0x30;
+
+ code |= (bank << 4);
+ color |= ((galaxian_attributesram[(x << 1) | 1] & 0x40) >> 3);
+
+ SET_TILE_INFO(0, code, color, 0);
+}
+
+VIDEO_START( drivfrcg )
+{
+ bg_tilemap = tilemap_create(drivfrcg_get_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32);
+
+ tilemap_set_transparent_pen(bg_tilemap,0);
+ tilemap_set_scroll_cols(bg_tilemap, 32);
+ tilemap_set_scroll = tilemap_set_scrolly;
+
+ modify_charcode = 0;
+ modify_spritecode = mshuttle_modify_spritecode;
+ modify_color = drivfrcg_modify_color;
+ modify_ypos = 0;
+
+ mooncrst_gfxextend = 0;
+
+ draw_bullets = 0;
+
+ draw_background = galaxian_draw_background;
+ background_enable = 0;
+ background_blue = 0;
+ background_red = 0;
+ background_green = 0;
+
+ draw_stars = noop_draw_stars;
+
+ flipscreen_x = 0;
+ flipscreen_y = 0;
+
+ spriteram2_present = 0;
+
+ spritevisiblearea = &_spritevisiblearea;
+ spritevisibleareaflipx = &_spritevisibleareaflipx;
+
+ color_mask = 0xff;
+
+ state_save_register();
+}
+
+VIDEO_START( ad2083 )
+{
+ bg_tilemap = tilemap_create(drivfrcg_get_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32);
+
+ tilemap_set_transparent_pen(bg_tilemap,0);
+ tilemap_set_scroll_cols(bg_tilemap, 32);
+ tilemap_set_scroll = tilemap_set_scrolly;
+
+ modify_charcode = 0;
+ modify_spritecode = ad2083_modify_spritecode;
+ modify_color = 0;
+ modify_ypos = 0;
+
+ mooncrst_gfxextend = 0;
+
+ draw_bullets = scramble_draw_bullets;
+
+ draw_background = turtles_draw_background;
+ background_enable = 0;
+ background_blue = 0;
+ background_red = 0;
+ background_green = 0;
+
+ draw_stars = noop_draw_stars;
+
+ flipscreen_x = 0;
+ flipscreen_y = 0;
+
+ spriteram2_present = 0;
+
+ spritevisiblearea = &_spritevisiblearea;
+ spritevisibleareaflipx = &_spritevisibleareaflipx;
+
+ color_mask = 7;
+
+ state_save_register();
+}
+
+UINT8 *racknrol_tiles_bank;
+
+WRITE8_HANDLER( racknrol_tiles_bank_w )
+{
+ racknrol_tiles_bank[offset] = data;
+ tilemap_mark_all_tiles_dirty(bg_tilemap);
+}
+
+static TILE_GET_INFO( racknrol_get_tile_info )
+{
+ int code = galaxian_videoram[tile_index];
+ UINT8 x = tile_index & 0x1f;
+ UINT8 color = galaxian_attributesram[(x << 1) | 1] & 7;
+ UINT8 bank = racknrol_tiles_bank[x] & 7;
+
+ code |= (bank << 8);
+
+ SET_TILE_INFO(0, code, color, 0);
+}
+
+VIDEO_START( racknrol )
+{
+ bg_tilemap = tilemap_create(racknrol_get_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32);
+
+ tilemap_set_transparent_pen(bg_tilemap,0);
+ tilemap_set_scroll_cols(bg_tilemap, 32);
+ tilemap_set_scroll = tilemap_set_scrolly;
+
+ modify_charcode = 0;
+ modify_spritecode = 0;
+ modify_color = 0;
+ modify_ypos = 0;
+
+ mooncrst_gfxextend = 0;
+
+ draw_bullets = 0;
+
+ draw_background = galaxian_draw_background;
+ background_enable = 0;
+ background_blue = 0;
+ background_red = 0;
+ background_green = 0;
+
+ draw_stars = noop_draw_stars;
+
+ flipscreen_x = 0;
+ flipscreen_y = 0;
+
+ spriteram2_present = 0;
+
+ spritevisiblearea = &_spritevisiblearea;
+ spritevisibleareaflipx = &_spritevisibleareaflipx;
+
+ color_mask = 0xff;
+
+ state_save_register();
+}
+
+VIDEO_START( bongo )
+{
+ video_start_galaxian_plain(machine);
+
+ modify_spritecode = batman2_modify_spritecode;
+}
+
+static TILE_GET_INFO( dambustr_get_tile_info2 )
+{
+ UINT8 x = tile_index & 0x1f;
+
+ UINT16 code = dambustr_videoram2[tile_index];
+ UINT8 color = galaxian_attributesram[(x << 1) | 1] & color_mask;
+
+ if (modify_charcode)
+ {
+ modify_charcode(&code, x);
+ }
+
+ if (modify_color)
+ {
+ modify_color(&color);
+ }
+
+ SET_TILE_INFO(0, code, color, 0);
+}
+
+VIDEO_START( dambustr )
+{
+ video_start_galaxian(machine);
+
+ dambustr_bg_split_line = 0;
+ dambustr_bg_color_1 = 0;
+ dambustr_bg_color_2 = 0;
+ dambustr_bg_priority = 0;
+ dambustr_char_bank = 0;
+
+ draw_background = dambustr_draw_background;
+
+ modify_charcode = dambustr_modify_charcode;
+ modify_spritecode = dambustr_modify_spritecode;
+
+ draw_bullets = dambustr_draw_bullets;
+
+ /* allocate the temporary bitmap for the background priority */
+ dambustr_tmpbitmap = auto_bitmap_alloc(machine->screen[0].width, machine->screen[0].height, machine->screen[0].format);
+
+ /* make a copy of the tilemap to emulate background priority */
+ dambustr_videoram2 = auto_malloc(0x0400);
+ dambustr_tilemap2 = tilemap_create(dambustr_get_tile_info2,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32);
+
+ tilemap_set_transparent_pen(dambustr_tilemap2,0);
+}
+
+
+WRITE8_HANDLER( galaxian_videoram_w )
+{
+ galaxian_videoram[offset] = data;
+ tilemap_mark_tile_dirty(bg_tilemap, offset);
+}
+
+READ8_HANDLER( galaxian_videoram_r )
+{
+ return galaxian_videoram[offset];
+}
+
+
+WRITE8_HANDLER( galaxian_attributesram_w )
+{
+ if (galaxian_attributesram[offset] != data)
+ {
+ if (offset & 0x01)
+ {
+ /* color change */
+ int i;
+
+ for (i = offset >> 1; i < 0x0400; i += 32)
+ tilemap_mark_tile_dirty(bg_tilemap, i);
+ }
+ else
+ {
+ if (modify_ypos)
+ {
+ modify_ypos(&data);
+ }
+
+ tilemap_set_scroll(bg_tilemap, offset >> 1, data);
+ }
+
+ galaxian_attributesram[offset] = data;
+ }
+}
+
+
+WRITE8_HANDLER( galaxian_flip_screen_x_w )
+{
+ if (flipscreen_x != (data & 0x01))
+ {
+ flipscreen_x = data & 0x01;
+
+ tilemap_set_flip(bg_tilemap, (flipscreen_x ? TILEMAP_FLIPX : 0) | (flipscreen_y ? TILEMAP_FLIPY : 0));
+ }
+}
+
+WRITE8_HANDLER( galaxian_flip_screen_y_w )
+{
+ if (flipscreen_y != (data & 0x01))
+ {
+ flipscreen_y = data & 0x01;
+
+ tilemap_set_flip(bg_tilemap, (flipscreen_x ? TILEMAP_FLIPX : 0) | (flipscreen_y ? TILEMAP_FLIPY : 0));
+ }
+}
+
+
+WRITE8_HANDLER( gteikob2_flip_screen_x_w )
+{
+ galaxian_flip_screen_x_w(offset, ~data);
+}
+
+WRITE8_HANDLER( gteikob2_flip_screen_y_w )
+{
+ galaxian_flip_screen_y_w(offset, ~data);
+}
+
+
+WRITE8_HANDLER( hotshock_flip_screen_w )
+{
+ galaxian_flip_screen_x_w(offset, data);
+ galaxian_flip_screen_y_w(offset, data);
+}
+
+
+WRITE8_HANDLER( scramble_background_enable_w )
+{
+ background_enable = data & 0x01;
+}
+
+WRITE8_HANDLER( scramble_background_red_w )
+{
+ background_red = data & 0x01;
+}
+
+WRITE8_HANDLER( scramble_background_green_w )
+{
+ background_green = data & 0x01;
+}
+
+WRITE8_HANDLER( scramble_background_blue_w )
+{
+ background_blue = data & 0x01;
+}
+
+
+WRITE8_HANDLER( galaxian_stars_enable_w )
+{
+ galaxian_stars_on = data & 0x01;
+
+ if (!galaxian_stars_on)
+ {
+ stars_scrollpos = 0;
+ }
+}
+
+
+WRITE8_HANDLER( darkplnt_bullet_color_w )
+{
+ darkplnt_bullet_color = data & 0x01;
+}
+
+
+
+WRITE8_HANDLER( galaxian_gfxbank_w )
+{
+ if (gfxbank[offset] != data)
+ {
+ gfxbank[offset] = data;
+
+ tilemap_mark_all_tiles_dirty(bg_tilemap);
+ }
+}
+
+WRITE8_HANDLER( rockclim_videoram_w )
+{
+ rockclim_videoram[offset] = data;
+ tilemap_mark_tile_dirty(rockclim_tilemap, offset);
+}
+
+WRITE8_HANDLER( rockclim_scroll_w )
+{
+ switch(offset&3)
+ {
+ case 0: rockclim_h=(rockclim_h&0xff00)|data;tilemap_set_scrollx(rockclim_tilemap , 0, rockclim_h );break;
+ case 1: rockclim_h=(rockclim_h&0xff)|(data<<8);tilemap_set_scrollx(rockclim_tilemap , 0, rockclim_h );break;
+ case 2: rockclim_v=(rockclim_v&0xff00)|data;tilemap_set_scrolly(rockclim_tilemap , 0, rockclim_v );break;
+ case 3: rockclim_v=(rockclim_v&0xff)|(data<<8);tilemap_set_scrolly(rockclim_tilemap , 0, rockclim_v );break;
+ }
+
+}
+
+
+READ8_HANDLER( rockclim_videoram_r )
+{
+ return rockclim_videoram[offset];
+}
+
+
+WRITE8_HANDLER( dambustr_bg_split_line_w )
+{
+ dambustr_bg_split_line = data;
+}
+
+
+WRITE8_HANDLER( dambustr_bg_color_w )
+{
+ dambustr_bg_color_1 = (BIT(data,2)<<2) | (BIT(data,1)<<1) | BIT(data,0);
+ dambustr_bg_color_2 = (BIT(data,6)<<2) | (BIT(data,5)<<1) | BIT(data,4);
+ dambustr_bg_priority = BIT(data,3);
+ dambustr_char_bank = BIT(data,7);
+ tilemap_mark_all_tiles_dirty(bg_tilemap);
+}
+
+
+
+/* character banking functions */
+
+static void gmgalax_modify_charcode(UINT16 *code,UINT8 x)
+{
+ *code |= (gfxbank[0] << 9);
+}
+
+static void mooncrst_modify_charcode(UINT16 *code,UINT8 x)
+{
+ if (gfxbank[2] && ((*code & 0xc0) == 0x80))
+ {
+ *code = (*code & 0x3f) | (gfxbank[0] << 6) | (gfxbank[1] << 7) | 0x0100;
+ }
+}
+
+static void mooncrgx_modify_charcode(UINT16 *code,UINT8 x)
+{
+ if (gfxbank[2] && ((*code & 0xc0) == 0x80))
+ {
+ *code = (*code & 0x3f) | (gfxbank[1] << 6) | (gfxbank[0] << 7) | 0x0100;
+ }
+}
+
+static void moonqsr_modify_charcode(UINT16 *code,UINT8 x)
+{
+ *code |= ((galaxian_attributesram[(x << 1) | 1] & 0x20) << 3);
+}
+
+static void mshuttle_modify_charcode(UINT16 *code,UINT8 x)
+{
+ *code |= ((galaxian_attributesram[(x << 1) | 1] & 0x30) << 4);
+}
+
+static void pisces_modify_charcode(UINT16 *code,UINT8 x)
+{
+ *code |= (gfxbank[0] << 8);
+}
+
+static void mimonkey_modify_charcode(UINT16 *code,UINT8 x)
+{
+ *code |= (gfxbank[0] << 8) | (gfxbank[2] << 9);
+}
+
+static void batman2_modify_charcode(UINT16 *code,UINT8 x)
+{
+ if (*code & 0x80)
+ {
+ *code |= (gfxbank[0] << 8);
+ }
+}
+
+static void mariner_modify_charcode(UINT16 *code,UINT8 x)
+{
+ UINT8 *prom;
+
+
+ /* bit 0 of the PROM controls character banking */
+
+ prom = memory_region(REGION_USER2);
+
+ *code |= ((prom[x] & 0x01) << 8);
+}
+
+static void jumpbug_modify_charcode(UINT16 *code,UINT8 x)
+{
+ if (((*code & 0xc0) == 0x80) &&
+ (gfxbank[2] & 0x01))
+ {
+ *code += 128 + (( gfxbank[0] & 0x01) << 6) +
+ (( gfxbank[1] & 0x01) << 7) +
+ ((~gfxbank[4] & 0x01) << 8);
+ }
+}
+
+
+static void dambustr_modify_charcode(UINT16 *code,UINT8 x)
+{
+ if (dambustr_char_bank == 0) { // text mode
+ *code |= 0x0300;
+ }
+ else { // graphics mode
+ if (x == 28) // only line #28 stays in text mode
+ *code |= 0x0300;
+ else
+ *code &= 0x00ff;
+ };
+}
+
+
+
+/* sprite banking functions */
+
+static void gmgalax_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs)
+{
+ *code |= (gfxbank[0] << 7) | 0x40;
+}
+
+static void mooncrst_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs)
+{
+ if (gfxbank[2] && ((*code & 0x30) == 0x20))
+ {
+ *code = (*code & 0x0f) | (gfxbank[0] << 4) | (gfxbank[1] << 5) | 0x40;
+ }
+}
+
+static void mooncrgx_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs)
+{
+ if (gfxbank[2] && ((*code & 0x30) == 0x20))
+ {
+ *code = (*code & 0x0f) | (gfxbank[1] << 4) | (gfxbank[0] << 5) | 0x40;
+ }
+}
+
+static void moonqsr_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs)
+{
+ *code |= ((spriteram[offs + 2] & 0x20) << 1);
+}
+
+static void mshuttle_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs)
+{
+ *code |= ((spriteram[offs + 2] & 0x30) << 2);
+}
+
+static void calipso_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs)
+{
+ /* No flips */
+ *code = spriteram[offs + 1];
+ *flipx = 0;
+ *flipy = 0;
+}
+
+static void pisces_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs)
+{
+ *code |= (gfxbank[0] << 6);
+}
+
+static void mimonkey_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs)
+{
+ *code |= (gfxbank[0] << 6) | (gfxbank[2] << 7);
+}
+
+static void batman2_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs)
+{
+ /* only the upper 64 sprites are used */
+ *code |= 0x40;
+}
+
+static void jumpbug_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs)
+{
+ if (((*code & 0x30) == 0x20) &&
+ (gfxbank[2] & 0x01) != 0)
+ {
+ *code += 32 + (( gfxbank[0] & 0x01) << 4) +
+ (( gfxbank[1] & 0x01) << 5) +
+ ((~gfxbank[4] & 0x01) << 6);
+ }
+}
+
+static void dkongjrm_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs)
+{
+ /* No x flip */
+ *code = (spriteram[offs + 1] & 0x7f) | 0x80;
+ *flipx = 0;
+}
+
+static void ad2083_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs)
+{
+ /* No x flip */
+ *code = (spriteram[offs + 1] & 0x7f) | ((spriteram[offs + 2] & 0x30) << 2);
+ *flipx = 0;
+}
+
+static void dambustr_modify_spritecode(UINT8 *spriteram,int *code,int *flipx,int *flipy,int offs)
+{
+ *code += 0x40;
+}
+
+
+/* color PROM mapping functions */
+
+static void frogger_modify_color(UINT8 *color)
+{
+ *color = ((*color >> 1) & 0x03) | ((*color << 2) & 0x04);
+}
+
+static void gmgalax_modify_color(UINT8 *color)
+{
+ *color |= (gfxbank[0] << 3);
+}
+
+static void drivfrcg_modify_color(UINT8 *color)
+{
+ *color = ((*color & 0x40) >> 3) | (*color & 7);
+}
+
+/* y position mapping functions */
+
+static void frogger_modify_ypos(UINT8 *sy)
+{
+ *sy = (*sy << 4) | (*sy >> 4);
+}
+
+
+/* bullet drawing functions */
+
+static void galaxian_draw_bullets(running_machine *machine, mame_bitmap *bitmap, int offs, int x, int y)
+{
+ int i;
+
+
+ for (i = 0; i < 4; i++)
+ {
+ x--;
+
+ if (x >= machine->screen[0].visarea.min_x &&
+ x <= machine->screen[0].visarea.max_x)
+ {
+ int color;
+
+
+ /* yellow missile, white shells (this is the terminology on the schematics) */
+ color = ((offs == 7*4) ? BULLETS_COLOR_BASE : BULLETS_COLOR_BASE + 1);
+
+ *BITMAP_ADDR16(bitmap, y, x) = machine->pens[color];
+ }
+ }
+}
+
+static void gteikob2_draw_bullets(running_machine *machine, mame_bitmap *bitmap, int offs, int x, int y)
+{
+ galaxian_draw_bullets(machine, bitmap, offs, 260 - x, y);
+}
+
+static void scramble_draw_bullets(running_machine *machine, mame_bitmap *bitmap, int offs, int x, int y)
+{
+ if (flipscreen_x) x++;
+
+ x = x - 6;
+
+ if (x >= machine->screen[0].visarea.min_x &&
+ x <= machine->screen[0].visarea.max_x)
+ {
+ /* yellow bullets */
+ *BITMAP_ADDR16(bitmap, y, x) = machine->pens[BULLETS_COLOR_BASE];
+ }
+}
+
+static void darkplnt_draw_bullets(running_machine *machine, mame_bitmap *bitmap, int offs, int x, int y)
+{
+ if (flipscreen_x) x++;
+
+ x = x - 6;
+
+ if (x >= machine->screen[0].visarea.min_x &&
+ x <= machine->screen[0].visarea.max_x)
+ {
+ *BITMAP_ADDR16(bitmap, y, x) = machine->pens[32 + darkplnt_bullet_color];
+ }
+}
+
+static void theend_draw_bullets(running_machine *machine, mame_bitmap *bitmap, int offs, int x, int y)
+{
+ int i;
+
+
+ /* same as Galaxian, but all bullets are yellow */
+ for (i = 0; i < 4; i++)
+ {
+ x--;
+
+ if (x >= machine->screen[0].visarea.min_x &&
+ x <= machine->screen[0].visarea.max_x)
+ {
+ *BITMAP_ADDR16(bitmap, y, x) = machine->pens[BULLETS_COLOR_BASE];
+ }
+ }
+}
+
+static void dambustr_draw_bullets(running_machine *machine, mame_bitmap *bitmap, int offs, int x, int y)
+{
+ int i, color;
+
+ if (flip_screen_x) x++;
+
+ x = x - 6;
+
+ /* bullets are 2 pixels wide */
+ for (i = 0; i < 2; i++)
+ {
+ if (offs < 4*4)
+ {
+ color = BULLETS_COLOR_BASE;
+ y--;
+ }
+ else {
+ color = BULLETS_COLOR_BASE + 1;
+ x--;
+ }
+
+ if (x >= machine->screen[0].visarea.min_x &&
+ x <= machine->screen[0].visarea.max_x)
+ {
+ *BITMAP_ADDR16(bitmap, y, x) = machine->pens[color];
+ }
+ }
+}
+
+
+
+/* background drawing functions */
+
+static void galaxian_draw_background(running_machine *machine, mame_bitmap *bitmap)
+{
+ /* plain black background */
+ fillbitmap(bitmap,machine->pens[0],&machine->screen[0].visarea);
+}
+
+static void scramble_draw_background(running_machine *machine, mame_bitmap *bitmap)
+{
+ if (background_enable)
+ {
+ fillbitmap(bitmap,machine->pens[BACKGROUND_COLOR_BASE],&machine->screen[0].visarea);
+ }
+ else
+ {
+ fillbitmap(bitmap,machine->pens[0],&machine->screen[0].visarea);
+ }
+}
+
+static void turtles_draw_background(running_machine *machine, mame_bitmap *bitmap)
+{
+ int color = (background_blue << 2) | (background_green << 1) | background_red;
+
+ fillbitmap(bitmap,machine->pens[BACKGROUND_COLOR_BASE + color],&machine->screen[0].visarea);
+}
+
+static void frogger_draw_background(running_machine *machine, mame_bitmap *bitmap)
+{
+ /* color split point verified on real machine */
+ if (flipscreen_x)
+ {
+ plot_box(bitmap, 0, 0, 128, 256, machine->pens[0]);
+ plot_box(bitmap, 128, 0, 128, 256, machine->pens[BACKGROUND_COLOR_BASE]);
+ }
+ else
+ {
+ plot_box(bitmap, 0, 0, 128, 256, machine->pens[BACKGROUND_COLOR_BASE]);
+ plot_box(bitmap, 128, 0, 128, 256, machine->pens[0]);
+ }
+}
+
+static void stratgyx_draw_background(running_machine *machine, mame_bitmap *bitmap)
+{
+ UINT8 x;
+ UINT8 *prom;
+
+
+ /* the background PROM is connected the following way:
+
+ bit 0 = 0 enables the blue gun if BCB is asserted
+ bit 1 = 0 enables the red gun if BCR is asserted and
+ the green gun if BCG is asserted
+ bits 2-7 are unconnected */
+
+ prom = memory_region(REGION_USER1);
+
+ for (x = 0; x < 32; x++)
+ {
+ int sx,color;
+
+
+ color = 0;
+
+ if ((~prom[x] & 0x02) && background_red) color |= 0x01;
+ if ((~prom[x] & 0x02) && background_green) color |= 0x02;
+ if ((~prom[x] & 0x01) && background_blue) color |= 0x04;
+
+ if (flipscreen_x)
+ {
+ sx = 8 * (31 - x);
+ }
+ else
+ {
+ sx = 8 * x;
+ }
+
+ plot_box(bitmap, sx, 0, 8, 256, machine->pens[BACKGROUND_COLOR_BASE + color]);
+ }
+}
+
+static void minefld_draw_background(running_machine *machine, mame_bitmap *bitmap)
+{
+ if (background_enable)
+ {
+ int x;
+
+
+ for (x = 0; x < 128; x++)
+ {
+ plot_box(bitmap, x, 0, 1, 256, machine->pens[BACKGROUND_COLOR_BASE + x]);
+ }
+
+ for (x = 0; x < 120; x++)
+ {
+ plot_box(bitmap, x + 128, 0, 1, 256, machine->pens[BACKGROUND_COLOR_BASE + x + 128]);
+ }
+
+ plot_box(bitmap, 248, 0, 16, 256, machine->pens[BACKGROUND_COLOR_BASE]);
+ }
+ else
+ {
+ fillbitmap(bitmap,machine->pens[0],&machine->screen[0].visarea);
+ }
+}
+
+static void rescue_draw_background(running_machine *machine, mame_bitmap *bitmap)
+{
+ if (background_enable)
+ {
+ int x;
+
+
+ for (x = 0; x < 128; x++)
+ {
+ plot_box(bitmap, x, 0, 1, 256, machine->pens[BACKGROUND_COLOR_BASE + x]);
+ }
+
+ for (x = 0; x < 120; x++)
+ {
+ plot_box(bitmap, x + 128, 0, 1, 256, machine->pens[BACKGROUND_COLOR_BASE + x + 8]);
+ }
+
+ plot_box(bitmap, 248, 0, 16, 256, machine->pens[BACKGROUND_COLOR_BASE]);
+ }
+ else
+ {
+ fillbitmap(bitmap,machine->pens[0],&machine->screen[0].visarea);
+ }
+}
+
+static void mariner_draw_background(running_machine *machine, mame_bitmap *bitmap)
+{
+ UINT8 x;
+ UINT8 *prom;
+
+
+ /* the background PROM contains the color codes for each 8 pixel
+ line (column) of the screen. The first 0x20 bytes for unflipped,
+ and the 2nd 0x20 bytes for flipped screen. */
+
+ prom = memory_region(REGION_USER1);
+
+ if (flipscreen_x)
+ {
+ for (x = 0; x < 32; x++)
+ {
+ int color;
+
+
+ if (x == 0)
+ color = 0;
+ else
+ color = prom[0x20 + x - 1];
+
+ plot_box(bitmap, 8 * (31 - x), 0, 8, 256, machine->pens[BACKGROUND_COLOR_BASE + color]);
+ }
+ }
+ else
+ {
+ for (x = 0; x < 32; x++)
+ {
+ int color;
+
+
+ if (x == 31)
+ color = 0;
+ else
+ color = prom[x + 1];
+
+ plot_box(bitmap, 8 * x, 0, 8, 256, machine->pens[BACKGROUND_COLOR_BASE + color]);
+ }
+ }
+}
+
+static void dambustr_draw_background(running_machine *machine, mame_bitmap *bitmap)
+{
+ int col1 = BACKGROUND_COLOR_BASE + dambustr_bg_color_1;
+ int col2 = BACKGROUND_COLOR_BASE + dambustr_bg_color_2;
+
+ if (flip_screen_x)
+ {
+ plot_box(bitmap, 0, 0, 256-dambustr_bg_split_line, 256, machine->pens[col2]);
+ plot_box(bitmap, 256-dambustr_bg_split_line, 0, dambustr_bg_split_line, 256, machine->pens[col1]);
+ }
+ else
+ {
+ plot_box(bitmap, 0, 0, 256-dambustr_bg_split_line, 256, machine->pens[col1]);
+ plot_box(bitmap, 256-dambustr_bg_split_line, 0, dambustr_bg_split_line, 256, machine->pens[col2]);
+ }
+
+}
+
+static void dambustr_draw_upper_background(mame_bitmap *bitmap)
+{
+ static rectangle clip = { 0, 0, 0, 0 };
+
+ if (flip_screen_x)
+ {
+ clip.min_x = 254 - dambustr_bg_split_line;
+ clip.max_x = dambustr_bg_split_line;
+ clip.min_y = 0;
+ clip.max_y = 255;
+ copybitmap(bitmap, dambustr_tmpbitmap, 0, 0, 0, 0, &clip, TRANSPARENCY_NONE, 0);
+ }
+ else
+ {
+ clip.min_x = 0;
+ clip.max_x = 254 - dambustr_bg_split_line;
+ clip.min_y = 0;
+ clip.max_y = 255;
+ copybitmap(bitmap, dambustr_tmpbitmap, 0, 0, 0, 0, &clip, TRANSPARENCY_NONE, 0);
+ }
+}
+
+
+
+/* star drawing functions */
+
+void galaxian_init_stars(running_machine *machine, int colors_offset)
+{
+ int i;
+ int total_stars;
+ UINT32 generator;
+ int x,y;
+
+
+ galaxian_stars_on = 0;
+ stars_blink_state = 0;
+ stars_blink_timer = timer_alloc(stars_blink_callback);
+ stars_scroll_timer = timer_alloc(stars_scroll_callback);
+ timer_adjusted = 0;
+ stars_colors_start = colors_offset;
+
+ for (i = 0;i < 64;i++)
+ {
+ int bits,r,g,b;
+ static const int map[4] = { 0x00, 0x88, 0xcc, 0xff };
+
+
+ bits = (i >> 0) & 0x03;
+ r = map[bits];
+ bits = (i >> 2) & 0x03;
+ g = map[bits];
+ bits = (i >> 4) & 0x03;
+ b = map[bits];
+ palette_set_color_rgb(machine,colors_offset+i,r,g,b);
+ }
+
+
+ /* precalculate the star background */
+
+ total_stars = 0;
+ generator = 0;
+
+ for (y = 0;y < 256;y++)
+ {
+ for (x = 0;x < 512;x++)
+ {
+ UINT32 bit0;
+
+
+ bit0 = ((~generator >> 16) & 0x01) ^ ((generator >> 4) & 0x01);
+
+ generator = (generator << 1) | bit0;
+
+ if (((~generator >> 16) & 0x01) && (generator & 0xff) == 0xff)
+ {
+ int color;
+
+
+ color = (~(generator >> 8)) & 0x3f;
+ if (color)
+ {
+ stars[total_stars].x = x;
+ stars[total_stars].y = y;
+ stars[total_stars].color = color;
+
+ total_stars++;
+ }
+ }
+ }
+ }
+
+ if (total_stars != STAR_COUNT)
+ {
+ fatalerror("total_stars = %d, STAR_COUNT = %d",total_stars,STAR_COUNT);
+ }
+}
+
+static void plot_star(running_machine *machine, mame_bitmap *bitmap, int x, int y, int color)
+{
+ if (y < machine->screen[0].visarea.min_y ||
+ y > machine->screen[0].visarea.max_y ||
+ x < machine->screen[0].visarea.min_x ||
+ x > machine->screen[0].visarea.max_x)
+ return;
+
+
+ if (flipscreen_x)
+ {
+ x = 255 - x;
+ }
+ if (flipscreen_y)
+ {
+ y = 255 - y;
+ }
+
+ *BITMAP_ADDR16(bitmap, y, x) = machine->pens[stars_colors_start + color];
+}
+
+static void noop_draw_stars(running_machine *machine, mame_bitmap *bitmap)
+{
+}
+
+void galaxian_draw_stars(running_machine *machine, mame_bitmap *bitmap)
+{
+ int offs;
+
+
+ if (!timer_adjusted)
+ {
+ start_stars_scroll_timer();
+ timer_adjusted = 1;
+ }
+
+
+ for (offs = 0;offs < STAR_COUNT;offs++)
+ {
+ int x,y;
+
+
+ x = ((stars[offs].x + stars_scrollpos) & 0x01ff) >> 1;
+ y = ( stars[offs].y + ((stars_scrollpos + stars[offs].x) >> 9)) & 0xff;
+
+ if ((y & 0x01) ^ ((x >> 3) & 0x01))
+ {
+ plot_star(machine, bitmap, x, y, stars[offs].color);
+ }
+ }
+}
+
+void scramble_draw_stars(running_machine *machine, mame_bitmap *bitmap)
+{
+ int offs;
+
+
+ if (!timer_adjusted)
+ {
+ start_stars_blink_timer(100000, 10000, 0.00001);
+ timer_adjusted = 1;
+ }
+
+
+ for (offs = 0;offs < STAR_COUNT;offs++)
+ {
+ int x,y;
+
+
+ x = stars[offs].x >> 1;
+ y = stars[offs].y;
+
+ if ((y & 0x01) ^ ((x >> 3) & 0x01))
+ {
+ /* determine when to skip plotting */
+ switch (stars_blink_state & 0x03)
+ {
+ case 0:
+ if (!(stars[offs].color & 0x01)) continue;
+ break;
+ case 1:
+ if (!(stars[offs].color & 0x04)) continue;
+ break;
+ case 2:
+ if (!(stars[offs].y & 0x02)) continue;
+ break;
+ case 3:
+ /* always plot */
+ break;
+ }
+
+ plot_star(machine, bitmap, x, y, stars[offs].color);
+ }
+ }
+}
+
+static void rescue_draw_stars(running_machine *machine, mame_bitmap *bitmap)
+{
+ int offs;
+
+
+ /* same as Scramble, but only top (left) half of screen */
+
+ if (!timer_adjusted)
+ {
+ start_stars_blink_timer(100000, 10000, 0.00001);
+ timer_adjusted = 1;
+ }
+
+
+ for (offs = 0;offs < STAR_COUNT;offs++)
+ {
+ int x,y;
+
+
+ x = stars[offs].x >> 1;
+ y = stars[offs].y;
+
+ if ((x < 128) && ((y & 0x01) ^ ((x >> 3) & 0x01)))
+ {
+ /* determine when to skip plotting */
+ switch (stars_blink_state & 0x03)
+ {
+ case 0:
+ if (!(stars[offs].color & 0x01)) continue;
+ break;
+ case 1:
+ if (!(stars[offs].color & 0x04)) continue;
+ break;
+ case 2:
+ if (!(stars[offs].y & 0x02)) continue;
+ break;
+ case 3:
+ /* always plot */
+ break;
+ }
+
+ plot_star(machine, bitmap, x, y, stars[offs].color);
+ }
+ }
+}
+
+static void mariner_draw_stars(running_machine *machine, mame_bitmap *bitmap)
+{
+ int offs;
+ UINT8 *prom;
+
+
+ if (!timer_adjusted)
+ {
+ start_stars_scroll_timer();
+ timer_adjusted = 1;
+ }
+
+
+ /* bit 2 of the PROM controls star visibility */
+
+ prom = memory_region(REGION_USER2);
+
+ for (offs = 0;offs < STAR_COUNT;offs++)
+ {
+ int x,y;
+
+
+ x = ((stars[offs].x + -stars_scrollpos) & 0x01ff) >> 1;
+ y = ( stars[offs].y + ((-stars_scrollpos + stars[offs].x) >> 9)) & 0xff;
+
+ if ((y & 0x01) ^ ((x >> 3) & 0x01))
+ {
+ if (prom[(x/8 + 1) & 0x1f] & 0x04)
+ {
+ plot_star(machine, bitmap, x, y, stars[offs].color);
+ }
+ }
+ }
+}
+
+static void jumpbug_draw_stars(running_machine *machine, mame_bitmap *bitmap)
+{
+ int offs;
+
+
+ if (!timer_adjusted)
+ {
+ start_stars_blink_timer(100000, 10000, 0.00001);
+ start_stars_scroll_timer();
+ timer_adjusted = 1;
+ }
+
+
+ for (offs = 0;offs < STAR_COUNT;offs++)
+ {
+ int x,y;
+
+
+ x = stars[offs].x >> 1;
+ y = stars[offs].y;
+
+ /* determine when to skip plotting */
+ if ((y & 0x01) ^ ((x >> 3) & 0x01))
+ {
+ switch (stars_blink_state & 0x03)
+ {
+ case 0:
+ if (!(stars[offs].color & 0x01)) continue;
+ break;
+ case 1:
+ if (!(stars[offs].color & 0x04)) continue;
+ break;
+ case 2:
+ if (!(stars[offs].y & 0x02)) continue;
+ break;
+ case 3:
+ /* always plot */
+ break;
+ }
+
+ x = ((stars[offs].x + stars_scrollpos) & 0x01ff) >> 1;
+ y = ( stars[offs].y + ((stars_scrollpos + stars[offs].x) >> 9)) & 0xff;
+
+ /* no stars in the status area */
+ if (x >= 240) continue;
+
+ plot_star(machine, bitmap, x, y, stars[offs].color);
+ }
+ }
+}
+
+
+static TIMER_CALLBACK( stars_blink_callback )
+{
+ stars_blink_state++;
+}
+
+static void start_stars_blink_timer(double ra, double rb, double c)
+{
+ /* calculate the period using the formula given in the 555 datasheet */
+
+ int period_in_ms = 693 * (ra + 2.0 * rb) * c;
+
+ timer_adjust(stars_blink_timer, ATTOTIME_IN_MSEC(period_in_ms), 0, ATTOTIME_IN_MSEC(period_in_ms));
+}
+
+
+static TIMER_CALLBACK( stars_scroll_callback )
+{
+ if (galaxian_stars_on)
+ {
+ stars_scrollpos++;
+ }
+}
+
+static void start_stars_scroll_timer()
+{
+ timer_adjust(stars_scroll_timer, video_screen_get_frame_period(0), 0, video_screen_get_frame_period(0));
+}
+
+
+
+static TILE_GET_INFO( get_tile_info )
+{
+ UINT8 x = tile_index & 0x1f;
+
+ UINT16 code = galaxian_videoram[tile_index];
+ UINT8 color = galaxian_attributesram[(x << 1) | 1] & color_mask;
+
+ if (modify_charcode)
+ {
+ modify_charcode(&code, x);
+ }
+
+ if (modify_color)
+ {
+ modify_color(&color);
+ }
+
+ SET_TILE_INFO(0, code, color, 0);
+}
+
+static TILE_GET_INFO( rockclim_get_tile_info )
+{
+ UINT16 code = rockclim_videoram[tile_index];
+ SET_TILE_INFO(2, code, 0, 0);
+}
+
+static void draw_bullets_common(running_machine *machine, mame_bitmap *bitmap)
+{
+ int offs;
+
+
+ for (offs = 0;offs < galaxian_bulletsram_size;offs += 4)
+ {
+ UINT8 sx,sy;
+
+ sy = 255 - galaxian_bulletsram[offs + 1];
+ sx = 255 - galaxian_bulletsram[offs + 3];
+
+ if (sy < machine->screen[0].visarea.min_y ||
+ sy > machine->screen[0].visarea.max_y)
+ continue;
+
+ if (flipscreen_y) sy = 255 - sy;
+
+ draw_bullets(machine, bitmap, offs, sx, sy);
+ }
+}
+
+
+static void draw_sprites(running_machine *machine, mame_bitmap *bitmap, UINT8 *spriteram, size_t spriteram_size)
+{
+ int offs;
+
+
+ for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
+ {
+ UINT8 sx,sy,color;
+ int flipx,flipy,code;
+
+
+ sx = spriteram[offs + 3] + 1; /* the existence of +1 is supported by a LOT of games */
+ sy = spriteram[offs]; /* Anteater, Mariner, for example */
+ flipx = spriteram[offs + 1] & 0x40;
+ flipy = spriteram[offs + 1] & 0x80;
+ code = spriteram[offs + 1] & 0x3f;
+ color = spriteram[offs + 2] & color_mask;
+
+ if (modify_spritecode)
+ {
+ modify_spritecode(spriteram, &code, &flipx, &flipy, offs);
+ }
+
+ if (modify_color)
+ {
+ modify_color(&color);
+ }
+
+ if (modify_ypos)
+ {
+ modify_ypos(&sy);
+ }
+
+ if (flipscreen_x)
+ {
+ sx = 240 - sx;
+ flipx = !flipx;
+ }
+
+ if (flipscreen_y)
+ {
+ flipy = !flipy;
+ }
+ else
+ {
+ sy = 240 - sy;
+ }
+
+
+ /* In at least Amidar Turtles, sprites #0, #1 and #2 need to be moved */
+ /* down (left) one pixel to be positioned correctly. */
+ /* Note that the adjustment must be done AFTER handling flipscreen, thus */
+ /* proving that this is a hardware related "feature" */
+
+ if (offs < 3*4) sy++;
+
+
+ drawgfx(bitmap,machine->gfx[1],
+ code,color,
+ flipx,flipy,
+ sx,sy,
+ flipscreen_x ? spritevisibleareaflipx : spritevisiblearea,TRANSPARENCY_PEN,0);
+ }
+}
+
+
+VIDEO_UPDATE( galaxian )
+{
+ draw_background(machine, bitmap);
+
+
+ if (galaxian_stars_on)
+ {
+ draw_stars(machine, bitmap);
+ }
+
+
+ tilemap_draw(bitmap, 0, bg_tilemap, 0, 0);
+
+
+ if (draw_bullets)
+ {
+ draw_bullets_common(machine, bitmap);
+ }
+
+
+ draw_sprites(machine, bitmap, galaxian_spriteram, galaxian_spriteram_size);
+
+ if (spriteram2_present)
+ {
+ draw_sprites(machine, bitmap, galaxian_spriteram2, galaxian_spriteram2_size);
+ }
+ return 0;
+}
+
+
+VIDEO_UPDATE( dambustr )
+{
+ int i, j;
+ UINT8 color;
+
+ draw_background(machine, bitmap);
+
+ if (galaxian_stars_on)
+ {
+ draw_stars(machine, bitmap);
+ }
+
+ /* save the background for drawing it again later, if background has priority over characters */
+ copybitmap(dambustr_tmpbitmap, bitmap, 0, 0, 0, 0, &machine->screen[0].visarea, TRANSPARENCY_NONE, 0);
+
+ tilemap_draw(bitmap, 0, bg_tilemap, 0, 0);
+
+ if (draw_bullets)
+ {
+ draw_bullets_common(machine, bitmap);
+ }
+
+ draw_sprites(machine, bitmap, galaxian_spriteram, galaxian_spriteram_size);
+
+ if (dambustr_bg_priority)
+ {
+ /* draw the upper part of the background, as it has priority */
+ dambustr_draw_upper_background(bitmap);
+
+ /* only rows with color code > 3 are stronger than the background */
+ memset(dambustr_videoram2, 0x20, 0x0400);
+ for (i=0; i<32; i++) {
+ color = galaxian_attributesram[(i << 1) | 1] & color_mask;
+ if (color > 3) {
+ for (j=0; j<32; j++)
+ dambustr_videoram2[32*j+i] = galaxian_videoram[32*j+i];
+ };
+ };
+ tilemap_mark_all_tiles_dirty(dambustr_tilemap2);
+ tilemap_draw(bitmap, 0, dambustr_tilemap2, 0, 0);
+ };
+
+ return 0;
+}
+