Finish HacksComponent, integrate AutoRotate into Block header

This commit is contained in:
UnknownShadow200 2017-08-25 15:13:46 +10:00
parent 160d1874a6
commit b181be4af0
10 changed files with 168 additions and 197 deletions

View File

@ -157,15 +157,11 @@ namespace ClassicalSharp.GraphicsAPI {
int a1 = ((p1 & alphaMask) >> 24) & 0xFF;
int a2 = ((p2 & alphaMask) >> 24) & 0xFF;
int aSum = (a1 + a2);
aSum = aSum > 0 ? aSum : 2; // avoid divide by 0 below
aSum = aSum > 0 ? aSum : 1; // avoid divide by 0 below
// Convert RGB to pre-multiplied form
int r1 = ((p1 >> 16) & 0xFF) * a1;
int r2 = ((p2 >> 16) & 0xFF) * a2;
int g1 = ((p1 >> 8) & 0xFF) * a1;
int g2 = ((p2 >> 8) & 0xFF) * a2;
int b1 = (p1 & 0xFF) * a1;
int b2 = (p2 & 0xFF) * a2;
int r1 = ((p1 >> 16) & 0xFF) * a1, g1 = ((p1 >> 8) & 0xFF) * a1, b1 = (p1 & 0xFF) * a1;
int r2 = ((p2 >> 16) & 0xFF) * a2, g2 = ((p2 >> 8) & 0xFF) * a2, b2 = (p2 & 0xFF) * a2;
// https://stackoverflow.com/a/347376
// We need to convert RGB back from the pre-multiplied average into normal form

View File

@ -1,121 +0,0 @@
#if 0
#include "AutoRotate.h"
#include "Block.h"
#include "GameProps.h"
#include "LocationUpdate.h"
#include "LocalPlayer.h"
#include "Funcs.h"
#define AR_EQ1(s, x) (s.length >= 1 && Char_ToLower(s.buffer[0]) == x)
#define AR_EQ2(s, x, y) (s.length >= 2 && Char_ToLower(s.buffer[0]) == x && Char_ToLower(s.buffer[1]) == y)
BlockID AutoRotate_RotateBlock(BlockID block) {
String name = Block_Name[block];
Int32 dirIndex = String_LastIndexOf(&name, '-');
if (dirIndex == -1) return block; /* not a directional block */
String dir = name.Substring(dirIndex + 1);
name = name.Substring(0, dirIndex);
Vector3 translated, offset;
Vector3I_ToVector3(&translated, &Game_SelectedPos.TranslatedPos);
Vector3_Subtract(&offset, &Game_SelectedPos.Intersect, &translated);
if (AR_EQ2(dir, 'n','w') || AR_EQ2(dir, 'n','e') || AR_EQ2(dir, 's','w') || AR_EQ2(dir, 's','e')) {
return AutoRotate_RotateCorner(block, &name, offset);
} else if (AR_EQ1(dir, 'u') || AR_EQ1(dir, 'd')) {
return AutoRotate_RotateVertical(block, &name, offset);
} else if (AR_EQ1(dir, 'n') || AR_EQ1(dir, 'w') || AR_EQ1(dir, 's') || AR_EQ1(dir, 'e')) {
return AutoRotate_RotateDirection(block, &name, offset);
} else if (AR_EQ2(dir, 'u','d') || AR_EQ2(dir, 'w','e') || AR_EQ2(dir, 'n','s')) {
return AutoRotate_RotateOther(block, &name, offset);
}
return block;
}
BlockID AutoRotate_RotateCorner(BlockID block, String* name, Vector3 offset) {
if (offset.X < 0.5f && offset.Z < 0.5f) {
return AutoRotate_Find(block, name, "-NW");
} else if (offset.X >= 0.5f && offset.Z < 0.5f) {
return AutoRotate_Find(block, name, "-NE");
} else if (offset.X < 0.5f && offset.Z >= 0.5f) {
return AutoRotate_Find(block, name, "-SW");
} else if (offset.X >= 0.5f && offset.Z >= 0.5f) {
return AutoRotate_Find(block, name, "-SE");
}
return block;
}
BlockID AutoRotate_RotateVertical(BlockID block, String* name, Vector3 offset) {
if (offset.Y >= 0.5f) {
return AutoRotate_Find(block, name, "-U");
} else {
return AutoRotate_Find(block, name, "-D");
}
}
BlockID AutoRotate_RotateOther(BlockID block, String* name, Vector3 offset) {
/* Fence type blocks */
if (AutoRotate_Find(BlockID_Invalid, name, "-UD") == BlockID_Invalid) {
Real32 headY = LocalPlayer_Instance.Base.Base.HeadY;
headY = LocationUpdate_Clamp(headY);
if (headY < 45.0f || (headY >= 135.0f && headY < 225.0f) || headY > 315.0f) {
return AutoRotate_Find(block, name, "-WE");
} else {
return AutoRotate_Find(block, name, "-NS");
}
}
/* Thin pillar type blocks */
Face face = Game_SelectedPos.ClosestFace;
if (face == Face_YMax || face == Face_YMin)
return AutoRotate_Find(block, name, "-UD");
if (face == Face_XMax || face == Face_XMin)
return AutoRotate_Find(block, name, "-WE");
if (face == Face_ZMax || face == Face_ZMin)
return AutoRotate_Find(block, name, "-NS");
return block;
}
BlockID AutoRotate_RotateDirection(BlockID block, String* name, Vector3 offset) {
Vector3 SE = Vector3_Create3(+1.0f, 0.0f, 1.0f);
Vector3 SW = Vector3_Create3(-1.0f, 0.0f, 1.0f);
Vector3I pos = Game_SelectedPos.TranslatedPos;
Vector3 exact = Game_SelectedPos.Intersect;
Vector3 exactFlat = exact; exactFlat.Y = 0.0f;
Vector3 SEToPoint = exactFlat; SEToPoint.X -= pos.X; SEToPoint.Z -= pos.Z;
Vector3 SWToPoint = exactFlat; SWToPoint.X -= (pos.X + 1); SWToPoint.Z -= pos.Z;
Real32 dotSE = Vector3_Dot(&SEToPoint, &SW);
Real32 dotSW = Vector3_Dot(&SWToPoint, &SE);
if (dotSE <= 0.0f) { /* NorthEast */
if (dotSW <= 0.0f) { /* NorthWest */
return AutoRotate_Find(block, name, "-N");
} else { /* SouthEast */
return AutoRotate_Find(block, name, "-E");
}
} else { /* SouthWest */
if (dotSW <= 0.0f) { /* NorthWest */
return AutoRotate_Find(block, name, "-W");
} else { /* SouthEast */
return AutoRotate_Find(block, name, "-S");
}
}
}
static BlockID AutoRotate_Find(BlockID block, String* name, const UInt8* suffix) {
UInt8 buffer[String_BufferSize(128)];
String temp = String_FromRawBuffer(buffer, 128);
String_AppendString(&temp, name);
String_AppendConstant(&temp, suffix);
Int32 rotated = Block_FindID(&temp);
if (rotated != -1) return (BlockID)rotated;
return block;
}
#endif

View File

@ -1,27 +0,0 @@
#if 0
#ifndef CS_AUTOROTATE_H
#define CS_AUTOROTATE_H
#include "Typedefs.h"
#include "BlockID.h"
#include "String.h"
#include "Vectors.h"
/* Performs automatic rotation of directional blocks.
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/
/* Attempts to find the rotated block based on the user's orientation and offset on selected block. */
BlockID AutoRotate_RotateBlock(BlockID block);
static BlockID AutoRotate_RotateCorner(BlockID block, String* name, Vector3 offset);
static BlockID AutoRotate_RotateVertical(BlockID block, String* name, Vector3 offset);
static BlockID AutoRotate_RotateOther(BlockID block, String* name, Vector3 offset);
static BlockID AutoRotate_RotateDirection(BlockID block, String* name, Vector3 offset);
static BlockID AutoRotate_Find(BlockID block, String* name, const UInt8* suffix);
#endif
#endif

View File

@ -3,6 +3,22 @@
#include "Funcs.h"
#include "ExtMath.h"
#include "TerrainAtlas.h"
#include "Player.h"
TextureLoc Block_TopTex[Block_CpeCount] = { 0, 1, 0, 2, 16, 4, 15, 17, 14, 14,
30, 30, 18, 19, 32, 33, 34, 21, 22, 48, 49, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 24, 23, 6, 6, 7, 9, 4,
36, 37, 16, 11, 25, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 26, 53, 52, };
TextureLoc Block_SideTex[Block_CpeCount] = { 0, 1, 3, 2, 16, 4, 15, 17, 14, 14,
30, 30, 18, 19, 32, 33, 34, 20, 22, 48, 49, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 40, 39, 5, 5, 7, 8, 35,
36, 37, 16, 11, 41, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 42, 53, 52, };
TextureLoc Block_BottomTex[Block_CpeCount] = { 0, 1, 2, 2, 16, 4, 15, 17, 14, 14,
30, 30, 18, 19, 32, 33, 34, 21, 22, 48, 49, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 56, 55, 6, 6, 7, 10, 4,
36, 37, 16, 11, 57, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 58, 53, 52 };
void Block_Reset(void) {
Block_Init();
@ -102,9 +118,9 @@ void Block_ResetProps(BlockID block) {
Block_SetSide(0, block);
#endif
} else {
Block_SetTex(topTex[block], Face_YMax, block);
Block_SetTex(bottomTex[block], Face_YMin, block);
Block_SetSide(sideTex[block], block);
Block_SetTex(Block_TopTex[block], Face_YMax, block);
Block_SetTex(Block_BottomTex[block], Face_YMin, block);
Block_SetSide(Block_SideTex[block], block);
}
}
@ -423,4 +439,117 @@ void Block_SetXStretch(BlockID block, bool stretch) {
void Block_SetZStretch(BlockID block, bool stretch) {
Block_CanStretch[block] &= 0xFC; /* ~0x03 */
Block_CanStretch[block] |= (stretch ? 0x03 : (UInt8)0);
}
#define AR_EQ1(s, x) (s.length >= 1 && Char_ToLower(s.buffer[0]) == x)
#define AR_EQ2(s, x, y) (s.length >= 2 && Char_ToLower(s.buffer[0]) == x && Char_ToLower(s.buffer[1]) == y)
BlockID AutoRotate_Find(BlockID block, String* name, const UInt8* suffix) {
UInt8 buffer[String_BufferSize(128)];
String temp = String_FromRawBuffer(buffer, 128);
String_AppendString(&temp, name);
String_AppendConstant(&temp, suffix);
Int32 rotated = Block_FindID(&temp);
if (rotated != -1) return (BlockID)rotated;
return block;
}
BlockID AutoRotate_RotateCorner(BlockID block, String* name, Vector3 offset) {
if (offset.X < 0.5f && offset.Z < 0.5f) {
return AutoRotate_Find(block, name, "-NW");
} else if (offset.X >= 0.5f && offset.Z < 0.5f) {
return AutoRotate_Find(block, name, "-NE");
} else if (offset.X < 0.5f && offset.Z >= 0.5f) {
return AutoRotate_Find(block, name, "-SW");
} else if (offset.X >= 0.5f && offset.Z >= 0.5f) {
return AutoRotate_Find(block, name, "-SE");
}
return block;
}
BlockID AutoRotate_RotateVertical(BlockID block, String* name, Vector3 offset) {
if (offset.Y >= 0.5f) {
return AutoRotate_Find(block, name, "-U");
} else {
return AutoRotate_Find(block, name, "-D");
}
}
BlockID AutoRotate_RotateOther(BlockID block, String* name, Vector3 offset) {
/* Fence type blocks */
if (AutoRotate_Find(BlockID_Invalid, name, "-UD") == BlockID_Invalid) {
Real32 headY = LocalPlayer_Instance.Base.Base.HeadY;
headY = LocationUpdate_Clamp(headY);
if (headY < 45.0f || (headY >= 135.0f && headY < 225.0f) || headY > 315.0f) {
return AutoRotate_Find(block, name, "-WE");
} else {
return AutoRotate_Find(block, name, "-NS");
}
}
/* Thin pillar type blocks */
Face face = Game_SelectedPos.ClosestFace;
if (face == Face_YMax || face == Face_YMin)
return AutoRotate_Find(block, name, "-UD");
if (face == Face_XMax || face == Face_XMin)
return AutoRotate_Find(block, name, "-WE");
if (face == Face_ZMax || face == Face_ZMin)
return AutoRotate_Find(block, name, "-NS");
return block;
}
BlockID AutoRotate_RotateDirection(BlockID block, String* name, Vector3 offset) {
Vector3 SE = Vector3_Create3(+1.0f, 0.0f, 1.0f);
Vector3 SW = Vector3_Create3(-1.0f, 0.0f, 1.0f);
Vector3I pos = Game_SelectedPos.TranslatedPos;
Vector3 exact = Game_SelectedPos.Intersect;
Vector3 exactFlat = exact; exactFlat.Y = 0.0f;
Vector3 SEToPoint = exactFlat; SEToPoint.X -= pos.X; SEToPoint.Z -= pos.Z;
Vector3 SWToPoint = exactFlat; SWToPoint.X -= (pos.X + 1); SWToPoint.Z -= pos.Z;
Real32 dotSE = Vector3_Dot(&SEToPoint, &SW);
Real32 dotSW = Vector3_Dot(&SWToPoint, &SE);
if (dotSE <= 0.0f) { /* NorthEast */
if (dotSW <= 0.0f) { /* NorthWest */
return AutoRotate_Find(block, name, "-N");
} else { /* SouthEast */
return AutoRotate_Find(block, name, "-E");
}
} else { /* SouthWest */
if (dotSW <= 0.0f) { /* NorthWest */
return AutoRotate_Find(block, name, "-W");
} else { /* SouthEast */
return AutoRotate_Find(block, name, "-S");
}
}
}
BlockID AutoRotate_RotateBlock(BlockID block) {
String name = Block_Name[block];
Int32 dirIndex = String_LastIndexOf(&name, '-');
if (dirIndex == -1) return block; /* not a directional block */
String dir = String_UNSAFE_SubstringAt(&name, dirIndex + 1);
String baseName = String_UNSAFE_Substring(&name, 0, dirIndex);
Vector3 translated, offset;
Vector3I_ToVector3(&translated, &Game_SelectedPos.TranslatedPos);
Vector3_Subtract(&offset, &Game_SelectedPos.Intersect, &translated);
if (AR_EQ2(dir, 'n', 'w') || AR_EQ2(dir, 'n', 'e') || AR_EQ2(dir, 's', 'w') || AR_EQ2(dir, 's', 'e')) {
return AutoRotate_RotateCorner(block, &baseName, offset);
} else if (AR_EQ1(dir, 'u') || AR_EQ1(dir, 'd')) {
return AutoRotate_RotateVertical(block, &baseName, offset);
} else if (AR_EQ1(dir, 'n') || AR_EQ1(dir, 'w') || AR_EQ1(dir, 's') || AR_EQ1(dir, 'e')) {
return AutoRotate_RotateDirection(block, &baseName, offset);
} else if (AR_EQ2(dir, 'u', 'd') || AR_EQ2(dir, 'w', 'e') || AR_EQ2(dir, 'n', 's')) {
return AutoRotate_RotateOther(block, &baseName, offset);
}
return block;
}

View File

@ -9,7 +9,8 @@
#include "Bitmap.h"
#include "Constants.h"
#include "Compiler.h"
/* Stores properties and data for blocks
/* Stores properties and data for blocks.
Also performs automatic rotation of directional blocks.
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/
@ -242,20 +243,6 @@ static void Block_SetXStretch(BlockID block, bool stretch);
static void Block_SetZStretch(BlockID block, bool stretch);
static TextureLoc topTex[Block_CpeCount] = { 0, 1, 0, 2, 16, 4, 15, 17, 14, 14,
30, 30, 18, 19, 32, 33, 34, 21, 22, 48, 49, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 24, 23, 6, 6, 7, 9, 4,
36, 37, 16, 11, 25, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 26, 53, 52, };
static TextureLoc sideTex[Block_CpeCount] = { 0, 1, 3, 2, 16, 4, 15, 17, 14, 14,
30, 30, 18, 19, 32, 33, 34, 20, 22, 48, 49, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 40, 39, 5, 5, 7, 8, 35,
36, 37, 16, 11, 41, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 42, 53, 52, };
static TextureLoc bottomTex[Block_CpeCount] = { 0, 1, 2, 2, 16, 4, 15, 17, 14, 14,
30, 30, 18, 19, 32, 33, 34, 21, 22, 48, 49, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 56, 55, 6, 6, 7, 10, 4,
36, 37, 16, 11, 57, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 58, 53, 52 };
/* Attempts to find the rotated block based on the user's orientation and offset on selected block. */
BlockID AutoRotate_RotateBlock(BlockID block);
#endif

View File

@ -175,7 +175,6 @@
<ItemGroup>
<ClInclude Include="2DStructs.h" />
<ClInclude Include="AABB.h" />
<ClInclude Include="AutoRotate.h" />
<ClInclude Include="AxisLinesRenderer.h" />
<ClInclude Include="BlockID.h" />
<ClInclude Include="Block.h" />
@ -249,7 +248,6 @@
<ClCompile Include="2DStructs.c" />
<ClCompile Include="AABB.c" />
<ClCompile Include="EntityComponents.c" />
<ClCompile Include="AutoRotate.c" />
<ClCompile Include="AxisLinesRenderer.c" />
<ClCompile Include="Block.c" />
<ClCompile Include="BordersRenderer.c" />

View File

@ -342,9 +342,6 @@
<ClInclude Include="ModelCache.h">
<Filter>Header Files\Entities\Model</Filter>
</ClInclude>
<ClInclude Include="AutoRotate.h">
<Filter>Header Files\Blocks</Filter>
</ClInclude>
<ClInclude Include="DisplayDevice.h">
<Filter>Header Files\Platform\Window</Filter>
</ClInclude>
@ -515,9 +512,6 @@
<ClCompile Include="ModelCache.c">
<Filter>Source Files\Entities\Model</Filter>
</ClCompile>
<ClCompile Include="AutoRotate.c">
<Filter>Source Files\Blocks</Filter>
</ClCompile>
<ClCompile Include="TiltComp.c">
<Filter>Source Files\Entities\Components</Filter>
</ClCompile>

View File

@ -166,10 +166,10 @@ void HacksComponent_ParseHorizontalSpeed(HacksComponent* hacks) {
Int32 end = String_IndexOf(joined, ' ', start);
if (end < 0) end = joined->length;
string num = joined.Substring(start, end - start);
Real32 value = 0.0f;
if (!Convert_TryParseReal32(num, &value) || value <= 0.0f) return;
hacks->MaxSpeedMultiplier = value;
String speedStr = String_UNSAFE_Substring(joined, start, end - start);
Real32 speed = 0.0f;
if (!Convert_TryParseReal32(&speedStr, &speed) || speed <= 0.0f) return;
hacks->MaxSpeedMultiplier = speed;
}
void HacksComponent_ParseFlag(HacksComponent* hacks, const UInt8* incFlag, const UInt8* excFlag, bool* target) {

View File

@ -1,5 +1,6 @@
#include "String.h"
#include "Funcs.h"
#include "ErrorHandler.h"
String String_FromEmptyBuffer(UInt8* buffer, UInt16 capacity) {
String str;
@ -54,6 +55,24 @@ void String_Clear(STRING_TRANSIENT String* str) {
str->length = 0;
}
String String_UNSAFE_Substring(STRING_REF String* str, Int32 offset, Int32 length) {
if (offset < 0 || offset > str->length) {
ErrorHandler_Fail("Offset for substring out of range");
}
if (length < 0 || length > str->length) {
ErrorHandler_Fail("Length for substring out of range");
}
if (offset + length > str->length) {
ErrorHandler_Fail("Result substring is out of range");
}
String sub = *str;
sub.buffer += offset;
sub.length = length;
sub.capacity = length;
return sub;
}
bool String_Equals(STRING_TRANSIENT String* a, STRING_TRANSIENT String* b) {
if (a->length != b->length) return false;
@ -186,14 +205,6 @@ Int32 String_IndexOfString(STRING_TRANSIENT String* str, STRING_TRANSIENT String
return -1;
}
bool String_ContainsString(STRING_TRANSIENT String* str, STRING_TRANSIENT String* sub) {
return String_IndexOfString(str, sub) >= 0;
}
bool String_StartsWith(STRING_TRANSIENT String* str, STRING_TRANSIENT String* sub) {
return String_IndexOfString(str, sub) == 0;
}
#define Convert_ControlCharsCount 32
UInt16 Convert_ControlChars[Convert_ControlCharsCount] = {

View File

@ -35,6 +35,10 @@ String String_MakeNull(void);
void String_MakeLowercase(STRING_TRANSIENT String* str);
/* Sets all characters in the given string to NULL, then sets length t0 0. */
void String_Clear(STRING_TRANSIENT String* str);
/* Returns a string that points directly to a substring of the given string.
NOTE: THIS IS UNSAFE - IT MAINTAINS A REFERENCE TO THE ORIGINAL BUFFER, AND THE SUBSTRING IS NOT NULL TERMINATED */
String String_UNSAFE_Substring(STRING_REF String* str, Int32 offset, Int32 length);
#define String_UNSAFE_SubstringAt(str, offset) (String_UNSAFE_Substring(str, offset, (str)->length - (offset)))
/* Returns whether two strings have same contents. */
bool String_Equals(STRING_TRANSIENT String* a, STRING_TRANSIENT String* b);
@ -62,9 +66,9 @@ UInt8 String_CharAt(STRING_TRANSIENT String* str, Int32 offset);
/* Find the first index of sub in given string, -1 if not found. */
Int32 String_IndexOfString(STRING_TRANSIENT String* str, STRING_TRANSIENT String* sub);
/* Returns whether sub is contained within string. */
bool String_ContainsString(STRING_TRANSIENT String* str, STRING_TRANSIENT String* sub);
#define String_ContainsString(str, sub) (String_IndexOfString(str, sub) >= 0)
/* Returns whether given string starts with sub. */
bool String_StartsWith(STRING_TRANSIENT String* str, STRING_TRANSIENT String* sub);
#define String_StartsWith(str, sub) (String_IndexOfString(str, sub) == 0)
/* Converts a code page 437 index into a unicode character. */
UInt16 Convert_CP437ToUnicode(UInt8 c);