#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); }