Skip to content
Snippets Groups Projects
save_load.c 3.22 KiB
Newer Older
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#include "dungeon.h"
#include "save_load.h"

FILE* open_save_file(char* mode) {
	char *home = getenv("HOME");
	char *path;

	path = malloc(strlen(home) + strlen(FILENAME) + 1);

	strcpy(path, home);
	strcat(path, FILENAME);
	
	FILE* f = fopen(path, mode);
	
	if (!f) {
		fprintf(stderr, "Error: Cannot open file: %s\n", path);
		free(path);
		exit(-1);
	}
	
	free(path);
	
	return f;
}

void read_short(FILE* f, uint16_t* val) {
	uint16_t tmp;
	fread(&tmp, 2, 1, f);
	*val = be16toh(tmp);
}

void read_int(FILE* f, uint32_t* val) {
	uint32_t tmp;
	fread(&tmp, 4, 1, f);
	*val = be32toh(tmp);
}

void write_short(FILE* f, uint16_t val) {
	uint16_t tmp = val;
	tmp = htobe16(tmp);
	fwrite(&tmp, 2, 1, f);
}

void write_int(FILE* f, uint32_t val) {
	uint32_t tmp = val;
	tmp = htobe32(tmp);
	fwrite(&tmp, 4, 1, f);
}

void load_dungeon(dungeon_t* d) {
	int i;
	
	FILE* f = open_save_file("r");
	
	// Skip the file type marker, version, and filesize
	fseek(f, 20, SEEK_CUR);
	
	// Read the player position
	fread(&(d->player_pos.x), 1, 1, f);
	fread(&(d->player_pos.y), 1, 1, f);
	
	// Read the hardness map
	fread(d->hardness, 1, MAP_WIDTH * MAP_HEIGHT, f);
	
	// Read the rooms
	read_short(f, &(d->room_count));
	d->room_list = malloc(d->room_count * sizeof(room_t));
	
	for (i = 0; i < d->room_count; i++) {
		fread(&(d->room_list[i].x), 1, 1, f);
		fread(&(d->room_list[i].y), 1, 1, f);
		fread(&(d->room_list[i].w), 1, 1, f);
		fread(&(d->room_list[i].h), 1, 1, f);
	}
	
	// Read the up staircases
	read_short(f, &(d->upstair_count));
	d->upstair_list = malloc(d->upstair_count * sizeof(position_t));
	
	for (i = 0; i < d->upstair_count; i++) {
		fread(&(d->upstair_list[i].x), 1, 1, f);
		fread(&(d->upstair_list[i].y), 1, 1, f);
	}
	
	// Read the down staircases
	read_short(f, &(d->downstair_count));
	d->downstair_list = malloc(d->downstair_count * sizeof(position_t));
	
	for (i = 0; i < d->downstair_count; i++) {
		fread(&(d->downstair_list[i].x), 1, 1, f);
		fread(&(d->downstair_list[i].y), 1, 1, f);
	}
	
	fclose(f);
}

void save_dungeon(dungeon_t* d) {
	int i;
	
	FILE* f = open_save_file("w");
	
	// Write the file-type maker
	fprintf(f, "%s", FILETYPE_MARKER);
	
	// Write the version number
	write_int(f, VERSION);
	
	// Write the filesize
	write_int(f, 1708 + (d->room_count*4) + (d->downstair_count*2) + (d->upstair_count*2));
	
	// Write the player position
	fwrite(&(d->player_pos.x), 1, 1, f);
	fwrite(&(d->player_pos.y), 1, 1, f);
	
	// Write the hardness map
	fwrite(d->hardness, 1, MAP_WIDTH * MAP_HEIGHT, f);
	
	// Write the rooms
	write_short(f, d->room_count);
	
	for (i = 0; i < d->room_count; i++) {
		fwrite(&(d->room_list[i].x), 1, 1, f);
		fwrite(&(d->room_list[i].y), 1, 1, f);
		fwrite(&(d->room_list[i].w), 1, 1, f);
		fwrite(&(d->room_list[i].h), 1, 1, f);
	}
	
	// Write the up staircases
	write_short(f, d->upstair_count);
	
	for (i = 0; i < d->upstair_count; i++) {
		fwrite(&(d->upstair_list[i].x), 1, 1, f);
		fwrite(&(d->upstair_list[i].y), 1, 1, f);
	}
	
	// Read the down staircases
	write_short(f, d->downstair_count);

	for (i = 0; i < d->downstair_count; i++) {
		fwrite(&(d->downstair_list[i].x), 1, 1, f);
		fwrite(&(d->downstair_list[i].y), 1, 1, f);
	}
	
	fclose(f);
}