- File operations work on "data/" folder or ".jrf" file

- [NEW] fopenres() works on .jrf resources, fopen on normal files
This commit is contained in:
2022-10-11 17:58:03 +02:00
parent a74ca5033c
commit b282bd05d5
8 changed files with 185 additions and 24 deletions

123
jfile.cpp Normal file
View File

@@ -0,0 +1,123 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include "jfile.h"
#define DEFAULT_FILENAME "data.jrf"
#define DEFAULT_FOLDER "data/"
#pragma pack(push,1)
struct DATA_Header {
char magic[4];
uint32_t num_files;
uint32_t index_offset;
};
struct DATA_Info {
uint32_t offset;
uint32_t length;
char name[13];
};
struct DATA_Index {
DATA_Info* file_info;
};
struct DATA_File {
DATA_Header header;
DATA_Index index;
};
#pragma pack(pop)
char *resource_filename = NULL;
char *resource_folder = NULL;
DATA_File *data_file = NULL;
int file_source = SOURCE_FILE;
char scratch[255];
void file_setresourcefilename(const char *str) {
if (resource_filename != NULL) free(resource_filename);
resource_filename = (char*)malloc(strlen(str)+1);
strcpy(resource_filename, str);
}
void file_setresourcefolder(const char *str) {
if (resource_folder != NULL) free(resource_folder);
resource_folder = (char*)malloc(strlen(str)+1);
strcpy(resource_folder, str);
}
void file_setsource(const int src) {
file_source = src%2; // mod 2 so it always is a valid value, 0 (file) or 1 (folder)
if (src==SOURCE_FOLDER && resource_folder==NULL) file_setresourcefolder(DEFAULT_FOLDER);
}
bool file_getdictionary() {
if (resource_filename == NULL) file_setresourcefilename(DEFAULT_FILENAME);
FILE* f = fopen(resource_filename, "rb");
if (f) {
data_file = (DATA_File*)malloc(sizeof(DATA_File));
fread((char*)&data_file->header, sizeof(DATA_Header), 1, f);
fseek(f, data_file->header.index_offset, SEEK_SET);
data_file->index.file_info = (DATA_Info*)malloc(data_file->header.num_files * sizeof(DATA_Info));
fread((char*)data_file->index.file_info, data_file->header.num_files * sizeof(DATA_Info), 1, f);
fclose(f);
return true;
} else {
return false;
}
}
char *file_getfilenamewithfolder(const char* filename) {
strcpy(scratch, resource_folder);
strcat(scratch, filename);
return scratch;
}
FILE *file_getfilepointer(const char *resourcename, int& filesize, const bool binary) {
if (file_source==SOURCE_FILE and not data_file) {
if (not file_getdictionary()) file_setsource(SOURCE_FOLDER);
}
FILE *f;
if (file_source==SOURCE_FILE) {
bool found = false;
int count = 0;
while( !found && count < data_file->header.num_files ) {
found = ( strcmp( resourcename, data_file->index.file_info[count].name ) == 0 );
if( !found ) count++;
}
if( !found ) {
perror("El recurs no s'ha trobat en l'arxiu de recursos");
exit(1);
}
filesize = data_file->index.file_info[count].length;
f = fopen(resource_filename, binary?"rb":"r");
if (not f) {
perror("No s'ha pogut obrir l'arxiu de recursos");
exit(1);
}
fseek(f, data_file->index.file_info[count].offset, SEEK_SET);
} else {
f = fopen(file_getfilenamewithfolder(resourcename), binary?"rb":"r");
fseek(f, 0, SEEK_END);
filesize = ftell(f);
fseek(f, 0, SEEK_SET);
}
return f;
}
char *file_getfilebuffer(const char *resourcename, int& filesize) {
FILE *f = file_getfilepointer(resourcename, filesize, true);
char* buffer = (char*)malloc(filesize);
fread(buffer, filesize, 1, f);
fclose(f);
return buffer;
}