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.effectTail = &battle.effectHead;
battle.objectiveTail = &battle.objectiveHead; battle.objectiveTail = &battle.objectiveHead;
battle.locationTail = &battle.locationHead; battle.locationTail = &battle.locationHead;
app.delegate.logic = &logic; app.delegate.logic = &logic;
app.delegate.draw = &draw; app.delegate.draw = &draw;
memset(&app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS); memset(&app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS);
initQuadtree(&battle.quadtree); initQuadtree(&battle.quadtree);
initBullets(); initBullets();
initEntities(); initEntities();
initStars(); initStars();
initBullets(); initBullets();
initBackground(); initBackground();
initEffects(); initEffects();
initHud(); initHud();
initRadar(); initRadar();
initMessageBox(); initMessageBox();
initMissionInfo(); initMissionInfo();
initDebris(); initDebris();
resetWaypoints(); resetWaypoints();
show = SHOW_BATTLE; show = SHOW_BATTLE;
getWidget("ok", "startBattle")->action = start; getWidget("ok", "startBattle")->action = start;
getWidget("resume", "inBattle")->action = resume; getWidget("resume", "inBattle")->action = resume;
getWidget("options", "inBattle")->action = options; getWidget("options", "inBattle")->action = options;
getWidget("restart", "inBattle")->action = retry; getWidget("restart", "inBattle")->action = retry;
getWidget("quit", "inBattle")->action = quitBattle; getWidget("quit", "inBattle")->action = quitBattle;
getWidget("continue", "battleWon")->action = continueGame; getWidget("continue", "battleWon")->action = continueGame;
getWidget("retry", "battleWon")->action = retry; getWidget("retry", "battleWon")->action = retry;
getWidget("retry", "battleLost")->action = retry; getWidget("retry", "battleLost")->action = retry;
getWidget("quit", "battleLost")->action = quitBattle; getWidget("quit", "battleLost")->action = quitBattle;
selectWidget("ok", "startBattle"); 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) if (battle.status == MS_IN_PROGRESS || battle.status == MS_COMPLETE || battle.status == MS_FAILED)
{ {
handleKeyboard(); handleKeyboard();
if (show == SHOW_BATTLE) if (show == SHOW_BATTLE)
{ {
if (!battle.epic || (battle.epic && !battle.playerSelect)) if (!battle.epic || (battle.epic && !battle.playerSelect))
@ -114,7 +114,7 @@ static void logic(void)
} }
} }
} }
doWidgets(); doWidgets();
} }
@ -129,58 +129,58 @@ static void doBattle(void)
{ {
ssx = ssy = 0; ssx = ssy = 0;
} }
scrollBackground(-ssx * 0.1, -ssy * 0.1); scrollBackground(-ssx * 0.1, -ssy * 0.1);
battle.planet.x -= ssx * 0.05; battle.planet.x -= ssx * 0.05;
battle.planet.y -= ssy * 0.05; battle.planet.y -= ssy * 0.05;
doHud(); doHud();
doStars(ssx, ssy); doStars(ssx, ssy);
doBullets(); doBullets();
doEntities(); doEntities();
doEffects(); doEffects();
doDebris(); doDebris();
doPlayer(); doPlayer();
doObjectives(); doObjectives();
if (player != NULL) if (player != NULL)
{ {
doLocations(); doLocations();
doMessageBox(); doMessageBox();
if (battle.status == MS_IN_PROGRESS) if (battle.status == MS_IN_PROGRESS)
{ {
doScript(); doScript();
} }
} }
if (battle.status != MS_IN_PROGRESS) if (battle.status != MS_IN_PROGRESS)
{ {
battle.missionFinishedTimer--; battle.missionFinishedTimer--;
} }
if (battle.stats[STAT_TIME] % FPS == 0) if (battle.stats[STAT_TIME] % FPS == 0)
{ {
runScriptFunction("TIME %d", battle.stats[STAT_TIME] / 60); runScriptFunction("TIME %d", battle.stats[STAT_TIME] / 60);
} }
battle.stats[STAT_TIME]++; battle.stats[STAT_TIME]++;
if (battle.unwinnable && battle.missionFinishedTimer <= -FPS * 6) if (battle.unwinnable && battle.missionFinishedTimer <= -FPS * 6)
{ {
postBattle(); postBattle();
destroyBattle(); destroyBattle();
initGalacticMap(); initGalacticMap();
} }
} }
@ -192,41 +192,41 @@ static void draw(void)
battle.camera.x = player->x - (SCREEN_WIDTH / 2); battle.camera.x = player->x - (SCREEN_WIDTH / 2);
battle.camera.y = player->y - (SCREEN_HEIGHT / 2); battle.camera.y = player->y - (SCREEN_HEIGHT / 2);
} }
drawBackground(battle.background); drawBackground(battle.background);
blitScaled(battle.planetTexture, battle.planet.x, battle.planet.y, battle.planetWidth, battle.planetHeight); blitScaled(battle.planetTexture, battle.planet.x, battle.planet.y, battle.planetWidth, battle.planetHeight);
drawStars(); drawStars();
drawEntities(); drawEntities();
drawBullets(); drawBullets();
drawDebris(); drawDebris();
drawEffects(); drawEffects();
if (dev.debug) if (dev.debug)
{ {
drawLocations(); drawLocations();
} }
drawHud(); drawHud();
if (player != NULL) if (player != NULL)
{ {
drawMessageBox(); drawMessageBox();
} }
drawMissionInfo(); drawMissionInfo();
switch (show) switch (show)
{ {
case SHOW_MENU: case SHOW_MENU:
drawMenu(); drawMenu();
break; break;
case SHOW_OPTIONS: case SHOW_OPTIONS:
drawOptions(); drawOptions();
break; break;
@ -236,22 +236,22 @@ static void draw(void)
static void drawMenu(void) static void drawMenu(void)
{ {
SDL_Rect r; SDL_Rect r;
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 128); SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 128);
SDL_RenderFillRect(app.renderer, NULL); SDL_RenderFillRect(app.renderer, NULL);
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE); SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
r.w = 400; r.w = 400;
r.h = 400; r.h = 400;
r.x = (SCREEN_WIDTH / 2) - r.w / 2; r.x = (SCREEN_WIDTH / 2) - r.w / 2;
r.y = (SCREEN_HEIGHT / 2) - r.h / 2; r.y = (SCREEN_HEIGHT / 2) - r.h / 2;
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 0); SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 0);
SDL_RenderFillRect(app.renderer, &r); SDL_RenderFillRect(app.renderer, &r);
SDL_SetRenderDrawColor(app.renderer, 200, 200, 200, 255); SDL_SetRenderDrawColor(app.renderer, 200, 200, 200, 255);
SDL_RenderDrawRect(app.renderer, &r); SDL_RenderDrawRect(app.renderer, &r);
drawWidgets("inBattle"); drawWidgets("inBattle");
} }
@ -266,21 +266,21 @@ static void handleKeyboard(void)
selectWidget("resume", "inBattle"); selectWidget("resume", "inBattle");
show = SHOW_MENU; show = SHOW_MENU;
break; break;
case SHOW_MENU: case SHOW_MENU:
show = SHOW_BATTLE; show = SHOW_BATTLE;
break; break;
case SHOW_OBJECTIVES: case SHOW_OBJECTIVES:
show = SHOW_BATTLE; show = SHOW_BATTLE;
break; break;
} }
memset(app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS); memset(app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS);
playSound(SND_GUI_CLOSE); playSound(SND_GUI_CLOSE);
} }
if (app.keyboard[SDL_SCANCODE_TAB]) if (app.keyboard[SDL_SCANCODE_TAB])
{ {
battle.status = MS_PAUSED; battle.status = MS_PAUSED;
@ -295,57 +295,57 @@ static void start(void)
static void resume(void) static void resume(void)
{ {
show = SHOW_BATTLE; show = SHOW_BATTLE;
memset(app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS); memset(app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS);
} }
static void continueGame(void) static void continueGame(void)
{ {
postBattle(); postBattle();
destroyBattle(); destroyBattle();
initGalacticMap(); initGalacticMap();
} }
static void options(void) static void options(void)
{ {
show = SHOW_OPTIONS; show = SHOW_OPTIONS;
initOptions(returnFromOptions); initOptions(returnFromOptions);
} }
static void returnFromOptions(void) static void returnFromOptions(void)
{ {
show = SHOW_MENU; show = SHOW_MENU;
selectWidget("resume", "inBattle"); selectWidget("resume", "inBattle");
} }
static void retry(void) static void retry(void)
{ {
postBattle(); postBattle();
destroyBattle(); destroyBattle();
initBattle(); initBattle();
loadMission(game.currentMission->filename); loadMission(game.currentMission->filename);
} }
static void quitBattle(void) static void quitBattle(void)
{ {
postBattle(); postBattle();
destroyBattle(); destroyBattle();
initGalacticMap(); initGalacticMap();
} }
static void postBattle(void) static void postBattle(void)
{ {
int i; int i;
for (i = 0 ; i < STAT_MAX ; i++) for (i = 0 ; i < STAT_MAX ; i++)
{ {
if (i != STAT_TIME && i != STAT_EPIC_KILL_STREAK) if (i != STAT_TIME && i != STAT_EPIC_KILL_STREAK)
@ -353,12 +353,12 @@ static void postBattle(void)
game.stats[i] += battle.stats[i]; game.stats[i] += battle.stats[i];
} }
} }
if (game.currentMission && !game.currentMission->completed) if (game.currentMission && !game.currentMission->completed)
{ {
game.currentMission->completed = (battle.status == MS_COMPLETE || !battle.numObjectivesTotal); game.currentMission->completed = (battle.status == MS_COMPLETE || !battle.numObjectivesTotal);
} }
} }
void destroyBattle(void) void destroyBattle(void)
@ -369,7 +369,7 @@ void destroyBattle(void)
Effect *e; Effect *e;
Objective *o; Objective *o;
Location *l; Location *l;
while (battle.entityHead.next) while (battle.entityHead.next)
{ {
ent = battle.entityHead.next; ent = battle.entityHead.next;
@ -377,7 +377,7 @@ void destroyBattle(void)
free(ent); free(ent);
} }
battle.entityTail = &battle.entityHead; battle.entityTail = &battle.entityHead;
while (battle.bulletHead.next) while (battle.bulletHead.next)
{ {
b = battle.bulletHead.next; b = battle.bulletHead.next;
@ -385,7 +385,7 @@ void destroyBattle(void)
free(b); free(b);
} }
battle.bulletTail = &battle.bulletHead; battle.bulletTail = &battle.bulletHead;
while (battle.debrisHead.next) while (battle.debrisHead.next)
{ {
d = battle.debrisHead.next; d = battle.debrisHead.next;
@ -393,7 +393,7 @@ void destroyBattle(void)
free(d); free(d);
} }
battle.debrisTail = &battle.debrisHead; battle.debrisTail = &battle.debrisHead;
while (battle.effectHead.next) while (battle.effectHead.next)
{ {
e = battle.effectHead.next; e = battle.effectHead.next;
@ -401,7 +401,7 @@ void destroyBattle(void)
free(e); free(e);
} }
battle.effectTail = &battle.effectHead; battle.effectTail = &battle.effectHead;
while (battle.objectiveHead.next) while (battle.objectiveHead.next)
{ {
o = battle.objectiveHead.next; o = battle.objectiveHead.next;
@ -409,7 +409,7 @@ void destroyBattle(void)
free(o); free(o);
} }
battle.objectiveTail = &battle.objectiveHead; battle.objectiveTail = &battle.objectiveHead;
while (battle.locationHead.next) while (battle.locationHead.next)
{ {
l = battle.locationHead.next; l = battle.locationHead.next;
@ -417,16 +417,22 @@ void destroyBattle(void)
free(l); free(l);
} }
battle.locationTail = &battle.locationHead; battle.locationTail = &battle.locationHead;
cJSON_Delete(battle.missionJSON); cJSON_Delete(battle.missionJSON);
resetHud(); resetHud();
resetMessageBox(); resetMessageBox();
destroyEntities(); destroyEntities();
destroyScript(); destroyScript();
destroyQuadtree(); 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 huntTarget(Bullet *b);
static void checkCollisions(Bullet *b); static void checkCollisions(Bullet *b);
static void resizeDrawList(void);
static Bullet bulletDef[BT_MAX]; static Bullet bulletDef[BT_MAX];
static Bullet *bulletsToDraw[MAX_BULLETS_TO_DRAW]; static Bullet **bulletsToDraw;
static int incomingMissile; static int incomingMissile;
static int drawCapacity;
void initBullets(void) void initBullets(void)
{ {
incomingMissile = 0; 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) void initBulletDefs(void)
@ -40,27 +45,27 @@ void initBulletDefs(void)
char *text; char *text;
int type; int type;
Bullet *def; Bullet *def;
memset(&bulletDef, 0, sizeof(Bullet) * BT_MAX); memset(&bulletDef, 0, sizeof(Bullet) * BT_MAX);
text = readFile(getFileLocation("data/battle/bullets.json")); text = readFile(getFileLocation("data/battle/bullets.json"));
root = cJSON_Parse(text); root = cJSON_Parse(text);
for (node = root->child ; node != NULL ; node = node->next) for (node = root->child ; node != NULL ; node = node->next)
{ {
type = lookup(cJSON_GetObjectItem(node, "type")->valuestring); type = lookup(cJSON_GetObjectItem(node, "type")->valuestring);
def = &bulletDef[type]; def = &bulletDef[type];
def->type = type; def->type = type;
def->damage = cJSON_GetObjectItem(node, "damage")->valueint; def->damage = cJSON_GetObjectItem(node, "damage")->valueint;
def->texture = getTexture(cJSON_GetObjectItem(node, "texture")->valuestring); def->texture = getTexture(cJSON_GetObjectItem(node, "texture")->valuestring);
def->sound = lookup(cJSON_GetObjectItem(node, "sound")->valuestring); def->sound = lookup(cJSON_GetObjectItem(node, "sound")->valuestring);
def->flags = flagsToLong(cJSON_GetObjectItem(node, "flags")->valuestring, NULL); def->flags = flagsToLong(cJSON_GetObjectItem(node, "flags")->valuestring, NULL);
SDL_QueryTexture(def->texture, NULL, NULL, &def->w, &def->h); SDL_QueryTexture(def->texture, NULL, NULL, &def->w, &def->h);
} }
cJSON_Delete(root); cJSON_Delete(root);
free(text); free(text);
} }
@ -70,16 +75,16 @@ void doBullets(void)
int i = 0; int i = 0;
Bullet *b; Bullet *b;
Bullet *prev = &battle.bulletHead; Bullet *prev = &battle.bulletHead;
incomingMissile = 0; incomingMissile = 0;
memset(bulletsToDraw, 0, sizeof(Bullet*) * MAX_BULLETS_TO_DRAW); memset(bulletsToDraw, 0, sizeof(Bullet*) * MAX_BULLETS_TO_DRAW);
for (b = battle.bulletHead.next ; b != NULL ; b = b->next) for (b = battle.bulletHead.next ; b != NULL ; b = b->next)
{ {
b->x += b->dx; b->x += b->dx;
b->y += b->dy; b->y += b->dy;
if (b->type == BT_ROCKET) if (b->type == BT_ROCKET)
{ {
addMissileEngineEffect(b); addMissileEngineEffect(b);
@ -87,29 +92,29 @@ void doBullets(void)
else if (b->type == BT_MISSILE) else if (b->type == BT_MISSILE)
{ {
addMissileEngineEffect(b); addMissileEngineEffect(b);
huntTarget(b); huntTarget(b);
if (b->target == player && player != NULL && player->health > 0) if (b->target == player && player != NULL && player->health > 0)
{ {
incomingMissile = 1; incomingMissile = 1;
} }
} }
checkCollisions(b); checkCollisions(b);
if (--b->life <= 0) if (--b->life <= 0)
{ {
if (player != NULL && player->alive == ALIVE_ALIVE && b->type == BT_MISSILE && b->damage > 0 && b->target == player) if (player != NULL && player->alive == ALIVE_ALIVE && b->type == BT_MISSILE && b->damage > 0 && b->target == player)
{ {
battle.stats[STAT_MISSILES_EVADED]++; battle.stats[STAT_MISSILES_EVADED]++;
} }
if (b == battle.bulletTail) if (b == battle.bulletTail)
{ {
battle.bulletTail = prev; battle.bulletTail = prev;
} }
prev->next = b->next; prev->next = b->next;
free(b); free(b);
b = prev; 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)) 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; bulletsToDraw[i++] = b;
if (i >= MAX_BULLETS_TO_DRAW)
if (i == drawCapacity)
{ {
printf("Too many bullets to draw\n"); resizeDrawList();
exit(1);
} }
} }
} }
prev = b; 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) static void checkCollisions(Bullet *b)
{ {
Entity *e, **candidates; Entity *e, **candidates;
int i; int i;
candidates = getAllEntsWithin(b->x - (b->w / 2), b->y - (b->h / 2), b->w, b->h, NULL); 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]) for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i])
{ {
if (e->flags & EF_TAKES_DAMAGE) if (e->flags & EF_TAKES_DAMAGE)
@ -146,7 +174,7 @@ static void checkCollisions(Bullet *b)
{ {
continue; 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 != 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) if (b->owner->side == e->side)
@ -164,38 +192,38 @@ static void checkCollisions(Bullet *b)
battle.stats[STAT_ROCKETS_HIT]++; battle.stats[STAT_ROCKETS_HIT]++;
} }
} }
if (!(e->flags & EF_IMMORTAL)) if (!(e->flags & EF_IMMORTAL))
{ {
damageFighter(e, b->damage, b->flags); damageFighter(e, b->damage, b->flags);
} }
b->life = 0; b->life = 0;
b->damage = 0; b->damage = 0;
if (b->flags & BF_EXPLODES) if (b->flags & BF_EXPLODES)
{ {
addMissileExplosion(b); addMissileExplosion(b);
playBattleSound(SND_EXPLOSION_1, b->x, b->y); playBattleSound(SND_EXPLOSION_1, b->x, b->y);
if (e == player) if (e == player)
{ {
battle.stats[STAT_MISSILES_STRUCK]++; battle.stats[STAT_MISSILES_STRUCK]++;
} }
} }
/* assuming that health <= 0 will always mean killed */ /* assuming that health <= 0 will always mean killed */
if (e->health <= 0 && b->owner == player) if (e->health <= 0 && b->owner == player)
{ {
battle.stats[STAT_ENEMIES_KILLED_PLAYER]++; battle.stats[STAT_ENEMIES_KILLED_PLAYER]++;
battle.stats[STAT_EPIC_KILL_STREAK]++; battle.stats[STAT_EPIC_KILL_STREAK]++;
} }
if (b->owner == player && b->type == BT_MISSILE) if (b->owner == player && b->type == BT_MISSILE)
{ {
battle.stats[STAT_MISSILES_HIT]++; battle.stats[STAT_MISSILES_HIT]++;
} }
return; return;
} }
} }
@ -206,12 +234,12 @@ void drawBullets(void)
{ {
int i; int i;
Bullet *b; Bullet *b;
for (i = 0, b = bulletsToDraw[i] ; b != NULL ; b = bulletsToDraw[++i]) 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); blitRotated(b->texture, b->x - battle.camera.x, b->y - battle.camera.y, b->angle);
} }
if (incomingMissile && battle.stats[STAT_TIME] % FPS < 40) if (incomingMissile && battle.stats[STAT_TIME] % FPS < 40)
{ {
drawText(SCREEN_WIDTH / 2, SCREEN_HEIGHT - 60, 18, TA_CENTER, colors.red, "WARNING: INCOMING MISSILE!"); 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 dir;
int wantedAngle = getAngle(b->x, b->y, b->target->x, b->target->y); int wantedAngle = getAngle(b->x, b->y, b->target->x, b->target->y);
wantedAngle %= 360; wantedAngle %= 360;
if (fabs(wantedAngle - b->angle) > TURN_THRESHOLD) if (fabs(wantedAngle - b->angle) > TURN_THRESHOLD)
{ {
dir = (wantedAngle - b->angle + 360) % 360 > 180 ? -1 : 1; dir = (wantedAngle - b->angle + 360) % 360 > 180 ? -1 : 1;
b->angle += dir * TURN_SPEED; b->angle += dir * TURN_SPEED;
b->angle = mod(b->angle, 360); b->angle = mod(b->angle, 360);
/* lower your speed while you're not at the correct angle */ /* lower your speed while you're not at the correct angle */
b->dx *= 0.38; b->dx *= 0.38;
b->dy *= 0.38; b->dy *= 0.38;
@ -243,14 +271,14 @@ static void applyMissileThrust(Bullet *b)
{ {
int maxSpeed; int maxSpeed;
float v, thrust; float v, thrust;
b->dx += sin(TO_RAIDANS(b->angle)); b->dx += sin(TO_RAIDANS(b->angle));
b->dy += -cos(TO_RAIDANS(b->angle)); b->dy += -cos(TO_RAIDANS(b->angle));
maxSpeed = MAX(MIN(b->target->speed + 1, 999), 3); maxSpeed = MAX(MIN(b->target->speed + 1, 999), 3);
thrust = sqrt((b->dx * b->dx) + (b->dy * b->dy)); thrust = sqrt((b->dx * b->dx) + (b->dy * b->dy));
if (thrust > maxSpeed) if (thrust > maxSpeed)
{ {
v = (maxSpeed / sqrt(thrust)); v = (maxSpeed / sqrt(thrust));
@ -264,9 +292,9 @@ static void huntTarget(Bullet *b)
if (b->target != NULL && b->target->health > 0) if (b->target != NULL && b->target->health > 0)
{ {
faceTarget(b); faceTarget(b);
applyMissileThrust(b); applyMissileThrust(b);
if (b->target == player && battle.ecmTimer < FPS) if (b->target == player && battle.ecmTimer < FPS)
{ {
b->life = 0; b->life = 0;
@ -283,16 +311,16 @@ static void huntTarget(Bullet *b)
static Bullet *createBullet(int type, int x, int y, Entity *owner) static Bullet *createBullet(int type, int x, int y, Entity *owner)
{ {
Bullet *b; Bullet *b;
b = malloc(sizeof(Bullet)); b = malloc(sizeof(Bullet));
memset(b, 0, sizeof(Bullet)); memset(b, 0, sizeof(Bullet));
battle.bulletTail->next = b; battle.bulletTail->next = b;
battle.bulletTail = b; battle.bulletTail = b;
memcpy(b, &bulletDef[type], sizeof(Bullet)); memcpy(b, &bulletDef[type], sizeof(Bullet));
b->next = NULL; b->next = NULL;
b->x = x; b->x = x;
b->y = y; b->y = y;
b->dx += sin(TO_RAIDANS(owner->angle)) * 16; 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->angle = owner->angle;
b->owner = owner; b->owner = owner;
b->target = owner->target; b->target = owner->target;
return b; return b;
} }
@ -311,44 +339,44 @@ void fireGuns(Entity *owner)
int i; int i;
float x, y; float x, y;
float c, s; float c, s;
for (i = 0 ; i < MAX_FIGHTER_GUNS ; i++) for (i = 0 ; i < MAX_FIGHTER_GUNS ; i++)
{ {
if (owner->guns[i].type == owner->selectedGunType || (owner->guns[i].type != BT_NONE && owner->combinedGuns)) if (owner->guns[i].type == owner->selectedGunType || (owner->guns[i].type != BT_NONE && owner->combinedGuns))
{ {
s = sin(TO_RAIDANS(owner->angle)); s = sin(TO_RAIDANS(owner->angle));
c = cos(TO_RAIDANS(owner->angle)); c = cos(TO_RAIDANS(owner->angle));
x = (owner->guns[i].x * c) - (owner->guns[i].y * s); x = (owner->guns[i].x * c) - (owner->guns[i].y * s);
y = (owner->guns[i].x * s) + (owner->guns[i].y * c); y = (owner->guns[i].x * s) + (owner->guns[i].y * c);
x += owner->x; x += owner->x;
y += owner->y; y += owner->y;
b = createBullet(owner->guns[i].type, x, y, owner); b = createBullet(owner->guns[i].type, x, y, owner);
if (owner == player) if (owner == player)
{ {
battle.stats[STAT_SHOTS_FIRED]++; battle.stats[STAT_SHOTS_FIRED]++;
} }
} }
} }
owner->reload = owner->reloadTime; owner->reload = owner->reloadTime;
playBattleSound(b->sound, owner->x, owner->y); playBattleSound(b->sound, owner->x, owner->y);
} }
void fireRocket(Entity *owner) void fireRocket(Entity *owner)
{ {
Bullet *b; Bullet *b;
b = createBullet(BT_ROCKET, owner->x, owner->y, owner); b = createBullet(BT_ROCKET, owner->x, owner->y, owner);
playBattleSound(b->sound, owner->x, owner->y); playBattleSound(b->sound, owner->x, owner->y);
owner->reload = FPS; owner->reload = FPS;
if (owner == player) if (owner == player)
{ {
battle.stats[STAT_ROCKETS_FIRED]++; battle.stats[STAT_ROCKETS_FIRED]++;
@ -358,20 +386,20 @@ void fireRocket(Entity *owner)
void fireMissile(Entity *owner) void fireMissile(Entity *owner)
{ {
Bullet *b; Bullet *b;
b = createBullet(BT_MISSILE, owner->x, owner->y, owner); b = createBullet(BT_MISSILE, owner->x, owner->y, owner);
b->life = FPS * 30; b->life = FPS * 30;
owner->missiles--; owner->missiles--;
if (owner == player) if (owner == player)
{ {
battle.stats[STAT_MISSILES_FIRED]++; battle.stats[STAT_MISSILES_FIRED]++;
} }
playBattleSound(b->sound, owner->x, owner->y); playBattleSound(b->sound, owner->x, owner->y);
if (owner->target == player) if (owner->target == player)
{ {
playSound(SND_INCOMING); playSound(SND_INCOMING);
@ -380,4 +408,7 @@ void fireMissile(Entity *owner)
void destroyBulletDefs(void) 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" #include "../json/cJSON.h"
#define TURN_SPEED 2 #define TURN_SPEED 2
#define TURN_THRESHOLD 3 #define TURN_THRESHOLD 3
#define MAX_BULLETS_TO_DRAW 512 #define INITIAL_BULLET_DRAW_CAPACITY 32
extern SDL_Texture *getTexture(char *filename); extern SDL_Texture *getTexture(char *filename);
extern void blitRotated(SDL_Texture *texture, int x, int y, float angle); 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" #include "debris.h"
static void changeCourse(Debris *d); 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 SDL_Texture *debrisTexture[MAX_DEBRIS_TEXTURES];
static int drawCapacity;
void initDebris(void) void initDebris(void)
{ {
memset(debrisToDraw, 0, sizeof(Debris*) * MAX_DEBRIS_TO_DRAW);
debrisTexture[0] = getTexture("gfx/debris/debris1.png"); debrisTexture[0] = getTexture("gfx/debris/debris1.png");
debrisTexture[1] = getTexture("gfx/debris/debris2.png"); debrisTexture[1] = getTexture("gfx/debris/debris2.png");
debrisTexture[2] = getTexture("gfx/debris/debris3.png"); debrisTexture[2] = getTexture("gfx/debris/debris3.png");
debrisTexture[3] = getTexture("gfx/debris/debris4.png"); debrisTexture[3] = getTexture("gfx/debris/debris4.png");
debrisTexture[4] = getTexture("gfx/debris/debris5.png"); debrisTexture[4] = getTexture("gfx/debris/debris5.png");
debrisTexture[5] = getTexture("gfx/debris/debris6.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) void addDebris(int x, int y, int amount)
{ {
int i; int i;
Debris *d; Debris *d;
for (i = 0 ; i < amount ; i++) for (i = 0 ; i < amount ; i++)
{ {
d = malloc(sizeof(Debris)); d = malloc(sizeof(Debris));
memset(d, 0, sizeof(Debris)); memset(d, 0, sizeof(Debris));
battle.debrisTail->next = d; battle.debrisTail->next = d;
battle.debrisTail = d; battle.debrisTail = d;
d->x = x; d->x = x;
d->y = y; d->y = y;
d->dx = rand() % 1000 - rand() % 1000; 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 = rand() % 1000 - rand() % 1000;
d->dy *= 0.01; d->dy *= 0.01;
d->health = FPS + (FPS * (rand() % 3)); d->health = FPS + (FPS * (rand() % 3));
d->texture = debrisTexture[rand() % MAX_DEBRIS_TEXTURES]; d->texture = debrisTexture[rand() % MAX_DEBRIS_TEXTURES];
} }
} }
@ -65,34 +70,34 @@ void doDebris(void)
{ {
int i; int i;
Debris *d, *prev; Debris *d, *prev;
memset(debrisToDraw, 0, sizeof(Debris*) * MAX_DEBRIS_TO_DRAW); memset(debrisToDraw, 0, sizeof(Debris*) * MAX_DEBRIS_TO_DRAW);
prev = &battle.debrisHead; prev = &battle.debrisHead;
i = 0; i = 0;
for (d = battle.debrisHead.next ; d != NULL ; d = d->next) for (d = battle.debrisHead.next ; d != NULL ; d = d->next)
{ {
d->x += d->dx; d->x += d->dx;
d->y += d->dy; d->y += d->dy;
if (--d->thinkTime <= 0) if (--d->thinkTime <= 0)
{ {
changeCourse(d); changeCourse(d);
} }
d->angle = mod(d->angle + 1, 360); d->angle = mod(d->angle + 1, 360);
addDebrisFire(d->x, d->y); addDebrisFire(d->x, d->y);
if (--d->health <= 0) if (--d->health <= 0)
{ {
if (d == battle.debrisTail) if (d == battle.debrisTail)
{ {
battle.debrisTail = prev; battle.debrisTail = prev;
} }
prev->next = d->next; prev->next = d->next;
free(d); free(d);
d = prev; 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)) 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; debrisToDraw[i++] = d;
if (i >= MAX_DEBRIS_TO_DRAW)
if (i == drawCapacity)
{ {
printf("Too much debris to draw\n"); resizeDrawList();
exit(1);
} }
} }
} }
prev = d; 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) static void changeCourse(Debris *d)
{ {
float dir; float dir;
dir = rand() % 25 - rand() % 25; dir = rand() % 25 - rand() % 25;
dir *= 0.01; dir *= 0.01;
d->dx += dir; d->dx += dir;
dir = rand() % 25 - rand() % 25; dir = rand() % 25 - rand() % 25;
dir *= 0.01; dir *= 0.01;
d->dy += dir; d->dy += dir;
d->thinkTime = 1 + (rand() % 5); d->thinkTime = 1 + (rand() % 5);
} }
@ -133,9 +161,16 @@ void drawDebris(void)
{ {
int i; int i;
Debris *d; Debris *d;
for (i = 0, d = debrisToDraw[i] ; d != NULL ; d = debrisToDraw[++i]) 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); 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" #include "../json/cJSON.h"
#define MAX_DEBRIS_TO_DRAW 512 #define INITIAL_DEBRIS_DRAW_CAPACITY 32
#define MAX_DEBRIS_TEXTURES 6 #define MAX_DEBRIS_TEXTURES 6
extern float mod(float n, float x); extern float mod(float n, float x);
extern void blitRotated(SDL_Texture *texture, int x, int y, float angle); 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 *explosionTexture;
static SDL_Texture *shieldHitTexture; static SDL_Texture *shieldHitTexture;
static SDL_Texture *haloTexture; static SDL_Texture *haloTexture;
static Effect **effectsToDraw;
void initEffects(void) void initEffects(void)
{ {
explosionTexture = getTexture("gfx/effects/explosion.png"); explosionTexture = getTexture("gfx/effects/explosion.png");
shieldHitTexture = getTexture("gfx/effects/shieldHit.png"); shieldHitTexture = getTexture("gfx/effects/shieldHit.png");
haloTexture = getTexture("gfx/effects/halo.png"); haloTexture = getTexture("gfx/effects/halo.png");
drawCapacity = INITIAL_EFFECTS_TO_DRAW;
effectsToDraw = malloc(sizeof(Effect*) * drawCapacity);
} }
void doEffects(void) void doEffects(void)
{ {
Effect *e; Effect *e;
Effect *prev = &battle.effectHead; Effect *prev = &battle.effectHead;
for (e = battle.effectHead.next ; e != NULL ; e = e->next) for (e = battle.effectHead.next ; e != NULL ; e = e->next)
{ {
e->x += e->dx; e->x += e->dx;
e->y += e->dy; e->y += e->dy;
e->a -= (e->type != EFFECT_ECM) ? 1 : 3; e->a -= (e->type != EFFECT_ECM) ? 1 : 3;
e->a = MAX(0, e->a); e->a = MAX(0, e->a);
e->health--; e->health--;
e->size += e->scaleAmount; e->size += e->scaleAmount;
if (e->health <= 0) if (e->health <= 0)
{ {
if (e == battle.effectTail) if (e == battle.effectTail)
{ {
battle.effectTail = prev; battle.effectTail = prev;
} }
prev->next = e->next; prev->next = e->next;
free(e); free(e);
e = prev; 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; 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) void drawEffects(void)
{ {
int i;
Effect *e; Effect *e;
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND); 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_SetRenderDrawColor(app.renderer, e->r, e->g, e->b, e->a);
SDL_SetTextureBlendMode(e->texture, SDL_BLENDMODE_ADD); SDL_SetTextureBlendMode(e->texture, SDL_BLENDMODE_ADD);
SDL_SetTextureAlphaMod(e->texture, e->a); SDL_SetTextureAlphaMod(e->texture, e->a);
switch (e->type) switch (e->type)
{ {
case EFFECT_POINT: case EFFECT_POINT:
SDL_RenderDrawPoint(app.renderer, e->x - battle.camera.x, e->y - battle.camera.y); SDL_RenderDrawPoint(app.renderer, e->x - battle.camera.x, e->y - battle.camera.y);
break; break;
case EFFECT_LINE: 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); 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; break;
case EFFECT_TEXTURE: case EFFECT_TEXTURE:
SDL_SetTextureColorMod(e->texture, e->r, e->g, e->b); 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); blitScaled(e->texture, e->x - battle.camera.x, e->y - battle.camera.y, e->size, e->size);
break; break;
case EFFECT_HALO: case EFFECT_HALO:
SDL_SetTextureColorMod(e->texture, e->r, e->g, e->b); 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); blitScaled(e->texture, e->x - battle.camera.x - (e->size / 2), e->y - battle.camera.y - (e->size / 2), e->size, e->size);
break; break;
case EFFECT_ECM: case EFFECT_ECM:
SDL_SetTextureColorMod(e->texture, e->r, e->g, e->b); 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); blitScaled(e->texture, SCREEN_WIDTH / 2 - (e->size / 2), SCREEN_HEIGHT / 2 - (e->size / 2), e->size, e->size);
break; break;
} }
} }
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE); SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
} }
@ -120,24 +161,24 @@ void drawShieldHitEffect(Entity *e)
void addSmallFighterExplosion(void) void addSmallFighterExplosion(void)
{ {
Effect *e; Effect *e;
e = malloc(sizeof(Effect)); e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect)); memset(e, 0, sizeof(Effect));
battle.effectTail->next = e; battle.effectTail->next = e;
battle.effectTail = e; battle.effectTail = e;
e->type = EFFECT_TEXTURE; e->type = EFFECT_TEXTURE;
e->x = self->x + (rand() % 16 - rand() % 16); e->x = self->x + (rand() % 16 - rand() % 16);
e->y = self->y + (rand() % 16 - rand() % 16); e->y = self->y + (rand() % 16 - rand() % 16);
e->texture = explosionTexture; e->texture = explosionTexture;
e->size = 32; e->size = 32;
setRandomFlameHue(e); setRandomFlameHue(e);
e->a = 128 + (rand() % 128); e->a = 128 + (rand() % 128);
e->health = e->a; e->health = e->a;
e->x -= e->size / 2; e->x -= e->size / 2;
e->y -= e->size / 2; e->y -= e->size / 2;
} }
@ -145,24 +186,24 @@ void addSmallFighterExplosion(void)
void addDebrisFire(int x, int y) void addDebrisFire(int x, int y)
{ {
Effect *e; Effect *e;
e = malloc(sizeof(Effect)); e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect)); memset(e, 0, sizeof(Effect));
battle.effectTail->next = e; battle.effectTail->next = e;
battle.effectTail = e; battle.effectTail = e;
e->type = EFFECT_TEXTURE; e->type = EFFECT_TEXTURE;
e->x = x + (rand() % 8 - rand() % 8); e->x = x + (rand() % 8 - rand() % 8);
e->y = y + (rand() % 8 - rand() % 8); e->y = y + (rand() % 8 - rand() % 8);
e->texture = explosionTexture; e->texture = explosionTexture;
e->size = 4 + rand() % 12; e->size = 4 + rand() % 12;
setRandomFlameHue(e); setRandomFlameHue(e);
e->a = rand() % 256; e->a = rand() % 256;
e->health = e->a; e->health = e->a;
e->x -= e->size / 2; e->x -= e->size / 2;
e->y -= e->size / 2; e->y -= e->size / 2;
} }
@ -171,16 +212,16 @@ void addSmallExplosion(void)
{ {
int i; int i;
Effect *e; Effect *e;
for (i = 0 ; i < 32 ; i++) for (i = 0 ; i < 32 ; i++)
{ {
e = malloc(sizeof(Effect)); e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect)); memset(e, 0, sizeof(Effect));
battle.effectTail->next = e; battle.effectTail->next = e;
battle.effectTail = e; battle.effectTail = e;
e->type = EFFECT_TEXTURE; e->type = EFFECT_TEXTURE;
e->x = self->x; e->x = self->x;
e->y = self->y; e->y = self->y;
e->dx = (rand() % 25) - (rand() % 25); e->dx = (rand() % 25) - (rand() % 25);
@ -190,23 +231,23 @@ void addSmallExplosion(void)
e->texture = explosionTexture; e->texture = explosionTexture;
e->size = 32 + (rand() % 64); e->size = 32 + (rand() % 64);
e->r = 255; e->r = 255;
setRandomFlameHue(e); setRandomFlameHue(e);
e->a = 128 + (rand() % 128); e->a = 128 + (rand() % 128);
e->health = e->a; e->health = e->a;
e->x -= e->size / 2; e->x -= e->size / 2;
e->y -= e->size / 2; e->y -= e->size / 2;
} }
for (i = 0 ; i < 96 ; i++) for (i = 0 ; i < 96 ; i++)
{ {
e = malloc(sizeof(Effect)); e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect)); memset(e, 0, sizeof(Effect));
battle.effectTail->next = e; battle.effectTail->next = e;
battle.effectTail = e; battle.effectTail = e;
e->type = EFFECT_LINE; e->type = EFFECT_LINE;
e->x = self->x; e->x = self->x;
e->y = self->y; e->y = self->y;
@ -214,10 +255,10 @@ void addSmallExplosion(void)
e->dx *= 0.1; e->dx *= 0.1;
e->dy = rand() % 64 - rand() % 64; e->dy = rand() % 64 - rand() % 64;
e->dy *= 0.1; e->dy *= 0.1;
e->a = 128; e->a = 128;
e->health = e->a; e->health = e->a;
setRandomFlameHue(e); setRandomFlameHue(e);
} }
} }
@ -226,16 +267,16 @@ void addMissileExplosion(Bullet *b)
{ {
int i; int i;
Effect *e; Effect *e;
for (i = 0 ; i < 8 ; i++) for (i = 0 ; i < 8 ; i++)
{ {
e = malloc(sizeof(Effect)); e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect)); memset(e, 0, sizeof(Effect));
battle.effectTail->next = e; battle.effectTail->next = e;
battle.effectTail = e; battle.effectTail = e;
e->type = EFFECT_TEXTURE; e->type = EFFECT_TEXTURE;
e->x = b->x; e->x = b->x;
e->y = b->y; e->y = b->y;
e->dx = (rand() % 25) - (rand() % 25); e->dx = (rand() % 25) - (rand() % 25);
@ -245,23 +286,23 @@ void addMissileExplosion(Bullet *b)
e->texture = explosionTexture; e->texture = explosionTexture;
e->size = 32 + (rand() % 64); e->size = 32 + (rand() % 64);
e->r = 255; e->r = 255;
setRandomFlameHue(e); setRandomFlameHue(e);
e->a = 128 + (rand() % 128); e->a = 128 + (rand() % 128);
e->health = e->a; e->health = e->a;
e->x -= e->size / 2; e->x -= e->size / 2;
e->y -= e->size / 2; e->y -= e->size / 2;
} }
for (i = 0 ; i < 24 ; i++) for (i = 0 ; i < 24 ; i++)
{ {
e = malloc(sizeof(Effect)); e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect)); memset(e, 0, sizeof(Effect));
battle.effectTail->next = e; battle.effectTail->next = e;
battle.effectTail = e; battle.effectTail = e;
e->type = EFFECT_LINE; e->type = EFFECT_LINE;
e->x = b->x; e->x = b->x;
e->y = b->y; e->y = b->y;
@ -269,10 +310,10 @@ void addMissileExplosion(Bullet *b)
e->dx *= 0.1; e->dx *= 0.1;
e->dy = rand() % 64 - rand() % 64; e->dy = rand() % 64 - rand() % 64;
e->dy *= 0.1; e->dy *= 0.1;
e->a = 128; e->a = 128;
e->health = e->a; e->health = e->a;
setRandomFlameHue(e); setRandomFlameHue(e);
} }
} }
@ -282,33 +323,33 @@ void addEngineEffect(void)
Effect *e; Effect *e;
float c, s; float c, s;
int h; int h;
e = malloc(sizeof(Effect)); e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect)); memset(e, 0, sizeof(Effect));
battle.effectTail->next = e; battle.effectTail->next = e;
battle.effectTail = e; battle.effectTail = e;
e->type = EFFECT_TEXTURE; e->type = EFFECT_TEXTURE;
s = sin(TO_RAIDANS(self->angle)); s = sin(TO_RAIDANS(self->angle));
c = cos(TO_RAIDANS(self->angle)); c = cos(TO_RAIDANS(self->angle));
h = self->h / 2; h = self->h / 2;
e->x = -(h * s) + self->x; e->x = -(h * s) + self->x;
e->y = (h * c) + self->y; e->y = (h * c) + self->y;
e->x += rand() % 4 - rand() % 4; e->x += rand() % 4 - rand() % 4;
e->texture = explosionTexture; e->texture = explosionTexture;
e->size = 16; e->size = 16;
e->r = 128; e->r = 128;
e->g = 128; e->g = 128;
e->b = 255; e->b = 255;
e->a = 64; e->a = 64;
e->health = e->a; e->health = e->a;
e->x -= e->size / 2; e->x -= e->size / 2;
e->y -= e->size / 2; e->y -= e->size / 2;
} }
@ -316,32 +357,32 @@ void addEngineEffect(void)
void addLargeEngineEffect(void) void addLargeEngineEffect(void)
{ {
Effect *e; Effect *e;
e = malloc(sizeof(Effect)); e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect)); memset(e, 0, sizeof(Effect));
battle.effectTail->next = e; battle.effectTail->next = e;
battle.effectTail = e; battle.effectTail = e;
e->type = EFFECT_TEXTURE; e->type = EFFECT_TEXTURE;
e->x = self->x; e->x = self->x;
e->y = self->y; e->y = self->y;
e->x -= sin(TO_RAIDANS(self->angle)) * 16; e->x -= sin(TO_RAIDANS(self->angle)) * 16;
e->y -= -cos(TO_RAIDANS(self->angle)) * 16; e->y -= -cos(TO_RAIDANS(self->angle)) * 16;
e->x += rand() % 4; e->x += rand() % 4;
e->x -= rand() % 4; e->x -= rand() % 4;
e->texture = explosionTexture; e->texture = explosionTexture;
e->size = 64; e->size = 64;
e->r = 128; e->r = 128;
e->g = 128; e->g = 128;
e->b = 255; e->b = 255;
e->a = 64; e->a = 64;
e->health = e->a; e->health = e->a;
e->x -= e->size / 2; e->x -= e->size / 2;
e->y -= e->size / 2; e->y -= e->size / 2;
} }
@ -349,30 +390,30 @@ void addLargeEngineEffect(void)
void addMissileEngineEffect(Bullet *b) void addMissileEngineEffect(Bullet *b)
{ {
Effect *e; Effect *e;
e = malloc(sizeof(Effect)); e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect)); memset(e, 0, sizeof(Effect));
battle.effectTail->next = e; battle.effectTail->next = e;
battle.effectTail = e; battle.effectTail = e;
e->type = EFFECT_TEXTURE; e->type = EFFECT_TEXTURE;
e->x = b->x; e->x = b->x;
e->y = b->y; e->y = b->y;
e->x -= sin(TO_RAIDANS(b->angle)) * 10; e->x -= sin(TO_RAIDANS(b->angle)) * 10;
e->y -= -cos(TO_RAIDANS(b->angle)) * 10; e->y -= -cos(TO_RAIDANS(b->angle)) * 10;
e->x += rand() % 4; e->x += rand() % 4;
e->x -= rand() % 4; e->x -= rand() % 4;
e->texture = explosionTexture; e->texture = explosionTexture;
e->size = 12; e->size = 12;
setRandomFlameHue(e); setRandomFlameHue(e);
e->a = 128; e->a = 128;
e->health = e->a; e->health = e->a;
e->x -= e->size / 2; e->x -= e->size / 2;
e->y -= e->size / 2; e->y -= e->size / 2;
} }
@ -381,14 +422,14 @@ void addShieldSplinterEffect(Entity *ent)
{ {
int i; int i;
Effect *e; Effect *e;
for (i = 0 ; i < 48 ; i++) for (i = 0 ; i < 48 ; i++)
{ {
e = malloc(sizeof(Effect)); e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect)); memset(e, 0, sizeof(Effect));
battle.effectTail->next = e; battle.effectTail->next = e;
battle.effectTail = e; battle.effectTail = e;
e->type = EFFECT_LINE; e->type = EFFECT_LINE;
e->x = ent->x; e->x = ent->x;
e->y = ent->y; e->y = ent->y;
@ -396,9 +437,9 @@ void addShieldSplinterEffect(Entity *ent)
e->dx *= 0.1; e->dx *= 0.1;
e->dy = rand() % 64 - rand() % 64; e->dy = rand() % 64 - rand() % 64;
e->dy *= 0.1; e->dy *= 0.1;
e->a = 255; e->a = 255;
setRandomShieldHue(e); setRandomShieldHue(e);
} }
} }
@ -407,27 +448,27 @@ void addECMEffect(Entity *ent)
{ {
int i; int i;
Effect *e; Effect *e;
for (i = 0 ; i < 3 ; i++) for (i = 0 ; i < 3 ; i++)
{ {
e = malloc(sizeof(Effect)); e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect)); memset(e, 0, sizeof(Effect));
battle.effectTail->next = e; battle.effectTail->next = e;
battle.effectTail = e; battle.effectTail = e;
e->type = EFFECT_ECM; e->type = EFFECT_ECM;
e->x = ent->x; e->x = ent->x;
e->y = ent->y; e->y = ent->y;
e->size = i * 4; e->size = i * 4;
e->scaleAmount = 5; e->scaleAmount = 5;
e->texture = haloTexture; e->texture = haloTexture;
e->r = 128; e->r = 128;
e->g = 128 + (i * 64); e->g = 128 + (i * 64);
e->b = 255; e->b = 255;
e->a = 255; e->a = 255;
e->health = 255; e->health = 255;
} }
} }
@ -435,20 +476,20 @@ void addECMEffect(Entity *ent)
static void setRandomFlameHue(Effect *e) static void setRandomFlameHue(Effect *e)
{ {
e->r = 255; e->r = 255;
switch (rand() % 4) switch (rand() % 4)
{ {
case 0: case 0:
break; break;
case 1: case 1:
e->g = 128; e->g = 128;
break; break;
case 2: case 2:
e->g = 255; e->g = 255;
break; break;
case 3: case 3:
e->g = e->b = 255; e->g = e->b = 255;
break; break;
@ -458,23 +499,30 @@ static void setRandomFlameHue(Effect *e)
static void setRandomShieldHue(Effect *e) static void setRandomShieldHue(Effect *e)
{ {
e->b = 255; e->b = 255;
switch (rand() % 4) switch (rand() % 4)
{ {
case 0: case 0:
e->g = 128; e->g = 128;
break; break;
case 1: case 1:
e->g = 196; e->g = 196;
break; break;
case 2: case 2:
e->g = 255; e->g = 255;
break; break;
case 3: case 3:
e->r = e->g = 255; e->r = e->g = 255;
break; 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" #include "../common.h"
#define INITIAL_EFFECTS_TO_DRAW 128
extern void blitScaled(SDL_Texture *texture, int x, int y, int w, int h); extern void blitScaled(SDL_Texture *texture, int x, int y, int w, int h);
extern SDL_Texture *getTexture(char *name); extern SDL_Texture *getTexture(char *name);
extern void blit(SDL_Texture *t, int x, int y, int center); extern void blit(SDL_Texture *t, int x, int y, int center);