rREM - raylib Resource EMbedder
This commit is contained in:
parent
d25f6e5b1f
commit
5b59c0b7e9
10 changed files with 911 additions and 166 deletions
2
Makefile
2
Makefile
|
@ -1,4 +1,4 @@
|
||||||
PACKAGES= raylib raygui raymath easings physics
|
PACKAGES= raylib raygui raymath easings physics rres
|
||||||
|
|
||||||
GO?= go
|
GO?= go
|
||||||
|
|
||||||
|
|
8
examples/others/resources/data.h
Normal file
8
examples/others/resources/data.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#define NUM_RESOURCES 6
|
||||||
|
|
||||||
|
#define RES_coin.wav 0x00000000 // Embedded as WAVE
|
||||||
|
#define RES_raylib_logo.gif 0x00000001 // Embedded as IMAGE
|
||||||
|
#define RES_raylib_logo.jpg 0x00000002 // Embedded as IMAGE
|
||||||
|
#define RES_raylib_logo.png 0x00000003 // Embedded as IMAGE
|
||||||
|
#define RES_raylib_logo.tga 0x00000004 // Embedded as IMAGE
|
||||||
|
#define RES_tanatana.ogg 0x00000005 // Embedded as VORBIS
|
BIN
examples/others/resources/data.rres
Normal file
BIN
examples/others/resources/data.rres
Normal file
Binary file not shown.
95
examples/others/resources/main.go
Normal file
95
examples/others/resources/main.go
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
//"bytes"
|
||||||
|
|
||||||
|
"github.com/gen2brain/raylib-go/raylib"
|
||||||
|
)
|
||||||
|
|
||||||
|
const numTextures = 4
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
screenWidth := int32(800)
|
||||||
|
screenHeight := int32(450)
|
||||||
|
|
||||||
|
raylib.InitWindow(screenWidth, screenHeight, "raylib [core] example - resources loading")
|
||||||
|
|
||||||
|
raylib.InitAudioDevice()
|
||||||
|
|
||||||
|
// OpenAsset() will also work on Android (reads files from assets/)
|
||||||
|
reader, err := raylib.OpenAsset("data.rres")
|
||||||
|
if err != nil {
|
||||||
|
raylib.TraceLog(raylib.LogWarning, "[%s] rRES raylib resource file could not be opened: %v", "data.rres", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer reader.Close()
|
||||||
|
|
||||||
|
// bindata
|
||||||
|
//b := MustAsset("data.rres")
|
||||||
|
//reader := bytes.NewReader(b)
|
||||||
|
|
||||||
|
res := raylib.LoadResource(reader, 0, nil)
|
||||||
|
wav := raylib.LoadWaveEx(res.Data, int32(res.Param1), int32(res.Param2), int32(res.Param3), int32(res.Param4))
|
||||||
|
snd := raylib.LoadSoundFromWave(wav)
|
||||||
|
raylib.UnloadWave(wav)
|
||||||
|
|
||||||
|
textures := make([]raylib.Texture2D, numTextures)
|
||||||
|
for i := 0; i < numTextures; i++ {
|
||||||
|
r := raylib.LoadResource(reader, i+1, nil)
|
||||||
|
image := raylib.LoadImagePro(r.Data, int32(r.Param1), int32(r.Param2), raylib.TextureFormat(r.Param3))
|
||||||
|
textures[i] = raylib.LoadTextureFromImage(image)
|
||||||
|
raylib.UnloadImage(image)
|
||||||
|
}
|
||||||
|
|
||||||
|
currentTexture := 0
|
||||||
|
|
||||||
|
raylib.SetTargetFPS(60)
|
||||||
|
|
||||||
|
for !raylib.WindowShouldClose() {
|
||||||
|
if raylib.IsKeyPressed(raylib.KeySpace) {
|
||||||
|
raylib.PlaySound(snd)
|
||||||
|
}
|
||||||
|
|
||||||
|
if raylib.IsMouseButtonPressed(raylib.MouseLeftButton) {
|
||||||
|
currentTexture = (currentTexture + 1) % numTextures // Cycle between the textures
|
||||||
|
}
|
||||||
|
|
||||||
|
raylib.BeginDrawing()
|
||||||
|
|
||||||
|
raylib.ClearBackground(raylib.RayWhite)
|
||||||
|
|
||||||
|
raylib.DrawTexture(textures[currentTexture], screenWidth/2-textures[currentTexture].Width/2, screenHeight/2-textures[currentTexture].Height/2, raylib.RayWhite)
|
||||||
|
|
||||||
|
raylib.DrawText("MOUSE LEFT BUTTON to CYCLE TEXTURES", 40, 410, 10, raylib.Gray)
|
||||||
|
raylib.DrawText("SPACE to PLAY SOUND", 40, 430, 10, raylib.Gray)
|
||||||
|
|
||||||
|
switch currentTexture {
|
||||||
|
case 0:
|
||||||
|
raylib.DrawText("GIF", 272, 70, 20, raylib.Gray)
|
||||||
|
break
|
||||||
|
case 1:
|
||||||
|
raylib.DrawText("JPEG", 272, 70, 20, raylib.Gray)
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
raylib.DrawText("PNG", 272, 70, 20, raylib.Gray)
|
||||||
|
break
|
||||||
|
case 3:
|
||||||
|
raylib.DrawText("TGA", 272, 70, 20, raylib.Gray)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
raylib.EndDrawing()
|
||||||
|
}
|
||||||
|
|
||||||
|
raylib.UnloadSound(snd)
|
||||||
|
|
||||||
|
for _, t := range textures {
|
||||||
|
raylib.UnloadTexture(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
raylib.CloseAudioDevice()
|
||||||
|
|
||||||
|
raylib.CloseWindow()
|
||||||
|
}
|
|
@ -132,12 +132,13 @@ func LoadWave(fileName string) Wave {
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadWaveEx - Load wave data from float array data (32bit)
|
// LoadWaveEx - Load wave data from float array data (32bit)
|
||||||
func LoadWaveEx(data unsafe.Pointer, sampleCount int32, sampleRate int32, sampleSize int32, channels int32) Wave {
|
func LoadWaveEx(data []byte, sampleCount int32, sampleRate int32, sampleSize int32, channels int32) Wave {
|
||||||
|
cdata := unsafe.Pointer(&data[0])
|
||||||
csampleCount := (C.int)(sampleCount)
|
csampleCount := (C.int)(sampleCount)
|
||||||
csampleRate := (C.int)(sampleRate)
|
csampleRate := (C.int)(sampleRate)
|
||||||
csampleSize := (C.int)(sampleSize)
|
csampleSize := (C.int)(sampleSize)
|
||||||
cchannels := (C.int)(channels)
|
cchannels := (C.int)(channels)
|
||||||
ret := C.LoadWaveEx(data, csampleCount, csampleRate, csampleSize, cchannels)
|
ret := C.LoadWaveEx(cdata, csampleCount, csampleRate, csampleSize, cchannels)
|
||||||
v := NewWaveFromPointer(unsafe.Pointer(&ret))
|
v := NewWaveFromPointer(unsafe.Pointer(&ret))
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
321
raylib/rres.go
321
raylib/rres.go
|
@ -2,212 +2,209 @@ package raylib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"compress/flate"
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
|
"crypto/des"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/dsnet/compress/bzip2"
|
||||||
|
"github.com/klauspost/compress/flate"
|
||||||
|
"github.com/pierrec/lz4"
|
||||||
|
"github.com/rootlch/encrypt"
|
||||||
|
"github.com/ulikunitz/xz"
|
||||||
|
|
||||||
|
"github.com/gen2brain/raylib-go/rres"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RRESFileHeader - rRES file header (8 byte)
|
// LoadResource - Load resource from file by id
|
||||||
type RRESFileHeader struct {
|
|
||||||
// File identifier: rRES (4 byte)
|
|
||||||
ID [4]int8
|
|
||||||
// File version and subversion (2 byte)
|
|
||||||
Version uint16
|
|
||||||
// Number of resources in this file (2 byte)
|
|
||||||
Count uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
// RRESInfoHeader - rRES info header, every resource includes this header (16 byte + 16 byte)
|
|
||||||
type RRESInfoHeader struct {
|
|
||||||
// Resource unique identifier (4 byte)
|
|
||||||
ID uint32
|
|
||||||
// Resource data type (1 byte)
|
|
||||||
DataType uint8
|
|
||||||
// Resource data compression type (1 byte)
|
|
||||||
CompType uint8
|
|
||||||
// Resource data encryption type (1 byte)
|
|
||||||
CryptoType uint8
|
|
||||||
// Resource data parts count, used for splitted data (1 byte)
|
|
||||||
PartsCount uint8
|
|
||||||
// Resource data size (compressed or not, only DATA) (4 byte)
|
|
||||||
DataSize uint32
|
|
||||||
// Resource data size (uncompressed, only DATA) (4 byte)
|
|
||||||
UncompSize uint32
|
|
||||||
// Resouce parameter 1 (4 byte)
|
|
||||||
Param1 uint32
|
|
||||||
// Resouce parameter 2 (4 byte)
|
|
||||||
Param2 uint32
|
|
||||||
// Resouce parameter 3 (4 byte)
|
|
||||||
Param3 uint32
|
|
||||||
// Resouce parameter 4 (4 byte)
|
|
||||||
Param4 uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
// rRES data types
|
|
||||||
const (
|
|
||||||
RRESTypeRaw = iota
|
|
||||||
RRESTypeImage
|
|
||||||
RRESTypeWave
|
|
||||||
RRESTypeVertex
|
|
||||||
RRESTypeText
|
|
||||||
RRESTypeFontImage
|
|
||||||
RRESTypeFontData
|
|
||||||
RRESTypeDirectory
|
|
||||||
)
|
|
||||||
|
|
||||||
// Compression types
|
|
||||||
const (
|
|
||||||
// No data compression
|
|
||||||
RRESCompNone = iota
|
|
||||||
// DEFLATE compression
|
|
||||||
RRESCompDeflate
|
|
||||||
// LZ4 compression
|
|
||||||
RRESCompLz4
|
|
||||||
// LZMA compression
|
|
||||||
RRESCompLzma
|
|
||||||
// BROTLI compression
|
|
||||||
RRESCompBrotli
|
|
||||||
)
|
|
||||||
|
|
||||||
// Image formats
|
|
||||||
const (
|
|
||||||
// 8 bit per pixel (no alpha)
|
|
||||||
RRESImUncompGrayscale = iota + 1
|
|
||||||
// 16 bpp (2 channels)
|
|
||||||
RRESImUncompGrayAlpha
|
|
||||||
// 16 bpp
|
|
||||||
RRESImUncompR5g6b5
|
|
||||||
// 24 bpp
|
|
||||||
RRESImUncompR8g8b8
|
|
||||||
// 16 bpp (1 bit alpha)
|
|
||||||
RRESImUncompR5g5b5a1
|
|
||||||
// 16 bpp (4 bit alpha)
|
|
||||||
RRESImUncompR4g4b4a4
|
|
||||||
// 32 bpp
|
|
||||||
RRESImUncompR8g8b8a8
|
|
||||||
// 4 bpp (no alpha)
|
|
||||||
RRESImCompDxt1Rgb
|
|
||||||
// 4 bpp (1 bit alpha)
|
|
||||||
RRESImCompDxt1Rgba
|
|
||||||
// 8 bpp
|
|
||||||
RRESImCompDxt3Rgba
|
|
||||||
// 8 bpp
|
|
||||||
RRESImCompDxt5Rgba
|
|
||||||
// 4 bpp
|
|
||||||
RRESImCompEtc1Rgb
|
|
||||||
// 4 bpp
|
|
||||||
RRESImCompEtc2Rgb
|
|
||||||
// 8 bpp
|
|
||||||
RRESImCompEtc2EacRgba
|
|
||||||
// 4 bpp
|
|
||||||
RRESImCompPvrtRgb
|
|
||||||
// 4 bpp
|
|
||||||
RRESImCompPvrtRgba
|
|
||||||
// 8 bpp
|
|
||||||
RRESImCompAstc4x4Rgba
|
|
||||||
// 2 bpp
|
|
||||||
RRESImCompAstc8x8Rgba
|
|
||||||
)
|
|
||||||
|
|
||||||
// RRESVert
|
|
||||||
const (
|
|
||||||
RRESVertPosition = iota
|
|
||||||
RRESVertTexcoord1
|
|
||||||
RRESVertTexcoord2
|
|
||||||
RRESVertTexcoord3
|
|
||||||
RRESVertTexcoord4
|
|
||||||
RRESVertNormal
|
|
||||||
RRESVertTangent
|
|
||||||
RRESVertColor
|
|
||||||
RRESVertIndex
|
|
||||||
)
|
|
||||||
|
|
||||||
// RRESVert
|
|
||||||
const (
|
|
||||||
RRESVertByte = iota
|
|
||||||
RRESVertShort
|
|
||||||
RRESVertInt
|
|
||||||
RRESVertHfloat
|
|
||||||
RRESVertFloat
|
|
||||||
)
|
|
||||||
|
|
||||||
// LoadResource - Load resource from file (only one)
|
|
||||||
// NOTE: Returns uncompressed data with parameters, only first resource found
|
|
||||||
func LoadResource(fileName string) []byte {
|
|
||||||
return LoadResourceByID(fileName, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadResourceByID - Load resource from file by id
|
|
||||||
// NOTE: Returns uncompressed data with parameters, search resource by id
|
// NOTE: Returns uncompressed data with parameters, search resource by id
|
||||||
func LoadResourceByID(fileName string, rresID int) (data []byte) {
|
func LoadResource(reader io.ReadSeeker, rresID int, key []byte) (data rres.Data) {
|
||||||
file, err := OpenAsset(fileName)
|
var fileHeader rres.FileHeader
|
||||||
if err != nil {
|
var infoHeader rres.InfoHeader
|
||||||
TraceLog(LogWarning, "[%s] rRES raylib resource file could not be opened", fileName)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
fileHeader := RRESFileHeader{}
|
reader.Seek(0, 0)
|
||||||
infoHeader := RRESInfoHeader{}
|
|
||||||
|
|
||||||
// Read rres file header
|
// Read rres file header
|
||||||
err = binary.Read(file, binary.LittleEndian, &fileHeader)
|
err := binary.Read(reader, binary.LittleEndian, &fileHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
TraceLog(LogWarning, err.Error())
|
TraceLog(LogWarning, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//fmt.Printf("%+v\n", fileHeader)
|
|
||||||
|
|
||||||
// Verify "rRES" identifier
|
// Verify "rRES" identifier
|
||||||
id := fmt.Sprintf("%c", fileHeader.ID)
|
id := fmt.Sprintf("%c", fileHeader.ID)
|
||||||
if id != "[r R E S]" {
|
if id != "[r R E S]" {
|
||||||
TraceLog(LogWarning, "[%s] is not a valid raylib resource file", fileName)
|
TraceLog(LogWarning, "not a valid raylib resource file")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
file.Seek(int64(unsafe.Sizeof(fileHeader)), os.SEEK_CUR)
|
reader.Seek(int64(unsafe.Sizeof(fileHeader)), os.SEEK_CUR)
|
||||||
|
|
||||||
for i := 0; i < int(fileHeader.Count); i++ {
|
for i := 0; i < int(fileHeader.Count); i++ {
|
||||||
// Read resource info and parameters
|
// Read resource info and parameters
|
||||||
err = binary.Read(file, binary.LittleEndian, &infoHeader)
|
err = binary.Read(reader, binary.LittleEndian, &infoHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
TraceLog(LogWarning, err.Error())
|
TraceLog(LogWarning, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//fmt.Printf("%+v\n", infoHeader)
|
reader.Seek(int64(unsafe.Sizeof(infoHeader)), os.SEEK_CUR)
|
||||||
|
|
||||||
file.Seek(int64(unsafe.Sizeof(infoHeader)), os.SEEK_CUR)
|
|
||||||
|
|
||||||
if int(infoHeader.ID) == rresID {
|
if int(infoHeader.ID) == rresID {
|
||||||
|
data.Type = uint32(infoHeader.DataType)
|
||||||
|
data.Param1 = infoHeader.Param1
|
||||||
|
data.Param2 = infoHeader.Param2
|
||||||
|
data.Param3 = infoHeader.Param3
|
||||||
|
data.Param4 = infoHeader.Param4
|
||||||
|
|
||||||
// Read resource data block
|
// Read resource data block
|
||||||
data = make([]byte, infoHeader.DataSize)
|
b := make([]byte, infoHeader.DataSize)
|
||||||
file.Read(data)
|
reader.Read(b)
|
||||||
|
|
||||||
if infoHeader.CompType == RRESCompDeflate {
|
|
||||||
// Uncompress data
|
// Uncompress data
|
||||||
b := bytes.NewReader(data)
|
switch infoHeader.CompType {
|
||||||
r := flate.NewReader(b)
|
case rres.CompNone:
|
||||||
|
data.Data = b
|
||||||
|
case rres.CompDeflate:
|
||||||
|
r := flate.NewReader(bytes.NewReader(b))
|
||||||
|
|
||||||
data = make([]byte, infoHeader.UncompSize)
|
u := make([]byte, infoHeader.UncompSize)
|
||||||
r.Read(data)
|
r.Read(u)
|
||||||
|
|
||||||
|
data.Data = u
|
||||||
|
|
||||||
|
r.Close()
|
||||||
|
case rres.CompLZ4:
|
||||||
|
r := lz4.NewReader(bytes.NewReader(b))
|
||||||
|
|
||||||
|
u := make([]byte, infoHeader.UncompSize)
|
||||||
|
r.Read(u)
|
||||||
|
|
||||||
|
data.Data = u
|
||||||
|
case rres.CompLZMA2:
|
||||||
|
r, err := xz.NewReader(bytes.NewReader(b))
|
||||||
|
if err != nil {
|
||||||
|
TraceLog(LogWarning, "[ID %d] %v", infoHeader.ID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(data) > 0 {
|
u := make([]byte, infoHeader.UncompSize)
|
||||||
TraceLog(LogInfo, "[%s][ID %d] Resource data loaded successfully", fileName, infoHeader.ID)
|
r.Read(u)
|
||||||
|
|
||||||
|
data.Data = u
|
||||||
|
case rres.CompBZIP2:
|
||||||
|
r, err := bzip2.NewReader(bytes.NewReader(b), &bzip2.ReaderConfig{})
|
||||||
|
if err != nil {
|
||||||
|
TraceLog(LogWarning, "[ID %d] %v", infoHeader.ID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
u := make([]byte, infoHeader.UncompSize)
|
||||||
|
r.Read(u)
|
||||||
|
|
||||||
|
data.Data = u
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrypt data
|
||||||
|
switch infoHeader.CryptoType {
|
||||||
|
case rres.CryptoXOR:
|
||||||
|
c, err := encrypt.NewXor(string(key))
|
||||||
|
if err != nil {
|
||||||
|
TraceLog(LogWarning, "[ID %d] %v", infoHeader.ID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b := c.Encode(data.Data)
|
||||||
|
data.Data = b
|
||||||
|
case rres.CryptoAES:
|
||||||
|
b, err := decryptAES(key, data.Data)
|
||||||
|
if err != nil {
|
||||||
|
TraceLog(LogWarning, "[ID %d] %v", infoHeader.ID, err)
|
||||||
|
}
|
||||||
|
data.Data = b
|
||||||
|
case rres.Crypto3DES:
|
||||||
|
b, err := decrypt3DES(key, data.Data)
|
||||||
|
if err != nil {
|
||||||
|
TraceLog(LogWarning, "[ID %d] %v", infoHeader.ID, err)
|
||||||
|
}
|
||||||
|
data.Data = b
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.Data != nil {
|
||||||
|
TraceLog(LogInfo, "[ID %d] Resource data loaded successfully", infoHeader.ID)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Skip required data to read next resource infoHeader
|
// Skip required data to read next resource infoHeader
|
||||||
file.Seek(int64(infoHeader.DataSize), os.SEEK_CUR)
|
reader.Seek(int64(infoHeader.DataSize), os.SEEK_CUR)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(data) == 0 {
|
if data.Data == nil {
|
||||||
TraceLog(LogInfo, "[%s][ID %d] Requested resource could not be found", fileName, rresID)
|
TraceLog(LogInfo, "[ID %d] Requested resource could not be found", rresID)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unpad
|
||||||
|
func unpad(src []byte) ([]byte, error) {
|
||||||
|
length := len(src)
|
||||||
|
unpadding := int(src[length-1])
|
||||||
|
|
||||||
|
if unpadding > length {
|
||||||
|
return nil, fmt.Errorf("unpad error. This can happen when incorrect encryption key is used.")
|
||||||
|
}
|
||||||
|
|
||||||
|
return src[:(length - unpadding)], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// decryptAES
|
||||||
|
func decryptAES(key, text []byte) ([]byte, error) {
|
||||||
|
block, err := aes.NewCipher(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len(text) % aes.BlockSize) != 0 {
|
||||||
|
return nil, fmt.Errorf("blocksize must be multiple of decoded message length")
|
||||||
|
}
|
||||||
|
|
||||||
|
iv := text[:aes.BlockSize]
|
||||||
|
msg := text[aes.BlockSize:]
|
||||||
|
|
||||||
|
cfb := cipher.NewCFBDecrypter(block, iv)
|
||||||
|
cfb.XORKeyStream(msg, msg)
|
||||||
|
|
||||||
|
unpadMsg, err := unpad(msg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return unpadMsg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// decrypt3DES
|
||||||
|
func decrypt3DES(key, text []byte) ([]byte, error) {
|
||||||
|
block, err := des.NewCipher(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len(text) % des.BlockSize) != 0 {
|
||||||
|
return nil, fmt.Errorf("blocksize must be multiple of decoded message length")
|
||||||
|
}
|
||||||
|
|
||||||
|
iv := text[:des.BlockSize]
|
||||||
|
msg := text[des.BlockSize:]
|
||||||
|
|
||||||
|
cbc := cipher.NewCBCDecrypter(block, iv)
|
||||||
|
cbc.CryptBlocks(msg, msg)
|
||||||
|
|
||||||
|
unpadMsg, err := unpad(msg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return unpadMsg, nil
|
||||||
|
}
|
||||||
|
|
3
rres/README.md
Normal file
3
rres/README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
## rres [](https://godoc.org/github.com/gen2brain/raylib-go/rres)
|
||||||
|
|
||||||
|
raylib resources.
|
25
rres/cmd/rrem/README.md
Normal file
25
rres/cmd/rrem/README.md
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
## rrem
|
||||||
|
|
||||||
|
rREM - raylib Resource EMbedder.
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
Usage of ./rrem:
|
||||||
|
-base string
|
||||||
|
Resources file basename (default "data")
|
||||||
|
-bin
|
||||||
|
Generate Go bindata (.go file)
|
||||||
|
-comp int
|
||||||
|
Compression type, 0=None, 1=Deflate, 2=LZ4, 5=LZMA2 (XZ), 6=BZIP2 (default 5)
|
||||||
|
-enc int
|
||||||
|
Encryption type, 0=None, 1=XOR, 2=AES, 3=3DES
|
||||||
|
-header
|
||||||
|
Generate C header (.h file)
|
||||||
|
-key string
|
||||||
|
Encryption key
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
[Example](https://github.com/gen2brain/raylib-go/tree/master/examples/others/resources).
|
453
rres/cmd/rrem/main.go
Normal file
453
rres/cmd/rrem/main.go
Normal file
|
@ -0,0 +1,453 @@
|
||||||
|
// rREM - raylib Resource EMbedder
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
|
"crypto/des"
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/binary"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/draw"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
_ "image/gif"
|
||||||
|
_ "image/jpeg"
|
||||||
|
_ "image/png"
|
||||||
|
|
||||||
|
"github.com/blezek/tga"
|
||||||
|
_ "github.com/jbuchbinder/gopnm"
|
||||||
|
_ "golang.org/x/image/bmp"
|
||||||
|
|
||||||
|
"github.com/dsnet/compress/bzip2"
|
||||||
|
"github.com/jfreymuth/oggvorbis"
|
||||||
|
"github.com/jteeuwen/go-bindata"
|
||||||
|
"github.com/klauspost/compress/flate"
|
||||||
|
"github.com/moutend/go-wav"
|
||||||
|
"github.com/pierrec/lz4"
|
||||||
|
"github.com/rootlch/encrypt"
|
||||||
|
"github.com/ulikunitz/xz"
|
||||||
|
|
||||||
|
"github.com/gen2brain/raylib-go/rres"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
tga.RegisterFormat()
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
base := flag.String("base", "data", "Resources file basename")
|
||||||
|
comp := flag.Int("comp", rres.CompLZMA2, "Compression type, 0=None, 1=Deflate, 2=LZ4, 5=LZMA2 (XZ), 6=BZIP2")
|
||||||
|
enc := flag.Int("enc", rres.CryptoNone, "Encryption type, 0=None, 1=XOR, 2=AES, 3=3DES")
|
||||||
|
key := flag.String("key", "", "Encryption key")
|
||||||
|
header := flag.Bool("header", false, "Generate C header (.h file)")
|
||||||
|
bin := flag.Bool("bin", false, "Generate Go bindata (.go file)")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if len(flag.Args()) == 0 {
|
||||||
|
flag.Usage()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch *comp {
|
||||||
|
case rres.CompNone:
|
||||||
|
case rres.CompDeflate:
|
||||||
|
case rres.CompLZ4:
|
||||||
|
case rres.CompLZMA2:
|
||||||
|
case rres.CompBZIP2:
|
||||||
|
default:
|
||||||
|
fmt.Printf("compression type %d not implemented\n", *comp)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch *enc {
|
||||||
|
case rres.CryptoNone:
|
||||||
|
case rres.CryptoXOR:
|
||||||
|
case rres.CryptoAES:
|
||||||
|
case rres.Crypto3DES:
|
||||||
|
default:
|
||||||
|
fmt.Printf("encryption type %d not implemented\n", *enc)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *enc != 0 {
|
||||||
|
if *key == "" {
|
||||||
|
fmt.Printf("encryption requires key (-k)\n")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if len(*key) != 16 && len(*key) != 24 {
|
||||||
|
fmt.Printf("wrong key length, it should be 16 or 24\n")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rresFile, err := os.Create(fmt.Sprintf("%s.rres", *base))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer rresFile.Close()
|
||||||
|
|
||||||
|
var headerFile *os.File
|
||||||
|
if *header {
|
||||||
|
headerFile, err = os.Create(fmt.Sprintf("%s.h", *base))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer headerFile.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileHeader rres.FileHeader
|
||||||
|
|
||||||
|
// "rRES" identifier
|
||||||
|
copy(fileHeader.ID[:], "rRES")
|
||||||
|
fileHeader.Count = uint16(len(flag.Args()))
|
||||||
|
fileHeader.Version = 1
|
||||||
|
|
||||||
|
// Write file header
|
||||||
|
err = binary.Write(rresFile, binary.LittleEndian, &fileHeader)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
rresFile.Seek(int64(unsafe.Sizeof(fileHeader)), os.SEEK_CUR)
|
||||||
|
|
||||||
|
if *header {
|
||||||
|
// Write C header file
|
||||||
|
_, err = headerFile.Write([]byte(fmt.Sprintf("#define NUM_RESOURCES %d\n\n", flag.NArg())))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for id, filename := range flag.Args() {
|
||||||
|
var data []byte
|
||||||
|
var infoHeader rres.InfoHeader
|
||||||
|
|
||||||
|
file, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%s: %v\n", filename, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err = ioutil.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%s: %v\n", filename, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
file.Close()
|
||||||
|
|
||||||
|
infoHeader.ID = uint32(id)
|
||||||
|
infoHeader.CompType = uint8(*comp)
|
||||||
|
infoHeader.CryptoType = uint8(*enc)
|
||||||
|
infoHeader.DataType = uint8(fileType(filename))
|
||||||
|
infoHeader.PartsCount = uint8(1)
|
||||||
|
|
||||||
|
// Params
|
||||||
|
switch infoHeader.DataType {
|
||||||
|
case rres.TypeImage:
|
||||||
|
img, _, err := image.Decode(bytes.NewReader(data))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%s: %v\n", filename, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
rect := img.Bounds()
|
||||||
|
width, height := rect.Dx(), rect.Dy()
|
||||||
|
|
||||||
|
infoHeader.Param1 = uint32(width)
|
||||||
|
infoHeader.Param2 = uint32(height)
|
||||||
|
|
||||||
|
switch img.ColorModel() {
|
||||||
|
case color.GrayModel:
|
||||||
|
infoHeader.Param3 = rres.ImUncompGrayscale
|
||||||
|
|
||||||
|
i := image.NewGray(rect)
|
||||||
|
draw.Draw(i, rect, img, rect.Min, draw.Src)
|
||||||
|
data = i.Pix
|
||||||
|
case color.Gray16Model:
|
||||||
|
infoHeader.Param3 = rres.ImUncompGrayAlpha
|
||||||
|
|
||||||
|
i := image.NewGray16(rect)
|
||||||
|
draw.Draw(i, rect, img, rect.Min, draw.Src)
|
||||||
|
data = i.Pix
|
||||||
|
default:
|
||||||
|
infoHeader.Param3 = rres.ImUncompR8g8b8a8
|
||||||
|
|
||||||
|
i := image.NewNRGBA(rect)
|
||||||
|
draw.Draw(i, rect, img, rect.Min, draw.Src)
|
||||||
|
data = i.Pix
|
||||||
|
}
|
||||||
|
|
||||||
|
case rres.TypeWave:
|
||||||
|
a := &wav.File{}
|
||||||
|
err := wav.Unmarshal(data, a)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%s: %v\n", filename, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err = ioutil.ReadAll(a)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%s: %v\n", filename, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
infoHeader.Param1 = uint32(a.Samples())
|
||||||
|
infoHeader.Param2 = uint32(a.SamplesPerSec())
|
||||||
|
infoHeader.Param3 = uint32(a.BitsPerSample())
|
||||||
|
infoHeader.Param4 = uint32(a.Channels())
|
||||||
|
case rres.TypeVorbis:
|
||||||
|
r, err := oggvorbis.NewReader(bytes.NewReader(data))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%s: %v\n", filename, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d, _, err := oggvorbis.ReadAll(bytes.NewReader(data))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%s: %v\n", filename, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert []float32 to []byte
|
||||||
|
header := *(*reflect.SliceHeader)(unsafe.Pointer(&d))
|
||||||
|
header.Len *= 4
|
||||||
|
header.Cap *= 4
|
||||||
|
data = *(*[]byte)(unsafe.Pointer(&header))
|
||||||
|
|
||||||
|
infoHeader.Param1 = uint32(r.SampleRate())
|
||||||
|
infoHeader.Param2 = uint32(r.Bitrate().Nominal)
|
||||||
|
infoHeader.Param3 = uint32(r.Channels())
|
||||||
|
case rres.TypeVertex:
|
||||||
|
// TODO https://github.com/sheenobu/go-obj
|
||||||
|
case rres.TypeText, rres.TypeRaw:
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encryption
|
||||||
|
switch infoHeader.CryptoType {
|
||||||
|
case rres.CryptoXOR:
|
||||||
|
c, err := encrypt.NewXor(*key)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b := c.Encode(data)
|
||||||
|
data = b
|
||||||
|
case rres.CryptoAES:
|
||||||
|
b, err := encryptAES([]byte(*key), data)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
data = b
|
||||||
|
case rres.Crypto3DES:
|
||||||
|
b, err := encrypt3DES([]byte(*key), data)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
data = b
|
||||||
|
}
|
||||||
|
|
||||||
|
infoHeader.UncompSize = uint32(len(data))
|
||||||
|
|
||||||
|
// Compression
|
||||||
|
switch infoHeader.CompType {
|
||||||
|
case rres.CompNone:
|
||||||
|
infoHeader.DataSize = uint32(len(data))
|
||||||
|
case rres.CompDeflate:
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
|
w, err := flate.NewWriter(buf, flate.BestCompression)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = w.Write(data)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Close()
|
||||||
|
|
||||||
|
infoHeader.DataSize = uint32(len(buf.Bytes()))
|
||||||
|
data = buf.Bytes()
|
||||||
|
case rres.CompLZ4:
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
|
w := lz4.NewWriter(buf)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = w.Write(data)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Close()
|
||||||
|
|
||||||
|
infoHeader.DataSize = uint32(len(buf.Bytes()))
|
||||||
|
data = buf.Bytes()
|
||||||
|
case rres.CompLZMA2:
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
|
w, err := xz.NewWriter(buf)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = w.Write(data)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Close()
|
||||||
|
|
||||||
|
infoHeader.DataSize = uint32(len(buf.Bytes()))
|
||||||
|
data = buf.Bytes()
|
||||||
|
case rres.CompBZIP2:
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
|
w, err := bzip2.NewWriter(buf, &bzip2.WriterConfig{Level: bzip2.BestCompression})
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = w.Write(data)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Close()
|
||||||
|
|
||||||
|
infoHeader.DataSize = uint32(len(buf.Bytes()))
|
||||||
|
data = buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write resource info and parameters
|
||||||
|
err = binary.Write(rresFile, binary.LittleEndian, &infoHeader)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rresFile.Seek(int64(unsafe.Sizeof(infoHeader)), os.SEEK_CUR)
|
||||||
|
|
||||||
|
// Write resource data
|
||||||
|
_, err = rresFile.Write(data)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var typeName string
|
||||||
|
switch infoHeader.DataType {
|
||||||
|
case rres.TypeImage:
|
||||||
|
typeName = "IMAGE"
|
||||||
|
case rres.TypeWave:
|
||||||
|
typeName = "WAVE"
|
||||||
|
case rres.TypeVorbis:
|
||||||
|
typeName = "VORBIS"
|
||||||
|
case rres.TypeText:
|
||||||
|
typeName = "TEXT"
|
||||||
|
default:
|
||||||
|
typeName = "RAW"
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%s %d // Embedded as %s\n", filepath.Base(filename), id, typeName)
|
||||||
|
|
||||||
|
if *header {
|
||||||
|
headerFile.Write([]byte(fmt.Sprintf("#define RES_%s 0x%08x\t\t// Embedded as %s\n", filepath.Base(filename), id, typeName)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate bindata
|
||||||
|
if *bin {
|
||||||
|
cfg := bindata.NewConfig()
|
||||||
|
cfg.NoCompress = true
|
||||||
|
cfg.Output = fmt.Sprintf("%s.go", *base)
|
||||||
|
cfg.Input = make([]bindata.InputConfig, 1)
|
||||||
|
cfg.Input[0] = bindata.InputConfig{Path: fmt.Sprintf("%s.rres", *base), Recursive: false}
|
||||||
|
|
||||||
|
err := bindata.Translate(cfg)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fileType returns resource file type
|
||||||
|
func fileType(f string) int {
|
||||||
|
switch strings.ToLower(filepath.Ext(f)) {
|
||||||
|
case ".jpg", ".jpeg", ".png", ".bmp", ".tga", ".gif":
|
||||||
|
return rres.TypeImage
|
||||||
|
case ".txt", ".csv", ".info", ".md":
|
||||||
|
return rres.TypeText
|
||||||
|
case ".wav":
|
||||||
|
return rres.TypeWave
|
||||||
|
case ".ogg":
|
||||||
|
return rres.TypeVorbis
|
||||||
|
case ".obj":
|
||||||
|
return rres.TypeVertex
|
||||||
|
default:
|
||||||
|
return rres.TypeRaw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pad to block size
|
||||||
|
func pad(src []byte, blockSize int) []byte {
|
||||||
|
padding := blockSize - len(src)%blockSize
|
||||||
|
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
|
||||||
|
return append(src, padtext...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// encryptAES
|
||||||
|
func encryptAES(key, text []byte) ([]byte, error) {
|
||||||
|
block, err := aes.NewCipher(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := pad(text, aes.BlockSize)
|
||||||
|
ciphertext := make([]byte, aes.BlockSize+len(msg))
|
||||||
|
iv := ciphertext[:aes.BlockSize]
|
||||||
|
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cfb := cipher.NewCFBEncrypter(block, iv)
|
||||||
|
cfb.XORKeyStream(ciphertext[aes.BlockSize:], msg)
|
||||||
|
|
||||||
|
return ciphertext, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// encrypt3DES
|
||||||
|
func encrypt3DES(key, text []byte) ([]byte, error) {
|
||||||
|
block, err := des.NewTripleDESCipher([]byte(key))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := pad(text, des.BlockSize)
|
||||||
|
ciphertext := make([]byte, des.BlockSize+len(msg))
|
||||||
|
iv := ciphertext[:des.BlockSize]
|
||||||
|
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cbc := cipher.NewCBCEncrypter(block, iv)
|
||||||
|
cbc.CryptBlocks(ciphertext[des.BlockSize:], msg)
|
||||||
|
|
||||||
|
return ciphertext, nil
|
||||||
|
}
|
163
rres/rres.go
Normal file
163
rres/rres.go
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
package rres
|
||||||
|
|
||||||
|
type Data struct {
|
||||||
|
// Resource type (4 byte)
|
||||||
|
Type uint32
|
||||||
|
|
||||||
|
// Resource parameter 1 (4 byte)
|
||||||
|
Param1 uint32
|
||||||
|
// Resource parameter 2 (4 byte)
|
||||||
|
Param2 uint32
|
||||||
|
// Resource parameter 3 (4 byte)
|
||||||
|
Param3 uint32
|
||||||
|
// Resource parameter 4 (4 byte)
|
||||||
|
Param4 uint32
|
||||||
|
|
||||||
|
// Resource data
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileHeader - rRES file header (8 byte)
|
||||||
|
type FileHeader struct {
|
||||||
|
// File identifier: rRES (4 byte)
|
||||||
|
ID [4]byte
|
||||||
|
// File version and subversion (2 byte)
|
||||||
|
Version uint16
|
||||||
|
// Number of resources in this file (2 byte)
|
||||||
|
Count uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// InfoHeader - rRES info header, every resource includes this header (16 byte + 16 byte)
|
||||||
|
type InfoHeader struct {
|
||||||
|
// Resource unique identifier (4 byte)
|
||||||
|
ID uint32
|
||||||
|
// Resource data type (1 byte)
|
||||||
|
DataType uint8
|
||||||
|
// Resource data compression type (1 byte)
|
||||||
|
CompType uint8
|
||||||
|
// Resource data encryption type (1 byte)
|
||||||
|
CryptoType uint8
|
||||||
|
// Resource data parts count, used for splitted data (1 byte)
|
||||||
|
PartsCount uint8
|
||||||
|
// Resource data size (compressed or not, only DATA) (4 byte)
|
||||||
|
DataSize uint32
|
||||||
|
// Resource data size (uncompressed, only DATA) (4 byte)
|
||||||
|
UncompSize uint32
|
||||||
|
// Resource parameter 1 (4 byte)
|
||||||
|
Param1 uint32
|
||||||
|
// Resource parameter 2 (4 byte)
|
||||||
|
Param2 uint32
|
||||||
|
// Resource parameter 3 (4 byte)
|
||||||
|
Param3 uint32
|
||||||
|
// Resource parameter 4 (4 byte)
|
||||||
|
Param4 uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// rRES data types
|
||||||
|
const (
|
||||||
|
TypeRaw = iota
|
||||||
|
TypeImage
|
||||||
|
TypeWave
|
||||||
|
TypeVertex
|
||||||
|
TypeText
|
||||||
|
TypeFontImage
|
||||||
|
TypeFontCharData
|
||||||
|
TypeDirectory
|
||||||
|
TypeVorbis
|
||||||
|
)
|
||||||
|
|
||||||
|
// Compression types
|
||||||
|
const (
|
||||||
|
// No data compression
|
||||||
|
CompNone = iota
|
||||||
|
// DEFLATE compression
|
||||||
|
CompDeflate
|
||||||
|
// LZ4 compression
|
||||||
|
CompLZ4
|
||||||
|
// LZMA compression
|
||||||
|
CompLZMA
|
||||||
|
// BROTLI compression
|
||||||
|
CompBrotli
|
||||||
|
// LZMA2 (XZ) compression
|
||||||
|
CompLZMA2
|
||||||
|
// BZIP2 compression
|
||||||
|
CompBZIP2
|
||||||
|
)
|
||||||
|
|
||||||
|
// Encryption types
|
||||||
|
const (
|
||||||
|
// No data encryption
|
||||||
|
CryptoNone = iota
|
||||||
|
// XOR (128 bit) encryption
|
||||||
|
CryptoXOR
|
||||||
|
// RIJNDAEL (128 bit) encryption (AES)
|
||||||
|
CryptoAES
|
||||||
|
// Triple DES encryption
|
||||||
|
Crypto3DES
|
||||||
|
// Blowfish encryption
|
||||||
|
CryptoBlowfish
|
||||||
|
// Extended TEA encryption
|
||||||
|
CryptoXTEA
|
||||||
|
)
|
||||||
|
|
||||||
|
// Image formats
|
||||||
|
const (
|
||||||
|
// 8 bit per pixel (no alpha)
|
||||||
|
ImUncompGrayscale = iota + 1
|
||||||
|
// 16 bpp (2 channels)
|
||||||
|
ImUncompGrayAlpha
|
||||||
|
// 16 bpp
|
||||||
|
ImUncompR5g6b5
|
||||||
|
// 24 bpp
|
||||||
|
ImUncompR8g8b8
|
||||||
|
// 16 bpp (1 bit alpha)
|
||||||
|
ImUncompR5g5b5a1
|
||||||
|
// 16 bpp (4 bit alpha)
|
||||||
|
ImUncompR4g4b4a4
|
||||||
|
// 32 bpp
|
||||||
|
ImUncompR8g8b8a8
|
||||||
|
// 4 bpp (no alpha)
|
||||||
|
ImCompDxt1Rgb
|
||||||
|
// 4 bpp (1 bit alpha)
|
||||||
|
ImCompDxt1Rgba
|
||||||
|
// 8 bpp
|
||||||
|
ImCompDxt3Rgba
|
||||||
|
// 8 bpp
|
||||||
|
ImCompDxt5Rgba
|
||||||
|
// 4 bpp
|
||||||
|
ImCompEtc1Rgb
|
||||||
|
// 4 bpp
|
||||||
|
ImCompEtc2Rgb
|
||||||
|
// 8 bpp
|
||||||
|
ImCompEtc2EacRgba
|
||||||
|
// 4 bpp
|
||||||
|
ImCompPvrtRgb
|
||||||
|
// 4 bpp
|
||||||
|
ImCompPvrtRgba
|
||||||
|
// 8 bpp
|
||||||
|
ImCompAstc4x4Rgba
|
||||||
|
// 2 bpp
|
||||||
|
ImCompAstc8x8Rgba
|
||||||
|
)
|
||||||
|
|
||||||
|
// Vert
|
||||||
|
const (
|
||||||
|
VertPosition = iota
|
||||||
|
VertTexcoord1
|
||||||
|
VertTexcoord2
|
||||||
|
VertTexcoord3
|
||||||
|
VertTexcoord4
|
||||||
|
VertNormal
|
||||||
|
VertTangent
|
||||||
|
VertColor
|
||||||
|
VertIndex
|
||||||
|
)
|
||||||
|
|
||||||
|
// Vert
|
||||||
|
const (
|
||||||
|
VertByte = iota
|
||||||
|
VertShort
|
||||||
|
VertInt
|
||||||
|
VertHfloat
|
||||||
|
VertFloat
|
||||||
|
)
|
Loading…
Add table
Add a link
Reference in a new issue