2011-08-24 14:14:44 +02:00
|
|
|
/*
|
|
|
|
Copyright (C) 2003 Parallel Realities
|
2015-03-01 21:37:32 +01:00
|
|
|
Copyright (C) 2011, 2012, 2013 Guus Sliepen
|
2020-03-05 21:01:46 +01:00
|
|
|
Copyright (C) 2015-2019 Layla Marchant <diligentcircle@riseup.net>
|
2011-08-24 14:14:44 +02:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
2015-02-26 17:20:36 +01:00
|
|
|
as published by the Free Software Foundation; either version 3
|
2011-08-24 14:14:44 +02:00
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2015-02-26 17:20:36 +01:00
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
2011-08-24 14:14:44 +02:00
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2015-02-26 17:20:36 +01:00
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2011-08-24 14:14:44 +02:00
|
|
|
*/
|
|
|
|
|
2017-01-21 05:48:53 +01:00
|
|
|
#include <errno.h>
|
2017-01-25 16:48:29 +01:00
|
|
|
#include <stdio.h>
|
2017-01-21 05:48:53 +01:00
|
|
|
#include <sys/stat.h>
|
2016-01-02 22:59:48 +01:00
|
|
|
#include <unistd.h>
|
|
|
|
|
2020-02-27 01:46:33 +01:00
|
|
|
#ifdef __HAIKU__
|
|
|
|
#include <FindDirectory.h>
|
|
|
|
#else
|
2019-07-03 19:20:18 +02:00
|
|
|
#ifndef _WIN32
|
2017-02-01 22:10:48 +01:00
|
|
|
#include <pwd.h>
|
|
|
|
#endif
|
2020-02-27 01:46:33 +01:00
|
|
|
#endif
|
2017-02-01 22:10:48 +01:00
|
|
|
|
2017-01-21 05:48:53 +01:00
|
|
|
#include "SDL.h"
|
2017-01-22 06:11:13 +01:00
|
|
|
|
2019-06-04 03:05:38 +02:00
|
|
|
#ifndef NOFONT
|
|
|
|
#include "SDL_ttf.h"
|
|
|
|
#endif
|
|
|
|
|
2017-01-22 06:11:13 +01:00
|
|
|
#ifndef NOSOUND
|
2017-01-21 05:48:53 +01:00
|
|
|
#include "SDL_mixer.h"
|
2017-01-22 06:11:13 +01:00
|
|
|
#endif
|
2017-01-21 05:48:53 +01:00
|
|
|
|
|
|
|
#include "colors.h"
|
2016-11-26 00:21:31 +01:00
|
|
|
#include "defs.h"
|
|
|
|
#include "structs.h"
|
|
|
|
|
2017-01-21 05:48:53 +01:00
|
|
|
#include "audio.h"
|
|
|
|
#include "collectable.h"
|
|
|
|
#include "engine.h"
|
|
|
|
#include "game.h"
|
|
|
|
#include "gfx.h"
|
|
|
|
#include "player.h"
|
|
|
|
#include "renderer.h"
|
|
|
|
#include "screen.h"
|
|
|
|
#include "window.h"
|
|
|
|
|
2015-05-21 01:49:37 +02:00
|
|
|
Engine engine;
|
2011-08-24 14:14:44 +02:00
|
|
|
|
2015-05-21 01:49:37 +02:00
|
|
|
void engine_init()
|
2011-08-24 14:14:44 +02:00
|
|
|
{
|
|
|
|
engine.musicVolume = 100;
|
2016-11-19 17:43:50 +01:00
|
|
|
engine.useAudio = 1;
|
2011-08-24 14:14:44 +02:00
|
|
|
|
2012-03-11 15:21:38 +01:00
|
|
|
engine.maxAliens = 9;
|
2011-08-24 14:14:44 +02:00
|
|
|
|
2012-03-11 15:21:38 +01:00
|
|
|
engine.ssx = 0;
|
2011-08-24 14:14:44 +02:00
|
|
|
engine.ssy = 0;
|
2015-02-27 05:23:08 +01:00
|
|
|
engine.smx = 0;
|
|
|
|
engine.smy = 0;
|
2011-08-24 14:14:44 +02:00
|
|
|
|
2019-05-23 17:25:54 +02:00
|
|
|
engine.bulletHead = malloc(sizeof(*engine.bulletHead));
|
2019-05-19 19:40:50 +02:00
|
|
|
if (engine.bulletHead == NULL)
|
|
|
|
{
|
|
|
|
engine_error("Failed to allocate memory for bullet head.");
|
|
|
|
}
|
2011-08-24 14:14:44 +02:00
|
|
|
engine.bulletHead->next = NULL;
|
|
|
|
engine.bulletTail = engine.bulletHead;
|
|
|
|
|
2019-05-23 17:25:54 +02:00
|
|
|
engine.explosionHead = malloc(sizeof(*engine.explosionHead));
|
2019-05-20 00:22:53 +02:00
|
|
|
if (engine.explosionHead == NULL)
|
|
|
|
{
|
|
|
|
engine_error("Failed to allocate memory for explosion head.");
|
|
|
|
}
|
2011-08-24 14:14:44 +02:00
|
|
|
engine.explosionHead->next = NULL;
|
|
|
|
engine.explosionTail = engine.explosionHead;
|
|
|
|
|
2019-05-23 17:25:54 +02:00
|
|
|
engine.collectableHead = malloc(sizeof(*engine.collectableHead));
|
2019-05-20 00:22:53 +02:00
|
|
|
if (engine.collectableHead == NULL)
|
|
|
|
{
|
|
|
|
engine_error("Failed to allocate memory for collectable head.");
|
|
|
|
}
|
2011-08-24 14:14:44 +02:00
|
|
|
engine.collectableHead->next = NULL;
|
|
|
|
engine.collectableTail = engine.collectableHead;
|
|
|
|
|
2019-05-23 17:25:54 +02:00
|
|
|
engine.debrisHead = malloc(sizeof(*engine.debrisHead));
|
2019-05-20 00:22:53 +02:00
|
|
|
if (engine.debrisHead == NULL)
|
|
|
|
{
|
|
|
|
engine_error("Failed to allocate memory for debris head.");
|
|
|
|
}
|
2011-08-24 14:14:44 +02:00
|
|
|
engine.debrisHead->next = NULL;
|
|
|
|
engine.debrisTail = engine.debrisHead;
|
|
|
|
|
|
|
|
engine.commsSection = 0;
|
|
|
|
|
2013-09-30 16:52:43 +02:00
|
|
|
for (int i = 0; i < KEY_LAST; i++)
|
2012-03-11 15:21:38 +01:00
|
|
|
engine.keyState[i] = 0;
|
2011-08-24 14:14:44 +02:00
|
|
|
|
2012-03-11 15:21:38 +01:00
|
|
|
engine.eventTimer = 0;
|
2011-08-24 14:14:44 +02:00
|
|
|
engine.counter2 = 0;
|
|
|
|
engine.timeTaken = 0;
|
|
|
|
engine.timeMission = 0;
|
|
|
|
engine.counter = 0;
|
|
|
|
engine.seconds = 0;
|
|
|
|
engine.minutes = 0;
|
2016-11-19 17:43:50 +01:00
|
|
|
engine.paused = 0;
|
2011-08-24 14:14:44 +02:00
|
|
|
engine.gameSection = SECTION_TITLE;
|
|
|
|
|
2016-11-19 17:43:50 +01:00
|
|
|
engine.cheat = 0;
|
|
|
|
engine.cheatShield = 0;
|
|
|
|
engine.cheatAmmo = 0;
|
|
|
|
engine.cheatCash = 0;
|
2011-08-24 14:14:44 +02:00
|
|
|
}
|
2016-01-02 22:59:48 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
Something went wrong. This stops the game, present the error message and
|
|
|
|
prompts the user to press space or ctrl to exit the game. This is unlikely to
|
|
|
|
be seen by people unless something really stoopid happens!
|
|
|
|
*/
|
|
|
|
void engine_showError(int errorId, const char *name)
|
|
|
|
{
|
|
|
|
screen_clear(black);
|
|
|
|
|
|
|
|
if (errorId != 2)
|
|
|
|
{
|
|
|
|
screen_renderString("A file error has occurred", -1, 200, FONT_RED);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf("Couldn't create or write to directory '%s'\n", name);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2019-06-02 17:28:26 +02:00
|
|
|
char string[STRMAX];
|
2016-01-02 22:59:48 +01:00
|
|
|
|
|
|
|
switch(errorId)
|
|
|
|
{
|
|
|
|
case 0:
|
2020-03-05 22:44:13 +01:00
|
|
|
snprintf(string, STRMAX, "%s was not found in the Starfighter data package", name);
|
2016-01-02 22:59:48 +01:00
|
|
|
screen_renderString(string, -1, 250, FONT_WHITE);
|
|
|
|
screen_renderString("Please try again. If this error persists, contact the authors", -1, 275, FONT_WHITE);
|
|
|
|
screen_renderString("or reinstall the game", -1, 300, FONT_WHITE);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
screen_renderString("Project: Starfighter encountered an error whilst", -1, 250, FONT_WHITE);
|
|
|
|
screen_renderString("attempting to load game data. Please try running", -1, 275, FONT_WHITE);
|
|
|
|
screen_renderString("the game again. If the errors persist, reinstall the game", -1, 300, FONT_WHITE);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
screen_renderString("Project: Starfighter encountered a critical error", -1, 250, FONT_WHITE);
|
|
|
|
screen_renderString("while attempting to perform a required program function.", -1, 275, FONT_WHITE);
|
|
|
|
screen_renderString("Please contact the authors with details.", -1, 300, FONT_WHITE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
screen_renderString("Project: Starfighter will now exit", -1, 450, FONT_WHITE);
|
|
|
|
screen_renderString("Press Space to continue", -1, 475, FONT_WHITE);
|
|
|
|
|
|
|
|
renderer_update();
|
|
|
|
|
|
|
|
engine.keyState[KEY_ALTFIRE] = 0;
|
|
|
|
|
|
|
|
while (!engine.keyState[KEY_ALTFIRE])
|
|
|
|
{
|
2016-11-26 00:01:36 +01:00
|
|
|
player_getInput();
|
2016-01-02 22:59:48 +01:00
|
|
|
game_delayFrame();
|
|
|
|
}
|
|
|
|
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2019-05-19 19:40:50 +02:00
|
|
|
/*
|
|
|
|
Show a warning. Used when non-fatal things go wrong.
|
|
|
|
*/
|
|
|
|
void engine_warn(const char *msg)
|
|
|
|
{
|
2019-05-25 04:05:09 +02:00
|
|
|
printf("WARNING: %s\n", msg);
|
2019-05-19 19:40:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Show an error and exit. Used for critical errors that should definitely
|
|
|
|
never happen.
|
|
|
|
*/
|
|
|
|
void engine_error(const char *msg)
|
|
|
|
{
|
2019-05-25 04:05:09 +02:00
|
|
|
printf("ERROR: %s\nAborting\n", msg);
|
2019-05-19 19:40:50 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2016-01-02 22:59:48 +01:00
|
|
|
/*
|
2016-01-10 04:00:20 +01:00
|
|
|
This gets the user's home directory, then creates the config directory.
|
2016-01-02 22:59:48 +01:00
|
|
|
*/
|
|
|
|
void engine_setupConfigDirectory()
|
|
|
|
{
|
|
|
|
const char *userHome;
|
2019-07-03 23:00:46 +02:00
|
|
|
const char *subdir;
|
2017-02-01 22:10:48 +01:00
|
|
|
char dir[PATH_MAX];
|
2016-01-02 22:59:48 +01:00
|
|
|
|
2017-02-10 16:39:27 +01:00
|
|
|
#ifdef _WIN32
|
2019-07-03 23:00:46 +02:00
|
|
|
subdir = "pr-starfighter-config";
|
2016-01-02 22:59:48 +01:00
|
|
|
|
2019-07-03 23:00:46 +02:00
|
|
|
if ((userHome = getenv("APPDATA")) == NULL)
|
|
|
|
userHome = ".";
|
2016-01-02 22:59:48 +01:00
|
|
|
|
2019-07-03 23:00:46 +02:00
|
|
|
snprintf(dir, PATH_MAX, "%s/%s", userHome, subdir);
|
2017-02-01 22:10:48 +01:00
|
|
|
if ((mkdir(dir) != 0) && (errno != EEXIST))
|
|
|
|
engine_showError(2, dir);
|
|
|
|
|
2020-02-27 01:46:33 +01:00
|
|
|
snprintf(engine.configDirectory, PATH_MAX, "%s/", dir);
|
|
|
|
#elif __HAIKU__
|
|
|
|
subdir = "starfighter";
|
|
|
|
|
|
|
|
char path[PATH_MAX];
|
|
|
|
if (find_directory(B_USER_SETTINGS_DIRECTORY, 0, false, path, PATH_MAX) == B_OK)
|
|
|
|
snprintf(dir, PATH_MAX, "%s/%s", path, subdir);
|
|
|
|
|
|
|
|
if ((mkdir(dir, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH) != 0) && (errno != EEXIST))
|
|
|
|
engine_showError(2, dir);
|
|
|
|
|
2019-07-03 23:00:46 +02:00
|
|
|
snprintf(engine.configDirectory, PATH_MAX, "%s/", dir);
|
2017-02-01 22:10:48 +01:00
|
|
|
#else
|
2019-07-03 23:00:46 +02:00
|
|
|
subdir = "starfighter";
|
|
|
|
|
|
|
|
if ((userHome = getenv("XDG_CONFIG_HOME")) != NULL)
|
|
|
|
{
|
|
|
|
snprintf(dir, PATH_MAX, "%s/%s", userHome, subdir);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
if ((userHome = getenv("HOME")) == NULL)
|
|
|
|
userHome = getpwuid(getuid())->pw_dir;
|
|
|
|
|
|
|
|
snprintf(dir, PATH_MAX, "%s/.config", userHome);
|
|
|
|
if ((mkdir(dir, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH) != 0) && (errno != EEXIST))
|
|
|
|
engine_showError(2, dir);
|
|
|
|
|
|
|
|
snprintf(dir, PATH_MAX, "%s/.config/%s", userHome, subdir);
|
|
|
|
}
|
2016-01-02 22:59:48 +01:00
|
|
|
|
|
|
|
if ((mkdir(dir, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH) != 0) && (errno != EEXIST))
|
|
|
|
engine_showError(2, dir);
|
2019-07-03 23:00:46 +02:00
|
|
|
|
|
|
|
snprintf(engine.configDirectory, PATH_MAX, "%s/", dir);
|
2017-02-01 22:10:48 +01:00
|
|
|
#endif
|
2016-01-02 22:59:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
This sets up the video and sound system, and creates Starfighter's window.
|
|
|
|
*/
|
|
|
|
void engine_setMode()
|
|
|
|
{
|
|
|
|
strcpy(engine.configDirectory, "");
|
|
|
|
|
|
|
|
engine_setupConfigDirectory();
|
|
|
|
|
|
|
|
/* Initialize the SDL library */
|
|
|
|
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_JOYSTICK) < 0)
|
|
|
|
{
|
|
|
|
printf("Couldn't initialize SDL: %s\n", SDL_GetError());
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
char filename[PATH_MAX];
|
|
|
|
int fullScreen = 0;
|
|
|
|
int useSound = 1;
|
|
|
|
int useMusic = 1;
|
|
|
|
int autoPause = 0;
|
|
|
|
|
|
|
|
FILE *fp;
|
2018-04-21 16:44:33 +02:00
|
|
|
snprintf(filename, PATH_MAX, "%sconf", engine.configDirectory);
|
2017-03-28 16:35:11 +02:00
|
|
|
fp = fopen(filename, "r");
|
2016-01-02 22:59:48 +01:00
|
|
|
|
|
|
|
if (fp != NULL)
|
|
|
|
{
|
|
|
|
if (fscanf(fp, "%d %d %d %d", &fullScreen, &useSound, &useMusic, &autoPause) < 4)
|
|
|
|
printf("Warning: Config file \"%s\" is not correctly formatted\n", filename);
|
|
|
|
fclose(fp);
|
|
|
|
}
|
|
|
|
|
|
|
|
engine.fullScreen = fullScreen;
|
|
|
|
engine.useSound = useSound;
|
|
|
|
engine.useMusic = useMusic;
|
|
|
|
engine.autoPause = autoPause;
|
|
|
|
|
2019-05-30 19:14:32 +02:00
|
|
|
screen_adjustDimensions(DEFAULT_SCREEN_WIDTH, DEFAULT_SCREEN_HEIGHT);
|
2016-01-02 22:59:48 +01:00
|
|
|
|
2019-05-30 18:29:47 +02:00
|
|
|
window = SDL_CreateWindow("Project: Starfighter",
|
|
|
|
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
|
|
|
screen->w, screen->h, SDL_WINDOW_RESIZABLE);
|
2016-01-02 22:59:48 +01:00
|
|
|
if (window == NULL)
|
|
|
|
{
|
|
|
|
printf("Could not create window: %s\n", SDL_GetError());
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_SetWindowIcon(window, gfx_loadImage("gfx/alienDevice.png"));
|
2017-02-05 22:40:59 +01:00
|
|
|
SDL_SetWindowFullscreen(window, engine.fullScreen ? FULLSCREEN : 0);
|
2016-01-02 22:59:48 +01:00
|
|
|
|
2019-05-30 19:14:32 +02:00
|
|
|
renderer_reset();
|
2016-01-02 22:59:48 +01:00
|
|
|
|
2017-01-22 06:11:13 +01:00
|
|
|
#ifndef NOSOUND
|
2016-01-02 22:59:48 +01:00
|
|
|
if (engine.useAudio)
|
|
|
|
{
|
2019-06-06 15:30:22 +02:00
|
|
|
if (Mix_OpenAudio(44100, AUDIO_S16, 2, 1024) < 0)
|
2016-01-02 22:59:48 +01:00
|
|
|
{
|
|
|
|
printf("Warning: Couldn't set 44100 Hz 16-bit stereo audio - Reason:\n%s\n", Mix_GetError());
|
|
|
|
printf("Sound and Music will be disabled\n");
|
2016-11-19 17:43:50 +01:00
|
|
|
engine.useAudio = 0;
|
2016-01-02 22:59:48 +01:00
|
|
|
}
|
|
|
|
}
|
2017-01-22 06:11:13 +01:00
|
|
|
#endif
|
2016-01-02 22:59:48 +01:00
|
|
|
|
|
|
|
SDL_ShowCursor(SDL_DISABLE);
|
|
|
|
SDL_EventState(SDL_MOUSEMOTION, SDL_DISABLE);
|
|
|
|
|
|
|
|
SDL_JoystickEventState(SDL_ENABLE);
|
|
|
|
SDL_JoystickOpen(0);
|
|
|
|
}
|
|
|
|
|
2019-05-30 18:01:42 +02:00
|
|
|
void engine_setFullscreen(int value)
|
|
|
|
{
|
|
|
|
engine.fullScreen = value;
|
|
|
|
|
|
|
|
// Clear the screen (prevents artifacts)
|
|
|
|
screen_clear(black);
|
|
|
|
renderer_update();
|
2019-05-30 18:29:47 +02:00
|
|
|
screen_clear(black);
|
|
|
|
screen_addBuffer(0, 0, screen->w, screen->h);
|
2019-05-30 18:01:42 +02:00
|
|
|
|
|
|
|
SDL_SetWindowFullscreen(window, engine.fullScreen ? FULLSCREEN : 0);
|
|
|
|
}
|
|
|
|
|
2016-11-23 03:16:49 +01:00
|
|
|
void engine_resetLists()
|
|
|
|
{
|
2016-11-25 18:37:26 +01:00
|
|
|
Object *ob, *ob2;
|
|
|
|
Collectable *c1, *c2;
|
2016-11-26 00:41:55 +01:00
|
|
|
LinkedRect *r1, *r2;
|
2016-11-23 03:16:49 +01:00
|
|
|
|
|
|
|
ob = engine.bulletHead->next;
|
|
|
|
while(ob != NULL)
|
|
|
|
{
|
|
|
|
ob2 = ob;
|
|
|
|
ob = ob->next;
|
2019-05-20 00:22:53 +02:00
|
|
|
free(ob2);
|
2016-11-23 03:16:49 +01:00
|
|
|
}
|
|
|
|
engine.bulletHead->next = NULL;
|
|
|
|
engine.bulletTail = engine.bulletHead;
|
|
|
|
|
|
|
|
ob = engine.explosionHead->next;
|
|
|
|
while(ob != NULL)
|
|
|
|
{
|
|
|
|
ob2 = ob;
|
|
|
|
ob = ob->next;
|
2019-05-20 00:22:53 +02:00
|
|
|
free(ob2);
|
2016-11-23 03:16:49 +01:00
|
|
|
}
|
|
|
|
engine.explosionHead->next = NULL;
|
|
|
|
engine.explosionTail = engine.explosionHead;
|
|
|
|
|
|
|
|
c1 = engine.collectableHead->next;
|
|
|
|
while (c1 != NULL)
|
|
|
|
{
|
|
|
|
c2 = c1;
|
|
|
|
c1 = c1->next;
|
2019-05-20 00:22:53 +02:00
|
|
|
free(c2);
|
2016-11-23 03:16:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
engine.collectableHead->next = NULL;
|
|
|
|
engine.collectableTail = engine.collectableHead;
|
2019-06-06 15:30:22 +02:00
|
|
|
|
2016-11-23 03:16:49 +01:00
|
|
|
r1 = screen_bufferHead->next;
|
|
|
|
while (r1 != NULL)
|
|
|
|
{
|
|
|
|
r2 = r1;
|
|
|
|
r1 = r1->next;
|
2019-05-20 00:22:53 +02:00
|
|
|
free(r2);
|
2016-11-23 03:16:49 +01:00
|
|
|
}
|
2019-06-06 15:30:22 +02:00
|
|
|
|
2016-11-23 03:16:49 +01:00
|
|
|
screen_bufferHead->next = NULL;
|
|
|
|
screen_bufferTail = screen_bufferHead;
|
|
|
|
|
|
|
|
ob = engine.debrisHead->next;
|
|
|
|
while(ob != NULL)
|
|
|
|
{
|
|
|
|
ob2 = ob;
|
|
|
|
ob = ob->next;
|
2019-05-20 00:22:53 +02:00
|
|
|
free(ob2);
|
2016-11-23 03:16:49 +01:00
|
|
|
}
|
|
|
|
engine.debrisHead->next = NULL;
|
|
|
|
engine.debrisTail = engine.debrisHead;
|
|
|
|
}
|
|
|
|
|
2016-01-02 22:59:48 +01:00
|
|
|
/*
|
|
|
|
Removes [hopefully] all the resources that has been
|
|
|
|
loaded and created during the game. This is called by
|
|
|
|
atexit();
|
|
|
|
*/
|
|
|
|
void engine_cleanup()
|
|
|
|
{
|
|
|
|
gfx_free();
|
|
|
|
SDL_FreeSurface(gfx_background);
|
2019-05-30 22:46:55 +02:00
|
|
|
SDL_FreeSurface(gfx_unscaledBackground);
|
2016-01-02 22:59:48 +01:00
|
|
|
audio_free();
|
2016-11-23 03:16:49 +01:00
|
|
|
engine_resetLists();
|
2019-05-19 19:40:50 +02:00
|
|
|
free(engine.bulletHead);
|
2019-05-20 00:22:53 +02:00
|
|
|
free(engine.explosionHead);
|
|
|
|
free(engine.collectableHead);
|
|
|
|
free(screen_bufferHead);
|
2016-01-02 22:59:48 +01:00
|
|
|
|
Fixed more magic numbers.
God, this one was definitely the biggest headache of all of the
magic number erasing. Never did I expect such cryptic problems.
The first problem was that the entirety of the player's weapon
struct was a part of the save file, *including the weapon's "image
indexes"*. Since the indexes have been changed, and the originally
used one is now unavailable when it's requested, this was causing
a segfault later on. Had to fix this by setting the image index
when the game is loaded.
The second problem was related to another bug I've been confused
about for years: the one that causes mobile rays to fire 5 green
shots. The entire reason those shots were green was because
the weapon's image indexes were undefined, and *that was causing
them to default to 0*. 0 was simply the index of green plasma.
Of course, though, now attempting to use that image causes a
segfault, so for now, I've fixed this by changing the image index
of the mobile rays to the red plasma bolts.
There are still some magic numbers left, related to the intermission
screen. But the hardest part is now done, thank God.
2016-01-06 04:12:29 +01:00
|
|
|
for (int i = 0 ; i < FONT_MAX ; i++)
|
2016-01-02 22:59:48 +01:00
|
|
|
{
|
2016-01-04 04:39:16 +01:00
|
|
|
if (gfx_fontSprites[i] != NULL)
|
|
|
|
SDL_FreeSurface(gfx_fontSprites[i]);
|
2016-01-02 22:59:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
char filename[PATH_MAX];
|
|
|
|
strcpy(filename, "");
|
|
|
|
|
2019-06-04 03:05:38 +02:00
|
|
|
#ifndef NOFONT
|
|
|
|
if (gfx_unicodeFont != NULL)
|
|
|
|
{
|
|
|
|
TTF_CloseFont(gfx_unicodeFont);
|
|
|
|
gfx_unicodeFont = NULL;
|
|
|
|
}
|
|
|
|
if (TTF_WasInit())
|
|
|
|
{
|
|
|
|
TTF_Quit();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-01-22 06:11:13 +01:00
|
|
|
#ifndef NOSOUND
|
2016-01-02 22:59:48 +01:00
|
|
|
if (engine.useAudio)
|
|
|
|
{
|
|
|
|
Mix_CloseAudio();
|
|
|
|
}
|
2017-01-22 06:11:13 +01:00
|
|
|
#endif
|
2016-01-02 22:59:48 +01:00
|
|
|
|
|
|
|
// Save the config using current settings
|
|
|
|
FILE *fp;
|
2018-04-21 16:44:33 +02:00
|
|
|
snprintf(filename, PATH_MAX, "%sconf", engine.configDirectory);
|
2017-03-28 16:35:11 +02:00
|
|
|
fp = fopen(filename, "w");
|
2016-01-02 22:59:48 +01:00
|
|
|
if (fp != NULL)
|
|
|
|
{
|
|
|
|
fprintf(fp, "%d %d %d %d\n", engine.fullScreen, engine.useSound,
|
|
|
|
engine.useMusic, engine.autoPause);
|
|
|
|
fclose(fp);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf("Error saving config\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_Quit();
|
|
|
|
printf("Thank You for playing Starfighter\n");
|
|
|
|
}
|