Index: savefile.c =================================================================== --- savefile.c (revision 1634) +++ savefile.c (working copy) @@ -371,6 +371,10 @@ char new_savefile[1024]; char old_savefile[1024]; + + /* Playing movies can't be saved */ + if (p_ptr->noscore & NOSCORE_REPLAY) + return FALSE; /* New savefile */ strnfmt(new_savefile, sizeof(new_savefile), "%s.new", savefile); Index: util.c =================================================================== --- util.c (revision 1634) +++ util.c (working copy) @@ -20,6 +20,7 @@ #include "randname.h" +static int macro__true; /* * Convert a decimal to a single digit hex number @@ -807,7 +808,6 @@ } - /* * Initialize the "macro" package */ @@ -823,7 +823,23 @@ return (0); } +void macro_enable(void) +{ + macro__num = macro__true; +} +bool macro_enabled(void) +{ + return macro__num >= 0; + +} + +void macro_disable(void) +{ + macro__true = macro__num; + macro__num = -1; +} + /* * Free the macro package */ @@ -967,6 +983,10 @@ char buf[1024]; + /* Invariant: While replaying a movie, macros are defined by the local machine */ + if (!macro_enabled()) + return readlog(); + /* Initialize the no return */ ke0.type = EVT_NONE; ke0.key = 0; @@ -1229,6 +1249,19 @@ term *old = Term; + /* Movie replay interrupt */ + while (!macro_enabled() && 0 == Term_inkey(&ke, FALSE, FALSE)) + { + /* Give the audience a chance to stretch */ + log_pause(); + log_nowait(); + /* Parse local input */ + ke = inkey_ex(); + if (dungeon_stateless(ke)) + return ke; + log_resume(); + } + /* Initialise keypress */ ke.key = 0; ke.type = EVT_NONE; @@ -1244,7 +1277,7 @@ inkey_base = inkey_xtra = inkey_flag = FALSE; inkey_scan = 0; - /* Accept result */ + /* Accept result, but don't log (inkey_next is defined in game logic) */ return (ke); } @@ -1475,7 +1508,8 @@ inkey_base = inkey_xtra = inkey_flag = FALSE; inkey_scan = 0; - /* Return the keypress */ + /* Invariant: log all logical keypresses */ + writelog(ke); return (ke); } Index: cmd0.c =================================================================== --- cmd0.c (revision 1634) +++ cmd0.c (working copy) @@ -144,9 +144,12 @@ { "Redraw the screen", KTRL('R'), CMD_NULL, do_cmd_redraw }, { "Load \"screen dump\"", '(', CMD_NULL, do_cmd_load_screen }, - { "Save \"screen dump\"", ')', CMD_NULL, do_cmd_save_screen } + { "Save \"screen dump\"", ')', CMD_NULL, do_cmd_save_screen }, + { "Toggle movie state", '&', CMD_NULL, do_cmd_toggle_movie } }; Index: z-file.c =================================================================== --- z-file.c (revision 1634) +++ z-file.c (working copy) @@ -619,7 +619,37 @@ #endif +/** Elementary types **/ +bool fwrite_l(u32b l, ang_file *fp) { + u32b buf[1]; + *buf = htonl(l); + return fwrite(&buf, sizeof(*buf), 1, fp->fh); +} +bool fwrite_s(u16b s, ang_file *fp) { + u16b buf[1]; + *buf = htons(s); + return fwrite(&buf, sizeof(*buf), 1, fp->fh); +} +bool fwrite_b(byte b, ang_file *fp) { + return fwrite(&b, sizeof(b), 1, fp->fh); +} +bool fread_l(ang_file *fp, u32b *l) { + u32b buf[1]; + int read = (fread(&buf, sizeof(*buf), 1, fp->fh) == 1); + *l = ntohl(*buf); + return read; +} +bool fread_s(ang_file *fp, u16b *s) { + u16b buf[1]; + int read = (fread(&buf, sizeof(*buf), 1, fp->fh) == 1); + *s = ntohs(*buf); + return read; +} +bool fread_b(ang_file *fp, byte *b) { + return (fread(b, sizeof(*b), 1, fp->fh) == 1); +} + /** Line-based IO **/ /* Index: z-file.h =================================================================== --- z-file.h (revision 1634) +++ z-file.h (working copy) @@ -203,7 +203,15 @@ bool file_writec(ang_file *f, byte b); +/** Elementary types **/ +bool fwrite_l(u32b l, ang_file *fp); +bool fwrite_s(u16b s, ang_file *fp); +bool fwrite_b(byte b, ang_file *fp); +bool fread_l(ang_file *fp, u32b *l); +bool fread_s(ang_file *fp, u16b *s); +bool fread_b(ang_file *fp, byte *b); + /*** Directory code ***/ /** Index: dungeon.c =================================================================== --- dungeon.c (revision 1634) +++ dungeon.c (working copy) @@ -1563,6 +1563,10 @@ } } +bool dungeon_stateless(ui_event_data ke) +{ + return false; +} /* @@ -1804,6 +1808,10 @@ /* Hack -- Enforce "delayed death" */ if (p_ptr->chp < 0) p_ptr->is_dead = TRUE; + else if (p_ptr->noscore & NOSCORE_MOVIE) { + start_reading(); + } + /* Process */ while (TRUE) { @@ -1913,6 +1921,10 @@ /* Make a new level */ generate_cave(); } + if (p_ptr->noscore & NOSCORE_REPLAY) + { + log_exit(); + } /* Tell the UI we're done with the game state */ event_signal(EVENT_LEAVE_GAME); Index: files.c =================================================================== --- files.c (revision 1634) +++ files.c (working copy) @@ -1772,6 +1772,11 @@ death_screen(); } + if (p_ptr->noscore & NOSCORE_REPLAY) + { + log_exit(); + } + /* Still alive */ else { Index: types.h =================================================================== --- types.h (revision 1634) +++ types.h (working copy) @@ -33,6 +33,8 @@ /** Function prototype for the UI to provide to remove native buttons */ typedef int (*button_kill_f)(unsigned char); +/** Pref-file dump function **/ +typedef void (*dump_func)(ang_file *); /**** Available Structs ****/ Index: defines.h =================================================================== --- defines.h (revision 1634) +++ defines.h (working copy) @@ -2209,10 +2209,10 @@ #define NOSCORE_WIZARD 0x0002 #define NOSCORE_DEBUG 0x0008 #define NOSCORE_BORG 0x0010 +#define NOSCORE_MOVIE 0x0020 +#define NOSCORE_REPLAY 0x0040 -#endif /* !INCLUDED_DEFINES_H */ - #define SCAN_INSTANT ((u32b) -1) #define SCAN_OFF 0 #define SCAN_MACRO 45 @@ -2221,3 +2221,6 @@ /* Whether to learn egos and flavors with less than complete information */ #define EASY_LEARN 1 + + +#endif /* !INCLUDED_DEFINES_H */ Index: Makefile.src =================================================================== --- Makefile.src (revision 1634) +++ Makefile.src (working copy) @@ -77,6 +77,7 @@ init2.o \ load.o \ load-old.o \ + logger.o \ monster/melee1.o \ monster/melee2.o \ monster/monster1.o \ Index: externs.h =================================================================== --- externs.h (revision 1634) +++ externs.h (working copy) @@ -315,6 +315,7 @@ /* dungeon.c */ extern void dungeon_change_level(int dlev); +extern bool dungeon_stateless(ui_event_data ke); extern void play_game(void); extern int value_check_aux1(const object_type *o_ptr); @@ -361,6 +362,14 @@ /* load.c */ extern bool old_load(void); +/* logger.c */ +extern void do_cmd_toggle_movie(void); +extern void log_nowait(void); +extern ui_event_data readlog(void); +extern void writelog(ui_event_data ke); +extern void start_reading(void); +extern void log_exit(void); + /* melee1.c */ bool check_hit(int power, int level); bool make_attack_normal(int m_idx); @@ -639,6 +648,10 @@ extern int color_text_to_attr(cptr name); extern cptr attr_to_text(byte a); +extern void macro_enable(void); +extern void macro_disable(void); +extern bool macro_enabled(void); + #ifdef SUPPORT_GAMMA extern void build_gamma_table(int gamma); extern byte gamma_table[256];