示例#1
0
/*! 
 Updates g_game.race to reflect current race data
 \author  jfpatry
 \date    Created:  2000-09-24
 \date    Modified: 2000-09-24
 */
void update_race_data( void )
{
    int i, course_index;
    
    if ( g_game.practicing ) {
        open_course_data_t *data;
        
        data = (open_course_data_t*) get_list_elem_data( cur_elem );
        g_game.race.course = data->course;
        g_game.race.name = data->name;
        g_game.race.description = data->description;
        g_game.race.conditions = data->conditions;
        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.time_req[0] = data->par_time;
    } else {
        race_data_t *data;
        data = (race_data_t*) get_list_elem_data( cur_elem );
        g_game.race = *data;
    }
}
示例#2
0
static void save_click_cb( button_t *button, void *userdata )
{
    check_assertion( userdata == NULL, "userdata is not null" );

    cur_sound = listbox_get_current_item( sound_listbox );
    int snd = *((int*) get_list_elem_data( cur_sound ));

    cur_video = listbox_get_current_item( video_listbox );
    int vid = *((int*) get_list_elem_data( cur_video ));

    setparam_sound_enabled(snd);

    if (getparam_music_enabled() == 1 && snd == 0)
        stopMusic();
    setparam_music_enabled (snd);
    
    saveparamSoundEnabled(snd);

    setparam_video_quality (vid);
    set_video_quality(vid);

    saveparamVideoQuality(vid);
    
    set_game_mode( GAME_TYPE_SELECT );
    
    ui_set_dirty();
}
示例#3
0
/*! 
 Updates the race results based on the results of the race just completed
 Should be called before last_race_completed is updated.
 \author  jfpatry
 \date    Created:  2000-09-24
 \date    Modified: 2000-09-24
 */
static void update_race_results( void )
{
    char *event;
    char *cup;
    bool_t update_score = False;
    char *race_name;
    scalar_t time;
    int herring;
    int score;
    
    if ( g_game.practicing ) {
        open_course_data_t *data;
        data = (open_course_data_t*)get_list_elem_data( cur_elem );
        race_name = data->name;
    } else {
        race_data_t *data;
        data = (race_data_t*)get_list_elem_data( cur_elem );
        race_name = data->name;
    }
    
    event = g_game.current_event;
    cup = g_game.current_cup;
    
    if ( !get_saved_race_results( plyr->name,
                                 event,
                                 cup,
                                 race_name,
                                 g_game.difficulty,
                                 &time,
                                 &herring,
                                 &score ) )
    {
        update_score = True;
    } else if ( !g_game.practicing && !cup_complete ) {
        /* Scores are always overwritten if cup isn't complete */
        update_score = True;
    } else if ( plyr->score > score ) {
        update_score = True;
    } else {
        update_score = False;
    }
    
    if ( update_score ) {
        bool_t result;
        result = 
	    set_saved_race_results( plyr->name,
                               event,
                               cup,
                               race_name,
                               g_game.difficulty,
                               g_game.time,
                               plyr->herring,
                               plyr->score ); 
        if ( !result ) {
            print_warning( IMPORTANT_WARNING,
                          "Couldn't save race results" );
        }
    }
}
示例#4
0
/*! 
 Updates g_game.race to reflect current race data
 \author  jfpatry
 \date    Created:  2000-09-24
 \date    Modified: 2000-09-24
 */
void update_race_data( void )
{
    int i;
    
    if ( g_game.practicing ) {
		
		g_game.rankings_loaded=false;
		
        open_course_data_t *data;
        
        data = (open_course_data_t*) get_list_elem_data( cur_elem );
        g_game.race.course = data->course;
        g_game.race.name = data->name;
        g_game.race.description = data->description;
        g_game.race.conditions = data->conditions;
        ssbutton_set_state( conditions_ssbtn, (int) data->conditions );
        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.time_req[0] = data->par_time;
        
        g_game.race.mirrored = (bool_t) ssbutton_get_state( mirror_ssbtn );
		//g_game.race.conditions = (race_conditions_t) ssbutton_get_state(conditions_ssbtn );
        g_game.race.windy = (bool_t) ssbutton_get_state( wind_ssbtn );
        g_game.race.snowing = (bool_t) ssbutton_get_state( snow_ssbtn );
    } else {
        race_data_t *data;
        data = (race_data_t*) get_list_elem_data( cur_elem );
        g_game.race = *data;
        
        if ( cup_complete && 
            mirror_ssbtn != NULL &&
            conditions_ssbtn != NULL &&
            wind_ssbtn != NULL &&
            snow_ssbtn != NULL )
        {
            /* If the cup is complete, allowed to customize settings */
            g_game.race.mirrored = (bool_t) ssbutton_get_state( mirror_ssbtn );
            g_game.race.conditions = (race_conditions_t) ssbutton_get_state(
                                                                            conditions_ssbtn );
            g_game.race.windy = (bool_t) ssbutton_get_state( wind_ssbtn );
            g_game.race.snowing = (bool_t) ssbutton_get_state( snow_ssbtn );
        }
    }
}
示例#5
0
/*! 
 Call when a race has just been won
 \author  jfpatry
 \date    Created:  2000-09-24
 \date    Modified: 2000-09-24
 */
void update_for_won_race( void )
{
    race_data_t *race_data;
    
    check_assertion( g_game.practicing == False,
                    "Tried to update for won race in practice mode" );
    
    race_data = (race_data_t*)get_list_elem_data( cur_elem );
    
    if ( last_completed_race == NULL ||
        compare_race_positions( cup_data, last_completed_race, 
                               cur_elem ) > 0 )
    {
        last_completed_race = cur_elem;
		
        if ( cur_elem == get_list_tail( race_list ) ) {
            cup_complete = True;
            
            if ( !set_last_completed_cup( 
                                         plyr->name,
                                         g_game.current_event,
                                         g_game.difficulty,
                                         g_game.current_cup ) )
            {
                print_warning( IMPORTANT_WARNING,
                              "Couldn't save cup completion" );
            } else {
                print_debug( DEBUG_GAME_LOGIC, 
                            "Cup %s completed", 
                            g_game.current_cup );
            }
        }
    }
}
示例#6
0
bool_t flush_fonts(void)
{
    font_node_t *fontnode;
    hash_search_t  sptr;
    list_t delete_list;
    list_elem_t elem;
    char *key;
    bool_t result;

    delete_list = create_list();
  
    begin_hash_scan(font_table, &sptr);
    while ( next_hash_entry(sptr, &key, (hash_entry_t*)(&fontnode)) ) {
	if (fontnode->ref_count == 0) {
	    elem = insert_list_elem(delete_list, NULL, (list_elem_data_t)key);
	}
    }
    end_hash_scan(sptr);

    elem = get_list_head(delete_list);
    while (elem != NULL) {
	key = (char*)get_list_elem_data(elem);

	result = del_font( key );
	check_assertion(result, "Attempt to flush non-existant font");

	elem = get_next_list_elem(delete_list, elem);
    }

    del_list(delete_list);

    return True;

}
示例#7
0
/*! 
  Draws the listbox
  \return  None
  \author  jfpatry
  \date    Created:  2000-09-18
  \date    Modified: 2000-09-18
*/
void listbox_draw( listbox_t *listbox )
{
    font_t *font;

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

    glDisable( GL_TEXTURE_2D );
    
    if(listbox->background_colour.a != 0.0) {
        glColor4dv( (scalar_t*)&listbox->border_colour );
        
        glRectf( listbox->pos.x, 
             listbox->pos.y,
             listbox->pos.x + listbox->w - listbox->arrow_width,
             listbox->pos.y + listbox->h );

        glColor4dv( (scalar_t*)&listbox->background_colour );

        glRectf( listbox->pos.x + listbox->border_width, 
             listbox->pos.y + listbox->border_width,
             listbox->pos.x + listbox->w - listbox->border_width -
             listbox->arrow_width,
             listbox->pos.y + listbox->h - listbox->border_width );
    }
    
    glEnable( GL_TEXTURE_2D );

    if ( !get_font_binding( listbox->font_binding, &font ) ) {
	print_warning( IMPORTANT_WARNING,
		       "Couldn't get font object for binding %s",
		       listbox->font_binding );
    } else {
	int w, asc, desc;
	char *string;

	string = listbox->label_gen_func( 
	    get_list_elem_data( listbox->cur_item ) );

	get_font_metrics( font, string, &w, &asc, &desc );

	bind_font_texture( font );

	glColor4f( 1.0, 1.0, 1.0, 1.0 );

	glPushMatrix();
	{
	    glTranslatef( 
		listbox->pos.x + listbox->border_width + listbox->text_pad,
		listbox->pos.y + listbox->h/2.0 - asc/2.0 + desc/2.0,
		0 );

	    draw_string( font, string );
	}
	glPopMatrix();
    }

    button_draw( listbox->up_button );
    button_draw( listbox->down_button );
}
示例#8
0
/*! 
 Callback called when race listbox item changes
 \author  jfpatry
 \date    Created:  2000-09-24
 \date    Modified: 2000-09-24
 */
static void race_listbox_item_change_cb( listbox_t *listbox, void *userdata )
{
    check_assertion( userdata == NULL, "userdata is not null" );
    
    cur_elem = listbox_get_current_item( listbox );
    
    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 );
        
        ui_set_dirty();
    } else {
        race_data_t *data;
        
        data = (race_data_t*) get_list_elem_data( cur_elem );
        textarea_set_text( desc_ta, data->description );
        
        if ( cup_complete && 
            conditions_ssbtn &&
            wind_ssbtn &&
            snow_ssbtn &&
            mirror_ssbtn ) 
        {
            ssbutton_set_state( conditions_ssbtn,
                               (int) data->conditions );
            ssbutton_set_state( wind_ssbtn,
                               (int) data->windy );
            ssbutton_set_state( snow_ssbtn,
                               (int) data->snowing );
            ssbutton_set_state( mirror_ssbtn,
                               (int) data->mirrored );
        }
        
        update_button_enabled_states();
        
        ui_set_dirty();
    } 
    
    update_race_data();
}
示例#9
0
void update_text()
{
    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 );
		button_set_text(course_title_label, data->name);
		SDL_Log("update_text practice=%s", data->course);
		button_set_text(play_button, get_race_text());
		refresh_scores_for_course(data->course);
    } else {
        race_data_t *data;

        data = (race_data_t*) get_list_elem_data( cur_elem );
        textarea_set_text( desc_ta, data->description );
		button_set_text(course_title_label, data->name);
		SDL_Log("update_text race=%s", data->course);
		button_set_text(play_button, get_race_text());
		refresh_scores_for_course(data->course);
    }
}
示例#10
0
char* editSynchronizeScoresRequest()
{
    
    list_t race_list = NULL;
    list_elem_t cur_elem = NULL;
    player_data_t *plyr = NULL;
    
    open_course_data_t *data;
    
    plyr = get_player_data( local_player() );
    
    g_game.current_event = "__Practice_Event__";
    g_game.current_cup = "__Practice_Cup__";
    g_game.difficulty = 1;
    
    race_list = get_open_courses_list();
    
    cur_elem = get_list_head( race_list );
    
    scalar_t time;
    int herring;
    int score;
    int minutes;
    int seconds;
    int hundredths;
    int i=0;
    char request[10000];
    char* tempRequest;
    strcpy(request,"");
    do
    {
        data = (open_course_data_t*) get_list_elem_data( cur_elem );
        if ( get_saved_race_results( plyr->name,
                                    g_game.current_event,
                                    g_game.current_cup,
                                    data->name,
                                    g_game.difficulty,
                                    &time,
                                    &herring,
                                    &score ) )
        {
            if (i>0) strcat(request,"&");
            get_time_components( time, &minutes, &seconds, &hundredths);
            asprintf(&tempRequest,"piste[%d]=%s&score[%d]=%d&herring[%d]=%d&time[%d]=%02d:%02d:%02d",i,data->name,i,score,i,herring,i,minutes,seconds,hundredths);
            strcat(request,tempRequest);
            free(tempRequest);
            i++;
        }
    }
    while (cur_elem = get_next_list_elem(race_list, cur_elem));
    return request;
}
示例#11
0
static void continue_click_cb( button_t *button, void *userdata )
{
    cup_data_t *cup_data;
    player_data_t *plyr = get_player_data( local_player() );
    
    check_assertion( userdata == NULL, "userdata is not null" );
    
    cur_event = listbox_get_current_item( event_listbox );
    event_data = (event_data_t*) get_list_elem_data( cur_event );
    
    cur_cup = listbox_get_current_item( cup_listbox );
    cup_data = (cup_data_t*) get_list_elem_data( cur_cup );
    
    g_game.current_event = get_event_name( event_data );
    g_game.current_cup = get_cup_name( cup_data );
    
    plyr->lives = INIT_NUM_LIVES;
    
    set_game_mode( RACE_SELECT );
    
    ui_set_dirty();
}
示例#12
0
/*! 
 Callback called when facebook button is clicked
 \author  Emmanuel de Roux
 \date    Created:  2009-09-12
 \date    Modified: 2000-09-12
 */
static void fb_click_cb( button_t *button, void *userdata )
{
	
	scalar_t time;
	open_course_data_t *data;
	data = (open_course_data_t*)get_list_elem_data( cur_elem );
	char* race_name = data->name;
	
	char* mode = g_game.is_speed_only_mode?(char*)Localize("Time Trial","src/race_select.c"):(char*)Localize("classic","src/race_select.c");
	
	char *event,*cup;
	event = g_game.current_event;
	cup = g_game.current_cup;
	
	player_data_t *plyr = get_player_data( local_player() );
	
	int herring, score;
	int minutes, seconds, hundredths;
	
	if (g_game.practicing) {
		if ( get_saved_race_results( plyr->name,
									 event,
									 cup,
									 race_name,
									 g_game.difficulty,
									 &time,
									 &herring,
									 &score ) )
		{
			get_time_components( time, &minutes, &seconds, &hundredths );
		}
		
		if (!g_game.rankings_loaded) {
			facebookPublishDialogDisplayed = false;
			displayRankingsAfterRace(g_game.race.name,plyr->score,plyr->herring,minutes,seconds,hundredths);	
		}
    }
	
	char* scoreTxt;
	
	if (g_game.is_speed_only_mode) asprintf(&scoreTxt, "%02d:%02d:%02d", minutes, seconds, hundredths);
	else asprintf(&scoreTxt, "%d pts", plyr->score );
	
    if (g_game.rankings_loaded==true) { 
		publishNewHighScore(scoreTxt,race_name,mode,g_game.worldRanking,g_game.countryRanking,g_game.totalRanking);
		facebookPublishDialogDisplayed=True;
	}
	
	free(scoreTxt);
}
示例#13
0
/* Return 1-based index for a course_name or 0 if not found */
unsigned int get_course_index(const char* course_name)
{
    int course_index = 0;
    list_t course_list=get_score_courses_list();
    list_elem_t cur_elem=get_list_head(course_list);
    while (cur_elem != NULL)
    {
        open_course_data_t *data = (open_course_data_t*) get_list_elem_data(cur_elem);

        if (strcmp(data->course, course_name) == 0)
        {
            return course_index + 1;
        }
        ++course_index;
        cur_elem=(open_course_data_t*) get_next_list_elem(course_list, cur_elem);
    }
    return 0U;
}
示例#14
0
static void event_listbox_item_change_cb( listbox_t *listbox, void *userdata )
{
    list_elem_t cur_event;
    list_t cup_list;
    
    check_assertion( userdata == NULL, "userdata is not null" );
    
    cur_event = listbox_get_current_item( listbox );
    event_data = (event_data_t*) get_list_elem_data( cur_event );
    
    cup_list =  get_event_cup_list( event_data );
    listbox_set_item_list( cup_listbox, cup_list,
                          cup_list_elem_to_string_func );
    
    set_cur_cup_to_first_incomplete( event_data, cup_list );
    
    listbox_set_current_item( cup_listbox, cur_cup );
    
    update_button_enabled_states();
    
    ui_set_dirty();
}
示例#15
0
/*!
 Returns the cup data for the specified cup name
 \author  jfpatry
 \date    Created:  2000-09-23
 \date    Modified: 2000-09-23
 */
list_elem_t get_event_cup_by_name( event_data_t *event, char *name )
{
    list_elem_t cur_cup;
    cup_data_t *data;

    cur_cup = get_list_head( event->cup_list );

    while (1) {
        if ( cur_cup == NULL ) {
            return NULL;
        }

        data = (cup_data_t*)get_list_elem_data( cur_cup );

        if ( strcmp( data->name, name ) == 0 ) {
            return cur_cup;
        }

        cur_cup = get_next_list_elem( event->cup_list, cur_cup );
    }

    return NULL;
}
示例#16
0
/*!
 Returns the event data for the event with specified name
 \author  jfpatry
 \date    Created:  2000-09-23
 \date    Modified: 2000-09-23
 */
list_elem_t get_event_by_name( char *event_name )
{
    list_elem_t cur_event = NULL;
    event_data_t *data;

    cur_event = get_list_head( event_list );

    while (1) {
        if ( cur_event == NULL ) {
            return NULL;
        }

        data = (event_data_t*) get_list_elem_data( cur_event );

        if ( strcmp( data->name, event_name ) == 0 ) {
            return cur_event;
        }

        cur_event = get_next_list_elem( event_list, cur_event );
    }

    return NULL;
}
示例#17
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 draw_preview()
{
    GLuint texobj;
    
	{
		rect_t screen_rect;
		open_course_data_t *data;
        int w=getparam_x_resolution();
        int h=getparam_y_resolution();
        float colors[]={1, 1, 1, 1};
        shader_set_color(colors);

        data = (open_course_data_t*) get_list_elem_data( cur_elem );
		if ( !get_texture_binding( data->course, &texobj ) ) {
			if ( !get_texture_binding( "no_preview", &texobj ) ) {
				texobj = 0;
			}
		}
        
        glBindTexture( GL_TEXTURE_2D, texobj );

        draw_textured_quad(0.105*w, 0.45*h, 0.34*w, 0.34*h);
	}
}
示例#18
0
/*! 
 Updates the race results based on the results of the race just completed
 Should be called before last_race_completed is updated.
 \author  jfpatry
 \date    Created:  2000-09-24
 \date    Modified: 2000-09-24
 */
static void update_race_results( void )
{
    char *event;
    char *cup;
    bool_t update_score = False;
    char *race_name;
    scalar_t time;
    int herring;
    int score;
	
    if ( g_game.practicing ) {
        open_course_data_t *data;
        data = (open_course_data_t*)get_list_elem_data( cur_elem );
        race_name = data->name;
    } else {
        race_data_t *data;
        data = (race_data_t*)get_list_elem_data( cur_elem );
        race_name = data->name;
    }
    
    event = g_game.current_event;
    cup = g_game.current_cup;
    
    if ( !get_saved_race_results( plyr->name,
                                 event,
                                 cup,
                                 race_name,
                                 g_game.difficulty,
                                 &time,
                                 &herring,
                                 &score ) )
    {
        update_score = True;
    } else if ( !g_game.practicing && !cup_complete ) {
        /* Scores are always overwritten if cup isn't complete */
        update_score = True;
    } else if ( (g_game.is_speed_only_mode && plyr->score < score) || (!g_game.is_speed_only_mode && plyr->score > score) ) {
        update_score = True;
    } else {
        update_score = False;
    }
    
    if ( update_score ) {
		//affiche le message facebook
		char score[BUFF_LEN];
		int minutes, seconds, hundredths;
		get_time_components( g_game.time, &minutes, &seconds, &hundredths );
		if (g_game.is_speed_only_mode) sprintf((char*)score, "%02d:%02d:%02d", minutes, seconds, hundredths );
		else sprintf((char*)score, "%d pts", plyr->score );
		
		char* mode = g_game.is_speed_only_mode?(char*)Localize("Time Trial","src/race_select.c"):(char*)Localize("classic","src/race_select.c");
		//message facebook publié
		//Si cette fonction est executée, elle bloque l'execution de la suivnte grace a une variable statique; voir dans TRFacebookController
		publishFirstScore(score,race_name,mode);
        bool_t result;
        result = 
	    set_saved_race_results( plyr->name,
                               event,
                               cup,
                               race_name,
                               g_game.difficulty,
                               g_game.time,
                               plyr->herring,
                               plyr->score ); 
        if ( !result ) {
            print_warning( IMPORTANT_WARNING,
                          "Couldn't save race results" );
        }
    }
}
示例#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
/*! 
 Draws a status message on the screen
 \author  jfpatry
 \date    Created:  2000-09-24
 \date    Modified: 2000-09-24
 */
void draw_status_msg( int x_org, int y_org, int box_width, int box_height )
{
    char *msg;
    scalar_t time;
    int herring;
    int score;
    font_t *label_font;
    font_t *font;
    char buff[BUFF_LEN];
    bool_t draw_stats = True;
    
    if ( !g_game.practicing ) {
        if ( is_current_race_completed() ) {
            race_data_t *race_data;
            
            if ( cup_complete ) {
                msg = "Best result:";
            } else {
                msg = "Race won! Your result:";
            }
            
            race_data = (race_data_t*)get_list_elem_data( cur_elem );
            
            if ( !get_saved_race_results( plyr->name,
                                         g_game.current_event,
                                         g_game.current_cup,
                                         race_data->name,
                                         g_game.difficulty,
                                         &time,
                                         &herring,
                                         &score ) )
            {
                difficulty_level_t d = g_game.difficulty;
                
                print_warning( IMPORTANT_WARNING,
                              "No saved results for race `%s'.  Using "
                              "race minimum requirements.",
                              race_data->name );
                
                time = g_game.race.time_req[d];
                herring = g_game.race.herring_req[d];
                score = g_game.race.score_req[d];
            }
        } else if ( plyr->lives <= 0 ) {
            msg = "You don't have any lives left.";
            draw_stats = False;
        } else {
            difficulty_level_t d = g_game.difficulty;
            
            time = g_game.race.time_req[d];
            herring = g_game.race.herring_req[d];
            score = g_game.race.score_req[d];
            
            if ( is_current_race_first_incomplete() ) {
                msg = "Needed to advance:";
            } else {
                msg = "You can't enter this race yet.";
                draw_stats = False;
            }
        }
    } else {
        open_course_data_t *data;
        
        data = (open_course_data_t*)get_list_elem_data( cur_elem );
        
        msg = "Best result:";
        
        if ( !get_saved_race_results( plyr->name,
                                     g_game.current_event,
                                     g_game.current_cup,
                                     data->name,
                                     g_game.difficulty,
                                     &time,
                                     &herring,
                                     &score ) )
        {
            /* Don't display anything if no score saved */
            return;
        }
    }
    
#ifdef __APPLE__
#define yTranslation -10
#else
#define yTranslation 0
#endif
    
    if ( !get_font_binding( "race_requirements", &font ) ||
        !get_font_binding( "race_requirements_label", &label_font ) ) 
    {
        print_warning( IMPORTANT_WARNING,
                      "Couldn't get fonts for race requirements" );
    } else {
        glPushMatrix();
        {
            glTranslatef( x_org + 160 * mHeight / 320,
                         y_org + 60 * mHeight / 320+yTranslation * mHeight / 320,
                         0 );
            
            bind_font_texture( label_font );
            draw_string( label_font, msg );
        }
        glPopMatrix();
        
        if ( draw_stats ) {
            glPushMatrix();
            {
                int minutes;
                int seconds;
                int hundredths;
                
                get_time_components( time, &minutes, &seconds, &hundredths );
                
                glTranslatef( x_org + 160 * mHeight / 320,
                             y_org + 44 * mHeight / 320+yTranslation * mHeight / 320,
                             0 );
                
                
                bind_font_texture( label_font );
                draw_string( label_font, "Time: " );
                
                sprintf( buff, "%02d:%02d.%02d",
                        minutes, seconds, hundredths );
                bind_font_texture( font );
                draw_string( font, buff );
                
                bind_font_texture( label_font );
                draw_string( label_font, "    Fish: " );
                
                sprintf( buff, "%03d", herring ); 
                bind_font_texture( font );
                draw_string( font, buff );
            }
            glPopMatrix();
            glPushMatrix();
            {                
                glTranslatef( x_org + 160 * mHeight / 320,
                             y_org + 28 * mHeight / 320+yTranslation * mHeight / 320,
                             0 );
                
                bind_font_texture( label_font );
                draw_string( label_font, "Score: " );
                
                sprintf( buff, "%06d", score );
                bind_font_texture( font );
                draw_string( font, buff );
            }
            glPopMatrix();
        }
    }
}
示例#21
0
/*! 
 Draws a status message on the screen
 \author  jfpatry
 \date    Created:  2000-09-24
 \date    Modified: 2000-09-24
 */
void draw_status_msg( int x_org, int y_org, int box_width, int box_height )
{
    const char *msg;
    scalar_t time;
    int herring;
    int score;
    font_t *label_font;
    font_t *font;
    char buff[BUFF_LEN];
    bool_t draw_stats = True;
    
    if ( g_game.practicing ) {
        open_course_data_t *data;
        
        data = (open_course_data_t*)get_list_elem_data( cur_elem );
        
        msg = Localize("Best result:","");
        
        if ( !get_saved_race_results( plyr->name,
                                     g_game.current_event,
                                     g_game.current_cup,
                                     data->name,
                                     g_game.difficulty,
                                     &time,
                                     &herring,
                                     &score ) )
        {
            /* Don't display anything if no score saved */
            return;
        }
        
        
#ifdef __APPLE__
#define yTranslation -10
#else
#define yTranslation 0
#endif
        
        if ( !get_font_binding( "race_requirements", &font ) ||
            !get_font_binding( "race_requirements_label", &label_font ) ) 
        {
            print_warning( IMPORTANT_WARNING,
                          "Couldn't get fonts for race requirements" );
        } else {
            glPushMatrix();
            {
                glTranslatef( x_org + 0,
                             y_org + 200+yTranslation,
                             0 );
                
                bind_font_texture( label_font );
                draw_string( label_font, msg );
            }
            glPopMatrix();
            
            if ( draw_stats ) {
                glPushMatrix();
                {
                    int minutes;
                    int seconds;
                    int hundredths;
                    
                    get_time_components( time, &minutes, &seconds, &hundredths );
                    
                    glTranslatef( x_org + 0,
                                 y_org + 184+yTranslation,
                                 0 );
                    
                    
                    bind_font_texture( label_font );
                    draw_string( label_font, Localize("Time: ","") );
                    
                    sprintf( buff, "%02d:%02d.%02d",
                            minutes, seconds, hundredths );
                    bind_font_texture( font );
                    draw_string( font, buff );
#ifdef __APPLE__
                    if (!g_game.is_speed_only_mode || !g_game.practicing) {
#endif
                        bind_font_texture( label_font );
                        draw_string( label_font, Localize("    Fish: ","") );
                        
                        sprintf( buff, "%03d", herring ); 
                        bind_font_texture( font );
                        draw_string( font, buff );
                        
                        bind_font_texture( label_font );
                        draw_string( label_font, Localize("     Score: ","") );
                        
                        sprintf( buff, "%06d", score );
                        bind_font_texture( font );
                        draw_string( font, buff );
#ifdef __APPLE__
                    }
#endif
                }
                glPopMatrix();
            }
        }
    }
}
示例#22
0
const char* get_current_course_name()
{
    open_course_data_t *data;
    data = (open_course_data_t*) get_list_elem_data( cur_elem );
    return data->course;
}
示例#23
0
void init_saved_games( void ) 
{
    char dir_name[BUFF_LEN];
    FILE* save_stream;
    save_info_t this_save;
    char player_name[BUFF_LEN];
    int sav_index;
    char file_name[BUFF_LEN];
    int i;
    char magic[4];
    list_t dir_file_list = NULL;
    list_elem_t cur_dir_file = NULL;
    char *cur_dir_filename = NULL;


    progress_save_table = create_hash_table();

    for (i=0; i<DIFFICULTY_NUM_LEVELS; i++) {
	results_save_table[i] = create_hash_table();
    }
 
    if (get_config_dir_name( dir_name, sizeof(dir_name) ) != 0) {
	return;
    }

    dir_file_list = get_dir_file_list(dir_name);
    if ( dir_file_list == NULL ) {
	/* Config dir doesn't exist.  Don't print warning since this is a
	   normal condition the first time the program is run. */
	return;
    }

    for ( cur_dir_file = get_list_head( dir_file_list );
	  cur_dir_file != NULL;
	  cur_dir_file = get_next_list_elem( dir_file_list, cur_dir_file ) )
    {
	cur_dir_filename = (char*) get_list_elem_data( cur_dir_file );

	if (get_sav_index(cur_dir_filename, &sav_index)) {

	    strncpy(player_name, cur_dir_filename, sav_index);
	    player_name[sav_index] = '\0';

	    sprintf( file_name, "%s" DIR_SEPARATOR "%s", 
		     dir_name,
		     cur_dir_filename );

	    save_stream = fopen( file_name, "r" );

	    if ( fread( magic, sizeof(magic), 1, save_stream ) != 1 ||
		 strncmp( magic, SAVE_MAGIC_V1, sizeof(magic) ) != 0 ) 
	    {
		print_warning( IMPORTANT_WARNING,
			       "`%s' is not a valid saved game file",
			       file_name );
		fclose( save_stream);
		continue;
	    }


	    if (save_stream != NULL) {
		while (fread( &this_save, sizeof(this_save), 1, save_stream)) {
		    switch ( this_save.data_type ) {
		    case EVENT_INFO:
			set_last_completed_cup( player_name, 
						this_save.data.event.event, 
						this_save.data.event.difficulty, 
						this_save.data.event.cup );
			print_debug( DEBUG_SAVE,
				     "Read completed from `%s': "
				     "name: %s, event: %s, difficulty: %d, cup: %s",
				     cur_dir_filename, 
				     player_name,
				     this_save.data.event.event,
				     this_save.data.event.difficulty,
				     this_save.data.event.cup );
			break;

		    case RACE_RESULTS:
			set_saved_race_results( player_name,
						this_save.data.results.event,
						this_save.data.results.cup,
						this_save.data.results.race,
						this_save.data.results.difficulty,
						this_save.data.results.time,
						this_save.data.results.herring,
						this_save.data.results.score );
			print_debug( DEBUG_SAVE,
				     "Read results from `%s': "
				     "name: %s, event: %s, cup: %s, "
				     "race: %s, difficulty: %d, time: %g, "
				     "herring: %d, score: %d",
				     cur_dir_filename, 
				     player_name,
				     this_save.data.results.event,
				     this_save.data.results.cup,
				     this_save.data.results.race,
				     this_save.data.results.difficulty,
				     this_save.data.results.time,
				     this_save.data.results.herring,
				     this_save.data.results.score );
			break;

		    default:
			print_warning( IMPORTANT_WARNING, 
				       "Unrecognized data type in save file." );

		    }
		}


		if ( fclose( save_stream ) != 0 ) {
		    perror( "fclose" );
		}
	    } else {
		print_warning( IMPORTANT_WARNING,
			       "Couldn't read file `%s': %s",
			       file_name, strerror( errno ) );
	    }
	}
    }

    free_dir_file_list( dir_file_list );
}
示例#24
0
static void set_widget_positions_and_draw_decorations()
{
    int h = getparam_y_resolution();
    int box_width, box_height, box_max_y;
    int x_org, y_org;
    char *string;
    font_t *font;
    int text_width, asc, desc;
    list_t cup_list;
    GLuint texobj;
    
#ifdef __APPLE__
    /* set the dimensions of the box in which all widgets should fit */
    box_width = 300;
    box_height = 310;
    box_max_y = h - 128;
    x_org = 10;
    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 + 40 - button_get_width( back_btn )/2.0,
                                     12 ) );
    
    button_set_position(
                        continue_btn,
                        make_point2d( x_org + 232 - button_get_width( continue_btn )/2.0,
                                     12 ) );
                                     
    button_set_position(
                        howToPlay_btn,
                        make_point2d( x_org + 160 - button_get_width( continue_btn )/2.0,
                                     100 ) );
    //Out of the field of view
    //in Tux Rider World Challenge, there is no more events and cup, just training
    //I'm adapting from The Tux Racer system by selecting the first and only event
    //I hide its list box out of the field of view
    //and each cup for this event is a training
    
    listbox_set_position( 
                         event_listbox,
                         make_point2d( x_org+500,
                                      y_org + 500 ) );
    
    listbox_set_position( 
                         cup_listbox,
                         make_point2d( x_org+50,
                                      y_org + 193 ) );
    
#else
    int w = getparam_x_resolution();

    /* set the dimensions of the box in which all widgets should fit */
    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(
                        continue_btn,
                        make_point2d( x_org + 329 - button_get_width( continue_btn )/2.0,
                                     42 ) );
    
    listbox_set_position( 
                         cup_listbox,
                         make_point2d( x_org + 52,
                                      y_org + 103 ) );
    
    listbox_set_position( 
                         event_listbox,
                         make_point2d( x_org + 52,
                                      y_org + 193 ) );
    
#endif
    
    /* 
     * Draw other stuff 
     */
    
    /* Event & cup icons */
    if ( !get_texture_binding( get_event_icon_texture_binding( event_data ),
                              &texobj ) ) {
        texobj = 0;
    }
    
    glBindTexture( GL_TEXTURE_2D, texobj );
    
    glBegin( GL_QUADS );
    {
        point2d_t tll, tur;
        point2d_t ll, ur;
        
#ifdef __APPLE__
        //out of the field of view
        ll = make_point2d( x_org, y_org + 500 );
        ur = make_point2d( x_org + 44, y_org + 500 + 44 );
        tll = make_point2d( 0, 0 );
        tur = make_point2d( 44.0/64.0, 44.0/64.0 );
#else
        ll = make_point2d( x_org, y_org + 193 );
        ur = make_point2d( x_org + 44, y_org + 193 + 44 );
        tll = make_point2d( 0, 0 );
        tur = make_point2d( 44.0/64.0, 44.0/64.0 );
#endif
        
        glTexCoord2f( tll.x, tll.y );
        glVertex2f( ll.x, ll.y );
        
        glTexCoord2f( tur.x, tll.y );
        glVertex2f( ur.x, ll.y );
        
        glTexCoord2f( tur.x, tur.y );
        glVertex2f( ur.x, ur.y );
        
        glTexCoord2f( tll.x, tur.y );
        glVertex2f( ll.x, ur.y );
    }
    glEnd();
    
    
    if ( !get_texture_binding( 
                              get_cup_icon_texture_binding( 
                                                           (cup_data_t*) get_list_elem_data( cur_cup ) ), &texobj ) ) 
    {
        texobj = 0;
    }
    
    glBindTexture( GL_TEXTURE_2D, texobj );
    
#ifdef __APPLE__DISABLED__
    {
        point2d_t tll, tur;
        point2d_t ll, ur;
        
        ll = make_point2d( x_org, y_org + 103 );
        ur = make_point2d( x_org + 44, y_org + 103 + 44 );
        tll = make_point2d( 0, 0 );
        tur = make_point2d( 44.0/64.0, 44.0/64.0 );
        
        const GLfloat vertices []=
        {
            ll.x, ll.y,
            ur.x, ll.y,
            ur.x, ur.y,
            ll.x, ur.y
        };
        
        const GLfloat texCoords []=
        {
            tll.x, tll.y,
            tur.x, tll.y,
            tur.x, tur.y,
            tll.x, tur.y,
        };
        
        glEnableClientState (GL_VERTEX_ARRAY);
        glVertexPointer (2, GL_FLOAT , 0, vertices);	
        glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    }
#else
    glBegin( GL_QUADS );
    {
        point2d_t tll, tur;
        point2d_t ll, ur;
        
#ifdef __APPLE__
        ll = make_point2d( x_org, y_org + 193 );
        ur = make_point2d( x_org + 44, y_org + 193 + 44 );
        tll = make_point2d( 0, 0 );
        tur = make_point2d( 44.0/64.0, 44.0/64.0 );
#else
        ll = make_point2d( x_org, y_org + 103 );
        ur = make_point2d( x_org + 44, y_org + 103 + 44 );
        tll = make_point2d( 0, 0 );
        tur = make_point2d( 44.0/64.0, 44.0/64.0 );
#endif
        
        glTexCoord2f( tll.x, tll.y );
        glVertex2f( ll.x, ll.y );
        
        glTexCoord2f( tur.x, tll.y );
        glVertex2f( ur.x, ll.y );
        
        glTexCoord2f( tur.x, tur.y );
        glVertex2f( ur.x, ur.y );
        
        glTexCoord2f( tll.x, tur.y );
        glVertex2f( ll.x, ur.y );
    }
    glEnd();
#endif
    
    if ( !get_font_binding( "menu_label", &font ) ) {
        print_warning( IMPORTANT_WARNING,
                      "Couldn't get font for binding menu_label" );
    } else {
        bind_font_texture( font );
#ifdef __APPLE__
        string = "Select a training";
#else
        string = "Select event and cup";
#endif
        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();
    }
    
    if ( !get_font_binding( "event_and_cup_label", &font ) ) {
        print_warning( IMPORTANT_WARNING,
                      "Couldn't get font for binding menu_label" );
    } 
#ifdef __APPLE__
    
    cur_event = listbox_get_current_item( event_listbox );
    event_data = (event_data_t*) get_list_elem_data( cur_event );
    cup_list = get_event_cup_list( event_data );
    cur_cup = listbox_get_current_item( cup_listbox );
    
    if ( is_cup_complete( event_data, cur_cup ) ) {
        string = "You've won this Training !";
    } else if ( is_cup_first_incomplete_cup( event_data, cur_cup ) ) {
        string = "You must complete this training first";
    } else {
        string = "You cannot enter this training yet"; 
    }
    
    if ( !get_font_binding( "cup_status", &font ) ) {
        print_warning( IMPORTANT_WARNING,
                      "Couldn't get font for binding cup_status" );
    } else {
        bind_font_texture( font );
        
        get_font_metrics( font, string, &text_width, &asc, &desc );
        
        glPushMatrix();
        {
            glTranslatef( x_org + box_width/2.0 - text_width/2.0,
                         y_org+140, 
                         0 );
            
            draw_string( font, string );
        }
        glPopMatrix();
    }
    
#else
    else {
示例#25
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 *current_course;
    GLuint texobj;
    
    /* set the dimensions of the box in which all widgets should fit */
    box_width = 300;
    box_height = 310;
    box_max_y = h - 128;
    x_org = 10;
    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(MARGIN_WIDTH,
                                     MARGIN_HEIGHT ) );
    
    button_set_position(
                        start_btn,
                        make_point2d(w - button_get_width( start_btn ) - MARGIN_WIDTH,
                                     MARGIN_HEIGHT ) );
    
    listbox_set_position(
                         race_listbox,
                         make_point2d( x_org,
                                      y_org + 235 ) );
    textarea_set_position( 
                          desc_ta,
                          make_point2d( x_org + w - textarea_get_width(desc_ta) - 10,
                                       y_org + 26));
    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 ) );
        
    } 
    
    /* 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 );
    
    /* 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;
    float yoffset = 26 + 30;
    glBegin( GL_QUADS );
    {
        glVertex2f( x_org, y_org + yoffset );
        glVertex2f( x_org + 140, y_org + yoffset );
        glVertex2f( x_org + 140, y_org + yoffset+107 );
        glVertex2f( x_org, y_org + yoffset+107 );
    }
    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 - margin, y_org + yoffset+margin );
        
        glTexCoord2d( 1, 1);
        glVertex2f( x_org + 140 - margin, y_org + yoffset+margin+99 );
        
        glTexCoord2d( 0, 1);
        glVertex2f( x_org + margin, y_org + yoffset+margin+99 );
    }
    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
}
示例#26
0
static void race_select_init(void)
{
    point2d_t dummy_pos = {0, 0};
	coord_t button_coord;
	list_elem_t tmp;
    int i;
    
    scoreboard_open=True;
    
    winsys_set_display_func( main_loop );
    winsys_set_idle_func( main_loop );
    winsys_set_reshape_func( reshape );
    winsys_set_mouse_func( GameMenu_mouse_func );
    winsys_set_motion_func( GameMenu_motion_func );
    winsys_set_passive_motion_func( GameMenu_motion_func );
	winsys_set_joystick_func( NULL );
	winsys_set_joystick_button_func( NULL );
    
	winsys_reset_js_bindings();
	winsys_add_js_axis_bindings();
	winsys_add_js_button_binding(SDL_CONTROLLER_BUTTON_A, SDLK_RETURN);
	winsys_add_js_button_binding(SDL_CONTROLLER_BUTTON_B, SDLK_ESCAPE);
    
	winsys_add_js_button_binding(SDL_CONTROLLER_BUTTON_DPAD_LEFT, SDLK_LEFT);
	winsys_add_js_button_binding(SDL_CONTROLLER_BUTTON_DPAD_RIGHT, SDLK_RIGHT);

	GameMenu_init();
	setup_gui();

    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__";
#ifdef SPEED_MODE
        if(g_game.is_speed_only_mode)
            race_list = get_speed_courses_list();
        else
            race_list = get_score_courses_list();
#else
        race_list = get_score_courses_list();
#endif
        cup_data = NULL;
        last_completed_race = NULL;
        event_data = NULL;
    }
    
    /* 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 */
		if (cur_elem==NULL)
		{
			cur_elem = get_list_head( race_list );
		}
		else
		{
			bool_t needs_changing=False;
			tmp=get_list_head(race_list);
			while (tmp!=cur_elem && tmp!=NULL)
			{
				tmp=get_next_list_elem(race_list, tmp);
			}
			if (!tmp)
			{
				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();
        }
	}
    
    /* 
     * Create text area 
     */
    desc_ta = textarea_create( make_point2d(
		0.1*getparam_x_resolution(), 0.2*getparam_y_resolution()),
		0.4*getparam_x_resolution(), 0.23*getparam_y_resolution(), "race_description", "" );
    
    textarea_set_visible( desc_ta, True );
    
    update_race_data();
    
	button_coord.x_coord_type=button_coord.y_coord_type=NORMALIZED_COORD;
	button_coord.x=0.50;
	button_coord.y=0.85;
	button_coord.x_just=CENTER_JUST;
	button_coord.y_just=CENTER_JUST;
    
	gui_add_widget(course_title_label=create_label(""), &button_coord);
    
	button_coord.x=0.1;
	button_coord.x_just=LEFT_JUST;
	gui_add_widget(prev_course_btn=create_button(LEFT_ARROW, prev_cb), &button_coord);
    
	button_coord.x=0.9;
	button_coord.x_just=RIGHT_JUST;
	gui_add_widget(next_course_btn=create_button(RIGHT_ARROW, next_cb), &button_coord);
    
	course_title_label->font_binding="race_selection_title";
	prev_course_btn->font_binding="race_selection_title";
	next_course_btn->font_binding="race_selection_title";
    
	button_coord.x=0.30;
	button_coord.y=0.09;
	button_coord.x_just=CENTER_JUST;
	gui_add_widget(back_button=create_button(get_back_text(), back_cb), &button_coord);
    
	button_coord.x=0.70;
	gui_add_widget(play_button=create_button(get_race_text(), play_cb), &button_coord);
    
	init_scoreboard_labels();
	init_scoreboard();

    play_music( "start_screen" );
}
示例#27
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" );
}