Update C sources
This commit is contained in:
parent
02424e2e10
commit
bd6bf15356
53 changed files with 62247 additions and 9914 deletions
|
@ -39,7 +39,7 @@ func main() {
|
|||
|
||||
for !rl.WindowShouldClose() {
|
||||
// Refill audio stream if required
|
||||
if rl.IsAudioBufferProcessed(stream) {
|
||||
if rl.IsAudioStreamProcessed(stream) {
|
||||
numSamples := int32(0)
|
||||
if samplesLeft >= maxSamplesPerUpdate {
|
||||
numSamples = maxSamplesPerUpdate
|
||||
|
|
|
@ -38,19 +38,17 @@ func main() {
|
|||
|
||||
camera := rl.Camera2D{}
|
||||
camera.Target = rl.NewVector2(float32(player.X+20), float32(player.Y+20))
|
||||
camera.Offset = rl.NewVector2(0, 0)
|
||||
camera.Offset = rl.NewVector2(float32(screenWidth/2), float32(screenHeight/2))
|
||||
camera.Rotation = 0.0
|
||||
camera.Zoom = 1.0
|
||||
|
||||
rl.SetTargetFPS(30)
|
||||
rl.SetTargetFPS(60)
|
||||
|
||||
for !rl.WindowShouldClose() {
|
||||
if rl.IsKeyDown(rl.KeyRight) {
|
||||
player.X += 2 // Player movement
|
||||
camera.Offset.X -= 2 // Camera displacement with player movement
|
||||
player.X += 2 // Player movement
|
||||
} else if rl.IsKeyDown(rl.KeyLeft) {
|
||||
player.X -= 2 // Player movement
|
||||
camera.Offset.X += 2 // Camera displacement with player movement
|
||||
player.X -= 2 // Player movement
|
||||
}
|
||||
|
||||
// Camera target follows player
|
||||
|
|
|
@ -5,17 +5,19 @@ import (
|
|||
)
|
||||
|
||||
func main() {
|
||||
hmd := rl.GetVrDeviceInfo(rl.HmdOculusRiftCv1) // Oculus Rift CV1
|
||||
rl.InitWindow(int32(hmd.HScreenSize), int32(hmd.VScreenSize), "raylib [core] example - vr simulator")
|
||||
//hmd := rl.GetVrDeviceInfo(rl.HmdOculusRiftCv1) // Oculus Rift CV1
|
||||
//rl.InitWindow(int32(hmd.HScreenSize), int32(hmd.VScreenSize), "raylib [core] example - vr simulator")
|
||||
rl.InitWindow(800, 450, "raylib [core] example - vr simulator")
|
||||
|
||||
// NOTE: default device (simulator)
|
||||
rl.InitVrSimulator(hmd) // Init VR device
|
||||
//rl.InitVrSimulator(hmd) // Init VR device
|
||||
rl.InitVrSimulator() // Init VR device
|
||||
|
||||
camera := rl.Camera{}
|
||||
camera.Position = rl.NewVector3(5.0, 2.0, 5.0) // Camera position
|
||||
camera.Target = rl.NewVector3(0.0, 2.0, 0.0) // Camera looking at point
|
||||
camera.Up = rl.NewVector3(0.0, 1.0, 0.0) // Camera up vector (rotation towards target)
|
||||
camera.Fovy = 60.0 // Camera field-of-view Y
|
||||
camera.Fovy = 60.0 // Camera field-of-view Y
|
||||
|
||||
cubePosition := rl.NewVector3(0.0, 0.0, 0.0)
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
|
@ -21,11 +23,14 @@ func main() {
|
|||
cubicmap := rl.LoadTextureFromImage(image) // Convert image to texture to display (VRAM)
|
||||
|
||||
mesh := rl.GenMeshCubicmap(*image, rl.NewVector3(1.0, 1.0, 1.0))
|
||||
fmt.Printf("%+v\n", mesh)
|
||||
|
||||
model := rl.LoadModelFromMesh(mesh)
|
||||
|
||||
// NOTE: By default each cube is mapped to one part of texture atlas
|
||||
texture := rl.LoadTexture("cubicmap_atlas.png") // Load map texture
|
||||
model.Material.Maps[rl.MapDiffuse].Texture = texture // Set map diffuse texture
|
||||
texture := rl.LoadTexture("cubicmap_atlas.png") // Load map texture
|
||||
model.Materials = make([]rl.Material, 1)
|
||||
model.Materials[0].Maps[rl.MapDiffuse].Texture = texture // Set map diffuse texture
|
||||
|
||||
mapPosition := rl.NewVector3(-16.0, 0.0, -8.0) // Set model position
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
//"fmt"
|
||||
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
|
@ -20,10 +22,12 @@ func main() {
|
|||
texture := rl.LoadTextureFromImage(image) // Convert image to texture (VRAM)
|
||||
|
||||
mesh := rl.GenMeshHeightmap(*image, rl.NewVector3(16, 8, 16)) // Generate heightmap mesh (RAM and VRAM)
|
||||
model := rl.LoadModelFromMesh(mesh) // Load model from generated mesh
|
||||
|
||||
model.Material.Maps[rl.MapDiffuse].Texture = texture // Set map diffuse texture
|
||||
mapPosition := rl.NewVector3(-8.0, 0.0, -8.0) // Set model position
|
||||
//fmt.Printf("%+v\n", mesh)
|
||||
model := rl.LoadModelFromMesh(mesh) // Load model from generated mesh
|
||||
//fmt.Printf("%+v\n", model)
|
||||
model.Materials = make([]rl.Material, 1)
|
||||
model.Materials[0].Maps[rl.MapDiffuse].Texture = texture // Set map diffuse texture
|
||||
mapPosition := rl.NewVector3(-8.0, 0.0, -8.0) // Set model position
|
||||
|
||||
rl.UnloadImage(image) // Unload heightmap image from RAM, already uploaded to VRAM
|
||||
|
||||
|
|
|
@ -19,7 +19,8 @@ func main() {
|
|||
dwarf := rl.LoadModel("dwarf.obj") // Load OBJ model
|
||||
texture := rl.LoadTexture("dwarf_diffuse.png") // Load model texture
|
||||
|
||||
dwarf.Material.Maps[rl.MapDiffuse].Texture = texture // Set dwarf model diffuse texture
|
||||
dwarf.Materials = make([]rl.Material, 1)
|
||||
dwarf.Materials[0].Maps[rl.MapDiffuse].Texture = texture // Set dwarf model diffuse texture
|
||||
|
||||
position := rl.NewVector3(0.0, 0.0, 0.0) // Set model position
|
||||
|
||||
|
|
|
@ -29,10 +29,10 @@ func main() {
|
|||
//b := MustAsset("data.rres")
|
||||
//reader := bytes.NewReader(b)
|
||||
|
||||
res := rres.LoadResource(reader, 0, []byte("passwordpassword"))
|
||||
wav := rl.LoadWaveEx(res.Data, int32(res.Param1), int32(res.Param2), int32(res.Param3), int32(res.Param4))
|
||||
snd := rl.LoadSoundFromWave(wav)
|
||||
rl.UnloadWave(wav)
|
||||
//res := rres.LoadResource(reader, 0, []byte("passwordpassword"))
|
||||
//wav := rl.LoadWaveEx(res.Data, int32(res.Param1), int32(res.Param2), int32(res.Param3), int32(res.Param4))
|
||||
//snd := rl.LoadSoundFromWave(wav)
|
||||
//rl.UnloadWave(wav)
|
||||
|
||||
textures := make([]rl.Texture2D, numTextures)
|
||||
for i := 0; i < numTextures; i++ {
|
||||
|
@ -48,7 +48,7 @@ func main() {
|
|||
|
||||
for !rl.WindowShouldClose() {
|
||||
if rl.IsKeyPressed(rl.KeySpace) {
|
||||
rl.PlaySound(snd)
|
||||
//rl.PlaySound(snd)
|
||||
}
|
||||
|
||||
if rl.IsMouseButtonPressed(rl.MouseLeftButton) {
|
||||
|
@ -84,7 +84,7 @@ func main() {
|
|||
rl.EndDrawing()
|
||||
}
|
||||
|
||||
rl.UnloadSound(snd)
|
||||
//rl.UnloadSound(snd)
|
||||
|
||||
for _, t := range textures {
|
||||
rl.UnloadTexture(t)
|
||||
|
|
|
@ -21,7 +21,8 @@ func main() {
|
|||
dwarf := rl.LoadModel("dwarf.obj") // Load OBJ model
|
||||
texture := rl.LoadTexture("dwarf_diffuse.png") // Load model texture
|
||||
|
||||
dwarf.Material.Maps[rl.MapDiffuse].Texture = texture // Set dwarf model diffuse texture
|
||||
dwarf.Materials = make([]rl.Material, 1)
|
||||
dwarf.Materials[0].Maps[rl.MapDiffuse].Texture = texture // Set dwarf model diffuse texture
|
||||
|
||||
position := rl.NewVector3(0.0, 0.0, 0.0) // Set model position
|
||||
|
||||
|
|
|
@ -24,8 +24,9 @@ func main() {
|
|||
texture := rl.LoadTexture("dwarf_diffuse.png") // Load model texture
|
||||
shader := rl.LoadShader("glsl330/base.vs", "glsl330/grayscale.fs") // Load model shader
|
||||
|
||||
dwarf.Material.Shader = shader // Set shader effect to 3d model
|
||||
dwarf.Material.Maps[rl.MapDiffuse].Texture = texture // Set dwarf model diffuse texture
|
||||
dwarf.Materials = make([]rl.Material, 1)
|
||||
dwarf.Materials[0].Shader = shader // Set shader effect to 3d model
|
||||
dwarf.Materials[0].Maps[rl.MapDiffuse].Texture = texture // Set dwarf model diffuse texture
|
||||
|
||||
position := rl.NewVector3(0.0, 0.0, 0.0) // Set model position
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ func main() {
|
|||
fontChars := int32(0)
|
||||
|
||||
// TTF Font loading with custom generation parameters
|
||||
font := rl.LoadFontEx("fonts/KAISG.ttf", 96, 0, &fontChars)
|
||||
font := rl.LoadFontEx("fonts/KAISG.ttf", 96, &fontChars, 0)
|
||||
|
||||
// Generate mipmap levels to use trilinear filtering
|
||||
// NOTE: On 2D drawing it won't be noticeable, it looks like FILTER_BILINEAR
|
||||
|
@ -69,7 +69,7 @@ func main() {
|
|||
|
||||
if count == 1 { // Only support one ttf file dropped
|
||||
rl.UnloadFont(font)
|
||||
font = rl.LoadFontEx(droppedFiles[0], fontSize, 0, &fontChars)
|
||||
font = rl.LoadFontEx(droppedFiles[0], fontSize, &fontChars, 0)
|
||||
rl.ClearDroppedFiles()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,15 +11,15 @@ func main() {
|
|||
rl.InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture loading and drawing")
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
cat := rl.LoadImage("cat.png") // Load image in CPU memory (RAM)
|
||||
cat := rl.LoadImage("cat.png") // Load image in CPU memory (RAM)
|
||||
rl.ImageCrop(cat, rl.NewRectangle(100, 10, 280, 380)) // Crop an image piece
|
||||
rl.ImageFlipHorizontal(cat) // Flip cropped image horizontally
|
||||
rl.ImageResize(cat, 150, 200) // Resize flipped-cropped image
|
||||
rl.ImageFlipHorizontal(cat) // Flip cropped image horizontally
|
||||
rl.ImageResize(cat, 150, 200) // Resize flipped-cropped image
|
||||
|
||||
parrots := rl.LoadImage("parrots.png") // Load image in CPU memory (RAM)
|
||||
|
||||
// Draw one image over the other with a scaling of 1.5f
|
||||
rl.ImageDraw(parrots, cat, rl.NewRectangle(0, 0, float32(cat.Width), float32(cat.Height)), rl.NewRectangle(30, 40, float32(cat.Width)*1.5, float32(cat.Height)*1.5))
|
||||
rl.ImageDraw(parrots, cat, rl.NewRectangle(0, 0, float32(cat.Width), float32(cat.Height)), rl.NewRectangle(30, 40, float32(cat.Width)*1.5, float32(cat.Height)*1.5), rl.White)
|
||||
rl.ImageCrop(parrots, rl.NewRectangle(0, 50, float32(parrots.Width), float32(parrots.Height-100))) // Crop resulting image
|
||||
|
||||
rl.UnloadImage(cat) // Unload image from RAM
|
||||
|
|
|
@ -12,7 +12,7 @@ func main() {
|
|||
|
||||
// TTF Font loading with custom generation parameters
|
||||
var fontChars int32
|
||||
font := rl.LoadFontEx("fonts/KAISG.ttf", 64, 0, &fontChars)
|
||||
font := rl.LoadFontEx("fonts/KAISG.ttf", 64, &fontChars, 0)
|
||||
|
||||
parrots := rl.LoadImage("parrots.png") // Load image in CPU memory (RAM)
|
||||
|
||||
|
|
238
raylib/camera.h
238
raylib/camera.h
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
* #define CAMERA_IMPLEMENTATION
|
||||
* Generates the implementation of the library into the included file.
|
||||
* If not defined, the library is in header only mode and can be included in other headers
|
||||
* If not defined, the library is in header only mode and can be included in other headers
|
||||
* or source files without problems. But only ONE file should hold the implementation.
|
||||
*
|
||||
* #define CAMERA_STANDALONE
|
||||
|
@ -16,13 +16,13 @@
|
|||
* functions must be redefined to manage inputs accordingly.
|
||||
*
|
||||
* CONTRIBUTORS:
|
||||
* Marc Palau: Initial implementation (2014)
|
||||
* Ramon Santamaria: Supervision, review, update and maintenance
|
||||
* Marc Palau: Initial implementation (2014)
|
||||
*
|
||||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
* Copyright (c) 2015-2017 Ramon Santamaria (@raysan5)
|
||||
* Copyright (c) 2015-2019 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
|
@ -54,15 +54,6 @@
|
|||
// NOTE: Below types are required for CAMERA_STANDALONE usage
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(CAMERA_STANDALONE)
|
||||
// Camera modes
|
||||
typedef enum {
|
||||
CAMERA_CUSTOM = 0,
|
||||
CAMERA_FREE,
|
||||
CAMERA_ORBITAL,
|
||||
CAMERA_FIRST_PERSON,
|
||||
CAMERA_THIRD_PERSON
|
||||
} CameraMode;
|
||||
|
||||
// Vector2 type
|
||||
typedef struct Vector2 {
|
||||
float x;
|
||||
|
@ -77,12 +68,30 @@
|
|||
} Vector3;
|
||||
|
||||
// Camera type, defines a camera position/orientation in 3d space
|
||||
typedef struct Camera {
|
||||
Vector3 position;
|
||||
Vector3 target;
|
||||
Vector3 up;
|
||||
float fovy;
|
||||
} Camera;
|
||||
typedef struct Camera3D {
|
||||
Vector3 position; // Camera position
|
||||
Vector3 target; // Camera target it looks-at
|
||||
Vector3 up; // Camera up vector (rotation over its axis)
|
||||
float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic
|
||||
int type; // Camera type, defines projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC
|
||||
} Camera3D;
|
||||
|
||||
typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D
|
||||
|
||||
// Camera system modes
|
||||
typedef enum {
|
||||
CAMERA_CUSTOM = 0,
|
||||
CAMERA_FREE,
|
||||
CAMERA_ORBITAL,
|
||||
CAMERA_FIRST_PERSON,
|
||||
CAMERA_THIRD_PERSON
|
||||
} CameraMode;
|
||||
|
||||
// Camera projection modes
|
||||
typedef enum {
|
||||
CAMERA_PERSPECTIVE = 0,
|
||||
CAMERA_ORTHOGRAPHIC
|
||||
} CameraType;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -103,9 +112,9 @@ void UpdateCamera(Camera *camera); // Update camera pos
|
|||
|
||||
void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera)
|
||||
void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera)
|
||||
void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera)
|
||||
void SetCameraMoveControls(int frontKey, int backKey,
|
||||
int rightKey, int leftKey,
|
||||
void SetCameraSmoothZoomControl(int szoomKey); // Set camera smooth zoom key to combine with mouse (free camera)
|
||||
void SetCameraMoveControls(int frontKey, int backKey,
|
||||
int rightKey, int leftKey,
|
||||
int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras)
|
||||
#endif
|
||||
|
||||
|
@ -124,16 +133,14 @@ void SetCameraMoveControls(int frontKey, int backKey,
|
|||
|
||||
#if defined(CAMERA_IMPLEMENTATION)
|
||||
|
||||
#include <math.h> // Required for: sqrt(), sin(), cos()
|
||||
#include <math.h> // Required for: sqrt(), sinf(), cosf()
|
||||
|
||||
#ifndef PI
|
||||
#define PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#ifndef DEG2RAD
|
||||
#define DEG2RAD (PI/180.0f)
|
||||
#endif
|
||||
|
||||
#ifndef RAD2DEG
|
||||
#define RAD2DEG (180.0f/PI)
|
||||
#endif
|
||||
|
@ -181,21 +188,21 @@ void SetCameraMoveControls(int frontKey, int backKey,
|
|||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// Camera move modes (first person and third person cameras)
|
||||
typedef enum {
|
||||
MOVE_FRONT = 0,
|
||||
MOVE_BACK,
|
||||
MOVE_RIGHT,
|
||||
MOVE_LEFT,
|
||||
MOVE_UP,
|
||||
MOVE_DOWN
|
||||
typedef enum {
|
||||
MOVE_FRONT = 0,
|
||||
MOVE_BACK,
|
||||
MOVE_RIGHT,
|
||||
MOVE_LEFT,
|
||||
MOVE_UP,
|
||||
MOVE_DOWN
|
||||
} CameraMove;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
static Vector2 cameraAngle = { 0.0f, 0.0f }; // TODO: Remove! Compute it in UpdateCamera()
|
||||
static float cameraTargetDistance = 0.0f; // TODO: Remove! Compute it in UpdateCamera()
|
||||
static float playerEyesPosition = 1.85f; // Default player eyes position from ground (in meters)
|
||||
static Vector2 cameraAngle = { 0.0f, 0.0f }; // Camera angle in plane XZ
|
||||
static float cameraTargetDistance = 0.0f; // Camera distance from position to target
|
||||
static float playerEyesPosition = 1.85f; // Default player eyes position from ground (in meters)
|
||||
|
||||
static int cameraMoveControl[6] = { 'W', 'S', 'D', 'A', 'E', 'Q' };
|
||||
static int cameraPanControlKey = 2; // raylib: MOUSE_MIDDLE_BUTTON
|
||||
|
@ -227,36 +234,24 @@ static Vector2 GetMousePosition() { return (Vector2){ 0.0f, 0.0f }; }
|
|||
// Select camera mode (multiple camera modes available)
|
||||
void SetCameraMode(Camera camera, int mode)
|
||||
{
|
||||
// TODO: cameraTargetDistance and cameraAngle should be
|
||||
// calculated using camera parameters on UpdateCamera()
|
||||
|
||||
Vector3 v1 = camera.position;
|
||||
Vector3 v2 = camera.target;
|
||||
|
||||
|
||||
float dx = v2.x - v1.x;
|
||||
float dy = v2.y - v1.y;
|
||||
float dz = v2.z - v1.z;
|
||||
|
||||
|
||||
cameraTargetDistance = sqrtf(dx*dx + dy*dy + dz*dz);
|
||||
|
||||
Vector2 distance = { 0.0f, 0.0f };
|
||||
distance.x = sqrtf(dx*dx + dz*dz);
|
||||
distance.y = sqrtf(dx*dx + dy*dy);
|
||||
|
||||
|
||||
// Camera angle calculation
|
||||
cameraAngle.x = asinf( (float)fabs(dx)/distance.x); // Camera angle in plane XZ (0 aligned with Z, move positive CCW)
|
||||
cameraAngle.y = -asinf( (float)fabs(dy)/distance.y); // Camera angle in plane XY (0 aligned with X, move positive CW)
|
||||
|
||||
// NOTE: Just testing what cameraAngle means
|
||||
//cameraAngle.x = 0.0f*DEG2RAD; // Camera angle in plane XZ (0 aligned with Z, move positive CCW)
|
||||
//cameraAngle.y = -60.0f*DEG2RAD; // Camera angle in plane XY (0 aligned with X, move positive CW)
|
||||
|
||||
cameraAngle.x = atan2f(dx, dz); // Camera angle in plane XZ (0 aligned with Z, move positive CCW)
|
||||
cameraAngle.y = atan2f(dy, sqrtf(dx*dx + dz*dz)); // Camera angle in plane XY (0 aligned with X, move positive CW)
|
||||
|
||||
playerEyesPosition = camera.position.y;
|
||||
|
||||
|
||||
// Lock cursor for first person and third person cameras
|
||||
if ((mode == CAMERA_FIRST_PERSON) ||
|
||||
(mode == CAMERA_THIRD_PERSON)) DisableCursor();
|
||||
else EnableCursor();
|
||||
if ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON)) DisableCursor();
|
||||
else EnableCursor();
|
||||
|
||||
cameraMode = mode;
|
||||
}
|
||||
|
@ -273,24 +268,24 @@ void UpdateCamera(Camera *camera)
|
|||
static Vector2 previousMousePosition = { 0.0f, 0.0f };
|
||||
|
||||
// TODO: Compute cameraTargetDistance and cameraAngle here
|
||||
|
||||
|
||||
// Mouse movement detection
|
||||
Vector2 mousePositionDelta = { 0.0f, 0.0f };
|
||||
Vector2 mousePosition = GetMousePosition();
|
||||
int mouseWheelMove = GetMouseWheelMove();
|
||||
|
||||
|
||||
// Keys input detection
|
||||
bool panKey = IsMouseButtonDown(cameraPanControlKey);
|
||||
bool altKey = IsKeyDown(cameraAltControlKey);
|
||||
bool szoomKey = IsKeyDown(cameraSmoothZoomControlKey);
|
||||
|
||||
|
||||
bool direction[6] = { IsKeyDown(cameraMoveControl[MOVE_FRONT]),
|
||||
IsKeyDown(cameraMoveControl[MOVE_BACK]),
|
||||
IsKeyDown(cameraMoveControl[MOVE_RIGHT]),
|
||||
IsKeyDown(cameraMoveControl[MOVE_LEFT]),
|
||||
IsKeyDown(cameraMoveControl[MOVE_UP]),
|
||||
IsKeyDown(cameraMoveControl[MOVE_DOWN]) };
|
||||
|
||||
|
||||
// TODO: Consider touch inputs for camera
|
||||
|
||||
if (cameraMode != CAMERA_CUSTOM)
|
||||
|
@ -314,7 +309,7 @@ void UpdateCamera(Camera *camera)
|
|||
if (cameraTargetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP;
|
||||
}
|
||||
// Camera looking down
|
||||
// TODO: Review, weird comparisson of cameraTargetDistance == 120.0f?
|
||||
// TODO: Review, weird comparisson of cameraTargetDistance == 120.0f?
|
||||
else if ((camera->position.y > camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
|
||||
{
|
||||
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
|
||||
|
@ -335,7 +330,7 @@ void UpdateCamera(Camera *camera)
|
|||
if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP;
|
||||
}
|
||||
// Camera looking up
|
||||
// TODO: Review, weird comparisson of cameraTargetDistance == 120.0f?
|
||||
// TODO: Review, weird comparisson of cameraTargetDistance == 120.0f?
|
||||
else if ((camera->position.y < camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
|
||||
{
|
||||
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
|
||||
|
@ -380,34 +375,42 @@ void UpdateCamera(Camera *camera)
|
|||
else
|
||||
{
|
||||
// Camera panning
|
||||
camera->target.x += ((mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(cameraAngle.x)*sinf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
|
||||
camera->target.x += ((mousePositionDelta.x*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(cameraAngle.x)*sinf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
|
||||
camera->target.y += ((mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
|
||||
camera->target.z += ((mousePositionDelta.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.x)*sinf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
|
||||
camera->target.z += ((mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.x)*sinf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
|
||||
}
|
||||
}
|
||||
|
||||
// Update camera position with changes
|
||||
camera->position.x = -sinf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.x;
|
||||
camera->position.y = -sinf(cameraAngle.y)*cameraTargetDistance + camera->target.y;
|
||||
camera->position.z = -cosf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.z;
|
||||
} break;
|
||||
case CAMERA_ORBITAL:
|
||||
{
|
||||
cameraAngle.x += CAMERA_ORBITAL_SPEED; // Camera orbit angle
|
||||
cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); // Camera zoom
|
||||
|
||||
|
||||
// Camera distance clamp
|
||||
if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP;
|
||||
|
||||
|
||||
// Update camera position with changes
|
||||
camera->position.x = sinf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.x;
|
||||
camera->position.y = ((cameraAngle.y <= 0.0f)? 1 : -1)*sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y;
|
||||
camera->position.z = cosf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.z;
|
||||
|
||||
} break;
|
||||
case CAMERA_FIRST_PERSON:
|
||||
case CAMERA_THIRD_PERSON:
|
||||
{
|
||||
camera->position.x += (sinf(cameraAngle.x)*direction[MOVE_BACK] -
|
||||
sinf(cameraAngle.x)*direction[MOVE_FRONT] -
|
||||
cosf(cameraAngle.x)*direction[MOVE_LEFT] +
|
||||
cosf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
|
||||
|
||||
|
||||
camera->position.y += (sinf(cameraAngle.y)*direction[MOVE_FRONT] -
|
||||
sinf(cameraAngle.y)*direction[MOVE_BACK] +
|
||||
1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY;
|
||||
|
||||
|
||||
camera->position.z += (cosf(cameraAngle.x)*direction[MOVE_BACK] -
|
||||
cosf(cameraAngle.x)*direction[MOVE_FRONT] +
|
||||
sinf(cameraAngle.x)*direction[MOVE_LEFT] -
|
||||
|
@ -416,63 +419,70 @@ void UpdateCamera(Camera *camera)
|
|||
bool isMoving = false; // Required for swinging
|
||||
|
||||
for (int i = 0; i < 6; i++) if (direction[i]) { isMoving = true; break; }
|
||||
|
||||
|
||||
// Camera orientation calculation
|
||||
cameraAngle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY);
|
||||
cameraAngle.y += (mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY);
|
||||
|
||||
if (cameraMode == CAMERA_THIRD_PERSON)
|
||||
{
|
||||
// Angle clamp
|
||||
if (cameraAngle.y > CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD;
|
||||
else if (cameraAngle.y < CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD;
|
||||
|
||||
// Camera zoom
|
||||
cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
|
||||
// Angle clamp
|
||||
if (cameraAngle.y > CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD;
|
||||
else if (cameraAngle.y < CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD;
|
||||
|
||||
// Camera distance clamp
|
||||
if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP;
|
||||
// Camera is always looking at player
|
||||
camera->target.x = camera->position.x - sinf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
|
||||
camera->target.y = camera->position.y + sinf(cameraAngle.y)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
|
||||
camera->target.z = camera->position.z - cosf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
|
||||
|
||||
// Camera is always looking at player
|
||||
camera->target.x = camera->position.x + CAMERA_THIRD_PERSON_OFFSET.x*cosf(cameraAngle.x) + CAMERA_THIRD_PERSON_OFFSET.z*sinf(cameraAngle.x);
|
||||
camera->target.y = camera->position.y + CAMERA_THIRD_PERSON_OFFSET.y;
|
||||
camera->target.z = camera->position.z + CAMERA_THIRD_PERSON_OFFSET.z*sinf(cameraAngle.x) - CAMERA_THIRD_PERSON_OFFSET.x*sinf(cameraAngle.x);
|
||||
}
|
||||
else // CAMERA_FIRST_PERSON
|
||||
{
|
||||
// Angle clamp
|
||||
if (cameraAngle.y > CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD;
|
||||
else if (cameraAngle.y < CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD;
|
||||
if (isMoving) swingCounter++;
|
||||
|
||||
// Camera is always looking at player
|
||||
camera->target.x = camera->position.x - sinf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
|
||||
camera->target.y = camera->position.y + sinf(cameraAngle.y)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
|
||||
camera->target.z = camera->position.z - cosf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
|
||||
|
||||
if (isMoving) swingCounter++;
|
||||
// Camera position update
|
||||
// NOTE: On CAMERA_FIRST_PERSON player Y-movement is limited to player 'eyes position'
|
||||
camera->position.y = playerEyesPosition - sinf(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER;
|
||||
|
||||
// Camera position update
|
||||
// NOTE: On CAMERA_FIRST_PERSON player Y-movement is limited to player 'eyes position'
|
||||
camera->position.y = playerEyesPosition - sinf(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER;
|
||||
camera->up.x = sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
|
||||
camera->up.z = -sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
|
||||
|
||||
|
||||
} break;
|
||||
case CAMERA_THIRD_PERSON:
|
||||
{
|
||||
camera->position.x += (sinf(cameraAngle.x)*direction[MOVE_BACK] -
|
||||
sinf(cameraAngle.x)*direction[MOVE_FRONT] -
|
||||
cosf(cameraAngle.x)*direction[MOVE_LEFT] +
|
||||
cosf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
|
||||
|
||||
camera->position.y += (sinf(cameraAngle.y)*direction[MOVE_FRONT] -
|
||||
sinf(cameraAngle.y)*direction[MOVE_BACK] +
|
||||
1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY;
|
||||
|
||||
camera->position.z += (cosf(cameraAngle.x)*direction[MOVE_BACK] -
|
||||
cosf(cameraAngle.x)*direction[MOVE_FRONT] +
|
||||
sinf(cameraAngle.x)*direction[MOVE_LEFT] -
|
||||
sinf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
|
||||
|
||||
// Camera orientation calculation
|
||||
cameraAngle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY);
|
||||
cameraAngle.y += (mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY);
|
||||
|
||||
// Angle clamp
|
||||
if (cameraAngle.y > CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD;
|
||||
else if (cameraAngle.y < CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD;
|
||||
|
||||
// Camera zoom
|
||||
cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
|
||||
|
||||
// Camera distance clamp
|
||||
if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP;
|
||||
|
||||
// TODO: It seems camera->position is not correctly updated or some rounding issue makes the camera move straight to camera->target...
|
||||
camera->position.x = sinf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.x;
|
||||
if (cameraAngle.y <= 0.0f) camera->position.y = sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y;
|
||||
else camera->position.y = -sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y;
|
||||
camera->position.z = cosf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.z;
|
||||
|
||||
camera->up.x = sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
|
||||
camera->up.z = -sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Update camera position with changes
|
||||
if ((cameraMode == CAMERA_FREE) ||
|
||||
(cameraMode == CAMERA_ORBITAL) ||
|
||||
(cameraMode == CAMERA_THIRD_PERSON))
|
||||
{
|
||||
// TODO: It seems camera->position is not correctly updated or some rounding issue makes the camera move straight to camera->target...
|
||||
camera->position.x = sinf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.x;
|
||||
if (cameraAngle.y <= 0.0f) camera->position.y = sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y;
|
||||
else camera->position.y = -sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y;
|
||||
camera->position.z = cosf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.z;
|
||||
}
|
||||
}
|
||||
|
||||
// Set camera pan key to combine with mouse movement (free camera)
|
||||
|
@ -482,7 +492,7 @@ void SetCameraPanControl(int panKey) { cameraPanControlKey = panKey; }
|
|||
void SetCameraAltControl(int altKey) { cameraAltControlKey = altKey; }
|
||||
|
||||
// Set camera smooth zoom key to combine with mouse (free camera)
|
||||
void SetCameraSmoothZoomControl(int szKey) { cameraSmoothZoomControlKey = szKey; }
|
||||
void SetCameraSmoothZoomControl(int szoomKey) { cameraSmoothZoomControlKey = szoomKey; }
|
||||
|
||||
// Set camera move controls (1st person and 3rd person cameras)
|
||||
void SetCameraMoveControls(int frontKey, int backKey, int rightKey, int leftKey, int upKey, int downKey)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
* Copyright (c) 2018 Ahmad Fatoum & Ramon Santamaria (@raysan5)
|
||||
* Copyright (c) 2018-2019 Ahmad Fatoum & Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
|
@ -25,7 +25,7 @@
|
|||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#define RAYLIB_VERSION "2.1-dev"
|
||||
#define RAYLIB_VERSION "2.6-dev"
|
||||
|
||||
// Edit to control what features Makefile'd raylib is compiled with
|
||||
#if defined(RAYLIB_CMAKE)
|
||||
|
@ -42,6 +42,10 @@
|
|||
#define SUPPORT_GESTURES_SYSTEM 1
|
||||
// Mouse gestures are directly mapped like touches and processed by gestures system
|
||||
#define SUPPORT_MOUSE_GESTURES 1
|
||||
// Reconfigure standard input to receive key inputs, works with SSH connection.
|
||||
#define SUPPORT_SSH_KEYBOARD_RPI 1
|
||||
// Draw a mouse reference on screen (square cursor box)
|
||||
#define SUPPORT_MOUSE_CURSOR_RPI 1
|
||||
// Use busy wait loop for timing sync, if not defined, a high-resolution timer is setup and used
|
||||
//#define SUPPORT_BUSY_WAIT_LOOP 1
|
||||
// Wait for events passively (sleeping while no events) instead of polling them actively every frame
|
||||
|
@ -50,15 +54,16 @@
|
|||
#define SUPPORT_SCREEN_CAPTURE 1
|
||||
// Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()
|
||||
#define SUPPORT_GIF_RECORDING 1
|
||||
|
||||
// Allow scale all the drawn content to match the high-DPI equivalent size (only PLATFORM_DESKTOP)
|
||||
//#define SUPPORT_HIGH_DPI 1
|
||||
// Support CompressData() and DecompressData() functions
|
||||
#define SUPPORT_COMPRESSION_API 1
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: rlgl - Configuration Flags
|
||||
//------------------------------------------------------------------------------------
|
||||
// Support VR simulation functionality (stereo rendering)
|
||||
#define SUPPORT_VR_SIMULATOR 1
|
||||
// Include stereo rendering distortion shader (shader_distortion.h)
|
||||
#define SUPPORT_DISTORTION_SHADER 1
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
@ -66,10 +71,10 @@
|
|||
//------------------------------------------------------------------------------------
|
||||
// Draw rectangle shapes using font texture white character instead of default white texture
|
||||
// Allows drawing rectangles and text with a single draw call, very useful for GUI systems!
|
||||
#define SUPPORT_FONT_TEXTURE
|
||||
#define SUPPORT_FONT_TEXTURE 1
|
||||
// Use QUADS instead of TRIANGLES for drawing when possible
|
||||
// Some lines-based shapes could still use lines
|
||||
#define SUPPORT_QUADS_DRAW_MODE
|
||||
#define SUPPORT_QUADS_DRAW_MODE 1
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: textures - Configuration Flags
|
||||
|
@ -81,10 +86,10 @@
|
|||
//#define SUPPORT_FILEFORMAT_JPG 1
|
||||
//#define SUPPORT_FILEFORMAT_GIF 1
|
||||
//#define SUPPORT_FILEFORMAT_PSD 1
|
||||
#define SUPPORT_FILEFORMAT_DDS 1
|
||||
//#define SUPPORT_FILEFORMAT_DDS 1
|
||||
#define SUPPORT_FILEFORMAT_HDR 1
|
||||
#define SUPPORT_FILEFORMAT_KTX 1
|
||||
#define SUPPORT_FILEFORMAT_ASTC 1
|
||||
//#define SUPPORT_FILEFORMAT_KTX 1
|
||||
//#define SUPPORT_FILEFORMAT_ASTC 1
|
||||
//#define SUPPORT_FILEFORMAT_PKM 1
|
||||
//#define SUPPORT_FILEFORMAT_PVR 1
|
||||
|
||||
|
@ -114,6 +119,8 @@
|
|||
// Selected desired model fileformats to be supported for loading
|
||||
#define SUPPORT_FILEFORMAT_OBJ 1
|
||||
#define SUPPORT_FILEFORMAT_MTL 1
|
||||
#define SUPPORT_FILEFORMAT_IQM 1
|
||||
#define SUPPORT_FILEFORMAT_GLTF 1
|
||||
// Support procedural mesh generation functions, uses external par_shapes.h library
|
||||
// NOTE: Some generated meshes DO NOT include generated texture coordinates
|
||||
#define SUPPORT_MESH_GENERATION 1
|
||||
|
@ -127,8 +134,8 @@
|
|||
#define SUPPORT_FILEFORMAT_OGG 1
|
||||
#define SUPPORT_FILEFORMAT_XM 1
|
||||
#define SUPPORT_FILEFORMAT_MOD 1
|
||||
//#define SUPPORT_FILEFORMAT_FLAC 1
|
||||
#define SUPPORT_FILEFORMAT_MP3 1
|
||||
#define SUPPORT_FILEFORMAT_FLAC 1
|
||||
#define SUPPORT_FILEFORMAT_MP3 1
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
|
1797
raylib/core.c
1797
raylib/core.c
File diff suppressed because it is too large
Load diff
|
@ -372,14 +372,9 @@ func Fade(color Color, alpha float32) Color {
|
|||
return v
|
||||
}
|
||||
|
||||
// ShowLogo - Activates raylib logo at startup (can be done with flags)
|
||||
func ShowLogo() {
|
||||
C.ShowLogo()
|
||||
}
|
||||
|
||||
// SetConfigFlags - Setup some window configuration flags
|
||||
func SetConfigFlags(flags byte) {
|
||||
cflags := (C.uchar)(flags)
|
||||
cflags := (C.uint)(flags)
|
||||
C.SetConfigFlags(cflags)
|
||||
}
|
||||
|
||||
|
@ -590,15 +585,17 @@ func GetMousePosition() Vector2 {
|
|||
}
|
||||
|
||||
// SetMousePosition - Set mouse position XY
|
||||
func SetMousePosition(position Vector2) {
|
||||
cposition := position.cptr()
|
||||
C.SetMousePosition(*cposition)
|
||||
func SetMousePosition(x, y int) {
|
||||
cx := (C.int)(x)
|
||||
cy := (C.int)(y)
|
||||
C.SetMousePosition(cx, cy)
|
||||
}
|
||||
|
||||
// SetMouseScale - Set mouse scaling
|
||||
func SetMouseScale(scale float32) {
|
||||
cscale := (C.float)(scale)
|
||||
C.SetMouseScale(cscale)
|
||||
func SetMouseScale(scaleX, scaleY float32) {
|
||||
cscaleX := (C.float)(scaleX)
|
||||
cscaleY := (C.float)(scaleY)
|
||||
C.SetMouseScale(cscaleX, cscaleY)
|
||||
}
|
||||
|
||||
// GetMouseWheelMove - Returns mouse wheel movement Y
|
||||
|
|
4724
raylib/external/cgltf.h
vendored
4724
raylib/external/cgltf.h
vendored
File diff suppressed because it is too large
Load diff
6213
raylib/external/dr_flac.h
vendored
6213
raylib/external/dr_flac.h
vendored
File diff suppressed because it is too large
Load diff
1975
raylib/external/dr_mp3.h
vendored
1975
raylib/external/dr_mp3.h
vendored
File diff suppressed because it is too large
Load diff
3288
raylib/external/dr_wav.h
vendored
3288
raylib/external/dr_wav.h
vendored
File diff suppressed because it is too large
Load diff
19
raylib/external/jar_xm.h
vendored
19
raylib/external/jar_xm.h
vendored
|
@ -1925,7 +1925,6 @@ static void jar_xm_handle_note_and_instrument(jar_xm_context_t* ctx, jar_xm_chan
|
|||
|
||||
case 33: /* Xxy: Extra stuff */
|
||||
switch(s->effect_param >> 4) {
|
||||
|
||||
case 1: /* X1y: Extra fine portamento up */
|
||||
if(s->effect_param & 0x0F) {
|
||||
ch->extra_fine_portamento_up_param = s->effect_param & 0x0F;
|
||||
|
@ -2365,7 +2364,7 @@ static void jar_xm_tick(jar_xm_context_t* ctx) {
|
|||
float panning, volume;
|
||||
|
||||
panning = ch->panning +
|
||||
(ch->panning_envelope_panning - .5f) * (.5f - fabsf(ch->panning - .5f)) * 2.0f;
|
||||
(ch->panning_envelope_panning - .5f) * (.5f - fabs(ch->panning - .5f)) * 2.0f;
|
||||
|
||||
if(ch->tremor_on) {
|
||||
volume = .0f;
|
||||
|
@ -2660,6 +2659,22 @@ int jar_xm_create_context_from_file(jar_xm_context_t** ctx, uint32_t rate, const
|
|||
return 0;
|
||||
}
|
||||
|
||||
// not part of the original library
|
||||
void jar_xm_reset(jar_xm_context_t* ctx)
|
||||
{
|
||||
// I don't know what I am doing
|
||||
// this is probably very broken
|
||||
// but it kinda works
|
||||
for (uint16_t i = 0; i < jar_xm_get_number_of_channels(ctx); i++)
|
||||
{
|
||||
jar_xm_cut_note(&ctx->channels[i]);
|
||||
}
|
||||
ctx->current_row = 0;
|
||||
ctx->current_table_index = ctx->module.restart_position;
|
||||
ctx->current_tick = 0;
|
||||
}
|
||||
|
||||
|
||||
#endif//end of JAR_XM_IMPLEMENTATION
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
|
|
33744
raylib/external/miniaudio.h
vendored
Normal file
33744
raylib/external/miniaudio.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
2
raylib/external/par_shapes.h
vendored
2
raylib/external/par_shapes.h
vendored
|
@ -10,7 +10,7 @@
|
|||
// In addition to the comment block above each function declaration, the API
|
||||
// has informal documentation here:
|
||||
//
|
||||
// http://github.prideout.net/shapes/
|
||||
// https://prideout.net/shapes
|
||||
//
|
||||
// For our purposes, a "mesh" is a list of points and a list of triangles; the
|
||||
// former is a flattened list of three-tuples (32-bit floats) and the latter is
|
||||
|
|
44
raylib/external/rgif.h
vendored
44
raylib/external/rgif.h
vendored
|
@ -1,6 +1,8 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* rgif.h original implementation (gif.h) by Charlie Tangora [ctangora -at- gmail -dot- com]
|
||||
* rgif.h v0.5
|
||||
*
|
||||
* Original implementation (gif.h) by Charlie Tangora [ctangora -at- gmail -dot- com]
|
||||
* adapted to C99, reformatted and renamed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This file offers a simple, very limited way to create animated GIFs directly in code.
|
||||
|
@ -32,7 +34,7 @@
|
|||
*
|
||||
* ALTERNATIVE A - MIT License
|
||||
*
|
||||
* Copyright (c) 2017 Ramon Santamaria
|
||||
* Copyright (c) 2017-2019 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -76,8 +78,8 @@
|
|||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#ifndef GIF_H
|
||||
#define GIF_H
|
||||
#ifndef RGIF_H
|
||||
#define RGIF_H
|
||||
|
||||
#include <stdio.h> // Required for: FILE
|
||||
|
||||
|
@ -101,7 +103,7 @@ RGIFDEF bool GifBegin(const char *filename, unsigned int width, unsigned int hei
|
|||
RGIFDEF bool GifWriteFrame(const unsigned char *image, unsigned int width, unsigned int height, unsigned int delay, int bitDepth, bool dither);
|
||||
RGIFDEF bool GifEnd();
|
||||
|
||||
#endif // GIF_H
|
||||
#endif // RGIF_H
|
||||
|
||||
|
||||
/***********************************************************************************
|
||||
|
@ -116,23 +118,23 @@ RGIFDEF bool GifEnd();
|
|||
#include <string.h> // Required for: memcpy()
|
||||
|
||||
// Define these macros to hook into a custom memory allocator.
|
||||
// GIF_TEMP_MALLOC and GIF_TEMP_FREE will only be called in stack fashion - frees in the reverse order of mallocs
|
||||
// RGIF_TEMP_MALLOC and RGIF_TEMP_FREE will only be called in stack fashion - frees in the reverse order of mallocs
|
||||
// and any temp memory allocated by a function will be freed before it exits.
|
||||
#if !defined(GIF_TEMP_MALLOC)
|
||||
#if !defined(RGIF_TEMP_MALLOC)
|
||||
#include <stdlib.h>
|
||||
|
||||
#define GIF_TEMP_MALLOC malloc
|
||||
#define GIF_TEMP_FREE free
|
||||
#define RGIF_TEMP_MALLOC malloc
|
||||
#define RGIF_TEMP_FREE free
|
||||
#endif
|
||||
|
||||
// Check if custom malloc/free functions defined, if not, using standard ones
|
||||
// GIF_MALLOC and GIF_FREE are used only by GifBegin and GifEnd respectively,
|
||||
// RGIF_MALLOC and RGIF_FREE are used only by GifBegin and GifEnd respectively,
|
||||
// to allocate a buffer the size of the image, which is used to find changed pixels for delta-encoding.
|
||||
#if !defined(GIF_MALLOC)
|
||||
#if !defined(RGIF_MALLOC)
|
||||
#include <stdlib.h> // Required for: malloc(), free()
|
||||
|
||||
#define GIF_MALLOC(size) malloc(size)
|
||||
#define GIF_FREE(ptr) free(ptr)
|
||||
#define RGIF_MALLOC(size) malloc(size)
|
||||
#define RGIF_FREE(ptr) free(ptr)
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -223,7 +225,7 @@ RGIFDEF bool GifBegin(const char *filename, unsigned int width, unsigned int hei
|
|||
if (!gifFile) return false;
|
||||
|
||||
// Allocate space for one gif frame
|
||||
gifFrame = (unsigned char *)GIF_MALLOC(width*height*4);
|
||||
gifFrame = (unsigned char *)RGIF_MALLOC(width*height*4);
|
||||
|
||||
// GIF Header
|
||||
fputs("GIF89a",gifFile);
|
||||
|
@ -300,7 +302,7 @@ RGIFDEF bool GifEnd()
|
|||
fputc(0x3b, gifFile); // Trailer (end of file)
|
||||
fclose(gifFile);
|
||||
|
||||
GIF_FREE(gifFrame);
|
||||
RGIF_FREE(gifFrame);
|
||||
|
||||
gifFile = NULL;
|
||||
gifFrame = NULL;
|
||||
|
@ -589,7 +591,7 @@ static void GifMakePalette(const unsigned char *lastFrame, const unsigned char *
|
|||
// SplitPalette is destructive (it sorts the pixels by color) so
|
||||
// we must create a copy of the image for it to destroy
|
||||
int imageSize = width*height*4*sizeof(unsigned char);
|
||||
unsigned char *destroyableImage = (unsigned char*)GIF_TEMP_MALLOC(imageSize);
|
||||
unsigned char *destroyableImage = (unsigned char*)RGIF_TEMP_MALLOC(imageSize);
|
||||
memcpy(destroyableImage, nextFrame, imageSize);
|
||||
|
||||
int numPixels = width*height;
|
||||
|
@ -602,7 +604,7 @@ static void GifMakePalette(const unsigned char *lastFrame, const unsigned char *
|
|||
|
||||
GifSplitPalette(destroyableImage, numPixels, 1, lastElt, splitElt, splitDist, 1, buildForDither, pPal);
|
||||
|
||||
GIF_TEMP_FREE(destroyableImage);
|
||||
RGIF_TEMP_FREE(destroyableImage);
|
||||
|
||||
// add the bottom node for the transparency index
|
||||
pPal->treeSplit[1 << (bitDepth-1)] = 0;
|
||||
|
@ -619,7 +621,7 @@ static void GifDitherImage(const unsigned char *lastFrame, const unsigned char *
|
|||
// quantPixels initially holds color*256 for all pixels
|
||||
// The extra 8 bits of precision allow for sub-single-color error values
|
||||
// to be propagated
|
||||
int *quantPixels = (int*)GIF_TEMP_MALLOC(sizeof(int)*numPixels*4);
|
||||
int *quantPixels = (int*)RGIF_TEMP_MALLOC(sizeof(int)*numPixels*4);
|
||||
|
||||
for (int ii=0; ii<numPixels*4; ++ii)
|
||||
{
|
||||
|
@ -717,7 +719,7 @@ static void GifDitherImage(const unsigned char *lastFrame, const unsigned char *
|
|||
outFrame[ii] = quantPixels[ii];
|
||||
}
|
||||
|
||||
GIF_TEMP_FREE(quantPixels);
|
||||
RGIF_TEMP_FREE(quantPixels);
|
||||
}
|
||||
|
||||
// Picks palette colors for the image using simple thresholding, no dithering
|
||||
|
@ -857,7 +859,7 @@ static void GifWriteLzwImage(FILE *f, unsigned char *image, unsigned int left, u
|
|||
|
||||
fputc(minCodeSize, f); // min code size 8 bits
|
||||
|
||||
GifLzwNode *codetree = (GifLzwNode *)GIF_TEMP_MALLOC(sizeof(GifLzwNode)*4096);
|
||||
GifLzwNode *codetree = (GifLzwNode *)RGIF_TEMP_MALLOC(sizeof(GifLzwNode)*4096);
|
||||
|
||||
memset(codetree, 0, sizeof(GifLzwNode)*4096);
|
||||
int curCode = -1;
|
||||
|
@ -931,7 +933,7 @@ static void GifWriteLzwImage(FILE *f, unsigned char *image, unsigned int left, u
|
|||
|
||||
fputc(0, f); // image block terminator
|
||||
|
||||
GIF_TEMP_FREE(codetree);
|
||||
RGIF_TEMP_FREE(codetree);
|
||||
}
|
||||
|
||||
#endif // RGIF_IMPLEMENTATION
|
||||
|
|
216
raylib/external/stb_image.h
vendored
216
raylib/external/stb_image.h
vendored
|
@ -1,4 +1,4 @@
|
|||
/* stb_image - v2.18 - public domain image loader - http://nothings.org/stb
|
||||
/* stb_image - v2.23 - public domain image loader - http://nothings.org/stb
|
||||
no warranty implied; use at your own risk
|
||||
|
||||
Do this:
|
||||
|
@ -48,6 +48,11 @@ LICENSE
|
|||
|
||||
RECENT REVISION HISTORY:
|
||||
|
||||
2.23 (2019-08-11) fix clang static analysis warning
|
||||
2.22 (2019-03-04) gif fixes, fix warnings
|
||||
2.21 (2019-02-25) fix typo in comment
|
||||
2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
|
||||
2.19 (2018-02-11) fix warning
|
||||
2.18 (2018-01-30) fix warnings
|
||||
2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings
|
||||
2.16 (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes
|
||||
|
@ -83,6 +88,7 @@ RECENT REVISION HISTORY:
|
|||
Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query)
|
||||
Arseny Kapoulkine
|
||||
John-Mark Allen
|
||||
Carmelo J Fdez-Aguera
|
||||
|
||||
Bug & warning fixes
|
||||
Marc LeBlanc David Woo Guillaume George Martins Mozeiko
|
||||
|
@ -98,7 +104,7 @@ RECENT REVISION HISTORY:
|
|||
Aldo Culquicondor Philipp Wiesemann Dale Weiler github:sammyhw
|
||||
Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus
|
||||
Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo
|
||||
Christian Floisand Kevin Schmidt github:darealshinji
|
||||
Christian Floisand Kevin Schmidt JR Smith github:darealshinji
|
||||
Blazej Dariusz Roszkowski github:Michaelangel007
|
||||
*/
|
||||
|
||||
|
@ -160,6 +166,16 @@ RECENT REVISION HISTORY:
|
|||
//
|
||||
// ===========================================================================
|
||||
//
|
||||
// UNICODE:
|
||||
//
|
||||
// If compiling for Windows and you wish to use Unicode filenames, compile
|
||||
// with
|
||||
// #define STBI_WINDOWS_UTF8
|
||||
// and pass utf8-encoded filenames. Call stbi_convert_wchar_to_utf8 to convert
|
||||
// Windows wchar_t filenames to utf8.
|
||||
//
|
||||
// ===========================================================================
|
||||
//
|
||||
// Philosophy
|
||||
//
|
||||
// stb libraries are designed with the following priorities:
|
||||
|
@ -170,12 +186,12 @@ RECENT REVISION HISTORY:
|
|||
//
|
||||
// Sometimes I let "good performance" creep up in priority over "easy to maintain",
|
||||
// and for best performance I may provide less-easy-to-use APIs that give higher
|
||||
// performance, in addition to the easy to use ones. Nevertheless, it's important
|
||||
// performance, in addition to the easy-to-use ones. Nevertheless, it's important
|
||||
// to keep in mind that from the standpoint of you, a client of this library,
|
||||
// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all.
|
||||
//
|
||||
// Some secondary priorities arise directly from the first two, some of which
|
||||
// make more explicit reasons why performance can't be emphasized.
|
||||
// provide more explicit reasons why performance can't be emphasized.
|
||||
//
|
||||
// - Portable ("ease of use")
|
||||
// - Small source code footprint ("easy to maintain")
|
||||
|
@ -218,11 +234,10 @@ RECENT REVISION HISTORY:
|
|||
//
|
||||
// HDR image support (disable by defining STBI_NO_HDR)
|
||||
//
|
||||
// stb_image now supports loading HDR images in general, and currently
|
||||
// the Radiance .HDR file format, although the support is provided
|
||||
// generically. You can still load any file through the existing interface;
|
||||
// if you attempt to load an HDR file, it will be automatically remapped to
|
||||
// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1;
|
||||
// stb_image supports loading HDR images in general, and currently the Radiance
|
||||
// .HDR file format specifically. You can still load any file through the existing
|
||||
// interface; if you attempt to load an HDR file, it will be automatically remapped
|
||||
// to LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1;
|
||||
// both of these constants can be reconfigured through this interface:
|
||||
//
|
||||
// stbi_hdr_to_ldr_gamma(2.2f);
|
||||
|
@ -256,7 +271,7 @@ RECENT REVISION HISTORY:
|
|||
//
|
||||
// By default we convert iphone-formatted PNGs back to RGB, even though
|
||||
// they are internally encoded differently. You can disable this conversion
|
||||
// by by calling stbi_convert_iphone_png_to_rgb(0), in which case
|
||||
// by calling stbi_convert_iphone_png_to_rgb(0), in which case
|
||||
// you will always just get the native iphone "format" through (which
|
||||
// is BGR stored in RGB).
|
||||
//
|
||||
|
@ -318,6 +333,7 @@ enum
|
|||
STBI_rgb_alpha = 4
|
||||
};
|
||||
|
||||
#include <stdlib.h>
|
||||
typedef unsigned char stbi_uc;
|
||||
typedef unsigned short stbi_us;
|
||||
|
||||
|
@ -325,11 +341,13 @@ typedef unsigned short stbi_us;
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef STBIDEF
|
||||
#ifdef STB_IMAGE_STATIC
|
||||
#define STBIDEF static
|
||||
#else
|
||||
#define STBIDEF extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -354,10 +372,6 @@ typedef struct
|
|||
|
||||
STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels);
|
||||
STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels);
|
||||
#ifndef STBI_NO_GIF
|
||||
STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef STBI_NO_STDIO
|
||||
STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
|
||||
|
@ -365,6 +379,14 @@ STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *channels_in
|
|||
// for stbi_load_from_file, file pointer is left pointing immediately after image
|
||||
#endif
|
||||
|
||||
#ifndef STBI_NO_GIF
|
||||
STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
|
||||
#endif
|
||||
|
||||
#ifdef STBI_WINDOWS_UTF8
|
||||
STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input);
|
||||
#endif
|
||||
|
||||
////////////////////////////////////
|
||||
//
|
||||
// 16-bits-per-channel interface
|
||||
|
@ -524,6 +546,12 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
|
|||
#define STBI_ASSERT(x) assert(x)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define STBI_EXTERN extern "C"
|
||||
#else
|
||||
#define STBI_EXTERN extern
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#ifdef __cplusplus
|
||||
|
@ -648,14 +676,18 @@ static int stbi__cpuid3(void)
|
|||
|
||||
#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name
|
||||
|
||||
#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2)
|
||||
static int stbi__sse2_available(void)
|
||||
{
|
||||
int info3 = stbi__cpuid3();
|
||||
return ((info3 >> 26) & 1) != 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else // assume GCC-style if not VC++
|
||||
#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
|
||||
|
||||
#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2)
|
||||
static int stbi__sse2_available(void)
|
||||
{
|
||||
// If we're even attempting to compile this on GCC/Clang, that means
|
||||
|
@ -663,6 +695,8 @@ static int stbi__sse2_available(void)
|
|||
// instructions at will, and so are we.
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -1069,6 +1103,7 @@ static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef STBI_NO_GIF
|
||||
static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel)
|
||||
{
|
||||
int slice;
|
||||
|
@ -1080,6 +1115,7 @@ static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int byt
|
|||
bytes += slice_size;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
|
@ -1130,7 +1166,7 @@ static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x,
|
|||
return (stbi__uint16 *) result;
|
||||
}
|
||||
|
||||
#if !defined(STBI_NO_HDR) || !defined(STBI_NO_LINEAR)
|
||||
#if !defined(STBI_NO_HDR) && !defined(STBI_NO_LINEAR)
|
||||
static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
if (stbi__vertically_flip_on_load && result != NULL) {
|
||||
|
@ -1142,10 +1178,38 @@ static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, in
|
|||
|
||||
#ifndef STBI_NO_STDIO
|
||||
|
||||
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
|
||||
STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide);
|
||||
STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default);
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
|
||||
STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
|
||||
{
|
||||
return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static FILE *stbi__fopen(char const *filename, char const *mode)
|
||||
{
|
||||
FILE *f;
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
|
||||
wchar_t wMode[64];
|
||||
wchar_t wFilename[1024];
|
||||
if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
|
||||
return 0;
|
||||
|
||||
if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
|
||||
return 0;
|
||||
|
||||
#if _MSC_VER >= 1400
|
||||
if (0 != _wfopen_s(&f, wFilename, wMode))
|
||||
f = 0;
|
||||
#else
|
||||
f = _wfopen(wFilename, wMode);
|
||||
#endif
|
||||
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
if (0 != fopen_s(&f, filename, mode))
|
||||
f=0;
|
||||
#else
|
||||
|
@ -1538,18 +1602,18 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
|
|||
// convert source image with img_n components to one with req_comp components;
|
||||
// avoid switch per pixel, so use switch per scanline and massive macros
|
||||
switch (STBI__COMBO(img_n, req_comp)) {
|
||||
STBI__CASE(1,2) { dest[0]=src[0], dest[1]=255; } break;
|
||||
STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=255; } break;
|
||||
STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
||||
STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; } break;
|
||||
STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=255; } break;
|
||||
STBI__CASE(2,1) { dest[0]=src[0]; } break;
|
||||
STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
||||
STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break;
|
||||
STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; } break;
|
||||
STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break;
|
||||
STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=255; } break;
|
||||
STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
|
||||
STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = 255; } break;
|
||||
STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = 255; } break;
|
||||
STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
|
||||
STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; } break;
|
||||
STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break;
|
||||
STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break;
|
||||
STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
|
||||
default: STBI_ASSERT(0);
|
||||
}
|
||||
#undef STBI__CASE
|
||||
|
@ -1587,18 +1651,18 @@ static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int r
|
|||
// convert source image with img_n components to one with req_comp components;
|
||||
// avoid switch per pixel, so use switch per scanline and massive macros
|
||||
switch (STBI__COMBO(img_n, req_comp)) {
|
||||
STBI__CASE(1,2) { dest[0]=src[0], dest[1]=0xffff; } break;
|
||||
STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=0xffff; } break;
|
||||
STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
||||
STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=0xffff; } break;
|
||||
STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=0xffff; } break;
|
||||
STBI__CASE(2,1) { dest[0]=src[0]; } break;
|
||||
STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
||||
STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break;
|
||||
STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=0xffff; } break;
|
||||
STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break;
|
||||
STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=0xffff; } break;
|
||||
STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
|
||||
STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = 0xffff; } break;
|
||||
STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = 0xffff; } break;
|
||||
STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
|
||||
STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = src[3]; } break;
|
||||
STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break;
|
||||
STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break;
|
||||
STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
|
||||
default: STBI_ASSERT(0);
|
||||
}
|
||||
#undef STBI__CASE
|
||||
|
@ -1622,7 +1686,11 @@ static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
|
|||
for (k=0; k < n; ++k) {
|
||||
output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale);
|
||||
}
|
||||
if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f;
|
||||
}
|
||||
if (n < comp) {
|
||||
for (i=0; i < x*y; ++i) {
|
||||
output[i*comp + n] = data[i*comp + n]/255.0f;
|
||||
}
|
||||
}
|
||||
STBI_FREE(data);
|
||||
return output;
|
||||
|
@ -3595,7 +3663,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
|
|||
int k;
|
||||
unsigned int i,j;
|
||||
stbi_uc *output;
|
||||
stbi_uc *coutput[4];
|
||||
stbi_uc *coutput[4] = { NULL, NULL, NULL, NULL };
|
||||
|
||||
stbi__resample res_comp[4];
|
||||
|
||||
|
@ -3716,7 +3784,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
|
|||
if (n == 1)
|
||||
for (i=0; i < z->s->img_x; ++i) out[i] = y[i];
|
||||
else
|
||||
for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255;
|
||||
for (i=0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4730,7 +4798,7 @@ static void stbi__de_iphone(stbi__png *z)
|
|||
static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
||||
{
|
||||
stbi_uc palette[1024], pal_img_n=0;
|
||||
stbi_uc has_trans=0, tc[3];
|
||||
stbi_uc has_trans=0, tc[3]={0};
|
||||
stbi__uint16 tc16[3];
|
||||
stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0;
|
||||
int first=1,k,interlace=0, color=0, is_iphone=0;
|
||||
|
@ -5008,11 +5076,11 @@ static int stbi__high_bit(unsigned int z)
|
|||
{
|
||||
int n=0;
|
||||
if (z == 0) return -1;
|
||||
if (z >= 0x10000) n += 16, z >>= 16;
|
||||
if (z >= 0x00100) n += 8, z >>= 8;
|
||||
if (z >= 0x00010) n += 4, z >>= 4;
|
||||
if (z >= 0x00004) n += 2, z >>= 2;
|
||||
if (z >= 0x00002) n += 1, z >>= 1;
|
||||
if (z >= 0x10000) { n += 16; z >>= 16; }
|
||||
if (z >= 0x00100) { n += 8; z >>= 8; }
|
||||
if (z >= 0x00010) { n += 4; z >>= 4; }
|
||||
if (z >= 0x00004) { n += 2; z >>= 2; }
|
||||
if (z >= 0x00002) { n += 1;/* >>= 1;*/ }
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -5029,7 +5097,7 @@ static int stbi__bitcount(unsigned int a)
|
|||
// extract an arbitrarily-aligned N-bit value (N=bits)
|
||||
// from v, and then make it 8-bits long and fractionally
|
||||
// extend it to full full range.
|
||||
static int stbi__shiftsigned(int v, int shift, int bits)
|
||||
static int stbi__shiftsigned(unsigned int v, int shift, int bits)
|
||||
{
|
||||
static unsigned int mul_table[9] = {
|
||||
0,
|
||||
|
@ -5170,7 +5238,10 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||
psize = (info.offset - 14 - info.hsz) >> 2;
|
||||
}
|
||||
|
||||
s->img_n = ma ? 4 : 3;
|
||||
if (info.bpp == 24 && ma == 0xff000000)
|
||||
s->img_n = 3;
|
||||
else
|
||||
s->img_n = ma ? 4 : 3;
|
||||
if (req_comp && req_comp >= 3) // we can directly decode 3 or 4
|
||||
target = req_comp;
|
||||
else
|
||||
|
@ -5206,6 +5277,8 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||
out[z++] = pal[color][0];
|
||||
out[z++] = pal[color][1];
|
||||
out[z++] = pal[color][2];
|
||||
if (target == 4) out[z++] = 255;
|
||||
if (i+1 == (int) s->img_x) break;
|
||||
if((--bit_offset) < 0) {
|
||||
bit_offset = 7;
|
||||
v = stbi__get8(s);
|
||||
|
@ -5298,7 +5371,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||
stbi_uc *p1 = out + j *s->img_x*target;
|
||||
stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target;
|
||||
for (i=0; i < (int) s->img_x*target; ++i) {
|
||||
t = p1[i], p1[i] = p2[i], p2[i] = t;
|
||||
t = p1[i]; p1[i] = p2[i]; p2[i] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5478,6 +5551,8 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||
int RLE_repeating = 0;
|
||||
int read_next_pixel = 1;
|
||||
STBI_NOTUSED(ri);
|
||||
STBI_NOTUSED(tga_x_origin); // @TODO
|
||||
STBI_NOTUSED(tga_y_origin); // @TODO
|
||||
|
||||
// do a tiny bit of precessing
|
||||
if ( tga_image_type >= 8 )
|
||||
|
@ -5641,6 +5716,7 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||
// Microsoft's C compilers happy... [8^(
|
||||
tga_palette_start = tga_palette_len = tga_palette_bits =
|
||||
tga_x_origin = tga_y_origin = 0;
|
||||
STBI_NOTUSED(tga_palette_start);
|
||||
// OK, done
|
||||
return tga_data;
|
||||
}
|
||||
|
@ -5788,7 +5864,7 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||
// Else if n is 128, noop.
|
||||
// Endloop
|
||||
|
||||
// The RLE-compressed data is preceeded by a 2-byte data count for each row in the data,
|
||||
// The RLE-compressed data is preceded by a 2-byte data count for each row in the data,
|
||||
// which we're going to just skip.
|
||||
stbi__skip(s, h * channelCount * 2 );
|
||||
|
||||
|
@ -6341,22 +6417,27 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
|
|||
int first_frame;
|
||||
int pi;
|
||||
int pcount;
|
||||
STBI_NOTUSED(req_comp);
|
||||
|
||||
// on first frame, any non-written pixels get the background colour (non-transparent)
|
||||
first_frame = 0;
|
||||
if (g->out == 0) {
|
||||
if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header
|
||||
g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
|
||||
g->background = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
|
||||
g->history = (stbi_uc *) stbi__malloc(g->w * g->h);
|
||||
if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory");
|
||||
if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header
|
||||
if (!stbi__mad3sizes_valid(4, g->w, g->h, 0))
|
||||
return stbi__errpuc("too large", "GIF image is too large");
|
||||
pcount = g->w * g->h;
|
||||
g->out = (stbi_uc *) stbi__malloc(4 * pcount);
|
||||
g->background = (stbi_uc *) stbi__malloc(4 * pcount);
|
||||
g->history = (stbi_uc *) stbi__malloc(pcount);
|
||||
if (!g->out || !g->background || !g->history)
|
||||
return stbi__errpuc("outofmem", "Out of memory");
|
||||
|
||||
// image is treated as "tranparent" at the start - ie, nothing overwrites the current background;
|
||||
// image is treated as "transparent" at the start - ie, nothing overwrites the current background;
|
||||
// background colour is only used for pixels that are not rendered first frame, after that "background"
|
||||
// color refers to teh color that was there the previous frame.
|
||||
memset( g->out, 0x00, 4 * g->w * g->h );
|
||||
memset( g->background, 0x00, 4 * g->w * g->h ); // state of the background (starts transparent)
|
||||
memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame
|
||||
// color refers to the color that was there the previous frame.
|
||||
memset(g->out, 0x00, 4 * pcount);
|
||||
memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent)
|
||||
memset(g->history, 0x00, pcount); // pixels that were affected previous frame
|
||||
first_frame = 1;
|
||||
} else {
|
||||
// second frame - how do we dispoase of the previous one?
|
||||
|
@ -6417,6 +6498,13 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
|
|||
g->cur_x = g->start_x;
|
||||
g->cur_y = g->start_y;
|
||||
|
||||
// if the width of the specified rectangle is 0, that means
|
||||
// we may not see *any* pixels or the image is malformed;
|
||||
// to make sure this is caught, move the current y down to
|
||||
// max_y (which is what out_gif_code checks).
|
||||
if (w == 0)
|
||||
g->cur_y = g->max_y;
|
||||
|
||||
g->lflags = stbi__get8(s);
|
||||
|
||||
if (g->lflags & 0x40) {
|
||||
|
@ -6436,7 +6524,7 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
|
|||
return stbi__errpuc("missing color table", "Corrupt GIF");
|
||||
|
||||
o = stbi__process_gif_raster(s, g);
|
||||
if (o == NULL) return NULL;
|
||||
if (!o) return NULL;
|
||||
|
||||
// if this was the first frame,
|
||||
pcount = g->w * g->h;
|
||||
|
@ -6564,6 +6652,7 @@ static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||
stbi_uc *u = 0;
|
||||
stbi__gif g;
|
||||
memset(&g, 0, sizeof(g));
|
||||
STBI_NOTUSED(ri);
|
||||
|
||||
u = stbi__gif_load_next(s, &g, comp, req_comp, 0);
|
||||
if (u == (stbi_uc *) s) u = 0; // end of animated gif marker
|
||||
|
@ -6575,6 +6664,9 @@ static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||
// can be done for multiple frames.
|
||||
if (req_comp && req_comp != 4)
|
||||
u = stbi__convert_format(u, 4, req_comp, g.w, g.h);
|
||||
} else if (g.out) {
|
||||
// if there was an error and we allocated an image buffer, free it!
|
||||
STBI_FREE(g.out);
|
||||
}
|
||||
|
||||
// free buffers needed for multiple frame loading;
|
||||
|
@ -6851,7 +6943,12 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
|
|||
return 0;
|
||||
if (x) *x = s->img_x;
|
||||
if (y) *y = s->img_y;
|
||||
if (comp) *comp = info.ma ? 4 : 3;
|
||||
if (comp) {
|
||||
if (info.bpp == 24 && info.ma == 0xff000000)
|
||||
*comp = 3;
|
||||
else
|
||||
*comp = info.ma ? 4 : 3;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
@ -6894,7 +6991,7 @@ static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp)
|
|||
|
||||
static int stbi__psd_is16(stbi__context *s)
|
||||
{
|
||||
int channelCount, dummy, depth;
|
||||
int channelCount, depth;
|
||||
if (stbi__get32be(s) != 0x38425053) {
|
||||
stbi__rewind( s );
|
||||
return 0;
|
||||
|
@ -6909,8 +7006,8 @@ static int stbi__psd_is16(stbi__context *s)
|
|||
stbi__rewind( s );
|
||||
return 0;
|
||||
}
|
||||
dummy = stbi__get32be(s);
|
||||
dummy = stbi__get32be(s);
|
||||
(void) stbi__get32be(s);
|
||||
(void) stbi__get32be(s);
|
||||
depth = stbi__get16be(s);
|
||||
if (depth != 16) {
|
||||
stbi__rewind( s );
|
||||
|
@ -7237,6 +7334,9 @@ STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user
|
|||
|
||||
/*
|
||||
revision history:
|
||||
2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
|
||||
2.19 (2018-02-11) fix warning
|
||||
2.18 (2018-01-30) fix warnings
|
||||
2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug
|
||||
1-bit BMP
|
||||
*_is_16_bit api
|
||||
|
|
9
raylib/external/stb_image_resize.h
vendored
9
raylib/external/stb_image_resize.h
vendored
|
@ -1,4 +1,4 @@
|
|||
/* stb_image_resize - v0.95 - public domain image resizing
|
||||
/* stb_image_resize - v0.96 - public domain image resizing
|
||||
by Jorge L Rodriguez (@VinoBS) - 2014
|
||||
http://github.com/nothings/stb
|
||||
|
||||
|
@ -159,6 +159,7 @@
|
|||
Nathan Reed: warning fixes
|
||||
|
||||
REVISIONS
|
||||
0.96 (2019-03-04) fixed warnings
|
||||
0.95 (2017-07-23) fixed warnings
|
||||
0.94 (2017-03-18) fixed warnings
|
||||
0.93 (2017-03-03) fixed bug with certain combinations of heights
|
||||
|
@ -193,6 +194,7 @@ typedef uint16_t stbir_uint16;
|
|||
typedef uint32_t stbir_uint32;
|
||||
#endif
|
||||
|
||||
#ifndef STBIRDEF
|
||||
#ifdef STB_IMAGE_RESIZE_STATIC
|
||||
#define STBIRDEF static
|
||||
#else
|
||||
|
@ -202,7 +204,7 @@ typedef uint32_t stbir_uint32;
|
|||
#define STBIRDEF extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -2324,8 +2326,9 @@ static int stbir__resize_allocated(stbir__info *info,
|
|||
if (alpha_channel < 0)
|
||||
flags |= STBIR_FLAG_ALPHA_USES_COLORSPACE | STBIR_FLAG_ALPHA_PREMULTIPLIED;
|
||||
|
||||
if (!(flags&STBIR_FLAG_ALPHA_USES_COLORSPACE) || !(flags&STBIR_FLAG_ALPHA_PREMULTIPLIED))
|
||||
if (!(flags&STBIR_FLAG_ALPHA_USES_COLORSPACE) || !(flags&STBIR_FLAG_ALPHA_PREMULTIPLIED)) {
|
||||
STBIR_ASSERT(alpha_channel >= 0 && alpha_channel < info->channels);
|
||||
}
|
||||
|
||||
if (alpha_channel >= info->channels)
|
||||
return 0;
|
||||
|
|
220
raylib/external/stb_image_write.h
vendored
220
raylib/external/stb_image_write.h
vendored
|
@ -1,4 +1,4 @@
|
|||
/* stb_image_write - v1.08 - public domain - http://nothings.org/stb/stb_image_write.h
|
||||
/* stb_image_write - v1.13 - public domain - http://nothings.org/stb
|
||||
writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015
|
||||
no warranty implied; use at your own risk
|
||||
|
||||
|
@ -10,15 +10,9 @@
|
|||
|
||||
Will probably not work correctly with strict-aliasing optimizations.
|
||||
|
||||
If using a modern Microsoft Compiler, non-safe versions of CRT calls may cause
|
||||
compilation warnings or even errors. To avoid this, also before #including,
|
||||
|
||||
#define STBI_MSC_SECURE_CRT
|
||||
|
||||
ABOUT:
|
||||
|
||||
This header file is a library for writing images to C stdio. It could be
|
||||
adapted to write to memory or a general streaming interface; let me know.
|
||||
This header file is a library for writing images to C stdio or a callback.
|
||||
|
||||
The PNG output is not optimal; it is 20-50% larger than the file
|
||||
written by a decent optimizing implementation; though providing a custom
|
||||
|
@ -38,6 +32,14 @@ BUILDING:
|
|||
The returned data will be freed with STBIW_FREE() (free() by default),
|
||||
so it must be heap allocated with STBIW_MALLOC() (malloc() by default),
|
||||
|
||||
UNICODE:
|
||||
|
||||
If compiling for Windows and you wish to use Unicode filenames, compile
|
||||
with
|
||||
#define STBIW_WINDOWS_UTF8
|
||||
and pass utf8-encoded filenames. Call stbiw_convert_wchar_to_utf8 to convert
|
||||
Windows wchar_t filenames to utf8.
|
||||
|
||||
USAGE:
|
||||
|
||||
There are five functions, one for each image file format:
|
||||
|
@ -45,8 +47,8 @@ USAGE:
|
|||
int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
|
||||
int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
|
||||
int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
|
||||
int stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality);
|
||||
int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
|
||||
int stbi_write_jpg(char const *filename, int w, int h, int comp, const float *data, int quality);
|
||||
|
||||
void stbi_flip_vertically_on_write(int flag); // flag is non-zero to flip data vertically
|
||||
|
||||
|
@ -95,7 +97,7 @@ USAGE:
|
|||
at the end of the line.)
|
||||
|
||||
PNG allows you to set the deflate compression level by setting the global
|
||||
variable 'stbi_write_png_level' (it defaults to 8).
|
||||
variable 'stbi_write_png_compression_level' (it defaults to 8).
|
||||
|
||||
HDR expects linear float data. Since the format is always 32-bit rgb(e)
|
||||
data, alpha (if provided) is discarded, and for monochrome data it is
|
||||
|
@ -133,7 +135,12 @@ CREDITS:
|
|||
github:poppolopoppo
|
||||
Patrick Boettcher
|
||||
github:xeekworx
|
||||
|
||||
Cap Petschulat
|
||||
Simon Rodriguez
|
||||
Ivan Tikhonov
|
||||
github:ignotion
|
||||
Adam Schackart
|
||||
|
||||
LICENSE
|
||||
|
||||
See end of file for license information.
|
||||
|
@ -143,19 +150,26 @@ LICENSE
|
|||
#ifndef INCLUDE_STB_IMAGE_WRITE_H
|
||||
#define INCLUDE_STB_IMAGE_WRITE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
// if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline'
|
||||
#ifndef STBIWDEF
|
||||
#ifdef STB_IMAGE_WRITE_STATIC
|
||||
#define STBIWDEF static
|
||||
#define STBIWDEF static
|
||||
#else
|
||||
#define STBIWDEF extern
|
||||
#ifdef __cplusplus
|
||||
#define STBIWDEF extern "C"
|
||||
#else
|
||||
#define STBIWDEF extern
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
STBIWDEF int stbi_write_tga_with_rle;
|
||||
STBIWDEF int stbi_write_png_comperssion_level;
|
||||
STBIWDEF int stbi_write_force_png_filter;
|
||||
#ifndef STB_IMAGE_WRITE_STATIC // C++ forbids static forward declarations
|
||||
extern int stbi_write_tga_with_rle;
|
||||
extern int stbi_write_png_compression_level;
|
||||
extern int stbi_write_force_png_filter;
|
||||
#endif
|
||||
|
||||
#ifndef STBI_WRITE_NO_STDIO
|
||||
STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
|
||||
|
@ -163,6 +177,10 @@ STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const
|
|||
STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
|
||||
STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
|
||||
STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality);
|
||||
|
||||
#ifdef STBI_WINDOWS_UTF8
|
||||
STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef void stbi_write_func(void *context, void *data, int size);
|
||||
|
@ -175,10 +193,6 @@ STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x,
|
|||
|
||||
STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif//INCLUDE_STB_IMAGE_WRITE_H
|
||||
|
||||
#ifdef STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
|
@ -233,8 +247,8 @@ STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
|
|||
#define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff)
|
||||
|
||||
#ifdef STB_IMAGE_WRITE_STATIC
|
||||
static stbi__flip_vertically_on_write=0;
|
||||
static int stbi_write_png_compression level = 8;
|
||||
static int stbi__flip_vertically_on_write=0;
|
||||
static int stbi_write_png_compression_level = 8;
|
||||
static int stbi_write_tga_with_rle = 1;
|
||||
static int stbi_write_force_png_filter = -1;
|
||||
#else
|
||||
|
@ -269,15 +283,52 @@ static void stbi__stdio_write(void *context, void *data, int size)
|
|||
fwrite(data,1,size,(FILE*) context);
|
||||
}
|
||||
|
||||
static int stbi__start_write_file(stbi__write_context *s, const char *filename)
|
||||
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
|
||||
#ifdef __cplusplus
|
||||
#define STBIW_EXTERN extern "C"
|
||||
#else
|
||||
#define STBIW_EXTERN extern
|
||||
#endif
|
||||
STBIW_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide);
|
||||
STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default);
|
||||
|
||||
STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
|
||||
{
|
||||
return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static FILE *stbiw__fopen(char const *filename, char const *mode)
|
||||
{
|
||||
FILE *f;
|
||||
#ifdef STBI_MSC_SECURE_CRT
|
||||
if (fopen_s(&f, filename, "wb"))
|
||||
f = NULL;
|
||||
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
|
||||
wchar_t wMode[64];
|
||||
wchar_t wFilename[1024];
|
||||
if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
|
||||
return 0;
|
||||
|
||||
if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
|
||||
return 0;
|
||||
|
||||
#if _MSC_VER >= 1400
|
||||
if (0 != _wfopen_s(&f, wFilename, wMode))
|
||||
f = 0;
|
||||
#else
|
||||
f = fopen(filename, "wb");
|
||||
f = _wfopen(wFilename, wMode);
|
||||
#endif
|
||||
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
if (0 != fopen_s(&f, filename, mode))
|
||||
f=0;
|
||||
#else
|
||||
f = fopen(filename, mode);
|
||||
#endif
|
||||
return f;
|
||||
}
|
||||
|
||||
static int stbi__start_write_file(stbi__write_context *s, const char *filename)
|
||||
{
|
||||
FILE *f = stbiw__fopen(filename, "wb");
|
||||
stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f);
|
||||
return f != NULL;
|
||||
}
|
||||
|
@ -337,7 +388,7 @@ static void stbiw__putc(stbi__write_context *s, unsigned char c)
|
|||
static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c)
|
||||
{
|
||||
unsigned char arr[3];
|
||||
arr[0] = a, arr[1] = b, arr[2] = c;
|
||||
arr[0] = a; arr[1] = b; arr[2] = c;
|
||||
s->func(s->context, arr, 3);
|
||||
}
|
||||
|
||||
|
@ -385,10 +436,11 @@ static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, i
|
|||
if (stbi__flip_vertically_on_write)
|
||||
vdir *= -1;
|
||||
|
||||
if (vdir < 0)
|
||||
j_end = -1, j = y-1;
|
||||
else
|
||||
j_end = y, j = 0;
|
||||
if (vdir < 0) {
|
||||
j_end = -1; j = y-1;
|
||||
} else {
|
||||
j_end = y; j = 0;
|
||||
}
|
||||
|
||||
for (; j != j_end; j += vdir) {
|
||||
for (i=0; i < x; ++i) {
|
||||
|
@ -546,7 +598,7 @@ STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const
|
|||
|
||||
#define stbiw__max(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
|
||||
static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
|
||||
{
|
||||
int exponent;
|
||||
float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2]));
|
||||
|
@ -563,7 +615,7 @@ void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
|
|||
}
|
||||
}
|
||||
|
||||
void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte)
|
||||
static void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte)
|
||||
{
|
||||
unsigned char lengthbyte = STBIW_UCHAR(length+128);
|
||||
STBIW_ASSERT(length+128 <= 255);
|
||||
|
@ -571,7 +623,7 @@ void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char dat
|
|||
s->func(s->context, &databyte, 1);
|
||||
}
|
||||
|
||||
void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data)
|
||||
static void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data)
|
||||
{
|
||||
unsigned char lengthbyte = STBIW_UCHAR(length);
|
||||
STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code
|
||||
|
@ -579,7 +631,7 @@ void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *d
|
|||
s->func(s->context, data, length);
|
||||
}
|
||||
|
||||
void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline)
|
||||
static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline)
|
||||
{
|
||||
unsigned char scanlineheader[4] = { 2, 2, 0, 0 };
|
||||
unsigned char rgbe[4];
|
||||
|
@ -680,15 +732,15 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f
|
|||
char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
|
||||
s->func(s->context, header, sizeof(header)-1);
|
||||
|
||||
#ifdef STBI_MSC_SECURE_CRT
|
||||
len = sprintf_s(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
|
||||
#ifdef __STDC_WANT_SECURE_LIB__
|
||||
len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
|
||||
#else
|
||||
len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
|
||||
#endif
|
||||
s->func(s->context, buffer, len);
|
||||
|
||||
for(i=0; i < y; i++)
|
||||
stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i)*x);
|
||||
stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i));
|
||||
STBIW_FREE(scratch);
|
||||
return 1;
|
||||
}
|
||||
|
@ -803,7 +855,7 @@ static unsigned int stbiw__zhash(unsigned char *data)
|
|||
|
||||
#endif // STBIW_ZLIB_COMPRESS
|
||||
|
||||
unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
|
||||
STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
|
||||
{
|
||||
#ifdef STBIW_ZLIB_COMPRESS
|
||||
// user provided a zlib compress implementation, use that
|
||||
|
@ -816,7 +868,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
|
|||
unsigned int bitbuf=0;
|
||||
int i,j, bitcount=0;
|
||||
unsigned char *out = NULL;
|
||||
unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(char**));
|
||||
unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(unsigned char**));
|
||||
if (hash_table == NULL)
|
||||
return NULL;
|
||||
if (quality < 5) quality = 5;
|
||||
|
@ -839,7 +891,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
|
|||
for (j=0; j < n; ++j) {
|
||||
if (hlist[j]-data > i-32768) { // if entry lies within window
|
||||
int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i);
|
||||
if (d >= best) best=d,bestloc=hlist[j];
|
||||
if (d >= best) { best=d; bestloc=hlist[j]; }
|
||||
}
|
||||
}
|
||||
// when hash table entry is too long, delete half the entries
|
||||
|
@ -898,8 +950,8 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
|
|||
int blocklen = (int) (data_len % 5552);
|
||||
j=0;
|
||||
while (j < data_len) {
|
||||
for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1;
|
||||
s1 %= 65521, s2 %= 65521;
|
||||
for (i=0; i < blocklen; ++i) { s1 += data[j+i]; s2 += s1; }
|
||||
s1 %= 65521; s2 %= 65521;
|
||||
j += blocklen;
|
||||
blocklen = 5552;
|
||||
}
|
||||
|
@ -917,6 +969,9 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
|
|||
|
||||
static unsigned int stbiw__crc32(unsigned char *buffer, int len)
|
||||
{
|
||||
#ifdef STBIW_CRC32
|
||||
return STBIW_CRC32(buffer, len);
|
||||
#else
|
||||
static unsigned int crc_table[256] =
|
||||
{
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
||||
|
@ -958,6 +1013,7 @@ static unsigned int stbiw__crc32(unsigned char *buffer, int len)
|
|||
for (i=0; i < len; ++i)
|
||||
crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
|
||||
return ~crc;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define stbiw__wpng4(o,a,b,c,d) ((o)[0]=STBIW_UCHAR(a),(o)[1]=STBIW_UCHAR(b),(o)[2]=STBIW_UCHAR(c),(o)[3]=STBIW_UCHAR(d),(o)+=4)
|
||||
|
@ -987,31 +1043,35 @@ static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int
|
|||
int i;
|
||||
int type = mymap[filter_type];
|
||||
unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y);
|
||||
int signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes;
|
||||
|
||||
if (type==0) {
|
||||
memcpy(line_buffer, z, width*n);
|
||||
return;
|
||||
}
|
||||
|
||||
// first loop isn't optimized since it's just one pixel
|
||||
for (i = 0; i < n; ++i) {
|
||||
switch (type) {
|
||||
case 0: line_buffer[i] = z[i]; break;
|
||||
case 1: line_buffer[i] = z[i]; break;
|
||||
case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
|
||||
case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break;
|
||||
case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-stride_bytes],0)); break;
|
||||
case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break;
|
||||
case 3: line_buffer[i] = z[i] - (z[i-signed_stride]>>1); break;
|
||||
case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-signed_stride],0)); break;
|
||||
case 5: line_buffer[i] = z[i]; break;
|
||||
case 6: line_buffer[i] = z[i]; break;
|
||||
}
|
||||
}
|
||||
for (i=n; i < width*n; ++i) {
|
||||
switch (type) {
|
||||
case 0: line_buffer[i] = z[i]; break;
|
||||
case 1: line_buffer[i] = z[i] - z[i-n]; break;
|
||||
case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
|
||||
case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break;
|
||||
case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break;
|
||||
case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
|
||||
case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
|
||||
}
|
||||
switch (type) {
|
||||
case 1: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-n]; break;
|
||||
case 2: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-signed_stride]; break;
|
||||
case 3: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - ((z[i-n] + z[i-signed_stride])>>1); break;
|
||||
case 4: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-signed_stride], z[i-signed_stride-n]); break;
|
||||
case 5: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - (z[i-n]>>1); break;
|
||||
case 6: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
|
||||
STBIWDEF unsigned char *stbi_write_png_to_mem(const unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
|
||||
{
|
||||
int force_filter = stbi_write_force_png_filter;
|
||||
int ctype[5] = { -1, 0, 4, 2, 6 };
|
||||
|
@ -1033,11 +1093,11 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
|
|||
int filter_type;
|
||||
if (force_filter > -1) {
|
||||
filter_type = force_filter;
|
||||
stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, force_filter, line_buffer);
|
||||
stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, force_filter, line_buffer);
|
||||
} else { // Estimate the best filter by running through all of them:
|
||||
int best_filter = 0, best_filter_val = 0x7fffffff, est, i;
|
||||
for (filter_type = 0; filter_type < 5; filter_type++) {
|
||||
stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, filter_type, line_buffer);
|
||||
stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, filter_type, line_buffer);
|
||||
|
||||
// Estimate the entropy of the line using this filter; the less, the better.
|
||||
est = 0;
|
||||
|
@ -1050,7 +1110,7 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
|
|||
}
|
||||
}
|
||||
if (filter_type != best_filter) { // If the last iteration already got us the best filter, don't redo it
|
||||
stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, best_filter, line_buffer);
|
||||
stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, best_filter, line_buffer);
|
||||
filter_type = best_filter;
|
||||
}
|
||||
}
|
||||
|
@ -1102,14 +1162,10 @@ STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const
|
|||
{
|
||||
FILE *f;
|
||||
int len;
|
||||
unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
|
||||
unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len);
|
||||
if (png == NULL) return 0;
|
||||
#ifdef STBI_MSC_SECURE_CRT
|
||||
if (fopen_s(&f, filename, "wb"))
|
||||
f = NULL;
|
||||
#else
|
||||
f = fopen(filename, "wb");
|
||||
#endif
|
||||
|
||||
f = stbiw__fopen(filename, "wb");
|
||||
if (!f) { STBIW_FREE(png); return 0; }
|
||||
fwrite(png, 1, len, f);
|
||||
fclose(f);
|
||||
|
@ -1121,7 +1177,7 @@ STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const
|
|||
STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int stride_bytes)
|
||||
{
|
||||
int len;
|
||||
unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
|
||||
unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len);
|
||||
if (png == NULL) return 0;
|
||||
func(context, png, len);
|
||||
STBIW_FREE(png);
|
||||
|
@ -1416,15 +1472,13 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
|
|||
for(x = 0; x < width; x += 8) {
|
||||
float YDU[64], UDU[64], VDU[64];
|
||||
for(row = y, pos = 0; row < y+8; ++row) {
|
||||
// row >= height => use last input row
|
||||
int clamped_row = (row < height) ? row : height - 1;
|
||||
int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
|
||||
for(col = x; col < x+8; ++col, ++pos) {
|
||||
int p = (stbi__flip_vertically_on_write ? height-1-row : row)*width*comp + col*comp;
|
||||
float r, g, b;
|
||||
if(row >= height) {
|
||||
p -= width*comp*(row+1 - height);
|
||||
}
|
||||
if(col >= width) {
|
||||
p -= comp*(col+1 - width);
|
||||
}
|
||||
// if col >= width => use pixel from last input column
|
||||
int p = base_p + ((col < width) ? col : (width-1))*comp;
|
||||
|
||||
r = imageData[p+0];
|
||||
g = imageData[p+ofsG];
|
||||
|
@ -1476,6 +1530,12 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
|
|||
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
|
||||
/* Revision history
|
||||
1.11 (2019-08-11)
|
||||
|
||||
1.10 (2019-02-07)
|
||||
support utf8 filenames in Windows; fix warnings and platform ifdefs
|
||||
1.09 (2018-02-11)
|
||||
fix typo in zlib quality API, improve STB_I_W_STATIC in C++
|
||||
1.08 (2018-01-29)
|
||||
add stbi__flip_vertically_on_write, external zlib, zlib quality, choose PNG filter
|
||||
1.07 (2017-07-24)
|
||||
|
|
213
raylib/external/stb_perlin.h
vendored
213
raylib/external/stb_perlin.h
vendored
|
@ -1,4 +1,4 @@
|
|||
// stb_perlin.h - v0.3 - perlin noise
|
||||
// stb_perlin.h - v0.4 - perlin noise
|
||||
// public domain single-file C implementation by Sean Barrett
|
||||
//
|
||||
// LICENSE
|
||||
|
@ -32,6 +32,19 @@
|
|||
// details of the implementation, even if you ask for larger or no
|
||||
// wrapping.)
|
||||
//
|
||||
// float stb_perlin_noise3_seed( float x,
|
||||
// float y,
|
||||
// float z,
|
||||
// int x_wrap=0,
|
||||
// int y_wrap=0,
|
||||
// int z_wrap=0,
|
||||
// int seed)
|
||||
//
|
||||
// As above, but 'seed' selects from multiple different variations of the
|
||||
// noise function. The current implementation only uses the bottom 8 bits
|
||||
// of 'seed', but possibly in the future more bits will be used.
|
||||
//
|
||||
//
|
||||
// Fractal Noise:
|
||||
//
|
||||
// Three common fractal noise functions are included, which produce
|
||||
|
@ -40,16 +53,13 @@
|
|||
// 'octaves' times, so this parameter will affect runtime.
|
||||
//
|
||||
// float stb_perlin_ridge_noise3(float x, float y, float z,
|
||||
// float lacunarity, float gain, float offset, int octaves,
|
||||
// int x_wrap, int y_wrap, int z_wrap);
|
||||
// float lacunarity, float gain, float offset, int octaves)
|
||||
//
|
||||
// float stb_perlin_fbm_noise3(float x, float y, float z,
|
||||
// float lacunarity, float gain, int octaves,
|
||||
// int x_wrap, int y_wrap, int z_wrap);
|
||||
// float lacunarity, float gain, int octaves)
|
||||
//
|
||||
// float stb_perlin_turbulence_noise3(float x, float y, float z,
|
||||
// float lacunarity, float gain,int octaves,
|
||||
// int x_wrap, int y_wrap, int z_wrap);
|
||||
// float lacunarity, float gain, int octaves)
|
||||
//
|
||||
// Typical values to start playing with:
|
||||
// octaves = 6 -- number of "octaves" of noise3() to sum
|
||||
|
@ -60,6 +70,7 @@
|
|||
//
|
||||
// Contributors:
|
||||
// Jack Mott - additional noise functions
|
||||
// Jordan Peck - seeded noise
|
||||
//
|
||||
|
||||
|
||||
|
@ -67,18 +78,20 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
extern float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap);
|
||||
extern float stb_perlin_ridge_noise3(float x, float y, float z,float lacunarity, float gain, float offset, int octaves,int x_wrap, int y_wrap, int z_wrap);
|
||||
extern float stb_perlin_fbm_noise3(float x, float y, float z,float lacunarity, float gain, int octaves,int x_wrap, int y_wrap, int z_wrap);
|
||||
extern float stb_perlin_turbulence_noise3(float x, float y, float z, float lacunarity, float gain, int octaves,int x_wrap, int y_wrap, int z_wrap);
|
||||
extern float stb_perlin_ridge_noise3(float x, float y, float z, float lacunarity, float gain, float offset, int octaves);
|
||||
extern float stb_perlin_fbm_noise3(float x, float y, float z, float lacunarity, float gain, int octaves);
|
||||
extern float stb_perlin_turbulence_noise3(float x, float y, float z, float lacunarity, float gain, int octaves);
|
||||
extern float stb_perlin_noise3_wrap_nonpow2(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, unsigned char seed);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef STB_PERLIN_IMPLEMENTATION
|
||||
|
||||
#include <math.h> // fabs()
|
||||
|
||||
// not same permutation table as Perlin's reference to avoid copyright issues;
|
||||
// Perlin's table can be found at http://mrl.nyu.edu/~perlin/noise/
|
||||
// @OPTIMIZE: should this be unsigned char instead of int for cache?
|
||||
static unsigned char stb__perlin_randtab[512] =
|
||||
{
|
||||
23, 125, 161, 52, 103, 117, 70, 37, 247, 101, 203, 169, 124, 126, 44, 123,
|
||||
|
@ -115,6 +128,51 @@ static unsigned char stb__perlin_randtab[512] =
|
|||
131, 11, 163, 99, 234, 81, 227, 147, 156, 176, 17, 142, 69, 12, 110, 62,
|
||||
27, 255, 0, 194, 59, 116, 242, 252, 19, 21, 187, 53, 207, 129, 64, 135,
|
||||
61, 40, 167, 237, 102, 223, 106, 159, 197, 189, 215, 137, 36, 32, 22, 5,
|
||||
};
|
||||
|
||||
|
||||
// perlin's gradient has 12 cases so some get used 1/16th of the time
|
||||
// and some 2/16ths. We reduce bias by changing those fractions
|
||||
// to 5/64ths and 6/64ths
|
||||
|
||||
// this array is designed to match the previous implementation
|
||||
// of gradient hash: indices[stb__perlin_randtab[i]&63]
|
||||
static unsigned char stb__perlin_randtab_grad_idx[512] =
|
||||
{
|
||||
7, 9, 5, 0, 11, 1, 6, 9, 3, 9, 11, 1, 8, 10, 4, 7,
|
||||
8, 6, 1, 5, 3, 10, 9, 10, 0, 8, 4, 1, 5, 2, 7, 8,
|
||||
7, 11, 9, 10, 1, 0, 4, 7, 5, 0, 11, 6, 1, 4, 2, 8,
|
||||
8, 10, 4, 9, 9, 2, 5, 7, 9, 1, 7, 2, 2, 6, 11, 5,
|
||||
5, 4, 6, 9, 0, 1, 1, 0, 7, 6, 9, 8, 4, 10, 3, 1,
|
||||
2, 8, 8, 9, 10, 11, 5, 11, 11, 2, 6, 10, 3, 4, 2, 4,
|
||||
9, 10, 3, 2, 6, 3, 6, 10, 5, 3, 4, 10, 11, 2, 9, 11,
|
||||
1, 11, 10, 4, 9, 4, 11, 0, 4, 11, 4, 0, 0, 0, 7, 6,
|
||||
10, 4, 1, 3, 11, 5, 3, 4, 2, 9, 1, 3, 0, 1, 8, 0,
|
||||
6, 7, 8, 7, 0, 4, 6, 10, 8, 2, 3, 11, 11, 8, 0, 2,
|
||||
4, 8, 3, 0, 0, 10, 6, 1, 2, 2, 4, 5, 6, 0, 1, 3,
|
||||
11, 9, 5, 5, 9, 6, 9, 8, 3, 8, 1, 8, 9, 6, 9, 11,
|
||||
10, 7, 5, 6, 5, 9, 1, 3, 7, 0, 2, 10, 11, 2, 6, 1,
|
||||
3, 11, 7, 7, 2, 1, 7, 3, 0, 8, 1, 1, 5, 0, 6, 10,
|
||||
11, 11, 0, 2, 7, 0, 10, 8, 3, 5, 7, 1, 11, 1, 0, 7,
|
||||
9, 0, 11, 5, 10, 3, 2, 3, 5, 9, 7, 9, 8, 4, 6, 5,
|
||||
|
||||
// and a second copy so we don't need an extra mask or static initializer
|
||||
7, 9, 5, 0, 11, 1, 6, 9, 3, 9, 11, 1, 8, 10, 4, 7,
|
||||
8, 6, 1, 5, 3, 10, 9, 10, 0, 8, 4, 1, 5, 2, 7, 8,
|
||||
7, 11, 9, 10, 1, 0, 4, 7, 5, 0, 11, 6, 1, 4, 2, 8,
|
||||
8, 10, 4, 9, 9, 2, 5, 7, 9, 1, 7, 2, 2, 6, 11, 5,
|
||||
5, 4, 6, 9, 0, 1, 1, 0, 7, 6, 9, 8, 4, 10, 3, 1,
|
||||
2, 8, 8, 9, 10, 11, 5, 11, 11, 2, 6, 10, 3, 4, 2, 4,
|
||||
9, 10, 3, 2, 6, 3, 6, 10, 5, 3, 4, 10, 11, 2, 9, 11,
|
||||
1, 11, 10, 4, 9, 4, 11, 0, 4, 11, 4, 0, 0, 0, 7, 6,
|
||||
10, 4, 1, 3, 11, 5, 3, 4, 2, 9, 1, 3, 0, 1, 8, 0,
|
||||
6, 7, 8, 7, 0, 4, 6, 10, 8, 2, 3, 11, 11, 8, 0, 2,
|
||||
4, 8, 3, 0, 0, 10, 6, 1, 2, 2, 4, 5, 6, 0, 1, 3,
|
||||
11, 9, 5, 5, 9, 6, 9, 8, 3, 8, 1, 8, 9, 6, 9, 11,
|
||||
10, 7, 5, 6, 5, 9, 1, 3, 7, 0, 2, 10, 11, 2, 6, 1,
|
||||
3, 11, 7, 7, 2, 1, 7, 3, 0, 8, 1, 1, 5, 0, 6, 10,
|
||||
11, 11, 0, 2, 7, 0, 10, 8, 3, 5, 7, 1, 11, 1, 0, 7,
|
||||
9, 0, 11, 5, 10, 3, 2, 3, 5, 9, 7, 9, 8, 4, 6, 5,
|
||||
};
|
||||
|
||||
static float stb__perlin_lerp(float a, float b, float t)
|
||||
|
@ -124,12 +182,12 @@ static float stb__perlin_lerp(float a, float b, float t)
|
|||
|
||||
static int stb__perlin_fastfloor(float a)
|
||||
{
|
||||
int ai = (int) a;
|
||||
return (a < ai) ? ai-1 : ai;
|
||||
int ai = (int) a;
|
||||
return (a < ai) ? ai-1 : ai;
|
||||
}
|
||||
|
||||
// different grad function from Perlin's, but easy to modify to match reference
|
||||
static float stb__perlin_grad(int hash, float x, float y, float z)
|
||||
static float stb__perlin_grad(int grad_idx, float x, float y, float z)
|
||||
{
|
||||
static float basis[12][4] =
|
||||
{
|
||||
|
@ -147,26 +205,11 @@ static float stb__perlin_grad(int hash, float x, float y, float z)
|
|||
{ 0,-1,-1 },
|
||||
};
|
||||
|
||||
// perlin's gradient has 12 cases so some get used 1/16th of the time
|
||||
// and some 2/16ths. We reduce bias by changing those fractions
|
||||
// to 5/64ths and 6/64ths, and the same 4 cases get the extra weight.
|
||||
static unsigned char indices[64] =
|
||||
{
|
||||
0,1,2,3,4,5,6,7,8,9,10,11,
|
||||
0,9,1,11,
|
||||
0,1,2,3,4,5,6,7,8,9,10,11,
|
||||
0,1,2,3,4,5,6,7,8,9,10,11,
|
||||
0,1,2,3,4,5,6,7,8,9,10,11,
|
||||
0,1,2,3,4,5,6,7,8,9,10,11,
|
||||
};
|
||||
|
||||
// if you use reference permutation table, change 63 below to 15 to match reference
|
||||
// (this is why the ordering of the table above is funky)
|
||||
float *grad = basis[indices[hash & 63]];
|
||||
float *grad = basis[grad_idx];
|
||||
return grad[0]*x + grad[1]*y + grad[2]*z;
|
||||
}
|
||||
|
||||
float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap)
|
||||
float stb_perlin_noise3_internal(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, unsigned char seed)
|
||||
{
|
||||
float u,v,w;
|
||||
float n000,n001,n010,n011,n100,n101,n110,n111;
|
||||
|
@ -190,22 +233,22 @@ float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z
|
|||
y -= py; v = stb__perlin_ease(y);
|
||||
z -= pz; w = stb__perlin_ease(z);
|
||||
|
||||
r0 = stb__perlin_randtab[x0];
|
||||
r1 = stb__perlin_randtab[x1];
|
||||
r0 = stb__perlin_randtab[x0+seed];
|
||||
r1 = stb__perlin_randtab[x1+seed];
|
||||
|
||||
r00 = stb__perlin_randtab[r0+y0];
|
||||
r01 = stb__perlin_randtab[r0+y1];
|
||||
r10 = stb__perlin_randtab[r1+y0];
|
||||
r11 = stb__perlin_randtab[r1+y1];
|
||||
|
||||
n000 = stb__perlin_grad(stb__perlin_randtab[r00+z0], x , y , z );
|
||||
n001 = stb__perlin_grad(stb__perlin_randtab[r00+z1], x , y , z-1 );
|
||||
n010 = stb__perlin_grad(stb__perlin_randtab[r01+z0], x , y-1, z );
|
||||
n011 = stb__perlin_grad(stb__perlin_randtab[r01+z1], x , y-1, z-1 );
|
||||
n100 = stb__perlin_grad(stb__perlin_randtab[r10+z0], x-1, y , z );
|
||||
n101 = stb__perlin_grad(stb__perlin_randtab[r10+z1], x-1, y , z-1 );
|
||||
n110 = stb__perlin_grad(stb__perlin_randtab[r11+z0], x-1, y-1, z );
|
||||
n111 = stb__perlin_grad(stb__perlin_randtab[r11+z1], x-1, y-1, z-1 );
|
||||
n000 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r00+z0], x , y , z );
|
||||
n001 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r00+z1], x , y , z-1 );
|
||||
n010 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r01+z0], x , y-1, z );
|
||||
n011 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r01+z1], x , y-1, z-1 );
|
||||
n100 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r10+z0], x-1, y , z );
|
||||
n101 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r10+z1], x-1, y , z-1 );
|
||||
n110 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r11+z0], x-1, y-1, z );
|
||||
n111 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r11+z1], x-1, y-1, z-1 );
|
||||
|
||||
n00 = stb__perlin_lerp(n000,n001,w);
|
||||
n01 = stb__perlin_lerp(n010,n011,w);
|
||||
|
@ -218,7 +261,17 @@ float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z
|
|||
return stb__perlin_lerp(n0,n1,u);
|
||||
}
|
||||
|
||||
float stb_perlin_ridge_noise3(float x, float y, float z,float lacunarity, float gain, float offset, int octaves,int x_wrap, int y_wrap, int z_wrap)
|
||||
float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap)
|
||||
{
|
||||
return stb_perlin_noise3_internal(x,y,z,x_wrap,y_wrap,z_wrap,0);
|
||||
}
|
||||
|
||||
float stb_perlin_noise3_seed(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, int seed)
|
||||
{
|
||||
return stb_perlin_noise3_internal(x,y,z,x_wrap,y_wrap,z_wrap, (unsigned char) seed);
|
||||
}
|
||||
|
||||
float stb_perlin_ridge_noise3(float x, float y, float z, float lacunarity, float gain, float offset, int octaves)
|
||||
{
|
||||
int i;
|
||||
float frequency = 1.0f;
|
||||
|
@ -227,9 +280,8 @@ float stb_perlin_ridge_noise3(float x, float y, float z,float lacunarity, float
|
|||
float sum = 0.0f;
|
||||
|
||||
for (i = 0; i < octaves; i++) {
|
||||
float r = (float)(stb_perlin_noise3(x*frequency,y*frequency,z*frequency,x_wrap,y_wrap,z_wrap));
|
||||
r = r<0 ? -r : r; // fabs()
|
||||
r = offset - r;
|
||||
float r = stb_perlin_noise3_internal(x*frequency,y*frequency,z*frequency,0,0,0,(unsigned char)i);
|
||||
r = offset - (float) fabs(r);
|
||||
r = r*r;
|
||||
sum += r*amplitude*prev;
|
||||
prev = r;
|
||||
|
@ -239,7 +291,7 @@ float stb_perlin_ridge_noise3(float x, float y, float z,float lacunarity, float
|
|||
return sum;
|
||||
}
|
||||
|
||||
float stb_perlin_fbm_noise3(float x, float y, float z,float lacunarity, float gain, int octaves,int x_wrap, int y_wrap, int z_wrap)
|
||||
float stb_perlin_fbm_noise3(float x, float y, float z, float lacunarity, float gain, int octaves)
|
||||
{
|
||||
int i;
|
||||
float frequency = 1.0f;
|
||||
|
@ -247,14 +299,14 @@ float stb_perlin_fbm_noise3(float x, float y, float z,float lacunarity, float ga
|
|||
float sum = 0.0f;
|
||||
|
||||
for (i = 0; i < octaves; i++) {
|
||||
sum += stb_perlin_noise3(x*frequency,y*frequency,z*frequency,x_wrap,y_wrap,z_wrap)*amplitude;
|
||||
sum += stb_perlin_noise3_internal(x*frequency,y*frequency,z*frequency,0,0,0,(unsigned char)i)*amplitude;
|
||||
frequency *= lacunarity;
|
||||
amplitude *= gain;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
float stb_perlin_turbulence_noise3(float x, float y, float z, float lacunarity, float gain, int octaves,int x_wrap, int y_wrap, int z_wrap)
|
||||
float stb_perlin_turbulence_noise3(float x, float y, float z, float lacunarity, float gain, int octaves)
|
||||
{
|
||||
int i;
|
||||
float frequency = 1.0f;
|
||||
|
@ -262,15 +314,74 @@ float stb_perlin_turbulence_noise3(float x, float y, float z, float lacunarity,
|
|||
float sum = 0.0f;
|
||||
|
||||
for (i = 0; i < octaves; i++) {
|
||||
float r = stb_perlin_noise3(x*frequency,y*frequency,z*frequency,x_wrap,y_wrap,z_wrap)*amplitude;
|
||||
r = r<0 ? -r : r; // fabs()
|
||||
sum += r;
|
||||
float r = stb_perlin_noise3_internal(x*frequency,y*frequency,z*frequency,0,0,0,(unsigned char)i)*amplitude;
|
||||
sum += (float) fabs(r);
|
||||
frequency *= lacunarity;
|
||||
amplitude *= gain;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
float stb_perlin_noise3_wrap_nonpow2(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, unsigned char seed)
|
||||
{
|
||||
float u,v,w;
|
||||
float n000,n001,n010,n011,n100,n101,n110,n111;
|
||||
float n00,n01,n10,n11;
|
||||
float n0,n1;
|
||||
|
||||
int px = stb__perlin_fastfloor(x);
|
||||
int py = stb__perlin_fastfloor(y);
|
||||
int pz = stb__perlin_fastfloor(z);
|
||||
int x_wrap2 = (x_wrap ? x_wrap : 256);
|
||||
int y_wrap2 = (y_wrap ? y_wrap : 256);
|
||||
int z_wrap2 = (z_wrap ? z_wrap : 256);
|
||||
int x0 = px % x_wrap2, x1;
|
||||
int y0 = py % y_wrap2, y1;
|
||||
int z0 = pz % z_wrap2, z1;
|
||||
int r0,r1, r00,r01,r10,r11;
|
||||
|
||||
if (x0 < 0) x0 += x_wrap2;
|
||||
if (y0 < 0) y0 += y_wrap2;
|
||||
if (z0 < 0) z0 += z_wrap2;
|
||||
x1 = (x0+1) % x_wrap2;
|
||||
y1 = (y0+1) % y_wrap2;
|
||||
z1 = (z0+1) % z_wrap2;
|
||||
|
||||
#define stb__perlin_ease(a) (((a*6-15)*a + 10) * a * a * a)
|
||||
|
||||
x -= px; u = stb__perlin_ease(x);
|
||||
y -= py; v = stb__perlin_ease(y);
|
||||
z -= pz; w = stb__perlin_ease(z);
|
||||
|
||||
r0 = stb__perlin_randtab[x0];
|
||||
r0 = stb__perlin_randtab[r0+seed];
|
||||
r1 = stb__perlin_randtab[x1];
|
||||
r1 = stb__perlin_randtab[r1+seed];
|
||||
|
||||
r00 = stb__perlin_randtab[r0+y0];
|
||||
r01 = stb__perlin_randtab[r0+y1];
|
||||
r10 = stb__perlin_randtab[r1+y0];
|
||||
r11 = stb__perlin_randtab[r1+y1];
|
||||
|
||||
n000 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r00+z0], x , y , z );
|
||||
n001 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r00+z1], x , y , z-1 );
|
||||
n010 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r01+z0], x , y-1, z );
|
||||
n011 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r01+z1], x , y-1, z-1 );
|
||||
n100 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r10+z0], x-1, y , z );
|
||||
n101 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r10+z1], x-1, y , z-1 );
|
||||
n110 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r11+z0], x-1, y-1, z );
|
||||
n111 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r11+z1], x-1, y-1, z-1 );
|
||||
|
||||
n00 = stb__perlin_lerp(n000,n001,w);
|
||||
n01 = stb__perlin_lerp(n010,n011,w);
|
||||
n10 = stb__perlin_lerp(n100,n101,w);
|
||||
n11 = stb__perlin_lerp(n110,n111,w);
|
||||
|
||||
n0 = stb__perlin_lerp(n00,n01,v);
|
||||
n1 = stb__perlin_lerp(n10,n11,v);
|
||||
|
||||
return stb__perlin_lerp(n0,n1,u);
|
||||
}
|
||||
#endif // STB_PERLIN_IMPLEMENTATION
|
||||
|
||||
/*
|
||||
|
|
20
raylib/external/stb_rect_pack.h
vendored
20
raylib/external/stb_rect_pack.h
vendored
|
@ -1,4 +1,4 @@
|
|||
// stb_rect_pack.h - v0.11 - public domain - rectangle packing
|
||||
// stb_rect_pack.h - v1.00 - public domain - rectangle packing
|
||||
// Sean Barrett 2014
|
||||
//
|
||||
// Useful for e.g. packing rectangular textures into an atlas.
|
||||
|
@ -31,9 +31,12 @@
|
|||
//
|
||||
// Bugfixes / warning fixes
|
||||
// Jeremy Jaussaud
|
||||
// Fabian Giesen
|
||||
//
|
||||
// Version history:
|
||||
//
|
||||
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
|
||||
// 0.99 (2019-02-07) warning fixes
|
||||
// 0.11 (2017-03-03) return packing success/fail result
|
||||
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
|
||||
// 0.09 (2016-08-27) fix compiler warnings
|
||||
|
@ -347,6 +350,13 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
|
|||
width -= width % c->align;
|
||||
STBRP_ASSERT(width % c->align == 0);
|
||||
|
||||
// if it can't possibly fit, bail immediately
|
||||
if (width > c->width || height > c->height) {
|
||||
fr.prev_link = NULL;
|
||||
fr.x = fr.y = 0;
|
||||
return fr;
|
||||
}
|
||||
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
while (node->x + width <= c->width) {
|
||||
|
@ -410,7 +420,7 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
|
|||
}
|
||||
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
|
||||
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
|
||||
if (y + height < c->height) {
|
||||
if (y + height <= c->height) {
|
||||
if (y <= best_y) {
|
||||
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
|
||||
best_x = xpos;
|
||||
|
@ -492,17 +502,14 @@ static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, i
|
|||
STBRP_ASSERT(cur->next == NULL);
|
||||
|
||||
{
|
||||
stbrp_node *L1 = NULL, *L2 = NULL;
|
||||
int count=0;
|
||||
cur = context->active_head;
|
||||
while (cur) {
|
||||
L1 = cur;
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
cur = context->free_head;
|
||||
while (cur) {
|
||||
L2 = cur;
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
|
@ -544,9 +551,6 @@ STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int nu
|
|||
// we use the 'was_packed' field internally to allow sorting/unsorting
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = i;
|
||||
#ifndef STBRP_LARGE_RECTS
|
||||
STBRP_ASSERT(rects[i].w <= 0xffff && rects[i].h <= 0xffff);
|
||||
#endif
|
||||
}
|
||||
|
||||
// sort according to heuristic
|
||||
|
|
387
raylib/external/stb_truetype.h
vendored
387
raylib/external/stb_truetype.h
vendored
|
@ -1,5 +1,5 @@
|
|||
// stb_truetype.h - v1.18 - public domain
|
||||
// authored from 2009-2016 by Sean Barrett / RAD Game Tools
|
||||
// stb_truetype.h - v1.22 - public domain
|
||||
// authored from 2009-2019 by Sean Barrett / RAD Game Tools
|
||||
//
|
||||
// This library processes TrueType files:
|
||||
// parse files
|
||||
|
@ -22,12 +22,14 @@
|
|||
// Mikko Mononen: compound shape support, more cmap formats
|
||||
// Tor Andersson: kerning, subpixel rendering
|
||||
// Dougall Johnson: OpenType / Type 2 font handling
|
||||
// Daniel Ribeiro Maciel: basic GPOS-based kerning
|
||||
//
|
||||
// Misc other:
|
||||
// Ryan Gordon
|
||||
// Simon Glass
|
||||
// github:IntellectualKitty
|
||||
// Imanol Celaya
|
||||
// Daniel Ribeiro Maciel
|
||||
//
|
||||
// Bug/warning reports/fixes:
|
||||
// "Zer" on mollyrocket Fabian "ryg" Giesen
|
||||
|
@ -44,9 +46,14 @@
|
|||
// Rob Loach Cort Stratton
|
||||
// Kenney Phillis Jr. github:oyvindjam
|
||||
// Brian Costabile github:vassvik
|
||||
// Ken Voskuil (kaesve) Ryan Griege
|
||||
//
|
||||
// VERSION HISTORY
|
||||
//
|
||||
// 1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined
|
||||
// 1.21 (2019-02-25) fix warning
|
||||
// 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics()
|
||||
// 1.19 (2018-02-11) GPOS kerning, STBTT_fmod
|
||||
// 1.18 (2018-01-29) add missing function
|
||||
// 1.17 (2017-07-23) make more arguments const; doc fix
|
||||
// 1.16 (2017-07-12) SDF support
|
||||
|
@ -72,7 +79,7 @@
|
|||
//
|
||||
// USAGE
|
||||
//
|
||||
// Include this file in whatever places neeed to refer to it. In ONE C/C++
|
||||
// Include this file in whatever places need to refer to it. In ONE C/C++
|
||||
// file, write:
|
||||
// #define STB_TRUETYPE_IMPLEMENTATION
|
||||
// before the #include of this file. This expands out the actual
|
||||
|
@ -239,19 +246,6 @@
|
|||
// recommend it.
|
||||
//
|
||||
//
|
||||
// SOURCE STATISTICS (based on v0.6c, 2050 LOC)
|
||||
//
|
||||
// Documentation & header file 520 LOC \___ 660 LOC documentation
|
||||
// Sample code 140 LOC /
|
||||
// Truetype parsing 620 LOC ---- 620 LOC TrueType
|
||||
// Software rasterization 240 LOC \ .
|
||||
// Curve tesselation 120 LOC \__ 550 LOC Bitmap creation
|
||||
// Bitmap management 100 LOC /
|
||||
// Baked bitmap interface 70 LOC /
|
||||
// Font name matching & access 150 LOC ---- 150
|
||||
// C runtime library abstraction 60 LOC ---- 60
|
||||
//
|
||||
//
|
||||
// PERFORMANCE MEASUREMENTS FOR 1.06:
|
||||
//
|
||||
// 32-bit 64-bit
|
||||
|
@ -411,7 +405,8 @@ int main(int arg, char **argv)
|
|||
//// INTEGRATION WITH YOUR CODEBASE
|
||||
////
|
||||
//// The following sections allow you to supply alternate definitions
|
||||
//// of C library functions used by stb_truetype.
|
||||
//// of C library functions used by stb_truetype, e.g. if you don't
|
||||
//// link with the C runtime library.
|
||||
|
||||
#ifdef STB_TRUETYPE_IMPLEMENTATION
|
||||
// #define your own (u)stbtt_int8/16/32 before including to override this
|
||||
|
@ -427,7 +422,7 @@ int main(int arg, char **argv)
|
|||
typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1];
|
||||
typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1];
|
||||
|
||||
// #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h
|
||||
// e.g. #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h
|
||||
#ifndef STBTT_ifloor
|
||||
#include <math.h>
|
||||
#define STBTT_ifloor(x) ((int) floor(x))
|
||||
|
@ -440,6 +435,11 @@ int main(int arg, char **argv)
|
|||
#define STBTT_pow(x,y) pow(x,y)
|
||||
#endif
|
||||
|
||||
#ifndef STBTT_fmod
|
||||
#include <math.h>
|
||||
#define STBTT_fmod(x,y) fmod(x,y)
|
||||
#endif
|
||||
|
||||
#ifndef STBTT_cos
|
||||
#include <math.h>
|
||||
#define STBTT_cos(x) cos(x)
|
||||
|
@ -547,6 +547,8 @@ STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int p
|
|||
//
|
||||
// It's inefficient; you might want to c&p it and optimize it.
|
||||
|
||||
STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap);
|
||||
// Query the font vertical metrics without having to create a font first.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -632,6 +634,12 @@ STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h
|
|||
// To use with PackFontRangesGather etc., you must set it before calls
|
||||
// call to PackFontRangesGatherRects.
|
||||
|
||||
STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip);
|
||||
// If skip != 0, this tells stb_truetype to skip any codepoints for which
|
||||
// there is no corresponding glyph. If skip=0, which is the default, then
|
||||
// codepoints without a glyph recived the font's "missing character" glyph,
|
||||
// typically an empty box by convention.
|
||||
|
||||
STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above
|
||||
int char_index, // character to display
|
||||
float *xpos, float *ypos, // pointers to current position in screen pixel space
|
||||
|
@ -660,6 +668,7 @@ struct stbtt_pack_context {
|
|||
int height;
|
||||
int stride_in_bytes;
|
||||
int padding;
|
||||
int skip_missing;
|
||||
unsigned int h_oversample, v_oversample;
|
||||
unsigned char *pixels;
|
||||
void *nodes;
|
||||
|
@ -685,7 +694,7 @@ STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index);
|
|||
// file will only define one font and it always be at offset 0, so it will
|
||||
// return '0' for index 0, and -1 for all other indices.
|
||||
|
||||
// The following structure is defined publically so you can declare one on
|
||||
// The following structure is defined publicly so you can declare one on
|
||||
// the stack or as a global or etc, but you should treat it as opaque.
|
||||
struct stbtt_fontinfo
|
||||
{
|
||||
|
@ -695,7 +704,7 @@ struct stbtt_fontinfo
|
|||
|
||||
int numGlyphs; // number of glyphs, needed for range checking
|
||||
|
||||
int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf
|
||||
int loca,head,glyf,hhea,hmtx,kern,gpos; // table locations as offset from start of .ttf
|
||||
int index_map; // a cmap mapping for our chosen character encoding
|
||||
int indexToLocFormat; // format needed to map from glyph index to glyph
|
||||
|
||||
|
@ -724,6 +733,7 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep
|
|||
// and you want a speed-up, call this function with the character you're
|
||||
// going to process, then use glyph-based functions instead of the
|
||||
// codepoint-based functions.
|
||||
// Returns 0 if the character codepoint is not defined in the font.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -811,7 +821,7 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
|
|||
// returns # of vertices and fills *vertices with the pointer to them
|
||||
// these are expressed in "unscaled" coordinates
|
||||
//
|
||||
// The shape is a series of countours. Each one starts with
|
||||
// The shape is a series of contours. Each one starts with
|
||||
// a STBTT_moveto, then consists of a series of mixed
|
||||
// STBTT_lineto and STBTT_curveto segments. A lineto
|
||||
// draws a line from previous endpoint to its x,y; a curveto
|
||||
|
@ -907,7 +917,7 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc
|
|||
STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff);
|
||||
// These functions compute a discretized SDF field for a single character, suitable for storing
|
||||
// in a single-channel texture, sampling with bilinear filtering, and testing against
|
||||
// larger than some threshhold to produce scalable fonts.
|
||||
// larger than some threshold to produce scalable fonts.
|
||||
// info -- the font
|
||||
// scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap
|
||||
// glyph/codepoint -- the character to generate the SDF for
|
||||
|
@ -1338,6 +1348,7 @@ static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, in
|
|||
info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required
|
||||
info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required
|
||||
info->kern = stbtt__find_table(data, fontstart, "kern"); // not required
|
||||
info->gpos = stbtt__find_table(data, fontstart, "GPOS"); // not required
|
||||
|
||||
if (!cmap || !info->head || !info->hhea || !info->hmtx)
|
||||
return 0;
|
||||
|
@ -2256,7 +2267,7 @@ STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_inde
|
|||
}
|
||||
}
|
||||
|
||||
STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
|
||||
static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
|
||||
{
|
||||
stbtt_uint8 *data = info->data + info->kern;
|
||||
stbtt_uint32 needle, straw;
|
||||
|
@ -2286,9 +2297,260 @@ STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph)
|
||||
{
|
||||
stbtt_uint16 coverageFormat = ttUSHORT(coverageTable);
|
||||
switch(coverageFormat) {
|
||||
case 1: {
|
||||
stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2);
|
||||
|
||||
// Binary search.
|
||||
stbtt_int32 l=0, r=glyphCount-1, m;
|
||||
int straw, needle=glyph;
|
||||
while (l <= r) {
|
||||
stbtt_uint8 *glyphArray = coverageTable + 4;
|
||||
stbtt_uint16 glyphID;
|
||||
m = (l + r) >> 1;
|
||||
glyphID = ttUSHORT(glyphArray + 2 * m);
|
||||
straw = glyphID;
|
||||
if (needle < straw)
|
||||
r = m - 1;
|
||||
else if (needle > straw)
|
||||
l = m + 1;
|
||||
else {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case 2: {
|
||||
stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2);
|
||||
stbtt_uint8 *rangeArray = coverageTable + 4;
|
||||
|
||||
// Binary search.
|
||||
stbtt_int32 l=0, r=rangeCount-1, m;
|
||||
int strawStart, strawEnd, needle=glyph;
|
||||
while (l <= r) {
|
||||
stbtt_uint8 *rangeRecord;
|
||||
m = (l + r) >> 1;
|
||||
rangeRecord = rangeArray + 6 * m;
|
||||
strawStart = ttUSHORT(rangeRecord);
|
||||
strawEnd = ttUSHORT(rangeRecord + 2);
|
||||
if (needle < strawStart)
|
||||
r = m - 1;
|
||||
else if (needle > strawEnd)
|
||||
l = m + 1;
|
||||
else {
|
||||
stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4);
|
||||
return startCoverageIndex + glyph - strawStart;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
default: {
|
||||
// There are no other cases.
|
||||
STBTT_assert(0);
|
||||
} break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph)
|
||||
{
|
||||
stbtt_uint16 classDefFormat = ttUSHORT(classDefTable);
|
||||
switch(classDefFormat)
|
||||
{
|
||||
case 1: {
|
||||
stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2);
|
||||
stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4);
|
||||
stbtt_uint8 *classDef1ValueArray = classDefTable + 6;
|
||||
|
||||
if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount)
|
||||
return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID));
|
||||
|
||||
classDefTable = classDef1ValueArray + 2 * glyphCount;
|
||||
} break;
|
||||
|
||||
case 2: {
|
||||
stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2);
|
||||
stbtt_uint8 *classRangeRecords = classDefTable + 4;
|
||||
|
||||
// Binary search.
|
||||
stbtt_int32 l=0, r=classRangeCount-1, m;
|
||||
int strawStart, strawEnd, needle=glyph;
|
||||
while (l <= r) {
|
||||
stbtt_uint8 *classRangeRecord;
|
||||
m = (l + r) >> 1;
|
||||
classRangeRecord = classRangeRecords + 6 * m;
|
||||
strawStart = ttUSHORT(classRangeRecord);
|
||||
strawEnd = ttUSHORT(classRangeRecord + 2);
|
||||
if (needle < strawStart)
|
||||
r = m - 1;
|
||||
else if (needle > strawEnd)
|
||||
l = m + 1;
|
||||
else
|
||||
return (stbtt_int32)ttUSHORT(classRangeRecord + 4);
|
||||
}
|
||||
|
||||
classDefTable = classRangeRecords + 6 * classRangeCount;
|
||||
} break;
|
||||
|
||||
default: {
|
||||
// There are no other cases.
|
||||
STBTT_assert(0);
|
||||
} break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Define to STBTT_assert(x) if you want to break on unimplemented formats.
|
||||
#define STBTT_GPOS_TODO_assert(x)
|
||||
|
||||
static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
|
||||
{
|
||||
stbtt_uint16 lookupListOffset;
|
||||
stbtt_uint8 *lookupList;
|
||||
stbtt_uint16 lookupCount;
|
||||
stbtt_uint8 *data;
|
||||
stbtt_int32 i;
|
||||
|
||||
if (!info->gpos) return 0;
|
||||
|
||||
data = info->data + info->gpos;
|
||||
|
||||
if (ttUSHORT(data+0) != 1) return 0; // Major version 1
|
||||
if (ttUSHORT(data+2) != 0) return 0; // Minor version 0
|
||||
|
||||
lookupListOffset = ttUSHORT(data+8);
|
||||
lookupList = data + lookupListOffset;
|
||||
lookupCount = ttUSHORT(lookupList);
|
||||
|
||||
for (i=0; i<lookupCount; ++i) {
|
||||
stbtt_uint16 lookupOffset = ttUSHORT(lookupList + 2 + 2 * i);
|
||||
stbtt_uint8 *lookupTable = lookupList + lookupOffset;
|
||||
|
||||
stbtt_uint16 lookupType = ttUSHORT(lookupTable);
|
||||
stbtt_uint16 subTableCount = ttUSHORT(lookupTable + 4);
|
||||
stbtt_uint8 *subTableOffsets = lookupTable + 6;
|
||||
switch(lookupType) {
|
||||
case 2: { // Pair Adjustment Positioning Subtable
|
||||
stbtt_int32 sti;
|
||||
for (sti=0; sti<subTableCount; sti++) {
|
||||
stbtt_uint16 subtableOffset = ttUSHORT(subTableOffsets + 2 * sti);
|
||||
stbtt_uint8 *table = lookupTable + subtableOffset;
|
||||
stbtt_uint16 posFormat = ttUSHORT(table);
|
||||
stbtt_uint16 coverageOffset = ttUSHORT(table + 2);
|
||||
stbtt_int32 coverageIndex = stbtt__GetCoverageIndex(table + coverageOffset, glyph1);
|
||||
if (coverageIndex == -1) continue;
|
||||
|
||||
switch (posFormat) {
|
||||
case 1: {
|
||||
stbtt_int32 l, r, m;
|
||||
int straw, needle;
|
||||
stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
|
||||
stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
|
||||
stbtt_int32 valueRecordPairSizeInBytes = 2;
|
||||
stbtt_uint16 pairSetCount = ttUSHORT(table + 8);
|
||||
stbtt_uint16 pairPosOffset = ttUSHORT(table + 10 + 2 * coverageIndex);
|
||||
stbtt_uint8 *pairValueTable = table + pairPosOffset;
|
||||
stbtt_uint16 pairValueCount = ttUSHORT(pairValueTable);
|
||||
stbtt_uint8 *pairValueArray = pairValueTable + 2;
|
||||
// TODO: Support more formats.
|
||||
STBTT_GPOS_TODO_assert(valueFormat1 == 4);
|
||||
if (valueFormat1 != 4) return 0;
|
||||
STBTT_GPOS_TODO_assert(valueFormat2 == 0);
|
||||
if (valueFormat2 != 0) return 0;
|
||||
|
||||
STBTT_assert(coverageIndex < pairSetCount);
|
||||
STBTT__NOTUSED(pairSetCount);
|
||||
|
||||
needle=glyph2;
|
||||
r=pairValueCount-1;
|
||||
l=0;
|
||||
|
||||
// Binary search.
|
||||
while (l <= r) {
|
||||
stbtt_uint16 secondGlyph;
|
||||
stbtt_uint8 *pairValue;
|
||||
m = (l + r) >> 1;
|
||||
pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m;
|
||||
secondGlyph = ttUSHORT(pairValue);
|
||||
straw = secondGlyph;
|
||||
if (needle < straw)
|
||||
r = m - 1;
|
||||
else if (needle > straw)
|
||||
l = m + 1;
|
||||
else {
|
||||
stbtt_int16 xAdvance = ttSHORT(pairValue + 2);
|
||||
return xAdvance;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case 2: {
|
||||
stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
|
||||
stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
|
||||
|
||||
stbtt_uint16 classDef1Offset = ttUSHORT(table + 8);
|
||||
stbtt_uint16 classDef2Offset = ttUSHORT(table + 10);
|
||||
int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1);
|
||||
int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2);
|
||||
|
||||
stbtt_uint16 class1Count = ttUSHORT(table + 12);
|
||||
stbtt_uint16 class2Count = ttUSHORT(table + 14);
|
||||
STBTT_assert(glyph1class < class1Count);
|
||||
STBTT_assert(glyph2class < class2Count);
|
||||
|
||||
// TODO: Support more formats.
|
||||
STBTT_GPOS_TODO_assert(valueFormat1 == 4);
|
||||
if (valueFormat1 != 4) return 0;
|
||||
STBTT_GPOS_TODO_assert(valueFormat2 == 0);
|
||||
if (valueFormat2 != 0) return 0;
|
||||
|
||||
if (glyph1class >= 0 && glyph1class < class1Count && glyph2class >= 0 && glyph2class < class2Count) {
|
||||
stbtt_uint8 *class1Records = table + 16;
|
||||
stbtt_uint8 *class2Records = class1Records + 2 * (glyph1class * class2Count);
|
||||
stbtt_int16 xAdvance = ttSHORT(class2Records + 2 * glyph2class);
|
||||
return xAdvance;
|
||||
}
|
||||
} break;
|
||||
|
||||
default: {
|
||||
// There are no other cases.
|
||||
STBTT_assert(0);
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
break;
|
||||
};
|
||||
|
||||
default:
|
||||
// TODO: Implement other stuff.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int g2)
|
||||
{
|
||||
int xAdvance = 0;
|
||||
|
||||
if (info->gpos)
|
||||
xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2);
|
||||
else if (info->kern)
|
||||
xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2);
|
||||
|
||||
return xAdvance;
|
||||
}
|
||||
|
||||
STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2)
|
||||
{
|
||||
if (!info->kern) // if no kerning table, don't waste time looking up both codepoint->glyphs
|
||||
if (!info->kern && !info->gpos) // if no kerning table, don't waste time looking up both codepoint->glyphs
|
||||
return 0;
|
||||
return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2));
|
||||
}
|
||||
|
@ -2899,7 +3161,13 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
|
|||
if (e->y0 != e->y1) {
|
||||
stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
|
||||
if (z != NULL) {
|
||||
STBTT_assert(z->ey >= scan_y_top);
|
||||
if (j == 0 && off_y != 0) {
|
||||
if (z->ey < scan_y_top) {
|
||||
// this can happen due to subpixel positioning and some kind of fp rounding error i think
|
||||
z->ey = scan_y_top;
|
||||
}
|
||||
}
|
||||
STBTT_assert(z->ey >= scan_y_top); // if we get really unlucky a tiny bit of an edge can be out of bounds
|
||||
// insert at front
|
||||
z->next = active;
|
||||
active = z;
|
||||
|
@ -2968,7 +3236,7 @@ static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n)
|
|||
|
||||
static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n)
|
||||
{
|
||||
/* threshhold for transitioning to insertion sort */
|
||||
/* threshold for transitioning to insertion sort */
|
||||
while (n > 12) {
|
||||
stbtt__edge t;
|
||||
int c01,c12,c,m,i,j;
|
||||
|
@ -3103,7 +3371,7 @@ static void stbtt__add_point(stbtt__point *points, int n, float x, float y)
|
|||
points[n].y = y;
|
||||
}
|
||||
|
||||
// tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching
|
||||
// tessellate until threshold p is happy... @TODO warped to compensate for non-linear stretching
|
||||
static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n)
|
||||
{
|
||||
// midpoint
|
||||
|
@ -3528,6 +3796,7 @@ STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, in
|
|||
spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
|
||||
spc->h_oversample = 1;
|
||||
spc->v_oversample = 1;
|
||||
spc->skip_missing = 0;
|
||||
|
||||
stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
|
||||
|
||||
|
@ -3553,6 +3822,11 @@ STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h
|
|||
spc->v_oversample = v_oversample;
|
||||
}
|
||||
|
||||
STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip)
|
||||
{
|
||||
spc->skip_missing = skip;
|
||||
}
|
||||
|
||||
#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1)
|
||||
|
||||
static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
|
||||
|
@ -3695,6 +3969,7 @@ static float stbtt__oversample_shift(int oversample)
|
|||
STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
|
||||
{
|
||||
int i,j,k;
|
||||
int missing_glyph_added = 0;
|
||||
|
||||
k=0;
|
||||
for (i=0; i < num_ranges; ++i) {
|
||||
|
@ -3706,13 +3981,19 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stb
|
|||
int x0,y0,x1,y1;
|
||||
int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
|
||||
int glyph = stbtt_FindGlyphIndex(info, codepoint);
|
||||
stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
|
||||
scale * spc->h_oversample,
|
||||
scale * spc->v_oversample,
|
||||
0,0,
|
||||
&x0,&y0,&x1,&y1);
|
||||
rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
|
||||
rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
|
||||
if (glyph == 0 && (spc->skip_missing || missing_glyph_added)) {
|
||||
rects[k].w = rects[k].h = 0;
|
||||
} else {
|
||||
stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
|
||||
scale * spc->h_oversample,
|
||||
scale * spc->v_oversample,
|
||||
0,0,
|
||||
&x0,&y0,&x1,&y1);
|
||||
rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
|
||||
rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
|
||||
if (glyph == 0)
|
||||
missing_glyph_added = 1;
|
||||
}
|
||||
++k;
|
||||
}
|
||||
}
|
||||
|
@ -3746,7 +4027,7 @@ STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info
|
|||
// rects array must be big enough to accommodate all characters in the given ranges
|
||||
STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
|
||||
{
|
||||
int i,j,k, return_value = 1;
|
||||
int i,j,k, missing_glyph = -1, return_value = 1;
|
||||
|
||||
// save current values
|
||||
int old_h_over = spc->h_oversample;
|
||||
|
@ -3765,7 +4046,7 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const
|
|||
sub_y = stbtt__oversample_shift(spc->v_oversample);
|
||||
for (j=0; j < ranges[i].num_chars; ++j) {
|
||||
stbrp_rect *r = &rects[k];
|
||||
if (r->was_packed) {
|
||||
if (r->was_packed && r->w != 0 && r->h != 0) {
|
||||
stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
|
||||
int advance, lsb, x0,y0,x1,y1;
|
||||
int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
|
||||
|
@ -3811,6 +4092,13 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const
|
|||
bc->yoff = (float) y0 * recip_v + sub_y;
|
||||
bc->xoff2 = (x0 + r->w) * recip_h + sub_x;
|
||||
bc->yoff2 = (y0 + r->h) * recip_v + sub_y;
|
||||
|
||||
if (glyph == 0)
|
||||
missing_glyph = j;
|
||||
} else if (spc->skip_missing) {
|
||||
return_value = 0;
|
||||
} else if (r->was_packed && r->w == 0 && r->h == 0 && missing_glyph >= 0) {
|
||||
ranges[i].chardata_for_range[j] = ranges[i].chardata_for_range[missing_glyph];
|
||||
} else {
|
||||
return_value = 0; // if any fail, report failure
|
||||
}
|
||||
|
@ -3879,6 +4167,19 @@ STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *
|
|||
return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
|
||||
}
|
||||
|
||||
STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap)
|
||||
{
|
||||
int i_ascent, i_descent, i_lineGap;
|
||||
float scale;
|
||||
stbtt_fontinfo info;
|
||||
stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, index));
|
||||
scale = size > 0 ? stbtt_ScaleForPixelHeight(&info, size) : stbtt_ScaleForMappingEmToPixels(&info, -size);
|
||||
stbtt_GetFontVMetrics(&info, &i_ascent, &i_descent, &i_lineGap);
|
||||
*ascent = (float) i_ascent * scale;
|
||||
*descent = (float) i_descent * scale;
|
||||
*lineGap = (float) i_lineGap * scale;
|
||||
}
|
||||
|
||||
STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer)
|
||||
{
|
||||
float ipw = 1.0f / pw, iph = 1.0f / ph;
|
||||
|
@ -3932,7 +4233,7 @@ static int stbtt__ray_intersect_bezier(float orig[2], float ray[2], float q0[2],
|
|||
float discr = b*b - a*c;
|
||||
if (discr > 0.0) {
|
||||
float rcpna = -1 / a;
|
||||
float d = (float) sqrt(discr);
|
||||
float d = (float) STBTT_sqrt(discr);
|
||||
s0 = (b+d) * rcpna;
|
||||
s1 = (b-d) * rcpna;
|
||||
if (s0 >= 0.0 && s0 <= 1.0)
|
||||
|
@ -3994,7 +4295,7 @@ static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex
|
|||
orig[1] = y;
|
||||
|
||||
// make sure y never passes through a vertex of the shape
|
||||
y_frac = (float) fmod(y, 1.0f);
|
||||
y_frac = (float) STBTT_fmod(y, 1.0f);
|
||||
if (y_frac < 0.01f)
|
||||
y += 0.01f;
|
||||
else if (y_frac > 0.99f)
|
||||
|
@ -4099,12 +4400,7 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc
|
|||
int w,h;
|
||||
unsigned char *data;
|
||||
|
||||
// if one scale is 0, use same scale for both
|
||||
if (scale_x == 0) scale_x = scale_y;
|
||||
if (scale_y == 0) {
|
||||
if (scale_x == 0) return NULL; // if both scales are 0, return NULL
|
||||
scale_y = scale_x;
|
||||
}
|
||||
if (scale == 0) return NULL;
|
||||
|
||||
stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1);
|
||||
|
||||
|
@ -4494,6 +4790,9 @@ STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const
|
|||
|
||||
// FULL VERSION HISTORY
|
||||
//
|
||||
// 1.19 (2018-02-11) OpenType GPOS kerning (horizontal only), STBTT_fmod
|
||||
// 1.18 (2018-01-29) add missing function
|
||||
// 1.17 (2017-07-23) make more arguments const; doc fix
|
||||
// 1.16 (2017-07-12) SDF support
|
||||
// 1.15 (2017-03-03) make more arguments const
|
||||
// 1.14 (2017-01-16) num-fonts-in-TTC function
|
||||
|
|
5173
raylib/external/stb_vorbis.h
vendored
5173
raylib/external/stb_vorbis.h
vendored
File diff suppressed because it is too large
Load diff
1587
raylib/external/tinyobj_loader_c.h
vendored
Normal file
1587
raylib/external/tinyobj_loader_c.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
* #define GESTURES_IMPLEMENTATION
|
||||
* Generates the implementation of the library into the included file.
|
||||
* If not defined, the library is in header only mode and can be included in other headers
|
||||
* If not defined, the library is in header only mode and can be included in other headers
|
||||
* or source files without problems. But only ONE file should hold the implementation.
|
||||
*
|
||||
* #define GESTURES_STANDALONE
|
||||
|
@ -24,7 +24,7 @@
|
|||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
|
||||
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
|
@ -216,8 +216,8 @@ static float pinchDistance = 0.0f; // PINCH displacement distance (
|
|||
|
||||
static int currentGesture = GESTURE_NONE; // Current detected gesture
|
||||
|
||||
// Enabled gestures flags, all gestures enabled by default
|
||||
static unsigned int enabledGestures = 0b0000001111111111;
|
||||
// Enabled gestures flags, all gestures enabled by default
|
||||
static unsigned int enabledGestures = 0b0000001111111111;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Declaration
|
||||
|
@ -251,13 +251,13 @@ void ProcessGestureEvent(GestureEvent event)
|
|||
{
|
||||
// Reset required variables
|
||||
pointCount = event.pointCount; // Required on UpdateGestures()
|
||||
|
||||
|
||||
if (pointCount < 2)
|
||||
{
|
||||
if (event.touchAction == TOUCH_DOWN)
|
||||
{
|
||||
tapCounter++; // Tap counter
|
||||
|
||||
|
||||
// Detect GESTURE_DOUBLE_TAP
|
||||
if ((currentGesture == GESTURE_NONE) && (tapCounter >= 2) && ((GetCurrentTime() - eventTime) < TAP_TIMEOUT) && (Vector2Distance(touchDownPosition, event.position[0]) < DOUBLETAP_RANGE))
|
||||
{
|
||||
|
@ -269,15 +269,15 @@ void ProcessGestureEvent(GestureEvent event)
|
|||
tapCounter = 1;
|
||||
currentGesture = GESTURE_TAP;
|
||||
}
|
||||
|
||||
|
||||
touchDownPosition = event.position[0];
|
||||
touchDownDragPosition = event.position[0];
|
||||
|
||||
|
||||
touchUpPosition = touchDownPosition;
|
||||
eventTime = GetCurrentTime();
|
||||
|
||||
|
||||
firstTouchId = event.pointerId[0];
|
||||
|
||||
|
||||
dragVector = (Vector2){ 0.0f, 0.0f };
|
||||
}
|
||||
else if (event.touchAction == TOUCH_UP)
|
||||
|
@ -287,15 +287,15 @@ void ProcessGestureEvent(GestureEvent event)
|
|||
// NOTE: dragIntensity dependend on the resolution of the screen
|
||||
dragDistance = Vector2Distance(touchDownPosition, touchUpPosition);
|
||||
dragIntensity = dragDistance/(float)((GetCurrentTime() - swipeTime));
|
||||
|
||||
|
||||
startMoving = false;
|
||||
|
||||
|
||||
// Detect GESTURE_SWIPE
|
||||
if ((dragIntensity > FORCE_TO_SWIPE) && (firstTouchId == event.pointerId[0]))
|
||||
{
|
||||
// NOTE: Angle should be inverted in Y
|
||||
dragAngle = 360.0f - Vector2Angle(touchDownPosition, touchUpPosition);
|
||||
|
||||
|
||||
if ((dragAngle < 30) || (dragAngle > 330)) currentGesture = GESTURE_SWIPE_RIGHT; // Right
|
||||
else if ((dragAngle > 30) && (dragAngle < 120)) currentGesture = GESTURE_SWIPE_UP; // Up
|
||||
else if ((dragAngle > 120) && (dragAngle < 210)) currentGesture = GESTURE_SWIPE_LEFT; // Left
|
||||
|
@ -307,31 +307,31 @@ void ProcessGestureEvent(GestureEvent event)
|
|||
dragDistance = 0.0f;
|
||||
dragIntensity = 0.0f;
|
||||
dragAngle = 0.0f;
|
||||
|
||||
|
||||
currentGesture = GESTURE_NONE;
|
||||
}
|
||||
|
||||
|
||||
touchDownDragPosition = (Vector2){ 0.0f, 0.0f };
|
||||
pointCount = 0;
|
||||
}
|
||||
else if (event.touchAction == TOUCH_MOVE)
|
||||
{
|
||||
if (currentGesture == GESTURE_DRAG) eventTime = GetCurrentTime();
|
||||
|
||||
|
||||
if (!startMoving)
|
||||
{
|
||||
swipeTime = GetCurrentTime();
|
||||
startMoving = true;
|
||||
}
|
||||
|
||||
|
||||
moveDownPosition = event.position[0];
|
||||
|
||||
|
||||
if (currentGesture == GESTURE_HOLD)
|
||||
{
|
||||
if (resetHold) touchDownPosition = event.position[0];
|
||||
|
||||
|
||||
resetHold = false;
|
||||
|
||||
|
||||
// Detect GESTURE_DRAG
|
||||
if (Vector2Distance(touchDownPosition, moveDownPosition) >= MINIMUM_DRAG)
|
||||
{
|
||||
|
@ -339,7 +339,7 @@ void ProcessGestureEvent(GestureEvent event)
|
|||
currentGesture = GESTURE_DRAG;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dragVector.x = moveDownPosition.x - touchDownDragPosition.x;
|
||||
dragVector.y = moveDownPosition.y - touchDownDragPosition.y;
|
||||
}
|
||||
|
@ -350,28 +350,28 @@ void ProcessGestureEvent(GestureEvent event)
|
|||
{
|
||||
touchDownPosition = event.position[0];
|
||||
touchDownPosition2 = event.position[1];
|
||||
|
||||
|
||||
//pinchDistance = Vector2Distance(touchDownPosition, touchDownPosition2);
|
||||
|
||||
|
||||
pinchVector.x = touchDownPosition2.x - touchDownPosition.x;
|
||||
pinchVector.y = touchDownPosition2.y - touchDownPosition.y;
|
||||
|
||||
|
||||
currentGesture = GESTURE_HOLD;
|
||||
timeHold = GetCurrentTime();
|
||||
}
|
||||
else if (event.touchAction == TOUCH_MOVE)
|
||||
{
|
||||
pinchDistance = Vector2Distance(moveDownPosition, moveDownPosition2);
|
||||
|
||||
|
||||
touchDownPosition = moveDownPosition;
|
||||
touchDownPosition2 = moveDownPosition2;
|
||||
|
||||
|
||||
moveDownPosition = event.position[0];
|
||||
moveDownPosition2 = event.position[1];
|
||||
|
||||
|
||||
pinchVector.x = moveDownPosition2.x - moveDownPosition.x;
|
||||
pinchVector.y = moveDownPosition2.y - moveDownPosition.y;
|
||||
|
||||
|
||||
if ((Vector2Distance(touchDownPosition, moveDownPosition) >= MINIMUM_PINCH) || (Vector2Distance(touchDownPosition2, moveDownPosition2) >= MINIMUM_PINCH))
|
||||
{
|
||||
if ((Vector2Distance(moveDownPosition, moveDownPosition2) - pinchDistance) < 0) currentGesture = GESTURE_PINCH_IN;
|
||||
|
@ -382,7 +382,7 @@ void ProcessGestureEvent(GestureEvent event)
|
|||
currentGesture = GESTURE_HOLD;
|
||||
timeHold = GetCurrentTime();
|
||||
}
|
||||
|
||||
|
||||
// NOTE: Angle should be inverted in Y
|
||||
pinchAngle = 360.0f - Vector2Angle(moveDownPosition, moveDownPosition2);
|
||||
}
|
||||
|
@ -392,7 +392,7 @@ void ProcessGestureEvent(GestureEvent event)
|
|||
pinchAngle = 0.0f;
|
||||
pinchVector = (Vector2){ 0.0f, 0.0f };
|
||||
pointCount = 0;
|
||||
|
||||
|
||||
currentGesture = GESTURE_NONE;
|
||||
}
|
||||
}
|
||||
|
@ -409,14 +409,14 @@ void UpdateGestures(void)
|
|||
currentGesture = GESTURE_HOLD;
|
||||
timeHold = GetCurrentTime();
|
||||
}
|
||||
|
||||
|
||||
if (((GetCurrentTime() - eventTime) > TAP_TIMEOUT) && (currentGesture == GESTURE_DRAG) && (pointCount < 2))
|
||||
{
|
||||
currentGesture = GESTURE_HOLD;
|
||||
timeHold = GetCurrentTime();
|
||||
resetHold = true;
|
||||
}
|
||||
|
||||
|
||||
// Detect GESTURE_NONE
|
||||
if ((currentGesture == GESTURE_SWIPE_RIGHT) || (currentGesture == GESTURE_SWIPE_UP) || (currentGesture == GESTURE_SWIPE_LEFT) || (currentGesture == GESTURE_SWIPE_DOWN))
|
||||
{
|
||||
|
@ -428,7 +428,7 @@ void UpdateGestures(void)
|
|||
int GetTouchPointsCount(void)
|
||||
{
|
||||
// NOTE: point count is calculated when ProcessGestureEvent(GestureEvent event) is called
|
||||
|
||||
|
||||
return pointCount;
|
||||
}
|
||||
|
||||
|
@ -443,11 +443,11 @@ int GetGestureDetected(void)
|
|||
float GetGestureHoldDuration(void)
|
||||
{
|
||||
// NOTE: time is calculated on current gesture HOLD
|
||||
|
||||
|
||||
double time = 0.0;
|
||||
|
||||
|
||||
if (currentGesture == GESTURE_HOLD) time = GetCurrentTime() - timeHold;
|
||||
|
||||
|
||||
return (float)time;
|
||||
}
|
||||
|
||||
|
@ -455,7 +455,7 @@ float GetGestureHoldDuration(void)
|
|||
Vector2 GetGestureDragVector(void)
|
||||
{
|
||||
// NOTE: drag vector is calculated on one touch points TOUCH_MOVE
|
||||
|
||||
|
||||
return dragVector;
|
||||
}
|
||||
|
||||
|
@ -464,7 +464,7 @@ Vector2 GetGestureDragVector(void)
|
|||
float GetGestureDragAngle(void)
|
||||
{
|
||||
// NOTE: drag angle is calculated on one touch points TOUCH_UP
|
||||
|
||||
|
||||
return dragAngle;
|
||||
}
|
||||
|
||||
|
@ -473,7 +473,7 @@ Vector2 GetGesturePinchVector(void)
|
|||
{
|
||||
// NOTE: The position values used for pinchDistance are not modified like the position values of [core.c]-->GetTouchPosition(int index)
|
||||
// NOTE: pinch distance is calculated on two touch points TOUCH_MOVE
|
||||
|
||||
|
||||
return pinchVector;
|
||||
}
|
||||
|
||||
|
@ -482,7 +482,7 @@ Vector2 GetGesturePinchVector(void)
|
|||
float GetGesturePinchAngle(void)
|
||||
{
|
||||
// NOTE: pinch angle is calculated on two touch points TOUCH_MOVE
|
||||
|
||||
|
||||
return pinchAngle;
|
||||
}
|
||||
|
||||
|
@ -494,7 +494,7 @@ float GetGesturePinchAngle(void)
|
|||
static float Vector2Angle(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
float angle = atan2f(v2.y - v1.y, v2.x - v1.x)*(180.0f/PI);
|
||||
|
||||
|
||||
if (angle < 0) angle += 360.0f;
|
||||
|
||||
return angle;
|
||||
|
@ -518,13 +518,13 @@ static float Vector2Distance(Vector2 v1, Vector2 v2)
|
|||
static double GetCurrentTime(void)
|
||||
{
|
||||
double time = 0;
|
||||
|
||||
|
||||
#if defined(_WIN32)
|
||||
unsigned long long int clockFrequency, currentTime;
|
||||
|
||||
|
||||
QueryPerformanceFrequency(&clockFrequency); // BE CAREFUL: Costly operation!
|
||||
QueryPerformanceCounter(¤tTime);
|
||||
|
||||
|
||||
time = (double)currentTime/clockFrequency*1000.0f; // Time in miliseconds
|
||||
#endif
|
||||
|
||||
|
@ -533,24 +533,24 @@ static double GetCurrentTime(void)
|
|||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
uint64_t nowTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; // Time in nanoseconds
|
||||
|
||||
|
||||
time = ((double)nowTime/1000000.0); // Time in miliseconds
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
//#define CLOCK_REALTIME CALENDAR_CLOCK // returns UTC time since 1970-01-01
|
||||
//#define CLOCK_MONOTONIC SYSTEM_CLOCK // returns the time since boot time
|
||||
|
||||
|
||||
clock_serv_t cclock;
|
||||
mach_timespec_t now;
|
||||
host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
|
||||
|
||||
|
||||
// NOTE: OS X does not have clock_gettime(), using clock_get_time()
|
||||
clock_get_time(cclock, &now);
|
||||
mach_port_deallocate(mach_task_self(), cclock);
|
||||
uint64_t nowTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; // Time in nanoseconds
|
||||
|
||||
time = ((double)nowTime/1000000.0); // Time in miliseconds
|
||||
time = ((double)nowTime/1000000.0); // Time in miliseconds
|
||||
#endif
|
||||
|
||||
return time;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// The implementation of mini_al needs to #include windows.h which means it needs to go into
|
||||
// it's own translation unit. Not doing this will cause conflicts with CloseWindow(), etc.
|
||||
#define MAL_IMPLEMENTATION
|
||||
#include "external/mini_al.h"
|
||||
#include "external/miniaudio.h"
|
2511
raylib/models.c
2511
raylib/models.c
File diff suppressed because it is too large
Load diff
|
@ -162,11 +162,12 @@ func DrawGizmo(position Vector3) {
|
|||
C.DrawGizmo(*cposition)
|
||||
}
|
||||
|
||||
// LoadMesh - Load mesh from file
|
||||
func LoadMesh(fileName string) Mesh {
|
||||
// LoadMeshes - Load mesh from file
|
||||
func LoadMeshes(fileName string) Mesh {
|
||||
cfileName := C.CString(fileName)
|
||||
defer C.free(unsafe.Pointer(cfileName))
|
||||
ret := C.LoadMesh(cfileName)
|
||||
ccount := C.int(0)
|
||||
ret := C.LoadMeshes(cfileName, &ccount)
|
||||
v := newMeshFromPointer(unsafe.Pointer(&ret))
|
||||
return v
|
||||
}
|
||||
|
@ -197,7 +198,7 @@ func UnloadModel(model Model) {
|
|||
// UnloadMesh - Unload mesh from memory (RAM and/or VRAM)
|
||||
func UnloadMesh(mesh *Mesh) {
|
||||
cmesh := mesh.cptr()
|
||||
C.UnloadMesh(cmesh)
|
||||
C.UnloadMesh(*cmesh)
|
||||
}
|
||||
|
||||
// ExportMesh - Export mesh as an OBJ file
|
||||
|
@ -308,11 +309,12 @@ func GenMeshCubicmap(cubicmap Image, size Vector3) Mesh {
|
|||
return v
|
||||
}
|
||||
|
||||
// LoadMaterial - Load material data (.MTL)
|
||||
func LoadMaterial(fileName string) Material {
|
||||
// LoadMaterials - Load material data (.MTL)
|
||||
func LoadMaterials(fileName string) Material {
|
||||
cfileName := C.CString(fileName)
|
||||
defer C.free(unsafe.Pointer(cfileName))
|
||||
ret := C.LoadMaterial(cfileName)
|
||||
ccount := C.int(0)
|
||||
ret := C.LoadMaterials(cfileName, &ccount)
|
||||
v := newMaterialFromPointer(unsafe.Pointer(&ret))
|
||||
return v
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,7 +3,7 @@
|
|||
package rl
|
||||
|
||||
/*
|
||||
#include "external/stb_vorbis.c"
|
||||
//#include "external/stb_vorbis.c"
|
||||
|
||||
#include "raylib.h"
|
||||
#include <stdlib.h>
|
||||
|
@ -58,18 +58,6 @@ func LoadWave(fileName string) Wave {
|
|||
return v
|
||||
}
|
||||
|
||||
// LoadWaveEx - Load wave data from float array data (32bit)
|
||||
func LoadWaveEx(data []byte, sampleCount int32, sampleRate int32, sampleSize int32, channels int32) Wave {
|
||||
cdata := unsafe.Pointer(&data[0])
|
||||
csampleCount := (C.int)(sampleCount)
|
||||
csampleRate := (C.int)(sampleRate)
|
||||
csampleSize := (C.int)(sampleSize)
|
||||
cchannels := (C.int)(channels)
|
||||
ret := C.LoadWaveEx(cdata, csampleCount, csampleRate, csampleSize, cchannels)
|
||||
v := newWaveFromPointer(unsafe.Pointer(&ret))
|
||||
return v
|
||||
}
|
||||
|
||||
// LoadSound - Load sound to memory
|
||||
func LoadSound(fileName string) Sound {
|
||||
cfileName := C.CString(fileName)
|
||||
|
@ -315,10 +303,10 @@ func CloseAudioStream(stream AudioStream) {
|
|||
C.CloseAudioStream(*cstream)
|
||||
}
|
||||
|
||||
// IsAudioBufferProcessed - Check if any audio stream buffers requires refill
|
||||
func IsAudioBufferProcessed(stream AudioStream) bool {
|
||||
// IsAudioStreamProcessed - Check if any audio stream buffers requires refill
|
||||
func IsAudioStreamProcessed(stream AudioStream) bool {
|
||||
cstream := stream.cptr()
|
||||
ret := C.IsAudioBufferProcessed(*cstream)
|
||||
ret := C.IsAudioStreamProcessed(*cstream)
|
||||
v := bool(ret)
|
||||
return v
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* raylib.audio - Basic funtionality to work with audio
|
||||
* raudio - A simple and easy-to-use audio library based on miniaudio
|
||||
*
|
||||
* FEATURES:
|
||||
* - Manage audio device (init/close)
|
||||
|
@ -10,22 +10,17 @@
|
|||
* - Manage mixing channels
|
||||
* - Manage raw audio context
|
||||
*
|
||||
* LIMITATIONS (only OpenAL Soft):
|
||||
* Only up to two channels supported: MONO and STEREO (for additional channels, use AL_EXT_MCFORMATS)
|
||||
* Only the following sample sizes supported: 8bit PCM, 16bit PCM, 32-bit float PCM (using AL_EXT_FLOAT32)
|
||||
*
|
||||
* DEPENDENCIES:
|
||||
* mini_al - Audio device/context management (https://github.com/dr-soft/mini_al)
|
||||
* stb_vorbis - OGG audio files loading (http://www.nothings.org/stb_vorbis/)
|
||||
* jar_xm - XM module file loading
|
||||
* jar_mod - MOD audio file loading
|
||||
* dr_flac - FLAC audio file loading
|
||||
*
|
||||
* *OpenAL Soft - Audio device management, still used on HTML5 and OSX platforms
|
||||
* miniaudio.h - Audio device management lib (https://github.com/dr-soft/miniaudio)
|
||||
* stb_vorbis.h - Ogg audio files loading (http://www.nothings.org/stb_vorbis/)
|
||||
* dr_mp3.h - MP3 audio file loading (https://github.com/mackron/dr_libs)
|
||||
* dr_flac.h - FLAC audio file loading (https://github.com/mackron/dr_libs)
|
||||
* jar_xm.h - XM module file loading
|
||||
* jar_mod.h - MOD audio file loading
|
||||
*
|
||||
* CONTRIBUTORS:
|
||||
* David Reid (github: @mackron) (Nov. 2017):
|
||||
* - Complete port to mini_al library
|
||||
* - Complete port to miniaudio library
|
||||
*
|
||||
* Joshua Reisenauer (github: @kd7tck) (2015)
|
||||
* - XM audio module support (jar_xm)
|
||||
|
@ -36,7 +31,7 @@
|
|||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
|
||||
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
|
@ -55,17 +50,25 @@
|
|||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#ifndef AUDIO_H
|
||||
#define AUDIO_H
|
||||
#ifndef RAUDIO_H
|
||||
#define RAUDIO_H
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
//...
|
||||
// Allow custom memory allocators
|
||||
#ifndef RL_MALLOC
|
||||
#define RL_MALLOC(sz) malloc(sz)
|
||||
#endif
|
||||
#ifndef RL_CALLOC
|
||||
#define RL_CALLOC(n,sz) calloc(n,sz)
|
||||
#endif
|
||||
#ifndef RL_FREE
|
||||
#define RL_FREE(p) free(p)
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
// NOTE: Below types are required for CAMERA_STANDALONE usage
|
||||
//----------------------------------------------------------------------------------
|
||||
#ifndef __cplusplus
|
||||
// Boolean type
|
||||
|
@ -77,40 +80,43 @@
|
|||
|
||||
// Wave type, defines audio wave data
|
||||
typedef struct Wave {
|
||||
unsigned int sampleCount; // Number of samples
|
||||
unsigned int sampleRate; // Frequency (samples per second)
|
||||
unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
|
||||
unsigned int channels; // Number of channels (1-mono, 2-stereo)
|
||||
void *data; // Buffer data pointer
|
||||
unsigned int sampleCount; // Total number of samples
|
||||
unsigned int sampleRate; // Frequency (samples per second)
|
||||
unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
|
||||
unsigned int channels; // Number of channels (1-mono, 2-stereo)
|
||||
void *data; // Buffer data pointer
|
||||
} Wave;
|
||||
|
||||
// Sound source type
|
||||
typedef struct Sound {
|
||||
void *audioBuffer; // Pointer to internal data used by the audio system
|
||||
|
||||
unsigned int source; // Audio source id
|
||||
unsigned int buffer; // Audio buffer id
|
||||
int format; // Audio format specifier
|
||||
} Sound;
|
||||
|
||||
// Music type (file streaming from memory)
|
||||
// NOTE: Anything longer than ~10 seconds should be streamed
|
||||
typedef struct MusicData *Music;
|
||||
typedef struct rAudioBuffer rAudioBuffer;
|
||||
|
||||
// Audio stream type
|
||||
// NOTE: Useful to create custom audio streams not bound to a specific file
|
||||
typedef struct AudioStream {
|
||||
unsigned int sampleRate; // Frequency (samples per second)
|
||||
unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
|
||||
unsigned int channels; // Number of channels (1-mono, 2-stereo)
|
||||
unsigned int sampleRate; // Frequency (samples per second)
|
||||
unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
|
||||
unsigned int channels; // Number of channels (1-mono, 2-stereo)
|
||||
|
||||
void *audioBuffer; // Pointer to internal data used by the audio system.
|
||||
|
||||
int format; // Audio format specifier
|
||||
unsigned int source; // Audio source id
|
||||
unsigned int buffers[2]; // Audio buffers (double buffering)
|
||||
rAudioBuffer *buffer; // Pointer to internal data used by the audio system
|
||||
} AudioStream;
|
||||
|
||||
// Sound source type
|
||||
typedef struct Sound {
|
||||
unsigned int sampleCount; // Total number of samples
|
||||
AudioStream stream; // Audio stream
|
||||
} Sound;
|
||||
|
||||
// Music stream type (audio file streaming from memory)
|
||||
// NOTE: Anything longer than ~10 seconds should be streamed
|
||||
typedef struct Music {
|
||||
int ctxType; // Type of music context (audio filetype)
|
||||
void *ctxData; // Audio context data, depends on type
|
||||
|
||||
unsigned int sampleCount; // Total number of samples
|
||||
unsigned int loopCount; // Loops count (times music will play), 0 means infinite loop
|
||||
|
||||
AudioStream stream; // Audio stream
|
||||
} Music;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
|
@ -123,22 +129,31 @@ extern "C" { // Prevents name mangling of functions
|
|||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Audio device management functions
|
||||
void InitAudioDevice(void); // Initialize audio device and context
|
||||
void CloseAudioDevice(void); // Close the audio device and context
|
||||
bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully
|
||||
void SetMasterVolume(float volume); // Set master volume (listener)
|
||||
|
||||
// Wave/Sound loading/unloading functions
|
||||
Wave LoadWave(const char *fileName); // Load wave data from file
|
||||
Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from raw array data
|
||||
Sound LoadSound(const char *fileName); // Load sound from file
|
||||
Sound LoadSoundFromWave(Wave wave); // Load sound from wave data
|
||||
void UpdateSound(Sound sound, const void *data, int samplesCount);// Update sound buffer with new data
|
||||
void UnloadWave(Wave wave); // Unload wave data
|
||||
void UnloadSound(Sound sound); // Unload sound
|
||||
void ExportWave(Wave wave, const char *fileName); // Export wave data to file
|
||||
void ExportWaveAsCode(Wave wave, const char *fileName); // Export wave sample data to code (.h)
|
||||
|
||||
// Wave/Sound management functions
|
||||
void PlaySound(Sound sound); // Play a sound
|
||||
void StopSound(Sound sound); // Stop playing a sound
|
||||
void PauseSound(Sound sound); // Pause a sound
|
||||
void ResumeSound(Sound sound); // Resume a paused sound
|
||||
void StopSound(Sound sound); // Stop playing a sound
|
||||
void PlaySoundMulti(Sound sound); // Play a sound (using multichannel buffer pool)
|
||||
void StopSoundMulti(void); // Stop any sound playing (using multichannel buffer pool)
|
||||
int GetSoundsPlaying(void); // Get number of sounds playing in the multichannel
|
||||
bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing
|
||||
void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level)
|
||||
void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
|
||||
|
@ -146,6 +161,8 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels); // C
|
|||
Wave WaveCopy(Wave wave); // Copy a wave to a new wave
|
||||
void WaveCrop(Wave *wave, int initSample, int finalSample); // Crop a wave to defined samples range
|
||||
float *GetWaveData(Wave wave); // Get samples data from wave as a floats array
|
||||
|
||||
// Music management functions
|
||||
Music LoadMusicStream(const char *fileName); // Load music stream from file
|
||||
void UnloadMusicStream(Music music); // Unload music stream
|
||||
void PlayMusicStream(Music music); // Start music playing
|
||||
|
@ -161,12 +178,10 @@ float GetMusicTimeLength(Music music); // Get music tim
|
|||
float GetMusicTimePlayed(Music music); // Get current music time played (in seconds)
|
||||
|
||||
// AudioStream management functions
|
||||
AudioStream InitAudioStream(unsigned int sampleRate,
|
||||
unsigned int sampleSize,
|
||||
unsigned int channels); // Init audio stream (to stream raw audio pcm data)
|
||||
AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Init audio stream (to stream raw audio pcm data)
|
||||
void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount); // Update audio stream buffers with data
|
||||
void CloseAudioStream(AudioStream stream); // Close audio stream and free memory
|
||||
bool IsAudioBufferProcessed(AudioStream stream); // Check if any audio stream buffers requires refill
|
||||
bool IsAudioStreamProcessed(AudioStream stream); // Check if any audio stream buffers requires refill
|
||||
void PlayAudioStream(AudioStream stream); // Play audio stream
|
||||
void PauseAudioStream(AudioStream stream); // Pause audio stream
|
||||
void ResumeAudioStream(AudioStream stream); // Resume audio stream
|
||||
|
@ -179,4 +194,4 @@ void SetAudioStreamPitch(AudioStream stream, float pitch); // Set pitch for
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif // AUDIO_H
|
||||
#endif // RAUDIO_H
|
140
raylib/raylib.go
140
raylib/raylib.go
|
@ -74,17 +74,8 @@ func newWaveFromPointer(ptr unsafe.Pointer) Wave {
|
|||
|
||||
// Sound source type
|
||||
type Sound struct {
|
||||
// Audio source id
|
||||
Source uint32
|
||||
// Audio buffer id
|
||||
Buffer uint32
|
||||
// Audio format specifier
|
||||
Format int32
|
||||
}
|
||||
|
||||
// NewSound - Returns new Sound
|
||||
func NewSound(source, buffer uint32, format int32) Sound {
|
||||
return Sound{source, buffer, format}
|
||||
SampleCount uint32
|
||||
Stream AudioStream
|
||||
}
|
||||
|
||||
// newSoundFromPointer - Returns new Sound from pointer
|
||||
|
@ -95,16 +86,11 @@ func newSoundFromPointer(ptr unsafe.Pointer) Sound {
|
|||
// Music type (file streaming from memory)
|
||||
// NOTE: Anything longer than ~10 seconds should be streamed
|
||||
type Music struct {
|
||||
CtxType uint32
|
||||
_ [4]byte
|
||||
ctxOgg unsafe.Pointer
|
||||
ctxFlac unsafe.Pointer
|
||||
ctxXm unsafe.Pointer
|
||||
ctxMod unsafe.Pointer
|
||||
Stream AudioStream
|
||||
LoopCount int32
|
||||
TotalSamples uint32
|
||||
SamplesLeft uint32
|
||||
CtxType int32
|
||||
CtxData unsafe.Pointer
|
||||
SampleCount uint32
|
||||
LoopCount uint32
|
||||
Stream AudioStream
|
||||
}
|
||||
|
||||
// newMusicFromPointer - Returns new Music from pointer
|
||||
|
@ -121,17 +107,8 @@ type AudioStream struct {
|
|||
SampleSize uint32
|
||||
// Number of channels (1-mono, 2-stereo)
|
||||
Channels uint32
|
||||
// Audio format specifier
|
||||
Format int32
|
||||
// Audio source id
|
||||
Source uint32
|
||||
// Audio buffers (double buffering)
|
||||
Buffers [2]uint32
|
||||
}
|
||||
|
||||
// NewAudioStream - Returns new AudioStream
|
||||
func NewAudioStream(sampleRate, sampleSize, channels uint32, format int32, source uint32, buffers [2]uint32) AudioStream {
|
||||
return AudioStream{sampleRate, sampleSize, channels, format, source, buffers}
|
||||
// Buffer
|
||||
Buffer *_Ctype_struct_rAudioBuffer
|
||||
}
|
||||
|
||||
// newAudioStreamFromPointer - Returns new AudioStream from pointer
|
||||
|
@ -772,28 +749,31 @@ type Mesh struct {
|
|||
// Number of triangles stored (indexed or not)
|
||||
TriangleCount int32
|
||||
// Vertex position (XYZ - 3 components per vertex) (shader-location = 0)
|
||||
Vertices *[]float32
|
||||
Vertices *float32
|
||||
// Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
|
||||
Texcoords *[]float32
|
||||
Texcoords *float32
|
||||
// Vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
|
||||
Texcoords2 *[]float32
|
||||
Texcoords2 *float32
|
||||
// Vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
|
||||
Normals *[]float32
|
||||
Normals *float32
|
||||
// Vertex tangents (XYZ - 3 components per vertex) (shader-location = 4)
|
||||
Tangents *[]float32
|
||||
Tangents *float32
|
||||
// Vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
|
||||
Colors *[]uint8
|
||||
Colors *uint8
|
||||
// Vertex indices (in case vertex data comes indexed)
|
||||
Indices *[]uint16
|
||||
Indices *uint16
|
||||
// AnimVertices
|
||||
AnimVertices *float32
|
||||
// AnimNormals
|
||||
AnimNormals *float32
|
||||
// BoneIds
|
||||
BoneIds *int32
|
||||
// BoneWeights
|
||||
BoneWeights *float32
|
||||
// OpenGL Vertex Array Object id
|
||||
VaoID uint32
|
||||
// OpenGL Vertex Buffer Objects id (7 types of vertex data)
|
||||
VboID [7]uint32
|
||||
}
|
||||
|
||||
// NewMesh - Returns new Mesh
|
||||
func NewMesh(vertexCount, triangleCount int32, vertices, texcoords, texcoords2, normals, tangents *[]float32, colors *[]uint8, indices *[]uint16, vaoID uint32, vboID [7]uint32) Mesh {
|
||||
return Mesh{vertexCount, triangleCount, vertices, texcoords, texcoords2, normals, tangents, colors, indices, vaoID, vboID}
|
||||
VboID *uint32
|
||||
}
|
||||
|
||||
// newMeshFromPointer - Returns new Mesh from pointer
|
||||
|
@ -807,15 +787,8 @@ type Material struct {
|
|||
Shader Shader
|
||||
// Maps
|
||||
Maps [MaxMaterialMaps]MaterialMap
|
||||
// Padding
|
||||
_ [4]byte
|
||||
// Generic parameters (if required)
|
||||
Params *[]float32
|
||||
}
|
||||
|
||||
// NewMaterial - Returns new Material
|
||||
func NewMaterial(shader Shader, maps [MaxMaterialMaps]MaterialMap, params *[]float32) Material {
|
||||
return Material{shader, maps, [4]byte{}, params}
|
||||
Params *float32
|
||||
}
|
||||
|
||||
// newMaterialFromPointer - Returns new Material from pointer
|
||||
|
@ -833,21 +806,17 @@ type MaterialMap struct {
|
|||
Value float32
|
||||
}
|
||||
|
||||
// Model type
|
||||
type Model struct {
|
||||
// Vertex data buffers (RAM and VRAM)
|
||||
Mesh Mesh
|
||||
// Local transform matrix
|
||||
Transform Matrix
|
||||
// Shader and textures data
|
||||
Material Material
|
||||
// Padding
|
||||
_ [4]byte
|
||||
}
|
||||
|
||||
// NewModel - Returns new Model
|
||||
func NewModel(mesh Mesh, transform Matrix, material Material) Model {
|
||||
return Model{mesh, transform, material, [4]byte{}}
|
||||
Transform Matrix
|
||||
MeshCount int32
|
||||
Meshes []Mesh
|
||||
MaterialCount int32
|
||||
Materials []Material
|
||||
MeshMaterial *int32
|
||||
BoneCount int32
|
||||
Bones []BoneInfo
|
||||
BindPose []Transform
|
||||
}
|
||||
|
||||
// newModelFromPointer - Returns new Model from pointer
|
||||
|
@ -855,6 +824,19 @@ func newModelFromPointer(ptr unsafe.Pointer) Model {
|
|||
return *(*Model)(ptr)
|
||||
}
|
||||
|
||||
// BoneInfo type.
|
||||
type BoneInfo struct {
|
||||
Name [32]int8
|
||||
Parent int32
|
||||
}
|
||||
|
||||
// Transform type.
|
||||
type Transform struct {
|
||||
Translation Vector3
|
||||
Rotation Vector4
|
||||
Scale Vector3
|
||||
}
|
||||
|
||||
// Ray type (useful for raycast)
|
||||
type Ray struct {
|
||||
// Ray position (origin)
|
||||
|
@ -889,9 +871,9 @@ const (
|
|||
// VrDeviceInfo - Head-Mounted-Display device parameters
|
||||
type VrDeviceInfo struct {
|
||||
// HMD horizontal resolution in pixels
|
||||
HResolution int
|
||||
HResolution int32
|
||||
// HMD vertical resolution in pixels
|
||||
VResolution int
|
||||
VResolution int32
|
||||
// HMD horizontal size in meters
|
||||
HScreenSize float32
|
||||
// HMD vertical size in meters
|
||||
|
@ -911,7 +893,7 @@ type VrDeviceInfo struct {
|
|||
}
|
||||
|
||||
// NewVrDeviceInfo - Returns new VrDeviceInfo
|
||||
func NewVrDeviceInfo(hResolution, vResolution int, hScreenSize, vScreenSize, vScreenCenter, eyeToScreenDistance,
|
||||
func NewVrDeviceInfo(hResolution, vResolution int32, hScreenSize, vScreenSize, vScreenCenter, eyeToScreenDistance,
|
||||
lensSeparationDistance, interpupillaryDistance float32, lensDistortionValues, chromaAbCorrection [4]float32) VrDeviceInfo {
|
||||
|
||||
return VrDeviceInfo{hResolution, vResolution, hScreenSize, vScreenSize, vScreenCenter, eyeToScreenDistance,
|
||||
|
@ -977,21 +959,18 @@ func newCharInfoFromPointer(ptr unsafe.Pointer) CharInfo {
|
|||
|
||||
// Font type, includes texture and charSet array data
|
||||
type Font struct {
|
||||
// Font texture
|
||||
Texture Texture2D
|
||||
// Base size (default chars height)
|
||||
BaseSize int32
|
||||
// Number of characters
|
||||
CharsCount int32
|
||||
// Characters texture atlas
|
||||
Texture Texture2D
|
||||
// Characters rectangles in texture
|
||||
Recs *Rectangle
|
||||
// Characters info data
|
||||
Chars *CharInfo
|
||||
}
|
||||
|
||||
// NewFont - Returns new Font
|
||||
func NewFont(texture Texture2D, baseSize, charsCount int32, chars *CharInfo) Font {
|
||||
return Font{texture, baseSize, charsCount, chars}
|
||||
}
|
||||
|
||||
// newFontFromPointer - Returns new Font from pointer
|
||||
func newFontFromPointer(ptr unsafe.Pointer) Font {
|
||||
return *(*Font)(ptr)
|
||||
|
@ -1167,11 +1146,14 @@ func newRenderTexture2DFromPointer(ptr unsafe.Pointer) RenderTexture2D {
|
|||
|
||||
// Log message types
|
||||
const (
|
||||
LogInfo = 1 << iota
|
||||
LogAll = iota
|
||||
LogTrace
|
||||
LogDebug
|
||||
LogInfo
|
||||
LogWarning
|
||||
LogError
|
||||
LogDebug
|
||||
LogOther
|
||||
LogFatal
|
||||
LogNone
|
||||
)
|
||||
|
||||
var logTypeFlags = LogInfo | LogWarning | LogError
|
||||
|
|
935
raylib/raylib.h
935
raylib/raylib.h
File diff suppressed because it is too large
Load diff
105
raylib/raymath.h
105
raylib/raymath.h
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
* Copyright (c) 2015-2017 Ramon Santamaria (@raysan5)
|
||||
* Copyright (c) 2015-2019 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
|
@ -56,7 +56,7 @@
|
|||
#if defined(RAYMATH_IMPLEMENTATION)
|
||||
#if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED)
|
||||
#define RMDEF __declspec(dllexport) extern inline // We are building raylib as a Win32 shared library (.dll).
|
||||
#elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED)
|
||||
#elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED)
|
||||
#define RMDEF __declspec(dllimport) // We are using raylib as a Win32 shared library (.dll)
|
||||
#else
|
||||
#define RMDEF extern inline // Provide external definition
|
||||
|
@ -113,7 +113,7 @@
|
|||
float y;
|
||||
float z;
|
||||
} Vector3;
|
||||
|
||||
|
||||
// Quaternion type
|
||||
typedef struct Quaternion {
|
||||
float x;
|
||||
|
@ -148,7 +148,7 @@ RMDEF float Clamp(float value, float min, float max)
|
|||
return res > max ? max : res;
|
||||
}
|
||||
|
||||
// Calculate linear interpolation between two vectors
|
||||
// Calculate linear interpolation between two floats
|
||||
RMDEF float Lerp(float start, float end, float amount)
|
||||
{
|
||||
return start + amount*(end - start);
|
||||
|
@ -225,8 +225,8 @@ RMDEF Vector2 Vector2Scale(Vector2 v, float scale)
|
|||
// Multiply vector by vector
|
||||
RMDEF Vector2 Vector2MultiplyV(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
Vector2 result = { v1.x*v2.x, v1.y*v2.y };
|
||||
return result;
|
||||
Vector2 result = { v1.x*v2.x, v1.y*v2.y };
|
||||
return result;
|
||||
}
|
||||
|
||||
// Negate vector
|
||||
|
@ -246,8 +246,8 @@ RMDEF Vector2 Vector2Divide(Vector2 v, float div)
|
|||
// Divide vector by vector
|
||||
RMDEF Vector2 Vector2DivideV(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
Vector2 result = { v1.x/v2.x, v1.y/v2.y };
|
||||
return result;
|
||||
Vector2 result = { v1.x/v2.x, v1.y/v2.y };
|
||||
return result;
|
||||
}
|
||||
|
||||
// Normalize provided vector
|
||||
|
@ -388,15 +388,15 @@ RMDEF Vector3 Vector3Negate(Vector3 v)
|
|||
// Divide vector by a float value
|
||||
RMDEF Vector3 Vector3Divide(Vector3 v, float div)
|
||||
{
|
||||
Vector3 result = { v.x / div, v.y / div, v.z / div };
|
||||
return result;
|
||||
Vector3 result = { v.x / div, v.y / div, v.z / div };
|
||||
return result;
|
||||
}
|
||||
|
||||
// Divide vector by vector
|
||||
RMDEF Vector3 Vector3DivideV(Vector3 v1, Vector3 v2)
|
||||
{
|
||||
Vector3 result = { v1.x/v2.x, v1.y/v2.y, v1.z/v2.z };
|
||||
return result;
|
||||
Vector3 result = { v1.x/v2.x, v1.y/v2.y, v1.z/v2.z };
|
||||
return result;
|
||||
}
|
||||
|
||||
// Normalize provided vector
|
||||
|
@ -440,7 +440,7 @@ RMDEF Vector3 Vector3Transform(Vector3 v, Matrix mat)
|
|||
result.z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14;
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
// Transform a vector by quaternion rotation
|
||||
RMDEF Vector3 Vector3RotateByQuaternion(Vector3 v, Quaternion q)
|
||||
|
@ -794,6 +794,33 @@ RMDEF Matrix MatrixRotate(Vector3 axis, float angle)
|
|||
return result;
|
||||
}
|
||||
|
||||
// Returns xyz-rotation matrix (angles in radians)
|
||||
RMDEF Matrix MatrixRotateXYZ(Vector3 ang)
|
||||
{
|
||||
Matrix result = MatrixIdentity();
|
||||
|
||||
float cosz = cosf(-ang.z);
|
||||
float sinz = sinf(-ang.z);
|
||||
float cosy = cosf(-ang.y);
|
||||
float siny = sinf(-ang.y);
|
||||
float cosx = cosf(-ang.x);
|
||||
float sinx = sinf(-ang.x);
|
||||
|
||||
result.m0 = cosz * cosy;
|
||||
result.m4 = (cosz * siny * sinx) - (sinz * cosx);
|
||||
result.m8 = (cosz * siny * cosx) + (sinz * sinx);
|
||||
|
||||
result.m1 = sinz * cosy;
|
||||
result.m5 = (sinz * siny * sinx) + (cosz * cosx);
|
||||
result.m9 = (sinz * siny * cosx) - (cosz * sinx);
|
||||
|
||||
result.m2 = -siny;
|
||||
result.m6 = cosy * sinx;
|
||||
result.m10= cosy * cosx;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns x-rotation matrix (angle in radians)
|
||||
RMDEF Matrix MatrixRotateX(float angle)
|
||||
{
|
||||
|
@ -1159,7 +1186,7 @@ RMDEF Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to)
|
|||
// Above lines are equivalent to:
|
||||
//Quaternion result = QuaternionNlerp(q, QuaternionIdentity(), 0.5f);
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns a quaternion for a given rotation matrix
|
||||
|
@ -1320,21 +1347,21 @@ RMDEF void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle
|
|||
// Returns he quaternion equivalent to Euler angles
|
||||
RMDEF Quaternion QuaternionFromEuler(float roll, float pitch, float yaw)
|
||||
{
|
||||
Quaternion q = { 0 };
|
||||
Quaternion q = { 0 };
|
||||
|
||||
float x0 = cosf(roll*0.5f);
|
||||
float x1 = sinf(roll*0.5f);
|
||||
float y0 = cosf(pitch*0.5f);
|
||||
float y1 = sinf(pitch*0.5f);
|
||||
float z0 = cosf(yaw*0.5f);
|
||||
float z1 = sinf(yaw*0.5f);
|
||||
float x0 = cosf(roll*0.5f);
|
||||
float x1 = sinf(roll*0.5f);
|
||||
float y0 = cosf(pitch*0.5f);
|
||||
float y1 = sinf(pitch*0.5f);
|
||||
float z0 = cosf(yaw*0.5f);
|
||||
float z1 = sinf(yaw*0.5f);
|
||||
|
||||
q.x = x1*y0*z0 - x0*y1*z1;
|
||||
q.y = x0*y1*z0 + x1*y0*z1;
|
||||
q.z = x0*y0*z1 - x1*y1*z0;
|
||||
q.w = x0*y0*z0 + x1*y1*z1;
|
||||
q.x = x1*y0*z0 - x0*y1*z1;
|
||||
q.y = x0*y1*z0 + x1*y0*z1;
|
||||
q.z = x0*y0*z1 - x1*y1*z0;
|
||||
q.w = x0*y0*z0 + x1*y1*z1;
|
||||
|
||||
return q;
|
||||
return q;
|
||||
}
|
||||
|
||||
// Return the Euler angles equivalent to quaternion (roll, pitch, yaw)
|
||||
|
@ -1343,21 +1370,21 @@ RMDEF Vector3 QuaternionToEuler(Quaternion q)
|
|||
{
|
||||
Vector3 result = { 0 };
|
||||
|
||||
// roll (x-axis rotation)
|
||||
float x0 = 2.0f*(q.w*q.x + q.y*q.z);
|
||||
float x1 = 1.0f - 2.0f*(q.x*q.x + q.y*q.y);
|
||||
result.x = atan2f(x0, x1)*RAD2DEG;
|
||||
// roll (x-axis rotation)
|
||||
float x0 = 2.0f*(q.w*q.x + q.y*q.z);
|
||||
float x1 = 1.0f - 2.0f*(q.x*q.x + q.y*q.y);
|
||||
result.x = atan2f(x0, x1)*RAD2DEG;
|
||||
|
||||
// pitch (y-axis rotation)
|
||||
float y0 = 2.0f*(q.w*q.y - q.z*q.x);
|
||||
y0 = y0 > 1.0f ? 1.0f : y0;
|
||||
y0 = y0 < -1.0f ? -1.0f : y0;
|
||||
result.y = asinf(y0)*RAD2DEG;
|
||||
// pitch (y-axis rotation)
|
||||
float y0 = 2.0f*(q.w*q.y - q.z*q.x);
|
||||
y0 = y0 > 1.0f ? 1.0f : y0;
|
||||
y0 = y0 < -1.0f ? -1.0f : y0;
|
||||
result.y = asinf(y0)*RAD2DEG;
|
||||
|
||||
// yaw (z-axis rotation)
|
||||
float z0 = 2.0f*(q.w*q.z + q.x*q.y);
|
||||
float z1 = 1.0f - 2.0f*(q.y*q.y + q.z*q.z);
|
||||
result.z = atan2f(z0, z1)*RAD2DEG;
|
||||
// yaw (z-axis rotation)
|
||||
float z0 = 2.0f*(q.w*q.z + q.x*q.y);
|
||||
float z1 = 1.0f - 2.0f*(q.y*q.y + q.z*q.z);
|
||||
result.z = atan2f(z0, z1)*RAD2DEG;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
2689
raylib/rlgl.h
2689
raylib/rlgl.h
File diff suppressed because it is too large
Load diff
|
@ -87,20 +87,11 @@ func GetShaderLocation(shader Shader, uniformName string) int32 {
|
|||
func SetShaderValue(shader Shader, uniformLoc int32, value []float32, size int32) {
|
||||
cshader := shader.cptr()
|
||||
cuniformLoc := (C.int)(uniformLoc)
|
||||
cvalue := (*C.float)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&value)).Data))
|
||||
cvalue := unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&value)).Data)
|
||||
csize := (C.int)(size)
|
||||
C.SetShaderValue(*cshader, cuniformLoc, cvalue, csize)
|
||||
}
|
||||
|
||||
// SetShaderValuei - Set shader uniform value (int)
|
||||
func SetShaderValuei(shader Shader, uniformLoc int32, value []int32, size int32) {
|
||||
cshader := shader.cptr()
|
||||
cuniformLoc := (C.int)(uniformLoc)
|
||||
cvalue := (*C.int)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&value)).Data))
|
||||
csize := (C.int)(size)
|
||||
C.SetShaderValuei(*cshader, cuniformLoc, cvalue, csize)
|
||||
}
|
||||
|
||||
// SetShaderValueMatrix - Set shader uniform value (matrix 4x4)
|
||||
func SetShaderValueMatrix(shader Shader, uniformLoc int32, mat Matrix) {
|
||||
cshader := shader.cptr()
|
||||
|
@ -155,12 +146,11 @@ func GenTexturePrefilter(shader Shader, cubemap Texture2D, size int) Texture2D {
|
|||
}
|
||||
|
||||
// GenTextureBRDF - Generate BRDF texture using cubemap data
|
||||
func GenTextureBRDF(shader Shader, cubemap Texture2D, size int) Texture2D {
|
||||
func GenTextureBRDF(shader Shader, size int) Texture2D {
|
||||
cshader := shader.cptr()
|
||||
ccubemap := cubemap.cptr()
|
||||
csize := (C.int)(size)
|
||||
|
||||
ret := C.GenTextureBRDF(*cshader, *ccubemap, csize)
|
||||
ret := C.GenTextureBRDF(*cshader, csize)
|
||||
v := newTexture2DFromPointer(unsafe.Pointer(&ret))
|
||||
return v
|
||||
}
|
||||
|
@ -187,18 +177,9 @@ func EndBlendMode() {
|
|||
C.EndBlendMode()
|
||||
}
|
||||
|
||||
// GetVrDeviceInfo - Get VR device information for some standard devices
|
||||
func GetVrDeviceInfo(vrDevice VrDevice) VrDeviceInfo {
|
||||
cvrDevice := (C.int)(vrDevice)
|
||||
ret := C.GetVrDeviceInfo(cvrDevice)
|
||||
v := newVrDeviceInfoFromPointer(unsafe.Pointer(&ret))
|
||||
return v
|
||||
}
|
||||
|
||||
// InitVrSimulator - Init VR simulator for selected device
|
||||
func InitVrSimulator(vrDeviceInfo VrDeviceInfo) {
|
||||
cvrDeviceInfo := vrDeviceInfo.cptr()
|
||||
C.InitVrSimulator(*cvrDeviceInfo)
|
||||
func InitVrSimulator() {
|
||||
C.InitVrSimulator()
|
||||
}
|
||||
|
||||
// CloseVrSimulator - Close VR simulator for current device
|
||||
|
|
1108
raylib/shapes.c
1108
raylib/shapes.c
File diff suppressed because it is too large
Load diff
|
@ -117,7 +117,7 @@ func DrawRectanglePro(rec Rectangle, origin Vector2, rotation float32, colors []
|
|||
corigin := origin.cptr()
|
||||
crotation := (C.float)(rotation)
|
||||
ccolor := (*C.Color)(unsafe.Pointer(&colors[0]))
|
||||
C.DrawRectanglePro(*crec, *corigin, crotation, ccolor)
|
||||
C.DrawRectanglePro(*crec, *corigin, crotation, *ccolor)
|
||||
}
|
||||
|
||||
// DrawRectangleGradientV - Draw a vertical-gradient-filled rectangle
|
||||
|
@ -206,22 +206,6 @@ func DrawPoly(center Vector2, sides int32, radius, rotation float32, color Color
|
|||
C.DrawPoly(*ccenter, csides, cradius, crotation, *ccolor)
|
||||
}
|
||||
|
||||
// DrawPolyEx - Draw a closed polygon defined by points
|
||||
func DrawPolyEx(points []Vector2, numPoints int32, color Color) {
|
||||
cpoints := points[0].cptr()
|
||||
cnumPoints := (C.int)(numPoints)
|
||||
ccolor := color.cptr()
|
||||
C.DrawPolyEx(cpoints, cnumPoints, *ccolor)
|
||||
}
|
||||
|
||||
// DrawPolyExLines - Draw polygon lines
|
||||
func DrawPolyExLines(points []Vector2, numPoints int32, color Color) {
|
||||
cpoints := points[0].cptr()
|
||||
cnumPoints := (C.int)(numPoints)
|
||||
ccolor := color.cptr()
|
||||
C.DrawPolyExLines(cpoints, cnumPoints, *ccolor)
|
||||
}
|
||||
|
||||
// CheckCollisionRecs - Check collision between two rectangles
|
||||
func CheckCollisionRecs(rec1, rec2 Rectangle) bool {
|
||||
crec1 := rec1.cptr()
|
||||
|
|
1805
raylib/text.c
1805
raylib/text.c
File diff suppressed because it is too large
Load diff
|
@ -34,13 +34,13 @@ func LoadFont(fileName string) Font {
|
|||
}
|
||||
|
||||
// LoadFontEx - Load Font from file with extended parameters
|
||||
func LoadFontEx(fileName string, fontSize int32, charsCount int32, fontChars *int32) Font {
|
||||
func LoadFontEx(fileName string, fontSize int32, fontChars *int32, charsCount int32) Font {
|
||||
cfileName := C.CString(fileName)
|
||||
defer C.free(unsafe.Pointer(cfileName))
|
||||
cfontSize := (C.int)(fontSize)
|
||||
ccharsCount := (C.int)(charsCount)
|
||||
cfontChars := (*C.int)(unsafe.Pointer(fontChars))
|
||||
ret := C.LoadFontEx(cfileName, cfontSize, ccharsCount, cfontChars)
|
||||
ccharsCount := (C.int)(charsCount)
|
||||
ret := C.LoadFontEx(cfileName, cfontSize, cfontChars, ccharsCount)
|
||||
v := newFontFromPointer(unsafe.Pointer(&ret))
|
||||
return v
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -299,12 +299,13 @@ func ImageTextEx(font Font, text string, fontSize, spacing float32, tint Color)
|
|||
}
|
||||
|
||||
// ImageDraw - Draw a source image within a destination image
|
||||
func ImageDraw(dst, src *Image, srcRec, dstRec Rectangle) {
|
||||
func ImageDraw(dst, src *Image, srcRec, dstRec Rectangle, tint Color) {
|
||||
cdst := dst.cptr()
|
||||
csrc := src.cptr()
|
||||
csrcRec := srcRec.cptr()
|
||||
cdstRec := dstRec.cptr()
|
||||
C.ImageDraw(cdst, *csrc, *csrcRec, *cdstRec)
|
||||
ctint := tint.cptr()
|
||||
C.ImageDraw(cdst, *csrc, *csrcRec, *cdstRec, *ctint)
|
||||
}
|
||||
|
||||
// ImageDrawRectangle - Draw rectangle within an image
|
||||
|
|
197
raylib/utils.c
197
raylib/utils.c
|
@ -11,7 +11,7 @@
|
|||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
|
||||
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
|
@ -30,43 +30,49 @@
|
|||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "raylib.h" // WARNING: Required for: LogType enum
|
||||
|
||||
// Check if config flags have been externally provided on compilation line
|
||||
#if !defined(EXTERNAL_CONFIG_FLAGS)
|
||||
#include "config.h" // Defines module configuration flags
|
||||
#endif
|
||||
|
||||
#include "raylib.h" // WARNING: Required for: LogType enum
|
||||
#include "utils.h"
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
#include <errno.h>
|
||||
#include <android/log.h>
|
||||
#include <android/asset_manager.h>
|
||||
#include <errno.h> // Required for: Android error types
|
||||
#include <android/log.h> // Required for: Android log system: __android_log_vprint()
|
||||
#include <android/asset_manager.h> // Required for: Android assets manager: AAsset, AAssetManager_open(), ...
|
||||
#endif
|
||||
|
||||
#include <stdlib.h> // Required for: malloc(), free()
|
||||
#include <stdio.h> // Required for: fopen(), fclose(), fputc(), fwrite(), printf(), fprintf(), funopen()
|
||||
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
|
||||
#include <string.h> // Required for: strlen(), strrchr(), strcmp()
|
||||
#include <stdlib.h> // Required for: exit()
|
||||
#include <stdio.h> // Required for: printf(), sprintf()
|
||||
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
|
||||
#include <string.h> // Required for: strcpy(), strcat()
|
||||
|
||||
/* This should be in <stdio.h>, but Travis doesn't find it... */
|
||||
FILE *funopen(const void *cookie, int (*readfn)(void *, char *, int),
|
||||
int (*writefn)(void *, const char *, int),
|
||||
fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *));
|
||||
#define MAX_TRACELOG_BUFFER_SIZE 128 // Max length of one trace-log message
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Log types messages supported flags (bit based)
|
||||
static unsigned char logTypeFlags = LOG_INFO | LOG_WARNING | LOG_ERROR;
|
||||
// Log types messages
|
||||
static int logTypeLevel = LOG_INFO;
|
||||
static int logTypeExit = LOG_ERROR;
|
||||
static TraceLogCallback logCallback = NULL;
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
AAssetManager *assetManager;
|
||||
AAssetManager *assetManager = NULL;
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
// This should be in <stdio.h>, but Travis does not find it...
|
||||
FILE *funopen(const void *cookie, int (*readfn)(void *, char *, int), int (*writefn)(void *, const char *, int),
|
||||
fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *));
|
||||
|
||||
static int android_read(void *cookie, char *buf, int size);
|
||||
static int android_write(void *cookie, const char *buf, int size);
|
||||
static fpos_t android_seek(void *cookie, fpos_t offset, int whence);
|
||||
|
@ -77,82 +83,78 @@ static int android_close(void *cookie);
|
|||
// Module Functions Definition - Utilities
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Enable trace log message types (bit flags based)
|
||||
void SetTraceLog(unsigned char types)
|
||||
// Set the current threshold (minimum) log level
|
||||
void SetTraceLogLevel(int logType)
|
||||
{
|
||||
logTypeFlags = types;
|
||||
logTypeLevel = logType;
|
||||
}
|
||||
|
||||
// Set a trace log callback to enable custom logging bypassing raylib's one
|
||||
// Set the exit threshold (minimum) log level
|
||||
void SetTraceLogExit(int logType)
|
||||
{
|
||||
logTypeExit = logType;
|
||||
}
|
||||
|
||||
// Set a trace log callback to enable custom logging
|
||||
void SetTraceLogCallback(TraceLogCallback callback)
|
||||
{
|
||||
logCallback = callback;
|
||||
}
|
||||
|
||||
// Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG)
|
||||
void TraceLog(int msgType, const char *text, ...)
|
||||
void TraceLog(int logType, const char *text, ...)
|
||||
{
|
||||
#if defined(SUPPORT_TRACELOG)
|
||||
static char buffer[128];
|
||||
// Message has level below current threshold, don't emit
|
||||
if (logType < logTypeLevel) return;
|
||||
|
||||
va_list args;
|
||||
va_start(args, text);
|
||||
|
||||
if (logCallback)
|
||||
{
|
||||
logCallback(msgType, text, args);
|
||||
logCallback(logType, text, args);
|
||||
va_end(args);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(msgType)
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
switch(logType)
|
||||
{
|
||||
case LOG_INFO: strcpy(buffer, "INFO: "); break;
|
||||
case LOG_ERROR: strcpy(buffer, "ERROR: "); break;
|
||||
case LOG_WARNING: strcpy(buffer, "WARNING: "); break;
|
||||
case LOG_TRACE: __android_log_vprint(ANDROID_LOG_VERBOSE, "raylib", text, args); break;
|
||||
case LOG_DEBUG: __android_log_vprint(ANDROID_LOG_DEBUG, "raylib", text, args); break;
|
||||
case LOG_INFO: __android_log_vprint(ANDROID_LOG_INFO, "raylib", text, args); break;
|
||||
case LOG_WARNING: __android_log_vprint(ANDROID_LOG_WARN, "raylib", text, args); break;
|
||||
case LOG_ERROR: __android_log_vprint(ANDROID_LOG_ERROR, "raylib", text, args); break;
|
||||
case LOG_FATAL: __android_log_vprint(ANDROID_LOG_FATAL, "raylib", text, args); break;
|
||||
default: break;
|
||||
}
|
||||
#else
|
||||
char buffer[MAX_TRACELOG_BUFFER_SIZE] = { 0 };
|
||||
|
||||
switch (logType)
|
||||
{
|
||||
case LOG_TRACE: strcpy(buffer, "TRACE: "); break;
|
||||
case LOG_DEBUG: strcpy(buffer, "DEBUG: "); break;
|
||||
case LOG_INFO: strcpy(buffer, "INFO: "); break;
|
||||
case LOG_WARNING: strcpy(buffer, "WARNING: "); break;
|
||||
case LOG_ERROR: strcpy(buffer, "ERROR: "); break;
|
||||
case LOG_FATAL: strcpy(buffer, "FATAL: "); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
strcat(buffer, text);
|
||||
strcat(buffer, "\n");
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
switch(msgType)
|
||||
{
|
||||
case LOG_INFO: if (logTypeFlags & LOG_INFO) __android_log_vprint(ANDROID_LOG_INFO, "raylib", buffer, args); break;
|
||||
case LOG_WARNING: if (logTypeFlags & LOG_WARNING) __android_log_vprint(ANDROID_LOG_WARN, "raylib", buffer, args); break;
|
||||
case LOG_ERROR: if (logTypeFlags & LOG_ERROR) __android_log_vprint(ANDROID_LOG_ERROR, "raylib", buffer, args); break;
|
||||
case LOG_DEBUG: if (logTypeFlags & LOG_DEBUG) __android_log_vprint(ANDROID_LOG_DEBUG, "raylib", buffer, args); break;
|
||||
default: break;
|
||||
}
|
||||
#else
|
||||
switch(msgType)
|
||||
{
|
||||
case LOG_INFO: if (logTypeFlags & LOG_INFO) vprintf(buffer, args); break;
|
||||
case LOG_WARNING: if (logTypeFlags & LOG_WARNING) vprintf(buffer, args); break;
|
||||
case LOG_ERROR: if (logTypeFlags & LOG_ERROR) vprintf(buffer, args); break;
|
||||
case LOG_DEBUG: if (logTypeFlags & LOG_DEBUG) vprintf(buffer, args); break;
|
||||
default: break;
|
||||
}
|
||||
vprintf(buffer, args);
|
||||
#endif
|
||||
|
||||
va_end(args);
|
||||
|
||||
if (msgType == LOG_ERROR) exit(1); // If LOG_ERROR message, exit program
|
||||
if (logType >= logTypeExit) exit(1); // If exit message, exit program
|
||||
|
||||
#endif // SUPPORT_TRACELOG
|
||||
}
|
||||
|
||||
// Keep track of memory allocated
|
||||
// NOTE: mallocType defines the type of data allocated
|
||||
/*
|
||||
void RecordMalloc(int mallocType, int mallocSize, const char *msg)
|
||||
{
|
||||
// TODO: Investigate how to record memory allocation data...
|
||||
// Maybe creating my own malloc function...
|
||||
}
|
||||
*/
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
// Initialize asset manager from android app
|
||||
void InitAssetManager(AAssetManager *manager)
|
||||
|
@ -171,7 +173,7 @@ FILE *android_fopen(const char *fileName, const char *mode)
|
|||
|
||||
return funopen(asset, android_read, android_write, android_seek, android_close);
|
||||
}
|
||||
#endif
|
||||
#endif // PLATFORM_ANDROID
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Definition
|
||||
|
@ -199,4 +201,79 @@ static int android_close(void *cookie)
|
|||
AAsset_close((AAsset *)cookie);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif // PLATFORM_ANDROID
|
||||
|
||||
#if defined(PLATFORM_UWP)
|
||||
|
||||
#define MAX_MESSAGES 512 // If there are over 128 messages, I will cry... either way, this may be too much EDIT: Welp, 512
|
||||
|
||||
static int UWPOutMessageId = -1; // Stores the last index for the message
|
||||
static UWPMessage* UWPOutMessages[MAX_MESSAGES]; // Messages out to UWP
|
||||
|
||||
static int UWPInMessageId = -1; // Stores the last index for the message
|
||||
static UWPMessage* UWPInMessages[MAX_MESSAGES]; // Messages in from UWP
|
||||
|
||||
UWPMessage* CreateUWPMessage(void)
|
||||
{
|
||||
UWPMessage *msg = (UWPMessage *)RL_MALLOC(sizeof(UWPMessage));
|
||||
msg->type = UWP_MSG_NONE;
|
||||
Vector2 v0 = { 0, 0 };
|
||||
msg->paramVector0 = v0;
|
||||
msg->paramInt0 = 0;
|
||||
msg->paramInt1 = 0;
|
||||
msg->paramChar0 = 0;
|
||||
msg->paramFloat0 = 0;
|
||||
msg->paramDouble0 = 0;
|
||||
msg->paramBool0 = false;
|
||||
return msg;
|
||||
}
|
||||
|
||||
void DeleteUWPMessage(UWPMessage *msg)
|
||||
{
|
||||
RL_FREE(msg);
|
||||
}
|
||||
|
||||
bool UWPHasMessages(void)
|
||||
{
|
||||
return (UWPOutMessageId > -1);
|
||||
}
|
||||
|
||||
UWPMessage *UWPGetMessage(void)
|
||||
{
|
||||
if (UWPHasMessages()) return UWPOutMessages[UWPOutMessageId--];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void UWPSendMessage(UWPMessage *msg)
|
||||
{
|
||||
if (UWPInMessageId + 1 < MAX_MESSAGES)
|
||||
{
|
||||
UWPInMessageId++;
|
||||
UWPInMessages[UWPInMessageId] = msg;
|
||||
}
|
||||
else TraceLog(LOG_WARNING, "[UWP Messaging] Not enough array space to register new UWP inbound Message.");
|
||||
}
|
||||
|
||||
void SendMessageToUWP(UWPMessage *msg)
|
||||
{
|
||||
if (UWPOutMessageId + 1 < MAX_MESSAGES)
|
||||
{
|
||||
UWPOutMessageId++;
|
||||
UWPOutMessages[UWPOutMessageId] = msg;
|
||||
}
|
||||
else TraceLog(LOG_WARNING, "[UWP Messaging] Not enough array space to register new UWP outward Message.");
|
||||
}
|
||||
|
||||
bool HasMessageFromUWP(void)
|
||||
{
|
||||
return UWPInMessageId > -1;
|
||||
}
|
||||
|
||||
UWPMessage* GetMessageFromUWP(void)
|
||||
{
|
||||
if (HasMessageFromUWP()) return UWPInMessages[UWPInMessageId--];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif // PLATFORM_UWP
|
||||
|
|
|
@ -12,12 +12,12 @@ import (
|
|||
"os"
|
||||
)
|
||||
|
||||
// SetTraceLog - Enable trace log message types (bit flags based)
|
||||
// SetTraceLog - Enable trace log message types
|
||||
func SetTraceLog(typeFlags int) {
|
||||
logTypeFlags = typeFlags
|
||||
|
||||
ctypeFlags := (C.uchar)(typeFlags)
|
||||
C.SetTraceLog(ctypeFlags)
|
||||
ctypeFlags := (C.int)(typeFlags)
|
||||
C.SetTraceLogLevel(ctypeFlags)
|
||||
}
|
||||
|
||||
// TraceLog - Show trace log messages (INFO, WARNING, ERROR, DEBUG)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
|
||||
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
|
@ -36,7 +36,7 @@
|
|||
// Some basic Defines
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
#define fopen(name, mode) android_fopen(name, mode)
|
||||
#define fopen(name, mode) android_fopen(name, mode)
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -59,6 +59,65 @@ void InitAssetManager(AAssetManager *manager); // Initialize asset manager from
|
|||
FILE *android_fopen(const char *fileName, const char *mode); // Replacement for fopen()
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_UWP)
|
||||
// UWP Messages System
|
||||
typedef enum {
|
||||
UWP_MSG_NONE = 0,
|
||||
|
||||
// Send
|
||||
UWP_MSG_SHOW_MOUSE,
|
||||
UWP_MSG_HIDE_MOUSE,
|
||||
UWP_MSG_LOCK_MOUSE,
|
||||
UWP_MSG_UNLOCK_MOUSE,
|
||||
UWP_MSG_SET_MOUSE_LOCATION, // paramVector0 (pos)
|
||||
|
||||
// Receive (Into C)
|
||||
UWP_MSG_REGISTER_KEY, // paramInt0 (key), paramChar0 (status)
|
||||
UWP_MSG_REGISTER_CLICK, // paramInt0 (button), paramChar0 (status)
|
||||
UWP_MSG_SCROLL_WHEEL_UPDATE, // paramInt0 (delta)
|
||||
UWP_MSG_UPDATE_MOUSE_LOCATION, // paramVector0 (pos)
|
||||
UWP_MSG_SET_GAMEPAD_ACTIVE, // paramInt0 (gamepad), paramBool0 (active or not)
|
||||
UWP_MSG_SET_GAMEPAD_BUTTON, // paramInt0 (gamepad), paramInt1 (button), paramChar0 (status)
|
||||
UWP_MSG_SET_GAMEPAD_AXIS, // paramInt0 (gamepad), int1 (axis), paramFloat0 (value)
|
||||
UWP_MSG_SET_DISPLAY_DIMS, // paramVector0 (display dimensions)
|
||||
UWP_MSG_HANDLE_RESIZE, // paramVector0 (new dimensions) - Onresized event
|
||||
UWP_MSG_SET_GAME_TIME, // paramInt0
|
||||
} UWPMessageType;
|
||||
|
||||
typedef struct UWPMessage {
|
||||
UWPMessageType type; // Message type
|
||||
|
||||
Vector2 paramVector0; // Vector parameters
|
||||
int paramInt0; // Int parameter
|
||||
int paramInt1; // Int parameter
|
||||
char paramChar0; // Char parameters
|
||||
float paramFloat0; // Float parameters
|
||||
double paramDouble0; // Double parameters
|
||||
bool paramBool0; // Bool parameters
|
||||
|
||||
// More parameters can be added and fed to functions
|
||||
} UWPMessage;
|
||||
|
||||
// Allocate UWP Message
|
||||
RLAPI UWPMessage* CreateUWPMessage(void);
|
||||
|
||||
// Free UWP Message
|
||||
RLAPI void DeleteUWPMessage(UWPMessage* msg);
|
||||
|
||||
// Get messages into C++
|
||||
RLAPI bool UWPHasMessages(void);
|
||||
RLAPI UWPMessage* UWPGetMessage(void);
|
||||
RLAPI void UWPSendMessage(UWPMessage* msg);
|
||||
|
||||
// For C to call
|
||||
#ifndef __cplusplus // Hide from C++ code
|
||||
void SendMessageToUWP(UWPMessage* msg);
|
||||
bool HasMessageFromUWP(void);
|
||||
UWPMessage* GetMessageFromUWP(void);
|
||||
#endif
|
||||
|
||||
#endif //defined(PLATFORM_UWP)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue