Prepares pengine for more particle types.

Also fixed an invalid read bug.
This commit is contained in:
Linus Probert 2018-05-22 22:42:06 +02:00
parent bbe4526947
commit cc229c8b00
2 changed files with 109 additions and 38 deletions

View File

@ -25,15 +25,36 @@
#include "vector2d.h" #include "vector2d.h"
#include "random.h" #include "random.h"
typedef struct Particle_t { typedef enum ParticleType {
RECT,
LINE
} ParticleType;
typedef struct RectParticle {
Position pos; Position pos;
Vector2d velocity;
Dimension dim; Dimension dim;
} RectParticle;
typedef struct LineParticle {
Position startPos;
Position endPos;
} LineParticle;
typedef union ParticleUnion {
ParticleType type;
RectParticle rect;
LineParticle line;
} ParticleUnion;
typedef struct Particle {
ParticleType type;
Vector2d velocity;
unsigned int movetime; unsigned int movetime;
unsigned int lifetime; unsigned int lifetime;
bool fixed; bool fixed;
Uint8 blend_mode;
SDL_Color color; SDL_Color color;
Uint8 blend_mode;
ParticleUnion particle;
} Particle; } Particle;
typedef struct Engine_t { typedef struct Engine_t {
@ -44,17 +65,20 @@ typedef struct Engine_t {
static Engine *engine = NULL; static Engine *engine = NULL;
static Particle* static Particle*
create_particle(void) create_rect_particle(void)
{ {
Particle *p = ec_malloc(sizeof(Particle)); Particle *p = ec_malloc(sizeof(Particle));
p->pos = (Position) { 0, 0 };
p->dim = (Dimension) { 1, 1 }; p->type = RECT;
p->velocity = VECTOR2D_NODIR; p->velocity = VECTOR2D_NODIR;
p->movetime = 100; p->movetime = 100;
p->lifetime = 100; p->lifetime = 100;
p->fixed = false; p->fixed = false;
p->blend_mode = SDL_BLENDMODE_MOD; p->blend_mode = SDL_BLENDMODE_MOD;
p->color = C_WHITE; p->color = C_WHITE;
p->particle.rect.pos = (Position) { 0, 0 };
p->particle.rect.dim = (Dimension) { 1, 1 };
return p; return p;
} }
@ -101,12 +125,12 @@ particle_engine_bloodspray(Position pos, Dimension dim, unsigned int count)
w = get_random(3) + 2; w = get_random(3) + 2;
h = get_random(3) + 2; h = get_random(3) + 2;
p = create_particle(); p = create_rect_particle();
p->pos = (Position) { x, y }; p->particle.rect.pos = (Position) { x, y };
p->particle.rect.dim = (Dimension) { w, h };
p->velocity = (Vector2d) { (float) xv, (float) yv }; p->velocity = (Vector2d) { (float) xv, (float) yv };
p->movetime = mt; p->movetime = mt;
p->lifetime = lt; p->lifetime = lt;
p->dim = (Dimension) { w, h };
p->color = C_RED; p->color = C_RED;
linkedlist_append(&engine->game_particles, p); linkedlist_append(&engine->game_particles, p);
} }
@ -137,12 +161,12 @@ create_explosion(Position pos, Dimension dim, unsigned int c_count, ...)
lt = get_random(10); lt = get_random(10);
p = create_particle(); p = create_rect_particle();
p->pos = (Position) { x, y }; p->particle.rect.pos = (Position) { x, y };
p->particle.rect.dim = (Dimension) { 2, 2 };
p->velocity = (Vector2d) { (float) xv, (float) yv }; p->velocity = (Vector2d) { (float) xv, (float) yv };
p->movetime = lt; p->movetime = lt;
p->lifetime = lt; p->lifetime = lt;
p->dim = (Dimension) { 2, 2 };
p->color = colors[get_random((unsigned int) c_count-1)]; p->color = colors[get_random((unsigned int) c_count-1)];
linkedlist_append(&engine->game_particles, p); linkedlist_append(&engine->game_particles, p);
} }
@ -183,16 +207,16 @@ particle_engine_speed_lines(Position pos, Dimension dim, bool horizontal)
lt = get_random(10); lt = get_random(10);
p = create_particle(); p = create_rect_particle();
p->pos = (Position) { x, y };
p->velocity = (Vector2d) { 0, 0 }; p->velocity = (Vector2d) { 0, 0 };
p->movetime = lt; p->movetime = lt;
p->lifetime = lt; p->lifetime = lt;
if (horizontal)
p->dim = (Dimension) { 20, 1 };
else
p->dim = (Dimension) { 2, 20 };
p->color = color; p->color = color;
p->particle.rect.pos = (Position) { x, y };
if (horizontal)
p->particle.rect.dim = (Dimension) { 20, 1 };
else
p->particle.rect.dim = (Dimension) { 2, 20 };
linkedlist_append(&engine->game_particles, p); linkedlist_append(&engine->game_particles, p);
} }
} }
@ -214,13 +238,13 @@ particle_engine_sparkle(Position pos, Dimension dim)
lt = get_random(20); lt = get_random(20);
p = create_particle(); p = create_rect_particle();
p->pos = (Position) { x, y }; p->particle.rect.pos = (Position) { x, y };
p->particle.rect.dim = (Dimension) { 2, 2 };
p->velocity = (Vector2d) { (float) 0, (float) yv }; p->velocity = (Vector2d) { (float) 0, (float) yv };
p->movetime = lt; p->movetime = lt;
p->lifetime = lt; p->lifetime = lt;
p->blend_mode = SDL_BLENDMODE_BLEND; p->blend_mode = SDL_BLENDMODE_BLEND;
p->dim = (Dimension) { 2, 2 };
p->color = C_WHITE; p->color = C_WHITE;
p->color.a = (Uint8) alpha; p->color.a = (Uint8) alpha;
p->fixed = true; p->fixed = true;
@ -255,12 +279,12 @@ particle_engine_wind(Vector2d direction)
lt = get_random(500); lt = get_random(500);
p = create_particle(); p = create_rect_particle();
p->pos = (Position) { x, y }; p->particle.rect.pos = (Position) { x, y };
p->particle.rect.dim = (Dimension) { w, h };
p->velocity = (Vector2d) { direction.x * (float) velocity, direction.y * (float) velocity }; p->velocity = (Vector2d) { direction.x * (float) velocity, direction.y * (float) velocity };
p->movetime = lt; p->movetime = lt;
p->lifetime = lt; p->lifetime = lt;
p->dim = (Dimension) { w, h };
p->color = C_BLUE; p->color = C_BLUE;
p->fixed = true; p->fixed = true;
linkedlist_append(&engine->game_particles, p); linkedlist_append(&engine->game_particles, p);
@ -272,9 +296,21 @@ move_particle(Particle *particle, float deltaTime)
{ {
if (!particle->movetime) if (!particle->movetime)
return; return;
if (particle->type == RECT) {
particle->pos.x += (int) (particle->velocity.x * deltaTime); particle->particle.rect.pos.x +=
particle->pos.y += (int) (particle->velocity.y * deltaTime); (int) (particle->velocity.x * deltaTime);
particle->particle.rect.pos.y +=
(int) (particle->velocity.y * deltaTime);
} else if (particle->type == LINE) {
particle->particle.line.startPos.x +=
(int) (particle->velocity.x * deltaTime);
particle->particle.line.startPos.y +=
(int) (particle->velocity.y * deltaTime);
particle->particle.line.endPos.x +=
(int) (particle->velocity.x * deltaTime);
particle->particle.line.endPos.y +=
(int) (particle->velocity.y * deltaTime);
}
} }
static void static void
@ -308,17 +344,22 @@ particle_engine_update(float deltaTime)
} }
static void static void
render_particle(Particle *p, Camera *cam) render_rect_particle(Particle *p, Camera *cam)
{ {
Position pos; Position pos;
if (p->fixed) if (p->fixed)
pos = p->pos; pos = p->particle.rect.pos;
else else
pos = camera_to_camera_position(cam, &p->pos); pos = camera_to_camera_position(cam, &p->particle.rect.pos);
SDL_SetRenderDrawBlendMode(cam->renderer, p->blend_mode); SDL_SetRenderDrawBlendMode(cam->renderer, p->blend_mode);
SDL_Rect box = { pos.x, pos.y, p->dim.width, p->dim.height }; SDL_Rect box = {
pos.x,
pos.y,
p->particle.rect.dim.width,
p->particle.rect.dim.height
};
SDL_SetRenderDrawColor(cam->renderer, SDL_SetRenderDrawColor(cam->renderer,
p->color.r, p->color.r,
p->color.g, p->color.g,
@ -330,6 +371,32 @@ render_particle(Particle *p, Camera *cam)
SDL_SetRenderDrawBlendMode(cam->renderer, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawBlendMode(cam->renderer, SDL_BLENDMODE_BLEND);
} }
static void
render_line_particle(Particle *p, Camera *cam)
{
Position spos, epos;
if (p->fixed) {
spos = p->particle.line.startPos;
epos = p->particle.line.endPos;
} else {
spos = camera_to_camera_position(cam,
&p->particle.line.startPos);
epos = camera_to_camera_position(cam,
&p->particle.line.endPos);
}
SDL_SetRenderDrawBlendMode(cam->renderer, p->blend_mode);
SDL_SetRenderDrawColor(cam->renderer,
p->color.r,
p->color.g,
p->color.b,
p->color.a);
SDL_RenderDrawLine(cam->renderer, spos.x, spos.y, epos.x, epos.y);
// Reset the blend mode
SDL_SetRenderDrawBlendMode(cam->renderer, SDL_BLENDMODE_BLEND);
}
static void static void
render_particles(LinkedList *particles, Camera *cam) render_particles(LinkedList *particles, Camera *cam)
{ {
@ -338,7 +405,11 @@ render_particles(LinkedList *particles, Camera *cam)
LinkedList *render_list = particles; LinkedList *render_list = particles;
while (render_list) { while (render_list) {
render_particle(render_list->data, cam); Particle *p = render_list->data;
if (p->type == RECT)
render_rect_particle(p, cam);
else
render_line_particle(p, cam);
render_list = render_list->next; render_list = render_list->next;
} }
} }
@ -361,16 +432,14 @@ particle_engine_clear(void)
check_engine(); check_engine();
while (engine->game_particles) while (engine->game_particles)
free(linkedlist_pop(&engine->game_particles)); free(linkedlist_pop(&engine->game_particles));
while (engine->global_particles)
free(linkedlist_pop(&engine->global_particles));
} }
void void
particle_engine_close(void) particle_engine_close(void)
{ {
check_engine(); particle_engine_clear();
while (engine->game_particles)
free(linkedlist_pop(&engine->game_particles));
free(engine); free(engine);
engine = NULL; engine = NULL;
} }

View File

@ -267,11 +267,13 @@ roommatrix_reset(RoomMatrix *m)
void roommatrix_destroy(RoomMatrix *m) void roommatrix_destroy(RoomMatrix *m)
{ {
// Clear the list but don't destroy the items
// The items are destroyed in the map destruction
for (int i = 0; i < MAP_ROOM_WIDTH; ++i) { for (int i = 0; i < MAP_ROOM_WIDTH; ++i) {
for (int j = 0; j < MAP_ROOM_HEIGHT; ++j) { for (int j = 0; j < MAP_ROOM_HEIGHT; ++j) {
RoomSpace *space = &m->spaces[i][j]; RoomSpace *space = &m->spaces[i][j];
while (space->items) while (space->items)
item_destroy(linkedlist_pop(&space->items)); linkedlist_pop(&space->items);
} }
} }