1
0
Fork 0
mirror of https://github.com/ctruLua/ctruLua.git synced 2025-10-29 01:09:30 +00:00

Updated all the libs, added citro3d, added ctr.swkbd (WIP, untested)

This commit is contained in:
Firew0lf 2016-08-05 17:30:24 +02:00
parent 68a44645f7
commit 49c87e5526
97 changed files with 7341 additions and 944 deletions

View file

@ -0,0 +1,16 @@
#pragma once
#include "types.h"
typedef struct
{
u32 flags[2];
u64 permutation;
int attrCount;
} C3D_AttrInfo;
void AttrInfo_Init(C3D_AttrInfo* info);
int AttrInfo_AddLoader(C3D_AttrInfo* info, int regId, GPU_FORMATS format, int count);
int AttrInfo_AddFixed(C3D_AttrInfo* info, int regId);
C3D_AttrInfo* C3D_GetAttrInfo(void);
void C3D_SetAttrInfo(C3D_AttrInfo* info);

View file

@ -0,0 +1,63 @@
#pragma once
#include "types.h"
#include "buffers.h"
#define C3D_DEFAULT_CMDBUF_SIZE 0x40000
enum
{
C3D_UNSIGNED_BYTE = 0,
C3D_UNSIGNED_SHORT = 1,
};
bool C3D_Init(size_t cmdBufSize);
void C3D_FlushAsync(void);
void C3D_Fini(void);
float C3D_GetCmdBufUsage(void);
void C3D_BindProgram(shaderProgram_s* program);
void C3D_SetViewport(u32 x, u32 y, u32 w, u32 h);
void C3D_SetScissor(GPU_SCISSORMODE mode, u32 left, u32 top, u32 right, u32 bottom);
void C3D_DrawArrays(GPU_Primitive_t primitive, int first, int size);
void C3D_DrawElements(GPU_Primitive_t primitive, int count, int type, const void* indices);
// Immediate-mode vertex submission
void C3D_ImmDrawBegin(GPU_Primitive_t primitive);
void C3D_ImmSendAttrib(float x, float y, float z, float w);
void C3D_ImmDrawEnd(void);
static inline void C3D_ImmDrawRestartPrim(void)
{
GPUCMD_AddWrite(GPUREG_RESTART_PRIMITIVE, 1);
}
static inline void C3D_FlushAwait(void)
{
gspWaitForP3D();
}
static inline void C3D_Flush(void)
{
C3D_FlushAsync();
C3D_FlushAwait();
}
static inline void C3D_VideoSync(void)
{
gspWaitForEvent(GSPGPU_EVENT_VBlank0, false);
gfxSwapBuffersGpu();
}
// Fixed vertex attributes
C3D_FVec* C3D_FixedAttribGetWritePtr(int id);
static inline void C3D_FixedAttribSet(int id, float x, float y, float z, float w)
{
C3D_FVec* ptr = C3D_FixedAttribGetWritePtr(id);
ptr->x = x;
ptr->y = y;
ptr->z = z;
ptr->w = w;
}

View file

@ -0,0 +1,21 @@
#pragma once
#include "types.h"
typedef struct
{
u32 offset;
u32 flags[2];
} C3D_BufCfg;
typedef struct
{
u32 base_paddr;
int bufCount;
C3D_BufCfg buffers[12];
} C3D_BufInfo;
void BufInfo_Init(C3D_BufInfo* info);
int BufInfo_Add(C3D_BufInfo* info, const void* data, ptrdiff_t stride, int attribCount, u64 permutation);
C3D_BufInfo* C3D_GetBufInfo(void);
void C3D_SetBufInfo(C3D_BufInfo* info);

View file

@ -0,0 +1,13 @@
#pragma once
#include "types.h"
void C3D_DepthMap(float zScale, float zOffset);
void C3D_CullFace(GPU_CULLMODE mode);
void C3D_StencilTest(bool enable, GPU_TESTFUNC function, int ref, int inputMask, int writeMask);
void C3D_StencilOp(GPU_STENCILOP sfail, GPU_STENCILOP dfail, GPU_STENCILOP pass);
void C3D_BlendingColor(u32 color);
void C3D_DepthTest(bool enable, GPU_TESTFUNC function, GPU_WRITEMASK writemask);
void C3D_AlphaTest(bool enable, GPU_TESTFUNC function, int ref);
void C3D_AlphaBlend(GPU_BLENDEQUATION colorEq, GPU_BLENDEQUATION alphaEq, GPU_BLENDFACTOR srcClr, GPU_BLENDFACTOR dstClr, GPU_BLENDFACTOR srcAlpha, GPU_BLENDFACTOR dstAlpha);
void C3D_ColorLogicOp(GPU_LOGICOP op);
void C3D_FragOpMode(GPU_FRAGOPMODE mode);

View file

@ -0,0 +1,136 @@
#pragma once
#include "types.h"
#include "lightlut.h"
//-----------------------------------------------------------------------------
// Material
//-----------------------------------------------------------------------------
typedef struct
{
float ambient[3];
float diffuse[3];
float specular0[3];
float specular1[3];
float emission[3];
} C3D_Material;
//-----------------------------------------------------------------------------
// Light environment
//-----------------------------------------------------------------------------
// Forward declarations
typedef struct C3D_Light_t C3D_Light;
typedef struct C3D_LightEnv_t C3D_LightEnv;
typedef struct
{
u32 abs, select, scale;
} C3D_LightLutInputConf;
typedef struct
{
u32 ambient;
u32 numLights;
u32 config[2];
C3D_LightLutInputConf lutInput;
u32 permutation;
} C3D_LightEnvConf;
enum
{
C3DF_LightEnv_Dirty = BIT(0),
C3DF_LightEnv_MtlDirty = BIT(1),
C3DF_LightEnv_LCDirty = BIT(2),
#define C3DF_LightEnv_LutDirty(n) BIT(26+(n))
#define C3DF_LightEnv_LutDirtyAll (0x3F<<26)
};
struct C3D_LightEnv_t
{
void (* Update)(C3D_LightEnv* env);
void (* Dirty)(C3D_LightEnv* env);
u32 flags;
C3D_LightLut* luts[6];
float ambient[3];
C3D_Light* lights[8];
C3D_LightEnvConf conf;
C3D_Material material;
};
void C3D_LightEnvInit(C3D_LightEnv* env);
void C3D_LightEnvBind(C3D_LightEnv* env);
void C3D_LightEnvMaterial(C3D_LightEnv* env, const C3D_Material* mtl);
void C3D_LightEnvAmbient(C3D_LightEnv* env, float r, float g, float b);
void C3D_LightEnvLut(C3D_LightEnv* env, int lutId, int input, bool abs, C3D_LightLut* lut);
enum
{
GPU_SHADOW_PRIMARY = BIT(16),
GPU_SHADOW_SECONDARY = BIT(17),
GPU_INVERT_SHADOW = BIT(18),
GPU_SHADOW_ALPHA = BIT(19),
};
void C3D_LightEnvFresnel(C3D_LightEnv* env, GPU_FRESNELSEL selector);
void C3D_LightEnvBumpMode(C3D_LightEnv* env, GPU_BUMPMODE mode);
void C3D_LightEnvBumpSel(C3D_LightEnv* env, int texUnit);
void C3D_LightEnvShadowMode(C3D_LightEnv* env, u32 mode);
void C3D_LightEnvShadowSel(C3D_LightEnv* env, int texUnit);
void C3D_LightEnvClampHighlights(C3D_LightEnv* env, bool clamp);
//-----------------------------------------------------------------------------
// Light
//-----------------------------------------------------------------------------
typedef struct
{
u32 specular0, specular1, diffuse, ambient;
} C3D_LightMatConf;
typedef struct
{
C3D_LightMatConf material;
u16 position[3]; u16 padding0;
u16 spotDir[3]; u16 padding1;
u32 padding2;
u32 config;
u32 distAttnBias, distAttnScale;
} C3D_LightConf;
enum
{
C3DF_Light_Enabled = BIT(0),
C3DF_Light_Dirty = BIT(1),
C3DF_Light_MatDirty = BIT(2),
//C3DF_Light_Shadow = BIT(3),
//C3DF_Light_Spot = BIT(4),
//C3DF_Light_DistAttn = BIT(5),
C3DF_Light_SPDirty = BIT(14),
C3DF_Light_DADirty = BIT(15),
};
struct C3D_Light_t
{
u16 flags, id;
C3D_LightEnv* parent;
C3D_LightLut *lut_SP, *lut_DA;
float color[3];
C3D_LightConf conf;
};
int C3D_LightInit(C3D_Light* light, C3D_LightEnv* env);
void C3D_LightEnable(C3D_Light* light, bool enable);
void C3D_LightTwoSideDiffuse(C3D_Light* light, bool enable);
void C3D_LightGeoFactor(C3D_Light* light, int id, bool enable);
void C3D_LightColor(C3D_Light* light, float r, float g, float b);
void C3D_LightPosition(C3D_Light* light, C3D_FVec* pos);
void C3D_LightShadowEnable(C3D_Light* light, bool enable);
void C3D_LightSpotEnable(C3D_Light* light, bool enable);
void C3D_LightSpotDir(C3D_Light* light, float x, float y, float z);
void C3D_LightSpotLut(C3D_Light* light, C3D_LightLut* lut);
void C3D_LightDistAttnEnable(C3D_Light* light, bool enable);
void C3D_LightDistAttn(C3D_Light* light, C3D_LightLutDA* lut);

View file

@ -0,0 +1,29 @@
#pragma once
#include "types.h"
#include <math.h>
typedef struct
{
u32 data[256];
} C3D_LightLut;
typedef struct
{
C3D_LightLut lut;
float bias, scale;
} C3D_LightLutDA;
typedef float (* C3D_LightLutFunc)(float x, float param);
typedef float (* C3D_LightLutFuncDA)(float dist, float arg0, float arg1);
static inline float quadratic_dist_attn(float dist, float linear, float quad)
{
return 1.0f / (1.0f + linear*dist + quad*dist*dist);
}
void LightLut_FromArray(C3D_LightLut* lut, float* data);
void LightLut_FromFunc(C3D_LightLut* lut, C3D_LightLutFunc func, float param, bool negative);
void LightLutDA_Create(C3D_LightLutDA* lut, C3D_LightLutFuncDA func, float from, float to, float arg0, float arg1);
#define LightLut_Phong(lut, shininess) LightLut_FromFunc((lut), powf, (shininess), false)
#define LightLutDA_Quadratic(lut, from, to, linear, quad) LightLutDA_Create((lut), quadratic_dist_attn, (from), (to), (linear), (quad))

View file

@ -0,0 +1,671 @@
#pragma once
#include "types.h"
#include <math.h>
#include <string.h>
// See http://tauday.com/tau-manifesto
//#define M_TAU 6.28318530717958647693
/// The one true circumference-to-radius ratio
#define M_TAU (2*M_PI)
/**
* @brief Convert an angle from revolutions to radians
* @param[in] _angle Proportion of a full revolution
* @return Angle in radians
*/
#define C3D_Angle(_angle) ((_angle)*M_TAU)
/**
* @brief Convert an angle from degrees to radians
* @param[in] _angle Angle in degrees
* @return Angle in radians
*/
#define C3D_AngleFromDegrees(_angle) ((_angle)*M_TAU/360.0f)
#define C3D_AspectRatioTop (400.0f / 240.0f) ///< Aspect ratio for 3DS top screen
#define C3D_AspectRatioBot (320.0f / 240.0f) ///< Aspect ratio for 3DS bottom screen
///@name Vector Math
///@{
/**
* @brief Create a new FVec4
* @param[in] x X-component
* @param[in] y Y-component
* @param[in] z Z-component
* @param[in] w W-component
* @return New FVec4
*/
static inline C3D_FVec FVec4_New(float x, float y, float z, float w)
{
return (C3D_FVec){{ w, z, y, x }};
}
/**
* @brief Add two FVec4s
* @param[in] lhs Augend
* @param[in] rhs Addend
* @return lhs+rhs (sum)
*/
static inline C3D_FVec FVec4_Add(C3D_FVec lhs, C3D_FVec rhs)
{
// component-wise addition
return FVec4_New(lhs.x+rhs.x, lhs.y+rhs.y, lhs.z+rhs.z, lhs.w+rhs.w);
}
/**
* @brief Subtract two FVec4s
* @param[in] lhs Minuend
* @param[in] rhs Subtrahend
* @return lhs-rhs (difference)
*/
static inline C3D_FVec FVec4_Subtract(C3D_FVec lhs, C3D_FVec rhs)
{
// component-wise subtraction
return FVec4_New(lhs.x-rhs.x, lhs.y-rhs.y, lhs.z-rhs.z, lhs.w-rhs.w);
}
/**
* @brief Negate a FVec4
* @note This is the same as scaling by -1
* @param[in] v Vector to negate
* @return -v
*/
static inline C3D_FVec FVec4_Negate(C3D_FVec v)
{
// component-wise negation
return FVec4_New(-v.x, -v.y, -v.z, -v.w);
}
/**
* @brief Scale a FVec4
* @param[in] v Vector to scale
* @param[in] s Scale factor
* @return v*s
*/
static inline C3D_FVec FVec4_Scale(C3D_FVec v, float s)
{
// component-wise scaling
return FVec4_New(v.x*s, v.y*s, v.z*s, v.w*s);
}
/**
* @brief Perspective divide
* @param[in] v Vector to divide
* @return v/v.w
*/
static inline C3D_FVec FVec4_PerspDivide(C3D_FVec v)
{
// divide by w
return FVec4_New(v.x/v.w, v.y/v.w, v.z/v.w, 1.0f);
}
/**
* @brief Dot product of two FVec4s
* @param[in] lhs Left-side FVec4
* @param[in] rhs Right-side FVec4
* @return lhsrhs
*/
static inline float FVec4_Dot(C3D_FVec lhs, C3D_FVec rhs)
{
// A∙B = sum of component-wise products
return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z + lhs.w*rhs.w;
}
/**
* @brief Magnitude of a FVec4
* @param[in] v Vector
* @return v
*/
static inline float FVec4_Magnitude(C3D_FVec v)
{
// ‖v‖ = √(v∙v)
return sqrtf(FVec4_Dot(v,v));
}
/**
* @brief Normalize a FVec4
* @param[in] v FVec4 to normalize
* @return v/v
*/
static inline C3D_FVec FVec4_Normalize(C3D_FVec v)
{
// get vector magnitude
float m = FVec4_Magnitude(v);
// scale by inverse magnitude to get a unit vector
return FVec4_New(v.x/m, v.y/m, v.z/m, v.w/m);
}
/**
* @brief Create a new FVec3
* @param[in] x X-component
* @param[in] y Y-component
* @param[in] z Z-component
* @return New FVec3
*/
static inline C3D_FVec FVec3_New(float x, float y, float z)
{
return FVec4_New(x, y, z, 0.0f);
}
/**
* @brief Dot product of two FVec3s
* @param[in] lhs Left-side FVec3
* @param[in] rhs Right-side FVec3
* @return lhsrhs
*/
static inline float FVec3_Dot(C3D_FVec lhs, C3D_FVec rhs)
{
// A∙B = sum of component-wise products
return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z;
}
/**
* @brief Magnitude of a FVec3
* @param[in] v Vector
* @return v
*/
static inline float FVec3_Magnitude(C3D_FVec v)
{
// ‖v‖ = √(v∙v)
return sqrtf(FVec3_Dot(v,v));
}
/**
* @brief Normalize a FVec3
* @param[in] v FVec3 to normalize
* @return v/v
*/
static inline C3D_FVec FVec3_Normalize(C3D_FVec v)
{
// get vector magnitude
float m = FVec3_Magnitude(v);
// scale by inverse magnitude to get a unit vector
return FVec3_New(v.x/m, v.y/m, v.z/m);
}
/**
* @brief Add two FVec3s
* @param[in] lhs Augend
* @param[in] rhs Addend
* @return lhs+rhs (sum)
*/
static inline C3D_FVec FVec3_Add(C3D_FVec lhs, C3D_FVec rhs)
{
// component-wise addition
return FVec3_New(lhs.x+rhs.x, lhs.y+rhs.y, lhs.z+rhs.z);
}
/**
* @brief Subtract two FVec3s
* @param[in] lhs Minuend
* @param[in] rhs Subtrahend
* @return lhs-rhs (difference)
*/
static inline C3D_FVec FVec3_Subtract(C3D_FVec lhs, C3D_FVec rhs)
{
// component-wise subtraction
return FVec3_New(lhs.x-rhs.x, lhs.y-rhs.y, lhs.z-rhs.z);
}
/**
* @brief Distance between two 3D points
* @param[in] lhs Relative origin
* @param[in] rhs Relative point of interest
* @return lhs-rhs
*/
static inline float FVec3_Distance(C3D_FVec lhs, C3D_FVec rhs)
{
// distance = ‖lhs-rhs‖
return FVec3_Magnitude(FVec3_Subtract(lhs, rhs));
}
/**
* @brief Scale a FVec4
* @param[in] v Vector to scale
* @param[in] s Scale factor
* @return v*s
*/
static inline C3D_FVec FVec3_Scale(C3D_FVec v, float s)
{
// component-wise scaling
return FVec3_New(v.x*s, v.y*s, v.z*s);
}
/**
* @brief Negate a FVec4
* @note This is the same as scaling by -1
* @param[in] v Vector to negate
* @return -v
*/
static inline C3D_FVec FVec3_Negate(C3D_FVec v)
{
// component-wise negation
return FVec3_New(-v.x, -v.y, -v.z);
}
/**
* @brief Cross product of two FVec3s
* @note This returns a pseudo-vector which is perpendicular to the plane
* spanned by the two input vectors.
* @param[in] lhs Left-side FVec3
* @param[in] rhs Right-side FVec3
* @return lhs×rhs
*/
static inline C3D_FVec FVec3_Cross(C3D_FVec lhs, C3D_FVec rhs)
{
// A×B = (AyBz - AzBy, AzBx - AxBz, AxBy - AyBx)
return FVec3_New(lhs.y*rhs.z - lhs.z*rhs.y, lhs.z*rhs.x - lhs.x*rhs.z, lhs.x*rhs.y - lhs.y*rhs.x);
}
///@}
///@name Matrix Math
///@note All matrices are 4x4 unless otherwise noted
///@{
/**
* @brief Zero matrix
* @param[out] out Matrix to zero
*/
static inline void Mtx_Zeros(C3D_Mtx* out)
{
memset(out, 0, sizeof(*out));
}
/**
* @brief Copy a matrix
* @param[out] out Output matrix
* @param[in] in Input matrix
*/
static inline void Mtx_Copy(C3D_Mtx* out, const C3D_Mtx* in)
{
*out = *in;
}
/**
* @brief Identity matrix
* @param[out] out Matrix to fill
*/
void Mtx_Identity(C3D_Mtx* out);
/**
* @brief Multiply two matrices
* @param[out] out Output matrix
* @param[in] a Multiplicand
* @param[in] b Multiplier
*/
void Mtx_Multiply(C3D_Mtx* out, const C3D_Mtx* a, const C3D_Mtx* b);
/**
* @brief Inverse a matrix
* @note returns 0.0f if the matrix is degenerate; i.e. no inverse
* @param[in,out] out Matrix to inverse
* @return determinant
*/
float Mtx_Inverse(C3D_Mtx* out);
/**
* @brief Multiply 3x3 matrix by a FVec3
* @param[in] mtx Matrix
* @param[in] v Vector
* @return Product of mtx and v
*/
C3D_FVec Mtx_MultiplyFVec3(const C3D_Mtx* mtx, C3D_FVec v);
/**
* @brief Multiply 4x4 matrix by a FVec4
* @param[in] mtx Matrix
* @param[in] v Vector
* @return Product of mtx and v
*/
C3D_FVec Mtx_MultiplyFVec4(const C3D_Mtx* mtx, C3D_FVec v);
/**
* @brief Multiply 4x3 matrix by a FVec3
* @param[in] mtx Matrix
* @param[in] v Vector
* @return Product of mtx and v
*/
static inline C3D_FVec Mtx_MultiplyFVecH(const C3D_Mtx* mtx, C3D_FVec v)
{
v.w = 1.0f;
return Mtx_MultiplyFVec4(mtx, v);
}
///@}
/**
* @name 3D Transformation Matrix Math
* @note bRightSide is used to determine which side to perform the transformation.
* With an input matrix A and a transformation matrix B, bRightSide being
* true yields AB, while being false yield BA.
*/
///@{
/**
* @brief 3D translation
* @param[in,out] mtx Matrix to translate
* @param[in] x X component to translate
* @param[in] y Y component to translate
* @param[in] z Z component to translate
* @param[in] bRightSide Whether to transform from the right side
*/
void Mtx_Translate(C3D_Mtx* mtx, float x, float y, float z, bool bRightSide);
/**
* @brief 3D Scale
* @param[in,out] mtx Matrix to scale
* @param[in] x X component to scale
* @param[in] y Y component to scale
* @param[in] z Z component to scale
*/
void Mtx_Scale(C3D_Mtx* mtx, float x, float y, float z);
/**
* @brief 3D Rotation
* @param[in,out] mtx Matrix to rotate
* @param[in] axis Axis about which to rotate
* @param[in] angle Radians to rotate
* @param[in] bRightSide Whether to transform from the right side
*/
void Mtx_Rotate(C3D_Mtx* mtx, C3D_FVec axis, float angle, bool bRightSide);
/**
* @brief 3D Rotation about the X axis
* @param[in,out] mtx Matrix to rotate
* @param[in] angle Radians to rotate
* @param[in] bRightSide Whether to transform from the right side
*/
void Mtx_RotateX(C3D_Mtx* mtx, float angle, bool bRightSide);
/**
* @brief 3D Rotation about the Y axis
* @param[in,out] mtx Matrix to rotate
* @param[in] angle Radians to rotate
* @param[in] bRightSide Whether to transform from the right side
*/
void Mtx_RotateY(C3D_Mtx* mtx, float angle, bool bRightSide);
/**
* @brief 3D Rotation about the Z axis
* @param[in,out] mtx Matrix to rotate
* @param[in] angle Radians to rotate
* @param[in] bRightSide Whether to transform from the right side
*/
void Mtx_RotateZ(C3D_Mtx* mtx, float angle, bool bRightSide);
///@}
///@name 3D Projection Matrix Math
///@{
/**
* @brief Orthogonal projection
* @param[out] mtx Output matrix
* @param[in] left Left clip plane (X=left)
* @param[in] right Right clip plane (X=right)
* @param[in] bottom Bottom clip plane (Y=bottom)
* @param[in] top Top clip plane (Y=top)
* @param[in] near Near clip plane (Z=near)
* @param[in] far Far clip plane (Z=far)
* @param[in] isLeftHanded Whether to build a LH projection
*/
void Mtx_Ortho(C3D_Mtx* mtx, float left, float right, float bottom, float top, float near, float far, bool isLeftHanded);
/**
* @brief Perspective projection
* @param[out] mtx Output matrix
* @param[in] fovy Vertical field of view in radians
* @param[in] aspect Aspect ration of projection plane (width/height)
* @param[in] near Near clip plane (Z=near)
* @param[in] far Far clip plane (Z=far)
* @param[in] isLeftHanded Whether to build a LH projection
*/
void Mtx_Persp(C3D_Mtx* mtx, float fovy, float aspect, float near, float far, bool isLeftHanded);
/**
* @brief Stereo perspective projection
* @note Typically you will use iod to mean the distance between the eyes. Plug
* in -iod for the left eye and iod for the right eye.
* @note The focal length is defined by screen. If objects are further than this,
* they will appear to be inside the screen. If objects are closer than this,
* they will appear to pop out of the screen. Objects at this distance appear
* to be at the screen.
* @param[out] mtx Output matrix
* @param[in] fovy Vertical field of view in radians
* @param[in] aspect Aspect ration of projection plane (width/height)
* @param[in] near Near clip plane (Z=near)
* @param[in] far Far clip plane (Z=far)
* @param[in] iod Interocular distance
* @param[in] screen Focal length
* @param[in] isLeftHanded Whether to build a LH projection
*/
void Mtx_PerspStereo(C3D_Mtx* mtx, float fovy, float aspect, float near, float far, float iod, float screen, bool isLeftHanded);
/**
* @brief Orthogonal projection, tilted to account for the 3DS screen rotation
* @param[in] left Left clip plane (X=left)
* @param[in] right Right clip plane (X=right)
* @param[in] bottom Bottom clip plane (Y=bottom)
* @param[in] top Top clip plane (Y=top)
* @param[in] near Near clip plane (Z=near)
* @param[in] far Far clip plane (Z=far)
* @param[in] isLeftHanded Whether to build a LH projection
*/
void Mtx_OrthoTilt(C3D_Mtx* mtx, float left, float right, float bottom, float top, float near, float far, bool isLeftHanded);
/**
* @brief Perspective projection, tilted to account for the 3DS screen rotation
* @param[out] mtx Output matrix
* @param[in] fovy Vertical field of view in radians
* @param[in] aspect Aspect ration of projection plane (width/height)
* @param[in] near Near clip plane (Z=near)
* @param[in] far Far clip plane (Z=far)
* @param[in] isLeftHanded Whether to build a LH projection
*/
void Mtx_PerspTilt(C3D_Mtx* mtx, float fovy, float aspect, float near, float far, bool isLeftHanded);
/**
* @brief Stereo perspective projection, tilted to account for the 3DS screen rotation
* @note See the notes for Mtx_PerspStereo
* @param[out] mtx Output matrix
* @param[in] fovy Vertical field of view in radians
* @param[in] aspect Aspect ration of projection plane (width/height)
* @param[in] near Near clip plane (Z=near)
* @param[in] far Far clip plane (Z=far)
* @param[in] iod Interocular distance
* @param[in] screen Focal length
* @param[in] isLeftHanded Whether to build a LH projection
*/
void Mtx_PerspStereoTilt(C3D_Mtx* mtx, float fovy, float aspect, float near, float far, float iod, float screen, bool isLeftHanded);
/**
* @brief Left-handed Look-At matrix, using DirectX implementation
* @note See https://msdn.microsoft.com/en-us/library/windows/desktop/bb205342
* @param[out] out Output matrix.
* @param[in] cameraPosition Position of the intended camera in 3D space.
* @param[in] cameraTarget Position of the intended target the camera is supposed to face in 3D space.
* @param[in] cameraUpVector The vector that points straight up depending on the camera's "Up" direction.
* @param[in] isLeftHanded If true, output matrix is left-handed. If false, output matrix is right-handed.
*/
void Mtx_LookAt(C3D_Mtx* out, C3D_FVec cameraPosition, C3D_FVec cameraTarget, C3D_FVec cameraUpVector, bool isLeftHanded);
///@}
///@name Quaternion Math
///@{
//
/**
* @brief Create a new Quaternion
* @param[in] i I-component
* @param[in] j J-component
* @param[in] k K-component
* @param[in] r R-component
* @return New Quaternion
*/
#define Quat_New(i,j,k,r) FVec4_New(i,j,k,r)
/**
* @brief Negate a Quaternion
* @note This is the same as scaling by -1
* @param[in] q Quaternion to negate
* @return -q
*/
#define Quat_Negate(q) FVec4_Negate(q)
/**
* @brief Add two Quaternions
* @param[in] lhs Augend
* @param[in] rhs Addend
* @return lhs+rhs (sum)
*/
#define Quat_Add(lhs,rhs) FVec4_Add(lhs,rhs)
/**
* @brief Subtract two Quaternions
* @param[in] lhs Minuend
* @param[in] rhs Subtrahend
* @return lhs-rhs (difference)
*/
#define Quat_Subtract(lhs,rhs) FVec4_Subtract(lhs,rhs)
/**
* @brief Scale a Quaternion
* @param[in] q Quaternion to scale
* @param[in] s Scale factor
* @return q*s
*/
#define Quat_Scale(q,s) FVec4_Scale(q,s)
/**
* @brief Normalize a Quaternion
* @param[in] q Quaternion to normalize
* @return q/q
*/
#define Quat_Normalize(q) FVec4_Normalize(q)
/**
* @brief Dot product of two Quaternions
* @param[in] lhs Left-side Quaternion
* @param[in] rhs Right-side Quaternion
* @return lhsrhs
*/
#define Quat_Dot(lhs,rhs) FVec4_Dot(lhs,rhs)
/**
* @brief Multiply two Quaternions
* @param[in] lhs Multiplicand
* @param[in] rhs Multiplier
* @return lhs*rhs
*/
C3D_FQuat Quat_Multiply(C3D_FQuat lhs, C3D_FQuat rhs);
/**
* @brief Raise Quaternion to a power
* @note If p is 0, this returns the identity Quaternion.
* If p is 1, this returns q.
* @param[in] q Base Quaternion
* @param[in] p Power
* @return q^p
*/
C3D_FQuat Quat_Pow(C3D_FQuat q, float p);
/**
* @brief Cross product of Quaternion and FVec3
* @param[in] lhs Left-side Quaternion
* @param[in] rhs Right-side FVec3
* @return q×v
*/
C3D_FVec Quat_CrossFVec3(C3D_FQuat q, C3D_FVec v);
/**
* @brief 3D Rotation
* @param[in] q Quaternion to rotate
* @param[in] axis Axis about which to rotate
* @param[in] r Radians to rotate
* @param[in] bRightSide Whether to transform from the right side
* @return Rotated Quaternion
*/
C3D_FQuat Quat_Rotate(C3D_FQuat q, C3D_FVec axis, float r, bool bRightSide);
/**
* @brief 3D Rotation about the X axis
* @param[in] q Quaternion to rotate
* @param[in] r Radians to rotate
* @param[in] bRightSide Whether to transform from the right side
* @return Rotated Quaternion
*/
C3D_FQuat Quat_RotateX(C3D_FQuat q, float r, bool bRightSide);
/**
* @brief 3D Rotation about the Y axis
* @param[in] q Quaternion to rotate
* @param[in] r Radians to rotate
* @param[in] bRightSide Whether to transform from the right side
* @return Rotated Quaternion
*/
C3D_FQuat Quat_RotateY(C3D_FQuat q, float r, bool bRightSide);
/**
* @brief 3D Rotation about the Z axis
* @param[in] q Quaternion to rotate
* @param[in] r Radians to rotate
* @param[in] bRightSide Whether to transform from the right side
* @return Rotated Quaternion
*/
C3D_FQuat Quat_RotateZ(C3D_FQuat q, float r, bool bRightSide);
/**
* @brief Get 4x4 matrix equivalent to Quaternion
* @param[out] m Output matrix
* @param[in] q Input Quaternion
*/
void Mtx_FromQuat(C3D_Mtx* m, C3D_FQuat q);
/**
* @brief Identity Quaternion
* @return Identity Quaternion
*/
static inline C3D_FQuat Quat_Identity(void)
{
// r=1, i=j=k=0
return Quat_New(0.0f, 0.0f, 0.0f, 1.0f);
}
/**
* @brief Quaternion conjugate
* @param[in] q Quaternion of which to get conjugate
* @return Conjugate of q
*/
static inline C3D_FQuat Quat_Conjugate(C3D_FQuat q)
{
// q* = q.r - q.i - q.j - q.k
return Quat_New(-q.i, -q.j, -q.k, q.r);
}
/**
* @brief Quaternion inverse
* @note This is the same as raising to the power of -1
* @param[in] q Quaternion of which to get inverse
* @return Inverse of q
*/
static inline C3D_FQuat Quat_Inverse(C3D_FQuat q)
{
// q^-1 = (q.r - q.i - q.j - q.k) / (q.r^2 + q.i^2 + q.j^2 + q.k^2)
// = q* / (q∙q)
C3D_FQuat c = Quat_Conjugate(q);
float d = Quat_Dot(q, q);
return Quat_New(c.i/d, c.j/d, c.k/d, c.r/d);
}
/**
* @brief Cross product of FVec3 and Quaternion
* @param[in] lhs Left-side FVec3
* @param[in] rhs Right-side Quaternion
* @return v×q
*/
static inline C3D_FVec FVec3_CrossQuat(C3D_FVec v, C3D_FQuat q)
{
// v×q = q^-1×v
return Quat_CrossFVec3(Quat_Inverse(q), v);
}
///@}

View file

@ -0,0 +1,23 @@
#pragma once
#include "maths.h"
#define C3D_MTXSTACK_SIZE 8
typedef struct
{
C3D_Mtx m[C3D_MTXSTACK_SIZE];
int pos;
u8 unifType, unifPos, unifLen;
bool isDirty;
} C3D_MtxStack;
static inline C3D_Mtx* MtxStack_Cur(C3D_MtxStack* stk)
{
stk->isDirty = true;
return &stk->m[stk->pos];
}
void MtxStack_Init(C3D_MtxStack* stk);
void MtxStack_Bind(C3D_MtxStack* stk, GPU_SHADER_TYPE unifType, int unifPos, int unifLen);
C3D_Mtx* MtxStack_Push(C3D_MtxStack* stk);
C3D_Mtx* MtxStack_Pop(C3D_MtxStack* stk);
void MtxStack_Update(C3D_MtxStack* stk);

View file

@ -0,0 +1,28 @@
#pragma once
#include "types.h"
#include "texture.h"
typedef struct
{
C3D_Tex colorBuf, depthBuf;
u32 clearColor, clearDepth;
int depthFmt;
} C3D_RenderBuf;
bool C3D_RenderBufInit(C3D_RenderBuf* rb, int width, int height, int colorFmt, int depthFmt);
void C3D_RenderBufClearAsync(C3D_RenderBuf* rb);
void C3D_RenderBufTransferAsync(C3D_RenderBuf* rb, u32* frameBuf, u32 flags);
void C3D_RenderBufBind(C3D_RenderBuf* rb);
void C3D_RenderBufDelete(C3D_RenderBuf* rb);
static inline void C3D_RenderBufClear(C3D_RenderBuf* rb)
{
C3D_RenderBufClearAsync(rb);
gspWaitForPSC0();
}
static inline void C3D_RenderBufTransfer(C3D_RenderBuf* rb, u32* frameBuf, u32 flags)
{
C3D_RenderBufTransferAsync(rb, frameBuf, flags);
gspWaitForPPF();
}

View file

@ -0,0 +1,46 @@
#pragma once
#include "renderbuffer.h"
typedef struct C3D_RenderTarget_tag C3D_RenderTarget;
struct C3D_RenderTarget_tag
{
C3D_RenderTarget *next, *prev, *link, *frame[2];
C3D_RenderBuf renderBuf;
u32 transferFlags;
u8 clearBits;
bool drawOk, transferOk;
bool linked;
gfxScreen_t screen;
gfx3dSide_t side;
};
// Flags for C3D_FrameBegin
enum
{
C3D_FRAME_SYNCDRAW = BIT(0), // Do not render the frame until the previous has finished rendering
C3D_FRAME_NONBLOCK = BIT(1), // Return false instead of waiting for the GPU to finish rendering
};
bool C3D_FrameBegin(u8 flags);
bool C3D_FrameDrawOn(C3D_RenderTarget* target);
void C3D_FrameEnd(u8 flags);
// Flags for C3D_RenderTargetSetClear (only C3D_CLEAR_ALL implemented atm)
enum
{
C3D_CLEAR_COLOR = BIT(0),
C3D_CLEAR_DEPTH = BIT(1),
C3D_CLEAR_ALL = C3D_CLEAR_COLOR | C3D_CLEAR_DEPTH,
};
C3D_RenderTarget* C3D_RenderTargetCreate(int width, int height, int colorFmt, int depthFmt);
void C3D_RenderTargetDelete(C3D_RenderTarget* target);
void C3D_RenderTargetSetClear(C3D_RenderTarget* target, u32 clearBits, u32 clearColor, u32 clearDepth);
void C3D_RenderTargetSetOutput(C3D_RenderTarget* target, gfxScreen_t screen, gfx3dSide_t side, u32 transferFlags);
void C3D_SafeDisplayTransfer(u32* inadr, u32 indim, u32* outadr, u32 outdim, u32 flags);
void C3D_SafeTextureCopy(u32* inadr, u32 indim, u32* outadr, u32 outdim, u32 size, u32 flags);
void C3D_SafeMemoryFill(u32* buf0a, u32 buf0v, u32* buf0e, u16 control0, u32* buf1a, u32 buf1v, u32* buf1e, u16 control1);

View file

@ -0,0 +1,65 @@
#pragma once
#include "types.h"
typedef struct
{
u16 srcRgb, srcAlpha;
u16 opRgb, opAlpha;
u16 funcRgb, funcAlpha;
u32 color;
u16 scaleRgb, scaleAlpha;
} C3D_TexEnv;
enum
{
C3D_RGB = BIT(0),
C3D_Alpha = BIT(1),
C3D_Both = C3D_RGB | C3D_Alpha,
};
void TexEnv_Init(C3D_TexEnv* env);
C3D_TexEnv* C3D_GetTexEnv(int id);
void C3D_SetTexEnv(int id, C3D_TexEnv* env);
void C3D_TexEnvBufUpdate(int mode, int mask);
void C3D_TexEnvBufColor(u32 color);
static inline void C3D_TexEnvSrc(C3D_TexEnv* env, int mode, int s1, int s2, int s3)
{
int param = GPU_TEVSOURCES(s1, s2, s3);
if (mode & C3D_RGB)
env->srcRgb = param;
if (mode & C3D_Alpha)
env->srcAlpha = param;
}
static inline void C3D_TexEnvOp(C3D_TexEnv* env, int mode, int o1, int o2, int o3)
{
int param = GPU_TEVOPERANDS(o1, o2, o3);
if (mode & C3D_RGB)
env->opRgb = param;
if (mode & C3D_Alpha)
env->opAlpha = param;
}
static inline void C3D_TexEnvFunc(C3D_TexEnv* env, int mode, int param)
{
if (mode & C3D_RGB)
env->funcRgb = param;
if (mode & C3D_Alpha)
env->funcAlpha = param;
}
static inline void C3D_TexEnvColor(C3D_TexEnv* env, u32 color)
{
env->color = color;
}
static inline void C3D_TexEnvScale(C3D_TexEnv* env, int mode, int param)
{
if (mode & C3D_RGB)
env->scaleRgb = param;
if (mode & C3D_Alpha)
env->scaleAlpha = param;
}

View file

@ -0,0 +1,22 @@
#pragma once
#include "types.h"
typedef struct
{
void* data;
GPU_TEXCOLOR fmt : 4;
size_t size : 28;
u16 width, height;
u32 param;
} C3D_Tex;
bool C3D_TexInit(C3D_Tex* tex, int width, int height, GPU_TEXCOLOR format);
bool C3D_TexInitVRAM(C3D_Tex* tex, int width, int height, GPU_TEXCOLOR format);
void C3D_TexUpload(C3D_Tex* tex, const void* data);
void C3D_TexSetFilter(C3D_Tex* tex, GPU_TEXTURE_FILTER_PARAM magFilter, GPU_TEXTURE_FILTER_PARAM minFilter);
void C3D_TexSetWrap(C3D_Tex* tex, GPU_TEXTURE_WRAP_PARAM wrapS, GPU_TEXTURE_WRAP_PARAM wrapT);
void C3D_TexBind(int unitId, C3D_Tex* tex);
void C3D_TexFlush(C3D_Tex* tex);
void C3D_TexDelete(C3D_Tex* tex);

View file

@ -0,0 +1,32 @@
#pragma once
#ifdef _3DS
#include <3ds.h>
#else
#include <stdbool.h>
#include <stdint.h>
typedef uint8_t u8;
typedef uint32_t u32;
#endif
typedef u32 C3D_IVec;
typedef union
{
struct { float w, z, y, x; };
struct { float r, k, j, i; };
float c[4];
} C3D_FVec;
typedef C3D_FVec C3D_FQuat;
// Row-major 4x4 matrix
typedef union
{
C3D_FVec r[4]; // Rows are vectors
float m[4*4];
} C3D_Mtx;
static inline C3D_IVec IVec_Pack(u8 x, u8 y, u8 z, u8 w)
{
return (u32)x | ((u32)y << 8) | ((u32)z << 16) | ((u32)w << 24);
}

View file

@ -0,0 +1,77 @@
#pragma once
#include "types.h"
#define C3D_FVUNIF_COUNT 96
#define C3D_IVUNIF_COUNT 4
extern C3D_FVec C3D_FVUnif[2][C3D_FVUNIF_COUNT];
extern C3D_IVec C3D_IVUnif[2][C3D_IVUNIF_COUNT];
extern u16 C3D_BoolUnifs[2];
extern bool C3D_FVUnifDirty[2][C3D_FVUNIF_COUNT];
extern bool C3D_IVUnifDirty[2][C3D_IVUNIF_COUNT];
extern bool C3D_BoolUnifsDirty[2];
static inline C3D_FVec* C3D_FVUnifWritePtr(GPU_SHADER_TYPE type, int id, int size)
{
int i;
for (i = 0; i < size; i ++)
C3D_FVUnifDirty[type][id+i] = true;
return &C3D_FVUnif[type][id];
}
static inline C3D_IVec* C3D_IVUnifWritePtr(GPU_SHADER_TYPE type, int id)
{
id -= 0x60;
C3D_IVUnifDirty[type][id] = true;
return &C3D_IVUnif[type][id];
}
static inline void C3D_FVUnifMtxNx4(GPU_SHADER_TYPE type, int id, const C3D_Mtx* mtx, int num)
{
int i;
C3D_FVec* ptr = C3D_FVUnifWritePtr(type, id, num);
for (i = 0; i < num; i ++)
ptr[i] = mtx->r[i]; // Struct copy.
}
static inline void C3D_FVUnifMtx4x4(GPU_SHADER_TYPE type, int id, const C3D_Mtx* mtx)
{
C3D_FVUnifMtxNx4(type, id, mtx, 4);
}
static inline void C3D_FVUnifMtx3x4(GPU_SHADER_TYPE type, int id, const C3D_Mtx* mtx)
{
C3D_FVUnifMtxNx4(type, id, mtx, 3);
}
static inline void C3D_FVUnifMtx2x4(GPU_SHADER_TYPE type, int id, const C3D_Mtx* mtx)
{
C3D_FVUnifMtxNx4(type, id, mtx, 2);
}
static inline void C3D_FVUnifSet(GPU_SHADER_TYPE type, int id, float x, float y, float z, float w)
{
C3D_FVec* ptr = C3D_FVUnifWritePtr(type, id, 1);
ptr->x = x;
ptr->y = y;
ptr->z = z;
ptr->w = w;
}
static inline void C3D_IVUnifSet(GPU_SHADER_TYPE type, int id, int x, int y, int z, int w)
{
C3D_IVec* ptr = C3D_IVUnifWritePtr(type, id);
*ptr = IVec_Pack(x, y, z, w);
}
static inline void C3D_BoolUnifSet(GPU_SHADER_TYPE type, int id, bool value)
{
id -= 0x68;
C3D_BoolUnifsDirty[type] = true;
if (value)
C3D_BoolUnifs[type] |= BIT(id);
else
C3D_BoolUnifs[type] &= ~BIT(id);
}
void C3D_UpdateUniforms(GPU_SHADER_TYPE type);

View file

@ -0,0 +1,30 @@
#pragma once
#ifdef CITRO3D_BUILD
#error "This header file is only for external users of citro3d."
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include "c3d/types.h"
#include "c3d/maths.h"
#include "c3d/mtxstack.h"
#include "c3d/uniforms.h"
#include "c3d/attribs.h"
#include "c3d/buffers.h"
#include "c3d/base.h"
#include "c3d/texenv.h"
#include "c3d/effect.h"
#include "c3d/texture.h"
#include "c3d/light.h"
#include "c3d/renderbuffer.h"
#include "c3d/renderqueue.h"
#ifdef __cplusplus
}
#endif