if (tape.pausing || AllPlayersGone)
joy = 0;
- HandleGameActions(joy);
+ HandleGameActions((byte)joy);
break;
default:
#include "files.h"
#include "tape.h"
#include "joystick.h"
+#include "network.h"
void GetPlayerConfig()
{
}
}
-void PlayerActions(struct PlayerInfo *player, int player_action)
+void PlayerActions(struct PlayerInfo *player, byte player_action)
{
- static int stored_player_action[MAX_PLAYERS];
+ static byte stored_player_action[MAX_PLAYERS];
static int num_stored_actions = 0;
BOOL moved = FALSE, snapped = FALSE, bombed = FALSE;
int jx = player->jx, jy = player->jy;
}
}
-void GameActions(int player_action)
+void GameActions(byte player_action)
{
static long action_delay = 0;
long action_delay_value;
else
recorded_player_action = NULL;
+ SendToServer_MovePlayer(player_action);
+
for(i=0; i<MAX_PLAYERS; i++)
{
int actual_player_action = player_action;
void EdelsteinFunkeln(int, int);
void MauerWaechst(int, int);
void MauerAbleger(int, int);
-void GameActions(int);
+void GameActions(byte);
void ScrollLevel(int, int);
BOOL MoveFigureOneStep(struct PlayerInfo *, int, int, int, int);
void InitServer()
{
- standalone = FALSE + TRUE;
+ standalone = FALSE;
+ networking = !standalone;
if (standalone)
return;
if (!ConnectToServer(server_host, server_port))
Error(ERR_EXIT, "cannot connect to multiplayer server");
- SendNicknameToServer(local_player->alias_name);
- SendProtocolVersionToServer();
+ SendToServer_Nickname(local_player->alias_name);
+ SendToServer_ProtocolVersion();
}
void InitSound()
#endif /* #ifndef MSDOS */
typedef int BOOL;
+typedef unsigned char byte;
#ifndef FALSE
#define FALSE 0
BOOL changed;
struct
{
- unsigned char joystickdata[MAX_PLAYERS];
- unsigned char delay;
+ byte joystickdata[MAX_PLAYERS];
+ byte delay;
} pos[MAX_TAPELEN];
};
break;
if (option_len >= MAX_OPTION_LEN)
- Error(ERR_EXITHELP, "unrecognized option '%s'", option);
+ Error(ERR_EXIT_HELP, "unrecognized option '%s'", option);
if (strncmp(option, "--", 2) == 0) /* treat '--' like '-' */
option++;
{
*option_arg++ = '\0'; /* cut argument from option */
if (*option_arg == '\0') /* no argument after '=' */
- Error(ERR_EXITHELP, "option '%s' has invalid argument", option_str);
+ Error(ERR_EXIT_HELP, "option '%s' has invalid argument", option_str);
}
option_len = strlen(option);
if (strcmp(option, "-") == 0)
- Error(ERR_EXITHELP, "unrecognized option '%s'", option);
+ Error(ERR_EXIT_HELP, "unrecognized option '%s'", option);
else if (strncmp(option, "-help", option_len) == 0)
{
printf("Usage: %s [options] [server.name [port]]\n"
else if (strncmp(option, "-display", option_len) == 0)
{
if (option_arg == NULL)
- Error(ERR_EXITHELP, "option '%s' requires an argument", option_str);
+ Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str);
display_name = option_arg;
if (option_arg == next_option)
else if (strncmp(option, "-levels", option_len) == 0)
{
if (option_arg == NULL)
- Error(ERR_EXITHELP, "option '%s' requires an argument", option_str);
+ Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str);
level_directory = option_arg;
if (option_arg == next_option)
verbose = TRUE;
}
else if (*option == '-')
- Error(ERR_EXITHELP, "unrecognized option '%s'", option_str);
+ Error(ERR_EXIT_HELP, "unrecognized option '%s'", option_str);
else if (server_host == NULL)
{
server_host = *options_left;
{
server_port = atoi(*options_left);
if (server_port < 1024)
- Error(ERR_EXITHELP, "bad port number '%d'", server_port);
+ Error(ERR_EXIT_HELP, "bad port number '%d'", server_port);
printf("port == %d\n", server_port);
}
else
- Error(ERR_EXITHELP, "too many arguments");
+ Error(ERR_EXIT_HELP, "too many arguments");
options_left++;
}
void Error(int mode, char *format_str, ...)
{
FILE *output_stream = stderr;
+ char *process_name = "";
+
+ if (mode == ERR_EXIT_SOUNDSERVER)
+ process_name = " sound server";
if (format_str)
{
int i_value;
double d_value;
- fprintf(output_stream, "%s: ", program_name);
+ fprintf(output_stream, "%s%s: ", program_name, process_name);
va_start(ap, format_str); /* ap points to first unnamed argument */
break;
default:
- fprintf(stderr, "\nError(): invalid format string: %s\n",format_str);
+ fprintf(stderr, "\n%s: Error(): invalid format string: %s\n",
+ program_name, format_str);
CloseAllAndExit(10);
}
}
fprintf(output_stream, "\n");
}
- if (mode == ERR_EXITHELP)
+ if (mode == ERR_EXIT_HELP)
fprintf(output_stream, "%s: Try option '--help' for more information.\n",
program_name);
- if (mode == ERR_EXIT || mode == ERR_EXITHELP)
+ if (mode != ERR_RETURN)
{
- fprintf(output_stream, "%s: aborting\n", program_name);
+ fprintf(output_stream, "%s%s: aborting\n", program_name, process_name);
CloseAllAndExit(1);
}
}
#define ERR_RETURN 0
#define ERR_EXIT 1
-#define ERR_EXITHELP 2
+#define ERR_EXIT_HELP 2
+#define ERR_EXIT_SOUNDSERVER 3
void InitCounter(void);
unsigned long Counter(void);
#include <errno.h>
#include "network.h"
+#include "game.h"
+#include "tape.h"
+#include "files.h"
+#include "misc.h"
int norestart = 0;
int nospeedup = 0;
#define OP_NICK 1
#define OP_PLAY 2
-#define OP_FALL 3
+#define OP_MOVE 3
#define OP_DRAW 4
#define OP_LOST 5
#define OP_GONE 6
#define OP_WON 22
#define OP_ZERO 23
+#define MAXNICKLEN 14
+
+struct user
+{
+ byte nr;
+ char name[MAXNICKLEN+2];
+ struct user *next;
+};
+
+struct user me =
+{
+ 0,
+ "no name",
+ NULL
+};
+
/* server stuff */
#define BUFLEN 4096
exit(1);
}
+void *mmalloc(int n)
+{
+ void *r;
+
+ r = malloc(n);
+ if (r == NULL)
+ fatal("Out of memory");
+ return r;
+}
+
void u_sleep(int i)
{
struct timeval tm;
}
}
+struct user *finduser(unsigned char c)
+{
+ struct user *u;
+
+ for (u = &me; u; u = u->next)
+ if (u->nr == c)
+ return u;
+
+ fatal("Protocol error: reference to non-existing user");
+ return NULL; /* so that gcc -Wall doesn't complain */
+}
+
+char *get_user_name(unsigned char c)
+{
+ struct user *u;
+
+ if (c == 0)
+ return("the server");
+ else if (c == me.nr)
+ return("you");
+ else
+ for (u = &me; u; u = u->next)
+ if (u->nr == c && u->name && strlen(u->name))
+ return(u->name);
+
+ return("no name");
+}
+
void startserver()
{
char *options[2];
return(TRUE);
}
-void SendNicknameToServer(char *nickname)
+void SendToServer_Nickname(char *nickname)
{
static char msgbuf[300];
sysmsg(msgbuf);
}
-void SendProtocolVersionToServer()
+void SendToServer_ProtocolVersion()
{
buf[1] = OP_VERSION;
buf[2] = PROT_VERS_1;
sendbuf(5);
}
+void SendToServer_StartPlaying()
+{
+ buf[1] = OP_PLAY;
+ buf[2] = (unsigned char)(level_nr / 256);
+ buf[3] = (unsigned char)(level_nr % 256);
+ buf[4] = (unsigned char)(leveldir_nr / 256);
+ buf[5] = (unsigned char)(leveldir_nr % 256);
+ strcpy(&buf[6], leveldir[leveldir_nr].name);
+ sendbuf(strlen(leveldir[leveldir_nr].name)+1 + 6);
+}
+
+void SendToServer_MovePlayer(byte player_action)
+{
+ buf[1] = OP_MOVE;
+ buf[2] = player_action;
+ sendbuf(3);
+}
+
void handlemessages()
{
unsigned int len;
+ struct user *u, *v = NULL;
static char msgbuf[300];
while (nread >= 4 && nread >= 4 + readbuf[3])
{
case OP_YOUARE:
printf("OP_YOUARE: %d\n", buf[0]);
+ me.nr = buf[0];
+
+ TestPlayer = buf[0] - 1;
+
break;
case OP_NEW:
printf("OP_NEW: %d\n", buf[0]);
sprintf(msgbuf, "new client %d connected", buf[0]);
sysmsg(msgbuf);
+
+ for (u = &me; u; u = u->next)
+ {
+ if (u->nr == buf[0])
+ Error(ERR_EXIT, "multiplayer server sent duplicate player id");
+ else
+ v = u;
+ }
+
+ v->next = u = mmalloc(sizeof(struct user));
+ u->nr = buf[0];
+ u->name[0] = '\0';
+ u->next = NULL;
+
+ break;
+
+ case OP_NICK:
+ printf("OP_NICK: %d\n", buf[0]);
+ u = finduser(buf[0]);
+ buf[len] = 0;
+ sprintf(msgbuf, "client %d calls itself \"%s\"", buf[0], &buf[2]);
+ sysmsg(msgbuf);
+ strncpy(u->name, &buf[2], MAXNICKLEN);
break;
case OP_GONE:
printf("OP_GONE: %d\n", buf[0]);
- sprintf(msgbuf, "client %d disconnected", buf[0]);
+ u = finduser(buf[0]);
+ sprintf(msgbuf, "client %d (%s) disconnected",
+ buf[0], get_user_name(buf[0]));
sysmsg(msgbuf);
+
+ for (v = &me; v; v = v->next)
+ if (v->next == u)
+ v->next = u->next;
+ free(u);
+
break;
case OP_BADVERS:
- {
- static char tmpbuf[128];
-
- sprintf(tmpbuf, "Protocol version mismatch: server expects %d.%d.x instead of %d.%d.%d\n", buf[2], buf[3], PROT_VERS_1, PROT_VERS_2, PROT_VERS_3);
- fatal(tmpbuf);
- }
+ Error(ERR_RETURN, "protocol version mismatch");
+ Error(ERR_EXIT, "server expects %d.%d.x instead of %d.%d.%d",
+ buf[2], buf[3], PROT_VERS_1, PROT_VERS_2, PROT_VERS_3);
break;
-
+
case OP_PLAY:
printf("OP_PLAY: %d\n", buf[0]);
- sprintf(msgbuf, "client %d starts game", buf[0]);
+ sprintf(msgbuf, "client %d starts game [level %d from levedir %d (%s)]\n",
+ buf[0],
+ (buf[2] << 8) + buf[3],
+ (buf[4] << 8) + buf[5],
+ &buf[6]);
sysmsg(msgbuf);
+
+ if (strcmp(leveldir[(buf[4] << 8) + buf[5]].name, &buf[6]) == 0)
+ {
+ leveldir_nr = (buf[4] << 8) + buf[5];
+
+ local_player->leveldir_nr = leveldir_nr;
+ LoadPlayerInfo(PLAYER_LEVEL);
+ SavePlayerInfo(PLAYER_SETUP);
+
+ level_nr = (buf[2] << 8) + buf[3];
+
+ TapeErase();
+ LoadLevelTape(level_nr);
+
+ GetPlayerConfig();
+ LoadLevel(level_nr);
+
+ {
+ if (autorecord_on)
+ TapeStartRecording();
+
+ game_status = PLAYING;
+ InitGame();
+ }
+ }
+ else
+ {
+ Error(ERR_RETURN, "no such level directory: '%s'", &buf[6]);
+ }
+ break;
+
+ case OP_MOVE:
+ if (buf[2])
+ {
+ printf("OP_MOVE: %d\n", buf[0]);
+ sprintf(msgbuf, "client %d moves player [0x%02x]", buf[0], buf[2]);
+ sysmsg(msgbuf);
+ }
break;
case OP_PAUSE:
sysmsg(msgbuf);
break;
- case OP_NICK:
- printf("OP_NICK: %d\n", buf[0]);
- sprintf(msgbuf, "client %d calls itself \"%s\"", buf[0], &buf[2]);
- sysmsg(msgbuf);
- break;
-
case OP_MSG:
printf("OP_MSG: %d\n", buf[0]);
sprintf(msgbuf, "client %d sends message", buf[0]);
#include "main.h"
BOOL ConnectToServer(char *, int);
-void SendNicknameToServer(char *);
-void SendProtocolVersionToServer(void);
+void SendToServer_Nickname(char *);
+void SendToServer_ProtocolVersion(void);
+void SendToServer_StartPlaying(void);
+void SendToServer_MovePlayer(byte);
void HandleNetworking(void);
#endif
#include "tape.h"
#include "joystick.h"
#include "cartoons.h"
+#include "network.h"
#ifdef MSDOS
extern unsigned char get_ascii(KeySym);
}
else if (y==8)
{
- if (autorecord_on)
- TapeStartRecording();
+ if (standalone)
+ {
+ if (autorecord_on)
+ TapeStartRecording();
- game_status = PLAYING;
- InitGame();
+ game_status = PLAYING;
+ InitGame();
+ }
+ else
+ SendToServer_StartPlaying();
}
else if (y==9)
{
DrawSetupScreen();
}
-void HandleGameActions(int player_action)
+void HandleGameActions(byte player_action)
{
if (game_status != PLAYING)
return;
void DrawSetupScreen(void);
void HandleSetupScreen(int, int, int, int, int);
void CalibrateJoystick(void);
-void HandleGameActions(int);
+void HandleGameActions(byte);
void HandleVideoButtons(int, int, int);
void HandleSoundButtons(int, int, int);
void HandleGameButtons(int, int, int);
if (!FD_ISSET(sound_pipe[0], &sound_fdset))
continue;
if (read(sound_pipe[0], &snd_ctrl, sizeof(snd_ctrl)) != sizeof(snd_ctrl))
- Error(ERR_EXIT, "broken pipe - no sounds");
+ Error(ERR_EXIT_SOUNDSERVER, "broken pipe - no sounds");
#ifdef VOXWARE
audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
if (audio_ctl == -1)
- Error(ERR_EXIT, "cannot open /dev/audioCtl - no sounds");
+ Error(ERR_EXIT_SOUNDSERVER, "cannot open /dev/audioCtl - no sounds");
if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
- Error(ERR_EXIT, "no audio info - no sounds");
+ Error(ERR_EXIT_SOUNDSERVER, "no audio info - no sounds");
if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
- Error(ERR_EXIT, "ulaw audio not available - no sounds");
+ Error(ERR_EXIT_SOUNDSERVER, "ulaw audio not available - no sounds");
ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
DrawVideoDisplay(VIDEO_STATE_REC_OFF,0);
}
-void TapeRecordAction(int joy[MAX_PLAYERS])
+void TapeRecordAction(byte joy[MAX_PLAYERS])
{
int i;
void TapeStartRecording(void);
void TapeStopRecording(void);
-void TapeRecordAction(int *);
+void TapeRecordAction(byte *);
void TapeRecordDelay(void);
void TapeTogglePause(void);
void TapeStartPlaying(void);