1 /************************************************************\
2 *                                                            *
3 *                      RISK  -  for X11                      *
4 *                                                            *
5 *            Lasse \O verlier <lasse@pvv.unit.no>            *
6 *        Hans Kristian Nordengen <nordeng@pvv.unit.no>       *
7 *                                                            *
8 \************************************************************/
9 
10 #include "xrisk.h"
11 #include "xriskex.h"
12 #include "risklibex.h"
13 #include "randomex.h"
14 #include "init_riskex.h"
15 #include "init_playex.h"
16 #include "functionsex.h"
17 #include "cursors2.h"
18 #include "actions_menu_but.h"
19 #include "cardex.h"
20 #include "actions_menu_butex.h"
21 #include "control_statesex.h"
22 #include "xrisklibex.h"
23 #include "parseoptex.h"
24 #include "errorhandlersex.h"
25 
26 struct Player       *players[MAX_PLAYERS+1]; /* List of all players   */
27 struct Card         *cards[NUM_CARDS+1];     /* List of cards not out */
28 struct Continent     continents[NUM_CONTINENTS]; /* List of continents*/
29 struct Mission      *missions[MAX_MISSIONS+1];   /* List of missions  */
30 struct Country       countries[NUM_COUNTRIES];   /* List of countries */
31 struct Continent     free_choise;         /* Continent of free choice */
32 struct Country       Joker;               /* The joker                */
33 XColor               colors[MAX_PLAYERS]; /* Basis color-table        */
34 char                *sentencemapping[MAX_MAPS];  /* List of mappings  */
35 char                *map;             /* Byte-representation of map   */
36 char                *unitp[3];        /* Byte-representation of units */
37 int                  num_players;     /* Players still alive          */
38 struct State        *states[NUM_STATES];   /* Availible states        */
39 struct Control_Data  control_data;         /* Status of the game      */
40 int                  who_where[NUM_STATES];/* Which player, what state*/
41 struct Game_Options  game_options;         /* Options in this game    */
42 
43 /* Check if player has to change cards */
check_cards(player)44 int check_cards(player)
45      playerp player;
46 {
47   int state;
48   state = player->state->state;
49 
50   if (   (player->num_cards < 5)  || (state <= WAIT_FOR_ALL_1)
51       || (state == WAIT_FOR_TURN) || (state == START_TURN)
52       || (state == P_A_WHERE)     || (state == P_A_STRENG)
53       || (state == P_A_NUMBER)    || (state == P_A_PLACE)
54       || (state == ATTACK_LAND)   || (state == A_STRENG)
55       || (state == A_NUMBER)      || (state == END_GAME)
56       || (state == CLOSE_GAME)) return(0);
57 
58   player->pstat->armies_left = 0;
59   new_state(player,P_A_WHERE);
60   player->card_win->allow_ch = 2;
61   exchange_card(player);
62   return(0);
63 }
64 
65 /* Parse an action */
do_action(player,action)66 int do_action(player, action)
67      playerp player;
68      actionp action;
69 {
70   int i;
71 
72   if (!action->func) return(0);
73   if ((!(action)) || (! (i=(action->func)(player)) )) return(0);
74   new_state(player,action->next_state[i-1]);
75   return(1);
76 }
77 
78 /* Initialize a new player-state */
new_state(player,next_state)79 int new_state(player, next_state)
80      playerp player;
81      int next_state;
82 {
83   xconp xinfo;
84   xinfo = player->xcon;
85 
86   if (!do_action(player,&(player->state->all_actions->exit_func)))
87     {
88       (who_where[player->state->state]) ^= (1<<player->indexs);
89       player->state                      = states[next_state];
90       (who_where[next_state])           ^= (1<<player->indexs);
91 
92       if (xinfo)
93 	{
94 	  if (all_cursors[next_state].map    != NUMB_CURSORS) XDefineCursor
95 	    (xinfo->disp,xinfo->win,
96 	     xinfo->cursors[all_cursors[next_state].map]);
97 	  if (all_cursors[next_state].cards  != NUMB_CURSORS) XDefineCursor
98 	    (xinfo->disp,player->card_win->win,
99 	     xinfo->cursors[all_cursors[next_state].cards]);
100 	  if (all_cursors[next_state].info   != NUMB_CURSORS) XDefineCursor
101 	    (xinfo->disp,player->info_win->win,
102 	     xinfo->cursors[all_cursors[next_state].info]);
103 	  if (all_cursors[next_state].scroll != NUMB_CURSORS) XDefineCursor
104 	    (xinfo->disp,xinfo->scrollwin,
105 	     xinfo->cursors[all_cursors[next_state].scroll]);
106 	}
107       do_action(player,&(player->state->all_actions->init_func));
108     }
109   return(1);
110 }
111 
112 /* Parsing when a player press a button */
parse_buttons(player,actions)113 int parse_buttons(player, actions)
114      playerp player;
115      button_actionsp actions;
116 {
117   XEvent *eventp;
118 
119   eventp = GetEventp(player);
120   if (eventp->type == KeyPress) do_action
121     (player,&(player->state->all_actions->action_kB));
122   else
123     if (eventp->type == ButtonPress)
124       {
125 	if (eventp->xbutton.button == Button1)
126 	  do_action(player,&(actions->action_mB1));
127 
128 	else if (eventp->xbutton.button == Button2)
129 	  do_action(player,&(actions->action_mB2));
130 
131 	else if (eventp->xbutton.button == Button3)
132 	  do_action(player,&(actions->action_mB3));
133       }
134   return(0);
135 }
136 
137 /* Always return 1 */
chk_allways()138 int chk_allways()
139 {
140   return(1);
141 }
142 
143 /* Stand here and parse events */
xrisk_mainloop()144 void xrisk_mainloop()
145 {
146   xconp    xinfo;
147   statep   state;
148   playerp  player;
149   int      t,t1;
150   int      eventType;
151   Window   eventWindow;
152 
153   while(!(control_data.control_action->c_func)())
154     Do_each_player(t) if
155       ((!do_action(players[t],&(players[t]->state->all_actions->func)))
156        && (players[t]->xcon) && (RegEvent(players[t])))
157 	{
158 	  player      = players[t];
159 	  xinfo       = player->xcon;
160 	  state       = player->state;
161 	  eventType   = GetEventp(player)->type;
162 	  eventWindow = GetEventp(player)->xany.window;
163 
164 	  switch (eventType)
165 	    {
166 	    case KeyPress:
167 	    case ButtonPress:
168 	      if (eventWindow == player->pstat->spec_win) do_action
169 		(player,&(state->all_actions->spec_func));
170 
171 	      else if (eventWindow == xinfo->win) parse_buttons
172 		(player,&(state->all_actions->map_but_actions));
173 
174 	      else if (eventWindow == player->xcon->scrollwin) parse_buttons
175 	       (player,&(state->actions_other_win[SCROLL_WIN].button_actions));
176 
177 	      else if (eventWindow == player->info_win->win) parse_buttons
178 		(player,&(state->actions_other_win[INFO_WIN].button_actions));
179 
180 	      else if (eventWindow == player->card_win->win) parse_buttons
181 		(player,&(state->actions_other_win[CARD_WIN].button_actions));
182 
183 	      else if (eventWindow == xinfo->menu_butt[MENU_WRITE])
184 		get_menu_string(player);
185 
186 	      else for(t1=0;t1<MENU_NUMB;t1++)
187 		if (eventWindow == xinfo->menu_butt[t1])
188 		  parse_buttons(player,&(actions_menu_but[t1].button_actions));
189 
190 	      check_cards(player);
191 	      check_mission(player);
192 	      break;
193 
194 	    case Expose:
195 	      if (eventWindow == xinfo->win)
196 		expose_mapwin(player);
197 
198 	      else if (eventWindow == player->xcon->scrollwin)
199 		{
200 		  if (!GetEventp(player)->xexpose.count)
201 		    write_msg_all((char *)NULL);
202 		}
203 
204 	      else if (eventWindow == player->info_win->upper)
205 		expose_infowin(player);
206 
207 	      else if (eventWindow == player->info_win->lower)
208 		expose_infowin(player);
209 
210 	      else for(t1=0;t1<CARDS_MAX_SHOWN;t1++)
211 		if (eventWindow == player->card_win->buttons[t1])
212 		  {
213 		    expose_card_button(player, t1);
214 		    break;
215 		  }
216 		  else if (eventWindow == player->card_win->cards[t1])
217 		    {
218 		      expose_card_win(player, t1);
219 		      break;
220 		    }
221 
222 	      for(t1=0;t1<MENU_NUMB;t1++)
223 		if (eventWindow == xinfo->menu_butt[t1])
224 		  {
225 		    expose_action_menu(player, t1);
226 		    break;
227 		  }
228 
229 	      break;
230 
231 	    default:
232 	      fprintf(stderr,"Window %d Type %d\n",eventWindow, eventType);
233 	    }
234 	}
235   /* The only way to handle errorsituations is to restart a new
236      xrisk_mainloop for every error that occures */
237   exit(0);
238 }
239 
240 /* Our main-function */
main(argc,argv)241 void main(argc,argv)
242      int argc;
243      char **argv;
244 {
245   int numopt;
246 
247   numopt      = parseopt(argc,argv);
248   num_players = argc-numopt;
249 
250   if ((num_players<2)||(num_players>MAX_PLAYERS))
251     {
252       printf("Mail bugs to xrisk@pvv.unit.no\n");
253 
254       printf("Usage: xrisk [-m] [-d] [-llanguage] ");
255       printf("machine1 machine2 [machine3 ..]\n");
256       printf("-m to disable mission\n");
257       printf("-l to use another language ( norwegian, english, german)\n");
258       printf("-d two players\n");
259       printf("Min : 2 machines \n");
260       printf("Max : 8 machines\n");
261       risk_exit("Your number %d client(s)\n",num_players,LAST_ARG);
262     }
263   map = get_picture(PICTURFILE,XSIZE,YSIZE);
264 
265   init_risk();
266   init_play(&argv[numopt]);
267   init_errorhandlers();
268   xrisk_mainloop();
269 }
270