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:
committed by
Pasi Kallinen
parent
b02dae91a1
commit
a588541a27
@@ -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 ### */
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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*/
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -546,6 +546,8 @@ msexit()
|
||||
getreturn("to end");
|
||||
synch_cursor();
|
||||
#endif
|
||||
getreturn_enabled = TRUE;
|
||||
wait_synch();
|
||||
return;
|
||||
}
|
||||
#endif /* MICRO || WIN32 || OS2 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user