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: addPlayer.c,v 1.12 2000/01/23 18:37:44 tony Exp $
20 *
21 * $Log: addPlayer.c,v $
22 * Revision 1.12 2000/01/23 18:37:44 tony
23 * removed a debug printf
24 *
25 * Revision 1.11 2000/01/15 17:34:12 morphy
26 * Fixes to update color indicator to initial color and after editing color
27 *
28 * Revision 1.10 2000/01/10 22:47:39 tony
29 * made colorstuff more private to colormap.c, only scrollbars get set wrong, rest seems to work ok now
30 *
31 *
32 *
33 \file "Add player" dialog
34 */
35
36 #include <X11/X.h>
37 #include <X11/Intrinsic.h>
38 #include <X11/StringDefs.h>
39 #include <X11/Shell.h>
40 #include <X11/Xaw/Scrollbar.h>
41 #include <X11/Xaw/Form.h>
42 #include <X11/Xaw/Command.h>
43 #include <X11/Xaw/AsciiText.h>
44 #include <X11/Xaw/Viewport.h>
45 #include <X11/Xaw/List.h>
46
47 #include <stdlib.h>
48
49 #include "addPlayer.h"
50 #include "colorEdit.h"
51 #include "client.h"
52 #include "utils.h"
53 #include "types.h"
54 #include "gui-vars.h"
55 #include "riskgame.h"
56 #include "callbacks.h"
57 #include "debug.h"
58
59
60 /* Private functions */
61 void PLAYER_EditColor(void);
62 void PLAYER_SetSpecies(Int32 iSpecies);
63 void PLAYER_SpeciesCreated(Int32 iSpecies);
64 void PLAYER_SpeciesDestroyed(Int32 iSpecies);
65 void PLAYER_RenderSpecies(void);
66 void PLAYER_Ok(void);
67 void PLAYER_Cancel(void);
68 void PLAYER_SelectSpecies(Widget w, XtPointer pData, XtPointer call_data);
69 Int32 PLAYER_SlotToSpecies(Int32 iSlot);
70 Int32 PLAYER_SpeciesToSlot(Int32 iSpecies);
71
72
73 /* Globals */
74 static Flag fPoppedUp = FALSE;
75 static String *ppstrStrings = NULL;
76 static Int32 *piSlotToSpecies = NULL;
77 static Int32 iCurrentSpecies = SPECIES_HUMAN;
78 static Int32 iNumSlots = 1;
79 Int32 r, g, b; /* really static? at least keep global */
80
81 /* Action tables */
82 static XtActionsRec actionTable[] =
83 {
84 { "playerEditColor", (XtActionProc)PLAYER_EditColor },
85 { "playerOk", (XtActionProc)PLAYER_Ok },
86 { "playerCancel", (XtActionProc)PLAYER_Cancel },
87 { NULL, NULL }
88 };
89
90 /* Widgets */
91 static Widget wAddPlayerShell;
92 static Widget wPlayerNameText;
93 static Widget wPlayerSpeciesListbox;
94 static Widget wPlayerDescText;
95 static Widget wPlayerVersionText;
96 static Widget wPlayerAuthorText;
97 static Widget wPlayerDummy1;
98 static Widget wPlayerDummy2;
99 static Widget wPlayerDummy3;
100 static Widget wPlayerDummy4;
101 static Widget wAddPlayerForm;
102 static Widget wPlayerNameLabel;
103 static Widget wPlayerSpeciesLabel;
104 static Widget wPlayerSpeciesViewport;
105 static Widget wPlayerAuthorLabel;
106 static Widget wPlayerVersionLabel;
107 static Widget wPlayerDescLabel;
108 static Widget wPlayerColorLabel;
109 static Widget wPlayerColorDisplay;
110 static Widget wPlayerOk;
111 static Widget wPlayerCancel;
112
113
114 /**
115 * Pick a color for this player
116 \par store in map
117 */
118
PLAYER_InitColor()119 void PLAYER_InitColor() {
120 r = rand() % 65536;
121 g = rand() % 65536;
122 b = rand() % 65536;
123 while ((r+g+b) < 120000)
124 {
125 r = r + (rand() % 30000);
126 g = g + (rand() % 30000);
127 b = b + (rand() % 30000);
128 }
129 if (r>=65536)
130 r = 65535;
131 if (g>=65536)
132 g = 65535;
133 if (b>=65536)
134 b = 65535;
135 COLOR_StoreColor(COLOR_DieToColor(0), r, g, b);
136 }
137
138
139 /************************************************************************
140 * FUNCTION: PLAYER_BuildDialog
141 * HISTORY:
142 * 01.29.95 ESF Created.
143 * PURPOSE:
144 * NOTES:
145 ************************************************************************/
PLAYER_BuildDialog(void)146 void PLAYER_BuildDialog(void)
147 {
148 wAddPlayerShell = XtCreatePopupShell("wAddPlayerShell",
149 transientShellWidgetClass,
150 wToplevel, pVisualArgs, iVisualCount);
151
152 /* The form */
153 wAddPlayerForm = XtCreateManagedWidget("wAddPlayerForm",
154 formWidgetClass, wAddPlayerShell,
155 NULL, 0);
156
157 /* Player name */
158 wPlayerNameLabel = XtCreateManagedWidget("wPlayerNameLabel",
159 labelWidgetClass,
160 wAddPlayerForm, NULL, 0);
161 wPlayerNameText = XtVaCreateManagedWidget("wPlayerNameText",
162 asciiTextWidgetClass,
163 wAddPlayerForm,
164 XtNeditType, XawtextEdit,
165 NULL);
166
167 /* Player species */
168 wPlayerSpeciesLabel = XtCreateManagedWidget("wPlayerSpeciesLabel",
169 labelWidgetClass,
170 wAddPlayerForm, NULL, 0);
171 wPlayerSpeciesViewport = XtCreateManagedWidget("wPlayerSpeciesViewport",
172 viewportWidgetClass,
173 wAddPlayerForm, NULL, 0);
174 wPlayerSpeciesListbox = XtVaCreateManagedWidget("wPlayerSpeciesListbox",
175 listWidgetClass,
176 wPlayerSpeciesViewport,
177 NULL);
178 XtAddCallback(wPlayerSpeciesListbox, XtNcallback, PLAYER_SelectSpecies,
179 NULL);
180
181 /* Player description */
182 wPlayerDummy1 = XtCreateManagedWidget("wPlayerDummy1",
183 labelWidgetClass,
184 wAddPlayerForm, NULL, 0);
185 wPlayerDescLabel = XtCreateManagedWidget("wPlayerDescLabel",
186 labelWidgetClass,
187 wAddPlayerForm, NULL, 0);
188 wPlayerDescText = XtVaCreateManagedWidget("wPlayerDescText",
189 asciiTextWidgetClass,
190 wAddPlayerForm,
191 XtNwrap, XawtextWrapWord,
192 XtNautoFill, True,
193 NULL);
194
195 /* Player version */
196 wPlayerDummy2 = XtCreateManagedWidget("wPlayerDummy2",
197 labelWidgetClass,
198 wAddPlayerForm, NULL, 0);
199 wPlayerVersionLabel = XtCreateManagedWidget("wPlayerVersionLabel",
200 labelWidgetClass,
201 wAddPlayerForm, NULL, 0);
202 wPlayerVersionText = XtCreateManagedWidget("wPlayerVersionText",
203 asciiTextWidgetClass,
204 wAddPlayerForm, NULL, 0);
205
206 /* Player author */
207 wPlayerAuthorLabel = XtCreateManagedWidget("wPlayerAuthorLabel",
208 labelWidgetClass,
209 wAddPlayerForm, NULL, 0);
210 wPlayerAuthorText = XtCreateManagedWidget("wPlayerAuthorText",
211 asciiTextWidgetClass,
212 wAddPlayerForm, NULL, 0);
213
214 /* Player color */
215 wPlayerColorLabel = XtCreateManagedWidget("wPlayerColorLabel",
216 labelWidgetClass,
217 wAddPlayerForm, NULL, 0);
218 wPlayerColorDisplay = XtVaCreateManagedWidget("wPlayerColorDisplay",
219 labelWidgetClass,
220 wAddPlayerForm,
221 XtNbackground,
222 COLOR_QueryColor(COLOR_DieToColor(0)),
223 NULL);
224
225 /* Space */
226 wPlayerDummy3 = XtCreateManagedWidget("wPlayerDummy3", formWidgetClass,
227 wAddPlayerForm, NULL, 0);
228
229 /* OK and Cancel buttons */
230 wPlayerDummy4 = XtCreateManagedWidget("wPlayerDummy4", formWidgetClass,
231 wAddPlayerForm, NULL, 0);
232 wPlayerOk = XtCreateManagedWidget("wPlayerOk", commandWidgetClass,
233 wAddPlayerForm, NULL, 0);
234 XtAddCallback(wPlayerOk, XtNcallback, (XtCallbackProc)PLAYER_Ok, NULL);
235 wPlayerCancel = XtCreateManagedWidget("wPlayerCancel", commandWidgetClass,
236 wAddPlayerForm, NULL, 0);
237 XtAddCallback(wPlayerCancel, XtNcallback,
238 (XtCallbackProc)PLAYER_Cancel, NULL);
239
240 /* Add Actions */
241 XtAppAddActions(appContext, actionTable, XtNumber(actionTable));
242
243 /* Init the string table and mapping function */
244 ppstrStrings = (String *)MEM_Alloc(sizeof(String)*2);
245 ppstrStrings[0] = (String)MEM_Alloc(strlen(
246 RISK_GetNameOfSpecies(SPECIES_HUMAN))+1);
247 strcpy(ppstrStrings[0], RISK_GetNameOfSpecies(SPECIES_HUMAN));
248 ppstrStrings[1] = (String)NULL;
249 piSlotToSpecies = (Int32 *)MEM_Alloc(sizeof(Int32)*1);
250 piSlotToSpecies[0] = SPECIES_HUMAN;
251 }
252
253
254 /************************************************************************
255 * FUNCTION: PLAYER_PopupDialog
256 * HISTORY:
257 * 01.29.95 ESF Created.
258 * 02.26.95 ESF Fixed to generate brighter random colors.
259 * 04.30.95 ESF Fixed to generate even brighter random colors.
260 * 05.06.95 ESF Fixed a bug whereas the wrong species was highlighted.
261 * 15.01.00 MSH Fixed to update color indicator to initial color.
262 * PURPOSE:
263 * NOTES: called from "Register players"
264 ************************************************************************/
PLAYER_PopupDialog(void)265 void PLAYER_PopupDialog(void)
266 {
267 Int32 x, y;
268 /* Center the new shell */
269 UTIL_CenterShell(wAddPlayerShell, wToplevel, &x, &y);
270 XtVaSetValues(wAddPlayerShell,
271 XtNallowShellResize, False,
272 XtNx, x,
273 XtNy, y,
274 XtNborderWidth, 1,
275 XtNtitle, "Add Player",
276 NULL);
277
278
279 /* TBD: Could make sure here that COLOR_DieToColor(0) had a
280 * reasonable color for the new player, i.e. unique, nice...
281 * for now pick a random color...but not too dim!!
282 */
283 PLAYER_InitColor();
284
285 /* Update the color indicator */
286 XtVaSetValues(wPlayerColorDisplay, XtNbackground,
287 COLOR_QueryColor(COLOR_DieToColor(0)), NULL);
288
289 /* Do the species stuff */
290 PLAYER_RenderSpecies();
291 PLAYER_SetSpecies(iCurrentSpecies);
292 XawListHighlight(wPlayerSpeciesListbox,
293 PLAYER_SpeciesToSlot(iCurrentSpecies));
294
295 /* Pop the dialog up, set the keyboard focus */
296 XtPopup(wAddPlayerShell, XtGrabExclusive);
297 fPoppedUp = TRUE;
298 XtSetKeyboardFocus(wToplevel, wPlayerNameText);
299 XtSetKeyboardFocus(wAddPlayerShell, wPlayerNameText);
300 }
301
302
303 /************************************************************************
304 * FUNCTION: PLAYER_Ok
305 * HISTORY:
306 * 01.29.94 ESF Created.
307 * 01.31.94 ESF Delete the strings after registering.
308 * 02.05.94 ESF Remove local registration from here.
309 * 02.05.94 ESF Adding color validity checking.
310 * 03.07.94 ESF Switched to varargs Xt calls.
311 * 03.08.94 ESF Fixed lack of NULL termination in XtVa calls.
312 * 05.04.94 ESF Fixed DistObj changes, added SetNumLivePlayers()
313 * 05.07.94 ESF Fixed to not let too many players register.
314 * 11.16.94 ESF Fixed to not send info to the server re. new player.
315 * 01.15.95 ESF Fixed to not allocate memory for the empty strings.
316 * PURPOSE:
317 * NOTES:
318 ************************************************************************/
PLAYER_Ok(void)319 void PLAYER_Ok(void)
320 {
321 CString strPlayerName;
322 Int32 iNewPlayer;
323 XColor xColor;
324 char buf[256];
325
326 /* Get the name */
327 XtVaGetValues(wPlayerNameText, XtNstring, &strPlayerName, NULL);
328
329 /* Don't bother doing anything if something's not filled out */
330 if (!strlen(strPlayerName))
331 return;
332
333 /* See if there are too many players */
334 if ((iNewPlayer=CLNT_AllocPlayer(CBK_IncomingMessage)) == -1)
335 {
336 (void)UTIL_PopupDialog("Error", "Maximum number of players exceeded!",
337 1, "Ok", NULL, NULL);
338 return;
339 }
340
341 /* Get the XColor from the color index */
342 COLOR_GetColor(COLOR_DieToColor(0),
343 &xColor.red, &xColor.green, &xColor.blue);
344 snprintf(buf, sizeof(buf), "#%02x%02x%02x",
345 xColor.red/256, xColor.green/256, xColor.blue/256);
346
347 /* Init. the player */
348 RISK_SetColorCStringOfPlayer(iNewPlayer, buf);
349 RISK_SetSpeciesOfPlayer(iNewPlayer, iCurrentSpecies);
350 RISK_SetNameOfPlayer(iNewPlayer, strPlayerName);
351
352 /* If the client is human, then the client is this one, otherwise
353 * it's the AI client that registered it.
354 */
355
356 if (iCurrentSpecies == SPECIES_HUMAN)
357 RISK_SetClientOfPlayer(iNewPlayer, CLNT_GetThisClientID());
358 else
359 RISK_SetClientOfPlayer(iNewPlayer,
360 RISK_GetClientOfSpecies(iCurrentSpecies));
361
362 /* This player is now finished. Note this */
363 RISK_SetAllocationStateOfPlayer(iNewPlayer, ALLOC_COMPLETE);
364
365 /* Make sure the name's erased */
366 XtVaSetValues(wPlayerNameText, XtNstring, "", NULL);
367
368 XtPopdown(wAddPlayerShell);
369 fPoppedUp = FALSE;
370
371 /* Reset keyboard focus */
372 XtSetKeyboardFocus(wToplevel, wToplevel);
373 }
374
375
376 /************************************************************************
377 * FUNCTION: PLAYER_Cancel
378 * HISTORY:
379 * 01.29.95 ESF Created.
380 * 02.12.95 ESF Finished.
381 * PURPOSE:
382 * NOTES:
383 ************************************************************************/
PLAYER_Cancel(void)384 void PLAYER_Cancel(void)
385 {
386 CString strName;
387
388 /* Make sure the player name widget
389 * is empty, popup warning if not.
390 */
391
392 XtVaGetValues(wPlayerNameText, XtNstring, &strName, NULL);
393 if (strlen(strName))
394 if (UTIL_PopupDialog("Warning", "Discard current registration data?",
395 2, "Yes", "No", NULL) == QUERY_NO)
396 return;
397
398 XtPopdown(wAddPlayerShell);
399
400 /* Reset keyboard focus */
401 XtSetKeyboardFocus(wToplevel, wToplevel);
402 }
403
404
405 /************************************************************************
406 * FUNCTION: PLAYER_EditColor
407 * HISTORY:
408 * 01.29.95 ESF Created.
409 * 15.01.00 MSH Fixed to update color indicator widget after edit.
410 * PURPOSE:
411 * NOTES:
412 ************************************************************************/
PLAYER_EditColor(void)413 void PLAYER_EditColor(void)
414 {
415 /* Relinquish the keyboard focus */
416 XtUngrabKeyboard(wPlayerNameText, CurrentTime);
417
418 /* Popup the color editing dialog */
419 COLEDIT_EditColor(COLOR_DieToColor(0), FALSE);
420
421 /* Update the color indicator */
422 XtVaSetValues(wPlayerColorDisplay, XtNbackground,
423 COLOR_QueryColor(COLOR_DieToColor(0)), NULL);
424
425 /* Regain the keyboard focus */
426 while(XtGrabKeyboard(wPlayerNameText, True, GrabModeAsync, GrabModeAsync,
427 CurrentTime) == GrabNotViewable)
428 ; /* TwiddleThumbs() */
429 }
430
431
432 /************************************************************************
433 * FUNCTION: PLAYER_SetSpecies
434 * HISTORY:
435 * 02.12.95 ESF Created.
436 * PURPOSE:
437 * NOTES:
438 ************************************************************************/
PLAYER_SetSpecies(Int32 iSpecies)439 void PLAYER_SetSpecies(Int32 iSpecies)
440 {
441 if ((RISK_GetNameOfSpecies(iSpecies)) == NULL)
442 {
443 printf("Warning: Illegal species (%d)\n", iSpecies);
444 return;
445 }
446
447 XtVaSetValues(wPlayerDescText, XtNstring,
448 RISK_GetDescriptionOfSpecies(iSpecies), NULL);
449 XtVaSetValues(wPlayerAuthorText, XtNstring,
450 RISK_GetAuthorOfSpecies(iSpecies), NULL);
451 XtVaSetValues(wPlayerVersionText, XtNstring,
452 RISK_GetVersionOfSpecies(iSpecies), NULL);
453 }
454
455
456 /************************************************************************
457 * FUNCTION: PLAYER_Callback
458 * HISTORY:
459 * 02.23.95 ESF Created.
460 * PURPOSE:
461 * NOTES:
462 ************************************************************************/
PLAYER_Callback(Int32 iMessType,void * pvMess)463 void PLAYER_Callback(Int32 iMessType, void *pvMess)
464 {
465 /*
466 * SpeciesCreated --> Add species to species list
467 * SpeciesDestroyed --> Delete species from species list
468 */
469
470 if (iMessType == MSG_OBJINTUPDATE &&
471 ((MsgObjIntUpdate *)pvMess)->iField == SPE_ALLOCATION &&
472 ((MsgObjIntUpdate *)pvMess)->iNewValue == ALLOC_COMPLETE)
473 {
474 /* SpeciesCreated */
475 PLAYER_SpeciesCreated(((MsgObjStrUpdate *)pvMess)->iIndex1);
476 }
477
478 else if (iMessType == MSG_OBJINTUPDATE &&
479 ((MsgObjIntUpdate *)pvMess)->iField == SPE_ALLOCATION &&
480 ((MsgObjIntUpdate *)pvMess)->iNewValue == ALLOC_NONE)
481 {
482 /* SpeciesDestroyed */
483 PLAYER_SpeciesDestroyed(((MsgObjIntUpdate *)pvMess)->iIndex1);
484 }
485 }
486
487
488 #define PAD_LENGTH 34
489
490 /************************************************************************
491 * FUNCTION: PLAYER_RenderSpecies
492 * HISTORY:
493 * 02.23.95 ESF Created.
494 * 03.03.95 ESF Finished.
495 * 04.01.95 ESF Fixed a bug, needed parens around iNumSpecies+1.
496 * PURPOSE:
497 * NOTES:
498 ************************************************************************/
PLAYER_RenderSpecies(void)499 void PLAYER_RenderSpecies(void)
500 {
501 /* This is just a first approximation of a future, perhaps much
502 * faster or smarter version. This one does its job, though...
503 */
504
505 XawListReturnStruct *pItem;
506 Int32 i, j, k, iLastSelection, iLastSpecies;
507 Int32 iNumSpecies = RISK_GetNumSpecies();
508 CString *ppstr = (CString *)MEM_Alloc(sizeof(CString)*(iNumSpecies+1));
509 Int32 *piMap = (Int32 *)MEM_Alloc(sizeof(Int32)*iNumSpecies);
510 CString str;
511
512 for (i=j=0; i<RISK_GetNumSpecies(); i++, j++)
513 {
514 /* Find the next live species */
515 while(RISK_GetAllocationStateOfSpecies(j) == FALSE)
516 j++;
517
518 str = RISK_GetNameOfSpecies(j);
519 D_Assert(str, "Null species.");
520
521 /* Add it to the list, with a padding of spaces */
522 ppstr[i] = MEM_Alloc(sizeof(Char)*PAD_LENGTH);
523 strcpy(ppstr[i], str);
524 for(k=strlen(str); k<PAD_LENGTH-1; k++)
525 ppstr[i][k] = ' ';
526 ppstr[i][k] = '\0';
527
528 /* Add the mapping from slot to species */
529 piMap[i] = j;
530 }
531 ppstr[i] = (String)NULL;
532
533 /* Find out the last selection */
534 pItem = XawListShowCurrent(wPlayerSpeciesListbox);
535 iLastSelection = pItem->list_index;
536 iLastSpecies = PLAYER_SlotToSpecies(iLastSelection);
537 XtFree((void *)pItem);
538
539 /* Display the list! */
540 XtVaSetValues(wPlayerSpeciesListbox,
541 XtNlist, ppstr,
542 XtNnumberStrings, iNumSpecies,
543 NULL);
544
545 /* If there were old strings, free all of the memory */
546 if (ppstrStrings)
547 {
548 for (i=0; i!=iNumSlots; i++)
549 MEM_Free(ppstrStrings[i]);
550 MEM_Free(ppstrStrings);
551 }
552 if (piSlotToSpecies)
553 MEM_Free(piSlotToSpecies);
554
555 /* Keep the new list of strings and the new mapping */
556 ppstrStrings = ppstr;
557 piSlotToSpecies = piMap;
558 iNumSlots = iNumSpecies;
559
560 /* Select the last species if it's still around */
561 if ((iLastSpecies = PLAYER_SpeciesToSlot(iLastSpecies)) != -1)
562 XawListHighlight(wPlayerSpeciesListbox, iLastSpecies);
563 else
564 XawListHighlight(wPlayerSpeciesListbox,
565 MIN(iLastSelection, iNumSpecies-1));
566 }
567
568
569 /************************************************************************
570 * FUNCTION: PLAYER_SpeciesDestroyed
571 * HISTORY:
572 * 02.23.95 ESF Created.
573 * PURPOSE:
574 * NOTES:
575 ************************************************************************/
PLAYER_SpeciesDestroyed(Int32 iSpecies)576 void PLAYER_SpeciesDestroyed(Int32 iSpecies)
577 {
578 UNUSED(iSpecies);
579 if (fPoppedUp == TRUE)
580 PLAYER_RenderSpecies();
581 }
582
583
584 /************************************************************************
585 * FUNCTION: PLAYER_SpeciesCreated
586 * HISTORY:
587 * 02.23.95 ESF Created.
588 * PURPOSE:
589 * NOTES:
590 ************************************************************************/
PLAYER_SpeciesCreated(Int32 iSpecies)591 void PLAYER_SpeciesCreated(Int32 iSpecies)
592 {
593 UNUSED(iSpecies);
594 if (fPoppedUp == TRUE)
595 PLAYER_RenderSpecies();
596 }
597
598
599 /************************************************************************
600 * FUNCTION: PLAYER_SelectSpecies
601 * HISTORY:
602 * 03.03.95 ESF Created.
603 * PURPOSE:
604 * NOTES:
605 ************************************************************************/
PLAYER_SelectSpecies(Widget w,XtPointer pData,XtPointer call_data)606 void PLAYER_SelectSpecies(Widget w, XtPointer pData, XtPointer call_data)
607 {
608 const XawListReturnStruct *pItem =
609 XawListShowCurrent(wPlayerSpeciesListbox);
610 const Int32 iIndex = pItem->list_index;
611 UNUSED(w);
612 UNUSED(pData);
613 UNUSED(call_data);
614
615 /* Free up memory */
616 XtFree((void *)pItem);
617
618 /* If it's off any of the species, then set the one that was set */
619 if (iIndex == -1)
620 {
621 PLAYER_SetSpecies(iCurrentSpecies);
622 XawListHighlight(wPlayerSpeciesListbox,
623 PLAYER_SpeciesToSlot(iCurrentSpecies));
624 return;
625 }
626
627 /* Find out what species it is */
628 iCurrentSpecies = PLAYER_SlotToSpecies(iIndex);
629
630 /* Put in the description, author, etc. */
631 PLAYER_SetSpecies(iCurrentSpecies);
632 }
633
634
635 /************************************************************************
636 * FUNCTION: PLAYER_SlotToSpecies
637 * HISTORY:
638 * 03.03.95 ESF Created.
639 * PURPOSE:
640 * NOTES:
641 ************************************************************************/
PLAYER_SlotToSpecies(Int32 iSlot)642 Int32 PLAYER_SlotToSpecies(Int32 iSlot)
643 {
644 D_Assert(iSlot>=-1, "Wierd slot!");
645 D_Assert(piSlotToSpecies, "No mapping!");
646
647 /* This means that the user has clicked off of any slot */
648 if (iSlot == -1)
649 return iCurrentSpecies;
650
651 return piSlotToSpecies[iSlot];
652 }
653
654
655 /************************************************************************
656 * FUNCTION: PLAYER_SpeciesToSlot
657 * HISTORY:
658 * 03.03.95 ESF Created.
659 * 05.13.95 ESF Fixed to not return error.
660 * PURPOSE:
661 * NOTES:
662 ************************************************************************/
PLAYER_SpeciesToSlot(Int32 iSpecies)663 Int32 PLAYER_SpeciesToSlot(Int32 iSpecies)
664 {
665 Int32 i;
666
667 for (i=0;
668 ppstrStrings[i]!=NULL;
669 i++)
670 {
671 if (piSlotToSpecies[i] == iSpecies)
672 return i;
673 }
674
675 /* The species doesn't exist, return SPECIES_HUMAN */
676 iCurrentSpecies = SPECIES_HUMAN;
677 return iCurrentSpecies;
678 }
679