lexsdl 0.3.0

A wrapper for SDL2 to abstract away annoying parts
#include"LEXSDL.h"
#include"LEXSDL_internal.h"

/* NOTE s

Errors
	-1: could not add the first sprite.
	-2: could not add sprite.
	-3: invalid texture.
*/

/* Inline Functions */
inline void updateFrameDimensions(LEXSDL_SpriteID id){
	LEXSDLDATA.sprites[id].frameDimensions.x = (LEXSDLDATA.sprites[id].frameDimensions.w * LEXSDLDATA.sprites[id].currentFrame);
}

/* Creation */

static LEXSDL_SpriteID LEXSDL_SpriteAdd(LEXSDL_Sprite sprite){
	if(LEXSDLDATA.sprites == NULL){
		LEXSDLDATA.sprites = calloc(1,sizeof(LEXSDL_Sprite));
		if(LEXSDLDATA.sprites == NULL)
			return LEXSDL_SpriteCreationFailed;
		LEXSDLDATA.sprites[LEXSDLDATA.spritesQuantity] = sprite;
	}
	
	LEXSDL_Sprite *newptr = realloc(LEXSDLDATA.sprites, (LEXSDLDATA.spritesQuantity+1) * sizeof(LEXSDL_Sprite));
	
	if(newptr == NULL)
		return LEXSDL_SpriteCreationFailed;
	
	LEXSDLDATA.sprites = newptr;
	LEXSDLDATA.sprites[LEXSDLDATA.spritesQuantity] = sprite;
	
	LEXSDLDATA.spritesQuantity++;
	return LEXSDLDATA.spritesQuantity-1; //returns the id of the sprite
}

LEXSDL_SpriteID LEXSDL_CreateSprite(LEXSDL_TextureID textureID, uint32_t frames, uint32_t fps, SDL_Rect frameDimensions){
	// WARNING frames != 0;
	if(frames == 0)
		frames = 1;
	
	// check if the texture is valid.
	if ((textureID >= LEXSDLDATA.texturesQuantity) || !LEXSDLDATA.textures[textureID])
		return LEXSDL_SpriteTextureInvalid;
	
	LEXSDL_Sprite sprite = {
		(frames -1),
		0,
		0,
		fps,
		textureID,
		frameDimensions,
		0
	};
	return LEXSDL_SpriteAdd(sprite);
}



/* Getters */

uint32_t LEXSDL_SpriteGetCurrentFrame(LEXSDL_SpriteID id){
	if((id >= LEXSDLDATA.spritesQuantity) || LEXSDLDATA.sprites[id].freed)
		return 0;
	return LEXSDLDATA.sprites[id].currentFrame + 1;
}

SDL_Rect LEXSDL_SpriteGetFrameDimensions(LEXSDL_SpriteID id){
	if((id >= LEXSDLDATA.spritesQuantity) || LEXSDLDATA.sprites[id].freed)
		return (SDL_Rect){-1,-1,-1,-1};
	return LEXSDLDATA.sprites[id].frameDimensions;
}

uint32_t LEXSDL_SpriteGetFrames(LEXSDL_SpriteID id){
	if((id >= LEXSDLDATA.spritesQuantity) || LEXSDLDATA.sprites[id].freed)
		return LEXSDL_SpriteIDInvalid;
	return LEXSDLDATA.sprites[id].frames + 1;
}

uint32_t LEXSDL_SpriteGetFps(LEXSDL_SpriteID id){
	if((id >= LEXSDLDATA.spritesQuantity) || LEXSDLDATA.sprites[id].freed)
		return LEXSDL_SpriteIDInvalid;
	return LEXSDLDATA.sprites[id].fps;
}

SDL_Texture* LEXSDL_SpriteGetTexture(LEXSDL_SpriteID id){
	if((id >= LEXSDLDATA.spritesQuantity) || LEXSDLDATA.sprites[id].freed)
		return NULL;
	return LEXSDLDATA.textures[LEXSDLDATA.sprites[id].textureID];
}

LEXSDL_TextureID LEXSDL_SpriteGetTextureId(LEXSDL_SpriteID id){
	if((id >= LEXSDLDATA.spritesQuantity) || LEXSDLDATA.sprites[id].freed)
		return LEXSDL_SpriteIDInvalid;
	return LEXSDLDATA.sprites[id].textureID;
}

LEXSDL_SpriteID LEXSDL_SpriteSetTextureId(LEXSDL_SpriteID id, LEXSDL_TextureID textureID){
	if((id >= LEXSDLDATA.spritesQuantity) || LEXSDLDATA.sprites[id].freed)
		return LEXSDL_SpriteIDInvalid;
	LEXSDLDATA.sprites[id].textureID = textureID;
	return LEXSDL_SpriteOperationSucceded;
}




/* Manipulation */

LEXSDL_SpriteID LEXSDL_SpriteClone(LEXSDL_SpriteID id){
	return LEXSDL_SpriteAdd(LEXSDLDATA.sprites[id]);
}

void LEXSDL_SpriteSkipFrames(LEXSDL_SpriteID id, uint32_t frames){
	LEXSDLDATA.sprites[id].currentFrame += frames;
	if (LEXSDLDATA.sprites[id].currentFrame > LEXSDLDATA.sprites[id].frames)
		LEXSDLDATA.sprites[id].currentFrame = 0;
	updateFrameDimensions(id);

}

void LEXSDL_SpriteSetFrame(LEXSDL_SpriteID id, uint32_t frame){
	if (frame > LEXSDLDATA.sprites[id].frames)
		LEXSDLDATA.sprites[id].currentFrame = 0;
	else 
		LEXSDLDATA.sprites[id].currentFrame = frame;
	updateFrameDimensions(id);
}

void LEXSDL_SpriteStep(LEXSDL_SpriteID id){
	if (LEXSDLDATA.sprites[id].currentFrame < LEXSDLDATA.sprites[id].frames)
		LEXSDLDATA.sprites[id].currentFrame++;
	else
		LEXSDLDATA.sprites[id].currentFrame = 0;
	updateFrameDimensions(id);
}

void LEXSDL_SpriteUpdate(LEXSDL_SpriteID id){
	LEXSDLDATA.sprites[id].delta += LEXSDLDATA.delta;
	while(LEXSDLDATA.sprites[id].delta > (1000 / LEXSDLDATA.sprites[id].fps)){
		LEXSDLDATA.sprites[id].delta -= 1000 / LEXSDLDATA.sprites[id].fps;
		if(LEXSDLDATA.sprites[id].currentFrame < LEXSDLDATA.sprites[id].frames)
			LEXSDLDATA.sprites[id].currentFrame++;
		else
			LEXSDLDATA.sprites[id].currentFrame = 0;
	}
	updateFrameDimensions(id);
}



/* Drawing */
void LEXSDL_SpriteDraw(LEXSDL_SpriteID id, int x, int y, int w, int h){
	SDL_Rect dstrect = {x,y,w,h};
	SDL_RenderCopy(LEXSDLDATA.renderer, LEXSDLDATA.textures[LEXSDLDATA.sprites[id].textureID], &LEXSDLDATA.sprites[id].frameDimensions, &dstrect);
}

void LEXSDL_SpriteDrawFlip(LEXSDL_SpriteID id, int x, int y, int w, int h){
	SDL_Rect dstrect = {x,y,w,h};
	SDL_RenderCopyEx(LEXSDLDATA.renderer, LEXSDLDATA.textures[LEXSDLDATA.sprites[id].textureID], &LEXSDLDATA.sprites[id].frameDimensions,&dstrect, 0,NULL, SDL_FLIP_HORIZONTAL);
}

void LEXSDL_SpriteDrawFlipRot(LEXSDL_SpriteID id, int x, int y, int w, int h, double rot){
	SDL_Rect dstrect = {x,y,w,h};
	SDL_RenderCopyEx(LEXSDLDATA.renderer, LEXSDLDATA.textures[LEXSDLDATA.sprites[id].textureID], &LEXSDLDATA.sprites[id].frameDimensions,&dstrect, rot,NULL, SDL_FLIP_HORIZONTAL);
}

void LEXSDL_SpriteDrawRot(LEXSDL_SpriteID id, int x, int y, int w, int h, double rot){
	SDL_Rect dstrect = {x,y,w,h};
	SDL_RenderCopyEx(LEXSDLDATA.renderer, LEXSDLDATA.textures[LEXSDLDATA.sprites[id].textureID], &LEXSDLDATA.sprites[id].frameDimensions,&dstrect, rot,NULL, SDL_FLIP_NONE);
}



/* Playing */
void LEXSDL_SpritePlay(LEXSDL_SpriteID id, int x, int y, int w, int h){
	SDL_Rect dstrect = {x,y,w,h};
	SDL_RenderCopy(LEXSDLDATA.renderer, LEXSDLDATA.textures[LEXSDLDATA.sprites[id].textureID], &LEXSDLDATA.sprites[id].frameDimensions, &dstrect);
	if(LEXSDLDATA.sprites[id].fps > 0) LEXSDL_SpriteUpdate(id);
	else LEXSDL_SpriteStep(id);
}

void LEXSDL_SpritePlayBackground(LEXSDL_SpriteID id){
	SDL_RenderCopy(LEXSDLDATA.renderer, LEXSDLDATA.textures[LEXSDLDATA.sprites[id].textureID], &LEXSDLDATA.sprites[id].frameDimensions, NULL);
	LEXSDL_SpriteUpdate(id);
	if(LEXSDLDATA.sprites[id].fps > 0) LEXSDL_SpriteUpdate(id);
	else LEXSDL_SpriteStep(id);
}

// void LEXSDL_SpritePlayRot(size_t id, double rot);
void LEXSDL_SpritePlayFlip(LEXSDL_SpriteID id, int x, int y, int w, int h){
	SDL_Rect dstrect = {x,y,w,h};
	SDL_RenderCopyEx(LEXSDLDATA.renderer, LEXSDLDATA.textures[LEXSDLDATA.sprites[id].textureID], &LEXSDLDATA.sprites[id].frameDimensions,&dstrect, 0,NULL,SDL_FLIP_HORIZONTAL);
	if(LEXSDLDATA.sprites[id].fps > 0) LEXSDL_SpriteUpdate(id);
	else LEXSDL_SpriteStep(id);}

void LEXSDL_SpritePlayFlipRot(LEXSDL_SpriteID id, int x, int y, int w, int h, double rot){
	SDL_Rect dstrect = {x,y,w,h};
	SDL_RenderCopyEx(LEXSDLDATA.renderer, LEXSDLDATA.textures[LEXSDLDATA.sprites[id].textureID], &LEXSDLDATA.sprites[id].frameDimensions,&dstrect, rot,NULL, SDL_FLIP_HORIZONTAL);
	if(LEXSDLDATA.sprites[id].fps > 0) LEXSDL_SpriteUpdate(id);
	else LEXSDL_SpriteStep(id);
}

void LEXSDL_SpritePlayRot(LEXSDL_SpriteID id, int x, int y, int w, int h, double rot){
	SDL_Rect dstrect = {x,y,w,h};
	SDL_RenderCopyEx(LEXSDLDATA.renderer, LEXSDLDATA.textures[LEXSDLDATA.sprites[id].textureID], &LEXSDLDATA.sprites[id].frameDimensions,&dstrect, rot,NULL, SDL_FLIP_NONE);
	if(LEXSDLDATA.sprites[id].fps > 0) LEXSDL_SpriteUpdate(id);
	else LEXSDL_SpriteStep(id);
}