1 /* Copyright (C) 1993, 1992 Nathan Sidwell */
2 /* RCS $Id: makemris.c,v 4.20 1995/12/21 15:55:04 nathan Exp $ */
3 /*{{{  includes*/
4 #include "xmris.h"
5 #include "defmris.h"
6 #include <X11/Xaw/Form.h>
7 #include <X11/Xaw/Paned.h>
8 #include <X11/Xaw/Simple.h>
9 #include "makecom.c"
10 /*}}}*/
11 /*{{{  tables*/
12 /*{{{  static color*/
13 static struct
14 {
15   unsigned  backgrounds;      /* normal background */
16   unsigned  current[2][3];    /* current colors */
17   int       state;            /* type of colors */
18   unsigned  busy;             /* not arrived at target */
19   unsigned  whizz;            /* whizz value */
20   unsigned  count;            /* delay count */
21 } color;    /* color information */
22 /*}}}*/
23 /*{{{  static Arg toplevel_args[] =*/
24 static Arg toplevel_args[] =
25 {
26   {XtNinput, True},
27 };
28 /*}}}*/
29 /*}}}*/
30 /*{{{  prototypes*/
31 static Boolean convert_string2keysym PROTOARG((Display *, XrmValue *,
32     Cardinal *, XrmValue *, XrmValue *, XtPointer *));
33 /*}}}*/
34 /*{{{  Boolean convert_string2keysym(display, args, num_args, from, to, data)*/
35 static Boolean convert_string2keysym
36 /* ARGSUSED */
37 FUNCARG((display, args, num_args, from, to, data),
38 	Display   *display
39 ARGSEP  XrmValue  *args
40 ARGSEP  Cardinal  *num_args
41 ARGSEP  XrmValue  *from
42 ARGSEP  XrmValue  *to
43 ARGSEP  XtPointer *data
44 )
45 /*
46  * converts a key name string to a key code
47  */
48 {
49   static KeySym keysym;
50 
51   if(to->size < sizeof(KeySym))
52     {
53       to->size = sizeof(KeySym);
54       return False;
55     }
56   keysym = XStringToKeysym((char CONST *)from->addr);
57   if(keysym != NoSymbol)
58     {
59       to->size = sizeof(KeySym);
60       if(to->addr)
61 	*(KeySym *)to->addr = keysym;
62       else
63 	to->addr = (XtPointer)&keysym;
64       return True;
65     }
66   else
67     {
68       XtDisplayStringConversionWarning(display, from->addr, XtRKeySym);
69       return False;
70     }
71 }
72 /*}}}*/
73 /*{{{  void create_widget()*/
74 extern VOIDFUNC create_widget FUNCARGVOID
75 /*
76  * Create the graphics contexts, sprites and colours and stuff.
77  * sets visual and stuff for the toplevel widget
78  */
79 {
80   display.form = XtVaCreateManagedWidget("form", formWidgetClass,
81       display.toplevel, XtNdefaultDistance, (XtArgVal)0, (String)NULL);
82   display.garden = XtVaCreateManagedWidget(&names[data.gender != False][1],
83       simpleWidgetClass, display.form, XtNwidth, (XtArgVal)WINDOW_WIDTH,
84       XtNheight, (XtArgVal)WINDOW_HEIGHT, (String)NULL);
85   create_resources(display.garden);
86   assert(!(VEL_X_FAST * FAST_STEPS * 2 % VEL_X));
87   assert(!(VEL_Y_FAST * FAST_STEPS * 2 % VEL_Y));
88   return;
89 }
90 /*}}}*/
91 /*{{{  void color_cycle()*/
92 extern VOIDFUNC color_cycle FUNCARGVOID
93 /*
94  * Moves the background colors towards their targets. Called during
95  * each animation cycle, and programmed by color_set.
96  */
97 {
98   if(color.busy)
99     {
100       assert(display.dynamic);
101       if(!color.count--)
102 	{
103 	  unsigned  target[3];
104 	  unsigned  ix;
105 
106 	  color.count = WHIZZ_CYCLES - 1;
107 	  color.busy = 0;
108 	  for(ix = 2; ix--;)
109 	    {
110 	      /*{{{  set target*/
111 	      if(color.state == BACKGROUND_WHIZZ)
112 		/*{{{  set whizz target*/
113 		{
114 		  unsigned  cycle, offset;
115 		  unsigned  a, b, c;
116 
117 		  color.busy = 1;
118 		  offset = color.whizz % WHIZZ_STEPS * WHIZZ_SIZE;
119 		  cycle = color.whizz / WHIZZ_STEPS;
120 		  if(cycle & 1)
121 		    a = 0xFFFF - offset, b = 0xFFFF, c = 0;
122 		  else
123 		    a = 0xFFFF, b = offset, c = 0;
124 		  if(cycle / 2 == 1)
125 		    c = b, b = a, a = 0;
126 		  else if(cycle / 2 == 2)
127 		    c = a, a = b, b = 0;
128 		  target[0] = a;
129 		  target[1] = b;
130 		  target[2] = c;
131 		  if(ix)
132 		    for(cycle = 3; cycle--;)
133 		      target[cycle] ^= 0xFFFF;
134 		}
135 		/*}}}*/
136 	      else
137 		/*{{{  set drone or normal target*/
138 		{
139 		  XColor    *sptr;
140 
141 		  sptr = &colors[backgrounds[color.state ==
142 		      BACKGROUND_DRONES ? BACKGROUNDS :
143 		      color.backgrounds][ix]];
144 		  target[0] = sptr->red;
145 		  target[1] = sptr->green;
146 		  target[2] = sptr->blue;
147 		}
148 		/*}}}*/
149 	      /*}}}*/
150 	      /*{{{  move*/
151 	      {
152 		unsigned  gun;
153 		unsigned  *tptr, *cptr;
154 
155 		for(tptr = target, cptr = color.current[ix], gun = 3;
156 		    gun--; tptr++, cptr++)
157 		  if(*tptr > *cptr)
158 		    {
159 		      if(*tptr - *cptr <= WHIZZ_SIZE)
160 			*cptr = *tptr;
161 		      else
162 			{
163 			  *cptr += WHIZZ_SIZE;
164 			  color.busy = 1;
165 			}
166 		    }
167 		  else if(*tptr < *cptr)
168 		    {
169 		      if(*cptr - *tptr <= WHIZZ_SIZE)
170 			*cptr = *tptr;
171 		      else
172 			{
173 			  *cptr -= WHIZZ_SIZE;
174 			  color.busy = 1;
175 			}
176 		    }
177 	      }
178 	      /*}}}*/
179 	      /*{{{  store*/
180 	      {
181 		XColor    *cptr;
182 		unsigned  *sptr;
183 
184 		sptr = color.current[ix];
185 		cptr = &colors[COLOR_DYNAMIC + ix];
186 		cptr->red = sptr[0];
187 		cptr->green = sptr[1];
188 		cptr->blue = sptr[2];
189 		cptr->flags = DoRed | DoGreen | DoBlue;
190 		XStoreColor(display.display, display.colormap, cptr);
191 	      }
192 	      /*}}}*/
193 	    }
194 	  color.whizz = (color.whizz + 1) % (6 * WHIZZ_STEPS);
195 	}
196     }
197   return;
198 }
199 /*}}}*/
200 /*{{{  void color_set(type)*/
201 extern VOIDFUNC color_set
202 FUNCARG((type),
203 	int       type
204 )
205 /*
206  * Set the board background colours to be what they ought.
207  * either one of the BACKGROUND_ specials, or a background index.
208  * color_cycle actually sets the color for us.
209  */
210 {
211   if(display.dynamic)
212     {
213       color.count = 0;
214       if(type < 0 || type >= BACKGROUNDS)
215 	color.state = type;
216       else
217 	{
218 	  color.state = BACKGROUND_NORMAL;
219 	  color.backgrounds = type;
220 	}
221       color.busy = 1;
222     }
223   return;
224 }
225 /*}}}*/
226 /*{{{  void open_toolkit(arc, argv)*/
227 extern VOIDFUNC open_toolkit
228 FUNCARG((argc, argv),
229 	int     argc
230 ARGSEP  String  *argv
231 )
232 {
233 #if !__STDC__
234   /*{{{  K&R string fixups*/
235   {
236     char      *ptr;
237 
238     ptr = XtMalloc(strlen(XMRISVERSION) + strlen(DATE) +
239 	strlen(title_text[0].text));
240     sprintf(ptr, title_text[0].text, XMRISVERSION, DATE);
241     title_text[0].text = ptr;
242   }
243   /*}}}*/
244 #endif /* __STDC__ */
245   extract_options(&argc, argv, command_options);
246   default_gender = GAME_GENDER;
247   /*{{{  determine gender of the game*/
248   if(*argv)
249     {
250       size_t    length;
251       unsigned  ix;
252       char CONST *ptr;
253 
254       for(ptr = *argv + strlen(*argv); ptr != *argv && *ptr != '/'; ptr--)
255 	/* EMPTY */;
256       if(*ptr == '/')
257 	ptr++;
258       for(length = 0; ptr[length] && ptr[length] != '.'; length++)
259 	/*  EMPTY */;
260       for(ix = 2; ix--;)
261 	{
262 	  size_t    other;
263 
264 	  other = strlen(&names[ix][1]);
265 	  if(length >= other &&
266 	      !strncmp(&ptr[length - other], &names[ix][1], other))
267 	    default_gender = ix;
268 	}
269     }
270   /*}}}*/
271   if(data.help == False)
272     /*{{{  more setup*/
273     {
274       if(data.nodisplay == False)
275 	{
276 	  XrmOptionDescRec CONST *ptr;
277 
278 	  /* as options is an extern of unknown size, I can't use
279 	   * XtNumber() to get its size, so I've done it this way
280 	   */
281 	  for(ptr = options; *(char CONST **)ptr; ptr++)
282 	    /* EMPTY */;
283 	  display.toplevel = XtAppInitialize(&display.context, "Xmris",
284 	      options, (Cardinal)(ptr - options),
285 	      (Cardinal *)&argc, (String *)argv,
286 	      (String *)NULL, toplevel_args, XtNumber(toplevel_args));
287 	}
288       if(argc > 1)
289 	/*{{{  error*/
290 	{
291 	  unsigned  ix;
292 
293 	  data.help = True;
294 	  data.colors = False;
295 	  fprintf(stderr, "%s: Unknown option%s:", argv[0],
296 	      argc > 2 ? "s" : "");
297 	  for(ix = 1; ix != argc; ix++)
298 	    fprintf(stderr, "%s %s", ix == 1 ? "" : ",", argv[ix]);
299 	  fputc('\n', stderr);
300 	}
301 	/*}}}*/
302       else if(data.nodisplay != False)
303 	{
304 	  if(data.scores == False && !data.expire &&
305 	      !data.remove && !data.format)
306 	    fatal_error("-nodisplay must be accompanied by -scores, -expire, -remove or -format");
307 	}
308       else
309 	/*{{{  some more setup*/
310 	{
311 	  XtResource CONST *ptr;
312 	  char CONST *dir;
313 
314 	  XtAppSetTypeConverter(display.context, XtRString, XtRKeySym,
315 	      convert_string2keysym, (XtConvertArgRec *)NULL, 0, XtCacheNone,
316 	      (void (*)PROTOARG((XtAppContext, XrmValue *, XtPointer,
317 		  XrmValue *, Cardinal *)))NULL);
318 	  XtAppSetTypeConverter(display.context, XtRString, XtRGender,
319 	      convert_string2gender, (XtConvertArgRec *)NULL, 0, XtCacheNone,
320 	      (void (*)PROTOARG((XtAppContext, XrmValue *, XtPointer,
321 		  XrmValue *, Cardinal *)))NULL);
322 	  display.display = XtDisplay(display.toplevel);
323 	  dir = data.dir;
324 	  for(ptr = resources; *(char CONST **)ptr; ptr++)
325 	    /* EMPTY */;
326 	  XtGetApplicationResources(display.toplevel, (XtPointer)&data,
327 	      resources, (Cardinal)(ptr - resources), (Arg *)NULL, 0);
328 	  if(dir)
329 	    data.dir = dir;
330 	  gettoplevelresources();
331 	  XtVaSetValues(display.toplevel,
332 	      XtNtitle, (XtArgVal)names[data.gender != False],
333 	      XtNiconName, (XtArgVal)names[data.gender != False],
334 	      NULL);
335 	  {
336 	    XKeyboardState keyboard;
337 
338 	    XGetKeyboardControl(display.display, &keyboard);
339 	    display.repeat = keyboard.global_auto_repeat;
340 	  }
341 	}
342 	/*}}}*/
343       if(!data.dir)
344 	data.dir = (char *)resources[0].default_addr;
345     }
346     /*}}}*/
347   return;
348 }
349 /*}}}*/
350