⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chart.c

📁 LTris a tetris clone for Linux
💻 C
字号:
/***************************************************************************                          chart.c  -  description                             -------------------    begin                : Mon Sep 24 2001    copyright            : (C) 2001 by Michael Speck    email                : kulkanie@gmx.net ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/#include "ltris.h"#include "chart.h"#include "list.h"#define CHART_FILE_NAME "ltris.hscr"List *charts = 0; /* list of all loaded level set charts */char chart_path[512]; /* path charts where actually loaded/created from */int chart_loaded = 0; /* true if highscore succesfully loaded */int chart_w, chart_h; /* size of higscore chart */int chart_gap = 10;int chart_level_offset = 0; /* level offset (name's left aligned, score's right aligned) */char *cheader = "Name      Level    Score";Font *cfont = 0, *chfont = 0, *ccfont = 0; /* normal, highlight and caption font */extern Config config;extern Sdl sdl;extern char *gametype_names[7];/*====================================================================Local====================================================================*//*====================================================================Reset charts====================================================================*/void chart_reset( Set_Chart *chart ){    int i;    memset( chart->entries, 0, sizeof( Chart_Entry ) * CHART_ENTRY_COUNT );    for ( i = 0; i < CHART_ENTRY_COUNT; i++ )        chart_add( chart, "............",  i + 1, 10000 * ( i + 1 ) );    for ( i = 0; i < CHART_ENTRY_COUNT; i++ )        chart->entries[i].new_entry = 0;}/*====================================================================Create/delete set chart.====================================================================*/Set_Chart* chart_set_create( char *name ){	Set_Chart *chart = calloc( 1, sizeof( Set_Chart ) );	chart->name = strdup( name );	chart_reset( chart );	return chart;}void chart_set_delete( void *ptr ){	Set_Chart *chart = (Set_Chart*)ptr;	if ( !chart ) return;	if ( chart->name ) free( chart->name );	free( chart );}/*====================================================================Read entries of a chart from file position.====================================================================*/void chart_read_entries( FILE *file, char *file_name, Set_Chart *chart ){    char buffer[128];    int i;    for ( i = 0; i < CHART_ENTRY_COUNT; i++ ) {        if ( feof( file ) ) {            fprintf( stderr, "Unexpected EOF in '%s' in entry %i... reading of highscore aborted.\n",                     file_name, i );            break;        }        fgets( buffer, 128, file ); buffer[strlen(buffer) - 1] = 0; /* remove newline */        strcpy( chart->entries[i].name, buffer );        fgets( buffer, 128, file ); buffer[strlen(buffer) - 1] = 0; /* remove newline */        chart->entries[i].level = atoi( buffer );        fgets( buffer, 128, file ); buffer[strlen(buffer) - 1] = 0; /* remove newline */        chart->entries[i].score = strtod( buffer, 0 );    }}/*====================================================================Load all highscores from path. If not found create chart withone set 'Classic'.ReturnValue: True if successful====================================================================*/int chart_load_from_path( char *path ){    FILE *file = 0;    char file_name[512];	char setname[1024];	char aux[4];	Set_Chart *chart = 0;    /* full file name */    sprintf( file_name, "%s/%s", path, CHART_FILE_NAME );	/* clear chart list */	list_clear( charts );    /* open file */    file = fopen( file_name, "r" );    if ( file ) {		/* test if it's new format or old one. */		fread( aux, sizeof( char ), 3, file ); aux[3] = 0;		fseek( file, 0, SEEK_SET );		if ( strequal( ">>>", aux ) ) {			/* new format: load all set charts */			while( !feof( file ) ) {				/* check if next sign is an '>' else skip reading */				aux[0] = 0;				fread( aux, sizeof( char ), 1, file );				fseek( file, -1, SEEK_CUR );				if ( aux[0] != '>' ) break;				chart = calloc( 1, sizeof( Set_Chart ) );				/* get name: >>>name */				fscanf( file, ">>>%s\n", setname );				chart->name = strdup( setname );				/* entries */				chart_read_entries( file, file_name, chart );				/* add */				list_add( charts, chart );			}		}		else {			/* old format: load single chart as 'Classic' */			fprintf( stderr, "Converting highscore chart as format changed.\n" );			chart = chart_set_create( gametype_names[1] );			chart_read_entries( file, file_name, chart );			list_add( charts, chart );		}        fclose( file );    }    else {        fprintf( stderr, "Highscore chart doesn't exist in '%s'... creating new one.\n", path );		chart = chart_set_create( gametype_names[1] );		list_add( charts, chart );    }    /* test if writing is allowed without changing actual contents */    if ( ( file = fopen( file_name, "a" ) ) == 0 ) {        fprintf( stderr, "Write permission for '%s' denied.\n", file_name );        return 0;    }    else        fclose( file );    strcpy( chart_path, path );    chart_loaded = 1;    return 1;}/*====================================================================Publics====================================================================*//*====================================================================Load highscore. If it doesn't exist try to create it in HI_DIR ifthis fails fall back to ~/.lbreakout and create highscore there.====================================================================*/void chart_load(){	/* create list */	if ( charts ) list_delete( charts ); charts = 0;	charts = list_create( LIST_AUTO_DELETE, chart_set_delete );    /* load highscore */    if ( !chart_load_from_path( HI_DIR ) ) {        fprintf( stderr, "Unable to access highscore chart in '%s'.\n", HI_DIR );        fprintf( stderr, "Trying to use config directory '%s'.\n", config.dir_name );        if ( !chart_load_from_path( config.dir_name ) ) {            fprintf( stderr, "Unable to access highscore chart in config directory... won't be "                             "able to save any results. Sorry.\n" );            return;        }    }    printf( "Saving highscore chart in: %s\n", chart_path );    /* load resources */    cfont = load_fixed_font( "f_small_yellow.bmp", 32, 96, 8 );    chfont = load_fixed_font( "f_small_white.bmp", 32, 96, 8 );    ccfont = load_fixed_font( "f_yellow.bmp", 32, 96, 10 );    /* compute size and position stuff of highscore */    chart_w = text_width( ccfont, cheader );    chart_h = ccfont->height +  chart_gap + /* title + gap */			  cfont->height * CHART_ENTRY_COUNT + /* entries */              chart_gap + /*gap between caption and entries */              ccfont->height; /* caption size */    chart_level_offset = text_width( ccfont, "name.-----" ) + text_width( ccfont, "Level" ) / 2; /* level offset centered */}/*====================================================================Delete resources====================================================================*/void chart_delete(){    free_font( &cfont );    free_font( &chfont );    free_font( &ccfont );	if ( charts ) list_delete( charts ); charts = 0;}/*====================================================================Save chart in directory it was loaded from.====================================================================*/void chart_save(){    char file_name[512];    int i;	Set_Chart *chart = 0;    FILE *file = 0;    if ( !chart_loaded ) return;    /* full file name */    sprintf( file_name, "%s/%s", chart_path, CHART_FILE_NAME );    /* open file */    file = fopen( file_name, "w" );    if ( !file ) {        fprintf( stderr, "??? Highscore chart loaded properly but cannot save?\n" );        return;    }	/* save all charts */	list_reset( charts );	while ( ( chart = list_next( charts ) ) !=  0 ) {		fprintf( file, ">>>%s\n", chart->name );    	for ( i = 0; i < CHART_ENTRY_COUNT; i++ )        	fprintf( file, "%s\n%i\n%.0f\n", chart->entries[i].name, chart->entries[i].level, chart->entries[i].score );	}		    fclose( file );}/*====================================================================Check if this player entered the highscore chart and update it.====================================================================*/void chart_add( Set_Chart *chart, char *name, int level, double score ){    /* add new entry at blind end of chart */    strcpy( chart->entries[CHART_ENTRY_COUNT].name, name );    chart->entries[CHART_ENTRY_COUNT].level = level;    chart->entries[CHART_ENTRY_COUNT].score = score;    chart->entries[CHART_ENTRY_COUNT].new_entry = 1;    /* sort algorithm is stable so first sort levels then score */    chart_sort( chart, SORT_BY_LEVEL );    chart_sort( chart, SORT_BY_SCORE );}/*====================================================================Sort chart with stable algorithm (bubble sort's ok) by wantedvalue.====================================================================*/void chart_swap( Chart_Entry *entry1, Chart_Entry *entry2 ){    Chart_Entry dummy;    dummy = *entry1;    *entry1 = *entry2;    *entry2 = dummy;}void chart_sort( Set_Chart *chart, int type ){    int j;    int changed = 0;    /* use entry dummy as well so count is CHART_ENTRY_COUNT + 1 */    do {        changed = 0;        for ( j = 0; j < CHART_ENTRY_COUNT; j++ )            switch ( type ) {                case SORT_BY_LEVEL:                    if ( chart->entries[j].level < chart->entries[j + 1].level ) {                        chart_swap( &chart->entries[j], &chart->entries[j + 1] );                        changed = 1;                    }                    break;                case SORT_BY_SCORE:                    if ( chart->entries[j].score < chart->entries[j + 1].score ) {                        chart_swap( &chart->entries[j], &chart->entries[j + 1] );                        changed = 1;                    }                    break;            }    } while ( changed );}/*====================================================================Draw highscores centered in regio x,y,w,h====================================================================*/void chart_show( Set_Chart *chart, int x, int y, int w, int h ){    char number_buffer[24];    int entry_offset; /* y offset of entries */    Font *font;    int i;    /* adjust x,y so it's centered */    x += ( w - chart_w ) / 2;    y += ( h - chart_h ) / 2;	/* title = name of levelset */    ccfont->align = ALIGN_X_CENTER | ALIGN_Y_TOP;    write_text( ccfont, sdl.screen, x + ( chart_w >> 1 ), y,  chart->name, OPAQUE );	/* caption */    ccfont->align = ALIGN_X_LEFT | ALIGN_Y_TOP;    write_text( ccfont, sdl.screen, x, y + ccfont->height + chart_gap, cheader, OPAQUE );    /* get entry offset */    entry_offset = ( ccfont->height + chart_gap ) * 2 + y;    /* entries */    for ( i = 0; i < CHART_ENTRY_COUNT; i++ ) {        font = cfont;        if ( chart->entries[i].new_entry ) font = chfont;        /* name */        font->align = ALIGN_X_LEFT | ALIGN_Y_TOP;        write_text( font, sdl.screen, x, entry_offset, chart->entries[i].name, OPAQUE );        /* level */        font->align = ALIGN_X_CENTER | ALIGN_Y_TOP;        sprintf( number_buffer, "%i", chart->entries[i].level );        write_text( font, sdl.screen, x + chart_level_offset, entry_offset, number_buffer, OPAQUE );        /* score */        font->align = ALIGN_X_RIGHT | ALIGN_Y_TOP;        sprintf( number_buffer, "%.0f", chart->entries[i].score );        write_text( font, sdl.screen, x + chart_w, entry_offset, number_buffer, OPAQUE );        /* change offset */        entry_offset += font->height;    }    add_refresh_rect( x, y, chart_w, chart_h );}/*====================================================================Clear all new_entry flags (done before new players are addedto chart when game over).====================================================================*/void chart_clear_new_entries(){    int i;    Set_Chart *chart;    list_reset( charts );    while ( ( chart = list_next( charts ) ) != 0 ) {        chart->entries[CHART_ENTRY_COUNT].score = chart->entries[CHART_ENTRY_COUNT].level = 0;        for ( i = 0; i < CHART_ENTRY_COUNT + 1; i++ )             chart->entries[i].new_entry = 0;    }}/*====================================================================Query set chart by this name or if not found create a new oneby this name.====================================================================*/Set_Chart* chart_set_query( char *name ){	Set_Chart *chart = 0;	list_reset( charts );	while ( ( chart = list_next( charts ) ) != 0 )		if ( strequal( name, chart->name ) )			return chart;	/* not found so create it */	fprintf( stderr, "First chart query for '%s'. Creating this chart.\n", name );	chart = chart_set_create( name );	list_add( charts, chart );	return chart;}/*====================================================================Query chart by id. If id is invalid return 0.====================================================================*/Set_Chart* chart_set_query_id( int id ){	if ( id >= charts->count ) {		fprintf( stderr, "Chart index '%i' is out of range!\n", id );		return 0;	}	return (Set_Chart*)list_get( charts, id );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -