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

📄 hiscore.cpp

📁 蕃茄炸弹超人[ACT]I ve no Tomatoes 开放原始码
💻 CPP
字号:
/*************************************************************************

                         "I Have No Tomatoes"
                  Copyright (c) 2004, Mika Halttunen

 This software is provided 'as-is', without any express or implied
 warranty. In no event will the authors be held liable for any damages
 arising from the use of this software.

 Permission is granted to anyone to use this software for any purpose,
 including commercial applications, and to alter it and redistribute
 it freely, subject to the following restrictions:

    1. The origin of this software must not be misrepresented; you must
    not claim that you wrote the original software. If you use this
    software in a product, an acknowledgment in the product documentation
    would be appreciated but is not required.

    2. Altered source versions must be plainly marked as such, and must
    not be misrepresented as being the original software.

    3. This notice may not be removed or altered from any source
    distribution.


 Mika Halttunen <lsoft@mbnet.fi>

*************************************************************************/

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "SDL.h"
#include "SDL_opengl.h"
#include "init.h"
#include "font.h"
#include "game.h"
#include "mymath.h"
#include "soundmusic.h"
#include "texture.h"
#include "hiscore.h"
#include "menu.h"
#include "timer.h"
#include "screenshot.h"

#ifndef WIN32#include <string>using namespace std;#endif

// Hiscore lists
HISCORE_LIST hiscore_1;
HISCORE_LIST hiscore_2;


// Fading stuff (from game.cpp)
// Are we fading? (0 == no, 1 == fade in, 2 == fade out)
extern int fading;
extern float fade_amount;


#ifndef WIN32// Helper function from config.cppstring get_tomatoes_dir();#endif// Helper function which returns suitable path for the// hiscore file. It first checks the user's home directory,// and if that fails it uses the HISCORE_DIR defined in the// makefile.char *get_hiscore_location(int which, bool write) {#ifndef WIN32	// Get the path to the hiscore file
	string tmp;
	if(which == 1)
		tmp = get_tomatoes_dir() + HISCORE_FILE;
	else
		tmp = get_tomatoes_dir() + HISCORE_FILE2;
	// Check if the hiscore file exists there	if(!write) {		FILE *ftest = fopen(tmp.c_str(), "rb");		if(!ftest) {			// It doesn't exist, try the default
			if(which == 1)
				return (HISCORE_DIR HISCORE_FILE);
			else
				return (HISCORE_DIR HISCORE_FILE2);		}		fclose(ftest);	}	return (char*)tmp.c_str();#endif	// Return the HISCORE_DIR	if(which == 1)
		return (HISCORE_DIR HISCORE_FILE);
	else
		return (HISCORE_DIR HISCORE_FILE2);}

// From game.cpp
bool handle_event(SDL_Event &event);
// Input name and update the listvoid HISCORE_LIST::input_name(int place) {	// We modify directly the list's names[place] entry	memset(list[place].name, 0, sizeof(list[place].name));
	char *str = list[place].name;	// Current position in string	int pos = 0;	bool typed = false;	int cursor_blink = 0;
	back_anim = 0.0f;
	bx_roll = RANDF(0,1);
	by_roll = RANDF(0,1);
	bx_roll_dir = RANDF(-0.001f,0.001f);
	by_roll_dir = RANDF(-0.001f,0.001f);
	memset(key, 0, sizeof(key));

	// Fade in
	fading = 1;
	fade_amount = 1.0f;
	SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);	// Loop	timer_count = 0;	bool done = false;	while(!done) {		while(timer_count > 0) {			// Handle events			SDL_Event event;			while(SDL_PollEvent(&event)) {				done = handle_event(event);		// from 'game.cpp'			}			// If the current music has finished, start playing another
			check_music_finished();

			// Fade
			if(fading) {
				if(fading == 1) {
					// Fade in
					fade_amount -= 0.01f;
					if(fade_amount <= 0.0f) {
						fading = 0;
						fade_amount = 0.0f;
					}
				}
				else if(fading == 2) {
					// Fade out
					fade_amount += 0.01f;
					if(fade_amount >= 1.0f) {
						fading = 0;
						fade_amount = 1.0f;
						done = true;
					}
				}
			}

			// Take a screenshot?			if(key[SDLK_F12])				save_screenshot();			// Blink			cursor_blink++;			cursor_blink %= 20;			// Get the keyboard modifiers			SDLMod keymods = SDL_GetModState();			// Check input			typed = true;			if(key[SDLK_0])				str[pos] = '0';			else if(key[SDLK_EXCLAIM] || ((keymods & KMOD_SHIFT) && key[SDLK_1]))				str[pos] = '!';			else if(key[SDLK_1])				str[pos] = '1';			else if(key[SDLK_2])				str[pos] = '2';			else if(key[SDLK_3])				str[pos] = '3';			else if(key[SDLK_4])				str[pos] = '4';			else if(key[SDLK_5])				str[pos] = '5';			else if(key[SDLK_6])				str[pos] = '6';			else if(key[SDLK_7])				str[pos] = '7';			else if(key[SDLK_8])				str[pos] = '8';			else if(key[SDLK_9])				str[pos] = '9';			else if(key[SDLK_a])				str[pos] = 'A';			else if(key[SDLK_b])				str[pos] = 'B';			else if(key[SDLK_c])				str[pos] = 'C';			else if(key[SDLK_d])				str[pos] = 'D';			else if(key[SDLK_e])				str[pos] = 'E';			else if(key[SDLK_f])				str[pos] = 'F';			else if(key[SDLK_g])				str[pos] = 'G';			else if(key[SDLK_h])				str[pos] = 'H';			else if(key[SDLK_i])				str[pos] = 'I';			else if(key[SDLK_j])				str[pos] = 'J';			else if(key[SDLK_k])				str[pos] = 'K';			else if(key[SDLK_l])				str[pos] = 'L';			else if(key[SDLK_m])				str[pos] = 'M';			else if(key[SDLK_n])				str[pos] = 'N';			else if(key[SDLK_o])				str[pos] = 'O';			else if(key[SDLK_p])				str[pos] = 'P';			else if(key[SDLK_q])				str[pos] = 'Q';			else if(key[SDLK_r])				str[pos] = 'R';			else if(key[SDLK_s])				str[pos] = 'S';			else if(key[SDLK_t])				str[pos] = 'T';			else if(key[SDLK_u])				str[pos] = 'U';			else if(key[SDLK_v])				str[pos] = 'V';			else if(key[SDLK_w])				str[pos] = 'W';			else if(key[SDLK_x])				str[pos] = 'X';			else if(key[SDLK_y])				str[pos] = 'Y';			else if(key[SDLK_z])				str[pos] = 'Z';			else if(key[SDLK_COMMA])				str[pos] = ',';			else if(key[SDLK_PERIOD])				str[pos] = '.';			else if(key[SDLK_KP_MINUS] || key[SDLK_MINUS])				str[pos] = '-';			else if(key[SDLK_SPACE])				str[pos] = ' ';			else if(key[SDLK_BACKSPACE]) {
				play_sound(SND_MENU1, false);				typed = false;				str[pos] = '\0';				pos--;				if(pos < 0)					pos = 0;				str[pos] = '\0';			}			else if(key[SDLK_RETURN] && pos > 0 && str[0] != ' ') {				fading = 2;				typed = false;			}			else {				typed = false;			}			// Clear the key array			memset(key, 0, sizeof(key));

			// Animate the background
			back_anim = add_angle(back_anim, 2.0f);
			bx_roll += bx_roll_dir;
			if(bx_roll > 1.0f)
				bx_roll -= 1.0f;
			else if(bx_roll < 0.0f)
				bx_roll += 1.0f;

			by_roll += by_roll_dir;
			if(by_roll > 1.0f)
				by_roll -= 1.0f;
			else if(by_roll < 0.0f)
				by_roll += 1.0f;

			// Modify string			if(typed) {				play_sound(SND_MENU1, false);				pos++;				if(pos > NAME_LEN-1)					pos = NAME_LEN-1;				str[pos] = '\0';				typed = false;			}			timer_count--;		}
		// Draw the menu (with the list)
		draw_menu(-1, -1, place, fade_amount, this);
		begin_fonts();
		// Draw the cursor		float c = 1 - fade_amount;
		if(cursor_blink < 10 && fading != 2 && !done) {
			glLoadIdentity();
			set_font_scale(0.6f, 0.6f);
			glTranslatef(-3.7f + glfont_length(str) + 0.15f, 2.2f - place * 0.7f, -13);
			glColor3f(c,c,c);
			glBegin(GL_TRIANGLE_STRIP);
				glVertex2f(0.3f, 0.6f);
				glVertex2f(0.0f, 0.6f);
				glVertex2f(0.3f, 0.0f);
				glVertex2f(0.0f, 0.0f);
			glEnd();
		}

		// Draw the congratulations message
		set_font_scale(1,1);
		glLoadIdentity();
		glColor3f(c,c,c);
		glEnable(GL_BLEND);
		glprintf_center(font1, 0, 0, -4.5f, -13, "CONGRATULATIONS");

		end_fonts();		// Flush and swap the buffers
		glFlush();
		SDL_GL_SwapBuffers();
	}	SDL_EnableKeyRepeat(0,0);}

// Draw the list. Hilights the 'place'.
void HISCORE_LIST::draw(int place, float fade) {
	float ypos = 2.2f;

	set_font_scale(0.8f,0.7f);
	glColor4f(0.1f,1,1, fade);
	glprintf_center(font1, 0, 0, 3.05f, -13, "%s", ((this == &hiscore_1) ? "SINGLE PLAYER HIGH SCORES" : "TWO PLAYERS HIGH SCORES"));

	set_font_scale(0.6f, 0.6f);

	for(int f=0; f<NUM_NAMES; f++) {
		float a = (float)f / (float)NUM_NAMES;
		a = 1.0f - (a * 0.4f);

		// Draw the number
		if(place != f)
			glColor4f(a,a,0.8f*a, fade);
		else
			glColor4f(1,1,0.8f, fade);
		glprintf(font1, 0, -5.0f, ypos, -13, "%2d.", f+1);

		// Draw the name
		if(place != f)
			glColor4f(a,a,a, fade);
		else
			glColor4f(1,1,1, fade);
		glprintf(font1, 0, -3.7f, ypos, -13, "%s", list[f].name);

		// Draw the score
		if(place != f)
			glColor4f(0.8f*a,a,0.8f*a, fade);
		else
			glColor4f(0.8f,1,0.8f, fade);
		glprintf(font1, 0, 3.4f, ypos, -13, "%03d", list[f].score);

		// Draw the hilight bar
		if(place == f) {
			glColor4f(0.2f, 0.2f, 0.2f, fade);
			glBlendFunc(GL_SRC_ALPHA, GL_ONE);
			BIND_TEXTURE(0);
			glBegin(GL_TRIANGLE_STRIP);
				glVertex3f(4.7f, ypos + 0.65f, -13);
				glVertex3f(-4.7f, ypos + 0.65f, -13);
				glVertex3f(4.7f, ypos - 0.05f, -13);
				glVertex3f(-4.7f, ypos - 0.05f, -13);
			glEnd();
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		}

		ypos -= 0.7f;
	}

	set_font_scale(1,1);
}


// Save the list to a file
void HISCORE_LIST::save(char *file) {
	FILE *fout;
	fout = fopen(file, "wb");
	if(!fout)
		error_msg("Unable to save the hiscore list to %s!\n", file);

	// Write the scores
	int f;
	for(f=0; f<NUM_NAMES; f++)
		fwrite(&list[f].score, sizeof(int), 1, fout);

	// Write the names
	for(f=0; f<NUM_NAMES; f++)
		fwrite(list[f].name, NAME_LEN, 1, fout);

	fclose(fout);
}


// Load the list from a file
void HISCORE_LIST::load(char *file) {
	FILE *fin;
	fin = fopen(file, "rb");
	if(!fin) {
		// The list wasn't found, no problem.
		clear();
		return;
	}

	// Read the scores
	int f;
	for(f=0; f<NUM_NAMES; f++)
		fread(&list[f].score, sizeof(int), 1, fin);

	// Read the names
	for(f=0; f<NUM_NAMES; f++)
		fread(list[f].name, NAME_LEN, 1, fin);

	fclose(fin);
}


// Add a name to the list. Returns the place.
int HISCORE_LIST::add_name(char *name, int score) {
	// Check if we qualify
	if(list[NUM_NAMES-1].score >= score)
		return -1;

	// Replace the last entry
	memset(list[NUM_NAMES-1].name, 0, sizeof(list[NUM_NAMES-1].name));
	strcpy(list[NUM_NAMES-1].name, name);
	list[NUM_NAMES-1].score = score;

	// Sort
	sort();

	// Find ourselves and return the place
	for(int f=NUM_NAMES-1; f >= 0; f--)
		if(strcmp(name, list[f].name) == 0 && score == list[f].score)
			return f;

	// This shouldn't happen..
	return -1;
}


// Comparison function for qsort
int sort_cmp(const void *a, const void *b) {
	RECORD ra = *(RECORD*)a;
	RECORD rb = *(RECORD*)b;

	// Sort by the score
	if(ra.score < rb.score)
		return 1;
	else if(ra.score > rb.score)
		return -1;

	// The scores are same, sort by the name
	return strcmp(ra.name, rb.name);
}


// Sort the list using qsort
void HISCORE_LIST::sort() {
	qsort(list, NUM_NAMES, sizeof(RECORD), sort_cmp);
}


// Clear the list
void HISCORE_LIST::clear() {
	for(int f=0; f<NUM_NAMES; f++) {
		memset(list[f].name, 0, sizeof(list[f].name));
		strcpy(list[f].name, "- - - - - - - - - -");
		list[f].score = 0;
	}
}

⌨️ 快捷键说明

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