#include "angband.h" #include "ui-event.h" #include "player/types.h" #include "externs.h" #include "sys/time.h" static u64b max_wait_ms = 30000; /* cannot exceed MAX_SHORT */ static u64b prev_time; static ang_file *logfile; static char macro_file[1024]; extern void macro_disable(void); extern void macro_enable(void); u64b milliseconds(void) { struct timeval t; gettimeofday(&t, 0); return ((u64b)1000)*t.tv_sec + t.tv_usec/1000; } void log_nowait(void) { prev_time = 0; } void writelog(ui_event_data ke) { u64b delta; u64b cur_time; byte l2type; if (logfile == NULL || (p_ptr->noscore & NOSCORE_REPLAY)) return; if (ke.type == EVT_NONE) return; cur_time = milliseconds(); if (prev_time == 0) { delta = 0; } else { delta = cur_time - prev_time; if (delta > max_wait_ms) delta = max_wait_ms ; } prev_time = cur_time; fwrite_s((u16b)delta, logfile); fwrite_l((u32b) ke.type, logfile); #if 0 fwrite_b(ke.mousex, logfile); fwrite_b(ke.mousey, logfile); fwrite_b((byte) ke.key, logfile); fwrite_s((u16b) ke.index, logfile); #endif #if 0 for (l2type = 1; l2type <= ke.type/2; l2type *= 2); fwrite_b((byte) l2type+'A', logfile); #endif #if 1 if (!(ke.type & ( EVT_KBRD | EVT_ESCAPE | EVT_BACK | EVT_MOVE | EVT_SELECT))) { fwrite_b(ke.mousex, logfile); fwrite_b(ke.mousey, logfile); } if (!(ke.type & (EVT_MOUSE || EVT_SELECT))) fwrite_b((byte) ke.key, logfile); if (!(ke.type & (EVT_KBRD | EVT_ESCAPE | EVT_BACK))) fwrite_s((u16b) ke.index, logfile); #endif printf("%d:%c:%o:%o:%d\n", ke.type, ke.key, ke.mousex, ke.mousey, ke.index); fflush(stdout); } void log_pause() { macro_enable(); } void log_resume() { macro_disable(); } ui_event_data readlog(void) { u16b delta; bool success; byte l2type; ui_event_data ke = { EVT_NONE, 0, 0, 0, 0 }; success = fread_s(logfile, &delta); success &= fread_l(logfile, &ke.type); #if 0 success &= fread_b(logfile, &ke.mousex); success &= fread_b(logfile, &ke.mousey); success &= fread_b(logfile, (byte*) &ke.key); success &= fread_s(logfile, (u16b*) &ke.index); #endif #if 0 success &= fread_b(logfile, &l2type); l2type -= 'A'; /* l2type cannot be 0 -- EVT_NONE not logged */ for (ke.type = 1; ke.type *= 2; --l2type); #endif #if 1 if (!(ke.type & ( EVT_KBRD | EVT_ESCAPE | EVT_BACK | EVT_MOVE | EVT_SELECT))) { success &= fread_b(logfile, &ke.mousex); success &= fread_b(logfile, &ke.mousey); } if (!(ke.type & (EVT_MOUSE || EVT_SELECT))) success &= fread_b(logfile, (byte*) &ke.key); if(!(ke.type & (EVT_KBRD | EVT_ESCAPE | EVT_BACK))) success &= fread_s(logfile, (u16b*) &ke.index); #endif printf("%d:%c:%x:%x:%d\n", ke.type, ke.key, ke.mousex, ke.mousey, ke.index); Term_flush(); if (!success) { plog("Thththat's all folks!"); quit(0); } if (delta > max_wait_ms) delta = max_wait_ms; #if 1 if (delta > 100 && delta < 500) delta = 500; #endif while (delta > 0) { ui_event_data dummy; if (0 == Term_inkey(&dummy, FALSE, FALSE)) break; else if (delta > 300) { Term_xtra(TERM_XTRA_DELAY, 300); Term_xtra(TERM_XTRA_EVENT, FALSE); delta -= 300; } else { Term_xtra(TERM_XTRA_DELAY, delta); delta = 0; } } return ke; } void do_cmd_record_movie(void) { char name[84]; char dirname[1024]; char fname[1024]; size_t i; ang_file *fprf; ui_event_data ke = { EVT_RESIZE, Term->wid, Term->hgt, '\xff', 0 }; const dump_func prefs[] = { autoinsc_dump, squelch_dump, option_dump, keymap_dump }; strnfmt(name, sizeof name, "%s.bmv", op_ptr->full_name); get_file(name, dirname, sizeof dirname); mkdir(dirname, 0733); p_ptr->noscore |= NOSCORE_MOVIE; save_game(); path_build(fname, sizeof fname, dirname, "save"); file_move(savefile, fname); p_ptr->noscore &= ~NOSCORE_MOVIE; save_game(); path_build(fname, sizeof fname, dirname, "pref"); fprf = file_open(fname, MODE_WRITE, FTYPE_TEXT); for (i = 0; i < N_ELEMENTS(prefs); i++) { prefs[i](fprf); } file_close(fprf); path_build(fname, sizeof fname, dirname, "log"); logfile = file_open(fname, MODE_WRITE, FTYPE_RAW); writelog(ke); } void cmd_stop_logging(void) { file_close(logfile); logfile = NULL; } void start_reading() { char dirname[1024]; char filename[1024]; ang_file *fpref; p_ptr->noscore |= NOSCORE_REPLAY; my_strcpy(dirname, savefile, strrchr(savefile, *PATH_SEP)-savefile+1); path_build(filename, sizeof filename, dirname, "pref"); process_pref_file(filename); path_build(filename, sizeof filename, dirname, "log"); path_build(macro_file, sizeof macro_file, dirname, "macros"); fpref = file_open(macro_file, MODE_WRITE, FTYPE_TEXT); macro_dump(fpref); file_close(fpref); log_resume(); logfile = file_open(filename, MODE_READ, FTYPE_RAW); }