예제 #1
0
void hud_print_time(
	program_state_t* PS,
	int x,
	int y,
	alignment_t alignment,
	int color,
	microtime_t micros
	)
{
	bool_t dot_visible = (PS->current_time_us % 1000000 < 800000);
	int ms = micros / 1000;
	int sec = ms / 1000;
	int min = sec / 60;
	sec -= 60 * min;
	char* s;

	// Format time to string with blinking colon
	asprintf(
		&s,
		(dot_visible) ? "T=%02d:%02d.%d" : "T=%02d %02d.%d",
		min,
		sec,
		(ms % 1000) / 100
	);

	hud_printf( PS, x, y, alignment, color, s );
	free( s );
}
예제 #2
0
파일: intro.c 프로젝트: jaeh/may_first
void draw_overlay( program_state_t* PS )
{
	int w = PS->window_width;
	int h = PS->window_height;
	microtime_t T = PS->current_time_us;

	GLfloat R, G, B;

	glViewport( 0, 0, w, h );		// Using screen coordinates

	glMatrixMode( GL_PROJECTION );		// Setup 2D mode
	glLoadIdentity();
	gluOrtho2D( 0, w, 0, h );

	glMatrixMode( GL_MODELVIEW );
	glDisable( GL_DEPTH_TEST );
	glLoadIdentity();

	color_from_hue( (T % 6000000) / 6000000.0, &R, &G, &B );
	glColor3f( R, G, B );

	glLineWidth( 2 );
	glBegin( GL_LINES );
		glVertex2i( 0, 2*h/3 );
		glVertex2i( w, 2*h/3 );
	glEnd();
	glLineWidth( 1 );

	hud_printf( PS,
		w/2,
		2*h/3 + PS->line_height/2,
		ALIGN_CENTER,
		0xFFFFFF,
		PROGRAM_NAME
	);

	hud_printf( PS,
		w/2,
		2*h/3 - 3*PS->line_height/2,
		ALIGN_CENTER,
		0x888888,
		PROGRAM_VERSION
	);
}
예제 #3
0
/* get_weapon_color()
 * Returns two colors (enabled/disabled) for rendering the weapon status.
 * If blinking is indicated for the weapon, the returned colors will be bright
 * "blink colors" for a certain fraction in a looping time interval.
 */
void hud_weapon_state(
	program_state_t* PS,
	game_state_t* GS,
	int weapon_nr,
	char* caption,
	int x,
	int y
	)
{
	int color_enabled;
	int color_disabled;

	weapon_t* wpn = &(GS->ship.weapons[weapon_nr]);

	microtime_t elapsed_time
		= PS->current_time_us
		- wpn->blink_start_us
	;

	bool_t highlight
		= (elapsed_time % HUD_BLINK_SPEED > 2*HUD_BLINK_SPEED/3 )
	;

	if (wpn->blink_until_us > PS->current_time_us) {

		color_enabled
			= highlight
			? COLOR_ENABLED_LO
			: COLOR_BLINK_HI
		;

		color_disabled
			= highlight
			? COLOR_DISABLED_LO
			: COLOR_BLINK_HI
		;
	} else {
		color_enabled  = COLOR_ENABLED_HI;
		color_disabled = COLOR_DISABLED_HI;
	}

	hud_printf(
		PS,
		x, y,
		ALIGN_LEFT,
		(wpn->enabled ? color_enabled : color_disabled ),
		caption
	);
}
예제 #4
0
void debug_times(
	program_state_t* PS,
	char* format_string,
	microtime_t us,
	int* line_count
	)
{
	hud_printf(
		PS,
		PS->line_height,
		PS->line_height * (*line_count)++,
		(ALIGN_LEFT | ALIGN_MIDDLE),
		COLOR_TEXT_LO,
		format_string,
		us
	);
}
예제 #5
0
void draw_debug( program_state_t* PS, game_state_t* GS )
{
#if DEBUG

	int w = PS->window_width;
	int h = PS->window_height;

	int line_count = 3;

	setup_gl_2D( w, h );

#if DEBUG_MEMORY
	struct mallinfo mi = mallinfo();

	hud_printf(
		PS,
		PS->line_height,
		PS->line_height*line_count++,
		ALIGN_LEFT | ALIGN_MIDDLE,
		COLOR_TEXT_LO,
		"Mem: uordblks(%d) delta(%d)",
		(int) mi.uordblks,
		(int) (PS->initial_TAS - mi.uordblks)
	);

	if (PS->initial_TAS == -1) {
		PS->initial_TAS = mi.uordblks;
	}
#endif

	hud_printf(
		PS,
		PS->line_height,
		PS->line_height*line_count++,
		ALIGN_LEFT | ALIGN_MIDDLE,
		COLOR_TEXT_LO,
		"Tframe(%.3fms) F/s(%.3f)",
		PS->average_frame_time / 1000.0,
		1000000.0 / PS->average_frame_time
	);

#if DEBUG_TIMES
	debug_times(
		PS, "highest_frame_time = %lld",
		PS->highest_frame_time, &line_count
	);
	debug_times(
		PS, "lowest_frame_time  = %lld",
		PS->lowest_frame_time, &line_count
	);
	debug_times(
		PS, "pause_since_us  = %lld",
		PS->pause_since_us - PS->program_start_us, &line_count
	);
	debug_times(
		PS, "current_time_us = %lld",
		PS->current_time_us - PS->program_start_us, &line_count
	);
	debug_times(
		PS, "game_time_us = %lld",
		PS->game_time_us, &line_count
	);
	debug_times(
		PS, "game_start_us   = %lld",
		PS->game_start_us - PS->program_start_us, &line_count
	);
#endif

#if DEBUG_SHIP
	hud_printf(
		PS,
		PS->line_height,
		PS->line_height*line_count++,
		ALIGN_LEFT | ALIGN_MIDDLE,
		COLOR_TEXT_LO,
		"ship.position = ( %g | %g | %g )",
		GS->ship.position.x,
		GS->ship.position.y,
		GS->ship.position.z
	);

	hud_printf(
		PS,
		PS->line_height,
		PS->line_height*line_count++,
		ALIGN_LEFT | ALIGN_MIDDLE,
		COLOR_TEXT_LO,
		"ship.velocity = ( %g | %g | %g )",
		GS->ship.velocity.x,
		GS->ship.velocity.y,
		GS->ship.velocity.z
	);

	hud_printf(
		PS,
		PS->line_height,
		PS->line_height*line_count++,
		ALIGN_LEFT | ALIGN_MIDDLE,
		COLOR_TEXT_LO,
		"camera_speed_pitch(%f) ",
		GS->ship.camera_speed_pitch
	);
#endif

#if DEBUG_GAME_STATISTICS
	hud_printf(
		PS,
		PS->line_height,
		PS->line_height*line_count++,
		ALIGN_LEFT | ALIGN_MIDDLE,
		COLOR_TEXT_LO,
		"En Route(%d) Fired(%d) Missed(%d)",
		GS->shots_en_route,
		GS->shots_fired,
		GS->shots_missed
	);

	hud_printf(
		PS,
		PS->line_height,
		PS->line_height*line_count++,
		ALIGN_LEFT | ALIGN_MIDDLE,
		COLOR_TEXT_LO,
		"Lsr(%d) Enm(%d %d %d %d) Xpl(%d) BBl(%d %d %d %d)",
		GS->nr_active_lasers,
		GS->nr_active_enemies[0],
		GS->nr_active_enemies[1],
		GS->nr_active_enemies[2],
		GS->nr_active_enemies[3],
		GS->nr_active_explosions,
		GS->nr_active_bonus_bubbles[0],
		GS->nr_active_bonus_bubbles[1],
		GS->nr_active_bonus_bubbles[2],
		GS->nr_active_bonus_bubbles[3]
	);

	calculate_total_score( PS, GS );
	hud_printf(
		PS,
		PS->line_height,
		PS->line_height*line_count++,
		ALIGN_LEFT | ALIGN_MIDDLE,
		COLOR_TEXT_LO,
		"Speed bonus: %d",
		GS->score.speed
	);

	hud_printf(
		PS,
		PS->line_height,
		PS->line_height*line_count++,
		ALIGN_LEFT | ALIGN_MIDDLE,
		COLOR_TEXT_LO,
		"nr_active_enemies(%d)",
		GS->nr_active_enemies_total
	);

	hud_printf(
		PS,
		PS->line_height,
		PS->line_height*line_count++,
		ALIGN_LEFT | ALIGN_MIDDLE,
		COLOR_TEXT_LO,
		"add_enemy_beyond_y(%.2f) distance(%.2f)",
		GS->add_enemy_beyond_y,
		GS->ship.position.y - GS->add_enemy_beyond_y
	);
#endif

	hud_printf(
		PS,
		PS->line_height,
		PS->line_height*line_count++,
		ALIGN_LEFT | ALIGN_MIDDLE,
		COLOR_TEXT_LO,
		"%s %s",
		PROGRAM_NAME,
		PROGRAM_VERSION
	);
#endif
}
예제 #6
0
/* draw_hud()
 * Main HUD rendering function, calculates some statistics needed only for
 * the display
 */
void draw_hud( program_state_t* PS, game_state_t* GS )
{
	int w = PS->window_width;
	int h = PS->window_height;

	setup_gl_2D( w, h );

	hud_draw_level_nr( PS, GS );

	draw_hud_panel_background( PS, ALIGN_TOP );


	/* TIME, HIT RATIO, SCORE */

	hud_print_time(
		PS,
		1*PS->line_height,
		h - 3*PS->line_height/2,
		ALIGN_LEFT,
		COLOR_TEXT_LO,
		PS->game_time_us
	);
	hud_printf(
		PS,
		7*PS->line_height,
		h - 3*PS->line_height/2,
		ALIGN_LEFT,
		COLOR_TEXT_LO,
		"HR:%.0f%%",
		calculate_hit_ratio(GS) * 100.0
	);
	hud_printf(
		PS,
		11.5*PS->line_height,
		h - 3*PS->line_height/2,
		ALIGN_LEFT,
		COLOR_TEXT_HI,
		"SCORE:%d",
		GS->score.current
	);


	/* WEAPON STATE */

	hud_weapon_state(
		PS, GS, WEAPON_LASER_1, "[LSR]",
		w - 12 * PS->line_height,
		h - 3*PS->line_height/2
	);
	hud_weapon_state(
		PS, GS, WEAPON_LASER_2, "[DBL]",
		w - 9 * PS->line_height,
		h - 3*PS->line_height/2
	);
	hud_weapon_state(
		PS, GS, WEAPON_ROUNDSHOT, "[RSH]",
		w - 6 * PS->line_height,
		h - 3*PS->line_height/2
	);
	hud_weapon_state(
		PS, GS, WEAPON_AUTOFIRE, "[AF] ",
		w - 3 * PS->line_height,
		h - 3*PS->line_height/2
	);


	/* RESOURCE */

	draw_hud_resource( PS, GS );


	/* ENEMIES */

	hud_current_enemies( PS, GS );


	/* BOTTOM MENU (MAIN MENU, PAUSE) */

	if (PS->run_mode & (RM_PAUSE | RM_MAIN_MENU)) {

		draw_hud_panel_background( PS, ALIGN_BOTTOM );

		hud_printf(
			PS,
			w/2,
			PS->line_height/2,
			ALIGN_CENTER,
			0xFFFFFF,

			(PS->run_mode == RM_PAUSE)
			? "PAUSE - Press [RETURN] to continue, [ESC] to exit the game."
			: "Press [RETURN] to start a new game, [ESC] to exit the game."
		);
	}


	/* AFTER LIFE SCORE */

	if (PS->run_mode & (RM_MAIN_MENU | RM_PAUSE)) {

		hud_score_summary( PS, GS );
	}
}
예제 #7
0
/* hud_score_summary()
 * Display a detailed explanation how score was calculated.
 * Details need to be manually adjusted the algorithm in
 * game.c: calculate_total_score()
 */
void hud_score_summary( program_state_t* PS, game_state_t* GS )
{
	int w = PS->window_width;
	int h = PS->window_height;
	int x = w/2;
	int y = 3*h/5;
	int i = 6;                // Initial upwards offset, half of text shown

	int score         = GS->score.current;
	int total_score   = calculate_total_score( PS, GS );
	//...int s_elapsed = PS->game_time_us / 1000000.0;

	score_info_t* si = &(GS->score);


	hud_printf(
		PS,
		x,
		y + (i--) * (PS->line_height),
		ALIGN_CENTER, 0xAAAAAA,
		"SCORE                               %7d",
		score
	);
#ifdef DISABLED_CODE
	hud_printf(
		PS,
		x,
		y + (i--) * (PS->line_height),
		ALIGN_CENTER, 0xAAAAAA,
		"DISTANCE       %7d  x%7d  = %7d",
		si->distance,
		BONUS_FACTOR_DISTANCE,
		BONUS_FACTOR_DISTANCE * si->distance
	);

	hud_printf(
		PS,
		x,
		y + (i--) * (PS->line_height),
		ALIGN_CENTER, 0xAAAAAA,
		"FRENZY    %5d /%5d  * %6d  = %7d",
		GS->enemies_killed,
		si->distance,
		BONUS_FACTOR_ENEMIES,
		BONUS_FACTOR_ENEMIES * GS->enemies_killed /
			( (si->distance == 0) ? 1 : si->distance )
	);
#endif
	--i;   // Omit one line

	hud_printf(
		PS,
		x,
		y + (i--) * (PS->line_height),
		ALIGN_CENTER, 0xAAAAAA,
		"HIT RATIO     %7d%%  x%7d  = %7d",
		si->hit_ratio,
		score,
		score * si->hit_ratio/100
	);

	hud_printf(
		PS,
		x,
		y + (i--) * (PS->line_height),
		ALIGN_CENTER, 0xAAAAAA,
		"SPEED BONUS   %7d%%  x%7d  = %7d",
		si->speed,
		score,
		score * si->speed/100
	);

	hud_printf(
		PS,
		x,
		y + (i--) * (PS->line_height),
		ALIGN_CENTER, 0xAAAAAA,
		"ENERGY MAXIMUM %7d  x%7d  = %7d",
		si->best_resource,
		BONUS_FACTOR_BEST_RESOURCE,
		BONUS_FACTOR_BEST_RESOURCE * si->best_resource
	);

	--i;   // Omit one line


	hud_printf(
		PS,
		x,
		y + (i--) * (PS->line_height),
		ALIGN_CENTER, 0xFFFFFF,
		"                             TOTAL: %7d",
		total_score
	);

	--i;   // Omit one line

	hud_printf(
		PS,
		x,
		y + (i--) * (PS->line_height),
		ALIGN_CENTER, 0xAAAAAA,
		( total_score > GS->score.high_score ? "High Score!" : "High Score: %d (Wave %d)" ),
		GS->score.high_score,
		GS->score.high_score_level
	);
}
예제 #8
0
void draw_hud_resource( program_state_t* PS, game_state_t* GS )
{
	int	i, j;
	real_t	x, y;
	GLfloat	R, G, B;

	real_t	bar_width, step_size;
	real_t	resource;
	int	resource_color;
	int	hit_points = calculate_hit_points( GS->current_resource );

	microtime_t Tc = PS->current_time_us;

	int w = PS->window_width;
	int h = PS->window_height;

	// In cheat mode, after the numbers are output as digits, ..
	// ..we use an adjusted Resource value to get a nice bar size
	resource
		= GS->current_resource
#if CHEAT_MODE
		/ CHEAT_RESOURCE_FACTOR
#endif
	;


	/* CALCULATE BASE COLOR indicating level of resource */

	color_from_hue(
		// The following ratio is manually tweaked to give nice..
		// ..results up to 10K. Perhaps using log2 would be better?
		fmin( 1.0, sqrt(GS->current_resource) / 100.0 ),
		&R, &G, &B
	);

	resource_color                          // Pack the float values into..
		= ((int)(R * 255) << 16)        // ..a handy int.
		+ ((int)(G * 255) << 8)
		+ ((int)(B * 255) << 0)
	;


	/* RENDER RESOURCE as TEXT (ALIGN_TOP Panel) */

	hud_printf(
		PS,
		PS->window_width/2,
		h - 3*PS->line_height/2,
		ALIGN_CENTER,
		resource_color,
		"ENERGY: %d (%d)",
		GS->current_resource,
		GS->best_resource
	);

	/* CALCULATE BLINK COLOR */

	// From here on, everything rendered might be blinking

	if (resource >= 200) {
		/* Reuse R, G and B from above, no change needed */
	} else {
		if      (resource < 50)   i = 150000;
		else if (resource < 100)  i = 225000;
		else if (resource < 150)  i = 350000;
		else {                    i = 500000;
		}

		GLfloat f = fabs((int)(Tc % i) - i/2) / ((GLfloat)i/2);
		R = R * f;
		G = G * f;
		B = B * f;

		// Additionally blink white, when Resource critically low
		if ((resource < 50) && (Tc % 150000 < 50000)) {
			R = G = B = 1.0;
		}
	}
	resource_color                          // Pack the float values into..
		= ((int)(R * 255) << 16)        // ..a handy int.
		+ ((int)(G * 255) << 8)
		+ ((int)(B * 255) << 0)
	;


	/* RESOURCE BAR */

	// Calculate size of the bar
	bar_width = sqrt(resource) * 10.0;   //... Perhaps we should use log2 ?
	step_size = round( bar_width / hit_points );

	glBegin( GL_LINES );
	glColor3f( R, G, B );

	for( i = 0 ; i < 5 ; i++ ) {
		for( j = 0 ; j < hit_points ; j++ ) {

			x = (w - bar_width)/2 + (real_t)j * step_size;
			y = h - 3*PS->line_height + i*2;

			glVertex2i( x + 1.0,             y );
			glVertex2i( x - 1.0 + step_size, y );
		}
	}
	glEnd();

	hud_printf(
		PS,
		PS->window_width/2,
		h - 9*PS->line_height/2,
		ALIGN_CENTER,
		resource_color,
		"%d",
		hit_points
	);
}
예제 #9
0
void hud_draw_level_nr( program_state_t* PS, game_state_t* GS )
{
	const int w = LEVEL_QUAD_WIDTH;
	const int h = LEVEL_QUAD_HEIGHT;
	const int y = LEVEL_OFFSET_Y;

	int number;
	GLfloat digit_x;
	bool_t draw_zero;

	int quad_x  = LEVEL_OFFSET_X - LEVEL_QUAD_WIDTH/2;


	number = GS->current_level;
	draw_zero = (number == 0);
	while (number > 9) {
		quad_x += LEVEL_QUAD_WIDTH/2;
		number /= 10;
	}
	number = GS->current_level;

	glEnable( GL_BLEND );
	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

	glEnable( GL_TEXTURE_2D );
	glBindTexture( GL_TEXTURE_2D, PS->textures.digits );

	glBegin( GL_QUADS );
	glColor4f( 1,1,1, 0.5 );
	                                // more centered vertically.
	while (number || draw_zero) {
		digit_x = ((number % 10) / 10.0);
		draw_zero = FALSE;      // Only draw the zero once

		glTexCoord2f( digit_x,     1 );  glVertex2i( quad_x,   y-h/2 );
		glTexCoord2f( digit_x+0.1, 1 );  glVertex2i( quad_x+w, y-h/2 );
		glTexCoord2f( digit_x+0.1, 0 );  glVertex2i( quad_x+w, y+h/2 );
		glTexCoord2f( digit_x,     0 );  glVertex2i( quad_x,   y+h/2 );

		quad_x -= LEVEL_QUAD_WIDTH;
		number /= 10;
	}
	glEnd();

	glDisable( GL_TEXTURE_2D );
	glDisable( GL_BLEND );

	hud_printf(
		PS,
		LEVEL_OFFSET_X,
		LEVEL_OFFSET_Y - LEVEL_QUAD_HEIGHT - PS->line_height/2,
		ALIGN_CENTER,
		0x808080,
		"WAVE"
	);

	if (GS->show_wave_until_us > PS->current_time_us) {

		int w = PS->window_width;
		int h = PS->window_height;

		real_t fade
			= (real_t)(GS->show_wave_until_us - PS->current_time_us)
			/ NEXT_WAVE_NOTICE_DURATION
		;

		fade = sin( fade * 1.444 );

		int color
			= ( (int)(fade * (real_t)0x44) * 0x10000 )
			+ ( (int)(fade * (real_t)0xAA) * 0x100 )
			+ ( (int)(fade * (real_t)0x11) )
		;

		hud_printf(
			PS,
			w/2, 4*h/6, ALIGN_CENTER, color, "Wave %d",
			GS->current_level
		);
	}
}