/* * Output a message to the top line of the screen. * * Break long messages into multiple pieces (40-72 chars). * * Allow multiple short messages to "share" the top line. * * Prompt the user to make sure he has a chance to read them. * * These messages are memorized for later reference (see above). * * We could do a "Term_fresh()" to provide "flicker" if needed. * * The global "msg_flag" variable can be cleared to tell us to "erase" any * "pending" messages still on the screen, instead of using "msg_flush()". * This should only be done when the user is known to have read the message. * * We must be very careful about using the "msg("%s", )" functions without * explicitly calling the special "msg("%s", NULL)" function, since this may * result in the loss of information if the screen is cleared, or if anything * is displayed on the top line. * * Hack -- Note that "msg("%s", NULL)" will clear the top line even if no * messages are pending. */ static void msg_print_aux(u16b type, const char *msg) { int n; char *t; char buf[1024]; byte color; int w, h; if (!Term) return; /* Obtain the size */ (void)Term_get_size(&w, &h); /* Hack -- Reset */ if (!msg_flag) message_column = 0; /* Message Length */ n = (msg ? strlen(msg) : 0); /* Hack -- flush when requested or needed */ if (message_column && (!msg || ((message_column + n) > (w - 8)))) { /* Flush */ msg_flush(message_column); /* Forget it */ msg_flag = FALSE; /* Reset */ message_column = 0; } /* No message */ if (!msg) return; /* Paranoia */ if (n > 1000) return; /* Memorize the message (if legal) */ if (character_generated && !(p_ptr->is_dead)) message_add(msg, type); /* Window stuff */ p_ptr->redraw |= (PR_MESSAGE); /* Copy it */ my_strcpy(buf, msg, sizeof(buf)); /* Analyze the buffer */ t = buf; /* Get the color of the message */ color = message_type_color(type); /* Split message */ while (n > w - 1) { char oops; int check, split; /* Default split */ split = w - 8; /* Find the rightmost split point */ for (check = (w / 2); check < w - 8; check++) if (t[check] == ' ') split = check; /* Save the split character */ oops = t[split]; /* Split the message */ t[split] = '\0'; /* Display part of the message */ Term_putstr(0, 0, split, color, t); /* Flush it */ msg_flush(split + 1); /* Restore the split character */ t[split] = oops; /* Insert a space */ t[--split] = ' '; /* Prepare to recurse on the rest of "buf" */ t += split; n -= split; } /* Display the tail of the message */ Term_putstr(message_column, 0, n, color, t); /* Remember the message */ msg_flag = TRUE; /* Remember the position */ message_column += n + 1; /* Send refresh event */ event_signal(EVENT_MESSAGE); }
/** * Output a message to the top line of the screen. * * Break long messages into multiple pieces (40-72 chars). * * Allow multiple short messages to "share" the top line. * * Prompt the user to make sure he has a chance to read them. * * These messages are memorized for later reference (see above). * * We could do a "Term_fresh()" to provide "flicker" if needed. * * The global "msg_flag" variable can be cleared to tell us to "erase" any * "pending" messages still on the screen, instead of using "msg_flush()". * This should only be done when the user is known to have read the message. * * We must be very careful about using the "msg("%s", )" functions without * explicitly calling the special "msg("%s", NULL)" function, since this may * result in the loss of information if the screen is cleared, or if anything * is displayed on the top line. * * Hack -- Note that "msg("%s", NULL)" will clear the top line even if no * messages are pending. */ void display_message(game_event_type unused, game_event_data *data, void *user) { int n; char *t; char buf[1024]; byte color; int w, h; int type; const char *msg; if (!data) return; type = data->message.type; msg = data->message.msg; if (type == MSG_BELL || !msg || !Term || !character_generated) return; /* Obtain the size */ (void)Term_get_size(&w, &h); /* Hack -- Reset */ if (!msg_flag) message_column = 0; /* Message Length */ n = (msg ? strlen(msg) : 0); /* Hack -- flush when requested or needed */ if (message_column && (!msg || ((message_column + n) > (w - 8)))) { /* Flush */ msg_flush(message_column); /* Forget it */ msg_flag = false; /* Reset */ message_column = 0; } /* No message */ if (!msg) return; /* Paranoia */ if (n > 1000) return; /* Copy it */ my_strcpy(buf, msg, sizeof(buf)); /* Analyze the buffer */ t = buf; /* Get the color of the message */ color = message_type_color(type); /* Split message */ while (n > w - 1) { char oops; int check, split; /* Default split */ split = w - 8; /* Find the rightmost split point */ for (check = (w / 2); check < w - 8; check++) if (t[check] == ' ') split = check; /* Save the split character */ oops = t[split]; /* Split the message */ t[split] = '\0'; /* Display part of the message */ Term_putstr(0, 0, split, color, t); /* Flush it */ msg_flush(split + 1); /* Restore the split character */ t[split] = oops; /* Insert a space */ t[--split] = ' '; /* Prepare to recurse on the rest of "buf" */ t += split; n -= split; } /* Display the tail of the message */ Term_putstr(message_column, 0, n, color, t); /* Remember the message */ msg_flag = true; /* Remember the position */ message_column += n + 1; }