de-uglyfied ship glList
[cave9.git] / src / display.cpp
blob16ddc767543c3b204999b7c03c81a1995a061590
2 #include <SDL_image.h>
3 #include <SDL_opengl.h>
4 #include <GL/gl.h>
5 #include <GL/glu.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <math.h>
9 #include <float.h>
10 #include <assert.h>
11 #include "display.h"
13 void viewport(Display* display, GLsizei w, GLsizei h, GLsizei bpp,
14 bool fullscreen, int aa=0)
16 // video mode
17 SDL_GL_SetAttribute( SDL_GL_RED_SIZE, bpp/3 );
18 SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, bpp/3 );
19 SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, bpp/3 );
20 SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
21 SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
23 if(aa) {
24 SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 );
25 SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, aa );
28 int flags = SDL_HWSURFACE|SDL_OPENGLBLIT|SDL_RESIZABLE;
29 if(fullscreen)
30 flags |= SDL_FULLSCREEN;
31 display->screen = SDL_SetVideoMode(w, h, bpp, flags);
32 if(display->screen == NULL)
33 goto error;
35 bpp = display->screen->format->BitsPerPixel;
36 //printf("%dx%dx%d\n", display->screen->w, display->screen->h, display->screen->format->BitsPerPixel);
38 #if 0
39 if(aa) {
40 int arg;
41 SDL_GL_GetAttribute( SDL_GL_MULTISAMPLEBUFFERS, &arg );
42 printf("SDL_GL_MULTISAMPLEBUFFERS %d\n", arg);
43 SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &arg );
44 printf("SDL_GL_MULTISAMPLESAMPLES %d\n", arg);
46 #endif
48 SDL_WM_SetCaption("cave9 -- 9hells.org", "cave9");
49 SDL_ShowCursor(SDL_DISABLE);
51 // projection
52 glViewport(0,0,w,h);
54 glMatrixMode(GL_PROJECTION);
55 glLoadIdentity();
56 gluPerspective(45,-w/(GLfloat)h,display->near_plane,display->far_plane);
59 // settings
60 glClearColor(0,0,0,0);
61 glClearDepth(1);
63 glDepthFunc(GL_LEQUAL);
64 glEnable(GL_DEPTH_TEST);
66 glPolygonMode( GL_FRONT, GL_FILL );
67 glEnable(GL_CULL_FACE);
68 glCullFace(GL_FRONT);
70 if(aa) {
71 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
72 glShadeModel(GL_SMOOTH);
73 glEnable(GL_LINE_SMOOTH);
74 } else {
75 glShadeModel(GL_FLAT);
76 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
79 glLineWidth(16);
81 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
84 glFogi(GL_FOG_MODE, GL_LINEAR);
85 GLfloat fog_color[] = {0,0,0,1};
86 glFogfv(GL_FOG_COLOR, fog_color);
87 glFogf(GL_FOG_START, display->near_plane);
88 glFogf(GL_FOG_END, display->far_plane);
89 glEnable(GL_FOG);
92 if(aa) {
93 #ifdef GL_ARB_multisample
94 glEnable(GL_MULTISAMPLE_ARB);
95 #endif
96 glHint(GL_MULTISAMPLE_FILTER_HINT_NV,GL_NICEST);
99 return;
100 error:
101 fprintf(stderr, "SDL ERROR: %s\n", SDL_GetError());
102 exit(1);
105 void display_world_transform(Display* display, Ship* player)
107 COPY(display->cam, player->pos);
108 ADD2(display->target, player->pos, player->lookAt);
109 //display->target[1]=display->target[1]*.5+player->pos[1]*.5;
110 //display->target[2]+=10;
111 gluLookAt(
112 display->cam[0], display->cam[1], display->cam[2],
113 display->target[0], display->target[1], display->target[2],
114 0,1,0
118 void cave_model(Display* display, Cave* cave, int wire)
120 for( int i = 0; i < SEGMENT_COUNT-1; ++i ) {
121 int i0 = (cave->i + i)%SEGMENT_COUNT;
123 if( (wire ? cave->gl_wire_list : cave->gl_list)[i0] == 0 ) {
124 int id = wire ?
125 (cave->gl_wire_list[i0] = i0 + display->wire_list_start) :
126 (cave->gl_list[i0] = i0 + display->list_start) ;
128 glNewList( id, GL_COMPILE );
130 int i1 = (i0 + 1)%SEGMENT_COUNT;
131 if(!wire)
132 glBindTexture(GL_TEXTURE_2D, display->texture_id);
133 glBegin(GL_QUAD_STRIP);
134 for( int k = 0; k <= SECTOR_COUNT; ++k ) {
136 int k0 = k%SECTOR_COUNT;
138 if(!wire) {
139 if(i0==0||i1==0||k==3*SECTOR_COUNT/4)
140 glColor4f(1, 0, 0, 0.5);
141 else
142 glColor4f(1, 1, 1, 0.5);
145 if(!wire) {
146 glTexCoord2f(
147 (float)(cave->i+i)/SEGMENT_COUNT,
148 (float)k/SECTOR_COUNT);
149 } else {
150 glColor4f(
151 (float)i0/SEGMENT_COUNT,
152 1-(float)i0/SEGMENT_COUNT,
153 (float)k0/SECTOR_COUNT,
154 0.5);
156 glVertex3fv(cave->segs[i0][k0]);
158 if(!wire) {
159 glTexCoord2f(
160 ((float)(cave->i+i+1))/SEGMENT_COUNT,
161 (float)k/SECTOR_COUNT);
162 } else {
163 glColor4f(
164 (float)i1/SEGMENT_COUNT,
165 1-(float)i1/SEGMENT_COUNT,
166 (float)k0/SECTOR_COUNT,
167 0.5);
169 glVertex3fv(cave->segs[i1][k0]);
171 glEnd();
173 glEndList();
176 if(wire) {
177 glDisable(GL_DEPTH_TEST);
178 glEnable(GL_BLEND);
179 glDisable(GL_TEXTURE_2D);
180 } else {
181 glEnable(GL_DEPTH_TEST);
182 glDisable(GL_BLEND);
183 glEnable(GL_TEXTURE_2D);
186 glCallList( (wire ? cave->gl_wire_list : cave->gl_list)[i0] );
191 void monolith_model(Display* display, Cave* cave, Ship* player)
193 if(!display->monoliths)
194 return;
196 glColor3f(.2,.2,.2);
198 float w = MONOLITH_WIDTH/2;
199 float h = MONOLITH_HEIGHT/2;
200 float d = MONOLITH_DEPTH;
202 glEnable(GL_DEPTH_TEST);
203 glDisable(GL_BLEND);
204 glDisable(GL_TEXTURE_2D);
206 glPushMatrix();
208 glTranslatef( cave->monolith_x, cave->monolith_y, cave->segs[0][0][2] );
209 glRotatef( cave->monolith_yaw, 1, 0, 0 );
211 glBegin( GL_QUAD_STRIP );
212 glVertex3f( +w, -h, d ); glVertex3f( -w, -h, d );
213 glVertex3f( +w, -h, 0 ); glVertex3f( -w, -h, 0 );
214 glVertex3f( +w, +h, 0 ); glVertex3f( -w, +h, 0 );
215 glVertex3f( +w, +h, d ); glVertex3f( -w, +h, d );
216 glEnd();
218 glBegin( GL_QUADS );
219 glVertex3f( -w, -h, d ); glVertex3f( -w, +h, d );
220 glVertex3f( -w, +h, 0 ); glVertex3f( -w, -h, 0 );
222 glVertex3f( +w, +h, d ); glVertex3f( +w, -h, d );
223 glVertex3f( +w, -h, 0 ); glVertex3f( +w, +h, 0 );
224 glEnd();
226 glPopMatrix();
229 void ship_model(Display* display, Ship* ship)
231 if(!display->cockpit)
232 return;
234 if(ship->dist <= 0)
235 return;
237 float alpha = (1-MIN(1,(ship->pos[2]/MIN_CAVE_RADIUS_DEPTH)))/8.;
238 if(alpha == 0)
239 return;
241 float alert_dist = ship->radius*10;
242 float white = ship->dist <= 0 || ship->dist > alert_dist ? 1 :
243 1-(alert_dist - ship->dist)/alert_dist;
245 float f =1.8;
247 glDisable(GL_DEPTH_TEST);
248 glEnable(GL_BLEND);
249 glDisable(GL_TEXTURE_2D);
251 glColor4f(1,white,white,alpha);
252 glPushMatrix();
253 glTranslatef(0,0,-SHIP_RADIUS*f);
254 glCallList( display->ship_list );
255 glPopMatrix();
257 glPushMatrix();
258 display_world_transform(display, ship);
259 glTranslatef(
260 ship->pos[0],
261 ship->pos[1],
262 ship->pos[2]+SHIP_RADIUS*f
264 glCallList( display->ship_list );
265 glPopMatrix();
268 void render_text(Display* display, GLuint id, const char* text,
269 float x, float y, float w, float h,
270 float r, float g, float b)
272 if(text == NULL || text[0] == '\0')
273 return;
274 SDL_Color color = {0xff,0xff,0xff,0xff};
275 SDL_Surface* label = TTF_RenderText_Blended(display->font, text, color);
276 assert(label != NULL);
278 glDisable(GL_DEPTH_TEST);
279 glEnable(GL_BLEND);
280 glEnable(GL_TEXTURE_2D);
282 glBindTexture(GL_TEXTURE_2D, id);
283 gluBuild2DMipmaps(GL_TEXTURE_2D,
284 GL_RGBA, label->w, label->h,
285 GL_RGBA, GL_UNSIGNED_BYTE, label->pixels);
287 SDL_FreeSurface(label);
289 glPushMatrix();
290 glColor3f(r,g,b);
291 glTranslatef(0,0,-2.65); // XXX magic number
292 glBegin(GL_QUAD_STRIP);
293 glTexCoord2f(0,1); glVertex3f(1-x*2+w,1-y*2-h,.5);
294 glTexCoord2f(0,0); glVertex3f(1-x*2+w,1-y*2+h,0);
296 glTexCoord2f(1,1); glVertex3f(1-x*2-w,1-y*2-h,.5);
297 glTexCoord2f(1,0); glVertex3f(1-x*2-w,1-y*2+h,0);
298 glEnd();
299 glPopMatrix();
302 void display_hud(Display* display, Ship* player)
304 if(player->dist == FLT_MAX)
305 return;
307 float max_vel[3] = { MAX_VEL_X, MAX_VEL_Y, MAX_VEL_Z };
308 float vel = MIN(1,
309 log(1+LEN(player->vel)-MAX_VEL_Z) /
310 log(1+LEN(max_vel)-MAX_VEL_Z));
311 char gauge[11];
312 int i = int(vel*10);
313 memset(gauge,'/',i);
314 gauge[i] = '\0';
316 int score = (int)player->pos[2];
318 #define HUD_TEXT_MAX 80
319 char buf[HUD_TEXT_MAX];
320 if(player->dist > 0) {
321 snprintf(buf, HUD_TEXT_MAX, "velocity %-10s score %9d",
322 gauge, score
324 } else {
325 if(score > display->session_score)
326 display->session_score = score;
327 if(player->start) {
328 snprintf(buf, HUD_TEXT_MAX, "velocity %s score %d (%d) - %d",
329 gauge, score,
330 display->session_score,
331 (int)player->start
333 } else {
334 if(score > display->local_score) {
335 display->local_score = score;
336 FILE* fp = fopen(SCORE_FILE, "w");
337 if(fp == NULL) {
338 perror("failed to open score file");
339 } else {
340 fprintf(fp, "%d", display->local_score);
341 fclose(fp);
344 if(score > display->global_score) {
345 display->global_score = score;
346 display_net_update(display);
348 snprintf(buf, HUD_TEXT_MAX, "velocity %s score %d (%d/%d/%d)",
349 gauge, score,
350 display->session_score,
351 display->local_score,
352 display->global_score
357 float white = player->dist <= 0 ? 1 : 1-vel;
358 render_text(display, display->hud_id, buf, .5,.9,1,.2, 1,white,white);
361 char display_message_buf[256];
362 void display_message(Display* display, Cave* cave, Ship* player, const char* buf)
364 strncpy(display_message_buf, buf, sizeof(display_message_buf)-1);
365 display_message_buf[sizeof(display_message_buf)-1] = '\0';
366 display_frame(display, cave, player);
369 void display_start_frame(Display* display, float r, float g, float b)
371 glClearColor(r,g,b,1);
372 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
373 glMatrixMode(GL_MODELVIEW);
374 glLoadIdentity();
377 void display_end_frame(Display* display)
379 glFinish();
381 SDL_GL_SwapBuffers();
384 void display_frame(Display* display, Cave* cave, Ship* player)
386 int hit = player->dist <= SHIP_RADIUS*1.1;
388 display_start_frame(display, hit,0,0);
390 if(!hit) { // avoid drawing the cave from outside
391 glPushMatrix();
392 display_world_transform(display, player);
393 cave_model(display, cave, 0);
394 monolith_model(display, cave, player);
395 glPopMatrix();
398 ship_model(display, player);
399 display_minimap(display, cave, player);
400 display_hud(display, player);
401 render_text(display, display->msg_id, display_message_buf, .5,.5,1,.25, 1,1,1);
403 display_end_frame(display);
406 GLuint display_make_ship_list()
408 /* Magic Numbers: It is possible to create a dodecahedron by attaching two pentagons
409 * to each face of a cube. The coordinates of the points are:
410 * (+-x,0, z); (+-1, 1, 1); (0, z, x )
411 * where x = 0.61803398875 and z = 1.61803398875.
414 const double x = 0.61803398875;
415 const double z = 1.61803398875;
416 const double n1 = 0.525731112119;
417 const double n2 = 0.850650808354;
419 GLuint ship_list = glGenLists( SEGMENT_COUNT );
420 glNewList( ship_list, GL_COMPILE );
421 glBegin( GL_LINE_LOOP );
422 glNormal3d( 0, n1, n2 );
423 glVertex3d( 0, z, x );
424 glVertex3d( -1, 1, 1 );
425 glVertex3d( -x, 0, z );
426 glVertex3d( x, 0, z );
427 glVertex3d( 1, 1, 1 );
428 glEnd();
429 glBegin( GL_LINE_LOOP );
430 glNormal3d( 0, n1, -n2 );
431 glVertex3d( 0, z, -x );
432 glVertex3d( 1, 1, -1 );
433 glVertex3d( x, 0, -z );
434 glVertex3d( -x, 0, -z );
435 glVertex3d( -1, 1, -1 );
436 glEnd();
437 glBegin( GL_LINE_LOOP );
438 glNormal3d( 0, -n1, n2 );
439 glVertex3d( 0, -z, x );
440 glVertex3d( 1, -1, 1 );
441 glVertex3d( x, 0, z );
442 glVertex3d( -x, 0, z );
443 glVertex3d( -1, -1, 1 );
444 glEnd();
445 glBegin( GL_LINE_LOOP );
446 glNormal3d( 0, -n1, -n2 );
447 glVertex3d( 0, -z, -x );
448 glVertex3d( -1, -1, -1 );
449 glVertex3d( -x, 0, -z );
450 glVertex3d( x, 0, -z );
451 glVertex3d( 1, -1, -1 );
452 glEnd();
454 glBegin( GL_LINE_LOOP );
455 glNormal3d( n2, 0, n1 );
456 glVertex3d( x, 0, z );
457 glVertex3d( 1, -1, 1 );
458 glVertex3d( z, -x, 0 );
459 glVertex3d( z, x, 0 );
460 glVertex3d( 1, 1, 1 );
461 glEnd();
462 glBegin( GL_LINE_LOOP );
463 glNormal3d( -n2, 0, n1 );
464 glVertex3d( -x, 0, z );
465 glVertex3d( -1, 1, 1 );
466 glVertex3d( -z, x, 0 );
467 glVertex3d( -z, -x, 0 );
468 glVertex3d( -1, -1, 1 );
469 glEnd();
470 glBegin( GL_LINE_LOOP );
471 glNormal3d( n2, 0, -n1 );
472 glVertex3d( x, 0, -z );
473 glVertex3d( 1, 1, -1 );
474 glVertex3d( z, x, 0 );
475 glVertex3d( z, -x, 0 );
476 glVertex3d( 1, -1, -1 );
477 glEnd();
478 glBegin( GL_LINE_LOOP );
479 glNormal3d( -n2, 0, -n1 );
480 glVertex3d( -x, 0, -z );
481 glVertex3d( -1, -1, -1 );
482 glVertex3d( -z, -x, 0 );
483 glVertex3d( -z, x, 0 );
484 glVertex3d( -1, 1, -1 );
485 glEnd();
487 glBegin( GL_LINE_LOOP );
488 glNormal3d( n1, n2, 0 );
489 glVertex3d( z, x, 0 );
490 glVertex3d( 1, 1, -1 );
491 glVertex3d( 0, z, -x );
492 glVertex3d( 0, z, x );
493 glVertex3d( 1, 1, 1 );
494 glEnd();
495 glBegin( GL_LINE_LOOP );
496 glNormal3d( n1, -n2, 0 );
497 glVertex3d( z, -x, 0 );
498 glVertex3d( 1, -1, 1 );
499 glVertex3d( 0, -z, x );
500 glVertex3d( 0, -z, -x );
501 glVertex3d( 1, -1, -1 );
502 glEnd();
503 glBegin( GL_LINE_LOOP );
504 glNormal3d( -n1, n2, 0 );
505 glVertex3d( -z, x, 0 );
506 glVertex3d( -1, 1, 1 );
507 glVertex3d( 0, z, x );
508 glVertex3d( 0, z, -x );
509 glVertex3d( -1, 1, -1 );
510 glEnd();
511 glBegin( GL_LINE_LOOP );
512 glNormal3d( -n1, -n2, 0 );
513 glVertex3d( -z, -x, 0 );
514 glVertex3d( -1, -1, -1 );
515 glVertex3d( 0, -z, -x );
516 glVertex3d( 0, -z, x );
517 glVertex3d( -1, -1, 1 );
518 glEnd();
520 glEndList();
522 return ship_list;
525 void display_init(Display* display, Args* args)
528 memset(display, 0, sizeof(Display));
530 if(SDL_Init(SDL_INIT_VIDEO) != 0) {
531 fprintf(stderr, "SDL_Init(): %s\n", SDL_GetError());
532 exit(1);
534 atexit(SDL_Quit);
536 display->near_plane = MIN(SEGMENT_LEN,SHIP_RADIUS)/4.; // was EPSILON;
537 display->far_plane = SEGMENT_COUNT * SEGMENT_LEN;
538 SET(display->cam, 0,0,0);
539 SET(display->target, 0,0,1);
541 int w = args->width;
542 int h = args->height;
543 int f = args->fullscreen;
544 if(args->highres) {
545 #if SDL_VERSION_ATLEAST(1,2,11)
546 const SDL_VideoInfo* info = SDL_GetVideoInfo();
547 assert(info != NULL);
548 w = info->current_w;
549 h = info->current_h;
550 #else
551 w = 1024;
552 h = 768;
553 #endif
554 f = 1;
556 viewport(display, w, h, args->bpp, f, args->antialiasing);
558 display->list_start = glGenLists( SEGMENT_COUNT );
559 display->wire_list_start = glGenLists( SEGMENT_COUNT );
561 if(TTF_Init() != 0) {
562 fprintf(stderr, "TTF_Init(): %s\n", TTF_GetError());
563 exit(1);
565 atexit(TTF_Quit);
567 char* font_filename = FONT_FILE;
568 int font_size = args->antialiasing ? 96 : 48;
569 display->font = TTF_OpenFont(font_filename, font_size); // FIXME path
570 if(display->font == NULL) {
571 fprintf(stderr, "TTF_OpenFont(%s): %s\n", font_filename, TTF_GetError());
572 exit(1);
575 glGenTextures(1, &display->hud_id);
576 glBindTexture(GL_TEXTURE_2D, display->hud_id);
577 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
578 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
579 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
580 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
582 glGenTextures(1, &display->msg_id);
583 glBindTexture(GL_TEXTURE_2D, display->msg_id);
584 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
585 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
586 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
587 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
589 display_start_frame(display, 0,0,0);
590 render_text(display, display->msg_id, "loading cave9", .5,.5,1,.25, 1,1,1);
591 display_end_frame(display);
593 char* texture_filename = TEXTURE_FILE;
595 glGenTextures(1, &display->texture_id);
596 glBindTexture(GL_TEXTURE_2D, display->texture_id);
597 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
598 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
600 SDL_Surface* texture = IMG_Load(texture_filename);
601 if(texture == NULL) {
602 fprintf(stderr, "IMG_Load(%s): %s\n", texture_filename, IMG_GetError());
603 exit(1);
606 GLenum err = gluBuild2DMipmaps(GL_TEXTURE_2D,
607 GL_RGB, texture->w, texture->h,
608 GL_RGB, GL_UNSIGNED_BYTE,texture->pixels);
609 if(err) {
610 fprintf(stderr, "gluBuild2DMipmaps(): %s\n", gluErrorString(err));
611 exit(1);
614 SDL_FreeSurface(texture);
616 display->ship_list = display_make_ship_list();
618 display->monoliths = args->monoliths;
619 display->cockpit = args->cockpit;
621 display->session_score = 0;
623 display->local_score = 0;
624 FILE* fp = fopen(SCORE_FILE, "r");
625 if(fp == NULL) {
626 perror("failed to open score file");
627 } else {
628 fscanf(fp, "%d", &display->local_score);
629 fclose(fp);
632 display->global_score = 0;
634 if(SDLNet_Init()==-1)
636 fprintf(stderr, "SDLNet_Init(): %s\n",SDLNet_GetError());
637 exit(1);
639 atexit(SDLNet_Quit);
641 IPaddress addr;
642 display->udp_sock = 0;
643 display->udp_pkt = NULL;
644 if(SDLNet_ResolveHost(&addr,GLOBAL_SCORE_HOST, GLOBAL_SCORE_PORT) == -1) {
645 fprintf(stderr, "SDLNet_ResolveHost(): %s\n", SDLNet_GetError());
646 } else {
647 display->udp_sock=SDLNet_UDP_Open(0);
648 if(display->udp_sock == 0) {
649 fprintf(stderr, "SDLNet_UDP_Open(): %s\n", SDLNet_GetError());
650 display_net_finish(display);
651 } else {
652 if(SDLNet_UDP_Bind(display->udp_sock, 0, &addr) == -1) {
653 fprintf(stderr, "SDLNet_UDP_Bind(): %s\n", SDLNet_GetError());
654 display_net_finish(display);
655 } else {
656 display->udp_pkt = SDLNet_AllocPacket(GLOBAL_SCORE_LEN);
657 if(display->udp_pkt == NULL) {
658 display_net_finish(display);
666 void display_net_update(Display* display)
668 if(display->udp_sock == 0)
669 return;
671 snprintf((char*)display->udp_pkt->data,GLOBAL_SCORE_LEN,"%d",display->global_score);
672 display->udp_pkt->len = GLOBAL_SCORE_LEN;
673 if(SDLNet_UDP_Send(display->udp_sock,0,display->udp_pkt) == 0) {
674 fprintf(stderr, "SDLNet_UDP_Send(): %s\n", SDLNet_GetError());
675 } else {
676 SDL_Delay(666); // XXX only wait 666ms for hiscores
677 if(SDLNet_UDP_Recv(display->udp_sock,display->udp_pkt) == 0) {
678 fprintf(stderr, "SDLNet_UDP_Recv(%s,%d): %s\n",
679 GLOBAL_SCORE_HOST, GLOBAL_SCORE_PORT, SDLNet_GetError());
680 } else {
681 sscanf((char*)display->udp_pkt->data,"%d",&display->global_score);
686 void display_net_finish(Display* display)
688 if(display->udp_pkt != NULL){
689 SDLNet_FreePacket(display->udp_pkt);
690 display->udp_pkt = NULL;
692 if(display->udp_sock != 0) {
693 SDLNet_UDP_Close(display->udp_sock);
694 display->udp_sock = 0;
698 void display_minimap(Display* display, Cave* cave, Ship* player)
700 glPushMatrix();
701 glScalef(.0065,.003,.001);
702 glRotatef(-90,0,1,0);
703 glTranslatef(
704 -player->pos[0]-1000, // XXX hardcoded
705 -player->pos[1]-100,
706 -player->pos[2]-(SEGMENT_COUNT-1)*SEGMENT_LEN/2);
707 cave_model(display, cave, 1);
708 glPopMatrix();
712 // vim600:fdm=syntax:fdn=1: