mirror of
https://github.com/LIV2/WinUAE.git
synced 2025-12-06 00:12:52 +00:00
225 lines
4.7 KiB
C++
225 lines
4.7 KiB
C++
|
|
static uae_u8 *inprec_buffer, *inprec_p;
|
|
static struct zfile *inprec_zf;
|
|
static int inprec_size;
|
|
int input_recording = 0;
|
|
static uae_u8 *inprec_plast, *inprec_plastptr;
|
|
static int inprec_div;
|
|
|
|
static uae_u32 oldbuttons[4];
|
|
static uae_u16 oldjoy[2];
|
|
|
|
int inprec_open(char *fname, int record)
|
|
{
|
|
uae_u32 t = (uae_u32)time(0);
|
|
int i;
|
|
|
|
inprec_close();
|
|
inprec_zf = zfile_fopen(fname, record > 0 ? "wb" : "rb");
|
|
if (inprec_zf == NULL)
|
|
return 0;
|
|
inprec_size = 10000;
|
|
inprec_div = 1;
|
|
if (record < 0) {
|
|
uae_u32 id;
|
|
zfile_fseek (inprec_zf, 0, SEEK_END);
|
|
inprec_size = zfile_ftell (inprec_zf);
|
|
zfile_fseek (inprec_zf, 0, SEEK_SET);
|
|
inprec_buffer = inprec_p = (uae_u8*)xmalloc (inprec_size);
|
|
zfile_fread (inprec_buffer, inprec_size, 1, inprec_zf);
|
|
inprec_plastptr = inprec_buffer;
|
|
id = inprec_pu32();
|
|
if (id != 'UAE\0') {
|
|
inprec_close();
|
|
return 0;
|
|
}
|
|
inprec_pu32();
|
|
t = inprec_pu32();
|
|
i = inprec_pu32();
|
|
while (i-- > 0)
|
|
inprec_pu8();
|
|
inprec_p = inprec_plastptr;
|
|
oldbuttons[0] = oldbuttons[1] = oldbuttons[2] = oldbuttons[3] = 0;
|
|
oldjoy[0] = oldjoy[1] = 0;
|
|
if (record < -1)
|
|
inprec_div = maxvpos;
|
|
} else if (record > 0) {
|
|
inprec_buffer = inprec_p = (uae_u8*)xmalloc (inprec_size);
|
|
inprec_ru32('UAE\0');
|
|
inprec_ru8(1);
|
|
inprec_ru8(UAEMAJOR);
|
|
inprec_ru8(UAEMINOR);
|
|
inprec_ru8(UAESUBREV);
|
|
inprec_ru32(t);
|
|
inprec_ru32(0); // extra header size
|
|
} else {
|
|
return 0;
|
|
}
|
|
input_recording = record;
|
|
srand(t);
|
|
CIA_inprec_prepare();
|
|
write_log ("inprec initialized '%s', mode=%d\n", fname, input_recording);
|
|
return 1;
|
|
}
|
|
|
|
void inprec_close(void)
|
|
{
|
|
if (!inprec_zf)
|
|
return;
|
|
if (inprec_buffer && input_recording > 0) {
|
|
hsync_counter++;
|
|
inprec_rstart(INPREC_END);
|
|
inprec_rend();
|
|
hsync_counter--;
|
|
zfile_fwrite (inprec_buffer, inprec_p - inprec_buffer, 1, inprec_zf);
|
|
inprec_p = inprec_buffer;
|
|
}
|
|
zfile_fclose (inprec_zf);
|
|
inprec_zf = NULL;
|
|
xfree (inprec_buffer);
|
|
inprec_buffer = NULL;
|
|
input_recording = 0;
|
|
write_log ("inprec finished\n");
|
|
}
|
|
|
|
void inprec_ru8(uae_u8 v)
|
|
{
|
|
*inprec_p++= v;
|
|
}
|
|
void inprec_ru16(uae_u16 v)
|
|
{
|
|
inprec_ru8((uae_u8)(v >> 8));
|
|
inprec_ru8((uae_u8)v);
|
|
}
|
|
void inprec_ru32(uae_u32 v)
|
|
{
|
|
inprec_ru16((uae_u16)(v >> 16));
|
|
inprec_ru16((uae_u16)v);
|
|
}
|
|
void inprec_rstr(const char *s)
|
|
{
|
|
while(*s) {
|
|
inprec_ru8(*s);
|
|
s++;
|
|
}
|
|
inprec_ru8(0);
|
|
}
|
|
void inprec_rstart(uae_u8 type)
|
|
{
|
|
write_log ("INPREC: %08X: %d\n", hsync_counter, type);
|
|
inprec_ru32(hsync_counter);
|
|
inprec_ru8(0);
|
|
inprec_plast = inprec_p;
|
|
inprec_ru8(0xff);
|
|
inprec_ru8(type);
|
|
}
|
|
void inprec_rend(void)
|
|
{
|
|
*inprec_plast = inprec_p - (inprec_plast + 2);
|
|
if (inprec_p >= inprec_buffer + inprec_size - 256) {
|
|
zfile_fwrite (inprec_buffer, inprec_p - inprec_buffer, 1, inprec_zf);
|
|
inprec_p = inprec_buffer;
|
|
}
|
|
}
|
|
|
|
int inprec_pstart(uae_u8 type)
|
|
{
|
|
uae_u8 *p = inprec_p;
|
|
uae_u32 hc = hsync_counter;
|
|
static uae_u8 *lastp;
|
|
uae_u32 hc_orig, hc2_orig;
|
|
|
|
if (savestate_state)
|
|
return 0;
|
|
if (p[5 + 1] == INPREC_END) {
|
|
inprec_close();
|
|
return 0;
|
|
}
|
|
hc_orig = hc;
|
|
hc /= inprec_div;
|
|
hc *= inprec_div;
|
|
for (;;) {
|
|
uae_u32 hc2 = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
|
|
if (p > lastp) {
|
|
write_log ("INPREC: Next %08x (%08x=%d): %d (%d)\n", hc2, hc, hc2 - hc, p[5 + 1], p[5]);
|
|
lastp = p;
|
|
}
|
|
hc2_orig = hc2;
|
|
hc2 /= inprec_div;
|
|
hc2 *= inprec_div;
|
|
if (hc > hc2) {
|
|
write_log ("INPREC: %08x > %08x: %d (%d) missed!\n", hc, hc2, p[5 + 1], p[5]);
|
|
inprec_close();
|
|
return 0;
|
|
}
|
|
if (hc2 != hc) {
|
|
lastp = p;
|
|
break;
|
|
}
|
|
if (p[5 + 1] == type) {
|
|
write_log ("INPREC: %08x: %d (%d) (%+d)\n", hc, type, p[5], hc_orig - hc2_orig);
|
|
inprec_plast = p;
|
|
inprec_plastptr = p + 5 + 2;
|
|
return 1;
|
|
}
|
|
p += 5 + 2 + p[5];
|
|
}
|
|
inprec_plast = NULL;
|
|
return 0;
|
|
}
|
|
void inprec_pend(void)
|
|
{
|
|
uae_u8 *p = inprec_p;
|
|
uae_u32 hc = hsync_counter;
|
|
|
|
if (!inprec_plast)
|
|
return;
|
|
inprec_plast[5 + 1] = 0;
|
|
inprec_plast = NULL;
|
|
inprec_plastptr = NULL;
|
|
hc /= inprec_div;
|
|
hc *= inprec_div;
|
|
for (;;) {
|
|
uae_u32 hc2 = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
|
|
hc2 /= inprec_div;
|
|
hc2 *= inprec_div;
|
|
if (hc2 != hc)
|
|
break;
|
|
if (p[5 + 1] != 0)
|
|
return;
|
|
p += 5 + 2 + p[5];
|
|
}
|
|
inprec_p = p;
|
|
if (p[5 + 1] == INPREC_END)
|
|
inprec_close();
|
|
}
|
|
|
|
uae_u8 inprec_pu8(void)
|
|
{
|
|
return *inprec_plastptr++;
|
|
}
|
|
uae_u16 inprec_pu16(void)
|
|
{
|
|
uae_u16 v = inprec_pu8() << 8;
|
|
v |= inprec_pu8();
|
|
return v;
|
|
}
|
|
uae_u32 inprec_pu32(void)
|
|
{
|
|
uae_u32 v = inprec_pu16() << 16;
|
|
v |= inprec_pu16();
|
|
return v;
|
|
}
|
|
int inprec_pstr(char *s)
|
|
{
|
|
int len = 0;
|
|
for(;;) {
|
|
uae_u8 v = inprec_pu8();
|
|
*s++ = v;
|
|
if (!v)
|
|
break;
|
|
len++;
|
|
}
|
|
return len;
|
|
}
|