rnd-19980918
[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 || !cpu_friendly)
57   {
58     /* we want to wait less than 5 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 = Counter();
114
115   if (actual_counter < *counter_var + delay && actual_counter >= *counter_var)
116     sleep_milliseconds(*counter_var + delay - actual_counter);
117
118   *counter_var = actual_counter;
119 }
120
121 char *int2str(int ct, int nr)
122 {
123   static char str[20];
124
125   sprintf(str,"%09d",ct);
126   return(&str[strlen(str)-nr]);
127 }
128
129 unsigned int SimpleRND(unsigned int max)
130 {
131   static unsigned long root = 654321;
132   struct timeval current_time;
133
134   gettimeofday(&current_time,NULL);
135   root = root * 4253261 + current_time.tv_sec + current_time.tv_usec;
136   return(root % max);
137 }
138
139 unsigned int RND(unsigned int max)
140 {
141   return(random_linux_libc() % max);
142 }
143
144 unsigned int InitRND(long seed)
145 {
146   struct timeval current_time;
147
148   if (seed==NEW_RANDOMIZE)
149   {
150     gettimeofday(&current_time,NULL);
151     srandom_linux_libc((unsigned int) current_time.tv_usec);
152     return((unsigned int) current_time.tv_usec);
153   }
154   else
155   {
156     srandom_linux_libc((unsigned int) seed);
157     return((unsigned int) seed);
158   }
159 }
160
161 char *GetLoginName()
162 {
163   struct passwd *pwd;
164
165   if (!(pwd=getpwuid(getuid())))
166     return("ANONYMOUS");
167   else
168     return(pwd->pw_name);
169 }
170
171 void MarkTileDirty(int x, int y)
172 {
173   int xx = redraw_x1 + x;
174   int yy = redraw_y1 + y;
175
176   if (!redraw[xx][yy])
177   {
178     redraw[xx][yy] = TRUE;
179     redraw_tiles++;
180     redraw_mask |= REDRAW_TILES;
181   }
182 }