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