empserver/src/lib/subs/pr.c

339 lines
6.6 KiB
C

/*
* Empire - A multi-player, client/server Internet based war game.
* Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---
*
* See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
* related information and legal notices. It is expected that any future
* projects/authors will amend these files as needed.
*
* ---
*
* pr.c: Use to do output to a player
*
* Known contributors to this file:
* Dave Pare, 1986, 1989
* Steve McClure, 1998-2000
*/
/*
* The pr routine historically arranged for nonbuffered i/o
* because stdio didn't used to automatically flush stdout before
* it read something from stdin. Now pr() prepends an "output id"
* in front of each line of text, informing the user interface
* what sort of item it is seeing; prompt, noecho prompt,
* more input data, etc.
*/
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#include <stdarg.h>
#include "proto.h"
#include "misc.h"
#include "player.h"
#include "nat.h"
#include "empio.h"
#include "file.h"
#include "com.h"
#include "news.h"
#include "tel.h"
extern int update_pending;
#include "prototypes.h"
static void outid(struct player *pl, int n);
/*VARARGS*/
void
pr(s_char *format, ...)
{
s_char buf[4096];
va_list ap;
va_start(ap, format);
(void)vsprintf(buf, format, ap);
va_end(ap);
pr_player(player, C_DATA, buf);
}
void
prnf(s_char *buf)
{
pr_player(player, C_DATA, buf);
}
/*VARARGS*/
void
pr_id(struct player *p, int id, s_char *format, ...)
{
s_char buf[4096];
va_list ap;
if (p->curid >= 0) {
io_puts(p->iop, "\n");
p->curid = -1;
}
va_start(ap, format);
(void)vsprintf(buf, format, ap);
va_end(ap);
pr_player(p, id, buf);
}
void
pr_flash(struct player *pl, s_char *format, ...)
{
s_char buf[4096];
va_list ap;
if (pl->state != PS_PLAYING)
return;
va_start(ap, format);
(void)vsprintf(buf, format, ap);
va_end(ap);
pr_player(pl, C_FLASH, buf);
io_output(pl->iop, IO_NOWAIT);
}
void
pr_inform(struct player *pl, s_char *format, ...)
{
s_char buf[4096];
va_list ap;
if (pl->state != PS_PLAYING)
return;
va_start(ap, format);
(void)vsprintf(buf, format, ap);
va_end(ap);
pr_player(pl, C_INFORM, buf);
io_output(pl->iop, IO_NOWAIT);
}
void
pr_wall(s_char *format, ...)
{
s_char buf[4096];
struct player *p;
va_list ap;
va_start(ap, format);
(void)vsprintf(buf, format, ap);
va_end(ap);
for (p = player_next(0); p; p = player_next(p)) {
if (p->state != PS_PLAYING)
continue;
pr_player(p, C_FLASH, buf);
io_output(p->iop, IO_NOWAIT);
}
}
void
pr_player(struct player *pl, int id, s_char *buf)
{
register s_char *p;
register s_char *bp;
register int len;
bp = buf;
while (*bp != '\0') {
if (pl->curid != -1 && pl->curid != id) {
io_puts(pl->iop, "\n");
pl->curid = -1;
}
if (pl->curid == -1) {
outid(pl, id);
}
p = strchr(bp, '\n');
if (p != 0) {
len = (p - bp) + 1;
if (pl->command && (pl->command->c_flags & C_MOD))
io_write(pl->iop, bp, len, IO_NOWAIT);
else
io_write(pl->iop, bp, len, IO_WAIT);
bp += len;
pl->curid = -1;
} else {
len = io_puts(pl->iop, bp);
bp += len;
}
}
}
/*
* highlighted characters have hex 80 or'ed in
* with them to designate their highlightedness
*/
void
pr_hilite(s_char *buf)
{
register s_char *bp;
register s_char c;
s_char *p;
p = (s_char *)malloc(strlen(buf) + 1);
strcpy(p, buf);
for (bp = p; 0 != (c = *bp); bp++)
if (isprint(c))
*bp |= 0x80;
pr(p);
free(p);
}
/*
* output hex code + space
*/
static void
outid(struct player *pl, int n)
{
s_char c;
s_char buf[3];
if (n > C_LAST) {
logerror("outid: %d not valid code\n", n);
return;
}
if (n >= 10)
c = 'a' - 10 + n;
else
c = '0' + n;
buf[0] = c;
buf[1] = ' ';
buf[2] = '\0';
io_puts(pl->iop, buf);
pl->curid = n;
}
void
prredir(s_char *redir)
{
pr_id(player, *redir == '>' ? C_REDIR : C_PIPE, "%s\n", redir);
}
void
prexec(s_char *file)
{
pr_id(player, C_EXECUTE, "%s\n", file);
}
void
prprompt(int min, int btu)
{
pr_id(player, C_PROMPT, "%d %d\n", min, btu);
}
void
showvers(int vers)
{
pr_id(player, C_INIT, "%d\n", vers);
}
int
prmptrd(s_char *prompt, s_char *str, int size)
{
int r;
pr_id(player, C_FLUSH, "%s\n", prompt);
if ((r = recvclient(str, size)) < 0)
return r;
time(&player->curup);
if (*str == 0)
return 1;
return strlen(str);
}
void
prdate(void)
{
time_t now;
(void)time(&now);
pr(ctime(&now));
}
/*
* print x,y formatting as country
*/
void
prxy(s_char *format, coord x, coord y, natid country)
{
s_char buf[255];
struct natstr *np;
np = getnatp(country);
sprintf(buf, format, xrel(np, x), yrel(np, y));
pr(buf);
}
/*VARARGS*/
void
PR(int cn, s_char *format, ...)
{
/* XXX should really do this on a per-nation basis */
static s_char longline[MAXNOC][512];
int newline;
va_list ap;
s_char buf[1024];
va_start(ap, format);
(void)vsprintf(buf, format, ap);
va_end(ap);
newline = strrchr(buf, '\n') ? 1 : 0;
strcat(longline[cn], buf);
if (newline) {
if (update_pending || (cn && cn != player->cnum))
typed_wu(0, cn, longline[cn], TEL_BULLETIN);
else
pr_player(player, C_DATA, longline[cn]);
longline[cn][0] = '\0';
}
}
void
PRdate(natid cn)
{
time_t now;
(void)time(&now);
PR(cn, ctime(&now));
}
void
pr_beep(void)
{
struct natstr *np = getnatp(player->cnum);
if (np->nat_flags & NF_BEEP)
pr("\07");
}
void
mpr(int cn, s_char *format, ...)
{
s_char buf[4096];
va_list ap;
va_start(ap, format);
(void)vsprintf(buf, format, ap);
va_end(ap);
if (cn) {
if (update_pending || cn != player->cnum)
typed_wu(0, cn, buf, TEL_BULLETIN);
else
pr_player(player, C_DATA, buf);
}
}