Saving state.
- Good place for gainz in liberty - Cutting off PR - known issue: boats' rotations while driving are incorrect.
This commit is contained in:
@@ -104,6 +104,8 @@ OBJS_TEXCONV += \
|
||||
OBJS_O3 = \
|
||||
../vendor/librw/src/dc/rwdc.o \
|
||||
../src/liberty/core/World.o \
|
||||
../src/liberty/core/Zones.o \
|
||||
../src/liberty/core/ZoneCull.o \
|
||||
../src/liberty/collision/Collision.o \
|
||||
../src/liberty/math/math.o \
|
||||
../src/liberty/math/Matrix.o \
|
||||
@@ -111,11 +113,22 @@ OBJS_O3 = \
|
||||
../src/liberty/math/Rect.o \
|
||||
../src/liberty/math/Vector.o \
|
||||
../vendor/librw/src/base.o \
|
||||
../src/liberty/renderer/Shadows.o
|
||||
|
||||
OBJS_NO_FAST_MATH = \
|
||||
../src/liberty/renderer/Shadows.o \
|
||||
../src/liberty/renderer/Renderer.o \
|
||||
../src/liberty/animation/FrameUpdate.o \
|
||||
../src/liberty/animation/RpAnimblend.o \
|
||||
../src/liberty/control/PathFind.o \
|
||||
../src/liberty/core/Cam.o \
|
||||
../src/liberty/core/Camera.o
|
||||
../src/liberty/peds/Ped.o \
|
||||
../src/liberty/peds/PedAI.o \
|
||||
../src/liberty/vehicles/Automobile.o
|
||||
|
||||
# ICE list with with -O3
|
||||
OBJS_O2 = \
|
||||
../src/liberty/animation/AnimBlendNode.o
|
||||
|
||||
# ICE list with -ffast-math
|
||||
OBJS_NO_FAST_MATH =
|
||||
|
||||
KOS_CPPFLAGS += -fbuiltin -ffast-math -ffp-contract=fast \
|
||||
-mfsrra -mfsca
|
||||
@@ -169,6 +182,9 @@ clean:
|
||||
$(OBJS_O3): %.o: %.cpp
|
||||
kos-c++ $(CXXFLAGS) $(CPPFLAGS) -O3 -c $< -o $@
|
||||
|
||||
$(OBJS_O2): %.o: %.cpp
|
||||
kos-c++ $(CXXFLAGS) $(CPPFLAGS) -O2 -c $< -o $@
|
||||
|
||||
$(OBJS_NO_FAST_MATH): %.o: %.cpp
|
||||
kos-c++ $(CXXFLAGS) $(CPPFLAGS) -O3 -c $< -o $@ -fno-fast-math
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ CAnimBlendNode::Update(CVector &trans, CQuaternion &rot, float weight)
|
||||
float blend = association->GetBlendAmount(weight);
|
||||
if(blend > 0.0f){
|
||||
float kfAdt = player->GetNextTimeDelta();
|
||||
float t = kfAdt == 0.0f ? 0.0f : (kfAdt - remainingTime)/kfAdt;
|
||||
float t = kfAdt == 0.0f ? 0.0f : dc::Div<true, false>(kfAdt - remainingTime, kfAdt);
|
||||
if(player->type & CAnimBlendSequence::KF_TRANS){
|
||||
auto kfdAt = player->GetNextTranslationDelta();
|
||||
auto kfBt = player->GetPrevTranslation();
|
||||
@@ -153,7 +153,7 @@ CAnimBlendNode::CalcDeltas(void)
|
||||
if(cos > 1.0f)
|
||||
cos = 1.0f;
|
||||
theta = Acos(cos);
|
||||
invSin = theta == 0.0f ? 0.0f : 1.0f/Sin(theta);
|
||||
invSin = theta == 0.0f ? 0.0f : dc::Invert<true, false>(Sin(theta));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -164,7 +164,7 @@ CAnimBlendNode::GetCurrentTranslation(CVector &trans, float weight)
|
||||
float blend = association->GetBlendAmount(weight);
|
||||
if(blend > 0.0f){
|
||||
auto kfAdt = player->GetNextTimeDelta();
|
||||
float t = kfAdt == 0.0f ? 0.0f : (kfAdt - remainingTime)/kfAdt;
|
||||
float t = kfAdt == 0.0f ? 0.0f : dc::Div<true, false>(kfAdt - remainingTime, kfAdt);
|
||||
if(player->type & CAnimBlendSequence::KF_TRANS){
|
||||
auto kfdAt = player->GetNextTranslationDelta();
|
||||
auto kfBt = player->GetPrevTranslation();
|
||||
|
||||
@@ -3267,24 +3267,24 @@ CCam::Process_BehindBoat(const CVector &CameraTarget, float TargetOrientation, f
|
||||
if(m_bCollisionChecksOn || ResetStatics){
|
||||
CVector TestPoint;
|
||||
// Weird calculations here, also casting bool to float...
|
||||
c = Cos(TargetOrientation);
|
||||
s = Sin(TargetOrientation);
|
||||
c = Cos<false>(TargetOrientation);
|
||||
s = Sin<false>(TargetOrientation);
|
||||
TestPoint = TheCamera.CarZoomValueSmooth * CVector(-c, -s, 0.0f) +
|
||||
(TheCamera.CarZoomValueSmooth+7.0f) * CVector(-c, -s, 0.0f) +
|
||||
TargetCoors;
|
||||
TestPoint.z = WaterLevel + TheCamera.CarZoomValueSmooth;
|
||||
float Test1 = CWorld::GetIsLineOfSightClear(TestPoint, TargetCoors, true, false, false, true, false, true, true);
|
||||
|
||||
c = Cos(TargetOrientation + 0.8f);
|
||||
s = Sin(TargetOrientation + DEGTORAD(40.0f));
|
||||
c = Cos<false>(TargetOrientation + 0.8f);
|
||||
s = Sin<false>(TargetOrientation + DEGTORAD(40.0f));
|
||||
TestPoint = TheCamera.CarZoomValueSmooth * CVector(-c, -s, 0.0f) +
|
||||
(TheCamera.CarZoomValueSmooth+7.0f) * CVector(-c, -s, 0.0f) +
|
||||
TargetCoors;
|
||||
TestPoint.z = WaterLevel + TheCamera.CarZoomValueSmooth;
|
||||
float Test2 = CWorld::GetIsLineOfSightClear(TestPoint, TargetCoors, true, false, false, true, false, true, true);
|
||||
|
||||
c = Cos(TargetOrientation - 0.8);
|
||||
s = Sin(TargetOrientation - DEGTORAD(40.0f));
|
||||
c = Cos<false>(TargetOrientation - 0.8);
|
||||
s = Sin<false>(TargetOrientation - DEGTORAD(40.0f));
|
||||
TestPoint = TheCamera.CarZoomValueSmooth * CVector(-c, -s, 0.0f) +
|
||||
(TheCamera.CarZoomValueSmooth+7.0f) * CVector(-c, -s, 0.0f) +
|
||||
TargetCoors;
|
||||
@@ -3307,8 +3307,7 @@ CCam::Process_BehindBoat(const CVector &CameraTarget, float TargetOrientation, f
|
||||
DeltaBeta = TargetOrientation - Beta;
|
||||
}
|
||||
|
||||
c = Cos(Beta);
|
||||
s = Sin(Beta);
|
||||
auto [s, c] = SinCos<false>(Beta);
|
||||
TestPoint.x = TheCamera.CarZoomValueSmooth * -c +
|
||||
(TheCamera.CarZoomValueSmooth + 7.0f) * -c +
|
||||
TargetCoors.x;
|
||||
@@ -3333,8 +3332,7 @@ CCam::Process_BehindBoat(const CVector &CameraTarget, float TargetOrientation, f
|
||||
// inlined
|
||||
WellBufferMe(TargetWhenChecksWereOn, &Beta, &BetaSpeed, 0.07f, 0.015f, true);
|
||||
|
||||
s = Sin(Beta);
|
||||
c = Cos(Beta);
|
||||
auto [s, c] = SinCos<false>(Beta);
|
||||
Source = TheCamera.CarZoomValueSmooth * CVector(-c, -s, 0.0f) +
|
||||
(TheCamera.CarZoomValueSmooth+7.0f) * CVector(-c, -s, 0.0f) +
|
||||
TargetCoors;
|
||||
|
||||
@@ -3694,7 +3694,7 @@ CCamera::IsBoxVisible(CVUVECTOR *box, const CMatrix *mat)
|
||||
#ifdef GTA_PS2
|
||||
TransformPoints(box, 8, *mat, box);
|
||||
#else
|
||||
#ifdef FIX_BUGS
|
||||
#if defined(FIX_BUGS) && !defined(DC_SH4)
|
||||
for (i = 0; i < 8; i++)
|
||||
box[i] = *mat * box[i];
|
||||
#else
|
||||
|
||||
@@ -54,7 +54,7 @@ CMatrix::Detach(void)
|
||||
void
|
||||
CMatrix::Update(void)
|
||||
{
|
||||
#if 1
|
||||
#ifndef DC_SH4
|
||||
GetRight() = m_attachment->right;
|
||||
GetForward() = m_attachment->up;
|
||||
GetUp() = m_attachment->at;
|
||||
@@ -68,15 +68,15 @@ void
|
||||
CMatrix::UpdateRW(void)
|
||||
{
|
||||
if (m_attachment) {
|
||||
#if 1
|
||||
#ifndef DC_SH4
|
||||
m_attachment->right = GetRight();
|
||||
m_attachment->up = GetForward();
|
||||
m_attachment->at = GetUp();
|
||||
m_attachment->pos = GetPosition();
|
||||
RwMatrixUpdate(m_attachment);
|
||||
#else
|
||||
mat_copy(*m_attachment, *this);
|
||||
#endif
|
||||
RwMatrixUpdate(m_attachment);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,8 +84,10 @@ void
|
||||
CMatrix::operator=(CMatrix const &rhs)
|
||||
{
|
||||
mat_copy(*this, rhs);
|
||||
#ifndef DC_SH4
|
||||
if (m_attachment)
|
||||
UpdateRW();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -168,7 +170,7 @@ CMatrix::SetScale(float s)
|
||||
void
|
||||
CMatrix::SetTranslate(float x, float y, float z)
|
||||
{
|
||||
#if 1
|
||||
#ifndef DC_SH4
|
||||
rx = 1.0f;
|
||||
ry = 0.0f;
|
||||
rz = 0.0f;
|
||||
@@ -247,34 +249,52 @@ CMatrix::SetRotateZOnly(float angle)
|
||||
void
|
||||
CMatrix::SetRotateX(float angle)
|
||||
{
|
||||
#ifndef DC_SH4
|
||||
SetRotateXOnly(angle);
|
||||
px = 0.0f;
|
||||
py = 0.0f;
|
||||
pz = 0.0f;
|
||||
#else
|
||||
dc::mat_identity2();
|
||||
dc::mat_apply_rotate_x(angle);
|
||||
dc::mat_store2(*this);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CMatrix::SetRotateY(float angle)
|
||||
{
|
||||
#ifndef DC_SH4
|
||||
SetRotateYOnly(angle);
|
||||
px = 0.0f;
|
||||
py = 0.0f;
|
||||
pz = 0.0f;
|
||||
#else
|
||||
dc::mat_identity2();
|
||||
dc::mat_apply_rotate_y(angle);
|
||||
dc::mat_store2(*this);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
CMatrix::SetRotateZ(float angle)
|
||||
{
|
||||
#ifndef DC_SH4
|
||||
SetRotateZOnly(angle);
|
||||
px = 0.0f;
|
||||
py = 0.0f;
|
||||
pz = 0.0f;
|
||||
#else
|
||||
dc::mat_identity2();
|
||||
dc::mat_apply_rotate_z(angle);
|
||||
dc::mat_store2(*this);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
CMatrix::SetRotate(float xAngle, float yAngle, float zAngle)
|
||||
{
|
||||
#if 1
|
||||
auto [sX, cX] = SinCos(xAngle);
|
||||
auto [sY, cY] = SinCos(yAngle);
|
||||
auto [sZ, cZ] = SinCos(zAngle);
|
||||
@@ -294,15 +314,19 @@ CMatrix::SetRotate(float xAngle, float yAngle, float zAngle)
|
||||
px = 0.0f;
|
||||
py = 0.0f;
|
||||
pz = 0.0f;
|
||||
#else
|
||||
dc::mat_set_rotate(xAngle, yAngle, zAngle);
|
||||
dc::mat_store2(*this);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
CMatrix::RotateX(float x)
|
||||
{
|
||||
#if 0 && defined(DC_SH4) // this is bugged and does not yield correct results
|
||||
dc::mat_load2(reinterpret_cast<matrix_t *>(this));
|
||||
mat_rotate_x(x);
|
||||
dc::mat_store2(reinterpret_cast<matrix_t *>(this));
|
||||
#if 0// this is bugged and does not yield correct results
|
||||
dc::mat_set_rotate_x(x);
|
||||
mat_apply(*this);
|
||||
dc::mat_store2(*this);
|
||||
#else
|
||||
auto [s, c] = SinCos(x);
|
||||
|
||||
@@ -329,10 +353,10 @@ CMatrix::RotateX(float x)
|
||||
void
|
||||
CMatrix::RotateY(float y)
|
||||
{
|
||||
#if 0 && defined(DC_SH4) // this is bugged and does not yield correct results
|
||||
dc::mat_load2(reinterpret_cast<matrix_t *>(this));
|
||||
mat_rotate_y(y);
|
||||
dc::mat_store2(reinterpret_cast<matrix_t *>(this));
|
||||
#if 0 // this is bugged and does not yield correct results
|
||||
dc::mat_set_rotate_y(y);
|
||||
mat_apply(*this);
|
||||
dc::mat_store2(*this);
|
||||
#else
|
||||
auto [s, c] = SinCos(y);
|
||||
|
||||
@@ -359,10 +383,10 @@ CMatrix::RotateY(float y)
|
||||
void
|
||||
CMatrix::RotateZ(float z)
|
||||
{
|
||||
#if 0 && defined(DC_SH4) // this is bugged and does not yield correct results
|
||||
dc::mat_load2(reinterpret_cast<matrix_t *>(this));
|
||||
mat_rotate_z(z);
|
||||
dc::mat_store2(reinterpret_cast<matrix_t *>(this));
|
||||
#if 0// this is bugged and does not yield correct results
|
||||
dc::mat_set_rotate_z(z);
|
||||
mat_apply(*this);
|
||||
dc::mat_store2(*this);
|
||||
#else
|
||||
auto [s, c] = SinCos(z);
|
||||
|
||||
@@ -389,10 +413,10 @@ CMatrix::RotateZ(float z)
|
||||
void
|
||||
CMatrix::Rotate(float x, float y, float z)
|
||||
{
|
||||
#if 0 && defined(DC_SH4) // this is bugged and does not yield correct results
|
||||
dc::mat_load2(reinterpret_cast<matrix_t *>(this));
|
||||
mat_rotate(x, y, z);
|
||||
dc::mat_store2(reinterpret_cast<matrix_t *>(this));
|
||||
#if 0 // this is bugged and does not yield correct results
|
||||
dc::mat_set_rotate(x, y, z);
|
||||
mat_apply(*this);
|
||||
dc::mat_store2(*this);
|
||||
#else
|
||||
auto [sX, cX] = SinCos(x);
|
||||
auto [sY, cY] = SinCos(y);
|
||||
|
||||
@@ -80,7 +80,7 @@ CPointLights::GenerateLightsAffectingObject(Const CVector *objCoors)
|
||||
distance = dist.Magnitude();
|
||||
if(distance < radius){
|
||||
|
||||
float distNorm = distance/radius;
|
||||
float distNorm = Div<true, false>(distance, radius);
|
||||
if(aLights[i].type == LIGHT_DARKEN){
|
||||
// darken the object the closer it is
|
||||
ret *= distNorm;
|
||||
|
||||
@@ -1315,8 +1315,9 @@ CalcNewDelta(RwV2d *a, RwV2d *b)
|
||||
#define TOINT(x) ((int)(x))
|
||||
#endif
|
||||
|
||||
template<typename F>
|
||||
void
|
||||
CRenderer::ScanSectorPoly(RwV2d *poly, int32 numVertices, void (*scanfunc)(CPtrList *))
|
||||
CRenderer::ScanSectorPoly(RwV2d *poly, int32 numVertices, F&& scanfunc)
|
||||
{
|
||||
float miny, maxy;
|
||||
int y, yend;
|
||||
|
||||
@@ -90,7 +90,8 @@ public:
|
||||
static void ConstructRenderList(void);
|
||||
static void ScanWorld(void);
|
||||
static void RequestObjectsInFrustum(void);
|
||||
static void ScanSectorPoly(RwV2d *poly, int32 numVertices, void (*scanfunc)(CPtrList *));
|
||||
template<typename F>
|
||||
static void ScanSectorPoly(RwV2d *poly, int32 numVertices, F &&scanfunc);
|
||||
static void ScanBigBuildingList(CPtrList &list);
|
||||
static void ScanSectorList(CPtrList *lists);
|
||||
static void ScanSectorList_Priority(CPtrList *lists);
|
||||
|
||||
4
vendor/librw/src/base.cpp
vendored
4
vendor/librw/src/base.cpp
vendored
@@ -410,7 +410,7 @@ Matrix::translate(const V3d *translation, CombineOp op)
|
||||
Matrix trans;
|
||||
dc::mat_set_translation(translation->x, translation->y, translation->z);
|
||||
dc::mat_store2(trans);
|
||||
trans.flags = Matrix::TYPEORTHONORMAL;
|
||||
trans.flags = TYPEORTHONORMAL;
|
||||
#endif
|
||||
switch(op){
|
||||
case COMBINEREPLACE:
|
||||
@@ -439,7 +439,7 @@ Matrix::scale(const V3d *scale, CombineOp op)
|
||||
Matrix scl;
|
||||
dc::mat_set_scale(scale->x, scale->y, scale->z);
|
||||
dc::mat_store2(scl);
|
||||
scl.flags = Matrix::TYPEORTHONORMAL;
|
||||
scl.flags = TYPEORTHONORMAL;
|
||||
#endif
|
||||
switch(op){
|
||||
case COMBINEREPLACE:
|
||||
|
||||
56
vendor/librw/src/camera.cpp
vendored
56
vendor/librw/src/camera.cpp
vendored
@@ -493,33 +493,7 @@ Camera::frustumTestSphere(const Sphere *s) const
|
||||
static_assert(offsetof (decltype (p[0].plane), distance)
|
||||
-offsetof (decltype (p[0].plane.normal), z) == sizeof (float));
|
||||
|
||||
asm volatile (R"(
|
||||
frchg
|
||||
|
||||
fmov.s @%0+,fr0
|
||||
fmov.s @%1+,fr1
|
||||
fmov.s @%2+,fr2
|
||||
fmov.s @%3+,fr3
|
||||
|
||||
fmov.s @%0+,fr4
|
||||
fmov.s @%1+,fr5
|
||||
fmov.s @%2+,fr6
|
||||
fmov.s @%3+,fr7
|
||||
|
||||
fmov.s @%0+,fr8
|
||||
fmov.s @%1+,fr9
|
||||
fmov.s @%2+,fr10
|
||||
fmov.s @%3+,fr11
|
||||
|
||||
fmov.s @%0,fr12
|
||||
fmov.s @%1,fr13
|
||||
fmov.s @%2,fr14
|
||||
fmov.s @%3,fr15
|
||||
|
||||
frchg
|
||||
)" : "+&r" (base_ptr0), "+&r" (base_ptr1), "+&r" (base_ptr2), "+&r" (base_ptr3)
|
||||
:
|
||||
: );
|
||||
mat_load_rows(base_ptr0, base_ptr1, base_ptr2, base_ptr3);
|
||||
|
||||
float dists[4];
|
||||
mat_trans_vec4_nodiv_nomod(sx, sy, sz, sw,
|
||||
@@ -643,33 +617,7 @@ Camera::frustumTestSphereNear(const Sphere *s) const
|
||||
static_assert(offsetof (decltype (p[0].plane), distance)
|
||||
-offsetof (decltype (p[0].plane.normal), z) == sizeof (float));
|
||||
|
||||
asm volatile (R"(
|
||||
frchg
|
||||
|
||||
fmov.s @%0+,fr0
|
||||
fmov.s @%1+,fr1
|
||||
fmov.s @%2+,fr2
|
||||
fmov.s @%3+,fr3
|
||||
|
||||
fmov.s @%0+,fr4
|
||||
fmov.s @%1+,fr5
|
||||
fmov.s @%2+,fr6
|
||||
fmov.s @%3+,fr7
|
||||
|
||||
fmov.s @%0+,fr8
|
||||
fmov.s @%1+,fr9
|
||||
fmov.s @%2+,fr10
|
||||
fmov.s @%3+,fr11
|
||||
|
||||
fmov.s @%0,fr12
|
||||
fmov.s @%1,fr13
|
||||
fmov.s @%2,fr14
|
||||
fmov.s @%3,fr15
|
||||
|
||||
frchg
|
||||
)" : "+&r" (base_ptr0), "+&r" (base_ptr1), "+&r" (base_ptr2), "+&r" (base_ptr3)
|
||||
:
|
||||
: );
|
||||
mat_load_rows(base_ptr0, base_ptr1, base_ptr2, base_ptr3);
|
||||
|
||||
float dists[4];
|
||||
mat_trans_vec4_nodiv_nomod(sx, sy, sz, sw,
|
||||
|
||||
3
vendor/librw/src/dc/rwdc.cpp
vendored
3
vendor/librw/src/dc/rwdc.cpp
vendored
@@ -811,7 +811,8 @@ struct chunked_vector {
|
||||
}
|
||||
|
||||
// Iterate over each element and invoke the callback.
|
||||
void forEach(void(*cb)(T&)) {
|
||||
template<typename F>
|
||||
void forEach(F&& cb) {
|
||||
for (chunk* curr = first; curr; curr = curr->header.next) {
|
||||
for (size_t i = 0; i < curr->header.used; ++i) {
|
||||
cb(curr->items[i]);
|
||||
|
||||
1064
vendor/librw/src/dc/rwdc_common.h
vendored
1064
vendor/librw/src/dc/rwdc_common.h
vendored
File diff suppressed because it is too large
Load Diff
17
vendor/librw/src/rwbase.h
vendored
17
vendor/librw/src/rwbase.h
vendored
@@ -451,6 +451,9 @@ struct alignas(8) MatrixBase
|
||||
uint32 pad3;
|
||||
float posw = 1.0f;
|
||||
};
|
||||
|
||||
operator matrix_t *() { return reinterpret_cast<matrix_t *>(this); }
|
||||
operator const matrix_t *() const { return reinterpret_cast<const matrix_t *>(this); }
|
||||
};
|
||||
|
||||
struct Matrix: public MatrixBase
|
||||
@@ -463,9 +466,9 @@ struct Matrix: public MatrixBase
|
||||
|
||||
Matrix() {}
|
||||
|
||||
Matrix(MatrixBase &&aggregate):
|
||||
MatrixBase{aggregate}
|
||||
{}
|
||||
Matrix(MatrixBase &&aggregate){
|
||||
*this = aggregate;
|
||||
}
|
||||
|
||||
Matrix(const Matrix &rhs) {
|
||||
*this = rhs;
|
||||
@@ -476,8 +479,10 @@ struct Matrix: public MatrixBase
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator matrix_t *() { return reinterpret_cast<matrix_t *>(this); }
|
||||
operator const matrix_t *() const { return reinterpret_cast<const matrix_t *>(this); }
|
||||
Matrix &operator=(const MatrixBase &rhs) {
|
||||
dc::mat_copy(*this, rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
static Matrix *create(void);
|
||||
void destroy(void);
|
||||
@@ -514,10 +519,12 @@ inline void convMatrix(Matrix *dst, RawMatrix *src){
|
||||
|
||||
inline void convMatrix(RawMatrix *dst, Matrix *src){
|
||||
*dst = *(RawMatrix*)src;
|
||||
#ifndef DC_SH4
|
||||
dst->rightw = 0.0;
|
||||
dst->upw = 0.0;
|
||||
dst->atw = 0.0;
|
||||
dst->posw = 1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
struct Line
|
||||
|
||||
Reference in New Issue
Block a user