From 2875a46833a615082120d19eac5c67b545593829 Mon Sep 17 00:00:00 2001 From: "nethack.allison" Date: Thu, 20 Feb 2003 10:51:40 +0000 Subject: [PATCH] Roll back the last-minute patch after found problems with it --- win/win32/mhmsgwnd.c | 329 +++++++++++++++++++++---------------------- 1 file changed, 159 insertions(+), 170 deletions(-) diff --git a/win/win32/mhmsgwnd.c b/win/win32/mhmsgwnd.c index 9bd004810..ad9c0250e 100644 --- a/win/win32/mhmsgwnd.c +++ b/win/win32/mhmsgwnd.c @@ -20,14 +20,21 @@ struct window_line { int attr; - char text[MAXWINDOWTEXT+1]; + char text[MAXWINDOWTEXT]; }; typedef struct mswin_nethack_message_window { size_t max_text; struct window_line window_text[MAX_MSG_LINES]; +#ifdef MSG_WRAP_TEXT + int window_text_lines[MAX_MSG_LINES]; /* How much space this text line takes */ +#endif int lines_last_turn; /* lines added during the last turn */ + int cleared; /* clear was called */ + int last_line; /* last line in the message history */ + struct window_line new_line; int lines_not_seen; /* lines not yet seen by user after last turn or --More-- */ + int in_more; /* We are in a --More-- prompt */ int nevermore; /* We want no more --More-- prompts */ int xChar; /* horizontal scrolling unit */ @@ -51,11 +58,6 @@ static void onMSNH_HScroll(HWND hWnd, WPARAM wParam, LPARAM lParam); static COLORREF setMsgTextColor(HDC hdc, int gray); static void onPaint(HWND hWnd); static void onCreate(HWND hWnd, WPARAM wParam, LPARAM lParam); -static BOOL can_append_text(HWND hWnd, int attr, const char* text ); - /* check if text can be appended to the last line without wrapping */ - -static BOOL more_prompt_check(HWND hWnd); - /* check if "--more--" promt needs to be displayed */ #ifdef USER_SOUNDS extern void play_sound_for_message(const char* str); @@ -213,41 +215,22 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) { PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr)lParam; SCROLLINFO si; - char* p; - BOOL check_more = FALSE; if( msg_data->append == 1) { /* Forcibly append to line, even if we pass the edge */ - strncat(data->window_text[MSG_LINES-1].text, msg_data->text, - MAXWINDOWTEXT - strlen(data->window_text[MSG_LINES-1].text)); + strncat(data->window_text[data->last_line].text, msg_data->text, + MAXWINDOWTEXT - strlen(data->window_text[data->last_line].text)); } else if( msg_data->append < 0) { /* remove that many chars */ - int len = strlen(data->window_text[MSG_LINES-1].text); + int len = strlen(data->window_text[data->last_line].text); int newend = max(len + msg_data->append, 0); - data->window_text[MSG_LINES-1].text[newend] = '\0'; + data->window_text[data->last_line].text[newend] = '\0'; } else { - if( can_append_text(hWnd, msg_data->attr, msg_data->text ) ) { - strncat(data->window_text[MSG_LINES-1].text, " ", MAXWINDOWTEXT-strlen(data->window_text[MSG_LINES-1].text)); - strncat(data->window_text[MSG_LINES-1].text, msg_data->text, MAXWINDOWTEXT-strlen(data->window_text[MSG_LINES-1].text)); - } else { - /* check if the string is empty */ - for(p = data->window_text[MSG_LINES-1].text; *p && isspace(*p); p++); - - if( *p ) { - /* last string is not empty - scroll up */ - memmove(&data->window_text[0], - &data->window_text[1], - (MSG_LINES-1)*sizeof(data->window_text[0])); - } - - /* append new text to the end of the array */ - data->window_text[MSG_LINES-1].attr = msg_data->attr; - strncpy(data->window_text[MSG_LINES-1].text, msg_data->text, MAXWINDOWTEXT); - - data->lines_not_seen++; - data->lines_last_turn++; - check_more = TRUE; - } + /* Try to append but move the whole message to the next line if + it doesn't fit */ + /* just schedule for displaying */ + data->new_line.attr = msg_data->attr; + strncpy(data->new_line.text, msg_data->text, MAXWINDOWTEXT); } /* reset V-scroll position to display new text */ @@ -259,43 +242,6 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) si.nPos = data->yPos; SetScrollInfo(hWnd, SB_VERT, &si, TRUE); - /* check for "--more--" */ - if( check_more && !data->nevermore && more_prompt_check(hWnd) ) { - int okkey = 0; - int chop; - // @@@ Ok respnses - - /* append more prompt and inticate the update */ - strncat(data->window_text[MSG_LINES-1].text, MORE, MAXWINDOWTEXT - strlen(data->window_text[MSG_LINES-1].text)); - InvalidateRect(hWnd, NULL, TRUE); - - /* get the input */ - while (!okkey) { - char c = mswin_nhgetch(); - - switch (c) - { - /* space or enter */ - case ' ': - case '\015': - okkey = 1; - break; - /* ESC */ - case '\033': - data->nevermore = 1; - okkey = 1; - break; - default: - break; - } - } - - /* erase the "--more--" prompt */ - chop = strlen(data->window_text[MSG_LINES-1].text) - strlen(MORE); - data->window_text[MSG_LINES-1].text[chop] = '\0'; - data->lines_not_seen = 0; - } - /* update window content */ InvalidateRect(hWnd, NULL, TRUE); @@ -307,8 +253,9 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) case MSNH_MSG_CLEAR_WINDOW: { - data->lines_last_turn = 0; + data->cleared = 1; data->lines_not_seen = 0; + /* do --More-- again if needed */ data->nevermore = 0; break; } @@ -533,6 +480,7 @@ void onPaint(HWND hWnd) LastLine = min (MSG_LINES-1, data->yPos - (client_rt.bottom - ps.rcPaint.bottom)/data->yChar); y = min( ps.rcPaint.bottom, client_rt.bottom ); for (i=LastLine; i>=FirstLine; i--) { + int lineidx = (data->last_line + 1 + i) % MSG_LINES; x = data->xChar * (2 - data->xPos); draw_rt.left = x; @@ -540,21 +488,120 @@ void onPaint(HWND hWnd) draw_rt.top = y - data->yChar; draw_rt.bottom = y; - oldFont = SelectObject(hdc, mswin_get_font(NHW_MESSAGE, data->window_text[i].attr, hdc, FALSE)); + oldFont = SelectObject(hdc, mswin_get_font(NHW_MESSAGE, data->window_text[lineidx].attr, hdc, FALSE)); + /* find out if we can concatenate the scheduled message without wrapping, + but only if no clear_nhwindow was done just before putstr'ing this one. + */ + if (i == MSG_LINES-1 + && strlen(data->new_line.text) > 0) { + /* concatenate to the previous line if that is not empty, and + if it has the same attribute, and no clear was done. + */ + if (strlen(data->window_text[lineidx].text) > 0 + && (data->window_text[lineidx].attr + == data->new_line.attr) + && !data->cleared) { + RECT tmpdraw_rt = draw_rt; + /* assume this will never work when textsize is near MAXWINDOWTEXT */ + char tmptext[MAXWINDOWTEXT]; + TCHAR tmpwbuf[MAXWINDOWTEXT+2]; + + strcpy(tmptext, data->window_text[lineidx].text); + strncat(tmptext, " ", + MAXWINDOWTEXT - strlen(tmptext)); + strncat(tmptext, data->new_line.text, + MAXWINDOWTEXT - strlen(tmptext)); + /* Always keep room for a --More-- */ + strncat(tmptext, MORE, + MAXWINDOWTEXT - strlen(tmptext)); + NH_A2W(tmptext, tmpwbuf, sizeof(tmpwbuf)); + /* Find out how large the bounding rectangle of the text is */ + DrawText(hdc, tmpwbuf, _tcslen(tmpwbuf), &tmpdraw_rt, DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT); + if ((tmpdraw_rt.bottom - tmpdraw_rt.top) == (draw_rt.bottom - draw_rt.top) /* fits pixelwise */ + && (strlen(data->window_text[lineidx].text) + + strlen(data->new_line.text) < MAXWINDOWTEXT)) /* fits charwise */ + { + /* strip off --More-- of this combined line and make it so */ + tmptext[strlen(tmptext) - strlen(MORE)] = '\0'; + strcpy(data->window_text[lineidx].text, tmptext); + data->new_line.text[0] = '\0'; + i++; /* Start from the last line again */ + continue; + } + } + if (strlen(data->new_line.text) > 0) { + /* if we get here, the new line was not concatenated. Add it on a new line, + but first check whether we should --More--. */ + RECT tmpdraw_rt = draw_rt; + TCHAR tmpwbuf[MAXWINDOWTEXT+2]; + HGDIOBJ oldFont; + int new_screen_lines; + int screen_lines_not_seen = 0; + /* Count how many screen lines we haven't seen yet. */ +#ifdef MSG_WRAP_TEXT + { + int n; + for (n = data->lines_not_seen - 1; n >= 0; n--) { + screen_lines_not_seen += + data->window_text_lines[(data->last_line - n + MSG_LINES) % MSG_LINES]; + } + } +#else + screen_lines_not_seen = data->lines_not_seen; +#endif + /* Now find out how many screen lines we would like to add */ + NH_A2W(data->new_line.text, tmpwbuf, sizeof(tmpwbuf)); + /* Find out how large the bounding rectangle of the text is */ + oldFont = SelectObject(hdc, mswin_get_font(NHW_MESSAGE, data->window_text[lineidx].attr, hdc, FALSE)); + DrawText(hdc, tmpwbuf, _tcslen(tmpwbuf), &tmpdraw_rt, DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT); + SelectObject(hdc, oldFont); + new_screen_lines = (tmpdraw_rt.bottom - tmpdraw_rt.top) / data->yChar; + /* If this together is more than fits on the window, we must + --More--, unless: + - We are in --More-- already (the user is scrolling the window) + - The user pressed ESC + */ + if (screen_lines_not_seen + new_screen_lines > MSG_VISIBLE_LINES + && !data->in_more && !data->nevermore) { + data->in_more = 1; + /* Show --More-- on last line */ + strcat(data->window_text[data->last_line].text, MORE); + /* Go on drawing, but remember we must do a more afterwards */ + do_more = 1; + } else if (!data->in_more) { + data->last_line++; + data->last_line %= MSG_LINES; + data->window_text[data->last_line].attr = data->new_line.attr; + strncpy(data->window_text[data->last_line].text, data->new_line.text, MAXWINDOWTEXT); + data->new_line.text[0] = '\0'; + if (data->cleared) { + /* now we are drawing a new line, the old lines can be redrawn in grey.*/ + data->lines_last_turn = 0; + data->cleared = 0; + } + data->lines_last_turn++; + data->lines_not_seen++; + /* and start over */ + i++; /* Start from the last line again */ + continue; + } + } + } /* convert to UNICODE */ - NH_A2W(data->window_text[i].text, wbuf, sizeof(wbuf)); + NH_A2W(data->window_text[lineidx].text, wbuf, sizeof(wbuf)); wlen = _tcslen(wbuf); setMsgTextColor(hdc, i < (MSG_LINES - data->lines_last_turn)); #ifdef MSG_WRAP_TEXT /* Find out how large the bounding rectangle of the text is */ DrawText(hdc, wbuf, wlen, &draw_rt, DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT); - /* move that rectangle up, so that the bottom remains at the same height */ + /* move that rectangle up, so that the bottom remains at the same height */ draw_rt.top = y - (draw_rt.bottom - draw_rt.top); draw_rt.bottom = y; - - /* Now really draw it */ - DrawText(hdc, wbuf, wlen, &draw_rt, DT_NOPREFIX | DT_WORDBREAK); + /* Remember the height of this line for subsequent --More--'s */ + data->window_text_lines[lineidx] = (draw_rt.bottom - draw_rt.top) / data->yChar; + /* Now really draw it */ + DrawText(hdc, wbuf, wlen, &draw_rt, DT_NOPREFIX | DT_WORDBREAK); /* Find out the cursor (caret) position */ if (i == MSG_LINES-1) { @@ -597,6 +644,39 @@ void onPaint(HWND hWnd) SelectObject(hdc, oldFont); y -= draw_rt.bottom - draw_rt.top; } + if (do_more) { + int okkey = 0; + int chop; + // @@@ Ok respnses + + while (!okkey) { + char c = mswin_nhgetch(); + + switch (c) + { + /* space or enter */ + case ' ': + case '\015': + okkey = 1; + break; + /* ESC */ + case '\033': + data->nevermore = 1; + okkey = 1; + break; + default: + break; + } + } + chop = strlen(data->window_text[data->last_line].text) + - strlen(MORE); + data->window_text[data->last_line].text[chop] = '\0'; + data->in_more = 0; + data->lines_not_seen = 0; + /* We did the --More--, reset the lines_not_seen; now draw that + new line. This is the easiest method */ + InvalidateRect(hWnd, NULL, TRUE); + } } SetTextColor (hdc, OldFg); SetBkColor (hdc, OldBg); @@ -656,95 +736,4 @@ void mswin_message_window_size (HWND hWnd, LPSIZE sz) GetClientRect(hWnd, &client_rt); sz->cy = sz->cy - (client_rt.bottom - client_rt.top) + data->yChar * MSG_VISIBLE_LINES; -} - -/* check if text can be appended to the last line without wrapping */ -BOOL can_append_text(HWND hWnd, int attr, const char* text ) -{ - PNHMessageWindow data; - char tmptext[MAXWINDOWTEXT+1]; - HDC hdc; - HGDIOBJ saveFont; - RECT draw_rt; - BOOL retval = FALSE; - - data = (PNHMessageWindow)GetWindowLong(hWnd, GWL_USERDATA); - - /* cannot append if lines_not_seen is 0 (beginning of the new turn */ - if( data->lines_not_seen==0 ) return FALSE; - - /* cannot append text with different attrbutes */ - if( data->window_text[MSG_LINES-1].attr != attr ) return FALSE; - - /* check if the maximum string langth will be exceeded */ - if( strlen(data->window_text[MSG_LINES-1].text)+ - 2 + /* space characters */ - strlen(text) + - strlen(MORE) >= MAXWINDOWTEXT ) return FALSE; - - /* check if the text is goinf to fin into a single line */ - strcpy(tmptext, data->window_text[MSG_LINES-1].text ); - strcat(tmptext, " " ); - strcat(tmptext, text ); - strcat(tmptext, MORE ); - - hdc = GetDC(hWnd); - saveFont = SelectObject(hdc, mswin_get_font(NHW_MESSAGE, data->window_text[MSG_LINES-1].attr, hdc, FALSE)); - GetClientRect(hWnd, &draw_rt); - draw_rt.bottom = draw_rt.top; /* we only need width for the DrawText */ - DrawText(hdc, tmptext, strlen(tmptext), &draw_rt, DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT); - - /* we will check against 1.5 of the font size in order to determine - if the text is single-line or not - just to be on the safe size */ - retval = (draw_rt.bottom-draw_rt.top)<(data->yChar+data->yChar/2); - - /* free device context */ - SelectObject(hdc, saveFont); - ReleaseDC (hWnd, hdc); - return retval; -} - -/* check if "--more--" promt needs to be displayed - basically, check if the lines not seen are going to find in the message window -*/ -BOOL more_prompt_check(HWND hWnd) -{ - PNHMessageWindow data; - HDC hdc; - HGDIOBJ saveFont; - RECT client_rt, draw_rt; - BOOL retval = FALSE; - int visible_lines = 0; - int i; - int remaining_height; - - data = (PNHMessageWindow)GetWindowLong(hWnd, GWL_USERDATA); - - if( data->lines_not_seen==0 ) return FALSE; /* don't bother checking - nothig to "more" */ - if( data->lines_not_seen>=MSG_LINES ) return TRUE; /* history size exceeded - always more */ - - GetClientRect(hWnd, &client_rt); - remaining_height = client_rt.bottom - client_rt.top; - - hdc = GetDC(hWnd); - saveFont = SelectObject(hdc, mswin_get_font(NHW_MESSAGE, ATR_NONE, hdc, FALSE)); - for( i=0; ilines_not_seen; i++ ) { - /* we only need width for the DrawText */ - SetRect(&draw_rt, client_rt.left, client_rt.top, client_rt.right, client_rt.top); - SelectObject(hdc, mswin_get_font(NHW_MESSAGE, data->window_text[MSG_LINES-i-1].attr, hdc, FALSE)); - remaining_height -= - DrawText( hdc, - data->window_text[MSG_LINES-i-1].text, - strlen(data->window_text[MSG_LINES-i-1].text), - &draw_rt, - DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT - ); - if( remaining_height<0 ) break; - } - - /* free device context */ - SelectObject(hdc, saveFont); - ReleaseDC (hWnd, hdc); - return (remaining_height<0); /* TRUE if lines_not_seen take more that window height */ -} - +} \ No newline at end of file -- 2.40.0