Add weapon cycling bindings for mouse and joystick buttons. Add weapon cycling bindi...
[chocolate-doom.git] / src / d_net.c
blobfaf478215bae16bfe39cda2e94b4105b66f6a2d6
1 // Emacs style mode select -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // Copyright(C) 1993-1996 Id Software, Inc.
5 // Copyright(C) 2005 Simon Howard
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 // 02111-1307, USA.
22 // DESCRIPTION:
23 // DOOM Network game communication and protocol,
24 // all OS independend parts.
26 //-----------------------------------------------------------------------------
30 #include "doomfeatures.h"
32 #include "d_main.h"
33 #include "m_argv.h"
34 #include "m_menu.h"
35 #include "i_system.h"
36 #include "i_timer.h"
37 #include "i_video.h"
38 #include "g_game.h"
39 #include "doomdef.h"
40 #include "doomstat.h"
42 #include "deh_main.h"
44 #include "net_client.h"
45 #include "net_gui.h"
46 #include "net_io.h"
47 #include "net_query.h"
48 #include "net_server.h"
49 #include "net_sdl.h"
50 #include "net_loop.h"
54 // NETWORKING
56 // gametic is the tic about to (or currently being) run
57 // maketic is the tick that hasn't had control made for it yet
58 // nettics[] has the maketics for all players
60 // a gametic cannot be run until nettics[] > gametic for all players
63 ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS];
64 int nettics[MAXPLAYERS];
66 int maketic;
68 // Used for original sync code.
70 int lastnettic;
71 int skiptics = 0;
73 // Reduce the bandwidth needed by sampling game input less and transmitting
74 // less. If ticdup is 2, sample half normal, 3 = one third normal, etc.
76 int ticdup;
78 // Send this many extra (backup) tics in each packet.
80 int extratics;
82 // Amount to offset the timer for game sync.
84 fixed_t offsetms;
86 // Use new client syncronisation code
88 boolean net_cl_new_sync = true;
90 // Connected but not participating in the game (observer)
92 boolean drone = false;
94 // 35 fps clock adjusted by offsetms milliseconds
96 static int GetAdjustedTime(void)
98 int time_ms;
100 time_ms = I_GetTimeMS();
102 if (net_cl_new_sync)
104 // Use the adjustments from net_client.c only if we are
105 // using the new sync mode.
107 time_ms += (offsetms / FRACUNIT);
110 return (time_ms * TICRATE) / 1000;
114 // NetUpdate
115 // Builds ticcmds for console player,
116 // sends out a packet
118 int lasttime;
120 void NetUpdate (void)
122 int nowtime;
123 int newtics;
124 int i;
125 int gameticdiv;
127 // If we are running with singletics (timing a demo), this
128 // is all done separately.
130 if (singletics)
131 return;
133 #ifdef FEATURE_MULTIPLAYER
135 // Run network subsystems
137 NET_CL_Run();
138 NET_SV_Run();
140 #endif
142 // check time
143 nowtime = GetAdjustedTime() / ticdup;
144 newtics = nowtime - lasttime;
146 lasttime = nowtime;
148 if (skiptics <= newtics)
150 newtics -= skiptics;
151 skiptics = 0;
153 else
155 skiptics -= newtics;
156 newtics = 0;
159 // build new ticcmds for console player
160 gameticdiv = gametic/ticdup;
162 for (i=0 ; i<newtics ; i++)
164 ticcmd_t cmd;
166 I_StartTic ();
167 D_ProcessEvents ();
169 // Always run the menu
171 M_Ticker ();
173 if (drone)
175 // In drone mode, do not generate any ticcmds.
177 continue;
180 if (net_cl_new_sync)
182 // If playing single player, do not allow tics to buffer
183 // up very far
185 if ((!netgame || demoplayback) && maketic - gameticdiv > 2)
186 break;
188 // Never go more than ~200ms ahead
190 if (maketic - gameticdiv > 8)
191 break;
193 else
195 if (maketic - gameticdiv >= 5)
196 break;
199 //printf ("mk:%i ",maketic);
200 G_BuildTiccmd(&cmd);
202 #ifdef FEATURE_MULTIPLAYER
204 if (netgame && !demoplayback)
206 NET_CL_SendTiccmd(&cmd, maketic);
209 #endif
210 netcmds[consoleplayer][maketic % BACKUPTICS] = cmd;
212 ++maketic;
213 nettics[consoleplayer] = maketic;
218 // Start game loop
220 // Called after the screen is set but before the game starts running.
223 void D_StartGameLoop(void)
225 lasttime = GetAdjustedTime() / ticdup;
230 // D_CheckNetGame
231 // Works out player numbers among the net participants
233 extern int viewangleoffset;
235 void D_CheckNetGame (void)
237 int i;
238 int num_players;
240 // default values for single player
242 consoleplayer = 0;
243 netgame = false;
244 ticdup = 1;
245 extratics = 1;
246 lowres_turn = false;
247 offsetms = 0;
249 for (i=0; i<MAXPLAYERS; i++)
251 playeringame[i] = false;
252 nettics[i] = 0;
255 playeringame[0] = true;
257 #ifdef FEATURE_MULTIPLAYER
260 net_addr_t *addr = NULL;
263 // @category net
265 // Start a multiplayer server, listening for connections.
268 if (M_CheckParm("-server") > 0)
270 NET_SV_Init();
271 NET_SV_AddModule(&net_loop_server_module);
272 NET_SV_AddModule(&net_sdl_module);
274 net_loop_client_module.InitClient();
275 addr = net_loop_client_module.ResolveAddress(NULL);
277 else
279 //!
280 // @category net
282 // Automatically search the local LAN for a multiplayer
283 // server and join it.
286 i = M_CheckParm("-autojoin");
288 if (i > 0)
290 addr = NET_FindLANServer();
292 if (addr == NULL)
294 I_Error("No server found on local LAN");
299 // @arg <address>
300 // @category net
302 // Connect to a multiplayer server running on the given
303 // address.
306 i = M_CheckParm("-connect");
308 if (i > 0)
310 net_sdl_module.InitClient();
311 addr = net_sdl_module.ResolveAddress(myargv[i+1]);
313 if (addr == NULL)
315 I_Error("Unable to resolve '%s'\n", myargv[i+1]);
320 if (addr != NULL)
322 if (M_CheckParm("-drone") > 0)
324 drone = true;
328 // @category net
330 // Run as the left screen in three screen mode.
333 if (M_CheckParm("-left") > 0)
335 viewangleoffset = ANG90;
336 drone = true;
339 //!
340 // @category net
342 // Run as the right screen in three screen mode.
345 if (M_CheckParm("-right") > 0)
347 viewangleoffset = ANG270;
348 drone = true;
351 if (!NET_CL_Connect(addr))
353 I_Error("D_CheckNetGame: Failed to connect to %s\n",
354 NET_AddrToString(addr));
357 printf("D_CheckNetGame: Connected to %s\n", NET_AddrToString(addr));
359 NET_WaitForStart();
363 #endif
365 num_players = 0;
367 for (i=0; i<MAXPLAYERS; ++i)
369 if (playeringame[i])
370 ++num_players;
373 DEH_printf("startskill %i deathmatch: %i startmap: %i startepisode: %i\n",
374 startskill, deathmatch, startmap, startepisode);
376 DEH_printf("player %i of %i (%i nodes)\n",
377 consoleplayer+1, num_players, num_players);
379 // Show players here; the server might have specified a time limit
381 if (timelimit > 0)
383 DEH_printf("Levels will end after %d minute", timelimit);
384 if (timelimit > 1)
385 printf("s");
386 printf(".\n");
392 // D_QuitNetGame
393 // Called before quitting to leave a net game
394 // without hanging the other players
396 void D_QuitNetGame (void)
398 if (debugfile)
399 fclose (debugfile);
401 #ifdef FEATURE_MULTIPLAYER
403 NET_SV_Shutdown();
404 NET_CL_Disconnect();
406 #endif
410 // Returns true if there are currently any players in the game.
412 static boolean PlayersInGame(void)
414 int i;
416 for (i=0; i<MAXPLAYERS; ++i)
418 if (playeringame[i])
420 return true;
424 return false;
427 static int GetLowTic(void)
429 int i;
430 int lowtic;
432 #ifdef FEATURE_MULTIPLAYER
433 if (net_client_connected)
435 lowtic = INT_MAX;
437 for (i=0; i<MAXPLAYERS; ++i)
439 if (playeringame[i])
441 if (nettics[i] < lowtic)
442 lowtic = nettics[i];
446 else
447 #endif
449 lowtic = maketic;
452 return lowtic;
456 // TryRunTics
458 int oldnettics;
459 int frametics[4];
460 int frameon;
461 int frameskip[4];
462 int oldnettics;
464 extern boolean advancedemo;
466 void TryRunTics (void)
468 int i;
469 int lowtic;
470 int entertic;
471 static int oldentertics;
472 int realtics;
473 int availabletics;
474 int counts;
476 // get real tics
477 entertic = I_GetTime() / ticdup;
478 realtics = entertic - oldentertics;
479 oldentertics = entertic;
481 // get available tics
482 NetUpdate ();
484 lowtic = GetLowTic();
486 availabletics = lowtic - gametic/ticdup;
488 // decide how many tics to run
490 if (net_cl_new_sync)
492 counts = availabletics;
494 else
496 // decide how many tics to run
497 if (realtics < availabletics-1)
498 counts = realtics+1;
499 else if (realtics < availabletics)
500 counts = realtics;
501 else
502 counts = availabletics;
504 if (counts < 1)
505 counts = 1;
507 frameon++;
509 if (!demoplayback)
511 int keyplayer = -1;
513 // ideally maketic should be 1 - 3 tics above lowtic
514 // if we are consistantly slower, speed up time
516 for (i=0 ; i<MAXPLAYERS ; i++)
518 if (playeringame[i])
520 keyplayer = i;
521 break;
525 if (keyplayer < 0)
527 // If there are no players, we can never advance anyway
529 return;
532 if (consoleplayer == keyplayer)
534 // the key player does not adapt
536 else
538 if (maketic <= nettics[keyplayer])
540 lasttime--;
541 // printf ("-");
544 frameskip[frameon & 3] = (oldnettics > nettics[keyplayer]);
545 oldnettics = maketic;
547 if (frameskip[0] && frameskip[1] && frameskip[2] && frameskip[3])
549 skiptics = 1;
550 // printf ("+");
556 if (counts < 1)
557 counts = 1;
559 // wait for new tics if needed
561 while (!PlayersInGame() || lowtic < gametic/ticdup + counts)
563 NetUpdate ();
565 lowtic = GetLowTic();
567 if (lowtic < gametic/ticdup)
568 I_Error ("TryRunTics: lowtic < gametic");
570 // Don't stay in this loop forever. The menu is still running,
571 // so return to update the screen
573 if (I_GetTime() / ticdup - entertic > 0)
575 return;
578 I_Sleep(1);
581 // run the count * ticdup dics
582 while (counts--)
584 for (i=0 ; i<ticdup ; i++)
586 // check that there are players in the game. if not, we cannot
587 // run a tic.
589 if (!PlayersInGame())
591 return;
594 if (gametic/ticdup > lowtic)
595 I_Error ("gametic>lowtic");
596 if (advancedemo)
597 D_DoAdvanceDemo ();
599 G_Ticker ();
600 gametic++;
602 // modify command for duplicated tics
603 if (i != ticdup-1)
605 ticcmd_t *cmd;
606 int buf;
607 int j;
609 buf = (gametic/ticdup)%BACKUPTICS;
610 for (j=0 ; j<MAXPLAYERS ; j++)
612 cmd = &netcmds[j][buf];
613 cmd->chatchar = 0;
614 if (cmd->buttons & BT_SPECIAL)
615 cmd->buttons = 0;
619 NetUpdate (); // check for new console commands