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