void extractAssets() { if (!getenv("APPDIR")) { logger->log("error: APPDIR is not set!"); return; } const std::string fileName = std::string(getenv( "APPDIR")).append("/data.zip"); logger->log("Extracting asset into: " + fileName); uint8_t *buf = new uint8_t[1000000]; FILE *const file = fopen(fileName.c_str(), "w"); for (int f = 0; f < 100; f ++) { std::string part = strprintf("manaplus-data.zip%u%u", static_cast<unsigned int>(f / 10), static_cast<unsigned int>(f % 10)); logger->log("testing asset: " + part); SDL_RWops *const rw = SDL_RWFromFile(part.c_str(), "r"); if (rw) { const int size = SDL_RWsize(rw); int size2 = SDL_RWread(rw, buf, 1, size); logger->log("asset size: %d", size2); fwrite(buf, 1, size2, file); SDL_RWclose(rw); Dirs::setProgress(); } else { break; } } fclose(file); const std::string fileName2 = std::string(getenv( "APPDIR")).append("/locale.zip"); FILE *const file2 = fopen(fileName2.c_str(), "w"); SDL_RWops *const rw = SDL_RWFromFile("manaplus-locale.zip", "r"); if (rw) { const int size = SDL_RWsize(rw); int size2 = SDL_RWread(rw, buf, 1, size); fwrite(buf, 1, size2, file2); SDL_RWclose(rw); Dirs::setProgress(); } fclose(file2); delete [] buf; }
int Dx_File_ReadFile(const char *filename, unsigned char **dData, unsigned int *dSize) { unsigned char *data; unsigned int size; int retval; SDL_RWops *rwops = Dx_File_OpenStream(filename); if (rwops == NULL) { return -1; } size = (unsigned int)SDL_RWsize(rwops); retval = 0; data = DXALLOC(size); if (SDL_RWread(rwops, data, size, 1) < 1) { retval = -1; DXFREE(data); } else { *dData = data; *dSize = size; } SDL_RWclose(rwops); return retval; }
extern char * load_text(SDL_RWops *rw, size_t *size) { assert(rw != NULL); if (!rw) { LOG_ERROR("Can't open file %p\n", (void*)rw); return NULL; } long int lenght = SDL_RWsize(rw); char *text = NULL; if(size && (lenght > 0)) { *size = lenght - 1; text = malloc(lenght); text[lenght - 1] = 0; SDL_RWread(rw, text, lenght - 1, 1); SDL_RWclose(rw); } return text; }
void FileHandle::initialize(const char* a_filePath, EFileMode a_fileMode) { eastl::string path = FileUtils::getApplicationExePath(); path = path.substr(0, path.rfind("bin\\")); path.append(a_filePath); eastl::replace(path.begin(), path.end(), '/', '\\'); m_filePath = path; const char* fileModeStr; switch (a_fileMode) { case EFileMode::READ: fileModeStr = "rb"; break; case EFileMode::WRITE: fileModeStr = "wb"; break; case EFileMode::READWRITE: fileModeStr = "w+b"; break; default: return; } m_rwops = SDL_RWFromFile(m_filePath.c_str(), fileModeStr); m_isOpen = (m_rwops != NULL); if (!m_rwops) { print("Could not find or open the file %s, fullpath: %s\n", a_filePath, m_filePath.c_str()); return; } m_size = uint64(SDL_RWsize(m_rwops)); }
Sint64 u8file::fsize(){ if(m_size==-1){ m_size=SDL_RWsize(m_file); } return m_size; }
char* readFile(const char* filename, int* size) { SDL_RWops *rw = SDL_RWFromFile(filename, "rb"); if (rw == NULL) return NULL; Sint64 res_size = SDL_RWsize(rw); char* res = (char*)malloc(res_size + 1); Sint64 nb_read_total = 0, nb_read = 1; char* buf = res; while (nb_read_total < res_size && nb_read != 0) { nb_read = SDL_RWread(rw, buf, 1, (res_size - nb_read_total)); nb_read_total += nb_read; buf += nb_read; } SDL_RWclose(rw); if (nb_read_total != res_size) { free(res); return NULL; } res[nb_read_total] = '\0'; if (size != NULL) *size = nb_read_total; return res; }
uint32 file_read(const char* filename, void** outputBuff) { SDL_RWops *rw = SDL_RWFromFile(filename, "r"); if (rw == nullptr) return FeEReturnCode::File_OpenFailed; size_t res_size = (size_t)SDL_RWsize(rw); *outputBuff = (char*)FE_ALLOCATE(res_size + 1, 1); size_t nb_read_total = 0, nb_read = 1; char* buf = (char*)*outputBuff; while (nb_read_total < res_size && nb_read != 0) { nb_read = SDL_RWread(rw, buf, 1, (res_size - nb_read_total)); nb_read_total += nb_read; buf += nb_read; } SDL_RWclose(rw); if (nb_read_total != res_size) { free(*outputBuff); return FeEReturnCode::File_ReadFailed; } ((char*)*outputBuff)[nb_read_total] = '\0'; return FeEReturnCode::Success; }
int char_buffer_from_file(char *filename, struct char_buffer **buffer) { SDL_RWops *rw_ops = SDL_RWFromFile(filename,"rb"); if (rw_ops == NULL) return -1; Sint64 filesize = SDL_RWsize(rw_ops); // No idea if this check works correctly if (filesize > MAX_BUFFER_SIZE) return -1; char_buffer_new(filesize, buffer); Sint64 bytes_read = 0; Sint64 bytes_read_total = 0; do { bytes_read = SDL_RWread( rw_ops, (*buffer)->buffer + bytes_read_total, 1, filesize - bytes_read_total); bytes_read_total += bytes_read; } while ((bytes_read_total < filesize) && (bytes_read != 0)); return 0; }
int Dx_FileRead_eof(int fileHandle) { FileHandle *handle = (FileHandle *)PL_Handle_GetData(fileHandle, DXHANDLE_FILE); if (handle != NULL) { SDL_RWops *rwops = handle->rwops; return (SDL_RWsize(rwops) == SDL_RWtell(rwops)) ? DXTRUE : DXFALSE; } return DXFALSE; }
void Font_p::Load(const std::string& _file, int _size, int _flags) { unsigned char *bitmap = new unsigned char[512 * 512]; SDL_RWops* tempFlow = ResourceManager::Get().Load(_file, _flags); if (tempFlow != NULL) { int flowSize = (int)SDL_RWsize(tempFlow); unsigned char *raw = new unsigned char[flowSize]; SDL_RWread(tempFlow, raw, flowSize, 1); this->cdata = new stbtt_bakedchar[96]; this->fontHeight = (float) _size; stbtt_BakeFontBitmap((const unsigned char*)raw, 0, this->fontHeight, bitmap, 512, 512, 32, 96, (stbtt_bakedchar*)(this->cdata)); delete[] raw; SDL_RWclose(tempFlow); } unsigned char* bitmap2 = new unsigned char[512 * 512 * 4]; int ss = 512 * 512; for (int i = 0; i < ss; i++) { bitmap2[i * 4 + 0] = 0xff; bitmap2[i * 4 + 1] = 0xff; bitmap2[i * 4 + 2] = 0xff; bitmap2[i * 4 + 3] = bitmap[i]; } delete [] bitmap; SDL_Surface* surface = SDL_CreateRGBSurfaceFrom(bitmap2, 512, 512, 4 * 8, 512 * 4, 0xff, 0xff00, 0xff0000, 0xff000000); this->texture = SDL_CreateTextureFromSurface(g_app->sdlRenderer, surface); delete[] bitmap2; SDL_FreeSurface(surface); //font = TTF_OpenFontRW(g_app->resourceManager->Load(_file, _flags), 1, _size); }
unsigned int oxGetSize(oxHandle* h) { #if OXYGINE_SDL && !OXYGINE_FILESYSTEM_USE_STDIO return (int)SDL_RWsize((SDL_RWops*)h); #else oxFileSeek(h, 0, ox_FILESEEK_END); unsigned int size = (unsigned int)oxFileTell(h); oxFileSeek(h, 0, ox_FILESEEK_SET); return size; #endif }
int FILE_HANDLE::getLength () { #ifndef HX_WINDOWS return SDL_RWsize (((SDL_RWops*)handle)); #else return 0; #endif }
/* Load all the data from an SDL data stream */ void * SDL_LoadFile_RW(SDL_RWops * src, size_t *datasize, int freesrc) { const int FILE_CHUNK_SIZE = 1024; Sint64 size; size_t size_read, size_total; void *data = NULL, *newdata; if (!src) { SDL_InvalidParamError("src"); return NULL; } size = SDL_RWsize(src); if (size < 0) { size = FILE_CHUNK_SIZE; } data = SDL_malloc((size_t)(size + 1)); size_total = 0; for (;;) { if ((((Sint64)size_total) + FILE_CHUNK_SIZE) > size) { size = (size_total + FILE_CHUNK_SIZE); newdata = SDL_realloc(data, (size_t)(size + 1)); if (!newdata) { SDL_free(data); data = NULL; SDL_OutOfMemory(); goto done; } data = newdata; } size_read = SDL_RWread(src, (char *)data+size_total, 1, (size_t)(size-size_total)); if (size_read == 0) { break; } size_total += size_read; } if (datasize) { *datasize = size_total; } ((char *)data)[size_total] = '\0'; done: if (freesrc && src) { SDL_RWclose(src); } return data; }
FileData Platform::readEntireFile(const char *filename) { FileData result = {0}; SDL_RWops *diffuse_file = SDL_RWFromFile(filename, "rb"); if(diffuse_file) { result.size = (u64)SDL_RWsize(diffuse_file); result.contents = (char *)SDL_malloc(result.size); SDL_RWread(diffuse_file, result.contents, 1, result.size); SDL_RWclose(diffuse_file); } else { error(formatString("Can't read %s", filename)); } return result; }
/* Given a file_path and buffer, attempts to load save data into the buffer * up to the suppled size in bytes. Returns the size of the file if successful, * returns 0 if unsuccessful. Buffer should at least be of length size*/ unsigned long load_SRAM(const char *file_path, unsigned char *data, unsigned long size) { log_message(LOG_INFO, "Attempting to load SRAM for file: %s\n",file_path); SDL_RWops *rw = SDL_RWFromFile(file_path, "rb"); if (rw == NULL) { log_message(LOG_ERROR, "Error opening file %s: %s\n", file_path, SDL_GetError()); return 0; } Sint64 res_size = SDL_RWsize(rw); if (res_size > size) { log_message(LOG_ERROR, "Error opening file %s: File is too large to be SRAM snapshot\n", file_path); return 0; } if (res_size == 0) { log_message(LOG_WARN, "File %s has a size of 0 bytes\n", file_path); return 0; } Sint64 nb_read_total = 0, nb_read = 1; unsigned char* buf = data; while (nb_read_total < res_size && nb_read != 0) { nb_read = SDL_RWread(rw, buf, 1, (res_size - nb_read_total)); nb_read_total += nb_read; buf += nb_read; } SDL_RWclose(rw); if (nb_read_total != res_size) { log_message(LOG_ERROR, "Bytes expected (%lu) is not equal to bytes read (%lu)\n", res_size, nb_read_total); free(data); return 0; } return res_size; }
/* Given a file_path and buffer to store file data in, attempts to * read the file into the buffer. Returns the size of the file if successful, * returns 0 if unsuccessful. Buffer should be at minimum of size "MAX_FILE_SIZE"*/ unsigned long load_rom_from_file(const char* filename, unsigned char *data) { SDL_RWops *rw = SDL_RWFromFile(filename, "rb"); if (rw == NULL) { log_message(LOG_ERROR, "Error opening file %s: %s\n", filename, SDL_GetError()); return 0; } Sint64 res_size = SDL_RWsize(rw); if (res_size > MAX_FILE_SIZE) { log_message(LOG_ERROR, "Error opening file %s: File is too large to be a Gameboy ROM\n", filename); return 0; } if (res_size == 0) { log_message(LOG_WARN, "File %s has a size of 0 bytes\n", filename); return 0; } Sint64 nb_read_total = 0, nb_read = 1; unsigned char* buf = data; while (nb_read_total < res_size && nb_read != 0) { nb_read = SDL_RWread(rw, buf, 1, (res_size - nb_read_total)); nb_read_total += nb_read; buf += nb_read; } SDL_RWclose(rw); if (nb_read_total != res_size) { log_message(LOG_ERROR, "Bytes expected (%lu) is not equal to bytes read (%lu)\n", res_size, nb_read_total); free(data); return 0; } return res_size; }
/* * Add or update an entry into the Mappings Database */ int SDL_GameControllerAddMappingsFromRW(SDL_RWops * rw, int freerw) { const char *platform = SDL_GetPlatform(); int controllers = 0; char *buf, *line, *line_end, *tmp, *comma, line_platform[64]; size_t db_size, platform_len; if (rw == NULL) { return SDL_SetError("Invalid RWops"); } db_size = (size_t)SDL_RWsize(rw); buf = (char *)SDL_malloc(db_size + 1); if (buf == NULL) { if (freerw) { SDL_RWclose(rw); } return SDL_SetError("Could allocate space to not read DB into memory"); } if (SDL_RWread(rw, buf, db_size, 1) != 1) { if (freerw) { SDL_RWclose(rw); } SDL_free(buf); return SDL_SetError("Could not read DB"); } if (freerw) { SDL_RWclose(rw); } buf[db_size] = '\0'; line = buf; while (line < buf + db_size) { line_end = SDL_strchr(line, '\n'); if (line_end != NULL) { *line_end = '\0'; } else { line_end = buf + db_size; } /* Extract and verify the platform */ tmp = SDL_strstr(line, SDL_CONTROLLER_PLATFORM_FIELD); if (tmp != NULL) { tmp += SDL_strlen(SDL_CONTROLLER_PLATFORM_FIELD); comma = SDL_strchr(tmp, ','); if (comma != NULL) { platform_len = comma - tmp + 1; if (platform_len + 1 < SDL_arraysize(line_platform)) { SDL_strlcpy(line_platform, tmp, platform_len); if (SDL_strncasecmp(line_platform, platform, platform_len) == 0 && SDL_GameControllerAddMapping(line) > 0) { controllers++; } } } } line = line_end + 1; } SDL_free(buf); return controllers; }
void TR_Level::read_tr2_level(SDL_RWops * const src, bool demo) { uint32_t i; // Version uint32_t file_version = read_bitu32(src); if (file_version != 0x0000002d) Sys_extError("Wrong level version"); read_tr_palette(src, this->palette); read_tr2_palette16(src, this->palette16); this->num_textiles = 0; this->num_room_textiles = 0; this->num_obj_textiles = 0; this->num_bump_textiles = 0; this->num_misc_textiles = 0; this->read_32bit_textiles = false; this->textile8_count = this->num_textiles = read_bitu32(src); this->textile8 = (tr_textile8_t*)malloc(this->textile8_count * sizeof(tr_textile8_t)); for (i = 0; i < this->textile8_count; i++) read_tr_textile8(src, this->textile8[i]); this->textile16_count = this->textile8_count; this->textile16 = (tr2_textile16_t*)malloc(this->textile16_count * sizeof(tr2_textile16_t)); for (i = 0; i < this->textile16_count; i++) read_tr2_textile16(src, this->textile16[i]); // Unused if (read_bitu32(src) != 0) Sys_extWarn("Bad value for 'unused'"); this->rooms_count = read_bitu16(src); this->rooms = (tr5_room_t*)calloc(this->rooms_count, sizeof(tr5_room_t)); for (i = 0; i < this->rooms_count; i++) read_tr2_room(src, this->rooms[i]); this->floor_data_size = read_bitu32(src); this->floor_data = (uint16_t*)malloc(this->floor_data_size * sizeof(uint16_t)); for(i = 0; i < this->floor_data_size; i++) this->floor_data[i] = read_bitu16(src); read_mesh_data(src); this->animations_count = read_bitu32(src); this->animations = (tr_animation_t*)malloc(this->animations_count * sizeof(tr_animation_t)); for (i = 0; i < this->animations_count; i++) read_tr_animation(src, this->animations[i]); this->state_changes_count = read_bitu32(src); this->state_changes = (tr_state_change_t*)malloc(this->state_changes_count * sizeof(tr_state_change_t)); for (i = 0; i < this->state_changes_count; i++) read_tr_state_changes(src, this->state_changes[i]); this->anim_dispatches_count = read_bitu32(src); this->anim_dispatches = (tr_anim_dispatch_t*)malloc(this->anim_dispatches_count * sizeof(tr_anim_dispatch_t)); for (i = 0; i < this->anim_dispatches_count; i++) read_tr_anim_dispatches(src, this->anim_dispatches[i]); this->anim_commands_count = read_bitu32(src); this->anim_commands = (int16_t*)malloc(this->anim_commands_count * sizeof(int16_t)); for (i = 0; i < this->anim_commands_count; i++) this->anim_commands[i] = read_bit16(src); this->mesh_tree_data_size = read_bitu32(src); this->mesh_tree_data = (uint32_t*)malloc(this->mesh_tree_data_size * sizeof(uint32_t)); for (i = 0; i < this->mesh_tree_data_size; i++) this->mesh_tree_data[i] = read_bitu32(src); // 4 bytes read_frame_moveable_data(src); this->static_meshes_count = read_bitu32(src); this->static_meshes = (tr_staticmesh_t*)malloc(this->static_meshes_count * sizeof(tr_staticmesh_t)); for (i = 0; i < this->static_meshes_count; i++) read_tr_staticmesh(src, this->static_meshes[i]); this->object_textures.resize( read_bitu32(src) ); for (i = 0; i < this->object_textures.size(); i++) read_tr_object_texture(src, this->object_textures[i]); this->sprite_textures.resize( read_bitu32(src) ); for (i = 0; i < this->sprite_textures.size(); i++) read_tr_sprite_texture(src, this->sprite_textures[i]); this->sprite_sequences_count = read_bitu32(src); this->sprite_sequences = (tr_sprite_sequence_t*)malloc(this->sprite_sequences_count * sizeof(tr_sprite_sequence_t)); for (i = 0; i < this->sprite_sequences_count; i++) read_tr_sprite_sequence(src, this->sprite_sequences[i]); if (demo) read_tr_lightmap(src, this->lightmap); this->cameras_count = read_bitu32(src); this->cameras = (tr_camera_t*)malloc(this->cameras_count * sizeof(tr_camera_t)); for (i = 0; i < this->cameras_count; i++) { this->cameras[i].x = read_bit32(src); this->cameras[i].y = read_bit32(src); this->cameras[i].z = read_bit32(src); this->cameras[i].room = read_bit16(src); this->cameras[i].unknown1 = read_bitu16(src); } this->sound_sources_count = read_bitu32(src); this->sound_sources = (tr_sound_source_t*)malloc(this->sound_sources_count * sizeof(tr_sound_source_t)); for(i = 0; i < this->sound_sources_count; i++) { this->sound_sources[i].x = read_bit32(src); this->sound_sources[i].y = read_bit32(src); this->sound_sources[i].z = read_bit32(src); this->sound_sources[i].sound_id = read_bitu16(src); this->sound_sources[i].flags = read_bitu16(src); } this->boxes_count = read_bitu32(src); this->boxes = (tr_box_t*)malloc(this->boxes_count * sizeof(tr_box_t)); for (i = 0; i < this->boxes_count; i++) read_tr2_box(src, this->boxes[i]); this->overlaps_count = read_bitu32(src); this->overlaps = (uint16_t*)malloc(this->overlaps_count * sizeof(uint16_t)); for (i = 0; i < this->overlaps_count; i++) this->overlaps[i] = read_bitu16(src); // Zones SDL_RWseek(src, this->boxes_count * 20, RW_SEEK_CUR); this->animated_textures_count = read_bitu32(src); this->animated_textures_uv_count = 0; // No UVRotate in TR2 this->animated_textures = (uint16_t*)malloc(this->animated_textures_count * sizeof(uint16_t)); for (i = 0; i < this->animated_textures_count; i++) { this->animated_textures[i] = read_bitu16(src); } this->items_count = read_bitu32(src); this->items = (tr2_item_t*)malloc(this->items_count * sizeof(tr2_item_t)); for (i = 0; i < this->items_count; i++) read_tr2_item(src, this->items[i]); if (!demo) read_tr_lightmap(src, this->lightmap); this->cinematic_frames_count = read_bitu16(src); this->cinematic_frames = (tr_cinematic_frame_t*)malloc(this->cinematic_frames_count * sizeof(tr_cinematic_frame_t)); for (i = 0; i < this->cinematic_frames_count; i++) { read_tr_cinematic_frame(src, this->cinematic_frames[i]); } this->demo_data_count = read_bitu16(src); this->demo_data = (uint8_t*)malloc(this->demo_data_count * sizeof(uint8_t)); for(i=0; i < this->demo_data_count; i++) this->demo_data[i] = read_bitu8(src); // Soundmap this->soundmap = (int16_t*)malloc(TR_AUDIO_MAP_SIZE_TR2 * sizeof(int16_t)); for(i=0; i < TR_AUDIO_MAP_SIZE_TR2; i++) this->soundmap[i] = read_bit16(src); this->sound_details_count = read_bitu32(src); this->sound_details = (tr_sound_details_t*)malloc(this->sound_details_count * sizeof(tr_sound_details_t)); for(i = 0; i < this->sound_details_count; i++) { this->sound_details[i].sample = read_bitu16(src); this->sound_details[i].volume = read_bitu16(src); this->sound_details[i].chance = read_bitu16(src); this->sound_details[i].num_samples_and_flags_1 = read_bitu8(src); this->sound_details[i].flags_2 = read_bitu8(src); this->sound_details[i].sound_range = TR_AUDIO_DEFAULT_RANGE; this->sound_details[i].pitch = (int16_t)TR_AUDIO_DEFAULT_PITCH; } this->sample_indices_count = read_bitu32(src); this->sample_indices = (uint32_t*)malloc(this->sample_indices_count * sizeof(uint32_t)); for(i=0; i < this->sample_indices_count; i++) this->sample_indices[i] = read_bitu32(src); // remap all sample indices here for(i = 0; i < this->sound_details_count; i++) { if(this->sound_details[i].sample < this->sample_indices_count) { this->sound_details[i].sample = this->sample_indices[this->sound_details[i].sample]; } } // LOAD SAMPLES // In TR2, samples are stored in separate file called MAIN.SFX. // If there is no such files, no samples are loaded. SDL_RWops *newsrc = SDL_RWFromFile(this->sfx_path, "rb"); if (newsrc == NULL) { Sys_extWarn("read_tr2_level: failed to open \"%s\"! No samples loaded.", this->sfx_path); } else { this->samples_data.resize( SDL_RWsize(newsrc) ); this->samples_count = 0; for(i = 0; i < this->samples_data.size(); i++) { this->samples_data[i] = read_bitu8(newsrc); if((i >= 4) && (*((uint32_t*)(this->samples_data.data()+i-4)) == 0x46464952)) /// RIFF { this->samples_count++; } } SDL_RWclose(newsrc); newsrc = NULL; } }
size_t SDLRWops::size() { return SDL_RWsize(rwops_); }
size_t ex_os_fsize ( ex_file_t *_file ) { return (size_t)SDL_RWsize((SDL_RWops *)_file); }
bool SDLFileInputStream::open( const FilePath & _folder, const FilePath & _fileName, size_t _offset, size_t _size ) { STDEX_THREAD_GUARD_SCOPE( this, "SDLFileInputStream::open" ); # ifdef _DEBUG m_folder = _folder.c_str(); m_fileName = _fileName.c_str(); # endif Char filePath[MENGINE_MAX_PATH]; if( this->openFile_( _folder, _fileName, filePath ) == false ) { return false; } Sint64 size = SDL_RWsize(m_rwops); if( 0 > size ) { this->close_(); LOGGER_ERROR(m_serviceProvider)("SDLFileInputStream::open %s invalid file size" , filePath ); return false; } if( _offset + _size > size ) { LOGGER_ERROR(m_serviceProvider)("SDLFileInputStream::open %s invalid file range %d:%d size %d" , filePath , _offset , _size , size ); return false; } m_size = _size == 0 ? (size_t)size : _size; m_offset = _offset; m_carriage = 0; m_capacity = 0; m_reading = 0; if( m_offset != 0 ) { Sint64 result = SDL_RWseek( m_rwops, static_cast<Sint64>(m_offset), RW_SEEK_SET ); if( 0 > result ) { const char* sdlError = SDL_GetError(); LOGGER_ERROR( m_serviceProvider )("Win32InputStream::open seek offset %d size %d get error %s" , m_offset , m_size , sdlError ); return false; } } return true; }
void TR_Level::read_tr5_level(SDL_RWops * const src) { uint32_t i; uint8_t *comp_buffer = NULL; uint8_t *uncomp_buffer = NULL; SDL_RWops *newsrc = NULL; // Version uint32_t file_version = read_bitu32(src); if (file_version != 0x00345254) Sys_extError("Wrong level version"); this->num_textiles = 0; this->num_room_textiles = 0; this->num_obj_textiles = 0; this->num_bump_textiles = 0; this->num_misc_textiles = 0; this->read_32bit_textiles = false; uint32_t uncomp_size; uint32_t comp_size; unsigned long size; this->num_room_textiles = read_bitu16(src); this->num_obj_textiles = read_bitu16(src); this->num_bump_textiles = read_bitu16(src); this->num_misc_textiles = 3; this->num_textiles = this->num_room_textiles + this->num_obj_textiles + this->num_bump_textiles + this->num_misc_textiles; uncomp_size = read_bitu32(src); if (uncomp_size == 0) Sys_extError("read_tr5_level: textiles32 uncomp_size == 0"); comp_size = read_bitu32(src); if (comp_size > 0) { uncomp_buffer = new uint8_t[uncomp_size]; this->textile32.resize( this->num_textiles ); comp_buffer = new uint8_t[comp_size]; if (SDL_RWread(src, comp_buffer, 1, comp_size) < comp_size) Sys_extError("read_tr5_level: textiles32"); size = uncomp_size; if (uncompress(uncomp_buffer, &size, comp_buffer, comp_size) != Z_OK) Sys_extError("read_tr5_level: uncompress"); if (size != uncomp_size) Sys_extError("read_tr5_level: uncompress size mismatch"); delete [] comp_buffer; comp_buffer = NULL; if ((newsrc = SDL_RWFromMem(uncomp_buffer, uncomp_size)) == NULL) Sys_extError("read_tr5_level: SDL_RWFromMem"); for (i = 0; i < (this->num_textiles - this->num_misc_textiles); i++) read_tr4_textile32(newsrc, this->textile32[i]); SDL_RWclose(newsrc); newsrc = NULL; delete [] uncomp_buffer; uncomp_buffer = NULL; this->read_32bit_textiles = true; } uncomp_size = read_bitu32(src); if (uncomp_size == 0) Sys_extError("read_tr5_level: textiles16 uncomp_size == 0"); comp_size = read_bitu32(src); if (comp_size > 0) { if (this->textile32.empty()) { uncomp_buffer = new uint8_t[uncomp_size]; this->textile16_count = this->num_textiles; this->textile16 = (tr2_textile16_t*)malloc(this->textile16_count * sizeof(tr2_textile16_t)); comp_buffer = new uint8_t[comp_size]; if (SDL_RWread(src, comp_buffer, 1, comp_size) < comp_size) Sys_extError("read_tr5_level: textiles16"); size = uncomp_size; if (uncompress(uncomp_buffer, &size, comp_buffer, comp_size) != Z_OK) Sys_extError("read_tr5_level: uncompress"); if (size != uncomp_size) Sys_extError("read_tr5_level: uncompress size mismatch"); delete [] comp_buffer; comp_buffer = NULL; if ((newsrc = SDL_RWFromMem(uncomp_buffer, uncomp_size)) == NULL) Sys_extError("read_tr5_level: SDL_RWFromMem"); for (i = 0; i < (this->num_textiles - this->num_misc_textiles); i++) read_tr2_textile16(newsrc, this->textile16[i]); SDL_RWclose(newsrc); newsrc = NULL; delete [] uncomp_buffer; uncomp_buffer = NULL; } else { SDL_RWseek(src, comp_size, SEEK_CUR); } } uncomp_size = read_bitu32(src); if (uncomp_size == 0) Sys_extError("read_tr5_level: textiles32d uncomp_size == 0"); comp_size = read_bitu32(src); if (comp_size > 0) { uncomp_buffer = new uint8_t[uncomp_size]; if ((uncomp_size / (256 * 256 * 4)) > 3) Sys_extWarn("read_tr5_level: num_misc_textiles > 3"); if (this->textile32.empty()) { this->textile32.resize( this->num_misc_textiles ); } comp_buffer = new uint8_t[comp_size]; if (SDL_RWread(src, comp_buffer, 1, comp_size) < comp_size) Sys_extError("read_tr5_level: misc_textiles"); size = uncomp_size; if (uncompress(uncomp_buffer, &size, comp_buffer, comp_size) != Z_OK) Sys_extError("read_tr5_level: uncompress"); if (size != uncomp_size) Sys_extError("read_tr5_level: uncompress size mismatch"); delete [] comp_buffer; comp_buffer = NULL; if ((newsrc = SDL_RWFromMem(uncomp_buffer, uncomp_size)) == NULL) Sys_extError("read_tr5_level: SDL_RWFromMem"); for (i = (this->num_textiles - this->num_misc_textiles); i < this->num_textiles; i++) read_tr4_textile32(newsrc, this->textile32[i]); SDL_RWclose(newsrc); newsrc = NULL; delete [] uncomp_buffer; uncomp_buffer = NULL; } // flags? /* I found 2 flags in the TR5 file format. Directly after the sprite textures are 2 ints as a flag. The first one is the lara type: 0 Normal 3 Catsuit 4 Divesuit 6 Invisible The second one is the weather type (effects all outside rooms): 0 No weather 1 Rain 2 Snow (in title.trc these are red triangles falling from the sky). */ i = read_bitu16(src); i = read_bitu16(src); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[1]"); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[2]"); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[3]"); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[4]"); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[5]"); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[6]"); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[7]"); // LevelDataSize1 read_bitu32(src); // LevelDataSize2 read_bitu32(src); // Unused if (read_bitu32(src) != 0) Sys_extWarn("Bad value for 'unused'"); this->rooms_count = read_bitu32(src); this->rooms = (tr5_room_t*)calloc(this->rooms_count, sizeof(tr5_room_t)); for (i = 0; i < this->rooms_count; i++) read_tr5_room(src, this->rooms[i]); this->floor_data_size = read_bitu32(src); this->floor_data = (uint16_t*)malloc(this->floor_data_size * sizeof(uint16_t)); for(i = 0; i < this->floor_data_size; i++) this->floor_data[i] = read_bitu16(src); read_mesh_data(src); this->animations_count = read_bitu32(src); this->animations = (tr_animation_t*)malloc(this->animations_count * sizeof(tr_animation_t)); for (i = 0; i < this->animations_count; i++) { read_tr4_animation(src, this->animations[i]); } this->state_changes_count = read_bitu32(src); this->state_changes = (tr_state_change_t*)malloc(this->state_changes_count * sizeof(tr_state_change_t)); for (i = 0; i < this->state_changes_count; i++) read_tr_state_changes(src, this->state_changes[i]); this->anim_dispatches_count = read_bitu32(src); this->anim_dispatches = (tr_anim_dispatch_t*)malloc(this->anim_dispatches_count * sizeof(tr_anim_dispatch_t)); for (i = 0; i < this->anim_dispatches_count; i++) read_tr_anim_dispatches(src, this->anim_dispatches[i]); this->anim_commands_count = read_bitu32(src); this->anim_commands = (int16_t*)malloc(this->anim_commands_count * sizeof(int16_t)); for (i = 0; i < this->anim_commands_count; i++) this->anim_commands[i] = read_bit16(src); this->mesh_tree_data_size = read_bitu32(src); this->mesh_tree_data = (uint32_t*)malloc(this->mesh_tree_data_size * sizeof(uint32_t)); for (i = 0; i < this->mesh_tree_data_size; i++) this->mesh_tree_data[i] = read_bitu32(src); // 4 bytes read_frame_moveable_data(src); this->static_meshes_count = read_bitu32(src); this->static_meshes = (tr_staticmesh_t*)malloc(this->static_meshes_count * sizeof(tr_staticmesh_t)); for (i = 0; i < this->static_meshes_count; i++) read_tr_staticmesh(src, this->static_meshes[i]); if (read_bit8(src) != 'S') Sys_extError("read_tr5_level: 'SPR' not found"); if (read_bit8(src) != 'P') Sys_extError("read_tr5_level: 'SPR' not found"); if (read_bit8(src) != 'R') Sys_extError("read_tr5_level: 'SPR' not found"); if (read_bit8(src) != 0) Sys_extError("read_tr5_level: 'SPR' not found"); this->sprite_textures.resize( read_bitu32(src) ); for (i = 0; i < this->sprite_textures.size(); i++) read_tr4_sprite_texture(src, this->sprite_textures[i]); this->sprite_sequences_count = read_bitu32(src); this->sprite_sequences = (tr_sprite_sequence_t*)malloc(this->sprite_sequences_count * sizeof(tr_sprite_sequence_t)); for (i = 0; i < this->sprite_sequences_count; i++) read_tr_sprite_sequence(src, this->sprite_sequences[i]); this->cameras_count = read_bitu32(src); this->cameras = (tr_camera_t*)malloc(this->cameras_count * sizeof(tr_camera_t)); for (i = 0; i < this->cameras_count; i++) { this->cameras[i].x = read_bit32(src); this->cameras[i].y = read_bit32(src); this->cameras[i].z = read_bit32(src); this->cameras[i].room = read_bit16(src); this->cameras[i].unknown1 = read_bitu16(src); } this->flyby_cameras_count = read_bitu32(src); this->flyby_cameras = (tr4_flyby_camera_t*)malloc(this->flyby_cameras_count * sizeof(tr4_flyby_camera_t)); for (i = 0; i < this->flyby_cameras_count; i++) { this->flyby_cameras[i].cam_x = read_bit32(src); this->flyby_cameras[i].cam_y = read_bit32(src); this->flyby_cameras[i].cam_z = read_bit32(src); this->flyby_cameras[i].target_x = read_bit32(src); this->flyby_cameras[i].target_y = read_bit32(src); this->flyby_cameras[i].target_z = read_bit32(src); this->flyby_cameras[i].sequence = read_bit8(src); this->flyby_cameras[i].index = read_bit8(src); this->flyby_cameras[i].fov = read_bitu16(src); this->flyby_cameras[i].roll = read_bitu16(src); this->flyby_cameras[i].timer = read_bitu16(src); this->flyby_cameras[i].speed = read_bitu16(src); this->flyby_cameras[i].flags = read_bitu16(src); this->flyby_cameras[i].room_id = read_bitu32(src); } this->sound_sources_count = read_bitu32(src); this->sound_sources = (tr_sound_source_t*)malloc(this->sound_sources_count * sizeof(tr_sound_source_t)); for(i = 0; i < this->sound_sources_count; i++) { this->sound_sources[i].x = read_bit32(src); this->sound_sources[i].y = read_bit32(src); this->sound_sources[i].z = read_bit32(src); this->sound_sources[i].sound_id = read_bitu16(src); this->sound_sources[i].flags = read_bitu16(src); } this->boxes_count = read_bitu32(src); this->boxes = (tr_box_t*)malloc(this->boxes_count * sizeof(tr_box_t)); for (i = 0; i < this->boxes_count; i++) read_tr2_box(src, this->boxes[i]); this->overlaps_count = read_bitu32(src); this->overlaps = (uint16_t*)malloc(this->overlaps_count * sizeof(uint16_t)); for (i = 0; i < this->overlaps_count; i++) this->overlaps[i] = read_bitu16(src); // Zones SDL_RWseek(src, this->boxes_count * 20, SEEK_CUR); this->animated_textures_count = read_bitu32(src); this->animated_textures = (uint16_t*)malloc(this->animated_textures_count * sizeof(uint16_t)); for (i = 0; i < this->animated_textures_count; i++) { this->animated_textures[i] = read_bitu16(src); } this->animated_textures_uv_count = read_bitu8(src); if (read_bit8(src) != 'T') Sys_extError("read_tr5_level: '\\0TEX' not found"); if (read_bit8(src) != 'E') Sys_extError("read_tr5_level: '\\0TEX' not found"); if (read_bit8(src) != 'X') Sys_extError("read_tr5_level: '\\0TEX' not found"); if (read_bit8(src) != 0) Sys_extError("read_tr5_level: '\\0TEX' not found"); this->object_textures.resize( read_bitu32(src) ); for (i = 0; i < this->object_textures.size(); i++) { read_tr4_object_texture(src, this->object_textures[i]); if (read_bitu16(src) != 0) Sys_extWarn("read_tr5_level: obj_tex trailing bitu16 != 0"); } this->items_count = read_bitu32(src); this->items = (tr2_item_t*)malloc(this->items_count * sizeof(tr2_item_t)); for (i = 0; i < this->items_count; i++) read_tr4_item(src, this->items[i]); this->ai_objects_count = read_bitu32(src); this->ai_objects = (tr4_ai_object_t*)malloc(this->ai_objects_count * sizeof(tr4_ai_object_t)); for(i=0; i < this->ai_objects_count; i++) { this->ai_objects[i].object_id = read_bitu16(src); this->ai_objects[i].room = read_bitu16(src); this->ai_objects[i].x = read_bit32(src); this->ai_objects[i].y = read_bit32(src); this->ai_objects[i].z = read_bit32(src); // 16 this->ai_objects[i].ocb = read_bitu16(src); this->ai_objects[i].flags = read_bitu16(src); // 20 this->ai_objects[i].angle = read_bit32(src); // 24 } this->demo_data_count = read_bitu16(src); this->demo_data = (uint8_t*)malloc(this->demo_data_count * sizeof(uint8_t)); for(i=0; i < this->demo_data_count; i++) this->demo_data[i] = read_bitu8(src); // Soundmap this->soundmap = (int16_t*)malloc(TR_AUDIO_MAP_SIZE_TR5 * sizeof(int16_t)); for(i=0; i < TR_AUDIO_MAP_SIZE_TR5; i++) this->soundmap[i] = read_bit16(src); this->sound_details_count = read_bitu32(src); this->sound_details = (tr_sound_details_t*)malloc(this->sound_details_count * sizeof(tr_sound_details_t)); for(i=0; i < this->sound_details_count; i++) { this->sound_details[i].sample = read_bitu16(src); this->sound_details[i].volume = (uint16_t)read_bitu8(src); // n x 2.6 this->sound_details[i].sound_range = (uint16_t)read_bitu8(src); // n as is this->sound_details[i].chance = (uint16_t)read_bitu8(src); // If n = 99, n = 0 (max. chance) this->sound_details[i].pitch = (int16_t)read_bit8(src); // n as is this->sound_details[i].num_samples_and_flags_1 = read_bitu8(src); this->sound_details[i].flags_2 = read_bitu8(src); } this->sample_indices_count = read_bitu32(src); this->sample_indices = (uint32_t*)malloc(this->sample_indices_count * sizeof(uint32_t)); for(i=0; i < this->sample_indices_count; i++) this->sample_indices[i] = read_bitu32(src); SDL_RWseek(src, 6, SEEK_CUR); // In TR5, sample indices are followed by 6 0xCD bytes. - correct - really 0xCDCDCDCDCDCD // LOAD SAMPLES i = read_bitu32(src); // Read num samples if(i) { this->samples_count = i; // Since sample data is the last part, we simply load whole last // block of file as single array. this->samples_data.resize( SDL_RWsize(src) - SDL_RWtell(src) ); for(i = 0; i < this->samples_data.size(); i++) this->samples_data[i] = read_bitu8(src); } }
// opens the file, returns NULL if it fails. void* cfg_OpenFile( const char* fileName ) { if( SDL_strlen( fileName ) >= ( FILE_PATH_LEN - 1 ) ) { llog( LOG_ERROR, "Configuration file path too long" ); return NULL; } CFGFile* newFile = (CFGFile*)mem_Allocate( sizeof( CFGFile ) ); if( newFile == NULL ) { llog( LOG_INFO, "Unable to open configuration file." ); return NULL; } newFile->sbAttributes = NULL; SDL_strlcpy( newFile->filePath, fileName, FILE_PATH_LEN - 1 ); newFile->filePath[FILE_PATH_LEN-1] = 0; SDL_RWops* rwopsFile = SDL_RWFromFile( fileName, "r" ); if( rwopsFile == NULL ) { // file doesn't exist, just create a new empty configuration file to use return newFile; } // TODO: change this so everything is happening in place and there are no allocations // parse what this configuration file currently has in it char buffer[READ_BUFFER_SIZE]; size_t numRead; char* fileText = NULL; llog( LOG_INFO, "Stream size: %i", (int)SDL_RWsize( rwopsFile ) ); while( ( numRead = SDL_RWread( rwopsFile, (void*)buffer, sizeof( char ), sizeof( buffer ) ) ) != 0 ) { char* c = sb_Add( fileText, (int)numRead ); for( size_t i = 0; i < numRead; ++i ) { *c++ = buffer[i]; } } sb_Push( fileText, 0 ); // make this c-string compatible // got the entire file text, now tokenize and parse // only tokens we're worried about are '=' and '/r/n' // everything before the '=' is the attribute name, everything // after is the attribute value, all white space should be cut // off of each end int gettingAttrName = 1; const char* delimiters = "\f\v\t =\r\n"; char* token = strtok( fileText, delimiters ); CFGAttribute attr; while( token != NULL ) { // cut off white space, don't care about preserving memory if( gettingAttrName ) { SDL_strlcpy( attr.fileName, token, sizeof( attr.fileName ) - 1 ); attr.fileName[sizeof( attr.fileName ) - 1] = 0; gettingAttrName = 0; } else { attr.value = SDL_atoi( token ); sb_Push( newFile->sbAttributes, attr ); llog( LOG_INFO, "New attribute: %s %i", attr.fileName, attr.value ); gettingAttrName = 1; } token = strtok( NULL, delimiters ); } sb_Release( fileText ); SDL_RWclose( rwopsFile ); return newFile; }
bool ModelData::loadObj(const std::string& filename, MaterialManager& mManager) { SDL_RWops *io = SDL_RWFromFile(filename.c_str(), "rb"); const Sint64 maxBytes{SDL_RWsize(io)+1}; //Maximum model file size in bytes char *fileText=reinterpret_cast<char*>(malloc(maxBytes)); memset(fileText,0,maxBytes); if (io != NULL) { SDL_RWread(io,fileText,1,maxBytes); SDL_RWclose(io); } std::istringstream objfile{fileText}; name=filename; std::vector<vec3> verts,norms; std::vector<vec2> coords; std::map<std::string,Material*> materials; std::string line,currentObject; while(std::getline(objfile,line)) { std::istringstream ss{line}; std::string tmp; ss>>tmp; if(tmp=="f") { std::vector<std::string> units; //Load up to 4 units of data (a quad) for(size_t i{}; i<4 and ss>>tmp; ++i) units.push_back(tmp); for(auto unit: units) { std::istringstream split{unit}; size_t index[3]; Vertex v{{},{},{}}; //Vertex std::getline(split,tmp,'/'); std::istringstream value{tmp}; if(value>>index[0]) { if(index[0]>verts.size()) { console.log("Model resource failed to load: vertices out of bounds "+filename); return true; } v.vertex=verts[index[0]-1]; } else { console.log("Model resource failed to load: no vertex data "+filename); return true; } //Coordinate std::getline(split,tmp,'/'); value.clear(); value.str(tmp); if(value>>index[1]) { if(index[1]>coords.size()) { console.log("Model resource failed to load: texture coordinates out of bounds "+filename); return true; } v.coordinate=coords[index[1]-1]; } //Normal std::getline(split,tmp,'/'); value.clear(); value.str(tmp); if(value>>index[2]) { if(index[2]>norms.size()) { console.log("Model resource failed to load: normals out of bounds "+filename); return true; } v.normal=norms[index[2]-1]; } vertexdata.push_back(v); } //Copy data to make two triangles form a quad if(units.size()==4) { vertexdata.push_back(*(vertexdata.end()-4)); vertexdata.insert(vertexdata.end()-3,*(vertexdata.end()-3)); } }
SDL_AudioSpec *Mix_LoadWAV_RW_(SDL_RWops *src, int freesrc, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len) { /* * only process in case of 32000hz / 48000Hz (not 44100 / 22050 / 11025Hz) * part of codes were refered from bmx2wav/bmx2ogg project. */ // // these part is already checked before, so don't do error checking // // RIFF header int riffheader = sdl_read_int(src); #if 0 if (riffheader != RIFF_HEADER) { ERROR } #endif // file size sdl_read_int(src); // WAVE header int wavheader = sdl_read_int(src); #if 0 if (wavheader != WAVE_HEADER) { ERROR } #endif // skip until met fmt chunk for (;;) { if (sdl_read_int(src) == FMT_CHUNK) { break; } sdl_read_skip(src, sdl_read_int(src)); } // fmt byte size int fmt_byte_size = sdl_read_int(src); // fmt id if (sdl_read_short(src) != FMT_ID) { ERROR } // channel count int channel_count = sdl_read_short(src); if (channel_count != 1 && channel_count != 2) { ERROR } // frequency int frequency = sdl_read_int(src); // byte per second int byte_per_second = sdl_read_int(src); // block size int block_size = sdl_read_short(src); // bit rate int bit_rate = sdl_read_short(src); if (bit_rate != 4 && bit_rate != 8 && bit_rate != 16 && bit_rate != 24 && bit_rate != 32) { ERROR } // check once again (valid block size?) // as it's too minor problem, we'll gonna skip this #if STRICT_CHECK if (block_size != (bit_rate / 8) * channel_count) { ERROR } if (byte_per_second != frequency * block_size) { ERROR } #endif // // if bit is general one (8 / 16 / 32) // then use default SDL loader // otherwise (24 bit), load it by using this module. // if (bit_rate == 8 || bit_rate == 16 || bit_rate == 32) { SDL_RWseek(src, 0, RW_SEEK_SET); return SDL_LoadWAV_RW(src, freesrc, spec, audio_buf, audio_len); } // skip extended format byte if (fmt_byte_size - FMT_BYTE_SIZE > 0) { sdl_read_skip(src, fmt_byte_size - FMT_BYTE_SIZE); } // skip until met data chunk for (;;) { if (sdl_read_int(src) == DATA_CHUNK) { break; } sdl_read_skip(src, sdl_read_int(src)); } // data size int data_size = sdl_read_int(src); // data size check if (data_size % ((bit_rate / 8) * channel_count) != 0) { #if STRICT_CHECK // some WAVE file doesn't returns valid size // better fix it rather then returning ERROR ERROR #else data_size -= data_size % ((bit_rate / 8) * channel_count); #endif } // // get data size strictly by checking file size // Sint64 filetotsize = SDL_RWsize(src); Sint64 filepos = SDL_RWtell(src); if (filetotsize - filepos < data_size) data_size = filetotsize - filepos; // // now we know data size, so allocate buffer // *audio_buf = NULL; *audio_len = 0; memset(spec, '\0', sizeof(SDL_AudioSpec)); // // convert it to 16bit, always, // spec->format = AUDIO_S16; spec->channels = channel_count; spec->freq = frequency; spec->samples = 4096; /* buffer size */ int samples = data_size / (bit_rate / 8) / channel_count; /* x2 : we'll going to interpret audio data as 16bit */ *audio_len = spec->size = samples * spec->channels * 2; *audio_buf = (Uint8 *)SDL_malloc(*audio_len); if (*audio_buf == NULL) goto done; // // all metadata were gathered... start to read WAV file // store raw if freq is 44100 / 22050 / 11025Hz. // int pos = 0; int mul = 2 * spec->channels; // // before continue, if wav file is 4 bit per sample, // then extend it into 16 bit per sample. // #define READBIT read_bit_wav(src, bit_rate) if (bit_rate == 4) { // it's 2 sample per a byte, actually. bit_rate = 8; Uint16* write_buf = *audio_buf; for (int i = 0; i < samples / 2 * spec->channels; i++) { Uint16 _t = READBIT; *(write_buf++) = read_4bit_first(_t); *(write_buf++) = read_4bit_last(_t); } } else { for (int i = 0; i < samples; i++) { int bufpos = i * mul; *((Uint16*)(*audio_buf + bufpos)) = READBIT; if (spec->channels == 2) *((Uint16*)(*audio_buf + bufpos + 2)) = READBIT; } } /* * cleanup */ done: if (freesrc && src) { SDL_RWclose(src); } return(spec); }
static PHYSFS_sint64 SDLRWIoLength(struct PHYSFS_Io *io) { return SDL_RWsize(getSDLRWops(io)); }
static zip_int64_t vfs_zipfile_srcfunc(void *userdata, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { VFSNode *zipnode = userdata; VFSZipFileData *zdata = zipnode->data1; VFSZipFileTLS *tls = vfs_zipfile_get_tls(zipnode, false); VFSNode *source = zdata->source; zip_int64_t ret = -1; if(!tls) { return -1; } switch(cmd) { case ZIP_SOURCE_OPEN: { tls->stream = vfs_node_open(source, VFS_MODE_READ); if(!tls->stream) { zip_error_set(&tls->error, ZIP_ER_OPEN, 0); return -1; } return 0; } case ZIP_SOURCE_CLOSE: { if(tls->stream) { SDL_RWclose(tls->stream); tls->stream = NULL; } return 0; } case ZIP_SOURCE_STAT: { zip_stat_t *stat = data; zip_stat_init(stat); stat->valid = ZIP_STAT_COMP_METHOD | ZIP_STAT_ENCRYPTION_METHOD; stat->comp_method = ZIP_CM_STORE; stat->encryption_method = ZIP_EM_NONE; if(tls->stream) { stat->valid |= ZIP_STAT_SIZE | ZIP_STAT_COMP_SIZE; stat->size = SDL_RWsize(tls->stream); stat->comp_size = stat->size; } return sizeof(struct zip_stat); } case ZIP_SOURCE_READ: { assume(tls->stream != NULL); ret = SDL_RWread(tls->stream, data, 1, len); if(!ret) { LOG_SDL_ERROR; zip_error_set(&tls->error, ZIP_ER_READ, 0); ret = -1; } return ret; } case ZIP_SOURCE_SEEK: { struct zip_source_args_seek *s; s = ZIP_SOURCE_GET_ARGS(struct zip_source_args_seek, data, len, &tls->error); assume(tls->stream != NULL); ret = SDL_RWseek(tls->stream, s->offset, s->whence); if(ret < 0) { LOG_SDL_ERROR; zip_error_set(&tls->error, ZIP_ER_SEEK, 0); } return ret; } case ZIP_SOURCE_TELL: { assume(tls->stream != NULL); ret = SDL_RWtell(tls->stream); if(ret < 0) { LOG_SDL_ERROR; zip_error_set(&tls->error, ZIP_ER_TELL, 0); } return ret; } case ZIP_SOURCE_ERROR: { return zip_error_to_data(&tls->error, data, len); } case ZIP_SOURCE_SUPPORTS: { return ZIP_SOURCE_SUPPORTS_SEEKABLE; } case ZIP_SOURCE_FREE: { return 0; } default: { zip_error_set(&tls->error, ZIP_ER_INTERNAL, 0); return -1; } } }
bool File::OpenInternal(const String& fileName, FileMode mode, bool fromPackage) { Close(); compressed_ = false; readSyncNeeded_ = false; writeSyncNeeded_ = false; FileSystem* fileSystem = GetSubsystem<FileSystem>(); if (fileSystem && !fileSystem->CheckAccess(GetPath(fileName))) { ATOMIC_LOGERRORF("Access denied to %s", fileName.CString()); return false; } if (fileName.Empty()) { ATOMIC_LOGERROR("Could not open file with empty name"); return false; } #ifdef __ANDROID__ if (ATOMIC_IS_ASSET(fileName)) { if (mode != FILE_READ) { ATOMIC_LOGERROR("Only read mode is supported for Android asset files"); return false; } assetHandle_ = SDL_RWFromFile(ATOMIC_ASSET(fileName), "rb"); if (!assetHandle_) { ATOMIC_LOGERRORF("Could not open Android asset file %s", fileName.CString()); return false; } else { fileName_ = fileName; mode_ = mode; position_ = 0; if (!fromPackage) { size_ = SDL_RWsize(assetHandle_); offset_ = 0; } checksum_ = 0; return true; } } #endif #ifdef _WIN32 handle_ = _wfopen(GetWideNativePath(fileName).CString(), openMode[mode]); #else handle_ = fopen(GetNativePath(fileName).CString(), openMode[mode]); #endif // If file did not exist in readwrite mode, retry with write-update mode if (mode == FILE_READWRITE && !handle_) { #ifdef _WIN32 handle_ = _wfopen(GetWideNativePath(fileName).CString(), openMode[mode + 1]); #else handle_ = fopen(GetNativePath(fileName).CString(), openMode[mode + 1]); #endif } if (!handle_) { ATOMIC_LOGERRORF("Could not open file %s", fileName.CString()); return false; } if (!fromPackage) { fseek((FILE*)handle_, 0, SEEK_END); long size = ftell((FILE*)handle_); fseek((FILE*)handle_, 0, SEEK_SET); if (size > M_MAX_UNSIGNED) { ATOMIC_LOGERRORF("Could not open file %s which is larger than 4GB", fileName.CString()); Close(); size_ = 0; return false; } size_ = (unsigned)size; offset_ = 0; } fileName_ = fileName; mode_ = mode; position_ = 0; checksum_ = 0; return true; }
bool replay_read(Replay *rpy, SDL_RWops *file, ReplayReadMode mode, const char *source) { int64_t filesize; // must be signed SDL_RWops *vfile = file; if(!source) { source = "<unknown>"; } if(!(mode & REPLAY_READ_ALL) ) { log_fatal("%s: Called with invalid read mode %x", source, mode); } mode &= REPLAY_READ_ALL; filesize = SDL_RWsize(file); if(filesize < 0) { log_warn("%s: SDL_RWsize() failed: %s", source, SDL_GetError()); } if(mode & REPLAY_READ_META) { memset(rpy, 0, sizeof(Replay)); if(filesize > 0 && filesize <= sizeof(replay_magic_header) + 2) { log_warn("%s: Replay file is too short (%"PRIi64")", source, filesize); return false; } size_t ofs = 0; if(!replay_read_header(rpy, file, filesize, &ofs, source)) { return false; } bool compression = false; if(rpy->version & REPLAY_VERSION_COMPRESSION_BIT) { if(rpy->fileoffset < SDL_RWtell(file)) { log_warn("%s: Invalid offset %"PRIi32"", source, rpy->fileoffset); return false; } vfile = SDL_RWWrapZReader(SDL_RWWrapSegment(file, ofs, rpy->fileoffset, false), REPLAY_COMPRESSION_CHUNK_SIZE, true); filesize = -1; compression = true; } if(!replay_read_meta(rpy, vfile, filesize, source)) { if(compression) { SDL_RWclose(vfile); } return false; } if(compression) { SDL_RWclose(vfile); vfile = file; } else { rpy->fileoffset = SDL_RWtell(file); } } if(mode & REPLAY_READ_EVENTS) { if(!(mode & REPLAY_READ_META)) { if(!rpy->fileoffset) { log_fatal("%s: Tried to read events before reading metadata", source); } for(int i = 0; i < rpy->numstages; ++i) { if(rpy->stages[i].events) { log_warn("%s: BUG: Reading events into a replay that already had events, call replay_destroy_events() if this is intended", source); replay_destroy_events(rpy); break; } } if(SDL_RWseek(file, rpy->fileoffset, RW_SEEK_SET) < 0) { log_warn("%s: SDL_RWseek() failed: %s", source, SDL_GetError()); return false; } } bool compression = false; if(rpy->version & REPLAY_VERSION_COMPRESSION_BIT) { vfile = SDL_RWWrapZReader(file, REPLAY_COMPRESSION_CHUNK_SIZE, false); filesize = -1; compression = true; } if(!replay_read_events(rpy, vfile, filesize, source)) { if(compression) { SDL_RWclose(vfile); } replay_destroy_events(rpy); return false; } if(compression) { SDL_RWclose(vfile); } // useless byte to simplify the premature EOF check, can be anything SDL_ReadU8(file); } return true; }