1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <time.h> 5 #include <ctype.h> 6 #include <sys/time.h> 7 #include <sys/types.h> 8 #include <sys/uio.h> 9 #include <X11/Intrinsic.h> 10 #include <X11/X.h> 11 #include <X11/Xlib.h> 12 #include <X11/Xutil.h> 13 #include <X11/Xos.h> 14 #include <X11/StringDefs.h> 15 #include <X11/Shell.h> 16 #include <X11/cursorfont.h> 17 #include <X11/keysym.h> 18 #include <X11/keysymdef.h> 19 20 #include "functionsdef.h" 21 22 /* Font-sizes.... Not aa good way to do it */ 23 #define FONTH 10 24 #define FILLH 3 25 #define FONTB 6 26 27 /* Maximal number of map-strings */ 28 #define MAX_MAPS 999 29 30 /* Max lengt of misc strings */ 31 #define MAXLEN_NMISC 31 32 #define MAXLEN_MISC 255 33 34 /* Max and min length of your name */ 35 #define MAXLEN_NPLAYER 9 36 #define MINLEN_NPLAYER 1 37 #define WIDTH_NMISC MAXLEN_NMISC*FONTB 38 39 /* Shuffle cards with or without "joker" */ 40 #define WITH_JOKER 1 41 #define NO_JOKER 0 42 43 /* Last argument to functions with varargs */ 44 #define LAST_ARG (char *)0xffff 45 46 /* The name of all windows ( See also <files>.mapping ) */ 47 #define CARD_WIN_NAME "#024_Cards - information" 48 #define INFO_WIN_NAME "#043_Risk - information" 49 #define WINNAME "#049_XRISK" 50 51 /* Used to describe the cards (window) */ 52 #define UNITX 120 /* Width pic of soldier */ 53 #define UNITY 100 /* Height pic of soldier */ 54 #define BORDERX 120 /* Width pic of borders */ 55 #define BORDERY 120 /* Height pic of borders */ 56 #define CARDS_MAX_PLAYER 50 /* Max number of cards player */ 57 #define CARDS_MAX_SHOWN 10 /* Max number of cards shown */ 58 #define CARDS_ROW 5 /* Cards in each row */ 59 #define C_FRAME 1 /* Width of frame */ 60 #define C_WIDTH 120 /* Width of cards */ 61 #define C_HEIGHT 240 /* Height of cards */ 62 #define CF_WIDTH (C_WIDTH+2*C_FRAME) /* Width of card with frame */ 63 #define CF_HEIGHT (C_HEIGHT+2*C_FRAME)/* Height of card w. frame */ 64 #define C_SPACE 3 /* Space between cards */ 65 #define C_BUTTONH 2*FONTH /* Height of but. to press */ 66 #define C_BUTTONW C_WIDTH /* Width of but. to press */ 67 #define CF_BUTTONW (C_BUTTONW+2*C_FRAME) /* Width with frame */ 68 #define CF_BUTTONH (C_BUTTONH+2*C_FRAME) /* Height with frame */ 69 #define UNIT0 "#161_artillery" /* Names */ 70 #define UNIT1 "#162_infantry" /* Names */ 71 #define UNIT2 "#163_cavalry" /* Names */ 72 #define JOKER "#164_joker" /* Names */ 73 #define V_UNIT0 1 /* Used to identify cards when exchanging */ 74 #define V_UNIT1 10 /* Used to identify cards when exchanging */ 75 #define V_UNIT2 100 /* Used to identify cards when exchanging */ 76 #define V_JOKER 1000 /* Used to identify cards when exchanging */ 77 78 /* Used to descrbe map-window */ 79 #define XSIZE 800 /* Width of map */ 80 #define YSIZE 800 /* Height of map */ 81 #define TEXTX 80 /* Where to write position of cursor */ 82 #define TEXTY 750 /* Where to write position of cursor */ 83 #define MSGX (TEXTX+WIDTH_NMISC) /* Where to write private */ 84 #define MSGY (TEXTY) /* messages */ 85 #define MSGLEN (XSIZE-MSGX) /* And the length of them */ 86 #define SCWINX 410 /* Where to place the */ 87 #define SCWINY 0 /* scroll - window */ 88 #define SCWINL (XSIZE-2-SCWINX) /* And the size */ 89 #define SCWINH 100 /* of it */ 90 #define SCWINR 1 /* Thickness of frame */ 91 #define SCLINES (SCWINH/(FONTH+FILLH)) /* Number of lines */ 92 #define MENU_H 17 /* Hight menu buttons upper left */ 93 #define MENU_B 150 /* Width menu buttons upper left */ 94 95 /* How do write a sentence */ 96 #define CENTER 1 /* Senter it */ 97 #define CLR 2 /* Clear a box with specified size before */ 98 #define DRAWIMAGESTRING 4 /* Use XDrawImageString */ 99 #define BACKCOLOR 42 /* Color of ocean's and backround */ 100 #define FORECOLOR 43 /* Color of borders and writing */ 101 102 /* Several options ( Most of them yet to be implemented )*/ 103 #define MISSION 0x0001 /* Want missions ? */ 104 #define GET_CARDS_ON_KILL 0x0002 /* Get cards from your victims */ 105 #define LOOSE_CARDS_ON_SUICIDE 0x0004 /* Explains itself */ 106 #define SEQ_PLACEMENT_START 0x0008 /* Or paralell plasement */ 107 #define NO_SUICIDE 0x0010 /* Let players kill themself */ 108 #define VOTE_FOR_SUICIDE 0x0020 /* Semi - suicide - solution */ 109 #define ONE_ARMY_EACH_COUNTRY 0x0040 /* Initially armies on the map */ 110 #define ENABLE_TALK_WINDOW 0x0080 /* Automaticly start xmtalk ? */ 111 #define CARD_WINDOW_SMALL 0x0100 /* Get aa small cardswindow */ 112 #define GET_CARD_REL_ARMIES 0x0200 /* Why not ??? */ 113 #define TWO_ACTIVE_PLAYERS 0x0400 /* Two active players(buggy) */ 114 #define DEFAULT_OPTIONS MISSION /* Default settings */ 115 116 /* Individual temporary options available to each player ( Buttons ) */ 117 #define DO_OR_DIE 1 118 119 /* For the user to define */ 120 #define ARMIES_START 30 /* Armies to start with */ 121 #define MAX_ARMIES_START 7 /* Max. armies in each county when we start */ 122 #define FREE_MOVES 7 /* Max. free moves */ 123 124 /* The information - window */ 125 #define WIDTH_BUTT 19 /* Width button */ 126 #define SPACE 2 /* Space between buttons */ 127 #define FRAME 1 /* With of frame */ 128 #define CHAR_WIDTH_COL 11 /* Max. number of characters in colomn */ 129 #define WIDTH_COL (CHAR_WIDTH_COL*FONTB+FRAME) /* Width colomn */ 130 #define START_COL (WIDTH_BUTT+2*(SPACE+FRAME)) /* First colomn */ 131 #define HEIGHT_ROWS (WIDTH_BUTT+SPACE+2*FRAME) /* Hight colomn */ 132 #define DX_KOL (WIDTH_COL-FRAME) /* Area to clear in colomn */ 133 #define START_TEXT_X (START_COL+FRAME) /* Where to place text */ 134 #define START_TEXT_Y ((HEIGHT_ROWS+FONTH)/2+FILLH) /* in x,y coords */ 135 #define NUM_COL 8 /* Number of colums */ 136 #define U_NAME_PLAYER 0 /* Update name of player */ 137 #define U_COUNTRIES 1 /* Update name of coutries */ 138 #define U_CONTINENTS 2 /* Update numb of continents */ 139 #define U_CARDS 3 /* Update numb of cards */ 140 #define U_ARMIES 4 /* Update numb of forces */ 141 #define U_ARMIES_LOST 5 /* Update numb of forces lost */ 142 #define U_ARMIES_KILLED 6 /* Update numb of forces killed */ 143 #define U_ARMIES_GAINED 7 /* Update numb of forces gained */ 144 #define O_ALL 8 /* Update all fields */ 145 #define ALL_THE_TEXT {"#039_Name","#026_Country","#037_Continent","#023_Card","#019_Armies","#038_Lost","#036_Killed","#031_Gained"} /* Text */ 146 147 /* How to update infowin and some other places when we get/loose/move armies */ 148 #define UPDATE 1 /* These armies we gained or lost */ 149 #define NO_UPDATE 0 /* These armies we are just moving */ 150 151 /* Defining defining */ 152 #define NUM_COLORS 64 /* Numbers of colors we allocate */ 153 #define NUM_COUNTRIES 42 /* Numbers of countries on the map */ 154 #define MAX_MISSIONS 20 /* Number of missions (max) */ 155 #define NUM_CONTINENTS 6 /* Number of continents */ 156 #define NUM_JOKERS 2 /* Numbers of jokers */ 157 #define NUM_CARDS (NUM_COUNTRIES+NUM_JOKERS) /* Number of cards */ 158 #define MAX_PLAYERS 8 /* Maximum number of players */ 159 160 /* To avoid problems whith litte/big - endian when saving integers on disc */ 161 #define Fgetint(i,s,t) for((i)=0,t=3;t>=0;t--) (i)+=(fgetc(s)<<(t*8)) 162 #define Fputint(i,s,t) for(t=3;t>=0;t--) fputc((char)(((i)>>(t*8))&255),s) 163 164 #define Do_each_player(t) for(t=0;t<MAX_PLAYERS;t++) if (players[t]) 165 #define Switch(p1,p2,t) do{(t)=(p1) ; (p1)=(p2) ; (p2)=(t) ;}while(0) 166 #define Get_index_coord(x,y) map[(x)+(y)*XSIZE] 167 #define Random(i) ( (unsigned) (i*ran1())) 168 #define Throw_dice() (Random(6)+1) 169 #define Min(a,b) ((a)<(b)?(a):(b)) 170 #define Max(a,b) ((a)>(b)?(a):(b)) 171 #define Chosen(I,i) ( (I) & (1<< (i)) ) 172 #define Choose(I,i) ( (I) ^= (1<< (i)) ) 173 #define Clr(I,i) ( (I) &= (255^(i)) ) 174 #define SetFlag(s,i) ( (s->attr.attr_game) |= (i) ) 175 #define ClrFlag(s,i) ( (s->attr.attr_game) &= (255^(i)) ) 176 #define SwitchFlag(s,i) ( (s->attr.attr_game) ^= (i) ) 177 #define FlagSet(s,i) ( (s->attr.attr_game) & (i) ) 178 #define GetEvent(s) ( (s)->pstat->event ) 179 #define GetEventp(s) ( &((s)->pstat->event) ) 180 #define RegEvent(s) XCheckMaskEvent(s->xcon->disp,\ 181 KeyPressMask|ButtonPressMask|ExposureMask,\ 182 &(s->pstat->event)) 183 #ifndef XRASDIR 184 #define XRASDIR "/home/lise1d/nordeng/src/c/risk/xras" 185 #endif 186 #ifndef MAPDIR 187 #define MAPDIR "/home/lise1d/nordeng/src/c/risk/languages" 188 #endif 189 #ifndef DATAFILE 190 #define DATAFILE "/home/lise1d/nordeng/src/c/risk/data/risk.data" 191 #endif 192 #ifndef LANGUAGE 193 #define LANGUAGE "norwegian" 194 #endif 195 #define PICTURFILE "#156_world" 196 #define EXTENTION ".xras" 197 198 199 #define Country Card /* Use same struct to represent a card and a country */ 200 201 typedef unsigned char byte; 202 typedef struct Country *countryp; 203 typedef struct Continent *continentp; 204 typedef struct Player *playerp; 205 typedef struct Mission *missionp; 206 typedef struct Xcon *xconp; 207 typedef struct Info_Win *info_winp; 208 typedef struct Card_Win *card_winp; 209 typedef struct Card *cardp; 210 typedef struct PStat *pstatp; 211 typedef struct Action *actionp; 212 typedef struct State *statep; 213 typedef struct Risk_Cursors *risk_cursorsp; 214 typedef struct Actions_Other_Win *actions_other_winp; 215 typedef struct Button_Actions *button_actionsp; 216 typedef struct Control_Actions *control_actionsp; 217 typedef struct Control_Data *control_datap; 218 typedef struct All_Actions *all_actionsp; 219 220 /* These options should be possible to set when starting the game */ 221 struct Game_Options 222 { 223 int armies_start; /* Number of armies to distribute initially */ 224 int max_armies_start; /* Max. numb. of armies in each country initially */ 225 int options; /* Several options defined above (bits/flags) */ 226 char *language; /* What language to use */ 227 }; 228 229 /* The structure parsed by the function do_action */ 230 struct Action 231 { 232 int (*func)(); /* Which function to call */ 233 int next_state[2]; /* Which state is next if any state at all */ 234 }; 235 236 /* Functions controlling the behaviour of the game */ 237 struct Control_Actions 238 { 239 int index; /* Which control action */ 240 int index_next; /* Which control action next */ 241 int c_state; /* Which player-state to check for */ 242 int (*c_func)(); /* The control-action */ 243 int next_state; /* Which stat to give the player .... */ 244 }; 245 246 /* A table to show where the players are and the control-state */ 247 struct Control_Data 248 { 249 int *who_where; /* Players in the state we're watching */ 250 control_actionsp control_action; /* See above */ 251 }; 252 253 /* What to do if we get a button-event */ 254 struct Button_Actions 255 { 256 struct Action action_mB1; /* Button-event for mouse-buton1 */ 257 struct Action action_mB2; /* Button-event for mouse-buton2 */ 258 struct Action action_mB3; /* Button-event for mouse-buton3 */ 259 }; 260 261 /* Actions beloning to the map-window */ 262 struct All_Actions 263 { 264 int state; /* Which state this is */ 265 int next_state; /* Next natural state */ 266 struct Action init_func; /* Function to initialize state */ 267 struct Action func; /* Function to call continously */ 268 struct Button_Actions map_but_actions; /* Handling of mouse-events */ 269 struct Action action_kB; /* Handling of keypress-events */ 270 struct Action spec_func; /* Handling of special event */ 271 struct Action exit_func; /* Function when exiting state */ 272 }; 273 274 275 /* Attach events to a Window */ 276 struct Actions_Other_Win 277 { 278 int index; /* Intern index of this window */ 279 struct Button_Actions button_actions; /* Actions when events in window */ 280 }; 281 282 /* Which cursors we want to use */ 283 struct Cursor_Table 284 { 285 int index; /* Intern index of this cursor */ 286 unsigned int shape; /* The shape of the cursor */ 287 }; 288 289 /* Which cursor to which window and in what state */ 290 struct Risk_Cursors 291 { 292 int state; /* Which state */ 293 int map; /* Cursor in map-window */ 294 int cards; /* Cursor in card-window */ 295 int info; /* Cursor in info-window */ 296 int scroll; /* Cursor in scroll_window */ 297 }; 298 299 /* All information needed about each state */ 300 struct State 301 { 302 int state; /* Index of state */ 303 int *who_where; /* Players in this state */ 304 all_actionsp all_actions; /* Actions in mapwindow */ 305 actions_other_winp actions_other_win; /* Actions in other windows */ 306 risk_cursorsp risk_cursors; /* Cursors belonging to this state */ 307 }; 308 309 /* Some data used by functions called, more like a working area */ 310 struct PStat 311 { 312 playerp player; 313 int return_state; 314 XEvent event; /* What event was the last */ 315 char genstring[1024]; /* Used when getting text from player */ 316 char *string[1024]; /* Might need some more strings */ 317 Window win; /* Usely the window in which to write */ 318 int flags,strlen,strmin,strmax,x,y,dx,dy; /* Getting text */ 319 int clear_field; /* Want to clear field after used it ? */ 320 unsigned long fc,bc; /* Foregroundcolor, Backgroundcolor */ 321 countryp country,from,target;/* Move/attack/misc. from -> target */ 322 int flag,armies_max,armies_min,armies_left,armies_move; /* sth */ 323 int (*funk1)(),(*funk2)(),(*funk3)(); /* Might come handsome */ 324 Window spec_win; /* Window in where to expect events */ 325 time_t exit_press; /* Last press in suecide-window ?? */ 326 }; 327 328 /* This attributes is uniq to each player and changable during play */ 329 typedef struct 330 { 331 int attr_game; /* Do or die, etc. */ 332 int attack_armies; /* Number of attacking armies */ 333 } Attribs; 334 335 /* Information about the card-window */ 336 struct Card_Win 337 { 338 playerp player; /* Who owns it */ 339 XSetWindowAttributes attr; /* Attributes */ 340 unsigned long attrmask; /* Attribute-mask */ 341 XSizeHints *s_h; /* Size of window */ 342 Window win; /* Window id */ 343 struct Card **card; /* Cards it holds */ 344 XImage *aimage[3]; /* Images of avelinger */ 345 XImage *gimage[CARDS_MAX_PLAYER]; /* Images of countries */ 346 XSizeHints *k_h[CARDS_MAX_SHOWN]; /* Size subwindows */ 347 XSizeHints *b_h[CARDS_MAX_SHOWN]; /* Size subwindows */ 348 Window cards[CARDS_MAX_SHOWN]; /* Subwindow id's */ 349 Window buttons[CARDS_MAX_SHOWN]; /* Subwindow id's */ 350 int chosen,exchange,allow_ch; /* Some status-information */ 351 }; 352 353 /* Information concerning the info-window */ 354 struct Info_Win 355 { 356 XSetWindowAttributes attr; /* Attributes */ 357 unsigned long attrmask; /* Attribute mask */ 358 XSizeHints *s_h,*u_h,*l_h; /* Size of windows */ 359 XWMHints *wmh; /* To set InputHint */ 360 Window win,upper,lower; /* Window id's */ 361 Window button,child[NUM_COLORS]; /* Button window id's */ 362 }; 363 364 /* Information about Xconection and the mapwindow */ 365 struct Xcon 366 { 367 Display *disp; /* Display connected to player */ 368 int scr; /* Screen connected to player */ 369 GC gc; /* Graphic Contest connected to player */ 370 Screen *screen; /* Screen of this player */ 371 Window win,root,scrollwin,menu_butt[MENU_NUMB]; /* Windows */ 372 XImage *ximage; /* Image of the map */ 373 XSetWindowAttributes attr; /* Attributes when opening the mapwindow */ 374 unsigned long attrmask; /* Which attributes we whish to set */ 375 Visual *visual; /* Visual connected to player */ 376 unsigned int depth; /* Depth of screen */ 377 Colormap cmap; /* Common colormap to all windows */ 378 Cursor cursors[NUMB_CURSORS]; /* List of all cursors */ 379 unsigned long pixm[NUM_COLORS]; /* List of all colors */ 380 unsigned long black,white; /* Very special colors */ 381 int indexs; /* Index of this player */ 382 }; 383 384 /* Information about each player */ 385 struct Player 386 { 387 char name[MAXLEN_NPLAYER+1]; /* The players name */ 388 char client[MAXLEN_NMISC+1]; /* Name of the players machine */ 389 XColor *colors[MAX_PLAYERS]; /* Colortable of all players */ 390 struct Card *card[CARDS_MAX_PLAYER+1]; /* Possesed cards */ 391 struct Country *conquests[NUM_COUNTRIES+1]; /* List of conquests */ 392 missionp mission; /* The players mission or NULL */ 393 xconp xcon; /* Connection to X-server */ 394 card_winp card_win; /* Cards-window */ 395 info_winp info_win; /* Information-window */ 396 statep state; /* Pointer to state */ 397 pstatp pstat; /* State-working-area */ 398 Attribs attr; /* Changable attributes */ 399 int offensiv; /* Have i been offensive ?? */ 400 int num_cards; /* Number of cards I've got */ 401 int num_conquests; /* Number of conguests */ 402 int num_continents; /* Number of continents */ 403 int num_armies_gained; /* Total num. of armies gained */ 404 int num_armies,armies_lost,armies_killed; /* Statistics */ 405 int indexs; /* Index of this player */ 406 }; 407 408 /* Info about missions */ 409 struct Mission 410 { 411 char sentence[MAXLEN_MISC+1]; /* The mission written out */ 412 playerp victim; /* Who to kill */ 413 struct Continent **conquestscont; /* Which continents to conquer */ 414 int conquestsc; /* How many countries to conquer */ 415 int army; /* How many armies in each country */ 416 }; 417 418 /* Information about each coutry/card */ 419 struct Country 420 { 421 char name[MAXLEN_NMISC+1]; /* Name of country */ 422 playerp occupant; /* Who is the ocupant */ 423 int number; /* Number of armies */ 424 struct Country **neighbours; /* What neigbours */ 425 continentp continent; /* In what continent */ 426 char unit[MAXLEN_NMISC+1]; /* Name army unit */ 427 int indexunit; /* Index of unit */ 428 char *border; /* Borderpicture raster */ 429 int x,y; /* Something */ 430 int indexl; /* Index of land */ 431 int value; /* When changing cards */ 432 }; 433 434 /* Info about each continent */ 435 struct Continent 436 { 437 char name[MAXLEN_NMISC+1]; /* Name of continent */ 438 struct Country **countries; /* Countries in continent */ 439 int weight; /* Armies to get on conquest */ 440 }; 441 442 extern struct Player *players[MAX_PLAYERS+1]; /* List of all players */ 443 extern struct Card *cards[NUM_CARDS+1]; /* List of cards not out */ 444 extern struct Continent continents[NUM_CONTINENTS]; /* List of continents*/ 445 extern struct Mission *missions[MAX_MISSIONS+1]; /* List of missions */ 446 extern struct Country countries[NUM_COUNTRIES]; /* List of countries */ 447 extern struct Continent free_choise; /* Continent of free choice */ 448 extern struct Country Joker; /* The joker */ 449 extern XColor colors[MAX_PLAYERS]; /* Basis color-table */ 450 extern char *sentencemapping[MAX_MAPS]; /* List of mappings */ 451 extern char *map; /* Byte-representation of map */ 452 extern char *unitp[3]; /* Byte-representation of units */ 453 extern int num_players; /* Players still alive */ 454 extern struct State *states[NUM_STATES]; /* Availible states */ 455 extern struct Control_Data control_data; /* Status of the game */ 456 extern int who_where[NUM_STATES];/* Which player, what state*/ 457 extern struct Game_Options game_options; /* Options in this game */ 458