-/* I/O routines (SPEAK, PSPEAK, RSPEAK, SETPRM, GETIN, YES) */
-
-void newspeak(char* msg)
-{
- // Do nothing if we got a null pointer.
- if (msg == NULL)
- return;
-
- // Do nothing if we got an empty string.
- if (strlen(msg) == 0)
- return;
-
- // Print a newline if the global game.blklin says to.
- if (game.blklin == true)
- printf("\n");
-
- // Create a copy of our string, so we can edit it.
- char* copy = xstrdup(msg);
-
- // Staging area for stringified parameters.
- char parameters[5][100]; // FIXME: to be replaced with dynamic allocation
-
- // Handle format specifiers (including the custom %C, %L, %S) by adjusting the parameter accordingly, and replacing the specifier with %s.
- int pi = 0; // parameter index
- for (int i = 0; i < strlen(msg); ++i)
- {
- if (msg[i] == '%')
- {
- ++pi;
-
- // Integer specifier. In order to accommodate the fact that PARMS can have both legitimate integers *and* packed tokens, stringify everything. Future work may eliminate the need for this.
- if (msg[i + 1] == 'd')
- {
- copy[i + 1] = 's';
- sprintf(parameters[pi], "%ld", PARMS[pi]);
- }
-
- // Unmodified string specifier.
- if (msg[i + 1] == 's')
- {
- packed_to_token(PARMS[pi], parameters[pi]);
- }
-
- // Singular/plural specifier.
- if (msg[i + 1] == 'S')
- {
- copy[i + 1] = 's';
- if (PARMS[pi - 1] > 1) // look at the *previous* parameter (which by necessity must be numeric)
- {
- sprintf(parameters[pi], "%s", "s");
- }
- else
- {
- sprintf(parameters[pi], "%s", "");
- }
- }
-
- // All-lowercase specifier.
- if (msg[i + 1] == 'L')
- {
- copy[i + 1] = 's';
- packed_to_token(PARMS[pi], parameters[pi]);
- for (int i = 0; i < strlen(parameters[pi]); ++i)
- {
- parameters[pi][i] = tolower(parameters[pi][i]);
- }
- }
-
- // First char uppercase, rest lowercase.
- if (msg[i + 1] == 'C')
- {
- copy[i + 1] = 's';
- packed_to_token(PARMS[pi], parameters[pi]);
- for (int i = 0; i < strlen(parameters[pi]); ++i)
- {
- parameters[pi][i] = tolower(parameters[pi][i]);
- }
- parameters[pi][0] = toupper(parameters[pi][0]);
- }
- }
+long token_to_packed(const char token[6])
+{
+ const char ascii_to_advent[] = {
+ 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63,
+
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63,
+
+ 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63,
+ };
+
+ size_t t_len = strlen(token);
+ long packed = 0;
+ for (size_t i = 0; i < t_len; ++i) {
+ char mapped = ascii_to_advent[(int) token[i]];
+ packed |= (mapped << (6 * i));