示例#1
0
/*
 * @brief render animations
 *
 * @param [in] *ga  animation data
 * @param [in] frametime  how long this frame took
 * @param [in] x  2D screen x co-ordinate to render at
 * @param [in] y  2D screen y co-ordinate to render at
 * @param [in] menu select if this is rendered in menu screen, or fullscreen
 */
void generic_anim_render(generic_anim *ga, float frametime, int x, int y, bool menu, const generic_extras *ge)
{
	if ((ge != nullptr) && (ga->use_hud_color == true)) {
		Warning(LOCATION, "Monochrome generic anims can't use extra info (yet)");
		return;
	}

	float a = 1.0f;
	if (ge != nullptr) {
		a = ge->alpha;
	}
	if (ga->type == BM_TYPE_PNG) {
		generic_anim_render_variable_frame_delay(ga, frametime, a);
	}
	else {
		generic_anim_render_fixed_frame_delay(ga, frametime);
	}

	if(ga->num_frames > 0) {
		ga->previous_frame = ga->current_frame;

		if(ga->use_hud_color) {
			gr_aabitmap(x, y, (menu ? GR_RESIZE_MENU : GR_RESIZE_FULL));
		}
		else {
			if (ge == nullptr) {
				gr_bitmap(x, y, (menu ? GR_RESIZE_MENU : GR_RESIZE_FULL));
			}
			else if (ge->draw == true) {
				// currently only for lua streaminganim objects
				// and don't draw them unless requested...
				gr_bitmap_uv(x, y, ge->width, ge->height, ge->u0, ge->v0, ge->u1, ge->v1, GR_RESIZE_NONE);
			}
		}
	}
}
示例#2
0
void radar_blit_gauge()
{
	gr_set_bitmap(Radar_gauge.first_frame+1, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
	gr_aabitmap( Radar_coords[gr_screen.res][0], Radar_coords[gr_screen.res][1] );
} 
/**
 * @brief This function is called to blit the next frame of an anim instance to the screen.
 * This is normally called by the anim_render_all() function.
 *
 * @param instance Pointer to animation instance
 * @param frametime	Time elapsed since last call, in seconds
 */
int anim_show_next_frame(anim_instance *instance, float frametime)
{
	int	bitmap_id, bitmap_flags=0, new_frame_num, frame_diff=0, i, n_frames=0,frame_save;
	float percent_through, time;
	vertex	image_vertex;
	int aabitmap = 0;
	int bpp = 16;

	Assert( instance != NULL );

	instance->time_elapsed += frametime;

	// Advance to the next frame, if we determine enough time has elapsed.
	if(instance->direction == ANIM_DIRECT_FORWARD)
		n_frames = instance->stop_at - instance->start_at + 1;
	else if(instance->direction == ANIM_DIRECT_REVERSE)
		n_frames = instance->start_at - instance->stop_at + 1;

	time = n_frames / i2fl(instance->parent->fps);

	percent_through = instance->time_elapsed / time;

	if(instance->direction == ANIM_DIRECT_FORWARD)
		new_frame_num = instance->start_at - 1 + fl2i(percent_through * n_frames + 0.5f);
	else
		new_frame_num = instance->start_at - 1 - fl2i(percent_through * n_frames + 0.5f);

	frame_save = instance->frame_num;

	// If framerate independent, use the new_frame_num... unless instance->skip_frames is
	// FALSE, then only advance a maximum of one frame (this is needed since some big animations
	// should just play slower rather than taking the hit of decompressing multiple frames and
	// creating an even greater slowdown	
	if (instance->framerate_independent) {
		if(instance->direction == ANIM_DIRECT_FORWARD){
			if ( new_frame_num > instance->last_frame_num) {
				if ( instance->skip_frames )
					instance->frame_num = new_frame_num;
				else
					instance->frame_num++;
			}
		} else if(instance->direction == ANIM_DIRECT_REVERSE){
			if( new_frame_num < instance->last_frame_num) {
				if ( instance->skip_frames )
					instance->frame_num = new_frame_num;
				else
					instance->frame_num--;
			}
		}
	}
	else {			
		if(instance->direction == ANIM_DIRECT_FORWARD){
			if ( new_frame_num > instance->last_frame_num) {
				instance->frame_num++;
			}
		} else if(instance->direction == ANIM_DIRECT_REVERSE){
			if ( new_frame_num < instance->last_frame_num) {
				instance->frame_num--;
			}
		}			
	}

	if(instance->direction == ANIM_DIRECT_FORWARD){
		if ( instance->frame_num < instance->start_at ) {
			instance->frame_num = instance->start_at;
		}	
	} else if(instance->direction == ANIM_DIRECT_REVERSE){
		if ( instance->frame_num > instance->start_at ) {
			instance->frame_num = instance->start_at;
		}	
	}

	if ( instance->stop_now == TRUE ) {
		return -1;
	}

	// If past the last frame, clamp to the last frame and then set the stop_now flag in the
	// anim instance.  The next iteration, the animation will stop.
	if(instance->direction == ANIM_DIRECT_FORWARD){
		if (instance->frame_num >= instance->stop_at ) {
			if (instance->looped) {										// looped animations
				instance->frame_num = instance->stop_at;
				instance->time_elapsed = 0.0f;
			} else if(instance->ping_pong) {							// pingponged animations
				instance->frame_num = instance->stop_at;
				anim_reverse_direction(instance);
			} else {															// one-shot animations
				instance->frame_num = instance->stop_at;
				instance->last_frame_num = instance->frame_num;
				instance->stop_now = TRUE;
			}
		}
	} else if(instance->direction == ANIM_DIRECT_REVERSE){
		if (instance->frame_num <= instance->stop_at ) {
			if (instance->looped) {										// looped animations
				instance->frame_num = instance->stop_at;
				instance->time_elapsed = 0.0f;
			} else if(instance->ping_pong) {							// pingponged animations
				instance->frame_num = instance->stop_at;
				anim_reverse_direction(instance);
			} else {															// one-shot animations
				instance->frame_num = instance->stop_at+1;
				instance->last_frame_num = instance->frame_num;
				instance->stop_now = TRUE;
			}
		}
	}

	if(instance->direction == ANIM_DIRECT_FORWARD){
		if( instance->last_frame_num >= instance->start_at ) {
			frame_diff = instance->frame_num - instance->last_frame_num;		
		} else {
			frame_diff = 1;
		}
	} else if(instance->direction == ANIM_DIRECT_REVERSE){
		if( instance->last_frame_num <= instance->start_at ) {
			frame_diff = instance->last_frame_num - instance->frame_num;
		} else {
			frame_diff = 1;
		}
	}		
	Assert(frame_diff >= 0);
	Assert( instance->frame_num >= 0 && instance->frame_num < instance->parent->total_frames );

	// if the anim is paused, ignore all the above changes and still display this frame
	if(instance->paused || Anim_paused){
		instance->frame_num = frame_save;
		instance->time_elapsed -= frametime;
		frame_diff = 0;
	}

	if (instance->parent->flags & ANF_XPARENT){
		bitmap_flags = 0;
	} 
	bpp = 16;
	if(instance->aa_color != NULL){
		bitmap_flags |= BMP_AABITMAP;
		aabitmap = 1;
		bpp = 8;
	}	

	if ( frame_diff > 0 ) {
		instance->last_frame_num = instance->frame_num;		

		t1 = timer_get_fixed_seconds();
		for ( i = 0; i < frame_diff; i++ ) {
			anim_check_for_palette_change(instance);			

			// if we're playing backwards, every frame must be a keyframe and we set the data ptr here
			if(instance->direction == ANIM_DIRECT_REVERSE){
				if ( anim_instance_is_streamed(instance) ) {
					instance->file_offset = instance->parent->file_offset + instance->parent->keys[instance->frame_num-1].offset;
				} else {
					instance->data = instance->parent->data + instance->parent->keys[instance->frame_num-1].offset;
				}
			}

			ubyte *temp = NULL;
			int temp_file_offset = -1;			

			// if we're using bitmap polys
			BM_SELECT_TEX_FORMAT();

			if ( anim_instance_is_streamed(instance) ) {
				if ( instance->xlate_pal ){
					temp_file_offset = unpack_frame_from_file(instance, instance->frame, instance->parent->width*instance->parent->height, instance->parent->palette_translation, aabitmap, bpp);
				} else {
					temp_file_offset = unpack_frame_from_file(instance, instance->frame, instance->parent->width*instance->parent->height, NULL, aabitmap, bpp);
				}
			} else {
				if ( instance->xlate_pal ){
					temp = unpack_frame(instance, instance->data, instance->frame, instance->parent->width*instance->parent->height, instance->parent->palette_translation, aabitmap, bpp);
				} else {
					temp = unpack_frame(instance, instance->data, instance->frame, instance->parent->width*instance->parent->height, NULL, aabitmap, bpp);
				}
			}

			// always go back to screen format
			BM_SELECT_SCREEN_FORMAT();

			// see if we had an error during decode (corrupted anim stream)
			if ( (temp == NULL) && (temp_file_offset < 0) ) {
				mprintf(("ANI: Fatal ERROR at frame %i!!  Aborting playback of \"%s\"...\n", instance->frame_num, instance->parent->name));

				// return -1 to end all playing of this anim instanc
				return -1;
			}

			if(instance->direction == ANIM_DIRECT_FORWARD){
				if ( anim_instance_is_streamed(instance) ) {
					instance->file_offset = temp_file_offset;
				} else {
					instance->data = temp;
				}
			}			
		}
		t2 = timer_get_fixed_seconds();
	}
	else {
		t2=t1=0;
	}

	// this only happens when the anim is being looped, we need to reset the last_frame_num
	if ( (instance->time_elapsed == 0) && (instance->looped) ) {
		instance->last_frame_num = -1;
		instance->frame_num = -1;
		instance->data = instance->parent->data;
		instance->file_offset = instance->parent->file_offset;
		instance->loop_count++;
	}

	t1 = timer_get_fixed_seconds();
	if ( frame_diff == 0 && instance->last_bitmap != -1 ) {
		bitmap_id = instance->last_bitmap;
	}
	else {
		if ( instance->last_bitmap != -1 ){
			bm_release(instance->last_bitmap);
		}
		bitmap_id = bm_create(bpp, instance->parent->width, instance->parent->height, instance->frame, bitmap_flags);
	}
	
	if ( bitmap_id == -1 ) {
		// anim has finsished playing, free the instance frame data
		anim_release_render_instance(instance);	
		return -1;

		// NOTE: there is no need to free the instance, since it was pre-allocated as 
		//       part of the anim_free_list
	}
	else {
		gr_set_bitmap(bitmap_id);
		
		// determine x,y to display the bitmap at
		if ( instance->world_pos == NULL ) {
			int old_max_w_unscaled = gr_screen.max_w_unscaled;
			int old_max_h_unscaled = gr_screen.max_h_unscaled;
			int old_max_w_unscaled_zoomed = gr_screen.max_w_unscaled_zoomed;
			int old_max_h_unscaled_zoomed = gr_screen.max_h_unscaled_zoomed;
			gr_set_screen_scale(instance->base_w, instance->base_h);
			gr_set_clip(0, 0, instance->base_w, instance->base_h, GR_RESIZE_MENU);
			if ( instance->aa_color == NULL ) {
				gr_bitmap(instance->x, instance->y, GR_RESIZE_MENU_NO_OFFSET);
			}
			else {
				gr_set_color_fast( (color*)instance->aa_color );
				gr_aabitmap(instance->x, instance->y, GR_RESIZE_MENU_NO_OFFSET);
			}
			gr_set_screen_scale(old_max_w_unscaled, old_max_h_unscaled, old_max_w_unscaled_zoomed, old_max_h_unscaled_zoomed);
			gr_reset_clip();
		}
		else {
			g3_rotate_vertex(&image_vertex,instance->world_pos);
			Assert(instance->radius != 0.0f);
			//g3_draw_bitmap(&image_vertex, 0, instance->radius*1.5f, TMAP_FLAG_TEXTURED | TMAP_HTL_2D);
			material mat_params;
			material_set_unlit(&mat_params, bitmap_id, 1.0f, false, false);
			g3_render_rect_screen_aligned_2d(&mat_params, &image_vertex, 0, instance->radius*1.5f);
		}
									  
		instance->last_bitmap = bitmap_id;
	}

	t2 = timer_get_fixed_seconds();

	return 0;
}
示例#4
0
void radar_blit_gauge_std()
{
	gr_set_bitmap(Radar_gauge.first_frame+1);
	gr_aabitmap( Current_radar_global->Radar_coords[gr_screen.res][0], Current_radar_global->Radar_coords[gr_screen.res][1] );
} 
示例#5
0
void radar_draw_image_std(int x, int y, int rad, int idx, int size)
{
	// this we will move as ships.tbl option (or use for radar scaling etc etc)
	//int size = 24; 

	int w, h, old_bottom, old_bottom_unscaled, old_right, old_right_unscaled;
	float scalef, wf, hf, xf, yf;
	vec3d blip_scaler;

	if (bm_get_info(idx, &w, &h) < 0)
	{
		// Just if something goes terribly wrong
		radar_draw_circle_std(x, y, rad);
		return;
	}

	// just to make sure the missing casts wont screw the math
	wf = (float)w;
	hf = (float)h;
	xf = (float)x;
	yf = (float)y;

	// make sure we use the larger dimension for the scaling
	// lets go case by case to make sure there are no probs
	if (size == -1)
		scalef = 1.0f;
	else if ((h == w) && (size == h))
		scalef = 1.0f;
	else if (h > w)
		scalef = ((float)size) / hf;
	else
		scalef = ((float)size) / wf;

	Assert(scalef != 0);

	// animate the targeted icon - option 1 of highlighting the targets
	if (rad == Current_radar_global->Radar_blip_radius_target[gr_screen.res])
	{
		if (radar_target_id_flags & RTIF_PULSATE)
		{
			scalef *= 1.3f + (sinf(10 * f2fl(Missiontime)) * 0.3f);
		}
		if (radar_target_id_flags & RTIF_BLINK)
		{
			if (Missiontime & 8192)
				return;
		}
		if (radar_target_id_flags & RTIF_ENLARGE)
		{
			scalef *= 1.3f;
		}
	}

	// setup the scaler
	blip_scaler.xyz.x = scalef;
	blip_scaler.xyz.y = scalef;
	blip_scaler.xyz.z = 1.0f;

	old_bottom = gr_screen.clip_bottom;
	old_bottom_unscaled = gr_screen.clip_bottom_unscaled;
	gr_screen.clip_bottom = (int)(old_bottom / scalef);
	gr_screen.clip_bottom_unscaled = (int)(old_bottom_unscaled / scalef);

	old_right = gr_screen.clip_right;
	old_right_unscaled = gr_screen.clip_right_unscaled;
	gr_screen.clip_right = (int)(old_right / scalef);
	gr_screen.clip_right_unscaled = (int)(old_right_unscaled / scalef);

	// scale the drawing coordinates
	x = (int)((xf / scalef) - wf / 2.0f);
	y = (int)((yf / scalef) - hf / 2.0f);

	gr_push_scale_matrix(&blip_scaler);
	gr_set_bitmap(idx, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f);
	gr_aabitmap(x, y);
	gr_pop_scale_matrix();

	gr_screen.clip_bottom = old_bottom;
	gr_screen.clip_bottom_unscaled = old_bottom_unscaled;

	gr_screen.clip_right = old_right;
	gr_screen.clip_right_unscaled = old_right_unscaled;
}