Files
CydandClaude Opus 4.8 4abbf8879f Initial import of Red Planet v4.10 Win32 source
Imports the current Win32 source for the pod-racing game 'Red Planet',
built on the MUNGA engine and its L4 (Win32/DirectX) platform layer:

- MUNGA / MUNGA_L4: cross-platform engine core and Win32 backend
- RP / RP_L4: Red Planet game logic and Win32 application
- DivLoader, Setup1: asset loader and installer project
- lib, MUNGA_L4/openal, MUNGA_L4/sos: third-party audio dependencies

Removed stale Subversion metadata and added .gitignore/.gitattributes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 07:59:51 -05:00

712 lines
16 KiB
C++

#include "munga.h"
#pragma hdrstop
#include "matrix.h"
#include "affnmtrx.h"
#include "origin.h"
#if defined(USE_SIGNATURE)
int
Is_Signature_Bad(const volatile AbstractMatrix4x4 *)
{
return False;
}
#endif
//
//###########################################################################
//###########################################################################
//
AbstractMatrix4x4&
AbstractMatrix4x4::operator=(const AbstractMatrix4x4 &m)
{
//#if sizeof(entries) > sizeof(m.entries)
//# error memcpy size mismatch!
//#endif
memcpy(entries, m.entries, sizeof(m.entries));
return *this;
}
//
//###########################################################################
//###########################################################################
//
AbstractMatrix4x4&
AbstractMatrix4x4::Transpose(const AbstractMatrix4x4 &m)
{
entries[0] = m.entries[0];
entries[1] = m.entries[4];
entries[2] = m.entries[8];
entries[3] = m.entries[12];
entries[4] = m.entries[1];
entries[5] = m.entries[5];
entries[6] = m.entries[9];
entries[7] = m.entries[13];
entries[8] = m.entries[2];
entries[9] = m.entries[6];
entries[10] = m.entries[10];
entries[11] = m.entries[14];
entries[12] = m.entries[3];
entries[13] = m.entries[7];
entries[14] = m.entries[11];
entries[15] = m.entries[15];
return *this;
}
//
//###########################################################################
//###########################################################################
//
Logical
AbstractMatrix4x4::TestInstance() const
{
return True;
}
const Matrix4x4
Matrix4x4::Identity(True);
//
//###########################################################################
//###########################################################################
//
Matrix4x4&
Matrix4x4::BuildIdentity()
{
(*this)(0,0) = 1.0f;
(*this)(1,0) = 0.0f;
(*this)(2,0) = 0.0f;
(*this)(3,0) = 0.0f;
(*this)(0,1) = 0.0f;
(*this)(1,1) = 1.0f;
(*this)(2,1) = 0.0f;
(*this)(3,1) = 0.0f;
(*this)(0,2) = 0.0f;
(*this)(1,2) = 0.0f;
(*this)(2,2) = 1.0f;
(*this)(3,2) = 0.0f;
(*this)(0,3) = 0.0f;
(*this)(1,3) = 0.0f;
(*this)(2,3) = 0.0f;
(*this)(3,3) = 1.0f;
return *this;
}
//
//###########################################################################
//###########################################################################
//
Matrix4x4&
Matrix4x4::operator=(const AffineMatrix &m)
{
(*this)(0,0) = m(0,0);
(*this)(0,1) = m(0,1);
(*this)(0,2) = m(0,2);
(*this)(0,3) = 0.0f;
(*this)(1,0) = m(1,0);
(*this)(1,1) = m(1,1);
(*this)(1,2) = m(1,2);
(*this)(1,3) = 0.0f;
(*this)(2,0) = m(2,0);
(*this)(2,1) = m(2,1);
(*this)(2,2) = m(2,2);
(*this)(2,3) = 0.0f;
(*this)(3,0) = m(3,0);
(*this)(3,1) = m(3,1);
(*this)(3,2) = m(3,2);
(*this)(3,3) = 1.0f;
return *this;
}
Matrix4x4& Matrix4x4::operator=(const D3DXMATRIX &m)
{
(*this)(0,0) = m._11;
(*this)(0,1) = m._12;
(*this)(0,2) = m._13;
(*this)(0,3) = m._14;
(*this)(1,0) = m._21;
(*this)(1,1) = m._22;
(*this)(1,2) = m._23;
(*this)(1,3) = m._24;
(*this)(2,0) = m._31;
(*this)(2,1) = m._32;
(*this)(2,2) = m._33;
(*this)(2,3) = m._34;
(*this)(3,0) = m._41;
(*this)(3,1) = m._42;
(*this)(3,2) = m._43;
(*this)(3,3) = m._44;
return *this;
}
//
//###########################################################################
//###########################################################################
//
Matrix4x4&
Matrix4x4::operator=(const Origin& p)
{
Check_Pointer(this);
Check(&p);
BuildRotation(p.angularPosition);
BuildTranslation(p.linearPosition);
(*this)(0,3) = 0.0f;
(*this)(1,3) = 0.0f;
(*this)(2,3) = 0.0f;
(*this)(3,3) = 1.0f;
return *this;
}
//
//#############################################################################
//#############################################################################
//
Matrix4x4&
Matrix4x4::operator=(const EulerAngles &angles)
{
Check_Pointer(this);
Check(&angles);
SinCosPair
x,
y,
z;
x = angles.pitch;
y = angles.yaw;
z = angles.roll;
(*this)(0,0) = y.cosine*z.cosine;
(*this)(0,1) = y.cosine*z.sine;
(*this)(0,2) = -y.sine;
(*this)(0,3) = 0.0f;
(*this)(1,0) = x.sine*y.sine*z.cosine - x.cosine*z.sine;
(*this)(1,1) = x.sine*y.sine*z.sine + x.cosine*z.cosine;
(*this)(1,2) = x.sine*y.cosine;
(*this)(1,3) = 0.0f;
(*this)(2,0) = x.cosine*y.sine*z.cosine + x.sine*z.sine;
(*this)(2,1) = x.cosine*y.sine*z.sine - x.sine*z.cosine;
(*this)(2,2) = x.cosine*y.cosine;
(*this)(2,3) = 0.0f;
(*this)(3,0) = 0.0f;
(*this)(3,1) = 0.0f;
(*this)(3,2) = 0.0f;
(*this)(3,3) = 1.0f;
Check(this);
return *this;
}
//
//###########################################################################
//###########################################################################
//
Matrix4x4&
Matrix4x4::BuildRotation(const Quaternion &q)
{
Check_Pointer(this);
Check(&q);
Scalar
a = q.x*q.y,
b = q.y*q.z,
c = q.z*q.x,
d = q.w*q.x,
e = q.w*q.y,
f = q.w*q.z,
g = q.w*q.w,
h = q.x*q.x,
i = q.y*q.y,
j = q.z*q.z;
(*this)(0,0) = g + h - i - j;
(*this)(1,0) = 2.0f*(a - f);
(*this)(2,0) = 2.0f*(c + e);
(*this)(0,1) = 2.0f*(f + a);
(*this)(1,1) = g - h + i - j;
(*this)(2,1) = 2.0f*(b - d);
(*this)(0,2) = 2.0f*(c - e);
(*this)(1,2) = 2.0f*(b + d);
(*this)(2,2) = g - h - i + j;
return *this;
}
//
//###########################################################################
//###########################################################################
//
Matrix4x4&
Matrix4x4::operator=(const Quaternion &q)
{
Check_Pointer(this);
Check(&q);
BuildRotation(q);
(*this)(0,3) = 0.0f;
(*this)(1,3) = 0.0f;
(*this)(2,3) = 0.0f;
(*this)(3,0) = 0.0f;
(*this)(3,1) = 0.0f;
(*this)(3,2) = 0.0f;
(*this)(3,3) = 1.0f;
return *this;
}
//
//###########################################################################
//###########################################################################
//
Matrix4x4&
Matrix4x4::BuildTranslation(const Point3D& p)
{
Check_Pointer(this);
Check(&p);
(*this)(3,0) = p.x;
(*this)(3,1) = p.y;
(*this)(3,2) = p.z;
return *this;
}
//
//###########################################################################
//###########################################################################
//
Matrix4x4&
Matrix4x4::operator=(const Point3D& p)
{
Check_Pointer(this);
Check(&p);
BuildTranslation(p);
(*this)(0,0) = 1.0f;
(*this)(0,1) = 0.0f;
(*this)(0,2) = 0.0f;
(*this)(0,3) = 0.0f;
(*this)(1,0) = 0.0f;
(*this)(1,1) = 1.0f;
(*this)(1,2) = 0.0f;
(*this)(1,3) = 0.0f;
(*this)(2,0) = 0.0f;
(*this)(2,1) = 0.0f;
(*this)(2,2) = 1.0f;
(*this)(2,3) = 0.0f;
(*this)(3,3) = 1.0f;
return *this;
}
//
//###########################################################################
//###########################################################################
//
Matrix4x4&
Matrix4x4::Multiply(
const Matrix4x4 &Source1,
const Matrix4x4 &Source2
)
{
(*this)(0,0) =
Source1(0,0)*Source2(0,0)
+ Source1(0,1)*Source2(1,0)
+ Source1(0,2)*Source2(2,0)
+ Source1(0,3)*Source2(3,0);
(*this)(1,0) =
Source1(1,0)*Source2(0,0)
+ Source1(1,1)*Source2(1,0)
+ Source1(1,2)*Source2(2,0)
+ Source1(1,3)*Source2(3,0);
(*this)(2,0) =
Source1(2,0)*Source2(0,0)
+ Source1(2,1)*Source2(1,0)
+ Source1(2,2)*Source2(2,0)
+ Source1(2,3)*Source2(3,0);
(*this)(3,0) =
Source1(3,0)*Source2(0,0)
+ Source1(3,1)*Source2(1,0)
+ Source1(3,2)*Source2(2,0)
+ Source1(3,3)*Source2(3,0);
(*this)(0,1) =
Source1(0,0)*Source2(0,1)
+ Source1(0,1)*Source2(1,1)
+ Source1(0,2)*Source2(2,1)
+ Source1(0,3)*Source2(3,1);
(*this)(1,1) =
Source1(1,0)*Source2(0,1)
+ Source1(1,1)*Source2(1,1)
+ Source1(1,2)*Source2(2,1)
+ Source1(1,3)*Source2(3,1);
(*this)(2,1) =
Source1(2,0)*Source2(0,1)
+ Source1(2,1)*Source2(1,1)
+ Source1(2,2)*Source2(2,1)
+ Source1(2,3)*Source2(3,1);
(*this)(3,1) =
Source1(3,0)*Source2(0,1)
+ Source1(3,1)*Source2(1,1)
+ Source1(3,2)*Source2(2,1)
+ Source1(3,3)*Source2(3,1);
(*this)(0,2) =
Source1(0,0)*Source2(0,2)
+ Source1(0,1)*Source2(1,2)
+ Source1(0,2)*Source2(2,2)
+ Source1(0,3)*Source2(3,2);
(*this)(1,2) =
Source1(1,0)*Source2(0,2)
+ Source1(1,1)*Source2(1,2)
+ Source1(1,2)*Source2(2,2)
+ Source1(1,3)*Source2(3,2);
(*this)(2,2) =
Source1(2,0)*Source2(0,2)
+ Source1(2,1)*Source2(1,2)
+ Source1(2,2)*Source2(2,2)
+ Source1(2,3)*Source2(3,2);
(*this)(3,2) =
Source1(3,0)*Source2(0,2)
+ Source1(3,1)*Source2(1,2)
+ Source1(3,2)*Source2(2,2)
+ Source1(3,3)*Source2(3,2);
(*this)(0,3) =
Source1(0,0)*Source2(0,3)
+ Source1(0,1)*Source2(1,3)
+ Source1(0,2)*Source2(2,3)
+ Source1(0,3)*Source2(3,3);
(*this)(1,3) =
Source1(1,0)*Source2(0,3)
+ Source1(1,1)*Source2(1,3)
+ Source1(1,2)*Source2(2,3)
+ Source1(1,3)*Source2(3,3);
(*this)(2,3) =
Source1(2,0)*Source2(0,3)
+ Source1(2,1)*Source2(1,3)
+ Source1(2,2)*Source2(2,3)
+ Source1(2,3)*Source2(3,3);
(*this)(3,3) =
Source1(3,0)*Source2(0,3)
+ Source1(3,1)*Source2(1,3)
+ Source1(3,2)*Source2(2,3)
+ Source1(3,3)*Source2(3,3);
return *this;
}
//
//###########################################################################
//###########################################################################
//
Matrix4x4&
Matrix4x4::Multiply(
const Matrix4x4 &Source1,
const AffineMatrix &Source2
)
{
(*this)(0,0) =
Source1(0,0)*Source2(0,0)
+ Source1(0,1)*Source2(1,0)
+ Source1(0,2)*Source2(2,0)
+ Source1(0,3)*Source2(3,0);
(*this)(1,0) =
Source1(1,0)*Source2(0,0)
+ Source1(1,1)*Source2(1,0)
+ Source1(1,2)*Source2(2,0)
+ Source1(1,3)*Source2(3,0);
(*this)(2,0) =
Source1(2,0)*Source2(0,0)
+ Source1(2,1)*Source2(1,0)
+ Source1(2,2)*Source2(2,0)
+ Source1(2,3)*Source2(3,0);
(*this)(3,0) =
Source1(3,0)*Source2(0,0)
+ Source1(3,1)*Source2(1,0)
+ Source1(3,2)*Source2(2,0)
+ Source1(3,3)*Source2(3,0);
(*this)(0,1) =
Source1(0,0)*Source2(0,1)
+ Source1(0,1)*Source2(1,1)
+ Source1(0,2)*Source2(2,1)
+ Source1(0,3)*Source2(3,1);
(*this)(1,1) =
Source1(1,0)*Source2(0,1)
+ Source1(1,1)*Source2(1,1)
+ Source1(1,2)*Source2(2,1)
+ Source1(1,3)*Source2(3,1);
(*this)(2,1) =
Source1(2,0)*Source2(0,1)
+ Source1(2,1)*Source2(1,1)
+ Source1(2,2)*Source2(2,1)
+ Source1(2,3)*Source2(3,1);
(*this)(3,1) =
Source1(3,0)*Source2(0,1)
+ Source1(3,1)*Source2(1,1)
+ Source1(3,2)*Source2(2,1)
+ Source1(3,3)*Source2(3,1);
(*this)(0,2) =
Source1(0,0)*Source2(0,2)
+ Source1(0,1)*Source2(1,2)
+ Source1(0,2)*Source2(2,2)
+ Source1(0,3)*Source2(3,2);
(*this)(1,2) =
Source1(1,0)*Source2(0,2)
+ Source1(1,1)*Source2(1,2)
+ Source1(1,2)*Source2(2,2)
+ Source1(1,3)*Source2(3,2);
(*this)(2,2) =
Source1(2,0)*Source2(0,2)
+ Source1(2,1)*Source2(1,2)
+ Source1(2,2)*Source2(2,2)
+ Source1(2,3)*Source2(3,2);
(*this)(3,2) =
Source1(3,0)*Source2(0,2)
+ Source1(3,1)*Source2(1,2)
+ Source1(3,2)*Source2(2,2)
+ Source1(3,3)*Source2(3,2);
(*this)(0,3) = Source1(0,3);
(*this)(1,3) = Source1(1,3);
(*this)(2,3) = Source1(2,3);
(*this)(3,3) = Source1(3,3);
return *this;
}
//
//###########################################################################
//###########################################################################
//
Matrix4x4&
Matrix4x4::Multiply(
const AffineMatrix &Source1,
const Matrix4x4 &Source2
)
{
(*this)(0,0) =
Source1(0,0)*Source2(0,0)
+ Source1(0,1)*Source2(1,0)
+ Source1(0,2)*Source2(2,0);
(*this)(1,0) =
Source1(1,0)*Source2(0,0)
+ Source1(1,1)*Source2(1,0)
+ Source1(1,2)*Source2(2,0);
(*this)(2,0) =
Source1(2,0)*Source2(0,0)
+ Source1(2,1)*Source2(1,0)
+ Source1(2,2)*Source2(2,0);
(*this)(3,0) =
Source1(3,0)*Source2(0,0)
+ Source1(3,1)*Source2(1,0)
+ Source1(3,2)*Source2(2,0)
+ Source2(3,0);
(*this)(0,1) =
Source1(0,0)*Source2(0,1)
+ Source1(0,1)*Source2(1,1)
+ Source1(0,2)*Source2(2,1);
(*this)(1,1) =
Source1(1,0)*Source2(0,1)
+ Source1(1,1)*Source2(1,1)
+ Source1(1,2)*Source2(2,1);
(*this)(2,1) =
Source1(2,0)*Source2(0,1)
+ Source1(2,1)*Source2(1,1)
+ Source1(2,2)*Source2(2,1);
(*this)(3,1) =
Source1(3,0)*Source2(0,1)
+ Source1(3,1)*Source2(1,1)
+ Source1(3,2)*Source2(2,1)
+ Source2(3,1);
(*this)(0,2) =
Source1(0,0)*Source2(0,2)
+ Source1(0,1)*Source2(1,2)
+ Source1(0,2)*Source2(2,2);
(*this)(1,2) =
Source1(1,0)*Source2(0,2)
+ Source1(1,1)*Source2(1,2)
+ Source1(1,2)*Source2(2,2);
(*this)(2,2) =
Source1(2,0)*Source2(0,2)
+ Source1(2,1)*Source2(1,2)
+ Source1(2,2)*Source2(2,2);
(*this)(3,2) =
Source1(3,0)*Source2(0,2)
+ Source1(3,1)*Source2(1,2)
+ Source1(3,2)*Source2(2,2)
+ Source2(3,2);
(*this)(0,3) =
Source1(0,0)*Source2(0,3)
+ Source1(0,1)*Source2(1,3)
+ Source1(0,2)*Source2(2,3);
(*this)(1,3) =
Source1(1,0)*Source2(0,3)
+ Source1(1,1)*Source2(1,3)
+ Source1(1,2)*Source2(2,3);
(*this)(2,3) =
Source1(2,0)*Source2(0,3)
+ Source1(2,1)*Source2(1,3)
+ Source1(2,2)*Source2(2,3);
(*this)(3,3) =
Source1(3,0)*Source2(0,3)
+ Source1(3,1)*Source2(1,3)
+ Source1(3,2)*Source2(2,3)
+ Source2(3,3);
return *this;
}
//
//###########################################################################
//###########################################################################
//
Matrix4x4&
Matrix4x4::Multiply(
const AffineMatrix &m1,
const AffineMatrix &m2
)
{
Cast_Object(AffineMatrix*,this)->Multiply(m1,m2);
(*this)(0,3) = 0.0f;
(*this)(1,3) = 0.0f;
(*this)(2,3) = 0.0f;
(*this)(3,3) = 1.0f;
return *this;
}
//
//###########################################################################
//###########################################################################
//
Matrix4x4&
Matrix4x4::SetToProjection(
Scalar Z_Plane,
Scalar Inv_Q,
Scalar Dx,
Scalar Dy,
Scalar Inv_Dz
)
{
Scalar
temp;
//
// This may need to be transposed!!!!
//
(*this)(0,0) = 1.0;
(*this)(0,1) = 0.0;
(*this)(0,2) = 0.0;
(*this)(0,3) = 0.0;
(*this)(1,0) = 0.0;
(*this)(1,1) = 1.0;
(*this)(1,2) = 0.0;
(*this)(1,3) = 0.0;
temp = Dx * Inv_Dz;
(*this)(3,0) = temp * Z_Plane;
(*this)(2,0) = -temp;
temp = Dy * Inv_Dz;
(*this)(3,1) = temp * Z_Plane;
(*this)(2,1) = -temp;
Inv_Dz *= -Inv_Q;
(*this)(2,2) = Z_Plane * Inv_Dz;
(*this)(2,3) = Z_Plane * (1.0 - (*this)(2,2));
(*this)(3,2) = Inv_Dz;
(*this)(3,3) = 1.0 - (*this)(2,2);
return *this;
}
//
//###########################################################################
//###########################################################################
//
D3DXMATRIX Matrix4x4::ToD3DMatrix()
{
D3DXMATRIX d3dMatrix;
memcpy(d3dMatrix.m, entries, sizeof(Scalar) * 16);
//// reverse x translation
//d3dMatrix(3, 0) *= -1;
//// reverse yaw rotation
//d3dMatrix(0, 0) *= -1;
//d3dMatrix(0, 2) *= -1;
//d3dMatrix(2, 0) *= -1;
//d3dMatrix(2, 2) *= -1;
return d3dMatrix;
}
//
//###########################################################################
//###########################################################################
//
std::ostream& operator <<(std::ostream& Stream, const Matrix4x4 &A_Matrix)
{
Stream << std::setprecision(4);
Stream << "\n\t| " << std::setw(9) << A_Matrix(0,0) << ", " << std::setw(9);
Stream << A_Matrix(0,1) << ", " << std::setw(9) << A_Matrix(0,2) << ", ";
Stream << std::setw(9) << A_Matrix(0,3) << " |\n\t| " << std::setw(9);
Stream << A_Matrix(1,0) << ", " << std::setw(9) << A_Matrix(1,1) << ", ";
Stream << std::setw(9) << A_Matrix(1,2) << ", " << std::setw(9) << A_Matrix(1,3);
Stream << " |\n\t| " << std::setw(9) << A_Matrix(2,0) << ", " << std::setw(9);
Stream << A_Matrix(2,1) << ", " << std::setw(9) << A_Matrix(2,2) << ", ";
Stream << std::setw(9) << A_Matrix(2,3) << " |\n\t| " << std::setw(9);
Stream << A_Matrix(3,0) << ", " << std::setw(9) << A_Matrix(3,1) << ", ";
Stream << std::setw(9) << A_Matrix(3,2) << ", " << std::setw(9) << A_Matrix(3,3);
return Stream << " |";
}
//
//###########################################################################
//###########################################################################
//
TransposedMatrix&
TransposedMatrix::operator=(const AffineMatrix &m)
{
//#if sizeof(m.entries) > sizeof(entries)
//# error memcpy size mismatch!
//#endif
memcpy(entries, m.entries, sizeof(m.entries));
(*this)(0,3) = 0.0f;
(*this)(1,3) = 0.0f;
(*this)(2,3) = 0.0f;
(*this)(3,3) = 1.0f;
return *this;
}
#if defined(TEST_CLASS)
# include "matrix.tcp"
#endif