1 /*
2 * actions.c -- xrobots
3 *
4 * Copyright 1989 Brian Warkentine
5 *
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the author's name not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission. The author makes no representations about the
13 * suitability of this software for any purpose. It is provided "as is"
14 * without express or implied warranty.
15 *
16 * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
17 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE
18 * AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
19 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
20 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
21 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 *
23 * The author's current employer has no connection with this software, as it
24 * was written before being employed at Sun. The following address is for
25 * contacting the author only and does not imply any responsibility on the
26 * behalf of Sun Microsystems.
27 *
28 * Contact the author at:
29 * Brian Warkentine (brianw@Sun.COM)
30 * Sun Microsystems
31 * 2550 Garcia Avenue
32 * Mountain View, Ca 94043-1100
33 *
34 */
35
36 #include <X11/X.h>
37 #include <X11/Intrinsic.h>
38 #include <X11/StringDefs.h>
39 #include <math.h>
40 #include <stdlib.h>
41 #include "xrobots.h"
42
43 extern Widget sonic_command;
44
45 void
sonic_action()46 sonic_action()
47 {
48 static Arg arg = { XtNsensitive, False};
49 if(!game_active) return;
50 XtSetValues(sonic_command,&arg,1);
51 sonic_screwdriver();
52 }
53
54 void
reset_sonic_button()55 reset_sonic_button()
56 {
57 static Arg arg = { XtNsensitive, True };
58 XtSetValues(sonic_command,&arg,1);
59 }
60
61 /*ARGSUSED*/
62 XtActionProc
do_nothing_action(w,event,params,num_params)63 do_nothing_action(w,event,params,num_params)
64 Widget w;
65 XEvent *event;
66 String *params;
67 Cardinal *num_params;
68 {
69 /* do nothing */
70 return NULL;
71 }
72
73
74 /*----------------------------------------------------------------------*/
75
76
77 int
determine_direction(button_x,button_y)78 determine_direction(button_x,button_y)
79 int button_x,button_y;
80 {
81 /*
82 * Given the mouse's x&y position, this routine determines the direction
83 * relative to the player, and returns the result coded into a int.
84 */
85 float slope, invslope;
86 int direction = 0;
87 int coord_x = pos_to_coord(human_x) + CELLSIZE/2,
88 coord_y = pos_to_coord(human_y) + CELLSIZE/2;
89
90 if( (abs(coord_x - button_x) < (CELLSIZE/2)+2) &&
91 (abs(coord_y - button_y) < (CELLSIZE/2)+2))
92 return(STILL); /* cursor is directly over the player */
93
94 if(button_x - coord_x != 0) {
95 slope = fabs((float)(button_y - coord_y) / (float)(button_x - coord_x));
96
97 if( button_x > coord_x ) { /* in coordinates 1 or 4 */
98 if( (slope < 2) && (human_x < MAXX) )
99 direction = RIGHT;
100 }
101 else /* in coordinates 2 or 3 */
102 if( (slope < 2) && (human_x > -1) )
103 direction = LEFT;
104 }
105
106 if(button_y - coord_y != 0) {
107 invslope = fabs((float)(button_x - coord_x) / (float)(button_y - coord_y));
108
109 if( button_y > coord_y ) { /* in coordinates 1 or 2 */
110 if( (invslope < 2) && (human_y < MAXY) )
111 direction |= DOWN;
112 }
113
114 else /* in coordinates 3 or 4 */
115 if( (invslope < 2) && (human_y > -1) )
116 direction |= UP;
117 }
118 return(direction);
119 }
120
121 /*----------------------------------------------------------------------*/
122
123 static int
get_next_position(diff_x,diff_y,mousex,mousey,params,num_params)124 get_next_position(diff_x, diff_y, mousex, mousey, params, num_params)
125 int *diff_x, *diff_y, mousex, mousey, num_params;
126 String *params;
127 {
128 int direction;
129
130 *diff_x = *diff_y = 0;
131
132 if(!num_params) { /* no parameters - the mouse was used pointer */
133
134 direction = determine_direction(mousex,mousey);
135 if(!direction) return -1;
136
137 if(direction & UP) *diff_y = -1;
138 if(direction & DOWN) *diff_y = 1;
139 if(direction & LEFT) *diff_x = -1;
140 if(direction & RIGHT) *diff_x = 1;
141
142 return 0;
143 }
144
145 while(num_params--) {
146 /* else pull the direction out of the parameters. */
147
148 if(!strcmp("right",*(params+num_params))) *diff_x = 1;
149 if(!strcmp("left", *(params+num_params))) *diff_x = -1;
150 if(!strcmp("up", *(params+num_params))) *diff_y = -1;
151 if(!strcmp("down", *(params+num_params))) *diff_y = 1;
152 }
153 return 0;
154 }
155
156 /*----------------------------------------------------------------------*/
157
158
159 /*ARGSUSED*/
160 XtActionProc
move_action(w,event,params,num_params)161 move_action(w,event,params,num_params)
162 Widget w;
163 XButtonEvent *event;
164 String *params;
165 Cardinal *num_params;
166 {
167 /*
168 * Called to move the player's icon. This action can be called
169 * when a mouse button is pressed or when a key is pressed.
170 */
171 int diff_x, diff_y;
172 int num_wasted;
173
174 if(!game_active) return NULL;
175
176 if(get_next_position(&diff_x, &diff_y, event->x, event->y,
177 params, *num_params))
178 return NULL;
179
180 last_human_x = human_x;
181 last_human_y = human_y;
182
183 if( can_go(human_x+diff_x,human_y+diff_y) ) {
184 human_x += diff_x;
185 human_y += diff_y;
186 num_wasted = chase(0);
187 show_movement();
188 add_score(num_wasted);
189 if(!num_robots)
190 new_level();
191 else
192 display_possible_moves();
193 auto_teleport();
194 pointer_moved((Widget)0,(caddr_t)0,event);
195 }
196 XFlush(display);
197 }
198
199
200
201 /*ARGSUSED*/
202 XtActionProc
jump_action(w,event,params,num_params)203 jump_action(w,event,params,num_params)
204 Widget w;
205 XButtonEvent *event;
206 String *params;
207 Cardinal *num_params;
208 {
209 /*
210 * don't just move once, move until it can't go any farther.
211 */
212 int diff_x, diff_y;
213 int num_wasted;
214
215 if(!game_active) return NULL;
216
217 if(get_next_position(&diff_x, &diff_y, event->x, event->y,
218 params, *num_params))
219 return NULL;
220
221 if(! can_go(human_x+diff_x,human_y+diff_y) )
222 return NULL;
223
224 while( can_go(human_x+diff_x,human_y+diff_y) ) {
225 last_human_x = human_x;
226 last_human_y = human_y;
227 human_x += diff_x;
228 human_y += diff_y;
229 num_wasted = chase(0);
230 if(app_data.showjumps)
231 show_movement();
232 add_score(num_wasted);
233 if(!num_robots)
234 break;
235 XFlush(display);
236 }
237 if(!num_robots)
238 new_level();
239 else
240 if(!app_data.showjumps)
241 display_level();
242 display_possible_moves();
243 auto_teleport();
244 pointer_moved((Widget)0,(caddr_t)0,event);
245 XFlush(display);
246 }
247
248
249
250 /*ARGSUSED*/
251 XtActionProc
go_here_action(w,event,params,num_params)252 go_here_action(w,event,params,num_params)
253 Widget w;
254 XButtonEvent *event;
255 String *params;
256 Cardinal *num_params;
257 {
258 /*
259 * This action causes player's icon to try to go to a spot in the
260 * play area. It stops if a move cannot be made.
261 */
262 int direction;
263 int tmp_human_x, tmp_human_y;
264 int num_wasted;
265
266 if(!game_active) return NULL;
267
268 while(direction = determine_direction(event->x,event->y)) {
269 if(direction == STILL) break;
270 tmp_human_x = human_x;
271 tmp_human_y = human_y;
272
273 if(direction & UP) tmp_human_y--;
274 if(direction & DOWN) tmp_human_y++;
275 if(direction & LEFT) tmp_human_x--;
276 if(direction & RIGHT) tmp_human_x++;
277
278 if( !can_go(tmp_human_x,tmp_human_y) )
279 break;
280 last_human_x = human_x;
281 last_human_y = human_y;
282 human_x = tmp_human_x;
283 human_y = tmp_human_y;
284 num_wasted = chase(0);
285 if(app_data.showjumps)
286 show_movement();
287 add_score(num_wasted);
288 if(!num_robots)
289 break;
290 if(app_data.spiffy)
291 pointer_moved((Widget)0,(caddr_t)0,event);
292 XFlush(display);
293 }
294 if(!num_robots)
295 new_level();
296 else
297 if(!app_data.showjumps)
298 display_level();
299 display_possible_moves();
300 auto_teleport();
301 pointer_moved((Widget)0,(caddr_t)0,event);
302 XFlush(display);
303 }
304
305
306
307 /*ARGSUSED*/
308 XtEventHandler
pointer_moved(w,closure,event)309 pointer_moved(w, closure, event)
310 Widget w;
311 caddr_t closure;
312 XPointerMovedEvent *event;
313 {
314 if(game_active)
315 /* could probably suck up any other pointer motion events here... */
316 update_pointer( determine_direction(event->x,event->y) );
317 }
318
319