diff options
Diffstat (limited to 'docs/release/src/hbmame/drivers/monaco.cpp')
-rw-r--r-- | docs/release/src/hbmame/drivers/monaco.cpp | 2256 |
1 files changed, 2256 insertions, 0 deletions
diff --git a/docs/release/src/hbmame/drivers/monaco.cpp b/docs/release/src/hbmame/drivers/monaco.cpp new file mode 100644 index 00000000000..c5f9a2730e4 --- /dev/null +++ b/docs/release/src/hbmame/drivers/monaco.cpp @@ -0,0 +1,2256 @@ +// license:BSD-3-Clause +// copyright-holders:Phil Stroffolino,Robbbert +/* +Monaco GP Simulator v0.1 +http://www.jps.net/camilty/monman.htm +Phil Stroffolino + +To Do: +- abstract and externalize in-game parameters (speeds,accel,timing) +- fix distribution of computer car +- computer cars should avoid rescue car lane when present +- computer cars should move to center in bridge zone +- player lives not hooked up +- high score tracking +- extended play colors + +General: + Score Increases as a function of the player's speed. + Speed of Terrain scrolling is independent. + +Computer Cars: + The bridge section is different from the others (besides all the cars going + faster after so many points(6K and 8K). + +Display Panel: + The cockpit model displays TIME (2 digit), top 5 scores (4 digits each), + your Score (4 digits), Players to Date (3 digits)(daily), and + Ranking (3 digits) (this is final score ranking, not position during the game). + + The top 999 high scores are internally recorded in a RAM. + The player's ranking is updated only after gamplay is finished (during the + fanfare). + +Timed Play: + X000-X295 A-Smooth Zone + X295-X450 B-Slip Zone + X450-X795 A-Smooth Zone + X795-X000 C-Tunnel + +Extended Play: + X000-X095 A-Smooth Zone + X095-X150 D-Gravel Zone + X150-X295 A-Smooth Zone + X295-X475 B-Slip Zone + X475-X595 A-Smooth Zone + X595-X635 E-Bridge Zone + X635-X795 A-Smooth Zone + X795-X000 C-Tunnel Zone + +Oil Slicks (pool): + X185 (during zone A) + X685 (during zone A) + After 8000 points, two pools come out in succession + (the second about 20-30 points from the first). + +Rescue Car (firetruck) + The rescue car only appears during Extended play. Tolerance -50 (not+) + X000 + X075 + X125 + X250 + X500 + + The rescue car appears in a mid-right lane. It does not move side to side, + it just moves slowly up the screen until it goes off the screen. + + In extended play, the rescue car was observed to come out AT LEAST ONCE + during each 1000 points cycle. I have observed the rescue car coming + out as much a 3 TIMES in one 1000 point cycle. + I could not find a pattern in the time or count interval between the + rescue cars. However, 72% were between 750 and 1250 point intervals + (most around 875) while the remaining 28% were 500 point intervals or + lower. Therfore, we can narrow down WHERE the rescue cars appear, but + IF it is going to appear seems to have some randomness to it. + + +notes: + when the player first appears (game start, after a spinout, after + a crash), the player's car shows up on the extreme right of the + screen and is totally invulnerable (even if over water on the + bridge scene!). The road doesn't scroll at all until you give the + car some gas. Note that once you start moving, you can never + completely come to a stop. + + Once you move to left onto the center part of the + road, normal collision behavior takes over. You earn no points + while in the invulnerable state. The player can remain in this + state forever during timed play (until time runs out). In extended + play, the player's car will explode after several seconds of driving. + +--------------------------------------------------------------------------- + +Board 96598-P is an oscillator board that generates the game sounds. +It is activated by outputs from Board Assy A (96577X). + +Board Assy's A (96577X) and B (96578X) are the main guts of the gameplay +and contain the sprite roms. + +Board Assy A +- accepts all of the game inputs +- sends the signals for the sounds to the Oscillator board +- outputs to the L.E.D. score display board +- directly interacts with Board Assy B + Components: + Start Timer Control + Player Control (pedal, steering, shifter) + My Car light control, explosion, and pool (oil slick) skid + Other Car Control + +Board Assy B +- outputs the video +- outputs to the L.E.D. score display board +- directly interacts with Board Assy A. + Components: + Display of Letter + Road Movement Horizontal + Road Movement Vertical (Right and Left) + Background (sprite) coloring + Road Object (tunnel, bridge, water) control + Signal Sync + Rescue Car, Player Car, Bridge--Video and Control + + (On the second set, boards A and B have different part numbers + (97091X and 97092X) and two less roms. These boards were made + later then the first set. I have interchanged these boards with + each other, and they seem to be interchangable, the only + difference seems to be the rom size, which only 2 of the roms + utilize the full 1024 bytes (second set).) + +Oscillator Board 96598 +ROM ID IC# +PRm-40 IC21 PRm-40 <both type 6331-1, 16 pin> + engine (constant; pitch varies with speed) + passing (two variations) + bonus (chimes) + fanfare + explosion + slip zone + siren (rescue car) +*/ + +/* The following changes were done by Robbbert on 2007-Dec-08: + +1. Add siren sound for ambulance +2. Add slip sound for puddle +3. Save and display high scores, score, number of games played, and ranking +4. Play fanfare sound if high score exceeded +5. Fix the gears so that each has its own max speed and acceleration rates +6. Keep track of extra lives (er, cars). +7. In extended play, you lose a life. When they are all gone, the game ends +8. When game ends, all sounds are turned off, except Crash sound is allowed to finish, and fanfare can play. +9. When you crash, you nearly stop, instead of continuing at full speed. +10. Once you start moving, you cannot completely stop (as documented above) +11. Sound volume adjustment confined to the machine driver. +12. Volume adjusted so the sound is no longer grossly overdriven. +13. Add the overlay file (it was always compiled but never used), and activated the LEDs. +14. Add support for Mr.Do artwork. +15. Add speedometer + +There is a bunch more things to be done + +1. Don't get points while not on the track +2. Fall in the water if you don't line up for the bridge +3. Show the bridge warning before you reach the bridge +4. Different engine sounds depending on the speed +5. Add sounds when passing other cars +6. Plus some of what's listed above by the original author +*/ + +#include "emu.h" +#include "cpu/z80/z80.h" +#include "sound/samples.h" +#include "emupal.h" +#include "screen.h" +#include "speaker.h" +#include "monaco.lh" + + +#define kRESCUE_CAR_SPEED (1.75) +#define SCREEN_WIDTH 384 /* 12 car lengths */ +#define SCREEN_HEIGHT 240 /* 15 car widths */ +#define BRIDGE_YPOS ((SCREEN_HEIGHT-16)/2-8) +#define PAGE_SIZE (14*32) +#define NUM_COMPUTER_CARS 4 + +/* red */ +#define TEXT_GAMEOVER 2 +#define TEXT_EXTENDEDPLAY 0 + +/* blue */ +#define TEXT_DEPOSITCOIN 3 +#define TEXT_START 1 + +enum +{ + GFX_UNKNOWN,GFX_EXPLOSION,GFX_PLAYER,GFX_SHAKE,GFX_SPINOUT1,GFX_SPINOUT2, + GFX_SPRAY,GFX_COMPUTER,GFX_TEXT, + GFX_TREE,GFX_GRASS,GFX_SHRUB,GFX_HOUSE, + GFX_TUNNEL,GFX_POOL,GFX_BELT, + GFX_RESCUE_CAR,GFX_SIGNAL,GFX_DUMMY, + GFX_BRIDGE1,GFX_BRIDGE2 +}; + +enum +{ + CYAN_PEN = 0x91, + BLACK_PEN = 0x94, + YELLOW_PEN = 0x95, + GREY_PEN = 0x96 +}; + +enum +{ + RESCUE_CLUT = 0x50, + HOUSE_CLUT = 0x60, + WATER_CLUT = 0x70, + PLAYER_CLUT = 0x80, + TREE_CLUT = 0x84, + SHRUB_CLUT = 0x88, + GRASS_CLUT = 0x8c, + CYAN_CLUT = 0x90, + RED_CLUT = 0x92, + YELLOW_CLUT = 0x94 +}; + +enum +{ + GREEN_CAR, YELLOW_CAR, /* slow */ + CYAN_CAR, PURPLE_CAR, /* medium */ + BLUE_CAR, /* fast */ + NUM_COMPUTER_CAR_TYPES +}; + +enum +{ + PAGE_SMOOTH, + PAGE_SLIP, + PAGE_TUNNEL, + PAGE_GRAVEL, + PAGE_BRIDGE +}; + +enum +{ + COLLISION_CRASH, + COLLISION_POOL +}; + +enum monaco_mode +{ + MODE_ATTRACT, + /* cars zoom up the screen (max 2 on the screen at a time) + * player's car is not visible + * "GAME OVER" is centered near the middle-top + * "DEPOSIT COIN" is centered near the bottom + */ + MODE_START, + MODE_INVULNERABLE, + MODE_NORMAL, /* driving */ + MODE_GRAVEL, + MODE_SLIP1, /* skidding */ + MODE_SLIP2, + MODE_SPINOUT1, + MODE_SPINOUT2, + MODE_SPINOUT3, + MODE_SPINOUT4, + MODE_CRASH1, + MODE_CRASH2, + MODE_CRASH3, + MODE_CRASH4 +}; + +class monaco_state : public driver_device +{ +public: + monaco_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this,"maincpu") + , m_samples(*this, "samples") + , m_p_ram(*this, "ram") + , m_gfxdecode(*this, "gfxdecode") + , m_palette(*this, "palette") + , m_out_digit(*this, "digit%u", 0U) + { } + + void init_monaco(); + void monaco(machine_config &config); +private: + DECLARE_READ8_MEMBER(monaco_ram_r); + DECLARE_WRITE8_MEMBER(monaco_ram_w); + INTERRUPT_GEN_MEMBER(monaco_interrupt); + DECLARE_VIDEO_START(monaco); + void monaco_map(address_map &map); + void machine_reset() override; + uint32_t screen_update_monaco(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + struct monaco_gfx *m_monaco_gfx; + enum monaco_mode m_monaco_mode; + uint32_t monaco_word_r (uint16_t offset); + void monaco_word_w (uint16_t offset, uint32_t data); + int get_player_xpos( void ); + void handle_collision( int sx, int sy, int width, int height, int type ); + int read_coin(); + void update_player_speed(); + double get_player_delta( void ); + void HandlePlayer(); + void update_computer_cars( void ); + void HandleRescue( void ); + void HandlePool( void ); + void GameOver(); + void HandleEvents(); + void draw_computer( bitmap_ind16 &bitmap, const rectangle clip); + void draw_pool( bitmap_ind16 &bitmap, const rectangle clip); + void draw_player( bitmap_ind16 &bitmap, const rectangle clip); + void draw_strip( bitmap_ind16 &bitmap, int sy, int x0, int x1, int xpos, int pen); + void DrawSmoothZone( bitmap_ind16 &bitmap, const rectangle clip, int xpos); + void DrawSlipZone( bitmap_ind16 &bitmap, const rectangle clip, int xpos); + void DrawGravelZone( bitmap_ind16 &bitmap, const rectangle clip, int xpos); + void DrawBridgeZone( bitmap_ind16 &bitmap, const rectangle clip, int xpos); + void DrawTunnelZone( bitmap_ind16 &bitmap, int xpos); + void DrawTunnelWall( bitmap_ind16 &bitmap, const rectangle clip, int xpos); + void draw_light_helper( bitmap_ind16 &bitmap, int xpos); + void draw_wall( bitmap_ind16 &bitmap, const rectangle clip); + void draw_light( bitmap_ind16 &bitmap); + void draw_page( bitmap_ind16 &bitmap, const rectangle clip, int which, int xpos); + void draw_background( bitmap_ind16 &bitmap, const rectangle clip); + void draw_text( bitmap_ind16 &bitmap, const rectangle clip); + void draw_leds( bitmap_ind16 &bitmap); + void draw_signal( bitmap_ind16 &bitmap); + int m_anim_timer; + + /* LED display */ + uint16_t m_plays; + uint16_t m_rank; + uint16_t m_rank_display; // shows 0 until game ends + uint32_t m_score; + uint32_t m_bonus_score; + uint8_t m_in_ext_play; + uint8_t m_gear; + uint16_t m_time; + uint8_t m_lives; + int m_bShaking; + double m_speed; + double m_player_ypos; + double m_computer_speed; + double m_xpos[NUM_COMPUTER_CARS]; + double m_ypos[NUM_COMPUTER_CARS]; + double m_dy[NUM_COMPUTER_CARS]; + double m_rescue_xpos; + double m_pool_xpos; + double m_scroll; + double m_distance; + int m_ticks; + int m_page_current; + int m_page_next; + int m_page_next2; + + double m_track_bottom_inset; + double m_track_top_inset; + double m_track_bottom_delta; + double m_track_top_delta; + int m_bSignalVisible; + int m_left_text; + int m_right_text; + int m_bExtendedPlay; + int m_left_page, m_right_page; + int m_top_inset, m_bottom_inset; + int m_player_x, m_player_y, m_player_tile, m_player_splash; + int m_pool_x, m_pool_y; + int m_rescue_x, m_rescue_y, m_rescue_tile; + int m_x[NUM_COMPUTER_CARS]; + int m_y[NUM_COMPUTER_CARS]; + int m_tile[NUM_COMPUTER_CARS]; + int m_color[NUM_COMPUTER_CARS]; + uint32_t m_led_high1; + uint32_t m_led_high2; + uint32_t m_led_high3; + uint32_t m_led_high4; + uint32_t m_led_high5; + uint32_t m_led_score; + uint16_t m_led_time; + uint16_t m_led_rank; + uint16_t m_led_plays; + uint16_t m_led_lives; + uint16_t m_led_gear; + uint16_t m_led_speed; + required_device<cpu_device> m_maincpu; + required_device<samples_device> m_samples; + required_shared_ptr<uint8_t> m_p_ram; + required_device<gfxdecode_device> m_gfxdecode; + required_device<palette_device> m_palette; + output_finder<105> m_out_digit; +}; + + +enum +{ + eSAMPLE_PASS1, + eSAMPLE_PASS2, + eSAMPLE_CRASH, + eSAMPLE_ENGINE, + eSAMPLE_EXTEND, + eSAMPLE_FANFARE, + eSAMPLE_SIREN, + eSAMPLE_SLIP, +// eSAMPLE_GRAVEL +}; + +#define DOWN 0x01 +#define UP 0x02 +#define RIGHT 0x04 +#define LEFT 0x08 +#define COIN 0x10 +#define ACCEL1 0x20 +#define ACCEL2 0x40 +#define ACCEL3 0x80 + +#define IS_PRESSED(key) (ioport("IN0")->read() & key) + +#define EXT_SCORE (2000<<8) // number of points needed to get extended play, 2000 +#define FIRST_TIME (90<<8) // number of seconds when coin inserted, 90 + + +READ8_MEMBER( monaco_state::monaco_ram_r ) +{ + return m_p_ram[offset]; +} + +WRITE8_MEMBER( monaco_state::monaco_ram_w ) +{ + m_p_ram[offset] = data; +} + +uint32_t monaco_state::monaco_word_r (uint16_t offset) +{ + address_space &space = m_maincpu->space(AS_PROGRAM); + uint8_t byte0 = monaco_ram_r (space, (offset << 2)); + uint8_t byte1 = monaco_ram_r (space, (offset << 2) + 1); + uint8_t byte2 = monaco_ram_r (space, (offset << 2) + 2); + uint8_t byte3 = monaco_ram_r (space, (offset << 2) + 3); + return (byte3<<24) | (byte2<<16) | (byte1<<8) | byte0; +} + +void monaco_state::monaco_word_w (uint16_t offset, uint32_t data) +{ + address_space &space = m_maincpu->space(AS_PROGRAM); + uint8_t byte0 = data & 0xff; + uint8_t byte1 = (data & 0xff00) >> 8; + uint8_t byte2 = (data & 0xff0000) >> 16; + uint8_t byte3 = (data & 0xff000000) >> 24; + monaco_ram_w (space, (offset << 2), byte0); + monaco_ram_w (space, (offset << 2) + 1, byte1); + monaco_ram_w (space, (offset << 2) + 2, byte2); + monaco_ram_w (space, (offset << 2) + 3, byte3); +} + +int monaco_state::get_player_xpos( void ) +{ + return SCREEN_WIDTH-32-m_speed; +} + +void monaco_state::handle_collision( int sx, int sy, int width, int height, int type ) +{ + int px, py; + + if( m_monaco_mode == MODE_NORMAL ) + { + px = get_player_xpos(); + py = m_player_ypos + 8; + + if( px < sx + width && + sx < px + 32 && + py < sy + height && + sy < py + 16 ) + { + m_samples->start( 3, eSAMPLE_CRASH ); + m_anim_timer = 0; + m_speed = 15; /* you almost stop when you crash */ + if( type == COLLISION_CRASH ) + { + if( !m_in_ext_play ) + { + m_monaco_mode = MODE_SPINOUT1; + } + else + { + m_monaco_mode = MODE_CRASH1; + m_lives--; + } + } + else if( type == COLLISION_POOL ) + { + m_pool_xpos = 512; + m_monaco_mode = MODE_SLIP1; + } + } + } +} + +/*****************************************************************/ + +int monaco_state::read_coin() +{ + static int old_trigger; + if( IS_PRESSED(COIN) ) + { + old_trigger = 1; + } + else { + if( old_trigger ){ + old_trigger = 0; + return 1; + } + old_trigger = 0; + } + return 0; +} + +void monaco_state::update_player_speed() +{ + double desired_speed, min_speed, max_speed = 44; + int accel = 0; + + if( IS_PRESSED(ACCEL1) ) accel = 1; + if( IS_PRESSED(ACCEL2) ) accel = 2; + if( IS_PRESSED(ACCEL3) ) accel = 3; + + /* gearstick is a mechanical device which can be moved anytime */ + if( IS_PRESSED(UP) ) + m_gear = 1; + else + if( IS_PRESSED(DOWN) ) + m_gear = 0; + + if (m_monaco_mode == MODE_ATTRACT) + { + m_speed = 0; + m_in_ext_play = 0; + return; + } + else + if( m_monaco_mode == MODE_START ) + { + if( accel ) m_monaco_mode = MODE_INVULNERABLE; + else return; + } + + if (m_speed) + min_speed = m_gear?0.5:0.25; + else + min_speed = 0; + + if (m_gear) + { + max_speed = 125; + if (m_score > 6000<<8) max_speed = 152; + if (m_score > 8000<<8) max_speed = 180; + } + + /* min: 0; max: 6 */ + /* 30 is derived by absolute maximum speed (above) divided by 6 */ + desired_speed = 30*(accel?(m_gear*3+accel):min_speed); + + /* 1st gear */ + if (!m_gear) + { + if (desired_speed > m_speed) m_speed += 1; + + if (desired_speed < m_speed) m_speed -= 4; + } + else + { + if (desired_speed > m_speed) m_speed += 0.4; + + if (desired_speed < m_speed) m_speed -= 2; + } + + if (m_speed < min_speed) m_speed = min_speed; + + if (m_speed > max_speed) m_speed = max_speed; +} + +double monaco_state::get_player_delta( void ) +{ + if( m_monaco_mode == MODE_ATTRACT || m_monaco_mode == MODE_START ) return 0; + return m_speed/16.0; +} + +void monaco_state::HandlePlayer() +{ + double dy = 0; + int sy = m_player_ypos; + update_player_speed(); + if( IS_PRESSED(RIGHT) && sy>0 ) dy-=1.0; + if( IS_PRESSED(LEFT) && sy<SCREEN_HEIGHT-32 ) dy+=1.0; + if( m_page_current == PAGE_SLIP ) dy = dy*0.5; + m_player_ypos += dy; +} + +/*****************************************************************/ + +void monaco_state::update_computer_cars( void ) +{ + int i; + int delta = get_player_delta(); + for( i=0; i<NUM_COMPUTER_CARS; i++ ) + { + int top_inset = m_track_top_inset; + int bottom_inset = m_track_bottom_inset; + int sx,sy; + m_xpos[i] += delta-m_computer_speed; + if( m_xpos[i] < -256 ) + m_xpos[i] += SCREEN_WIDTH*2; + else + if( m_xpos[i] > SCREEN_WIDTH + 256 ) + m_xpos[i] -= SCREEN_WIDTH*2; + + m_ypos[i] += m_dy[i]; + + sx = m_xpos[i]; + sy = m_ypos[i]; + + if( ( m_dy[i]<0 && sy<top_inset ) || + ( m_dy[i]>0 && sy+16>SCREEN_HEIGHT-bottom_inset ) ) + { + m_dy[i] *= -1; + } + + handle_collision( sx-32, sy, 32, 16, COLLISION_CRASH ); + } +} + +#define DELTA_TIME (256.0/60) + +void monaco_state::HandleRescue( void ) +{ + if( m_rescue_xpos > -64 ) + { + m_rescue_xpos -= kRESCUE_CAR_SPEED; + handle_collision( + m_rescue_xpos, + (SCREEN_HEIGHT-32)/2, + 64, + 32, + COLLISION_CRASH ); + } +} + +void monaco_state::HandlePool( void ) +{ + if( m_pool_xpos < SCREEN_WIDTH ) + { + m_pool_xpos += get_player_delta(); + handle_collision( + m_pool_xpos, + (SCREEN_HEIGHT-32)/2, + 32, + 32, + COLLISION_POOL ); + } +} + +void monaco_state::GameOver() +{ + m_monaco_mode = MODE_ATTRACT; /* this causes speed to be zero */ + m_rank_display = m_rank; /* show rank on led display */ + monaco_word_w (m_rank, m_score); /* save players score in RAM */ + m_led_high1 = monaco_word_r(1); + m_led_high2 = monaco_word_r(2); + m_led_high3 = monaco_word_r(3); /* show the 5 highest scores on led display */ + m_led_high4 = monaco_word_r(4); + m_led_high5 = monaco_word_r(5); + m_samples->stop(0); /* turn off engine sounds */ + m_samples->stop(1); + m_samples->stop(2); +} + +void monaco_state::HandleEvents() +{ + int score = m_score>>8; + int event = (score)%1000; + + if (m_monaco_mode == MODE_ATTRACT) return; + + if( m_page_current == PAGE_SMOOTH && + (score == 8000 || score == 8030 || event == 185 || event == 685) ) + { + m_pool_xpos = -32<<8; + } + + if( m_in_ext_play ) + { + /* Extended Play */ + if( m_rescue_xpos<= -64 && + (machine().rand()&3) == 0 && + (event == 0 || event == 75 || event == 125 || event == 250 || event == 500) ) + { + m_rescue_xpos = SCREEN_WIDTH; + m_samples->start( 1, eSAMPLE_SIREN ); + } + + if( event == 0 ) m_page_next2 = PAGE_SMOOTH; + else if( event == 95 ) m_page_next2 = PAGE_GRAVEL; + else if( event == 150 ) m_page_next2 = PAGE_SMOOTH; + else if( event == 295 ) m_page_next2 = PAGE_SLIP; + else if( event == 475 ) m_page_next2 = PAGE_SMOOTH; + else if( event == 595 ) m_page_next2 = PAGE_BRIDGE; + else if( event == 635 ) m_page_next2 = PAGE_SMOOTH; + else if( event == 795 ) m_page_next2 = PAGE_TUNNEL; + } + else + { + /* Timed Play */ + if( event == 0 ) m_page_next2 = PAGE_SMOOTH; + else if( event == 295 ) m_page_next2 = PAGE_SLIP; + else if( event == 450 ) m_page_next2 = PAGE_SMOOTH; + else if( event == 795 ) m_page_next2 = PAGE_TUNNEL; + } + + if ((!m_time) && (!m_in_ext_play)) + { + if (m_score > EXT_SCORE) + { + /* Turn On Extended Play */ + m_in_ext_play = 1; +// m_samples->start( 2, eSAMPLE_EXTEND ); + } + else + m_lives = 0; + } + + if ((!m_lives) && (m_monaco_mode != MODE_ATTRACT)) + { + /* Game Over */ + if (m_rank == 1) m_samples->start (4, eSAMPLE_FANFARE); + + GameOver(); + } +} + +INTERRUPT_GEN_MEMBER( monaco_state::monaco_interrupt ) +{ + int i; + double delta = get_player_delta(); + + HandleRescue(); + HandlePool(); + HandlePlayer(); + /* increase score */ + m_score += m_speed; + /* cap the score at 9999 */ + if ( m_score > (9999<<8 | 255)) m_score = (9999<<8 | 255); + + /* Bonus car at 2000, 4000, 6000, 8000 points */ + + if ( m_score < 9000<<8) m_bonus_score += m_speed; + + if ( m_bonus_score > 2000<<8 ) + { + m_lives++; + m_bonus_score -= 2000<<8; + m_samples->start( 2, eSAMPLE_EXTEND ); + } + /* decrease time remaining */ + if( m_time>0 ) + { + if( m_monaco_mode != MODE_ATTRACT && m_monaco_mode != MODE_START ) + { + if( m_time<DELTA_TIME ) m_time = 0; + else m_time -= DELTA_TIME; + } + } + /* adjust ranking if a score is passed */ + if (m_rank > 1) + { + if (m_score > monaco_word_r (m_rank - 1)) + { + monaco_word_w ( m_rank , monaco_word_r (m_rank - 1)); + m_rank--; + } + } + + HandleEvents(); + + switch( m_monaco_mode ) + { + case MODE_ATTRACT: + m_pool_xpos = SCREEN_WIDTH; + m_rescue_xpos = -64; + + if( read_coin() ) + { + m_samples->start( 0, eSAMPLE_ENGINE, 1/*loop*/ ); + m_score = 0; + m_bonus_score = 0; + m_rank_display = 0xffff; /* rank is blank till game ends */ + m_lives = 1; + if (m_plays < 999) m_plays++; + m_rank = m_plays; + m_time = FIRST_TIME; + m_monaco_mode = MODE_START; + m_anim_timer = 0; + m_player_ypos = 0;//32; + } + default: + break; + } + + m_scroll += delta; + if( m_scroll>=14*32 ) + { + m_scroll -= 14*32; + m_page_current = m_page_next; + m_page_next = m_page_next2; + } + + m_ticks++; /* for animation */ + + if( m_page_next != PAGE_TUNNEL && m_page_current != PAGE_TUNNEL && + m_page_next != PAGE_BRIDGE && m_page_current != PAGE_BRIDGE ) + { + /* delta: player speed */ + m_track_bottom_inset += m_track_bottom_delta*delta/8; + m_track_top_inset += m_track_top_delta*delta/8; + + if( m_track_bottom_inset <= 32 ) + { + m_track_bottom_delta = 1; + } + else if( m_track_bottom_inset >= 96 ) + { + m_track_bottom_delta = -1; + } + + if( m_track_top_inset <= 32 ) + { + m_track_top_delta = 1; + } + else if( m_track_top_inset >= 64 ) + { + m_track_top_delta = -1; + } + } + + switch( m_monaco_mode ) + { + case MODE_ATTRACT: + break; + case MODE_START: + if( m_speed ) + { + m_monaco_mode = MODE_INVULNERABLE; + m_anim_timer = 0; + } + break; + + case MODE_INVULNERABLE: + m_anim_timer++; + if( m_anim_timer > 60*2 ) + { + m_monaco_mode = MODE_NORMAL; + m_anim_timer = 0; + } + break; + + case MODE_NORMAL: + break; + + case MODE_GRAVEL: +// m_samples->start (1, eSAMPLE_GRAVEL); There is no code to make this mode occur + break; + + case MODE_SLIP1: + case MODE_SLIP2: + m_anim_timer++; + if( m_anim_timer>16 ) + { + m_anim_timer = 0; + if( m_monaco_mode!=MODE_SLIP2 ) + { + m_monaco_mode = MODE_SLIP2; + } + else + { + m_monaco_mode = MODE_NORMAL; + } + } + m_samples->start( 1, eSAMPLE_SLIP ); + break; + + case MODE_SPINOUT1: + case MODE_SPINOUT2: + case MODE_SPINOUT3: + case MODE_SPINOUT4: + if( m_player_ypos > 0 ) + { + uint8_t temp = (m_anim_timer/2)&3; + if (temp == 0) m_monaco_mode = MODE_SPINOUT1; + else if (temp == 1) m_monaco_mode = MODE_SPINOUT2; + else if (temp == 2) m_monaco_mode = MODE_SPINOUT3; + else if (temp == 3) m_monaco_mode = MODE_SPINOUT4; + m_anim_timer++; + m_player_ypos-=2.0; + } + else + { + m_player_ypos = 0; + m_monaco_mode = MODE_INVULNERABLE; + m_anim_timer = 0; + } + if( m_speed > 40 ) + { + m_speed-= 1.0; + } + break; + + case MODE_CRASH1: + case MODE_CRASH2: + case MODE_CRASH3: + case MODE_CRASH4: + m_anim_timer++; + if( m_anim_timer>8 ) + { + m_anim_timer = 0; + if( m_monaco_mode == MODE_CRASH1 ) m_monaco_mode = MODE_CRASH2; + else + if( m_monaco_mode == MODE_CRASH2 ) m_monaco_mode = MODE_CRASH3; + else + if( m_monaco_mode == MODE_CRASH3 ) m_monaco_mode = MODE_CRASH4; + else + { + m_monaco_mode = MODE_INVULNERABLE; + m_player_ypos = 0; + } + } + break; + default: + break; + } + + if( m_monaco_mode == MODE_NORMAL ) + { + if( m_player_ypos+16 > m_track_top_inset+8 && + m_player_ypos+16 < SCREEN_HEIGHT - (m_track_bottom_inset+8) ) + { + m_bShaking = 0; + } + else if( m_player_ypos+16 > m_track_top_inset+8 - 16 && + m_player_ypos+16 < SCREEN_HEIGHT - (m_track_bottom_inset+8 - 16) ) + { + /* brush roadside */ + m_bShaking = 1; + } + else + { + /* crash wall */ + m_monaco_mode = MODE_SPINOUT1; + m_anim_timer = 0; + m_bShaking = 1; + } + } + else + { + m_bShaking = 0; + } + + update_computer_cars(); + + for( i=0; i<NUM_COMPUTER_CARS; i++ ) + { + m_x[i] = m_xpos[i] - 32; + m_y[i] = m_ypos[i]; + m_tile[i] = (m_ticks&2)>>1; + m_color[i] = i; /* hack */ + } + m_rescue_x = m_rescue_xpos; + m_rescue_y = BRIDGE_YPOS; + m_rescue_tile = (m_ticks&2)>>1; + m_pool_x = m_pool_xpos; + m_pool_y = (SCREEN_HEIGHT-32)/2; + m_top_inset = m_track_top_inset; + m_bottom_inset = m_track_bottom_inset; + m_bSignalVisible = (m_page_next == PAGE_BRIDGE || m_page_next == PAGE_BRIDGE ); + m_led_score = m_score; + m_led_gear = m_gear; + m_led_lives = m_lives; + m_led_time = m_time; + m_led_rank = m_rank_display; + // m_led_rank = m_rank; /* test to display real-time ranking */ + m_led_plays = m_plays; + m_led_speed = m_speed; + m_right_page = m_page_current; + m_left_page = m_page_next; + m_left_text = -1; + m_right_text = -1; + + /* we stretch the text so that it is proportioned correctly + ** compared to the rest of the in-game graphics + */ + + switch( m_monaco_mode ) + { + case MODE_ATTRACT: + m_left_text = TEXT_GAMEOVER; + m_right_text = TEXT_DEPOSITCOIN; + break; + + case MODE_START: + m_right_text = TEXT_START; + break; + + default: + break; + } + + if (m_in_ext_play) m_left_text = TEXT_EXTENDEDPLAY; + + m_player_x = get_player_xpos(); + m_player_y = m_player_ypos; + m_player_tile = -1; + m_player_splash = -1; + switch( m_monaco_mode ) + { + case MODE_ATTRACT: + break; + + case MODE_SLIP1: + m_player_splash = 0; + m_player_tile = (m_ticks&2)>>1; + break; + + case MODE_SLIP2: + m_player_splash = 1; + m_player_tile = (m_ticks&2)>>1; + break; + + case MODE_SPINOUT1: + m_player_tile = 2; + break; + + case MODE_SPINOUT2: + m_player_tile = 3; + break; + + case MODE_SPINOUT3: + m_player_tile = 4; + break; + case MODE_SPINOUT4: + m_player_tile = 5; + break; + + case MODE_CRASH1: + case MODE_CRASH2: + case MODE_CRASH3: + case MODE_CRASH4: + m_player_tile = m_monaco_mode-MODE_CRASH1 + 6; + break; + + default: + if( m_bShaking ) + { + m_player_tile = 10+((m_ticks&4)>>2); + } + else + { + m_player_tile = (m_ticks&2)>>1; + } + break; + } + + return; +} + +/*********************************************/ + +void monaco_state::monaco_map(address_map &map) {/* fake */ + map(0x0000,0xefff).rom(); + map(0xf000,0xffff).rw(FUNC(monaco_state::monaco_ram_r),FUNC(monaco_state::monaco_ram_w)).share("ram"); /* scores need 4000 bytes */ +} + +static INPUT_PORTS_START( monaco ) + PORT_START("IN0") /* fake */ + PORT_BIT( DOWN, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY + PORT_BIT( UP, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY + PORT_BIT( RIGHT, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY + PORT_BIT( LEFT, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY + PORT_BIT( COIN, IP_ACTIVE_HIGH, IPT_COIN1 ) + PORT_BIT( ACCEL1, IP_ACTIVE_HIGH, IPT_BUTTON1 ) + PORT_BIT( ACCEL2, IP_ACTIVE_HIGH, IPT_BUTTON2 ) + PORT_BIT( ACCEL3, IP_ACTIVE_HIGH, IPT_BUTTON3 ) +INPUT_PORTS_END + +/***************************************************************************/ + +static gfx_layout tree_layout = +{ + 32,32, + 1, /* number of characters */ + 2, /* number of bitplanes */ + { 0,4 }, + { + 0x003,0x002,0x001,0x000,0x103,0x102,0x101,0x100, + 0x203,0x202,0x201,0x200,0x303,0x302,0x301,0x300, + 0x403,0x402,0x401,0x400,0x503,0x502,0x501,0x500, + 0x603,0x602,0x601,0x600,0x703,0x702,0x701,0x700 + }, + { + 0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38, + 0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78, + 0x80,0x88,0x90,0x98,0xa0,0xa8,0xb0,0xb8, + 0xc0,0xc8,0xd0,0xd8,0xe0,0xe8,0xf0,0xf8 + }, + 0 +}; + +static gfx_layout pool_layout = +{ + 32,32, + 1, /* number of characters */ + 1, /* number of bitplanes */ + { 0 }, + { + 0x003,0x002,0x001,0x000,0x103,0x102,0x101,0x100, + 0x203,0x202,0x201,0x200,0x303,0x302,0x301,0x300, + 0x403,0x402,0x401,0x400,0x503,0x502,0x501,0x500, + 0x603,0x602,0x601,0x600,0x703,0x702,0x701,0x700 + }, + { + 0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38, + 0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78, + 0x80,0x88,0x90,0x98,0xa0,0xa8,0xb0,0xb8, + 0xc0,0xc8,0xd0,0xd8,0xe0,0xe8,0xf0,0xf8 + }, + 4 +}; + +static gfx_layout player_layout = +{ + 32,32, + 2, /* number of characters */ + 2, /* number of bitplanes */ + { 0,4 }, + { + 0x003,0x002,0x001,0x000,0x103,0x102,0x101,0x100, + 0x203,0x202,0x201,0x200,0x303,0x302,0x301,0x300, + 0x403,0x402,0x401,0x400,0x503,0x502,0x501,0x500, + 0x603,0x602,0x601,0x600,0x703,0x702,0x701,0x700 + }, + { + 0x80,0x88,0x90,0x98,0xa0,0xa8,0xb0,0xb8, + 0xc0,0xc8,0xd0,0xd8,0xe0,0xe8,0xf0,0xf8, + 0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38, + 0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78 + }, + 0x800 +}; + +static gfx_layout text_layout = +{ + 16,64, + 4, /* number of characters */ + 1, /* number of bitplanes */ + { 0 }, + { + 0x007,0x006,0x005,0x004,0x003,0x002,0x001,0x000, + 0x207,0x206,0x205,0x204,0x203,0x202,0x201,0x200, + }, + { + 0x100,0x108,0x110,0x118,0x120,0x128,0x130,0x138, + 0x140,0x148,0x150,0x158,0x160,0x168,0x170,0x178, + 0x180,0x188,0x190,0x198,0x1a0,0x1a8,0x1b0,0x1b8, + 0x1c0,0x1c8,0x1d0,0x1d8,0x1e0,0x1e8,0x1f0,0x1f8, + 0x000,0x008,0x010,0x018,0x020,0x028,0x030,0x038, + 0x040,0x048,0x050,0x058,0x060,0x068,0x070,0x078, + 0x080,0x088,0x090,0x098,0x0a0,0x0a8,0x0b0,0x0b8, + 0x0c0,0x0c8,0x0d0,0x0d8,0x0e0,0x0e8,0x0f0,0x0f8, + }, + 0x400 +}; + +static gfx_layout house_layout = +{ + 32,32, + 1, /* number of characters */ + 4, /* number of bitplanes */ + { 0,2,4,6 }, + { + 0x001,0x000,0x101,0x100,0x201,0x200,0x301,0x300, + 0x401,0x400,0x501,0x500,0x601,0x600,0x701,0x700, + 0x801,0x800,0x901,0x900,0xa01,0xa00,0xb01,0xb00, + 0xc01,0xc00,0xd01,0xd00,0xe01,0xe00,0xf01,0xf00 + }, + { + 0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38, + 0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78, + 0x80,0x88,0x90,0x98,0xa0,0xa8,0xb0,0xb8, + 0xc0,0xc8,0xd0,0xd8,0xe0,0xe8,0xf0,0xf8 + }, + 4 +}; + +static gfx_layout signal_layout = +{ + 32,32, + 1, /* number of characters */ + 1, /* number of bitplanes */ + { 0 }, + { + 0x001,0x000,0x101,0x100,0x201,0x200,0x301,0x300, + 0x401,0x400,0x501,0x500,0x601,0x600,0x701,0x700, + 0x801,0x800,0x901,0x900,0xa01,0xa00,0xb01,0xb00, + 0xc01,0xc00,0xd01,0xd00,0xe01,0xe00,0xf01,0xf00 + }, + { + 0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38, + 0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78, + 0x80,0x88,0x90,0x98,0xa0,0xa8,0xb0,0xb8, + 0xc0,0xc8,0xd0,0xd8,0xe0,0xe8,0xf0,0xf8, + }, + 0 +}; + +static gfx_layout dummy_layout = +{ + 32,16, + 2, /* number of characters */ + 2, /* number of bitplanes */ + { 4,6 }, + { + 0x001,0x000,0x101,0x100,0x201,0x200,0x301,0x300, + 0x401,0x400,0x501,0x500,0x601,0x600,0x701,0x700, + 0x801,0x800,0x901,0x900,0xa01,0xa00,0xb01,0xb00, + 0xc01,0xc00,0xd01,0xd00,0xe01,0xe00,0xf01,0xf00 + }, + { + 0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38, + 0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78 + }, + 0x80 +}; + +static gfx_layout computer_layout = +{ + 32,16, + 2, /* number of characters */ + 4, /* number of bitplanes */ + { 0,2,4,6 }, + { + 0x001,0x000,0x081,0x080,0x101,0x100,0x181,0x180, + 0x201,0x200,0x281,0x280,0x301,0x300,0x381,0x380, + 0x401,0x400,0x481,0x480,0x501,0x500,0x581,0x580, + 0x601,0x600,0x681,0x680,0x701,0x700,0x781,0x780 + }, + { + 0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38, + 0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78 + }, + 0x800 +}; + +static gfx_layout rescue_layout = +{ + 64,16, + 2, /* number of characters */ + 4, /* number of bitplanes */ + { 0,2,4,6 }, + { + 0x001,0x001,0x000,0x000,0x081,0x081,0x080,0x080, + 0x101,0x101,0x100,0x100,0x181,0x181,0x180,0x180, + 0x201,0x201,0x200,0x200,0x281,0x281,0x280,0x280, + 0x301,0x301,0x300,0x300,0x381,0x381,0x380,0x380, + 0x401,0x401,0x400,0x400,0x481,0x481,0x480,0x480, + 0x501,0x501,0x500,0x500,0x581,0x581,0x580,0x580, + 0x601,0x601,0x600,0x600,0x681,0x681,0x680,0x680, + 0x701,0x701,0x700,0x700,0x781,0x781,0x780,0x780 + }, + { + 0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38, + 0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78 + }, + 0x800 +}; + +static gfx_layout explode_layout = +{ + 32,32, + 4, /* number of characters */ + 1, /* number of bitplanes */ + { 0 }, + { + 0x007,0x006,0x005,0x004,0x003,0x002,0x001,0x000, + 0x107,0x106,0x105,0x104,0x103,0x102,0x101,0x100, + 0x207,0x206,0x205,0x204,0x203,0x202,0x201,0x200, + 0x307,0x306,0x305,0x304,0x303,0x302,0x301,0x300, + }, + { + 0x80,0x88,0x90,0x98,0xa0,0xa8,0xb0,0xb8, + 0xc0,0xc8,0xd0,0xd8,0xe0,0xe8,0xf0,0xf8, + 0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38, + 0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78 + }, + 0x400 +}; + +static gfx_layout bridge_layout = +{ + 32,16, + 2, /* number of characters */ + 4, /* number of bitplanes */ + { 0,1,2,3 }, + { + 0x004,0x000,0x104,0x100,0x204,0x200,0x304,0x300, + 0x404,0x400,0x504,0x500,0x604,0x600,0x704,0x700, + 0x804,0x800,0x904,0x900,0xa04,0xa00,0xb04,0xb00, + 0xc04,0xc00,0xd04,0xd00,0xe04,0xe00,0xf04,0xf00 + }, + { + 0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38, + 0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78 + }, + 0x80 +}; + +static gfx_layout unknown_layout = +{ /* police car? */ + 32,32, + 2, /* number of characters */ + 1, /* number of bitplanes */ + { 0 }, + { + 0x307,0x306,0x305,0x304,0x303,0x302,0x301,0x300, + 0x207,0x206,0x205,0x204,0x203,0x202,0x201,0x200, + 0x107,0x106,0x105,0x104,0x103,0x102,0x101,0x100, + 0x007,0x006,0x005,0x004,0x003,0x002,0x001,0x000, + }, + { + 0x80,0x88,0x90,0x98,0xa0,0xa8,0xb0,0xb8, + 0xc0,0xc8,0xd0,0xd8,0xe0,0xe8,0xf0,0xf8, + 0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38, + 0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78 + }, + 0x400 +}; + + +static gfx_layout tunnel_layout = +{ + 32,32, + 2, /* number of characters */ + 1, /* number of bitplanes */ + { 0 }, + { + 0x003,0x002,0x001,0x000,0x103,0x102,0x101,0x100, + 0x203,0x202,0x201,0x200,0x303,0x302,0x301,0x300, + 0x403,0x402,0x401,0x400,0x503,0x502,0x501,0x500, + 0x603,0x602,0x601,0x600,0x703,0x702,0x701,0x700 + }, + { + 0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38, + 0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78, + 0x80,0x88,0x90,0x98,0xa0,0xa8,0xb0,0xb8, + 0xc0,0xc8,0xd0,0xd8,0xe0,0xe8,0xf0,0xf8 + }, + 4 +}; + +static gfx_layout belt_layout = { + 32,16, + 2, /* number of characters */ + 1, /* number of bitplanes */ + { 4 }, + { + 0x003,0x002,0x001,0x000,0x103,0x102,0x101,0x100, + 0x203,0x202,0x201,0x200,0x303,0x302,0x301,0x300, + 0x403,0x402,0x401,0x400,0x503,0x502,0x501,0x500, + 0x603,0x602,0x601,0x600,0x703,0x702,0x701,0x700 + }, + { + 0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38, + 0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78, + 0x80,0x88,0x90,0x98,0xa0,0xa8,0xb0,0xb8, + 0xc0,0xc8,0xd0,0xd8,0xe0,0xe8,0xf0,0xf8 + }, + 0x80 +}; + +static GFXDECODE_START( gfx_monaco ) + GFXDECODE_ENTRY( "gfx1", 0x0100, unknown_layout, 0x00, 1) /* PR125: unused; police car? */ + GFXDECODE_ENTRY( "gfx1", 0x0200, explode_layout, RED_CLUT, 2) /* PR126: explosion */ + GFXDECODE_ENTRY( "gfx1", 0x0400, player_layout, PLAYER_CLUT, 1) /* PR127: player's car */ + GFXDECODE_ENTRY( "gfx1", 0x0600, player_layout, PLAYER_CLUT, 1) /* PR128: swerving (rough road) */ + GFXDECODE_ENTRY( "gfx1", 0x0800, player_layout, PLAYER_CLUT, 1) /* PR129: spinout1 */ + GFXDECODE_ENTRY( "gfx1", 0x0a00, player_layout, PLAYER_CLUT, 1) /* PR130: spinout2 */ + GFXDECODE_ENTRY( "gfx1", 0x0c00, explode_layout, CYAN_CLUT, 1) /* PR131: spray */ + GFXDECODE_ENTRY( "gfx1", 0x0e00, computer_layout, 0x00, 5) /* PR132: computer car A,B */ + GFXDECODE_ENTRY( "gfx1", 0x1000, text_layout, CYAN_CLUT, 2) /* PR133: text */ + GFXDECODE_ENTRY( "gfx1", 0x1200, tree_layout, TREE_CLUT, 1) /* PR134: tree */ + GFXDECODE_ENTRY( "gfx1", 0x1300, tree_layout, TREE_CLUT, 1) /* PR134: grass */ + GFXDECODE_ENTRY( "gfx1", 0x1400, tree_layout, SHRUB_CLUT, 1) /* PR135: shrub */ + GFXDECODE_ENTRY( "gfx1", 0x1600, house_layout, HOUSE_CLUT, 1) /* PR136: house */ + GFXDECODE_ENTRY( "gfx1", 0x1800, tunnel_layout, RED_CLUT, 1) /* PR137: tunnel */ + GFXDECODE_ENTRY( "gfx1", 0x1900, pool_layout, CYAN_CLUT, 1) /* PR137: pool (oil slick) */ + GFXDECODE_ENTRY( "gfx1", 0x1900, belt_layout, GRASS_CLUT, 2) /* PR137: red/green belt */ + GFXDECODE_ENTRY( "gfx1", 0x1a00, rescue_layout, RESCUE_CLUT, 1) /* PR138: rescue car */ + GFXDECODE_ENTRY( "gfx1", 0x1c00, signal_layout, YELLOW_CLUT, 1) /* PR139: bridge signal (yellow on black)*/ + GFXDECODE_ENTRY( "gfx1", 0x1c00, dummy_layout, PLAYER_CLUT, 1) /* PR139: dummy car */ + GFXDECODE_ENTRY( "gfx1", 0x1e00, bridge_layout, WATER_CLUT, 1) /* PR140: bridge-water */ + GFXDECODE_ENTRY( "gfx1", 0x2000, bridge_layout, WATER_CLUT, 1) /* PR141: bridge-pillar */ +GFXDECODE_END + +static const char *const monaco_sample_names[] = +{ + "*monaco", + "6car1", + "6car2", + "6crash", + "6engine", + "6extend", + "6fanfare", + "6siren", + "6slip", +// "gravel", + 0 +}; + +/* ch 0 = engine; ch 1 = ambulance, puddle; ch 2 = extra car; ch 3 = crash; ch 4 = fanfare */ + +void monaco_state::machine_reset() +{ + uint16_t i; + m_time = 0; /* time remaining = 0 */ + m_score = 0; /* player score = 0 */ + m_gear = 0; /* low gear */ + m_plays = 0; /* no games played */ + for (i = 0;i < 1000;i++) + monaco_word_w (i, 0); /* delete all scores from RAM */ + GameOver(); +} + +void monaco_state::monaco(machine_config &config) +{ + /* basic machine hardware */ + Z80(config, m_maincpu, 200); // fake + m_maincpu->set_addrmap(AS_PROGRAM, &monaco_state::monaco_map); + m_maincpu->set_vblank_int("screen", FUNC(monaco_state::monaco_interrupt)); + + /* video hardware */ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_refresh_hz(60); + screen.set_vblank_time(ATTOSECONDS_IN_USEC(4368)); + screen.set_size(SCREEN_WIDTH, SCREEN_HEIGHT); + screen.set_visarea(0, SCREEN_WIDTH-1, 0, SCREEN_HEIGHT-1); + screen.set_screen_update(FUNC(monaco_state::screen_update_monaco)); + screen.set_palette(m_palette); + + GFXDECODE(config, m_gfxdecode, m_palette, gfx_monaco); + PALETTE(config, m_palette, palette_device::BLACK, 160); // set up in video start + + MCFG_VIDEO_START_OVERRIDE(monaco_state, monaco) + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + SAMPLES(config, m_samples); + m_samples->set_channels(5); + m_samples->set_samples_names(monaco_sample_names); + m_samples->add_route(ALL_OUTPUTS, "mono", 0.90); +} + +/*****************************************************************/ + +ROM_START( monaco ) + ROM_REGION( 0xf000, "maincpu", ROMREGION_ERASE00 ) /* fake */ + + ROM_REGION( 0x3000, "gfx1", 0 ) + ROM_LOAD( "pr125", 512*0, 512, CRC(7a66ed4c) SHA1(514e129c334a551b931c90b063b073a9b4bdffc3) ) /* light data */ + ROM_LOAD( "pr126", 512*1, 512, CRC(5d7a8f12) SHA1(b4f0d21b91a7cf7002f99c08788669c7c38be51d) ) /* explosion */ + ROM_LOAD( "pr127", 512*2, 512, CRC(8ffdc2f0) SHA1(05cc3330c067965b8b90b5d27119fe9f26580a13) ) /* car(2)main */ + ROM_LOAD( "pr128", 512*3, 512, CRC(dde29dea) SHA1(34c413edff991297471bd0bc193c4bd8ede4e468) ) /* car(2)rotated */ + ROM_LOAD( "pr129", 512*4, 512, CRC(7b18af26) SHA1(3d1ff2610813544c3b9b65182f081272a9537640) ) /* car(2)rotated */ + ROM_LOAD( "pr130", 512*5, 512, CRC(9ef1913b) SHA1(58830121781b8a13532eaf8ea13ec07f10522320) ) /* car(2) spinout */ + ROM_LOAD( "pr131", 512*6, 512, CRC(ff31eb01) SHA1(fd6bcd92c4bd919bb1a96ca97688d46cb310b39d) ) /* splash */ + ROM_LOAD( "pr132", 512*7, 512, CRC(6b8ad9bc) SHA1(be36e3b6b647d3a9565bc45903027c791dc889e5) ) /* car(2)(other) */ + ROM_LOAD( "pr133", 512*8, 512, CRC(d50641d9) SHA1(bf399e9830c88e4d8f8fb386305f54ef766946d9) ) /* text(4) */ + ROM_LOAD( "pr134", 512*9, 512, CRC(8ebd50bb) SHA1(98d51f503753d4d7191a09b509d26c1e049e981a) ) /* tree, grass */ + ROM_LOAD( "pr135", 512*10, 512, CRC(986eda32) SHA1(73fa539d4c83748952d9339985208520fec955f3) ) /* shrub */ + ROM_LOAD( "pr136", 512*11, 512, CRC(ecc5d1a2) SHA1(33bff7381785557a85e4c8bdd74679b59e0ed9d5) ) /* house */ + ROM_LOAD( "pr137", 512*12, 512, CRC(ddd9004e) SHA1(5229c34578e66d9c51a05439a516513946ba69ed) ) /* tunnel, oil slip */ + ROM_LOAD( "pr138", 512*13, 512, CRC(058e53cf) SHA1(7c3aaaca5a9e9ce3a3badd0dcc8360342673a397) ) /* firetruck */ + ROM_LOAD( "pr139", 512*14, 512, CRC(e8ba0794) SHA1(eadd7425134f26b1c126bbcd3d3dabf4b2e1fe70) ) /* car, bridge symbol */ + ROM_LOAD( "pr140", 512*15, 512, CRC(48e9971b) SHA1(c0c265cdc08727e3caaf49cdfe728a91c4c46ba2) ) /* bridge-water */ + ROM_LOAD( "pr141", 512*16, 512, CRC(99934236) SHA1(ec271f3e690d5c57ead9132b22b9b1b966e4d170) ) /* bridge-pillar */ + + ROM_REGION( 32*3, "proms", 0 ) + ROM_LOAD( "prm38", 0*32, 32, CRC(82dd0a0f) SHA1(3e7e475c3270853d70c1fe90a773172532b60cfb) ) /* acceleration related */ + ROM_LOAD( "prm39", 1*32, 32, CRC(6acfa0da) SHA1(1e56da4cdf71a095eac29878969b831babac222b) ) /* regulates opponent car speed */ + +// ROM_LOAD( "prm-40", 2*32, 32, CRC(8030dac8) ) +/* PR40 is in the Fanfare sound circuit and seems to access the particular + * notes for the fanfare sound (so PR40 may contain timing and pointer info + * on the melody). The switch (SW1) I mentioned before that helped in tuning + * the fanfare sound with the 6 pots seems to help in making the tuning of each + * pot for output of one of three audio frequencies (262, 330, 392 Hz), + * instead of having to tune to 6 different frequencies (a production/test + * equipment issue). + * In any case, if we get a good sample of this fanfare sound, we will not + * need to bother with this circuit or PR40. As far a I have seen, the + * fanfare sound only comes up at the end of the game if you have a top five + * score and possibly when you plug in the game. + */ +ROM_END + +void monaco_state::init_monaco() +{ + int i; + const double dy_table[5] = + { + 0.75, + 1.25, + 1.75, + 2.00, + 2.50 + }; + + m_computer_speed = 52*16/256.0; + m_track_bottom_inset = 32; + m_track_top_inset = 32; + m_track_bottom_delta = 1; + m_track_top_delta = 1; + + /* computer car */ + for( i=0; i<NUM_COMPUTER_CARS; i++ ) + { + m_xpos[i] = i*32*3 + ((i>1)?192:0); + m_ypos[i] = (SCREEN_HEIGHT-16)/2; + m_dy[i] = dy_table[i]; + } +} + +/* rom parent machine inp init */ +GAMEL( 1979, monaco, 0, monaco, monaco, monaco_state, init_monaco, ROT90, "Sega", "Monaco GP", 0, layout_monaco ) + + + + +/* Monaco GP video hardware simulation */ + + +#define plot_pixel(bitmap,x,y,col) do { bitmap.pix16(y, x) = col; } while (0) + +void monaco_state::draw_computer( bitmap_ind16 &bitmap, const rectangle clip ) +{ + int i; + + for( i=0; i<NUM_COMPUTER_CARS; i++ ) + { + m_gfxdecode->gfx(GFX_COMPUTER)->transpen( + bitmap, clip, + m_tile[i], + m_color[i], + 0,0, + m_x[i], + m_y[i], + 0 ); + } + + m_gfxdecode->gfx(GFX_RESCUE_CAR)->transpen( + bitmap, clip, + m_rescue_tile, + 0, /* color */ + 0,0, + m_rescue_x, + m_rescue_y, + 0 ); +} + +void monaco_state::draw_pool( bitmap_ind16 &bitmap, const rectangle clip ) +{ + m_gfxdecode->gfx(GFX_POOL)->transpen( + bitmap, clip, + 0,0, /* tile,color */ + 0,0, /* flip */ + m_pool_x, + m_pool_y, + 0 ); +} + +void monaco_state::draw_player( bitmap_ind16 &bitmap, const rectangle clip ) +{ + int gfx; + int tile; + + switch( m_player_splash ) + { + case 0: + m_gfxdecode->gfx(GFX_SPRAY)->transpen( bitmap, clip, + 2,0,0,0, + m_player_x, + m_player_y+32-8, + 0); + m_gfxdecode->gfx(GFX_SPRAY)->transpen( bitmap, clip, + 0,0,0,0, + m_player_x, + m_player_y-32+8, + 0); + break; + case 1: + m_gfxdecode->gfx(GFX_SPRAY)->transpen( bitmap, clip, + 3,0,0,0, + m_player_x, + m_player_y+32-8, + 0); + m_gfxdecode->gfx(GFX_SPRAY)->transpen( bitmap, clip, + 1,0,0,0, + m_player_x, + m_player_y-32+8, + 0); + break; + } + + tile = m_player_tile; + gfx = 0; + if( tile>=0 ) + { + switch( tile ) + { + case 0: + case 1: gfx = GFX_PLAYER; break; + + case 2: + case 3: gfx = GFX_SPINOUT1; tile -= 2; break; + + case 4: + case 5: gfx = GFX_SPINOUT2; tile -= 4; break; + + case 6: + case 7: + case 8: + case 9: gfx = GFX_EXPLOSION; tile -= 6; break; + + case 10: + case 11: gfx = GFX_SHAKE; tile -= 10; break; + } + + m_gfxdecode->gfx(gfx)->transpen( bitmap, clip, + tile,0, + 0,0, + m_player_x, + m_player_y, + 0); + } +} + +/*****************************************************************/ + +void monaco_state::draw_strip( bitmap_ind16 &bitmap, int sy, int x0, int x1, int xpos, int pen ) +{ + int sx; + if( x0<xpos ) x0 = xpos; + if( x1>xpos+PAGE_SIZE ) x1 = xpos+PAGE_SIZE; + if( x0<0 ) x0 = 0; + if( x1>SCREEN_WIDTH ) x1 = SCREEN_WIDTH; + for( sx=x0; sx<x1; sx++ ) plot_pixel( bitmap,sx,sy,pen ); +} + +void monaco_state::DrawSmoothZone( bitmap_ind16 &bitmap, const rectangle clip, int xpos ) +{ + const uint8_t data[14] = + { + GFX_GRASS,GFX_GRASS,GFX_GRASS, + GFX_TREE,GFX_GRASS,GFX_TREE, + GFX_GRASS,GFX_HOUSE,GFX_GRASS, + GFX_SHRUB,GFX_SHRUB, + GFX_GRASS,GFX_GRASS,GFX_GRASS + }; + int top_inset = m_top_inset; + int bottom_inset = m_bottom_inset; + int i; + + draw_strip( bitmap, top_inset, xpos, xpos+PAGE_SIZE, xpos, YELLOW_PEN ); + draw_strip( bitmap, SCREEN_HEIGHT-1 - bottom_inset, xpos, xpos+PAGE_SIZE, xpos, YELLOW_PEN ); + + for( i=0; i<14; i++ ) + { + int code = data[i]; + gfx_element *gfx = m_gfxdecode->gfx(code); + gfx_element *belt = m_gfxdecode->gfx((code==GFX_HOUSE)?GFX_DUMMY:GFX_BELT); + int j; + + for( j=0; j<3; j++ ) + { + gfx->opaque( bitmap, clip, + 0,0, /* number, color */ + 0,0, /* no flip */ + xpos, m_top_inset-32-16-j*32 ); + + gfx->opaque( bitmap, clip, + 0,0, /* number, color */ + 0,0, /* no flip */ + xpos,SCREEN_HEIGHT-m_bottom_inset+j*32+16-8 ); + } + belt->opaque( bitmap, clip, + 0,0, /* number, color */ + 0,0, /* no flip */ + xpos, m_top_inset-16 ); + + belt->opaque( bitmap, clip, + 0,0, /* number, color */ + 0,0, /* no flip */ + xpos,SCREEN_HEIGHT-m_bottom_inset ); + + xpos += 32; + } +} + +void monaco_state::DrawSlipZone( bitmap_ind16 &bitmap, const rectangle clip, int xpos ) +{ + const uint8_t data[14] = + { + GFX_SHRUB,GFX_SHRUB,GFX_SHRUB, + GFX_SHRUB,GFX_SHRUB,GFX_SHRUB, + GFX_SHRUB,GFX_HOUSE, + GFX_SHRUB,GFX_SHRUB,GFX_SHRUB, + GFX_SHRUB,/* start */GFX_SHRUB,GFX_SHRUB + }; + + int top_inset = m_top_inset; + int bottom_inset = m_bottom_inset; + int i; + + draw_strip( bitmap, top_inset, xpos, xpos+PAGE_SIZE, xpos, YELLOW_PEN ); + draw_strip( bitmap, SCREEN_HEIGHT-1 - bottom_inset, xpos, xpos+PAGE_SIZE, xpos, YELLOW_PEN ); + + for( i=0; i<14; i++ ){ + int code = data[i]; + gfx_element *gfx = m_gfxdecode->gfx(code); + gfx_element *belt = m_gfxdecode->gfx((code==GFX_HOUSE)?GFX_DUMMY:GFX_BELT); + int j; + + for( j=0; j<3; j++ ){ + gfx->opaque( bitmap, clip, + 0,0, /* number, color */ + 0,0, /* no flip */ + xpos, top_inset-32-j*32-16 ); + + gfx->opaque( bitmap, clip, + 0,0, /* number, color */ + 0,0, /* no flip */ + xpos,SCREEN_HEIGHT-bottom_inset+j*32+16-8 ); + } + + belt->opaque( bitmap, clip, + 0,0, /* number, color */ + 0,0, /* no flip */ + xpos, top_inset-16 ); + + belt->opaque( bitmap, clip, + 0,0, /* number, color */ + 0,0, /* no flip */ + xpos,SCREEN_HEIGHT-bottom_inset ); + + xpos += 32; + } +} + +void monaco_state::DrawGravelZone( bitmap_ind16 &bitmap, const rectangle clip, int xpos ) +{ + const uint8_t data[14] = { + GFX_SHRUB,GFX_SHRUB,GFX_SHRUB, + GFX_SHRUB,GFX_SHRUB,GFX_SHRUB, + GFX_SHRUB,GFX_HOUSE, + GFX_SHRUB,GFX_SHRUB,GFX_SHRUB, + GFX_SHRUB,GFX_SHRUB,GFX_SHRUB + }; + int top_inset = m_top_inset; + int bottom_inset = m_bottom_inset; + int i; + int xpos0 = xpos; + + for( i=0; i<14; i++ ) + { + int code = data[i]; + gfx_element *gfx = m_gfxdecode->gfx(code); + gfx_element *belt = m_gfxdecode->gfx((code==GFX_HOUSE)?GFX_DUMMY:GFX_BELT); + int j; + int ypos; + + /* draw gravel */ + if( data[i]!=GFX_HOUSE ) + { + ypos = SCREEN_HEIGHT-bottom_inset-32; + m_gfxdecode->gfx(GFX_BELT)->opaque( bitmap, clip, + 1,1, /* number, color */ + 0,0, /* no flip */ + xpos, ypos+32-8 ); + ypos-=24; + while( ypos>0 ){ + m_gfxdecode->gfx(GFX_BELT)->opaque( bitmap, clip, + 1,1, /* number, color */ + 0,0, /* no flip */ + xpos, ypos ); + ypos -= 16; + } + } + + for( j=0; j<3; j++ ) + { + ypos = SCREEN_HEIGHT-bottom_inset+16+j*32-8; + gfx->opaque( bitmap, clip, + 0,0, /* number, color */ + 0,0, /* no flip */ + xpos, ypos ); + } + + for( j=0; j<3; j++ ) + { + ypos = top_inset-32-16-j*32; + gfx->opaque( bitmap, clip, + 0,0, /* number, color */ + 0,0, /* no flip */ + xpos, ypos ); + } + + belt->opaque( bitmap, clip, + 0,0, /* number, color */ + 0,0, /* no flip */ + xpos, top_inset-16 ); + + belt->opaque( bitmap, clip, + 0,0, /* number, color */ + 0,0, /* no flip */ + xpos,SCREEN_HEIGHT-bottom_inset ); + + + xpos += 32; + } + draw_strip( bitmap, top_inset, xpos0, xpos0+PAGE_SIZE, xpos0, YELLOW_PEN ); + draw_strip( bitmap, SCREEN_HEIGHT-1 - bottom_inset, xpos0, xpos0+PAGE_SIZE, xpos0, YELLOW_PEN ); +} + +void monaco_state::DrawBridgeZone( bitmap_ind16 &bitmap, const rectangle clip, int xpos ) +{ + gfx_element *gfx1 = m_gfxdecode->gfx(GFX_BRIDGE1); + gfx_element *gfx2 = m_gfxdecode->gfx(GFX_BRIDGE2); + + int i; + for( i=0; i<14; i++ ) + { + int j; + gfx_element *gfx = (i==0)?gfx2:gfx1; + for( j=0; j<7; j++ ) + { + int flip; + for( flip=0; flip<=1; flip++ ) + { + int ypos = flip?(SCREEN_HEIGHT-16-j*16)+8:j*16-8; + if( j<5 ) + { /* water */ + gfx1->opaque( bitmap, clip, + 0,0, /* number, color */ + 0,flip, + xpos, ypos ); + } + else + { /* edge of bridge */ + gfx->opaque( bitmap, clip, + j-5,0, /* number, color */ + 0,flip, + xpos, ypos ); + } + } + } + xpos += 32; + } +} + +void monaco_state::DrawTunnelZone( bitmap_ind16 &bitmap, int xpos ) +{ + int pen = YELLOW_PEN; + int top_inset = m_top_inset; + int bottom_inset = m_bottom_inset; + draw_strip( bitmap, top_inset, xpos, xpos+PAGE_SIZE, xpos, pen ); + draw_strip( bitmap, SCREEN_HEIGHT-1 - bottom_inset, xpos, xpos+PAGE_SIZE, xpos, pen ); +} + +void monaco_state::DrawTunnelWall( bitmap_ind16 &bitmap, const rectangle clip, int xpos ) +{ + rectangle clip2; + gfx_element *gfx = m_gfxdecode->gfx(GFX_TUNNEL); + int top_inset = m_top_inset - 16; + int bottom_inset = m_bottom_inset - 16; + int i; + + clip2.min_x = clip.min_x; + clip2.max_x = clip.max_x; + clip2.max_y = clip.max_y; + clip2.min_y = SCREEN_HEIGHT-bottom_inset; + + for( i=0; i<14; i++ ) + { + int j; + for( j=0; j<2; j++ ) + { + gfx->transpen( bitmap, clip, + 1,0, /* number, color */ + 0,0, /* no flip */ + xpos, top_inset-32-j*32, 0 ); + + gfx->transpen( bitmap, clip, + 1,0, /* number, color */ + 0,0, /* no flip */ + xpos, SCREEN_HEIGHT-bottom_inset+j*32 - 8, 0 ); + } + xpos += 32; + } +} + +void monaco_state::draw_light_helper( bitmap_ind16 &bitmap, int xpos ) +{ + int pen = BLACK_PEN; + const unsigned char *source = memregion( "gfx1" )->base(); + int x0 = m_player_x-128; + int y0 = m_player_y-48; + int sy; + for( sy=0; sy<SCREEN_HEIGHT; sy++ ) + { + int i = sy-y0; + if( i<0 || i>=128 ) + { + draw_strip( bitmap, sy, xpos, xpos+PAGE_SIZE, xpos, pen ); + } + else + { + int left = x0+source[i]; + int right = x0+source[i+128]; + draw_strip( bitmap, sy, xpos, left, xpos, pen ); + draw_strip( bitmap, sy, right, xpos+PAGE_SIZE, xpos, pen ); + } + } +} + +void monaco_state::draw_wall( bitmap_ind16 &bitmap, const rectangle clip ) +{ + if( m_right_page == PAGE_TUNNEL ) + DrawTunnelWall( bitmap, clip, SCREEN_WIDTH-14*32+m_scroll ); + + if( m_left_page == PAGE_TUNNEL ) + DrawTunnelWall( bitmap, clip, SCREEN_WIDTH-14*32*2+m_scroll ); +} + +void monaco_state::draw_light( bitmap_ind16 &bitmap ) +{ + if( m_right_page == PAGE_TUNNEL ) + draw_light_helper( bitmap, SCREEN_WIDTH-14*32+m_scroll ); + + if( m_left_page == PAGE_TUNNEL ) + draw_light_helper( bitmap, SCREEN_WIDTH-14*32*2+m_scroll ); +} + +void monaco_state::draw_page( bitmap_ind16 &bitmap, const rectangle clip, int which, int xpos ) +{ + rectangle r; + r.min_x = xpos; + r.max_x = xpos+PAGE_SIZE-1; + r.min_y = 0; + r.max_y = SCREEN_HEIGHT-1; + bitmap.fill( (which!=PAGE_SLIP)?GREY_PEN:CYAN_PEN,r ); + switch( which ) + { + case PAGE_SMOOTH: + DrawSmoothZone( bitmap, clip, xpos ); + break; + + case PAGE_SLIP: + DrawSlipZone( bitmap, clip, xpos ); + break; + + case PAGE_TUNNEL: + DrawTunnelZone( bitmap, xpos ); + break; + + case PAGE_GRAVEL: + DrawGravelZone( bitmap, clip, xpos ); + break; + + case PAGE_BRIDGE: + DrawBridgeZone( bitmap, clip, xpos ); + break; + } +} + +void monaco_state::draw_background( bitmap_ind16 &bitmap, const rectangle clip ) +{ + draw_page(bitmap, clip, + m_right_page, + SCREEN_WIDTH-14*32+m_scroll ); + + draw_page(bitmap, clip, + m_left_page, + SCREEN_WIDTH-14*32*2+m_scroll ); +} + +void monaco_state::draw_text( bitmap_ind16 &bitmap, const rectangle clip ) +{ + int sx = (SCREEN_WIDTH-8)/2; + int sy = (SCREEN_HEIGHT-128)/2; + + if( m_left_text != -1 ) + { + m_gfxdecode->gfx(GFX_TEXT)->zoom_transpen( bitmap, clip, + m_left_text,0, + 0,0, /* flip */ + sx-96,sy, + 1<<16, 2<<16, 0 + ); + } + + if( m_right_text != -1 ) + { + m_gfxdecode->gfx(GFX_TEXT)->zoom_transpen( bitmap, clip, + m_right_text,1, + 0,0, /* flip */ + SCREEN_WIDTH-32,sy, + 1<<16, 2<<16, 0 + ); + } +} + +/* last two values are L and H used to display in gear field (not supported officially)*/ +static const uint8_t led_map[12] = { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x38,0x76 }; + +/* following outputs LED's for bezel. also displays time,score&speed text versions (text version disabled here) */ + +void monaco_state::draw_leds( bitmap_ind16 &bitmap ) +{ + int i; // must be signed + uint32_t data; + +// data = m_speed; +// for( i=2; i>=0; i-- ) +// { +// drawgfx_transpen( bitmap, led_font, +// data%10,0, /* number, color */ +// 0,1, /* no flip */ +// 9,SCREEN_HEIGHT-6-i*6, +// NULL, TRANSPARENCY_NONE,0 ); +// +// data = data/10; +// } + + data = m_led_high1>>8; + for( i=3; i>=0; i-- ) + { + m_out_digit[10+i] = led_map[data%10]; + data = data/10; + } + + data = m_led_high2>>8; + for( i=3; i>=0; i-- ) + { + m_out_digit[20+i] = led_map[data%10]; + data = data/10; + } + + data = m_led_high3>>8; + for( i=3; i>=0; i-- ) + { + m_out_digit[30+i] = led_map[data%10]; + data = data/10; + } + + data = m_led_high4>>8; + for( i=3; i>=0; i-- ) + { + m_out_digit[40+i] = led_map[data%10]; + data = data/10; + } + + data = m_led_high5>>8; + for( i=3; i>=0; i-- ) + { + m_out_digit[50+i] = led_map[data%10]; + data = data/10; + } + + data = m_led_score>>8; + for( i=3; i>=0; i-- ) + { +// drawgfx_transpen( bitmap, led_font, +// data%10,0, /* number, color */ +// 0,1, /* no flip */ +// 0,SCREEN_HEIGHT-6-i*6, +// NULL, TRANSPARENCY_NONE,0 ); + + m_out_digit[i] = led_map[data%10]; + data = data/10; + } + + data = m_led_plays; + for( i=2; i>=0; i-- ) + { + m_out_digit[60+i] = led_map[data%10]; + data = data/10; + } + + data = m_led_rank; + for( i=2; i>=0; i-- ) + { + if (data == 0xffff) + { + m_out_digit[70+i] = 0; // make it blank + } + else + { + m_out_digit[70+i] = led_map[data%10]; + data = data/10; + } + } + + data = m_led_speed; + for( i=2; i>=0; i-- ) + { +// drawgfx_transpen( bitmap, led_font, +// data%10,0, /* number, color */ +// 0,1, /* no flip */ +// 9,SCREEN_HEIGHT-6-i*6, +// NULL, TRANSPARENCY_NONE,0 ); +// + m_out_digit[80+i] = led_map[data%10]; + data = data/10; + } + + data = m_led_gear; + for( i=0; i>=0; i-- ) + { + m_out_digit[90+i] = led_map[10+data%10]; + data = data/10; + } + + data = m_led_lives; + for( i=0; i>=0; i-- ) + { + m_out_digit[100+i] = led_map[data%10]; + data = data/10; + } + + data = m_led_time>>8; + for( i=1; i>=0; i-- ) + { +// drawgfx_opaque( bitmap, NULL, led_font, +// data%10,0, /* number, color */ +// 0,1, /* no flip */ +// 18,SCREEN_HEIGHT-6-i*6 ); + + m_out_digit[i+4] = led_map[data%10]; + data = data/10; + } +} + +void monaco_state::draw_signal( bitmap_ind16 &bitmap ) +{ + if( m_bSignalVisible ) + { +// drawgfx_opaque( +// bitmap, NULL, machine().gfx[GFX_SIGNAL], +// 0,0, /* number, color */ +// 0,0, /* no flip */ +// 32,(SCREEN_HEIGHT - 32)/2 ); + } +} + +uint32_t monaco_state::screen_update_monaco(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + const rectangle &visarea = screen.visible_area(); + draw_background( bitmap, visarea ); + draw_pool( bitmap, visarea ); + draw_computer( bitmap, visarea ); + draw_light( bitmap ); + draw_wall( bitmap, visarea ); + draw_text( bitmap, visarea ); + draw_player( bitmap, visarea ); + draw_signal( bitmap ); + draw_leds( bitmap ); + return 0; +} + +VIDEO_START_MEMBER( monaco_state, monaco ) +{ + m_out_digit.resolve(); + + m_palette->set_pen_color( 0, 0x00,0x00,0x00 ); /* black (tire) */ + m_palette->set_pen_color( 1, 0xff,0xff,0xff ); /* white (trim) */ + /* computer car */ + for( u8 i=0; i<NUM_COMPUTER_CAR_TYPES; i++ ) + { + const unsigned char clut[3*NUM_COMPUTER_CAR_TYPES] = + { + 0x00,0xff,0x00, /* green car */ + 0xff,0xff,0x00, /* yellow car */ + 0x00,0xff,0xff, /* cyan car */ + 0xff,0x00,0xff, /* purple car */ + 0x00,0x00,0xff /* blue car */ + }; + + m_palette->set_pen_color( 16*i+0x8, 0x00,0x00,0x00 ); /* black (tire) */ + m_palette->set_pen_color( 16*i+0xa, 0xff,0xff,0xff ); /* white (trim) */ + m_palette->set_pen_color( 16*i+0xc, clut[i*3+0],clut[i*3+1],clut[i*3+2] ); + } + /* rescue car */ + m_palette->set_pen_color( 0x50+0x8, 0x00,0x00,0x00 ); // black + m_palette->set_pen_color( 0x50+0x9, 0xff,0xff,0x00 ); // yellow + m_palette->set_pen_color( 0x50+0xa, 0xff,0xff,0xff ); // white + m_palette->set_pen_color( 0x50+0xc, 0xff,0x00,0x00 ); // red (light) + /* house */ + m_palette->set_pen_color( 0x60+0x0, 0x00,0x00,0x00 ); // ground + m_palette->set_pen_color( 0x60+0x9, 0xff,0x00,0x00 ); // right roof + m_palette->set_pen_color( 0x60+0xa, 0xff,0x00,231 ); // left roof + m_palette->set_pen_color( 0x60+0xb, 0x00,198,255 ); // front + m_palette->set_pen_color( 0x60+0xc, 0xff,0xff,0xff ); // trim + /* water */ + m_palette->set_pen_color( 0x70, 0x00,0x00,0xff );//l.blue + m_palette->set_pen_color( 0x71, 0xff,0x00,0x00 );//red + m_palette->set_pen_color( 0x72, 0xff,0xff,0x00 );//yellow + m_palette->set_pen_color( 0x73, 0x00,0x00,0x00 );//black + m_palette->set_pen_color( 0x74, 0x00,0x00,0x00 );//N/A + m_palette->set_pen_color( 0x75, 0xff,0xff,0xff );//white + m_palette->set_pen_color( 0x76, 0x9f,0x9f,0x9f );//grey (road) + m_palette->set_pen_color( 0x77, 0x00,0x00,0x9f );//d.blue + /* player car */ + m_palette->set_pen_color( 0x80, 0x00,0x00,0x00 ); + m_palette->set_pen_color( 0x81, 0xff,0x00,0x00 ); // red (car body) + m_palette->set_pen_color( 0x82, 0xff,0xff,0xff ); // white (trim) + m_palette->set_pen_color( 0x83, 0x00,0x00,0x00 ); // black (tire) + /* tree */ + m_palette->set_pen_color( 0x84, 0xff,0xff,0x00 ); // yellow + m_palette->set_pen_color( 0x85, 0x00,0x00,0x00 ); // dark green + m_palette->set_pen_color( 0x86, 0x00,165,0x00 ); // light green + m_palette->set_pen_color( 0x87, 0x00,0x00,0x00 ); // black? + /* shrub */ + m_palette->set_pen_color( 0x88, 0x00,0x00,0x00 ); + m_palette->set_pen_color( 0x89, 0x00,0xff,0x00 ); + m_palette->set_pen_color( 0x8a, 0x00,0x00,0xff ); + m_palette->set_pen_color( 0x8b, 0xff,0xff,0xff ); + /* grass */ + m_palette->set_pen_color( 0x8c, 0x00,0x00,0x00 ); + m_palette->set_pen_color( 0x8d, 0x00,0x9f,0x00 ); // dark green + m_palette->set_pen_color( 0x8e, 0x00,0x00,0x00 ); + m_palette->set_pen_color( 0x8f, 0x00,0x00,0x9f ); // dark blue + m_palette->set_pen_color( 0x90, 0x00,0x00,0x00 ); // black + m_palette->set_pen_color( 0x91, 0x00,0xff,0xff ); // cyan + m_palette->set_pen_color( 0x92, 0x00,0x00,0x00 ); // grey + m_palette->set_pen_color( 0x93, 0xff,0x00,0x00 ); // red + m_palette->set_pen_color( 0x94, 0x00,0x00,0x00 ); // black + m_palette->set_pen_color( 0x95, 255,215,0 ); // yellow trim + m_palette->set_pen_color( 0x96, 132,132,132 ); // grey (road) +// 0,198,255: wet road +// 255,215,0: yellow trim +} |