diff --git a/include/arc/graphics/sprite.h b/include/arc/graphics/sprite.h index fe71bf9..092fe81 100644 --- a/include/arc/graphics/sprite.h +++ b/include/arc/graphics/sprite.h @@ -11,27 +11,46 @@ extern "C" { #include "arc/math/rectangle.h" #include "arc/std/array.h" +/** + * @brief +*/ +typedef enum ARC_SpriteAxis { + ARC_SPRITE_AXIS_NONE = 0x00, + ARC_SPRITE_AXIS_Y = 0x01, + ARC_SPRITE_AXIS_X = 0x02, +} ARC_SpriteAxix; + /** * @brief a sprite type - * - * @note the actual type should be define by overriding for a graphics api - */ -typedef struct ARC_Sprite ARC_Sprite; +*/ +typedef struct ARC_Sprite { + ARC_Spritesheet *spritesheet; + ARC_Array frames; + uint32_t frameIndex; + + double angle; + + ARC_FPoint origin; + + float opacity; + + ARC_SpriteAxix axis; +} ARC_Sprite; /** * @brief creates ARC_Sprite type * * @param sprite ARC_Sprite that is being created * @param spritesheet ARC_Spritesheet that ARC_Sprite will be pulled from - * @param frames ARC_Array of bounds of sprite on spritesheet - */ -void ARC_Sprite_Create(ARC_Sprite **sprite, ARC_Spritesheet *spritesheet, ARC_Array *frames); + * @param frames ARC_Array of ARC_FRect bounds of sprite on spritesheet +*/ +void ARC_Sprite_Create(ARC_Sprite **sprite, ARC_Spritesheet *spritesheet, ARC_Array frames); /** * @brief destroys ARC_Sprite type * * @param sprite ARC_Sprite to destroy - */ +*/ void ARC_Sprite_Destroy(ARC_Sprite *sprite); /** @@ -39,20 +58,8 @@ void ARC_Sprite_Destroy(ARC_Sprite *sprite); * * @param newSprite ARC_Sprite that is being copied to and created * @param oldSprite ARC_Sprite contents that are being copied - */ -void ARC_Sprite_Copy(ARC_Sprite **newSprite, ARC_Sprite *oldSprite); - -//TODO: temp -/** - * @brief sets ARC_Sprite's opacity - * - * @param sprite ARC_Sprite that is changing opacity - * @param opacity new opacity for ARC_Sprite - * - * @note this is temp because opacity probably should be a value - * bigger than 255 */ -void ARC_Sprite_SetOpacity(ARC_Sprite *sprite, uint8_t opacity); +void ARC_Sprite_Copy(ARC_Sprite **newSprite, ARC_Sprite *oldSprite); /** * @brief renders ARC_Sprite type @@ -60,51 +67,59 @@ void ARC_Sprite_SetOpacity(ARC_Sprite *sprite, uint8_t opacity); * @param sprite ARC_Sprite that will be rendered * @param renderer ARC_Renderer that is handling rendering * @param renderBounds area of renderer that ARC_Sprite will be rendered to - */ -void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds); - -//TODO: move this to a better location -typedef enum ARC_Sprite_Axis { - ARC_SPRITE_AXIS_NONE = 0x00, - ARC_SPRITE_AXIS_Y = 0x01, - ARC_SPRITE_AXIS_X = 0x02, -} ARC_Sprite_Axix; +*/ +void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_FRect renderBounds); /** - * @brief renders ARC_Sprite type with flip + * @brief renders ARC_Sprite type at a point and at a set scale * - * @param sprite ARC_Sprite that will be rendered - * @param renderer ARC_Renderer that is handling rendering - * @param renderBounds area of renderer that ARC_Sprite will be rendered to - * @param axis axis to flip sprite - */ -void ARC_Sprite_RenderFlip(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds, enum ARC_Sprite_Axis axis); + * @param sprite ARC_Sprite that will be rendered + * @param renderer ARC_Renderer that is handling rendering + * @param point point on the renderer that ARC_Sprite will be rendered to (will be scaled as well) + * @param scale the scale to render at +*/ +void ARC_Sprite_RenderAt(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_FPoint point, double scale); /** - * @brief renders ARC_Sprite type with rotation + * @brief switches ARC_Sprite's frames to next for animation * - * @param sprite ARC_Sprite that will be rendered - * @param renderer ARC_Renderer that is handling rendering - * @param renderBounds area of renderer that ARC_Sprite will be rendered to - * @param angle angle to rotate ARC_Sprite - * @param center point to rotate ARC_Sprite around - */ -void ARC_Sprite_RenderRotated(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds, ARC_Point *center, double angle); + * @param sprite ARC_Sprite that is having its frame updated +*/ +void ARC_Sprite_IterateFrame(ARC_Sprite *sprite); /** * @brief switches ARC_Sprite's frame to specified index * * @param sprite ARC_Sprite that is having its frame set * @param index uint32_t to set ARC_Sprite's frame index to - */ +*/ void ARC_Sprite_SetFrameIndex(ARC_Sprite *sprite, uint32_t index); /** - * @brief switches ARC_Sprite's frames to next for animation + * @brief sets the origin point of the sprite (the rotation and position point) * - * @param sprite ARC_Sprite that is having its frame updated - */ -void ARC_Sprite_IterateFrame(ARC_Sprite *sprite); + * @param sprite ARC_Sprite that is having its angle set + * @param index the given agnel in degrees to rotate around (rotated clockwise) +*/ +void ARC_Sprite_SetAngle(ARC_Sprite *sprite, double angle); + +/** + * @brief sets the origin point of the sprite (the rotation and position point) + * + * @param sprite ARC_Sprite that is having its origin set + * @param origin the point on the arc sprite (based on its bounds/frame) to rotate around +*/ +void ARC_Sprite_SetOrigin(ARC_Sprite *sprite, ARC_FPoint origin); + +/** + * @brief sets ARC_Sprite's opacity + * + * @note opacity is a float value between 0.0 and 1.0 (1.0 is fully opaque) + * + * @param sprite ARC_Sprite that is changing opacity + * @param opacity new opacity for ARC_Sprite +*/ +void ARC_Sprite_SetOpacity(ARC_Sprite *sprite, float opacity); /** * @brief gets ARC_Sprite's current frame @@ -112,22 +127,22 @@ void ARC_Sprite_IterateFrame(ARC_Sprite *sprite); * @param sprite ARC_Sprite to get frame from * * @return index ARC_Sprite's current frame index - */ +*/ uint32_t ARC_Sprite_GetFrameIndex(ARC_Sprite *sprite); /** * @brief returns the current bounds based on the ARC_Sprite's frames * * @param sprite ARC_Sprite to get bounds from - */ -ARC_Rect *ARC_Sprite_GetBounds(ARC_Sprite *sprite); +*/ +ARC_FRect *ARC_Sprite_GetBounds(ARC_Sprite *sprite); /** * @brief returns the array of bounds that a sprite has * * @param sprite ARC_Sprite to get all the bounds from */ -ARC_Array *ARC_Sprite_GetAllBounds(ARC_Sprite *sprite); +ARC_Array ARC_Sprite_GetAllBounds(ARC_Sprite *sprite); #ifdef __cplusplus } diff --git a/packages/graphics/sdl3/config.c b/packages/graphics/sdl3/config.c index 0ddd255..a41317c 100644 --- a/packages/graphics/sdl3/config.c +++ b/packages/graphics/sdl3/config.c @@ -3,8 +3,8 @@ #include #include #include "renderer.h" -#include "sprite.h" -#include "spritesheet.h" +#include "arc/graphics/sprite.h" +#include "arc/graphics/spritesheet.h" #include "arc/std/string.h" #include "arc/std/parser/helpers.h" #include "arc/std/errno.h" diff --git a/packages/graphics/sdl3/sprite.c b/packages/graphics/sdl3/sprite.c index b97fe88..97be32e 100644 --- a/packages/graphics/sdl3/sprite.c +++ b/packages/graphics/sdl3/sprite.c @@ -1,20 +1,26 @@ #include "arc/graphics/sprite.h" -#include "sprite.h" #include "spritesheet.h" -#include "renderer.h" #include "arc/math/point.h" #include "arc/math/rectangle.h" #include "arc/std/errno.h" #include +#include -void ARC_Sprite_Create(ARC_Sprite **sprite, ARC_Spritesheet *spritesheet, ARC_Array *frames){ +void ARC_Sprite_Create(ARC_Sprite **sprite, ARC_Spritesheet *spritesheet, ARC_Array frames){ *sprite = (ARC_Sprite *)malloc(sizeof(ARC_Sprite)); (*sprite)->spritesheet = spritesheet; (*sprite)->frames = frames; - (*sprite)->frameIndex = (uint32_t *)malloc(sizeof(uint32_t)); - *(*sprite)->frameIndex = 0; - (*sprite)->opacity = 255; + (*sprite)->frameIndex = 0; + + (*sprite)->angle = 0.0; + + (*sprite)->origin = (ARC_FPoint){ 0.0, 0.0 }; + + //called this way to also set the alpha mod + ARC_Sprite_SetOpacity(*sprite, 1.0f); + + (*sprite)->axis = ARC_SPRITE_AXIS_NONE; } void ARC_Sprite_Destroy(ARC_Sprite *sprite){ @@ -24,73 +30,78 @@ void ARC_Sprite_Destroy(ARC_Sprite *sprite){ void ARC_Sprite_Copy(ARC_Sprite **newSprite, ARC_Sprite *oldSprite){ *newSprite = (ARC_Sprite *)malloc(sizeof(ARC_Sprite)); (*newSprite)->spritesheet = oldSprite->spritesheet; - (*newSprite)->frames = oldSprite->frames; - (*newSprite)->frameIndex = (uint32_t *)malloc(sizeof(uint32_t)); - *(*newSprite)->frameIndex = *oldSprite->frameIndex; + (*newSprite)->frames = oldSprite->frames; + (*newSprite)->frameIndex = oldSprite->frameIndex; + (*newSprite)->angle = oldSprite->angle; + (*newSprite)->origin = oldSprite->origin; + (*newSprite)->opacity = oldSprite->opacity; } -void ARC_Sprite_SetOpacity(ARC_Sprite *sprite, uint8_t opacity){ - sprite->opacity = opacity; +void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_FRect renderBounds){ + SDL_RenderTexture((SDL_Renderer *)renderer, sprite->spritesheet->texture, (SDL_FRect *)(sprite->frames.data + sprite->frameIndex), (SDL_FRect *)&renderBounds); } -void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds){ - //TODO: note, this is set here so not all entities in the sheet get opacity set - SDL_SetTextureAlphaMod((SDL_Texture *)sprite->spritesheet->texture, sprite->opacity); - ARC_FRect sourceRect = ARC_Rect_CastToFRect(*(ARC_Rect *)(sprite->frames->data + *sprite->frameIndex)); - ARC_FRect destinationRect = ARC_Rect_CastToFRect(*renderBounds); - SDL_RenderTexture((SDL_Renderer *)renderer, sprite->spritesheet->texture, (SDL_FRect *)&sourceRect, (SDL_FRect *)&destinationRect); -} +void ARC_Sprite_RenderAt(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_FPoint point, double scale){ + ARC_FRect sourceRect = *(ARC_FRect *)(sprite->frames.data + sprite->frameIndex); + //TODO: check that this works + ARC_FRect destinationRect = { + (point.x - sprite->origin.x) * scale, + (point.y - sprite->origin.y) * scale, + sourceRect.w * scale, + sourceRect.h * scale + }; -void ARC_Sprite_RenderFlip(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds, enum ARC_Sprite_Axis axis){ + //TODO: probably want to optomize this SDL_FlipMode flip = SDL_FLIP_NONE; - if(axis & ARC_SPRITE_AXIS_X){ + if(sprite->axis & ARC_SPRITE_AXIS_X){ flip |= SDL_FLIP_HORIZONTAL; } - if(axis & ARC_SPRITE_AXIS_Y){ + if(sprite->axis & ARC_SPRITE_AXIS_Y){ flip |= SDL_FLIP_VERTICAL; } - //TODO: note, this is set here so not all entities in the sheet get opacity set - SDL_SetTextureAlphaMod((SDL_Texture *)sprite->spritesheet->texture, sprite->opacity); - ARC_FRect sourceRect = ARC_Rect_CastToFRect(*(ARC_Rect *)(sprite->frames->data + *sprite->frameIndex)); - ARC_FRect destinationRect = ARC_Rect_CastToFRect(*renderBounds); - SDL_RenderTextureRotated((SDL_Renderer *)renderer, sprite->spritesheet->texture, (SDL_FRect *)&sourceRect, (SDL_FRect *)&destinationRect, 0.0, NULL, flip); + SDL_RenderTextureRotated((SDL_Renderer *)renderer, sprite->spritesheet->texture, (SDL_FRect *)&sourceRect, (SDL_FRect *)&destinationRect, sprite->angle, (SDL_FPoint *)&(sprite->origin), flip); } -void ARC_Sprite_RenderRotated(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds, ARC_Point *center, double angle){ - //TODO: note, this is set here so not all entities in the sheet get opacity set - SDL_SetTextureAlphaMod((SDL_Texture *)sprite->spritesheet->texture, sprite->opacity); - ARC_FRect sourceRect = ARC_Rect_CastToFRect(*(ARC_Rect *)(sprite->frames->data + *sprite->frameIndex)); - ARC_FRect destinationRect = ARC_Rect_CastToFRect(*renderBounds); - SDL_RenderTextureRotated((SDL_Renderer *)renderer, sprite->spritesheet->texture, (SDL_FRect *)&sourceRect, (SDL_FRect *)&destinationRect, angle, NULL, SDL_FLIP_NONE); +void ARC_Sprite_IterateFrame(ARC_Sprite *sprite){ + sprite->frameIndex++; + + if(sprite->frameIndex == sprite->frames.size){ + sprite->frameIndex = 0; + } } void ARC_Sprite_SetFrameIndex(ARC_Sprite *sprite, uint32_t index){ - if(sprite->frames->size <= index){ + if(sprite->frames.size <= index){ arc_errno = ARC_ERRNO_DATA; ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("in ARC_Sprite_SetFrameIndex(sprite, %d); index out of bounds", index); return; } - *sprite->frameIndex = index; + sprite->frameIndex = index; } -void ARC_Sprite_IterateFrame(ARC_Sprite *sprite){ - ++*sprite->frameIndex; +void ARC_Sprite_SetAngle(ARC_Sprite *sprite, double angle){ + sprite->angle = angle; +} - if(*sprite->frameIndex == sprite->frames->size){ - *sprite->frameIndex = 0; - } +void ARC_Sprite_SetOrigin(ARC_Sprite *sprite, ARC_FPoint origin){ + sprite->origin = origin; +} + +void ARC_Sprite_SetOpacity(ARC_Sprite *sprite, float opacity){ + sprite->opacity = opacity; + SDL_SetTextureAlphaMod((SDL_Texture *)sprite->spritesheet->texture, sprite->opacity); } uint32_t ARC_Sprite_GetFrameIndex(ARC_Sprite *sprite){ - return *sprite->frameIndex; + return sprite->frameIndex; } -ARC_Rect *ARC_Sprite_GetBounds(ARC_Sprite *sprite){ - return (ARC_Rect *)sprite->frames->data + *sprite->frameIndex; +ARC_FRect *ARC_Sprite_GetBounds(ARC_Sprite *sprite){ + return (ARC_FRect *)sprite->frames.data + sprite->frameIndex; } -ARC_Array *ARC_Sprite_GetAllBounds(ARC_Sprite *sprite){ +ARC_Array ARC_Sprite_GetAllBounds(ARC_Sprite *sprite){ return sprite->frames; } diff --git a/packages/graphics/sdl3/sprite.h b/packages/graphics/sdl3/sprite.h deleted file mode 100644 index ced571a..0000000 --- a/packages/graphics/sdl3/sprite.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef ARC_SDL_SPRITE_H_ -#define ARC_SDL_SPRITE_H_ - -#include "arc/graphics/sprite.h" - -struct ARC_Sprite { - ARC_Spritesheet *spritesheet; - ARC_Array *frames; - uint32_t *frameIndex; - //TODO: temp - uint8_t opacity; -}; - -#endif // !ARC_SDL_SPRITE_H_