add clicklook option to allow looking at things on the display by clicking
right mouse button when floating mouse pointer over them
Izchak's lighting store is now able to stock oil for your lamp
+provide core support for saving of messsage history in save file
Platform- and/or Interface-Specific New Features
------------------------------------------------
win32gui: support perm_invent
win32gui: menu option to add/remove windows captions
+tty: add window port routines for saving/restoring message recall history
Code Cleanup and Reorganization
change if it indicated that it wants to be by setting the
corresponding bit in the wincap mask.
+getmsghistory(init)
+ -- This is used to preserve message history between games by
+ obtaining the messages from the window port so that the core
+ can put them into the savefile.
+ The routine is called repeatedly from the core save routine,
+ and the window port routine is expected to successively return
+ each message that it wants the game to store in the savefile,
+ starting with the oldest message first, finishing
+ with the most recent.
+ If init is TRUE, start over again from most recent message.
+
+putmsghistory(msg)
+ -- The is the counterpart to getmsghistory() for restores
+ used to reload the port's message recall buffer.
+ The routine is called repeatedly from the core restore
+ routine, starting with the oldest message first, and
+ finishing with the most recent one that it read from the savefile.
+ The window port routine is expected to load the message
+ recall buffers in such a way that the ordering remains correct.
+ The window port routine should make no assumptions about how
+ many messages are forthcoming, nor should it assume that
+ another message will follow this one, so it must be careful
+ to keep all pointers/indexes intact at the end of each call.
+ If the window port receives more messages that can fit in
+ its buffers, it is expected to scroll away the oldest from
+ its buffers, much like it would with new messages being
+ produced.
+
+
III. Global variables
The following global variables are defined in decl.c and must be used by
E void FDECL(choose_windows, (const char *));
E char FDECL(genl_message_menu, (CHAR_P,int,const char *));
E void FDECL(genl_preference_update, (const char *));
+E char *FDECL(genl_getmsghistory, (BOOLEAN_P));
+E void FDECL(genl_putmsghistory, (const char *));
/* ### wizard.c ### */
* Incrementing EDITLEVEL can be used to force invalidation of old bones
* and save files.
*/
-#define EDITLEVEL 3
+#define EDITLEVEL 4
#define COPYRIGHT_BANNER_A \
"NetHack, Copyright 1985-2003"
void FDECL((*win_outrip), (winid,int));
void FDECL((*win_preference_update), (const char *));
+ char * FDECL((*win_getmsghistory), (BOOLEAN_P));
+ void FDECL((*win_putmsghistory), (const char *));
};
extern NEARDATA struct window_procs windowprocs;
#define outrip (*windowprocs.win_outrip)
#define preference_update (*windowprocs.win_preference_update)
+#define getmsghistory (*windowprocs.win_getmsghistory)
+#define putmsghistory (*windowprocs.win_putmsghistory)
/*
* WINCAP
E void FDECL(genl_outrip, (winid,int));
+E char *FDECL(tty_getmsghistory, (BOOLEAN_P));
+E void FDECL(tty_putmsghistory, (const char *));
+
+
#ifdef NO_TERMS
# ifdef MAC
# ifdef putchar
restnames(fd);
restore_waterlevel(fd);
+ restore_msghistory(fd);
/* must come after all mons & objs are restored */
relink_timers(FALSE);
relink_light_sources(FALSE);
clear_id_mapping();
}
+restore_msghistory(fd)
+register int fd;
+{
+ int msgsize, k, msgcount = 0;
+ char msg[BUFSZ];
+
+ while(1) {
+ mread(fd, (genericptr_t) &msgsize, sizeof(msgsize));
+ if(msgsize == -1) break;
+ if (msgsize > (BUFSZ - 1))
+ panic("restore_msghistory: msg too big (%d)", msgsize);
+ mread(fd, (genericptr_t)msg, msgsize);
+ msg[msgsize] = '\0';
+ putmsghistory(msg);
+ ++msgcount;
+ }
+#ifdef DEBUG_MSGCOUNT
+ pline("Read %d messages from savefile.", msgcount);
+#endif
+}
/* Clear all structures for object and monster ID mapping. */
STATIC_OVL void
savefruitchn(fd, mode);
savenames(fd, mode);
save_waterlevel(fd, mode);
+ save_msghistory(fd, mode);
bflush(fd);
}
ffruit = 0;
}
+save_msghistory(fd, mode)
+register int fd, mode;
+{
+ char *msg, buf[BUFSZ];
+ int msgcount = 0, msglen = 0;
+ int minusone = -1;
+ boolean init = TRUE;
+
+ /* Ask window port for each message in sequence */
+ while ((msg = getmsghistory(init)) != 0) {
+ init = FALSE;
+ msglen = strlen(msg);
+ if (msglen < (BUFSZ-1))
+ Strcpy(buf, msg);
+ else {
+ /* impossible */
+ (void)strncpy(buf, msg, (BUFSZ - 1));
+ buf[BUFSZ-1] = '\0';
+ msglen = strlen(buf);
+ }
+ bwrite(fd, (genericptr_t)&msglen, sizeof(msglen));
+ bwrite(fd, (genericptr_t)msg, msglen);
+ ++msgcount;
+ }
+ bwrite(fd, (genericptr_t) &minusone, sizeof(int));
+#ifdef DEBUG_MSGCOUNT
+ pline("Stored %d messages into savefile.", msgcount);
+#endif
+}
+
/* also called by prscore(); this probably belongs in dungeon.c... */
void
free_dungeons()
they support.
Just return in this genl one. */
}
+
+char *
+genl_getmsghistory(init)
+boolean init;
+{
+ /* window ports can provide
+ their own getmsghistory() routine to
+ preserve message history between games.
+ The routine is called repeatedly from
+ the core save routine, and the window
+ port is expected to successively return
+ each message that it wants saved, starting
+ with the oldest message first, finishing
+ with the most recent.
+ Return null pointer when finished.
+ */
+ return (char *)0;
+}
+
+/*ARGSUSED*/
+void
+genl_putmsghistory(msg)
+const char *msg;
+{
+ /* window ports can provide
+ their own putmsghistory() routine to
+ load message history from a saved game.
+ The routine is called repeatedly from
+ the core restore routine, starting with
+ the oldest saved message first, and
+ finishing with the latest.
+ The window port routine is expected to
+ load the message recall buffers in such
+ a way that the ordering is preserved.
+ The window port routine should make no
+ assumptions about how many messages are
+ forthcoming, nor should it assume that
+ another message will follow this one,
+ so it should keep all pointers/indexes
+ intact at the end of each call.
+ */
+}
+
/*windows.c*/
amii_delay_output,
amii_delay_output,
amii_outrip,
- genl_preference_update
+ genl_preference_update,
+ genl_getmsghistory,
+ genl_putmsghistory
};
/* The view window layout uses the same function names so we can use
amii_delay_output,
amii_delay_output,
amii_outrip,
- genl_preference_update
+ genl_preference_update,
+ genl_getmsghistory,
+ genl_putmsghistory
};
unsigned short amii_initmap[ AMII_MAXCOLORS ];
0, // mac_end_screen,
genl_outrip,
genl_preference_update,
+ genl_getmsghistory,
+ genl_putmsghistory,
};
/*macwin.c*/
mswin_end_screen,
mswin_outrip,
mswin_preference_update,
+ genl_getmsghistory,
+ genl_putmsghistory,
};
/*
genl_outrip,
#endif
genl_preference_update,
+ genl_getmsghistory,
+ genl_putmsghistory,
};
extern "C" void play_usersound(const char* filename, int volume)
genl_outrip,
#endif
X11_preference_update,
+ genl_getmsghistory,
+ genl_putmsghistory,
};
/*
Gem_start_screen,
Gem_end_screen,
Gem_outrip,
- Gem_preference_update
+ Gem_preference_update,
+ genl_getmsghistory,
+ genl_putmsghistory
};
#ifdef MAC
gnome_end_screen,
gnome_outrip,
genl_preference_update,
+ genl_getmsghistory,
+ genl_putmsghistory,
};
/*
-/* SCCS Id: @(#)topl.c 3.4 1996/10/24 */
+/* SCCS Id: @(#)topl.c 3.4 2003/10/05 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
return q;
}
+
+/*
+ * This is called by the core save routines.
+ * Each time we are called, we return one string from the
+ * message history starting with the oldest message first. each time
+ * we are called. Each time after that, we return a more recent message,
+ * until there are no more messages to return. Then we return a final
+ * null string.
+ */
+char *
+tty_getmsghistory(init)
+boolean init;
+{
+ static int idx = 0, state = 0;
+ static boolean doneinit = FALSE;
+ register struct WinDesc *cw = wins[WIN_MESSAGE];
+ char *retstr = (char *)0;
+
+ /*
+ * state 0 = normal return with string from msg history.
+ * state 1 = finished with recall data, return toplines.
+ * state 2 = completely finished, return null string.
+ */
+ if (init) {
+ doneinit = TRUE;
+ state = 0;
+ idx = cw->maxrow;
+ }
+ if (doneinit && state < 2) {
+ if (state == 1) {
+ ++state;
+ return toplines;
+ }
+ do {
+ if(cw->data[idx] && strcmp(cw->data[idx], "") )
+ retstr = cw->data[idx];
+ idx = (idx + 1) % cw->rows;
+ } while (idx != cw->maxrow && !retstr);
+ if (idx == cw->maxrow) ++state;
+ }
+ return retstr;
+}
+
+/*
+ * This is called by the core savefile restore routines.
+ * Each time we are called, we stuff the string into our message
+ * history recall buffer. The core will send the oldest message
+ * first (actually it sends them in the order they exist in the
+ * save file, but that is supposed to be the oldest first).
+ */
+void
+tty_putmsghistory(msg)
+const char *msg;
+{
+ register struct WinDesc *cw = wins[WIN_MESSAGE];
+ int idx = cw->maxrow;
+ unsigned len = strlen(msg) + 1;
+
+ if (len > (unsigned)cw->datlen[idx]) {
+ if (cw->data[idx]) free(cw->data[idx]);
+ len += (8 - (len & 7)); /* pad up to next multiple of 8 */
+ cw->data[idx] = (char *)alloc(len);
+ cw->datlen[idx] = (short)len;
+ }
+ Strcpy(cw->data[idx], msg);
+ cw->maxcol = cw->maxrow = (idx + 1) % cw->rows;
+}
#endif /* TTY_GRAPHICS */
/*topl.c*/
#else
genl_preference_update,
#endif
+ tty_getmsghistory,
+ tty_putmsghistory,
};
static int maxwin = 0; /* number of windows in use */
mswin_end_screen,
mswin_outrip,
mswin_preference_update,
+ genl_getmsghistory,
+ genl_putmsghistory,
};