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 boolean NDECL(friday_13th);
E int NDECL(night); E int NDECL(night);
E int NDECL(midnight); 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 ### */ /* ### invent.c ### */

View File

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

View File

@@ -61,6 +61,11 @@
boolean friday_13th (void) boolean friday_13th (void)
int night (void) int night (void)
int midnight (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 #ifdef LINT
#define Static /* pacify lint */ #define Static /* pacify lint */
@@ -183,7 +188,7 @@ char *
strip_newline(str) strip_newline(str)
char *str; char *str;
{ {
char *p = index(str, '\n'); char *p = rindex(str, '\n');
if (p) { if (p) {
if (p > str && *(p - 1) == '\r') if (p > str && *(p - 1) == '\r')
@@ -1101,4 +1106,69 @@ midnight()
return (getlt()->tm_hour == 0); 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*/ /*hacklib.c*/

View File

@@ -139,6 +139,15 @@ char *argv[];
/* use STDERR by default /* use STDERR by default
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
_CrtSetReportFile(_CRT_ASSERT, _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
#endif #endif

View File

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

View File

@@ -245,6 +245,25 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
data = (PNHMessageWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA); data = (PNHMessageWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
switch (wParam) { switch (wParam) {
case MSNH_MSG_PUTSTR: { 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; PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr) lParam;
SCROLLINFO si; SCROLLINFO si;
char *p; char *p;
@@ -271,10 +290,17 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
/* check for "--more--" */ /* check for "--more--" */
if (!data->nevermore && more_prompt_check(hWnd)) { if (!data->nevermore && more_prompt_check(hWnd)) {
int okkey = 0; int okkey = 0;
int chop; char tmptext[MAXWINDOWTEXT + 1];
// @@@ Ok respnses // @@@ 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( strncat(
data->window_text[MSG_LINES - 1].text, MORE, data->window_text[MSG_LINES - 1].text, MORE,
MAXWINDOWTEXT MAXWINDOWTEXT
@@ -301,10 +327,9 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
} }
} }
/* erase the "--more--" prompt */ /* restore original text */
chop = strlen(data->window_text[MSG_LINES - 1].text) strcpy(data->window_text[MSG_LINES - 1].text, tmptext);
- strlen(MORE);
data->window_text[MSG_LINES - 1].text[chop] = '\0';
data->lines_not_seen = 0; data->lines_not_seen = 0;
} }
@@ -601,6 +626,7 @@ onPaint(HWND hWnd)
- (client_rt.bottom - ps.rcPaint.bottom) / data->yChar); - (client_rt.bottom - ps.rcPaint.bottom) / data->yChar);
y = min(ps.rcPaint.bottom, client_rt.bottom); y = min(ps.rcPaint.bottom, client_rt.bottom);
for (i = LastLine; i >= FirstLine; i--) { for (i = LastLine; i >= FirstLine; i--) {
char tmptext[MAXWINDOWTEXT + 1];
x = data->xChar * (2 - data->xPos); x = data->xChar * (2 - data->xPos);
draw_rt.left = x; draw_rt.left = x;
@@ -612,8 +638,10 @@ onPaint(HWND hWnd)
hdc, mswin_get_font(NHW_MESSAGE, data->window_text[i].attr, hdc, mswin_get_font(NHW_MESSAGE, data->window_text[i].attr,
hdc, FALSE)); hdc, FALSE));
/* convert to UNICODE */ /* convert to UNICODE stripping newline */
NH_A2W(data->window_text[i].text, wbuf, sizeof(wbuf)); strcpy(tmptext, data->window_text[i].text);
strip_newline(tmptext);
NH_A2W(tmptext, wbuf, sizeof(wbuf));
wlen = _tcslen(wbuf); wlen = _tcslen(wbuf);
setMsgTextColor(hdc, i < (MSG_LINES - data->lines_last_turn)); setMsgTextColor(hdc, i < (MSG_LINES - data->lines_last_turn));
#ifdef MSG_WRAP_TEXT #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) if (data->window_text[MSG_LINES - 1].attr != attr)
return FALSE; 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 */ /* check if the maximum string langth will be exceeded */
if (strlen(data->window_text[MSG_LINES - 1].text) + 2 if (strlen(data->window_text[MSG_LINES - 1].text) + 2
+ /* space characters */ + /* space characters */
@@ -772,10 +804,11 @@ can_append_text(HWND hWnd, int attr, const char *text)
>= MAXWINDOWTEXT) >= MAXWINDOWTEXT)
return FALSE; 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); strcpy(tmptext, data->window_text[MSG_LINES - 1].text);
strcat(tmptext, " "); strcat(tmptext, " ");
strcat(tmptext, text); strcat(tmptext, text);
strip_newline(tmptext);
strcat(tmptext, MORE); strcat(tmptext, MORE);
hdc = GetDC(hWnd); hdc = GetDC(hWnd);
@@ -836,6 +869,8 @@ more_prompt_check(HWND hWnd)
hdc, FALSE)); hdc, FALSE));
strcpy(tmptext, data->window_text[MSG_LINES - i - 1].text); strcpy(tmptext, data->window_text[MSG_LINES - i - 1].text);
strip_newline(tmptext);
if (i == 0) if (i == 0)
strcat(tmptext, MORE); strcat(tmptext, MORE);

View File

@@ -36,13 +36,9 @@ mswin_display_splash_window(BOOL show_ver)
RECT controlrt; RECT controlrt;
HWND hWnd; HWND hWnd;
int buttop; int buttop;
int strsize = 0; strbuf_t strbuf;
int bufsize = BUFSZ;
char *buf = malloc(bufsize);
if (buf == NULL) strbuf_init(&strbuf);
panic("out of memory");
buf[0] = '\0';
hWnd = CreateDialog(GetNHApp()->hApp, MAKEINTRESOURCE(IDD_SPLASH), hWnd = CreateDialog(GetNHApp()->hApp, MAKEINTRESOURCE(IDD_SPLASH),
GetNHApp()->hMainWnd, NHSplashWndProc); GetNHApp()->hMainWnd, NHSplashWndProc);
@@ -87,9 +83,9 @@ mswin_display_splash_window(BOOL show_ver)
clientrt.right - 2 * SPLASH_OFFSET_X, controlrt.bottom, TRUE); clientrt.right - 2 * SPLASH_OFFSET_X, controlrt.bottom, TRUE);
/* Fill the text control */ /* 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); COPYRIGHT_BANNER_B, COPYRIGHT_BANNER_C, COPYRIGHT_BANNER_D);
strsize = strlen(buf);
if (show_ver) { if (show_ver) {
/* Show complete version information */ /* Show complete version information */
@@ -98,43 +94,16 @@ mswin_display_splash_window(BOOL show_ver)
int verstrsize = 0; int verstrsize = 0;
getversionstring(verbuf); getversionstring(verbuf);
verstrsize = strlen(verbuf); strbuf_append(&strbuf, verbuf);
if (verstrsize + strlen("\r\n\r\n") + 1 < BUFSZ - 1) strbuf_append(&strbuf, "\n\n");
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);
/* Add compile options */ /* Add compile options */
f = dlb_fopen(OPTIONS_USED, RDTMODE); f = dlb_fopen(OPTIONS_USED, RDTMODE);
if (f) { if (f) {
char line[LLEN + 1]; char line[LLEN + 1];
while (dlb_fgets(line, LLEN, f)) { while (dlb_fgets(line, LLEN, f))
size_t len; strbuf_append(&strbuf, line);
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;
}
(void) dlb_fclose(f); (void) dlb_fclose(f);
} }
} else { } else {
@@ -147,32 +116,18 @@ mswin_display_splash_window(BOOL show_ver)
if (nf != NULL) { if (nf != NULL) {
char line[LLEN + 1]; char line[LLEN + 1];
while (fgets(line, LLEN, nf)) { while (fgets(line, LLEN, nf))
size_t len; strbuf_append(&strbuf, line);
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;
}
(void) fclose(nf); (void) fclose(nf);
} else { } 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); ShowWindow(hWnd, SW_SHOW);
while (IsWindow(hWnd) && GetMessage(&msg, NULL, 0, 0) != 0) { 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_bg_color = RGB(0, 0, 0);
COLORREF message_fg_color = RGB(0xFF, 0xFF, 0xFF); COLORREF message_fg_color = RGB(0xFF, 0xFF, 0xFF);
strbuf_t raw_print_strbuf = { 0 };
/* Interface definition, for windows.c */ /* Interface definition, for windows.c */
struct window_procs mswin_procs = { struct window_procs mswin_procs = {
"MSWIN", "MSWIN",
@@ -717,8 +719,7 @@ mswin_exit_nhwindows(const char *str)
/* Write Window settings to the registry */ /* Write Window settings to the registry */
mswin_write_reg(); mswin_write_reg();
while (max_brush)
DeleteObject(brush_table[--max_brush]);
} }
/* Prepare the window to be suspended. */ /* Prepare the window to be suspended. */
@@ -1238,6 +1239,7 @@ void
mswin_wait_synch() mswin_wait_synch()
{ {
logDebug("mswin_wait_synch()\n"); 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 raw_print(str) -- Print directly to a screen, or otherwise guarantee that
the user sees str. raw_print() appends a newline to str. 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 void
mswin_raw_print(const char *str) mswin_raw_print(const char *str)
{ {
TCHAR wbuf[255];
logDebug("mswin_raw_print(%s)\n", str); logDebug("mswin_raw_print(%s)\n", str);
if (str && *str) { if (str && *str) {
extern int redirect_stdout; extern int redirect_stdout;
if (!redirect_stdout) if (!redirect_stdout)
NHMessageBox(GetNHApp()->hMainWnd, mswin_raw_print_accumulate(str, FALSE);
NH_A2W(str, wbuf, sizeof(wbuf)),
MB_ICONINFORMATION | MB_OK);
else else
fprintf(stdout, "%s", str); fprintf(stdout, "%s", str);
} }
@@ -1326,11 +1360,14 @@ possible).
void void
mswin_raw_print_bold(const char *str) mswin_raw_print_bold(const char *str)
{ {
TCHAR wbuf[255];
logDebug("mswin_raw_print_bold(%s)\n", str); logDebug("mswin_raw_print_bold(%s)\n", str);
if (str && *str) if (str && *str) {
NHMessageBox(GetNHApp()->hMainWnd, NH_A2W(str, wbuf, sizeof(wbuf)), extern int redirect_stdout;
MB_ICONINFORMATION | MB_OK); 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_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(const char *str);
void mswin_raw_print_bold(const char *str); void mswin_raw_print_bold(const char *str);
void mswin_raw_print_flush();
int mswin_nhgetch(void); int mswin_nhgetch(void);
int mswin_nh_poskey(int *x, int *y, int *mod); int mswin_nh_poskey(int *x, int *y, int *mod);
void mswin_nhbell(void); void mswin_nhbell(void);