142 lines
3.2 KiB
Odin
142 lines
3.2 KiB
Odin
package game
|
|
|
|
import "base:runtime"
|
|
import "core:c"
|
|
import "core:log"
|
|
import "core:strings"
|
|
import "libs:physfs"
|
|
import rl "vendor: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)
|
|
}
|
|
}
|