Пример #1
0
/*!
 * \brief
 * Starts a tilemap animation
 * 
 * \param index
 * Id of the animation to set (0 <= id < num_animations)
 * 
 * \param nlayer
 * Id of the layer to animate (0 <= id < num_layers)
 * 
 * \param sequence
 * Reference of the sequence to assign
 * 
 * \see
 * Animations
 */
bool TLN_SetTilemapAnimation (int index, int nlayer, TLN_Sequence sequence)
{
	Animation* animation;
	
	if (index >= engine->numanimations)
	{
		TLN_SetLastError (TLN_ERR_IDX_ANIMATION);
		return false;
	}
	if (nlayer >= engine->numlayers)
	{
		TLN_SetLastError (TLN_ERR_IDX_LAYER);
		return false;
	}

	/* validate type */
	if (!CheckBaseObject (sequence, OT_SEQUENCE))
		return false;
	
	animation = &engine->animations[index];
	SetAnimation (animation, sequence, TYPE_TILEMAP);
	animation->idx = nlayer;

	TLN_SetLastError (TLN_ERR_OK);
	return true;
}
Пример #2
0
/*!
 * \brief
 * Starts a sprite animation
 * 
 * \param index
 * Id of the animation to set (0 <= id < num_animations)
 * 
 * \param nsprite
 * If of the sprite to animate (0 <= id < num_sprites)
 * 
 * \param sequence
 * Reference of the sequence to assign
 * 
 * \param loop
 * amount of times to loop, 0=infinite
 * 
 * \see
 * Animations
 */
bool TLN_SetSpriteAnimation (int index, int nsprite, TLN_Sequence sequence, int loop)
{
	Animation* animation;
	
	if (index >= engine->numanimations)
	{
		TLN_SetLastError (TLN_ERR_IDX_ANIMATION);
		return false;
	}
	if (nsprite >= engine->numsprites)
	{
		TLN_SetLastError (TLN_ERR_IDX_SPRITE);
		return false;
	}

	/* validate type */
	if (!CheckBaseObject (sequence, OT_SEQUENCE))
		return false;
	
	animation = &engine->animations[index];
	SetAnimation (animation, sequence, TYPE_SPRITE);
	animation->idx = nsprite;
	animation->loop = loop;

	TLN_SetLastError (TLN_ERR_OK);
	return true;
}
Пример #3
0
/*!
 * \brief
 * Load image file (8-bit BMP or PNG)
 *
 * \param filename
 * File name with the image
 *
 * \returns
 * Handler to the loaded image or NULL if error
 *
 * \see
 * TLN_DeleteBitmap()
 */
TLN_Bitmap TLN_LoadBitmap (char *filename)
{
    TLN_Bitmap bitmap;

    if (!CheckFile (filename))
    {
        TLN_SetLastError (TLN_ERR_FILE_NOT_FOUND);
        return NULL;
    }

    /* try png, else bmp*/
    bitmap = LoadPNG (filename);
    if (bitmap == NULL)
        bitmap = LoadBMP (filename);

    /* bitmap loaded */
    if (bitmap)
    {
        /* accept only 8 bpp */
        int bpp = TLN_GetBitmapDepth (bitmap);
        if (bpp == 8)
            TLN_SetLastError (TLN_ERR_OK);
        else
        {
            TLN_DeleteBitmap (bitmap);
            bitmap = NULL;
        }
    }

    if (!bitmap)
        TLN_SetLastError (TLN_ERR_WRONG_FORMAT);

    return bitmap;
}
Пример #4
0
/**
 * \brief
 * Checks the state of the specified animation
 * 
 * \param index
 * Id of the animation to check (0 <= id < num_animations)
 * 
 * \returns
 * true if animation is running, false if it's finished or inactive
 */
bool TLN_GetAnimationState (int index)
{
	if (index >= engine->numanimations)
	{
		TLN_SetLastError (TLN_ERR_IDX_ANIMATION);
		return false;
	}

	TLN_SetLastError (TLN_ERR_OK);
	return engine->animations[index].enabled;
}
Пример #5
0
/*!
 * \brief
 * Creates a new sequence for the animation engine
 * 
 * \param name
 * String with an unique name to query later
 * 
 * \param target
 * For tileset animations, the tile index to animate
 * 
 * \param count
 * Number of frames
 * 
 * \param frames
 * Array of TLN_Frame items with indexes and delays
 * 
 * \returns
 * Reference to the new sequence or NULL if error
 * 
 * \remarks
 * Use this function to create tileset or sprite animations
 * 
 * \see
 * TLN_SetTilemapAnimation(), TLN_SetSpriteAnimation()
 */
TLN_Sequence TLN_CreateSequence (const char* name, int target, int count, TLN_SequenceFrame* frames)
{
	int size;
	TLN_Sequence sequence;
	TLN_SequenceFrame* frame;
	
	size = count*sizeof(TLN_SequenceFrame);
	sequence = CreateBaseObject (OT_SEQUENCE, sizeof(struct Sequence) + size);
	if (!sequence)
		return NULL;

	if (name)
	{
		sequence->hash = hash(0, name, strlen(name));
		strncpy (sequence->name, name, 32);
	}
	sequence->target = target;
	sequence->count = count;

	frame = (TLN_SequenceFrame*)&sequence->data;
	memcpy (frame, frames, sizeof(TLN_SequenceFrame)*count);

	TLN_SetLastError (TLN_ERR_OK);
	return sequence;
}
Пример #6
0
/*!
 * \brief
 * Sets the playback speed of a given animation
 * 
 * \param index
 * Id of the animation to set (0 <= id < num_animations)
 * 
 * \param delay
 * New delay between frames to assign
 * 
 * Each sequence has its own delay set in the sqx file. However sometimes it's convenient
 * to speed up or down the playback speed in realtime, for example for a character that is
 * accelerating.
 * 
 * \remarks
 * The meaning of the delay value (i.e. its units) is application dependant. It can usually be frames
 * or milliseconds. Make sure that its units match the ones insode the sqx file and the ones
 * passed to the TLN_UpdateFrame()
 * 
 * \see
 * Animations, TLN_UpdateFrame()
 */
bool TLN_SetAnimationDelay (int index, int delay)
{
	Animation* animation;
	
	if (index >= engine->numanimations)
	{
		TLN_SetLastError (TLN_ERR_IDX_ANIMATION);
		return false;
	}
	
	animation = &engine->animations[index];
	animation->delay = delay;

	TLN_SetLastError (TLN_ERR_OK);
	return true;
}
Пример #7
0
/*!
 * \brief
 * Creates a color cycle sequence for palette animation
 * 
 * \param name
 * String with an unique name to query later
 * 
 * \param count
 * Number of color strips
 * 
 * \param strips
 * Array of color strips to assign
 * 
 * \returns
 * Reference to the created cycle or NULL if error
 * 
 * \remarks
 * Use this function to create advanced palette animation effects
 * 
 * \see
 * TLN_ColorStrip(), TLN_SetPaletteAnimation()
 */
TLN_Sequence TLN_CreateCycle (const char* name, int count, TLN_ColorStrip* strips)
{
	int size, c;
	TLN_Sequence sequence;
	TLN_ColorStrip* srcstrip;
	struct Strip* dststrip;
	
	size = count*sizeof(struct Strip);
	sequence = CreateBaseObject (OT_SEQUENCE, sizeof(struct Sequence) + size);
	if (!sequence)
		return NULL;

	if (name)
	{
		sequence->hash = hash(0, name, strlen(name));
		strncpy (sequence->name, name, 32);
	}
	
	sequence->count = count;
	srcstrip = strips;
	dststrip = (struct Strip*)&sequence->data;
	for (c=0; c<count; c++)
	{
		dststrip->delay = srcstrip->delay;
		dststrip->first = srcstrip->first;
		dststrip->count = srcstrip->count;
		dststrip->dir   = srcstrip->dir;
		srcstrip++;
		dststrip++;
	}

	TLN_SetLastError (TLN_ERR_OK);
	return sequence;
}
Пример #8
0
/*!
 * \brief
 * Disables the animation so it stops playing and returns it to the list of available animations
 * 
 * \param index
 * Id of the animation to set (0 <= id < num_animations)
 * 
 * \see
 * Animations
 */
bool TLN_DisableAnimation (int index)
{
	Animation* animation;
	
	if (index >= engine->numanimations)
	{
		TLN_SetLastError (TLN_ERR_IDX_ANIMATION);
		return false;
	}
	
	animation = &engine->animations[index];
	animation->enabled = false;
	animation->type = TYPE_NONE;
	animation->sequence = NULL;

	TLN_SetLastError (TLN_ERR_OK);
	return true;
}
Пример #9
0
/*!
 * \brief
 * Loads a palette from a standard .act file
 * 
 * \param filename
 * ACT file containing the palette to load
 * 
 * \returns
 * A reference to the newly loaded palette, or NULL if error
 * 
 * \remarks
 * Palettes are also automatically created when loading tilesets and spritesets.
 * Use the functions TLN_GetTilesetPalette() and TLN_GetSpritesetPalette() to retrieve them.
 * 
 * \see
 * TLN_GetTilesetPalette(), TLN_GetSpritesetPalette()
 */
TLN_Palette TLN_LoadPalette (char *filename)
{
	FILE *pf;
	TLN_Palette palette = NULL;
	int size;
	int c;

	/* open file */
	pf = fopen (filename, "rb");
	if (!pf)
	{
		TLN_SetLastError (TLN_ERR_FILE_NOT_FOUND);
		return NULL;
	}

	/* check size */
	fseek (pf, 0, SEEK_END);
	size = ftell (pf);

	/* load trailing and get number of entries */
	if (size == ACT_SIZE)
	{
		fseek (pf, - (int)sizeof(trailing), SEEK_END);
		fread (&trailing, sizeof(trailing), 1, pf);
		trailing.entries = SWAP(trailing.entries);
		trailing.transparent = SWAP(trailing.transparent);
	}
	else
		trailing.entries = size/3;

	/* create palette and load from file */
	palette = TLN_CreatePalette (trailing.entries);
	fseek (pf, 0, SEEK_SET);
	for (c=0; c<trailing.entries; c++)
	{
		BYTE src[3];
		fread (src, sizeof(src), 1, pf);
		TLN_SetPaletteColor (palette, c, src[0], src[1], src[2]);
	}

	fclose (pf);
	TLN_SetLastError (TLN_ERR_OK);
	return palette;
}
Пример #10
0
/*!
 * \brief
 * Starts a palette animation
 * 
 * \param index
 * Id of the animation to set (0 <= id < num_animations)
 * 
 * \param palette
 * Reference of the palette to be animated
 * 
 * \param sequence
 * Reference of the sequence to assign
 * 
 * \param blend
 * true for smooth frame interpolation, false for classic, discrete mode
 */
bool TLN_SetPaletteAnimation (int index, TLN_Palette palette, TLN_Sequence sequence, bool blend)
{
	Animation* animation;
	int c;
	struct Strip* strips;

	TLN_SetLastError (TLN_ERR_OK);
	
	if (index >= engine->numanimations)
	{
		TLN_SetLastError (TLN_ERR_IDX_ANIMATION);
		return false;
	}
	
	animation = &engine->animations[index];

	if (animation->sequence == sequence)
		return true;

	/* validate type */
	if (!CheckBaseObject (palette, OT_PALETTE) || !CheckBaseObject (sequence, OT_SEQUENCE))
		return false;

	SetAnimation (animation, sequence, TYPE_PALETTE);
	animation->palette = palette;
	animation->blend = blend;

	/* start timers */
	strips = (struct Strip*)&sequence->data;
	for (c=0; c<sequence->count; c++)
	{
		strips[c].timer = 0;
		strips[c].t0 = 0;
	}

	/* create auxiliary palette */
	if (animation->srcpalette == NULL)
		animation->srcpalette = TLN_CreatePalette (256);
	CopyBaseObject (animation->srcpalette, palette);

	return true;
}
Пример #11
0
/*!
 * \brief
 * Deletes the sequence and frees resources
 * 
 * \param sequence
 * Reference to the sequence to be deleted
 * 
 * \remarks
 * Don't delete an active sequence!
 */
bool TLN_DeleteSequence (TLN_Sequence sequence)
{
	if (CheckBaseObject (sequence, OT_SEQUENCE))
	{
		DeleteBaseObject (sequence);
		TLN_SetLastError (TLN_ERR_OK);
		return true;
	}
	else
		return false;
}
Пример #12
0
/*!
 * \brief
 * Sets the source palette of a color cycle animation
 * 
 * \param index
 * Id of the animation to set (0 <= id < num_animations)
 * 
 * \param palette
 * Reference of the palette to assign
 * 
 * \remarks
 * Use this function to change the palette assigned to a color cycle animation running.
 * This is useful to combine color cycling and palette interpolation at the same time
 */
bool TLN_SetPaletteAnimationSource (int index, TLN_Palette palette)
{
	Animation* animation;

	if (index >= engine->numanimations)
	{
		TLN_SetLastError (TLN_ERR_IDX_ANIMATION);
		return false;
	}

	if (!CheckBaseObject (palette, OT_PALETTE))
		return false;

	animation = &engine->animations[index];
	CopyBaseObject (animation->srcpalette, palette);
	CopyBaseObject (animation->palette, palette);

	TLN_SetLastError (TLN_ERR_OK);
	return true;
}
Пример #13
0
/*!
 * \brief
 * Finds an available (unused) animation
 * 
 * \returns
 * Index of the first unused animation (starting from 0) or -1 if none found
 */
int TLN_GetAvailableAnimation (void)
{
	int c;

	TLN_SetLastError (TLN_ERR_OK);
	for (c=0; c<engine->numanimations; c++)
	{
		if (!engine->animations[c].enabled)
			return c;
	}
	return -1;
}
Пример #14
0
/*!
 * \brief
 * Creates a duplicate of the specified sequence
 * 
 * \param src
 * Sequence to clone
 * 
 * \returns
 * A reference to the newly cloned sequence, or NULL if error
 *
 * \see
 * TLN_FindSequence()
 */
TLN_Sequence TLN_CloneSequence (TLN_Sequence src)
{
	TLN_Sequence sequence;

	if (!CheckBaseObject (src, OT_SEQUENCE))
		return NULL;

	sequence = CloneBaseObject (src);
	if (sequence)
	{
		TLN_SetLastError (TLN_ERR_OK);
		return sequence;
	}
	else
		return NULL;
}
Пример #15
0
// TODO
JNIEXPORT jint JNICALL Java_Tilengine_CreateCycle (JNIEnv* env, jobject thisobj, jstring name, jint num_strips, jobjectArray strips)
{
	TLN_SetLastError (TLN_ERR_UNSUPPORTED);
	return 0;
}
Пример #16
0
// TODO
JNIEXPORT jboolean JNICALL Java_Tilengine_SetLayerAffineTransform (JNIEnv* env, jobject thisobj, jint nlayer, jobject aff)
{
	TLN_SetLastError (TLN_ERR_UNSUPPORTED);
	return false;
}
Пример #17
0
// TODO
JNIEXPORT jint JNICALL Java_Tilengine_CreateTilemap (JNIEnv* env, jobject thisobj, jint rows, jint cols, jobjectArray tiles)
{
	TLN_SetLastError (TLN_ERR_UNSUPPORTED);
	return 0;
}
Пример #18
0
JNIEXPORT void JNICALL Java_Tilengine_SetLastError (JNIEnv* env, jobject thisobj, jint error)
{
	TLN_SetLastError (error);
}
Пример #19
0
/*!
 * \brief
 * Loads a spriteset from a png/txt file pair
 * 
 * \param name
 * Base name of the files containing the spriteset
 * 
 * \returns
 * Reference to the newly loaded spriteset or NULL if error
 * 
 * \remarks
 * The spriteset comes in a pair of files called name.png and name.txt. The png file contains
 * the spriteset, whereas the txt contains the coordinates of the rectangles that define individual sprites.
 * These files can be created wit the spritesheet packer tool (http://spritesheetpacker.codeplex.com/)
 * \remarks
 * An associated palette is also created, it can be obtained calling TLN_GetSpritesetPalette()
 */
TLN_Spriteset TLN_LoadSpriteset (const char* name)
{
	FILE *pf;
	char filename[64];
	char line[64];
	int entries = 0;
	TLN_Bitmap bitmap;
	TLN_Spriteset spriteset;
	TLN_Rect *rects, *rect;
	int c;

	/* load png file */
	sprintf (filename, "%s.png", name);
	bitmap = TLN_LoadBitmap (filename);
	if (!bitmap)
		return NULL;

	/* load txt file */
	sprintf (filename, "%s.txt", name);
	pf = FileOpen (filename);
	if (!pf)
	{
		TLN_DeleteBitmap (bitmap);
		TLN_SetLastError (TLN_ERR_FILE_NOT_FOUND);
		return NULL;
	}

	/* count lines */
	while (fgets (line, 64, pf))
		entries++;

	rects = malloc (sizeof(TLN_Rect)*entries);
	if (!rects)
	{
		TLN_DeleteBitmap (bitmap);
		TLN_SetLastError (TLN_ERR_OUT_OF_MEMORY);
		fclose (pf);
		return NULL;
	}

	/* read entries */
	fseek (pf, 0, SEEK_SET);
	for (c=0; c<entries; c++)
	{
		char* equals;
		char imagename[64];

		/* lee linea */
		fgets (line, 64, pf);
		rect = &rects[c];

		/* formato SpriteSheetPacker: name = x y w h */
		equals = strchr (line, '=');
		if (equals != NULL)
		{
			sscanf (line, "%s = %d %d %d %d", imagename, &rect->x, &rect->y, &rect->w, &rect->h);
			continue;
		}

		/* formato Leshy SpriteSheet Tool csv: name,x,y,w,h */
		equals = strchr (line, ',');
		if (equals != NULL)
		{
			char* del = line;
			while (*del)
			{
				if (*del == ',')
					*del = ' ';
				del++;
			}
			sscanf (line, "%s %d %d %d %d", imagename, &rect->x, &rect->y, &rect->w, &rect->h);
			continue;
		}
	}
	fclose (pf);

	/* create */
	spriteset = TLN_CreateSpriteset (
		entries, 
		rects, 
		TLN_GetBitmapPtr (bitmap, 0,0), 
		TLN_GetBitmapWidth (bitmap),
		TLN_GetBitmapHeight (bitmap), 
		TLN_GetBitmapPitch (bitmap), 
		TLN_ClonePalette(TLN_GetBitmapPalette(bitmap))
	);
	
	/* free resources */
	free (rects);
	TLN_DeleteBitmap (bitmap);
	
	if (spriteset)
		TLN_SetLastError (TLN_ERR_OK);
	else
		TLN_SetLastError (TLN_ERR_OUT_OF_MEMORY);
	
	return spriteset;
}