예제 #1
0
/*!
 tux_open_courses Tcl callback
 \author  jfpatry
 \date    Created:  2000-09-19
 \date    Modified: 2000-09-19
 */
static int open_courses_cb( ClientData cd, Tcl_Interp *ip,
                            int argc, const char **argv )
{
    char *err_msg;
    const char **list = NULL;
    int num_courses;
    list_elem_t last_elem = NULL;
    list_elem_t last_speed_elem = NULL;
    list_elem_t last_score_elem = NULL;
    int i, j;
    char preview_file[100];

    check_assertion( initialized,
                     "course_mgr module not initialized" );

    if ( argc != 2 ) {
        err_msg = "Wrong number of arguments";
        goto bail_open_courses;
    }

    if ( Tcl_SplitList( ip, argv[1], &num_courses, &list ) == TCL_ERROR ) {
        err_msg = "Argument is not a list";
        goto bail_open_courses;
    }

    /* Add items to end of list */
    last_elem = get_list_tail( open_course_list );
    last_speed_elem = get_list_tail( speed_course_list );
    last_score_elem = get_list_tail( score_course_list );

    for ( i=0; i<num_courses; i++ ) {
        open_course_data_t *data;
        data = create_open_course_data( ip, list[i], &err_msg );

#ifdef __ANDROID__
        sprintf(preview_file, "courses/%s/preview.jpg", data->course);
#else
        sprintf(preview_file, "%s/courses/%s/preview.jpg", getparam_data_dir(), data->course);
#endif

        load_texture(data->course, preview_file, 1);
        bind_texture(data->course, data->course);

        if ( data == NULL ) {
            goto bail_open_courses;
        }

        last_elem = insert_list_elem(
                        open_course_list,
                        last_elem,
                        (list_elem_data_t) data );
        if(data->speed)
        {
            last_speed_elem = insert_list_elem(
                                  speed_course_list,
                                  last_speed_elem,
                                  (list_elem_data_t) data );
        }
        if(data->score)
        {
            last_score_elem = insert_list_elem(
                                  score_course_list,
                                  last_score_elem,
                                  (list_elem_data_t) data );
        }

    }

    Tcl_Free( (char*) list );
    list = NULL;

    return TCL_OK;

bail_open_courses:

    /* We'll leave the data that was successfully added in the list. */

    Tcl_AppendResult(
        ip,
        "Error in call to tux_open_courses: ",
        err_msg,
        "\n",
        "Usage: tux_open_courses { list of open courses }",
        (NULL) );
    return TCL_ERROR;
}
예제 #2
0
/*! 
  Sets the font binding to be used when the button is disabled
  \author  jfpatry
  \date    Created:  2000-09-17
  \date    Modified: 2000-09-17
*/
void button_set_disabled_font_binding( button_t *button, char *binding )
{
    check_assertion( button != NULL, "button is NULL" );

    button->disabled_font_binding = binding;
}
예제 #3
0
bool_t load_texture( char *texname, char *filename, int repeatable )
{
    IMAGE *texImage;
    texture_node_t *tex;
    int max_texture_size;


    print_debug(DEBUG_TEXTURE, "Loading texture %s from file: %s", 
		texname, filename);
    if ( initialized == False ) {
        check_assertion( 0, "texture module not initialized" );
    } 

    texImage = ImageLoad( filename );

    if ( texImage == NULL ) {
    	print_warning( IMPORTANT_WARNING, 
		       "couldn't load image %s", filename );
    	return False;
    }

    if (get_hash_entry( texture_table, texname, (hash_entry_t*)&tex )) { 
	print_debug(DEBUG_TEXTURE, "Found texture %s with id: %d", 
		    texname, tex->texture_id);
        glDeleteTextures( 1, &(tex->texture_id) );
    } else {
        tex = (texture_node_t*)malloc(sizeof(texture_node_t));

	check_assertion( tex != NULL, "out of memory" );

	tex->ref_count = 0;
	add_hash_entry( texture_table, texname, (hash_entry_t)tex ); 
    }
 
    tex->repeatable = repeatable;
    glGenTextures( 1, &(tex->texture_id) );
    glBindTexture( GL_TEXTURE_2D, tex->texture_id );

    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);


    if ( repeatable ) {
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
    } else {
#ifndef __APPLE__DISABLED__
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
#endif
    }
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
                     get_min_filter() );

    /* Check if we need to scale image */
    glGetIntegerv( GL_MAX_TEXTURE_SIZE, &max_texture_size );
    if ( texImage->sizeX > max_texture_size ||
	 texImage->sizeY > max_texture_size ) 
    {
#ifdef __APPLE__DISABLED__
        abort(); //We don't support that yet
#else
	char *newdata = (char*)malloc( texImage->sizeZ *
				       max_texture_size *
				       max_texture_size );

	check_assertion( newdata != NULL, "out of memory" );

	print_debug( DEBUG_TEXTURE, "Texture `%s' too large -- scaling to "
		     "maximum allowed size",
		     filename );


	/* In the case of large- or small-aspect ratio textures, this
           could end up using *more* space... oh well. */
	gluScaleImage( texImage->sizeZ == 3 ? GL_RGB : GL_RGBA,
		       texImage->sizeX, texImage->sizeY, 
		       GL_UNSIGNED_BYTE,
		       texImage->data,
		       max_texture_size, max_texture_size, 
		       GL_UNSIGNED_BYTE,
		       newdata );

	free( texImage->data );
	texImage->data = (unsigned char*) newdata;
	texImage->sizeX = max_texture_size;
	texImage->sizeY = max_texture_size;
#endif
    }

#ifndef __APPLE__
    gluBuild2DMipmaps( GL_TEXTURE_2D, texImage->sizeZ, texImage->sizeX,
		       texImage->sizeY, texImage->sizeZ == 3 ? GL_RGB : GL_RGBA, 
		       GL_UNSIGNED_BYTE, texImage->data );
#else
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    
    glTexImage2D( GL_TEXTURE_2D, 0, texImage->sizeZ == 3 ? GL_RGB : GL_RGBA, texImage->sizeX,
		       texImage->sizeY == 255 ? 256 : texImage->sizeY /* Work around for tree.png */,
               0, texImage->sizeZ == 3 ? GL_RGB : GL_RGBA,
		       GL_UNSIGNED_BYTE, texImage->data );
#endif
    free( texImage->data );
    free( texImage );
	TRDebugLog("%dx%d %d (%d)\n", texImage->sizeX, texImage->sizeY, texImage->sizeZ, glGetError());
    return True;
} 
예제 #4
0
파일: audio.c 프로젝트: wosigh/tuxracer
/*! 
  Initializes the audio module.
  \author  jfpatry
  \date    Created:  2000-08-13
  \date    Modified: 2000-08-13
*/
void init_audio()
{
    int hz, channels, buffer;
    Uint16 format;

    check_assertion( !initialized_,
		     "init_audio called twice" );

    sound_contexts_ = create_hash_table();
    music_contexts_ = create_hash_table();
    initialized_ = True;

    /*
     * Init SDL Audio 
     */    
    if ( getparam_no_audio() == False ) {

	if ( SDL_Init( SDL_INIT_AUDIO ) < 0 ) {
	    handle_error( 1, "Couldn't initialize SDL: %s", SDL_GetError() );
	}

	/* Open the audio device */
	switch (getparam_audio_freq_mode()) {
	case 0:
	    hz = 11025;
	    break;
	case 1:
	    hz = 22050;
	    break;
	case 2:
	    hz = 44100;
	    break;
	default:
	    hz = 22050;
	    setparam_audio_freq_mode(1);
	}

	switch ( getparam_audio_format_mode() ) {
	case 0:
	    format = AUDIO_U8;
	    break;
	case 1:
	    format = AUDIO_S16SYS;
	    break;
	default:
	    format = AUDIO_S16SYS;
	    setparam_audio_format_mode( 1 );
	}

	if ( getparam_audio_stereo() ) {
	    channels = 2;
	} else {
	    channels = 1;
	}

	buffer = getparam_audio_buffer_size();


	if ( Mix_OpenAudio(hz, format, channels, buffer) < 0 ) {
	    print_warning( 1,
			   "Warning: Couldn't set %d Hz %d-bit audio\n"
			   "  Reason: %s\n", 
			   hz,  
			   getparam_audio_format_mode() == 0 ? 8 : 16,
			   SDL_GetError());
	} else {
	    print_debug( DEBUG_SOUND,
			 "Opened audio device at %d Hz %d-bit audio",
			 hz, 
			 getparam_audio_format_mode() == 0 ? 8 : 16 );
	}

    }
}
예제 #5
0
void quit_click_cb( button_t *button, void *userdata )
{
    check_assertion( userdata == NULL, "userdata is not null" );

    winsys_exit( 0 );
}
예제 #6
0
/*! 
 Mode initialization function
 \author  jfpatry
 \date    Created:  2000-09-24
 \date    Modified: 2000-09-24
 */
static void race_select_init(void)
{
    listbox_list_elem_to_string_fptr_t conv_func = NULL;
    point2d_t dummy_pos = {0, 0};
    int i;
    
    winsys_set_display_func( main_loop );
    winsys_set_idle_func( main_loop );
    winsys_set_reshape_func( reshape );
    winsys_set_mouse_func( ui_event_mouse_func );
    winsys_set_motion_func( ui_event_motion_func );
    winsys_set_passive_motion_func( ui_event_motion_func );
    
    plyr = get_player_data( local_player() );
    
    /* Setup the race list */
    if ( g_game.practicing ) {
        g_game.current_event = "__Practice_Event__";
        g_game.current_cup = "__Practice_Cup__";
        if(g_game.is_speed_only_mode)
            race_list = get_speed_courses_list();
        else
            race_list = get_score_courses_list();
        conv_func = get_name_from_open_course_data;
        cup_data = NULL;
        last_completed_race = NULL;
        event_data = NULL;
    } else {
        event_data = (event_data_t*) get_list_elem_data( 
                                                        get_event_by_name( g_game.current_event ) );
        check_assertion( event_data != NULL,
                        "Couldn't find current event." );
        cup_data = (cup_data_t*) get_list_elem_data(
                                                    get_event_cup_by_name( event_data, g_game.current_cup ) );
        check_assertion( cup_data != NULL,
                        "Couldn't find current cup." );
        race_list = get_cup_race_list( cup_data );
        conv_func = get_name_from_race_data;
    }
    
    /* Unless we're coming back from a race, initialize the race data to 
     defaults.
     */
    if ( g_game.prev_mode != GAME_OVER ) {
        /* Make sure we don't play previously loaded course */
        cup_complete = False;
        
        /* Initialize the race data */
        cur_elem = get_list_head( race_list );
        
        if ( g_game.practicing ) {
            g_game.race.course = NULL;
            g_game.race.name = NULL;
            g_game.race.description = NULL;
            
            for (i=0; i<DIFFICULTY_NUM_LEVELS; i++) {
                g_game.race.herring_req[i] = 0;
                g_game.race.time_req[i] = 0;
                g_game.race.score_req[i] = 0;
            }
            
            g_game.race.mirrored = False;
            g_game.race.conditions = RACE_CONDITIONS_SUNNY;
            g_game.race.windy = False;
            g_game.race.snowing = False;
        } else {
            /* Not practicing */
            
            race_data_t *data;
            data = (race_data_t*) get_list_elem_data( cur_elem );
            g_game.race = *data;
            
            if ( is_cup_complete( event_data, 
                                 get_event_cup_by_name( 
                                                       event_data, 
                                                       g_game.current_cup ) ) )
            {
                cup_complete = True;
                last_completed_race = get_list_tail( race_list );
            } else {
                cup_complete = False;
                last_completed_race = NULL;
            }
        }
    } else {
        /* Back from a race */
        if ( !g_game.race_aborted ) {
            update_race_results();
        }
        
    }
    
    back_btn = button_create( dummy_pos,
                             150, 40, 
                             "button_label", 
                             Localize("Back","") );
    button_set_hilit_font_binding( back_btn, "button_label_hilit" );
    button_set_visible( back_btn, True );
    button_set_click_event_cb( back_btn, back_click_cb, NULL );
    
    start_btn = button_create( dummy_pos,
                              150, 40,
                              "button_label",
                              Localize("Race!","") );
    button_set_hilit_font_binding( start_btn, "button_label_hilit" );
    button_set_disabled_font_binding( start_btn, "button_label_disabled" );
    button_set_visible( start_btn, True );
    button_set_click_event_cb( start_btn, start_click_cb, NULL );
    
#ifdef __APPLE__
    race_listbox = listbox_create( dummy_pos,
                                  300, 44,
                                  "course_name_label",
                                  race_list,
                                  conv_func );
    
#else
    race_listbox = listbox_create( dummy_pos,
                                  460, 44,
                                  "listbox_item",
                                  race_list,
                                  conv_func );
    
#endif
    
    
    listbox_set_current_item( race_listbox, cur_elem );
    
    listbox_set_item_change_event_cb( race_listbox, 
                                     race_listbox_item_change_cb, 
                                     NULL );
    
    listbox_set_visible( race_listbox, True );
    
    /* 
     * Create text area 
     */
#ifdef __APPLE__
    desc_ta = textarea_create( dummy_pos,
                              170, 147,
                              "race_description",
                              "" );
    
#else
    desc_ta = textarea_create( dummy_pos,
                              312, 107,
                              "race_description",
                              "" );
    
#endif
    
    if ( g_game.practicing ) {
        open_course_data_t *data;
        data = (open_course_data_t*) get_list_elem_data( cur_elem );
        textarea_set_text( desc_ta, data->description );
    } else {
        race_data_t *data;
        data = (race_data_t*) get_list_elem_data( cur_elem );
        textarea_set_text( desc_ta, data->description );
    }
    
    textarea_set_visible( desc_ta, True );
    
    
    /* 
     * Create state buttons - only if practicing or if cup_complete
     */
    
    if ( g_game.practicing || cup_complete ) {
        /* mirror */
        mirror_ssbtn = ssbutton_create( dummy_pos,
                                       32, 32,
                                       2 );
        ssbutton_set_state_image( mirror_ssbtn, 
                                 0, 
                                 "mirror_button",
                                 make_point2d( 0.0/64.0, 32.0/64.0 ),
                                 make_point2d( 32.0/64.0, 64.0/64.0 ),
                                 white );
        
        ssbutton_set_state_image( mirror_ssbtn, 
                                 1, 
                                 "mirror_button",
                                 make_point2d( 32.0/64.0, 32.0/64.0 ),
                                 make_point2d( 64.0/64.0, 64.0/64.0 ),
                                 white );
        
        ssbutton_set_state( mirror_ssbtn, (int)g_game.race.mirrored );
#ifdef __APPLE__
        ssbutton_set_visible( mirror_ssbtn, False );
#else
        ssbutton_set_visible( mirror_ssbtn, True );
#endif
        
        /* conditions */
        conditions_ssbtn = ssbutton_create( dummy_pos,
                                           32, 32,
                                           4 );
        
        float border = 2.0;
        ssbutton_set_state_image( conditions_ssbtn, 
                                 0, 
                                 "conditions_button",
                                 make_point2d( (0.0 + border)/64.0, (32.0 + border)/64.0 ),
                                 make_point2d( (32.0 - border)/64.0, (64.0 - border)/64.0 ),
                                 white );
        
        ssbutton_set_state_image( conditions_ssbtn, 
                                 1, 
                                 "conditions_button",
                                 make_point2d( (32.0 + border)/64.0, (0.0 + border)/64.0 ),
                                 make_point2d( (64.0 - border)/64.0, (32.0 - border)/64.0 ),
                                 white );
        
        ssbutton_set_state_image( conditions_ssbtn, 
                                 2, 
                                 "conditions_button",
                                 make_point2d( (32.0 + border)/64.0, (32.0 + border)/64.0 ),
                                 make_point2d( (64.0 - border)/64.0, (64.0 - border)/64.0 ),
                                 white );
        
        ssbutton_set_state_image( conditions_ssbtn, 
                                 3, 
                                 "conditions_button",
                                 make_point2d( (0.0 + border)/64.0, (0.0 + border)/64.0 ),
                                 make_point2d( (32.0 - border)/64.0, (32.0 - border)/64.0 ),
                                 white );
        
        ssbutton_set_state( conditions_ssbtn, (int)g_game.race.conditions );
        ssbutton_set_visible( conditions_ssbtn, True );
        
#ifdef __APPLE__
        ssbutton_set_visible( conditions_ssbtn, False );
#else
        ssbutton_set_visible( conditions_ssbtn, True );
#endif
        
        /* wind */
        wind_ssbtn = ssbutton_create( dummy_pos,
                                     32, 32,
                                     2 );
        ssbutton_set_state_image( wind_ssbtn, 
                                 0, 
                                 "wind_button",
                                 make_point2d( 0.0/64.0, 32.0/64.0 ),
                                 make_point2d( 32.0/64.0, 64.0/64.0 ),
                                 white );
        
        ssbutton_set_state_image( wind_ssbtn, 
                                 1, 
                                 "wind_button",
                                 make_point2d( 32.0/64.0, 32.0/64.0 ),
                                 make_point2d( 64.0/64.0, 64.0/64.0 ),
                                 white );
        
        ssbutton_set_state( wind_ssbtn, (int)g_game.race.windy );
#ifdef __APPLE__
        ssbutton_set_visible( wind_ssbtn, False );
#else
        ssbutton_set_visible( wind_ssbtn, True );
#endif
        
        /* snow */
        snow_ssbtn = ssbutton_create( dummy_pos,
                                     32, 32,
                                     2 );
        ssbutton_set_state_image( snow_ssbtn, 
                                 0, 
                                 "snow_button",
                                 make_point2d( 0.0/64.0, 32.0/64.0 ),
                                 make_point2d( 32.0/64.0, 64.0/64.0 ),
                                 white );
        
        ssbutton_set_state_image( snow_ssbtn, 
                                 1, 
                                 "snow_button",
                                 make_point2d( 32.0/64.0, 32.0/64.0 ),
                                 make_point2d( 64.0/64.0, 64.0/64.0 ),
                                 white );
        
        ssbutton_set_state( snow_ssbtn, (int)g_game.race.snowing );
#ifdef __APPLE__
        ssbutton_set_visible( snow_ssbtn, False );
#else
        ssbutton_set_visible( snow_ssbtn, True );
#endif
        /* XXX snow button doesn't do anything, so disable for now */
        ssbutton_set_enabled( snow_ssbtn, False );
        
        /* Can't change conditions if in cup mode */
        if ( !g_game.practicing ) {
            ssbutton_set_enabled( conditions_ssbtn, False );
            ssbutton_set_enabled( wind_ssbtn, False );
            ssbutton_set_enabled( snow_ssbtn, False );
            ssbutton_set_enabled( mirror_ssbtn, False );
        }
        
    } else {
        conditions_ssbtn = NULL;
        wind_ssbtn = NULL;
        snow_ssbtn = NULL;
        mirror_ssbtn = NULL;
    }
    
    update_race_data();
    update_button_enabled_states();
    
    play_music( "start_screen" );
}
예제 #7
0
void calc_normals(const char *course)
{
    scalar_t *elevation;
    scalar_t courseWidth, courseLength;
    int nx, ny;
    int x,y;
    point_t p0, p1, p2;
    vector_t n, nml, v1, v2;
    char buff[BUFF_LEN];
	
    sprintf( buff, "%s/courses/%s/normal.data", getparam_data_dir(), course );
	
    get_course_dimensions( &courseWidth, &courseLength );
    get_course_divisions( &nx, &ny );
	
    if(nmls != (void*)-1 && nmls_fd != -1) 
    {
        munmap(nmls, nmls_len);
        close(nmls_fd);
    }
#if 0
    else {
        free(nmls);
    }
#endif
	
    struct stat buf;
    int exists = (stat(buff, &buf) == 0);
	
    if(exists) {
        nmls_fd = open(buff, O_RDONLY);
        if ( nmls_fd == -1) {
            handle_system_error( 1, "can't open file failed" );
        }
		
        TRDebugLog("mapping to memory normal.data\n");
        nmls_len = sizeof(vector_t)*nx*ny;
        nmls = mmap(NULL, nmls_len, PROT_READ, MAP_SHARED,nmls_fd, 0);
        if ( nmls == (void *)-1 ) {
            handle_system_error( 1, "read mmap failed" );
        }
    }
    else {
        nmls_len = sizeof(vector_t)*nx*ny;
		
#if TARGET_IPHONE_SIMULATOR
        nmls_fd = open(buff, O_RDWR | O_CREAT | O_TRUNC, 0644);
        if ( nmls_fd == -1) {
            handle_system_error( 1, "can't open file failed" );
        }
		
		
        int result = lseek(nmls_fd, nmls_len-1, SEEK_SET);
        if (result == -1) {
            handle_system_error( 1, "can't write file failed" );
        }
        
        result = write(nmls_fd, "", 1);
        if (result != 1) {
            handle_system_error( 1, "can't write file failed" );
        }
		
        nmls = mmap(NULL, nmls_len, PROT_READ | PROT_WRITE, MAP_SHARED, nmls_fd, 0);
        if ( nmls == (void *)-1 ) {
            handle_system_error( 1, "write mmap failed" );
        }
		
        TRDebugLog("Writing to normal.data\n");
#else
# ifdef TR_DEBUG_MODE
        abort(); // This shouldn't be reached on simulator. Crash to indicate.
# endif
        nmls = malloc(nmls_len);
#endif
        
        elevation = get_course_elev_data();
		
        for ( y=0; y<ny; y++) {
            for ( x=0; x<nx; x++) {
                nml = make_vector( 0., 0., 0. );
                
                p0 = make_point( XCD(x), ELEV(x,y), ZCD(y) );
                
                /* The terrain is meshed as follows:
                 ...
                 +-+-+-+-+            x<---+
                 |\|/|\|/|                 |
                 ...+-+-+-+-+...              V
                 |/|\|/|\|                 y
                 +-+-+-+-+
                 ...
                 
                 So there are two types of vertices: those surrounded by
                 four triangles (x+y is odd), and those surrounded by
                 eight (x+y is even).
                 */
                
#define POINT(x,y) make_point( XCD(x), ELEV(x,y), ZCD(y) )
                
                if ( (x + y) % 2 == 0 ) {
                    if ( x > 0 && y > 0 ) {
                        p1 = POINT(x,  y-1);
                        p2 = POINT(x-1,y-1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v2, v1 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                        
                        p1 = POINT(x-1,y-1);
                        p2 = POINT(x-1,y  );
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v2, v1 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                    } 
                    if ( x > 0 && y < ny-1 ) {
                        p1 = POINT(x-1,y  );
                        p2 = POINT(x-1,y+1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v2, v1 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                        
                        p1 = POINT(x-1,y+1);
                        p2 = POINT(x  ,y+1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v2, v1 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                    } 
                    if ( x < nx-1 && y > 0 ) {
                        p1 = POINT(x+1,y  );
                        p2 = POINT(x+1,y-1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v2, v1 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                        
                        p1 = POINT(x+1,y-1);
                        p2 = POINT(x  ,y-1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v2, v1 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                    } 
                    if ( x < nx-1 && y < ny-1 ) {
                        p1 = POINT(x+1,y  );
                        p2 = POINT(x+1,y+1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v1, v2 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                        
                        p1 = POINT(x+1,y+1);
                        p2 = POINT(x  ,y+1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v1, v2 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                        
                    } 
                } else {
                    /* x + y is odd */
                    if ( x > 0 && y > 0 ) {
                        p1 = POINT(x,  y-1);
                        p2 = POINT(x-1,y  );
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v2, v1 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                    } 
                    if ( x > 0 && y < ny-1 ) {
                        p1 = POINT(x-1,y  );
                        p2 = POINT(x  ,y+1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v2, v1 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                    } 
                    if ( x < nx-1 && y > 0 ) {
                        p1 = POINT(x+1,y  );
                        p2 = POINT(x  ,y-1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v2, v1 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                    } 
                    if ( x < nx-1 && y < ny-1 ) {
                        p1 = POINT(x+1,y  );
                        p2 = POINT(x  ,y+1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v1, v2 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                    } 
                }
                
                normalize_vector( &nml );
                NORMAL(x,y) = nml;
                continue;
            } 
#undef POINT
        }
#if TARGET_IPHONE_SIMULATOR
        munmap(nmls, nmls_len);
        close(nmls_fd);
		
        nmls_fd = open(buff, O_RDONLY);
        if (nmls_fd == -1) {
            handle_system_error( 1, "can't remount normal.data" );
        }
		
        TRDebugLog("remounting to memory normal.data\n");
        nmls_len = sizeof(vector_t)*nx*ny;
        nmls = mmap(NULL, nmls_len, PROT_READ, MAP_SHARED, nmls_fd, 0);
        if ( nmls == (void *)-1 ) {
            handle_system_error( 1, "remount mmap failed" );
        }
#endif
    }
} 
예제 #8
0
/*! 
  Returns the visibility status of the specified listbox
  \return  True iff listbox is visible
  \author  jfpatry
  \date    Created:  2000-09-17
  \date    Modified: 2000-09-17
*/
bool_t listbox_is_visible( listbox_t *listbox )
{
    check_assertion( listbox != NULL, "listbox is NULL" );

    return listbox->visible;
}
예제 #9
0
/*! 
  Returns the active state of the listbox
  \return  Active state of listbox
  \author  jfpatry
  \date    Created:  2000-09-18
  \date    Modified: 2000-09-18
*/
bool_t listbox_is_active( listbox_t *listbox )
{
    check_assertion( listbox != NULL, "listbox is NULL" );

    return listbox->active;
}
예제 #10
0
/*! 
  Returns the width of the listbox
  \return  The width of the listbox
  \author  jfpatry
  \date    Created:  2000-09-17
  \date    Modified: 2000-09-17
*/
scalar_t listbox_get_width( listbox_t *listbox )
{
    check_assertion( listbox != NULL, "listbox is NULL" );

    return listbox->w;
}
예제 #11
0
/*! 
  Returns the height of the listbox
  \return  The height of the listbox
  \author  jfpatry
  \date    Created:  2000-09-17
  \date    Modified: 2000-09-17
*/
scalar_t listbox_get_height( listbox_t *listbox )
{
    check_assertion( listbox != NULL, "listbox is NULL" );

    return listbox->h;
}
예제 #12
0
/*! 
  Returns the listbox's current item
  \return  The currently selected listbox item
  \author  jfpatry
  \date    Created:  2000-09-17
  \date    Modified: 2000-09-17
*/
list_elem_t listbox_get_current_item( listbox_t *listbox )
{
    check_assertion( listbox != NULL, "listbox is NULL" );

    return listbox->cur_item;
}
예제 #13
0
/*! 
  Creates a new listbox
  \return  The new listbox object
  \author  jfpatry
  \date    Created:  2000-09-17
  \date    Modified: 2000-09-17
*/
listbox_t* listbox_create( point2d_t pos, scalar_t w, scalar_t h, 
			   char *font_binding, list_t item_list,
			   listbox_list_elem_to_string_fptr_t func )
{
    listbox_t *listbox;
    char *binding;
    point2d_t ll;
    point2d_t ur;

    listbox = (listbox_t*)malloc( sizeof(listbox_t) );

    check_assertion( listbox != NULL, "out of memory" );

    listbox->pos = pos;
    listbox->w = w;
    listbox->h = h;
    listbox->arrow_width = DEFAULT_ARROW_REGION_WIDTH;
    listbox->border_width = DEFAULT_BORDER_WIDTH;
    listbox->text_pad = DEFAULT_TEXT_PAD;
    listbox->arrow_vert_separation = DEFAULT_ARROW_VERT_SEPARATION;
    listbox->font_binding = font_binding;
    listbox->border_colour = ui_foreground_colour;
    listbox->background_colour = ui_background_colour; 

    /* Create up arrow button */
    listbox->up_button = button_create( 
	make_point2d( 0, 0 ), /* position will be set later */
	DEFAULT_ARROW_BUTTON_WIDTH,
	(mWidth>320)?DEFAULT_ARROW_BUTTON_HEIGHT:DEFAULT_ARROW_BUTTON_HEIGHT/2,
	NULL,
	NULL );

    binding = "listbox_arrows";

    ll = make_point2d( 0.0/64.0, 16.0/64.0 );
    ur = make_point2d( 32.0/64.0, 32.0/64.0 );
    button_set_image( listbox->up_button, binding, ll, ur, white );

    ll = make_point2d( 32.0/64.0, 16.0/64.0 );
    ur = make_point2d( 64.0/64.0, 32.0/64.0 );
    button_set_disabled_image( listbox->up_button, binding, ll, ur, 
			       white );

    ll = make_point2d( 32.0/64.0, 48.0/64.0 );
    ur = make_point2d( 64.0/64.0, 64.0/64.0 );
    button_set_hilit_image( listbox->up_button, binding, ll, ur, 
			    white );

    ll = make_point2d( 0.0/64.0, 48.0/64.0 );
    ur = make_point2d( 32.0/64.0, 64.0/64.0 );
    button_set_clicked_image( listbox->up_button, binding, ll, ur, 
			      white );


    button_set_click_event_cb( listbox->up_button, 
			       listbox_arrow_click_cb,
			       listbox );

    /* Create down arrow button */
    listbox->down_button = button_create( 
	make_point2d( 0, 0 ), /* position will be set later */
	DEFAULT_ARROW_BUTTON_WIDTH,
	(mWidth>320)?DEFAULT_ARROW_BUTTON_HEIGHT:DEFAULT_ARROW_BUTTON_HEIGHT/2,
	NULL,
	NULL );

    binding = "listbox_arrows";

    ll = make_point2d( 0.0/64.0, 0.0/64.0 );
    ur = make_point2d( 32.0/64.0, 16.0/64.0 );
    button_set_image( listbox->down_button, binding, ll, ur, white );

    ll = make_point2d( 32.0/64.0, 0.0/64.0 );
    ur = make_point2d( 64.0/64.0, 16.0/64.0 );
    button_set_disabled_image( listbox->down_button, binding, ll, ur, 
			       white );

    ll = make_point2d( 32.0/64.0, 32.0/64.0 );
    ur = make_point2d( 64.0/64.0, 48.0/64.0 );
    button_set_hilit_image( listbox->down_button, binding, ll, ur, 
			    white );

    ll = make_point2d( 0.0/64.0, 32.0/64.0 );
    ur = make_point2d( 32.0/64.0, 48.0/64.0 );
    button_set_clicked_image( listbox->down_button, binding, ll, ur, 
			      white );

    button_set_click_event_cb( listbox->down_button, 
			       listbox_arrow_click_cb,
			       listbox );

    button_set_click_event_cb( listbox->down_button, 
			       listbox_arrow_click_cb,
			       listbox );

    listbox->item_change_cb = NULL;
    listbox->item_change_cb_userdata = NULL;

    listbox->item_list = item_list;
    listbox->cur_item = get_list_head( listbox->item_list );

    listbox->label_gen_func = func;

    listbox->visible = False;
    listbox->active = False;

    update_button_enabled_states( listbox );

    update_button_positions( listbox );

    return listbox;
}
예제 #14
0
/*! 
  Callback to draws the listbox
  \return  None
  \author  jfpatry
  \date    Created:  2000-09-17
  \date    Modified: 2000-09-17
*/
static void listbox_draw_cb( void *widget )
{
    check_assertion( widget != NULL, "widget is NULL" );

    listbox_draw( (listbox_t*) widget );
}
예제 #15
0
/*!
 Creates a race_data_t object from a Tcl string.
 \return  New race_data_t object if successful, or NULL if error
 \author  jfpatry
 \date    Created:  2000-09-19
 \date    Modified: 2000-09-19
 */
static
race_data_t* create_race_data ( Tcl_Interp *ip, const char *string, char **err_msg )
{
    const char **argv = NULL;
    const char **orig_argv = NULL;
    int argc = 0;

    char *course = NULL;
    char *name = NULL;
    char *description = NULL;

    int      herring_req[DIFFICULTY_NUM_LEVELS];
    bool_t   herring_req_init = False;
    scalar_t time_req[DIFFICULTY_NUM_LEVELS];
    bool_t   time_req_init = False;
    int score_req[DIFFICULTY_NUM_LEVELS];
    bool_t   score_req_init = False;

    bool_t   mirrored = False;
    race_conditions_t conditions = RACE_CONDITIONS_SUNNY;
    bool_t   windy = False;
    bool_t   snowing = False;

    race_data_t *race_data = NULL;

    if ( Tcl_SplitList( ip, string, &argc, &argv ) == TCL_ERROR ) {
        *err_msg = "race data is not a list";
        goto bail_race_data;
    }

    orig_argv = argv;

    while ( *argv != NULL ) {
        if ( strcmp( *argv, "-course" ) == 0 ) {
            NEXT_ARG;

            if ( *argv == NULL ) {
                *err_msg = "No data supplied for -course in race data";
                goto bail_race_data;
            }

            course = string_copy( *argv );
        } else if ( strcmp( *argv, "-name" ) == 0 ) {
            NEXT_ARG;

            if ( *argv == NULL ) {
                *err_msg = "No data supplied for -name in race data";
                goto bail_race_data;
            }

            name = string_copy( *argv );
        } else if ( strcmp( *argv, "-description" ) == 0 ) {
            NEXT_ARG;

            if ( *argv == NULL ) {
                *err_msg = "No data supplied for -description in race data";
                goto bail_race_data;
            }

            description = string_copy( *argv );
        } else if ( strcmp( *argv, "-herring" ) == 0 ) {
            NEXT_ARG;

            if ( *argv == NULL ) {
                *err_msg = "No data supplied for -herring in race data";
                goto bail_race_data;
            }

            if ( get_tcl_int_tuple(
                        ip, *argv, herring_req,
                        sizeof(herring_req)/sizeof(herring_req[0]) ) == TCL_ERROR )
            {
                *err_msg = "Value for -herring is not a list or has "
                           "the wrong number of elements";
                goto bail_race_data;
            }

            herring_req_init = True;
        } else if ( strcmp( *argv, "-time" ) == 0 ) {
            NEXT_ARG;

            if ( *argv == NULL ) {
                *err_msg = "No data supplied for -time in race data" ;
                goto bail_race_data;
            }

            if ( get_tcl_tuple( ip, *argv, time_req,
                                sizeof(time_req)/sizeof(time_req[0]) )
                    == TCL_ERROR )
            {
                *err_msg = "Value for -time is not a list or hsa the "
                           "wrong number of elements";
                goto bail_race_data;
            }

            time_req_init = True;
        } else if ( strcmp( *argv, "-score" ) == 0 ) {
            NEXT_ARG;

            if ( *argv == NULL ) {
                *err_msg = "No data supplied for -score in race data";
                goto bail_race_data;
            }

            if ( get_tcl_int_tuple( ip, *argv, score_req,
                                    sizeof(score_req)/sizeof(score_req[0]) )
                    == TCL_ERROR )
            {
                *err_msg = "Value for -score is not a list or has the "
                           "wrong number of elements";
                goto bail_race_data;
            }

            score_req_init = True;
        } else if ( strcmp( *argv, "-mirrored" ) == 0 ) {
            NEXT_ARG;

            if ( *argv == NULL ) {
                *err_msg = "No data supplied for -mirrored in race data";
                goto bail_race_data;
            }

            if ( string_cmp_no_case( *argv, "yes" ) == 0 ) {
                mirrored = True;
            } else {
                mirrored = False;
            }
        } else if ( strcmp( *argv, "-conditions" ) == 0 ) {
            int i;
            NEXT_ARG;

            if ( *argv == NULL ) {
                *err_msg = "No data supplied for -conditions in race data";
                goto bail_race_data;
            }

            for ( i=0; i<RACE_CONDITIONS_NUM_CONDITIONS; i++ ) {
                if ( string_cmp_no_case( race_condition_names[i],
                                         *argv ) == 0 )
                {
                    break;
                }
            }

            if ( i == RACE_CONDITIONS_NUM_CONDITIONS ) {
                *err_msg = "Invalid value for -conditions in race data";
                goto bail_race_data;
            }

            conditions = (race_conditions_t)i;
        } else if ( strcmp( *argv, "-windy" ) == 0 ) {
            NEXT_ARG;

            if ( *argv == NULL ) {
                *err_msg = "No data supplied for -windy in race data";
                goto bail_race_data;
            }

            if ( string_cmp_no_case( *argv, "yes" ) == 0 ) {
                windy = True;
            } else {
                windy = False;
            }
        } else if ( strcmp( *argv, "-snowing" ) == 0 ) {
            NEXT_ARG;

            if ( *argv == NULL ) {
                *err_msg = "No data supplied for -snowing in race data";
                goto bail_race_data;
            }

            if ( string_cmp_no_case( *argv, "yes" ) == 0 ) {
                snowing = True;
            } else {
                snowing = False;
            }
        } else {
            sprintf( err_buff, "unrecognized option `%s' in race data",
                     *argv );
            *err_msg = err_buff;
            goto bail_race_data;
        }

        NEXT_ARG;
    }

    /* Check mandatory arguments */
    if ( course == NULL ) {
        *err_msg = "No course specified in race data";
        goto bail_race_data;
    }

    if ( !herring_req_init ||
            !time_req_init ||
            !score_req_init )
    {
        *err_msg = "Must specify requirement for herring, time, and score.";
        goto bail_race_data;
    }

    /* Create new race_data_t object */

    race_data = (race_data_t*) malloc( sizeof(race_data_t) );
    check_assertion( race_data != NULL, "out of memory" );

    race_data->course = course;
    race_data->name = name;
    race_data->description = description;

    memcpy( race_data->herring_req, herring_req, sizeof(herring_req) );
    memcpy( race_data->time_req, time_req, sizeof(time_req) );
    memcpy( race_data->score_req, score_req, sizeof(score_req) );

    race_data->mirrored = mirrored;
    race_data->conditions = conditions;
    race_data->windy = windy;
    race_data->snowing = snowing;

    Tcl_Free( (char*) orig_argv );

    return race_data;

bail_race_data:

    if ( orig_argv ) {
        Tcl_Free( (char*) orig_argv );
    }

    if ( course ) {
        free( course );
    }

    if ( name ) {
        free( name );
    }

    if ( description ) {
        free( description );
    }

    if ( race_data ) {
        free( race_data );
    }

    return NULL;
}
예제 #16
0
path_searcht::resultt path_searcht::operator()(
  const goto_functionst &goto_functions)
{
  locst locs(ns);
  var_mapt var_map(ns);
  
  locs.build(goto_functions);

  // this is the container for the history-forest  
  path_symex_historyt history;
  
  queue.push_back(initial_state(var_map, locs, history));
  
  // set up the statistics
  number_of_dropped_states=0;
  number_of_paths=0;
  number_of_VCCs=0;
  number_of_steps=0;
  number_of_feasible_paths=0;
  number_of_infeasible_paths=0;
  number_of_VCCs_after_simplification=0;
  number_of_failed_properties=0;
  number_of_locs=locs.size();

  // stop the time
  start_time=current_time();
  
  initialize_property_map(goto_functions);
  
  while(!queue.empty())
  {
    number_of_steps++;
  
    // Pick a state from the queue,
    // according to some heuristic.
    // The state moves to the head of the queue.
    pick_state();
    
    // move into temporary queue
    queuet tmp_queue;
    tmp_queue.splice(
      tmp_queue.begin(), queue, queue.begin(), ++queue.begin());
    
    try
    {
      statet &state=tmp_queue.front();
      
      // record we have seen it
      loc_data[state.get_pc().loc_number].visited=true;

      debug() << "Loc: #" << state.get_pc().loc_number
              << ", queue: " << queue.size()
              << ", depth: " << state.get_depth();
      for(const auto & s : queue)
        debug() << ' ' << s.get_depth();
        
      debug() << eom;
    
      if(drop_state(state))
      {
        number_of_dropped_states++;
        number_of_paths++;
        continue;
      }
      
      if(!state.is_executable())
      {
        number_of_paths++;
        continue;
      }

      if(eager_infeasibility &&
         state.last_was_branch() &&
         !is_feasible(state))
      {
        number_of_infeasible_paths++;
        number_of_paths++;
        continue;
      }
      
      if(number_of_steps%1000==0)
      {
        status() << "Queue " << queue.size()
                 << " thread " << state.get_current_thread()
                 << '/' << state.threads.size()
                 << " PC " << state.pc() << messaget::eom;
      }

      // an error, possibly?
      if(state.get_instruction()->is_assert())
      {
        if(show_vcc)
          do_show_vcc(state);
        else
        {
          check_assertion(state);
          
          // all assertions failed?
          if(number_of_failed_properties==property_map.size())
            break;
        }
      }

      // execute
      path_symex(state, tmp_queue);
      
      // put at head of main queue
      queue.splice(queue.begin(), tmp_queue);
    }
    catch(const std::string &e)
    {
      error() << e << eom;
      number_of_dropped_states++;
    }
    catch(const char *e)
    {
      error() << e << eom;
      number_of_dropped_states++;
    }
    catch(int)
    {
      number_of_dropped_states++;
    }
  }
  
  report_statistics();
  
  return number_of_failed_properties==0?SAFE:UNSAFE;
}
예제 #17
0
/*!
 Creates a cup_data_t object from a Tcl string.
 \return  New cup_data_t object if successful, or NULL if error
 \author  jfpatry
 \date    Created:  2000-09-19
 \date    Modified: 2000-09-19
 */
static
cup_data_t* create_cup_data( Tcl_Interp *ip, const char *string, char **err_msg )
{
    const char **argv = NULL;
    const char **orig_argv = NULL;
    int argc = 0;

    char *name = NULL;
    char *icon = NULL;
    list_t race_list = NULL;
    list_elem_t last_race = NULL;
    const char **races = NULL;
    int num_races = 0;
    int i;

    cup_data_t *cup_data = NULL;

    if ( Tcl_SplitList( ip, string, &argc, &argv ) == TCL_ERROR ) {
        *err_msg = "cup data is not a list";
        goto bail_cup_data;
    }

    orig_argv = argv;

    while ( *argv != NULL ) {
        if ( strcmp( *argv, "-name" ) == 0 ) {
            NEXT_ARG;

            if ( *argv == NULL ) {
                *err_msg = "No data supplied for -name in cup data";
                goto bail_cup_data;
            }

            name = string_copy( *argv );
        } else if ( strcmp( *argv, "-icon" ) == 0 ) {
            NEXT_ARG;

            if ( *argv == NULL ) {
                *err_msg = "No data supplied for -icon in cup data";
                goto bail_cup_data;
            }

            icon = string_copy( *argv );
        } else if ( strcmp( *argv, "-races" ) == 0 ) {
            NEXT_ARG;

            if ( *argv == NULL ) {
                *err_msg= "No data supplied for -races in cup data";
                goto bail_cup_data;
            }

            race_list = create_list();
            last_race = NULL;

            if ( Tcl_SplitList( ip, *argv, &num_races, &races ) == TCL_ERROR ) {
                *err_msg = "Race data is not a list in event data";
                goto bail_cup_data;
            }

            for ( i=0; i<num_races; i++) {
                race_data_t *race_data;
                race_data = create_race_data( ip, races[i], err_msg );
                if ( race_data == NULL ) {
                    goto bail_cup_data;
                }

                last_race = insert_list_elem( race_list, last_race,
                                              (list_elem_data_t) race_data );
            }

            Tcl_Free( (char*) races );
            races = NULL;
        } else {
            sprintf( err_buff, "Unrecognized argument `%s'", *argv );
            *err_msg = err_buff;
            goto bail_cup_data;
        }

        NEXT_ARG;
    }

    /* Make sure mandatory fields have been specified */
    if ( name == NULL ) {
        *err_msg = "Must specify a name in cup data";
        goto bail_cup_data;
    }

    if ( icon == NULL ) {
        *err_msg = "Must specify an icon texture in cup data";
        goto bail_cup_data;
    }

    if ( race_list == NULL ) {
        *err_msg = "Must specify a race list in cup data";
        goto bail_cup_data;
    }

    /* Create a new cup data object */
    cup_data = (cup_data_t*) malloc( sizeof( cup_data_t ) );
    check_assertion( cup_data != NULL, "out of memory" );

    cup_data->name = name;
    cup_data->race_list = race_list;

    bind_texture( name, icon );

    Tcl_Free( (char*) orig_argv );
    argv = NULL;

    free( icon );

    return cup_data;

bail_cup_data:

    if ( orig_argv ) {
        Tcl_Free( (char*) orig_argv );
    }

    if ( name ) {
        free( name );
    }

    if ( icon ) {
        free( icon );
    }

    if ( races ) {
        Tcl_Free( (char*) races );
    }

    /* Clean out race list */
    if ( race_list ) {
        last_race = get_list_tail( race_list );
        while ( last_race != NULL ) {
            race_data_t *data;
            data = (race_data_t*) delete_list_elem( race_list, last_race );
            free( data );
            last_race = get_list_tail( race_list );
        }

        del_list( race_list );
    }

    if ( cup_data ) {
        free( cup_data );
    }

    return NULL;
}
예제 #18
0
float	quadsquare::RecomputeError(const quadcornerdata& cd)
// Recomputes the error values for this tree.  Returns the
// max error.
// Also updates MinY & MaxY.
{
    int	i;
    int j;
    int t;
    int	half = 1 << cd.Level;
    int	whole = half << 1;
    float terrain_error;
	
    // Measure error of center and edge vertices.
    float	maxerror = 0;

    // Compute error of center vert.
    float	e;
    if (cd.ChildIndex & 1) {
	e = fabs(Vertex[0].Y - (cd.Verts[1].Y + cd.Verts[3].Y) * 0.5);
    } else {
	e = fabs(Vertex[0].Y - (cd.Verts[0].Y + cd.Verts[2].Y) * 0.5);
    }
    if (e > maxerror) maxerror = e;

    // Initial min/max.
    MaxY = Vertex[0].Y;
    MinY = Vertex[0].Y;

    // Check min/max of corners.
    for (i = 0; i < 4; i++) {
	float	y = cd.Verts[i].Y;
	if (y < MinY) MinY = y;
	if (y > MaxY) MaxY = y;
    }
	
    // Edge verts.
    e = fabs(Vertex[1].Y - (cd.Verts[0].Y + cd.Verts[3].Y) * 0.5);
    if (e > maxerror) maxerror = e;
    Error[0] = e;
	
    e = fabs(Vertex[4].Y - (cd.Verts[2].Y + cd.Verts[3].Y) * 0.5);
    if (e > maxerror) maxerror = e;
    Error[1] = e;

    // Terrain edge checks
    if ( cd.Level == 0 && cd.xorg <= RowSize-1 && cd.zorg <= NumRows-1 ) {

	// Check South vertex
	int x = cd.xorg + half;
	int z = cd.zorg + whole;
	int idx = x  + z * RowSize;
	bool different_terrains = false;

	terrain_error = 0.f;

	check_assertion( x >= 0, "x coordinate is negative" );
	check_assertion( z >= 0, "z coordinate is negative" );

        if ( x < RowSize && z < NumRows ) {

	    if ( x < RowSize - 1 ) {
		if ( Terrain[idx] != Terrain[idx+1] ) {
		    different_terrains = true;
		}
	    }
	    if ( z >= 1 ) {
		idx -= RowSize;
		if ( Terrain[idx] != Terrain[idx+1] ) {
		    different_terrains = true;
		}
	    }

	    if ( different_terrains ) {
		ForceSouthVert = true;
		terrain_error = TERRAIN_ERROR_SCALE * whole * whole;
	    } else {
		ForceSouthVert = false;
	    }

	    if ( terrain_error > Error[0] ) {
		Error[0] = terrain_error;
	    }
	    if ( Error[0] > maxerror ) {
		maxerror = Error[0];
	    }
	}

	// Check East vertex
	x = cd.xorg + whole;
	z = cd.zorg + half;
	idx = x  + z * RowSize;
	terrain_error = 0;
	different_terrains = false;

        if ( x < RowSize && z < NumRows ) {

	    if ( z >= 1 ) {
		if ( Terrain[idx] != Terrain[idx-RowSize] ) {
		    different_terrains = true;
		}
	    }
	    if ( z >= 1 && x < RowSize - 1 ) {
		idx += 1;
		if ( Terrain[idx] != Terrain[idx-RowSize] ) {
		    different_terrains = true;
		}
	    }

	    if ( different_terrains ) {
		ForceEastVert = true;
		terrain_error = TERRAIN_ERROR_SCALE * whole * whole;
	    } else {
		ForceEastVert = false;
	    }

	    if ( terrain_error > Error[1] ) {
		Error[1] = terrain_error;
	    }
	    if ( Error[1] > maxerror ) {
		maxerror = Error[1];
	    }
        }
    }

    // Min/max of edge verts.
    for (i = 0; i < 4; i++) {
	float	y = Vertex[1 + i].Y;
	if (y < MinY) MinY = y;
	if (y > MaxY) MaxY = y;
    }
	
    // Check child squares.
    for (i = 0; i < 4; i++) {
	quadcornerdata	q;
	if (Child[i]) {
	    SetupCornerData(&q, cd, i);
	    Error[i+2] = Child[i]->RecomputeError(q);

	    if (Child[i]->MinY < MinY) MinY = Child[i]->MinY;
	    if (Child[i]->MaxY > MaxY) MaxY = Child[i]->MaxY;
	} else {
	    // Compute difference between bilinear average at child center, and diagonal edge approximation.
	    Error[i+2] = fabs((Vertex[0].Y + cd.Verts[i].Y) - (Vertex[i+1].Y + Vertex[((i+1)&3) + 1].Y)) * 0.25;
	}
	if (Error[i+2] > maxerror) maxerror = Error[i+2];
    }

    //
    // Compute terrain_error
    //
    int terrain;

    int *terrain_count = new int[(int)NumTerrains];

    for (t=0; t<NumTerrains; t++) {
	terrain_count[t] = 0;
    }

    for (i=cd.xorg; i<=cd.xorg+whole; i++) {
	for (j=cd.zorg; j<=cd.zorg+whole; j++) {

	    if ( i < 0 || i >= RowSize ||
		 j < 0 || j >= NumRows ) 
	    {
		continue;
	    }

	    terrain = (int) Terrain[ i + RowSize*j ];
	    check_assertion( terrain >= 0 && 
			     terrain < NumTerrains,
			     "Invalid terrain type" );
	    terrain_count[ terrain ] += 1;
	}
    }

    int max_count = 0;
    int max_type = 0;
    int total = 0;
    for (t=0; t<NumTerrains; t++) {
	if ( terrain_count[t] > max_count ) {
	    max_count = terrain_count[t];
	    max_type = t;
	}
	total += terrain_count[t];
    }

    delete [] terrain_count;

    /* Calculate a terrain error that varies between 0 and 1 */
    if ( total > 0 ) {
	terrain_error = (1.0 - max_count / total);  
	if ( NumTerrains > 1 ) {
	    terrain_error *= NumTerrains / ( NumTerrains - 1.0 );
	}
    } else {
	terrain_error = 0;
    }

    /* and scale it by the square area */
    terrain_error *= whole * whole;

    /* and finally scale it so that it's comparable to height error */
    terrain_error *= TERRAIN_ERROR_SCALE;

    if ( terrain_error > maxerror ) {
	maxerror = terrain_error;
    }

    if ( terrain_error > Error[0] ) {
	Error[0] = terrain_error;
    }
    if ( terrain_error > Error[1] ) {
	Error[1] = terrain_error;
    }


    // The error  and MinY/MaxY values for this node and descendants are correct now.
    Dirty = false;
	
    return maxerror;
}
예제 #19
0
/*! 
 Sets the widget positions and draws other on-screen goo 
 \author  jfpatry
 \date    Created:  2000-09-24
 \date    Modified: 2000-09-24
 */
static void set_widget_positions_and_draw_decorations()
{
    int w = getparam_x_resolution();
    int h = getparam_y_resolution();
    int box_width, box_height, box_max_y;
    int x_org, y_org;
    char *string;
    font_t *font;
    char *current_course;
    int text_width, asc, desc;
    GLuint texobj;
    
    /* set the dimensions of the box in which all widgets should fit */
#ifdef __APPLE__
    box_width = w;
    box_height = 200 * mHeight / 320;
    box_max_y = h - 128 * mHeight / 320;
    x_org = 10 * mHeight / 320;
    y_org = box_height/2 * mHeight / 320;
    
    if ( y_org + box_height > box_max_y ) {
        y_org = box_max_y - box_height + 50 * mHeight / 320;
    }
    
    button_set_position( 
                        back_btn,
                        make_point2d( 0,
                                     0 ) );
    
    button_set_position(
                        start_btn,
                        make_point2d( box_width - button_get_width( start_btn ),
                                     0 ) );
    
    listbox_set_position(
                         race_listbox,
                         make_point2d( 160 * mHeight / 320,
                                       box_height/2.0+40 * mHeight / 320 ) );
#ifdef __APPLE__    
    textarea_set_position( 
                          desc_ta,
                          make_point2d( 1000,
                                        1000 ) );
#else
    textarea_set_position( 
                          desc_ta,
                          make_point2d( x_org,
                                       y_org + 66 * mHeight / 320 ) );
#endif
    
    if ( g_game.practicing || 
        ( cup_complete &&
         conditions_ssbtn &&
         wind_ssbtn &&
         snow_ssbtn &&
         mirror_ssbtn ) ) 
    {
        ssbutton_set_position(
                              conditions_ssbtn,
                              make_point2d( x_org + box_width - 4*36 + 4,
                                           y_org + 151 ) );
        
        ssbutton_set_position(
                              wind_ssbtn,
                              make_point2d( x_org + box_width - 3*36 + 4 ,
                                           y_org + 151 ) );
        
        ssbutton_set_position(
                              snow_ssbtn,
                              make_point2d( x_org + box_width - 2*36 + 4,
                                           y_org + 151 ) );
        
        ssbutton_set_position(
                              mirror_ssbtn,
                              make_point2d( x_org + box_width - 1*36 + 4,
                                           y_org + 151 ) );
        
#else
        box_width = 460;
        box_height = 310;
        box_max_y = h - 128;
        x_org = w/2 - box_width/2;
        y_org = h/2 - box_height/2;
        
        if ( y_org + box_height > box_max_y ) {
            y_org = box_max_y - box_height;
        }
        
        button_set_position( 
                            back_btn,
                            make_point2d( x_org + 131 - button_get_width( back_btn )/2.0,
                                         42 ) );
        
        button_set_position(
                            start_btn,
                            make_point2d( x_org + 343 - button_get_width( start_btn )/2.0,
                                         42 ) );
        
        listbox_set_position(
                             race_listbox,
                             make_point2d( x_org,
                                          y_org + 221 ) );
        
        textarea_set_position( 
                              desc_ta,
                              make_point2d( x_org,
                                           y_org + 66 ) );
        
        if ( g_game.practicing || 
            ( cup_complete &&
             conditions_ssbtn &&
             wind_ssbtn &&
             snow_ssbtn &&
             mirror_ssbtn ) ) 
        {
            ssbutton_set_position(
                                  conditions_ssbtn,
                                  make_point2d( x_org + box_width - 4*36 + 4,
                                               y_org + 181 ) );
            
            ssbutton_set_position(
                                  wind_ssbtn,
                                  make_point2d( x_org + box_width - 3*36 + 4 ,
                                               y_org + 181 ) );
            
            ssbutton_set_position(
                                  snow_ssbtn,
                                  make_point2d( x_org + box_width - 2*36 + 4,
                                               y_org + 181 ) );
            
            ssbutton_set_position(
                                  mirror_ssbtn,
                                  make_point2d( x_org + box_width - 1*36 + 4,
                                               y_org + 181 ) );
#endif
        } else {
            /* Draw tux life icons */
            GLuint texobj;
            int i;
            
            glPushMatrix();
            {
#ifdef __APPLE__
                glTranslatef( 10 * mHeight / 320,
                             60 * mHeight / 320,
                             0 );
#else
                glTranslatef( x_org + box_width - 4*36 + 4,
                             y_org + 181,
                             0 );
#endif
                
                
                check_assertion( INIT_NUM_LIVES == 4, 
                                "Assumption about number of lives invalid -- "
                                "need to recode this part" );
                
                if ( !get_texture_binding( "tux_life", &texobj ) ) {
                    texobj = 0;
                }
                
                glBindTexture( GL_TEXTURE_2D, texobj );
                
                for ( i=0; i<4; i++ ) {
                    point2d_t ll, ur;
                    if ( plyr->lives > i ) {
                        ll = make_point2d( 0, 0.5 );
                        ur = make_point2d( 1, 1 );
                    } else {
                        ll = make_point2d( 0, 0 );
                        ur = make_point2d( 1, 0.5 );
                    }
                    
                    glBegin( GL_QUADS );
                    {
                        glTexCoord2f( ll.x, ll.y );
                        glVertex2f( 0, 0 );
                        
                        glTexCoord2f( ur.x, ll.y );
                        glVertex2f( 32 * mHeight / 320, 0 );
                        
                        glTexCoord2f( ur.x, ur.y );
                        glVertex2f( 32 * mHeight / 320, 32 * mHeight / 320 );
                        
                        glTexCoord2f( ll.x, ur.y );
                        glVertex2f( 0, 32 * mHeight / 320 );
                    }
                    glEnd();
                    glTranslatef( 36 * mHeight / 320, 0, 0 );
                }
            }
            glPopMatrix();
        }

#ifndef __APPLE__ // We don't care about that stuff

        /* Draw other stuff */
        if ( !get_font_binding( "menu_label", &font ) ) {
            print_warning( IMPORTANT_WARNING,
                          "Couldn't get font for binding menu_label" );
        } else {
            bind_font_texture( font );
            string = "Select a race";
            get_font_metrics( font, string, &text_width,  &asc, &desc );
            
            glPushMatrix();
            {
                glTranslatef( x_org + box_width/2.0 - text_width/2.0,
                             y_org + 310 - asc, 
                             0 );
                
                draw_string( font, string );
            }
            glPopMatrix();
        }
        /* Draw text indicating race requirements (if race not completed), 
         or results in race if race completed. */
        draw_status_msg( x_org, y_org, box_width, box_height );

#else

        /* Draw text indicating race requirements (if race not completed), 
         or results in race if race completed. */
        draw_status_msg( x_org, y_org, box_width, box_height );

#endif


        /* Draw preview */
        if ( g_game.practicing ) {
            list_elem_t elem;
            open_course_data_t *data;
            
            elem = listbox_get_current_item( race_listbox );
            data = (open_course_data_t*) get_list_elem_data( elem );
            current_course = data->course;
        } else {
            list_elem_t elem;
            race_data_t *data;
            
            elem = listbox_get_current_item( race_listbox );
            data = (race_data_t*) get_list_elem_data( elem );
            current_course = data->course;
        }
        
        glDisable( GL_TEXTURE_2D );
        
        glColor4f( 0.0, 0.0, 0.0, 0.3 );
        
#ifdef __APPLE__
        float margin = 4.f * mHeight / 320;
        float yoffset = 26 * mHeight / 320 + 30 * mHeight / 320;
        glBegin( GL_QUADS );
        {
            glVertex2f( x_org, y_org + yoffset );
            glVertex2f( x_org + 140 * mHeight / 320, y_org + yoffset );
            glVertex2f( x_org + 140 * mHeight / 320, y_org + yoffset+107 * mHeight / 320 );
            glVertex2f( x_org, y_org + yoffset+107 * mHeight / 320 );
        }
        glEnd();
#else
        glBegin( GL_QUADS );
        {
            glVertex2f( x_org+box_width-140, y_org+66 );
            glVertex2f( x_org+box_width, y_org+66 );
            glVertex2f( x_org+box_width, y_org+66+107 );
            glVertex2f( x_org+box_width-140, y_org+66+107 );
        }
        glEnd();
#endif

        glColor4f( 1.0, 1.0, 1.0, 1.0 );
        glEnable( GL_TEXTURE_2D );
        
        if ( !get_texture_binding( current_course, &texobj ) ) {
            if ( !get_texture_binding( "no_preview", &texobj ) ) {
                texobj = 0;
            }
        }
        
        glBindTexture( GL_TEXTURE_2D, texobj );
        
#ifdef __APPLE__
        glBegin( GL_QUADS );
        {
            glTexCoord2d( 0, 0);
            glVertex2f( x_org + margin, y_org + yoffset+margin );
            
            glTexCoord2d( 1, 0);
            glVertex2f( x_org + 140 * mHeight / 320 - margin, y_org + yoffset+margin );
            
            glTexCoord2d( 1, 1);
            glVertex2f( x_org + 140 * mHeight / 320 - margin, y_org + yoffset+margin+99 * mHeight / 320 );
            
            glTexCoord2d( 0, 1);
            glVertex2f( x_org + margin, y_org + yoffset+margin+99 * mHeight / 320 );
        }
        glEnd();
        
#else
        glBegin( GL_QUADS );
        {
            glTexCoord2d( 0, 0);
            glVertex2f( x_org+box_width-136, y_org+70 );
            
            glTexCoord2d( 1, 0);
            glVertex2f( x_org+box_width-4, y_org+70 );
            
            glTexCoord2d( 1, 1);
            glVertex2f( x_org+box_width-4, y_org+70+99 );
            
            glTexCoord2d( 0, 1);
            glVertex2f( x_org+box_width-136, y_org+70+99 );
        }
        glEnd();
#endif
    }
    
    
    /*---------------------------------------------------------------------------*/
    /*! 
     Mode initialization function
     \author  jfpatry
     \date    Created:  2000-09-24
     \date    Modified: 2000-09-24
     */
    static void race_select_init(void)
    {
        listbox_list_elem_to_string_fptr_t conv_func = NULL;
        point2d_t dummy_pos = {0, 0};
        int i;
        
        winsys_set_display_func( main_loop );
        winsys_set_idle_func( main_loop );
        winsys_set_reshape_func( reshape );
        winsys_set_mouse_func( ui_event_mouse_func );
        winsys_set_motion_func( ui_event_motion_func );
        winsys_set_passive_motion_func( ui_event_motion_func );
        
        plyr = get_player_data( local_player() );
        
        /* Setup the race list */
        if ( g_game.practicing ) {
            g_game.current_event = "__Practice_Event__";
            g_game.current_cup = "__Practice_Cup__";
            race_list = get_open_courses_list();
            conv_func = get_name_from_open_course_data;
            cup_data = NULL;
            last_completed_race = NULL;
            event_data = NULL;
        } else {
            event_data = (event_data_t*) get_list_elem_data( 
                                                            get_event_by_name( g_game.current_event ) );
            check_assertion( event_data != NULL,
                            "Couldn't find current event." );
            cup_data = (cup_data_t*) get_list_elem_data(
                                                        get_event_cup_by_name( event_data, g_game.current_cup ) );
            check_assertion( cup_data != NULL,
                            "Couldn't find current cup." );
            race_list = get_cup_race_list( cup_data );
            conv_func = get_name_from_race_data;
        }
        
        /* Unless we're coming back from a race, initialize the race data to 
         defaults.
         */
        if ( g_game.prev_mode != GAME_OVER ) {
            /* Make sure we don't play previously loaded course */
            cup_complete = False;
            
            /* Initialize the race data */
            cur_elem = get_list_head( race_list );
            
            if ( g_game.practicing ) {
                g_game.race.course = NULL;
                g_game.race.name = NULL;
                g_game.race.description = NULL;
                
                for (i=0; i<DIFFICULTY_NUM_LEVELS; i++) {
                    g_game.race.herring_req[i] = 0;
                    g_game.race.time_req[i] = 0;
                    g_game.race.score_req[i] = 0;
                }
                
                g_game.race.mirrored = False;
                g_game.race.conditions = RACE_CONDITIONS_SUNNY;
                g_game.race.windy = False;
                g_game.race.snowing = False;
            } else {
                /* Not practicing */
                
                race_data_t *data;
                data = (race_data_t*) get_list_elem_data( cur_elem );
                g_game.race = *data;
                
                if ( is_cup_complete( event_data, 
                                     get_event_cup_by_name( 
                                                           event_data, 
                                                           g_game.current_cup ) ) )
                {
                    cup_complete = True;
                    last_completed_race = get_list_tail( race_list );
                } else {
                    cup_complete = False;
                    last_completed_race = NULL;
                }
            }
        } else {
            /* Back from a race */
            if ( !g_game.race_aborted ) {
                update_race_results();
            }
            
            if (!g_game.practicing && !cup_complete) {
                if ( was_current_race_won() ) {
                    update_for_won_race();
                    
                    /* Advance to next race */
                    if ( cur_elem != get_list_tail( race_list ) ) {
                        cur_elem = get_next_list_elem( race_list, cur_elem );
                    }
                } else {
                    /* lost race */
                    plyr->lives -= 1;
                }
                print_debug( DEBUG_GAME_LOGIC, "Current lives: %d", plyr->lives );
            }
        }
        
        back_btn = button_create( dummy_pos,
                                 80 * mWidth / 480, 48 * mHeight / 320, 
                                 "button_label", 
                                 (mWidth>320)?"Back":"<< " );
        button_set_hilit_font_binding( back_btn, "button_label_hilit" );
        button_set_visible( back_btn, True );
        button_set_click_event_cb( back_btn, back_click_cb, NULL );
        
        start_btn = button_create( dummy_pos,
                                  80 * mWidth / 480, 48 * mHeight / 320,
                                  "button_label",
                                  (mWidth>320)?"Race":" >>" );
        button_set_hilit_font_binding( start_btn, "button_label_hilit" );
        button_set_disabled_font_binding( start_btn, "button_label_disabled" );
        button_set_visible( start_btn, True );
        button_set_click_event_cb( start_btn, start_click_cb, NULL );
        
#ifdef __APPLE__
        race_listbox = listbox_create( dummy_pos,
                                      mWidth - 170 * mHeight / 320, 44 * mHeight / 320,
                                      "course_name_label",
                                      race_list,
                                      conv_func );
        
#else
        race_listbox = listbox_create( dummy_pos,
                                      460 * mHeight / 320, 44 * mHeight / 320,
                                      "listbox_item",
                                      race_list,
                                      conv_func );
        
#endif
        
        
        listbox_set_current_item( race_listbox, cur_elem );
        
        listbox_set_item_change_event_cb( race_listbox, 
                                         race_listbox_item_change_cb, 
                                         NULL );
        
        listbox_set_visible( race_listbox, True );
        
        /* 
         * Create text area 
         */
#ifdef __APPLE__
        desc_ta = textarea_create( dummy_pos,
                                  150, 147,
                                  "race_description",
                                  "" );
        
#else
        desc_ta = textarea_create( dummy_pos,
                                  312, 107,
                                  "race_description",
                                  "" );
        
#endif
        
        if ( g_game.practicing ) {
            open_course_data_t *data;
            data = (open_course_data_t*) get_list_elem_data( cur_elem );
            textarea_set_text( desc_ta, data->description );
        } else {
            race_data_t *data;
            data = (race_data_t*) get_list_elem_data( cur_elem );
            textarea_set_text( desc_ta, data->description );
        }
        
        textarea_set_visible( desc_ta, True );
        
        
        /* 
         * Create state buttons - only if practicing or if cup_complete
         */
        
        if ( g_game.practicing || cup_complete ) {
            /* mirror */
            mirror_ssbtn = ssbutton_create( dummy_pos,
                                           32, 32,
                                           2 );
            ssbutton_set_state_image( mirror_ssbtn, 
                                     0, 
                                     "mirror_button",
                                     make_point2d( 0.0/64.0, 32.0/64.0 ),
                                     make_point2d( 32.0/64.0, 64.0/64.0 ),
                                     white );
            
            ssbutton_set_state_image( mirror_ssbtn, 
                                     1, 
                                     "mirror_button",
                                     make_point2d( 32.0/64.0, 32.0/64.0 ),
                                     make_point2d( 64.0/64.0, 64.0/64.0 ),
                                     white );
            
            ssbutton_set_state( mirror_ssbtn, (int)g_game.race.mirrored );
#ifdef __APPLE__
            ssbutton_set_visible( mirror_ssbtn, False );
#else
            ssbutton_set_visible( mirror_ssbtn, True );
#endif
            
            /* conditions */
            conditions_ssbtn = ssbutton_create( dummy_pos,
                                               32, 32,
                                               4 );

            float border = 2.0;
            ssbutton_set_state_image( conditions_ssbtn, 
                                     0, 
                                     "conditions_button",
                                     make_point2d( (0.0 + border)/64.0, (32.0 + border)/64.0 ),
                                     make_point2d( (32.0 - border)/64.0, (64.0 - border)/64.0 ),
                                     white );
            
            ssbutton_set_state_image( conditions_ssbtn, 
                                     1, 
                                     "conditions_button",
                                     make_point2d( (32.0 + border)/64.0, (0.0 + border)/64.0 ),
                                     make_point2d( (64.0 - border)/64.0, (32.0 - border)/64.0 ),
                                     white );
            
            ssbutton_set_state_image( conditions_ssbtn, 
                                     2, 
                                     "conditions_button",
                                     make_point2d( (32.0 + border)/64.0, (32.0 + border)/64.0 ),
                                     make_point2d( (64.0 - border)/64.0, (64.0 - border)/64.0 ),
                                     white );

            ssbutton_set_state_image( conditions_ssbtn, 
                                     3, 
                                     "conditions_button",
                                     make_point2d( (0.0 + border)/64.0, (0.0 + border)/64.0 ),
                                     make_point2d( (32.0 - border)/64.0, (32.0 - border)/64.0 ),
                                     white );
            
            ssbutton_set_state( conditions_ssbtn, (int)g_game.race.conditions );
            ssbutton_set_visible( conditions_ssbtn, True );

#ifdef __APPLE__
            ssbutton_set_visible( conditions_ssbtn, False );
#else
            ssbutton_set_visible( conditions_ssbtn, True );
#endif
            
            /* wind */
            wind_ssbtn = ssbutton_create( dummy_pos,
                                         32, 32,
                                         2 );
            ssbutton_set_state_image( wind_ssbtn, 
                                     0, 
                                     "wind_button",
                                     make_point2d( 0.0/64.0, 32.0/64.0 ),
                                     make_point2d( 32.0/64.0, 64.0/64.0 ),
                                     white );
            
            ssbutton_set_state_image( wind_ssbtn, 
                                     1, 
                                     "wind_button",
                                     make_point2d( 32.0/64.0, 32.0/64.0 ),
                                     make_point2d( 64.0/64.0, 64.0/64.0 ),
                                     white );
            
            ssbutton_set_state( wind_ssbtn, (int)g_game.race.windy );
#ifdef __APPLE__
            ssbutton_set_visible( wind_ssbtn, False );
#else
            ssbutton_set_visible( wind_ssbtn, True );
#endif
            
            /* snow */
            snow_ssbtn = ssbutton_create( dummy_pos,
                                         32, 32,
                                         2 );
            ssbutton_set_state_image( snow_ssbtn, 
                                     0, 
                                     "snow_button",
                                     make_point2d( 0.0/64.0, 32.0/64.0 ),
                                     make_point2d( 32.0/64.0, 64.0/64.0 ),
                                     white );
            
            ssbutton_set_state_image( snow_ssbtn, 
                                     1, 
                                     "snow_button",
                                     make_point2d( 32.0/64.0, 32.0/64.0 ),
                                     make_point2d( 64.0/64.0, 64.0/64.0 ),
                                     white );
            
            ssbutton_set_state( snow_ssbtn, (int)g_game.race.snowing );
#ifdef __APPLE__
            ssbutton_set_visible( snow_ssbtn, False );
#else
            ssbutton_set_visible( snow_ssbtn, True );
#endif
            /* XXX snow button doesn't do anything, so disable for now */
            ssbutton_set_enabled( snow_ssbtn, False );
            
            /* Can't change conditions if in cup mode */
            if ( !g_game.practicing ) {
                ssbutton_set_enabled( conditions_ssbtn, False );
                ssbutton_set_enabled( wind_ssbtn, False );
                ssbutton_set_enabled( snow_ssbtn, False );
                ssbutton_set_enabled( mirror_ssbtn, False );
            }
            
        } else {
            conditions_ssbtn = NULL;
            wind_ssbtn = NULL;
            snow_ssbtn = NULL;
            mirror_ssbtn = NULL;
        }
        
        update_race_data();
        update_button_enabled_states();
        
        play_music( "start_screen" );
    }
예제 #20
0
void	quadsquare::UpdateAux(const quadcornerdata& cd, const float ViewerLocation[3], float CenterError, clip_result_t vis )
// Does the actual work of updating enabled states and tree growing/shrinking.
{
    BlockUpdateCount++;	//xxxxx

    check_assertion( vis != NotVisible, "Invalid visibility value" );
    if ( vis != NoClip ) {
	vis = ClipSquare( cd );

	if ( vis == NotVisible ) {
	    return;
	}
    }
	
    // Make sure error values are current.
    if (Dirty) {
	RecomputeError(cd);
    }

    int	half = 1 << cd.Level;
    int	whole = half << 1;

    // See about enabling child verts.

    // East vert.
    if ( (EnabledFlags & 1) == 0 && 
	 VertexTest(cd.xorg + whole, Vertex[1].Y, cd.zorg + half, 
		    Error[0], ViewerLocation, cd.Level, East) == true ) 
    {
	EnableEdgeVertex(0, false, cd);	
    }

    // South vert.
    if ( (EnabledFlags & 8) == 0 && 
	 VertexTest(cd.xorg + half, Vertex[4].Y, cd.zorg + whole, 
		    Error[1], ViewerLocation, cd.Level, South) == true ) 
    {
	EnableEdgeVertex(3, false, cd);	
    }

    if (cd.Level > 0) {
	if ((EnabledFlags & 32) == 0) {
	    if (BoxTest(cd.xorg, cd.zorg, half, MinY, MaxY, Error[3], ViewerLocation) == true) EnableChild(1, cd);	// nw child.er
	}
	if ((EnabledFlags & 16) == 0) {
	    if (BoxTest(cd.xorg + half, cd.zorg, half, MinY, MaxY, Error[2], ViewerLocation) == true) EnableChild(0, cd);	// ne child.
	}
	if ((EnabledFlags & 64) == 0) {
	    if (BoxTest(cd.xorg, cd.zorg + half, half, MinY, MaxY, Error[4], ViewerLocation) == true) EnableChild(2, cd);	// sw child.
	}
	if ((EnabledFlags & 128) == 0) {
	    if (BoxTest(cd.xorg + half, cd.zorg + half, half, MinY, MaxY, Error[5], ViewerLocation) == true) EnableChild(3, cd);	// se child.
	}
		
	// Recurse into child quadrants as necessary.
	quadcornerdata	q;
		
	if (EnabledFlags & 32) {
	    SetupCornerData(&q, cd, 1);
	    Child[1]->UpdateAux(q, ViewerLocation, Error[3], vis);
	}
	if (EnabledFlags & 16) {
	    SetupCornerData(&q, cd, 0);
	    Child[0]->UpdateAux(q, ViewerLocation, Error[2], vis);
	}
	if (EnabledFlags & 64) {
	    SetupCornerData(&q, cd, 2);
	    Child[2]->UpdateAux(q, ViewerLocation, Error[4], vis);
	}
	if (EnabledFlags & 128) {
	    SetupCornerData(&q, cd, 3);
	    Child[3]->UpdateAux(q, ViewerLocation, Error[5], vis);
	}
    }
	
    // Test for disabling.  East, South, and center.
    if ( (EnabledFlags & 1) && 
	 SubEnabledCount[0] == 0 && 
	 VertexTest(cd.xorg + whole, Vertex[1].Y, cd.zorg + half, 
		    Error[0], ViewerLocation, cd.Level, East) == false) 
    {
	EnabledFlags &= ~1;
	quadsquare*	s = GetNeighbor(0, cd);
	if (s) s->EnabledFlags &= ~4;
    }

    if ( (EnabledFlags & 8) && 
	 SubEnabledCount[1] == 0 && 
	 VertexTest(cd.xorg + half, Vertex[4].Y, cd.zorg + whole, 
		    Error[1], ViewerLocation, cd.Level, South) == false) 
    {
	EnabledFlags &= ~8;
	quadsquare*	s = GetNeighbor(3, cd);
	if (s) s->EnabledFlags &= ~2;
    }

    if (EnabledFlags == 0 &&
	cd.Parent != NULL &&
	BoxTest(cd.xorg, cd.zorg, whole, MinY, MaxY, CenterError, 
		ViewerLocation) == false)
    {
	// Disable ourself.
	cd.Parent->Square->NotifyChildDisable(*cd.Parent, cd.ChildIndex);	// nb: possibly deletes 'this'.
    }
}
예제 #21
0
void update_key_frame( player_data_t *plyr, scalar_t dt )
{
    int idx;
    scalar_t frac;
    point_t pos;
    scalar_t v;
    matrixgl_t cob_mat, rot_mat;

    char *root;
    char *lsh;
    char *rsh;
    char *lhp;
    char *rhp;
    char *lkn;
    char *rkn;
    char *lank;
    char *rank;
    char *head;
    char *neck;
    char *tail;

    root = get_tux_root_node();
    lsh  = get_tux_left_shoulder_joint();
    rsh  = get_tux_right_shoulder_joint();
    lhp  = get_tux_left_hip_joint();
    rhp  = get_tux_right_hip_joint();
    lkn  = get_tux_left_knee_joint();
    rkn  = get_tux_right_knee_joint();
    lank = get_tux_left_ankle_joint();
    rank = get_tux_right_ankle_joint();
    head = get_tux_head();
    neck = get_tux_neck();
    tail = get_tux_tail_joint();

    keyTime += dt;

    for (idx = 1; idx < numFrames; idx ++) {
        if ( keyTime < frames[idx].time )
            break;
    } 

    if ( idx == numFrames || numFrames == 0 ) {
        set_game_mode( RACING );
        return;
    } 

    reset_scene_node( root );
    reset_scene_node( lsh );
    reset_scene_node( rsh );
    reset_scene_node( lhp );
    reset_scene_node( rhp );
    reset_scene_node( lkn );
    reset_scene_node( rkn );
    reset_scene_node( lank );
    reset_scene_node( rank );
    reset_scene_node( head );
    reset_scene_node( neck );
    reset_scene_node( tail );

    check_assertion( idx > 0, "invalid keyframe index" );

    if ( fabs( frames[idx-1].time - frames[idx].time ) < EPS ) {
	frac = 1.;
    } else {
	frac = (keyTime - frames[idx].time) 
	    / ( frames[idx-1].time - frames[idx].time );
    }

    pos.x = interp( frac, frames[idx-1].pos.x, frames[idx].pos.x );
    pos.z = interp( frac, frames[idx-1].pos.z, frames[idx].pos.z );
    pos.y = interp( frac, frames[idx-1].pos.y, frames[idx].pos.y );
    pos.y += find_y_coord( pos.x, pos.z );

    set_tux_pos( plyr, pos );

    make_identity_matrix( cob_mat );

    v = interp( frac, frames[idx-1].yaw, frames[idx].yaw );
    rotate_scene_node( root, 'y', v );
    make_rotation_matrix( rot_mat, v, 'y' );
    multiply_matrices( cob_mat, cob_mat, rot_mat );

    v = interp( frac, frames[idx-1].pitch, frames[idx].pitch );
    rotate_scene_node( root, 'x', v );
    make_rotation_matrix( rot_mat, v, 'x' );
    multiply_matrices( cob_mat, cob_mat, rot_mat );

    v = interp( frac, frames[idx-1].l_shldr, frames[idx].l_shldr );
    rotate_scene_node( lsh, 'z', v );

    v = interp( frac, frames[idx-1].r_shldr, frames[idx].r_shldr );
    rotate_scene_node( rsh, 'z', v );

    v = interp( frac, frames[idx-1].l_hip, frames[idx].l_hip );
    rotate_scene_node( lhp, 'z', v );

    v = interp( frac, frames[idx-1].r_hip, frames[idx].r_hip );
    rotate_scene_node( rhp, 'z', v );

    /* Set orientation */
    plyr->orientation = make_quaternion_from_matrix( cob_mat );
    plyr->orientation_initialized = True;
} 
예제 #22
0
tex_font_metrics_t* load_tex_font_metrics( char *filename )
{
    tex_font_metrics_t *tfm = NULL;
    FILE *tfm_file = NULL;
    int i;
    char magic[4];
    char *err_msg;
    int endian_check;
    bool_t swap_bytes;
    struct char_dims ch_dims;
    int num_chars;
    int texture_width, texture_height;
    char dummy;

    check_assertion( sizeof(int) == 4,
		     "This architecture's integer size is != 4" );
    check_assertion( sizeof(short) == 2,
		     "This architecture's short integer size is != 2" );
    check_assertion( sizeof(char) == 1,
		     "This architecture's char size is != 1" );

    /* Open file */
    tfm_file = fopen( filename, "rb" );
    if ( tfm_file == NULL ) {
	print_warning( MISSING_FILE_WARNING,
		       "Couldn't open font metrics file %s", filename );
	return NULL;
    }

    tfm = (tex_font_metrics_t*)malloc( sizeof(tex_font_metrics_t) );
    check_assertion( tfm != NULL, "out of memory" );

    /* Initialize tfm */
    for (i=0; i<MAX_TEX_FONT_CHARS; i++) {
	tfm->char_data[i] = NULL;
    }

    /* Check magic number */
    READ_BYTES( tfm_file, magic, sizeof(magic), False );

    if ( strncmp( magic, "\377tfm", 4 ) != 0 ) {
	err_msg = "File is not a valid tfm file";
	goto bail;
    }

    /* Check endian-ness */
    READ_BYTES( tfm_file, &endian_check, sizeof(int), False );

    if ( endian_check == 0x12345678 ) {
	swap_bytes = False;
    } else if ( endian_check == 0x78563412 ) {
	swap_bytes = True;
    } else {
	err_msg = "File is not a valid tfm file";
	goto bail;
    }

    /* Read in texture_width, texture_height, max_ascent, max_descent */
    READ_BYTES( tfm_file, &texture_width, sizeof(int), swap_bytes );
    READ_BYTES( tfm_file, &texture_height, sizeof(int), swap_bytes );
    READ_BYTES( tfm_file, &tfm->max_ascent, sizeof(int), swap_bytes );
    READ_BYTES( tfm_file, &tfm->max_descent, sizeof(int), swap_bytes );

    READ_BYTES( tfm_file, &num_chars, sizeof(int), swap_bytes );

    for (i=0; i<num_chars; i++) {
	tfm_char_data_t *cd;
	scalar_t sstep = 0.5/texture_width;
	scalar_t tstep = 0.5/texture_height;

	READ_BYTES( tfm_file, &ch_dims.ch, sizeof(unsigned short), swap_bytes );
	READ_BYTES( tfm_file, &ch_dims.w, sizeof(unsigned char), False );
	READ_BYTES( tfm_file, &ch_dims.h, sizeof(unsigned char), False );
	READ_BYTES( tfm_file, &ch_dims.x_offset, sizeof(char), False );
	READ_BYTES( tfm_file, &ch_dims.y_offset, sizeof(char), False );
	READ_BYTES( tfm_file, &ch_dims.kern_width, sizeof(char), False );
	READ_BYTES( tfm_file, &dummy, sizeof(char), False );
	READ_BYTES( tfm_file, &ch_dims.x_pixel, sizeof(short), swap_bytes );
	READ_BYTES( tfm_file, &ch_dims.y_pixel, sizeof(short), swap_bytes );

	if ( ch_dims.ch >= MAX_TEX_FONT_CHARS ) {
	    err_msg = "Two-byte characters are not supported";
	    goto bail;
	}

	cd = ( tfm_char_data_t * ) malloc( sizeof( tfm_char_data_t ) );

	check_assertion( cd != NULL, "out of memory" );

	cd->ll = make_point2d( ch_dims.x_offset, ch_dims.y_offset );
	cd->lr = make_point2d( cd->ll.x + ch_dims.w, cd->ll.y );
	cd->ur = make_point2d( cd->lr.x, cd->lr.y + ch_dims.h );
	cd->ul = make_point2d( cd->ur.x - ch_dims.w, cd->ur.y );

	cd->tex_ll = make_point2d( ch_dims.x_pixel / (scalar_t)texture_width + 
				   sstep,
				   ch_dims.y_pixel / (scalar_t)texture_height +
				   tstep );
	cd->tex_lr = make_point2d( cd->tex_ll.x + sstep +
				   ch_dims.w / (scalar_t)texture_width,
				   cd->tex_ll.y + tstep );
	cd->tex_ur = make_point2d( cd->tex_lr.x + sstep,
				   cd->tex_lr.y + tstep +
				   ch_dims.h / (scalar_t)texture_height );
	cd->tex_ul = make_point2d( cd->tex_ur.x + sstep - 
				   ch_dims.w / (scalar_t)texture_width,
				   cd->tex_ur.y + tstep );

	cd->kern_width = ch_dims.kern_width;

	tfm->char_data[ch_dims.ch] = cd;
    }

    fclose( tfm_file );

    return tfm;

bail:
    if ( tfm != NULL ) {
	for (i=0; i<MAX_TEX_FONT_CHARS; i++) {
	    if ( tfm->char_data[i] != NULL ) {
		free( tfm->char_data[i] );
	    }
	}
	free( tfm );
    }

    if ( tfm_file != NULL ) {
	fclose( tfm_file );
    }

    print_warning( IMPORTANT_WARNING, 
		   "Error opening font metrics file `%s': %s\n",
		   filename, err_msg );
    return NULL;
}
예제 #23
0
/* 
 * Tcl callback to allow setting of game configuration variables from Tcl.
 */
static int set_param_cb ( ClientData cd, Tcl_Interp *ip, 
			  int argc, const char *argv[]) 
{
    int i;
    int tmp_int;
    int num_params;
    struct param *parm;

    if ( argc != 3 ) {
        Tcl_AppendResult(ip, argv[0], ": invalid number of arguments\n", 
			 "Usage: ", argv[0], " <parameter name> <value>",
			 (char *)0 );
        return TCL_ERROR;
    } 

    /* Search for parameter */
    parm = NULL;
    num_params = sizeof(Params)/sizeof(struct param);
    for (i=0; i<num_params; i++) {
	parm = (struct param*)&Params + i;

	if ( strcmp( parm->name, argv[1] ) == 0 ) {
	    break;
	}
    }

    /* If can't find parameter, report error */
    if ( parm == NULL || i == num_params ) {
	Tcl_AppendResult(ip, argv[0], ": invalid parameter `",
			 argv[1], "'", (char *)0 );
	return TCL_ERROR;
    }

    /* Set value of parameter */
    switch ( parm->type ) {
    case PARAM_STRING:
	set_param_string( parm, argv[2] ); 
	break;

    case PARAM_CHAR:
	if ( strlen( argv[2] ) > 1 ) {
	    Tcl_AppendResult(ip, "\n", argv[0], ": value for `",
			     argv[1], "' must be a single character", 
			     (char *)0 );
	    return TCL_ERROR;
	}
	set_param_char( parm, argv[2][0] );
	break;

    case PARAM_INT:
	if ( Tcl_GetInt( ip, argv[2], &tmp_int ) != TCL_OK ) {
	    Tcl_AppendResult(ip, "\n", argv[0], ": value for `",
			     argv[1], "' must be an integer", 
			     (char *)0 );
	    return TCL_ERROR;
	}
	set_param_int( parm, tmp_int );
	break;

    case PARAM_BOOL:
	if ( Tcl_GetBoolean( ip, argv[2], &tmp_int ) != TCL_OK ) {
	    Tcl_AppendResult(ip, "\n", argv[0], ": value for `",
			     argv[1], "' must be a boolean", 
			     (char *)0 );
	    return TCL_ERROR;
	}
	check_assertion( tmp_int == 0 || tmp_int == 1, 
			 "invalid boolean value" );
	set_param_bool( parm, (bool_t) tmp_int );
	break;

    default:
	code_not_reached();
    }

    return TCL_OK;
} 
예제 #24
0
/*!
 tux_events Tcl callback
 Here's a sample call to tux_events:

 tux_events {
 {
 -name "Herring Run" -icon noicon -cups {
 {
 -name "Cup 1" -icon noicon -races {
 {
 -course path_of_daggers \
 -description "nice long description" \
 -herring { 15 20 25 30 } \
 -time { 40.0 35.0 30.0 25.0 } \
 -score { 0 0 0 0 } \
 -mirrored yes -conditions cloudy \
 -windy no -snowing no
 }
 {
 -course ingos_speedway \
 -description "nice long description" \
 -herring { 15 20 25 30 } \
 -time { 40.0 35.0 30.0 25.0 } \
 -score { 0 0 0 0 } \
 -mirrored yes -conditions cloudy \
 -windy no -snowing no
 }
 }
 -name "Cup 2" -icon noicon -races {
 {
 -course penguins_cant_fly \
 -description "nice long description" \
 -herring { 15 20 25 30 } \
 -time { 40.0 35.0 30.0 25.0 } \
 -score { 0 0 0 0 } \
 -mirrored yes -conditions cloudy \
 -windy no -snowing no
 }
 {
 -course ingos_speedway \
 -description "nice long description" \
 -herring { 15 20 25 30 } \
 -time { 40.0 35.0 30.0 25.0 } \
 -score { 0 0 0 0 } \
 -mirrored yes -conditions cloudy \
 -windy no -snowing no
 }
 }
 }
 }
 }
 }

 \return  Tcl error code
 \author  jfpatry
 \date    Created:  2000-09-19
 \date    Modified: 2000-09-19
 */
static int events_cb( ClientData cd, Tcl_Interp *ip,
                      int argc, const char **argv )
{
    char *err_msg;
    const char **list = NULL;
    int num_events;
    list_elem_t last_event = NULL;
    int i;

    /* Make sure module has been initialized */
    check_assertion( initialized,
                     "course_mgr module not initialized" );

    if ( argc != 2 ) {
        err_msg = "Incorrect number of arguments";
        goto bail_events;
    }

    if ( Tcl_SplitList( ip, argv[1], &num_events, &list ) == TCL_ERROR ) {
        err_msg = "Argument is not a list";
        goto bail_events;
    }

    /* We currently only allow tux_events to be called once */
    last_event = get_list_tail( event_list );

    if ( last_event != NULL ) {
        err_msg = "tux_events has already been called; it can only be called "
                  "once.";
        goto bail_events;
    }

    for (i=0; i<num_events; i++) {
        event_data_t *data = create_event_data( ip, list[i], &err_msg );

        if ( data == NULL ) {
            goto bail_events;
        }

        last_event = insert_list_elem( event_list, last_event,
                                       (list_elem_data_t) data );
    }

    Tcl_Free( (char*) list );
    list = NULL;

    return TCL_OK;

bail_events:
    if ( list != NULL ) {
        Tcl_Free( (char*) list );
    }

    /* Clean out event list */
    if ( event_list != NULL ) {
        last_event = get_list_tail( event_list );
        while ( last_event != NULL ) {
            event_data_t *data;
            data = (event_data_t*) delete_list_elem( event_list,
                    last_event );
            free( data );
            last_event = get_list_tail( event_list );
        }
    }

    Tcl_AppendResult(
        ip,
        "Error in call to tux_events: ",
        err_msg,
        "\n",
        "Usage: tux_events { list of event data }",
        (NULL) );
    return TCL_ERROR;
}
예제 #25
0
/*! 
  Draws a button widget
  \return  None
  \author  jfpatry
  \date    Created:  2000-09-18
  \date    Modified: 2000-09-18
*/
void button_draw( button_t *button )
{
    GLuint texobj;
    texture_region_t *tex;
    point2d_t pos;
    scalar_t w, h;
    char *font_binding;

    check_assertion( button != NULL, "button is NULL" );

    pos = button->pos;
    w = button->w;
    h = button->h;

    glEnable( GL_TEXTURE_2D );

    tex = NULL;
    font_binding = NULL;

    if ( !button->enabled ) {
	if ( button->disabled_tex.binding ) {
	    tex = &button->disabled_tex;
	} else if ( button->tex.binding ) {
	    tex = &button->tex;
	}

	if ( button->disabled_font_binding ) {
	    font_binding = button->disabled_font_binding;
	} else if ( button->font_binding ) {
	    font_binding = button->font_binding;
	}
    } else if ( button->clicked ) {
	if ( button->clicked_tex.binding ) {
	    tex = &button->clicked_tex;
	} else if ( button->hilit_tex.binding ) {
	    tex = &button->hilit_tex;
	} else if ( button->tex.binding ) {
	    tex = &button->tex;
	} 

	if ( button->hilit_font_binding ) {
	    font_binding = button->hilit_font_binding;
	} else if ( button->font_binding ) {
	    font_binding = button->font_binding;
	}
    } else if ( button->focused ) {
	if ( button->hilit_tex.binding ) {
	    tex = &button->hilit_tex;
	} else if ( button->tex.binding ) {
	    tex = &button->tex;
	} 

	if ( button->hilit_font_binding ) {
	    font_binding = button->hilit_font_binding;
	} else if ( button->font_binding ) {
	    font_binding = button->font_binding;
	}
    } else {
	if ( button->tex.binding ) {
	    tex = &button->tex;
	} 

	if ( button->font_binding ) {
	    font_binding = button->font_binding;
	}
    }

    if ( tex != NULL ) {
	if ( !get_texture_binding( tex->binding, &texobj ) ) {
	    print_warning( IMPORTANT_WARNING,
			   "Couldnt get texture object for binding %s",
			   tex->binding );
	    texobj = 0;
	} 

	glBindTexture( GL_TEXTURE_2D, texobj );

	glColor4dv( (scalar_t*) &tex->colour );

	glBegin( GL_QUADS );
	{
	    glTexCoord2f( tex->ll.x, tex->ll.y );
	    glVertex3f( pos.x, pos.y, 0 );

	    glTexCoord2f( tex->ur.x, tex->ll.y );
	    glVertex3f( pos.x + w, pos.y, 0 );

	    glTexCoord2f( tex->ur.x, tex->ur.y );
	    glVertex3f( pos.x + w, pos.y + h, 0 );

	    glTexCoord2f( tex->ll.x, tex->ur.y );
	    glVertex3f( pos.x, pos.y + h, 0 );
	}
	glEnd();
    }

    if ( font_binding && button->label != NULL ) {
	font_t *font;
	int w, asc, desc;

	if (!get_font_binding( font_binding, &font )) {
	    print_warning( IMPORTANT_WARNING, 
			   "Couldn't get font object for binding %s",
			   font_binding );
	    font = NULL;
	} else {
	    bind_font_texture( font );

	    get_font_metrics( font, button->label, &w, &asc, &desc );

	    glPushMatrix();
	    {
		glTranslatef( button->pos.x + button->w/2.0 - w/2.0,
			      button->pos.y + button->h/2.0 - asc/2.0 + desc/2.0,
			      0.0 );

		draw_string( font, button->label );
	    
	    }
	    glPopMatrix();
	}
    }
    
}
예제 #26
0
/*!
 Creates an open_course_data_t object from a Tcl string.
 \author  jfpatry
 \date    Created:  2000-09-21
 \date    Modified: 2000-09-21
 */
open_course_data_t* create_open_course_data( Tcl_Interp *ip, const char *string,
        char **err_msg )
{
    const char **argv = NULL;
    const char **orig_argv = NULL;
    int argc = 0;

    char *course = NULL;
    char *name = NULL;
    char *description = NULL;
    race_conditions_t conditions = RACE_CONDITIONS_SUNNY;
    scalar_t par_time = 120;
    bool_t speed = True;
    bool_t score = True;

    open_course_data_t *open_course_data = NULL;

    if ( Tcl_SplitList( ip, string, &argc, &argv ) == TCL_ERROR ) {
        *err_msg = "open course data is not a list";
        goto bail_open_course_data;
    }

    orig_argv = argv;

    while ( *argv != NULL ) {
        if ( strcmp( *argv, "-course" ) == 0 ) {
            NEXT_ARG;

            if ( *argv == NULL ) {
                *err_msg = "No data supplied for -course in open course data";
                goto bail_open_course_data;
            }

            course = string_copy( *argv );
        } else if ( strcmp( *argv, "-name" ) == 0 ) {
            NEXT_ARG;

            if ( *argv == NULL ) {
                *err_msg = "No data supplied for -name in open course data";
                goto bail_open_course_data;
            }

            name = string_copy( *argv );
        } else if ( strcmp( *argv, "-description" ) == 0 ) {
            NEXT_ARG;

            if ( *argv == NULL ) {
                *err_msg = "No data supplied for -description in open course data";
                goto bail_open_course_data;
            }

            description = string_copy( *argv );
        } else if ( strcmp( *argv, "-par_time" ) == 0 ) {
            NEXT_ARG;

            if ( *argv == NULL ) {
                par_time = 120.0;
                print_warning( PEDANTIC_WARNING,
                               "No data supplied for -par_time in open course "
                               "data.  Using %g seconds.", par_time );
            } else if ( Tcl_GetDouble( ip, *argv, &par_time ) != TCL_OK ) {
                *err_msg = "Invalid value for -par_time in open course data";
                goto bail_open_course_data;
            }
        } else if ( strcmp( *argv, "-conditions" ) == 0 ) {
            int i;
            NEXT_ARG;

            if ( *argv == NULL ) {
                *err_msg = "No data supplied for -conditions in open course data";
                goto bail_open_course_data;
            }

            for ( i=0; i<RACE_CONDITIONS_NUM_CONDITIONS; i++ ) {
                if ( string_cmp_no_case( race_condition_names[i],
                                         *argv ) == 0 )
                {
                    break;
                }
            }

            if ( i == RACE_CONDITIONS_NUM_CONDITIONS ) {
                *err_msg = "Invalid value for -conditions in race data";
                goto bail_open_course_data;
            }

            conditions = (race_conditions_t)i;

        } else if ( strcmp( *argv, "-no_speed" ) == 0 ) {
            speed = False;
        } else if ( strcmp( *argv, "-no_score" ) == 0 ) {
            score = False;
        }
        else {
            sprintf( err_buff, "unrecognized option `%s' in open course data",
                     *argv );
            *err_msg = err_buff;
            goto bail_open_course_data;
        }

        NEXT_ARG;
    }

    /* Check mandatory arguments */
    if ( course == NULL ) {
        *err_msg = "No course specified in open course data";
        goto bail_open_course_data;
    }

    if ( name == NULL ) {
        *err_msg = "No name specified in open course data";
        goto bail_open_course_data;
    }


    /* Create new open_course_data_t object */
    open_course_data = (open_course_data_t*) malloc( sizeof(open_course_data_t) );
    check_assertion( open_course_data != NULL, "out of memory" );

    open_course_data->course = course;
    open_course_data->name = name;
    open_course_data->description = description;
    open_course_data->par_time = par_time;
    open_course_data->conditions = conditions;
    open_course_data->speed = speed;
    open_course_data->score = score;

    Tcl_Free( (char*) orig_argv );

    return open_course_data;

bail_open_course_data:

    if ( orig_argv ) {
        Tcl_Free( (char*) orig_argv );
    }

    if ( course ) {
        free( course );
    }

    if ( name ) {
        free( name );
    }

    if ( description ) {
        free( description );
    }

    if ( open_course_data ) {
        free( open_course_data );
    }

    return NULL;
}
예제 #27
0
/*! 
  Sets the button's position
  \return  None
  \author  jfpatry
  \date    Created:  2000-09-17
  \date    Modified: 2000-09-17
*/
void button_set_position( button_t *button, point2d_t pos )
{
    check_assertion( button != NULL, "button is NULL" );

    button->pos = pos;
}
예제 #28
0
/*! 
  Fills \c buff with a string describing the current OS (including version)
  \return  0 on success, 1 if buffer too small, -1 if failed to determine 
           OS version
  \author  jfpatry
  \date    Created:  2000-10-30
  \date    Modified: 2000-10-30
*/
int get_os_version( char *buff, int size )
{

#ifdef WIN32
    /* Win32 Version */

    /* See http://www.mvps.org/vb/index2.html?tips/getversionex.htm for 
       a table mapping OSVERSIONINFOEX entries to Windows version */

    char tmp_buff[BUFF_LEN];
    int tmp_buff_size = BUFF_LEN;
    char *ptr = tmp_buff;
    int len;
    
    OSVERSIONINFO osvi;
    
    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    
    if ( !GetVersionEx( (OSVERSIONINFO *) &osvi) ) {
	return -1;
    }
    
    switch (osvi.dwPlatformId)
    {
    case VER_PLATFORM_WIN32_NT:
	
	/* Check for NT versus 2000 */
	if ( osvi.dwMajorVersion <= 4 ) {
	    if ( !append_to_buff( &ptr, &tmp_buff_size, 
				  "Microsoft Windows NT" ) )
	    {
		return -1;
	    }
	}
	
	if ( osvi.dwMajorVersion == 5 ) {
	    if ( !append_to_buff( &ptr, &tmp_buff_size, 
				  "Microsoft Windows 2000" ) )
	    {
		return -1;
	    }
	}
	

	/* Display version, service pack (if any), and build number. */
	len = snprintf(ptr, tmp_buff_size, " version %d.%d %s (Build %d)",
		       osvi.dwMajorVersion,
		       osvi.dwMinorVersion,
		       osvi.szCSDVersion,
		       osvi.dwBuildNumber & 0xFFFF);

	check_assertion( len >= 0, "tmp_buff too small" );
	if ( len < 0 ) {
	    return -1;
	}

	ptr += len;
	tmp_buff_size -= len;
	
	break;
	
    case VER_PLATFORM_WIN32_WINDOWS:
	
	if ((osvi.dwMajorVersion > 4) || 
            ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion > 0)))
	{
	    if ( osvi.dwMinorVersion <= 10 ) {
		if ( strcmp( osvi.szCSDVersion, "A" ) == 0 ) {
		    if ( !append_to_buff( &ptr, &tmp_buff_size, 
					  "Microsoft Windows 98 SE") )
		    {
			return -1;
		    }
		} else {
		    if ( !append_to_buff( &ptr, &tmp_buff_size, 
					  "Microsoft Windows 98") )
		    {
			return -1;
		    }
		}
	    } else {
		if ( !append_to_buff( &ptr, &tmp_buff_size, 
				      "Microsoft Windows ME") )
		{
		    return -1;
		}
	    }
	} else {
	    if ( strcmp( osvi.szCSDVersion, "B" ) == 0 ) {
		if ( !append_to_buff( &ptr, &tmp_buff_size, 
				      "Microsoft Windows 95 OSR2") )
		{
		    return -1;
		}
	    } else {
		if ( !append_to_buff( &ptr, &tmp_buff_size, 
				      "Microsoft Windows 95") )
		{
		    return -1;
		}
	    }
	}

	/* Append Build */
	len = snprintf(ptr, tmp_buff_size, " (Build %d)",
		       osvi.dwBuildNumber & 0xFFFF);

	check_assertion( len >= 0, "tmp_buff too small" );
	if ( len < 0 ) {
	    return -1;
	}

	ptr += len;
	tmp_buff_size -= len;
	
	break;
	
    case VER_PLATFORM_WIN32s:
	if ( !append_to_buff( &ptr, &tmp_buff_size, "Microsoft Win32s") ) {
	    return -1;
	}
	
	break;
    }

    len = snprintf( buff, size, "%s", tmp_buff );
    if ( len < 0 ) {
	/* buffer too small */
	buff[size-1] = (char)0;
	return 1;
    }

    return 0;
    
#else
    /* Unix/Linux version */

    struct utsname utsname;

    if ( uname( &utsname ) >= 0 ) {
	if ( strlen( utsname.sysname ) + strlen( utsname.release ) +
	     strlen( utsname.version ) + 3 > size ) 
	{
	    if ( size > 0 ) {
		buff[0] = (char)0;
	    }
	    return 1;
	}

	sprintf( buff, "%s %s %s", 
		 utsname.sysname, utsname.release, utsname.version );
	
	return 0;
	
    } else {
	/* uname failed */
	return -1;
    }
#endif /* WIN32 */
}