Port SelectionBox to C.

This commit is contained in:
UnknownShadow200 2018-03-11 21:08:09 +11:00
parent c92b53bc79
commit 05d0c8f635
14 changed files with 311 additions and 163 deletions

View File

@ -276,7 +276,6 @@
<Compile Include="Selections\AxisLinesRenderer.cs" /> <Compile Include="Selections\AxisLinesRenderer.cs" />
<Compile Include="Selections\PickedPosRenderer.cs" /> <Compile Include="Selections\PickedPosRenderer.cs" />
<Compile Include="Selections\SelectionBox.cs" /> <Compile Include="Selections\SelectionBox.cs" />
<Compile Include="Selections\SelectionBoxComparer.cs" />
<Compile Include="Selections\SelectionManager.cs" /> <Compile Include="Selections\SelectionManager.cs" />
<Compile Include="Singleplayer\FallingPhysics.cs" /> <Compile Include="Singleplayer\FallingPhysics.cs" />
<Compile Include="Singleplayer\FoliagePhysics.cs" /> <Compile Include="Singleplayer\FoliagePhysics.cs" />

View File

@ -1,11 +1,12 @@
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 // Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
using System; using System;
using System.Collections.Generic;
using ClassicalSharp.GraphicsAPI; using ClassicalSharp.GraphicsAPI;
using OpenTK; using OpenTK;
namespace ClassicalSharp.Selections { namespace ClassicalSharp.Selections {
public class SelectionBox { internal class SelectionBox {
public byte ID; public byte ID;
public Vector3I Min, Max; public Vector3I Min, Max;
@ -75,4 +76,40 @@ namespace ClassicalSharp.Selections {
v.X = x2; v.Y = y2; v.Z = z2; vertices[index++] = v; v.X = x2; v.Y = y2; v.Z = z2; vertices[index++] = v;
} }
} }
internal class SelectionBoxComparer : IComparer<SelectionBox> {
public int Compare(SelectionBox a, SelectionBox b) {
// Reversed comparison order because we need to render back to front for alpha blending.
return a.MinDist == b.MinDist
? b.MaxDist.CompareTo(a.MaxDist)
: b.MinDist.CompareTo(a.MinDist);
}
internal void Intersect(SelectionBox box, Vector3 origin) {
Vector3I min = box.Min, max = box.Max;
float closest = float.PositiveInfinity, furthest = float.NegativeInfinity;
// Bottom corners
UpdateDist(origin, min.X, min.Y, min.Z, ref closest, ref furthest);
UpdateDist(origin, max.X, min.Y, min.Z, ref closest, ref furthest);
UpdateDist(origin, max.X, min.Y, max.Z, ref closest, ref furthest);
UpdateDist(origin, min.X, min.Y, max.Z, ref closest, ref furthest);
// Top corners
UpdateDist(origin, min.X, max.Y, min.Z, ref closest, ref furthest);
UpdateDist(origin, max.X, max.Y, min.Z, ref closest, ref furthest);
UpdateDist(origin, max.X, max.Y, max.Z, ref closest, ref furthest);
UpdateDist(origin, min.X, max.Y, max.Z, ref closest, ref furthest);
box.MinDist = closest; box.MaxDist = furthest;
}
static void UpdateDist(Vector3 p, float x2, float y2, float z2,
ref float closest, ref float furthest) {
float dx = x2 - p.X, dy = y2 - p.Y, dz = z2 - p.Z;
float dist = dx * dx + dy * dy + dz * dz;
if (dist < closest) closest = dist;
if (dist > furthest) furthest = dist;
}
}
} }

View File

@ -1,39 +0,0 @@
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
using System;
using System.Collections.Generic;
using OpenTK;
namespace ClassicalSharp.Selections {
internal class SelectionBoxComparer : IComparer<SelectionBox> {
public int Compare(SelectionBox a, SelectionBox b) {
// Reversed comparison order because we need to render back to front for alpha blending.
return a.MinDist == b.MinDist ? b.MaxDist.CompareTo(a.MaxDist)
: b.MinDist.CompareTo(a.MinDist);
}
internal void Intersect(SelectionBox box, Vector3 origin) {
Vector3I min = box.Min, max = box.Max;
float closest = float.PositiveInfinity, furthest = float.NegativeInfinity;
// Bottom corners
UpdateDist(origin, min.X, min.Y, min.Z, ref closest, ref furthest);
UpdateDist(origin, max.X, min.Y, min.Z, ref closest, ref furthest);
UpdateDist(origin, max.X, min.Y, max.Z, ref closest, ref furthest);
UpdateDist(origin, min.X, min.Y, max.Z, ref closest, ref furthest);
// Top corners
UpdateDist(origin, min.X, max.Y, min.Z, ref closest, ref furthest);
UpdateDist(origin, max.X, max.Y, min.Z, ref closest, ref furthest);
UpdateDist(origin, max.X, max.Y, max.Z, ref closest, ref furthest);
UpdateDist(origin, min.X, max.Y, max.Z, ref closest, ref furthest);
box.MinDist = closest; box.MaxDist = furthest;
}
static void UpdateDist(Vector3 p, float x2, float y2, float z2,
ref float closest, ref float furthest) {
float dist = Utils.DistanceSquared(p.X, p.Y, p.Z, x2, y2, z2);
if (dist < closest) closest = dist;
if (dist > furthest) furthest = dist;
}
}
}

View File

@ -81,14 +81,7 @@ namespace ClassicalSharp {
float cosA = (float)Math.Cos(angle), sinA = (float)Math.Sin(angle); float cosA = (float)Math.Cos(angle), sinA = (float)Math.Sin(angle);
return new Vector3(cosA * v.X + sinA * v.Y, -sinA * v.X + cosA * v.Y, v.Z); return new Vector3(cosA * v.X + sinA * v.Y, -sinA * v.X + cosA * v.Y, v.Z);
} }
/// <summary> Returns the square of the euclidean distance between two points. </summary>
public static float DistanceSquared(float x1, float y1, float z1, float x2, float y2, float z2) {
float dx = x2 - x1, dy = y2 - y1, dz = z2 - z1;
return dx * dx + dy * dy + dz * dz;
}
/// <summary> Returns a normalised vector that faces in the direction /// <summary> Returns a normalised vector that faces in the direction
/// described by the given yaw and pitch. </summary> /// described by the given yaw and pitch. </summary>
public static Vector3 GetDirVector(double yawRad, double pitchRad) { public static Vector3 GetDirVector(double yawRad, double pitchRad) {

View File

@ -106,10 +106,10 @@ void BordersRenderer_DrawX(Int32 x, Int32 z1, Int32 z2, Int32 y1, Int32 y2, Int3
if (y2 > endY) y2 = endY; if (y2 > endY) y2 = endY;
Real32 u2 = (Real32)z2 - (Real32)z1, v2 = (Real32)y2 - (Real32)y1; Real32 u2 = (Real32)z2 - (Real32)z1, v2 = (Real32)y2 - (Real32)y1;
v.Y = (Real32)y1; v.Z = (Real32)z1; v.U = 0.0f; v.V = v2; *ptr = v; ptr++; v.Y = (Real32)y1; v.Z = (Real32)z1; v.U = 0.0f; v.V = v2; *ptr++ = v;
v.Y = (Real32)y2; v.V = 0.0f; *ptr = v; ptr++; v.Y = (Real32)y2; v.V = 0.0f; *ptr++ = v;
v.Z = (Real32)z2; v.U = u2; *ptr = v; ptr++; v.Z = (Real32)z2; v.U = u2; *ptr++ = v;
v.Y = (Real32)y1; v.V = v2; *ptr = v; ptr++; v.Y = (Real32)y1; v.V = v2; *ptr++ = v;
} }
} }
*vertices = ptr; *vertices = ptr;
@ -130,10 +130,10 @@ void BordersRenderer_DrawZ(Int32 z, Int32 x1, Int32 x2, Int32 y1, Int32 y2, Int3
if (y2 > endY) y2 = endY; if (y2 > endY) y2 = endY;
Real32 u2 = (Real32)x2 - (Real32)x1, v2 = (Real32)y2 - (Real32)y1; Real32 u2 = (Real32)x2 - (Real32)x1, v2 = (Real32)y2 - (Real32)y1;
v.X = (Real32)x1; v.Y = (Real32)y1; v.U = 0.0f; v.V = v2; *ptr = v; ptr++; v.X = (Real32)x1; v.Y = (Real32)y1; v.U = 0.0f; v.V = v2; *ptr++ = v;
v.Y = (Real32)y2; v.V = 0.0f; *ptr = v; ptr++; v.Y = (Real32)y2; v.V = 0.0f; *ptr++ = v;
v.X = (Real32)x2; v.U = u2; *ptr = v; ptr++; v.X = (Real32)x2; v.U = u2; *ptr++ = v;
v.Y = (Real32)y1; v.V = v2; *ptr = v; ptr++; v.Y = (Real32)y1; v.V = v2; *ptr++ = v;
} }
} }
*vertices = ptr; *vertices = ptr;
@ -154,10 +154,10 @@ void BordersRenderer_DrawY(Int32 x1, Int32 z1, Int32 x2, Int32 z2, Real32 y, Int
if (z2 > endZ) z2 = endZ; if (z2 > endZ) z2 = endZ;
Real32 u2 = (Real32)x2 - (Real32)x1, v2 = (Real32)z2 - (Real32)z1; Real32 u2 = (Real32)x2 - (Real32)x1, v2 = (Real32)z2 - (Real32)z1;
v.X = (Real32)x1 + offset; v.Z = (Real32)z1 + offset; v.U = 0.0f; v.V = 0.0f; *ptr = v; ptr++; v.X = (Real32)x1 + offset; v.Z = (Real32)z1 + offset; v.U = 0.0f; v.V = 0.0f; *ptr++ = v;
v.Z = (Real32)z2 + offset; v.V = v2; *ptr = v; ptr++; v.Z = (Real32)z2 + offset; v.V = v2; *ptr++ = v;
v.X = (Real32)x2 + offset; v.U = u2; *ptr = v; ptr++; v.X = (Real32)x2 + offset; v.U = u2; *ptr++ = v;
v.Z = (Real32)z1 + offset; v.V = 0.0f; *ptr = v; ptr++; v.Z = (Real32)z1 + offset; v.V = 0.0f; *ptr++ = v;
} }
} }
*vertices = ptr; *vertices = ptr;

View File

@ -2,8 +2,6 @@
#include "TerrainAtlas.h" #include "TerrainAtlas.h"
#include "Constants.h" #include "Constants.h"
#define AddVertex *ptr = v; ptr++
/* Performance critical, use macro to ensure always inlined. */ /* Performance critical, use macro to ensure always inlined. */
#define ApplyTint \ #define ApplyTint \
if (Drawer_Tinted) {\ if (Drawer_Tinted) {\
@ -23,10 +21,10 @@ void Drawer_XMin(Int32 count, PackedCol col, TextureLoc texLoc, VertexP3fT2fC4b*
VertexP3fT2fC4b* ptr = *vertices; VertexP3fT2fC4b* ptr = *vertices;
VertexP3fT2fC4b v; v.X = Drawer_X1; v.Col = col; VertexP3fT2fC4b v; v.X = Drawer_X1; v.Col = col;
v.Y = Drawer_Y2; v.Z = Drawer_Z2 + (count - 1); v.U = u2; v.V = v1; AddVertex; v.Y = Drawer_Y2; v.Z = Drawer_Z2 + (count - 1); v.U = u2; v.V = v1; *ptr++ = v;
v.Z = Drawer_Z1; v.U = u1; AddVertex; v.Z = Drawer_Z1; v.U = u1; *ptr++ = v;
v.Y = Drawer_Y1; v.V = v2; AddVertex; v.Y = Drawer_Y1; v.V = v2; *ptr++ = v;
v.Z = Drawer_Z2 + (count - 1); v.U = u2; AddVertex; v.Z = Drawer_Z2 + (count - 1); v.U = u2; *ptr++ = v;
*vertices = ptr; *vertices = ptr;
} }
@ -40,10 +38,10 @@ void Drawer_XMax(Int32 count, PackedCol col, TextureLoc texLoc, VertexP3fT2fC4b*
VertexP3fT2fC4b* ptr = *vertices; VertexP3fT2fC4b* ptr = *vertices;
VertexP3fT2fC4b v; v.X = Drawer_X2; v.Col = col; VertexP3fT2fC4b v; v.X = Drawer_X2; v.Col = col;
v.Y = Drawer_Y2; v.Z = Drawer_Z1; v.U = u1; v.V = v1; AddVertex; v.Y = Drawer_Y2; v.Z = Drawer_Z1; v.U = u1; v.V = v1; *ptr++ = v;
v.Z = Drawer_Z2 + (count - 1); v.U = u2; AddVertex; v.Z = Drawer_Z2 + (count - 1); v.U = u2; *ptr++ = v;
v.Y = Drawer_Y1; v.V = v2; AddVertex; v.Y = Drawer_Y1; v.V = v2; *ptr++ = v;
v.Z = Drawer_Z1; v.U = u1; AddVertex; v.Z = Drawer_Z1; v.U = u1; *ptr++ = v;
*vertices = ptr; *vertices = ptr;
} }
@ -57,10 +55,10 @@ void Drawer_ZMin(Int32 count, PackedCol col, TextureLoc texLoc, VertexP3fT2fC4b*
VertexP3fT2fC4b* ptr = *vertices; VertexP3fT2fC4b* ptr = *vertices;
VertexP3fT2fC4b v; v.Z = Drawer_Z1; v.Col = col; VertexP3fT2fC4b v; v.Z = Drawer_Z1; v.Col = col;
v.X = Drawer_X2 + (count - 1); v.Y = Drawer_Y1; v.U = u2; v.V = v2; AddVertex; v.X = Drawer_X2 + (count - 1); v.Y = Drawer_Y1; v.U = u2; v.V = v2; *ptr++ = v;
v.X = Drawer_X1; v.U = u1; AddVertex; v.X = Drawer_X1; v.U = u1; *ptr++ = v;
v.Y = Drawer_Y2; v.V = v1; AddVertex; v.Y = Drawer_Y2; v.V = v1; *ptr++ = v;
v.X = Drawer_X2 + (count - 1); v.U = u2; AddVertex; v.X = Drawer_X2 + (count - 1); v.U = u2; *ptr++ = v;
*vertices = ptr; *vertices = ptr;
} }
@ -74,10 +72,10 @@ void Drawer_ZMax(Int32 count, PackedCol col, TextureLoc texLoc, VertexP3fT2fC4b*
VertexP3fT2fC4b* ptr = *vertices; VertexP3fT2fC4b* ptr = *vertices;
VertexP3fT2fC4b v; v.Z = Drawer_Z2; v.Col = col; VertexP3fT2fC4b v; v.Z = Drawer_Z2; v.Col = col;
v.X = Drawer_X2 + (count - 1); v.Y = Drawer_Y2; v.U = u2; v.V = v1; AddVertex; v.X = Drawer_X2 + (count - 1); v.Y = Drawer_Y2; v.U = u2; v.V = v1; *ptr++ = v;
v.X = Drawer_X1; v.U = u1; AddVertex; v.X = Drawer_X1; v.U = u1; *ptr++ = v;
v.Y = Drawer_Y1; v.V = v2; AddVertex; v.Y = Drawer_Y1; v.V = v2; *ptr++ = v;
v.X = Drawer_X2 + (count - 1); v.U = u2; AddVertex; v.X = Drawer_X2 + (count - 1); v.U = u2; *ptr++ = v;
*vertices = ptr; *vertices = ptr;
} }
@ -91,10 +89,10 @@ void Drawer_YMin(Int32 count, PackedCol col, TextureLoc texLoc, VertexP3fT2fC4b*
VertexP3fT2fC4b* ptr = *vertices; VertexP3fT2fC4b* ptr = *vertices;
VertexP3fT2fC4b v; v.Y = Drawer_Y1; v.Col = col; VertexP3fT2fC4b v; v.Y = Drawer_Y1; v.Col = col;
v.X = Drawer_X2 + (count - 1); v.Z = Drawer_Z2; v.U = u2; v.V = v2; AddVertex; v.X = Drawer_X2 + (count - 1); v.Z = Drawer_Z2; v.U = u2; v.V = v2; *ptr++ = v;
v.X = Drawer_X1; v.U = u1; AddVertex; v.X = Drawer_X1; v.U = u1; *ptr++ = v;
v.Z = Drawer_Z1; v.V = v1; AddVertex; v.Z = Drawer_Z1; v.V = v1; *ptr++ = v;
v.X = Drawer_X2 + (count - 1); v.U = u2; AddVertex; v.X = Drawer_X2 + (count - 1); v.U = u2; *ptr++ = v;
*vertices = ptr; *vertices = ptr;
} }
@ -108,9 +106,9 @@ void Drawer_YMax(Int32 count, PackedCol col, TextureLoc texLoc, VertexP3fT2fC4b*
VertexP3fT2fC4b* ptr = *vertices; VertexP3fT2fC4b* ptr = *vertices;
VertexP3fT2fC4b v; v.Y = Drawer_Y2; v.Col = col; VertexP3fT2fC4b v; v.Y = Drawer_Y2; v.Col = col;
v.X = Drawer_X2 + (count - 1); v.Z = Drawer_Z1; v.U = u2; v.V = v1; AddVertex; v.X = Drawer_X2 + (count - 1); v.Z = Drawer_Z1; v.U = u2; v.V = v1; *ptr++ = v;
v.X = Drawer_X1; v.U = u1; AddVertex; v.X = Drawer_X1; v.U = u1; *ptr++ = v;
v.Z = Drawer_Z2; v.V = v2; AddVertex; v.Z = Drawer_Z2; v.V = v2; *ptr++ = v;
v.X = Drawer_X2 + (count - 1); v.U = u2; AddVertex; v.X = Drawer_X2 + (count - 1); v.U = u2; *ptr++ = v;
*vertices = ptr; *vertices = ptr;
} }

View File

@ -165,10 +165,10 @@ void EnvRenderer_DrawSkyY(Int32 x1, Int32 z1, Int32 x2, Int32 z2, Int32 y, Int32
z2 = z1 + axisSize; z2 = z1 + axisSize;
if (z2 > endZ) z2 = endZ; if (z2 > endZ) z2 = endZ;
v.X = (Real32)x1; v.Z = (Real32)z1; *vertices = v; vertices++; v.X = (Real32)x1; v.Z = (Real32)z1; *vertices++ = v;
v.Z = (Real32)z2; *vertices = v; vertices++; v.Z = (Real32)z2; *vertices++ = v;
v.X = (Real32)x2; *vertices = v; vertices++; v.X = (Real32)x2; *vertices++ = v;
v.Z = (Real32)z1; *vertices = v; vertices++; v.Z = (Real32)z1; *vertices++ = v;
} }
} }
} }
@ -190,10 +190,10 @@ void EnvRenderer_DrawCloudsY(Int32 x1, Int32 z1, Int32 x2, Int32 z2, Int32 y, In
Real32 u1 = (Real32)x1 / 2048.0f + offset, u2 = (Real32)x2 / 2048.0f + offset; Real32 u1 = (Real32)x1 / 2048.0f + offset, u2 = (Real32)x2 / 2048.0f + offset;
Real32 v1 = (Real32)z1 / 2048.0f + offset, v2 = (Real32)z2 / 2048.0f + offset; Real32 v1 = (Real32)z1 / 2048.0f + offset, v2 = (Real32)z2 / 2048.0f + offset;
v.X = (Real32)x1; v.Z = (Real32)z1; v.U = u1; v.V = v1; *vertices = v; vertices++; v.X = (Real32)x1; v.Z = (Real32)z1; v.U = u1; v.V = v1; *vertices++ = v;
v.Z = (Real32)z2; v.V = v2; *vertices = v; vertices++; v.Z = (Real32)z2; v.V = v2; *vertices++ = v;
v.X = (Real32)x2; v.U = u2; *vertices = v; vertices++; v.X = (Real32)x2; v.U = u2; *vertices++ = v;
v.Z = (Real32)z1; v.V = v1; *vertices = v; vertices++; v.Z = (Real32)z1; v.V = v1; *vertices++ = v;
} }
} }
} }

View File

@ -62,7 +62,7 @@ void Gfx_Clear(void);
void Gfx_ClearColour(PackedCol col); void Gfx_ClearColour(PackedCol col);
void Gfx_SetDepthTest(bool enabled); void Gfx_SetDepthTest(bool enabled);
void Gfx_SetDepthTestFunc(Int32 compareFunc); void Gfx_SetDepthTestFunc(Int32 compareFunc);
void Gfx_SetColourWrite(bool enabled); void Gfx_SetColourWriteMask(bool r, bool g, bool b, bool a);
void Gfx_SetDepthWrite(bool enabled); void Gfx_SetDepthWrite(bool enabled);
/* Creates a vertex buffer that can have its data dynamically updated. */ /* Creates a vertex buffer that can have its data dynamically updated. */

View File

@ -47,24 +47,27 @@ void PickedPosRenderer_Render(Real64 delta) {
} }
void PickedPosRenderer_XQuad(Real32 x, Real32 z1, Real32 y1, Real32 z2, Real32 y2) { void PickedPosRenderer_XQuad(Real32 x, Real32 z1, Real32 y1, Real32 z2, Real32 y2) {
VertexP3fC4b_Set(pickedPos_ptr, x, y1, z1, pickedPos_col); pickedPos_ptr++; VertexP3fC4b v; v.X = x; v.Col = pickedPos_col;
VertexP3fC4b_Set(pickedPos_ptr, x, y2, z1, pickedPos_col); pickedPos_ptr++; v.Y = y1; v.Z = z1; *pickedPos_ptr++ = v;
VertexP3fC4b_Set(pickedPos_ptr, x, y2, z2, pickedPos_col); pickedPos_ptr++; v.Y = y2; *pickedPos_ptr++ = v;
VertexP3fC4b_Set(pickedPos_ptr, x, y1, z2, pickedPos_col); pickedPos_ptr++; v.Z = z2; *pickedPos_ptr++ = v;
} v.Y = y1; *pickedPos_ptr++ = v;
void PickedPosRenderer_ZQuad(Real32 z, Real32 x1, Real32 y1, Real32 x2, Real32 y2) {
VertexP3fC4b_Set(pickedPos_ptr, x1, y1, z, pickedPos_col); pickedPos_ptr++;
VertexP3fC4b_Set(pickedPos_ptr, x1, y2, z, pickedPos_col); pickedPos_ptr++;
VertexP3fC4b_Set(pickedPos_ptr, x2, y2, z, pickedPos_col); pickedPos_ptr++;
VertexP3fC4b_Set(pickedPos_ptr, x2, y1, z, pickedPos_col); pickedPos_ptr++;
} }
void PickedPosRenderer_YQuad(Real32 y, Real32 x1, Real32 z1, Real32 x2, Real32 z2) { void PickedPosRenderer_YQuad(Real32 y, Real32 x1, Real32 z1, Real32 x2, Real32 z2) {
VertexP3fC4b_Set(pickedPos_ptr, x1, y, z1, pickedPos_col); pickedPos_ptr++; VertexP3fC4b v; v.Y = y; v.Col = pickedPos_col;
VertexP3fC4b_Set(pickedPos_ptr, x1, y, z2, pickedPos_col); pickedPos_ptr++; v.X = x1; v.Z = z1; *pickedPos_ptr++ = v;
VertexP3fC4b_Set(pickedPos_ptr, x2, y, z2, pickedPos_col); pickedPos_ptr++; v.Z = z2; *pickedPos_ptr++ = v;
VertexP3fC4b_Set(pickedPos_ptr, x2, y, z1, pickedPos_col); pickedPos_ptr++; v.X = x2; *pickedPos_ptr++ = v;
v.Z = z1; *pickedPos_ptr++ = v;
}
void PickedPosRenderer_ZQuad(Real32 z, Real32 x1, Real32 y1, Real32 x2, Real32 y2) {
VertexP3fC4b v; v.Z = z; v.Col = pickedPos_col;
v.X = x1; v.Y = y1; *pickedPos_ptr++ = v;
v.Y = y2; *pickedPos_ptr++ = v;
v.X = x2; *pickedPos_ptr++ = v;
v.Y = y1; *pickedPos_ptr++ = v;
} }
void PickedPosRenderer_UpdateState(PickedPos* selected) { void PickedPosRenderer_UpdateState(PickedPos* selected) {

View File

@ -456,7 +456,7 @@ void StatusScreen_Render(GuiElement* elem, Real64 delta) {
Widget_Render(&screen->Status, delta); Widget_Render(&screen->Status, delta);
if (!Game_ClassicMode && Gui_Active == NULL) { if (!Game_ClassicMode && Gui_Active == NULL) {
if (StatusScreen_HacksChanged(screen)) { StatusScreen_UpdateHackState(screen, false); } if (StatusScreen_HacksChanged(screen)) { StatusScreen_UpdateHackState(screen); }
StatusScreen_DrawPosition(screen); StatusScreen_DrawPosition(screen);
Widget_Render(&screen->HackStates, delta); Widget_Render(&screen->HackStates, delta);
} }
@ -974,7 +974,7 @@ bool HUDScreen_HandlesKeyDown(GuiElement* elem, Key key) {
if (key == playerListKey && handles) { if (key == playerListKey && handles) {
if (!screen->ShowingList && !ServerConnection_IsSinglePlayer) { if (!screen->ShowingList && !ServerConnection_IsSinglePlayer) {
screen->WasShowingList = true; screen->WasShowingList = true;
ContextRecreated(); HUDScreen_ContextRecreated(screen);
} }
return true; return true;
} }

View File

@ -1,12 +1,16 @@
#include "SelectionBox.h" #include "SelectionBox.h"
#include "ExtMath.h"
#include "GraphicsAPI.h"
#include "GraphicsCommon.h"
#include "Event.h"
#include "Funcs.h"
void SelectionBox_Make(SelectionBox* box, Vector3I* p1, Vector3I* p2, PackedCol col) { /* Data for a selection box. */
box->ID = 0; typedef struct SelectionBox_ {
box->MinDist = 0.0f; box->MaxDist = 0.0f; Vector3I Min, Max;
Vector3I_Min(&box->Min, p1, p2); PackedCol Col;
Vector3I_Max(&box->Max, p1, p2); Real32 MinDist, MaxDist;
box->Col = col; } SelectionBox;
}
void SelectionBox_Render(SelectionBox* box, VertexP3fC4b** vertices, VertexP3fC4b** lineVertices) { void SelectionBox_Render(SelectionBox* box, VertexP3fC4b** vertices, VertexP3fC4b** lineVertices) {
Real32 offset = box->MinDist < 32.0f * 32.0f ? (1.0f / 32.0f) : (1.0f / 16.0f); Real32 offset = box->MinDist < 32.0f * 32.0f ? (1.0f / 32.0f) : (1.0f / 16.0f);
@ -46,27 +50,197 @@ void SelectionBox_Render(SelectionBox* box, VertexP3fC4b** vertices, VertexP3fC4
void SelectionBox_VerQuad(VertexP3fC4b** vertices, PackedCol col, void SelectionBox_VerQuad(VertexP3fC4b** vertices, PackedCol col,
Real32 x1, Real32 y1, Real32 z1, Real32 x2, Real32 y2, Real32 z2) { Real32 x1, Real32 y1, Real32 z1, Real32 x2, Real32 y2, Real32 z2) {
VertexP3fC4b* ptr = *vertices; VertexP3fC4b* ptr = *vertices;
VertexP3fC4b_Set(ptr, x1, y1, z1, col); ptr++; VertexP3fC4b v; v.Col = col;
VertexP3fC4b_Set(ptr, x1, y2, z1, col); ptr++;
VertexP3fC4b_Set(ptr, x2, y2, z2, col); ptr++; v.X = x1; v.Y = y1; v.Z = z1; *ptr++ = v;
VertexP3fC4b_Set(ptr, x2, y1, z2, col); ptr++; v.Y = y2; *ptr++ = v;
v.X = x2; v.Z = z2; *ptr++ = v;
v.Y = y1; *ptr++ = v;
*vertices = ptr; *vertices = ptr;
} }
void SelectionBox_HorQuad(VertexP3fC4b** vertices, PackedCol col, void SelectionBox_HorQuad(VertexP3fC4b** vertices, PackedCol col,
Real32 x1, Real32 z1, Real32 x2, Real32 z2, Real32 y) { Real32 x1, Real32 z1, Real32 x2, Real32 z2, Real32 y) {
VertexP3fC4b* ptr = *vertices; VertexP3fC4b* ptr = *vertices;
VertexP3fC4b_Set(ptr, x1, y, z1, col); ptr++; VertexP3fC4b v; v.Y = y; v.Col = col;
VertexP3fC4b_Set(ptr, x1, y, z2, col); ptr++;
VertexP3fC4b_Set(ptr, x2, y, z2, col); ptr++; v.X = x1; v.Z = z1; *ptr++ = v;
VertexP3fC4b_Set(ptr, x2, y, z1, col); ptr++; v.Z = z2; *ptr++ = v;
v.X = x2; *ptr++ = v;
v.Z = z1; *ptr++ = v;
*vertices = ptr; *vertices = ptr;
} }
void SelectionBox_Line(VertexP3fC4b** vertices, PackedCol col, void SelectionBox_Line(VertexP3fC4b** vertices, PackedCol col,
Real32 x1, Real32 y1, Real32 z1, Real32 x2, Real32 y2, Real32 z2) { Real32 x1, Real32 y1, Real32 z1, Real32 x2, Real32 y2, Real32 z2) {
VertexP3fC4b* ptr = *vertices; VertexP3fC4b* ptr = *vertices;
VertexP3fC4b_Set(ptr, x1, y1, z1, col); ptr++; VertexP3fC4b v; v.Col = col;
VertexP3fC4b_Set(ptr, x2, y2, z2, col); ptr++;
v.X = x1; v.Y = y1; v.Z = z1; *ptr++ = v;
v.X = x2; v.Y = y2; v.Z = z2; *ptr++ = v;
*vertices = ptr; *vertices = ptr;
}
Int32 SelectionBox_Compare(SelectionBox* a, SelectionBox* b) {
Real32 aDist, bDist;
if (a->MinDist == b->MinDist) {
aDist = a->MaxDist; bDist = b->MaxDist;
} else {
aDist = a->MinDist; bDist = b->MinDist;
}
/* Reversed comparison order result, because we need to render back to front for alpha blending */
if (aDist < bDist) return 1;
if (aDist > bDist) return -1;
return 0;
}
void SelectionBox_UpdateDist(Vector3 p, Real32 x2, Real32 y2, Real32 z2, Real32* closest, Real32* furthest) {
Real32 dx = x2 - p.X, dy = y2 - p.Y, dz = z2 - p.Z;
Real32 dist = dx * dx + dy * dy + dz * dz;
if (dist < *closest) *closest = dist;
if (dist > *furthest) *furthest = dist;
}
void SelectionBox_Intersect(SelectionBox* box, Vector3 origin) {
Vector3I min = box->Min, max = box->Max;
Real32 closest = MATH_POS_INF, furthest = -MATH_POS_INF;
/* Bottom corners */
SelectionBox_UpdateDist(origin, min.X, min.Y, min.Z, &closest, &furthest);
SelectionBox_UpdateDist(origin, max.X, min.Y, min.Z, &closest, &furthest);
SelectionBox_UpdateDist(origin, max.X, min.Y, max.Z, &closest, &furthest);
SelectionBox_UpdateDist(origin, min.X, min.Y, max.Z, &closest, &furthest);
/* Top corners */
SelectionBox_UpdateDist(origin, min.X, max.Y, min.Z, &closest, &furthest);
SelectionBox_UpdateDist(origin, max.X, max.Y, min.Z, &closest, &furthest);
SelectionBox_UpdateDist(origin, max.X, max.Y, max.Z, &closest, &furthest);
SelectionBox_UpdateDist(origin, min.X, max.Y, max.Z, &closest, &furthest);
box->MinDist = closest; box->MaxDist = furthest;
}
#define SELECTIONS_MAX 256
#define SELECTIONS_VERTICES 24
#define SELECTIONS_MAX_VERTICES SELECTIONS_MAX * SELECTIONS_VERTICES
UInt32 selections_count;
SelectionBox selections_list[SELECTIONS_MAX];
UInt8 selections_ids[SELECTIONS_MAX];
GfxResourceID selections_VB, selections_LineVB;
bool selections_allocated;
void Selections_Add(UInt8 id, Vector3I p1, Vector3I p2, PackedCol col) {
SelectionBox sel;
Vector3I_Min(&sel.Min, &p1, &p2);
Vector3I_Max(&sel.Max, &p1, &p2);
sel.Col = col;
Selections_Remove(id);
selections_list[selections_count] = sel;
selections_ids[selections_count] = id;
selections_count++;
}
void Selections_Remove(UInt8 id) {
UInt32 i;
for (i = 0; i < selections_count; i++) {
if (selections_ids[i] != id) continue;
for (; i < selections_count - 1; i++) {
selections_list[i] = selections_list[i + 1];
selections_ids[i] = selections_ids[i + 1];
}
selections_count--;
return;
}
}
void Selections_ContextLost(void) {
Gfx_DeleteVb(&selections_VB);
Gfx_DeleteVb(&selections_LineVB);
}
void Selections_ContextRecreated(void) {
if (!selections_allocated) return;
selections_VB = Gfx_CreateDynamicVb(VERTEX_FORMAT_P3FC4B, SELECTIONS_MAX_VERTICES);
selections_LineVB = Gfx_CreateDynamicVb(VERTEX_FORMAT_P3FC4B, SELECTIONS_MAX_VERTICES);
}
void Selections_QuickSort(Int32 left, Int32 right) {
UInt8* values = selections_ids; UInt8 value;
SelectionBox* keys = selections_list; SelectionBox key;
while (left < right) {
Int32 i = left, j = right;
SelectionBox* pivot = &keys[(i + j) / 2];
/* partition the list */
while (i <= j) {
while (SelectionBox_Compare(pivot, &keys[i]) > 0) i++;
while (SelectionBox_Compare(pivot, &keys[j]) < 0) j--;
QuickSort_Swap_KV_Maybe();
}
/* recurse into the smaller subset */
QuickSort_Recurse(Selections_QuickSort)
}
}
void Selections_Render(Real64 delta) {
if (selections_count == 0 || Gfx_LostContext) return;
/* TODO: Proper selection box sorting. But this is very difficult because
we can have boxes within boxes, intersecting boxes, etc. Probably not worth it. */
Vector3 camPos = Game_CurrentCameraPos;
UInt32 i;
for (i = 0; i < selections_count; i++) {
SelectionBox_Intersect(&selections_list[i], camPos);
}
Selections_QuickSort(0, selections_count - 1);
if (!selections_allocated) { /* lazy init as most servers don't use this */
Selections_ContextRecreated();
selections_allocated = true;
}
VertexP3fC4b vertices[SELECTIONS_MAX_VERTICES]; VertexP3fC4b* ptr = vertices;
VertexP3fC4b lineVertices[SELECTIONS_MAX_VERTICES]; VertexP3fC4b* linePtr = lineVertices;
for (i = 0; i < selections_count; i++) {
SelectionBox_Render(&selections_list[i], &ptr, &linePtr);
}
Gfx_SetBatchFormat(VERTEX_FORMAT_P3FC4B);
GfxCommon_UpdateDynamicVb_Lines(selections_LineVB, lineVertices,
selections_count * SELECTIONS_VERTICES);
Gfx_SetDepthWrite(false);
Gfx_SetAlphaBlending(true);
GfxCommon_UpdateDynamicVb_IndexedTris(selections_VB, vertices,
selections_count * SELECTIONS_VERTICES);
Gfx_SetDepthWrite(true);
Gfx_SetAlphaBlending(false);
}
void Selections_Init(void) {
Event_RegisterVoid(&GfxEvents_ContextLost, NULL, Selections_ContextLost);
Event_RegisterVoid(&GfxEvents_ContextRecreated, NULL, Selections_ContextRecreated);
}
void Selections_Reset(void) {
selections_count = 0;
}
void Selections_Free(void) {
Selections_ContextLost();
Event_UnregisterVoid(&GfxEvents_ContextLost, NULL, Selections_ContextLost);
Event_UnregisterVoid(&GfxEvents_ContextRecreated, NULL, Selections_ContextRecreated);
}
IGameComponent Selections_MakeComponent(void) {
IGameComponent comp = IGameComponent_MakeEmpty();
comp.Init = Selections_Init;
comp.Free = Selections_Free;
comp.Reset = Selections_Reset;
comp.OnNewMap = Selections_Reset;
return comp;
} }

View File

@ -1,35 +1,13 @@
#ifndef CC_SELECTIONBOX_H #ifndef CC_SELECTIONBOX_H
#define CC_SELECTIONBOX_H #define CC_SELECTIONBOX_H
#include "Typedefs.h" #include "Typedefs.h"
#include "PackedCol.h"
#include "Vectors.h"
#include "VertexStructs.h" #include "VertexStructs.h"
#include "GameStructs.h"
#include "Vectors.h"
/* Describes a selection box, and contains methods related to the selection box. /* Describes a selection box, and contains methods related to the selection box.
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/ */
/* Data for a selection box. */
typedef struct SelectionBox_ {
/* ID of this selection box.*/
UInt8 ID;
/* Minimum corner of the box. */
Vector3I Min;
/* Maximum corner of the box. */
Vector3I Max;
/* Colour of this box. */
PackedCol Col;
/* Closest distance to player of any of the eight corners of the box. */
Real32 MinDist;
/* Furthest distance to player of any of the eight corners of the box. */
Real32 MaxDist;
} SelectionBox;
/* Constructs a selection box. */
void SelectionBox_Make(SelectionBox* box, Vector3I* p1, Vector3I* p2, PackedCol col);
/* Constructs the vertices and line vertices for a selection box. */
void SelectionBox_Render(SelectionBox* box, VertexP3fC4b** vertices, VertexP3fC4b** lineVertices);
/* Draws a vertical quad. */ /* Draws a vertical quad. */
void SelectionBox_VerQuad(VertexP3fC4b** vertices, PackedCol col, void SelectionBox_VerQuad(VertexP3fC4b** vertices, PackedCol col,
Real32 x1, Real32 y1, Real32 z1, Real32 x2, Real32 y2, Real32 z2); Real32 x1, Real32 y1, Real32 z1, Real32 x2, Real32 y2, Real32 z2);
@ -39,4 +17,9 @@ void SelectionBox_HorQuad(VertexP3fC4b** vertices, PackedCol col,
/* Draws a line between two points. */ /* Draws a line between two points. */
void SelectionBox_Line(VertexP3fC4b** vertices, PackedCol col, void SelectionBox_Line(VertexP3fC4b** vertices, PackedCol col,
Real32 x1, Real32 y1, Real32 z1, Real32 x2, Real32 y2, Real32 z2); Real32 x1, Real32 y1, Real32 z1, Real32 x2, Real32 y2, Real32 z2);
IGameComponent Selections_MakeComponent(void);
void Selections_Render(Real64 delta);
void Selections_Add(UInt8 id, Vector3I p1, Vector3I p2, PackedCol col);
void Selections_Remove(UInt8 id);
#endif #endif

View File

@ -151,15 +151,15 @@ void WeatherRenderer_Render(Real64 deltaTime) {
Real32 x1 = (Real32)x, y1 = (Real32)y, z1 = (Real32)z; Real32 x1 = (Real32)x, y1 = (Real32)y, z1 = (Real32)z;
Real32 x2 = (Real32)(x + 1), y2 = (Real32)(y + height), z2 = (Real32)(z + 1); Real32 x2 = (Real32)(x + 1), y2 = (Real32)(y + height), z2 = (Real32)(z + 1);
v.X = x1; v.Y = y1; v.Z = z1; v.U = 0.0f; v.V = v1; *ptr = v; ptr++; v.X = x1; v.Y = y1; v.Z = z1; v.U = 0.0f; v.V = v1; *ptr++ = v;
v.Y = y2; v.V = v2; *ptr = v; ptr++; v.Y = y2; v.V = v2; *ptr++ = v;
v.X = x2; v.Z = z2; v.U = 1.0f; *ptr = v; ptr++; v.X = x2; v.Z = z2; v.U = 1.0f; *ptr++ = v;
v.Y = y1; v.V = v1; *ptr = v; ptr++; v.Y = y1; v.V = v1; *ptr++ = v;
v.Z = z1; *ptr = v; ptr++; v.Z = z1; *ptr++ = v;
v.Y = y2; v.V = v2; *ptr = v; ptr++; v.Y = y2; v.V = v2; *ptr++ = v;
v.X = x1; v.Z = z2; v.U = 0.0f; *ptr = v; ptr++; v.X = x1; v.Z = z2; v.U = 0.0f; *ptr++ = v;
v.Y = y1; v.V = v1; *ptr = v; ptr++; v.Y = y1; v.V = v1; *ptr++ = v;
} }
} }

View File

@ -1993,7 +1993,7 @@ Int32 PlayerListWidget_GetGroupCount(PlayerListWidget* widget, UInt16 id, Int32
Int32 PlayerListWidget_PlayerCompare(UInt16 x, UInt16 y) { Int32 PlayerListWidget_PlayerCompare(UInt16 x, UInt16 y) {
UInt8 xRank = TabList_GroupRanks[x]; UInt8 xRank = TabList_GroupRanks[x];
UInt8 yRank = TabList_GroupRanks[y]; UInt8 yRank = TabList_GroupRanks[y];
if (xRank != yRank) return (xRank < yRank ? 1 : -1); if (xRank != yRank) return (xRank < yRank ? -1 : 1);
UInt8 xNameBuffer[String_BufferSize(STRING_SIZE)]; UInt8 xNameBuffer[String_BufferSize(STRING_SIZE)];
String xName = String_InitAndClearArray(xNameBuffer); String xName = String_InitAndClearArray(xNameBuffer);