1 /*
2 * xtrojka (c) 1994,1995,1996 Maarten Los
3 *
4 * #include "COPYRIGHT"
5 *
6 * created: 27.xi.1995
7 * modified:
8 *
9 * This module handles the live score overview
10 */
11
12 #include "debug.h"
13
14 #include <errno.h>
15 #include <stdio.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <time.h>
19 #include <signal.h>
20 #include <pwd.h>
21
22 #include <X11/Intrinsic.h>
23 #include <X11/Xlib.h>
24 #include <X11/StringDefs.h>
25
26 #include "slist.h"
27
28 #include "xtrojka.h"
29 #include "scores.h"
30 #include "sh_slist.h"
31
32
33 #define YPOS(y) (((y)+1)*18)
34 #define XPOS 30
35 #define SCORE_STATUS_TIMEOUT 5000 /* millisecs */
36
37 extern Widget slist_screen;
38 extern XtAppContext app_context;
39 extern SCORES scores[NUMSCORES];
40 extern SCORES old_scores[NUMSCORES];
41 extern SCORES cur;
42
43
44 extern int position;
45 extern GAME_STATE game_state;
46
47
48 flag changed[NUMSCORES]; /* index table of new scores */
49
50 time_t last_time; /* time last changed of hiscores file */
51
52 XtIntervalId slist_clocker;
53
54
init_slist_mgr(void)55 void init_slist_mgr(void)
56 {
57 int pause = SCORE_STATUS_TIMEOUT;
58
59 DEBUG("slist.c", "init_slist_mgr")
60
61 slist_clocker =
62 XtAppAddTimeOut(app_context, pause,
63 (XtTimerCallbackProc)slist_intr, 0);
64 last_time = 0L;
65 }
66
67
slist_intr(w,id)68 void slist_intr(w, id)
69 Widget w;
70 XtIntervalId *id;
71 {
72 int pause = SCORE_STATUS_TIMEOUT;
73
74 DEBUG("slist.c", "slist_intr")
75
76 slist_clocker=XtAppAddTimeOut(app_context, pause,
77 (XtTimerCallbackProc)slist_intr, 0);
78
79 if((game_state == st_idle))
80 draw_slist(kUNFORCED);
81 }
82
83
84
copy_oldscores(void)85 void copy_oldscores(void)
86 {
87 int i;
88
89 DEBUG("slist.c", "copy_oldscores")
90
91 reset_changed();
92
93 if(position < NUMSCORES) {
94 memcpy((char*)&cur, (char*)&scores[position], sizeof(cur));
95 }
96
97 /* make a backup of the old scores */
98 for(i = 0; i < NUMSCORES; i++)
99 old_scores[i] = scores[i];
100 }
101
102
compare_scores(void)103 void compare_scores(void)
104 {
105 /*
106 * Check out which score is new in the list
107 * by comparing the old scorelist with the new one
108 */
109
110 int i,j;
111
112 DEBUG("slist.c", "compare_scores")
113
114 position = NUMSCORES;
115
116 /* now compare old scores with new scores */
117
118 j = 0;
119 for(i = 0; i < NUMSCORES; i++) {
120 if(is_newscore(scores[i]))
121 changed[i] = 1;
122 }
123
124 /*
125 * set the current position in the highscore list to
126 * that of the new score
127 */
128 for(i = 0; i < NUMSCORES; i++) {
129 if(!cmp_score(cur, scores[i])) {
130 position = i;
131 return;
132 }
133 }
134 }
135
136
is_newscore(s)137 flag is_newscore(s)
138 SCORES s;
139 /*
140 * see if a score entry is new, by checking it
141 * against all other entries.
142 */
143 {
144 int i;
145
146 DEBUG("slist.c", "is_newscore")
147
148 for(i = 0; i < NUMSCORES; i++)
149 if(cmp_score(s, old_scores[i]) == 0)
150 return 0;
151 return 1;
152 }
153
154
reset_changed(void)155 void reset_changed(void)
156 {
157 int i;
158
159 DEBUG("slist.c", "reset_changed")
160
161 /* clear changed index */
162 for(i = 0; i < NUMSCORES; i++)
163 changed[i] = 0;
164 }
165
166
cmp_score(s1,s2)167 int cmp_score(s1, s2)
168 SCORES s1, s2;
169 {
170 /*
171 * compare two score entries by looking at the _entire_ info.
172 * Two entries can have the same points, but might originate
173 * from two different players
174 */
175 DEBUG("slist.c", "cmp_score")
176
177 return memcmp((char*)&s1, (char*)&s2, sizeof(s1));
178 }
179
180
181
182
file_changed(s)183 flag file_changed(s)
184 char *s;
185 {
186 struct stat info;
187
188 DEBUG("slist.c", "file_changed")
189
190 if(stat(s, &info) < 0) {
191 fprintf(stderr,"%s '%s' (%d)\n", app_data.wstr_stat,
192 SCOREFILE, errno);
193 return 0;
194 }
195 if(info.st_mtime != last_time) {
196 last_time = info.st_mtime;
197 return 1;
198 }
199 return 0;
200 }
201
202
compose_score_string(s,pos,score,user,date)203 void compose_score_string(s,pos,score, user, date)
204 char *s;
205 int pos;
206 SCORES score;
207 char *user;
208 char *date;
209 {
210 DEBUG("slist.c", "compose_score_string")
211
212 sprintf(s,"%2d %9ld %2d %10s@%-12s %s %c",
213 pos+1, score.score, score.speed, user, score.host,
214 date, score.wizard ? '*' : ' ');
215 }
216
217
218
219