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