231 lines
6.1 KiB
C
231 lines
6.1 KiB
C
#include <stdio.h> /* remove() */
|
|
#include "lephisto.h"
|
|
#include "log.h"
|
|
#include "xml.h"
|
|
#include "player.h"
|
|
#include "toolkit.h"
|
|
#include "dialogue.h"
|
|
#include "menu.h"
|
|
#include "lfile.h"
|
|
#include "hook.h"
|
|
#include "save.h"
|
|
|
|
#define LOAD_WIDTH 400
|
|
#define LOAD_HEIGHT 300
|
|
|
|
#define BUTTON_WIDTH 50
|
|
#define BUTTON_HEIGHT 30
|
|
|
|
/* Externs. */
|
|
extern int player_save(xmlTextWriterPtr writer); /* A lot of stuff. */
|
|
extern int player_load(xmlNodePtr parent);
|
|
extern int missions_saveActive(xmlTextWriterPtr writer); /* Active missions. */
|
|
extern int missions_loadActive(xmlNodePtr parent);
|
|
extern int var_save(xmlTextWriterPtr writer); /* misn var. */
|
|
extern int var_load(xmlNodePtr parent);
|
|
extern int pfaction_save(xmlTextWriterPtr writer); /* Faction data. */
|
|
extern int pfaction_load(xmlNodePtr parent);
|
|
extern int hook_save(xmlTextWriterPtr writer); /* Hooks. */
|
|
extern int hook_load(xmlNodePtr parent);
|
|
extern int space_sysSave(xmlTextWriterPtr writer); /* Space stuff. */
|
|
extern int space_sysLoad(xmlNodePtr parent);
|
|
extern int diff_save(xmlTextWriterPtr writer);
|
|
extern int diff_load(xmlNodePtr parent);
|
|
extern void menu_main_close(void);
|
|
/* Static. */
|
|
static int save_data(xmlTextWriterPtr writer);
|
|
static void load_menu_close(unsigned int wdw, char* str);
|
|
static void load_menu_load(unsigned int wdw, char* str);
|
|
static void load_menu_delete(unsigned wdw, char* str);
|
|
static int load_game(char* file);
|
|
|
|
/* Save all the game data. */
|
|
static int save_data(xmlTextWriterPtr writer) {
|
|
/* The data itself. */
|
|
if(diff_save(writer) < 0) return -1; /* Must save first or can get cleared. */
|
|
if(player_save(writer) < 0) return -1;
|
|
if(missions_saveActive(writer) < 0) return -1;
|
|
if(var_save(writer) < 0) return -1;
|
|
if(pfaction_save(writer) < 0) return -1;
|
|
if(hook_save(writer) < 0) return -1;
|
|
if(space_sysSave(writer) < 0) return -1;
|
|
return 0;
|
|
}
|
|
|
|
/* Save the current game. */
|
|
int save_all(void) {
|
|
char file[PATH_MAX];
|
|
xmlDocPtr doc;
|
|
xmlTextWriterPtr writer;
|
|
|
|
writer = xmlNewTextWriterDoc(&doc, 0);
|
|
if(writer == NULL) {
|
|
ERR("testXmlwriterDoc: Error creating the xml writer.");
|
|
return -1;
|
|
}
|
|
|
|
xmlw_start(writer);
|
|
xmlw_startElem(writer, "lephisto_save");
|
|
|
|
/* Save the version or something.. */
|
|
xmlw_startElem(writer, "version");
|
|
xmlw_elem(writer, "lephisto", "%d.%d.%d", VMAJOR, VMINOR, VREV);
|
|
xmlw_elem(writer, "data", dataname);
|
|
xmlw_endElem(writer); /* Version. */
|
|
|
|
if(save_data(writer) < 0) {
|
|
ERR("Trying to save game data");
|
|
xmlFreeTextWriter(writer);
|
|
xmlFreeDoc(doc);
|
|
return -1;
|
|
}
|
|
|
|
xmlw_endElem(writer); /* lephisto_save. */
|
|
xmlw_done(writer);
|
|
|
|
if(lfile_dirMakeExist("saves") < 0) {
|
|
WARN("Aborting save...");
|
|
xmlFreeTextWriter(writer);
|
|
xmlFreeDoc(doc);
|
|
return -1;
|
|
}
|
|
snprintf(file, PATH_MAX, "%ssaves/%s.ls", lfile_basePath(), player_name);
|
|
|
|
/* Critical section, if crashes, the players save game gets screwed!!!
|
|
* HAHAHAHAHA!!!!! -- NOT!
|
|
*/
|
|
xmlFreeTextWriter(writer);
|
|
xmlSaveFileEnc(file, doc, "UTF-8");
|
|
xmlFreeDoc(doc);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Open the load game menu. */
|
|
void load_game_menu(void) {
|
|
unsigned int wid;
|
|
char** files;
|
|
int lfiles, i, len;
|
|
|
|
/* Window. */
|
|
wid = window_create("Load Game", -1, -1, LOAD_WIDTH, LOAD_HEIGHT);
|
|
|
|
/* Load the saves. */
|
|
files = lfile_readDir(&lfiles, "saves");
|
|
for(i = 0; i < lfiles; i++) {
|
|
len = strlen(files[i]);
|
|
|
|
/* No save extension. */
|
|
if((len < 6) || strcmp(&files[i][len-3], ".ls")) {
|
|
free(files[i]);
|
|
memmove(&files[i], &files[i+1], sizeof(char*) * (lfiles-i-1));
|
|
lfiles--;
|
|
i--;
|
|
}
|
|
else /* Remove the extension. */
|
|
files[i][len-3] = '\0';
|
|
}
|
|
|
|
/* Again.. What if there is no files? */
|
|
if(files == NULL) {
|
|
files = malloc(sizeof(char*));
|
|
files[0] = strdup("None");
|
|
lfiles = 1;
|
|
}
|
|
|
|
window_addList(wid, 20, -50,
|
|
LOAD_WIDTH-BUTTON_WIDTH-50, LOAD_HEIGHT-90,
|
|
"lstSaves", files, lfiles, 0, NULL);
|
|
|
|
/* Buttons. */
|
|
window_addButton(wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
|
"btnBack", "Back", load_menu_close);
|
|
|
|
window_addButton(wid, -20, 30 + BUTTON_HEIGHT, BUTTON_WIDTH, BUTTON_HEIGHT,
|
|
"btnLoad", "Load", load_menu_load);
|
|
|
|
window_addButton(wid, -20, 20+2*(10+BUTTON_HEIGHT), BUTTON_WIDTH, BUTTON_HEIGHT,
|
|
"btnDelete", "Del", load_menu_delete);
|
|
|
|
/* Default action. */
|
|
window_setAccept(wid, load_menu_load);
|
|
}
|
|
|
|
static void load_menu_close(unsigned int wdw, char* str) {
|
|
(void)str;
|
|
|
|
window_destroy(wdw);
|
|
}
|
|
|
|
static void load_menu_load(unsigned int wdw, char* str) {
|
|
(void)str;
|
|
char* save, path[PATH_MAX];
|
|
int wid;
|
|
|
|
wid = window_get("Load Game");
|
|
|
|
save = toolkit_getList(wid, "lstSaves");
|
|
|
|
if(strcmp(save, "None")==0)
|
|
return;
|
|
|
|
snprintf(path, PATH_MAX, "%ssaves/%s.ls", lfile_basePath(), save);
|
|
load_game(path);
|
|
load_menu_close(wdw, NULL);
|
|
menu_main_close();
|
|
}
|
|
|
|
static void load_menu_delete(unsigned int wdw, char* str) {
|
|
(void)str;
|
|
char* save, path[PATH_MAX];
|
|
int wid;
|
|
|
|
wid = window_get("Load Game");
|
|
save = toolkit_getList(wid, "lstSaves");
|
|
|
|
if(strcmp(save, "None") == 0)
|
|
return;
|
|
|
|
if(dialogue_YesNo("Permanently Delete?",
|
|
"Are you sure you want to permanently delete '%s'?", save) == 0)
|
|
return;
|
|
|
|
snprintf(path, PATH_MAX, "%ssaves/%s.ls", lfile_basePath(), save);
|
|
remove(path); /* Remove is more portable and will call unlink on Linux. */
|
|
|
|
/* Need to reload the menu. */
|
|
load_menu_close(wdw, NULL);
|
|
load_game_menu();
|
|
}
|
|
|
|
/* Load a new game. */
|
|
static int load_game(char* file) {
|
|
xmlNodePtr node;
|
|
xmlDocPtr doc;
|
|
|
|
doc = xmlParseFile(file);
|
|
node = doc->xmlChildrenNode; /* Base node. */
|
|
if(node == NULL) {
|
|
WARN("Savegame '%s' invalid!", file);
|
|
return -1;
|
|
}
|
|
|
|
diff_load(node); /* Must load first to work properly. */
|
|
player_load(node);
|
|
var_load(node);
|
|
missions_loadActive(node);
|
|
pfaction_load(node);
|
|
hook_load(node);
|
|
space_sysLoad(node);
|
|
|
|
/* Need to run takeoff hooks since player just "took off". */
|
|
hooks_run("takeoff");
|
|
hooks_run("enter");
|
|
|
|
xmlFreeDoc(doc);
|
|
xmlCleanupParser();
|
|
|
|
return 0;
|
|
}
|
|
|