Win32GUI: Gather raw_print text and display it all in single dialog

Defined strbuf_t and related routines to support dynamically sized
strings. Modified strip_newline() to strip the last newline in a string
instead of the first.

Simplified splash window code using new strbuf_t.

Prior to exiting game, re-enable getreturn and call wait_synch() in
case there is buffered raw prints that must be displayed to user.
This commit is contained in:
Bart House
2017-10-02 21:11:30 -07:00
committed by Pasi Kallinen
parent b02dae91a1
commit a588541a27
9 changed files with 200 additions and 80 deletions

View File

@@ -924,6 +924,11 @@ E int NDECL(phase_of_the_moon);
E boolean NDECL(friday_13th);
E int NDECL(night);
E int NDECL(midnight);
E void FDECL(strbuf_init, (strbuf_t *));
E void FDECL(strbuf_append, (strbuf_t *, const char *));
E void FDECL(strbuf_reserve, (strbuf_t *, int));
E void FDECL(strbuf_empty, (strbuf_t *));
E void FDECL(strbuf_nl_to_crlf, (strbuf_t *));
/* ### invent.c ### */

View File

@@ -151,6 +151,12 @@ enum game_end_types {
ASCENDED
};
typedef struct strbuf {
int len;
char * str;
char buf[256];
} strbuf_t;
#include "align.h"
#include "dungeon.h"
#include "monsym.h"

View File

@@ -61,6 +61,11 @@
boolean friday_13th (void)
int night (void)
int midnight (void)
void strbuf_init (strbuf *, const char *)
void strbuf_append (strbuf *, const char *)
void strbuf_reserve (strbuf *, int)
void strbuf_empty (strbuf *)
void strbuf_nl_to_crlf (strbuf_t *)
=*/
#ifdef LINT
#define Static /* pacify lint */
@@ -183,7 +188,7 @@ char *
strip_newline(str)
char *str;
{
char *p = index(str, '\n');
char *p = rindex(str, '\n');
if (p) {
if (p > str && *(p - 1) == '\r')
@@ -1101,4 +1106,69 @@ midnight()
return (getlt()->tm_hour == 0);
}
/* strbuf_init() initializes strbuf state for use */
void strbuf_init(strbuf_t * strbuf)
{
strbuf->str = NULL;
strbuf->len = 0;
}
/* strbuf_append() appends given str to strbuf->str */
void strbuf_append(strbuf_t * strbuf, const char * str)
{
if (strbuf->str == NULL)
strbuf_reserve(strbuf, strlen(str) + 1);
else
strbuf_reserve(strbuf, strlen(strbuf->str) + strlen(str) + 1);
strcat(strbuf->str, str);
}
/* strbuf_reserve() ensure strbuf->str has storage for len characters */
void strbuf_reserve(strbuf_t * strbuf, int len)
{
if (strbuf->str == NULL) {
strbuf->str = strbuf->buf;
strbuf->str[0] = '\0';
strbuf->len = sizeof(strbuf->buf);
}
if (len > strbuf->len) {
char * oldbuf = strbuf->str;
strbuf->len = len + sizeof(strbuf->buf);
strbuf->str = (char *) alloc(strbuf->len);
strcpy(strbuf->str, oldbuf);
if (oldbuf != strbuf->buf) free(oldbuf);
}
}
/* strbuf_empty() frees allocated memory and set strbuf to initial state */
void strbuf_empty(strbuf_t * strbuf)
{
if (strbuf->str != strbuf->buf)
free(strbuf->str);
strbuf_init(strbuf);
}
/* strbuf_nl_to_crlf() converts all occurences of \n to \r\n */
void strbuf_nl_to_crlf(strbuf_t * strbuf)
{
if (strbuf->str) {
int len = strlen(strbuf->str);
int count = 0;
char * cp = strbuf->str;
while (*cp) if (*cp++ == '\n') count++;
if (count) {
strbuf_reserve(strbuf, len + count + 1);
cp = strbuf->str + len + count;
while (count) {
if ((*cp-- = cp[-count]) == '\n') {
*cp-- = '\r';
count--;
}
}
}
}
}
/*hacklib.c*/

View File

@@ -139,6 +139,15 @@ char *argv[];
/* use STDERR by default
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
/* Heap Debugging
_CrtSetDbgFlag( _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)
| _CRTDBG_ALLOC_MEM_DF
| _CRTDBG_CHECK_ALWAYS_DF
| _CRTDBG_CHECK_CRT_DF
| _CRTDBG_DELAY_FREE_MEM_DF
| _CRTDBG_LEAK_CHECK_DF);
_CrtSetBreakAlloc(1423);
*/
# endif
#endif

View File

@@ -546,6 +546,8 @@ msexit()
getreturn("to end");
synch_cursor();
#endif
getreturn_enabled = TRUE;
wait_synch();
return;
}
#endif /* MICRO || WIN32 || OS2 */

View File

@@ -245,6 +245,25 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
data = (PNHMessageWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
switch (wParam) {
case MSNH_MSG_PUTSTR: {
/* Add the passed in message to the existing text. Support the
* adding of text that ends in newline. A newline in text
* will force any subsequent text that is added to be added on
* a new output line.
*
* TODO: Text can be added with newlines occurring within the text not
* just at the end. As currently implemented, this can cause
* the text to be rendered such that the text following the
* newline is rendered on a new line. This can cause a poor
* user experience when the user has set only a single text line
* for the message window. In this case, the user will not see
* any line other then the last line of text and the --MORE--
* message thus missing any text that appears before the last
* embedded newline. This does not meet the requirements of the
* message window.
* This code should be changed to do the right thing and split
* the text so that only lines that end in newlines are added to
* the stored window text.
*/
PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr) lParam;
SCROLLINFO si;
char *p;
@@ -271,10 +290,17 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
/* check for "--more--" */
if (!data->nevermore && more_prompt_check(hWnd)) {
int okkey = 0;
int chop;
char tmptext[MAXWINDOWTEXT + 1];
// @@@ Ok respnses
/* append more prompt and inticate the update */
/* save original text */
strcpy(tmptext, data->window_text[MSG_LINES - 1].text);
/* text could end in newline so strip it */
strip_newline(data->window_text[MSG_LINES - 1].text);
/* append more prompt and indicate the update */
strncat(
data->window_text[MSG_LINES - 1].text, MORE,
MAXWINDOWTEXT
@@ -301,10 +327,9 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
}
}
/* erase the "--more--" prompt */
chop = strlen(data->window_text[MSG_LINES - 1].text)
- strlen(MORE);
data->window_text[MSG_LINES - 1].text[chop] = '\0';
/* restore original text */
strcpy(data->window_text[MSG_LINES - 1].text, tmptext);
data->lines_not_seen = 0;
}
@@ -601,6 +626,7 @@ onPaint(HWND hWnd)
- (client_rt.bottom - ps.rcPaint.bottom) / data->yChar);
y = min(ps.rcPaint.bottom, client_rt.bottom);
for (i = LastLine; i >= FirstLine; i--) {
char tmptext[MAXWINDOWTEXT + 1];
x = data->xChar * (2 - data->xPos);
draw_rt.left = x;
@@ -612,8 +638,10 @@ onPaint(HWND hWnd)
hdc, mswin_get_font(NHW_MESSAGE, data->window_text[i].attr,
hdc, FALSE));
/* convert to UNICODE */
NH_A2W(data->window_text[i].text, wbuf, sizeof(wbuf));
/* convert to UNICODE stripping newline */
strcpy(tmptext, data->window_text[i].text);
strip_newline(tmptext);
NH_A2W(tmptext, wbuf, sizeof(wbuf));
wlen = _tcslen(wbuf);
setMsgTextColor(hdc, i < (MSG_LINES - data->lines_last_turn));
#ifdef MSG_WRAP_TEXT
@@ -765,6 +793,10 @@ can_append_text(HWND hWnd, int attr, const char *text)
if (data->window_text[MSG_LINES - 1].attr != attr)
return FALSE;
/* cannot append if current line ends in newline */
if (str_end_is(data->window_text[MSG_LINES - 1].text, "\n"))
return FALSE;
/* check if the maximum string langth will be exceeded */
if (strlen(data->window_text[MSG_LINES - 1].text) + 2
+ /* space characters */
@@ -772,10 +804,11 @@ can_append_text(HWND hWnd, int attr, const char *text)
>= MAXWINDOWTEXT)
return FALSE;
/* check if the text is goinf to fin into a single line */
/* check if the text is going to fit into a single line */
strcpy(tmptext, data->window_text[MSG_LINES - 1].text);
strcat(tmptext, " ");
strcat(tmptext, text);
strip_newline(tmptext);
strcat(tmptext, MORE);
hdc = GetDC(hWnd);
@@ -836,6 +869,8 @@ more_prompt_check(HWND hWnd)
hdc, FALSE));
strcpy(tmptext, data->window_text[MSG_LINES - i - 1].text);
strip_newline(tmptext);
if (i == 0)
strcat(tmptext, MORE);

View File

@@ -36,13 +36,9 @@ mswin_display_splash_window(BOOL show_ver)
RECT controlrt;
HWND hWnd;
int buttop;
int strsize = 0;
int bufsize = BUFSZ;
char *buf = malloc(bufsize);
strbuf_t strbuf;
if (buf == NULL)
panic("out of memory");
buf[0] = '\0';
strbuf_init(&strbuf);
hWnd = CreateDialog(GetNHApp()->hApp, MAKEINTRESOURCE(IDD_SPLASH),
GetNHApp()->hMainWnd, NHSplashWndProc);
@@ -87,9 +83,9 @@ mswin_display_splash_window(BOOL show_ver)
clientrt.right - 2 * SPLASH_OFFSET_X, controlrt.bottom, TRUE);
/* Fill the text control */
Sprintf(buf, "%s\r\n%s\r\n%s\r\n%s\r\n\r\n", COPYRIGHT_BANNER_A,
strbuf_reserve(&strbuf, BUFSIZ);
Sprintf(strbuf.str, "%s\n%s\n%s\n%s\n\n", COPYRIGHT_BANNER_A,
COPYRIGHT_BANNER_B, COPYRIGHT_BANNER_C, COPYRIGHT_BANNER_D);
strsize = strlen(buf);
if (show_ver) {
/* Show complete version information */
@@ -98,43 +94,16 @@ mswin_display_splash_window(BOOL show_ver)
int verstrsize = 0;
getversionstring(verbuf);
verstrsize = strlen(verbuf);
if (verstrsize + strlen("\r\n\r\n") + 1 < BUFSZ - 1)
strcat(verbuf, "\r\n\r\n");
verstrsize = strlen(verbuf);
if (strsize + verstrsize + 1 > bufsize) {
bufsize += BUFSZ;
buf = realloc(buf, bufsize);
if (buf == NULL)
panic("out of memory");
}
strcat(buf, verbuf);
strsize = strlen(buf);
strbuf_append(&strbuf, verbuf);
strbuf_append(&strbuf, "\n\n");
/* Add compile options */
f = dlb_fopen(OPTIONS_USED, RDTMODE);
if (f) {
char line[LLEN + 1];
while (dlb_fgets(line, LLEN, f)) {
size_t len;
len = strlen(line);
if (len > 0 && line[len - 1] == '\n') {
line[len - 1] = '\r';
line[len] = '\n';
line[len + 1] = '\0';
len++;
}
if (strsize + (int) len + 1 > bufsize) {
bufsize += BUFSZ;
buf = realloc(buf, bufsize);
if (buf == NULL)
panic("out of memory");
}
strcat(buf, line);
strsize += len;
}
while (dlb_fgets(line, LLEN, f))
strbuf_append(&strbuf, line);
(void) dlb_fclose(f);
}
} else {
@@ -147,32 +116,18 @@ mswin_display_splash_window(BOOL show_ver)
if (nf != NULL) {
char line[LLEN + 1];
while (fgets(line, LLEN, nf)) {
size_t len;
len = strlen(line);
if (len > 0 && line[len - 1] == '\n') {
line[len - 1] = '\r';
line[len] = '\n';
line[len + 1] = '\0';
len++;
}
if (strsize + (int) len + 1 > bufsize) {
bufsize += BUFSZ;
buf = realloc(buf, bufsize);
if (buf == NULL)
panic("out of memory");
}
strcat(buf, line);
strsize += len;
}
while (fgets(line, LLEN, nf))
strbuf_append(&strbuf, line);
(void) fclose(nf);
} else {
strcat(buf, "No news.");
strbuf_append(&strbuf, "No news.");
}
}
}
SetWindowText(GetDlgItem(hWnd, IDC_EXTRAINFO), buf);
free(buf);
strbuf_nl_to_crlf(&strbuf);
SetWindowText(GetDlgItem(hWnd, IDC_EXTRAINFO), strbuf.str);
strbuf_empty(&strbuf);
ShowWindow(hWnd, SW_SHOW);
while (IsWindow(hWnd) && GetMessage(&msg, NULL, 0, 0) != 0) {

View File

@@ -75,6 +75,8 @@ COLORREF status_fg_color = RGB(0xFF, 0xFF, 0xFF);
COLORREF message_bg_color = RGB(0, 0, 0);
COLORREF message_fg_color = RGB(0xFF, 0xFF, 0xFF);
strbuf_t raw_print_strbuf = { 0 };
/* Interface definition, for windows.c */
struct window_procs mswin_procs = {
"MSWIN",
@@ -717,8 +719,7 @@ mswin_exit_nhwindows(const char *str)
/* Write Window settings to the registry */
mswin_write_reg();
while (max_brush)
DeleteObject(brush_table[--max_brush]);
}
/* Prepare the window to be suspended. */
@@ -1238,6 +1239,7 @@ void
mswin_wait_synch()
{
logDebug("mswin_wait_synch()\n");
mswin_raw_print_flush();
}
/*
@@ -1293,6 +1295,40 @@ mswin_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph)
}
}
/*
* mswin_raw_print_accumulate() accumulate the given text into
* raw_print_strbuf.
*/
void
mswin_raw_print_accumulate(const char * str, boolean bold)
{
bold; // ignored for now
if (raw_print_strbuf.str != NULL) strbuf_append(&raw_print_strbuf, "\n");
strbuf_append(&raw_print_strbuf, str);
}
/*
* mswin_raw_print_flush() - display any text found in raw_print_strbuf in a
* dialog box and clear raw_print_strbuf.
*/
void
mswin_raw_print_flush()
{
if (raw_print_strbuf.str != NULL) {
int wlen = strlen(raw_print_strbuf.str) + 1;
TCHAR * wbuf = (TCHAR *) alloc(wlen * sizeof(TCHAR));
if (wbuf != NULL) {
NHMessageBox(GetNHApp()->hMainWnd,
NH_A2W(raw_print_strbuf.str, wbuf, wlen),
MB_ICONINFORMATION | MB_OK);
free(wbuf);
}
strbuf_empty(&raw_print_strbuf);
}
}
/*
raw_print(str) -- Print directly to a screen, or otherwise guarantee that
the user sees str. raw_print() appends a newline to str.
@@ -1305,14 +1341,12 @@ raw_print(str) -- Print directly to a screen, or otherwise guarantee that
void
mswin_raw_print(const char *str)
{
TCHAR wbuf[255];
logDebug("mswin_raw_print(%s)\n", str);
if (str && *str) {
extern int redirect_stdout;
if (!redirect_stdout)
NHMessageBox(GetNHApp()->hMainWnd,
NH_A2W(str, wbuf, sizeof(wbuf)),
MB_ICONINFORMATION | MB_OK);
mswin_raw_print_accumulate(str, FALSE);
else
fprintf(stdout, "%s", str);
}
@@ -1326,11 +1360,14 @@ possible).
void
mswin_raw_print_bold(const char *str)
{
TCHAR wbuf[255];
logDebug("mswin_raw_print_bold(%s)\n", str);
if (str && *str)
NHMessageBox(GetNHApp()->hMainWnd, NH_A2W(str, wbuf, sizeof(wbuf)),
MB_ICONINFORMATION | MB_OK);
if (str && *str) {
extern int redirect_stdout;
if (!redirect_stdout)
mswin_raw_print_accumulate(str, TRUE);
else
fprintf(stdout, "%s", str);
}
}
/*

View File

@@ -164,6 +164,7 @@ void mswin_cliparound(int x, int y);
void mswin_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph);
void mswin_raw_print(const char *str);
void mswin_raw_print_bold(const char *str);
void mswin_raw_print_flush();
int mswin_nhgetch(void);
int mswin_nh_poskey(int *x, int *y, int *mod);
void mswin_nhbell(void);