tbftss/src/system/init.c

386 lines
9.4 KiB
C
Raw Normal View History

2015-10-20 13:51:49 +02:00
/*
2019-01-01 17:14:11 +01:00
Copyright (C) 2015-2019 Parallel Realities
2015-10-20 13:51:49 +02:00
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
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
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "init.h"
static void loadConfig(int argc, char *argv[]);
static void loadConfigFile(char *filename);
2015-10-20 13:51:49 +02:00
void saveConfig(void);
static void showLoadingStep(float step, float maxSteps);
static void handleCommandLineConfig(int argc, char *argv[]);
2015-10-20 13:51:49 +02:00
void init18N(int argc, char *argv[])
{
int i;
int languageId = -1;
2016-03-03 19:03:07 +01:00
setlocale(LC_NUMERIC, "");
2016-03-03 19:03:07 +01:00
for (i = 1 ; i < argc ; i++)
{
if (strcmp(argv[i], "-language") == 0)
{
languageId = i + 1;
2016-03-03 19:03:07 +01:00
if (languageId >= argc)
{
2016-04-04 12:25:09 +02:00
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR, "You must specify a language to use with -language. Using default.");
}
}
}
2016-03-03 19:03:07 +01:00
setLanguage("tbftss", languageId == -1 ? NULL : argv[languageId]);
2016-03-03 19:03:07 +01:00
2016-04-04 12:25:09 +02:00
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Numeric is %s", setlocale(LC_NUMERIC, "C"));
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "atof(2.75) is %f", atof("2.75"));
}
void initSDL(int argc, char *argv[])
2015-10-20 13:51:49 +02:00
{
int rendererFlags, windowFlags;
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
/* do this here, so we don't destroy the save dir stored in app */
memset(&app, 0, sizeof(App));
2016-03-03 19:03:07 +01:00
/* done in src/plat/ */
2015-10-20 13:51:49 +02:00
createSaveFolder();
2019-10-23 19:43:19 +02:00
loadConfig(argc, argv);
2016-03-03 19:03:07 +01:00
2017-05-26 08:48:10 +02:00
rendererFlags = SDL_RENDERER_ACCELERATED;
2019-10-23 19:43:19 +02:00
2017-05-26 08:48:10 +02:00
if (app.vSync)
{
rendererFlags |= SDL_RENDERER_PRESENTVSYNC;
}
2019-10-23 19:43:19 +02:00
2015-10-20 13:51:49 +02:00
windowFlags = 0;
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
if (app.fullscreen)
{
windowFlags |= SDL_WINDOW_FULLSCREEN;
}
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0)
{
printf("Couldn't initialize SDL: %s\n", SDL_GetError());
exit(1);
}
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
SDL_ShowCursor(0);
2016-03-03 19:03:07 +01:00
if (Mix_OpenAudio(AUDIO_FREQUENCY, MIX_DEFAULT_FORMAT, AUDIO_CHANNELS, AUDIO_CHUNKSIZE) == -1)
2015-10-20 13:51:49 +02:00
{
printf("Couldn't initialize SDL Mixer\n");
exit(1);
}
2016-03-03 19:03:07 +01:00
Mix_AllocateChannels(AUDIO_MIX_CHANNELS);
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
Mix_Volume(-1, app.soundVolume * MIX_MAX_VOLUME / 10);
Mix_VolumeMusic(app.musicVolume * MIX_MAX_VOLUME / 10);
2016-02-22 13:47:41 +01:00
app.window = SDL_CreateWindow("TBFTSS - The Pandoran War", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, app.winWidth, app.winHeight, windowFlags);
2015-10-20 13:51:49 +02:00
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
app.renderer = SDL_CreateRenderer(app.window, -1, rendererFlags);
IMG_Init(IMG_INIT_PNG | IMG_INIT_JPG);
if (TTF_Init() < 0)
{
printf("Couldn't initialize SDL TTF: %s\n", SDL_GetError());
exit(1);
}
2016-03-03 19:03:07 +01:00
2018-12-12 09:32:32 +01:00
app.backBuffer = SDL_CreateTexture(app.renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, app.winWidth, app.winHeight);
2016-03-03 19:03:07 +01:00
2018-12-12 09:32:32 +01:00
app.uiBuffer = SDL_CreateTexture(app.renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, UI_WIDTH, UI_HEIGHT);
SDL_SetTextureBlendMode(app.uiBuffer, SDL_BLENDMODE_BLEND);
2018-12-17 09:30:47 +01:00
app.uiOffset.x = (app.winWidth / 2) - (UI_WIDTH / 2);
app.uiOffset.y = (app.winHeight / 2) - (UI_HEIGHT / 2);
2016-03-03 19:03:07 +01:00
2018-12-17 09:30:47 +01:00
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "UI offset: %d,%d\n", app.uiOffset.x, app.uiOffset.y);
2015-10-20 13:51:49 +02:00
}
void initGameSystem(void)
{
int i, numInitFuns;
void (*initFuncs[]) (void) = {
initGraphics,
initFonts,
initResources,
initSounds,
initWidgets,
initGame,
loadFighterDefs,
loadCapitalShipDefs,
loadItemDefs,
initBulletDefs,
initStarSystems,
initChallenges,
initStats,
initModalDialog,
2016-03-12 19:22:48 +01:00
initStars,
2016-03-27 12:32:38 +02:00
initControls,
2017-08-07 20:14:43 +02:00
initTrophies,
initFighterDatabase,
updateCustomResolutionOption
};
2016-03-03 19:03:07 +01:00
2018-12-06 09:37:19 +01:00
initAtlas();
2019-10-23 19:43:19 +02:00
2018-12-06 09:37:19 +01:00
initInput();
2019-10-23 19:43:19 +02:00
numInitFuns = sizeof(initFuncs) / sizeof(void*);
2016-03-03 19:03:07 +01:00
for (i = 0 ; i < numInitFuns ; i++)
{
2016-05-15 09:19:26 +02:00
showLoadingStep(i + 1, numInitFuns);
2016-03-03 19:03:07 +01:00
initFuncs[i]();
}
}
/*
2019-10-23 19:43:19 +02:00
* Just in case the initial loading takes a while on the target machine. The rest of the loading is pretty quick by comparison.
*/
static void showLoadingStep(float step, float maxSteps)
{
SDL_Rect r;
2016-03-03 19:03:07 +01:00
prepareScene();
2016-03-03 19:03:07 +01:00
2018-12-12 09:32:32 +01:00
r.w = 600;
r.h = 12;
r.x = (app.winWidth / 2) - r.w / 2;
r.y = (app.winHeight / 2) - r.h / 2;
2016-03-03 19:03:07 +01:00
SDL_SetRenderDrawColor(app.renderer, 128, 128, 128, 255);
SDL_RenderDrawRect(app.renderer, &r);
2016-03-03 19:03:07 +01:00
r.w *= (step / maxSteps);
r.x += 2;
r.y += 2;
r.w -= 4;
r.h -= 4;
2016-03-03 19:03:07 +01:00
SDL_SetRenderDrawColor(app.renderer, 128, 196, 255, 255);
SDL_RenderFillRect(app.renderer, &r);
2016-03-03 19:03:07 +01:00
presentScene();
2016-03-03 19:03:07 +01:00
SDL_Delay(1);
2015-10-20 13:51:49 +02:00
}
static void loadConfig(int argc, char *argv[])
2015-10-20 13:51:49 +02:00
{
char *configFilename;
2019-10-23 19:43:19 +02:00
/* load default config first */
loadConfigFile("data/app/"CONFIG_FILENAME);
2019-10-23 19:43:19 +02:00
/* load saved config */
configFilename = getSaveFilePath(CONFIG_FILENAME);
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
if (fileExists(configFilename))
{
loadConfigFile(configFilename);
2015-10-20 13:51:49 +02:00
}
2019-10-23 19:43:19 +02:00
handleCommandLineConfig(argc, argv);
2019-10-23 19:43:19 +02:00
/* don't go higher than 8K or lower than 1280 x 720 */
app.winWidth = MIN(MAX(app.winWidth, 1280), 7680);
app.winHeight = MIN(MAX(app.winHeight, 720), 4320);
2019-10-23 19:43:19 +02:00
2016-05-15 09:19:26 +02:00
/* so that the player doesn't get confused if this is a new game */
saveConfig();
}
static void loadConfigFile(char *filename)
{
int i;
2016-05-15 09:19:26 +02:00
cJSON *root, *controlsJSON, *node, *gameplayJSON;
char *text;
text = readFile(filename);
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
root = cJSON_Parse(text);
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
app.winWidth = cJSON_GetObjectItem(root, "winWidth")->valueint;
app.winHeight = cJSON_GetObjectItem(root, "winHeight")->valueint;
app.fullscreen = cJSON_GetObjectItem(root, "fullscreen")->valueint;
app.musicVolume = cJSON_GetObjectItem(root, "musicVolume")->valueint;
app.soundVolume = cJSON_GetObjectItem(root, "soundVolume")->valueint;
2017-05-26 08:48:10 +02:00
app.vSync = getJSONValue(root, "vSync", 1);
2019-10-23 19:43:19 +02:00
2016-03-03 19:03:07 +01:00
controlsJSON = cJSON_GetObjectItem(root, "controls");
if (controlsJSON)
{
node = cJSON_GetObjectItem(controlsJSON, "keys")->child;
while (node)
{
i = lookup(node->string);
2016-03-03 19:03:07 +01:00
app.keyControls[i] = node->valueint;
2016-03-03 19:03:07 +01:00
node = node->next;
}
2016-03-03 19:03:07 +01:00
node = cJSON_GetObjectItem(controlsJSON, "mouse")->child;
while (node)
{
i = lookup(node->string);
2016-03-03 19:03:07 +01:00
app.mouseControls[i] = node->valueint;
2016-03-03 19:03:07 +01:00
node = node->next;
}
}
2019-10-23 19:43:19 +02:00
2016-05-15 09:19:26 +02:00
gameplayJSON = cJSON_GetObjectItem(root, "gameplay");
if (gameplayJSON)
{
app.gameplay.friendlyFire = cJSON_GetObjectItem(gameplayJSON, "friendlyFire")->valueint;
app.gameplay.autoSwitchPlayerTarget = cJSON_GetObjectItem(gameplayJSON, "autoSwitchPlayerTarget")->valueint;
app.gameplay.missileReTarget = cJSON_GetObjectItem(gameplayJSON, "missileReTarget")->valueint;
app.gameplay.healthBars = cJSON_GetObjectItem(gameplayJSON, "healthBars")->valueint;
}
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
cJSON_Delete(root);
free(text);
}
void saveConfig(void)
{
2016-03-03 19:03:07 +01:00
int i;
2015-10-20 13:51:49 +02:00
char *out, *configFilename;
2016-05-15 09:19:26 +02:00
cJSON *root, *controlsJSON, *keysJSON, *mouseJSON, *gameplayJSON;
2016-03-03 19:03:07 +01:00
configFilename = getSaveFilePath(CONFIG_FILENAME);
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Saving config ...");
root = cJSON_CreateObject();
cJSON_AddNumberToObject(root, "winWidth", app.winWidth);
cJSON_AddNumberToObject(root, "winHeight", app.winHeight);
cJSON_AddNumberToObject(root, "fullscreen", app.fullscreen);
cJSON_AddNumberToObject(root, "musicVolume", app.musicVolume);
cJSON_AddNumberToObject(root, "soundVolume", app.soundVolume);
2017-05-26 08:48:10 +02:00
cJSON_AddNumberToObject(root, "vSync", app.vSync);
2016-03-03 19:03:07 +01:00
keysJSON = cJSON_CreateObject();
for (i = 0 ; i < CONTROL_MAX ; i++)
{
cJSON_AddNumberToObject(keysJSON, getLookupName("CONTROL_", i), app.keyControls[i]);
}
2016-03-03 19:03:07 +01:00
mouseJSON = cJSON_CreateObject();
for (i = 0 ; i < CONTROL_MAX ; i++)
{
cJSON_AddNumberToObject(mouseJSON, getLookupName("CONTROL_", i), app.mouseControls[i]);
}
2016-03-03 19:03:07 +01:00
controlsJSON = cJSON_CreateObject();
cJSON_AddItemToObject(controlsJSON, "keys", keysJSON);
cJSON_AddItemToObject(controlsJSON, "mouse", mouseJSON);
cJSON_AddItemToObject(root, "controls", controlsJSON);
2019-10-23 19:43:19 +02:00
2016-05-15 09:19:26 +02:00
gameplayJSON = cJSON_CreateObject();
cJSON_AddNumberToObject(gameplayJSON, "friendlyFire", app.gameplay.friendlyFire);
cJSON_AddNumberToObject(gameplayJSON, "autoSwitchPlayerTarget", app.gameplay.autoSwitchPlayerTarget);
cJSON_AddNumberToObject(gameplayJSON, "missileReTarget", app.gameplay.missileReTarget);
cJSON_AddNumberToObject(gameplayJSON, "healthBars", app.gameplay.healthBars);
cJSON_AddItemToObject(root, "gameplay", gameplayJSON);
2015-10-20 13:51:49 +02:00
out = cJSON_Print(root);
if (!writeFile(configFilename, out))
{
2016-03-03 19:03:07 +01:00
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR, "Failed to save config");
2015-10-20 13:51:49 +02:00
}
cJSON_Delete(root);
free(out);
}
static void handleCommandLineConfig(int argc, char *argv[])
{
int i;
2019-10-23 19:43:19 +02:00
for (i = 1 ; i < argc ; i++)
{
if (strcmp(argv[i], "-size") == 0)
{
sscanf(argv[i + 1], "%dx%d", &app.winWidth, &app.winHeight);
}
}
}
2015-10-20 13:51:49 +02:00
void cleanup(void)
{
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Cleaning up ...");
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
destroyLookups();
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
destroyTextures();
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
destroySounds();
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
destroyGame();
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
destroyFighterDefs();
2016-03-03 19:03:07 +01:00
2015-12-07 20:19:14 +01:00
destroyCapitalShipDefs();
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
destroyBulletDefs();
2016-03-03 19:03:07 +01:00
2015-11-16 12:27:03 +01:00
destroyItemDefs();
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
destroyStarSystems();
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
destroyBattle();
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
destroyGalacticMap();
2016-03-03 19:03:07 +01:00
2015-10-20 13:51:49 +02:00
destroyWidgets();
destroyResources();
2019-10-23 19:43:19 +02:00
2017-08-09 19:21:26 +02:00
destroyFighterDatabase();
2019-10-23 19:43:19 +02:00
destroyFighterStats();
2019-10-23 19:43:19 +02:00
2016-05-29 10:38:05 +02:00
destroyCredits();
2019-10-23 19:43:19 +02:00
2016-03-12 19:22:48 +01:00
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Done");
2019-10-23 19:43:19 +02:00
SDL_DestroyRenderer(app.renderer);
2019-10-23 19:43:19 +02:00
SDL_DestroyWindow(app.window);
2015-10-20 13:51:49 +02:00
TTF_Quit();
SDL_Quit();
}