Add more functions
This commit is contained in:
parent
fb93c7c94b
commit
349288d189
2 changed files with 165 additions and 10 deletions
|
@ -15,6 +15,28 @@ import (
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "github.com/gen2brain/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// LoadDataFromResource - Load raw data from rres resource chunk
|
||||||
|
//
|
||||||
|
// NOTE: Chunk data must be provided uncompressed/unencrypted
|
||||||
|
func LoadDataFromResource(chunk ResourceChunk) []byte {
|
||||||
|
cchunk := *(*C.rresResourceChunk)(unsafe.Pointer(&chunk))
|
||||||
|
var csize C.uint
|
||||||
|
ret := C.LoadDataFromResource(cchunk, &csize)
|
||||||
|
defer C.free(ret)
|
||||||
|
v := C.GoBytes(ret, C.int(csize))
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnpackResourceChunk - Unpack resource chunk data (decompres/decrypt data)
|
||||||
|
//
|
||||||
|
// NOTE: Function return 0 on success or other value on failure
|
||||||
|
func UnpackResourceChunk(chunk *ResourceChunk) ErrorType {
|
||||||
|
cchunk := (*C.rresResourceChunk)(unsafe.Pointer(chunk))
|
||||||
|
ret := C.UnpackResourceChunk(cchunk)
|
||||||
|
v := ErrorType(ret)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
func LoadImageFromResource(chunk ResourceChunk) rl.Image {
|
func LoadImageFromResource(chunk ResourceChunk) rl.Image {
|
||||||
cchunk := *(*C.rresResourceChunk)(unsafe.Pointer(&chunk))
|
cchunk := *(*C.rresResourceChunk)(unsafe.Pointer(&chunk))
|
||||||
ret := C.LoadImageFromResource(cchunk)
|
ret := C.LoadImageFromResource(cchunk)
|
||||||
|
|
153
rres/rres.go
153
rres/rres.go
|
@ -1,10 +1,18 @@
|
||||||
package rres
|
package rres
|
||||||
|
|
||||||
// #define RRES_IMPLEMENTATION
|
/*
|
||||||
// #include <rres.h>
|
#define RRES_IMPLEMENTATION
|
||||||
// #include <stdlib.h>
|
#include <rres.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
rresResourceChunkInfo GetResourceChunkInfoFromArray(rresResourceChunkInfo *infos, int index)
|
||||||
|
{
|
||||||
|
return infos[index];
|
||||||
|
}
|
||||||
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
|
"hash/crc32"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -51,7 +59,12 @@ type ResourceChunk struct {
|
||||||
// NOTE: It supports multiple resource chunks
|
// NOTE: It supports multiple resource chunks
|
||||||
type ResourceMulti struct {
|
type ResourceMulti struct {
|
||||||
Count uint32 // Resource chunks count
|
Count uint32 // Resource chunks count
|
||||||
Chunks *ResourceChunk // Resource chunks
|
chunks *ResourceChunk // Resource chunks
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chunks - Resource chunks
|
||||||
|
func (r *ResourceMulti) Chunks() []ResourceChunk {
|
||||||
|
return unsafe.Slice(r.chunks, r.Count)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DirEntry - CDIR: rres central directory entry
|
// DirEntry - CDIR: rres central directory entry
|
||||||
|
@ -60,7 +73,15 @@ type DirEntry struct {
|
||||||
Offset uint32 // Resource global offset in file
|
Offset uint32 // Resource global offset in file
|
||||||
Reserved uint32 // reserved
|
Reserved uint32 // reserved
|
||||||
FileNameSize uint32 // Resource fileName size (NULL terminator and 4-byte alignment padding considered)
|
FileNameSize uint32 // Resource fileName size (NULL terminator and 4-byte alignment padding considered)
|
||||||
FileName [MaxFilenameSize]int8 // Resource original fileName (NULL terminated and padded to 4-byte alignment)
|
fileName [MaxFilenameSize]int8 // Resource original fileName (NULL terminated and padded to 4-byte alignment)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileName - Resource original fileName
|
||||||
|
func (d *DirEntry) FileName() string {
|
||||||
|
cpointer := (*C.char)(unsafe.Pointer(&d.fileName[0]))
|
||||||
|
clength := C.int(d.FileNameSize)
|
||||||
|
fileName := C.GoStringN(cpointer, clength)
|
||||||
|
return fileName
|
||||||
}
|
}
|
||||||
|
|
||||||
// CentralDir - CDIR: rres central directory
|
// CentralDir - CDIR: rres central directory
|
||||||
|
@ -68,7 +89,12 @@ type DirEntry struct {
|
||||||
// NOTE: This data conforms the ResourceChunkData
|
// NOTE: This data conforms the ResourceChunkData
|
||||||
type CentralDir struct {
|
type CentralDir struct {
|
||||||
Count uint32 // Central directory entries count
|
Count uint32 // Central directory entries count
|
||||||
Entries *DirEntry // Central directory entries
|
entries *DirEntry // Central directory entries
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entries - Central directory entries
|
||||||
|
func (c *CentralDir) Entries() []DirEntry {
|
||||||
|
return unsafe.Slice(c.entries, c.Count)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FontGlyphInfo - FNTG: rres font glyphs info (32 bytes)
|
// FontGlyphInfo - FNTG: rres font glyphs info (32 bytes)
|
||||||
|
@ -326,8 +352,8 @@ func LoadResourceChunk(fileName string, rresId int32) ResourceChunk {
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnloadResourceChunk - Unload resource chunk from memory
|
// UnloadResourceChunk - Unload resource chunk from memory
|
||||||
func UnloadResourceChunk(chunk ResourceChunk) {
|
func UnloadResourceChunk(chunk *ResourceChunk) {
|
||||||
cchunk := *(*C.rresResourceChunk)(unsafe.Pointer(&chunk))
|
cchunk := *(*C.rresResourceChunk)(unsafe.Pointer(chunk))
|
||||||
C.rresUnloadResourceChunk(cchunk)
|
C.rresUnloadResourceChunk(cchunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,11 +367,48 @@ func LoadResourceMulti(fileName string, rresId int32) ResourceMulti {
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnloadResourceMulti - Unload resource from memory (multiple resource chunks)
|
// UnloadResourceMulti - Unload resource from memory (multiple resource chunks)
|
||||||
func UnloadResourceMulti(multi ResourceMulti) {
|
func UnloadResourceMulti(multi *ResourceMulti) {
|
||||||
cmulti := *(*C.rresResourceMulti)(unsafe.Pointer(&multi))
|
cmulti := *(*C.rresResourceMulti)(unsafe.Pointer(multi))
|
||||||
C.rresUnloadResourceMulti(cmulti)
|
C.rresUnloadResourceMulti(cmulti)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadResourceChunkInfo - Load resource chunk info for provided id
|
||||||
|
func LoadResourceChunkInfo(fileName string, rresId int32) ResourceChunkInfo {
|
||||||
|
cfileName := C.CString(fileName)
|
||||||
|
defer C.free(unsafe.Pointer(cfileName))
|
||||||
|
ret := C.rresLoadResourceChunkInfo(cfileName, C.int(rresId))
|
||||||
|
v := *(*ResourceChunkInfo)(unsafe.Pointer(&ret))
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadResourceChunkInfoAll - Load all resource chunks info
|
||||||
|
func LoadResourceChunkInfoAll(fileName string) []ResourceChunkInfo {
|
||||||
|
// Convert the fileName into a CString and releases the memory afterwards
|
||||||
|
cfileName := C.CString(fileName)
|
||||||
|
defer C.free(unsafe.Pointer(cfileName))
|
||||||
|
|
||||||
|
// The length of the resulted array is saved in the chunkCount variable
|
||||||
|
var chunkCount C.uint
|
||||||
|
cinfos := C.rresLoadResourceChunkInfoAll(cfileName, &chunkCount)
|
||||||
|
|
||||||
|
// The C array can be released afterwards, because the values are stored in a golang slice
|
||||||
|
defer C.free(unsafe.Pointer(cinfos))
|
||||||
|
|
||||||
|
// Iterate over the C array and store the values in a golang slice
|
||||||
|
infos := make([]ResourceChunkInfo, chunkCount)
|
||||||
|
for i := 0; i < int(chunkCount); i++ {
|
||||||
|
// Get the C value from the C array
|
||||||
|
ret := C.GetResourceChunkInfoFromArray(cinfos, C.int(i))
|
||||||
|
// Convert the C value into a golang value
|
||||||
|
v := *(*ResourceChunkInfo)(unsafe.Pointer(&ret))
|
||||||
|
// Save the golang value in the golang slice
|
||||||
|
infos[i] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
return infos
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadCentralDirectory - Load central directory resource chunk from file
|
||||||
func LoadCentralDirectory(fileName string) CentralDir {
|
func LoadCentralDirectory(fileName string) CentralDir {
|
||||||
cfileName := C.CString(fileName)
|
cfileName := C.CString(fileName)
|
||||||
defer C.free(unsafe.Pointer(cfileName))
|
defer C.free(unsafe.Pointer(cfileName))
|
||||||
|
@ -354,6 +417,42 @@ func LoadCentralDirectory(fileName string) CentralDir {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnloadCentralDirectory - Unload central directory resource chunk
|
||||||
|
func UnloadCentralDirectory(dir *CentralDir) {
|
||||||
|
cdir := *(*C.rresCentralDir)(unsafe.Pointer(dir))
|
||||||
|
C.rresUnloadCentralDirectory(cdir)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDataType - Get ResourceDataType from FourCC code
|
||||||
|
func GetDataType(fourCC [4]byte) ResourceDataType {
|
||||||
|
value := string(fourCC[:])
|
||||||
|
switch value {
|
||||||
|
case "NULL":
|
||||||
|
return DataNull
|
||||||
|
case "RAWD":
|
||||||
|
return DataRaw
|
||||||
|
case "TEXT":
|
||||||
|
return DataText
|
||||||
|
case "IMGE":
|
||||||
|
return DataImage
|
||||||
|
case "WAVE":
|
||||||
|
return DataWave
|
||||||
|
case "VRTX":
|
||||||
|
return DataVertex
|
||||||
|
case "FNTG":
|
||||||
|
return DataFontGlyphs
|
||||||
|
case "LINK":
|
||||||
|
return DataLink
|
||||||
|
case "CDIR":
|
||||||
|
return DataDirectory
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResourceId - Get resource id for a provided filename
|
||||||
|
//
|
||||||
|
// NOTE: It requires CDIR available in the file (it's optinal by design)
|
||||||
func GetResourceId(dir CentralDir, fileName string) int32 {
|
func GetResourceId(dir CentralDir, fileName string) int32 {
|
||||||
cfileName := C.CString(fileName)
|
cfileName := C.CString(fileName)
|
||||||
defer C.free(unsafe.Pointer(cfileName))
|
defer C.free(unsafe.Pointer(cfileName))
|
||||||
|
@ -362,3 +461,37 @@ func GetResourceId(dir CentralDir, fileName string) int32 {
|
||||||
v := int32(ret)
|
v := int32(ret)
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ComputeCRC32 - Compute CRC32 hash
|
||||||
|
//
|
||||||
|
// NOTE: CRC32 is used as rres id, generated from original filename
|
||||||
|
func ComputeCRC32(data []byte) uint32 {
|
||||||
|
return crc32.ChecksumIEEE(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCipherPassword - Set password to be used on data decryption
|
||||||
|
//
|
||||||
|
// NOTE: The cipher password is kept as an internal pointer to provided string, it's up to the user to manage that sensible data properly
|
||||||
|
//
|
||||||
|
// Password should be to allocate and set before loading an encrypted resource and it should be cleaned/wiped after the encrypted resource has been loaded
|
||||||
|
//
|
||||||
|
// You can use the WipeCipherPassword function to clear the password
|
||||||
|
func SetCipherPassword(pass string) {
|
||||||
|
cpass := C.CString(pass)
|
||||||
|
C.rresSetCipherPassword(cpass)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCipherPassword - Get password to be used on data decryption
|
||||||
|
func GetCipherPassword() string {
|
||||||
|
cpass := C.rresGetCipherPassword()
|
||||||
|
return C.GoString(cpass)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WipeCipherPassword - Clears the password from the C memory using explicit_bzero
|
||||||
|
//
|
||||||
|
// This is an approach but no guarantee
|
||||||
|
func WipeCipherPassword() {
|
||||||
|
cpass := C.rresGetCipherPassword()
|
||||||
|
C.explicit_bzero(unsafe.Pointer(cpass), C.strlen(cpass))
|
||||||
|
C.free(unsafe.Pointer(cpass))
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue