package game import "base:runtime" import "core:c" import "core:log" import "core:strings" import "libs:physfs" import rl "libs:raylib" @(private = "file") _ctx: runtime.Context init_physfs :: proc(args: []string) { _ctx = context physfs.init(strings.clone_to_cstring(args[0], context.temp_allocator)) physfs.setSaneConfig("serega", "gutter-runner", "zip", 0, 1) } init_physifs_raylib_callbacks :: proc() { rl.SetLoadFileDataCallback(raylib_load_file_data_physfs) rl.SetSaveFileDataCallback(raylib_save_file_data_physfs) rl.SetLoadFileTextCallback(raylib_load_file_text_physfs) rl.SetSaveFileTextCallback(raylib_save_file_text_physfs) } deinit_physfs :: proc() { rl.SetLoadFileDataCallback(nil) rl.SetSaveFileDataCallback(nil) rl.SetLoadFileTextCallback(nil) rl.SetSaveFileTextCallback(nil) physfs.deinit() } @(private = "file") raylib_load_file_data_physfs :: proc "c" (file_name: cstring, bytes_read: ^c.int) -> [^]u8 { context = _ctx bytes_read^ = 0 if physfs.exists(file_name) == 0 { log.warnf("PHYSFS: Tried to load unexisting file '%s'", file_name) return nil } // Open up the file. handle := physfs.openRead(file_name) if handle == nil { trace_physfs_error(file_name) return nil } defer physfs.close(handle) // Check to see how large the file is. size := physfs.fileLength(handle) if (size == -1) { log.warnf("PHYSFS: Cannot determine size of file '%s'", file_name) return nil } // Close safely when it's empty. if (size == 0) { return nil } // Read the file, return if it's empty. buffer := rl.MemAlloc(u32(size)) read := physfs.readBytes(handle, buffer, u64(size)) if read < 0 { rl.MemFree(buffer) trace_physfs_error(file_name) return nil } bytes_read^ = i32(read) return cast([^]u8)buffer } @(private = "file") raylib_save_file_data_physfs :: proc "c" ( file_name: cstring, data: rawptr, bytes_to_write: c.int, ) -> bool { context = _ctx // Protect against empty writes. if bytes_to_write <= 0 { return true } // Open the file. handle := physfs.openWrite(file_name) if handle == nil { trace_physfs_error(file_name) return false } defer physfs.close(handle) // Write the data to the file handle. if (physfs.writeBytes(handle, data, u64(bytes_to_write)) < 0) { trace_physfs_error(file_name) return false } return true } @(private = "file") raylib_load_file_text_physfs :: proc "c" (fileName: cstring) -> [^]u8 { bytesRead: i32 data := raylib_load_file_data_physfs(fileName, &bytesRead) if bytesRead == 0 { return nil } defer rl.MemFree(data) // Copy the data, and append a null terminator. text := cast([^]u8)rl.MemAlloc(u32(bytesRead + 1)) for i := i32(0); i < bytesRead; i += 1 { text[i] = data[i] } text[bytesRead] = 0 return text } @(private = "file") raylib_save_file_text_physfs :: proc "c" (fileName: cstring, text: cstring) -> bool { return raylib_save_file_data_physfs(fileName, cast(rawptr)text, i32(runtime.cstring_len(text))) } @(private = "file") trace_physfs_error :: proc(detail: cstring) { errorCode := physfs.getLastErrorCode() if errorCode == .OK { log.warnf("PHYSFS: %s", detail) } else { errorMessage := physfs.getErrorByCode(errorCode) log.warnf("PHYSFS: %s (%s)", errorMessage, detail) } }