1
0
mirror of https://github.com/borgesdan/xn65 synced 2024-12-29 21:54:47 +01:00

Merge pull request #1 from borgesdan/feature/Content

Feature/content
This commit is contained in:
Danilo Borges 2024-05-09 09:16:39 -03:00 committed by GitHub
commit 52ac1447c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
65 changed files with 3643 additions and 332 deletions

View File

@ -9,6 +9,8 @@ if (POLICY CMP0141)
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
endif()
set(ENV{VCPKG_ROOT} C:\\vcpkg)
project ("xna")
# Include sub-projects.

View File

@ -3,7 +3,43 @@
#
# Add source to this project's executable.
add_executable (xna WIN32 "xna.cpp" "xna.h" "platform/window-dx.cpp" "platform/device-dx.cpp" "platform/adapter-dx.cpp" "platform/swapchain-dx.cpp" "platform/rendertarget-dx.cpp" "platform/texture-dx.cpp" "platform/blendstate-dx.cpp" "platform/game-dx.cpp" "platform/clock-dx.cpp" "csharp/stream.cpp" "platform/gdevicemanager-dx.cpp" "platform/vertexinput-dx.cpp" "platform/shader-dx.cpp" "platform/rasterizerstate-dx.cpp" "platform/vertexbuffer-dx.cpp" "platform/indexbuffer-dx.cpp" "common/matrix.cpp" "platform/constbuffer-dx.cpp" "platform/databuffer-dx.cpp" "platform/samplerstate-dx.cpp" "platform/spritebatch-dx.cpp" "platform/spritefont-dx.cpp" "platform/depthstencilstate-dx.cpp" "platform/keyboard-dx.cpp" "platform/mouse-dx.cpp" "platform/gamepad-dx.cpp" "common/vectors.cpp" "platform/soundeffect-dx.cpp" "platform/displaymode-dx.cpp" "platform/presentparameters-dx.cpp" "game/component.cpp" "content/manager.cpp" "content/reader.cpp" "csharp/binary.cpp")
add_executable (xna WIN32
"xna.cpp"
"platform/window-dx.cpp"
"platform/device-dx.cpp"
"platform/adapter-dx.cpp"
"platform/swapchain-dx.cpp"
"platform/rendertarget-dx.cpp"
"platform/texture-dx.cpp"
"platform/blendstate-dx.cpp"
"platform/game-dx.cpp"
"platform/clock-dx.cpp"
"csharp/stream.cpp"
"platform/gdevicemanager-dx.cpp"
"platform/vertexinput-dx.cpp"
"platform/shader-dx.cpp"
"platform/rasterizerstate-dx.cpp"
"platform/vertexbuffer-dx.cpp"
"platform/indexbuffer-dx.cpp"
"common/matrix.cpp"
"platform/constbuffer-dx.cpp"
"platform/databuffer-dx.cpp"
"platform/samplerstate-dx.cpp"
"platform/spritebatch-dx.cpp"
"platform/spritefont-dx.cpp"
"platform/depthstencilstate-dx.cpp"
"platform/keyboard-dx.cpp"
"platform/mouse-dx.cpp"
"platform/gamepad-dx.cpp"
"common/vectors.cpp"
"platform/soundeffect-dx.cpp"
"platform/displaymode-dx.cpp"
"platform/presentparameters-dx.cpp"
"game/component.cpp"
"content/manager.cpp"
"content/reader.cpp"
"csharp/binary.cpp"
"content/lzx/decoder.cpp" "content/lzx/decoderstream.cpp" "content/typereadermanager.cpp" "csharp/object.cpp" "csharp/type.cpp" "platform/init-dx.cpp" "game/servicecontainer.cpp" "common/color.cpp")
if (CMAKE_VERSION VERSION_GREATER 3.12)
set_property(TARGET xna PROPERTY CXX_STANDARD 20)
@ -12,7 +48,6 @@ endif()
# TODO: Add tests and install targets if needed.
# -- Biblioteca DirectxTK --
# Url: https://github.com/microsoft/DirectXTK/wiki/DirectXTK
#
@ -30,5 +65,14 @@ endif()
# "CMAKE_TOOLCHAIN_FILE": "{VCPKG_DIR}\\scripts\\buildsystems\\vcpkg.cmake"
# }
#
# Instalaçao do libmspack
# $- vcpkg install libmspack
#
find_package(directxtk CONFIG REQUIRED)
target_link_libraries(${PROJECT_NAME} D3d11.lib dxgi.lib dxguid.lib d3dcompiler.lib Microsoft::DirectXTK)
include_directories($ENV{VCPKG_ROOT}\\packages\\libmspack_x64-windows\\include)
target_link_libraries(${PROJECT_NAME}
D3d11.lib dxgi.lib dxguid.lib d3dcompiler.lib Microsoft::DirectXTK
$ENV{VCPKG_ROOT}\\packages\\libmspack_x64-windows\\lib\\libmspack.lib
)

View File

@ -0,0 +1,5 @@
#include "color.hpp"
namespace xna {
}

View File

@ -189,6 +189,10 @@ namespace xna {
return Color::Multiply(value, scale);
}
constexpr operator Uint() const {
return _packedValue;
}
private:
Uint _packedValue{ 0 };

View File

@ -2,6 +2,7 @@
#define XNA_COMMON_MATH_HPP
#include <limits>
#include <cmath>
namespace xna {
struct MathHelper {
@ -9,9 +10,49 @@ namespace xna {
static constexpr double PI = 3.1415926535897931;
static constexpr double TAU = 6.2831853071795862;
static constexpr double EPSILON = std::numeric_limits<double>::epsilon();
};
using Math = MathHelper;
static constexpr float ToRadians(float degrees) { return degrees * (static_cast<float>(PI) / 180.0f); }
static constexpr float ToDegrees(float radians) { return radians * 57.2957764F; }
static float Distance(float value1, float value2) { return std::abs(value1 - value2); }
static float Min(float value1, float value2) { return (std::min)(value1, value2); }
static float Max(float value1, float value2) { return (std::max)(value1, value2); }
static constexpr float Clamp(float value, float min, float max) {
value = value > max ? max : value;
value = value < min ? min : value;
return value;
}
static constexpr float Lerp(float value1, float value2, float amount) {
return value1 + (value2 - value1) * amount;
}
static constexpr float Barycentric(float value1, float value2, float value3, float amount1, float amount2) {
return value1 + amount1 * (value2 - value1) + amount2 * (value3 - value1);
}
static constexpr float SmoothStep(float value1, float value2, float amount) {
const auto num = Clamp(amount, 0.0f, 1.0f);
return Lerp(value1, value2, (num * num * (3.0F - 2.0F * num)));
}
static float CatmullRom(float value1, float value2, float value3, float value4, float amount) {
const auto num1 = amount * amount;
const auto num2 = amount * num1;
return (0.5F * (2.0F * value2 + (-value1 + value3) * amount + (2.0F * value1 - 5.0F * value2 + 4.0F * value3 - value4) * num1 + (-value1 + 3.0F * value2 - 3.0F * value3 + value4) * num2));
}
static float Hermite(float value1, float tangent1, float value2, float tangent2, float amount) {
const auto num1 = amount;
const auto num2 = num1 * num1;
const auto num3 = num1 * num2;
const auto num4 = (2.0F * num3 - 3.0F * num2 + 1.0F);
const auto num5 = (-2.0F * num3 + 3.0F * num2);
const auto num6 = num3 - 2.0f * num2 + num1;
const auto num7 = num3 - num2;
return value1 * num4 + value2 * num5 + tangent1 * num6 + tangent2 * num7;
}
};
}
#endif

View File

@ -212,7 +212,7 @@ namespace xna {
}
Matrix Matrix::CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance) {
if (fieldOfView <= 0.0 || fieldOfView >= Math::PI || nearPlaneDistance <= 0.0 || farPlaneDistance <= 0.0 || nearPlaneDistance >= farPlaneDistance) {
if (fieldOfView <= 0.0 || fieldOfView >= MathHelper::PI || nearPlaneDistance <= 0.0 || farPlaneDistance <= 0.0 || nearPlaneDistance >= farPlaneDistance) {
return Matrix();
}

View File

@ -623,6 +623,47 @@ namespace xna {
vector3.Z = num3;
return vector3;
}
constexpr Vector4 Vector4::Transform(Vector2 const& position, Matrix const& matrix)
{
const auto num1 = (position.X * matrix.M11 + position.Y * matrix.M21) + matrix.M41;
const auto num2 = (position.X * matrix.M12 + position.Y * matrix.M22) + matrix.M42;
const auto num3 = (position.X * matrix.M13 + position.Y * matrix.M23) + matrix.M43;
const auto num4 = (position.X * matrix.M14 + position.Y * matrix.M24) + matrix.M44;
Vector4 vector4;
vector4.X = num1;
vector4.Y = num2;
vector4.Z = num3;
vector4.W = num4;
return vector4;
}
constexpr Vector4 Vector4::Transform(Vector3 const& position, Matrix const& matrix)
{
const auto num1 = (position.X * matrix.M11 + position.Y * matrix.M21 + position.Z * matrix.M31) + matrix.M41;
const auto num2 = (position.X * matrix.M12 + position.Y * matrix.M22 + position.Z * matrix.M32) + matrix.M42;
const auto num3 = (position.X * matrix.M13 + position.Y * matrix.M23 + position.Z * matrix.M33) + matrix.M43;
const auto num4 = (position.X * matrix.M14 + position.Y * matrix.M24 + position.Z * matrix.M34) + matrix.M44;
Vector4 vector4;
vector4.X = num1;
vector4.Y = num2;
vector4.Z = num3;
vector4.W = num4;
return vector4;
}
constexpr Vector4 Vector4::Transform(Vector4 const& vector, Matrix const& matrix) {
const auto num1 = (vector.X * matrix.M11 + vector.Y * matrix.M21 + vector.Z * matrix.M31 + vector.W * matrix.M41);
const auto num2 = (vector.X * matrix.M12 + vector.Y * matrix.M22 + vector.Z * matrix.M32 + vector.W * matrix.M42);
const auto num3 = (vector.X * matrix.M13 + vector.Y * matrix.M23 + vector.Z * matrix.M33 + vector.W * matrix.M43);
const auto num4 = (vector.X * matrix.M14 + vector.Y * matrix.M24 + vector.Z * matrix.M34 + vector.W * matrix.M44);
Vector4 vector4;
vector4.X = num1;
vector4.Y = num2;
vector4.Z = num3;
vector4.W = num4;
return vector4;
}
}
#endif

View File

@ -57,6 +57,55 @@ namespace xna {
vector3.Z = num15;
return vector3;
}
constexpr Vector4 Vector4::Transform(Vector2 const& value, Quaternion const& rotation)
{
const auto num1 = rotation.X + rotation.X;
const auto num2 = rotation.Y + rotation.Y;
const auto num3 = rotation.Z + rotation.Z;
const auto num4 = rotation.W * num1;
const auto num5 = rotation.W * num2;
const auto num6 = rotation.W * num3;
const auto num7 = rotation.X * num1;
const auto num8 = rotation.X * num2;
const auto num9 = rotation.X * num3;
const auto num10 = rotation.Y * num2;
const auto num11 = rotation.Y * num3;
const auto num12 = rotation.Z * num3;
const auto num13 = (value.X * (1.0F - num10 - num12) + value.Y * (num8 - num6));
const auto num14 = (value.X * (num8 + num6) + value.Y * (1.0F - num7 - num12));
const auto num15 = (value.X * (num9 - num5) + value.Y * (num11 + num4));
Vector4 vector4;
vector4.X = num13;
vector4.Y = num14;
vector4.Z = num15;
vector4.W = 1.0f;
return vector4;
}
constexpr Vector4 Vector4::Transform(Vector3 const& value, Quaternion const& rotation) {
const auto num1 = rotation.X + rotation.X;
const auto num2 = rotation.Y + rotation.Y;
const auto num3 = rotation.Z + rotation.Z;
const auto num4 = rotation.W * num1;
const auto num5 = rotation.W * num2;
const auto num6 = rotation.W * num3;
const auto num7 = rotation.X * num1;
const auto num8 = rotation.X * num2;
const auto num9 = rotation.X * num3;
const auto num10 = rotation.Y * num2;
const auto num11 = rotation.Y * num3;
const auto num12 = rotation.Z * num3;
const auto num13 = (value.X * (1.0F - num10 - num12) + value.Y * (num8 - num6) + value.Z * (num9 + num5));
const auto num14 = (value.X * (num8 + num6) + value.Y * (1.0F - num7 - num12) + value.Z * (num11 - num4));
const auto num15 = (value.X * (num9 - num5) + value.Y * (num11 + num4) + value.Z * (1.0F - num7 - num10));
Vector4 vector4;
vector4.X = num13;
vector4.Y = num14;
vector4.Z = num15;
vector4.W = 1.0f;
return vector4;
}
}
#endif

View File

@ -2,18 +2,113 @@
#define XNA_COMMON_RECTANGLE_HPP
#include "../types.hpp"
#include "point.hpp"
namespace xna {
struct Rectangle {
Int Height{ 0 };
Int Width{ 0 };
Int X{ 0 };
Int Y{ 0 };
Int Width{ 0 };
Int Height{ 0 };
constexpr Rectangle() = default;
constexpr Rectangle(const Int& X, const Int& Y, const Int& Width, const Int& Height):
X(X), Y(Y), Width(Width), Height(Height) {}
constexpr bool operator==(const Rectangle& other) const {
return Height == other.Height && Width == other.Width && X == other.X && Y == other.Y;
}
constexpr Int Left() const { return X; }
constexpr Int Right() const { return X + Width; }
constexpr Int Top() const { return Y; }
constexpr Int Bottom() const { return Y + Height; }
constexpr Point Location() const { return { X, Y }; }
constexpr void Location(Point const& p) {
X = p.X;
Y = p.Y;
}
constexpr Point Center() const { return { X + Width / 2, Y + Height / 2 }; }
constexpr static Rectangle Empty() { return {}; }
constexpr bool IsEmpty() const { return Width == 0 && Height == 0 && X == 0 && Y == 0; }
constexpr void Offset(Point const& amount) {
X += amount.X;
Y += amount.Y;
}
constexpr void Offset(Int x, Int y) {
X += x;
Y += y;
}
constexpr void Inflate(Int horizontalAmount, Int verticalAmount) {
X -= horizontalAmount;
Y -= verticalAmount;
Width += horizontalAmount * 2;
Height += verticalAmount * 2;
}
constexpr bool Contains(Int x, Int y) const {
return X <= x && x < X + Width && Y <= y && y < Y + Height;
}
constexpr bool Contains(Point const& value) const {
return X <= value.X && value.X < X + Width && Y <= value.Y && value.Y < Y + Height;
}
constexpr bool Contains(Rectangle const& value) const {
return X <= value.X && value.X + value.Width <= X + Width && Y <= value.Y && value.Y + value.Height <= Y + Height;
}
constexpr bool Intersects(Rectangle const& value) const {
return value.X < X + Width && X < value.X + value.Width && value.Y < Y + Height && Y < value.Y + value.Height;
}
constexpr static Rectangle Intersect(Rectangle const& value1, Rectangle const& value2) {
const auto left1 = value1.Left();
const auto left2 = value2.Left();
const auto bottom1 = value1.Bottom();
const auto bottom2 = value2.Bottom();
const auto maxX = value1.X > value2.X ? value1.X : value2.X;
const auto maxY = value1.Y > value2.Y ? value1.Y : value2.Y;
const auto maxl = left1 < left2 ? left1 : left2;
const auto maxb = bottom1 < bottom2 ? bottom1 : bottom2;
Rectangle rectangle{};
if (maxl > maxX && maxb > maxY) {
rectangle.X = maxX;
rectangle.Y = maxY;
rectangle.Width = maxl - maxX;
rectangle.Height = maxb - maxY;
}
return rectangle;
}
constexpr static Rectangle Union(Rectangle const& value1, Rectangle const& value2) {
const auto left1 = value1.Left();
const auto left2 = value2.Left();
const auto bottom1 = value1.Bottom();
const auto bottom2 = value2.Bottom();
const auto minX = value1.X < value2.X ? value1.X : value2.X;
const auto miny = value1.Y < value2.Y ? value1.Y : value2.Y;
const auto maxl = left1 > left2 ? left1 : left2;
const auto maxb = bottom1 > bottom2 ? bottom1 : bottom2;
Rectangle rectangle;
rectangle.X = minX;
rectangle.Y = miny;
rectangle.Width = maxl - minX;
rectangle.Height = maxb - miny;
return rectangle;
}
};
}

View File

@ -17,6 +17,14 @@ namespace xna {
return true;
}
bool Vector2::Transform(std::vector<Vector2> sourceArray, Matrix const& matrix, std::vector<Vector2>& destinationArray)
{
if (destinationArray.empty())
destinationArray.resize(sourceArray.size());
return Transform(sourceArray.data(), sourceArray.size(), matrix, destinationArray.data(), destinationArray.size());
}
bool Vector2::Transform(Vector2 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Matrix const& matrix,
Vector2* destinationArray, size_t destinationArrayLength, size_t destinationIndex, size_t length) {
if (!sourceArray || !destinationArray || destinationArrayLength < sourceArrayLength
@ -32,6 +40,14 @@ namespace xna {
return true;
}
bool Vector2::Transform(std::vector<Vector2> const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector<Vector2>& destinationArray, size_t destinationIndex, size_t length)
{
if (destinationArray.empty())
destinationArray.resize(sourceArray.size());
return Transform(sourceArray.data(), sourceArray.size(), sourceIndex, matrix, destinationArray.data(), destinationArray.size(), destinationIndex, length);
}
bool Vector2::TransformNormal(Vector2 const* sourceArray, size_t sourceArrayLength, Matrix const& matrix, Vector2* destinationArray, size_t destinationArrayLength) {
if (!sourceArray || !destinationArray || destinationArrayLength < sourceArrayLength)
return false;
@ -44,6 +60,14 @@ namespace xna {
return true;
}
bool Vector2::TransformNormal(std::vector<Vector2> const& sourceArray, Matrix const& matrix, std::vector<Vector2>& destinationArray)
{
if (destinationArray.empty())
destinationArray.resize(sourceArray.size());
return TransformNormal(sourceArray.data(), sourceArray.size(), matrix, destinationArray.data(), destinationArray.size());
}
bool Vector2::TransformNormal(Vector2 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Matrix const& matrix, Vector2* destinationArray, size_t destinationArrayLength, size_t destinationIndex, size_t length) {
if (!sourceArray || !destinationArray || destinationArrayLength < sourceArrayLength
@ -60,6 +84,14 @@ namespace xna {
return true;
}
bool Vector2::TransformNormal(std::vector<Vector2> const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector<Vector2>& destinationArray, size_t destinationIndex, size_t length)
{
if (destinationArray.empty())
destinationArray.resize(sourceArray.size());
return TransformNormal(sourceArray.data(), sourceArray.size(), sourceIndex, matrix, destinationArray.data(), destinationArray.size(), destinationIndex, length);
}
bool Vector2::Transform(Vector2 const* sourceArray, size_t sourceArrayLength, Quaternion const& rotation, Vector2* destinationArray, size_t destinationArrayLength) {
if (!sourceArray || !destinationArray || destinationArrayLength < sourceArrayLength)
return false;
@ -86,6 +118,14 @@ namespace xna {
return true;
}
bool Vector2::Transform(std::vector<Vector2> const& sourceArray, Quaternion const& rotation, std::vector<Vector2>& destinationArray)
{
if (destinationArray.empty())
destinationArray.resize(sourceArray.size());
return Transform(sourceArray.data(), sourceArray.size(), rotation, destinationArray.data(), destinationArray.size());
}
bool Vector2::Transform(Vector2 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Quaternion const& rotation,
Vector2* destinationArray, size_t destinationArrayLength, size_t destinationIndex, size_t length) {
if (!sourceArray || !destinationArray || destinationArrayLength < sourceArrayLength
@ -117,30 +157,20 @@ namespace xna {
return true;
}
void Vector3::Normalize() {
const auto num = 1.0f / std::sqrt(X * X + Y * Y + Z * Z);
X *= num;
Y *= num;
Z *= num;
}
Vector3 Vector3::Normalize(Vector3 const& value) {
const auto num = 1.0f / std::sqrt(value.X * value.X + value.Y * value.Y + value.Z * value.Z);
Vector3 vector3;
vector3.X = value.X * num;
vector3.Y = value.Y * num;
vector3.Z = value.Z * num;
return vector3;
}
bool xna::Vector3::Transform(std::vector<Vector3> const& sourceArray, Matrix const& matrix, std::vector<Vector3>& destinationArray)
bool Vector2::Transform(std::vector<Vector2> const& sourceArray, size_t sourceIndex, Quaternion const& rotation, std::vector<Vector2>& destinationArray, size_t destinationIndex, size_t length)
{
if (destinationArray.size() < sourceArray.size())
if (destinationArray.empty())
destinationArray.resize(sourceArray.size());
return Transform(sourceArray.data(), sourceArray.size(), sourceIndex, rotation, destinationArray.data(), destinationArray.size(), destinationIndex, length);
}
bool Vector3::Transform(Vector3 const* sourceArray, size_t sourceArrayLength, Matrix const& matrix, Vector3* destinationArray, size_t destinationLength)
{
if (!sourceArray || !destinationArray || destinationLength < sourceArrayLength)
return false;
for (size_t index = 0; index < sourceArray.size(); ++index)
for (size_t index = 0; index < sourceArrayLength; ++index)
{
const auto& source = sourceArray[index];
destinationArray[index].X = (source.X * matrix.M11 + source.Y * matrix.M21 + source.Z * matrix.M31) + matrix.M41;
@ -151,9 +181,17 @@ namespace xna {
return true;
}
bool Vector3::Transform(std::vector<Vector3> const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector<Vector3>& destinationArray, size_t destinationIndex, size_t length)
bool Vector3::Transform(std::vector<Vector3> const& sourceArray, Matrix const& matrix, std::vector<Vector3>& destinationArray)
{
if (sourceArray.size() < sourceIndex + length || destinationArray.size() < destinationIndex + length)
if (destinationArray.empty())
destinationArray.resize(sourceArray.size());
return Transform(sourceArray.data(), sourceArray.size(), matrix, destinationArray.data(), destinationArray.size());
}
bool Vector3::Transform(Vector3 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Matrix const& matrix, Vector3* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length)
{
if (!sourceArray || !destinationArray || sourceArrayLength < sourceIndex + length || destinationLength < destinationIndex + length)
return false;
for (size_t index = 0; index < length; ++index)
@ -161,18 +199,26 @@ namespace xna {
const auto& source = sourceArray[sourceIndex + index];
destinationArray[destinationIndex + index].X = (source.X * matrix.M11 + source.Y * matrix.M21 + source.Z * matrix.M31) + matrix.M41;
destinationArray[destinationIndex + index].Y = (source.X * matrix.M12 + source.Y * matrix.M22 + source.Z * matrix.M32) + matrix.M42;
destinationArray[destinationIndex + index].Z = (source.X * matrix.M13 + source.Y * matrix.M23 + source.Z * matrix.M33) + matrix.M43;
destinationArray[destinationIndex + index].Z = (source.X * matrix.M13 + source.Y * matrix.M23 + source.Z * matrix.M33) + matrix.M43;
}
return true;
}
bool Vector3::TransformNormal(std::vector<Vector3> const& sourceArray, Matrix const& matrix, std::vector<Vector3>& destinationArray)
bool Vector3::Transform(std::vector<Vector3> const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector<Vector3>& destinationArray, size_t destinationIndex, size_t length)
{
if (destinationArray.size() < sourceArray.size())
if (destinationArray.empty())
destinationArray.resize(sourceArray.size());
return Transform(sourceArray.data(), sourceArray.size(), sourceIndex, matrix, destinationArray.data(), destinationArray.size(), destinationIndex, length);
}
bool Vector3::TransformNormal(Vector3 const* sourceArray, size_t sourceArrayLength, Matrix const& matrix, Vector3* destinationArray, size_t destionationArrayLength)
{
if (!sourceArray || !destinationArray || sourceArrayLength < destionationArrayLength)
return false;
for (size_t index = 0; index < sourceArray.size(); ++index)
for (size_t index = 0; index < sourceArrayLength; ++index)
{
const auto& source = sourceArray[index];
destinationArray[index].X = source.X * matrix.M11 + source.Y * matrix.M21 + source.Z * matrix.M31;
@ -183,9 +229,17 @@ namespace xna {
return true;
}
bool Vector3::TransformNormal(std::vector<Vector3> const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector<Vector3>& destinationArray, size_t destinationIndex, size_t length)
bool Vector3::TransformNormal(std::vector<Vector3> const& sourceArray, Matrix const& matrix, std::vector<Vector3>& destinationArray)
{
if (sourceArray.size() < sourceIndex + length || destinationArray.size() < destinationIndex + length)
if (destinationArray.empty())
destinationArray.resize(sourceArray.size());
return TransformNormal(sourceArray.data(), sourceArray.size(), matrix, destinationArray.data(), destinationArray.size());
}
bool Vector3::TransformNormal(Vector3 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Matrix const& matrix, Vector3* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length)
{
if (!sourceArray || !destinationArray || sourceArrayLength < sourceIndex + length || destinationLength < destinationIndex + length)
return false;
for (size_t index = 0; index < length; ++index) {
@ -198,9 +252,17 @@ namespace xna {
return true;
}
bool Vector3::TransformNormal(std::vector<Vector3> const& sourceArray, Quaternion const& rotation, std::vector<Vector3>& destinationArray)
bool Vector3::TransformNormal(std::vector<Vector3> const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector<Vector3>& destinationArray, size_t destinationIndex, size_t length)
{
if (destinationArray.size() < sourceArray.size())
if (destinationArray.empty())
destinationArray.resize(sourceArray.size());
return TransformNormal(sourceArray.data(), sourceArray.size(), sourceIndex, matrix, destinationArray.data(), destinationArray.size(), destinationIndex, length);
}
bool Vector3::TransformNormal(Vector3 const* sourceArray, size_t sourceArrayLength, Quaternion const& rotation, Vector3* destinationArray, size_t destinationLength)
{
if (!sourceArray || !destinationArray || destinationLength < sourceArrayLength)
return false;
const auto num1 = rotation.X + rotation.X;
@ -225,7 +287,7 @@ namespace xna {
const auto num20 = num11 + num4;
const auto num21 = 1.0f - num7 - num10;
for (size_t index = 0; index < sourceArray.size(); ++index)
for (size_t index = 0; index < sourceArrayLength; ++index)
{
const auto& source = sourceArray[index];
destinationArray[index].X = source.X * num13 + source.Y * num14 + source.Z * num15;
@ -236,11 +298,19 @@ namespace xna {
return true;
}
bool Vector3::TransformNormal(std::vector<Vector3> const& sourceArray, size_t sourceIndex, Quaternion const& rotation, std::vector<Vector3>& destinationArray, size_t destinationIndex, size_t length)
bool Vector3::TransformNormal(std::vector<Vector3> const& sourceArray, Quaternion const& rotation, std::vector<Vector3>& destinationArray)
{
if (sourceArray.size() < sourceIndex + length || destinationArray.size() < destinationIndex + length)
if (destinationArray.empty())
destinationArray.resize(sourceArray.size());
return TransformNormal(sourceArray.data(), sourceArray.size(), rotation, destinationArray.data(), destinationArray.size());
}
bool Vector3::TransformNormal(Vector3 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Quaternion const& rotation, Vector3* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length)
{
if (!sourceArray || !destinationArray || sourceArrayLength < sourceIndex + length || destinationLength < destinationIndex + length)
return false;
const auto num1 = rotation.X + rotation.X;
const auto num2 = rotation.Y + rotation.Y;
const auto num3 = rotation.Z + rotation.Z;
@ -273,4 +343,155 @@ namespace xna {
return true;
}
bool Vector3::TransformNormal(std::vector<Vector3> const& sourceArray, size_t sourceIndex, Quaternion const& rotation, std::vector<Vector3>& destinationArray, size_t destinationIndex, size_t length)
{
if (destinationArray.empty())
destinationArray.resize(sourceArray.size());
return TransformNormal(sourceArray.data(), sourceArray.size(), sourceIndex, rotation, destinationArray.data(), destinationArray.size(), destinationIndex, length);
}
bool Vector4::Transform(Vector4 const* sourceArray, size_t sourceLength, Matrix const& matrix, Vector4* destinationArray, size_t destinationLength)
{
if (!sourceArray || !destinationArray || destinationLength < sourceLength)
return false;
for (size_t index = 0; index < sourceLength; ++index)
{
const auto& source = sourceArray[index];
destinationArray[index].X = source.X * matrix.M11 + source.Y * matrix.M21 + source.Z * matrix.M31 + source.W * matrix.M41;
destinationArray[index].Y = source.X * matrix.M12 + source.Y * matrix.M22 + source.Z * matrix.M32 + source.W * matrix.M42;
destinationArray[index].Z = source.X * matrix.M13 + source.Y * matrix.M23 + source.Z * matrix.M33 + source.W * matrix.M43;
destinationArray[index].W = source.X * matrix.M14 + source.Y * matrix.M24 + source.Z * matrix.M34 + source.W * matrix.M44;
}
return true;
}
bool Vector4::Transform(std::vector<Vector4> const& sourceArray, size_t sourceLength, Matrix const& matrix, std::vector<Vector4>& destinationArray)
{
if (destinationArray.empty())
destinationArray.resize(sourceArray.size());
return Transform(sourceArray.data(), sourceArray.size(), matrix, destinationArray.data(), destinationArray.size());
}
bool Vector4::Transform(Vector4 const* sourceArray, size_t sourceLength, size_t sourceIndex, Matrix const& matrix, Vector4* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length)
{
if (!sourceArray || !destinationArray || sourceLength < sourceIndex + length || destinationLength < destinationIndex + length)
return false;
for (size_t i = 0; i < length; ++i)
{
const auto& source = sourceArray[sourceIndex + i];
destinationArray[destinationIndex].X = source.X * matrix.M11 + source.Y * matrix.M21 + source.Z * matrix.M31 + source.W * matrix.M41;
destinationArray[destinationIndex].Y = source.X * matrix.M12 + source.Y * matrix.M22 + source.Z * matrix.M32 + source.W * matrix.M42;
destinationArray[destinationIndex].Z = source.X * matrix.M13 + source.Y * matrix.M23 + source.Z * matrix.M33 + source.W * matrix.M43;
destinationArray[destinationIndex].W = source.X * matrix.M14 + source.Y * matrix.M24 + source.Z * matrix.M34 + source.W * matrix.M44;
}
return true;
}
bool Vector4::Transform(std::vector<Vector4> const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector<Vector4>& destinationArray, size_t destinationIndex, size_t length)
{
if (destinationArray.empty())
destinationArray.resize(sourceArray.size());
return Transform(sourceArray.data(), sourceArray.size(), sourceIndex, matrix, destinationArray.data(), destinationArray.size(), destinationIndex, length);
}
bool Vector4::Transform(Vector4 const* sourceArray, size_t sourceLength, Quaternion const& rotation, Vector4* destinationArray, size_t destinationLength)
{
if (!sourceArray || !destinationArray || destinationLength < sourceLength)
return false;
const auto num1 = rotation.X + rotation.X;
const auto num2 = rotation.Y + rotation.Y;
const auto num3 = rotation.Z + rotation.Z;
const auto num4 = rotation.W * num1;
const auto num5 = rotation.W * num2;
const auto num6 = rotation.W * num3;
const auto num7 = rotation.X * num1;
const auto num8 = rotation.X * num2;
const auto num9 = rotation.X * num3;
const auto num10 = rotation.Y * num2;
const auto num11 = rotation.Y * num3;
const auto num12 = rotation.Z * num3;
const auto num13 = 1.0f - num10 - num12;
const auto num14 = num8 - num6;
const auto num15 = num9 + num5;
const auto num16 = num8 + num6;
const auto num17 = 1.0f - num7 - num12;
const auto num18 = num11 - num4;
const auto num19 = num9 - num5;
const auto num20 = num11 + num4;
const auto num21 = 1.0f - num7 - num10;
for (size_t index = 0; index < sourceLength; ++index)
{
const auto& source = sourceArray[index];
destinationArray[index].X = source.Z * num13 + source.Y * num14 + source.Z * num15;
destinationArray[index].Y = source.Z * num16 + source.Y * num17 + source.Z * num18;
destinationArray[index].Z = source.Z * num19 + source.Y * num20 + source.Z * num21;
destinationArray[index].W = sourceArray[index].W;
}
return true;
}
bool Vector4::Transform(std::vector<Vector4> const& sourceArray, Quaternion const& rotation, std::vector<Vector4>& destinationArray)
{
if (destinationArray.empty())
destinationArray.resize(sourceArray.size());
return Transform(sourceArray.data(), sourceArray.size(), rotation, destinationArray.data(), destinationArray.size());
}
bool Vector4::Transform(Vector4 const* sourceArray, size_t sourceLength, size_t sourceIndex, Quaternion const& rotation, Vector4* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length)
{
if (!sourceArray || !destinationArray || sourceLength < sourceIndex + length || destinationLength < destinationIndex + length)
return false;
const auto num1 = rotation.X + rotation.X;
const auto num2 = rotation.Y + rotation.Y;
const auto num3 = rotation.Z + rotation.Z;
const auto num4 = rotation.W * num1;
const auto num5 = rotation.W * num2;
const auto num6 = rotation.W * num3;
const auto num7 = rotation.X * num1;
const auto num8 = rotation.X * num2;
const auto num9 = rotation.X * num3;
const auto num10 = rotation.Y * num2;
const auto num11 = rotation.Y * num3;
const auto num12 = rotation.Z * num3;
const auto num13 = 1.0f - num10 - num12;
const auto num14 = num8 - num6;
const auto num15 = num9 + num5;
const auto num16 = num8 + num6;
const auto num17 = 1.0f - num7 - num12;
const auto num18 = num11 - num4;
const auto num19 = num9 - num5;
const auto num20 = num11 + num4;
const auto num21 = 1.0f - num7 - num10;
for (size_t i = 0; i < length; ++i)
{
const auto& source = sourceArray[sourceIndex + i];
destinationArray[destinationIndex].X = source.X * num13 + source.Y * num14 + source.Z * num15;
destinationArray[destinationIndex].Y = source.X * num16 + source.Y * num17 + source.Z * num18;
destinationArray[destinationIndex].Z = source.X * num19 + source.Y * num20 + source.Z * num21;
destinationArray[destinationIndex].W = source.W;
}
return true;
}
bool Vector4::Transform(std::vector<Vector4> const& sourceArray, size_t sourceIndex, Quaternion const& rotation, std::vector<Vector4>& destinationArray, size_t destinationIndex, size_t length)
{
if (destinationArray.empty())
destinationArray.resize(sourceArray.size());
return Transform(sourceArray.data(), sourceArray.size(), sourceIndex, rotation, destinationArray.data(), destinationArray.size(), destinationIndex, length);
}
}

View File

@ -53,8 +53,9 @@ namespace xna {
}
static inline Vector2 Normalize(Vector2 const& value) {
const auto normal = 1.0F / value.Length();
return { value.X * normal, value.Y * normal };
auto v = value;
v.Normalize();
return v;
}
static constexpr Vector2 Reflect(Vector2 const& vector, Vector2 const& normal) {
@ -136,14 +137,20 @@ namespace xna {
static constexpr Vector2 TransformNormal(Vector2 const& normal, Matrix const& matrix);
static constexpr Vector2 Transform(Vector2 const& value, Quaternion const& rotation);
static bool Transform(Vector2 const* sourceArray, size_t sourceArrayLength, Matrix const& matrix, Vector2* destinationArray, size_t destinationArrayLength);
static bool Transform(std::vector<Vector2> sourceArray, Matrix const& matrix, std::vector<Vector2>& destinationArray);
static bool Transform(Vector2 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Matrix const& matrix,
Vector2* destinationArray, size_t destinationArrayLength, size_t destinationIndex, size_t length);
static bool Transform(std::vector<Vector2> const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector<Vector2>& destinationArray, size_t destinationIndex, size_t length);
static bool TransformNormal(Vector2 const* sourceArray, size_t sourceArrayLength, Matrix const& matrix, Vector2* destinationArray, size_t destinationArrayLength);
static bool TransformNormal(std::vector<Vector2> const& sourceArray, Matrix const& matrix, std::vector<Vector2>& destinationArray);
static bool TransformNormal(Vector2 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Matrix const& matrix,
Vector2* destinationArray, size_t destinationArrayLength, size_t destinationIndex, size_t length);
static bool TransformNormal(std::vector<Vector2> const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector<Vector2>& destinationArray, size_t destinationIndex, size_t length);
static bool Transform(Vector2 const* sourceArray, size_t sourceArrayLength, Quaternion const& rotation, Vector2* destinationArray, size_t destinationArrayLength);
static bool Transform(std::vector<Vector2> const& sourceArray, Quaternion const& rotation, std::vector<Vector2>& destinationArray);
static bool Transform(Vector2 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Quaternion const& rotation,
Vector2* destinationArray, size_t destinationArrayLength, size_t destinationIndex, size_t length);
static bool Transform(std::vector<Vector2> const& sourceArray, size_t sourceIndex, Quaternion const& rotation, std::vector<Vector2>& destinationArray, size_t destinationIndex, size_t length);
static constexpr Vector2 Negate(Vector2 const& value) {
return { -value.X, -value.Y };
@ -260,8 +267,18 @@ namespace xna {
return vector1.X * vector2.X + vector1.Y * vector2.Y + vector1.Z * vector2.Z;
}
void Normalize();
static Vector3 Normalize(Vector3 const& value);
inline void Normalize() {
const auto num = 1.0f / Length();
X *= num;
Y *= num;
Z *= num;
}
static Vector3 Normalize(Vector3 const& value) {
auto v = value;
v.Normalize();
return v;
}
static constexpr Vector3 Cross(Vector3 const& vector1, Vector3 const& vector2) {
Vector3 vector3;
@ -364,11 +381,17 @@ namespace xna {
static constexpr Vector3 Transform(Vector3 const& position, Matrix const& matrix);
static constexpr Vector3 TransformNormal(Vector3 const& normal, Matrix const& matrix);
static constexpr Vector3 Transform(Vector3 const& value, Quaternion const& rotation);
static bool Transform(Vector3 const* sourceArray, size_t sourceArrayLength, Matrix const& matrix, Vector3* destinationArray, size_t destinationLength);
static bool Transform(std::vector<Vector3> const& sourceArray, Matrix const& matrix, std::vector<Vector3>& destinationArray);
static bool Transform(Vector3 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Matrix const& matrix, Vector3* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length);
static bool Transform(std::vector<Vector3> const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector<Vector3>& destinationArray, size_t destinationIndex, size_t length);
static bool TransformNormal(Vector3 const* sourceArray, size_t sourceArrayLength, Matrix const& matrix, Vector3* destinationArray, size_t destionationArrayLength);
static bool TransformNormal(std::vector<Vector3> const& sourceArray, Matrix const& matrix, std::vector<Vector3>& destinationArray);
static bool TransformNormal(Vector3 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Matrix const& matrix, Vector3* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length);
static bool TransformNormal(std::vector<Vector3> const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector<Vector3>& destinationArray, size_t destinationIndex, size_t length);
static bool TransformNormal(Vector3 const* sourceArray, size_t sourceArrayLength, Quaternion const& rotation,Vector3* destinationArray, size_t destinationLength);
static bool TransformNormal(std::vector<Vector3> const& sourceArray, Quaternion const& rotation, std::vector<Vector3>& destinationArray);
static bool TransformNormal(Vector3 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Quaternion const& rotation, Vector3* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length);
static bool TransformNormal(std::vector<Vector3> const& sourceArray, size_t sourceIndex, Quaternion const& rotation, std::vector<Vector3>& destinationArray, size_t destinationIndex, size_t length);
static constexpr Vector3 Negate(Vector3 const& value)
@ -474,12 +497,279 @@ namespace xna {
constexpr Vector4() = default;
constexpr Vector4(float value):
X(value), Y(value), Z(value), W(value){}
constexpr Vector4(float X, float Y, float Z, float W)
: X(X), Y(Y), Z(Z), W(W) { }
constexpr Vector4(Vector2 value, float Z, float W)
: X(value.X), Y(value.Y), Z(Z), W(W) { }
constexpr Vector4(Vector3 value, float W)
: X(value.X), Y(value.Y), Z(value.Z), W(W) { }
constexpr bool operator==(const Vector4& other) const {
return X == other.X && Y == other.Y && Z == other.Z && W == other.W;
}
static Vector4 Zero() { return {}; }
static Vector4 One() { return { 1 }; }
static Vector4 UnitX() { return { 1,0,0,0 }; }
static Vector4 UnitY() { return { 0,1,0,0 }; }
static Vector4 UnitZ() { return { 0,0,1,0 }; }
static Vector4 UnitW() { return { 0,0,0,1 }; }
float Length() const {
return sqrt(LengthSquared());
}
constexpr float LengthSquared() const {
return (X * X + Y * Y + Z * Z + W * W);
}
inline static float Distance(Vector4 const& value1, Vector4 const& value2) {
return sqrt(DistanceSquared(value1, value2));
}
static constexpr float DistanceSquared(Vector4 const& value1, Vector4 const& value2) {
const auto num1 = value1.X - value2.X;
const auto num2 = value1.Y - value2.Y;
const auto num3 = value1.Z - value2.Z;
const auto num4 = value1.W - value2.W;
return num1 * num1 + num2 * num2 + num3 * num3 + num4 * num4;
}
static constexpr float Dot(Vector4 const& vector1, Vector4 const& vector2) {
return vector1.X * vector2.X + vector1.Y * vector2.Y + vector1.Z * vector2.Z + vector1.W * vector2.W;
}
void Normalize() {
const auto num = 1.0f / Length();
X *= num;
Y *= num;
Z *= num;
W *= num;
}
inline static Vector4 Normalize(Vector4 const& vector) {
auto v = vector;
v.Normalize();
return v;
}
static constexpr Vector4 Min(Vector4 const& value1, Vector4 const& value2) {
Vector4 vector4;
vector4.X = value1.X < value2.X ? value1.X : value2.X;
vector4.Y = value1.Y < value2.Y ? value1.Y : value2.Y;
vector4.Z = value1.Z < value2.Z ? value1.Z : value2.Z;
vector4.W = value1.W < value2.W ? value1.W : value2.W;
return vector4;
}
static constexpr Vector4 Max(Vector4 const& value1, Vector4 const& value2) {
Vector4 vector4;
vector4.X = value1.X > value2.X ? value1.X : value2.X;
vector4.Y = value1.Y > value2.Y ? value1.Y : value2.Y;
vector4.Z = value1.Z > value2.Z ? value1.Z : value2.Z;
vector4.W = value1.W > value2.W ? value1.W : value2.W;
return vector4;
}
static Vector4 Clamp(Vector4 const& value1, Vector4 const& min, Vector4 const& max) {
const auto x = value1.X;
const auto num1 = x > max.X ? max.X : x;
const auto num2 = num1 < min.X ? min.X : num1;
const auto y = value1.Y;
const auto num3 = y > max.Y ? max.Y : y;
const auto num4 = num3 < min.Y ? min.Y : num3;
const auto z = value1.Z;
const auto num5 = z > max.Z ? max.Z : z;
const auto num6 = num5 < min.Z ? min.Z : num5;
const auto w = value1.W;
const auto num7 = w > max.W ? max.W : w;
const auto num8 = num7 < min.W ? min.W : num7;
Vector4 vector4;
vector4.X = num2;
vector4.Y = num4;
vector4.Z = num6;
vector4.W = num8;
return vector4;
}
static Vector4 Lerp(Vector4 const& value1, Vector4 const& value2, float amount) {
Vector4 vector4;
vector4.X = value1.X + (value2.X - value1.X) * amount;
vector4.Y = value1.Y + (value2.Y - value1.Y) * amount;
vector4.Z = value1.Z + (value2.Z - value1.Z) * amount;
vector4.W = value1.W + (value2.W - value1.W) * amount;
return vector4;
}
static Vector4 Barycentric(Vector4 const& value1, Vector4 const& value2, Vector4 const& value3, float amount1, float amount2) {
Vector4 vector4;
vector4.X = value1.X + amount1 * (value2.X - value1.X) + amount2 * (value3.X - value1.X);
vector4.Y = value1.Y + amount1 * (value2.Y - value1.Y) + amount2 * (value3.Y - value1.Y);
vector4.Z = value1.Z + amount1 * (value2.Z - value1.Z) + amount2 * (value3.Z - value1.Z);
vector4.W = value1.W + amount1 * (value2.W - value1.W) + amount2 * (value3.W - value1.W);
return vector4;
}
static Vector4 SmoothStep(Vector4 const& value1, Vector4 const& value2, float amount) {
amount = amount > 1.0F ? 1.0f : (amount < 0.0F ? 0.0f : amount);
amount = (amount * amount * (3.0F - 2.0F * amount));
Vector4 vector4;
vector4.X = value1.X + (value2.X - value1.X) * amount;
vector4.Y = value1.Y + (value2.Y - value1.Y) * amount;
vector4.Z = value1.Z + (value2.Z - value1.Z) * amount;
vector4.W = value1.W + (value2.W - value1.W) * amount;
return vector4;
}
static Vector4 CatmullRom(Vector4 const& value1, Vector4 const& value2, Vector4 const& value3, Vector4 const& value4, float amount) {
const auto num1 = amount * amount;
const auto num2 = amount * num1;
Vector4 vector4;
vector4.X = 0.5F * (2.0f * value2.X + (-value1.X + value3.X) * amount + (2.0F * value1.X - 5.0f * value2.X + 4.0f * value3.X - value4.X) * num1 + (-value1.X + 3.0f * value2.X - 3.0f * value3.X + value4.X) * num2);
vector4.Y = 0.5F * (2.0f * value2.Y + (-value1.Y + value3.Y) * amount + (2.0F * value1.Y - 5.0f * value2.Y + 4.0f * value3.Y - value4.Y) * num1 + (-value1.Y + 3.0f * value2.Y - 3.0f * value3.Y + value4.Y) * num2);
vector4.Z = 0.5F * (2.0f * value2.Z + (-value1.Z + value3.Z) * amount + (2.0F * value1.Z - 5.0f * value2.Z + 4.0f * value3.Z - value4.Z) * num1 + (-value1.Z + 3.0f * value2.Z - 3.0f * value3.Z + value4.Z) * num2);
vector4.W = 0.5F * (2.0f * value2.W + (-value1.W + value3.W) * amount + (2.0F * value1.W - 5.0f * value2.W + 4.0f * value3.W - value4.W) * num1 + (-value1.W + 3.0f * value2.W - 3.0f * value3.W + value4.W) * num2);
return vector4;
}
static Vector4 Hermite(Vector4 const& value1, Vector4 const& tangent1, Vector4 const& value2, Vector4 const& tangent2, float amount) {
const auto num1 = amount * amount;
const auto num2 = amount * num1;
const auto num3 = (2.0F * num2 - 3.0F * num1 + 1.0F);
const auto num4 = (-2.0F * num2 + 3.0F * num1);
const auto num5 = num2 - 2.0f * num1 + amount;
const auto num6 = num2 - num1;
Vector4 vector4;
vector4.X = (value1.X * num3 + value2.X * num4 + tangent1.X * num5 + tangent2.X * num6);
vector4.Y = (value1.Y * num3 + value2.Y * num4 + tangent1.Y * num5 + tangent2.Y * num6);
vector4.Z = (value1.Z * num3 + value2.Z * num4 + tangent1.Z * num5 + tangent2.Z * num6);
vector4.W = (value1.W * num3 + value2.W * num4 + tangent1.W * num5 + tangent2.W * num6);
return vector4;
}
static constexpr Vector4 Transform(Vector2 const& position, Matrix const& matrix);
static constexpr Vector4 Transform(Vector3 const& position, Matrix const& matrix);
static constexpr Vector4 Transform(Vector4 const& vector, Matrix const& matrix);
static constexpr Vector4 Transform(Vector2 const& value, Quaternion const& rotation);
static constexpr Vector4 Transform(Vector3 const& value, Quaternion const& rotation);
static bool Transform(Vector4 const* sourceArray, size_t sourceLength, Matrix const& matrix, Vector4* destinationArray, size_t destinationLength);
static bool Transform(std::vector<Vector4> const& sourceArray, size_t sourceLength, Matrix const& matrix, std::vector<Vector4>& destinationArray);
static bool Transform(Vector4 const* sourceArray, size_t sourceLength, size_t sourceIndex, Matrix const& matrix, Vector4* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length);
static bool Transform(std::vector<Vector4> const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector<Vector4>& destinationArray, size_t destinationIndex, size_t length);
static bool Transform(Vector4 const* sourceArray, size_t sourceLength, Quaternion const& rotation, Vector4* destinationArray, size_t destinationLength);
static bool Transform(std::vector<Vector4> const& sourceArray, Quaternion const& rotation, std::vector<Vector4>& destinationArray);
static bool Transform(Vector4 const* sourceArray, size_t sourceLength, size_t sourceIndex, Quaternion const& rotation, Vector4* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length);
static bool Transform(std::vector<Vector4> const& sourceArray, size_t sourceIndex, Quaternion const& rotation, std::vector<Vector4>& destinationArray, size_t destinationIndex, size_t length);
static constexpr Vector4 Negate(Vector4 const& value) {
Vector4 vector4;
vector4.X = -value.X;
vector4.Y = -value.Y;
vector4.Z = -value.Z;
vector4.W = -value.W;
return vector4;
}
static constexpr Vector4 Add(Vector4 const& value1, Vector4 const& value2) {
Vector4 vector4;
vector4.X = value1.X + value2.X;
vector4.Y = value1.Y + value2.Y;
vector4.Z = value1.Z + value2.Z;
vector4.W = value1.W + value2.W;
return vector4;
}
static constexpr Vector4 Subtract(Vector4 const& value1, Vector4 const& value2) {
Vector4 vector4;
vector4.X = value1.X - value2.X;
vector4.Y = value1.Y - value2.Y;
vector4.Z = value1.Z - value2.Z;
vector4.W = value1.W - value2.W;
return vector4;
}
static constexpr Vector4 Multiply(Vector4 const& value1, Vector4 const& value2)
{
Vector4 vector4;
vector4.X = value1.X * value2.X;
vector4.Y = value1.Y * value2.Y;
vector4.Z = value1.Z * value2.Z;
vector4.W = value1.W * value2.W;
return vector4;
}
static constexpr Vector4 Multiply(Vector4 const& value1, float scaleFactor)
{
Vector4 vector4;
vector4.X = value1.X * scaleFactor;
vector4.Y = value1.Y * scaleFactor;
vector4.Z = value1.Z * scaleFactor;
vector4.W = value1.W * scaleFactor;
return vector4;
}
static constexpr Vector4 Divide(Vector4 const& value1, Vector4 const& value2)
{
Vector4 vector4;
vector4.X = value1.X / value2.X;
vector4.Y = value1.Y / value2.Y;
vector4.Z = value1.Z / value2.Z;
vector4.W = value1.W / value2.W;
return vector4;
}
static constexpr Vector4 Divide(Vector4 const& value1, float divider)
{
float num = 1.0f / divider;
Vector4 vector4;
vector4.X = value1.X * num;
vector4.Y = value1.Y * num;
vector4.Z = value1.Z * num;
vector4.W = value1.W * num;
return vector4;
}
constexpr Vector4 operator-() const {
return Vector4::Negate(*this);
}
friend constexpr Vector4 operator+(Vector4 const& value1, Vector4 const& value2) {
return Vector4::Add(value1, value2);
}
friend constexpr Vector4 operator-(Vector4 const& value1, Vector4 const& value2) {
return Vector4::Subtract(value1, value2);
}
friend constexpr Vector4 operator*(Vector4 const& value1, Vector4 const& value2) {
return Vector4::Multiply(value1, value2);
}
friend constexpr Vector4 operator*(Vector4 const& value, float factor) {
return Vector4::Multiply(value, factor);
}
friend constexpr Vector4 operator*(float factor, Vector4 const& value) {
return Vector4::Multiply(value, factor);
}
friend constexpr Vector4 operator/(Vector4 const& value1, Vector4 const& value2) {
return Vector4::Divide(value1, value2);
}
friend constexpr Vector4 operator/(Vector4 const& value, float divider) {
return Vector4::Divide(value, divider);
}
friend constexpr Vector4 operator/(float divider, Vector4 const& value) {
return Vector4::Divide(value, divider);
}
};
}

View File

@ -0,0 +1,223 @@
#ifndef XNA_CONTENT_DEFAULTREADERS_ARRAY_HPP
#define XNA_CONTENT_DEFAULTREADERS_ARRAY_HPP
#include "reader.hpp"
#include "../default.hpp"
#include "../common/color.hpp"
#include "../common/matrix.hpp"
#include "../common/point.hpp"
#include "../common/rectangle.hpp"
#include "../csharp/timespan.hpp"
namespace xna {
class ObjectReader : public ContentTypeReaderT<Object> {
public:
ObjectReader() : ContentTypeReaderT(typeof<Object>()) {}
virtual Object Read(ContentReader& input, Object& existingInstance) override {
return Object();
}
};
class BooleanReader : public ContentTypeReaderT<bool> {
public:
BooleanReader() : ContentTypeReaderT(typeof<bool>()) {}
bool Read(ContentReader& input, bool& existingInstance) override {
return input.ReadBoolean();
}
};
class ByteReader : public ContentTypeReaderT<Byte> {
public:
ByteReader() : ContentTypeReaderT(typeof<Byte>()) {}
Byte Read(ContentReader& input, Byte& existingInstance) override {
const auto b = input.ReadByte();
return b;
}
};
class CharReader : public ContentTypeReaderT<Char> {
public:
CharReader() : ContentTypeReaderT(typeof<Char>()) {}
Char Read(ContentReader& input, Char& existingInstance) override {
const auto b = input.ReadChar();
return b;
}
};
class ColorReader : public ContentTypeReaderT<Color> {
public:
ColorReader() : ContentTypeReaderT(typeof<Color>()) {}
Color Read(ContentReader& input, Color& existingInstance) override {
const auto i = input.ReadUInt32();
return { i };
}
};
class DoubleReader : public ContentTypeReaderT<double> {
public:
DoubleReader() : ContentTypeReaderT(typeof<double>()) {}
double Read(ContentReader& input, double& existingInstance) override {
return input.ReadDouble();
}
};
class Int16Reader : public ContentTypeReaderT<Short> {
public:
Int16Reader() : ContentTypeReaderT(typeof<Short>()) {}
Short Read(ContentReader& input, Short& existingInstance) override {
return input.ReadInt16();
}
};
class Int32Reader : public ContentTypeReaderT<Int> {
public:
Int32Reader() : ContentTypeReaderT(typeof<Int>()) {}
Int Read(ContentReader& input, Int& existingInstance) override {
return input.ReadInt32();
}
};
class Int64Reader : public ContentTypeReaderT<Long> {
public:
Int64Reader() : ContentTypeReaderT(typeof<Long>()) {}
Long Read(ContentReader& input, Long& existingInstance) override {
return input.ReadInt64();
}
};
class MatrixReader : public ContentTypeReaderT<Matrix> {
public:
MatrixReader() : ContentTypeReaderT(typeof<Matrix>()) {}
Matrix Read(ContentReader& input, Matrix& existingInstance) override {
return input.ReadMatrix();
}
};
class PointReader : public ContentTypeReaderT<Point> {
public:
PointReader() : ContentTypeReaderT(typeof<Point>()) {}
Point Read(ContentReader& input, Point& existingInstance) override {
Point point;
point.X = input.ReadInt32();
point.Y = input.ReadInt32();
return point;
}
};
class QuaternionReader : public ContentTypeReaderT<Quaternion> {
public:
QuaternionReader() : ContentTypeReaderT(typeof<Quaternion>()) {}
Quaternion Read(ContentReader& input, Quaternion& existingInstance) override {
return input.ReadQuaternion();
}
};
class RectangleReader : public ContentTypeReaderT<Rectangle> {
public:
RectangleReader() : ContentTypeReaderT(typeof<Rectangle>()) {}
Rectangle Read(ContentReader& input, Rectangle& existingInstance) override {
Rectangle rectangle;
rectangle.X = input.ReadInt32();
rectangle.Y = input.ReadInt32();
rectangle.Width = input.ReadInt32();
rectangle.Height = input.ReadInt32();
return rectangle;
}
};
class SByteReader : public ContentTypeReaderT<Sbyte> {
public:
SByteReader() : ContentTypeReaderT(typeof<Sbyte>()) {}
Sbyte Read(ContentReader& input, Sbyte& existingInstance) override {
return input.ReadSByte();
}
};
class SingleReader : public ContentTypeReaderT<float> {
public:
SingleReader() : ContentTypeReaderT(typeof<float>()) {}
float Read(ContentReader& input, float& existingInstance) override {
return input.ReadSingle();
}
};
class TimeSpanReader : public ContentTypeReaderT<TimeSpan> {
public:
TimeSpanReader() : ContentTypeReaderT(typeof<TimeSpan>()) {}
TimeSpan Read(ContentReader& input, TimeSpan& existingInstance) override {
return TimeSpan::FromTicks(input.ReadInt64());
}
};
class UInt16Reader : public ContentTypeReaderT<Ushort> {
public:
UInt16Reader() : ContentTypeReaderT(typeof<Ushort>()) {}
Ushort Read(ContentReader& input, Ushort& existingInstance) override {
return input.ReadUInt16();
}
};
class UInt32Reader : public ContentTypeReaderT<Uint> {
public:
UInt32Reader() : ContentTypeReaderT(typeof<Uint>()) {}
Uint Read(ContentReader& input, Uint& existingInstance) override {
return input.ReadUInt32();
}
};
class UInt64Reader : public ContentTypeReaderT<Ulong> {
public:
UInt64Reader() : ContentTypeReaderT(typeof<Ulong>()) {}
Ulong Read(ContentReader& input, Ulong& existingInstance) override {
return input.ReadUInt64();
}
};
class Vector2Reader : public ContentTypeReaderT<Vector2> {
public:
Vector2Reader() : ContentTypeReaderT(typeof<Vector2>()) {}
Vector2 Read(ContentReader& input, Vector2& existingInstance) override {
return input.ReadVector2();
}
};
class Vector3Reader : public ContentTypeReaderT<Vector3> {
public:
Vector3Reader() : ContentTypeReaderT(typeof<Vector3>()) {}
Vector3 Read(ContentReader& input, Vector3& existingInstance) override {
return input.ReadVector3();
}
};
class Vector4Reader : public ContentTypeReaderT<Vector4> {
public:
Vector4Reader() : ContentTypeReaderT(typeof<Vector4>()) {}
Vector4 Read(ContentReader& input, Vector4& existingInstance) override {
return input.ReadVector4();
}
};
}
#endif

View File

@ -0,0 +1,5 @@
#include "decoder.hpp"
namespace xna {
}

View File

@ -0,0 +1,787 @@
#ifndef XNA_CONTENT_LZX_LZXDECODE_HPP
#define XNA_CONTENT_LZX_LZXDECODE_HPP
#include "../../default.hpp"
#include "../../csharp/stream.hpp"
#include <algorithm>
namespace xna {
struct LzxConstants {
static constexpr Ushort MIN_MATCH = 2;
static constexpr Ushort MAX_MATCH = 257;
static constexpr Ushort NUM_CHARS = 256;
enum class BLOCKTYPE {
INVALID = 0,
VERBATIM = 1,
ALIGNED = 2,
UNCOMPRESSED = 3
};
static constexpr Ushort PRETREE_NUM_ELEMENTS = 20;
static constexpr Ushort ALIGNED_NUM_ELEMENTS = 8;
static constexpr Ushort NUM_PRIMARY_LENGTHS = 7;
static constexpr Ushort NUM_SECONDARY_LENGTHS = 249;
static constexpr Ushort PRETREE_MAXSYMBOLS = PRETREE_NUM_ELEMENTS;
static constexpr Ushort PRETREE_TABLEBITS = 6;
static constexpr Ushort MAINTREE_MAXSYMBOLS = NUM_CHARS + 50 * 8;
static constexpr Ushort MAINTREE_TABLEBITS = 12;
static constexpr Ushort LENGTH_MAXSYMBOLS = NUM_SECONDARY_LENGTHS + 1;
static constexpr Ushort LENGTH_TABLEBITS = 12;
static constexpr Ushort ALIGNED_MAXSYMBOLS = ALIGNED_NUM_ELEMENTS;
static constexpr Ushort ALIGNED_TABLEBITS = 7;
static constexpr Ushort LENTABLE_SAFETY = 64;
};
struct LzxState {
Uint R0{ 1 }, R1{ 1 }, R2{ 1 }; /* for the LRU offset system */
Ushort main_elements{ 0 }; /* number of main tree elements */
Int header_read{ 0 }; /* have we started decoding at all yet? */
LzxConstants::BLOCKTYPE block_type{ LzxConstants::BLOCKTYPE::INVALID }; /* type of this block */
Uint block_length{ 0 }; /* uncompressed length of this block */
Uint block_remaining{ 0 }; /* uncompressed bytes still left to decode */
Uint frames_read{ 0 }; /* the number of CFDATA blocks processed */
Int intel_filesize{ 0 }; /* magic header value used for transform */
Int intel_curpos{ 0 }; /* current offset in transform space */
Int intel_started{ 0 }; /* have we seen any translateable data yet? */
std::vector<Ushort> PRETREE_table;
std::vector<Byte> PRETREE_len;
std::vector<Ushort> MAINTREE_table;
std::vector<Byte> MAINTREE_len;
std::vector<Ushort> LENGTH_table;
std::vector<Byte> LENGTH_len;
std::vector<Ushort> ALIGNED_table;
std::vector<Byte> ALIGNED_len;
// NEEDED MEMBERS
// CAB actualsize
// CAB window
// CAB window_size
// CAB window_posn
Uint actual_size{ 0 };
std::vector<Byte> window;
Uint window_size{ 0 };
Uint window_posn{ 0 };
};
class BitBuffer {
public:
BitBuffer(sptr<Stream> const& stream) : byteStream(stream) {
InitBitStream();
}
constexpr void InitBitStream() {
buffer = 0;
bitsleft = 0;
}
void EnsureBits(Byte bits) {
while (bitsleft < bits) {
const auto lo = static_cast<Byte>(byteStream->ReadByte());
const auto hi = static_cast<Byte>(byteStream->ReadByte());
//int amount2shift = sizeofstatic_cast<Uint>(*8 - 16 - bitsleft;
buffer |= static_cast<Uint>(((hi << 8) | lo) << (sizeof(Uint) * 8 - 16 - bitsleft));
bitsleft += 16;
}
}
constexpr Uint PeekBits(Byte bits) const
{
return (buffer >> ((sizeof(Uint) * 8) - bits));
}
constexpr void RemoveBits(Byte bits) {
buffer <<= bits;
bitsleft -= bits;
}
Uint ReadBits(Byte bits)
{
Uint ret = 0;
if (bits > 0)
{
EnsureBits(bits);
ret = PeekBits(bits);
RemoveBits(bits);
}
return ret;
}
constexpr Uint GetBuffer() const {
return buffer;
}
constexpr Byte GetBitsLeft() const {
return bitsleft;
}
private:
Uint buffer{ 0 };
Byte bitsleft{ 0 };
sptr<Stream> byteStream = nullptr;
};
class LzxDecoder {
public:
LzxDecoder(Int window) {
Uint wndsize = (Uint)(1 << window);
Int posn_slots = 0;
// setup proper exception
if (window < 15 || window > 21)
return;
// let's initialise our state
m_state.window = std::vector<Byte>(wndsize, 0xDC);
m_state.actual_size = wndsize;
m_state.window_size = wndsize;
/* initialize static tables */
if (extra_bits.empty()) {
extra_bits.resize(52);
for (size_t i = 0, j = 0; i <= 50; i += 2) {
extra_bits[i] = extra_bits[i + 1] = static_cast<Byte>(j);
if ((i != 0) && (j < 17))
j++;
}
}
if (position_base.empty()) {
position_base.resize(51);
for (size_t i = 0, j = 0; i <= 50; i++) {
position_base[i] = static_cast<Uint>(j);
j += static_cast<size_t>(1) << extra_bits[i];
}
}
/* calculate required position slots */
if (window == 20)
posn_slots = 42;
else if (window == 21)
posn_slots = 50;
else
posn_slots = window << 1;
m_state.main_elements = static_cast<Ushort>(LzxConstants::NUM_CHARS + (posn_slots << 3));
// yo dawg i herd u liek arrays so we put arrays in ur arrays so u can array while u array
m_state.PRETREE_table = std::vector<Ushort>((1 << LzxConstants::PRETREE_TABLEBITS) + (LzxConstants::PRETREE_MAXSYMBOLS << 1));
m_state.PRETREE_len = std::vector<Byte>(LzxConstants::PRETREE_MAXSYMBOLS + LzxConstants::LENTABLE_SAFETY);
m_state.MAINTREE_table = std::vector<Ushort>((1 << LzxConstants::MAINTREE_TABLEBITS) + (LzxConstants::MAINTREE_MAXSYMBOLS << 1));
m_state.MAINTREE_len = std::vector<Byte>(LzxConstants::MAINTREE_MAXSYMBOLS + LzxConstants::LENTABLE_SAFETY);
m_state.LENGTH_table = std::vector<Ushort>((1 << LzxConstants::LENGTH_TABLEBITS) + (LzxConstants::LENGTH_MAXSYMBOLS << 1));
m_state.LENGTH_len = std::vector<Byte>(LzxConstants::LENGTH_MAXSYMBOLS + LzxConstants::LENTABLE_SAFETY);
m_state.ALIGNED_table = std::vector<Ushort>((1 << LzxConstants::ALIGNED_TABLEBITS) + (LzxConstants::ALIGNED_MAXSYMBOLS << 1));
m_state.ALIGNED_len = std::vector<Byte>(LzxConstants::ALIGNED_MAXSYMBOLS + LzxConstants::LENTABLE_SAFETY);
/* initialise tables to 0 (because deltas will be applied to them) */
for (size_t i = 0; i < LzxConstants::MAINTREE_MAXSYMBOLS; i++)
m_state.MAINTREE_len[i] = 0;
for (size_t i = 0; i < LzxConstants::LENGTH_MAXSYMBOLS; i++)
m_state.LENGTH_len[i] = 0;
}
Int Decompress(sptr<Stream>& inData, Int inLen, sptr<Stream>& outData, Int outLen) {
BitBuffer bitbuf(inData);
auto startpos = inData->Position();
auto endpos = inData->Position() + inLen;
auto& window = m_state.window;
Uint window_posn = m_state.window_posn;
Uint window_size = m_state.window_size;
Uint R0 = m_state.R0;
Uint R1 = m_state.R1;
Uint R2 = m_state.R2;
Uint i = 0;
Uint j = 0;
Int togo = outLen;
Int this_run = 0;
Int main_element = 0;
Int match_length = 0;
Int match_offset = 0;
Int length_footer = 0;
Int extra = 0;
Int verbatim_bits = 0;
Int rundest = 0;
Int runsrc = 0;
Int copy_length = 0;
Int aligned_bits = 0;
bitbuf.InitBitStream();
/* read header if necessary */
if (m_state.header_read == 0)
{
const auto intel = bitbuf.ReadBits(1);
if (intel != 0)
{
// read the filesize
i = bitbuf.ReadBits(16);
j = bitbuf.ReadBits(16);
m_state.intel_filesize = static_cast<Int>((i << 16) | j);
}
m_state.header_read = 1;
}
while (togo > 0)
{
/* last block finished, new block expected */
if (m_state.block_remaining == 0)
{
// TODO may screw something up here
if (m_state.block_type == LzxConstants::BLOCKTYPE::UNCOMPRESSED) {
if ((m_state.block_length & 1) == 1)
inData->ReadByte(); /* realign bitstream to word */
bitbuf.InitBitStream();
}
m_state.block_type = static_cast<LzxConstants::BLOCKTYPE>(bitbuf.ReadBits(3));
i = bitbuf.ReadBits(16);
j = bitbuf.ReadBits(8);
m_state.block_remaining = m_state.block_length = static_cast<Uint>((i << 8) | j);
switch (m_state.block_type) {
case LzxConstants::BLOCKTYPE::ALIGNED: {
for (i = 0, j = 0; i < 8; i++) {
j = bitbuf.ReadBits(3);
m_state.ALIGNED_len[i] = static_cast<Byte>(j);
}
MakeDecodeTable(LzxConstants::ALIGNED_MAXSYMBOLS, LzxConstants::ALIGNED_TABLEBITS,
m_state.ALIGNED_len, m_state.ALIGNED_table);
//O mesmo que verbatim
ReadLengths(m_state.MAINTREE_len, 0, 256, bitbuf);
ReadLengths(m_state.MAINTREE_len, 256, m_state.main_elements, bitbuf);
MakeDecodeTable(LzxConstants::MAINTREE_MAXSYMBOLS, LzxConstants::MAINTREE_TABLEBITS,
m_state.MAINTREE_len, m_state.MAINTREE_table);
if (m_state.MAINTREE_len[0xE8] != 0)
m_state.intel_started = 1;
ReadLengths(m_state.LENGTH_len, 0, LzxConstants::NUM_SECONDARY_LENGTHS, bitbuf);
MakeDecodeTable(LzxConstants::LENGTH_MAXSYMBOLS, LzxConstants::LENGTH_TABLEBITS,
m_state.LENGTH_len, m_state.LENGTH_table);
break;
}
case LzxConstants::BLOCKTYPE::VERBATIM: {
ReadLengths(m_state.MAINTREE_len, 0, 256, bitbuf);
ReadLengths(m_state.MAINTREE_len, 256, m_state.main_elements, bitbuf);
MakeDecodeTable(LzxConstants::MAINTREE_MAXSYMBOLS, LzxConstants::MAINTREE_TABLEBITS,
m_state.MAINTREE_len, m_state.MAINTREE_table);
if (m_state.MAINTREE_len[0xE8] != 0)
m_state.intel_started = 1;
ReadLengths(m_state.LENGTH_len, 0, LzxConstants::NUM_SECONDARY_LENGTHS, bitbuf);
MakeDecodeTable(LzxConstants::LENGTH_MAXSYMBOLS, LzxConstants::LENGTH_TABLEBITS,
m_state.LENGTH_len, m_state.LENGTH_table);
break;
}
case LzxConstants::BLOCKTYPE::UNCOMPRESSED: {
m_state.intel_started = 1; /* because we can't assume otherwise */
bitbuf.EnsureBits(16); /* get up to 16 pad bits into the buffer */
if (bitbuf.GetBitsLeft() > 16)
inData->Seek(-2, SeekOrigin::Current); /* and align the bitstream! */
Byte hi = 0;
Byte mh = 0;
Byte ml = 0;
Byte lo = 0;
lo = static_cast<Byte>(inData->ReadByte());
ml = static_cast<Byte>(inData->ReadByte());
mh = static_cast<Byte>(inData->ReadByte());
hi = static_cast<Byte>(inData->ReadByte());
R0 = static_cast<Uint>(lo | ml << 8 | mh << 16 | hi << 24);
lo = static_cast<Byte>(inData->ReadByte());
ml = static_cast<Byte>(inData->ReadByte());
mh = static_cast<Byte>(inData->ReadByte());
hi = static_cast<Byte>(inData->ReadByte());
R1 = static_cast<Uint>(lo | ml << 8 | mh << 16 | hi << 24);
lo = static_cast<Byte>(inData->ReadByte());
ml = static_cast<Byte>(inData->ReadByte());
mh = static_cast<Byte>(inData->ReadByte());
hi = static_cast<Byte>(inData->ReadByte());
R2 = static_cast<Uint>(lo | ml << 8 | mh << 16 | hi << 24);
break;
}
default:
return -1; // TODO throw proper exception
}
}
return 0;
/* buffer exhaustion check */
if (inData->Position() > (startpos + inLen))
{
/* it's possible to have a file where the next run is less than
* 16 bits in size. In this case, the READ_HUFFSYM() macro used
* in building the tables will exhaust the buffer, so we should
* allow for this, but not allow those accidentally read bits to
* be used (so we check that there are at least 16 bits
* remaining - in this boundary case they aren't really part of
* the compressed data)
*/
//Debug.WriteLine("WTF");
if (inData->Position() > (startpos + inLen + 2) || bitbuf.GetBitsLeft() < 16)
return -1; //TODO throw proper exception
}
while ((this_run = static_cast<Int>(m_state.block_remaining)) > 0 && togo > 0)
{
if (this_run > togo)
this_run = togo;
togo -= this_run;
m_state.block_remaining -= static_cast<Uint>(this_run);
/* apply 2^x-1 mask */
window_posn &= window_size - 1;
/* runs can't straddle the window wraparound */
if ((window_posn + this_run) > window_size)
return -1; //TODO throw proper exception
switch (m_state.block_type)
{
case LzxConstants::BLOCKTYPE::VERBATIM: {
while (this_run > 0)
{
main_element = static_cast<Int>(ReadHuffSym(m_state.MAINTREE_table, m_state.MAINTREE_len,
LzxConstants::MAINTREE_MAXSYMBOLS, LzxConstants::MAINTREE_TABLEBITS,
bitbuf));
if (main_element < LzxConstants::NUM_CHARS)
{
/* literal: 0 to NUM_CHARS-1 */
window[window_posn++] = static_cast<Byte>(main_element);
this_run--;
}
else
{
/* match: NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
main_element -= LzxConstants::NUM_CHARS;
match_length = main_element & LzxConstants::NUM_PRIMARY_LENGTHS;
if (match_length == LzxConstants::NUM_PRIMARY_LENGTHS)
{
length_footer = static_cast<Int>(ReadHuffSym(m_state.LENGTH_table, m_state.LENGTH_len,
LzxConstants::LENGTH_MAXSYMBOLS, LzxConstants::LENGTH_TABLEBITS,
bitbuf));
match_length += length_footer;
}
match_length += LzxConstants::MIN_MATCH;
match_offset = main_element >> 3;
if (match_offset > 2)
{
/* not repeated offset */
if (match_offset != 3)
{
extra = extra_bits[match_offset];
verbatim_bits = static_cast<Int>(bitbuf.ReadBits(static_cast<Int>(extra)));
match_offset = static_cast<Int>(position_base[match_offset]) - 2 + verbatim_bits;
}
else
{
match_offset = 1;
}
/* update repeated offset LRU queue */
R2 = R1; R1 = R0; R0 = static_cast<Uint>(match_offset);
}
else if (match_offset == 0)
{
match_offset = (int)R0;
}
else if (match_offset == 1)
{
match_offset = (int)R1;
R1 = R0; R0 = static_cast<Uint>(match_offset);
}
else /* match_offset == 2 */
{
match_offset = (int)R2;
R2 = R0; R0 = static_cast<Uint>(match_offset);
}
rundest = (int)window_posn;
this_run -= match_length;
/* copy any wrapped around source data */
if (static_cast<Int>(window_posn) >= match_offset)
{
/* no wrap */
runsrc = rundest - match_offset;
}
else
{
runsrc = rundest + ((int)window_size - match_offset);
copy_length = match_offset - (int)window_posn;
if (copy_length < match_length)
{
match_length -= copy_length;
window_posn += static_cast<Uint>(copy_length);
while (copy_length-- > 0) window[rundest++] = window[runsrc++];
runsrc = 0;
}
}
window_posn += static_cast<Uint>(match_length);
/* copy match data - no worries about destination wraps */
while (match_length-- > 0) window[rundest++] = window[runsrc++];
}
}
break;
}
case LzxConstants::BLOCKTYPE::ALIGNED: {
while (this_run > 0)
{
main_element = static_cast<Int>(ReadHuffSym(m_state.MAINTREE_table, m_state.MAINTREE_len,
LzxConstants::MAINTREE_MAXSYMBOLS, LzxConstants::MAINTREE_TABLEBITS,
bitbuf));
if (main_element < LzxConstants::NUM_CHARS)
{
/* literal 0 to NUM_CHARS-1 */
window[window_posn++] = static_cast<Byte>(main_element);
this_run--;
}
else
{
/* match: NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
main_element -= LzxConstants::NUM_CHARS;
match_length = main_element & LzxConstants::NUM_PRIMARY_LENGTHS;
if (match_length == LzxConstants::NUM_PRIMARY_LENGTHS)
{
length_footer = static_cast<Int>(ReadHuffSym(m_state.LENGTH_table, m_state.LENGTH_len,
LzxConstants::LENGTH_MAXSYMBOLS, LzxConstants::LENGTH_TABLEBITS,
bitbuf));
match_length += length_footer;
}
match_length += LzxConstants::MIN_MATCH;
match_offset = main_element >> 3;
if (match_offset > 2)
{
/* not repeated offset */
extra = extra_bits[match_offset];
match_offset = static_cast<Int>(position_base[match_offset]) - 2;
if (extra > 3)
{
/* verbatim and aligned bits */
extra -= 3;
verbatim_bits = static_cast<Int>(bitbuf.ReadBits(static_cast<Byte>(extra)));
match_offset += (verbatim_bits << 3);
aligned_bits = static_cast<Int>(ReadHuffSym(m_state.ALIGNED_table, m_state.ALIGNED_len,
LzxConstants::ALIGNED_MAXSYMBOLS, LzxConstants::ALIGNED_TABLEBITS,
bitbuf));
match_offset += aligned_bits;
}
else if (extra == 3)
{
/* aligned bits only */
aligned_bits = static_cast<Int>(ReadHuffSym(m_state.ALIGNED_table, m_state.ALIGNED_len,
LzxConstants::ALIGNED_MAXSYMBOLS, LzxConstants::ALIGNED_TABLEBITS,
bitbuf));
match_offset += aligned_bits;
}
else if (extra > 0) /* extra==1, extra==2 */
{
/* verbatim bits only */
verbatim_bits = static_cast<Int>(bitbuf.ReadBits(static_cast<Byte>(extra)));
match_offset += verbatim_bits;
}
else /* extra == 0 */
{
/* ??? */
match_offset = 1;
}
/* update repeated offset LRU queue */
R2 = R1; R1 = R0; R0 = static_cast<Uint>(match_offset);
}
else if (match_offset == 0)
{
match_offset = (int)R0;
}
else if (match_offset == 1)
{
match_offset = (int)R1;
R1 = R0; R0 = static_cast<Uint>(match_offset);
}
else /* match_offset == 2 */
{
match_offset = (int)R2;
R2 = R0; R0 = static_cast<Uint>(match_offset);
}
rundest = (int)window_posn;
this_run -= match_length;
/* copy any wrapped around source data */
if (static_cast<Int>(window_posn) >= match_offset)
{
/* no wrap */
runsrc = rundest - match_offset;
}
else
{
runsrc = rundest + ((int)window_size - match_offset);
copy_length = match_offset - (int)window_posn;
if (copy_length < match_length)
{
match_length -= copy_length;
window_posn += static_cast<Uint>(copy_length);
while (copy_length-- > 0) window[rundest++] = window[runsrc++];
runsrc = 0;
}
}
window_posn += static_cast<Uint>(match_length);
/* copy match data - no worries about destination wraps */
while (match_length-- > 0) window[rundest++] = window[runsrc++];
}
}
break;
}
case LzxConstants::BLOCKTYPE::UNCOMPRESSED: {
if ((inData->Position() + this_run) > endpos) return -1; //TODO throw proper exception
std::vector<Byte> temp_buffer(this_run);
inData->Read(temp_buffer, 0, this_run);
for (size_t offset = 0; offset < temp_buffer.size(); ++offset)
window[window_posn + offset] = temp_buffer[offset];
window_posn += static_cast<Uint>(this_run);
break;
}
default:
return -1; //TODO throw proper exception
}
}
}
if (togo != 0)
return -1; //TODO throw proper exception
Int start_window_pos = static_cast<Int>(window_posn);
if (start_window_pos == 0)
start_window_pos = static_cast<Int>(window_size);
start_window_pos -= outLen;
outData->Write(window, start_window_pos, outLen);
m_state.window_posn = window_posn;
m_state.R0 = R0;
m_state.R1 = R1;
m_state.R2 = R2;
// TODO finish intel E8 decoding
/* intel E8 decoding */
if ((m_state.frames_read++ < 32768) && m_state.intel_filesize != 0)
{
if (outLen <= 6 || m_state.intel_started == 0)
{
m_state.intel_curpos += outLen;
}
else
{
Int dataend = outLen - 10;
auto curpos = static_cast<Uint>(m_state.intel_curpos);
m_state.intel_curpos = static_cast<Int>(curpos) + outLen;
while (outData->Position() < dataend)
{
if (outData->ReadByte() != 0xE8) {
curpos++;
continue;
}
}
}
return -1;
}
return 0;
}
public:
inline static std::vector<Uint> position_base;
inline static std::vector<Byte> extra_bits;
private:
LzxState m_state;
Int MakeDecodeTable(Uint nsyms, Uint nbits, std::vector<Byte>& length, std::vector<Ushort>& table) {
Ushort sym = 0;
Uint leaf = 0;
Byte bit_num = 1;
Uint fill;
Uint pos = 0; /* the current position in the decode table */
Uint table_mask = static_cast<Uint>(1 << static_cast<Int>(nbits));
Uint bit_mask = table_mask >> 1; /* don't do 0 length codes */
Uint next_symbol = bit_mask; /* base of allocation for long codes */
/* fill entries for codes short enough for a direct mapping */
while (bit_num <= nbits)
{
for (sym = 0; sym < nsyms; sym++)
{
if (length[sym] == bit_num)
{
leaf = pos;
if ((pos += bit_mask) > table_mask) return 1; /* table overrun */
/* fill all possible lookups of this symbol with the symbol itself */
fill = bit_mask;
while (fill-- > 0) table[leaf++] = sym;
}
}
bit_mask >>= 1;
bit_num++;
}
/* if there are any codes longer than nbits */
if (pos != table_mask)
{
/* clear the remainder of the table */
for (sym = static_cast<Ushort>(pos);
sym < table_mask; sym++) table[sym] = 0;
/* give ourselves room for codes to grow by up to 16 more bits */
pos <<= 16;
table_mask <<= 16;
bit_mask = 1 << 15;
while (bit_num <= 16)
{
for (sym = 0; sym < nsyms; sym++)
{
if (length[sym] == bit_num)
{
leaf = pos >> 16;
for (fill = 0; fill < bit_num - nbits; fill++)
{
/* if this path hasn't been taken yet, 'allocate' two entries */
if (table[leaf] == 0)
{
table[(next_symbol << 1)] = 0;
table[(next_symbol << 1) + 1] = 0;
table[leaf] = static_cast<Ushort>(next_symbol++);
}
/* follow the path and select either left or right for next bit */
leaf = static_cast<Uint>(table[leaf] << 1);
if (((pos >> static_cast<Int>(15 - fill)) & 1) == 1) leaf++;
}
table[leaf] = sym;
if ((pos += bit_mask) > table_mask) return 1;
}
}
bit_mask >>= 1;
bit_num++;
}
}
/* full talbe? */
if (pos == table_mask) return 0;
/* either erroneous table, or all elements are 0 - let's find out. */
for (sym = 0; sym < nsyms; sym++) if (length[sym] != 0) return 1;
return 0;
}
void ReadLengths(std::vector<Byte>& lens, Uint first, Uint last, BitBuffer& bitbuf) {
Uint x = 0;
Uint y = 0;
Int z = 0;
// hufftbl pointer here?
for (x = 0; x < 20; x++)
{
y = bitbuf.ReadBits(4);
m_state.PRETREE_len[x] = static_cast<Byte>(y);
}
MakeDecodeTable(LzxConstants::PRETREE_MAXSYMBOLS, LzxConstants::PRETREE_TABLEBITS,
m_state.PRETREE_len, m_state.PRETREE_table);
for (x = first; x < last;)
{
z = (int)ReadHuffSym(m_state.PRETREE_table, m_state.PRETREE_len,
LzxConstants::PRETREE_MAXSYMBOLS, LzxConstants::PRETREE_TABLEBITS, bitbuf);
if (z == 17)
{
y = bitbuf.ReadBits(4); y += 4;
while (y-- != 0) lens[x++] = 0;
}
else if (z == 18)
{
y = bitbuf.ReadBits(5); y += 20;
while (y-- != 0) lens[x++] = 0;
}
else if (z == 19)
{
y = bitbuf.ReadBits(1); y += 4;
z = static_cast<Int>(ReadHuffSym(m_state.PRETREE_table, m_state.PRETREE_len,
LzxConstants::PRETREE_MAXSYMBOLS, LzxConstants::PRETREE_TABLEBITS, bitbuf));
z = lens[x] - z; if (z < 0) z += 17;
while (y-- != 0) lens[x++] = static_cast<Byte>(z);
}
else
{
z = lens[x] - z; if (z < 0) z += 17;
lens[x++] = static_cast<Byte>(z);
}
}
}
Uint ReadHuffSym(std::vector<Ushort>& table, std::vector<Byte>& lengths, Uint nsyms, Uint nbits, BitBuffer& bitbuf) {
Uint i = 0;
Uint j = 0;
bitbuf.EnsureBits(16);
if ((i = table[bitbuf.PeekBits(static_cast<Byte>(nbits))]) >= nsyms)
{
j = static_cast<Uint>(1 << static_cast<Int>((sizeof(Uint) * 8) - nbits));
do
{
j >>= 1; i <<= 1; i |= (bitbuf.GetBuffer() & j) != 0 ? static_cast<Uint>(1) : 0;
if (j == 0) return 0; // TODO throw proper exception
} while ((i = table[i]) >= nsyms);
}
j = lengths[i];
bitbuf.RemoveBits(static_cast<Byte>(j));
return i;
}
};
}
#endif

View File

@ -0,0 +1,40 @@
#include "decoderstream.hpp"
namespace xna {
Int LzxDecoderStream::Length()
{
return 0;
}
Long LzxDecoderStream::Position()
{
return 0;
}
void LzxDecoderStream::Close()
{
}
Long LzxDecoderStream::Seek(Long offset, SeekOrigin const& origin, xna_error_ptr_arg)
{
return Long();
}
Int LzxDecoderStream::Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg)
{
return decompressedStream->Read(buffer, bufferLength, offset, count, err);
}
Int LzxDecoderStream::Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_ptr_arg)
{
return decompressedStream->Read(buffer, offset, count, err);
}
Int LzxDecoderStream::ReadByte(xna_error_ptr_arg)
{
return Int();
}
void LzxDecoderStream::Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg)
{
}
void LzxDecoderStream::Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_ptr_arg)
{
}
void LzxDecoderStream::WriteByte(Byte value, xna_error_ptr_arg)
{
}
}

View File

@ -0,0 +1,89 @@
#ifndef XNA_CONTENT_LZX_DECODERSTREAM_HPP
#define XNA_CONTENT_LZX_DECODERSTREAM_HPP
#include "decoder.hpp"
namespace xna {
class LzxDecoderStream : public Stream {
public:
LzxDecoderStream(sptr<Stream>& input, Int decompressedSize, Int compressedSize) {
dec = New<LzxDecoder>(16);
Decompress(input, decompressedSize, compressedSize);
}
private:
void Decompress(sptr<Stream>& stream, Int decompressedSize, Int compressedSize) {
//thanks to ShinAli (https://bitbucket.org/alisci01/xnbdecompressor)
// default window size for XNB encoded files is 64Kb (need 16 bits to represent it)
decompressedStream = New<MemoryStream>(decompressedSize);
auto startPos = stream->Position();
auto pos = startPos;
while (pos - startPos < compressedSize)
{
// the compressed stream is seperated into blocks that will decompress
// into 32Kb or some other size if specified.
// normal, 32Kb output blocks will have a short indicating the size
// of the block before the block starts
// blocks that have a defined output will be preceded by a byte of value
// 0xFF (255), then a short indicating the output size and another
// for the block size
// all shorts for these cases are encoded in big endian order
Int hi = stream->ReadByte();
Int lo = stream->ReadByte();
Int block_size = (hi << 8) | lo;
Int frame_size = 0x8000; // frame size is 32Kb by default
// does this block define a frame size?
if (hi == 0xFF) {
hi = lo;
lo = static_cast<Byte>(stream->ReadByte());
frame_size = (hi << 8) | lo;
hi = static_cast<Byte>(stream->ReadByte());
lo = static_cast<Byte>(stream->ReadByte());
block_size = (hi << 8) | lo;
pos += 5;
}
else
pos += 2;
// either says there is nothing to decode
if (block_size == 0 || frame_size == 0)
break;
auto decompressed = reinterpret_pointer_cast<Stream>(decompressedStream);
dec->Decompress(stream, block_size, decompressed, frame_size);
pos += block_size;
// reset the position of the input just incase the bit buffer
// read in some unused bytes
stream->Seek(pos, SeekOrigin::Begin);
}
if (decompressedStream->Position() != decompressedSize)
{
return;
}
decompressedStream->Seek(0, SeekOrigin::Begin);
}
private:
sptr<LzxDecoder> dec = nullptr;
sptr<MemoryStream>decompressedStream = nullptr;
// Inherited via Stream
Int Length() override;
Long Position() override;
void Close() override;
Long Seek(Long offset, SeekOrigin const& origin, xna_error_nullarg) override;
Int Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) override;
Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_nullarg) override;
Int ReadByte(xna_error_nullarg) override;
void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) override;
void Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_nullarg) override;
void WriteByte(Byte value, xna_error_nullarg) override;
virtual constexpr bool IsClosed() override { return false; }
};
}
#endif

View File

@ -1,21 +1,26 @@
#ifndef XNA_CONTENT_MANAGER_HPP
#define XNA_CONTENT_MANAGER_HPP
#include "../csharp/stream.hpp"
#include "../default.hpp"
#include "../game/servicecontainer.hpp"
#include "reader.hpp"
#include <algorithm>
#include <filesystem>
#include <map>
#include <algorithm>
#include "../csharp/stream.hpp"
namespace xna {
class ContentManager {
public:
ContentManager(String const& rootDirectory) :
_rootDirectory(rootDirectory),
_path(rootDirectory){};
friend class ContentReader;
virtual ~ContentManager(){
Unload();
ContentManager(String const& rootDirectory, sptr<GameServiceContainer> const& services) :
_rootDirectory(rootDirectory){
_services = services;
};
static sptr<GameServiceContainer> Services() {
return _services;
}
constexpr String RootDirectory() const {
@ -24,48 +29,43 @@ namespace xna {
void RootDirectory(String const& value) {
_rootDirectory = value;
_path = value;
}
virtual void Unload() {
if (_loadedAssets.empty())
return;
_loadedAssets.clear();
}
template <typename T>
sptr<T> Load(String const& assetName) {
if (assetName.empty()) return nullptr;
T Load(String const& assetName) {
if (assetName.empty()) return T();
if (_loadedAssets.contains(assetName)) {
const auto& ptr = _loadedAssets[assetName];
const auto obj1 = reinterpret_pointer_cast<T>(ptr);
auto obj2 = ReadAsset<T>(assetName);
return obj1;
}
const auto obj2 = ReadAsset<T>(assetName);
return obj2;
}
}
public:
protected:
template <typename T>
sptr<T> ReadAsset(String const& assetName) {
T ReadAsset(String const& assetName) {
auto input = OpenStream(assetName);
if (input->IsClosed())
return T();
auto contentReader = ContentReader::Create(this, input, assetName);
return contentReader->ReadAsset<T>();
}
sptr<Stream> OpenStream(String const& assetName) {
String filePath = _rootDirectory + "\\" + assetName + contentExtension;
const auto stream = New<FileStream>(filePath);
const auto stream = New<FileStream>(filePath, FileMode::Open);
//const auto stream = New<FileStream>(filePath);
return reinterpret_pointer_cast<Stream>(stream);
}
private:
String _rootDirectory;
std::filesystem::path _path;
std::map<String, sptr<void>> _loadedAssets;
String _rootDirectory;
std::vector<Byte> byteBuffer;
inline const static String contentExtension = ".xnb";
inline static sptr<GameServiceContainer> _services = nullptr;
};
}

View File

@ -1,9 +1,173 @@
#include "reader.hpp"
#include "manager.hpp"
#include "lzx/decoderstream.hpp"
#include "typereadermanager.hpp"
#include "manager.hpp"
namespace xna {
sptr<ContentReader> ContentReader::Create(ContentManager* contentManager, Stream& input, String const& assetName)
sptr<ContentReader> ContentReader::Create(ContentManager* contentManager, sptr<Stream>& input, String const& assetName)
{
return sptr<ContentReader>();
Int graphicsProfile = 0;
input = ContentReader::PrepareStream(input, assetName, graphicsProfile);
return std::shared_ptr<ContentReader>(new ContentReader(contentManager, input, assetName, graphicsProfile));
}
Vector2 ContentReader::ReadVector2()
{
Vector2 vector2;
vector2.X = ReadSingle();
vector2.Y = ReadSingle();
return vector2;
}
Vector3 ContentReader::ReadVector3()
{
Vector3 vector3;
vector3.X = ReadSingle();
vector3.Y = ReadSingle();
vector3.Z = ReadSingle();
return vector3;
}
Vector4 ContentReader::ReadVector4()
{
Vector4 vector4;
vector4.X = ReadSingle();
vector4.Y = ReadSingle();
vector4.Z = ReadSingle();
vector4.W = ReadSingle();
return vector4;
}
Matrix ContentReader::ReadMatrix()
{
Matrix matrix;
matrix.M11 = ReadSingle();
matrix.M12 = ReadSingle();
matrix.M13 = ReadSingle();
matrix.M14 = ReadSingle();
matrix.M21 = ReadSingle();
matrix.M22 = ReadSingle();
matrix.M23 = ReadSingle();
matrix.M24 = ReadSingle();
matrix.M31 = ReadSingle();
matrix.M32 = ReadSingle();
matrix.M33 = ReadSingle();
matrix.M34 = ReadSingle();
matrix.M41 = ReadSingle();
matrix.M42 = ReadSingle();
matrix.M43 = ReadSingle();
matrix.M44 = ReadSingle();
return matrix;
}
Quaternion ContentReader::ReadQuaternion()
{
Quaternion quaternion;
quaternion.X = ReadSingle();
quaternion.Y = ReadSingle();
quaternion.Z = ReadSingle();
quaternion.W = ReadSingle();
return quaternion;
}
Color ContentReader::ReadColor()
{
const auto packedValue = ReadUInt32();
return Color(packedValue);
}
float ContentReader::ReadSingle()
{
const auto int32 = ReadUInt32();
return *(float*)&int32;
}
double ContentReader::ReadDouble()
{
const auto int64 = ReadUInt64();
return *(double*)&int64;
}
std::vector<Byte> ContentReader::ReadByteBuffer(size_t size, xna_error_ptr_arg)
{
std::vector<Byte>& buffer = _contentManager->byteBuffer;
if (buffer.empty() || buffer.size() < size)
{
buffer = std::vector<Byte>(size);
//_contentManager->byteBuffer = buffer;
}
Int num = 0;
for (size_t index = 0; index < size; index += num)
{
num = Read(buffer, index, size - index);
if (num == 0) {
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
return std::vector<Byte>();
}
}
return buffer;
}
sptr<Stream> ContentReader::PrepareStream(sptr<Stream>& input, String const& assetName, Int& graphicsProfile)
{
BinaryReader binaryReader = BinaryReader(input);
if (binaryReader.ReadByte() != 'X' || binaryReader.ReadByte() != 'N' || binaryReader.ReadByte() != 'B')
return nullptr;
Int num1 = 0;
auto _byte = binaryReader.ReadByte(); //desfazer
if (_byte == 'w')
num1 = binaryReader.ReadUInt16();
else
return nullptr;
graphicsProfile = (num1 & XnbVersionProfileMask) >> XnbVersionProfileShift;
bool flag = false;
switch (num1 & -32513)
{
case XnbVersion:
flag = false;
break;
case XnbCompressedVersion:
flag = true;
break;
default:
return nullptr;
}
const auto num2 = binaryReader.ReadInt32();
if ((num2 - 10) > input->Length() - input->Position())
return nullptr;
if (!flag)
return input;
const Int compressedTodo = num2 - 14;
const auto decompressedTodo = binaryReader.ReadInt32();
auto lzxStream = New<LzxDecoderStream>(input, compressedTodo, decompressedTodo);
return reinterpret_pointer_cast<Stream>(lzxStream);
}
Int ContentReader::ReadHeader() {
auto _this = shared_from_this();
typeReaders = ContentTypeReaderManager::ReadTypeManifest(this->Read7BitEncodedInt(), _this);
auto length = this->Read7BitEncodedInt();
if (length > 0)
{
//TODO: length > 0
}
return length;
}
}

View File

@ -1,16 +1,153 @@
#ifndef XNA_CONTENT_READER_HPP
#define XNA_CONTENT_READER_HPP
#include "../common/color.hpp"
#include "../common/matrix.hpp"
#include "../common/quaternion.hpp"
#include "../common/vectors.hpp"
#include "../csharp/binary.hpp"
#include "../csharp/type.hpp"
#include "../default.hpp"
#include "typereadermanager.hpp"
#include <any>
namespace xna {
class ContentReader {
class ContentReader : public BinaryReader, public std::enable_shared_from_this<ContentReader> {
public:
static sptr<ContentReader> Create(ContentManager* contentManager, Stream& input, String const& assetName);
static sptr<ContentReader> Create(ContentManager* contentManager, sptr<Stream>& input, String const& assetName);
template <typename T>
T ReadAsset();
template <typename T>
T ReadObject();
template <typename T>
T ReadObject(T existingInstance);
template <typename T>
T ReadObject(ContentTypeReader& typeReader);
template <typename T>
T ReadObject(ContentTypeReader& typeReader, T existingInstance);
Vector2 ReadVector2();
Vector3 ReadVector3();
Vector4 ReadVector4();
Matrix ReadMatrix();
Quaternion ReadQuaternion();
Color ReadColor();
float ReadSingle();
double ReadDouble();
std::vector<Byte> ReadByteBuffer(size_t size, xna_error_nullarg);
private:
//ContentReader(ContentManager* contentManager, Stream& inut)
ContentReader(ContentManager* contentManager, sptr<Stream>& input, String const& assetName, Int graphicsProfile)
: BinaryReader(input), _contentManager(contentManager), _assetName(assetName) {}
static sptr<Stream> PrepareStream(sptr<Stream>& input, String const& assetName, Int& graphicsProfile);
Int ReadHeader();
template <typename T>
T ReadObjectInternal(std::any& existingInstance, xna_error_nullarg);
template <typename T>
T ReadObjectInternal(ContentTypeReader& typeReader, std::any& existingInstance, xna_error_nullarg);
template <typename T>
T InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_nullarg);
private:
ContentManager* _contentManager = nullptr;
String _assetName;
std::vector<sptr<ContentTypeReader>> typeReaders;
Int graphicsProfile{ 0 };
static constexpr Ushort XnbVersionProfileMask = 32512;
static constexpr Ushort XnbCompressedVersion = 32773;
static constexpr Ushort XnbVersion = 5;
static constexpr Int XnbVersionProfileShift = 8;
};
template<typename T>
inline T ContentReader::ReadObjectInternal(std::any& existingInstance, xna_error_ptr_arg)
{
const auto num = Read7BitEncodedInt();
if (num == 0) {
return T();
}
const auto index = num - 1;
if (index >= typeReaders.size()) {
xna_error_apply(err, XnaErrorCode::ARGUMENT_OUT_OF_RANGE);
return T();
}
auto reader = typeReaders[index];
return InvokeReader<T>(*reader, existingInstance, err);
}
template<typename T>
inline T ContentReader::InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_ptr_arg)
{
auto contentTypeReader = reinterpret_cast<ContentTypeReaderT<T>*>(&reader);
T objB;
if (contentTypeReader) {
auto existingInstance1 = existingInstance.has_value() ? std::any_cast<T>(existingInstance) : T();
objB = contentTypeReader->Read(*this, existingInstance1);
return objB;
}
return T();
}
template<typename T>
inline T ContentReader::ReadAsset()
{
const auto sharedResourceCount = ReadHeader();
auto obj = ReadObject<T>();
return obj;
}
template<typename T>
inline T ContentReader::ReadObject()
{
auto a = std::any();
return ReadObjectInternal<T>(a);
}
template<typename T>
inline T ContentReader::ReadObject(T existingInstance)
{
return ReadObjectInternal<T>(std::any(existingInstance));
}
template<typename T>
inline T ContentReader::ReadObject(ContentTypeReader& typeReader)
{
auto obj = std::any();
return ReadObjectInternal<T>(typeReader, obj);
}
template<typename T>
inline T ContentReader::ReadObject(ContentTypeReader& typeReader, T existingInstance)
{
return ReadObjectInternal<T>(typeReader, std::any(existingInstance));
}
template<typename T>
inline T ContentReader::ReadObjectInternal(ContentTypeReader& typeReader, std::any& existingInstance, xna_error_ptr_arg)
{
return typeReader.TargetIsValueType
? InvokeReader<T>(typeReader, existingInstance, err)
: ReadObjectInternal<T>(existingInstance, err);
}
}
#endif

View File

@ -0,0 +1,148 @@
#include "typereadermanager.hpp"
#include "reader.hpp"
#include "defaultreaders.hpp"
namespace xna {
std::vector<PContentTypeReader> ContentTypeReaderManager::ReadTypeManifest(Int typeCount, sptr<ContentReader>& contentReader, xna_error_ptr_arg)
{
initMaps();
auto contentTypeReaderArray = std::vector<PContentTypeReader>(typeCount);
std::vector<PContentTypeReader> newTypeReaders;
for (size_t index = 0; index < typeCount; ++index)
{
const auto readerTypeName = contentReader->ReadString();
const auto xnaType = readerTypeName.substr(0, readerTypeName.find(","));
auto typeReader = ContentTypeReaderManager::GetTypeReader(xnaType.empty() ? readerTypeName : xnaType, contentReader, newTypeReaders);
if (contentReader->ReadInt32() != typeReader->TypeVersion()) {
xna_error_apply(err, XnaErrorCode::BAD_TYPE);
ContentTypeReaderManager::RollbackAddReaders(newTypeReaders);
return std::vector<PContentTypeReader>();
}
contentTypeReaderArray[index] = typeReader;
if (!newTypeReaders.empty()) {
auto manager = std::shared_ptr<ContentTypeReaderManager>(new ContentTypeReaderManager(contentReader));
for (size_t i = 0; i < newTypeReaders.size(); ++i) {
auto& contentTypeReader = newTypeReaders[i];
contentTypeReader->Initialize(manager);
}
}
}
return contentTypeReaderArray;
}
sptr<ContentTypeReader> ContentTypeReaderManager::GetTypeReader(sptr<Type> const& targetType, sptr<ContentReader>& contentReader, xna_error_ptr_arg)
{
if (!targetType) {
xna_error_apply(err, XnaErrorCode::ARGUMENT_IS_NULL);
return nullptr;
}
sptr<ContentTypeReader> typeReader = nullptr;
if (!ContentTypeReaderManager::targetTypeToReader.contains(targetType)) {
xna_error_apply(err, XnaErrorCode::ARGUMENT_OUT_OF_RANGE);
return nullptr;
}
return ContentTypeReaderManager::targetTypeToReader[targetType];
}
ContentTypeReaderManager::ContentTypeReaderManager(sptr<ContentReader>& contentReader) {
initMaps();
}
sptr<ContentTypeReader> ContentTypeReaderManager::GetTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, std::vector<PContentTypeReader>& newTypeReaders, xna_error_ptr_arg)
{
sptr<ContentTypeReader> reader = nullptr;
if (ContentTypeReaderManager::nameToReader.contains(readerTypeName)) {
return ContentTypeReaderManager::nameToReader[readerTypeName];
}
else if (!ContentTypeReaderManager::InstantiateTypeReader(readerTypeName, contentReader, reader, err)) {
return reader;
}
if (xna_error_haserros(err))
return nullptr;
ContentTypeReaderManager::AddTypeReader(readerTypeName, contentReader, reader, err);
if (xna_error_haserros(err)) return nullptr;
newTypeReaders.push_back(reader);
return reader;
}
bool ContentTypeReaderManager::InstantiateTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, sptr<ContentTypeReader>& reader, xna_error_ptr_arg)
{
sptr<Type> type = nullptr;
if (Type::NameOfRegisteredTypes.contains(readerTypeName))
type = Type::NameOfRegisteredTypes[readerTypeName];
if (!type) {
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
return false;
}
if (ContentTypeReaderManager::readerTypeToReader.contains(type)) {
reader = ContentTypeReaderManager::readerTypeToReader[type];
ContentTypeReaderManager::nameToReader.insert({ readerTypeName, reader });
return false;
}
reader = ContentTypeReaderActivador::CreateInstance(type, err);
return true;
}
void ContentTypeReaderManager::AddTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, sptr<ContentTypeReader>& reader, xna_error_ptr_arg)
{
auto targetType = reader->TargetType();
if (ContentTypeReaderManager::targetTypeToReader.contains(targetType)) {
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
return;
}
ContentTypeReaderManager::targetTypeToReader.insert({ targetType, reader });
//ContentTypeReaderManager::readerTypeToReader.insert({ reader->GetType(), reader });
ContentTypeReaderManager::readerTypeToReader.insert({ typeof(*reader), reader});
ContentTypeReaderManager::nameToReader.insert({ readerTypeName, reader });
}
void ContentTypeReaderManager::RollbackAddReaders(std::vector<sptr<ContentTypeReader>>& newTypeReaders)
{
if (newTypeReaders.empty())
return;
for (size_t i = 0; i < newTypeReaders.size(); ++i) {
auto newTypeReader = newTypeReaders[i];
ContentTypeReaderManager::RollbackAddReader(ContentTypeReaderManager::nameToReader, newTypeReader);
ContentTypeReaderManager::RollbackAddReader(ContentTypeReaderManager::targetTypeToReader, newTypeReader);
ContentTypeReaderManager::RollbackAddReader(ContentTypeReaderManager::readerTypeToReader, newTypeReader);
}
}
void ContentTypeReaderManager::initMaps()
{
if (targetTypeToReader.empty() && readerTypeToReader.empty()) {
auto typeReader = New<ObjectReader>();
auto contentTypeReader = reinterpret_pointer_cast<ContentTypeReader>(typeReader);
//targetTypeToReader.insert({ typeReader->TargetType(), contentTypeReader});
//readerTypeToReader.insert({ typeReader->GetType(), contentTypeReader});
targetTypeToReader.insert({ typeof<Object>(), contentTypeReader});
readerTypeToReader.insert({ typeof<ObjectReader>(), contentTypeReader});
}
}
}

View File

@ -0,0 +1,153 @@
#ifndef XNA_CONTENT_TYPEREADER_HPP
#define XNA_CONTENT_TYPEREADER_HPP
#include "../csharp/type.hpp"
#include "../default.hpp"
#include <algorithm>
#include <map>
#include <any>
namespace xna {
//-------------------------------------------------------//
// ContentTypeReader //
//-------------------------------------------------------//
class ContentTypeReader {
public:
virtual Int TypeVersion() { return 0; }
virtual bool CanDeserializeIntoExistingObject() { return false; }
virtual void Initialize(sptr<ContentTypeReaderManager> const& manager) {}
sptr<Type> TargetType() { return _targetType; }
virtual std::any Read(ContentReader& input, std::any& existingInstance) = 0;
protected:
ContentTypeReader(sptr<Type> const& targetType) : _targetType(targetType)
{}
public:
bool TargetIsValueType{ false };
private:
sptr<Type> _targetType = nullptr;
};
template <class T>
class ContentTypeReaderT : public ContentTypeReader {
protected:
ContentTypeReaderT(sptr<Type> const& targetType) : ContentTypeReader(targetType){}
public:
virtual std::any Read(ContentReader& input, std::any& existingInstance) override{
return std::any();
}
virtual T Read(ContentReader& input, T& existingInstance) = 0;
};
//-------------------------------------------------------//
// ContentTypeReaderActivador //
//-------------------------------------------------------//
class ContentTypeReaderActivador {
public:
using Activador = sptr<ContentTypeReader>(*)();
static sptr<ContentTypeReader> CreateInstance(sptr<Type> const& type, xna_error_nullarg) {
if (!type)
{
xna_error_apply(err, XnaErrorCode::ARGUMENT_IS_NULL);
return nullptr;
}
const auto hash = type->GetHashCode();
if (!activators.contains(hash))
return nullptr;
auto activador = activators[hash];
if (!activador) return nullptr;
return activador();
}
static void SetActivador(sptr<Type> const& type, Activador activador, xna_error_nullarg) {
if (!type) {
xna_error_apply(err, XnaErrorCode::ARGUMENT_IS_NULL);
return;
}
const auto hash = type->GetHashCode();
if (!activators.contains(hash))
activators.insert({ hash, activador });
}
private:
inline static auto activators = std::map<size_t, Activador>();
ContentTypeReaderActivador();
ContentTypeReaderActivador(ContentTypeReaderActivador&&);
ContentTypeReaderActivador(ContentTypeReaderActivador&);
};
using PContentTypeReader = sptr<ContentTypeReader>;
using PType = sptr<Type>;
//-------------------------------------------------------//
// ContentTypeReaderManager //
//-------------------------------------------------------//
class ContentTypeReaderManager {
public:
static std::vector<PContentTypeReader> ReadTypeManifest(Int typeCount, sptr<ContentReader>& contentReader, xna_error_nullarg);
static sptr<ContentTypeReader> GetTypeReader(sptr<Type> const& targetType, sptr<ContentReader>& contentReader, xna_error_nullarg);
inline sptr<ContentTypeReader> GetTypeReader(sptr<Type> const& targetType, xna_error_nullarg) {
return ContentTypeReaderManager::GetTypeReader(targetType, this->contentReader, err);
}
inline static bool ContainsTypeReader(sptr<Type> const& targetType) {
return ContentTypeReaderManager::targetTypeToReader.contains(targetType);
}
private:
ContentTypeReaderManager(sptr<ContentReader>& contentReader);
static sptr<ContentTypeReader> GetTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, std::vector<PContentTypeReader>& newTypeReaders, xna_error_nullarg);
static bool InstantiateTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, sptr<ContentTypeReader>& reader, xna_error_nullarg);
static void AddTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, sptr<ContentTypeReader>& reader, xna_error_nullarg);
static void RollbackAddReaders(std::vector<sptr<ContentTypeReader>>& newTypeReaders);
static void RollbackAddReader(std::map<String, PContentTypeReader>& dictionary, sptr<ContentTypeReader>& reader) {
std::map<String, sptr<ContentTypeReader>>::iterator it;
for (it = dictionary.begin(); it != dictionary.end(); it++) {
if (it->second == reader) {
dictionary.erase(it->first);
it = dictionary.begin();
}
}
}
static void RollbackAddReader(std::map<PType, PContentTypeReader>& dictionary, sptr<ContentTypeReader>& reader) {
std::map<PType, sptr<ContentTypeReader>>::iterator it;
for (it = dictionary.begin(); it != dictionary.end(); it++) {
if (it->second == reader) {
dictionary.erase(it->first);
it = dictionary.begin();
}
}
}
private:
sptr<ContentReader> contentReader = nullptr;
inline static auto nameToReader = std::map<String, PContentTypeReader>();
inline static auto targetTypeToReader = std::map<PType, PContentTypeReader>();
inline static auto readerTypeToReader = std::map<PType, PContentTypeReader>();
static void initMaps();
};
}
#endif

View File

@ -1,4 +1,5 @@
#include "binary.hpp"
#include "../csharp/buffer.hpp"
namespace xna {
Int BinaryReader::PeekChar(xna_error_ptr_arg)
@ -6,7 +7,7 @@ namespace xna {
if (!stream) {
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
return -1;
}
}
const auto position = stream->Position();
const auto num = Read(err);
@ -260,14 +261,14 @@ namespace xna {
} while (num < val1);
return empty;
return sb;
}
Int BinaryReader::InternalReadOneChar(xna_error_ptr_arg)
{
Int num1 = 0;
Long num2 = 0;
Long num3 = stream->Position();
Long num3 = stream->Position();
if (charBytes.empty())
charBytes.resize(128);
@ -352,7 +353,7 @@ namespace xna {
}
}
Int BinaryReader::InternalReadChars(char* buffer, size_t bufferSize, Int index, Int count, xna_error_ptr_arg)
Int BinaryReader::InternalReadChars(Char* buffer, size_t bufferSize, size_t index, size_t count, xna_error_ptr_arg)
{
auto charCount = count;
@ -371,18 +372,18 @@ namespace xna {
if (count1 > 128)
count1 = 128;
Int num = 0;
Int position = 0;
Int byteCount;
std::vector<Byte> numArray;
byteCount = stream->Read(charBytes, 0, count1);
byteCount = stream->Read(charBytes, 0, static_cast<Int>(count1), err);
numArray = charBytes;
if (byteCount == 0)
return count - charCount;
return static_cast<Int>(count - charCount);
if (num < 0 || byteCount < 0 || (num + byteCount) > numArray.size()) {
if (position < 0 || byteCount < 0 || (position + byteCount) > numArray.size()) {
xna_error_apply(err, XnaErrorCode::ARGUMENT_OUT_OF_RANGE);
return -1;
}
@ -393,22 +394,28 @@ namespace xna {
}
auto data = reinterpret_cast<char*>(charBytes.data());
const auto result = std::string((data + num), (data + num) + byteCount);
auto pChars = reinterpret_cast<char*>(buffer);
//const auto result = std::string((data + position), (pChars + index) + byteCount);
const auto result = std::string((data + position), (data + position) + byteCount);
Buffer::BlockCopy(result.c_str(), position, pChars, index, byteCount);
const auto chars = result.size();
buffer = reinterpret_cast<Char*>(pChars);
charCount -= static_cast<Int>(chars);
index += static_cast<Int>(chars);
const auto chars = static_cast<Int>(result.size());
charCount -= chars;
index += chars;
}
return count - charCount;
return static_cast<Int>(count - charCount);
}
Long BinaryWriter::Seek(Int offset, SeekOrigin origin, xna_error_ptr_arg)
{
if (!_stream) {
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
return - 1;
return -1;
}
return _stream->Seek(offset, origin);
@ -648,4 +655,60 @@ namespace xna {
_buffer[7] = static_cast<Byte>(value >> 56);
_stream->Write(_buffer, 0, 8);
}
Int BinaryReader::Read7BitEncodedInt(xna_error_ptr_arg)
{
Int num1 = 0;
Int num2 = 0;
while (num2 != 35) {
auto num3 = ReadByte(err);
if (xna_error_haserros(err))
return -1;
num1 |= (static_cast<Int>(num3) & static_cast<Int>(SbyteMaxValue)) << num2;
num2 += 7;
if ((static_cast<Int>(num3) & 128) == 0)
return num1;
}
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
return -1;
}
Int BinaryReader::Read(std::vector<Char>& buffer, size_t index, size_t count, xna_error_ptr_arg)
{
return InternalReadChars(buffer.data(), buffer.size(), index, count, err);
}
Int BinaryReader::Read(std::vector<Byte>& buffer, size_t index, size_t count, xna_error_ptr_arg)
{
auto data = reinterpret_cast<Char*>(buffer.data());
return InternalReadChars(data, buffer.size(), index, count, err);
}
std::vector<Byte> BinaryReader::ReadBytes(size_t count, xna_error_ptr_arg)
{
std::vector<Byte> result(count);
Int numRead = 0;
do {
const auto n = stream->Read(result, static_cast<Int>(numRead), static_cast<Int>(count), err);
if (n == 0)
break;
numRead += n;
count -= n;
} while (count > 0);
if (numRead != result.size()) {
std::vector<Byte> copy(numRead);
Buffer::BlockCopy(result.data(), 0, copy.data(), 0, numRead);
result = copy;
}
return result;
}
}

View File

@ -7,7 +7,7 @@
namespace xna {
class BinaryReader {
public:
BinaryReader(Stream* const& input) {
BinaryReader(sptr<Stream> const& input) {
stream = input;
buffer = std::vector<Byte>(bufferLength);
}
@ -28,18 +28,15 @@ namespace xna {
double ReadDouble(xna_error_nullarg);
std::string ReadString(xna_error_nullarg);
Int Read(std::vector<Char>& buffer, size_t index, size_t count, xna_error_nullarg) {
return -1;
}
Int Read(std::vector<Char>& buffer, size_t index, size_t count, xna_error_nullarg);
Int Read(std::vector<Byte>& buffer, size_t index, size_t count, xna_error_nullarg);
std::vector<Byte> ReadBytes(size_t count, xna_error_nullarg) {
return std::vector<Byte>();
}
std::vector<Byte> ReadBytes(size_t count, xna_error_nullarg);
private:
static constexpr int maxCharBytesSize = 128;
static constexpr int bufferLength = 16;
Stream* stream = nullptr;
sptr<Stream> stream = nullptr;
std::vector<Byte> charBytes;
std::vector<Char> singleChar;
std::vector<Byte> buffer;
@ -47,38 +44,19 @@ namespace xna {
bool m2BytesPerChar{ false };
protected:
Int InternalReadOneChar(xna_error_nullarg);
void FillBuffer(Int numBytes, xna_error_nullarg);
Int Read7BitEncodedInt(xna_error_nullarg)
{
Int num1 = 0;
Int num2 = 0;
Int Read7BitEncodedInt(xna_error_nullarg);
while (num2 != 35) {
auto num3 = ReadByte(err);
if (xna_error_haserros(err))
return -1;
num1 |= (static_cast<Int>(num3) & static_cast<Int>(SbyteMaxValue)) << num2;
num2 += 7;
if ((static_cast<Int>(num3) & 128) == 0)
return num1;
}
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
return -1;
}
Int InternalReadChars(char* buffer, size_t bufferSize, Int index, Int count, xna_error_nullarg);
Int InternalReadChars(Char* buffer, size_t bufferSize, size_t index, size_t count, xna_error_nullarg);
};
class BinaryWriter {
public:
BinaryWriter(Stream* stream) : _stream(stream), _buffer(16) {
BinaryWriter(sptr<Stream> const& stream) : _stream(stream), _buffer(16) {
}
Long Seek(Int offset, SeekOrigin origin, xna_error_nullarg);
@ -103,7 +81,7 @@ namespace xna {
void Write(const char* _string, size_t stringLength, xna_error_nullarg);
public:
Stream* _stream;
sptr<Stream> _stream = nullptr;
private:
std::vector<Byte> _buffer;

View File

@ -8,14 +8,14 @@ namespace xna {
class Buffer {
public:
template <typename T>
static void BlockCopy(
T const* src,
rsize_t srcOffset,
T* dst,
rsize_t dstOffset,
rsize_t byteCount) {
static void BlockCopy(T const* src, rsize_t srcOffset, T* dst, rsize_t dstOffset, rsize_t byteCount) {
memmove_s(dst + dstOffset, byteCount, src + srcOffset, byteCount);
}
}
template <typename TSOURCE, typename TDEST>
static void BlockCopy(TSOURCE const* src, rsize_t srcOffset, TDEST* dst, rsize_t dstOffset, rsize_t byteCount) {
memmove_s(dst + dstOffset, byteCount, src + srcOffset, byteCount);
}
private:
constexpr Buffer() = default;

View File

@ -0,0 +1,12 @@
#include "object.hpp"
#include "type.hpp"
namespace xna {
size_t Object::GetHashCode() const
{
size_t seed = 0;
XnaHHashCombine(seed, this);
return seed;
}
}

View File

@ -0,0 +1,13 @@
#ifndef XNA_CSHARP_OBJECT_HPP
#define XNA_CSHARP_OBJECT_HPP
#include "../default.hpp"
namespace xna {
class Object {
public:
virtual size_t GetHashCode() const;
};
}
#endif

View File

@ -0,0 +1,15 @@
#ifndef XNA_CSHARP_SERVICE_HPP
#define XNA_CSHARP_SERVICE_HPP
#include "../default.hpp"
#include "type.hpp"
#include <any>
namespace xna {
class IServiceProvider {
public:
virtual std::any GetService(Type& serviceType) = 0;
};
}
#endif

View File

@ -165,7 +165,7 @@ namespace xna {
return -1;
}
if (_closed)
if (_closed || _truncated)
return 0;
auto _buff = reinterpret_cast<char*>(buffer);
@ -184,7 +184,7 @@ namespace xna {
}
Int FileStream::ReadByte(xna_error_ptr_arg){
if (_closed)
if (_closed || _truncated)
return 0;
char c = 0;

View File

@ -10,9 +10,11 @@
namespace xna {
class Stream {
public:
virtual ~Stream(){}
virtual Int Length() = 0;
virtual Long Position() = 0;
virtual void Close() = 0;
virtual bool IsClosed() = 0;
virtual Long Seek(Long offset, SeekOrigin const& origin, xna_error_nullarg) = 0;
virtual Int Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) = 0;
virtual Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_nullarg) = 0;
@ -47,13 +49,17 @@ namespace xna {
_buffer = std::vector<Byte>();
}
virtual Long Seek(Long offset, SeekOrigin const& origin, xna_error_ptr_arg) override;
virtual Int Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg) override;
virtual Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_ptr_arg) override;
virtual Int ReadByte(xna_error_ptr_arg) override;
virtual void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg) override;
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_ptr_arg) override;
virtual void WriteByte(Byte value, xna_error_ptr_arg) override;
virtual constexpr bool IsClosed() override {
return _closed;
}
virtual Long Seek(Long offset, SeekOrigin const& origin, xna_error_nullarg) override;
virtual Int Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) override;
virtual Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_nullarg) override;
virtual Int ReadByte(xna_error_nullarg) override;
virtual void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) override;
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_nullarg) override;
virtual void WriteByte(Byte value, xna_error_nullarg) override;
public:
Int _position{ 0 };
@ -65,7 +71,63 @@ namespace xna {
class FileStream : public Stream {
public:
FileStream(std::string const& path){
FileStream(String const& path, FileMode fileMode) {
int flags = std::fstream::in
| std::fstream::out
| std::fstream::binary;
const auto exists = std::filesystem::exists(path);
switch (fileMode)
{
//Especifica se deve abrir um arquivo existente.
case FileMode::Open:
if (!exists) {
_closed = true;
return;
}
break;
//Especifica que se deve abrir um arquivo, se existir;
// caso contrário, um novo arquivo deverá ser criado.
case FileMode::OpenOrCreate:
case FileMode::Create:
if (!exists)
flags |= std::fstream::trunc;
break;
//Especifica que o sistema operacional deve criar um novo arquivo.
//Se o arquivo já existir, não abre o arquivo.
case FileMode::CreateNew:
if (!exists)
flags |= std::fstream::trunc;
else
return;
break;
//Abre o arquivo, se existir, e busca o final do arquivo ou cria um novo arquivo.
case FileMode::Append:
if (!exists)
flags |= std::fstream::trunc;
else
flags |= std::fstream::app;
break;
//Especifica que se deve abrir um arquivo existente.
//Quando o arquivo for aberto, ele deverá ser truncado
//para que seu tamanho seja zero bytes.
//Tentativa de ler um arquivo truncado retornará 0;
case FileMode::Truncate:
flags |= std::fstream::trunc;
_truncated = true;
break;
default:
break;
}
_fstream.open(path.c_str(), flags);
if (!_fstream.good())
_closed = true;
}
FileStream(String const& path){
int flags = std::fstream::in
| std::fstream::out
| std::fstream::binary;
@ -78,7 +140,7 @@ namespace xna {
_fstream.open(path.c_str(), flags);
if (!_fstream.is_open())
if (!_fstream.good())
_closed = true;
}
@ -108,18 +170,25 @@ namespace xna {
_fstream.close();
}
virtual Long Seek(Long offset, SeekOrigin const& origin, xna_error_ptr_arg) override;
virtual Int Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg) override;
virtual Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_ptr_arg) override;
virtual Int ReadByte(xna_error_ptr_arg) override;
virtual void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg) override;
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_ptr_arg) override;
virtual void WriteByte(Byte value, xna_error_ptr_arg) override;
virtual constexpr bool IsClosed() override {
return _closed;
}
virtual Long Seek(Long offset, SeekOrigin const& origin, xna_error_nullarg) override;
virtual Int Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) override;
virtual Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_nullarg) override;
virtual Int ReadByte(xna_error_nullarg) override;
virtual void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) override;
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_nullarg) override;
virtual void WriteByte(Byte value, xna_error_nullarg) override;
public:
std::streampos _filesize{ 0 };
std::fstream _fstream;
private:
std::streampos _filesize{ 0 };
bool _closed{ false };
bool _truncated{ false };
Int endOfFile() {
if (_closed)

15
framework/csharp/type.cpp Normal file
View File

@ -0,0 +1,15 @@
#include "type.hpp"
namespace xna {
size_t Type::GetHashCode() const
{
size_t seed = 0;
XnaHHashCombine(seed, fullName);
XnaHHashCombine(seed, isClass);
XnaHHashCombine(seed, isEnum);
XnaHHashCombine(seed, isValueType);
XnaHHashCombine(seed, isPrimitive);
return seed;
}
}

88
framework/csharp/type.hpp Normal file
View File

@ -0,0 +1,88 @@
#ifndef XNA_CSHARP_TYPE_HPP
#define XNA_CSHARP_TYPE_HPP
#include "../default.hpp"
#include "object.hpp"
#include <type_traits>
#include <typeinfo>
#include <map>
namespace xna {
class Type : public Object {
public:
constexpr String FullName() const { return fullName; }
constexpr bool IsClass() const { return isClass; }
constexpr bool IsEnum() const { return isEnum; }
constexpr bool IsValueType() const { return isValueType; }
constexpr bool IsPrimitive() const { return isPrimitive; }
virtual size_t GetHashCode() const;
constexpr bool operator==(const Type& other) const {
return
fullName == other.fullName
&& isClass == other.isClass
&& isEnum == other.isEnum
&& isValueType == other.isValueType
&& isPrimitive == other.isPrimitive;
}
bool operator()(Type const& t1, Type const& t2) const {
return t1.GetHashCode() < t2.GetHashCode();
}
template <class T>
friend sptr<Type> typeof();
public:
inline static auto NameOfRegisteredTypes = std::map<std::string, sptr<Type>>();
private:
String fullName;
bool isClass{ false };
bool isEnum{ false };
bool isValueType{ false };
bool isPrimitive{ false };
};
template <class T>
inline sptr<Type> typeof() {
if (std::is_arithmetic<T>::value) {
auto primitiveType = New<Type>();
primitiveType->fullName = typeid(T).name();
primitiveType->isPrimitive = true;
primitiveType->isValueType = true;
return primitiveType;
}
if (std::is_enum<T>::value) {
auto enumType = New<Type>();
enumType->fullName = typeid(T).name();
enumType->isValueType = true;
enumType->isEnum = true;
return enumType;
}
if (std::is_class<T>::value) {
auto classType = New<Type>();
classType->fullName = typeid(T).name();
classType->isClass = true;
return classType;
}
return nullptr;
}
template <class T>
inline sptr<Type> typeof(T const* object) {
return typeof<T>();
}
template <class T>
inline sptr<Type> typeof(T const& object) {
return typeof<T>();
}
}
#endif

View File

@ -165,6 +165,15 @@ namespace xna {
Stretched = 2
};
enum class FileMode {
CreateNew,
Create,
Append,
Open,
OpenOrCreate,
Truncate
};
enum class FillMode
{
WireFrame,

View File

@ -15,10 +15,14 @@ namespace xna {
class Stream;
class FileStream;
class MemoryStream;
class Object;
class Type;
//Content
class ContentManager;
class ContentReader;
class ContentTypeReader;
class ContentTypeReaderManager;
//Framework
class BoundingBox;
@ -49,6 +53,7 @@ namespace xna {
class GraphicsDeviceManager;
class IGameTime;
class IGameComponent;
class GameServiceContainer;
//Graphics
class BlendState;
@ -83,6 +88,9 @@ namespace xna {
struct GamePadState;
struct KeyboardState;
struct MouseState;
//Pointer
using PTexture2D = std::shared_ptr<Texture2D>;
}
#endif

View File

@ -1,23 +1,21 @@
#ifndef XNA_GAME_GAME_HPP
#define XNA_GAME_GAME_HPP
#include "../enums.hpp"
#include "../forward.hpp"
#include "../types.hpp"
#include "../default.hpp"
#include "time.hpp"
#include "window.hpp"
#include "../game/component.hpp"
#include "component.hpp"
#include "servicecontainer.hpp"
namespace xna {
class IGame {
public:
virtual ~IGame(){}
virtual void Exit() = 0;
virtual int Run() = 0;
virtual sptr<GameWindow> Window() = 0;
virtual sptr<GraphicsDevice> GetGraphicsDevice() = 0;
virtual sptr<GameComponentCollection> Components() = 0;
virtual sptr<GameServiceContainer> Services() = 0;
virtual sptr<ContentManager> Content() = 0;
protected:
virtual void Draw(GameTime const& gameTime) = 0;

View File

@ -0,0 +1,18 @@
#include "servicecontainer.hpp"
namespace xna {
void GameServiceContainer::AddService(Type& type, std::any& provider)
{
auto hashCode = type.GetHashCode();
services.insert({ hashCode, provider });
}
std::any GameServiceContainer::GetService(Type& serviceType)
{
auto hashCode = serviceType.GetHashCode();
return services.contains(hashCode)
? services[hashCode]
: std::any();
}
}

View File

@ -2,12 +2,19 @@
#define XNA_GAME_SERVICECONTAINER_HPP
#include "../default.hpp"
#include "../csharp/service.hpp"
#include <map>
namespace xna {
class IServiceProvider {
};
class GameServiceContainer : public IServiceProvider {
public:
void AddService(Type& type, std::any& provider);
class GameServiceContainer {
// Inherited via IServiceProvider
std::any GetService(Type& serviceType) override;
private:
std::map<size_t, std::any> services;
};
}

View File

@ -6,11 +6,11 @@
namespace xna {
class GraphicsResource {
public:
GraphicsResource(GraphicsDevice* device) : m_device(device){}
GraphicsResource(sptr<GraphicsDevice> const& device) : m_device(device){}
virtual ~GraphicsResource(){}
virtual bool Bind(GraphicsDevice* device) {
virtual bool Bind(sptr<GraphicsDevice> const& device) {
if (device == m_device)
return false;
@ -20,7 +20,7 @@ namespace xna {
}
protected:
GraphicsDevice* m_device = nullptr;
sptr<GraphicsDevice> m_device = nullptr;
};
}

View File

@ -1,7 +1,7 @@
#ifndef XNA_GRAPHICS_RENDERTARGET_HPP
#define XNA_GRAPHICS_RENDERTARGET_HPP
#include "texture.hpp"
#include "../default.hpp"
namespace xna {
@ -9,8 +9,8 @@ namespace xna {
public:
virtual ~IRenderTarget2D(){}
virtual bool Initialize(GraphicsDevice& device) = 0;
virtual bool Apply(GraphicsDevice& device) = 0;
virtual bool Initialize(xna_error_nullarg) = 0;
virtual bool Apply(xna_error_nullarg) = 0;
};
}

View File

@ -1,9 +1,7 @@
#ifndef XNA_GRAPHICS_TEXTURE_HPP
#define XNA_GRAPHICS_TEXTURE_HPP
#include "../forward.hpp"
#include "../types.hpp"
#include "../enums.hpp"
#include "../default.hpp"
namespace xna {
class Texture {
@ -14,6 +12,8 @@ namespace xna {
virtual ~ITexture2D(){}
virtual Int Width() const = 0;
virtual Int Height() const = 0;
virtual Rectangle Bounds() const = 0;
virtual bool Initialize(xna_error_nullarg) = 0;
};
}

View File

@ -2,6 +2,7 @@
#define XNA_HELPERS_HPP
#include <string>
#include <utility>
namespace xna {
inline std::wstring XnaHToWString(const std::string& str)
@ -21,6 +22,12 @@ namespace xna {
wcstombs_s(&size, &str[0], str.size() + 1, wstr.c_str(), wstr.size());
return str;
}
template <class T>
static constexpr void XnaHHashCombine(std::size_t& seed, const T& v) {
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
}
#endif

View File

@ -45,7 +45,7 @@ namespace xna {
switch (format)
{
case SurfaceFormat::Color://21
return DXGI_FORMAT_B8G8R8A8_UNORM;
return DXGI_FORMAT_R8G8B8A8_UNORM;
case SurfaceFormat::Bgr565: //23
return DXGI_FORMAT_B5G6R5_UNORM;
case SurfaceFormat::Bgra5551://25
@ -92,6 +92,7 @@ namespace xna {
static constexpr SurfaceFormat ConvertDXGIFORMATToSurface(DXGI_FORMAT format) {
switch (format)
{
case DXGI_FORMAT_R8G8B8A8_UNORM:
case DXGI_FORMAT_B8G8R8A8_UNORM:
return SurfaceFormat::Color;
case DXGI_FORMAT_B5G6R5_UNORM:

View File

@ -21,7 +21,7 @@ namespace xna {
class BlendState : public IBlendState, public GraphicsResource {
public:
BlendState(GraphicsDevice* device) : GraphicsResource(device) {};
BlendState(sptr<GraphicsDevice> const& device) : GraphicsResource(device) {};
virtual ~BlendState() override {
if (dxBlendState) {

View File

@ -0,0 +1,40 @@
#ifndef XNA_PLATFORM_CONTENTREADERS_TEXTURE2D_HPP
#define XNA_PLATFORM_CONTENTREADERS_TEXTURE2D_HPP
#include "../../content/manager.hpp"
#include "../../content/reader.hpp"
#include "../../csharp/type.hpp"
#include "../texture-dx.hpp"
namespace xna {
class Texture2DReader : public ContentTypeReaderT<PTexture2D> {
public:
Texture2DReader() : ContentTypeReaderT(typeof<Texture2D>()){}
PTexture2D Read(ContentReader& input, PTexture2D& existingInstance) override{
const auto format = static_cast<SurfaceFormat>(input.ReadInt32());
const auto width = input.ReadInt32();
const auto height = input.ReadInt32();
const auto mipMaps = input.ReadInt32();
auto a_device = ContentManager::Services()->GetService(*typeof<GraphicsDevice>());
sptr<GraphicsDevice> device = nullptr;
if(a_device.has_value())
device = std::any_cast<sptr<GraphicsDevice>>(a_device);
auto texture2D = New<Texture2D>(device, width, height, mipMaps, format);
for (size_t level = 0; level < mipMaps; ++level) {
auto elementCount = input.ReadInt32();
std::vector<Byte> data = input.ReadByteBuffer(elementCount);
texture2D->SetData(static_cast<Int>(level), nullptr, data, 0, elementCount);
}
return texture2D;
}
};
}
#endif

View File

@ -8,7 +8,7 @@
namespace xna {
class DepthStencilState : public IDepthStencilState, public GraphicsResource {
public:
DepthStencilState(GraphicsDevice* device) : GraphicsResource(device) {
DepthStencilState(sptr<GraphicsDevice> const& device) : GraphicsResource(device) {
dxDescription = defaultDesc();
}

View File

@ -22,6 +22,8 @@ namespace xna {
bool GraphicsDevice::Initialize(GameWindow& gameWindow) {
reset();
auto _this = shared_from_this();
if (!createDevice()) return false;
@ -41,16 +43,17 @@ namespace xna {
_backgroundColor[2] = GetBValue(color) / 255.0f;
_backgroundColor[3] = 1.0f;
_swapChain = New<xna::SwapChain>(this);
_swapChain = New<xna::SwapChain>(_this);
_swapChain->Initialize();
hr = _factory->MakeWindowAssociation(gameWindow.WindowHandle(), DXGI_MWA_NO_ALT_ENTER);
if (FAILED(hr)) return false;
_renderTarget2D = New<RenderTarget2D>();
if (!_renderTarget2D->Initialize(*this)) return false;
_renderTarget2D = New<RenderTarget2D>(_this);
if (!_renderTarget2D->Initialize())
return false;
_renderTarget2D->Apply(*this);
_renderTarget2D->Apply();
D3D11_VIEWPORT view{};
view.TopLeftX = _viewport.X;
@ -63,7 +66,7 @@ namespace xna {
_context->RSSetViewports(1, &view);
_blendState = BlendState::NonPremultiplied();
_blendState->Bind(this);
_blendState->Bind(_this);
_blendState->Apply();
return true;

View File

@ -14,7 +14,7 @@
#include "presentparameters-dx.hpp"
namespace xna {
class GraphicsDevice : public IGraphicsDevice {
class GraphicsDevice : public IGraphicsDevice, public std::enable_shared_from_this<GraphicsDevice> {
public:
GraphicsDevice();
GraphicsDevice(GraphicsDeviceInformation const& info);

View File

@ -1,9 +1,33 @@
//DirectX
#include "dxgi.h"
#include "d3d11.h"
#include <d3d11_1.h>
#include <d3d11_2.h>
//HSLS
#include <d3dcompiler.h>
//DirectXTK
#include <DirectXMath.h>
#include <Audio.h>
#include <BufferHelpers.h>
#include <CommonStates.h>
#include <DDSTextureLoader.h>
#include <DirectXHelpers.h>
#include <Effects.h>
#include <GamePad.h>
#include <GeometricPrimitive.h>
#include <GraphicsMemory.h>
#include <Keyboard.h>
#include <Model.h>
#include <Mouse.h>
#include <PostProcess.h>
#include <PrimitiveBatch.h>
#include <ScreenGrab.h>
#include <SimpleMath.h>
#include <SpriteBatch.h>
#include <SpriteFont.h>
#include <VertexTypes.h>
#include <WICTextureLoader.h>
//Windows
#define NOMINMAX
#include <Windows.h>
#include <Windows.Foundation.h>

View File

@ -1,4 +1,4 @@
#define NOMINMAX
#include "../csharp/type.hpp"
#include "../game/time.hpp"
#include "audioengine-dx.hpp"
#include "device-dx.hpp"
@ -8,12 +8,14 @@
#include "keyboard-dx.hpp"
#include "mouse-dx.hpp"
#include "window-dx.hpp"
#include <Windows.h>
namespace xna {
Game::Game() {
services = New<GameServiceContainer>();
_contentManager = New<ContentManager>("", services);
_gameWindow = New<GameWindow>();
_gameWindow->Color(255, 155, 55);
_gameWindow->Color(146, 150, 154);
_gameWindow->Title("XN65");
_gameWindow->Size(
GraphicsDeviceManager::DefaultBackBufferWidth,
@ -22,15 +24,14 @@ namespace xna {
_gameComponents = New<GameComponentCollection>();
}
void Game::Exit()
{
void Game::Exit() {
_gameWindow->Close();
}
int Game::Run() {
Initialize();
if (_graphicsDevice == nullptr) {
if (graphicsDevice == nullptr) {
MessageBox(nullptr, "O dispositivo gráfico não foi inicializado corretamente", "XN65", MB_OK);
return EXIT_FAILURE;
}
@ -40,21 +41,21 @@ namespace xna {
void Game::Initialize() {
Keyboard::Initialize();
Mouse::Initialize();
Mouse::Initialize();
//initialize é requisito para GamePad
#if (_WIN32_WINNT >= 0x0A00 /*_WIN32_WINNT_WIN10*/)
Microsoft::WRL::Wrappers::RoInitializeWrapper initialize(RO_INIT_MULTITHREADED);
if (FAILED(initialize))
MessageBox(nullptr, "Ocorreu um erro ao executar Microsoft::WRL::Wrappers::RoInitializeWrapper. O GamePad não foi inicializado corretamente.", "XN65", MB_OK);
GamePad.Initialize();
//CoInitializeEx é requisito para AudioEngine
const auto hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
{
MessageBox(nullptr, "Ocorreu um erro ao chamar Microsoft::WRL::Wrappers::RoInitializeWrapper.", "XN65", MB_OK);
}
#else
HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
if (FAILED(hr))
MessageBox(nullptr, "Ocorreu um erro ao executar CoInitializeEx. O AudioEngine não foi inicializado corretamente.", "XN65", MB_OK);
{
MessageBox(nullptr, "Ocorreu um erro ao chamar CoInitializeEx.", "XN65", MB_OK);
}
#endif
_audioEngine = New<AudioEngine>();
@ -84,7 +85,7 @@ namespace xna {
_drawableGameComponents.clear();
}
_graphicsDevice->Present();
graphicsDevice->Present();
}
void Game::Update(GameTime const& gameTime) {
@ -142,5 +143,5 @@ namespace xna {
});
Draw(_currentGameTime);
}
}
}

View File

@ -1,65 +1,52 @@
#ifndef XNA_PLATFORM_GAME_DX_HPP
#define XNA_PLATFORM_GAME_DX_HPP
#include "../content/manager.hpp"
#include "../default.hpp"
#include "../game/game.hpp"
#include "dxheaders.hpp"
#include "dx/StepTimer.hpp"
#include "dxheaders.hpp"
namespace xna {
class Game : public IGame {
public:
Game();
Game();
virtual ~Game() override {
}
virtual void Exit() override;
virtual int Run() override;
void Exit() override;
int Run() override;
virtual sptr<GameWindow> Window() override {
return _gameWindow;
}
virtual sptr<GraphicsDevice> GetGraphicsDevice() override {
return _graphicsDevice;
}
sptr<GameComponentCollection> Components() override {
return _gameComponents;
}
constexpr void EnableGameComponents(bool value) {
_enabledGameComponents = value;
}
inline sptr<GameWindow> Window() override { return _gameWindow; }
inline sptr<GraphicsDevice> GetGraphicsDevice() override { return graphicsDevice; }
inline sptr<GameComponentCollection> Components() override { return _gameComponents; }
inline sptr<GameServiceContainer> Services() override { return services; }
inline sptr<ContentManager> Content() override { return _contentManager; }
constexpr void EnableGameComponents(bool value) { _enabledGameComponents = value; }
protected:
virtual void Draw(GameTime const& gameTime) override;
virtual void Draw(GameTime const& gameTime) override;
virtual void Initialize() override;
virtual void LoadContent() override{}
virtual void LoadContent() override{}
virtual void Update(GameTime const& gameTime) override;
public:
sptr<GraphicsDevice> _graphicsDevice{ nullptr };
sptr<GraphicsDevice> graphicsDevice = nullptr;
protected:
sptr<GameWindow> _gameWindow{ nullptr };
sptr<AudioEngine> _audioEngine = nullptr;
GameTime _currentGameTime{};
DX::StepTimer _stepTimer;
private:
int startLoop();
void step();
protected:
sptr<GameServiceContainer> services = nullptr;
private:
sptr<GameComponentCollection> _gameComponents = nullptr;
sptr<GameWindow> _gameWindow{ nullptr };
sptr<AudioEngine> _audioEngine = nullptr;
sptr<ContentManager> _contentManager;
std::vector<sptr<IGameComponent>> _drawableGameComponents;
size_t _drawableGameComponentsCount{ 0 };
bool _enabledGameComponents{ false };
bool _enabledGameComponents{ false };
GameTime _currentGameTime{};
DX::StepTimer _stepTimer{};
int startLoop();
void step();
};
}

View File

@ -33,10 +33,10 @@ namespace xna {
}
bool GraphicsDeviceManager::ToggleFullScreen() {
if (!_game || !_game->_graphicsDevice || !_game->_graphicsDevice->_swapChain)
if (!_game || !_game->graphicsDevice || !_game->graphicsDevice->_swapChain)
return false;
auto& swap = _game->_graphicsDevice->_swapChain;
auto& swap = _game->graphicsDevice->_swapChain;
BOOL state = false;
auto hr = swap->dxSwapChain->GetFullscreenState(&state, nullptr);
@ -110,7 +110,7 @@ namespace xna {
return false;
}
_game->_graphicsDevice = _device;
_game->graphicsDevice = _device;
return true;
}

View File

@ -0,0 +1,64 @@
#include "init-dx.hpp"
#include "../csharp/type.hpp"
#include "texture-dx.hpp"
#include "content-readers/texture2Dreader-dx.hpp"
#include "../content/typereadermanager.hpp"
#include "../content/defaultreaders.hpp"
namespace xna {
void InitPlatform::InitRegisteredTypes()
{
insertRegisteredReader<ObjectReader>("ObjecReader");
insertRegisteredReader<BooleanReader>("BooleanReader");
insertRegisteredReader<ByteReader>("ByteReader");
insertRegisteredReader<CharReader>("CharReader");
insertRegisteredReader<ColorReader>("ColorReader");
insertRegisteredReader<DoubleReader>("DoubleReader");
insertRegisteredReader<Int16Reader>("Int16Reader");
insertRegisteredReader<Int32Reader>("Int32Reader");
insertRegisteredReader<Int64Reader>("Int64Reader");
insertRegisteredReader<MatrixReader>("MatrixReader");
insertRegisteredReader<PointReader>("PointReader");
insertRegisteredReader<QuaternionReader>("QuaternionReader");
insertRegisteredReader<RectangleReader>("RectangleReader");
insertRegisteredReader<SByteReader>("SByteReader");
insertRegisteredReader<SingleReader>("SingleReader");
insertRegisteredReader<TimeSpanReader>("TimeSpanReader");
insertRegisteredReader<UInt16Reader>("UInt16Reader");
insertRegisteredReader<UInt32Reader>("UInt32Reader");
insertRegisteredReader<UInt64Reader>("UInt64Reader");
insertRegisteredReader<Vector2Reader>("Vector2Reader");
insertRegisteredReader<Vector3Reader>("Vector3Reader");
insertRegisteredReader<Vector4Reader>("Vector4Reader");
insertRegisteredReader<Texture2DReader>("Texture2DReader");
}
void InitPlatform::InitActivadors()
{
insertActivadorReader<ObjectReader>();
insertActivadorReader<BooleanReader>();
insertActivadorReader<ByteReader>();
insertActivadorReader<CharReader>();
insertActivadorReader<ColorReader>();
insertActivadorReader<DoubleReader>();
insertActivadorReader<Int16Reader>();
insertActivadorReader<Int32Reader>();
insertActivadorReader<Int64Reader>();
insertActivadorReader<MatrixReader>();
insertActivadorReader<PointReader>();
insertActivadorReader<QuaternionReader>();
insertActivadorReader<RectangleReader>();
insertActivadorReader<SByteReader>();
insertActivadorReader<SingleReader>();
insertActivadorReader<TimeSpanReader>();
insertActivadorReader<UInt16Reader>();
insertActivadorReader<UInt32Reader>();
insertActivadorReader<UInt64Reader>();
insertActivadorReader<Vector2Reader>();
insertActivadorReader<Vector3Reader>();
insertActivadorReader<Vector4Reader>();
insertActivadorReader<Texture2DReader>();
}
}

View File

@ -0,0 +1,36 @@
#ifndef XNA_PLATFORM_INIT_HPP
#define XNA_PLATFORM_INIT_HPP
#include "../default.hpp"
#include "../csharp/type.hpp"
#include "../content/typereadermanager.hpp"
namespace xna {
struct InitPlatform {
static void Init() {
InitRegisteredTypes();
InitActivadors();
}
static void InitRegisteredTypes();
static void InitActivadors();
private:
template <typename T>
static void insertRegisteredReader(String const& readerName) {
const auto reader = typeof<T>();
Type::NameOfRegisteredTypes.insert({ "xna::" + readerName, reader });
Type::NameOfRegisteredTypes.insert({ "Microsoft.Xna.Framework.Content." + readerName, reader });
}
template <typename T>
static void insertActivadorReader() {
ContentTypeReaderActivador::SetActivador(typeof<T>(), []() -> sptr<ContentTypeReader> {
auto obj = New <T>();
return reinterpret_pointer_cast<ContentTypeReader>(obj);
});
}
};
}
#endif

View File

@ -8,7 +8,7 @@
namespace xna {
class RasterizerState : public IRasterizerState, public GraphicsResource {
public:
RasterizerState(GraphicsDevice* device) : GraphicsResource(device){}
RasterizerState(sptr<GraphicsDevice> const& device) : GraphicsResource(device){}
virtual ~RasterizerState() override {
if (dxRasterizerState) {

View File

@ -4,30 +4,39 @@
#include "device-dx.hpp"
namespace xna {
bool RenderTarget2D::Initialize(GraphicsDevice& device) {
if (!device._device)
bool RenderTarget2D::Initialize(xna_error_ptr_arg) {
if (!m_device || !m_device->_device) {
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
return false;
if (_texture2D) {
_texture2D->Release();
_texture2D = nullptr;
}
if (!device._swapChain->GetBackBuffer(_texture2D))
if (dxTexture2D) {
dxTexture2D->Release();
dxTexture2D = nullptr;
}
if (!m_device->_swapChain->GetBackBuffer(dxTexture2D))
return false;
auto& dxdevice = device._device;
auto& dxdevice = m_device->_device;
const auto hr = dxdevice->CreateRenderTargetView(_texture2D, NULL, &_renderTargetView);
const auto hr = dxdevice->CreateRenderTargetView(dxTexture2D, NULL, &_renderTargetView);
if (FAILED(hr))
if (FAILED(hr)) {
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
return false;
}
return true;
}
bool RenderTarget2D::Apply(GraphicsDevice& device) {
auto& context = device._context;
bool RenderTarget2D::Apply(xna_error_ptr_arg) {
if (!m_device || !m_device->_context) {
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
return false;
}
auto& context = m_device->_context;
context->OMSetRenderTargets(1, &_renderTargetView, nullptr);
return true;
}

View File

@ -9,6 +9,8 @@
namespace xna {
class RenderTarget2D : public IRenderTarget2D, public Texture2D {
public:
RenderTarget2D(sptr<GraphicsDevice> const& device) : Texture2D(device){}
virtual ~RenderTarget2D() override {
if (_renderTargetView) {
_renderTargetView->Release();
@ -16,8 +18,8 @@ namespace xna {
}
}
virtual bool Initialize(GraphicsDevice& device) override;
virtual bool Apply(GraphicsDevice& device) override;
virtual bool Initialize(xna_error_nullarg) override;
virtual bool Apply(xna_error_nullarg) override;
public:
ID3D11RenderTargetView* _renderTargetView = nullptr;

View File

@ -8,7 +8,7 @@
namespace xna {
class SamplerState : public ISamplerState, public GraphicsResource {
public:
SamplerState(GraphicsDevice* device) : GraphicsResource(device) {
SamplerState(sptr<GraphicsDevice> const& device) : GraphicsResource(device) {
_description.MaxAnisotropy = 4;
}

View File

@ -8,7 +8,7 @@
namespace xna {
class Shader : public IShader, public GraphicsResource {
public:
Shader(GraphicsDevice* device) : GraphicsResource(device){}
Shader(sptr<GraphicsDevice> const& device) : GraphicsResource(device){}
virtual ~Shader() override {}
@ -19,7 +19,7 @@ namespace xna {
class VertexShader : public Shader {
public:
VertexShader(GraphicsDevice* device) : Shader(device){}
VertexShader(sptr<GraphicsDevice> const& device) : Shader(device){}
virtual ~VertexShader() override {
if (_vertexShader) {
@ -36,7 +36,7 @@ namespace xna {
class PixelShader : public Shader {
public:
PixelShader(GraphicsDevice* device) : Shader(device) {}
PixelShader(sptr<GraphicsDevice> const& device) : Shader(device) {}
virtual ~PixelShader() override {
if (_pixelShader) {

View File

@ -63,7 +63,7 @@ namespace xna {
if (!_dxspriteBatch)
return;
if (!texture._textureView)
if (!texture.dxShaderResource)
return;
const auto _position = XMFLOAT2(position.X, position.Y);
@ -71,7 +71,7 @@ namespace xna {
XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
_dxspriteBatch->Draw(
texture._textureView,
texture.dxShaderResource,
_position,
_color
);
@ -81,7 +81,7 @@ namespace xna {
if (!_dxspriteBatch)
return;
if (!texture._textureView)
if (!texture.dxShaderResource)
return;
const auto _position = XMFLOAT2(position.X, position.Y);
@ -98,7 +98,7 @@ namespace xna {
};
_dxspriteBatch->Draw(
texture._textureView,
texture.dxShaderResource,
_position,
sourceRectangle ? &_sourceRect : nullptr,
_color);
@ -108,7 +108,7 @@ namespace xna {
if (!_dxspriteBatch)
return;
if (!texture._textureView)
if (!texture.dxShaderResource)
return;
const auto _position = XMFLOAT2(position.X, position.Y);
@ -128,7 +128,7 @@ namespace xna {
const DxSpriteEffects _effects = static_cast<DxSpriteEffects>(effects);
_dxspriteBatch->Draw(
texture._textureView,
texture.dxShaderResource,
_position,
sourceRectangle ? &_sourceRect : nullptr,
_color,
@ -143,7 +143,7 @@ namespace xna {
if (!_dxspriteBatch)
return;
if (!texture._textureView)
if (!texture.dxShaderResource)
return;
const auto _position = XMFLOAT2(position.X, position.Y);
@ -164,7 +164,7 @@ namespace xna {
const XMFLOAT2 _scale = { scale.X, scale.Y };
_dxspriteBatch->Draw(
texture._textureView,
texture.dxShaderResource,
_position,
sourceRectangle ? &_sourceRect : nullptr,
_color,
@ -179,7 +179,7 @@ namespace xna {
if (!_dxspriteBatch)
return;
if (!texture._textureView)
if (!texture.dxShaderResource)
return;
RECT _destinationRect{};
@ -191,14 +191,14 @@ namespace xna {
const auto v4 = color.ToVector4();
const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
_dxspriteBatch->Draw(texture._textureView, _destinationRect, _color);
_dxspriteBatch->Draw(texture.dxShaderResource, _destinationRect, _color);
}
void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, Rectangle const* sourceRectangle, Color const& color) {
if (!_dxspriteBatch)
return;
if (!texture._textureView)
if (!texture.dxShaderResource)
return;
RECT _destinationRect{};
@ -219,14 +219,14 @@ namespace xna {
_sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height;
};
_dxspriteBatch->Draw(texture._textureView, _destinationRect, sourceRectangle ? &_sourceRect : nullptr, _color);
_dxspriteBatch->Draw(texture.dxShaderResource, _destinationRect, sourceRectangle ? &_sourceRect : nullptr, _color);
}
void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, Rectangle const* sourceRectangle, Color const& color, float rotation, Vector2 const& origin, SpriteEffects effects, float layerDepth) {
if (!_dxspriteBatch)
return;
if (!texture._textureView)
if (!texture.dxShaderResource)
return;
RECT _destinationRect{};
@ -251,7 +251,7 @@ namespace xna {
const auto _effects = static_cast<DxSpriteEffects>(effects);
_dxspriteBatch->Draw(
texture._textureView,
texture.dxShaderResource,
_destinationRect,
sourceRectangle ? &_sourceRect : nullptr,
_color,

View File

@ -9,7 +9,7 @@
namespace xna {
class SwapChain : public ISwapChain, public GraphicsResource {
public:
SwapChain(GraphicsDevice* device): GraphicsResource(device){}
SwapChain(sptr<GraphicsDevice> const& device): GraphicsResource(device){}
virtual ~SwapChain() override {
if (dxSwapChain) {

View File

@ -1,15 +1,12 @@
#include "texture-dx.hpp"
#include "WICTextureLoader.h"
#include "device-dx.hpp"
#include "../helpers.hpp"
namespace xna {
Texture2D::Texture2D() {
}
#include "adapter-dx.hpp"
namespace xna {
sptr<Texture2D> Texture2D::FromStream(GraphicsDevice& device, String const& fileName, xna_error_ptr_arg)
{
auto texture2d = New<Texture2D>();
auto _this = device.shared_from_this();
auto texture2d = New<Texture2D>(_this);
ID3D11Resource* resource = nullptr;
auto wstr = XnaHToWString(fileName);
@ -18,7 +15,7 @@ namespace xna {
device._context,
wstr.c_str(),
&resource,
&texture2d->_textureView,
&texture2d->dxShaderResource,
0U);
if (FAILED(result))
@ -33,7 +30,7 @@ namespace xna {
return nullptr;
}
result = resource->QueryInterface(IID_ID3D11Texture2D, (void**)&texture2d->_texture2D);
result = resource->QueryInterface(IID_ID3D11Texture2D, (void**)&texture2d->dxTexture2D);
if (FAILED(result)) {
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
@ -47,12 +44,284 @@ namespace xna {
}
D3D11_TEXTURE2D_DESC desc;
texture2d->_texture2D->GetDesc(&desc);
texture2d->_description = desc;
texture2d->dxTexture2D->GetDesc(&desc);
texture2d->dxDescription = desc;
resource->Release();
resource = nullptr;
return texture2d;
}
bool Texture2D::Initialize(xna_error_ptr_arg)
{
if (dxTexture2D) {
xna_error_apply(err, XnaErrorCode::WARNING_INITIALIZED_RESOURCE);
return false;
}
if (!m_device || !m_device->_device) {
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
return false;
}
auto hr = m_device->_device->CreateTexture2D(&dxDescription, nullptr, &dxTexture2D);
if (FAILED(hr)) {
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
return false;
}
ID3D11Resource* resource = nullptr;
hr = dxTexture2D->QueryInterface(IID_ID3D11Resource, (void**)&resource);
if (FAILED(hr)) {
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
return false;
}
hr = m_device->_device->CreateShaderResourceView(resource, &dxShaderDescription, &dxShaderResource);
if (resource) {
resource->Release();
resource = nullptr;
}
if (FAILED(hr)) {
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
return false;
}
return true;
}
Texture2D::Texture2D(sptr<GraphicsDevice> const& device, size_t width, size_t height) : GraphicsResource(device) {
setDefaultDesc();
dxDescription.Width = static_cast<UINT>(width);
dxDescription.Height = static_cast<UINT>(height);
}
Texture2D::Texture2D(sptr<GraphicsDevice> const& device) : GraphicsResource(device) {
setDefaultDesc();
}
Texture2D::Texture2D(sptr<GraphicsDevice> const& device, size_t width, size_t height, size_t mipMap, SurfaceFormat format) : GraphicsResource(device)
{
setDefaultDesc();
dxDescription.Width = static_cast<UINT>(width);
dxDescription.Height = static_cast<UINT>(height);
dxDescription.MipLevels = static_cast<UINT>(mipMap);
dxDescription.Format = GraphicsAdapter::ConvertSurfaceToDXGIFORMAT(format);
}
void Texture2D::SetData(std::vector<Uint> const& data, size_t startIndex, size_t elementCount, xna_error_ptr_arg)
{
if (!m_device || !m_device->_device || !m_device->_context) {
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
return;
}
internalSetData(data.data(), err);
}
void Texture2D::SetData(std::vector<Byte> const& data, size_t startIndex, size_t elementCount, xna_error_ptr_arg)
{
if (!m_device || !m_device->_device || !m_device->_context) {
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
return;
}
std::vector<UINT> finalData(elementCount / 4);
auto fIndex = 0;
for (size_t i = startIndex; i < elementCount; ++i) {
const auto& r = data[i];
const auto& g = data[++i];
const auto& b = data[++i];
const auto& a = data[++i];
finalData[fIndex] = Color(r, g, b, a);
++fIndex;
}
internalSetData(finalData.data(), err);
}
void Texture2D::SetData(Int level, Rectangle* rect, std::vector<Byte> const& data, size_t startIndex, size_t elementCount, xna_error_ptr_arg)
{
if (!m_device || !m_device->_device || !m_device->_context) {
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
return;
}
std::vector<UINT> finalData(elementCount / 4);
auto fIndex = 0;
for (size_t i = startIndex; i < elementCount; ++i) {
const auto& r = data[i];
const auto& g = data[++i];
const auto& b = data[++i];
const auto& a = data[++i];
finalData[fIndex] = Color(r, g, b, a);
++fIndex;
}
if (!dxTexture2D) {
auto hr = m_device->_device->CreateTexture2D(&dxDescription, nullptr, &dxTexture2D);
if (FAILED(hr)) {
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
return;
}
}
ID3D11Resource* resource = nullptr;
auto hr = dxTexture2D->QueryInterface(IID_ID3D11Resource, (void**)&resource);
if (FAILED(hr)) {
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
return;
}
D3D11_BOX box{};
if (rect) {
box.left = rect->X;
box.right = rect->X + rect->Width;
box.top = rect->Y;
box.bottom = rect->Y + rect->Height;
box.back = level;
box.front = 0;
}
m_device->_context->UpdateSubresource(resource, 0, rect ? &box : nullptr, finalData.data(), dxDescription.Width * R8G8B8A8U_BYTE_SIZE, 0);
if (dxShaderResource) {
dxShaderResource->Release();
dxShaderResource = nullptr;
}
dxShaderDescription.Texture2D.MipLevels = dxDescription.MipLevels;
hr = m_device->_device->CreateShaderResourceView(resource, &dxShaderDescription, &dxShaderResource);
if (resource) {
resource->Release();
resource = nullptr;
}
if (FAILED(hr)) {
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
return;
}
dxTexture2D->GetDesc(&dxDescription);
}
void Texture2D::SetData(std::vector<Color> const& data, size_t startIndex, size_t elementCount, xna_error_ptr_arg)
{
if (!m_device || !m_device->_device || !m_device->_context) {
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
return;
}
std::vector<UINT> finalData(elementCount);
auto finalDataIndex = 0;
for (size_t i = startIndex; i < elementCount; ++i) {
finalData[finalDataIndex] = static_cast<UINT>(data[i]);
++finalDataIndex;
}
internalSetData(finalData.data(), err);
}
sptr<Texture2D> Texture2D::FromMemory(GraphicsDevice& device, std::vector<Byte> const& data, xna_error_ptr_arg)
{
auto _this = device.shared_from_this();
auto texture2d = New<Texture2D>(_this);
ID3D11Resource* resource = nullptr;
auto hr = DirectX::CreateWICTextureFromMemory(
device._device,
device._context,
data.data(),
data.size(),
&resource,
&texture2d->dxShaderResource);
if (FAILED(hr))
{
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
if (resource) {
resource->Release();
resource = nullptr;
}
return nullptr;
}
hr = resource->QueryInterface(IID_ID3D11Texture2D, (void**)&texture2d->dxTexture2D);
if (FAILED(hr)) {
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
if (resource) {
resource->Release();
resource = nullptr;
}
return nullptr;
}
D3D11_TEXTURE2D_DESC desc;
texture2d->dxTexture2D->GetDesc(&desc);
texture2d->dxDescription = desc;
resource->Release();
resource = nullptr;
return texture2d;
}
void Texture2D::internalSetData(UINT const* data, xna_error_ptr_arg)
{
if (!dxTexture2D) {
auto hr = m_device->_device->CreateTexture2D(&dxDescription, nullptr, &dxTexture2D);
if (FAILED(hr)) {
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
return;
}
}
ID3D11Resource* resource = nullptr;
auto hr = dxTexture2D->QueryInterface(IID_ID3D11Resource, (void**)&resource);
if (FAILED(hr)) {
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
return;
}
m_device->_context->UpdateSubresource(resource, 0, nullptr, data, dxDescription.Width * R8G8B8A8U_BYTE_SIZE, 0);
if (dxShaderResource) {
dxShaderResource->Release();
dxShaderResource = nullptr;
}
dxShaderDescription.Texture2D.MipLevels = dxDescription.MipLevels;
hr = m_device->_device->CreateShaderResourceView(resource, &dxShaderDescription, &dxShaderResource);
if (resource) {
resource->Release();
resource = nullptr;
}
if (FAILED(hr)) {
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
return;
}
dxTexture2D->GetDesc(&dxDescription);
}
}

View File

@ -1,44 +1,84 @@
#ifndef XNA_PLATFORM_TEXTURE_DX_HPP
#define XNA_PLATFORM_TEXTURE_DX_HPP
#include "../common/rectangle.hpp"
#include "../graphics/gresource.hpp"
#include "../graphics/texture.hpp"
#include "dxgi.h"
#include "d3d11.h"
#include "../xnaerror.hpp"
#include "dxheaders.hpp"
#include "device-dx.hpp"
namespace xna {
class Texture2D : public ITexture2D {
class Texture2D : public ITexture2D, public GraphicsResource {
public:
Texture2D();
Texture2D() : GraphicsResource(nullptr){
setDefaultDesc();
}
Texture2D(sptr<GraphicsDevice> const& device);
Texture2D(sptr<GraphicsDevice> const& device, size_t width, size_t height);
Texture2D(sptr<GraphicsDevice> const& device, size_t width, size_t height, size_t mipMap, SurfaceFormat format);
virtual ~Texture2D() override {
if (_texture2D) {
_texture2D->Release();
_texture2D = nullptr;
if (dxTexture2D) {
dxTexture2D->Release();
dxTexture2D = nullptr;
}
if (_textureView) {
_textureView->Release();
_textureView = nullptr;
if (dxShaderResource) {
dxShaderResource->Release();
dxShaderResource = nullptr;
}
}
virtual constexpr Int Width() const override {
return _description.Width;
return dxDescription.Width;
}
virtual constexpr Int Height() const override {
return _description.Height;
return dxDescription.Height;
}
static sptr<Texture2D> FromStream(GraphicsDevice& device, String const& fileName, xna_error_nullarg);
constexpr Rectangle Bounds() const override {
return { 0, 0, static_cast<Int>(dxDescription.Width), static_cast<Int>(dxDescription.Height) };
}
bool Initialize(xna_error_nullarg) override;
void SetData(std::vector<Color> const& data, size_t startIndex = 0, size_t elementCount = 0, xna_error_nullarg);
void SetData(std::vector<Uint> const& data, size_t startIndex = 0, size_t elementCount = 0, xna_error_nullarg);
void SetData(std::vector<Byte> const& data, size_t startIndex = 0, size_t elementCount = 0, xna_error_nullarg);
void SetData(Int level, Rectangle* rect, std::vector<Byte> const& data, size_t startIndex, size_t elementCount, xna_error_nullarg);
static sptr<Texture2D> FromStream(GraphicsDevice& device, String const& fileName, xna_error_nullarg);
static sptr<Texture2D> FromMemory(GraphicsDevice& device, std::vector<Byte> const& data, xna_error_nullarg);
public:
ID3D11Texture2D* _texture2D{nullptr};
ID3D11ShaderResourceView* _textureView{ nullptr };
D3D11_TEXTURE2D_DESC _description{};
};
ID3D11Texture2D* dxTexture2D{ nullptr };
ID3D11ShaderResourceView* dxShaderResource{ nullptr };
D3D11_SUBRESOURCE_DATA dxSubResource{};
D3D11_TEXTURE2D_DESC dxDescription{};
D3D11_SHADER_RESOURCE_VIEW_DESC dxShaderDescription{};
private:
static constexpr int R8G8B8A8U_BYTE_SIZE = 4;
void setDefaultDesc() {
dxDescription.MipLevels = 1;
dxDescription.ArraySize = 1;
dxDescription.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
dxDescription.SampleDesc.Count = 1;
dxDescription.Usage = D3D11_USAGE_DEFAULT;
dxDescription.BindFlags = D3D11_BIND_SHADER_RESOURCE;
dxShaderDescription.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
dxShaderDescription.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
dxShaderDescription.Texture2D.MipLevels = dxDescription.MipLevels;
dxShaderDescription.Texture2D.MostDetailedMip = 0;
}
void internalSetData(UINT const* data, xna_error_nullarg);
};
}
#endif

View File

@ -44,6 +44,7 @@ namespace xna {
constexpr double DoubleMinValue = std::numeric_limits<double>::min();
using String = std::string;
using WString = std::wstring;
template <typename T>
using sptr = std::shared_ptr<T>;

View File

@ -9,28 +9,26 @@ using namespace xna;
namespace xna {
class Game1 : public Game {
public:
Game1() {
Game1() : Game() {
auto _game = reinterpret_cast<Game*>(this);
graphics = New<GraphicsDeviceManager>(_game);
graphics->PreferredBackBufferWidth(1280);
graphics->PreferredBackBufferHeight(720);
contentManager = New<ContentManager>("Content");
//const auto s = contentManager->_path.string();
// const auto current = std::filesystem::current_path();
auto s = contentManager->OpenStream("file");
Content()->RootDirectory("Content");
}
void Initialize() override {
graphics->Initialize();
std::any device = graphicsDevice;
services->AddService(*typeof<GraphicsDevice>(), device);
Game::Initialize();
}
void LoadContent() override {
spriteBatch = New<SpriteBatch>(*_graphicsDevice);
spriteBatch = New<SpriteBatch>(*graphicsDevice);
XnaErrorCode err;
texture = Texture2D::FromStream(*_graphicsDevice, "D:\\sprite.jpg", &err);
texture = Content()->Load<PTexture2D>("idle");
Game::LoadContent();
}
@ -43,10 +41,10 @@ namespace xna {
}
void Draw(GameTime const& gameTime) override {
_graphicsDevice->Clear(Colors::CornflowerBlue);
graphicsDevice->Clear(Colors::CornflowerBlue);
spriteBatch->Begin();
spriteBatch->Draw(*texture, position, Colors::White);
spriteBatch->Draw(*texture, Vector2(10, 10), Colors::White);
spriteBatch->End();
Game::Draw(gameTime);
@ -55,20 +53,14 @@ namespace xna {
private:
sptr<GraphicsDeviceManager> graphics = nullptr;
sptr<SpriteBatch> spriteBatch = nullptr;
sptr<Texture2D> texture = nullptr; //200x200
Vector2 position{};
std::vector<Vector2> points;
MouseState currentState{};
MouseState oldState{};
float vel = 1;
int var = 0;
sptr<ContentManager> contentManager;
PTexture2D texture = nullptr;
};
}
int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) {
xna::InitPlatform::Init();
auto game = xna::Game1();
const auto result = game.Run();
return result;

View File

@ -24,5 +24,7 @@
#include "Windows.h"
#include <iostream>
#include "content/manager.hpp"
#include "platform/init-dx.hpp"
#include "csharp/type.hpp"
// TODO: Reference additional headers your program requires here.

View File

@ -13,7 +13,9 @@ namespace xna {
BAD_CAST,
STREAM_ERROR,
UNINTIALIZED_RESOURCE,
END_OF_FILE
END_OF_FILE,
BAD_TYPE,
WARNING_INITIALIZED_RESOURCE
};
inline void xna_error_apply(XnaErrorCode* source, XnaErrorCode const& value) {
@ -22,7 +24,7 @@ namespace xna {
}
inline bool xna_error_haserros(XnaErrorCode* source) {
return source != nullptr;
return source != nullptr && *source != XnaErrorCode::NONE;
}
#define xna_error_nullarg XnaErrorCode* err = nullptr