8a17d8c3a1437719ea803e932ad489f75a12c3e6
[rocksndiamonds.git] / src / misc.c
1 /***********************************************************
2 *  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
3 *----------------------------------------------------------*
4 *  ©1995 Artsoft Development                               *
5 *        Holger Schemel                                    *
6 *        33659 Bielefeld-Senne                             *
7 *        Telefon: (0521) 493245                            *
8 *        eMail: aeglos@valinor.owl.de                      *
9 *               aeglos@uni-paderborn.de                    *
10 *               q99492@pbhrzx.uni-paderborn.de             *
11 *----------------------------------------------------------*
12 *  misc.c                                                  *
13 ***********************************************************/
14
15 #include "misc.h"
16 #include "tools.h"
17 #include "sound.h"
18 #include "random.h"
19
20 #include <pwd.h>
21 #include <unistd.h>
22 #include <time.h>
23 #include <sys/time.h>
24 #include <sys/param.h>
25 #include <sys/types.h>
26
27 static unsigned long mainCounter(int mode)
28 {
29   static struct timeval base_time = { 0, 0 };
30   struct timeval current_time;
31   unsigned long counter_ms;
32
33   gettimeofday(&current_time, NULL);
34
35   if (mode == INIT_COUNTER || current_time.tv_sec < base_time.tv_sec)
36     base_time = current_time;
37
38   counter_ms = (current_time.tv_sec  - base_time.tv_sec)  * 1000
39              + (current_time.tv_usec - base_time.tv_usec) / 1000;
40
41   return counter_ms;            /* return milliseconds since last init */
42 }
43
44 void InitCounter()              /* set counter back to zero */
45 {
46   mainCounter(INIT_COUNTER);
47 }
48
49 unsigned long Counter() /* get milliseconds since last call of InitCounter() */
50 {
51   return(mainCounter(READ_COUNTER));
52 }
53
54 static void sleep_milliseconds(unsigned long milliseconds_delay)
55 {
56   if (milliseconds_delay < 5)
57   {
58     /* we want to wait only a few ms -- if we assume that we have a
59        kernel timer resolution of 10 ms, we would wait far to long;
60        therefore it's better to do a short interval of busy waiting
61        to get our sleeping time more accurate */
62
63     unsigned long base_counter = Counter(), actual_counter = Counter();
64
65     while (actual_counter < base_counter + milliseconds_delay &&
66            actual_counter >= base_counter)
67       actual_counter = Counter();
68   }
69   else
70   {
71     struct timeval delay;
72
73     delay.tv_sec  = milliseconds_delay / 1000;
74     delay.tv_usec = 1000 * (milliseconds_delay % 1000);
75
76     if (select(0, NULL, NULL, NULL, &delay) != 0)
77       fprintf(stderr,"%s: in function sleep_milliseconds: select() failed!\n",
78               progname);
79   }
80 }
81
82 void Delay(unsigned long delay) /* Sleep specified number of milliseconds */
83 {
84   sleep_milliseconds(delay);
85 }
86
87 BOOL FrameReached(unsigned long *frame_counter_var, unsigned long frame_delay)
88 {
89   unsigned long actual_frame_counter = FrameCounter;
90
91   if (actual_frame_counter < *frame_counter_var+frame_delay &&
92       actual_frame_counter >= *frame_counter_var)
93     return(FALSE);
94
95   *frame_counter_var = actual_frame_counter;
96   return(TRUE);
97 }
98
99 BOOL DelayReached(unsigned long *counter_var, unsigned long delay)
100 {
101   unsigned long actual_counter = Counter();
102
103   if (actual_counter < *counter_var + delay &&
104       actual_counter >= *counter_var)
105     return(FALSE);
106
107   *counter_var = actual_counter;
108   return(TRUE);
109 }
110
111 void WaitUntilDelayReached(unsigned long *counter_var, unsigned long delay)
112 {
113   unsigned long actual_counter;
114
115   while(1)
116   {
117     actual_counter = Counter();
118
119     if (actual_counter < *counter_var + delay &&
120         actual_counter >= *counter_var)
121       sleep_milliseconds((*counter_var + delay - actual_counter) / 2);
122     else
123       break;
124   }
125
126   *counter_var = actual_counter;
127 }
128
129 char *int2str(int ct, int nr)
130 {
131   static char str[20];
132
133   sprintf(str,"%09d",ct);
134   return(&str[strlen(str)-nr]);
135 }
136
137 unsigned int SimpleRND(unsigned int max)
138 {
139   static unsigned long root = 654321;
140   struct timeval current_time;
141
142   gettimeofday(&current_time,NULL);
143   root = root * 4253261 + current_time.tv_sec + current_time.tv_usec;
144   return(root % max);
145 }
146
147 unsigned int RND(unsigned int max)
148 {
149   return(random_linux_libc() % max);
150 }
151
152 unsigned int InitRND(long seed)
153 {
154   struct timeval current_time;
155
156   if (seed==NEW_RANDOMIZE)
157   {
158     gettimeofday(&current_time,NULL);
159     srandom_linux_libc((unsigned int) current_time.tv_usec);
160     return((unsigned int) current_time.tv_usec);
161   }
162   else
163   {
164     srandom_linux_libc((unsigned int) seed);
165     return((unsigned int) seed);
166   }
167 }
168
169 char *GetLoginName()
170 {
171   struct passwd *pwd;
172
173   if (!(pwd=getpwuid(getuid())))
174     return("ANONYMOUS");
175   else
176     return(pwd->pw_name);
177 }
178
179 void MarkTileDirty(int x, int y)
180 {
181   int xx = redraw_x1 + x;
182   int yy = redraw_y1 + y;
183
184   if (!redraw[xx][yy])
185   {
186     redraw[xx][yy] = TRUE;
187     redraw_tiles++;
188     redraw_mask |= REDRAW_TILES;
189   }
190 }