Start of bullet, debris, and effect performance updates. Dynamic array sizing.

This commit is contained in:
Sweeney 2016-02-24 15:02:51 +00:00
parent ba41d615a2
commit 56540a56ac
7 changed files with 397 additions and 275 deletions

View File

@ -47,52 +47,52 @@ void initBattle(void)
battle.effectTail = &battle.effectHead;
battle.objectiveTail = &battle.objectiveHead;
battle.locationTail = &battle.locationHead;
app.delegate.logic = &logic;
app.delegate.draw = &draw;
memset(&app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS);
initQuadtree(&battle.quadtree);
initBullets();
initEntities();
initStars();
initBullets();
initBackground();
initEffects();
initHud();
initRadar();
initMessageBox();
initMissionInfo();
initDebris();
resetWaypoints();
show = SHOW_BATTLE;
getWidget("ok", "startBattle")->action = start;
getWidget("resume", "inBattle")->action = resume;
getWidget("options", "inBattle")->action = options;
getWidget("restart", "inBattle")->action = retry;
getWidget("quit", "inBattle")->action = quitBattle;
getWidget("continue", "battleWon")->action = continueGame;
getWidget("retry", "battleWon")->action = retry;
getWidget("retry", "battleLost")->action = retry;
getWidget("quit", "battleLost")->action = quitBattle;
selectWidget("ok", "startBattle");
}
@ -101,7 +101,7 @@ static void logic(void)
if (battle.status == MS_IN_PROGRESS || battle.status == MS_COMPLETE || battle.status == MS_FAILED)
{
handleKeyboard();
if (show == SHOW_BATTLE)
{
if (!battle.epic || (battle.epic && !battle.playerSelect))
@ -114,7 +114,7 @@ static void logic(void)
}
}
}
doWidgets();
}
@ -129,58 +129,58 @@ static void doBattle(void)
{
ssx = ssy = 0;
}
scrollBackground(-ssx * 0.1, -ssy * 0.1);
battle.planet.x -= ssx * 0.05;
battle.planet.y -= ssy * 0.05;
doHud();
doStars(ssx, ssy);
doBullets();
doEntities();
doEffects();
doDebris();
doPlayer();
doObjectives();
if (player != NULL)
{
doLocations();
doMessageBox();
if (battle.status == MS_IN_PROGRESS)
{
doScript();
}
}
if (battle.status != MS_IN_PROGRESS)
{
battle.missionFinishedTimer--;
}
if (battle.stats[STAT_TIME] % FPS == 0)
{
runScriptFunction("TIME %d", battle.stats[STAT_TIME] / 60);
}
battle.stats[STAT_TIME]++;
if (battle.unwinnable && battle.missionFinishedTimer <= -FPS * 6)
{
postBattle();
destroyBattle();
initGalacticMap();
}
}
@ -192,41 +192,41 @@ static void draw(void)
battle.camera.x = player->x - (SCREEN_WIDTH / 2);
battle.camera.y = player->y - (SCREEN_HEIGHT / 2);
}
drawBackground(battle.background);
blitScaled(battle.planetTexture, battle.planet.x, battle.planet.y, battle.planetWidth, battle.planetHeight);
drawStars();
drawEntities();
drawBullets();
drawDebris();
drawEffects();
if (dev.debug)
{
drawLocations();
}
drawHud();
if (player != NULL)
{
drawMessageBox();
}
drawMissionInfo();
switch (show)
{
case SHOW_MENU:
drawMenu();
break;
case SHOW_OPTIONS:
drawOptions();
break;
@ -236,22 +236,22 @@ static void draw(void)
static void drawMenu(void)
{
SDL_Rect r;
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 128);
SDL_RenderFillRect(app.renderer, NULL);
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
r.w = 400;
r.h = 400;
r.x = (SCREEN_WIDTH / 2) - r.w / 2;
r.y = (SCREEN_HEIGHT / 2) - r.h / 2;
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 0);
SDL_RenderFillRect(app.renderer, &r);
SDL_SetRenderDrawColor(app.renderer, 200, 200, 200, 255);
SDL_RenderDrawRect(app.renderer, &r);
drawWidgets("inBattle");
}
@ -266,21 +266,21 @@ static void handleKeyboard(void)
selectWidget("resume", "inBattle");
show = SHOW_MENU;
break;
case SHOW_MENU:
show = SHOW_BATTLE;
break;
case SHOW_OBJECTIVES:
show = SHOW_BATTLE;
break;
}
memset(app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS);
playSound(SND_GUI_CLOSE);
}
if (app.keyboard[SDL_SCANCODE_TAB])
{
battle.status = MS_PAUSED;
@ -295,57 +295,57 @@ static void start(void)
static void resume(void)
{
show = SHOW_BATTLE;
memset(app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS);
}
static void continueGame(void)
{
postBattle();
destroyBattle();
initGalacticMap();
}
static void options(void)
{
show = SHOW_OPTIONS;
initOptions(returnFromOptions);
}
static void returnFromOptions(void)
{
show = SHOW_MENU;
selectWidget("resume", "inBattle");
}
static void retry(void)
{
postBattle();
destroyBattle();
initBattle();
loadMission(game.currentMission->filename);
}
static void quitBattle(void)
{
postBattle();
destroyBattle();
initGalacticMap();
}
static void postBattle(void)
{
int i;
for (i = 0 ; i < STAT_MAX ; i++)
{
if (i != STAT_TIME && i != STAT_EPIC_KILL_STREAK)
@ -353,12 +353,12 @@ static void postBattle(void)
game.stats[i] += battle.stats[i];
}
}
if (game.currentMission && !game.currentMission->completed)
{
game.currentMission->completed = (battle.status == MS_COMPLETE || !battle.numObjectivesTotal);
}
}
void destroyBattle(void)
@ -369,7 +369,7 @@ void destroyBattle(void)
Effect *e;
Objective *o;
Location *l;
while (battle.entityHead.next)
{
ent = battle.entityHead.next;
@ -377,7 +377,7 @@ void destroyBattle(void)
free(ent);
}
battle.entityTail = &battle.entityHead;
while (battle.bulletHead.next)
{
b = battle.bulletHead.next;
@ -385,7 +385,7 @@ void destroyBattle(void)
free(b);
}
battle.bulletTail = &battle.bulletHead;
while (battle.debrisHead.next)
{
d = battle.debrisHead.next;
@ -393,7 +393,7 @@ void destroyBattle(void)
free(d);
}
battle.debrisTail = &battle.debrisHead;
while (battle.effectHead.next)
{
e = battle.effectHead.next;
@ -401,7 +401,7 @@ void destroyBattle(void)
free(e);
}
battle.effectTail = &battle.effectHead;
while (battle.objectiveHead.next)
{
o = battle.objectiveHead.next;
@ -409,7 +409,7 @@ void destroyBattle(void)
free(o);
}
battle.objectiveTail = &battle.objectiveHead;
while (battle.locationHead.next)
{
l = battle.locationHead.next;
@ -417,16 +417,22 @@ void destroyBattle(void)
free(l);
}
battle.locationTail = &battle.locationHead;
cJSON_Delete(battle.missionJSON);
resetHud();
resetMessageBox();
destroyEntities();
destroyScript();
destroyQuadtree();
destroyDebris();
destroyBullets();
destroyEffects();
}

View File

@ -22,16 +22,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
static void huntTarget(Bullet *b);
static void checkCollisions(Bullet *b);
static void resizeDrawList(void);
static Bullet bulletDef[BT_MAX];
static Bullet *bulletsToDraw[MAX_BULLETS_TO_DRAW];
static Bullet **bulletsToDraw;
static int incomingMissile;
static int drawCapacity;
void initBullets(void)
{
incomingMissile = 0;
memset(bulletsToDraw, 0, sizeof(Bullet*) * MAX_BULLETS_TO_DRAW);
drawCapacity = INITIAL_BULLET_DRAW_CAPACITY;
bulletsToDraw = malloc(sizeof(Bullet*) * drawCapacity);
memset(bulletsToDraw, 0, sizeof(Bullet*) * drawCapacity);
}
void initBulletDefs(void)
@ -40,27 +45,27 @@ void initBulletDefs(void)
char *text;
int type;
Bullet *def;
memset(&bulletDef, 0, sizeof(Bullet) * BT_MAX);
text = readFile(getFileLocation("data/battle/bullets.json"));
root = cJSON_Parse(text);
for (node = root->child ; node != NULL ; node = node->next)
{
type = lookup(cJSON_GetObjectItem(node, "type")->valuestring);
def = &bulletDef[type];
def->type = type;
def->damage = cJSON_GetObjectItem(node, "damage")->valueint;
def->texture = getTexture(cJSON_GetObjectItem(node, "texture")->valuestring);
def->sound = lookup(cJSON_GetObjectItem(node, "sound")->valuestring);
def->flags = flagsToLong(cJSON_GetObjectItem(node, "flags")->valuestring, NULL);
SDL_QueryTexture(def->texture, NULL, NULL, &def->w, &def->h);
}
cJSON_Delete(root);
free(text);
}
@ -70,16 +75,16 @@ void doBullets(void)
int i = 0;
Bullet *b;
Bullet *prev = &battle.bulletHead;
incomingMissile = 0;
memset(bulletsToDraw, 0, sizeof(Bullet*) * MAX_BULLETS_TO_DRAW);
for (b = battle.bulletHead.next ; b != NULL ; b = b->next)
{
b->x += b->dx;
b->y += b->dy;
if (b->type == BT_ROCKET)
{
addMissileEngineEffect(b);
@ -87,29 +92,29 @@ void doBullets(void)
else if (b->type == BT_MISSILE)
{
addMissileEngineEffect(b);
huntTarget(b);
if (b->target == player && player != NULL && player->health > 0)
{
incomingMissile = 1;
}
}
checkCollisions(b);
if (--b->life <= 0)
{
if (player != NULL && player->alive == ALIVE_ALIVE && b->type == BT_MISSILE && b->damage > 0 && b->target == player)
{
battle.stats[STAT_MISSILES_EVADED]++;
}
if (b == battle.bulletTail)
{
battle.bulletTail = prev;
}
prev->next = b->next;
free(b);
b = prev;
@ -119,25 +124,48 @@ void doBullets(void)
if (collision(b->x - (b->w / 2) - battle.camera.x, b->y - (b->h / 2) - battle.camera.y, b->w * 2, b->h * 2, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT))
{
bulletsToDraw[i++] = b;
if (i >= MAX_BULLETS_TO_DRAW)
if (i == drawCapacity)
{
printf("Too many bullets to draw\n");
exit(1);
resizeDrawList();
}
}
}
prev = b;
}
}
static void resizeDrawList(void)
{
int i, n;
Bullet **bullets;
n = drawCapacity + INITIAL_BULLET_DRAW_CAPACITY;
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Resizing bullet draw capacity: %d -> %d\n", drawCapacity, n);
bullets = malloc(sizeof(Bullet*) * n);
memset(bullets, 0, sizeof(Bullet*) * n);
for (i = 0 ; i < drawCapacity ; i++)
{
bullets[i] = bulletsToDraw[i];
}
free(bulletsToDraw);
bulletsToDraw = bullets;
drawCapacity = n;
}
static void checkCollisions(Bullet *b)
{
Entity *e, **candidates;
int i;
candidates = getAllEntsWithin(b->x - (b->w / 2), b->y - (b->h / 2), b->w, b->h, NULL);
for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i])
{
if (e->flags & EF_TAKES_DAMAGE)
@ -146,7 +174,7 @@ static void checkCollisions(Bullet *b)
{
continue;
}
if (b->owner != e && e->health > 0 && collision(b->x - b->w / 2, b->y - b->h / 2, b->w, b->h, e->x - e->w / 2, e->y - e->h / 2, e->w, e->h))
{
if (b->owner->side == e->side)
@ -164,38 +192,38 @@ static void checkCollisions(Bullet *b)
battle.stats[STAT_ROCKETS_HIT]++;
}
}
if (!(e->flags & EF_IMMORTAL))
{
damageFighter(e, b->damage, b->flags);
}
b->life = 0;
b->damage = 0;
if (b->flags & BF_EXPLODES)
{
addMissileExplosion(b);
playBattleSound(SND_EXPLOSION_1, b->x, b->y);
if (e == player)
{
battle.stats[STAT_MISSILES_STRUCK]++;
}
}
/* assuming that health <= 0 will always mean killed */
if (e->health <= 0 && b->owner == player)
{
battle.stats[STAT_ENEMIES_KILLED_PLAYER]++;
battle.stats[STAT_EPIC_KILL_STREAK]++;
}
if (b->owner == player && b->type == BT_MISSILE)
{
battle.stats[STAT_MISSILES_HIT]++;
}
return;
}
}
@ -206,12 +234,12 @@ void drawBullets(void)
{
int i;
Bullet *b;
for (i = 0, b = bulletsToDraw[i] ; b != NULL ; b = bulletsToDraw[++i])
{
blitRotated(b->texture, b->x - battle.camera.x, b->y - battle.camera.y, b->angle);
}
if (incomingMissile && battle.stats[STAT_TIME] % FPS < 40)
{
drawText(SCREEN_WIDTH / 2, SCREEN_HEIGHT - 60, 18, TA_CENTER, colors.red, "WARNING: INCOMING MISSILE!");
@ -222,17 +250,17 @@ static void faceTarget(Bullet *b)
{
int dir;
int wantedAngle = getAngle(b->x, b->y, b->target->x, b->target->y);
wantedAngle %= 360;
if (fabs(wantedAngle - b->angle) > TURN_THRESHOLD)
{
dir = (wantedAngle - b->angle + 360) % 360 > 180 ? -1 : 1;
b->angle += dir * TURN_SPEED;
b->angle = mod(b->angle, 360);
/* lower your speed while you're not at the correct angle */
b->dx *= 0.38;
b->dy *= 0.38;
@ -243,14 +271,14 @@ static void applyMissileThrust(Bullet *b)
{
int maxSpeed;
float v, thrust;
b->dx += sin(TO_RAIDANS(b->angle));
b->dy += -cos(TO_RAIDANS(b->angle));
maxSpeed = MAX(MIN(b->target->speed + 1, 999), 3);
thrust = sqrt((b->dx * b->dx) + (b->dy * b->dy));
if (thrust > maxSpeed)
{
v = (maxSpeed / sqrt(thrust));
@ -264,9 +292,9 @@ static void huntTarget(Bullet *b)
if (b->target != NULL && b->target->health > 0)
{
faceTarget(b);
applyMissileThrust(b);
if (b->target == player && battle.ecmTimer < FPS)
{
b->life = 0;
@ -283,16 +311,16 @@ static void huntTarget(Bullet *b)
static Bullet *createBullet(int type, int x, int y, Entity *owner)
{
Bullet *b;
b = malloc(sizeof(Bullet));
memset(b, 0, sizeof(Bullet));
battle.bulletTail->next = b;
battle.bulletTail = b;
memcpy(b, &bulletDef[type], sizeof(Bullet));
b->next = NULL;
b->x = x;
b->y = y;
b->dx += sin(TO_RAIDANS(owner->angle)) * 16;
@ -301,7 +329,7 @@ static Bullet *createBullet(int type, int x, int y, Entity *owner)
b->angle = owner->angle;
b->owner = owner;
b->target = owner->target;
return b;
}
@ -311,44 +339,44 @@ void fireGuns(Entity *owner)
int i;
float x, y;
float c, s;
for (i = 0 ; i < MAX_FIGHTER_GUNS ; i++)
{
if (owner->guns[i].type == owner->selectedGunType || (owner->guns[i].type != BT_NONE && owner->combinedGuns))
{
s = sin(TO_RAIDANS(owner->angle));
c = cos(TO_RAIDANS(owner->angle));
x = (owner->guns[i].x * c) - (owner->guns[i].y * s);
y = (owner->guns[i].x * s) + (owner->guns[i].y * c);
x += owner->x;
y += owner->y;
b = createBullet(owner->guns[i].type, x, y, owner);
if (owner == player)
{
battle.stats[STAT_SHOTS_FIRED]++;
}
}
}
owner->reload = owner->reloadTime;
playBattleSound(b->sound, owner->x, owner->y);
}
void fireRocket(Entity *owner)
{
Bullet *b;
b = createBullet(BT_ROCKET, owner->x, owner->y, owner);
playBattleSound(b->sound, owner->x, owner->y);
owner->reload = FPS;
if (owner == player)
{
battle.stats[STAT_ROCKETS_FIRED]++;
@ -358,20 +386,20 @@ void fireRocket(Entity *owner)
void fireMissile(Entity *owner)
{
Bullet *b;
b = createBullet(BT_MISSILE, owner->x, owner->y, owner);
b->life = FPS * 30;
owner->missiles--;
if (owner == player)
{
battle.stats[STAT_MISSILES_FIRED]++;
}
playBattleSound(b->sound, owner->x, owner->y);
if (owner->target == player)
{
playSound(SND_INCOMING);
@ -380,4 +408,7 @@ void fireMissile(Entity *owner)
void destroyBulletDefs(void)
{
free(bulletsToDraw);
bulletsToDraw = NULL;
}

View File

@ -22,9 +22,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../json/cJSON.h"
#define TURN_SPEED 2
#define TURN_THRESHOLD 3
#define MAX_BULLETS_TO_DRAW 512
#define TURN_SPEED 2
#define TURN_THRESHOLD 3
#define INITIAL_BULLET_DRAW_CAPACITY 32
extern SDL_Texture *getTexture(char *filename);
extern void blitRotated(SDL_Texture *texture, int x, int y, float angle);

View File

@ -21,34 +21,39 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "debris.h"
static void changeCourse(Debris *d);
static void resizeDrawList(void);
static Debris *debrisToDraw[MAX_DEBRIS_TO_DRAW];
static Debris **debrisToDraw;
static SDL_Texture *debrisTexture[MAX_DEBRIS_TEXTURES];
static int drawCapacity;
void initDebris(void)
{
memset(debrisToDraw, 0, sizeof(Debris*) * MAX_DEBRIS_TO_DRAW);
debrisTexture[0] = getTexture("gfx/debris/debris1.png");
debrisTexture[1] = getTexture("gfx/debris/debris2.png");
debrisTexture[2] = getTexture("gfx/debris/debris3.png");
debrisTexture[3] = getTexture("gfx/debris/debris4.png");
debrisTexture[4] = getTexture("gfx/debris/debris5.png");
debrisTexture[5] = getTexture("gfx/debris/debris6.png");
drawCapacity = INITIAL_BULLET_DRAW_CAPACITY;
debrisToDraw = malloc(sizeof(Bullet*) * drawCapacity);
memset(debrisToDraw, 0, sizeof(Bullet*) * drawCapacity);
}
void addDebris(int x, int y, int amount)
{
int i;
Debris *d;
for (i = 0 ; i < amount ; i++)
{
d = malloc(sizeof(Debris));
memset(d, 0, sizeof(Debris));
battle.debrisTail->next = d;
battle.debrisTail = d;
d->x = x;
d->y = y;
d->dx = rand() % 1000 - rand() % 1000;
@ -56,7 +61,7 @@ void addDebris(int x, int y, int amount)
d->dy = rand() % 1000 - rand() % 1000;
d->dy *= 0.01;
d->health = FPS + (FPS * (rand() % 3));
d->texture = debrisTexture[rand() % MAX_DEBRIS_TEXTURES];
}
}
@ -65,34 +70,34 @@ void doDebris(void)
{
int i;
Debris *d, *prev;
memset(debrisToDraw, 0, sizeof(Debris*) * MAX_DEBRIS_TO_DRAW);
prev = &battle.debrisHead;
i = 0;
for (d = battle.debrisHead.next ; d != NULL ; d = d->next)
{
d->x += d->dx;
d->y += d->dy;
if (--d->thinkTime <= 0)
{
changeCourse(d);
}
d->angle = mod(d->angle + 1, 360);
addDebrisFire(d->x, d->y);
if (--d->health <= 0)
{
if (d == battle.debrisTail)
{
battle.debrisTail = prev;
}
prev->next = d->next;
free(d);
d = prev;
@ -102,30 +107,53 @@ void doDebris(void)
if (collision(d->x - 16 - battle.camera.x, d->y - 16 - battle.camera.y, 32, 32, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT))
{
debrisToDraw[i++] = d;
if (i >= MAX_DEBRIS_TO_DRAW)
if (i == drawCapacity)
{
printf("Too much debris to draw\n");
exit(1);
resizeDrawList();
}
}
}
prev = d;
}
}
static void resizeDrawList(void)
{
int i, n;
Debris **debris;
n = drawCapacity + INITIAL_BULLET_DRAW_CAPACITY;
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Resizing debris draw capacity: %d -> %d\n", drawCapacity, n);
debris = malloc(sizeof(Debris*) * n);
memset(debris, 0, sizeof(Debris*) * n);
for (i = 0 ; i < drawCapacity ; i++)
{
debris[i] = debrisToDraw[i];
}
free(debrisToDraw);
debrisToDraw = debris;
drawCapacity = n;
}
static void changeCourse(Debris *d)
{
float dir;
dir = rand() % 25 - rand() % 25;
dir *= 0.01;
d->dx += dir;
dir = rand() % 25 - rand() % 25;
dir *= 0.01;
d->dy += dir;
d->thinkTime = 1 + (rand() % 5);
}
@ -133,9 +161,16 @@ void drawDebris(void)
{
int i;
Debris *d;
for (i = 0, d = debrisToDraw[i] ; d != NULL ; d = debrisToDraw[++i])
{
blitRotated(d->texture, d->x - battle.camera.x, d->y - battle.camera.y, d->angle);
}
}
void destroyDebris(void)
{
free(debrisToDraw);
debrisToDraw = NULL;
}

View File

@ -22,8 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../json/cJSON.h"
#define MAX_DEBRIS_TO_DRAW 512
#define MAX_DEBRIS_TEXTURES 6
#define INITIAL_DEBRIS_DRAW_CAPACITY 32
#define MAX_DEBRIS_TEXTURES 6
extern float mod(float n, float x);
extern void blitRotated(SDL_Texture *texture, int x, int y, float angle);

View File

@ -26,87 +26,128 @@ static void setRandomShieldHue(Effect *e);
static SDL_Texture *explosionTexture;
static SDL_Texture *shieldHitTexture;
static SDL_Texture *haloTexture;
static Effect **effectsToDraw;
void initEffects(void)
{
explosionTexture = getTexture("gfx/effects/explosion.png");
shieldHitTexture = getTexture("gfx/effects/shieldHit.png");
haloTexture = getTexture("gfx/effects/halo.png");
drawCapacity = INITIAL_EFFECTS_TO_DRAW;
effectsToDraw = malloc(sizeof(Effect*) * drawCapacity);
}
void doEffects(void)
{
Effect *e;
Effect *prev = &battle.effectHead;
for (e = battle.effectHead.next ; e != NULL ; e = e->next)
{
e->x += e->dx;
e->y += e->dy;
e->a -= (e->type != EFFECT_ECM) ? 1 : 3;
e->a = MAX(0, e->a);
e->health--;
e->size += e->scaleAmount;
if (e->health <= 0)
{
if (e == battle.effectTail)
{
battle.effectTail = prev;
}
prev->next = e->next;
free(e);
e = prev;
}
else
{
if (e->type == EFFECT_LINE || collision(e->x - (e->size / 2) - battle.camera.x, e->y - (b->size / 2) - battle.camera.y, e->size * 2, e->size * 2, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT))
{
effectsToDraw[i++] = e;
if (i == drawCapacity)
{
resizeDrawList();
}
}
}
prev = e;
}
}
static void resizeDrawList(void)
{
int i, n;
Effect **effects;
n = drawCapacity + INITIAL_EFFECT_DRAW_CAPACITY;
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Resizing effect draw capacity: %d -> %d\n", drawCapacity, n);
effects = malloc(sizeof(Effect*) * n);
memset(effects, 0, sizeof(Effect*) * n);
for (i = 0 ; i < drawCapacity ; i++)
{
effects[i] = effectsToDraw[i];
}
free(effectsToDraw);
effectsToDraw = effects;
drawCapacity = n;
}
void drawEffects(void)
{
int i;
Effect *e;
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND);
for (e = battle.effectHead.next ; e != NULL ; e = e->next)
for (i = 0, e = effectsToDraw[i] ; e != NULL ; e = effectsToDraw[++i])
{
SDL_SetRenderDrawColor(app.renderer, e->r, e->g, e->b, e->a);
SDL_SetTextureBlendMode(e->texture, SDL_BLENDMODE_ADD);
SDL_SetTextureAlphaMod(e->texture, e->a);
switch (e->type)
{
case EFFECT_POINT:
SDL_RenderDrawPoint(app.renderer, e->x - battle.camera.x, e->y - battle.camera.y);
break;
case EFFECT_LINE:
SDL_RenderDrawLine(app.renderer, e->x - battle.camera.x, e->y - battle.camera.y, e->x + (e->dx * 3) - battle.camera.x, e->y + (e->dy * 3) - battle.camera.y);
break;
case EFFECT_TEXTURE:
SDL_SetTextureColorMod(e->texture, e->r, e->g, e->b);
blitScaled(e->texture, e->x - battle.camera.x, e->y - battle.camera.y, e->size, e->size);
break;
case EFFECT_HALO:
SDL_SetTextureColorMod(e->texture, e->r, e->g, e->b);
blitScaled(e->texture, e->x - battle.camera.x - (e->size / 2), e->y - battle.camera.y - (e->size / 2), e->size, e->size);
break;
case EFFECT_ECM:
SDL_SetTextureColorMod(e->texture, e->r, e->g, e->b);
blitScaled(e->texture, SCREEN_WIDTH / 2 - (e->size / 2), SCREEN_HEIGHT / 2 - (e->size / 2), e->size, e->size);
break;
}
}
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
}
@ -120,24 +161,24 @@ void drawShieldHitEffect(Entity *e)
void addSmallFighterExplosion(void)
{
Effect *e;
e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect));
battle.effectTail->next = e;
battle.effectTail = e;
e->type = EFFECT_TEXTURE;
e->x = self->x + (rand() % 16 - rand() % 16);
e->y = self->y + (rand() % 16 - rand() % 16);
e->texture = explosionTexture;
e->size = 32;
setRandomFlameHue(e);
e->a = 128 + (rand() % 128);
e->health = e->a;
e->x -= e->size / 2;
e->y -= e->size / 2;
}
@ -145,24 +186,24 @@ void addSmallFighterExplosion(void)
void addDebrisFire(int x, int y)
{
Effect *e;
e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect));
battle.effectTail->next = e;
battle.effectTail = e;
e->type = EFFECT_TEXTURE;
e->x = x + (rand() % 8 - rand() % 8);
e->y = y + (rand() % 8 - rand() % 8);
e->texture = explosionTexture;
e->size = 4 + rand() % 12;
setRandomFlameHue(e);
e->a = rand() % 256;
e->health = e->a;
e->x -= e->size / 2;
e->y -= e->size / 2;
}
@ -171,16 +212,16 @@ void addSmallExplosion(void)
{
int i;
Effect *e;
for (i = 0 ; i < 32 ; i++)
{
e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect));
battle.effectTail->next = e;
battle.effectTail = e;
e->type = EFFECT_TEXTURE;
e->x = self->x;
e->y = self->y;
e->dx = (rand() % 25) - (rand() % 25);
@ -190,23 +231,23 @@ void addSmallExplosion(void)
e->texture = explosionTexture;
e->size = 32 + (rand() % 64);
e->r = 255;
setRandomFlameHue(e);
e->a = 128 + (rand() % 128);
e->health = e->a;
e->x -= e->size / 2;
e->y -= e->size / 2;
}
for (i = 0 ; i < 96 ; i++)
{
e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect));
battle.effectTail->next = e;
battle.effectTail = e;
e->type = EFFECT_LINE;
e->x = self->x;
e->y = self->y;
@ -214,10 +255,10 @@ void addSmallExplosion(void)
e->dx *= 0.1;
e->dy = rand() % 64 - rand() % 64;
e->dy *= 0.1;
e->a = 128;
e->health = e->a;
setRandomFlameHue(e);
}
}
@ -226,16 +267,16 @@ void addMissileExplosion(Bullet *b)
{
int i;
Effect *e;
for (i = 0 ; i < 8 ; i++)
{
e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect));
battle.effectTail->next = e;
battle.effectTail = e;
e->type = EFFECT_TEXTURE;
e->x = b->x;
e->y = b->y;
e->dx = (rand() % 25) - (rand() % 25);
@ -245,23 +286,23 @@ void addMissileExplosion(Bullet *b)
e->texture = explosionTexture;
e->size = 32 + (rand() % 64);
e->r = 255;
setRandomFlameHue(e);
e->a = 128 + (rand() % 128);
e->health = e->a;
e->x -= e->size / 2;
e->y -= e->size / 2;
}
for (i = 0 ; i < 24 ; i++)
{
e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect));
battle.effectTail->next = e;
battle.effectTail = e;
e->type = EFFECT_LINE;
e->x = b->x;
e->y = b->y;
@ -269,10 +310,10 @@ void addMissileExplosion(Bullet *b)
e->dx *= 0.1;
e->dy = rand() % 64 - rand() % 64;
e->dy *= 0.1;
e->a = 128;
e->health = e->a;
setRandomFlameHue(e);
}
}
@ -282,33 +323,33 @@ void addEngineEffect(void)
Effect *e;
float c, s;
int h;
e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect));
battle.effectTail->next = e;
battle.effectTail = e;
e->type = EFFECT_TEXTURE;
s = sin(TO_RAIDANS(self->angle));
c = cos(TO_RAIDANS(self->angle));
h = self->h / 2;
e->x = -(h * s) + self->x;
e->y = (h * c) + self->y;
e->x += rand() % 4 - rand() % 4;
e->texture = explosionTexture;
e->size = 16;
e->r = 128;
e->g = 128;
e->b = 255;
e->a = 64;
e->health = e->a;
e->x -= e->size / 2;
e->y -= e->size / 2;
}
@ -316,32 +357,32 @@ void addEngineEffect(void)
void addLargeEngineEffect(void)
{
Effect *e;
e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect));
battle.effectTail->next = e;
battle.effectTail = e;
e->type = EFFECT_TEXTURE;
e->x = self->x;
e->y = self->y;
e->x -= sin(TO_RAIDANS(self->angle)) * 16;
e->y -= -cos(TO_RAIDANS(self->angle)) * 16;
e->x += rand() % 4;
e->x -= rand() % 4;
e->texture = explosionTexture;
e->size = 64;
e->r = 128;
e->g = 128;
e->b = 255;
e->a = 64;
e->health = e->a;
e->x -= e->size / 2;
e->y -= e->size / 2;
}
@ -349,30 +390,30 @@ void addLargeEngineEffect(void)
void addMissileEngineEffect(Bullet *b)
{
Effect *e;
e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect));
battle.effectTail->next = e;
battle.effectTail = e;
e->type = EFFECT_TEXTURE;
e->x = b->x;
e->y = b->y;
e->x -= sin(TO_RAIDANS(b->angle)) * 10;
e->y -= -cos(TO_RAIDANS(b->angle)) * 10;
e->x += rand() % 4;
e->x -= rand() % 4;
e->texture = explosionTexture;
e->size = 12;
setRandomFlameHue(e);
e->a = 128;
e->health = e->a;
e->x -= e->size / 2;
e->y -= e->size / 2;
}
@ -381,14 +422,14 @@ void addShieldSplinterEffect(Entity *ent)
{
int i;
Effect *e;
for (i = 0 ; i < 48 ; i++)
{
e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect));
battle.effectTail->next = e;
battle.effectTail = e;
e->type = EFFECT_LINE;
e->x = ent->x;
e->y = ent->y;
@ -396,9 +437,9 @@ void addShieldSplinterEffect(Entity *ent)
e->dx *= 0.1;
e->dy = rand() % 64 - rand() % 64;
e->dy *= 0.1;
e->a = 255;
setRandomShieldHue(e);
}
}
@ -407,27 +448,27 @@ void addECMEffect(Entity *ent)
{
int i;
Effect *e;
for (i = 0 ; i < 3 ; i++)
{
e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect));
battle.effectTail->next = e;
battle.effectTail = e;
e->type = EFFECT_ECM;
e->x = ent->x;
e->y = ent->y;
e->size = i * 4;
e->scaleAmount = 5;
e->texture = haloTexture;
e->r = 128;
e->g = 128 + (i * 64);
e->b = 255;
e->a = 255;
e->health = 255;
}
}
@ -435,20 +476,20 @@ void addECMEffect(Entity *ent)
static void setRandomFlameHue(Effect *e)
{
e->r = 255;
switch (rand() % 4)
{
case 0:
break;
case 1:
e->g = 128;
break;
case 2:
e->g = 255;
break;
case 3:
e->g = e->b = 255;
break;
@ -458,23 +499,30 @@ static void setRandomFlameHue(Effect *e)
static void setRandomShieldHue(Effect *e)
{
e->b = 255;
switch (rand() % 4)
{
case 0:
e->g = 128;
break;
case 1:
e->g = 196;
break;
case 2:
e->g = 255;
break;
case 3:
e->r = e->g = 255;
break;
}
}
void destroyEffects(void)
{
free(effectsToDraw);
effectsToDraw = NULL;
}

View File

@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../common.h"
#define INITIAL_EFFECTS_TO_DRAW 128
extern void blitScaled(SDL_Texture *texture, int x, int y, int w, int h);
extern SDL_Texture *getTexture(char *name);
extern void blit(SDL_Texture *t, int x, int y, int center);