rnd-19980917
[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 = Counter(), actual_counter = Counter();
37     long delay = usec/1000;
38
39     while (actual_counter < base_counter+delay &&
40            actual_counter >= base_counter)
41       actual_counter = Counter();
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   return counter_ms;            /* return milliseconds since last init */
70 }
71
72 void InitCounter() /* set counter back to zero */
73 {
74   mainCounter(INIT_COUNTER);
75 }
76
77 long Counter()  /* get milliseconds since last call of InitCounter() */
78 {
79   return(mainCounter(READ_COUNTER));
80 }
81
82 void WaitCounter(long value)    /* wait for counter to reach value */
83 {
84   long wait;
85
86   while((wait=value-Counter())>0)
87     microsleep(wait * 1000);
88 }
89
90 void Delay(long value)          /* Delay 'value' milliseconds */
91 {
92   microsleep(value * 1000);
93 }
94
95 BOOL DelayReached(long *counter_var, int delay)
96 {
97   long actual_counter = Counter();
98
99   if (actual_counter >= *counter_var+delay || actual_counter < *counter_var)
100   {
101     *counter_var = actual_counter;
102     return(TRUE);
103   }
104   else
105     return(FALSE);
106 }
107
108 BOOL FrameReached(long *frame_counter_var, int frame_delay)
109 {
110   long actual_frame_counter = FrameCounter;
111
112   if (actual_frame_counter >= *frame_counter_var+frame_delay ||
113       actual_frame_counter < *frame_counter_var)
114   {
115     *frame_counter_var = actual_frame_counter;
116     return(TRUE);
117   }
118   else
119     return(FALSE);
120 }
121
122 char *int2str(int ct, int nr)
123 {
124   static char str[20];
125
126   sprintf(str,"%09d",ct);
127   return(&str[strlen(str)-nr]);
128 }
129
130 unsigned int SimpleRND(unsigned int max)
131 {
132   static unsigned long root = 654321;
133   struct timeval current_time;
134
135   gettimeofday(&current_time,NULL);
136   root = root * 4253261 + current_time.tv_sec + current_time.tv_usec;
137   return(root % max);
138 }
139
140 unsigned int RND(unsigned int max)
141 {
142   return(random_linux_libc() % max);
143 }
144
145 unsigned int InitRND(long seed)
146 {
147   struct timeval current_time;
148
149   if (seed==NEW_RANDOMIZE)
150   {
151     gettimeofday(&current_time,NULL);
152     srandom_linux_libc((unsigned int) current_time.tv_usec);
153     return((unsigned int) current_time.tv_usec);
154   }
155   else
156   {
157     srandom_linux_libc((unsigned int) seed);
158     return((unsigned int) seed);
159   }
160 }
161
162 char *GetLoginName()
163 {
164   struct passwd *pwd;
165
166   if (!(pwd=getpwuid(getuid())))
167     return("ANONYMOUS");
168   else
169     return(pwd->pw_name);
170 }
171
172 void MarkTileDirty(int x, int y)
173 {
174   int xx = redraw_x1 + x;
175   int yy = redraw_y1 + y;
176
177   if (!redraw[xx][yy])
178   {
179     redraw[xx][yy] = TRUE;
180     redraw_tiles++;
181     redraw_mask |= REDRAW_TILES;
182   }
183 }