1 /*
2  *   XFrisk - The classic board game for X
3  *   Copyright (C) 1993-1999 Elan Feingold (elan@aetherworks.com)
4  *
5  *   This program is free software; you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 2 of the License, or
8  *   (at your option) any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *   GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program; if not, write to the Free Software
17  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  *   $Id: gui.c,v 1.12 2000/01/10 22:47:40 tony Exp $
20  *
21  *   $Log: gui.c,v $
22  *   Revision 1.12  2000/01/10 22:47:40  tony
23  *   made colorstuff more private to colormap.c, only scrollbars get set wrong, rest seems to work ok now
24  *
25  *   Revision 1.11  2000/01/09 20:05:02  morphy
26  *   Corrections to color map loading - previously struct padding possibility was ignored
27  *
28  *   Revision 1.10  2000/01/09 19:17:43  morphy
29  *   Added Log tag in comment header
30  *
31  */
32 
33 #include <X11/X.h>
34 #include <X11/Intrinsic.h>
35 #include <X11/StringDefs.h>
36 #include <X11/Shell.h>
37 
38 #include <X11/Xaw/Form.h>
39 #include <X11/Xaw/List.h>
40 #include <X11/Xaw/Label.h>
41 #include <X11/Xaw/AsciiText.h>
42 #include <X11/Xaw/Viewport.h>
43 #include <X11/Xaw/Command.h>
44 #include <X11/Xaw/Toggle.h>
45 #include <X11/Xaw/Box.h>
46 #include <X11/Xaw/Scrollbar.h>
47 
48 #include <stdlib.h>
49 #include <stdio.h>
50 #include <unistd.h>
51 
52 #include "gui-vars.h"
53 #include "gui-func.h"
54 #include "callbacks.h"
55 #include "dice.h"
56 #include "cards.h"
57 #include "colormap.h"
58 #include "utils.h"
59 #include "debug.h"
60 #include "types.h"
61 #include "version.h"
62 #include "colorEdit.h"
63 #include "registerPlayers.h"
64 #include "addPlayer.h"
65 #include "viewCards.h"
66 #include "viewStats.h"
67 #include "viewFeedback.h"
68 #include "viewLog.h"
69 #include "viewStats.h"
70 #include "viewChat.h"
71 
72 
73 /* Main window widgets */
74 static Widget wMap;
75 static Widget wCurrentPlayer;
76 Widget wToplevel;
77 Widget wDiceBox, wMsgDestList, wErrorLabel;
78 Widget wActionList, wAttackList;
79 Widget wSendMsgText;
80 Widget wMsgText, wCommentLabel;
81 
82 /* Main stuff */
83 XtAppContext  appContext;
84 
85 
86 /* The view cards popup shell */
87 Widget wCardShell;
88 Widget wCardToggle[MAX_CARDS];
89 
90 /* The "place armies" popup shell */
91 Widget wArmiesShell, wArmiesText, wCancelArmiesButton;
92 
93 /* The "help" popup shell */
94 Widget wHelpShell;
95 Widget wHelpTopicList, wHelpLabel, wHelpText;
96 
97 /* The "generic popup" dialog */
98 Widget wDialogLabel, wDialogButton[3];
99 Widget wDialogShell;
100 
101 /* Action tables */
102 static XtActionsRec actionTable[] =
103 {
104   { "popupArmies",      (XtActionProc)UTIL_QueryYes },
105   { "mapClick",         (XtActionProc)CBK_MapClick },
106   { "mapShiftClick",    (XtActionProc)COLEDIT_MapShiftClick },
107   { "sendMessage",      (XtActionProc)CBK_SendMessage },
108   { NULL, NULL }
109 };
110 
111 #ifdef ENGLISH
112 static char *pstrAttackDice[] =
113 {
114   "1 die",
115   "2 dice",
116   "3 dice",
117   "Auto",
118 };
119 #endif
120 #ifdef FRENCH
121 static char *pstrAttackDice[] =
122 {
123   "1 d�",
124   "2 d�s",
125   "3 d�s",
126   "Auto",
127 };
128 #endif
129 
130 #ifdef ENGLISH
131 static char *pstrActions[] =
132 {
133   "Place",
134   "Attack",
135   "Do or die",
136   "move",
137 };
138 #endif
139 #ifdef FRENCH
140 static char *pstrActions[] =
141 {
142   "Placer",
143   "Attaquer",
144   "� mort",
145   "D�placer",
146 };
147 #endif
148 
149 /* Private functions */
150 static Int32 GUI_GetNumColorsInMap(CString strMapFile);
151 
152 Display        *hDisplay;
153 Window          hWindow;
154 GC              hGC, hGC_XOR;
155 Int32           iScreen;
156 XFontStruct    *pFont;
157 Pixmap          pixMapImage;
158 XImage         *pMapImage;
159 Visual         *pVisual;
160 
161 /* These are used to set up the visual in all shell widgets */
162 Int32           iVisualCount;
163 Arg             pVisualArgs[3];
164 
165 /************************************************************************
166  *  FUNCTION: GUI_Setup
167  *  HISTORY:
168  *     01.25.94  ESF  Created.
169  *     02.19.94  ESF  Added Card UI stuff.
170  *     03.03.94  ESF  Added callbacks for the remaining buttons.
171  *     03.03.94  ESF  Changed so `Number of Armies?' starts unmanaged.
172  *     03.04.94  ESF  Added another comment widget for error messages.
173  *     03.06.94  ESF  Added an army placement shell.
174  *     03.14.94  ESF  Changed shells to be transient.
175  *     04.01.94  ESF  Added help popup.
176  *     04.02.94  ESF  Added generic dialog with three possible answers.
177  *     05.19.94  ESF  Added TrueColor display patches.
178  *     09.14.94  ESF  Fixed so that it works with more TrueColor visuals.
179  *     01.24.95  ESF  Changed so that actions are added in one place.
180  *     01.24.95  ESF  Changed so that accelerators are done in res. file.
181  *     01.25.95  ESF  Added dummy widget for centering buttons in dialog.
182  *     19.12.99  TdH  Moved call to GUI_LoadMap(MAPFILE) here
183  *  PURPOSE:
184  *  NOTES:
185  ************************************************************************/
GUI_Setup(Int32 argc,CString * argv)186 void GUI_Setup(Int32 argc, CString *argv)
187 {
188   Int32         iCount, i, iVisualCount;
189   Arg           pArgs[10], pVisualArgs[3];
190   char buf[256];
191 
192   Widget wForm, wControls;
193   Widget wStatViewButton, wAboutButton;
194   Widget wAttackLabel;
195   Widget wActionLabel;
196   Widget wMsgDestLabel, wMsgDestViewport;
197   Widget wPlayField;
198   Widget wQuitButton, wRepeatButton, wCancelAttackButton;
199   Widget wHelpButton, wShowCardsButton, wShowMissionButton;
200   Widget wEndTurnButton;
201 
202   /* The view cards popup shell */
203   Widget wCardForm, wCardTableBox;
204   Widget wCardViewport;
205   Widget wExchangeButton, wCancelCardsButton;
206 
207   /* The "place armies" popup shell */
208   Widget wArmiesForm, wArmiesLabel;
209   Widget wFinishArmiesButton;
210 
211   /* The "help" popup shell */
212   Widget wHelpForm, wHelpTopicViewport;
213   Widget wHelpTopicLabel, wHelpOkButton;
214 
215   /* The "generic popup" dialog */
216   Widget wDialogForm;
217 
218   /* Setup a colormap for the application */
219   COLOR_GetColormap(pVisualArgs, &iVisualCount,
220 		    GUI_GetNumColorsInMap(MAPFILE) +
221 		    MAX_PLAYERS + NUM_OTHERCOLORS, argc, argv);
222 
223   /* Create the application's main window */
224   wToplevel = XtAppCreateShell(NULL, "XFrisk", applicationShellWidgetClass,
225 			       hDisplay, pVisualArgs, iVisualCount);
226 
227   /* Make sure to set the arguments from the command line */
228   XtVaSetValues(wToplevel,
229 		XtNargc, argc,
230  		XtNargv, argv,
231  		NULL);
232 
233   /* Add the action table */
234   XtAppAddActions(appContext, actionTable, XtNumber(actionTable));
235 
236   /* The main window UI stuff */
237   wForm = XtCreateManagedWidget("wForm", formWidgetClass, wToplevel,
238 				NULL, 0);
239   wMap = XtCreateManagedWidget("wMap", formWidgetClass, wForm,
240 			       NULL, 0);
241   wPlayField = XtCreateManagedWidget("wPlayField", formWidgetClass, wForm,
242                                     NULL, 0);
243   wControls = XtCreateManagedWidget("wControls", formWidgetClass, wForm,
244                                     NULL, 0);
245 
246   /* Holds the number of attack dice to use (1, 2, or 3) */
247   wAttackLabel = XtCreateManagedWidget("wAttackLabel", labelWidgetClass,
248 				       wControls, NULL, 0);
249   iCount=0;
250   XtSetArg(pArgs[iCount], XtNlist, pstrAttackDice); iCount++;
251   XtSetArg(pArgs[iCount], XtNnumberStrings, 4); iCount++;
252   wAttackList = XtCreateManagedWidget("wAttackList", listWidgetClass,
253 				      wControls, pArgs, iCount);
254   XtAddCallback(wAttackList, XtNcallback, CBK_Attack, NULL);
255 
256   /* Holds the action to perform (Place Armies, Attack, Free Move) */
257   wActionLabel = XtCreateManagedWidget("wActionLabel", labelWidgetClass,
258 				       wControls, NULL, 0);
259   iCount=0;
260   XtSetArg(pArgs[iCount], XtNlist, pstrActions); iCount++;
261   XtSetArg(pArgs[iCount], XtNnumberStrings, 4); iCount++;
262   wActionList = XtCreateManagedWidget("wActionList", listWidgetClass,
263 				      wControls, pArgs, iCount);
264   XtAddCallback(wActionList, XtNcallback, CBK_Action, NULL);
265 
266   /* Holds the destination of a message (All, [players...]) */
267   wMsgDestLabel = XtCreateManagedWidget("wMsgDestLabel", labelWidgetClass,
268 					wControls, NULL, 0);
269   wMsgDestViewport = XtCreateManagedWidget("wMsgDestViewport",
270 					   viewportWidgetClass, wControls,
271 					   NULL, 0);
272 
273 #ifdef ENGLISH
274   pstrMsgDstCString[0] = "All Players";
275 #endif
276 #ifdef FRENCH
277   pstrMsgDstCString[0] = "Tous les joueurs";
278 #endif
279   wMsgDestList = XtVaCreateManagedWidget("wMsgDestList", listWidgetClass,
280 					 wMsgDestViewport,
281 					 XtNlist, pstrMsgDstCString,
282 					 XtNnumberStrings, 1,
283 					 NULL);
284   XtAddCallback(wMsgDestList, XtNcallback, CBK_MsgDest, NULL);
285 
286   /* Holds the message to send */
287   wSendMsgText = XtVaCreateManagedWidget("wSendMsgText", asciiTextWidgetClass,
288 					 wControls,
289 					 XtNeditType, XawtextEdit,
290 					 XtNwrap, XawtextWrapNever,
291 					 NULL);
292 
293   /* Holds all of the messages */
294   wMsgText = XtVaCreateManagedWidget("wMsgText", asciiTextWidgetClass,
295 				     wControls,
296 				     XtNstring, "",
297 				     XtNscrollVertical, XawtextScrollAlways,
298 				     XtNwrap, XawtextWrapWord,
299 				     XtNautoFill, True,
300 				     NULL);
301 
302   /* Turns the color of the player who's turn it is */
303   wCurrentPlayer = XtCreateManagedWidget("wCurrentPlayer", formWidgetClass,
304 					 wPlayField, NULL, 0);
305 
306   /* Running commentary on the game, one liners, rules */
307   wCommentLabel = XtCreateManagedWidget("wCommentLabel", labelWidgetClass,
308 					wPlayField, NULL, 0);
309 
310   /* Tells about the game version */
311   wAboutButton = XtCreateManagedWidget("wAboutButton",
312 				       commandWidgetClass, wPlayField,
313 				       NULL, 0);
314   XtAddCallback(wAboutButton, XtNcallback, CBK_About, NULL);
315 
316   /* Cancel an attack */
317   wCancelAttackButton = XtCreateManagedWidget("wCancelAttackButton",
318 					      commandWidgetClass, wPlayField,
319 					      NULL, 0);
320   XtAddCallback(wCancelAttackButton, XtNcallback, CBK_CancelAttack, NULL);
321 
322   /* Repeat a single attack */
323   wRepeatButton = XtCreateManagedWidget("wRepeatButton", commandWidgetClass,
324 					wPlayField, NULL, 0);
325   XtAddCallback(wRepeatButton, XtNcallback, CBK_Repeat, NULL);
326 
327   /* End a turn */
328   wEndTurnButton = XtCreateManagedWidget("wEndTurnButton", commandWidgetClass,
329 					 wPlayField, NULL, 0);
330   XtAddCallback(wEndTurnButton, XtNcallback, CBK_EndTurn, NULL);
331 
332   /* Show the cards */
333   wShowCardsButton = XtCreateManagedWidget("wShowCardsButton",
334 					   commandWidgetClass, wPlayField,
335 					   NULL, 0);
336   XtAddCallback(wShowCardsButton, XtNcallback, CBK_ShowCards, NULL);
337 
338   /* Show the mission */
339   wShowMissionButton = XtCreateManagedWidget("wShowMissionButton",
340 					     commandWidgetClass, wPlayField,
341 					     NULL, 0);
342   XtAddCallback(wShowMissionButton, XtNcallback, CBK_ShowMission, NULL);
343 
344   /* Statistics View */
345   wStatViewButton = XtCreateManagedWidget("wStatViewButton",
346 					  commandWidgetClass, wPlayField,
347 					  NULL, 0);
348   XtAddCallback(wStatViewButton, XtNcallback,
349 		(XtCallbackProc)STAT_PopupDialog, NULL);
350 
351   /* Help */
352   wHelpButton = XtCreateManagedWidget("wHelpButton", commandWidgetClass,
353 				      wPlayField, NULL, 0);
354   XtAddCallback(wHelpButton, XtNcallback, CBK_Help, NULL);
355 
356   /* The Quit button */
357   wQuitButton = XtCreateManagedWidget("wQuitButton", commandWidgetClass,
358 					 wPlayField, NULL, 0);
359   XtAddCallback(wQuitButton, XtNcallback, CBK_Quit, NULL);
360 
361   /* Error messages */
362   wErrorLabel = XtCreateManagedWidget("wErrorLabel", labelWidgetClass,
363 				      wPlayField, NULL, 0);
364 
365   /* Holds the rolled dice bitmaps */
366   wDiceBox = XtCreateManagedWidget("wDiceBox", formWidgetClass,
367 				   wPlayField, NULL, 0);
368 
369   /* Finished */
370   XtRealizeWidget(wToplevel);
371 
372   /* Build the card popup shell */
373   wCardShell = XtCreatePopupShell("Cards", transientShellWidgetClass,
374 				  wToplevel, pVisualArgs, iVisualCount);
375   wCardForm = XtCreateManagedWidget("wCardForm", formWidgetClass,
376 				    wCardShell, NULL, 0);
377   wCardViewport = XtCreateManagedWidget("wCardViewport", viewportWidgetClass,
378 					wCardForm, NULL, 0);
379   wCardTableBox = XtCreateManagedWidget("wCardTableBox", boxWidgetClass,
380 					 wCardViewport, NULL, 0);
381 
382   for (i=0; i!=MAX_CARDS; i++)
383     {
384       snprintf(buf, sizeof(buf), "wCardToggle%d", i);
385       wCardToggle[i] = XtVaCreateWidget(buf, toggleWidgetClass,
386 					wCardTableBox,
387 					XtNwidth, CARD_WIDTH,
388 					XtNheight, CARD_HEIGHT,
389 					XtNborderWidth, 0,
390 					XtNhighlightThickness, 0,
391 					XtNlabel, "",
392 					NULL);
393     }
394 
395   wExchangeButton = XtCreateManagedWidget("wExchangeButton",
396 					  commandWidgetClass, wCardForm,
397 					  NULL, 0);
398   XtAddCallback(wExchangeButton, XtNcallback, CBK_ExchangeCards, NULL);
399   wCancelCardsButton = XtCreateManagedWidget("wCancelCardsButton",
400 					     commandWidgetClass, wCardForm,
401 					     NULL, 0);
402   XtAddCallback(wCancelCardsButton, XtNcallback, CBK_CancelCards, NULL);
403 
404   /* Build the army placement shell */
405   wArmiesShell = XtCreatePopupShell("Armies", transientShellWidgetClass,
406 				      wToplevel, pVisualArgs, iVisualCount);
407   wArmiesForm = XtCreateManagedWidget("wArmiesForm", formWidgetClass,
408 				      wArmiesShell, NULL, 0);
409   wArmiesLabel = XtCreateManagedWidget("wArmiesLabel", labelWidgetClass,
410 				       wArmiesForm, NULL, 0);
411   wArmiesText = XtVaCreateManagedWidget("wArmiesText", asciiTextWidgetClass,
412 					wArmiesForm, XtNeditType, XawtextEdit,
413 					NULL);
414   wFinishArmiesButton = XtCreateManagedWidget("wFinishArmiesButton",
415 					      commandWidgetClass, wArmiesForm,
416 					      NULL, 0);
417   XtAddCallback(wFinishArmiesButton, XtNcallback,
418 		(XtCallbackProc)UTIL_QueryYes, NULL);
419 
420   wCancelArmiesButton = XtCreateManagedWidget("wCancelArmiesButton",
421 					      commandWidgetClass, wArmiesForm,
422 					      NULL, 0);
423   XtAddCallback(wCancelArmiesButton, XtNcallback,
424 		(XtCallbackProc)UTIL_QueryNo, NULL);
425 
426   /* Build the help shell */
427   wHelpShell = XtCreatePopupShell("Help", transientShellWidgetClass,
428 				    wToplevel, pVisualArgs, iVisualCount);
429   wHelpForm = XtCreateManagedWidget("wHelpForm", formWidgetClass,
430 				    wHelpShell, NULL, 0);
431   wHelpTopicLabel = XtCreateManagedWidget("wHelpTopicLabel", labelWidgetClass,
432 					  wHelpForm, NULL, 0);
433   wHelpLabel = XtCreateManagedWidget("wHelpLabel", labelWidgetClass,
434 				     wHelpForm, NULL, 0);
435   wHelpTopicViewport = XtCreateManagedWidget("wHelpTopicViewport",
436 					     viewportWidgetClass,
437 					     wHelpForm, NULL, 0);
438   wHelpTopicList = XtCreateManagedWidget("wHelpTopicList", listWidgetClass,
439 					 wHelpTopicViewport, NULL, 0);
440   XtAddCallback(wHelpTopicList, XtNcallback, CBK_HelpSelectTopic, NULL);
441   wHelpText = XtVaCreateManagedWidget("wHelpText", asciiTextWidgetClass,
442 				      wHelpForm,
443 				      XtNwrap, XawtextWrapWord,
444 				      XtNdisplayCaret, False,
445 				      XtNscrollVertical, XawtextScrollAlways,
446 				      NULL);
447   wHelpOkButton = XtCreateManagedWidget("wHelpOkButton",
448 					commandWidgetClass, wHelpForm,
449 					NULL, 0);
450   XtAddCallback(wHelpOkButton, XtNcallback, CBK_HelpOk, NULL);
451 
452   /* Build the generic dialog shells */
453   wDialogShell = XtCreatePopupShell("Dialog", transientShellWidgetClass,
454 				      wToplevel, pVisualArgs, iVisualCount);
455   wDialogForm = XtCreateManagedWidget("wDialogForm", formWidgetClass,
456 				      wDialogShell, NULL, 0);
457   wDialogLabel = XtCreateManagedWidget("wDialogLabel", labelWidgetClass,
458 				       wDialogForm, NULL, 0);
459   wDialogButton[0] = XtCreateManagedWidget("wDialogButton1",
460 					   commandWidgetClass, wDialogForm,
461 					   NULL, 0);
462   XtAddCallback(wDialogButton[0], XtNcallback, (XtCallbackProc)UTIL_QueryYes,
463 		NULL);
464   wDialogButton[1] = XtCreateManagedWidget("wDialogButton2",
465 					   commandWidgetClass, wDialogForm,
466 					   NULL, 0);
467   XtAddCallback(wDialogButton[1], XtNcallback, (XtCallbackProc)UTIL_QueryNo,
468 		NULL);
469   wDialogButton[2] = XtCreateManagedWidget("wDialogButton3",
470 					   commandWidgetClass, wDialogForm,
471 					   NULL, 0);
472   XtAddCallback(wDialogButton[2], XtNcallback,
473 		(XtCallbackProc)UTIL_QueryCancel, NULL);
474 
475   /* Get a couple globals for the future */
476   hDisplay = XtDisplay(wMap);
477   hWindow  = XtWindow(wMap);
478   iScreen  = DefaultScreen(hDisplay);
479   hGC      = XCreateGC(hDisplay, hWindow, 0, NULL);
480   hGC_XOR  = XCreateGC(hDisplay, hWindow, 0, NULL);
481 
482   /* Set the XOR GC appropriately */
483   XSetFunction(hDisplay, hGC_XOR, GXinvert);
484   XSetLineAttributes(hDisplay, hGC_XOR, 2, LineSolid, CapButt, JoinMiter);
485 
486   /* Get the font */
487   if ((pFont=XLoadQueryFont(hDisplay, "fixed")) == NULL)
488     {
489 #ifdef ENGLISH
490       (void)UTIL_PopupDialog("Fatal Error",
491 			     "GUI: Couldn't get font 'fixed'!\n", 1,
492 #endif
493 #ifdef FRENCH
494       (void)UTIL_PopupDialog("Erreur fatale",
495 			     "GUI: Impossible de charger la fonte'fixed'!\n", 1,
496 #endif
497 			     "Ok", NULL, NULL);
498       UTIL_ExitProgram(-1);
499     }
500 
501   /* Build the object-like MVC View dialogs */
502   COLEDIT_BuildDialog();
503   REG_BuildDialog();
504   PLAYER_BuildDialog();
505   CARD_BuildDialog();
506   CHAT_BuildDialog();
507   STAT_BuildDialog();
508   LOG_BuildDialog();
509   FDBK_BuildDialog();
510 
511   /* Print a welcome message */
512 #ifdef ENGLISH
513   snprintf(buf, sizeof(buf), "Welcome to Frisk %s!", VERSION);
514 #endif
515 #ifdef FRENCH
516   snprintf(buf, sizeof(buf), "Bienvenu � Frisk %s!", VERSION);
517 #endif
518   UTIL_DisplayComment(buf);
519   GUI_LoadMap(MAPFILE);
520 }
521 
522 
523 /************************************************************************
524  *  FUNCTION: GUI_Start
525  *  HISTORY:
526  *     01.25.94  ESF  Created.
527  *     01.29.94  ESF  Added Registration popup.
528  *     03.16.94  ESF  Centering and automatic placement of wRegisterShell.
529  *     04.01.94  ESF  Fixed bug, XtNy had an x by it.
530  *     01.29.95  ESF  Cleaned up, almost nothing left.
531  *  PURPOSE:
532  *  NOTES:
533  ************************************************************************/
534 void GUI_Start(void)
535 {
536     XtAppMainLoop(appContext);
537 }
538 
539 
540 
541 /************************************************************************
542  *  FUNCTION: GUI_AddCallbacks
543  *  HISTORY:
544  *     01.25.94  ESF  Created
545  *     04.11.94  ESF  Added event handler for dice region.
546  *     01.24.95  ESF  Added event handler for keyboard.
547  *  PURPOSE:
548  *  NOTES:
549  ************************************************************************/
550 void GUI_AddCallbacks(Int32 iReadSock)
551 {
552   /* Add the input to receive messages from */
553   (void)XtAppAddInput (appContext, iReadSock, (XtPointer)XtInputReadMask,
554 		       CBK_XIncomingMessage, NULL);
555 
556   /* Add event handlers */
557   XtAddEventHandler(wMap, ExposureMask, False, (XtEventHandler)CBK_RefreshMap,
558 		    NULL);
559   XtAddEventHandler(wMap, ExposureMask, False, (XtEventHandler)CBK_RefreshDice,
560 		    NULL);
561 }
562 
563 
564 /************************************************************************
565  *  FUNCTION: GUI_LoadMap
566  *  HISTORY:
567  *     01.26.94  ESF  Created.
568  *     01.27.94  ESF  Added palette code.
569  *     01.28.94  ESF  Changed to allocate pixmap as well as image.
570  *     02.03.94  ESF  Don't allocate colors in order, use mapping.
571  *     02.23.94  ESF  Started adding 24 bit server support.
572  *     04.01.94  ESF  Fixed free on bogus pointer.
573  *     05.12.94  ESF  Moved world colors to colormap.c.
574  *     05.19.94  ESF  Added TrueColor display patches.
575  *     09.09.94  ESF  Fixed small bug in initializing player turn indicator.
576  *  PURPOSE:
577  *  NOTES: TdH: i think here need to do some adjusment for colormap
578  ************************************************************************/
579 void GUI_LoadMap(CString strMapFile)
580 {
581   Int32   iHeight, iWidth ,iNumPixels;
582   FILE   *hMap;
583   Int32   iPixels;
584   Byte    bColor, bLength, *pMapData, *pDataStream, *pBuffer, *pTemp;
585   Int32   lCurrent, lEnd, iNC;
586   char buf[256];
587 
588   /* Open file and get dimensions */
589   if ((hMap=UTIL_OpenFile(strMapFile, "r"))==NULL)
590     {
591 #ifdef ENGLISH
592       snprintf(buf, sizeof(buf), "GUI: Could not load %s.", strMapFile);
593       (void)UTIL_PopupDialog("Fatal Error", buf, 1, "Ok", NULL, NULL);
594 #endif
595 #ifdef FRENCH
596       snprintf(buf, sizeof(buf), "GUI: Ne peut charger %s.", strMapFile);
597       (void)UTIL_PopupDialog("Erreur fatale", buf, 1, "Ok", NULL, NULL);
598 #endif
599       UTIL_ExitProgram(-1);
600     }
601 
602   fscanf(hMap, "%d%d%d\n", &iWidth, &iHeight, &iNC);
603   COLOR_SetNumColors(iNC);
604 
605   /* Allocate memory for the map data */
606   pMapData = (unsigned char *)MEM_Alloc(iWidth*iHeight);
607 
608   /* Allocate memory for the buffer; first find out size of file */
609   lCurrent = ftell(hMap);
610   fseek(hMap, 0, SEEK_END);
611   lEnd = ftell(hMap);
612   fseek(hMap, lCurrent, SEEK_SET);
613   pTemp = pBuffer = (unsigned char *)MEM_Alloc(lEnd-lCurrent);
614 
615   /* Read in the rest of the file */
616   fread(pBuffer, 1, lEnd-lCurrent, hMap);
617 
618   iNumPixels = iWidth*iHeight;
619   for (iPixels=0,pDataStream=pMapData; iPixels < iNumPixels;  iPixels+=bLength)
620     {
621       /* Get a color segment */
622       bLength = *pBuffer++;
623       bColor  = *pBuffer++;
624 
625       /* Adjust for black/white */
626       if (bColor == BLACK)
627 	bColor = COLOR_GetNumColors()-2;
628       else if (bColor == WHITE)
629 	bColor = COLOR_GetNumColors()-1;
630 
631       /* Put it in the map image */
632       memset(pDataStream, COLOR_CountryToColor(bColor), bLength);
633       pDataStream += bLength;
634     }
635 
636   /* Create an image to hold the map */
637   pMapImage = XCreateImage(hDisplay, pVisual,
638 			   8, ZPixmap, 0, (char *)pMapData, iWidth, iHeight,
639 			   8, iWidth);
640 
641   /* Create a pixmap to hold the image server-side */
642   pixMapImage = XCreatePixmap(hDisplay,
643 			      RootWindowOfScreen(XtScreen(wMap)),
644 			      iWidth, iHeight,
645 			      DefaultDepth(hDisplay, DefaultScreen(hDisplay)));
646 
647   /* Save the world colormap */
648   COLOR_SetWorldColormap(pBuffer);
649   COLOR_SetWorldColors();
650 
651   /* Finally write map image to pixmap and window */
652   if (!COLOR_IsTrueColor())
653       XPutImage(hDisplay, pixMapImage, hGC, pMapImage, 0, 0, 0, 0,
654 		iWidth, iHeight);
655   XCopyArea(hDisplay, pixMapImage, hWindow, hGC,
656 	    0, 0, iWidth, iHeight, 0, 0);
657 
658   /* After colormap is established we want to do this (move it elsewhere!) */
659   XtVaSetValues(wCurrentPlayer, XtNbackground,
660      COLOR_QueryColor(COLOR_DieToColor(2)), NULL);
661 
662   /* Free up memory we were using */
663   MEM_Free(pTemp);
664 }
665 
666 
667 /************************************************************************
668  *  FUNCTION: GUI_GetNumColorsInMap
669  *  HISTORY:
670  *     09.14.94  ESF  Created.
671  *     10.02.94  ESF  Fixed to not call UTIL_PopupDialog.
672  *  PURPOSE:
673  *  NOTES: Called once?
674  ************************************************************************/
675 static Int32 GUI_GetNumColorsInMap(CString strMapFile)
676 {
677   FILE   *hMap;
678   Int32   iWidth, iHeight, iNumColors;
679 
680   /* Open file and get dimensions */
681   if ((hMap=UTIL_OpenFile(strMapFile, "r"))==NULL)
682     {
683       printf("CLIENT: Fatal error, could not load %s.\n", strMapFile);
684       UTIL_ExitProgram(-1);
685     }
686 
687   /* Read the header and close the file */
688   fscanf(hMap, "%d%d%d\n", &iWidth, &iHeight, &iNumColors);
689   fclose(hMap);
690 
691   return iNumColors;
692 }
693 
694 
695 /************************************************************************
696  *  FUNCTION: GUI_SetColorOfCurrentPlayer
697  *  HISTORY:
698  *     17.08.94  JC  Created.
699  *  PURPOSE:
700  *  NOTES:
701  ************************************************************************/
702 void GUI_SetColorOfCurrentPlayer(Int32 iColor)
703 {
704   Int32 c, d;
705 
706   c = COLOR_QueryColor(iColor);
707   XtVaGetValues(wCurrentPlayer, XtNbackground, &d, NULL);
708   if (d != c)
709       XtVaSetValues(wCurrentPlayer, XtNbackground, c, NULL);
710 }
711