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