IPXSETUP.C 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. /*
  2. Copyright (C) 1994-1995 Apogee Software, Ltd.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. // ipxsetup.c
  16. #include <conio.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <dos.h>
  20. #include <string.h>
  21. #include <process.h>
  22. #include <stdarg.h>
  23. #include <bios.h>
  24. #include <time.h>
  25. #include "..\rottnet.h"
  26. #include "ipxnet.h"
  27. #define VERSION "1.3"
  28. int numnetnodes;
  29. unsigned socketid = 0x882a; // 0x882a is the official ROTT socket
  30. int myargc;
  31. char **myargv;
  32. boolean server;
  33. boolean standalone;
  34. boolean master;
  35. setupdata_t nodesetup;
  36. #define MAXNETMESSAGES 25
  37. static int messagesused;
  38. static boolean StringUsed[MAXNETMESSAGES];
  39. static char * NetStrings[MAXNETMESSAGES]=
  40. {
  41. {"\nUm, I'm sure Player %d will join us soon.\n"},
  42. {"\nPlayer %d is starting to tick me off.\n"},
  43. {"\nIt seems Player %d has gone for a Moon Pie.\n"},
  44. {"\nHow long can Player %d take setting the dang thing up?\n"},
  45. {"\nPlayer %d...where are you?\n"},
  46. {"\nSigh. Player %d is a toadie.\n"},
  47. {"\nGo give Player %d a good swift kick in the...head.\n"},
  48. {"\nIs Player %d running off a removable drive or something?\n"},
  49. {"\nPlayer %d is a popo-head.\n"},
  50. {"\nPlayer %d is attempting to escape off the map.\n"},
  51. {"\nPLAYER %d!!!! GOON!\n"},
  52. {"\nYou know, waiting for Player %d reminds me of a story....\n"},
  53. {"\nTwo Player %d's walk into a bar....\n"},
  54. {"\nHow many Player %d's does it take to change a lightbulb?\n"
  55. "None, 'cause they don't DO anything. They just SIT there.\n"},
  56. {"\nANY TIME NOW PLAYER %d!!!\n"},
  57. {"\nI hear Player %d sucks dog's toes.\n"},
  58. {"\nWho votes that Player %d gets left outta this game (y/n)?\n"},
  59. {"\nLunch break's over, Player %d!\n"},
  60. {"\nWe're all waiting, Player %d.... Hello, McFly!!!\n"},
  61. {"\nNumber %d Player, our Number 1 delayer....\n"},
  62. {"\nINSTRUCTIONS: Player %d runs the setup program....\n"},
  63. {"\nOnce Player %d deigns to join us, let's toast 'em.\n"},
  64. {"\nPssst...If you go wake up Player %d, I'll put you in God mode.\n"},
  65. {"\nOkay, when we start, I'm giving Player %d only 5 hit points.\n"},
  66. {"\nIs Player %d in Shrooms Mode or what?\n"}
  67. };
  68. /*
  69. =============
  70. =
  71. = NetISR
  72. =
  73. =============
  74. */
  75. void NetISR (void)
  76. {
  77. if (rottcom.command == CMD_SEND)
  78. {
  79. ipxlocaltime++;
  80. SendPacket (rottcom.remotenode);
  81. }
  82. else if (rottcom.command == CMD_GET)
  83. {
  84. GetPacket ();
  85. }
  86. }
  87. /*
  88. =================
  89. =
  90. = Shutdown
  91. =
  92. =================
  93. */
  94. void Shutdown ( void )
  95. {
  96. ShutdownROTTCOM ();
  97. ShutdownNetwork();
  98. }
  99. /*
  100. ===================
  101. =
  102. = SetupRandomMessages
  103. =
  104. ===================
  105. */
  106. void SetupRandomMessages ( void )
  107. {
  108. messagesused=0;
  109. memset(StringUsed,0,sizeof(StringUsed));
  110. randomize();
  111. }
  112. /*
  113. ===================
  114. =
  115. = PrintRandomMessage
  116. =
  117. ===================
  118. */
  119. void PrintRandomMessage (int message, int player)
  120. {
  121. printf(NetStrings[message],player);
  122. }
  123. /*
  124. ===================
  125. =
  126. = GetRandomMessage
  127. =
  128. ===================
  129. */
  130. int GetRandomMessage ( void )
  131. {
  132. boolean found=false;
  133. int num;
  134. if (messagesused==MAXNETMESSAGES)
  135. SetupRandomMessages();
  136. while (found==false)
  137. {
  138. num = random(MAXNETMESSAGES);
  139. if (StringUsed[num]==false)
  140. {
  141. StringUsed[num]=true;
  142. found=true;
  143. messagesused++;
  144. }
  145. }
  146. return num;
  147. }
  148. #define client_NoResponse 0
  149. #define client_Echoed 1
  150. #define client_Done 2
  151. int playernumber;
  152. int clientstate[MAXNETNODES+1];
  153. /*
  154. ===================
  155. =
  156. = ResetNodeAddresses
  157. =
  158. = Finds all the nodes for the game and works out player numbers among them
  159. =
  160. ===================
  161. */
  162. void ResetNodeAddresses ( void )
  163. {
  164. int i;
  165. // Zero out client state structure
  166. playernumber=1;
  167. memset(clientstate,0,sizeof(clientstate));
  168. for (i=1 ; i<MAXNETNODES ; i++)
  169. memset (&nodeadr[i],0,sizeof(&nodeadr[i]));
  170. clientstate[0]=client_Done;
  171. if (standalone==false)
  172. {
  173. clientstate[playernumber]=client_Done;
  174. rottcom.consoleplayer=playernumber;
  175. memcpy (&nodeadr[playernumber], &nodeadr[0], //copy in local address
  176. sizeof(nodeadr[playernumber]) );
  177. printf ("\nServer is Player %d\n",playernumber);
  178. playernumber++;
  179. }
  180. }
  181. /*
  182. ===================
  183. =
  184. = LookForNodes
  185. =
  186. = Finds all the nodes for the game and works out player numbers among them
  187. =
  188. ===================
  189. */
  190. #define cmd_FindClient 1
  191. #define cmd_HereIAm 2
  192. #define cmd_YouAre 3
  193. #define cmd_IAm 4
  194. #define cmd_AllDone 5
  195. #define cmd_Info 6
  196. #define MAXWAIT 10
  197. void LookForNodes (void)
  198. {
  199. int i;
  200. struct time time;
  201. int oldsec;
  202. setupdata_t *setup;
  203. boolean done;
  204. short numplayers,extra;
  205. boolean showednum;
  206. short secondsleft;
  207. boolean masterset=false;
  208. done=false;
  209. oldsec = -1;
  210. secondsleft = MAXWAIT;
  211. setup = (setupdata_t *)&rottcom.data;
  212. ipxlocaltime = -1; // in setup time, not game time
  213. showednum = false;
  214. SetupRandomMessages ();
  215. if (server==true)
  216. {
  217. printf("SERVER MODE:\n");
  218. printf("============\n");
  219. printf("Attempting to find all clients for %i player NETROTT\n",
  220. numnetnodes);
  221. nodesetup.client=0;
  222. rottcom.client=0;
  223. rottcom.numplayers=numnetnodes;
  224. ResetNodeAddresses ();
  225. if (standalone==false)
  226. {
  227. masterset=true;
  228. }
  229. }
  230. else
  231. {
  232. printf("CLIENT MODE:\n");
  233. printf("============\n");
  234. printf("Attempting to find server\n");
  235. rottcom.numplayers=MAXPLAYERS;
  236. nodesetup.client=1;
  237. rottcom.client=1;
  238. }
  239. //
  240. // build local setup info
  241. //
  242. nodesetup.playernumber = 0;
  243. gettime (&time);
  244. oldsec = time.ti_sec;
  245. do
  246. {
  247. //
  248. // check for aborting
  249. //
  250. while ( bioskey(1) )
  251. {
  252. if ( (bioskey (0) & 0xff) == 27)
  253. Error ("\n\nNetwork game synchronization aborted.");
  254. }
  255. if (server==false) // Client code
  256. {
  257. //
  258. // listen to the network
  259. //
  260. while (GetPacket ())
  261. {
  262. extra = setup->extra;
  263. numplayers = setup->numplayers;
  264. if (remotetime != -1)
  265. { // an early game packet, not a setup packet
  266. if (rottcom.remotenode == -1)
  267. Error ("\n\nUnkown game packet: Other ROTT server present");
  268. }
  269. if (setup->client==0) // It's a server packet
  270. {
  271. switch (setup->command)
  272. {
  273. case cmd_FindClient:
  274. // copy the server's address
  275. if (rottcom.remotenode==-1) // only set if it is an unknown pkt
  276. {
  277. memcpy (&nodeadr[1], &remoteadr,
  278. sizeof(nodeadr[1]) );
  279. }
  280. nodesetup.command=cmd_HereIAm;
  281. if (master==true)
  282. nodesetup.extra=1;
  283. else
  284. nodesetup.extra=0;
  285. memcpy (&rottcom.data,
  286. &nodesetup,sizeof(*setup));
  287. rottcom.datalength = sizeof(*setup);
  288. SendPacket (1); // send to server
  289. printf (".");
  290. break;
  291. case cmd_Info:
  292. if (showednum==false)
  293. {
  294. printf("\nServer is looking for %d players\n",numplayers);
  295. showednum = true;
  296. }
  297. if ((extra>>8)!=0)
  298. {
  299. if ((extra>>8)==100)
  300. printf("\nServer found player %d\n",extra&0xff);
  301. else
  302. PrintRandomMessage((extra>>8)-1,extra&0xff);
  303. }
  304. break;
  305. case cmd_YouAre:
  306. rottcom.consoleplayer=setup->playernumber;
  307. nodesetup.command=cmd_IAm;
  308. nodesetup.playernumber=setup->playernumber;
  309. memcpy (&rottcom.data,
  310. &nodesetup,sizeof(*setup));
  311. rottcom.datalength = sizeof(*setup);
  312. SendPacket (1); // send to server
  313. printf (".");
  314. printf ("\nI am player %d\n",setup->playernumber);
  315. break;
  316. case cmd_AllDone:
  317. rottcom.numplayers=setup->playernumber;
  318. done=true;
  319. printf ("!");
  320. break;
  321. }
  322. }
  323. }
  324. }
  325. else // It's the server
  326. {
  327. //
  328. // listen to the network
  329. //
  330. while (GetPacket ())
  331. {
  332. extra = setup->extra;
  333. if (remotetime != -1)
  334. { // an early game packet, not a setup packet
  335. if (rottcom.remotenode == -1)
  336. Error ("\n\nUnkown game packet: Other clients still in game.");
  337. }
  338. if (setup->client==1) // It's a client packet
  339. {
  340. switch (setup->command)
  341. {
  342. case cmd_HereIAm:
  343. {
  344. int pnum;
  345. if ((masterset==false) && (extra==1)) // some client is using the 'master' param
  346. {
  347. ResetNodeAddresses ();
  348. masterset=true;
  349. rottcom.remotenode=-1;
  350. }
  351. pnum=playernumber;
  352. if (rottcom.remotenode==-1) // only set if it is an unknown pkt
  353. {
  354. // copy the client's address
  355. printf ("\nFound Player %d\n",pnum);
  356. memcpy (&nodeadr[playernumber], &remoteadr,
  357. sizeof(nodeadr[playernumber]) );
  358. nodesetup.extra=(short)(100<<8);
  359. nodesetup.extra |= playernumber;
  360. nodesetup.command=cmd_Info;
  361. nodesetup.numplayers=numnetnodes;
  362. rottcom.datalength = sizeof(*setup);
  363. memcpy (&rottcom.data, &nodesetup,sizeof(*setup));
  364. SendPacket (MAXNETNODES); // send to all
  365. }
  366. else
  367. pnum=rottcom.remotenode;
  368. if (clientstate[pnum]>client_Echoed)
  369. continue;
  370. nodesetup.command=cmd_YouAre;
  371. nodesetup.playernumber=pnum;
  372. memcpy (&rottcom.data,
  373. &nodesetup,sizeof(*setup));
  374. SendPacket (pnum); // send back to client
  375. clientstate[pnum]=client_Echoed;
  376. playernumber++;
  377. }
  378. break;
  379. case cmd_IAm:
  380. if (rottcom.remotenode==-1) // Shouldn't happen
  381. continue;
  382. // Error("\n\nReceived Identity packet before identification\n");
  383. if (rottcom.remotenode!=setup->playernumber)
  384. Error("\n\nReceived Incorrect player number\n");
  385. printf ("Finished Player %d\n",rottcom.remotenode);
  386. clientstate[rottcom.remotenode]=client_Done;
  387. break;
  388. }
  389. }
  390. else
  391. {
  392. if (rottcom.remotenode!=0)
  393. Error("\n\nMultiple ROTT Servers!\n");
  394. switch (setup->command)
  395. {
  396. case cmd_Info:
  397. if (((extra>>8)!=0) && (standalone==false))
  398. {
  399. if ((extra>>8)==100)
  400. printf("\nServer found player %d\n",extra&0xff);
  401. else
  402. PrintRandomMessage((extra>>8)-1,extra&0xff);
  403. }
  404. break;
  405. }
  406. }
  407. }
  408. // Check to see if we are indeed done
  409. done=true; // set it to true
  410. if (playernumber > numnetnodes+1)
  411. Error("\n\nFound too many players=%d\n",playernumber);
  412. if (playernumber <= numnetnodes)
  413. done=false;
  414. else
  415. {
  416. for (i=0;i<playernumber;i++)
  417. if (clientstate[i]!=client_Done)
  418. done=false;
  419. }
  420. gettime (&time);
  421. if (time.ti_sec == oldsec)
  422. continue;
  423. secondsleft--;
  424. if (secondsleft==0)
  425. {
  426. secondsleft=MAXWAIT;
  427. nodesetup.extra=(GetRandomMessage())+1;
  428. nodesetup.extra<<=8;
  429. nodesetup.extra|=playernumber;
  430. nodesetup.command=cmd_Info;
  431. nodesetup.numplayers=numnetnodes;
  432. rottcom.datalength = sizeof(*setup);
  433. memcpy (&rottcom.data, &nodesetup,sizeof(*setup));
  434. SendPacket (MAXNETNODES); // send to all
  435. }
  436. oldsec = time.ti_sec;
  437. printf (".");
  438. // Make a general inquiry for any potential ROTT players
  439. nodesetup.extra=0;
  440. nodesetup.command=cmd_FindClient;
  441. nodesetup.numplayers=numnetnodes;
  442. rottcom.datalength = sizeof(*setup);
  443. memcpy (&rottcom.data, &nodesetup,sizeof(*setup));
  444. SendPacket (MAXNETNODES); // send to all
  445. }
  446. } while (done==false);
  447. // Done with finding players send out startup info
  448. if (server==true)
  449. {
  450. int otime;
  451. gettime (&time);
  452. oldsec = time.ti_sec+1;
  453. if (oldsec>59)
  454. oldsec-=60;
  455. otime = time.ti_sec-1;
  456. while (oldsec!=time.ti_sec)
  457. {
  458. gettime (&time);
  459. if (time.ti_sec == otime)
  460. continue;
  461. otime = time.ti_sec;
  462. nodesetup.command=cmd_AllDone;
  463. nodesetup.playernumber=playernumber-1;
  464. rottcom.datalength = sizeof(*setup);
  465. memcpy (&rottcom.data, &nodesetup,sizeof(*setup));
  466. SendPacket (MAXNETNODES); // send to all
  467. }
  468. }
  469. if (server==true)
  470. {
  471. if (standalone == false)
  472. printf ("Server is player %i of %i\n", rottcom.consoleplayer, rottcom.numplayers);
  473. else
  474. printf ("Server is standalone\n");
  475. }
  476. else
  477. printf ("\nConsole is player %i of %i\n", rottcom.consoleplayer, rottcom.numplayers);
  478. while (GetPacket ()) {}
  479. }
  480. /*
  481. =============
  482. =
  483. = main
  484. =
  485. =============
  486. */
  487. void main (void)
  488. {
  489. int i;
  490. //
  491. // determine game parameters
  492. //
  493. numnetnodes = 2;
  494. rottcom.gametype=NETWORK_GAME;
  495. rottcom.remoteridicule = 0;
  496. printf("\n\n -----------------------------------\n");
  497. printf(" ROTT NETWORK DEVICE DRIVER V%s \n",VERSION);
  498. printf(" -----------------------------------\n");
  499. i = CheckParm ("-nodes");
  500. if (i && i < _argc-1)
  501. {
  502. numnetnodes = atoi(_argv[i+1]);
  503. }
  504. i = CheckParm ("-socket");
  505. if (i && i < _argc-1)
  506. {
  507. socketid = atoi(_argv[i+1]);
  508. }
  509. server=false;
  510. standalone=false;
  511. pause=false;
  512. master=false;
  513. if (CheckParm ("-server"))
  514. server=true;
  515. if (CheckParm ("-standalone"))
  516. standalone=true;
  517. if (CheckParm ("-pause"))
  518. pause=true;
  519. if (CheckParm ("-master"))
  520. master=true;
  521. if (CheckParm ("-remoteridicule"))
  522. rottcom.remoteridicule = 1;
  523. InitNetwork ();
  524. LookForNodes ();
  525. ipxlocaltime = 0; // no longer in setup
  526. LaunchROTT ();
  527. Shutdown ();
  528. exit(0);
  529. }