diff --git a/include/app.h b/include/app.h index c91a89f..f1e79e5 100644 --- a/include/app.h +++ b/include/app.h @@ -1,202 +1,21 @@ -#ifndef APPTYPES_H -#define APPTYPES_H +#ifndef APP_H +#define APP_H -// INCLUDES// -#include #include -// DEFINES// -#define TEXT_COLOR_DARK (Color){182, 137, 98, 255} -#define TEXT_COLOR_LIGHT (Color){243, 229, 194, 255} -#define STORAGE_DATA_FILE "save1.data" +#include "appCore.h" +#include "collisions.h" +#include "engineAssets.h" +#include "engineCamera.h" +#include "engineConfig.h" +#include "engineFont.h" +#include "engineWindow.h" +#include "game.h" +#include "gameover.h" +#include "logo.h" +#include "menu.h" -// ENUMS// -typedef enum { - MENU_CURSOR_TEX, - MENU_BIG_BUTTONS_TEX, - MENU_BOARD_TEX, - MENU_CLOUD_BACKGROUND, - MENU_CLOUD_MIDGROUND, - MENU_CLOUD_FOREGROUND, - MENU_TEX_COUNT -} MenuTextureID; - -typedef enum { MENU_MUSIC, MENU_SOUNDTRACK_COUNT } MenuSoundtrackID; - -typedef enum { HOVER_SOUND, CLICK_SOUND, MENU_SOUND_COUNT } MenuSoundID; - -typedef enum MenuView { MAIN = 0, SETTINGS = 1 } MenuView; - -typedef enum { START_SHIP, PLAYER_TEX_COUNT } playerTextureID; - -typedef enum { ANCHOR, SLOW_AHEAD, FAST_AHEAD, SPEED_COUNT } playerSpeedID; - -typedef enum { ISLAND, ISLANDS_TEX_COUNT } islandsTextureID; - -typedef enum { POST_FX, SHADER_COUNT } ShaderID; - -typedef enum { GAMEPLAY_THEME, AMBIENT, SOUNDTRACK_COUNT } SoundtrackID; - -typedef enum View { LOGO = 0, MENU = 1, GAMEPLAY = 2 } View; - -typedef enum { - STORAGE_POSITION_GOLD = 0, - STORAGE_POSITION_POSX = 1, - STORAGE_POSITION_POSY = 2, - STORAGE_POSITION_ROTATION = 3 -} StorageData; - -// STRUCTS// -typedef struct { - int frameCounter; - int positionX; - int positionY; - int lettersCount; - int topSideRecWidth; - int leftSideRecHeight; - int bottomSideRecWidth; - int rightSideRecHeight; - int state; - float alpha; -} LogoState; - -typedef struct { - Sprite sprite; - float scrolling; - float scale; - float scrollSpeed; - Vector2 pos; -} Background; - -typedef struct { - Assets assets; - Mouse mouse; - Texture2D textures[MENU_TEX_COUNT]; - Sound sounds[MENU_SOUND_COUNT]; - Soundtrack soundtracks[MENU_SOUNDTRACK_COUNT]; - ImageElement board; - ImageButton playButton; - ImageButton quitButton; - ImageButton settingsButton; - int menuScale; - Background background; - Background midground; - Background foreground; -} MenuMain; - -typedef struct { - Button showFPS; - Button limitFPS; - Button soundtrackOn; -} MenuSettings; - -typedef struct { - MenuView menuView; - MenuMain menuMain; - MenuSettings menuSettings; -} MenuState; - -typedef struct { - Sprite sprite; - Rectangle bounds; - Shader shader; - float time; -} Floor; - -typedef struct { - Sprite sprite; - Animation animation; - Physics physics; - float rotation; - Sound soundFlapping; - int health; - int gold; -} Player; - -typedef enum { BOAT, ENEMIES_TEX_COUNT } enemiesTextureID; - -typedef enum { START, SHIP_COUNT } shipID; - -typedef struct { - int id; - char *assetPath; - int frameSize; - int speed0; - int speed1; - int speed2; - int rotationSpeed; -} Ship; - -#define MAX_ENEMIES 100 - -typedef struct { - Config config; - int count; - Sprite sprite[MAX_ENEMIES]; - Animation animation[MAX_ENEMIES]; - Physics physics[MAX_ENEMIES]; - bool arrived[MAX_ENEMIES]; - Vector2 destPos[MAX_ENEMIES]; - bool alive[MAX_ENEMIES]; -} Enemies; - -typedef enum { FLYING, BIRDS_TEX_COUNT } birdsTextureID; - -#define MAX_BIRDS 100 - -typedef struct { - int count; - Sprite sprite[MAX_BIRDS]; - Animation animation[MAX_BIRDS]; - Physics physics[MAX_BIRDS]; - bool arrived[MAX_BIRDS]; - Vector2 destPos[MAX_BIRDS]; -} Birds; - -typedef struct { - Sprite sprite; - Animation animation; - Physics physics; -} Islands; - -#define MAX_PROJECTILES 100 -typedef struct { - int count; - Physics physics[MAX_PROJECTILES]; - bool active[MAX_PROJECTILES]; - float radius[MAX_PROJECTILES]; - Color color[MAX_PROJECTILES]; - Sound soundShooting[MAX_PROJECTILES]; - Sound soundImpact[MAX_PROJECTILES]; -} Projectiles; - -typedef struct { - Assets assets; - PostProcessing postFX[SHADER_COUNT]; - Soundtrack soundtracks[SOUNDTRACK_COUNT]; - RenderTexture2D target; - Floor floor; - Birds birds; - Enemies enemies; - Islands islands; - Mouse mouse; - Image image; - Projectiles projectiles; -} GameState; - -typedef struct { - View currentView; - bool running; - bool gameStarted; -} State; - -typedef struct { - bool showFPS; - bool limitFPS; - bool soundtrackOn; -} Flags; - -typedef struct { +struct App { Config config; State state; Flags flags; @@ -205,75 +24,11 @@ typedef struct { LogoState logo; MenuState menu; GameState game; -} App; - -// FUNCTIONS// -void InitLogo(LogoState *l); -void UpdateLogo(LogoState *l, View *currentView, bool *running); -void RenderLogo(const LogoState *l, Flags *flags); - -void InitBackground(float scrollSpeed, Background *bg, Texture2D *texture, - const TextureAsset *backgroundAsset); -void UpdateBackground(Background *bg); -void RenderBackground(Background *bg); - -void InitMenuMain(MenuMain *m); -void UpdateMenuMain(MenuMain *m, State *state, Flags *flags, - MenuView *menuView); -void RenderMenuMain(MenuMain *m, Font *font, const char *title, Flags *flags); -void CleanupMenuMain(MenuMain *m); - -void InitMenuSettings(MenuSettings *s); -void UpdateMenuSettings(MenuSettings *s, MenuView *menuView, State *state, - Flags *flags); -void RenderMenuSettings(MenuSettings *s, Flags *flags); -void CleanupMenuSettings(MenuSettings *s); - -void InitMenu(MenuState *m); -void UpdateMenu(MenuState *m, State *state, Flags *flags); -void RenderMenu(MenuState *m, Font *font, const char *title, Flags *flags); -void CleanupMenu(MenuState *m); - -Floor CreateFloor(void); -void UpdateFloor(Floor *floor); -void RenderFloor(Floor *floor); -void UnloadFloor(Floor *floor); - -playerSpeedID GetPlayerSpeedID(float speed); -Player *GetPlayer(void); -void CreatePlayer(void); -void UpdatePlayer(void); -void RenderPlayer(void); - -Enemies CreateEnemies(void); -void UpdateEnemies(Enemies *enemies); -void RenderEnemies(Enemies *enemies); - -Birds CreateBirds(void); -void UpdateBirds(Birds *birds); -void RenderBirds(Birds *birds); - -Islands CreateIslands(void); -void UpdateIslands(Islands *islands); -void RenderIslands(Islands *islands); - -Projectiles CreateProjectiles(void); -void UpdateProjectiles(Projectiles *projectiles, Enemies *enemies); -void RenderProjectiles(Projectiles *projectiles); - -void CheckPlayerCollisions(Player *player, Enemies *enemies); -void CheckEnemyCollisions(Enemies *enemies); -void CheckProjectileCollisions(Projectiles *projectiles, Enemies *enemies, - Player *player); - -void InitGame(App *app); -void UpdateGame(App *app); -void RenderComponents(App *app); -void RenderOverlay(Mouse *mouse); -void RenderGame(App *app); -void CleanupGame(App *app); + GameOverState gameOver; +}; void OnEscapeChangeView(App *app, View view); +void OnBoolChangeView(bool flag, App *app, View view); void OnWindowClosedStoppApp(App *app); void ConfigApp(App *app); @@ -281,4 +36,4 @@ void InitApp(App *app); void UpdateApp(App *app); void CleanupApp(App *app); -#endif // APPTYPES_H +#endif diff --git a/include/appCore.h b/include/appCore.h new file mode 100644 index 0000000..39922a7 --- /dev/null +++ b/include/appCore.h @@ -0,0 +1,42 @@ +#ifndef APP_CORE_H +#define APP_CORE_H + +#include +#include + +typedef struct App App; + +#define TEXT_COLOR_DARK (Color){182, 137, 98, 255} +#define TEXT_COLOR_LIGHT (Color){243, 229, 194, 255} +#define STORAGE_DATA_FILE "save1.data" + +typedef enum View { LOGO = 0, MENU = 1, GAMEPLAY = 2, GAMEOVER = 3 } View; + +typedef enum { + ACTION_FORWARD, + ACTION_BACKWARD, + ACTION_TURN_LEFT, + ACTION_TURN_RIGHT, + ACTION_FIRE_PORT, + ACTION_FIRE_STARBOARD, + ACTION_BACK, + ACTION_COUNT +} GameAction; + +typedef struct { + View currentView; + bool running; + bool gameStarted; + bool restartRequested; +} State; + +typedef struct { + bool showFPS; + bool limitFPS; + bool soundtrackOn; +} Flags; + +bool IsGameActionPressed(GameAction action); +bool IsGameActionDown(GameAction action); + +#endif diff --git a/include/birds.h b/include/birds.h new file mode 100644 index 0000000..c235fe7 --- /dev/null +++ b/include/birds.h @@ -0,0 +1,28 @@ +#ifndef BIRDS_H +#define BIRDS_H + +#include +#include + +#include "engineAnimation.h" +#include "enginePhysics.h" +#include "engineSprite.h" + +typedef enum { FLYING, BIRDS_TEX_COUNT } BirdsTextureID; + +#define MAX_BIRDS 100 + +typedef struct { + int count; + Sprite sprite[MAX_BIRDS]; + Animation animation[MAX_BIRDS]; + Physics physics[MAX_BIRDS]; + bool arrived[MAX_BIRDS]; + Vector2 destPos[MAX_BIRDS]; +} Birds; + +Birds CreateBirds(Camera2D *camera); +void UpdateBirds(Birds *birds, Camera2D *camera); +void RenderBirds(Birds *birds); + +#endif diff --git a/include/clouds.h b/include/clouds.h new file mode 100644 index 0000000..12aeae6 --- /dev/null +++ b/include/clouds.h @@ -0,0 +1,18 @@ +#ifndef CLOUDS_H +#define CLOUDS_H + +#include + +typedef struct { + Shader shader; + float time; + float coverage; +} Clouds; + +Clouds CreateClouds(void); +void UpdateClouds(Clouds *clouds, float deltaTime); +void RenderCloudShadows(Clouds *clouds, Camera2D *camera); +void RenderClouds(Clouds *clouds, Camera2D *camera); +void UnloadClouds(Clouds *clouds); + +#endif diff --git a/include/collisions.h b/include/collisions.h new file mode 100644 index 0000000..ae5aa07 --- /dev/null +++ b/include/collisions.h @@ -0,0 +1,15 @@ +#ifndef COLLISIONS_H +#define COLLISIONS_H + +#include "player.h" +#include "enemies.h" +#include "terrain.h" +#include "projectiles.h" + +void CheckPlayerCollisions(Player *player, Enemies *enemies); +void CheckEnemyCollisions(Enemies *enemies); +void CheckProjectileCollisions(Projectiles *projectiles, Enemies *enemies, + Player *player); +void CheckTerrainCollisions(Player *player, Enemies *enemies, Terrain *terrain); + +#endif // COLLISIONS_H diff --git a/include/enemies.h b/include/enemies.h new file mode 100644 index 0000000..2fb8912 --- /dev/null +++ b/include/enemies.h @@ -0,0 +1,43 @@ +#ifndef ENEMIES_H +#define ENEMIES_H + +#include +#include + +#include "engineAnimation.h" +#include "enginePhysics.h" +#include "engineSprite.h" +#include "pathfinding.h" +#include "player.h" +#include "projectiles.h" +#include "terrain.h" +#include "wake.h" + +typedef enum { BOAT, ENEMIES_TEX_COUNT } EnemiesTextureID; + +#define MAX_ENEMIES 100 + +typedef struct { + int count; + Sprite sprite[MAX_ENEMIES]; + Animation animation[MAX_ENEMIES]; + Physics physics[MAX_ENEMIES]; + bool arrived[MAX_ENEMIES]; + Vector2 destPos[MAX_ENEMIES]; + Vector2 path[MAX_ENEMIES][PATH_MAX_WAYPOINTS]; + int pathLength[MAX_ENEMIES]; + int pathIndex[MAX_ENEMIES]; + bool alive[MAX_ENEMIES]; + float reloadTimer[MAX_ENEMIES]; + float destinationCooldown[MAX_ENEMIES]; + bool chasing[MAX_ENEMIES]; + float chaseRepathTimer[MAX_ENEMIES]; + WakeTrail wakeTrail[MAX_ENEMIES]; +} Enemies; + +Enemies CreateEnemies(Camera2D *camera, Terrain *terrain); +void UpdateEnemies(Enemies *enemies, Camera2D *camera, Projectiles *projectiles, Player *player, + Terrain *terrain); +void RenderEnemies(Enemies *enemies); + +#endif diff --git a/include/engine.h b/include/engine.h index 61acc35..e2983ae 100644 --- a/include/engine.h +++ b/include/engine.h @@ -118,6 +118,13 @@ typedef struct { float weight; } Physics; +typedef struct { + bool overlapping; + bool hasDirection; // false when centers coincide, direction/overlap unset + Vector2 direction; // normalized, points from B to A + float overlap; +} CircleCollision; + typedef struct { Shader shader; int resolutionLoc; @@ -152,13 +159,12 @@ void UpdateArray(Array *array, void (*updateFunc)(void *)); void RenderArray(Array *array, void (*renderFunc)(void *)); void FreeArray(Array **array); -Camera2D *GetCamera(void); -Rectangle GetCameraRectangle(void); -void CreateCamera(Vector2 playerPosition, float initZoom); -void UpdateCameraTarget(Vector2 *position, const float smoothness); -void UpdateCameraZoom(const float *scaleFactor, const float *minZoom, +Rectangle GetCameraRectangle(Camera2D *camera); +Camera2D CreateCamera(Vector2 playerPosition, float initZoom); +void UpdateCameraTarget(Camera2D *camera, Vector2 *position, const float smoothness); +void UpdateCameraZoom(Camera2D *camera, const float *scaleFactor, const float *minZoom, const float *maxZoom); -void UpdateCamera2D(Vector2 *position, Mouse *mouse); +void UpdateCamera2D(Camera2D *camera, Vector2 *position, Mouse *mouse); void InitConfig(Config *config, const char *path); int GetConfigInt(Config *config, const char *key); @@ -182,6 +188,10 @@ ImageButton CreateImageButton(ButtonState state, Texture2D *texture, const TextureAsset *asset, Vector2 *source, Vector2 *clicked, Vector2 *hover, Rectangle *destRec); +ImageButton CreateMenuButton(Texture2D *texture, const TextureAsset *asset, + int textureRow, int screenRank, int buttonWidth, + int buttonHeight, Vector2 windowCenter, + int buttonSpacing); ImageElement CreateImageElement(Texture2D *texture, const TextureAsset *asset, Vector2 *source, Rectangle *destRec); int isImageButtonClicked(ImageButton *b, Sound soundHover, Sound soundClick); @@ -195,7 +205,7 @@ void renderButton(Button *b); Mouse CreateMouse(float zoomSpeed, float minZoom, float maxZoom, Texture2D *texture); void UpdateMouseScreen(Mouse *mouse); -void UpdateMouse(Mouse *mouse); +void UpdateMouse(Mouse *mouse, Camera2D *camera); Vector2 GetDirectionVector(void); ObjectArray CreateObjectArray(const Object *prototype, const size_t count); @@ -220,6 +230,9 @@ void UpdatePhysicsPosition(Vector2 *position, Vector2 *velocity); void UpdatePhysicsSpeed(float *speed, float *newSpeed); void UpdatePhysics(Physics *physics, Vector2 direction); +CircleCollision CheckCircleCollision(Vector2 posA, float radiusA, + Vector2 posB, float radiusB); + PostProcessing CreatePostFX(const char *shaderPath); void UpdatePostFX(PostProcessing *postFX); void RenderPostFX(PostProcessing *postFX, RenderTexture2D *target); @@ -243,7 +256,11 @@ float Cross2D(Vector2 a, Vector2 b); Vector2 GetPositionInsideRectangle(Rectangle rec); Vector2 GetPositionOutsideRectangle(Rectangle rec, int min, int max); -bool SaveStorageValue(const char *fileName, unsigned int position, int value); -int LoadStorageValue(const char *fileName, unsigned int position); +bool SaveStorageData(const char *fileName, int version, const void *data, unsigned int dataSize); +bool LoadStorageData(const char *fileName, int expectedVersion, void *data, unsigned int dataSize); + +Texture2D LoadTextureCached(const char *path); +Sound LoadSoundCached(const char *path); +void UnloadCachedAssets(void); #endif // ENGINE_H diff --git a/include/engineAnimation.h b/include/engineAnimation.h new file mode 100644 index 0000000..4c3736d --- /dev/null +++ b/include/engineAnimation.h @@ -0,0 +1,15 @@ +#ifndef ENGINE_ANIMATION_H +#define ENGINE_ANIMATION_H + +typedef struct { + int state; + int currentFrame; + int maxFrame; + int framesCounter; + int framesSpeed; + float animTimer; +} Animation; + +void UpdateAnimation(Animation *animation, float deltaTime); + +#endif diff --git a/include/engineArray.h b/include/engineArray.h new file mode 100644 index 0000000..16abcfb --- /dev/null +++ b/include/engineArray.h @@ -0,0 +1,50 @@ +#ifndef ENGINE_ARRAY_H +#define ENGINE_ARRAY_H + +#include "engineSprite.h" +#include "enginePhysics.h" +#include "engineVector.h" +#include +#include + +typedef struct { + void **elements; + unsigned int count; + unsigned int capacity; +} Array; + +typedef struct { + Sprite sprite; + Vector2 position; +} Object; + +typedef struct { + Object *data; + const Object *prototype; + size_t count; +} ObjectArray; + +Array *CreateArray(unsigned int initCapacity); +int AddElementToArray(Array *array, void *element); +int RemoveElementFromArray(Array *array, unsigned int index); +void *GetRandomElementFromArray(Array *array); +void UpdateArray(Array *array, void (*updateFunc)(void *)); +void RenderArray(Array *array, void (*renderFunc)(void *)); +void FreeArray(Array **array); + +ObjectArray CreateObjectArray(const Object *prototype, const size_t count); +Object *GetRandomObject(ObjectArray *objects); +void AddObjectToArray(ObjectArray *objects, const Object *prototype, + Vector2 position); +void SetPositionForObjectArray(ObjectArray *objects, + const Vector2Array *positions); +void SetRandomPositionForObjectArray(ObjectArray *objects, + const Rectangle bounds); +void SwapAndPopObjectsArrayOnRecCollision(ObjectArray *objects, + const Rectangle rec); +void SwapAndPopObjectsArrayOnPointCollision(ObjectArray *objects, + const Vector2 point); +Vector2 GetDirectionToObject(Object *object, Vector2 position); +void RenderObjectArray(const ObjectArray *objects); + +#endif // ENGINE_ARRAY_H diff --git a/include/engineAssets.h b/include/engineAssets.h new file mode 100644 index 0000000..50ca459 --- /dev/null +++ b/include/engineAssets.h @@ -0,0 +1,10 @@ +#ifndef ENGINE_ASSETS_H +#define ENGINE_ASSETS_H + +#include + +Texture2D LoadTextureCached(const char *path); +Sound LoadSoundCached(const char *path); +void UnloadCachedAssets(void); + +#endif // ENGINE_ASSETS_H diff --git a/include/engineCamera.h b/include/engineCamera.h new file mode 100644 index 0000000..908d12e --- /dev/null +++ b/include/engineCamera.h @@ -0,0 +1,14 @@ +#ifndef ENGINE_CAMERA_H +#define ENGINE_CAMERA_H + +#include "engineInput.h" +#include + +Rectangle GetCameraRectangle(Camera2D *camera); +Camera2D CreateCamera(Vector2 playerPosition, float initZoom); +void UpdateCameraTarget(Camera2D *camera, Vector2 *position, const float smoothness); +void UpdateCameraZoom(Camera2D *camera, const float *scaleFactor, const float *minZoom, + const float *maxZoom); +void UpdateCamera2D(Camera2D *camera, Vector2 *position, Mouse *mouse); + +#endif // ENGINE_CAMERA_H diff --git a/include/engineConfig.h b/include/engineConfig.h new file mode 100644 index 0000000..78792e2 --- /dev/null +++ b/include/engineConfig.h @@ -0,0 +1,25 @@ +#ifndef ENGINE_CONFIG_H +#define ENGINE_CONFIG_H + +#include +#include + +typedef struct { + char *path; + rini_data rini; +} Config; + +void InitConfig(Config *config, const char *path); +int GetConfigInt(Config *config, const char *key); +int GetConfigIntOrDefault(Config *config, const char *key, int default_value); +const char *GetConfigString(Config *config, const char *key); +const char *GetConfigStringOrDefault(Config *config, const char *key, const char *default_value); +const char *GetConfigDescription(Config *config, const char *key); +int SetConfigInt(Config *config, const char *key, int value, const char *desc); +int SetConfigString(Config *config, const char *key, const char *text, const char *desc); +int SetConfigDescription(Config *config, const char *key, const char *desc); +int AddCommentLine(Config *config, const char *comment); +void SaveConfig(Config *config); +void CleanUpConfig(Config *config); + +#endif diff --git a/include/engineFont.h b/include/engineFont.h new file mode 100644 index 0000000..9e75466 --- /dev/null +++ b/include/engineFont.h @@ -0,0 +1,9 @@ +#ifndef ENGINE_FONT_H +#define ENGINE_FONT_H + +#include + +void InitFont(Font *font, const char *path); +void CleanupFont(Font *font); + +#endif diff --git a/include/engineGui.h b/include/engineGui.h new file mode 100644 index 0000000..3d8841b --- /dev/null +++ b/include/engineGui.h @@ -0,0 +1,42 @@ +#ifndef ENGINE_GUI_H +#define ENGINE_GUI_H + +#include +#include + +#include "engineSprite.h" + +typedef struct { + Sprite sprite; + Vector2 notClicked; + Vector2 hover; + Vector2 clicked; + bool isHovered; + bool isClicked; +} ImageButton; + +typedef struct { + Sprite sprite; +} ImageElement; + +typedef struct { + Rectangle rec; + char *text; +} Button; + +ImageButton CreateImageButton(Texture2D *texture, const TextureAsset *asset, Vector2 *source, + Vector2 *clicked, Vector2 *hover, Rectangle *destRec); +ImageButton CreateMenuButton(Texture2D *texture, const TextureAsset *asset, int textureRow, + int screenRank, int buttonWidth, int buttonHeight, + Vector2 windowCenter, int buttonSpacing); +ImageElement CreateImageElement(Texture2D *texture, const TextureAsset *asset, Vector2 *source, + Rectangle *destRec); +int isImageButtonClicked(ImageButton *b, Sound soundHover, Sound soundClick); +void renderImageButton(ImageButton *b); +void renderImageElement(ImageElement *e); + +Button initButton(char *text, Vector2 dimensions, Vector2 position); +int isButtonClicked(Button *b); +void renderButton(Button *b); + +#endif diff --git a/include/engineInput.h b/include/engineInput.h new file mode 100644 index 0000000..bf36d42 --- /dev/null +++ b/include/engineInput.h @@ -0,0 +1,25 @@ +#ifndef ENGINE_INPUT_H +#define ENGINE_INPUT_H + +#include + +typedef struct { + Vector2 screenPosition; + Vector2 worldPosition; + float zoomSpeed; + float minZoom; + float maxZoom; + float scaleFactor; + float wheelMove; + bool leftButton; + bool rightButton; + Texture2D cursorTexture; +} Mouse; + +Mouse CreateMouse(float zoomSpeed, float minZoom, float maxZoom, + Texture2D *texture); +void UpdateMouseScreen(Mouse *mouse); +void UpdateMouse(Mouse *mouse, Camera2D *camera); +Vector2 GetDirectionVector(void); + +#endif // ENGINE_INPUT_H diff --git a/include/enginePhysics.h b/include/enginePhysics.h new file mode 100644 index 0000000..3ea73da --- /dev/null +++ b/include/enginePhysics.h @@ -0,0 +1,31 @@ +#ifndef ENGINE_PHYSICS_H +#define ENGINE_PHYSICS_H + +#include +#include + +typedef struct { + Vector2 position; + Vector2 direction; + Vector2 velocity; + float speed; + float weight; +} Physics; + +typedef struct { + bool overlapping; + bool hasDirection; + Vector2 direction; + float overlap; +} CircleCollision; + +void UpdatePhysicsDirection(Vector2 *direction, Vector2 vector); +void UpdatePhysicsVelocity(Vector2 *velocity, Vector2 *direction, float *speed); +void UpdatePhysicsPosition(Vector2 *position, Vector2 *velocity); +void UpdatePhysicsSpeed(float *speed, float *newSpeed); +void UpdatePhysics(Physics *physics, Vector2 direction); +float GetActualSpeed(Physics *physics); + +CircleCollision CheckCircleCollision(Vector2 posA, float radiusA, Vector2 posB, float radiusB); + +#endif diff --git a/include/enginePostfx.h b/include/enginePostfx.h new file mode 100644 index 0000000..481a8c0 --- /dev/null +++ b/include/enginePostfx.h @@ -0,0 +1,21 @@ +#ifndef ENGINE_POSTFX_H +#define ENGINE_POSTFX_H + +#include + +typedef struct { + Shader shader; + int resolutionLoc; + int strengthLoc; + int timeLoc; + float strength; + float time; +} PostProcessing; + +PostProcessing CreatePostFX(const char *shaderPath); +void UpdatePostFX(PostProcessing *postFX); +void UpdateShaders(PostProcessing *postFX, int count); +void RenderPostFX(PostProcessing *postFX, RenderTexture2D *target); +void UnloadPostFX(PostProcessing *postFX); + +#endif // ENGINE_POSTFX_H diff --git a/include/engineRectangle.h b/include/engineRectangle.h new file mode 100644 index 0000000..a1c886b --- /dev/null +++ b/include/engineRectangle.h @@ -0,0 +1,9 @@ +#ifndef ENGINE_RECTANGLE_H +#define ENGINE_RECTANGLE_H + +#include + +Vector2 GetPositionInsideRectangle(Rectangle rec); +Vector2 GetPositionOutsideRectangle(Rectangle rec, int min, int max); + +#endif diff --git a/include/engineSoundtrack.h b/include/engineSoundtrack.h new file mode 100644 index 0000000..c057d79 --- /dev/null +++ b/include/engineSoundtrack.h @@ -0,0 +1,16 @@ +#ifndef ENGINE_SOUNDTRACK_H +#define ENGINE_SOUNDTRACK_H + +#include +#include + +typedef struct { + Music music; + bool playing; + bool paused; +} Soundtrack; + +Soundtrack LoadSoundtrack(const char *musicPath); +void UpdateSoundtrack(Soundtrack *soundtrack, bool playing); + +#endif // ENGINE_SOUNDTRACK_H diff --git a/include/engineSprite.h b/include/engineSprite.h new file mode 100644 index 0000000..2ac9f6d --- /dev/null +++ b/include/engineSprite.h @@ -0,0 +1,49 @@ +#ifndef ENGINE_SPRITE_H +#define ENGINE_SPRITE_H + +#include + +typedef struct { + Texture2D texture; + Rectangle sourceRec; + Rectangle destRec; + Vector2 frameSize; + Vector2 origin; + float rotation; + Color color; +} Sprite; + +typedef struct { + const char *path; + float frameWidth; + float frameHeight; + float rotation; +} TextureAsset; + +typedef struct { + const char *path; +} ShaderAsset; + +typedef struct { + const char *path; +} SoundtrackAsset; + +typedef struct { + const char *path; +} SoundAsset; + +typedef struct { + const TextureAsset *textureAssets; + const ShaderAsset *shaderAssets; + const SoundtrackAsset *soundtrackAssets; + const SoundAsset *soundAssets; +} Assets; + +void UpdateSpriteSourceRec(Sprite *sprite, const Vector2 *vector); +void UpdateSpriteDestRec(Sprite *sprite, const Vector2 *vector); +void UpdateSpriteRotation(Sprite *sprite, float rotation); +void UpdateSpriteRotationTowards(Sprite *sprite, float rotation, float degreesPerSecond, + float deltaTime); +void RenderSprite(const Sprite *sprite); + +#endif diff --git a/include/engineStorage.h b/include/engineStorage.h new file mode 100644 index 0000000..79951c5 --- /dev/null +++ b/include/engineStorage.h @@ -0,0 +1,9 @@ +#ifndef ENGINE_STORAGE_H +#define ENGINE_STORAGE_H + +#include + +bool SaveStorageData(const char *fileName, int version, const void *data, unsigned int dataSize); +bool LoadStorageData(const char *fileName, int expectedVersion, void *data, unsigned int dataSize); + +#endif // ENGINE_STORAGE_H diff --git a/include/engineVector.h b/include/engineVector.h new file mode 100644 index 0000000..52dc479 --- /dev/null +++ b/include/engineVector.h @@ -0,0 +1,22 @@ +#ifndef ENGINE_VECTOR_H +#define ENGINE_VECTOR_H + +#include +#include +#include + +typedef struct { + Vector2 *data; + size_t count; +} Vector2Array; + +Vector2 GetDirectionBetweenTwoVectors(Vector2 vec1, Vector2 vec2); +float GetDistanceBetweenTwoVectors(Vector2 vec1, Vector2 vec2); +bool IsVectorZero(Vector2 v); +Vector2 GetRandomVector(const Rectangle bounds); +Vector2 RotationToVector2(float rotation); +float Vector2ToRotation(Vector2 vec); +float Cross2D(Vector2 a, Vector2 b); +void ApplyCollisionSteer(float *rotation, float side, float deltaTime); + +#endif diff --git a/include/engineWindow.h b/include/engineWindow.h new file mode 100644 index 0000000..5552cbc --- /dev/null +++ b/include/engineWindow.h @@ -0,0 +1,10 @@ +#ifndef ENGINE_WINDOW_H +#define ENGINE_WINDOW_H + +typedef struct { + int width; + int height; + const char *title; +} Window; + +#endif // ENGINE_WINDOW_H diff --git a/include/floor.h b/include/floor.h new file mode 100644 index 0000000..2f4b1e4 --- /dev/null +++ b/include/floor.h @@ -0,0 +1,26 @@ +#ifndef FLOOR_H +#define FLOOR_H + +#include + +#include "engineSprite.h" + +typedef struct { + Sprite sprite; + Rectangle bounds; + Shader shader; + float time; + Texture2D causticTexture; + Texture2D causticHighlightTexture; + Texture2D noiseTexture; + Texture2D cloudTexture; + Texture2D voronoiseTexture; + Texture2D depthGradientTexture; +} Floor; + +Floor CreateFloor(void); +void UpdateFloor(Floor *floor, Camera2D *camera); +void RenderFloor(Floor *floor); +void UnloadFloor(Floor *floor); + +#endif diff --git a/include/game.h b/include/game.h new file mode 100644 index 0000000..9335702 --- /dev/null +++ b/include/game.h @@ -0,0 +1,51 @@ +#ifndef GAME_H +#define GAME_H + +#include + +#include "appCore.h" +#include "birds.h" +#include "clouds.h" +#include "enemies.h" +#include "engineInput.h" +#include "enginePostfx.h" +#include "engineSoundtrack.h" +#include "engineSprite.h" +#include "floor.h" +#include "player.h" +#include "projectiles.h" +#include "terrain.h" +#include "wake.h" +#include "overlay.h" + +typedef enum { POST_FX, SHADER_COUNT } ShaderID; +typedef enum { GAMEPLAY_THEME, AMBIENT, SOUNDTRACK_COUNT } SoundtrackID; + +typedef struct { + Assets assets; + PostProcessing postFX[SHADER_COUNT]; + Soundtrack soundtracks[SOUNDTRACK_COUNT]; + RenderTexture2D target; + RenderTexture2D postFXTarget; + Camera2D camera; + Player player; + Floor floor; + Clouds clouds; + Wake wake; + Birds birds; + Enemies enemies; + Terrain terrain; + Mouse mouse; + Image image; + Projectiles projectiles; + Overlay overlay; +} GameState; + +void InitGame(App *app); +void UpdateGame(App *app); +void RenderComponents(App *app); +void RenderGame(App *app); +void ResetGame(App *app); +void CleanupGame(App *app); + +#endif diff --git a/include/gameover.h b/include/gameover.h new file mode 100644 index 0000000..1b7109c --- /dev/null +++ b/include/gameover.h @@ -0,0 +1,15 @@ +#ifndef GAMEOVER_H +#define GAMEOVER_H + +#include "appCore.h" +#include "engineGui.h" + +typedef struct { + Button restartButton; +} GameOverState; + +void InitGameOver(GameOverState *g); +void UpdateGameOver(App *app); +void RenderGameOver(App *app); + +#endif diff --git a/include/islands.h b/include/islands.h new file mode 100644 index 0000000..dd07f8f --- /dev/null +++ b/include/islands.h @@ -0,0 +1,31 @@ +#ifndef ISLANDS_H +#define ISLANDS_H + +#include "engineSprite.h" +#include + +#define MAX_ISLANDS 14 +// Perimeter samples used to build each island's procedural shape (see +// GenerateIsland in appGameIslands.c). Higher than you'd need for the old +// small islands since they're now rendered at much higher native resolution +// and a coarser sample count would show as flat facets on the coastline. +#define ISLAND_SHAPE_POINTS 28 + +typedef struct { + Vector2 position; + float radius; // collision radius (outer shore edge), in world units + Sprite sprite; // a small procedurally-painted texture, point-filtered like + // the rest of the cast, not a shader effect +} Island; + +typedef struct { + int count; + Island island[MAX_ISLANDS]; +} Islands; + +Islands CreateIslands(Camera2D *camera); +void UpdateIslands(Islands *islands, Camera2D *camera); +void RenderIslands(Islands *islands); +void UnloadIslands(Islands *islands); + +#endif // ISLANDS_H diff --git a/include/logo.h b/include/logo.h new file mode 100644 index 0000000..544d8cf --- /dev/null +++ b/include/logo.h @@ -0,0 +1,24 @@ +#ifndef LOGO_H +#define LOGO_H + +#include "appCore.h" +#include + +typedef struct { + int frameCounter; + int positionX; + int positionY; + int lettersCount; + int topSideRecWidth; + int leftSideRecHeight; + int bottomSideRecWidth; + int rightSideRecHeight; + int state; + float alpha; +} LogoState; + +void InitLogo(LogoState *l); +void UpdateLogo(LogoState *l, View *currentView, bool *running); +void RenderLogo(const LogoState *l, Flags *flags); + +#endif // LOGO_H diff --git a/include/menu.h b/include/menu.h new file mode 100644 index 0000000..1f659fe --- /dev/null +++ b/include/menu.h @@ -0,0 +1,85 @@ +#ifndef MENU_H +#define MENU_H + +#include + +#include "appCore.h" +#include "engineGui.h" +#include "engineInput.h" +#include "engineSoundtrack.h" +#include "engineSprite.h" + +typedef enum { + MENU_CURSOR_TEX, + MENU_BIG_BUTTONS_TEX, + MENU_BOARD_TEX, + MENU_CLOUD_BACKGROUND, + MENU_CLOUD_MIDGROUND, + MENU_CLOUD_FOREGROUND, + MENU_TEX_COUNT +} MenuTextureID; + +typedef enum { MENU_MUSIC, MENU_SOUNDTRACK_COUNT } MenuSoundtrackID; + +typedef enum { HOVER_SOUND, CLICK_SOUND, MENU_SOUND_COUNT } MenuSoundID; + +typedef enum MenuView { MAIN = 0, SETTINGS = 1 } MenuView; + +typedef struct { + Sprite sprite; + float scrolling; + float scale; + float scrollSpeed; + Vector2 pos; +} Background; + +typedef struct { + Assets assets; + Mouse mouse; + Texture2D textures[MENU_TEX_COUNT]; + Sound sounds[MENU_SOUND_COUNT]; + Soundtrack soundtracks[MENU_SOUNDTRACK_COUNT]; + ImageElement board; + ImageButton playButton; + ImageButton quitButton; + ImageButton settingsButton; + Button restartButton; + int menuScale; + Background background; + Background midground; + Background foreground; +} MenuMain; + +typedef struct { + Button showFPS; + Button limitFPS; + Button soundtrackOn; +} MenuSettings; + +typedef struct { + MenuView menuView; + MenuMain menuMain; + MenuSettings menuSettings; +} MenuState; + +void InitBackground(float scrollSpeed, Background *bg, Texture2D *texture, + const TextureAsset *backgroundAsset); +void UpdateBackground(Background *bg); +void RenderBackground(Background *bg); + +void InitMenuMain(MenuMain *m); +void UpdateMenuMain(MenuMain *m, State *state, Flags *flags, MenuView *menuView); +void RenderMenuMain(MenuMain *m, Font *font, const char *title, Flags *flags, bool gameStarted); +void CleanupMenuMain(MenuMain *m); + +void InitMenuSettings(MenuSettings *s); +void UpdateMenuSettings(MenuSettings *s, MenuView *menuView, State *state, Flags *flags); +void RenderMenuSettings(MenuSettings *s, Flags *flags); +void CleanupMenuSettings(MenuSettings *s); + +void InitMenu(MenuState *m); +void UpdateMenu(MenuState *m, State *state, Flags *flags); +void RenderMenu(MenuState *m, Font *font, const char *title, Flags *flags, State *state); +void CleanupMenu(MenuState *m); + +#endif diff --git a/include/overlay.h b/include/overlay.h new file mode 100644 index 0000000..25e485e --- /dev/null +++ b/include/overlay.h @@ -0,0 +1,20 @@ +#ifndef OVERLAY_H +#define OVERLAY_H + +#include +#include + +#include "engineInput.h" +#include "player.h" +#include "rose.h" +#include "rose.h" + +typedef struct { + Rose rose; +} Overlay; + +Overlay CreateOverlay(void); +void UpdateOverlay(Overlay *overlay, Player *player); +void RenderOverlay(Mouse *mouse, Player *player, Rose *rose); + +#endif diff --git a/include/pathfinding.h b/include/pathfinding.h new file mode 100644 index 0000000..e4e197a --- /dev/null +++ b/include/pathfinding.h @@ -0,0 +1,21 @@ +#ifndef PATHFINDING_H +#define PATHFINDING_H + +#include +#include + +#include "terrain.h" + +#define PATH_MAX_WAYPOINTS 16 + +typedef struct { + Vector2 waypoints[PATH_MAX_WAYPOINTS]; + int count; +} Path; + +bool IsWaterWithClearance(Terrain *terrain, Vector2 pos, float clearance); +Vector2 GetRandomWaterPositionNear(Terrain *terrain, Vector2 origin, float maxRadius, + float clearance); +Path FindWaterPath(Terrain *terrain, Vector2 start, Vector2 goal, float clearance); + +#endif diff --git a/include/player.h b/include/player.h new file mode 100644 index 0000000..a69909c --- /dev/null +++ b/include/player.h @@ -0,0 +1,35 @@ +#ifndef PLAYER_H +#define PLAYER_H + +#include + +#include "engineAnimation.h" +#include "engineConfig.h" +#include "enginePhysics.h" +#include "engineSprite.h" +#include "terrain.h" +#include "wake.h" + +typedef enum { START_SHIP, PLAYER_TEX_COUNT } PlayerTextureID; +typedef enum { ANCHOR, SLOW_AHEAD, FAST_AHEAD, SPEED_COUNT } PlayerSpeedID; + +typedef struct { + Sprite sprite; + Animation animation; + Physics physics; + float rotation; + Sound soundFlapping; + Config config; + int health; + int gold; + WakeTrail wakeTrail; +} Player; + +PlayerSpeedID GetPlayerSpeedID(float speed); +Player CreatePlayer(Terrain *terrain); +void UpdatePlayer(Player *player); +void RenderPlayer(Player *player); +void SavePlayer(Player *player); +void ResetPlayer(Player *player, Terrain *terrain); + +#endif diff --git a/include/projectiles.h b/include/projectiles.h new file mode 100644 index 0000000..ecd067c --- /dev/null +++ b/include/projectiles.h @@ -0,0 +1,30 @@ +#ifndef PROJECTILES_H +#define PROJECTILES_H + +#include +#include + +#include "enginePhysics.h" +#include "player.h" + +#define MAX_PROJECTILES 100 +#define PROJECTILE_SPEED 50.0f + +typedef struct { + int count; + Physics physics[MAX_PROJECTILES]; + bool active[MAX_PROJECTILES]; + bool friendly[MAX_PROJECTILES]; + float radius[MAX_PROJECTILES]; + Color color[MAX_PROJECTILES]; + Sound soundShooting[MAX_PROJECTILES]; + Sound soundImpact[MAX_PROJECTILES]; +} Projectiles; + +Projectiles CreateProjectiles(void); +bool FireProjectile(Projectiles *projectiles, Vector2 position, Vector2 direction, bool friendly); +void UpdateProjectiles(Projectiles *projectiles, Player *player); +void RenderProjectiles(Projectiles *projectiles); +void ResetProjectiles(Projectiles *projectiles); + +#endif diff --git a/include/rose.h b/include/rose.h new file mode 100644 index 0000000..e7def31 --- /dev/null +++ b/include/rose.h @@ -0,0 +1,20 @@ +#ifndef ROSE_H +#define ROSE_H + +#include +#include "engineSprite.h" +#include "player.h" + +#define ROSE_SCREEN_WIDTH_FRACTION 0.2f + +typedef enum { ROSE, ROSE_TEX_COUNT } RoseTextureID; + +typedef struct { + Sprite sprite; +} Rose; + +Rose CreateRose(void); +void UpdateRose(Rose *rose, Player *player); +void RenderRose(Rose *rose); + +#endif diff --git a/include/terrain.h b/include/terrain.h new file mode 100644 index 0000000..fc3969e --- /dev/null +++ b/include/terrain.h @@ -0,0 +1,36 @@ +#ifndef TERRAIN_H +#define TERRAIN_H + +#include +#include + +#include "engineSprite.h" + +#define TERRAIN_CHUNK_WORLD_SIZE 256.0f +#define TERRAIN_CHUNK_RESOLUTION ((int)TERRAIN_CHUNK_WORLD_SIZE) +#define TERRAIN_LOAD_RADIUS 2 +#define TERRAIN_GRID_SIZE (TERRAIN_LOAD_RADIUS * 2 + 1) +#define TERRAIN_MAX_CHUNKS (TERRAIN_GRID_SIZE * TERRAIN_GRID_SIZE) + +typedef struct { + bool active; + int chunkX, chunkY; + Sprite sprite; + bool *landMask; +} TerrainChunk; + +typedef struct { + TerrainChunk chunks[TERRAIN_MAX_CHUNKS]; + Shader shader; + float time; +} Terrain; + +Terrain CreateTerrain(Camera2D *camera); +void UpdateTerrain(Terrain *terrain, Camera2D *camera); +void RenderTerrain(Terrain *terrain); +void UnloadTerrain(Terrain *terrain); + +bool IsTerrainLand(Terrain *terrain, Vector2 worldPos); +bool IsTerrainLoaded(Terrain *terrain, Vector2 worldPos); + +#endif diff --git a/include/wake.h b/include/wake.h new file mode 100644 index 0000000..e374c64 --- /dev/null +++ b/include/wake.h @@ -0,0 +1,27 @@ +#ifndef WAKE_H +#define WAKE_H + +#include + +#define WAKE_TRAIL_POINTS 12 + +typedef struct { + Vector2 points[WAKE_TRAIL_POINTS]; + double timestamps[WAKE_TRAIL_POINTS]; + int count; +} WakeTrail; + +void UpdateWakeTrail(WakeTrail *trail, Vector2 position); +void ResetWakeTrail(WakeTrail *trail); + +typedef struct { + Shader shader; + float time; +} Wake; + +Wake CreateWake(void); +void UpdateWake(Wake *wake, float deltaTime); +void RenderShipWake(Wake *wake, WakeTrail *trail, float speed); +void UnloadWake(Wake *wake); + +#endif