rnd-19980915
[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 void microsleep(unsigned long usec)
28 {
29   if (usec < 5000)
30   {
31     /* we want to wait less than 5 ms -- if we assume that we have a
32        kernel timer resolution of 10 ms, we would wait far to long;
33        therefore it's better to do a short interval of busy waiting
34        to get our sleeping time more accurate */
35
36     long base_counter = Counter2(), actual_counter = Counter2();
37     long delay = usec/1000;
38
39     while (actual_counter < base_counter+delay &&
40            actual_counter >= base_counter)
41       actual_counter = Counter2();
42   }
43   else
44   {
45     struct timeval delay;
46
47     delay.tv_sec  = usec / 1000000;
48     delay.tv_usec = usec % 1000000;
49
50     if (select(0,NULL,NULL,NULL,&delay) != 0)
51       fprintf(stderr,"%s: in function microsleep: select failed!\n",
52               progname);
53   }
54 }
55
56 long mainCounter(int mode)
57 {
58   static struct timeval base_time = { 0, 0 };
59   struct timeval current_time;
60   long counter_ms;
61
62   gettimeofday(&current_time,NULL);
63   if (mode == INIT_COUNTER || current_time.tv_sec < base_time.tv_sec)
64     base_time = current_time;
65
66   counter_ms = (current_time.tv_sec - base_time.tv_sec)*1000
67              + (current_time.tv_usec - base_time.tv_usec)/1000;
68
69   if (mode == READ_COUNTER_100)
70     return(counter_ms/10);      /* return 1/100 secs since last init */
71   else  /*    READ_COUNTER_1000 */
72     return(counter_ms);         /* return 1/1000 secs since last init */
73 }
74
75 void InitCounter() /* set counter back to zero */
76 {
77   mainCounter(INIT_COUNTER);
78 }
79
80 long Counter()  /* returns 1/100 secs since last call of InitCounter() */
81 {
82   return(mainCounter(READ_COUNTER_100));
83 }
84
85 long Counter2() /* returns 1/1000 secs since last call of InitCounter() */
86 {
87   return(mainCounter(READ_COUNTER_1000));
88 }
89
90 void WaitCounter(long value)    /* wait for counter to reach value */
91 {
92   long wait;
93
94   while((wait=value-Counter())>0)
95     microsleep(wait*10000);
96 }
97
98 void WaitCounter2(long value)   /* wait for counter to reach value */
99 {
100   long wait;
101
102   while((wait=value-Counter2())>0)
103     microsleep(wait*1000);
104 }
105
106 void Delay(long value)
107 {
108   microsleep(value);
109 }
110
111 BOOL DelayReached(long *counter_var, int delay)
112 {
113   long actual_counter = Counter();
114
115   if (actual_counter >= *counter_var+delay || actual_counter < *counter_var)
116   {
117     *counter_var = actual_counter;
118     return(TRUE);
119   }
120   else
121     return(FALSE);
122 }
123
124 BOOL FrameReached(long *frame_counter_var, int frame_delay)
125 {
126   long actual_frame_counter = FrameCounter;
127
128   if (actual_frame_counter >= *frame_counter_var+frame_delay
129       || actual_frame_counter < *frame_counter_var)
130   {
131     *frame_counter_var = actual_frame_counter;
132     return(TRUE);
133   }
134   else
135     return(FALSE);
136 }
137
138 char *int2str(int ct, int nr)
139 {
140   static char str[20];
141
142   sprintf(str,"%09d",ct);
143   return(&str[strlen(str)-nr]);
144 }
145
146 unsigned int SimpleRND(unsigned int max)
147 {
148   static unsigned long root = 654321;
149   struct timeval current_time;
150
151   gettimeofday(&current_time,NULL);
152   root = root * 4253261 + current_time.tv_sec + current_time.tv_usec;
153   return(root % max);
154 }
155
156 unsigned int RND(unsigned int max)
157 {
158   return(random_linux_libc() % max);
159 }
160
161 unsigned int InitRND(long seed)
162 {
163   struct timeval current_time;
164
165   if (seed==NEW_RANDOMIZE)
166   {
167     gettimeofday(&current_time,NULL);
168     srandom_linux_libc((unsigned int) current_time.tv_usec);
169     return((unsigned int) current_time.tv_usec);
170   }
171   else
172   {
173     srandom_linux_libc((unsigned int) seed);
174     return((unsigned int) seed);
175   }
176 }
177
178 char *GetLoginName()
179 {
180   struct passwd *pwd;
181
182   if (!(pwd=getpwuid(getuid())))
183     return("ANONYMOUS");
184   else
185     return(pwd->pw_name);
186 }
187
188 void MarkTileDirty(int x, int y)
189 {
190   int xx = redraw_x1 + x;
191   int yy = redraw_y1 + y;
192
193   if (!redraw[xx][yy])
194   {
195     redraw[xx][yy] = TRUE;
196     redraw_tiles++;
197     redraw_mask |= REDRAW_TILES;
198   }
199 }