1 #include <stdlib.h>
2 #include <unistd.h>
3 #include <GL/glut.h>
4 
5 
6 #include "serverobject.h"
7 #include "sizes.h"
8 #include "input.h"
9 #include "netvariables.h"
10 #include "game.h"
11 #include "object.h"
12 #include "screen.h"
13 #include "configuration.h"
14 #include "serverconfig.h"
15 #include "score.h"
16 #include "sound.h"
17 #include "thread.h"
18 #include "netconfig.h"
19 #include "serverdata.h"
20 #include "scorevals.h"
21 #include "server.h"
22 #include "netdata.h"
23 #include "network.h"
24 
25 
26 struct ConfMenuItemStruct {
27   char ItemText[80];
28   char EntryText[80];
29   void *EntryValue;
30   int EntryLength;
31   int EntryType;
32   void (*EntryFunction)(char *, void *, int, int);
33   void (*ItemFunction)();
34 };
35 
36 struct ScoreMenuItemStruct {
37   char ItemText[80];
38   void (*ItemFunction)();
39 };
40 
41 struct MainMenuItemStruct {
42   char ItemText[80];
43   void (*ItemFunction)();
44 };
45 
46 
47 void SetupMainMenu();
48 void SetupConfMenu();
49 void SetupScoreMenu();
50 void SetupConfMenu();
51 void SetupScoreMenu();
52 void AbortGame();
53 void MainMenu();
54 void ConfMenu();
55 void ScoreMenu();
56 void SetupMainDisplay();
57 void SetupConfDisplay();
58 void InitMainMenu();
59 void InitConfMenu();
60 void InitScoreMenu();
61 void DrawMainMenu();
62 void DrawConfMenu();
63 void DrawScoreMenu();
64 void MainMenuItemSelected();
65 void ConfMenuItemSelected();
66 void ScoreMenuItemSelected();
67 void SetKeyValue();
68 void TextEntry();
69 void ScoreEntry();
70 void IntTextEntry();
71 void SetValue(char *ValueText, void *Value, int ValueLength, int type);
72 void SetKey(char *KeyId, char *Key);
73 void SetText(char *TextId, char *Text, int MaxLength);
74 void SetIntText(char *TextId, int *Value, int MaxLength);
75 void StartSingleGame();
76 void StartMultiGame();
77 void StartServer();
78 void KillServer();
79 void QuitGame();
80 
81 
82 int MainMenuItemHighlighted;
83 int ConfMenuItemHighlighted;
84 int ScoreMenuItemHighlighted;
85 char *KeyValue;
86 char KeyName[MAX_NAME_LENGTH];
87 char *TextValue;
88 char TextName[MAX_NAME_LENGTH];
89 int MaxTextLength;
90 int *IntValue;
91 int NewScreenWidth, NewScreenHeight;
92 pthread_t ServerThread;
93 int ServerStarted;
94 int TopItemDisplayed;
95 int BottomItemDisplayed;
96 int MainMenuStartHeight;
97 int ConfMenuStartHeight;
98 int NumMainMenuItems;
99 int NumConfMenuItems;
100 int NumScoreMenuItems;
101 struct MainMenuItemStruct MainMenuItems[MAX_MENU_ITEMS];
102 struct ConfMenuItemStruct ConfMenuItems[MAX_MENU_ITEMS];
103 struct ScoreMenuItemStruct ScoreMenuItems[MAX_MENU_ITEMS];
104 
105 
AbortGame()106 void AbortGame()
107 {
108   int rc;
109 
110   TellServer(ABORT_KEY, 1);
111   GameStop=1;
112 
113   CleanupSounds();
114 
115   if (GameType==SINGLE_PLAYER) {
116     rc=pthread_join(ServerThread, NULL);
117     if (!rc) {
118       ReadServerConfig(ServerConfigFileName);
119     }
120   }
121 
122   ReadConfig();
123 
124   pthread_mutex_unlock(&ClientLock);
125   InitMatrixMode();
126   glutKeyboardFunc(MainMenuKey);
127   glutKeyboardUpFunc(NULL);
128   glutSpecialFunc(MainMenuSpecialKey);
129   glutIdleFunc(NULL);
130   glutDisplayFunc(MainMenu);
131   MainMenu();
132 }
133 
134 
MainMenu()135 void MainMenu()
136 {
137   SetupMainDisplay();
138   ClearScreen();
139   DrawMainMenu();
140   UpdateScreen();
141 }
142 
143 
ConfMenu()144 void ConfMenu()
145 {
146   SetupConfDisplay();
147   ClearScreen();
148   DrawConfMenu();
149   UpdateScreen();
150 }
151 
152 
ScoreMenu()153 void ScoreMenu()
154 {
155   ClearScreen();
156   DrawScoreMenu();
157   UpdateScreen();
158 }
159 
160 
161 // Function to handle reading in one key
SetKeyValue()162 void SetKeyValue()
163 {
164   char KeyText[80]="Enter key for ";
165 
166   strcat(KeyText, KeyName);
167 
168   ClearScreen();
169   DrawText(ScreenWidth/2-100, ScreenHeight/2, KeyText, &Red, 1);
170   UpdateScreen();
171 }
172 
173 
174 // Function to handle reading in text entry
TextEntry()175 void TextEntry()
176 {
177   int pos;
178 
179   ClearScreen();
180   pos=DrawText(ScreenWidth/2-200, ScreenHeight/2, TextName, &Blue, 1);
181   DrawRect(pos+17, ScreenHeight/2-2, pos+17, ScreenHeight/2+20,
182 	   pos+300, ScreenHeight/2+20, pos+300, ScreenHeight/2-2, &DarkGray);
183   pos=DrawText(pos+20, ScreenHeight/2, TextValue, &Red, 1);
184   DrawRect(pos+2, ScreenHeight/2, pos+2, ScreenHeight/2+15,
185 	   pos+8, ScreenHeight/2+15, pos+8, ScreenHeight/2, &White);
186   UpdateScreen();
187 }
188 
189 
190 // Function to handle reading in entry of high score name
ScoreEntry()191 void ScoreEntry()
192 {
193   int pos;
194 
195   ClearScreen();
196   DrawText(ScreenWidth/2-200, ScreenHeight/2+50,
197 	   (char *)"Congratulations, you've made a high score", &Blue, 1);
198   pos=DrawText(ScreenWidth/2-200, ScreenHeight/2, (char *)"Enter Name", &Blue, 1);
199   DrawRect(pos+17, ScreenHeight/2-2, pos+17, ScreenHeight/2+20,
200 	   pos+300, ScreenHeight/2+20, pos+300, ScreenHeight/2-2, &DarkGray);
201   pos=DrawText(pos+20, ScreenHeight/2, TextValue, &Red, 1);
202   DrawRect(pos+2, ScreenHeight/2, pos+2, ScreenHeight/2+15,
203 	   pos+8, ScreenHeight/2+15, pos+8, ScreenHeight/2, &White);
204   UpdateScreen();
205 }
206 
207 
208 // Function to handle reading in text entry of integer
IntTextEntry()209 void IntTextEntry()
210 {
211   int pos;
212   char Value[80];
213 
214   sprintf(Value, "%d", *IntValue);
215 
216   ClearScreen();
217   pos=DrawText(ScreenWidth/2-200, ScreenHeight/2, TextName, &Blue, 1);
218   DrawRect(pos+17, ScreenHeight/2-2, pos+17, ScreenHeight/2+20,
219 	   pos+300, ScreenHeight/2+20, pos+300, ScreenHeight/2-2, &DarkGray);
220   pos+=20;
221   pos=DrawText(pos, ScreenHeight/2, Value, &Red, 1);
222 
223   DrawRect(pos+2, ScreenHeight/2, pos+2, ScreenHeight/2+15,
224 	   pos+8, ScreenHeight/2+15, pos+8, ScreenHeight/2, &White);
225   UpdateScreen();
226 }
227 
228 
DrawMainMenu()229 void DrawMainMenu()
230 {
231   int i;
232   struct Color *TextColor;
233 
234   for (i=TopItemDisplayed; i<=BottomItemDisplayed; i++) {
235     if (i==MainMenuItemHighlighted) {
236       TextColor=&White;
237     } else {
238       TextColor=&Blue;
239     }
240     DrawText(ScreenWidth/2-100,
241              ScreenHeight-MainMenuStartHeight-25*(i-TopItemDisplayed),
242              MainMenuItems[i].ItemText, TextColor, 1);
243   }
244 }
245 
246 
DrawConfMenu()247 void DrawConfMenu()
248 {
249   int i, pos;
250   char tempval[80];
251   struct Color *TextColor;
252 
253   for (i=TopItemDisplayed; i<=BottomItemDisplayed; i++) {
254     if (i==ConfMenuItemHighlighted) {
255       TextColor=&White;
256     } else {
257       TextColor=&Blue;
258     }
259     pos=DrawText(ScreenWidth/2-200,
260                  ScreenHeight-ConfMenuStartHeight-25*(i-TopItemDisplayed),
261                  ConfMenuItems[i].ItemText, TextColor, 1);
262     if (ConfMenuItems[i].EntryValue) {
263       if (ConfMenuItems[i].EntryType==0) {
264         strcpy(tempval, (char *)ConfMenuItems[i].EntryValue);
265       } else if (ConfMenuItems[i].EntryType==1) {
266         sprintf(tempval, "%d", *(int *)ConfMenuItems[i].EntryValue);
267       } else if (ConfMenuItems[i].EntryType==2) {
268         sprintf(tempval, "%c", *(char *)ConfMenuItems[i].EntryValue);
269       }
270       DrawText(pos+20, ScreenHeight-ConfMenuStartHeight-25*(i-TopItemDisplayed),
271                tempval, &Red, 1);
272     }
273   }
274 }
275 
276 
InitMainMenu()277 void InitMainMenu()
278 {
279   int itemnum=0;
280 
281   MainMenuItemHighlighted=0;
282 
283   strcpy(MainMenuItems[itemnum].ItemText, "Start Single Player Game");
284   MainMenuItems[itemnum].ItemFunction=StartSingleGame;
285   itemnum++;
286   strcpy(MainMenuItems[itemnum].ItemText, "Start Multi Player Game");
287   MainMenuItems[itemnum].ItemFunction=StartMultiGame;
288   itemnum++;
289   strcpy(MainMenuItems[itemnum].ItemText, "Start ATR Server");
290   MainMenuItems[itemnum].ItemFunction=StartServer;
291   itemnum++;
292   strcpy(MainMenuItems[itemnum].ItemText, "Stop ATR Server");
293   MainMenuItems[itemnum].ItemFunction=KillServer;
294   itemnum++;
295   strcpy(MainMenuItems[itemnum].ItemText, "Edit Game Configuration");
296   MainMenuItems[itemnum].ItemFunction=SetupConfMenu;
297   itemnum++;
298   strcpy(MainMenuItems[itemnum].ItemText, "View High Scores");
299   MainMenuItems[itemnum].ItemFunction=SetupScoreMenu;
300   itemnum++;
301   strcpy(MainMenuItems[itemnum].ItemText, "Quit Game");
302   MainMenuItems[itemnum].ItemFunction=QuitGame;
303   itemnum++;
304 
305   NumMainMenuItems=itemnum;
306 
307   if (NumMainMenuItems*25 <= ScreenHeight-25) {
308     MainMenuStartHeight=(ScreenHeight-(NumMainMenuItems+1)*25+50)/2;
309   } else {
310     MainMenuStartHeight=25+25/2;
311   }
312 }
313 
314 
DrawScoreMenu()315 void DrawScoreMenu()
316 {
317   int i;
318   char Score[10];
319   int NumScoresDisplayed;
320   struct Color *TextColor;
321 
322   DrawText(20, ScreenHeight-50, (char *)"Name", &Blue, 1);
323   DrawText(ScreenWidth/2, ScreenHeight-50, (char *)"Score", &Blue, 1);
324 
325   NumScoresDisplayed=(ScreenHeight-(150+25*NumScoreMenuItems))/25;
326   if (NumScoresDisplayed > NUM_HIGHSCORES) {
327     NumScoresDisplayed=NUM_HIGHSCORES;
328   }
329 
330   for (i=0; i<NumScoresDisplayed; i++) {
331     sprintf(Score, "%d", HighScores[i].Score);
332     DrawText(20, ScreenHeight-90-25*i, HighScores[i].Name, &Red, 1);
333     DrawText(ScreenWidth/2, ScreenHeight-90-25*i, Score, &Red, 1);
334   }
335 
336   for (i=0; i<NumScoreMenuItems; i++) {
337     if (i==ScoreMenuItemHighlighted) {
338       TextColor=&White;
339     } else {
340       TextColor=&Blue;
341     }
342     DrawText(ScreenWidth/2-100, 25*(NumScoreMenuItems-i+1), ScoreMenuItems[i].ItemText, TextColor, 1);
343   }
344 }
345 
346 
InitConfMenu()347 void InitConfMenu()
348 {
349   int itemnum=0;
350 
351   ConfMenuItemHighlighted=0;
352   strcpy(ConfMenuItems[itemnum].ItemText, "Server IP (MultiPlayer Only)");
353   strcpy(ConfMenuItems[itemnum].EntryText, "Enter Server IP");
354   ConfMenuItems[itemnum].EntryValue=ServerIP;
355   ConfMenuItems[itemnum].EntryLength=15;
356   ConfMenuItems[itemnum].EntryType=0;
357   ConfMenuItems[itemnum].EntryFunction=SetValue;
358   ConfMenuItems[itemnum].ItemFunction=NULL;
359   itemnum++;
360   strcpy(ConfMenuItems[itemnum].ItemText, "Server Port (MultiPlayer Only)");
361   strcpy(ConfMenuItems[itemnum].EntryText, "Enter Server Port");
362   ConfMenuItems[itemnum].EntryValue=&ServerPort;
363   ConfMenuItems[itemnum].EntryLength=5;
364   ConfMenuItems[itemnum].EntryType=1;
365   ConfMenuItems[itemnum].EntryFunction=SetValue;
366   ConfMenuItems[itemnum].ItemFunction=NULL;
367   itemnum++;
368   strcpy(ConfMenuItems[itemnum].ItemText, "Player Name (MultiPlayer Only)");
369   strcpy(ConfMenuItems[itemnum].EntryText, "Enter Player Name");
370   ConfMenuItems[itemnum].EntryValue=PlayerName;
371   ConfMenuItems[itemnum].EntryLength=MAX_PLAYERNAME_LENGTH-1;
372   ConfMenuItems[itemnum].EntryType=0;
373   ConfMenuItems[itemnum].EntryFunction=SetValue;
374   ConfMenuItems[itemnum].ItemFunction=NULL;
375   itemnum++;
376   strcpy(ConfMenuItems[itemnum].ItemText, "Screen Width");
377   strcpy(ConfMenuItems[itemnum].EntryText, "Enter Screen Width");
378   ConfMenuItems[itemnum].EntryValue=&NewScreenWidth;
379   ConfMenuItems[itemnum].EntryLength=4;
380   ConfMenuItems[itemnum].EntryType=1;
381   ConfMenuItems[itemnum].EntryFunction=SetValue;
382   ConfMenuItems[itemnum].ItemFunction=NULL;
383   itemnum++;
384   strcpy(ConfMenuItems[itemnum].ItemText, "Screen Height");
385   strcpy(ConfMenuItems[itemnum].EntryText, "Enter Screen Height");
386   ConfMenuItems[itemnum].EntryValue=&NewScreenHeight;
387   ConfMenuItems[itemnum].EntryLength=4;
388   ConfMenuItems[itemnum].EntryType=1;
389   ConfMenuItems[itemnum].EntryFunction=SetValue;
390   ConfMenuItems[itemnum].ItemFunction=NULL;
391   itemnum++;
392   strcpy(ConfMenuItems[itemnum].ItemText, "Volume");
393   strcpy(ConfMenuItems[itemnum].EntryText, "Enter Volume (Values 0 through 9)");
394   ConfMenuItems[itemnum].EntryValue=&newvolume;
395   ConfMenuItems[itemnum].EntryLength=1;
396   ConfMenuItems[itemnum].EntryType=1;
397   ConfMenuItems[itemnum].EntryFunction=SetValue;
398   ConfMenuItems[itemnum].ItemFunction=NULL;
399   itemnum++;
400   strcpy(ConfMenuItems[itemnum].ItemText, "Score Key (DeathMatch Only)");
401   strcpy(ConfMenuItems[itemnum].EntryText, "Enter Score Key");
402   ConfMenuItems[itemnum].EntryValue=&controls.Score;
403   ConfMenuItems[itemnum].EntryLength=1;
404   ConfMenuItems[itemnum].EntryType=2;
405   ConfMenuItems[itemnum].EntryFunction=SetValue;
406   ConfMenuItems[itemnum].ItemFunction=NULL;
407   itemnum++;
408   strcpy(ConfMenuItems[itemnum].ItemText, "Fire Key");
409   strcpy(ConfMenuItems[itemnum].EntryText, "Enter Fire Key");
410   ConfMenuItems[itemnum].EntryValue=&controls.Fire;
411   ConfMenuItems[itemnum].EntryLength=1;
412   ConfMenuItems[itemnum].EntryType=2;
413   ConfMenuItems[itemnum].EntryFunction=SetValue;
414   ConfMenuItems[itemnum].ItemFunction=NULL;
415   itemnum++;
416   strcpy(ConfMenuItems[itemnum].ItemText, "Shield Key");
417   strcpy(ConfMenuItems[itemnum].EntryText, "Enter Shield Key");
418   ConfMenuItems[itemnum].EntryValue=&controls.Shield;
419   ConfMenuItems[itemnum].EntryLength=1;
420   ConfMenuItems[itemnum].EntryType=2;
421   ConfMenuItems[itemnum].EntryFunction=SetValue;
422   ConfMenuItems[itemnum].ItemFunction=NULL;
423   itemnum++;
424   strcpy(ConfMenuItems[itemnum].ItemText, "Warp Key");
425   strcpy(ConfMenuItems[itemnum].EntryText, "Enter Warp Key");
426   ConfMenuItems[itemnum].EntryValue=&controls.Warp;
427   ConfMenuItems[itemnum].EntryLength=1;
428   ConfMenuItems[itemnum].EntryType=2;
429   ConfMenuItems[itemnum].EntryFunction=SetValue;
430   ConfMenuItems[itemnum].ItemFunction=NULL;
431   itemnum++;
432   strcpy(ConfMenuItems[itemnum].ItemText, "Nuke Key");
433   strcpy(ConfMenuItems[itemnum].EntryText, "Enter Nuke Key");
434   ConfMenuItems[itemnum].EntryValue=&controls.Nuke;
435   ConfMenuItems[itemnum].EntryLength=1;
436   ConfMenuItems[itemnum].EntryType=2;
437   ConfMenuItems[itemnum].EntryFunction=SetValue;
438   ConfMenuItems[itemnum].ItemFunction=NULL;
439   itemnum++;
440   strcpy(ConfMenuItems[itemnum].ItemText, "Quit Key");
441   strcpy(ConfMenuItems[itemnum].EntryText, "Enter Quit Key");
442   ConfMenuItems[itemnum].EntryValue=&controls.Quit;
443   ConfMenuItems[itemnum].EntryLength=1;
444   ConfMenuItems[itemnum].EntryType=2;
445   ConfMenuItems[itemnum].EntryFunction=SetValue;
446   ConfMenuItems[itemnum].ItemFunction=NULL;
447   itemnum++;
448   /*
449     strcpy(ConfMenuItems[itemnum].ItemText, "x Forward Key");
450     strcpy(ConfMenuItems[itemnum].EntryText, "Enter x Forward Key");
451     ConfMenuItems[itemnum].EntryValue=&controls.xForward;
452     ConfMenuItems[itemnum].EntryLength=1;
453     ConfMenuItems[itemnum].EntryType=2;
454     ConfMenuItems[itemnum].EntryFunction=SetValue;
455     ConfMenuItems[itemnum].ItemFunction=NULL;
456     itemnum++;
457     strcpy(ConfMenuItems[itemnum].ItemText, "x Backward Key");
458     strcpy(ConfMenuItems[itemnum].EntryText, "Enter x Backward Key");
459     ConfMenuItems[itemnum].EntryValue=&controls.xBackward;
460     ConfMenuItems[itemnum].EntryLength=1;
461     ConfMenuItems[itemnum].EntryType=2;
462     ConfMenuItems[itemnum].EntryFunction=SetValue;
463     ConfMenuItems[itemnum].ItemFunction=NULL;
464     itemnum++;
465     strcpy(ConfMenuItems[itemnum].ItemText, "y Forward Key");
466     strcpy(ConfMenuItems[itemnum].EntryText, "Enter y Forward Key");
467     ConfMenuItems[itemnum].EntryValue=&controls.yForward;
468     ConfMenuItems[itemnum].EntryLength=1;
469     ConfMenuItems[itemnum].EntryType=2;
470     ConfMenuItems[itemnum].EntryFunction=SetValue;
471     ConfMenuItems[itemnum].ItemFunction=NULL;
472     itemnum++;
473     strcpy(ConfMenuItems[itemnum].ItemText, "y Backward Key");
474     strcpy(ConfMenuItems[itemnum].EntryText, "Enter y Backward Key");
475     ConfMenuItems[itemnum].EntryValue=&controls.yBackward;
476     ConfMenuItems[itemnum].EntryLength=1;
477     ConfMenuItems[itemnum].EntryType=2;
478     ConfMenuItems[itemnum].EntryFunction=SetValue;
479     ConfMenuItems[itemnum].ItemFunction=NULL;
480     itemnum++;
481   */
482   strcpy(ConfMenuItems[itemnum].ItemText, "Forward Thrust Key");
483   strcpy(ConfMenuItems[itemnum].EntryText, "Enter Forward Thrust Key");
484   ConfMenuItems[itemnum].EntryValue=&controls.zForward;
485   ConfMenuItems[itemnum].EntryLength=1;
486   ConfMenuItems[itemnum].EntryType=2;
487   ConfMenuItems[itemnum].EntryFunction=SetValue;
488   ConfMenuItems[itemnum].ItemFunction=NULL;
489   itemnum++;
490   strcpy(ConfMenuItems[itemnum].ItemText, "Reverse Thrust Key");
491   strcpy(ConfMenuItems[itemnum].EntryText, "Enter Reverse Thrust Key");
492   ConfMenuItems[itemnum].EntryValue=&controls.zBackward;
493   ConfMenuItems[itemnum].EntryLength=1;
494   ConfMenuItems[itemnum].EntryType=2;
495   ConfMenuItems[itemnum].EntryFunction=SetValue;
496   ConfMenuItems[itemnum].ItemFunction=NULL;
497   itemnum++;
498   strcpy(ConfMenuItems[itemnum].ItemText, "x Forward Rotate Key");
499   strcpy(ConfMenuItems[itemnum].EntryText, "Enter x Forward Rotate Key");
500   ConfMenuItems[itemnum].EntryValue=&controls.xFRotate;
501   ConfMenuItems[itemnum].EntryLength=1;
502   ConfMenuItems[itemnum].EntryType=2;
503   ConfMenuItems[itemnum].EntryFunction=SetValue;
504   ConfMenuItems[itemnum].ItemFunction=NULL;
505   itemnum++;
506   strcpy(ConfMenuItems[itemnum].ItemText, "x Backward Rotate Key");
507   strcpy(ConfMenuItems[itemnum].EntryText, "Enter x Backward Rotate Key");
508   ConfMenuItems[itemnum].EntryValue=&controls.xBRotate;
509   ConfMenuItems[itemnum].EntryLength=1;
510   ConfMenuItems[itemnum].EntryType=2;
511   ConfMenuItems[itemnum].EntryFunction=SetValue;
512   ConfMenuItems[itemnum].ItemFunction=NULL;
513   itemnum++;
514   strcpy(ConfMenuItems[itemnum].ItemText, "y Forward Rotate Key");
515   strcpy(ConfMenuItems[itemnum].EntryText, "Enter y Forward Rotate Key");
516   ConfMenuItems[itemnum].EntryValue=&controls.yFRotate;
517   ConfMenuItems[itemnum].EntryLength=1;
518   ConfMenuItems[itemnum].EntryType=2;
519   ConfMenuItems[itemnum].EntryFunction=SetValue;
520   ConfMenuItems[itemnum].ItemFunction=NULL;
521   itemnum++;
522   strcpy(ConfMenuItems[itemnum].ItemText, "y Backward Rotate Key");
523   strcpy(ConfMenuItems[itemnum].EntryText, "Enter y Backward Rotate Key");
524   ConfMenuItems[itemnum].EntryValue=&controls.yBRotate;
525   ConfMenuItems[itemnum].EntryLength=1;
526   ConfMenuItems[itemnum].EntryType=2;
527   ConfMenuItems[itemnum].EntryFunction=SetValue;
528   ConfMenuItems[itemnum].ItemFunction=NULL;
529   itemnum++;
530   strcpy(ConfMenuItems[itemnum].ItemText, "z Forward Rotate Key");
531   strcpy(ConfMenuItems[itemnum].EntryText, "Enter z Forward Rotate Key");
532   ConfMenuItems[itemnum].EntryValue=&controls.zFRotate;
533   ConfMenuItems[itemnum].EntryLength=1;
534   ConfMenuItems[itemnum].EntryType=2;
535   ConfMenuItems[itemnum].EntryFunction=SetValue;
536   ConfMenuItems[itemnum].ItemFunction=NULL;
537   itemnum++;
538   strcpy(ConfMenuItems[itemnum].ItemText, "z Backward Rotate Key");
539   strcpy(ConfMenuItems[itemnum].EntryText, "Enter z Backward Rotate Key");
540   ConfMenuItems[itemnum].EntryValue=&controls.zBRotate;
541   ConfMenuItems[itemnum].EntryLength=1;
542   ConfMenuItems[itemnum].EntryType=2;
543   ConfMenuItems[itemnum].EntryFunction=SetValue;
544   ConfMenuItems[itemnum].ItemFunction=NULL;
545   itemnum++;
546   strcpy(ConfMenuItems[itemnum].ItemText, "Reverse View Key");
547   strcpy(ConfMenuItems[itemnum].EntryText, "Enter Reverse View Key");
548   ConfMenuItems[itemnum].EntryValue=&controls.rView;
549   ConfMenuItems[itemnum].EntryLength=1;
550   ConfMenuItems[itemnum].EntryType=2;
551   ConfMenuItems[itemnum].EntryFunction=SetValue;
552   ConfMenuItems[itemnum].ItemFunction=NULL;
553   itemnum++;
554   strcpy(ConfMenuItems[itemnum].ItemText, "Save Settings As Defaults");
555   *ConfMenuItems[itemnum].EntryText='\0';
556   ConfMenuItems[itemnum].EntryValue=NULL;
557   ConfMenuItems[itemnum].EntryLength=0;
558   ConfMenuItems[itemnum].EntryType=0;
559   ConfMenuItems[itemnum].EntryFunction=NULL;
560   ConfMenuItems[itemnum].ItemFunction=SaveConfig;
561   itemnum++;
562   strcpy(ConfMenuItems[itemnum].ItemText, "Return To Main Menu");
563   *ConfMenuItems[itemnum].EntryText='\0';
564   ConfMenuItems[itemnum].EntryValue=NULL;
565   ConfMenuItems[itemnum].EntryLength=0;
566   ConfMenuItems[itemnum].EntryType=0;
567   ConfMenuItems[itemnum].EntryFunction=NULL;
568   ConfMenuItems[itemnum].ItemFunction=SetupMainMenu;
569   itemnum++;
570 
571   NumConfMenuItems=itemnum;
572 
573   if (NumConfMenuItems*25 <= ScreenHeight-25) {
574     ConfMenuStartHeight=(ScreenHeight-NumConfMenuItems*25+50)/2;
575   } else {
576     ConfMenuStartHeight=25+25/2;
577   }
578 }
579 
580 
InitScoreMenu()581 void InitScoreMenu()
582 {
583   int itemnum=0;
584 
585   ScoreMenuItemHighlighted=0;
586 
587   strcpy(ScoreMenuItems[itemnum].ItemText, "Clear High Scores");
588   ScoreMenuItems[itemnum].ItemFunction=ClearHighScores;
589   itemnum++;
590   strcpy(ScoreMenuItems[itemnum].ItemText, "Return To Main Menu");
591   ScoreMenuItems[itemnum].ItemFunction=SetupMainMenu;
592   itemnum++;
593 
594   NumScoreMenuItems=itemnum;
595 }
596 
597 
SetupMainDisplay()598 void SetupMainDisplay()
599 {
600   if (TopItemDisplayed > MainMenuItemHighlighted) {
601     TopItemDisplayed=MainMenuItemHighlighted;
602   }
603   BottomItemDisplayed=TopItemDisplayed+(ScreenHeight-50)/25;
604   if (BottomItemDisplayed >= NumMainMenuItems) {
605     BottomItemDisplayed=NumMainMenuItems-1;
606     TopItemDisplayed=BottomItemDisplayed-(ScreenHeight-50)/25;
607     if (TopItemDisplayed < 0) {
608       TopItemDisplayed=0;
609     }
610   }
611   if (BottomItemDisplayed < MainMenuItemHighlighted) {
612     TopItemDisplayed+=MainMenuItemHighlighted-BottomItemDisplayed;
613     BottomItemDisplayed=MainMenuItemHighlighted;
614   }
615 }
616 
617 
SetupConfDisplay()618 void SetupConfDisplay()
619 {
620   if (TopItemDisplayed > ConfMenuItemHighlighted) {
621     TopItemDisplayed=ConfMenuItemHighlighted;
622   }
623   BottomItemDisplayed=TopItemDisplayed+(ScreenHeight-50)/25;
624   if (BottomItemDisplayed >= NumConfMenuItems) {
625     BottomItemDisplayed=NumConfMenuItems-1;
626     TopItemDisplayed=BottomItemDisplayed-(ScreenHeight-50)/25;
627     if (TopItemDisplayed < 0) {
628       TopItemDisplayed=0;
629     }
630   }
631   if (BottomItemDisplayed < ConfMenuItemHighlighted) {
632     TopItemDisplayed+=ConfMenuItemHighlighted-BottomItemDisplayed;
633     BottomItemDisplayed=ConfMenuItemHighlighted;
634   }
635 }
636 
637 
638 // Handle item selected from main menu
MainMenuItemSelected()639 void MainMenuItemSelected()
640 {
641   MainMenuItems[MainMenuItemHighlighted].ItemFunction();
642 }
643 
644 
ConfMenuItemSelected()645 void ConfMenuItemSelected()
646 {
647   if (ConfMenuItems[ConfMenuItemHighlighted].EntryFunction) {
648     ConfMenuItems[ConfMenuItemHighlighted].EntryFunction(ConfMenuItems[ConfMenuItemHighlighted].EntryText,
649                                                          ConfMenuItems[ConfMenuItemHighlighted].EntryValue,
650                                                          ConfMenuItems[ConfMenuItemHighlighted].EntryLength,
651                                                          ConfMenuItems[ConfMenuItemHighlighted].EntryType);
652   } else if (ConfMenuItems[ConfMenuItemHighlighted].ItemFunction) {
653     ConfMenuItems[ConfMenuItemHighlighted].ItemFunction();
654   }
655 }
656 
657 
ScoreMenuItemSelected()658 void ScoreMenuItemSelected()
659 {
660   ScoreMenuItems[ScoreMenuItemHighlighted].ItemFunction();
661 }
662 
663 
SetValue(char * ValueText,void * Value,int ValueLength,int type)664 void SetValue(char *ValueText, void *Value, int ValueLength, int type)
665 {
666   if (type==0) {
667     SetText(ValueText, (char *)Value, ValueLength);
668   } else if (type==1) {
669     SetIntText(ValueText, (int *)Value, ValueLength);
670   } else {
671     SetKey(ValueText, (char *)Value);
672   }
673 }
674 
675 
SetKey(char * KeyId,char * Key)676 void SetKey(char *KeyId, char *Key)
677 {
678   strcpy(KeyName, KeyId);
679   KeyValue=Key;
680 
681   glutKeyboardFunc(SetKeyValueKey);
682   glutSpecialFunc(NULL);
683   glutIdleFunc(NULL);
684   glutDisplayFunc(SetKeyValue);
685   SetKeyValue();
686 }
687 
688 
SetText(char * TextId,char * Text,int MaxLength)689 void SetText(char *TextId, char *Text, int MaxLength)
690 {
691   strcpy(TextName, TextId);
692   TextValue=Text;
693   MaxTextLength=MaxLength;
694 
695   glutKeyboardFunc(TextEntryKey);
696   glutSpecialFunc(NULL);
697   glutIdleFunc(NULL);
698   glutDisplayFunc(TextEntry);
699   TextEntry();
700 }
701 
702 
SetIntText(char * TextId,int * Value,int MaxLength)703 void SetIntText(char *TextId, int *Value, int MaxLength)
704 {
705   strcpy(TextName, TextId);
706   IntValue=Value;
707   MaxTextLength=MaxLength;
708 
709   glutKeyboardFunc(IntTextEntryKey);
710   glutSpecialFunc(NULL);
711   glutIdleFunc(NULL);
712   glutDisplayFunc(IntTextEntry);
713   IntTextEntry();
714 }
715 
716 
SetupMainMenu()717 void SetupMainMenu()
718 {
719   glutKeyboardFunc(MainMenuKey);
720   glutKeyboardUpFunc(NULL);
721   glutSpecialFunc(MainMenuSpecialKey);
722   glutIdleFunc(NULL);
723   glutDisplayFunc(MainMenu);
724   MainMenu();
725 }
726 
727 
SetupConfMenu()728 void SetupConfMenu()
729 {
730   glutKeyboardFunc(ConfMenuKey);
731   glutSpecialFunc(ConfMenuSpecialKey);
732   glutIdleFunc(NULL);
733   glutDisplayFunc(ConfMenu);
734   ConfMenu();
735 }
736 
737 
SetupScoreMenu()738 void SetupScoreMenu()
739 {
740   glutKeyboardFunc(ScoreMenuKey);
741   glutSpecialFunc(ScoreMenuSpecialKey);
742   glutIdleFunc(NULL);
743   glutDisplayFunc(ScoreMenu);
744   ScoreMenu();
745 }
746 
747 
StartSingleGame()748 void StartSingleGame()
749 {
750   pthread_attr_t attr;
751 
752   if (!ServerStarted) {
753     playsound(PrizeSound);
754     glutSpecialFunc(NULL);
755     glutKeyboardFunc(KeyDown);
756     glutKeyboardUpFunc(KeyUp);
757     glutIdleFunc(RunGame);
758     glutDisplayFunc(RunGame);
759 
760     InitMatrixMode();
761     SetupGameMatrixMode();
762     strcpy(ServerIP, "127.0.0.1");
763     ServerPort=12345;
764 
765     pthread_attr_init(&attr);
766     pthread_attr_setdetachstate(&attr, !PTHREAD_CREATE_DETACHED);
767     if (pthread_create(&ServerThread, &attr, Server, NULL)) {
768       printf("Pthread error\n");
769       exit(1);
770     }
771     pthread_attr_destroy(&attr);
772 
773     ServerStarted=1;
774     GameStop=0;
775     sleep(1);
776     NewGame();
777   } else {
778     playsound(ErrorSound);
779   }
780 }
781 
782 
StartMultiGame()783 void StartMultiGame()
784 {
785   playsound(PrizeSound);
786   glutSpecialFunc(NULL);
787   glutKeyboardFunc(KeyDown);
788   glutKeyboardUpFunc(KeyUp);
789   glutIdleFunc(RunGame);
790   glutDisplayFunc(RunGame);
791   InitMatrixMode();
792   SetupGameMatrixMode();
793   GameStop=0;
794   NewGame();
795 }
796 
797 
StartServer()798 void StartServer()
799 {
800   pthread_attr_t attr;
801 
802   if (!ServerStarted) {
803     playsound(PrizeSound);
804 
805     pthread_attr_init(&attr);
806     pthread_attr_setdetachstate(&attr, !PTHREAD_CREATE_DETACHED);
807     if (pthread_create(&ServerThread, &attr, Server, (void *)1)) {
808       printf("Pthread error\n");
809       exit(1);
810     }
811     pthread_attr_destroy(&attr);
812 
813     ServerStarted=1;
814     sleep(1);
815   } else {
816     playsound(ErrorSound);
817   }
818 }
819 
820 
KillServer()821 void KillServer()
822 {
823   if (ServerStarted) {
824     ServerStarted=1;
825     StopServer=1;
826     pthread_join(ServerThread, NULL);
827   } else {
828     playsound(ErrorSound);
829   }
830 }
831 
832 
QuitGame()833 void QuitGame()
834 {
835   exit(0);
836 }
837