Lephisto/src/save.c

160 lines
3.6 KiB
C

#include "lephisto.h"
#include "log.h"
#include "xml.h"
#include "player.h"
#include "toolkit.h"
#include "menu.h"
#include "lfile.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);
extern int missions_save(xmlTextWriterPtr writer);
extern int var_save(xmlTextWriterPtr writer); // misn var.
extern int player_load(xmlNodePtr parent);
extern void menu_main_close(void);
// Static.
static int save_data(xmlTextWriterPtr writer);
static void load_menu_close(char* str);
static void load_menu_load(char* str);
static int load_game(char* file);
// Save all the game data.
static int save_data(xmlTextWriterPtr writer) {
// The data itself.
if(player_save(writer) < 0) return -1;
if(missions_save(writer) < 0) return -1;
if(var_save(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);
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';
}
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);
// Default action.
window_setFptr(wid, load_menu_load);
}
static void load_menu_close(char* str) {
(void)str;
window_destroy(window_get("Load Game"));
}
static void load_menu_load(char* str) {
(void)str;
char* save, path[PATH_MAX];
int wid;
wid = window_get("Load Game");
save = toolkit_getList(wid, "lstSaves");
snprintf(path, PATH_MAX, "%ssaves/%s.ls", lfile_basePath(), save);
load_game(path);
load_menu_close(NULL);
menu_main_close();
}
// Load a new game.
static int load_game(char* file) {
xmlNodePtr node;
xmlDocPtr doc;
doc = xmlParseFile(file);
node = doc->xmlChildrenNode; // Base node.
player_load(node);
xmlFreeDoc(doc);
return 0;
}