diff --git a/game.ini b/data/game.ini similarity index 100% rename from game.ini rename to data/game.ini diff --git a/game.lua b/data/game.lua similarity index 100% rename from game.lua rename to data/game.lua diff --git a/jail_audio.cpp b/jail_audio.cpp index 8d1637a..eaa2fd9 100644 --- a/jail_audio.cpp +++ b/jail_audio.cpp @@ -2,6 +2,7 @@ #include "stb_vorbis.c" #include #include +#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); diff --git a/jfile.cpp b/jfile.cpp new file mode 100644 index 0000000..2cb7211 --- /dev/null +++ b/jfile.cpp @@ -0,0 +1,123 @@ +#include +#include +#include +#include +#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; +} \ No newline at end of file diff --git a/jfile.h b/jfile.h new file mode 100644 index 0000000..3c6f765 --- /dev/null +++ b/jfile.h @@ -0,0 +1,12 @@ +#pragma once +#include + +#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); diff --git a/lua.cpp b/lua.cpp index b8542a8..6eaf26b 100644 --- a/lua.cpp +++ b/lua.cpp @@ -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)); diff --git a/mini.cpp b/mini.cpp index d7381fe..eeaa349 100644 --- a/mini.cpp +++ b/mini.cpp @@ -1,5 +1,5 @@ #include "mini.h" -#include +#include "jfile.h" #include #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); } diff --git a/mini.h b/mini.h index 4ca3568..43cce4f 100644 --- a/mini.h +++ b/mini.h @@ -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();