/* valid macros:
* name - player's name
* lap - laps completed so far
* chkpt - last checkpoint crossed
* rank - position in the race, 0 if still racing
* time - time in seconds since the race started (#.##) */
/* returns a pointer to the end of dest */
local inline char *append_string(char *dest, const char *src)
{
while(*src) *dest++ = *src++;
return dest;
}
/* returns a pointer to the end of dest */
local inline char *append_integer(char *dest, int num)
{
char buf[11], *p = buf;
snprintf(buf, 11, "%d", num);
while(*p) *dest++ = *p++;
return dest;
}
/* returns a pointer to the end of dest */
local inline char *append_double(char *dest, double num)
{
char buf[11], *p = buf;
snprintf(buf, 11, "%.2f", num);
while(*p) *dest++ = *p++;
return dest;
}
/* p can be NULL. returns a %sound. */
local int expand_message(Arena *arena, Player *p, const char *format,
char *out, int outsize)
{
pdata *d = p ? PPDATA(p, pdkey) : NULL;
char *t = out;
int sound = 0;
/* keep looping until we run out of space or
* hit the end of the format string */
while(t - out < outsize && *format)
{
/* keep copying until we hit a % delimeter */
if (*format != '%')
*t++ = *format++;
else
{
const char *macro = ++format;
if (!strncmp(macro, "name", 4))
{
if (p)
{
t = append_string(t, p->name);
format += 4;
}
}
else if (!strncmp(macro, "lap", 3))
{
if (d)
{
t = append_integer(t, d->completedlaps);
format += 3;
}
}
else if (!strncmp(macro, "chkpt", 5))
{
if (d)
{
t = append_integer(t, d->nextchkpt);
format += 5;
}
}
else if (!strncmp(macro, "rank", 4))
{
if (d)
{
t = append_integer(t, d->rank);
format += 4;
}
}
else if (!strncmp(macro, "time", 4))
{
if (d)
{
t = append_double(t, (double)
(current_ticks() - d->start)
/ 100);
format += 4;
}
}
else
{
/* maybe it is a number (%bong) */
char *next;
int num = strtol(macro, &next, 0);
if (next != macro)
{
sound = num;
format = next;
}
}
}
}
*t = 0;
return sound;
}