summaryrefslogtreecommitdiff
path: root/src/messages.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/messages.cc')
-rw-r--r--src/messages.cc377
1 files changed, 31 insertions, 346 deletions
diff --git a/src/messages.cc b/src/messages.cc
index a4ce949d..071dc66e 100644
--- a/src/messages.cc
+++ b/src/messages.cc
@@ -1,368 +1,53 @@
#include "messages.hpp"
-#include "tome/make_array.hpp"
+#include "game.hpp"
-#include "z-term.h"
-#include "z-form.h"
-#include "z-util.h"
+#include <fmt/format.h>
+#include <string>
-/*
- * OPTION: Maximum number of messages to remember (see "io.c")
- * Default: assume maximal memorization of 2048 total messages
- */
-#define MESSAGE_MAX 2048
-
-/*
- * OPTION: Maximum space for the message text buffer (see "io.c")
- * Default: assume that each of the 2048 messages is repeated an
- * average of three times, and has an average length of 48
- */
-#define MESSAGE_BUF 32768
-
-
-
-
-/*
- * The next "free" index to use
- */
-static u16b message__next;
-
-/*
- * The index of the oldest message (none yet)
- */
-static u16b message__last;
-
-/*
- * The next "free" offset
- */
-static u16b message__head;
-
-/*
- * The offset to the oldest used char (none yet)
- */
-static u16b message__tail;
-
-/*
- * The array of offsets, by index [MESSAGE_MAX]
- */
-static u16b *message__ptr;
-
-/*
- * The array of colors, by index [MESSAGE_MAX]
- */
-static byte *message__color;
-
-/*
- * The array of message counts, by index [MESSAGE_MAX]
- */
-static u16b *message__count;
-
-/*
- * The array of chars, by offset [MESSAGE_BUF]
- */
-static char *message__buf;
-
-
-/*
-* Second try for the "message" handling routines.
-*
-* Each call to "message_add(s)" will add a new "most recent" message
-* to the "message recall list", using the contents of the string "s".
-*
-* The messages will be stored in such a way as to maximize "efficiency",
-* that is, we attempt to maximize the number of sequential messages that
-* can be retrieved, given a limited amount of storage space.
-*
-* We keep a buffer of chars to hold the "text" of the messages, not
-* necessarily in "order", and an array of offsets into that buffer,
-* representing the actual messages. This is made more complicated
-* by the fact that both the array of indexes, and the buffer itself,
-* are both treated as "circular arrays" for efficiency purposes, but
-* the strings may not be "broken" across the ends of the array.
-*
-* The "message_add()" function is rather "complex", because it must be
-* extremely efficient, both in space and time, for use with the Borg.
-*/
-
-void message_init()
+s16b Messages::size() const
{
- /* Message variables */
- message__ptr = make_array<u16b>(MESSAGE_MAX);
- message__color = make_array<byte>(MESSAGE_MAX);
- message__count = make_array<u16b>(MESSAGE_MAX);
- message__buf = make_array<char>(MESSAGE_BUF);
-
- /* Hack -- No messages yet */
- message__tail = MESSAGE_BUF;
+ return buffer.size();
}
-/*
-* How many messages are "available"?
-*/
-s16b message_num(void)
+message const &Messages::at(int age) const
{
- int last, next, n;
-
- /* Extract the indexes */
- last = message__last;
- next = message__next;
+ assert(age >= 0);
+ assert(age < size());
- /* Handle "wrap" */
- if (next < last) next += MESSAGE_MAX;
+ // Age indexes backward through history and is zero-based, so...
+ std::size_t i = buffer.size() - 1 - age;
- /* Extract the space */
- n = (next - last);
-
- /* Return the result */
- return (n);
+ // Get the message
+ return buffer.at(i);
}
-
-
-/*
-* Recall the "text" of a saved message
-*/
-cptr message_str(int age)
+void Messages::add(cptr msg, byte color)
{
- static char buf[1024];
- s16b x;
- s16b o;
- cptr s;
-
- /* Forgotten messages have no text */
- if ((age < 0) || (age >= message_num())) return ("");
-
- /* Acquire the "logical" index */
- x = (message__next + MESSAGE_MAX - (age + 1)) % MESSAGE_MAX;
-
- /* Get the "offset" for the message */
- o = message__ptr[x];
-
- /* Access the message text */
- s = &message__buf[o];
-
- /* Hack -- Handle repeated messages */
- if (message__count[x] > 1)
- {
- strnfmt(buf, 1024, "%s <%dx>", s, message__count[x]);
- s = buf;
- }
-
- /* Return the message text */
- return (s);
+ assert(msg != nullptr);
+ add(std::string(msg), color);
}
-/*
-* Recall the color of a saved message
-*/
-byte message_color(int age)
+void Messages::add(std::string const &msg, byte color)
{
- s16b x;
- byte color = TERM_WHITE;
-
- /* Forgotten messages have no text */
- if ((age < 0) || (age >= message_num())) return (TERM_WHITE);
-
- /* Acquire the "logical" index */
- x = (message__next + MESSAGE_MAX - (age + 1)) % MESSAGE_MAX;
-
- /* Get the "offset" for the message */
- color = message__color[x];
-
- /* Return the message text */
- return (color);
-}
-
-
-/*
-* Add a new message, with great efficiency
-*/
-void message_add(cptr str, byte color)
-{
- int i, k, x, n;
- cptr s;
-
-
- /*** Step 1 -- Analyze the message ***/
-
- /* Hack -- Ignore "non-messages" */
- if (!str) return;
-
- /* Message length */
- n = strlen(str);
-
- /* Important Hack -- Ignore "long" messages */
- if (n >= MESSAGE_BUF / 4) return;
-
-
- /*** Step 2 -- Handle repeated messages ***/
-
- /* Acquire the "logical" last index */
- x = (message__next + MESSAGE_MAX - 1) % MESSAGE_MAX;
-
- /* Get the last message text */
- s = &message__buf[message__ptr[x]];
-
- /* Last message repeated? */
- if (streq(str, s))
+ // If the message is the same as the last message,
+ // we just increment the counter instead of adding
+ // the message.
+ if ((!buffer.empty()) && (buffer.back().text == msg))
{
- /* Increase the message count */
- message__count[x]++;
-
- /* Success */
+ buffer.back().count += 1;
return;
}
+ // Push onto the end of the buffer.
+ message message;
+ message.color = color;
+ message.count = 1;
+ message.text = msg;
+ buffer.push_back(message);
+}
- /*** Step 3 -- Attempt to optimize ***/
-
- /* Limit number of messages to check */
- k = message_num() / 4;
-
- /* Limit number of messages to check */
- if (k > MESSAGE_MAX / 32) k = MESSAGE_MAX / 32;
-
- /* Check the last few messages (if any to count) */
- for (i = message__next; k; k--)
- {
- u16b q;
-
- cptr old;
-
- /* Back up and wrap if needed */
- if (i-- == 0) i = MESSAGE_MAX - 1;
-
- /* Stop before oldest message */
- if (i == message__last) break;
-
- /* Extract "distance" from "head" */
- q = (message__head + MESSAGE_BUF - message__ptr[i]) % MESSAGE_BUF;
-
- /* Do not optimize over large distance */
- if (q > MESSAGE_BUF / 2) continue;
-
- /* Access the old string */
- old = &message__buf[message__ptr[i]];
-
- /* Compare */
- if (!streq(old, str)) continue;
-
- /* Get the next message index, advance */
- x = message__next++;
-
- /* Handle wrap */
- if (message__next == MESSAGE_MAX) message__next = 0;
-
- /* Kill last message if needed */
- if (message__next == message__last) message__last++;
-
- /* Handle wrap */
- if (message__last == MESSAGE_MAX) message__last = 0;
-
- /* Assign the starting address */
- message__ptr[x] = message__ptr[i];
- message__color[x] = color;
- message__count[x] = 1;
-
- /* Success */
- return;
- }
-
-
- /*** Step 4 -- Ensure space before end of buffer ***/
-
- /* Kill messages and Wrap if needed */
- if (message__head + n + 1 >= MESSAGE_BUF)
- {
- /* Kill all "dead" messages */
- for (i = message__last; TRUE; i++)
- {
- /* Wrap if needed */
- if (i == MESSAGE_MAX) i = 0;
-
- /* Stop before the new message */
- if (i == message__next) break;
-
- /* Kill "dead" messages */
- if (message__ptr[i] >= message__head)
- {
- /* Track oldest message */
- message__last = i + 1;
- }
- }
-
- /* Wrap "tail" if needed */
- if (message__tail >= message__head) message__tail = 0;
-
- /* Start over */
- message__head = 0;
- }
-
-
- /*** Step 5 -- Ensure space before next message ***/
-
- /* Kill messages if needed */
- if (message__head + n + 1 > message__tail)
- {
- /* Grab new "tail" */
- message__tail = message__head + n + 1;
-
- /* Advance tail while possible past first "nul" */
- while (message__buf[message__tail - 1]) message__tail++;
-
- /* Kill all "dead" messages */
- for (i = message__last; TRUE; i++)
- {
- /* Wrap if needed */
- if (i == MESSAGE_MAX) i = 0;
-
- /* Stop before the new message */
- if (i == message__next) break;
-
- /* Kill "dead" messages */
- if ((message__ptr[i] >= message__head) &&
- (message__ptr[i] < message__tail))
- {
- /* Track oldest message */
- message__last = i + 1;
- }
- }
- }
-
-
- /*** Step 6 -- Grab a new message index ***/
-
- /* Get the next message index, advance */
- x = message__next++;
-
- /* Handle wrap */
- if (message__next == MESSAGE_MAX) message__next = 0;
-
- /* Kill last message if needed */
- if (message__next == message__last) message__last++;
-
- /* Handle wrap */
- if (message__last == MESSAGE_MAX) message__last = 0;
-
-
-
- /*** Step 7 -- Insert the message text ***/
-
- /* Assign the starting address */
- message__ptr[x] = message__head;
- message__color[x] = color;
- message__count[x] = 1;
-
- /* Append the new part of the message */
- for (i = 0; i < n; i++)
- {
- /* Copy the message */
- message__buf[message__head + i] = str[i];
- }
-
- /* Terminate */
- message__buf[message__head + i] = '\0';
-
- /* Advance the "head" pointer */
- message__head += n + 1;
+void Messages::add(message const &m)
+{
+ buffer.push_back(m);
}