01609: Various - tested srmp4 (ssv.c), ttmahjng (route16.c), vsmahjng (vsnes,c), tokkae (konamigx.c), sf2 (cps1.c): INP playback loses sync quickly

Rewrote INP recording from scratch, since all old INPs are broken anyways.
Header now includes timestamp, which overrides the default time base for MAME's system time.
Each frame recorded now gets a timestamp.
Analog ports are recorded once per frame and interpolated.
Analog port calculations are all done in fixed point for consistent results.
A bunch of other minor tweaks in the input port code.

There may still be a few changes to the final INP format (considering adding 
NVRAM data directly in the INP file, for example....) but this at least seems
to work for the games I've tried.
This commit is contained in:
Aaron Giles 2008-04-06 06:03:00 +00:00
parent c889f3124f
commit 830b8836fc
5 changed files with 777 additions and 570 deletions

File diff suppressed because it is too large Load Diff

View File

@ -39,6 +39,11 @@
#define INPUT_PORT_PAIR_TOKENS (2 * sizeof(UINT32) / sizeof(FPTR))
#define INP_HEADER_SIZE 64
#define INP_HEADER_MAJVERSION 2
#define INP_HEADER_MINVERSION 0
/* macro for a custom callback functions (PORT_CUSTOM) */
#define CUSTOM_INPUT(name) UINT32 name(running_machine *machine, void *param)
@ -630,20 +635,13 @@ struct _input_port_entry
typedef struct _inp_header inp_header;
struct _inp_header
{
char name[9]; /* 8 bytes for game->name + NUL */
char version[3]; /* byte[0] = 0, byte[1] = version byte[2] = beta_version */
char reserved[20]; /* for future use, possible store game options? */
};
typedef struct _ext_inp_header ext_inp_header;
struct _ext_inp_header
{
char header[7]; /* must be "XINP" followed by NULLs */
char shortname[9]; /* game shortname */
char version[32]; /* MAME version string */
UINT32 starttime; /* approximate INP start time */
char dummy[32]; /* for possible future expansion */
char header[8]; /* +00: 8 byte header - must be "MAMEINP\0" */
UINT64 basetime; /* +08: base time of recording */
UINT8 majversion; /* +10: major INP version */
UINT8 minversion; /* +11: minor INP version */
UINT8 reserved[2]; /* +12: must be zero */
char gamename[12]; /* +14: game name string, NULL-terminated */
char version[32]; /* +20: system version string, NULL-terminated */
};
@ -904,7 +902,7 @@ struct _ext_inp_header
FUNCTION PROTOTYPES
***************************************************************************/
void input_port_init(running_machine *machine, const input_port_token *ipt);
time_t input_port_init(running_machine *machine, const input_port_token *ipt);
const char *input_port_string_from_token(const input_port_token token);
input_port_entry *input_port_initialize(input_port_init_params *params, UINT32 type, const char *tag, UINT32 mask, UINT32 defval);
@ -938,8 +936,6 @@ int input_ui_pressed_repeat(int code, int speed);
void input_port_update_defaults(void);
void input_port_set_digital_value(int port, UINT32 value, UINT32 mask);
UINT32 get_crosshair_pos(int port_num, UINT8 player, UINT8 axis);
UINT32 readinputport(int port);

View File

@ -1517,6 +1517,7 @@ static void destroy_machine(running_machine *machine)
static void init_machine(running_machine *machine)
{
mame_private *mame = machine->mame_data;
time_t newbase;
int num;
/* initialize basic can't-fail systems here */
@ -1545,16 +1546,15 @@ static void init_machine(running_machine *machine)
/* init the osd layer */
osd_init(machine);
/* initialize the base time (needed for doing record/playback) */
time(&mame->base_time);
/* initialize the input system and input ports for the game */
/* this must be done before memory_init in order to allow specifying */
/* callbacks based on input port tags */
input_port_init(machine, machine->gamedrv->ipt);
/* initialize the base time (if not doing record/playback) */
if (machine->record_file == NULL && machine->playback_file == NULL)
time(&mame->base_time);
else
mame->base_time = 0;
newbase = input_port_init(machine, machine->gamedrv->ipt);
if (newbase != 0)
mame->base_time = newbase;
/* first load ROMs, then populate memory, and finally initialize CPUs */
/* these operations must proceed in this order */

View File

@ -1607,6 +1607,17 @@ const char *video_get_speed_text(running_machine *machine)
}
/*-------------------------------------------------
video_get_speed_percent - return the current
effective speed percentage
-------------------------------------------------*/
double video_get_speed_percent(running_machine *machine)
{
return global.speed_percent;
}
/*-------------------------------------------------
video_get_frameskip - return the current
actual frameskip (-1 means autoframeskip)

View File

@ -236,6 +236,9 @@ void video_set_speed_factor(int speed);
/* return text to display about the current speed */
const char *video_get_speed_text(running_machine *machine);
/* return the current effective speed percentage */
double video_get_speed_percent(running_machine *machine);
/* get/set the current frameskip (-1 means auto) */
int video_get_frameskip(void);
void video_set_frameskip(int frameskip);