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