Ejemplo n.º 1
0
/**
 * @brief Write the frames of a .ani file out to disk as .pcx files.
 * @details Use naming convention: filename0000.pcx, filename0001.pcx etc.
 *
 * @return If success 0, or if failed -1
 */
int anim_write_frames_out(char *filename)
{
	anim				*source_anim;
	anim_instance	*ai;
	char				root_name[256], pcxname[256];
	char				buf[64];
	int				i,j;
	ubyte				**row_data;

	strcpy_s(root_name, filename);
	root_name[strlen(filename)-4] = 0;

	source_anim = anim_load(filename);
	if ( source_anim == NULL ) 
		return -1;

	ai = init_anim_instance(source_anim, 16);

	row_data = (ubyte**)vm_malloc((source_anim->height+1) * 4);

	for ( i = 0; i < source_anim->total_frames; i++ ) {
		anim_get_next_raw_buffer(ai, 0, 0, 16);
		strcpy_s(pcxname, root_name);
		sprintf(buf,"%04d",i);
		strcat_s(pcxname, buf);

		for ( j = 0; j < source_anim->height; j++ ) {
			row_data[j] = &ai->frame[j*source_anim->width];
		}


		pcx_write_bitmap( pcxname,
								source_anim->width,
								source_anim->height,
								row_data,
								source_anim->palette);

		printf(".");

	}
	printf("\n");
	vm_free(row_data);
	return 0;
}
Ejemplo n.º 2
0
int generic_anim_stream(generic_anim *ga, const bool cache)
{
	CFILE *img_cfp = NULL;
	int anim_fps = 0;
	char full_path[MAX_PATH];
	int size = 0, offset = 0;
	const int NUM_TYPES = 3;
	const ubyte type_list[NUM_TYPES] = {BM_TYPE_EFF, BM_TYPE_ANI, BM_TYPE_PNG};
	const char *ext_list[NUM_TYPES] = {".eff", ".ani", ".png"};
	int rval = -1;
	int bpp;

	ga->type = BM_TYPE_NONE;

	rval = cf_find_file_location_ext(ga->filename, NUM_TYPES, ext_list, CF_TYPE_ANY, sizeof(full_path) - 1, full_path, &size, &offset, 0);

	// could not be found, or is invalid for some reason
	if ( (rval < 0) || (rval >= NUM_TYPES) )
		return -1;

	//make sure we can open it
	img_cfp = cfopen_special(full_path, "rb", size, offset, CF_TYPE_ANY);

	if (img_cfp == NULL) {
		return -1;
	}

	strcat_s(ga->filename, ext_list[rval]);
	ga->type = type_list[rval];
	//seek to the end
	cfseek(img_cfp, 0, CF_SEEK_END);

	cfclose(img_cfp);

	if(ga->type == BM_TYPE_ANI) {
		bpp = ANI_BPP_CHECK;
		if(ga->use_hud_color)
			bpp = 8;
		if (ga->ani.animation == nullptr) {
			ga->ani.animation = anim_load(ga->filename, CF_TYPE_ANY, 0);
		}
		if (ga->ani.instance == nullptr) {
			ga->ani.instance = init_anim_instance(ga->ani.animation, bpp);
		}

	#ifndef NDEBUG
		// for debug of ANI sizes
		strcpy_s(ga->ani.animation->name, ga->filename);
	#endif

		ga->num_frames = ga->ani.animation->total_frames;
		anim_fps = ga->ani.animation->fps;
		ga->height = ga->ani.animation->height;
		ga->width = ga->ani.animation->width;
		ga->buffer = ga->ani.instance->frame;
		ga->bitmap_id = bm_create(bpp, ga->width, ga->height, ga->buffer, (bpp==8)?BMP_AABITMAP:0);
		ga->ani.instance->last_bitmap = -1;

		ga->ani.instance->file_offset = ga->ani.animation->file_offset;
		ga->ani.instance->data = ga->ani.animation->data;

		ga->previous_frame = -1;
	}
	else if (ga->type == BM_TYPE_PNG) {
		if (ga->png.anim == nullptr) {
			try {
				ga->png.anim = new apng::apng_ani(ga->filename, cache);
			}
			catch (const apng::ApngException& e) {
				mprintf(("Failed to load apng: %s\n", e.what() ));
				delete ga->png.anim;
				ga->png.anim = nullptr;
				return -1;
			}
			nprintf(("apng", "apng read OK (%ix%i@%i) duration (%f)\n", ga->png.anim->w, ga->png.anim->h,
					ga->png.anim->bpp, ga->png.anim->anim_time));
		}
		ga->png.anim->goto_start();
		ga->current_frame = 0;
		ga->png.previous_frame_time = 0.0f;
		ga->num_frames = ga->png.anim->nframes;
		ga->height = ga->png.anim->h;
		ga->width = ga->png.anim->w;
		ga->previous_frame = -1;
		ga->buffer = ga->png.anim->frame.data.data();
		ga->bitmap_id = bm_create(ga->png.anim->bpp, ga->width, ga->height, ga->buffer, 0);
	}
	else {
		bpp = 32;
		if(ga->use_hud_color)
			bpp = 8;
		bm_load_and_parse_eff(ga->filename, CF_TYPE_ANY, &ga->num_frames, &anim_fps, &ga->keyframe, 0);
		char *p = strrchr( ga->filename, '.' );
		if ( p )
			*p = 0;
		char frame_name[MAX_FILENAME_LEN];
		snprintf(frame_name, MAX_FILENAME_LEN, "%s_0000", ga->filename);
		ga->bitmap_id = bm_load(frame_name);
		if(ga->bitmap_id < 0) {
			mprintf(("Cannot find first frame for eff streaming. eff Filename: %s", ga->filename));
			return -1;
		}
		snprintf(frame_name, MAX_FILENAME_LEN, "%s_0001", ga->filename);
		ga->eff.next_frame = bm_load(frame_name);
		bm_get_info(ga->bitmap_id, &ga->width, &ga->height);
		ga->previous_frame = 0;
	}

	// keyframe info
	if (ga->type == BM_TYPE_ANI) {
		//we only care if there are 2 keyframes - first frame, other frame to jump to for ship/weapons
		//mainhall door anis hav every frame as keyframe, so we don't care
		//other anis only have the first frame
		if(ga->ani.animation->num_keys == 2) {
			int key1 = ga->ani.animation->keys[0].frame_num;
			int key2 = ga->ani.animation->keys[1].frame_num;

			if (key1 < 0 || key1 >= ga->num_frames) key1 = -1;
			if (key2 < 0 || key2 >= ga->num_frames) key2 = -1;

			// some retail anis have their keyframes reversed
			// and some have their keyframes out of bounds
			if (key1 >= 0 && key1 >= key2) {
				ga->keyframe = ga->ani.animation->keys[0].frame_num;
				ga->keyoffset = ga->ani.animation->keys[0].offset;
			}
			else if (key2 >= 0 && key2 >= key1) {
				ga->keyframe = ga->ani.animation->keys[1].frame_num;
				ga->keyoffset = ga->ani.animation->keys[1].offset;
			}
		}
	}

	ga->streaming = 1;

	if (ga->type == BM_TYPE_PNG) {
		ga->total_time = ga->png.anim->anim_time;
	}
	else {
		if (anim_fps == 0) {
			Error(LOCATION, "animation (%s) has invalid fps of zero, fix this!", ga->filename);
		}
		ga->total_time = ga->num_frames / (float) anim_fps;
	}
	ga->done_playing = 0;
	ga->anim_time = 0.0f;

	return 0;
}