commit e73ce84eaa7c51913032684b7c276ca9f6cfa056 Author: cosmonaut Date: Mon Oct 4 18:10:25 2021 -0700 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..521e14a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.vs diff --git a/src/snowstorm.c b/src/snowstorm.c new file mode 100644 index 0000000..0751a3a --- /dev/null +++ b/src/snowstorm.c @@ -0,0 +1,200 @@ +/* Snowstorm - Particle effects in C + * + * Copyright (c) 2021 Evan Hemsley + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from + * the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in a + * product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + * + * Evan "cosmonaut" Hemsley + * + */ + +#include "Snowstorm.h" + +#include +#include + +typedef struct Snowstorm_Vector2 +{ + float x; + float y; +} Snowstorm_Vector2; + +static inline Snowstorm_Vector2 Vector2_Rotate(Snowstorm_Vector2 vector, float angle) +{ + Snowstorm_Vector2 rotated; + rotated.x = vector.x * cosf(angle) - vector.y * sinf(angle); + rotated.y = vector.x * sinf(angle) + vector.y * cosf(angle); + return rotated; +} + +static inline float Vector2_Magnitude(Snowstorm_Vector2 vector) +{ + return sqrtf(vector.x * vector.x + vector.y * vector.y); +} + +static inline Snowstorm_Vector2 Vector2_Normalize(Snowstorm_Vector2 vector) +{ + float length = Vector2_Magnitude(vector); + + Snowstorm_Vector2 normalized; + normalized.x = vector.x / length; + normalized.y = vector.y / length; + + return normalized; +} + +typedef struct Snowstorm_Particle +{ + float time; + Snowstorm_Vector2 position; + Snowstorm_Vector2 velocity; + Snowstorm_Vector2 scale; + float size; + float rotation; + float spin; + + float directionVariance; + float speedVariance; + Snowstorm_Vector2 catchup; +} Snowstorm_Particle; + +typedef struct Snowstorm_Context +{ + Snowstorm_Particle** particles; + uint32_t particleCount; + + Snowstorm_Vector2 wind; + + float directionChaos; + float speedChaos; + + float leftBound; + float topBound; + float rightBound; + float bottomBound; +} Snowstorm_Context; + +static Snowstorm_Context* context = NULL; + +static inline float Approach(float value, float target, float maxChange) +{ + return value + min(max(target - value, -maxChange), maxChange); +} + +static inline float WrapWithOvershoot(float value, float min, float max) +{ + if (value < min) + { + value = max - (min - value); + } + if (value > max) + { + value = min + (value - max); + } + return value; +} + +static inline float Random(float a) +{ + return (float)rand() / (float)(RAND_MAX / a); +} + +static inline float RandomRange(float min, float max) +{ + return Random(max - min) + min; +} + +void Snowstorm_Init() +{ + srand((unsigned int)time(NULL)); + + context = malloc(sizeof(Snowstorm_Context)); + + context->particles = NULL; + context->particleCount = 0; + + context->leftBound = -10; + context->rightBound = 490; + context->topBound = -10; + context->bottomBound = 280; + + context->wind.x = 0; + context->wind.y = 0; + + context->directionChaos = 0; + context->speedChaos = 0; +} + +void Snowstorm_Update(double delta) +{ + uint32_t i; + Snowstorm_Particle* particle = NULL; + + float deltaTime = (float)delta; + + for (i = 0; i < context->particleCount; i += 1) + { + particle = context->particles[i]; + + if (particle != NULL) + { + particle->time += deltaTime; + + float speed = Vector2_Magnitude(particle->velocity); + float rotation = sinf(particle->time / (speed * 100)) * particle->directionVariance; + + float windSpeed = Vector2_Magnitude(context->wind); + Snowstorm_Vector2 wind = Vector2_Normalize(context->wind); + wind.x *= (windSpeed + particle->speedVariance); + wind.y *= (windSpeed + particle->speedVariance); + + wind = Vector2_Rotate(wind, rotation); + + particle->velocity.x = Approach(particle->velocity.x, wind.x, particle->catchup.x); + particle->velocity.y = Approach(particle->velocity.y, wind.y, particle->catchup.y); + + particle->position.x = WrapWithOvershoot(particle->position.x + particle->velocity.x, context->leftBound, context->rightBound); + particle->position.y = WrapWithOvershoot(particle->position.y + particle->velocity.y, context->topBound, context->bottomBound); + + particle->scale.y = particle->size * sinf(particle->time / 10); + + particle->rotation += particle->spin; + } + } +} + +void Snowstorm_ApplyWind(double xSpeed, double ySpeed) +{ + uint32_t i; + Snowstorm_Particle* particle; + + for (i = 0; i < context->particleCount; i += 1) + { + particle = context->particles[i]; + + if (particle != NULL) + { + particle->directionVariance = RandomRange(-context->directionChaos, context->directionChaos); + particle->speedVariance = RandomRange(-context->speedChaos, context->speedChaos); + } + } + + context->wind.x = (float)xSpeed; + context->wind.y = (float)ySpeed; +} diff --git a/src/snowstorm.h b/src/snowstorm.h new file mode 100644 index 0000000..aac1884 --- /dev/null +++ b/src/snowstorm.h @@ -0,0 +1,76 @@ +/* Snowstorm - Particle effects in C + * + * Copyright (c) 2021 Evan Hemsley + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from + * the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in a + * product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + * + * Evan "cosmonaut" Hemsley + * + */ + +#ifndef SNOWSTORM_H +#define SNOWSTORM_H + +#include +#include +#include + +#ifdef _WIN32 +#define SNOWSTORMAPI __declspec(dllexport) +#define SNOWSTORMCALL __cdecl +#else +#define SNOWSTORMAPI +#define SNOWSTORMCALL +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Version API */ + +#define SNOWSTORM_ABI_VERSION 0 +#define SNOWSTORM_MAJOR_VERSION 0 +#define SNOWSTORM_MINOR_VERSION 1 +#define SNOWSTORM_PATCH_VERSION 0 +#define SNOWSTORM_COMPILED_VERSION ( \ + (SNOWSTORM_ABI_VERSION * 100 * 100 * 100) + \ + (SNOWSTORM_MAJOR_VERSION * 100 * 100) + \ + (SNOWSTORM_MINOR_VERSION * 100) + \ + (SNOWSTORM_PATCH_VERSION) \ +) + +SNOWSTORMAPI void Snowstorm_Init(); +SNOWSTORMAPI void Snowstorm_Update(double delta); +SNOWSTORMAPI void Snowstorm_ApplyWind(double xSpeed, double ySpeed); + +SNOWSTORMAPI void Snowstorm_SetBuffer(const char* bufferId); + +SNOWSTORMAPI double Snowstorm_RequiredSnowBufferSize(); +SNOWSTORMAPI double Snowstorm_FillSnowBuffer(); + +SNOWSTORMAPI void Snowstorm_PerformDestroys(); +SNOWSTORMAPI void Snowstorm_ClearAll(); +SNOWSTORMAPI void Snowstorm_Finish(); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SNOWSTORM_H */ diff --git a/visualc/Snowstorm.sln b/visualc/Snowstorm.sln new file mode 100644 index 0000000..89c2be3 --- /dev/null +++ b/visualc/Snowstorm.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31424.327 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Snowstorm", "Snowstorm.vcxproj", "{912587C6-EF96-4BF8-BFE8-0E7D8A70D556}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {912587C6-EF96-4BF8-BFE8-0E7D8A70D556}.Debug|x64.ActiveCfg = Debug|x64 + {912587C6-EF96-4BF8-BFE8-0E7D8A70D556}.Debug|x64.Build.0 = Debug|x64 + {912587C6-EF96-4BF8-BFE8-0E7D8A70D556}.Debug|x86.ActiveCfg = Debug|Win32 + {912587C6-EF96-4BF8-BFE8-0E7D8A70D556}.Debug|x86.Build.0 = Debug|Win32 + {912587C6-EF96-4BF8-BFE8-0E7D8A70D556}.Release|x64.ActiveCfg = Release|x64 + {912587C6-EF96-4BF8-BFE8-0E7D8A70D556}.Release|x64.Build.0 = Release|x64 + {912587C6-EF96-4BF8-BFE8-0E7D8A70D556}.Release|x86.ActiveCfg = Release|Win32 + {912587C6-EF96-4BF8-BFE8-0E7D8A70D556}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {22EBBD2E-C8D7-4352-BF1B-8188D6AE4259} + EndGlobalSection +EndGlobal diff --git a/visualc/Snowstorm.vcxproj b/visualc/Snowstorm.vcxproj new file mode 100644 index 0000000..334541d --- /dev/null +++ b/visualc/Snowstorm.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {912587c6-ef96-4bf8-bfe8-0e7d8a70d556} + Snowstorm + 10.0 + + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;SNOWSTORM_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + false + + + + + Level3 + true + true + true + WIN32;NDEBUG;SNOWSTORM_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + true + true + false + + + + + Level3 + true + _DEBUG;SNOWSTORM_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + false + + + + + Level3 + true + true + true + NDEBUG;SNOWSTORM_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + true + true + false + + + + + + + + + + Create + Create + Create + Create + + + + + + \ No newline at end of file diff --git a/visualc/Snowstorm.vcxproj.filters b/visualc/Snowstorm.vcxproj.filters new file mode 100644 index 0000000..1e57c7b --- /dev/null +++ b/visualc/Snowstorm.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/visualc/Snowstorm.vcxproj.user b/visualc/Snowstorm.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/visualc/Snowstorm.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file