rnd-20040823-2-src
[rocksndiamonds.git] / src / game_em / input.c
1 /* 2000-08-13T15:29:40Z
2  *
3  * handle input from x11 and keyboard and joystick
4  */
5
6 #include <X11/Xlib.h>
7 #include <X11/Xutil.h>
8 #include <X11/Xatom.h>
9 #include <X11/keysym.h>
10 #include <sys/time.h>
11 #include <sys/types.h>
12 #include <unistd.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <errno.h>
17
18 #include "global.h"
19 #include "display.h"
20 #include "level.h"
21
22
23 #if defined(TARGET_X11)
24
25 unsigned long Random;
26
27 struct PLAYER ply1;
28 struct PLAYER ply2;
29 struct LEVEL lev;
30
31 unsigned short **Boom;
32 unsigned short **Cave;
33 unsigned short **Next;
34 unsigned short **Draw;
35
36 static unsigned short *Index[4][HEIGHT];
37 static unsigned short Array[4][HEIGHT][WIDTH];
38
39 static int input_die;
40 static int input_pause;
41 static int input_refresh;
42 static int input_esc;
43
44 static struct timeval tv1;
45 static struct timeval tv2;
46
47 static int player_mode;
48 static char player_name[32];
49 static int player_level;
50
51 static void drawmenu(int pos)
52 {
53   char buffer[256];
54
55   switch(pos)
56   {
57     case 0:
58       switch(player_mode)
59       {
60         case 0:
61           strcpy(buffer, "quit emerald mine");
62           break;
63
64         case 1:
65           strcpy(buffer, "single player");
66           break;
67
68         case 2:
69           strcpy(buffer, "teamwork");
70           break;
71       }
72
73       title_string(4, 0, 40, buffer);
74       break;
75
76     case 1:
77       sprintf(buffer, "name: %s", player_name);
78       title_string(5, 0, 40, buffer);
79       break;
80
81     case 2:
82       sprintf(buffer, "level: %d", player_level);
83       title_string(6, 0, 40, buffer);
84       break;
85
86     case 3:
87       title_string(7, 0, 40, "highscores");
88       break;
89
90     case 4:
91       title_string(8, 0, 40, "start");
92       break;
93
94     case 5:
95       title_string(10, 3, 13, "played");
96       title_string(10, 14, 26, "score");
97       title_string(10, 27, 37, "won");
98       break;
99
100     case 6:
101       sprintf(buffer, "%d", 0);
102       title_string(11, 3, 13, buffer);
103       sprintf(buffer, "%d", 0);
104       title_string(11, 14, 26, buffer);
105       sprintf(buffer, "%d", 0);
106       title_string(11, 27, 37, buffer);
107       break;
108   }
109 }
110
111 void game_init_vars(void)
112 {
113   int x, y;
114
115   Random = 1684108901;
116
117   for (y = 0; y < HEIGHT; y++)
118     for (x = 0; x < WIDTH; x++)
119       Array[0][y][x] = ZBORDER;
120   for (y = 0; y < HEIGHT; y++)
121     for (x = 0; x < WIDTH; x++)
122       Array[1][y][x] = ZBORDER;
123   for (y = 0; y < HEIGHT; y++)
124     for (x = 0; x < WIDTH; x++)
125       Array[2][y][x] = ZBORDER;
126   for (y = 0; y < HEIGHT; y++)
127     for (x = 0; x < WIDTH; x++)
128       Array[3][y][x] = Xblank;
129
130   for (y = 0; y < HEIGHT; y++)
131     Index[0][y] = Array[0][y];
132   for (y = 0; y < HEIGHT; y++)
133     Index[1][y] = Array[1][y];
134   for (y = 0; y < HEIGHT; y++)
135     Index[2][y] = Array[2][y];
136   for (y = 0; y < HEIGHT; y++)
137     Index[3][y] = Array[3][y];
138
139   Cave = Index[0];
140   Next = Index[1];
141   Draw = Index[2];
142   Boom = Index[3];
143
144   player_mode = 1;                      /* start off as single player */
145   strcpy(player_name, "dave");
146   player_level = 0;
147
148   input_pause = 1    * 0;
149 }
150
151 int game_play_init(int level_nr, char *filename)
152 {
153   if (filename != NULL)
154   {
155     player_level = level_nr;
156
157     if (cave_convert(filename) != 0)
158       return 1;
159   }
160   else  /* !!! SOON OBSOLETE !!! */
161   {
162     char name[MAXNAME+2];
163
164     name[MAXNAME] = 0;
165     snprintf(name, MAXNAME+2, "%s/lev%02d", EM_LVL_DIR, player_level);
166
167     if (name[MAXNAME])
168       snprintf_overflow("read a level in cave/");
169
170     if (cave_convert(name) != 0)
171       return 1;
172   }
173
174   game_initscreen();
175   game_blitscore();
176   game_animscreen();
177
178   return 0;
179 }
180
181 int game_menu_loop(boolean init, byte action)
182 {
183   static int temp = -1;
184   static int pos = -1;
185
186   if (init)
187   {
188     temp = 1;
189     pos = 4;
190
191     return 0;
192   }
193
194   input_eventloop();
195
196   if (input_die)
197     return 1;
198
199   if (input_refresh)
200     blitscreen();
201
202   if (!input_pause)
203   {
204     title_blitscore();
205     title_animscreen();
206
207     ply1.joy_n = ply1.joy_e = ply1.joy_s = ply1.joy_w = 0;
208
209     readjoy(action);
210
211     if (temp == 0)
212     {
213       if (ply1.joy_fire)
214         return 2;
215
216       if (ply1.joy_e && player_level < 99)
217       {
218         player_level++;
219         drawmenu(2);
220       }
221
222       if (ply1.joy_w && player_level > 0)
223       {
224         player_level--;
225         drawmenu(2);
226       }
227
228       if (ply1.joy_n && pos > 0)
229       {
230         drawmenu(pos);
231         pos--;
232       }
233
234       if (ply1.joy_s && pos < 4)
235       {
236         drawmenu(pos);
237         pos++;
238       }
239     }
240
241     temp = (ply1.joy_n || ply1.joy_e || ply1.joy_s || ply1.joy_w ||
242             ply1.joy_fire);
243   }
244
245   return 0;
246 }
247
248 int game_play_loop(byte action)
249 {
250   input_eventloop();
251
252   if (input_die || input_esc)
253     return 1;
254
255   if (input_refresh)
256     blitscreen();
257
258   if (!input_pause)
259   {
260     game_animscreen();
261
262     frame = (frame - 1) & 7;
263
264     readjoy(action);
265
266 #if 1
267     if (input_esc)
268       return 1;
269 #endif
270
271     if (frame == 7)
272     {
273       synchro_1();
274       synchro_2();
275     }
276
277     if (frame == 6)
278     {
279       synchro_3();
280       sound_play();
281       game_blitscore();
282     }
283   }
284
285   return 0;
286 }
287
288 void game_menu_init(void)
289 {
290   int i;
291
292   title_initscreen();
293
294   for (i = 0; i < 7; i++)
295     drawmenu(i);                        /* display all lines */
296
297   title_blitscore();
298   title_animscreen();
299
300   game_menu_loop(1, 0);
301 }
302
303 int game_loop(byte action)
304 {
305 #if 0
306   printf("::: action == 0x%02x\n", action);
307 #endif
308
309   if (em_game_status == EM_GAME_STATUS_MENU)
310   {
311     int result = game_menu_loop(0, action);
312
313     if (result == 1)
314     {
315       /* exit program */
316
317       return 1;
318     }
319
320     if (result == 2)
321     {
322       /* start playing */
323
324       em_game_status = EM_GAME_STATUS_PLAY;
325       if (game_play_init(player_level, NULL) != 0)
326         em_game_status = EM_GAME_STATUS_MENU;
327     }
328   }
329   else if (em_game_status == EM_GAME_STATUS_PLAY)
330   {
331     if (game_play_loop(action) != 0)
332     {
333       /* stop playing */
334
335       if (skip_menu)
336         return 1;
337
338       em_game_status = EM_GAME_STATUS_MENU;
339       game_menu_init();
340     }
341   }
342
343   return 0;
344 }
345
346
347 /* read input device for players */
348
349 void readjoy(byte action)
350 {
351   unsigned int north = 0, east = 0, south = 0, west = 0, fire = 0;
352
353   if (action & JOY_LEFT)
354     west = 1;
355
356   if (action & JOY_RIGHT)
357     east = 1;
358
359   if (action & JOY_UP)
360     north = 1;
361
362   if (action & JOY_DOWN)
363     south = 1;
364
365   if (action & JOY_BUTTON_1)
366     fire = 1;
367
368 #if 0
369   if (action & JOY_BUTTON_2)
370     input_esc = 1;
371 #endif
372
373   ply1.joy_fire = fire;
374   if (ply1.joy_stick || (north | east | south | west))
375   {
376     ply1.joy_n = north;
377     ply1.joy_e = east;
378     ply1.joy_s = south;
379     ply1.joy_w = west;
380   }
381 }
382
383
384 /* handle events from x windows and block until the next frame */
385
386 void input_eventloop(void)
387 {
388   unsigned long count;
389
390   if (!input_pause)
391   {
392     XSync(display, False); /* block until all graphics are drawn */
393
394     if (gettimeofday(&tv2, 0) == -1)
395       tv2.tv_usec = 0;
396
397     count = tv2.tv_usec + 1000000 - tv1.tv_usec;
398     if (count >= 1000000)
399       count -= 1000000;
400
401     tv1.tv_usec = tv2.tv_usec;
402     if (count < 25000)
403     {
404       tv2.tv_sec = 0;
405       tv2.tv_usec = 25000 - count;
406 #if 1
407       select(0, 0, 0, 0, &tv2); /* sleep a bit */
408 #else
409       usleep(tv2.tv_usec);
410 #endif
411     }
412   }
413
414   input_esc = 0;
415   input_die = 0;
416   input_refresh = 0;
417 }
418
419 #endif