mirror of
https://github.com/holub/mame
synced 2025-05-21 13:18:56 +03:00
Added proper laserdisc support for MACH 3, Us vs. Them, and Cobra
Commander (MACH 3 hardware). Old laserdisc hacks are now removed. The code now talks to the standard Pioneer PR-8210 interface. Also removed hacky "target list" from the MACH 3 ROMs; this information is now decoded on the fly from the right channel laserdisc audio. Other Gottlieb cleanups: - moved sound inputs to audio/gottlieb and included them in all relevant drivers - ordered input ports and ROM definitions consistently Other laserdisc changes: - changed PR-8210 interface to work consistently for both Gottlieb and Stern games - added audio callback mechanism to allow drivers to peek at the raw audio streams - extended the VBI parser to be even more lenient
This commit is contained in:
parent
d20e6b6151
commit
95e3753dd2
@ -358,6 +358,12 @@ const char *attotime_string(attotime _time, int precision)
|
||||
else if (precision <= 9)
|
||||
{
|
||||
UINT32 upper = _time.attoseconds / ATTOSECONDS_PER_SECOND_SQRT;
|
||||
int temp = precision;
|
||||
while (temp < 9)
|
||||
{
|
||||
upper /= 10;
|
||||
temp++;
|
||||
}
|
||||
sprintf(buffer, "%d.%0*d", _time.seconds, precision, upper);
|
||||
}
|
||||
|
||||
@ -366,6 +372,12 @@ const char *attotime_string(attotime _time, int precision)
|
||||
{
|
||||
UINT32 lower;
|
||||
UINT32 upper = divu_64x32_rem(_time.attoseconds, ATTOSECONDS_PER_SECOND_SQRT, &lower);
|
||||
int temp = precision;
|
||||
while (temp < 18)
|
||||
{
|
||||
lower /= 10;
|
||||
temp++;
|
||||
}
|
||||
sprintf(buffer, "%d.%09d%0*d", _time.seconds, upper, precision - 9, lower);
|
||||
}
|
||||
return buffer;
|
||||
|
@ -90,7 +90,7 @@ typedef enum _playstate playstate;
|
||||
#define STOP_SPEED INT_TO_FRAC(0) /* no movement */
|
||||
#define PLAY_SPEED INT_TO_FRAC(1) /* regular playback speed */
|
||||
|
||||
#define GENERIC_SPINUP_TIME (attotime_make(3, 0))
|
||||
#define GENERIC_SPINUP_TIME (attotime_make(5, 0))
|
||||
#define GENERIC_LOAD_TIME (attotime_make(10, 0))
|
||||
#define GENERIC_RESET_SPEED INT_TO_FRAC(5000)
|
||||
|
||||
@ -102,10 +102,6 @@ typedef enum _playstate playstate;
|
||||
#define PR7820_SEARCH_SPEED INT_TO_FRAC(5000)
|
||||
|
||||
/* Pioneer PR-8210/LD-V1100 specific states */
|
||||
#define PR8210_MODE_GET_1ST 0
|
||||
#define PR8210_MODE_GET_2ND 1
|
||||
#define PR8210_MODE_GET_3RD 2
|
||||
|
||||
#define PR8210_SCAN_SPEED (INT_TO_FRAC(2000) / 30)
|
||||
#define PR8210_FAST_SPEED (PLAY_SPEED * 3)
|
||||
#define PR8210_SLOW_SPEED (PLAY_SPEED / 5)
|
||||
@ -159,9 +155,10 @@ typedef struct _pr8210_info pr8210_info;
|
||||
struct _pr8210_info
|
||||
{
|
||||
UINT8 mode; /* current mode */
|
||||
UINT16 commandtriplet[3]; /* current command triplet */
|
||||
attotime commandtime; /* command time */
|
||||
UINT8 commandbits; /* command bit count */
|
||||
UINT8 lastcommand; /* last command byte received */
|
||||
UINT16 accumulator; /* bit accumulator */
|
||||
attotime lastbittime; /* time of last bit received */
|
||||
attotime firstbittime; /* time of first bit in command */
|
||||
UINT8 seekstate; /* state of the seek command */
|
||||
};
|
||||
|
||||
@ -232,6 +229,7 @@ struct _laserdisc_state
|
||||
bitmap_t * emptyframe; /* blank frame */
|
||||
|
||||
/* audio data */
|
||||
laserdisc_audio_func audiocallback; /* callback function for audio processing */
|
||||
INT16 * audiobuffer[2]; /* buffer for audio samples */
|
||||
UINT32 audiobufsize; /* size of buffer */
|
||||
UINT32 audiobufin; /* input index */
|
||||
@ -313,8 +311,9 @@ struct _sound_token
|
||||
/* generic helper functions */
|
||||
static int update_position(laserdisc_state *ld);
|
||||
static void read_track_data(laserdisc_state *ld);
|
||||
static void process_track_data(laserdisc_state *ld);
|
||||
static void process_track_data(const device_config *device);
|
||||
static void parse_metadata(const UINT16 *videodata, UINT32 rowpixels, UINT32 width, UINT32 track, UINT8 which, field_metadata *metadata);
|
||||
static void fake_metadata(UINT32 track, UINT8 which, field_metadata *metadata);
|
||||
static void *custom_start(int clock, const struct CustomSound_interface *config);
|
||||
static void custom_stream_callback(void *param, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
|
||||
|
||||
@ -567,6 +566,19 @@ INLINE void set_hold_state(laserdisc_state *ld, attotime holdtime, playstate sta
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
reset_tracknum - reset the current track
|
||||
number to 1 and clear out other state
|
||||
-------------------------------------------------*/
|
||||
|
||||
INLINE void reset_tracknum(laserdisc_state *ld)
|
||||
{
|
||||
ld->curfractrack = ONE_TRACK;
|
||||
ld->last_frame = 0;
|
||||
ld->last_chapter = 0;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
add_to_current_track - add a value to the
|
||||
current track, stopping if we hit the min or
|
||||
@ -713,7 +725,7 @@ void laserdisc_vsync(const device_config *device)
|
||||
}
|
||||
|
||||
/* wait for previous read and decode to finish */
|
||||
process_track_data(ld);
|
||||
process_track_data(device);
|
||||
|
||||
/* update our position for this field */
|
||||
hittarget = update_position(ld);
|
||||
@ -1057,7 +1069,7 @@ static int update_position(laserdisc_state *ld)
|
||||
{
|
||||
/* if we're on the second field of a frame, the next frame is on the next track */
|
||||
/* but don't do it if we're seeking to frame 1, since that might be the very first frame */
|
||||
if (fieldnum == 1)// && (ld->last_frame == 1 || ld->targetframe != 1))
|
||||
if (fieldnum == 1)
|
||||
{
|
||||
add_to_current_track(ld, ONE_TRACK);
|
||||
LOG_POSITION(("on 2nd field, going to next track\n"));
|
||||
@ -1070,8 +1082,9 @@ static int update_position(laserdisc_state *ld)
|
||||
/* if we're in the lead-in or lead-out sections, advance more aggressively */
|
||||
if (frame == 0)
|
||||
{
|
||||
LOG_POSITION(("in lead-in, advancing by 10\n"));
|
||||
add_to_current_track(ld, 10 * ONE_TRACK);
|
||||
LOG_POSITION(("in lead-in, advancing by 1\n"));
|
||||
if (fieldnum == 1)
|
||||
add_to_current_track(ld, 1 * ONE_TRACK);
|
||||
return FALSE;
|
||||
}
|
||||
if (frame == 99999)
|
||||
@ -1205,8 +1218,9 @@ static void read_track_data(laserdisc_state *ld)
|
||||
track after it has been read
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void process_track_data(laserdisc_state *ld)
|
||||
static void process_track_data(const device_config *device)
|
||||
{
|
||||
laserdisc_state *ld = get_safe_token(device);
|
||||
UINT32 tracknum = FRAC_TO_INT(ld->curfractrack);
|
||||
UINT32 fieldnum = ld->fieldnum & 1;
|
||||
const UINT8 *rawdata = NULL;
|
||||
@ -1226,15 +1240,15 @@ static void process_track_data(laserdisc_state *ld)
|
||||
ld->readpending = FALSE;
|
||||
|
||||
/* parse the metadata */
|
||||
if (ld->avconfig.video_buffer != NULL)
|
||||
{
|
||||
if (ld->disc != NULL && ld->avconfig.video_buffer != NULL)
|
||||
parse_metadata((const UINT16 *)ld->avconfig.video_buffer, ld->avconfig.video_stride / 2, ld->videoframe[0]->width, tracknum, fieldnum, &ld->metadata[fieldnum]);
|
||||
//printf("Track %5d: Metadata = %d %08X %08X %08X\n", tracknum, ld->metadata[fieldnum].whiteflag, ld->metadata[fieldnum].line16, ld->metadata[fieldnum].line17, ld->metadata[fieldnum].line18);
|
||||
}
|
||||
else
|
||||
fake_metadata(tracknum, fieldnum, &ld->metadata[fieldnum]);
|
||||
printf("Track %5d: Metadata = %d %08X %08X %08X\n", tracknum, ld->metadata[fieldnum].whiteflag, ld->metadata[fieldnum].line16, ld->metadata[fieldnum].line17, ld->metadata[fieldnum].line18);
|
||||
|
||||
/* update the last seen frame and chapter */
|
||||
frame = frame_from_metadata(&ld->metadata[fieldnum]);
|
||||
if (frame != -1)
|
||||
if (frame >= 1 && frame < 99999)
|
||||
ld->last_frame = frame;
|
||||
chapter = chapter_from_metadata(&ld->metadata[fieldnum]);
|
||||
if (chapter != -1)
|
||||
@ -1253,6 +1267,10 @@ static void process_track_data(laserdisc_state *ld)
|
||||
samples = (rawdata[6] << 8) + rawdata[7];
|
||||
sampsource[0] = (const INT16 *)(rawdata + 12 + rawdata[4]) + 0 * samples;
|
||||
sampsource[1] = sampsource[0] + samples;
|
||||
|
||||
/* let the audio callback at it first */
|
||||
if (ld->audiocallback != NULL)
|
||||
(*ld->audiocallback)(device, ld->samplerate, samples, sampsource[0], sampsource[1]);
|
||||
|
||||
/* loop until all samples are copied */
|
||||
while (samples != 0)
|
||||
@ -1319,6 +1337,29 @@ static void parse_metadata(const UINT16 *videodata, UINT32 rowpixels, UINT32 wid
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
fake_metadata - fake metadata when there's
|
||||
no disc present
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void fake_metadata(UINT32 track, UINT8 which, field_metadata *metadata)
|
||||
{
|
||||
if (which == 0)
|
||||
{
|
||||
metadata->whiteflag = 1;
|
||||
metadata->line16 = 0;
|
||||
metadata->line17 = metadata->line18 = 0xf80000 |
|
||||
(((track / 10000) % 10) << 16) |
|
||||
(((track / 1000) % 10) << 12) |
|
||||
(((track / 100) % 10) << 8) |
|
||||
(((track / 10) % 10) << 4) |
|
||||
(((track / 1) % 10) << 0);
|
||||
}
|
||||
else
|
||||
memset(metadata, 0, sizeof(*metadata));
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
custom_start - custom audio start
|
||||
for laserdiscs
|
||||
@ -1327,7 +1368,7 @@ static void parse_metadata(const UINT16 *videodata, UINT32 rowpixels, UINT32 wid
|
||||
static void *custom_start(int clock, const struct CustomSound_interface *config)
|
||||
{
|
||||
sound_token *token = auto_malloc(sizeof(*token));
|
||||
token->stream = stream_create(0, 2, 44100, token, custom_stream_callback);
|
||||
token->stream = stream_create(0, 2, 48000, token, custom_stream_callback);
|
||||
token->ld = NULL;
|
||||
return token;
|
||||
}
|
||||
@ -1405,7 +1446,7 @@ static void custom_stream_callback(void *param, stream_sample_t **inputs, stream
|
||||
device start callback
|
||||
-------------------------------------------------*/
|
||||
|
||||
static DEVICE_START( laserdisc )
|
||||
static DEVICE_START(laserdisc)
|
||||
{
|
||||
int fps = 30, fpsfrac = 0, width = 720, height = 240, interlaced = 1, channels = 2, rate = 44100;
|
||||
const laserdisc_config *config = device->inline_config;
|
||||
@ -1417,6 +1458,9 @@ static DEVICE_START( laserdisc )
|
||||
|
||||
/* copy config data to the live state */
|
||||
ld->type = config->type;
|
||||
ld->audiocallback = config->audio;
|
||||
|
||||
/* find the disc */
|
||||
ld->disc = get_disk_handle(device->tag);
|
||||
for (sndnum = 0; sndnum < MAX_SOUND; sndnum++)
|
||||
if (device->machine->config->sound[sndnum].tag != NULL && strcmp(device->machine->config->sound[sndnum].tag, device->tag) == 0)
|
||||
@ -1474,7 +1518,7 @@ static DEVICE_START( laserdisc )
|
||||
device exit callback
|
||||
-------------------------------------------------*/
|
||||
|
||||
static DEVICE_STOP( laserdisc )
|
||||
static DEVICE_STOP(laserdisc)
|
||||
{
|
||||
laserdisc_state *ld = get_safe_token(device);
|
||||
|
||||
@ -1551,7 +1595,7 @@ static DEVICE_RESET( laserdisc )
|
||||
}
|
||||
|
||||
/* default to track 1 */
|
||||
ld->curfractrack = ONE_TRACK;
|
||||
reset_tracknum(ld);
|
||||
}
|
||||
|
||||
|
||||
@ -1559,7 +1603,7 @@ static DEVICE_RESET( laserdisc )
|
||||
device set info callback
|
||||
-------------------------------------------------*/
|
||||
|
||||
static DEVICE_SET_INFO( laserdisc )
|
||||
static DEVICE_SET_INFO(laserdisc)
|
||||
{
|
||||
laserdisc_state *ld = get_safe_token(device);
|
||||
switch (state)
|
||||
@ -1580,7 +1624,7 @@ static DEVICE_SET_INFO( laserdisc )
|
||||
device get info callback
|
||||
-------------------------------------------------*/
|
||||
|
||||
DEVICE_GET_INFO( laserdisc )
|
||||
DEVICE_GET_INFO(laserdisc)
|
||||
{
|
||||
const laserdisc_config *config = (device != NULL) ? device->inline_config : NULL;
|
||||
switch (state)
|
||||
@ -1921,8 +1965,7 @@ static void pr7820_enter_w(laserdisc_state *ld, UINT8 newstate)
|
||||
set_state(ld, LASERDISC_LOADING, STOP_SPEED, NULL_TARGET_FRAME);
|
||||
set_hold_state(ld, GENERIC_LOAD_TIME, LASERDISC_PLAYING_FORWARD, PLAY_SPEED);
|
||||
}
|
||||
|
||||
ld->curfractrack = ONE_TRACK;
|
||||
reset_tracknum(ld);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2055,10 +2098,9 @@ static void pr8210_soft_reset(laserdisc_state *ld)
|
||||
|
||||
ld->audio = AUDIO_CH1_ENABLE | AUDIO_CH2_ENABLE;
|
||||
ld->display = 0;
|
||||
pr8210->mode = PR8210_MODE_GET_1ST;
|
||||
pr8210->commandtime = timer_get_time();
|
||||
pr8210->commandbits = 0;
|
||||
memset( pr8210->commandtriplet, 0, 3*sizeof(UINT16) );
|
||||
pr8210->firstbittime = pr8210->lastbittime = timer_get_time();
|
||||
pr8210->accumulator = 0;
|
||||
pr8210->lastcommand = 0;
|
||||
pr8210->seekstate = 0;
|
||||
}
|
||||
|
||||
@ -2070,187 +2112,156 @@ static void pr8210_soft_reset(laserdisc_state *ld)
|
||||
|
||||
static void pr8210_command(laserdisc_state *ld)
|
||||
{
|
||||
static const UINT8 numbers[10] = { 0x01,0x11,0x09,0x19,0x05,0x15,0x0d,0x1d,0x03,0x13 };
|
||||
pr8210_info *pr8210 = &ld->u.pr8210;
|
||||
UINT8 cmd = pr8210->lastcommand;
|
||||
|
||||
/* if we don't have the entire command triplet yet, keep going */
|
||||
if ( pr8210->mode < PR8210_MODE_GET_3RD )
|
||||
/* look for and process numbers */
|
||||
if (!process_number(ld, cmd, numbers))
|
||||
{
|
||||
/* do some sanity checks on the command data */
|
||||
if ( pr8210->mode == PR8210_MODE_GET_2ND )
|
||||
switch(cmd)
|
||||
{
|
||||
/* if the commands don't match, then reassign the new command to the first word, then keep fetching */
|
||||
if ( pr8210->commandtriplet[PR8210_MODE_GET_1ST] != pr8210->commandtriplet[PR8210_MODE_GET_2ND] )
|
||||
{
|
||||
pr8210->commandtriplet[PR8210_MODE_GET_1ST] = pr8210->commandtriplet[PR8210_MODE_GET_2ND];
|
||||
pr8210->mode = PR8210_MODE_GET_2ND;
|
||||
return;
|
||||
}
|
||||
}
|
||||
case 0x00: CMDPRINTF(("pr8210: EOC\n"));
|
||||
/* EOC marker - can be safely ignored */
|
||||
break;
|
||||
|
||||
pr8210->mode++;
|
||||
}
|
||||
else /* we're ready to process the command */
|
||||
{
|
||||
/* do some sanity checks on the command data */
|
||||
static const UINT8 numbers[10] = { 0x01,0x11,0x09,0x19,0x05,0x15,0x0d,0x1d,0x03,0x13 };
|
||||
UINT16 cmd = pr8210->commandtriplet[PR8210_MODE_GET_1ST];
|
||||
case 0x02: CMDPRINTF(("pr8210: Slow reverse\n"));
|
||||
/* slow reverse */
|
||||
if (laserdisc_ready(ld))
|
||||
set_state(ld, LASERDISC_PLAYING_SLOW_REVERSE, -PR8210_SLOW_SPEED, NULL_TARGET_FRAME);
|
||||
break;
|
||||
|
||||
/* more sanity checking: bit 7 must be set for a valid command */
|
||||
if ( cmd & 0x80 )
|
||||
{
|
||||
/* extract the actual command number */
|
||||
cmd = ( cmd >> 2 ) & 0x1f;
|
||||
case 0x04: CMDPRINTF(("pr8210: Step forward\n"));
|
||||
/* step forward */
|
||||
if (laserdisc_ready(ld))
|
||||
set_state(ld, LASERDISC_STEPPING_FORWARD, PR8210_STEP_SPEED, NULL_TARGET_FRAME);
|
||||
break;
|
||||
|
||||
/* look for and process numbers */
|
||||
if (!process_number(ld, cmd, numbers))
|
||||
{
|
||||
switch( cmd )
|
||||
case 0x06 : CMDPRINTF(("pr8210: Chapter\n"));
|
||||
/* chapter -- not implemented */
|
||||
break;
|
||||
|
||||
case 0x08: CMDPRINTF(("pr8210: Scan forward\n"));
|
||||
/* scan forward */
|
||||
if (laserdisc_ready(ld))
|
||||
set_state(ld, LASERDISC_SCANNING_FORWARD, PR8210_SCAN_SPEED, NULL_TARGET_FRAME);
|
||||
break;
|
||||
|
||||
case 0x0a: CMDPRINTF(("pr8210: Pause\n"));
|
||||
/* still picture */
|
||||
if (laserdisc_ready(ld))
|
||||
set_state(ld, LASERDISC_STOPPED, STOP_SPEED, NULL_TARGET_FRAME);
|
||||
break;
|
||||
|
||||
case 0x0b : CMDPRINTF(("pr8210: Frame\n"));
|
||||
/* frame -- not implemented */
|
||||
break;
|
||||
|
||||
case 0x0c: CMDPRINTF(("pr8210: Fast reverse\n"));
|
||||
/* play reverse fast speed */
|
||||
if (laserdisc_ready(ld))
|
||||
set_state(ld, LASERDISC_PLAYING_FAST_REVERSE, -PR8210_FAST_SPEED, NULL_TARGET_FRAME);
|
||||
break;
|
||||
|
||||
case 0x0e: CMDPRINTF(("pr8210: Ch1 toggle\n"));
|
||||
/* channel 1 audio toggle */
|
||||
ld->audio ^= AUDIO_CH1_ENABLE;
|
||||
break;
|
||||
|
||||
case 0x10: CMDPRINTF(("pr8210: Fast forward\n"));
|
||||
/* play forward fast speed */
|
||||
if (laserdisc_ready(ld))
|
||||
set_state(ld, LASERDISC_PLAYING_FAST_FORWARD, PR8210_FAST_SPEED, NULL_TARGET_FRAME);
|
||||
break;
|
||||
|
||||
case 0x12: CMDPRINTF(("pr8210: Step reverse\n"));
|
||||
/* step backwards one frame */
|
||||
if (laserdisc_ready(ld))
|
||||
{
|
||||
case 0x00: CMDPRINTF(("pr8210: EOC\n"));
|
||||
/* EOC marker - can be safely ignored */
|
||||
break;
|
||||
|
||||
case 0x02: CMDPRINTF(("pr8210: Slow reverse\n"));
|
||||
/* slow reverse */
|
||||
if (laserdisc_ready(ld))
|
||||
set_state(ld, LASERDISC_PLAYING_SLOW_REVERSE, -PR8210_SLOW_SPEED, NULL_TARGET_FRAME);
|
||||
break;
|
||||
|
||||
case 0x04: CMDPRINTF(("pr8210: Step forward\n"));
|
||||
/* step forward */
|
||||
if (laserdisc_ready(ld))
|
||||
set_state(ld, LASERDISC_STEPPING_FORWARD, PR8210_STEP_SPEED, NULL_TARGET_FRAME);
|
||||
break;
|
||||
|
||||
case 0x06 : CMDPRINTF(("pr8210: Chapter\n"));
|
||||
/* chapter -- not implemented */
|
||||
break;
|
||||
|
||||
case 0x08: CMDPRINTF(("pr8210: Scan forward\n"));
|
||||
/* scan forward */
|
||||
if (laserdisc_ready(ld))
|
||||
set_state(ld, LASERDISC_SCANNING_FORWARD, PR8210_SCAN_SPEED, NULL_TARGET_FRAME);
|
||||
break;
|
||||
|
||||
case 0x0a: CMDPRINTF(("pr8210: Pause\n"));
|
||||
/* still picture */
|
||||
if (laserdisc_ready(ld))
|
||||
set_state(ld, LASERDISC_STOPPED, STOP_SPEED, NULL_TARGET_FRAME);
|
||||
break;
|
||||
|
||||
case 0x0b : CMDPRINTF(("pr8210: Frame\n"));
|
||||
/* frame -- not implemented */
|
||||
break;
|
||||
|
||||
case 0x0c: CMDPRINTF(("pr8210: Fast reverse\n"));
|
||||
/* play reverse fast speed */
|
||||
if (laserdisc_ready(ld))
|
||||
set_state(ld, LASERDISC_PLAYING_FAST_REVERSE, -PR8210_FAST_SPEED, NULL_TARGET_FRAME);
|
||||
break;
|
||||
|
||||
case 0x0e: CMDPRINTF(("pr8210: Ch1 toggle\n"));
|
||||
/* channel 1 audio toggle */
|
||||
ld->audio ^= AUDIO_CH1_ENABLE;
|
||||
break;
|
||||
|
||||
case 0x10: CMDPRINTF(("pr8210: Fast forward\n"));
|
||||
/* play forward fast speed */
|
||||
if (laserdisc_ready(ld))
|
||||
set_state(ld, LASERDISC_PLAYING_FAST_FORWARD, PR8210_FAST_SPEED, NULL_TARGET_FRAME);
|
||||
break;
|
||||
|
||||
case 0x12: CMDPRINTF(("pr8210: Step reverse\n"));
|
||||
/* step backwards one frame */
|
||||
if (laserdisc_ready(ld))
|
||||
{
|
||||
set_state(ld, LASERDISC_STEPPING_REVERSE, STOP_SPEED, NULL_TARGET_FRAME);
|
||||
add_to_current_track(ld, -ONE_TRACK);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x14: CMDPRINTF(("pr8210: Play\n"));
|
||||
/* begin playing at regular speed, or load the disc if it is parked */
|
||||
if (laserdisc_ready(ld))
|
||||
set_state(ld, LASERDISC_PLAYING_FORWARD, PLAY_SPEED, NULL_TARGET_FRAME);
|
||||
else
|
||||
{
|
||||
/* if we're already spinning up or loading, ignore */
|
||||
if (ld->state != LASERDISC_SPINUP && ld->state != LASERDISC_LOADING)
|
||||
{
|
||||
if (ld->state == LASERDISC_PARKED)
|
||||
{
|
||||
set_state(ld, LASERDISC_SPINUP, STOP_SPEED, NULL_TARGET_FRAME);
|
||||
set_hold_state(ld, GENERIC_SPINUP_TIME, LASERDISC_PLAYING_FORWARD, PLAY_SPEED);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_state(ld, LASERDISC_LOADING, STOP_SPEED, NULL_TARGET_FRAME);
|
||||
set_hold_state(ld, GENERIC_LOAD_TIME, LASERDISC_PLAYING_FORWARD, PLAY_SPEED);
|
||||
}
|
||||
|
||||
ld->curfractrack = ONE_TRACK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x16: CMDPRINTF(("pr8210: Ch2 toggle\n"));
|
||||
/* channel 1 audio toggle */
|
||||
ld->audio ^= AUDIO_CH2_ENABLE;
|
||||
break;
|
||||
|
||||
case 0x18: CMDPRINTF(("pr8210: Slow forward\n"));
|
||||
/* slow forward */
|
||||
if (laserdisc_ready(ld))
|
||||
set_state(ld, LASERDISC_PLAYING_SLOW_FORWARD, PR8210_SLOW_SPEED, NULL_TARGET_FRAME);
|
||||
break;
|
||||
|
||||
case 0x1a: CMDPRINTF(("pr8210: Seek\n"));
|
||||
/* seek */
|
||||
if ( pr8210->seekstate )
|
||||
{
|
||||
CMDPRINTF(("pr8210: Seeking to frame:%d\n", ld->parameter));
|
||||
/* we're ready to seek */
|
||||
set_state(ld, LASERDISC_SEARCHING_FRAME, PR8210_SEARCH_SPEED, ld->parameter);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* waiting for digits indicating position */
|
||||
ld->parameter = 0;
|
||||
}
|
||||
pr8210->seekstate ^=1 ;
|
||||
break;
|
||||
|
||||
case 0x1c: CMDPRINTF(("pr8210: Scan reverse\n"));
|
||||
/* scan reverse */
|
||||
if (laserdisc_ready(ld))
|
||||
set_state(ld, LASERDISC_SCANNING_REVERSE, -PR8210_SCAN_SPEED, NULL_TARGET_FRAME);
|
||||
break;
|
||||
|
||||
case 0x1e: CMDPRINTF(("pr8210: Reject\n"));
|
||||
/* eject the disc */
|
||||
if (laserdisc_ready(ld))
|
||||
{
|
||||
set_state(ld, LASERDISC_EJECTING, STOP_SPEED, NULL_TARGET_FRAME);
|
||||
set_hold_state(ld, GENERIC_LOAD_TIME, LASERDISC_EJECTED, STOP_SPEED);
|
||||
}
|
||||
break;
|
||||
|
||||
default: CMDPRINTF(("pr8210: Unknown command %02X\n", cmd));
|
||||
/* unknown command */
|
||||
break;
|
||||
set_state(ld, LASERDISC_STEPPING_REVERSE, STOP_SPEED, NULL_TARGET_FRAME);
|
||||
add_to_current_track(ld, -ONE_TRACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* reset our command data */
|
||||
memset( pr8210->commandtriplet, 0, 3*sizeof(UINT16) );
|
||||
pr8210->mode = PR8210_MODE_GET_1ST;
|
||||
case 0x14: CMDPRINTF(("pr8210: Play\n"));
|
||||
/* begin playing at regular speed, or load the disc if it is parked */
|
||||
if (laserdisc_ready(ld))
|
||||
set_state(ld, LASERDISC_PLAYING_FORWARD, PLAY_SPEED, NULL_TARGET_FRAME);
|
||||
else
|
||||
{
|
||||
/* if we're already spinning up or loading, ignore */
|
||||
if (ld->state != LASERDISC_SPINUP && ld->state != LASERDISC_LOADING)
|
||||
{
|
||||
if (ld->state == LASERDISC_PARKED)
|
||||
{
|
||||
set_state(ld, LASERDISC_SPINUP, STOP_SPEED, NULL_TARGET_FRAME);
|
||||
set_hold_state(ld, GENERIC_SPINUP_TIME, LASERDISC_PLAYING_FORWARD, PLAY_SPEED);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_state(ld, LASERDISC_LOADING, STOP_SPEED, NULL_TARGET_FRAME);
|
||||
set_hold_state(ld, GENERIC_LOAD_TIME, LASERDISC_PLAYING_FORWARD, PLAY_SPEED);
|
||||
}
|
||||
reset_tracknum(ld);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x16: CMDPRINTF(("pr8210: Ch2 toggle\n"));
|
||||
/* channel 1 audio toggle */
|
||||
ld->audio ^= AUDIO_CH2_ENABLE;
|
||||
break;
|
||||
|
||||
case 0x18: CMDPRINTF(("pr8210: Slow forward\n"));
|
||||
/* slow forward */
|
||||
if (laserdisc_ready(ld))
|
||||
set_state(ld, LASERDISC_PLAYING_SLOW_FORWARD, PR8210_SLOW_SPEED, NULL_TARGET_FRAME);
|
||||
break;
|
||||
|
||||
case 0x1a: CMDPRINTF(("pr8210: Seek\n"));
|
||||
/* seek */
|
||||
if (pr8210->seekstate)
|
||||
{
|
||||
CMDPRINTF(("pr8210: Seeking to frame:%d\n", ld->parameter));
|
||||
/* we're ready to seek */
|
||||
set_state(ld, LASERDISC_SEARCHING_FRAME, PR8210_SEARCH_SPEED, ld->parameter);
|
||||
/* before seeking, we hold in the searching state for 150usec, even if seeking to the same frame */
|
||||
/* Us vs. Them requires at least this much "non-video" time in order to work */
|
||||
set_hold_state(ld, ATTOTIME_IN_MSEC(150), LASERDISC_SEARCHING_FRAME, PR8210_SEARCH_SPEED);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* waiting for digits indicating position */
|
||||
ld->parameter = 0;
|
||||
}
|
||||
pr8210->seekstate ^= 1;
|
||||
break;
|
||||
|
||||
case 0x1c: CMDPRINTF(("pr8210: Scan reverse\n"));
|
||||
/* scan reverse */
|
||||
if (laserdisc_ready(ld))
|
||||
set_state(ld, LASERDISC_SCANNING_REVERSE, -PR8210_SCAN_SPEED, NULL_TARGET_FRAME);
|
||||
break;
|
||||
|
||||
case 0x1e: CMDPRINTF(("pr8210: Reject\n"));
|
||||
/* eject the disc */
|
||||
if (laserdisc_ready(ld))
|
||||
{
|
||||
set_state(ld, LASERDISC_EJECTING, STOP_SPEED, NULL_TARGET_FRAME);
|
||||
set_hold_state(ld, GENERIC_LOAD_TIME, LASERDISC_EJECTED, STOP_SPEED);
|
||||
}
|
||||
break;
|
||||
|
||||
default: CMDPRINTF(("pr8210: Unknown command %02X\n", cmd));
|
||||
/* unknown command */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
pr8210_command_w - write callback when the
|
||||
pr8210_control_w - write callback when the
|
||||
CONTROL line is toggled
|
||||
-------------------------------------------------*/
|
||||
|
||||
@ -2258,42 +2269,53 @@ static void pr8210_control_w(laserdisc_state *ld, UINT8 data)
|
||||
{
|
||||
pr8210_info *pr8210 = &ld->u.pr8210;
|
||||
|
||||
if ( data == ASSERT_LINE )
|
||||
if (data == ASSERT_LINE)
|
||||
{
|
||||
attotime curtime = timer_get_time();
|
||||
attotime delta;
|
||||
int longpulse;
|
||||
|
||||
/* if we timed out, reset the accumulator */
|
||||
delta = attotime_sub(curtime, pr8210->firstbittime);
|
||||
if (delta.attoseconds > ATTOTIME_IN_USEC(25320).attoseconds)
|
||||
{
|
||||
pr8210->firstbittime = curtime;
|
||||
pr8210->accumulator = 0x5555;
|
||||
// printf("Reset accumulator\n");
|
||||
}
|
||||
|
||||
/* get the time difference from the last assert */
|
||||
attotime delta = attotime_sub(timer_get_time(), pr8210->commandtime);
|
||||
|
||||
/* and update our internal command time */
|
||||
pr8210->commandtime = timer_get_time();
|
||||
delta = attotime_sub(curtime, pr8210->lastbittime);
|
||||
pr8210->lastbittime = curtime;
|
||||
|
||||
/* 0 bit delta is 1.05 msec, 1 bit delta is 2.11 msec */
|
||||
longpulse = (delta.attoseconds < ATTOTIME_IN_USEC(1500).attoseconds) ? 0 : 1;
|
||||
pr8210->accumulator = (pr8210->accumulator << 1) | longpulse;
|
||||
|
||||
#if 0
|
||||
{
|
||||
int usecdiff = (int)(delta.attoseconds / ATTOSECONDS_IN_USEC(1));
|
||||
|
||||
printf( "bitdelta = %d\n", usecdiff );
|
||||
printf("bitdelta = %5d (%d) - accum = %04X\n", usecdiff, longpulse, pr8210->accumulator);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* if the delay is less than 3 msec, we're receiving data */
|
||||
if ( delta.attoseconds < ATTOTIME_IN_MSEC(3).attoseconds )
|
||||
/* if we have a complete command, signal it */
|
||||
/* a complete command is 0,0,1 followed by 5 bits, followed by 0,0 */
|
||||
if ((pr8210->accumulator & 0x383) == 0x80)
|
||||
{
|
||||
/* 0 bit delta is 1.05 msec, 1 bit delta is 2.11 msec */
|
||||
int longpulse = ( delta.attoseconds < ATTOTIME_IN_USEC(1500).attoseconds ) ? 0 : 1;
|
||||
pr8210->commandtriplet[pr8210->mode] <<= 1;
|
||||
pr8210->commandtriplet[pr8210->mode] |= longpulse;
|
||||
UINT8 newcommand = (pr8210->accumulator >> 2) & 0x1f;
|
||||
|
||||
/* if we received 10 bits, see what we need to do */
|
||||
if ( ++pr8210->commandbits >= 10 )
|
||||
//printf("New command = %02X (last=%02X)\n", newcommand, pr8210->lastcommand);
|
||||
|
||||
/* if we got a double command, act on it */
|
||||
if (newcommand == pr8210->lastcommand)
|
||||
{
|
||||
/* reset bit shift count */
|
||||
pr8210->commandbits = 0;
|
||||
|
||||
/* mask just the 10 bits */
|
||||
pr8210->commandtriplet[pr8210->mode] &= 0x3ff;
|
||||
|
||||
/* execute command */
|
||||
pr8210_command( ld );
|
||||
pr8210_command(ld);
|
||||
pr8210->lastcommand = 0;
|
||||
}
|
||||
else
|
||||
pr8210->lastcommand = newcommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2623,8 +2645,7 @@ static void ldv1000_data_w(laserdisc_state *ld, UINT8 prev, UINT8 data)
|
||||
set_state(ld, LASERDISC_LOADING, STOP_SPEED, NULL_TARGET_FRAME);
|
||||
set_hold_state(ld, GENERIC_LOAD_TIME, LASERDISC_PLAYING_FORWARD, PLAY_SPEED);
|
||||
}
|
||||
|
||||
ld->curfractrack = ONE_TRACK;
|
||||
reset_tracknum(ld);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2793,7 +2814,7 @@ static void ldp1450_soft_reset(laserdisc_state *ld)
|
||||
ld->audio = AUDIO_CH1_ENABLE | AUDIO_CH2_ENABLE;
|
||||
ld->display = FALSE;
|
||||
set_state(ld, LASERDISC_STOPPED, STOP_SPEED, NULL_TARGET_FRAME);
|
||||
ld->curfractrack = ONE_TRACK;
|
||||
reset_tracknum(ld);
|
||||
}
|
||||
|
||||
|
||||
@ -2994,8 +3015,7 @@ static void ldp1450_data_w(laserdisc_state *ld, UINT8 prev, UINT8 data)
|
||||
set_state(ld, LASERDISC_LOADING, STOP_SPEED, NULL_TARGET_FRAME);
|
||||
set_hold_state(ld, GENERIC_LOAD_TIME, LASERDISC_PLAYING_FORWARD, PLAY_SPEED);
|
||||
}
|
||||
|
||||
ld->curfractrack = ONE_TRACK;
|
||||
reset_tracknum(ld);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -27,7 +27,7 @@ enum
|
||||
LASERDISC_TYPE_PIONEER_PR8210, /* Pioneer PR-8210 / LD-V1100 */
|
||||
LASERDISC_TYPE_PIONEER_LDV1000, /* Pioneer LD-V1000 */
|
||||
LASERDISC_TYPE_PHILLIPS_22VP932, /* Phillips 22VP932 (PAL) */
|
||||
LASERDISC_TYPE_SONY_LDP1450, /* Sony LDP-1450 */
|
||||
LASERDISC_TYPE_SONY_LDP1450 /* Sony LDP-1450 */
|
||||
};
|
||||
|
||||
/* laserdisc control lines */
|
||||
@ -60,10 +60,13 @@ enum
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
typedef void (*laserdisc_audio_func)(const device_config *device, int samplerate, int samples, const INT16 *ch0, const INT16 *ch1);
|
||||
|
||||
typedef struct _laserdisc_config laserdisc_config;
|
||||
struct _laserdisc_config
|
||||
{
|
||||
int type;
|
||||
int type;
|
||||
laserdisc_audio_func audio;
|
||||
};
|
||||
|
||||
|
||||
@ -76,6 +79,9 @@ struct _laserdisc_config
|
||||
MDRV_DEVICE_ADD(_tag, LASERDISC) \
|
||||
MDRV_DEVICE_CONFIG_DATA32(laserdisc_config, type, LASERDISC_TYPE_##_type)
|
||||
|
||||
#define MDRV_LASERDISC_AUDIO(_func) \
|
||||
MDRV_DEVICE_CONFIG_DATAPTR(laserdisc_config, audio, _func)
|
||||
|
||||
#define MDRV_LASERDISC_REMOVE(_tag, _type) \
|
||||
MDRV_DEVICE_REMOVE(_tag, _type)
|
||||
|
||||
@ -93,19 +99,46 @@ extern const struct CustomSound_interface laserdisc_custom_interface;
|
||||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
/* ----- core control and status ----- */
|
||||
|
||||
/* call this once per field (i.e., 59.94 times/second for NTSC) */
|
||||
void laserdisc_vsync(const device_config *device);
|
||||
|
||||
/* return a textual description of the current state (for debugging) */
|
||||
const char *laserdisc_describe_state(const device_config *device);
|
||||
|
||||
/* get a bitmap for the current frame (and the frame number) */
|
||||
UINT32 laserdisc_get_video(const device_config *device, bitmap_t **bitmap);
|
||||
|
||||
/* return the raw philips or white flag codes */
|
||||
UINT32 laserdisc_get_field_code(const device_config *device, UINT8 code);
|
||||
|
||||
|
||||
|
||||
/* ----- input and output ----- */
|
||||
|
||||
/* write to the parallel data port of the player */
|
||||
void laserdisc_data_w(const device_config *device, UINT8 data);
|
||||
|
||||
/* assert or clear a signal line connected to the player */
|
||||
void laserdisc_line_w(const device_config *device, UINT8 line, UINT8 newstate);
|
||||
|
||||
/* read from the parallel data port of the player */
|
||||
UINT8 laserdisc_data_r(const device_config *device);
|
||||
|
||||
/* read the state of a signal line connected to the player */
|
||||
UINT8 laserdisc_line_r(const device_config *device, UINT8 line);
|
||||
|
||||
|
||||
|
||||
/* ----- player specifics ----- */
|
||||
|
||||
/* specify the "slow" speed of the Pioneer PR-7820 */
|
||||
void pr7820_set_slow_speed(const device_config *device, double frame_rate_scaler);
|
||||
|
||||
|
||||
|
||||
/* ----- device interface ----- */
|
||||
|
||||
/* device get info callback */
|
||||
|
@ -18,6 +18,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#define MAX_SOURCE_WIDTH 1024
|
||||
#define MAX_CLOCK_DIFF 3
|
||||
|
||||
|
||||
|
||||
@ -92,29 +93,21 @@ int vbi_parse_manchester_code(const UINT16 *source, int sourcewidth, int sources
|
||||
for (x = 1; x < expectedbits; x++)
|
||||
{
|
||||
int curbit = firstedge + (double)x * clock;
|
||||
int offby;
|
||||
|
||||
/* exact match? */
|
||||
if (srcabs[curbit + 0] != srcabs[curbit + 1])
|
||||
continue;
|
||||
|
||||
/* off-by-one? */
|
||||
if (srcabs[curbit + 1 + 0] != srcabs[curbit + 1 + 1] || srcabs[curbit - 1 + 0] != srcabs[curbit - 1 + 1])
|
||||
{
|
||||
/* only continue if we're still in the running */
|
||||
if ((error += 1) < besterr)
|
||||
continue;
|
||||
}
|
||||
/* look for a match that is off by an amount up to the maximum */
|
||||
for (offby = 0; offby <= MAX_CLOCK_DIFF; offby++)
|
||||
if (srcabs[curbit + offby + 0] != srcabs[curbit + offby + 1] || srcabs[curbit - offby + 0] != srcabs[curbit - offby + 1])
|
||||
break;
|
||||
|
||||
/* off-by-two? */
|
||||
if (srcabs[curbit + 2 + 0] != srcabs[curbit + 2 + 1] || srcabs[curbit - 2 + 0] != srcabs[curbit - 2 + 1])
|
||||
{
|
||||
/* only continue if we're still in the running */
|
||||
if ((error += 2) < besterr)
|
||||
continue;
|
||||
}
|
||||
/* if we never found the edge, fail immediately */
|
||||
if (offby > MAX_CLOCK_DIFF)
|
||||
break;
|
||||
|
||||
/* anything else fails immediately */
|
||||
break;
|
||||
/* only continue if we're still in the running */
|
||||
error += offby;
|
||||
if (error >= besterr)
|
||||
break;
|
||||
}
|
||||
|
||||
/* if we got to the end, this is the best candidate so far */
|
||||
|
@ -31,13 +31,12 @@ static UINT8 nmi_state;
|
||||
|
||||
static UINT8 speech_control;
|
||||
static UINT8 sp0250_drq;
|
||||
static UINT8 last_command;
|
||||
|
||||
static UINT8 *dac_data;
|
||||
static UINT8 *psg_latch;
|
||||
static UINT8 *sp0250_latch;
|
||||
|
||||
static UINT8 last_command;
|
||||
|
||||
|
||||
static void gottlieb1_sh_w(const device_config *riot, UINT8 data);
|
||||
static void gottlieb2_sh_w(running_machine *machine, UINT8 data);
|
||||
@ -342,6 +341,28 @@ MACHINE_DRIVER_END
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Rev. 1 input ports
|
||||
*
|
||||
*************************************/
|
||||
|
||||
INPUT_PORTS_START( gottlieb1_sound )
|
||||
PORT_START_TAG("SB1")
|
||||
PORT_DIPUNKNOWN_DIPLOC( 0x01, 0x01, "SB1:7" )
|
||||
PORT_DIPUNKNOWN_DIPLOC( 0x02, 0x02, "SB1:6" )
|
||||
PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x04, "SB1:5" )
|
||||
PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x08, "SB1:1" )
|
||||
PORT_DIPUNKNOWN_DIPLOC( 0x10, 0x10, "SB1:4" )
|
||||
PORT_DIPUNKNOWN_DIPLOC( 0x20, 0x20, "SB1:3" )
|
||||
PORT_DIPNAME( 0x40, 0x40, "Sound Test" )
|
||||
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_BIT( 0x80, 0x80, IPT_UNKNOWN ) /* To U3-6 on QBert */
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Rev. 2 communication handlers
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -7,6 +7,12 @@
|
||||
#include "machine/6532riot.h"
|
||||
|
||||
|
||||
#define GOTTLIEB_VIDEO_HCOUNT 318
|
||||
#define GOTTLIEB_VIDEO_HBLANK 256
|
||||
#define GOTTLIEB_VIDEO_VCOUNT 256
|
||||
#define GOTTLIEB_VIDEO_VBLANK 240
|
||||
|
||||
|
||||
/*----------- defined in audio/gottlieb.c -----------*/
|
||||
|
||||
WRITE8_HANDLER( gottlieb_sh_w );
|
||||
@ -14,6 +20,7 @@ WRITE8_HANDLER( gottlieb_sh_w );
|
||||
MACHINE_DRIVER_EXTERN( gottlieb_soundrev1 );
|
||||
MACHINE_DRIVER_EXTERN( gottlieb_soundrev2 );
|
||||
|
||||
INPUT_PORTS_EXTERN( gottlieb1_sound );
|
||||
INPUT_PORTS_EXTERN( gottlieb2_sound );
|
||||
|
||||
|
||||
@ -31,4 +38,6 @@ extern WRITE8_HANDLER( gottlieb_laserdisc_video_control_w );
|
||||
extern WRITE8_HANDLER( gottlieb_paletteram_w );
|
||||
|
||||
VIDEO_START( gottlieb );
|
||||
VIDEO_START( gottlieb_laserdisc );
|
||||
VIDEO_UPDATE( gottlieb );
|
||||
VIDEO_UPDATE( gottlieb_laserdisc );
|
||||
|
@ -5,6 +5,8 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "gottlieb.h"
|
||||
#include "machine/laserdsc.h"
|
||||
#include "video/resnet.h"
|
||||
|
||||
UINT8 *gottlieb_charram;
|
||||
@ -12,12 +14,16 @@ UINT8 *gottlieb_charram;
|
||||
UINT8 gottlieb_gfxcharlo;
|
||||
UINT8 gottlieb_gfxcharhi;
|
||||
|
||||
static int background_priority = 0;
|
||||
static int spritebank;
|
||||
static UINT8 background_priority = 0;
|
||||
static UINT8 spritebank;
|
||||
|
||||
static tilemap *bg_tilemap;
|
||||
static double weights[4];
|
||||
|
||||
static render_texture *video_texture;
|
||||
static render_texture *overlay_texture;
|
||||
static const rectangle overlay_clip = { 0, GOTTLIEB_VIDEO_HBLANK-1, 0, GOTTLIEB_VIDEO_VBLANK-8 };
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
@ -41,7 +47,7 @@ WRITE8_HANDLER( gottlieb_paletteram_w )
|
||||
val = paletteram[offset | 1];
|
||||
r = combine_4_weights(weights, (val >> 0) & 1, (val >> 1) & 1, (val >> 2) & 1, (val >> 3) & 1);
|
||||
|
||||
palette_set_color(machine, offset / 2, MAKE_RGB(r, g, b));
|
||||
palette_set_color(machine, offset / 2, MAKE_ARGB(((offset & ~1) == 0) ? 0x00 : 0xff, r, g, b));
|
||||
}
|
||||
|
||||
|
||||
@ -89,6 +95,7 @@ WRITE8_HANDLER( gottlieb_laserdisc_video_control_w )
|
||||
/* bit 2 video enable (0 = black screen) */
|
||||
|
||||
/* bit 3 genlock control (1 = show laserdisc image) */
|
||||
render_container_set_palette_alpha(render_container_get_screen(machine->primary_screen), 0, (data & 0x08) ? 0x00 : 0xff);
|
||||
}
|
||||
|
||||
|
||||
@ -150,6 +157,27 @@ VIDEO_START( gottlieb )
|
||||
bg_tilemap = tilemap_create(get_bg_tile_info, tilemap_scan_rows, 8, 8, 32, 32);
|
||||
tilemap_set_transparent_pen(bg_tilemap, 0);
|
||||
tilemap_set_scrolldx(bg_tilemap, 0, 318 - 256);
|
||||
|
||||
/* save some state */
|
||||
state_save_register_global(background_priority);
|
||||
state_save_register_global(spritebank);
|
||||
}
|
||||
|
||||
|
||||
VIDEO_START( gottlieb_laserdisc )
|
||||
{
|
||||
/* handle normal video */
|
||||
VIDEO_START_CALL(gottlieb);
|
||||
|
||||
/* allocate an overlay texture */
|
||||
overlay_texture = render_texture_alloc(NULL, NULL);
|
||||
if (overlay_texture == NULL)
|
||||
fatalerror("Out of memory allocating overlay texture");
|
||||
|
||||
/* allocate a video texture */
|
||||
video_texture = render_texture_alloc(NULL, NULL);
|
||||
if (video_texture == NULL)
|
||||
fatalerror("Out of memory allocating video texture");
|
||||
}
|
||||
|
||||
|
||||
@ -209,3 +237,37 @@ VIDEO_UPDATE( gottlieb )
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
VIDEO_UPDATE( gottlieb_laserdisc )
|
||||
{
|
||||
const device_config *laserdisc = device_list_first(screen->machine->config->devicelist, LASERDISC);
|
||||
rectangle clip = *cliprect;
|
||||
bitmap_t *video_bitmap;
|
||||
|
||||
/* scale the cliprect to the screen and render it */
|
||||
clip.min_x = 0;
|
||||
clip.max_x = GOTTLIEB_VIDEO_HBLANK - 1;
|
||||
clip.min_y = cliprect->min_y * GOTTLIEB_VIDEO_VCOUNT / bitmap->height;
|
||||
clip.max_y = (cliprect->max_y + 1) * GOTTLIEB_VIDEO_VCOUNT / bitmap->height - 1;
|
||||
video_update_gottlieb(screen, bitmap, &clip);
|
||||
|
||||
/* if this is the last update, handle it */
|
||||
if (cliprect->max_y == video_screen_get_visible_area(screen)->max_y)
|
||||
{
|
||||
/* update the texture with the overlay contents */
|
||||
render_texture_set_bitmap(overlay_texture, bitmap, &overlay_clip, 0, TEXFORMAT_PALETTEA16);
|
||||
|
||||
/* now talk to the laserdisc */
|
||||
laserdisc_get_video(laserdisc, &video_bitmap);
|
||||
if (video_bitmap != NULL)
|
||||
render_texture_set_bitmap(video_texture, video_bitmap, NULL, 0, TEXFORMAT_YUY16);
|
||||
|
||||
/* add both quads to the screen */
|
||||
render_container_empty(render_container_get_screen(screen));
|
||||
render_screen_add_quad(screen, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), video_texture, PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1));
|
||||
render_screen_add_quad(screen, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), overlay_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_SCREENTEX(1));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user