/[cvs]/wurmi/viewer.c
ViewVC logotype

Contents of /wurmi/viewer.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.6 - (show annotations)
Mon Sep 10 16:55:22 2007 UTC (11 years, 1 month ago) by riso
Branch: MAIN
CVS Tags: HEAD
Changes since 1.5: +5 -0 lines
File MIME type: text/plain
Finalna verzia

1 #include "board.h"
2 #include "connect.h"
3 #include "SDLutils.h"
4 #include <SDL_thread.h>
5
6 #define THR_STACKSIZE 100000
7 #define TIMER 20
8
9 static const SDL_Color live_players_hi[] = {{255,0,0,0},{0,255,0,0},{0,0,255,0},{150,150,200,0},{255,0,255,0},{0,255,255,0}};
10 static const SDL_Color live_players_lo[] = {{150,0,0,0}, {0,150,0,0}, {0,0,150,0}, {70,70,100,0}, {150,0,150,0}, {0,150,150,0}};
11 static const SDL_Color live_players_dead[] = {{70,0,0,0}, {0,70,0,0}, {0,0,70,0}, {50,50,70,0}, {70,0,70,0}, {0,70,70,0}};
12 static const SDL_Color deadworm = {90,90,90,0};
13
14 SDLOPT options;
15 SDL_mutex *mut;
16 int thread_running=1;
17 TTF_Font *font;
18
19 int verbose =0;
20 int speed=10000;
21 char *server = "127.0.0.1";
22 int port=45678;
23 FILE *streamer;
24 int done = 0,closed=0,single=0;;
25 int scores_width=200;
26
27 /* board variable */
28 BRD *B;
29
30
31 /*
32 * display_help
33 */
34 void display_help() {
35 printf("usage: main <options>\n");
36 printf("\noptinons:\n");
37 printf("-?, --help : print this help page\n");
38 printf("-v : verbose debug messgaes (default off)\n");
39 printf("-f : fullscreen (default off)\n");
40 printf("-hw : use video memory (default no)\n");
41 printf("-w <width> : force width (default none)\n");
42 printf("-h <height>: force height (default none)\n");
43 printf("-b <bpp> : depth (default 32)\n");
44 printf("-sc <width> : width of right-hand scores table");
45 printf("-d <delay> : frame delay in microsec. (default 10000)\n");
46 printf("-s <ip address> : address of the streaming server\n");
47 printf("-p <port> : port of the streaming server\n");
48 printf("-single : single game\n");
49 }
50
51
52 /*
53 * parse_commandline
54 */
55 void parse_commandline(int argc, char ** argv, SDLOPT *opt) {
56 int i;
57
58 /* default video options */
59 opt->video_options_hw_surface=0;
60 opt->video_options_fullscreen=0;
61 opt->video_width=-1;
62 opt->video_height=-1;
63 opt->video_bpp=32;
64
65 /* scan commandline */
66 for (i=1;i<argc;i++) {
67 if (!strcmp(argv[i],"-?") || !strcmp(argv[i],"--help") ) {
68 display_help();
69 exit(1);
70 }
71 if (!strcmp(argv[i],"-v")) {verbose=1;continue;}
72 if (!strcmp(argv[i],"-single")) {single=1;continue;}
73 if (!strcmp(argv[i],"-f")) {opt->video_options_fullscreen=1;continue;}
74 if (!strcmp(argv[i],"-hw")) {opt->video_options_hw_surface=1;continue;}
75 if (!strcmp(argv[i],"-w")) {
76 if (sscanf(argv[i+1],"%d",&(opt->video_width))!=1) {
77 fprintf(stderr,"Wrong width.\n");
78 display_help();
79 exit(1);
80 }
81 i++;
82 continue;
83 }
84 if (!strcmp(argv[i],"-h")) {
85 if (sscanf(argv[i+1],"%d",&(opt->video_height))!=1) {
86 fprintf(stderr,"Wrong height.\n");
87 display_help();
88 exit(1);
89 }
90 i++;
91 continue;
92 }
93 if (!strcmp(argv[i],"-b")) {
94 if (sscanf(argv[i+1],"%d",&(opt->video_bpp))!=1) {
95 fprintf(stderr,"Wrong depth.\n");
96 display_help();
97 exit(1);
98 }
99 i++;
100 continue;
101 }
102 if (!strcmp(argv[i],"-d")) {
103 if (sscanf(argv[i+1],"%d",&(speed))!=1) {
104 fprintf(stderr,"Wrong delay.\n");
105 display_help();
106 exit(1);
107 }
108 i++;
109 continue;
110 }
111 if (!strcmp(argv[i],"-p")) {
112 if (sscanf(argv[i+1],"%d",&port)!=1) {
113 fprintf(stderr,"Wrong port.\n");
114 display_help();
115 exit(1);
116 }
117 i++;
118 continue;
119 }
120 if (!strcmp(argv[i],"-sc")) {
121 if (sscanf(argv[i+1],"%d",&scores_width)!=1) {
122 fprintf(stderr,"Wrong scores_width.\n");
123 display_help();
124 exit(1);
125 }
126 i++;
127 continue;
128 }
129 if (!strcmp(argv[i],"-s")) {
130 server = argv[i+1];
131 i++;
132 continue;
133 }
134 }
135
136 if (opt->video_options_hw_surface) opt->video_options=SDL_HWSURFACE|SDL_HWPALETTE|SDL_DOUBLEBUF; else opt->video_options=SDL_SWSURFACE;
137 if (opt->video_options_fullscreen) opt->video_options|=SDL_FULLSCREEN;
138 }
139
140
141 /* a dummy callback for timer setup */
142 Uint32 my_callback(Uint32 interval, void *param) {
143 SDL_Event event;
144
145 event.type = SDL_USEREVENT;
146 event.user.code = 1;
147 event.user.data1 = 0;
148 event.user.data2 = 0;
149 SDL_PushEvent(&event);
150 return interval;
151 }
152
153
154 /* make pulsating combination of colors */
155 Uint32 Combine(SDL_Surface *screen, int period, int time, SDL_Color src, SDL_Color dst) {
156 Uint8 r,g,b;
157
158 if (time>period) time=2*period-time;
159 r= (Uint8)((double)((period-time)*src.r+time*dst.r)/(double)(period));
160 g= (Uint8)((double)((period-time)*src.g+time*dst.g)/(double)(period));
161 b= (Uint8)((double)((period-time)*src.b+time*dst.b)/(double)(period));
162 return SDL_MapRGB(screen->format,r,g,b);
163 }
164
165
166 /* paint one square of food */
167 void PaintFood(SDL_Surface *screen, int x, int y, SDL_Rect board, unsigned long time) {
168 SDL_Rect R;
169 SDL_Color src={150,150,100,0}, dst={100,100,100,0};
170
171 R.x=x*TILESIZE+board.x;
172 R.y=y*TILESIZE+board.y;
173 R.w=R.h=TILESIZE;
174
175 /* set come color */
176 SDL_FillRect(screen,&R,Combine(screen,300,((x*y)%500+time)%600,src,dst));
177
178 }
179
180
181 /* paint one player tile: player plr at pos x,y */
182 void PaintPlayerTile(SDL_Surface *screen,int plr, int x,int y,SDL_Rect board, unsigned long time, int * live_players){
183
184 SDL_Rect R;
185 Uint32 c;
186 int p=80;
187 unsigned long t;
188
189 R.x=x*TILESIZE+board.x;
190 R.y=y*TILESIZE+board.y;
191 R.w=R.h=TILESIZE;
192
193 /* set come color */
194 if ((B->plr)[plr].alive) {
195 c=Combine(screen,p,(((x+y)%2)?(time%(2*p)):(time+p)%(2*p)),live_players_hi[plr],live_players_lo[plr]);
196 } else {
197 /* dead worm */
198 t=time-(B->plr)[plr].time_of_death;
199 if (t>850) t=850;
200 c=Combine(screen,850,t,live_players_dead[plr],deadworm);
201 }
202
203 SDL_FillRect(screen,&R,c);
204
205 }
206
207 /*
208 * paint the board B into screen rectangle
209 */
210 void PaintBoard(SDL_Surface *screen, SDL_Rect rect, unsigned long time, int * live_players) {
211 int i,j,p;
212
213
214 SDL_FillRect(screen,&rect,0);
215
216 /* paint */
217 for (i=0;i<(B->dim).x;i++)
218 for(j=0;j<(B->dim).y;j++) {
219 if (BPos(B,i,j)==B_FOOD)
220 PaintFood(screen,i,j,rect,time);
221 else if (BPos(B,i,j)!=B_EMPTY) {
222 /* which player */
223 p=BNum(BPos(B,i,j));
224 if (live_players[p]&&(!(B->plr)[p].alive)) {
225 live_players[p]=0;
226 (B->plr)[p].time_of_death=time;
227 }
228 PaintPlayerTile(screen,p,i,j,rect,time,live_players);
229 }
230 }
231 }
232
233
234 /*
235 * print scores
236 */
237 void PrintScores (SDL_Surface *screen,unsigned long time) {
238 SDL_Surface *msg;
239 SDL_Rect clip;
240
241 int i;
242 static char msgstr[10000];
243 unsigned long t;
244 Uint8 r,g,b;
245 SDL_Color clr;
246
247 clip.w=scores_width;
248 clip.h=screen->h;
249 clip.x=screen->w-clip.w;
250 clip.y=0;
251
252 SDL_FillRect(screen,&clip,0x000000);
253
254 for (i=0;i<B->nplayers;i++) {
255 sprintf(msgstr,"%s: %d",B->plr[i].name,B->plr[i].length);
256
257 if (B->plr[i].alive) {
258 msg=TTF_RenderText_Solid(font,msgstr,live_players_hi[i]);
259 } else {
260 t=time-(B->plr)[i].time_of_death;
261 if (t>850) t=850;
262 SDL_GetRGB (Combine(screen,850,t,live_players_lo[i],deadworm), screen->format,&r,&g,&b);
263 clr.r=r;clr.g=g;clr.b=b;
264 msg=TTF_RenderText_Solid(font,msgstr,clr);
265
266 }
267 apply_surface(msg,NULL,screen,clip.x+3,i*50+10);
268 SDL_FreeSurface(msg);
269 }
270 sprintf(msgstr, "Moves: %d", B->moves);
271 clr.r=clr.g=clr.b=255;
272 msg=TTF_RenderText_Solid(font,msgstr,clr);
273 apply_surface(msg,NULL,screen,clip.x+3,3*B->dim.y);
274 SDL_FreeSurface(msg);
275 }
276
277
278 /*
279 * main display procedure - setup stuff and event loop
280 * B must be properly set up before running this !!
281 */
282 int DisplayLoopThread(void *threadid){
283
284 SDL_Surface *screen, *border_tile;
285 int border_tilesize=32;
286
287 char kb; /* pressed key */
288
289 unsigned long time=0;
290 int *live_players;
291 int i,j;
292
293 SDL_Event event;
294 SDL_TimerID Timer;
295
296 SDL_Rect board_rect;
297
298 live_players=(int *)malloc(B->nplayers*sizeof(int));
299 for (i=0;i<B->nplayers;i++)
300 if (B->plr[i].alive) live_players[i]=1;
301 else {
302 live_players[i]=0;
303 B->plr[i].time_of_death=0;
304 }
305
306
307 /* set dimensions of the playground */
308 board_rect.x=30;
309 board_rect.y=30;
310 board_rect.w=TILESIZE*((B->dim).x);
311 board_rect.h=TILESIZE*((B->dim).y);
312
313 /* setup video and font */
314 if (options.video_width==-1) options.video_width=30+board_rect.w+40+scores_width;
315 if (options.video_height==-1) options.video_height=30+board_rect.h+70;
316 screen=init_video(&options);
317
318 font = TTF_OpenFont( "font.ttf", 18 );
319 if (font==NULL) ERROR("font.ttf not found\n");
320
321 /* prepare background */
322 border_tile=load_jpeg("tile.jpg");
323 if (border_tile==NULL) ERROR("tile.png not found\n");
324
325 /* put borders onto screen */
326 for (i=0;i<=board_rect.w+border_tilesize;i+=border_tilesize) {
327 apply_surface(border_tile,NULL,screen, board_rect.x-border_tilesize+i,board_rect.y-border_tilesize);
328 apply_surface(border_tile,NULL,screen, board_rect.x-border_tilesize+i,board_rect.y+board_rect.h);
329 }
330 for (j=0;j<=board_rect.h;j+=border_tilesize) {
331 apply_surface(border_tile,NULL,screen, board_rect.x-border_tilesize,board_rect.y+j);
332 apply_surface(border_tile,NULL,screen, board_rect.x+board_rect.w,board_rect.y+j);
333 }
334
335 /* clear event queue */
336 while(SDL_PollEvent(&event));
337
338 /* set timer for periodical updates */
339 Timer=SDL_AddTimer(TIMER, my_callback, NULL);
340 //my_callback(0,0);
341
342 /* paint the game into rectangle */
343 PaintBoard(screen,board_rect,time,live_players);
344 PrintScores(screen,time);
345
346 SDL_Flip(screen);
347
348
349 for(done=0;!done;){
350 if (!SDL_WaitEvent( &event )) break;
351 //printf("got event %lu\n",event.type);
352 switch( event.type ){
353 case SDL_USEREVENT:
354 time++;
355 SDL_mutexP(mut);
356 PaintBoard(screen,board_rect,time,live_players);
357 PrintScores(screen,time);
358 SDL_mutexV(mut);
359 SDL_Flip(screen);
360 while (SDL_PeepEvents(&event,1,SDL_GETEVENT,SDL_EVENTMASK(SDL_USEREVENT)));//{fprintf(stderr,"#");fflush(stderr);}
361 break;
362
363 case SDL_KEYDOWN:
364 if(event.key.keysym.sym==SDLK_ESCAPE) {done=1;break;}
365 if(event.key.keysym.sym==SDLK_f) {
366 SDL_WM_ToggleFullScreen(screen);
367 break;
368 }
369 if(event.key.keysym.sym==SDLK_z) {
370 SDL_mutexP(mut);
371 if (speed<1000) speed=0;
372 else speed-=1000;
373 SDL_mutexV(mut);
374 printf("increase speed (%d)\n",speed);
375 break;
376 }
377 if(event.key.keysym.sym==SDLK_x) {
378 speed+=1000;
379 printf("decrease speed (%d)\n",speed);
380 break;
381 }
382 if ((event.key.keysym.sym>=SDLK_a)&&(event.key.keysym.sym<=SDLK_z))
383 kb=event.key.keysym.sym-SDLK_a;
384 printf( "Key press detected %d\n",kb );
385 break;
386
387 case SDL_KEYUP:
388 /*printf( "Key release detected\n" );*/
389 break;
390
391 default:
392 break;
393 }
394 }
395
396 printf("Shutdown SDL...");fflush(stdout);
397
398 /* Shutdown all subsystems */
399 TTF_CloseFont( font );
400 TTF_Quit();
401 SDL_Quit();
402 free(live_players);
403 thread_running=0;
404 printf("done\n");
405 return 0;
406 }
407
408 void dbg() {
409 int i,j;
410 fprintf(stderr, "\n\n");
411 for (i=0; i<B->dim.y; i++) {
412 for (j=0; j<B->dim.x; j++)
413 fprintf(stderr, "%c", BPos(B,j,i)+33);
414 fprintf(stderr, "\n");
415 }
416 }
417
418 int main(int argc, char ** argv) {
419 SDL_Thread *tr;
420 char tmp[BUFFERSIZE];
421
422 parse_commandline(argc,argv,&options);
423 printf("viewer running on server %s:%u\n",server,port);
424
425 while (!(streamer = Connect(server, port))) sleep(1);
426 fgets(tmp, sizeof(tmp), streamer);
427 B = ReadBoard(tmp);
428
429 mut=SDL_CreateMutex();
430 tr=SDL_CreateThread(DisplayLoopThread,0);
431
432 printf("viewer: entering event loop\n");
433 while(thread_running&&!done) {
434 if (!feof(streamer)) {
435 fgets(tmp, sizeof(tmp), streamer);
436 SDL_mutexP(mut);
437 ApplyCommand(B, tmp);
438 //fprintf(stderr, "%s\n", tmp);
439 //dbg();
440 SDL_mutexV(mut);
441 usleep(speed);
442 }else {
443 if (single) {
444 printf("viewer: end of stream, waiting 5 sec before exit\n");
445 sleep(5);
446 done=1;
447 } else {
448 printf("viewer: end of stream, waiting for next game\n");
449 while (!(streamer = Connect(server, port))) sleep(1);
450 fgets(tmp, sizeof(tmp), streamer);
451 B = ReadBoard(tmp);
452 }
453 }
454 }
455 SDL_WaitThread(tr,NULL);
456 printf("viewer: exiting\n");
457 return 0;
458 }
459
460

CVS Admin">CVS Admin
ViewVC Help
Powered by ViewVC 1.1.26