- 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

View File

@@ -2,6 +2,7 @@
#include "stb_vorbis.c"
#include <SDL2/SDL.h>
#include <stdio.h>
#include "jfile.h"
#define JA_MAX_SIMULTANEOUS_CHANNELS 5
@@ -90,7 +91,11 @@ JA_Music JA_LoadMusic(const char* filename) {
int chan, samplerate;
JA_Music music = new JA_Music_t();
int fsize;
Uint8 *buffer = (Uint8*)file_getfilebuffer(filename, fsize);
// [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid.
/*
FILE *f = fopen(filename, "rb");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
@@ -98,6 +103,7 @@ JA_Music JA_LoadMusic(const char* filename) {
Uint8 *buffer = (Uint8*)malloc(fsize + 1);
fread(buffer, fsize, 1, f);
fclose(f);
*/
music->samples = stb_vorbis_decode_memory(buffer, fsize, &chan, &samplerate, &music->output);
free(buffer);
@@ -168,7 +174,12 @@ JA_Sound JA_NewSound(Uint8* buffer, Uint32 length) {
JA_Sound JA_LoadSound(const char* filename) {
JA_Sound sound = new JA_Sound_t();
SDL_AudioSpec wavSpec;
SDL_LoadWAV(filename, &wavSpec, &sound->buffer, &sound->length);
//SDL_LoadWAV(filename, &wavSpec, &sound->buffer, &sound->length);
int size;
char *buffer = file_getfilebuffer(filename, size);
SDL_LoadWAV_RW(SDL_RWFromMem(buffer, size),1, &wavSpec, &sound->buffer, &sound->length);
free(buffer);
SDL_AudioCVT cvt;
SDL_BuildAudioCVT(&cvt, wavSpec.format, wavSpec.channels, wavSpec.freq, JA_format, JA_channels, JA_freq);

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

12
jfile.h Normal file
View File

@@ -0,0 +1,12 @@
#pragma once
#include <stdio.h>
#define SOURCE_FILE 0
#define SOURCE_FOLDER 1
void file_setresourcefilename(const char *str);
void file_setresourcefolder(const char *str);
void file_setsource(const int src);
FILE *file_getfilepointer(const char *resourcename, int& filesize, const bool binary=false);
char *file_getfilebuffer(const char *resourcename, int& filesize);

13
lua.cpp
View File

@@ -1,6 +1,7 @@
#include "lua.h"
#include "lua/lua.hpp"
#include "mini.h"
#include "jfile.h"
extern "C" {
static int cpp_newsurf(lua_State *L) {
@@ -568,6 +569,11 @@ extern "C" {
fopen(str, mode);
return 0;
}
static int cpp_fopenres(lua_State *L) {
const char* str = luaL_checkstring(L, 1);
fopenres(str);
return 0;
}
static int cpp_fclose(lua_State *L) {
fclose();
return 0;
@@ -740,6 +746,7 @@ void push_lua_funcs() {
lua_pushcfunction(L,cpp_strlen); lua_setglobal(L, "strlen");
lua_pushcfunction(L,cpp_fopen); lua_setglobal(L, "fopen");
lua_pushcfunction(L,cpp_fopenres); lua_setglobal(L, "fopenres");
lua_pushcfunction(L,cpp_fclose); lua_setglobal(L, "fclose");
lua_pushcfunction(L,cpp_feof); lua_setglobal(L, "feof");
lua_pushcfunction(L,cpp_fwritei); lua_setglobal(L, "fwritei");
@@ -884,12 +891,16 @@ void lua_init(char* filenames) {
if (*pointer!=0) *(pointer++)=0;
// Load and execute file
if (luaL_loadfile(L, file_start)) { // "game.lua"
//if (luaL_loadfile(L, file_start)) { // "game.lua"
int size;
char* buffer = file_getfilebuffer(file_start, size);
if (luaL_loadbuffer(L, buffer, size, file_start)) {
debug("error loading game");
debug(lua_tostring(L, -1));
lua_pop(L,1);
return;
}
free(buffer);
if (lua_pcall(L,0, LUA_MULTRET, 0)) {
debug("runtime error");
debug(lua_tostring(L, -1));

View File

@@ -1,5 +1,5 @@
#include "mini.h"
#include <stdio.h>
#include "jfile.h"
#include <string.h>
#include "lua.h"
#include "gif.c"
@@ -27,6 +27,7 @@ surface_t *source_surface = NULL;
surface_t *map_surface = NULL;
FILE *file = NULL;
//uint8_t file_mode = 0;
bool file_ignore_comma=true;
char *lua_files=NULL;
@@ -80,25 +81,6 @@ Uint8 key_just_pressed = 0;
int mouse_x, mouse_y, mouse_wheel;
Uint32 mouse_buttons;
struct bmp_header_t {
uint16_t header; // 'BM' 0x4D42
uint32_t file_size;
uint32_t reserved; // ignore
uint32_t bmp_offset; // This is where the bmp data starts
uint32_t header_size; // Must be 40
int32_t bmp_width;
int32_t bmp_height;
uint16_t num_color_planes; // Must be 1
uint16_t bpp;
uint32_t compression; // expected 0
uint32_t image_size; // warning, can be 0. Do not trust. Only useful for compressed BMPs (in my experience, it's always the size in bytes (not pixels) of the bmp)
int32_t hres; // ignore
int32_t vres; // ignore
uint32_t num_colors; // warning, can be 0. if 0, num_colors = 2^bpp
uint32_t num_important_colors; // ignore
};
char* get_value_from_line(char* line) {
char* equal_character = strchr(line, '=');
if (equal_character == NULL) return NULL;
@@ -107,7 +89,8 @@ char* get_value_from_line(char* line) {
}
void read_ini() {
FILE *f = fopen("game.ini", "r");
int size;
FILE *f = file_getfilepointer("game.ini", size); // fopen("game.ini", "r");
char line[256];
if (f == NULL) return;
while (fgets(line, sizeof(line), f)) {
@@ -172,6 +155,13 @@ uint8_t loadsurf(const char* filename) {
while (i<10 && surfaces[i].p != NULL) ++i;
//[TODO] Gestionar el cas en que no queden surfaces lliures
int size;
uint8_t *buffer = (uint8_t*)file_getfilebuffer(filename, size);
surfaces[i].p = LoadGif(buffer, &surfaces[i].w, &surfaces[i].h);
surfaces[i].size = surfaces[i].w*surfaces[i].h;
free(buffer);
/*
FILE *f = fopen(filename, "rb");
if (f) {
fseek(f, 0, SEEK_END);
@@ -184,6 +174,7 @@ uint8_t loadsurf(const char* filename) {
surfaces[i].size = surfaces[i].w*surfaces[i].h;
free(buffer);
}
*/
return i;
}
@@ -310,6 +301,12 @@ void color(uint8_t color) {
}
uint32_t *loadpal(const char* filename) {
int size;
uint8_t *buffer = (uint8_t*)file_getfilebuffer(filename, size);
uint32_t *pal = LoadPalette(buffer);
free(buffer);
return pal;
/*
FILE *f = fopen(filename, "rb");
if (f) {
fseek(f, 0, SEEK_END);
@@ -324,7 +321,7 @@ uint32_t *loadpal(const char* filename) {
//memcpy(palette, pal, 1024);
//free(pal);
}
return NULL;
return NULL;*/
}
void setpal(uint32_t *pal) {
@@ -912,6 +909,12 @@ void fopen(const char *filename, uint8_t mode) {
file = fopen(filename, mode==0?"r":"w");
}
void fopenres(const char *filename) {
if (file != NULL) fclose(file);
int size;
file = file_getfilepointer(filename, size);
}
void fclose() {
fclose(file);
}

1
mini.h
View File

@@ -232,6 +232,7 @@ void pdebug();
uint8_t ascii(const char *str, uint8_t index);
void fopen(const char *filename, uint8_t mode=0);
void fopenres(const char *filename);
void fclose();
bool feof();