1 /*
2 Copyright notice:
3 
4 This is mine.  I'm only letting you use it.  Period.  Feel free to rip off
5 any of the code you see fit, but have the courtesy to give me credit.
6 Otherwise great hairy beasties will rip your eyes out and eat your flesh
7 when you least expect it.
8 
9 Jonny Goldman <jonathan@think.com>
10 
11 Wed May  8 1991
12 */
13 
14 /* widget.c -- handle things that make the playing field behave as a widget. */
15 
16 #ifdef HAVE_CONFIG_H
17 #include <config.h>
18 #endif
19 
20 #include "vaders.h"
21 #include <X11/Xaw/Form.h>
22 
23 typedef struct _BaseRec {
24   int x;			/* Location. */
25   int v;			/* velocity */
26   int width, height;		/* box of this base. */
27   XImage *shape_image;		/* an XImage for the spaceship */
28 } BaseRec, *Base;
29 
30 extern Base base;
31 
32 static void HandleFocus();
33 static void HandleStruct();
34 void Pause();
35 static Boolean TakeFocus();
36 
37 static XtActionsRec actions[] = {
38     {"grab-focus",	(XtActionProc) TakeFocus},
39     {"left",		MoveLeft},
40     {"right",		MoveRight},
41     {"stop",		Stop},
42     {"fire",		Fire},
43     {"pause",		Pause},
44     {"quit",		Quit},
45 };
46 
47 static char defaultTranslation[] =
48      "<Btn1Down>:	left()\n\
49      <Btn1Up>:		stop()\n\
50      <Btn2Down>:	fire()\n\
51      <Btn3Down>:	right()\n\
52      <Btn3Up>:		stop()\n\
53      <KeyDown>z:	fire()\n\
54      <KeyDown>\\,:	left()\n\
55      <KeyUp>\\,:	stop()\n\
56      <KeyDown>.:	right()\n\
57      <KeyUp>.:		stop()\n\
58      <KeyDown>\\ :	fire()\n\
59      <KeyDown>p:	pause()\n\
60      <KeyDown>q:	quit()";
61 
62 
ClassInitialize()63 static void ClassInitialize() {}
64 
65 /*ARGSUSED*/
Initialize(request,w)66 static void Initialize(request, w)
67 Widget request, w;
68 {
69     XtAddEventHandler(toplevel, (EventMask) FocusChangeMask, FALSE,
70 		      HandleFocus, (Opaque) NULL);
71     XtAddEventHandler(toplevel, (EventMask) StructureNotifyMask, FALSE,
72 		      HandleStruct, (Opaque) NULL);
73 }
74 
75 
Realize(w,valueMask,attributes)76 static void Realize(w, valueMask, attributes)
77 Widget w;
78 Mask *valueMask;
79 XSetWindowAttributes *attributes;
80 {
81   XGCValues forevalues;
82   XGCValues backvalues;
83   XGCValues basevalues;
84   XGCValues buildingvalues;
85   XGCValues vader1values;
86   XGCValues vader2values;
87   XGCValues vader3values;
88   XGCValues shotvalues;
89   XGCValues scorevalues;
90   XGCValues spacervalues;
91 
92   /*
93    * Safety check.
94    */
95 
96   if (w->core.width == 0) w->core.width = 1;
97   if (w->core.height == 0) w->core.height = 1;
98 
99   XtCreateWindow(w, (unsigned int) InputOutput, (Visual *) CopyFromParent,
100 		 *valueMask, attributes);
101 
102   gamewidth = scale*VWIDTH;
103   gameheight = scale*VHEIGHT;
104   gamewindow = XtWindow(gamewidget);
105   labelwindow = XtWindow(labelwidget);
106 
107   forevalues.background = WhitePixel(dpy, DefaultScreen(dpy));
108   forevalues.foreground = BlackPixel(dpy, DefaultScreen(dpy));
109   foregc = XCreateGC(dpy, XtWindow(w),
110 		     (XtGCMask) GCForeground | GCBackground, &forevalues);
111   XSetFunction(dpy, foregc, GXcopy);
112   backvalues.background = defaultback;
113   backvalues.foreground = defaultback;
114   backgc = XCreateGC(dpy, XtWindow(w),
115 		     (XtGCMask) GCForeground | GCBackground, &backvalues);
116   XSetFunction(dpy, backgc, GXcopy);
117   basevalues.background = defaultback;
118   basevalues.foreground = basepixel;
119   basegc = XCreateGC(dpy, XtWindow(w),
120 		     (XtGCMask) GCForeground | GCBackground, &basevalues);
121   XSetFunction(dpy, basegc, GXcopy);
122   buildingvalues.background = defaultback;
123   buildingvalues.foreground = buildingpixel;
124   buildinggc = XCreateGC(dpy, XtWindow(w),
125 		     (XtGCMask) GCForeground | GCBackground, &buildingvalues);
126   XSetFunction(dpy, buildinggc, GXcopy);
127   vader1values.background = defaultback;
128   vader1values.foreground = vader1pixel;
129   vadergc[0] = XCreateGC(dpy, XtWindow(w),
130 			 (XtGCMask) GCForeground | GCBackground, &vader1values);
131   XSetFunction(dpy, vadergc[0], GXcopy);
132   vader2values.background = defaultback;
133   vader2values.foreground = vader2pixel;
134   vadergc[1] = XCreateGC(dpy, XtWindow(w),
135 			 (XtGCMask) GCForeground | GCBackground, &vader2values);
136   XSetFunction(dpy, vadergc[1], GXcopy);
137   vader3values.background = defaultback;
138   vader3values.foreground = vader3pixel;
139   vadergc[2] = XCreateGC(dpy, XtWindow(w),
140 			 (XtGCMask) GCForeground | GCBackground, &vader3values);
141   XSetFunction(dpy, vadergc[2], GXcopy);
142   shotvalues.background = defaultback;
143   shotvalues.foreground = shotpixel;
144   shotgc = XCreateGC(dpy, XtWindow(w),
145 		     (XtGCMask) GCForeground | GCBackground, &shotvalues);
146   XSetFunction(dpy, shotgc, GXcopy);
147   scorevalues.background = defaultback;
148   scorevalues.foreground = scorepixel;
149   scorevalues.font = XLoadFont(dpy, vaderfont);
150   scoregc = XCreateGC(dpy, XtWindow(w),
151 		     (XtGCMask) GCForeground | GCBackground | GCFont, &scorevalues);
152   XSetFunction(dpy, scoregc, GXcopy);
153   shotvalues.background = defaultback;
154   shotvalues.foreground = vshotpixel;
155   vshotgc = XCreateGC(dpy, XtWindow(w),
156 		      (XtGCMask) GCForeground | GCBackground, &shotvalues);
157   XSetFunction(dpy, vshotgc, GXcopy);
158   spacervalues.background = defaultback;
159   spacervalues.foreground = spacerpixel;
160   spacergc = XCreateGC(dpy, XtWindow(w),
161 		       (XtGCMask) GCForeground | GCBackground, &spacervalues);
162   XSetFunction(dpy, spacergc, GXcopy);
163 
164   InitBase();
165   InitBuildings();
166   InitVaders();
167   InitSpacers();
168   InitShot();
169   InitScore();
170 }
171 
SuspendTimers()172 void SuspendTimers()
173 {
174   if (basetimerid)
175     XtRemoveTimeOut(basetimerid);
176   basetimerid = 0;
177   if (vadertimerid)
178     XtRemoveTimeOut(vadertimerid);
179   vadertimerid = 0;
180   if (shottimerid)
181     XtRemoveTimeOut(shottimerid);
182   shottimerid = 0;
183   if (vshottimerid)
184     XtRemoveTimeOut(vshottimerid);
185   vshottimerid = 0;
186   if (spacertimerid)
187     XtRemoveTimeOut(spacertimerid);
188   spacertimerid = 0;
189 }
190 
EnableTimers()191 void EnableTimers()
192 {
193   if (basetimerid == 0)
194     basetimerid = XtAddTimeOut(basewait, MoveBase, (Opaque) MoveBase);
195   if (vadertimerid == 0)
196     vadertimerid = XtAddTimeOut(vaderwait, MoveVaders,
197 			       (Opaque) MoveVaders);
198   if(spacertimerid == 0)
199     spacertimerid = XtAddTimeOut(spacerwait, MoveSpacer,
200 				 (Opaque) MoveSpacer);
201   if (shottimerid == 0)
202     shottimerid = XtAddTimeOut(shotwait, MoveShots,
203 			       (Opaque) MoveShots);
204   if (vshottimerid == 0)
205     vshottimerid = XtAddTimeOut(vshotwait, MoveVshots,
206 				(Opaque) MoveVshots);
207 }
208 
209 /*ARGSUSED*/
HandleExpose(w,event)210 static void HandleExpose(w, event)
211 Widget w;
212 XEvent *event;
213 {
214  /*  if (event->xexpose.count) return; */
215   XSync(dpy, 0);
216   /* suspend events */
217   SuspendTimers();
218   /* rebuild the display */
219   XSync(dpy, 0);
220   XClearWindow(dpy, gamewindow);
221   if (!basedestroyed)
222     PaintBase(basegc);
223   if(spacer_shown)
224     PaintSpacer(spacergc);
225   PaintAllVaders();
226   PaintAllShots();
227   PaintBasesLeft();
228   DrawBuildings();
229   PaintScore();
230   XSync(dpy, 0);
231   /* enable events */
232   if(!paused)
233     EnableTimers();
234 }
235 
236 /*ARGSUSED*/
Quit(w,closure,event)237 void Quit(w, closure, event)
238 Widget w;
239 Opaque closure;
240 XEvent *event;
241 {
242     XCloseDisplay(dpy);
243 #ifdef SCOREFILE
244 	SaveScore();
245 #endif
246     exit(0);
247 }
248 
249 int paused = 1;
250 
251 /*ARGSUSED*/
HandleFocus(w,closure,event)252 static void HandleFocus(w, closure, event)
253 Widget w;
254 Opaque closure;
255 XEvent *event;
256 {
257 }
258 
259 /*ARGSUSED*/
Pause(w,closure,event)260 void Pause(w, closure, event)
261 Widget w;
262 Opaque closure;
263 XEvent *event;
264 {
265   static Arg args[1];
266   if (paused) {
267     paused = 0;
268     EnableTimers();
269     XtSetArg(args[0], XtNlabel, _("Pause"));
270     XtSetValues(pausebutton, args, 1);
271     HandleExpose(NULL, NULL, NULL);
272   } else {
273     paused = 1;
274     SuspendTimers();
275     XtSetArg(args[0], XtNlabel, _("Resume"));
276     XtSetValues(pausebutton, args, 1);
277   }
278 }
279 
280 /*ARGSUSED*/
HandleStruct(w,closure,event)281 static void HandleStruct(w, closure, event)
282 Widget w;
283 Opaque closure;
284 XEvent *event;
285 {
286 }
287 
Destroy()288 static void Destroy() {}
289 
Resize()290 static void Resize() {}
291 
SetValues()292 static Boolean SetValues()
293 {
294   return FALSE;
295 }
296 
TakeFocus()297 static Boolean TakeFocus()
298 {
299     XSetInputFocus(dpy, gamewindow, RevertToPointerRoot, CurrentTime);
300     return TRUE;
301 }
302 
303 #include "me.h"
304 
ShowInfo(w,closure,event)305 void ShowInfo(w, closure, event)
306 Widget w;
307 Opaque closure;
308 XEvent *event;
309 {
310   int xloc, yloc;
311 
312   paused = 0;
313   Pause(NULL, NULL, NULL);
314   /* rebuild the display */
315   XSync(dpy, 0);
316   XClearWindow(dpy, gamewindow);
317   if (me_image == NULL) {
318     me_image = XCreateImage(dpy,
319 			    DefaultVisual(dpy, DefaultScreen(dpy)),
320 			    1,
321 			    XYBitmap,
322 			    0,
323 			    (scale == 1) ? me1_bits:me2_bits,
324 			    (scale == 1) ? me1_width : me2_width,
325 			    (scale == 1) ? me1_height: me2_height,
326 			    8, 0);
327     me_image->bitmap_bit_order = LSBFirst;
328     me_image->byte_order = LSBFirst;
329   }
330 
331   xloc = (gamewidth-((scale == 1) ? me1_width : me2_width))/2;
332   yloc = ((scale == 1) ? me1_width : me2_width) + 10;
333 
334   XPutImage(dpy, gamewindow, foregc, me_image,
335 	    0, 0,
336 	    xloc, 0,
337 	    (scale == 1) ? me1_width : me2_width,
338 	    (scale == 1) ? me1_height: me2_height);
339 
340   if (scale == 2)
341     XDrawImageString(dpy, gamewindow, scoregc, xloc, yloc, _("Xinvaders, by Jonny Goldman"), strlen(_("Xinvaders, by Jonny Goldman")));
342   else {
343     XDrawImageString(dpy, gamewindow, scoregc, xloc+30, yloc, "Xinvaders", 9);
344     XDrawImageString(dpy, gamewindow, scoregc, xloc, yloc+15, _("by Jonny Goldman"), strlen(_("by Jonny Goldman")));
345   }
346 
347   XSync(dpy, 0);
348 }
349 
350 
351 VadersClassRec vadersClassRec = {
352   {
353 /* core_class fields      */
354     /* superclass         */    (WidgetClass) &widgetClassRec,
355     /* class_name         */    "Xinvaders",
356     /* widget_size        */    sizeof(VadersRec),
357     /* class_initialize   */    ClassInitialize,
358     /* class_part_initiali*/	NULL,
359     /* class_inited       */    FALSE,
360     /* initialize         */    Initialize,
361     /* initialize_hook	  */	NULL,
362     /* realize            */    Realize,
363     /* actions            */    actions,
364     /* num_actions        */    XtNumber(actions),
365     /* resources          */    NULL,
366     /* num_resources      */    (Cardinal) 0,
367     /* xrm_class          */    NULLQUARK,
368     /* compress_motion    */    TRUE,
369     /* compress_exposure  */    TRUE,
370     /* compress_enterleave*/	TRUE,
371     /* visible_interest   */    FALSE,
372     /* destroy            */    Destroy,
373     /* resize             */    Resize,
374     /* expose             */    HandleExpose,
375     /* set_values         */    SetValues,
376     /* set_values_hook	  */	NULL,
377     /* set_values_almost  */	NULL,
378     /* get_values_hook	  */	NULL,
379     /* accept_focus       */    TakeFocus,
380     /* version		  */	XtVersion,
381     /* callback_private	  */	NULL,
382     /* tm_table		  */	defaultTranslation,
383     /* query_geometry	  */	NULL,
384     /* display_accelerator*/	NULL,
385     /* extension`	  */	NULL,
386   },{
387     /* mumble             */    0       /* Make C compiler happy   */
388   }
389 };
390 
391 WidgetClass vadersWidgetClass = (WidgetClass)&vadersClassRec;
392