diff --git a/src/snowstorm.c b/src/snowstorm.c index 2a1e7d1..f2dc6f4 100644 --- a/src/snowstorm.c +++ b/src/snowstorm.c @@ -118,6 +118,8 @@ static Snowstorm_Matrix3x2 Matrix3x2_CreateRotation(float radians) float c, s; float epsilon = 0.001f * PI / 180; /* 0.1 % of a degree */ + radians = fmodf(radians, PI * 2); + if (radians > -epsilon && radians < epsilon) { /* Exact case for zero rotation. */ @@ -217,6 +219,8 @@ typedef struct Snowstorm_Context Snowstorm_Vector2 wind; + float particleSize; + float leftBound; float topBound; float rightBound; @@ -256,19 +260,29 @@ static inline float RandomRange(float min, float max) return Random(max - min) + min; } +/* i wanted to use pointers but game maker mangles string to pointer casts. oh well */ +static Snowstorm_Context *contexts = NULL; +static uint32_t contextCount = 0; + void Snowstorm_Init() { srand((unsigned int)time(NULL)); } -const char* Snowstorm_Create() +/* FIXME: we should reuse IDs when contexts are destroyed */ +double Snowstorm_Create(double particleSize, double leftBound, double topBound, double rightBound, double bottomBound) { - Snowstorm_Context *context = malloc(sizeof(Snowstorm_Context)); + contexts = realloc(contexts, sizeof(Snowstorm_Context) * (contextCount + 1)); + contextCount += 1; + + Snowstorm_Context* context = &contexts[contextCount - 1]; context->particleCapacity = 128; context->particles = malloc(sizeof(Snowstorm_Particle) * context->particleCapacity); context->particleCount = 0; + context->particleSize = particleSize; + context->leftBound = -10; context->rightBound = 490; context->topBound = -10; @@ -282,37 +296,37 @@ const char* Snowstorm_Create() context->currentBufferAddress = NULL; - return (const char*)context; + return (double)(contextCount - 1); } -void Snowstorm_SetUVCount(const char *contextPointer, double count) +void Snowstorm_SetUVCount(double contextId, double count) { - Snowstorm_Context *context = (Snowstorm_Context*)contextPointer; + Snowstorm_Context* context = &contexts[(uint32_t)contextId]; context->uvCount = (uint32_t)count; context->uvs = realloc(context->uvs, sizeof(Snowstorm_UV) * context->uvCount); } -void Snowstorm_SetLeftTopUV(const char *contextPointer, double index, double left, double top) +void Snowstorm_SetLeftTopUV(double contextId, double index, double left, double top) { - Snowstorm_Context* context = (Snowstorm_Context*)contextPointer; + Snowstorm_Context* context = &contexts[(uint32_t)contextId]; context->uvs[(uint32_t)index].left = left; context->uvs[(uint32_t)index].top = top; } -void Snowstorm_SetRightBottomUV(const char* contextPointer, double index, double right, double bottom) +void Snowstorm_SetRightBottomUV(double contextId, double index, double right, double bottom) { - Snowstorm_Context* context = (Snowstorm_Context*)contextPointer; + Snowstorm_Context* context = &contexts[(uint32_t)contextId]; context->uvs[(uint32_t)index].right = right; context->uvs[(uint32_t)index].bottom = bottom; } -void Snowstorm_Update(const char *contextPointer) +void Snowstorm_Update(double contextId) { uint32_t i; - Snowstorm_Context* context = (Snowstorm_Context*)contextPointer; + Snowstorm_Context* context = &contexts[(uint32_t)contextId]; for (i = 0; i < context->particleCount; i += 1) { @@ -321,7 +335,7 @@ void Snowstorm_Update(const char *contextPointer) particle->time += particle->timeRate; float speed = Vector2_Magnitude(particle->velocity); - float rotation = sinf(particle->time / (speed * 100)) * particle->directionVariance; + float rotation = sinf(particle->time / (speed * 100)) * particle->directionVariance * (PI / 180.0f); // degrees to radians float windSpeed = Vector2_Magnitude(context->wind); Snowstorm_Vector2 wind = Vector2_Normalize(context->wind); @@ -342,10 +356,10 @@ void Snowstorm_Update(const char *contextPointer) } } -void Snowstorm_ApplyChaos(const char* contextPointer, double directionChaos, double speedChaos) +void Snowstorm_ApplyChaos(double contextId, double directionChaos, double speedChaos) { uint32_t i; - Snowstorm_Context* context = (Snowstorm_Context*)contextPointer; + Snowstorm_Context* context = &contexts[(uint32_t)contextId]; for (i = 0; i < context->particleCount; i += 1) { @@ -356,17 +370,17 @@ void Snowstorm_ApplyChaos(const char* contextPointer, double directionChaos, dou } } -void Snowstorm_ApplyWind(const char *contextPointer, double xSpeed, double ySpeed) +void Snowstorm_ApplyWind(double contextId, double xSpeed, double ySpeed) { - Snowstorm_Context* context = (Snowstorm_Context*)contextPointer; + Snowstorm_Context* context = &contexts[(uint32_t)contextId]; context->wind.x = (float)xSpeed; context->wind.y = (float)ySpeed; } -void Snowstorm_SetParticles(const char *contextPointer, double count) +void Snowstorm_SetParticles(double contextId, double count) { uint32_t i; - Snowstorm_Context* context = (Snowstorm_Context*)contextPointer; + Snowstorm_Context* context = &contexts[(uint32_t)contextId]; if (count > context->particleCapacity) { @@ -395,30 +409,32 @@ void Snowstorm_SetParticles(const char *contextPointer, double count) particle->rotation = 0; particle->uvIndex = rand() % context->uvCount; } + + context->particleCount = count; } -void Snowstorm_SetBufferAddress(const char *contextPointer, const char* bufferAddress) +void Snowstorm_SetBufferAddress(double contextId, const char* bufferAddress) { - Snowstorm_Context* context = (Snowstorm_Context*)contextPointer; + Snowstorm_Context* context = &contexts[(uint32_t)contextId]; context->currentBufferAddress = (uint8_t*)bufferAddress; } -double Snowstorm_RequiredSnowBufferSize(const char *contextPointer) +double Snowstorm_RequiredSnowBufferSize(double contextId) { - Snowstorm_Context* context = (Snowstorm_Context*)contextPointer; + Snowstorm_Context* context = &contexts[(uint32_t)contextId]; return (double)context->particleCount * 6 * (sizeof(Snowstorm_Vector2) + sizeof(Snowstorm_Color) + (2 * sizeof(float))); } -double Snowstorm_FillSnowBuffer(const char *contextPointer) +double Snowstorm_FillSnowBuffer(double contextId, double red, double green, double blue) { uint32_t i, vertexCount; - Snowstorm_Context* context = (Snowstorm_Context*)contextPointer; + Snowstorm_Context* context = &contexts[(uint32_t)contextId]; uint8_t* bufferAddress = context->currentBufferAddress; Snowstorm_Color color; - color.r = 255; - color.g = 255; - color.b = 255; + color.r = (uint8_t)red; + color.g = (uint8_t)green; + color.b = (uint8_t)blue; color.a = 255; vertexCount = 0; @@ -432,21 +448,21 @@ double Snowstorm_FillSnowBuffer(const char *contextPointer) Snowstorm_Vector2 leftBottom; Snowstorm_Vector2 rightBottom; - leftTop.x = -particle->scale.x; - leftTop.y = -particle->scale.y; + leftTop.x = context->particleSize * -particle->scale.x / 4; + leftTop.y = context->particleSize * -particle->scale.y / 4; - rightTop.x = particle->scale.x; - rightTop.y = -particle->scale.y; + rightTop.x = context->particleSize * particle->scale.x / 4; + rightTop.y = context->particleSize * -particle->scale.y / 4; - leftBottom.x = -particle->scale.x; - leftBottom.y = particle->scale.y; + leftBottom.x = context->particleSize * -particle->scale.x / 4; + leftBottom.y = context->particleSize * particle->scale.y / 4; - rightBottom.x = particle->scale.x; - rightBottom.y = particle->scale.y; + rightBottom.x = context->particleSize * particle->scale.x / 4; + rightBottom.y = context->particleSize * particle->scale.y / 4; Snowstorm_Matrix3x2 translation = Matrix3x2_CreateTranslation(particle->position.x, particle->position.y); Snowstorm_Matrix3x2 rotation = Matrix3x2_CreateRotation(particle->rotation); - Snowstorm_Matrix3x2 transform = Matrix3x2_Multiply(translation, rotation); + Snowstorm_Matrix3x2 transform = Matrix3x2_Multiply(rotation, translation); leftTop = Vector2_Transform(leftTop, transform); rightTop = Vector2_Transform(rightTop, transform); @@ -536,9 +552,9 @@ double Snowstorm_FillSnowBuffer(const char *contextPointer) return (double)vertexCount; } -void Snowstorm_Destroy(const char *contextPointer) +void Snowstorm_Destroy(double contextId) { - Snowstorm_Context* context = (Snowstorm_Context*)contextPointer; + Snowstorm_Context* context = &contexts[(uint32_t)contextId]; if (context->particles != NULL) { @@ -549,6 +565,4 @@ void Snowstorm_Destroy(const char *contextPointer) { free(context->uvs); } - - free(context); } diff --git a/src/snowstorm.h b/src/snowstorm.h index eb6ff89..5a335db 100644 --- a/src/snowstorm.h +++ b/src/snowstorm.h @@ -57,23 +57,24 @@ extern "C" { ) SNOWSTORMAPI void Snowstorm_Init(); -SNOWSTORMAPI const char* Snowstorm_Create(); /* have to return a string because game maker lol */ -SNOWSTORMAPI void Snowstorm_SetUVCount(const char *contextPointer, double count); +SNOWSTORMAPI double Snowstorm_Create(double particleSize, double leftBound, double topBound, double rightBound, double bottomBound); + +SNOWSTORMAPI void Snowstorm_SetUVCount(double contextId, double count); /* i split these up because game maker cant have more than 4 arguments with different types lol */ -SNOWSTORMAPI void Snowstorm_SetLeftTopUV(const char *contextPointer, double index, double left, double top); -SNOWSTORMAPI void Snowstorm_SetRightBottomUV(const char* contextPointer, double index, double right, double bottom); +SNOWSTORMAPI void Snowstorm_SetLeftTopUV(double contextId, double index, double left, double top); +SNOWSTORMAPI void Snowstorm_SetRightBottomUV(double contextId, double index, double right, double bottom); -SNOWSTORMAPI void Snowstorm_Update(const char *contextPointer); -SNOWSTORMAPI void Snowstorm_ApplyWind(const char *contextPointer, double xSpeed, double ySpeed); -SNOWSTORMAPI void Snowstorm_ApplyChaos(const char* contextPointer, double directionChaos, double speedChaos); -SNOWSTORMAPI void Snowstorm_SetParticles(const char *contextPointer, double count); +SNOWSTORMAPI void Snowstorm_Update(double contextId); +SNOWSTORMAPI void Snowstorm_ApplyWind(double contextId, double xSpeed, double ySpeed); +SNOWSTORMAPI void Snowstorm_ApplyChaos(double contextId, double directionChaos, double speedChaos); +SNOWSTORMAPI void Snowstorm_SetParticles(double contextId, double count); -SNOWSTORMAPI void Snowstorm_SetBufferAddress(const char *contextPointer, const char* bufferId); +SNOWSTORMAPI void Snowstorm_SetBufferAddress(double contextId, const char* bufferId); -SNOWSTORMAPI double Snowstorm_RequiredSnowBufferSize(const char *contextPointer); -SNOWSTORMAPI double Snowstorm_FillSnowBuffer(const char *contextPointer); +SNOWSTORMAPI double Snowstorm_RequiredSnowBufferSize(double contextId); +SNOWSTORMAPI double Snowstorm_FillSnowBuffer(double contextId, double red, double green, double blue); -SNOWSTORMAPI void Snowstorm_Destroy(const char *contextPointer); +SNOWSTORMAPI void Snowstorm_Destroy(double contextId); #ifdef __cplusplus } diff --git a/visualc/Snowstorm.vcxproj b/visualc/Snowstorm.vcxproj index 3c5fccc..28302bc 100644 --- a/visualc/Snowstorm.vcxproj +++ b/visualc/Snowstorm.vcxproj @@ -45,7 +45,7 @@ v142 - v142 + ClangCL