From ea712c67a3fa468a65e7b4dfc24f69315cad2265 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sun, 10 Jun 2018 15:24:05 +1000 Subject: [PATCH] Fix crashing with sprite textures above 255 --- ClassicalSharp/Blocks/BlockInfo.BoundsBox.cs | 69 ++++++++++---------- src/Client/Animations.c | 2 +- src/Client/Block.c | 24 +++---- src/Client/Options.c | 4 +- src/Client/TerrainAtlas.c | 2 +- src/Client/TerrainAtlas.h | 2 + src/Client/WinPlatform.c | 10 +-- 7 files changed, 59 insertions(+), 54 deletions(-) diff --git a/ClassicalSharp/Blocks/BlockInfo.BoundsBox.cs b/ClassicalSharp/Blocks/BlockInfo.BoundsBox.cs index 61e8343ac..d3cf11495 100644 --- a/ClassicalSharp/Blocks/BlockInfo.BoundsBox.cs +++ b/ClassicalSharp/Blocks/BlockInfo.BoundsBox.cs @@ -54,43 +54,24 @@ namespace ClassicalSharp { const float angle = 45f * Utils.Deg2Rad; static readonly Vector3 centre = new Vector3(0.5f, 0, 0.5f); internal static void RecalculateBB(BlockID block, FastBitmap fastBmp) { - int elemSize = fastBmp.Width / 16; - int texId = GetTextureLoc(block, Side.Right); - int texX = texId & 0x0F, texY = texId >> 4; + int tileSize = Atlas2D.TileSize; + int texLoc = GetTextureLoc(block, Side.Right); + int x = texLoc % Atlas2D.TilesPerRow, y = texLoc / Atlas2D.TilesPerRow; - float topY = GetSpriteBB_TopY(elemSize, texX, texY, fastBmp); - float bottomY = GetSpriteBB_BottomY(elemSize, texX, texY, fastBmp); - float leftX = GetSpriteBB_LeftX(elemSize, texX, texY, fastBmp); - float rightX = GetSpriteBB_RightX(elemSize, texX, texY, fastBmp); + float minX = 0, minY = 0, maxX = 1, maxY = 1; + if (y < Atlas2D.RowsCount) { + minX = GetSpriteBB_MinX(tileSize, x, y, fastBmp); + minY = GetSpriteBB_MinY(tileSize, x, y, fastBmp); + maxX = GetSpriteBB_MaxX(tileSize, x, y, fastBmp); + maxY = GetSpriteBB_MaxY(tileSize, x, y, fastBmp); + } - MinBB[block] = Utils.RotateY(leftX - 0.5f, bottomY, 0, angle) + centre; - MaxBB[block] = Utils.RotateY(rightX - 0.5f, topY, 0, angle) + centre; + MinBB[block] = Utils.RotateY(minX - 0.5f, minY, 0, angle) + centre; + MaxBB[block] = Utils.RotateY(maxX - 0.5f, maxY, 0, angle) + centre; CalcRenderBounds(block); } - unsafe static float GetSpriteBB_TopY(int size, int tileX, int tileY, FastBitmap fastBmp) { - for (int y = 0; y < size; y++) { - int* row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size); - for (int x = 0; x < size; x++) { - if ((byte)(row[x] >> 24) != 0) - return 1 - (float)y / size; - } - } - return 0; - } - - unsafe static float GetSpriteBB_BottomY(int size, int tileX, int tileY, FastBitmap fastBmp) { - for (int y = size - 1; y >= 0; y--) { - int* row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size); - for (int x = 0; x < size; x++) { - if ((byte)(row[x] >> 24) != 0) - return 1 - (float)(y + 1) / size; - } - } - return 1; - } - - unsafe static float GetSpriteBB_LeftX(int size, int tileX, int tileY, FastBitmap fastBmp) { + unsafe static float GetSpriteBB_MinX(int size, int tileX, int tileY, FastBitmap fastBmp) { for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { int* row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size); @@ -101,7 +82,18 @@ namespace ClassicalSharp { return 1; } - unsafe static float GetSpriteBB_RightX(int size, int tileX, int tileY, FastBitmap fastBmp) { + unsafe static float GetSpriteBB_MinY(int size, int tileX, int tileY, FastBitmap fastBmp) { + for (int y = size - 1; y >= 0; y--) { + int* row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size); + for (int x = 0; x < size; x++) { + if ((byte)(row[x] >> 24) != 0) + return 1 - (float)(y + 1) / size; + } + } + return 1; + } + + unsafe static float GetSpriteBB_MaxX(int size, int tileX, int tileY, FastBitmap fastBmp) { for (int x = size - 1; x >= 0; x--) { for (int y = 0; y < size; y++) { int* row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size); @@ -110,6 +102,17 @@ namespace ClassicalSharp { } } return 0; + } + + unsafe static float GetSpriteBB_MaxY(int size, int tileX, int tileY, FastBitmap fastBmp) { + for (int y = 0; y < size; y++) { + int* row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size); + for (int x = 0; x < size; x++) { + if ((byte)(row[x] >> 24) != 0) + return 1 - (float)y / size; + } + } + return 0; } } } \ No newline at end of file diff --git a/src/Client/Animations.c b/src/Client/Animations.c index 479b9ca0e..908a534c4 100644 --- a/src/Client/Animations.c +++ b/src/Client/Animations.c @@ -267,7 +267,7 @@ static void Animations_Validate(void) { Int32 maxX = data.FrameX + data.FrameSize * data.StatesCount; String_Clear(&msg); - Int32 tileX = data.TexLoc % ATLAS2D_TILES_PER_ROW, tileY = data.TexLoc / ATLAS2D_TILES_PER_ROW; + Int32 tileX = Atlas2D_TileX(data.TexLoc), tileY = Atlas2D_TileY(data.TexLoc); if (data.FrameSize > Atlas2D_TileSize) { String_Format2(&msg, "&cAnimation frames for tile (%i, %i) are bigger than the size of a tile in terrain.png", &tileX, &tileY); } else if (maxX > anims_bmp.Width || maxY > anims_bmp.Height) { diff --git a/src/Client/Block.c b/src/Client/Block.c index d9561dc83..e976bf33a 100644 --- a/src/Client/Block.c +++ b/src/Client/Block.c @@ -263,7 +263,7 @@ void Block_RecalculateSpriteBB(void) { } } -static Real32 Block_GetSpriteBB_TopY(Int32 size, Int32 tileX, Int32 tileY, Bitmap* bmp) { +static Real32 Block_GetSpriteBB_MaxY(Int32 size, Int32 tileX, Int32 tileY, Bitmap* bmp) { Int32 x, y; for (y = 0; y < size; y++) { UInt32* row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size); @@ -276,7 +276,7 @@ static Real32 Block_GetSpriteBB_TopY(Int32 size, Int32 tileX, Int32 tileY, Bitma return 0; } -static Real32 Block_GetSpriteBB_BottomY(Int32 size, Int32 tileX, Int32 tileY, Bitmap* bmp) { +static Real32 Block_GetSpriteBB_MinY(Int32 size, Int32 tileX, Int32 tileY, Bitmap* bmp) { Int32 x, y; for (y = size - 1; y >= 0; y--) { UInt32* row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size); @@ -289,7 +289,7 @@ static Real32 Block_GetSpriteBB_BottomY(Int32 size, Int32 tileX, Int32 tileY, Bi return 1; } -static Real32 Block_GetSpriteBB_LeftX(Int32 size, Int32 tileX, Int32 tileY, Bitmap* bmp) { +static Real32 Block_GetSpriteBB_MinX(Int32 size, Int32 tileX, Int32 tileY, Bitmap* bmp) { Int32 x, y; for (x = 0; x < size; x++) { for (y = 0; y < size; y++) { @@ -302,7 +302,7 @@ static Real32 Block_GetSpriteBB_LeftX(Int32 size, Int32 tileX, Int32 tileY, Bitm return 1; } -static Real32 Block_GetSpriteBB_RightX(Int32 size, Int32 tileX, Int32 tileY, Bitmap* bmp) { +static Real32 Block_GetSpriteBB_MaxX(Int32 size, Int32 tileX, Int32 tileY, Bitmap* bmp) { Int32 x, y; for (x = size - 1; x >= 0; x--) { for (y = 0; y < size; y++) { @@ -317,18 +317,18 @@ static Real32 Block_GetSpriteBB_RightX(Int32 size, Int32 tileX, Int32 tileY, Bit void Block_RecalculateBB(BlockID block) { Bitmap* bmp = &Atlas2D_Bitmap; - Int32 elemSize = Atlas2D_TileSize; + Int32 tileSize = Atlas2D_TileSize; TextureLoc texLoc = Block_GetTexLoc(block, FACE_XMAX); - Int32 texX = texLoc & 0x0F, texY = texLoc >> 4; + Int32 x = Atlas2D_TileX(texLoc), y = Atlas2D_TileY(texLoc); - Real32 topY = Block_GetSpriteBB_TopY(elemSize, texX, texY, bmp); - Real32 bottomY = Block_GetSpriteBB_BottomY(elemSize, texX, texY, bmp); - Real32 leftX = Block_GetSpriteBB_LeftX(elemSize, texX, texY, bmp); - Real32 rightX = Block_GetSpriteBB_RightX(elemSize, texX, texY, bmp); + Real32 minX = Block_GetSpriteBB_MinX(tileSize, x, y, bmp); + Real32 minY = Block_GetSpriteBB_MinY(tileSize, x, y, bmp); + Real32 maxX = Block_GetSpriteBB_RaxX(tileSize, x, y, bmp); + Real32 maxY = Block_GetSpriteBB_MaxY(tileSize, x, y, bmp); Vector3 centre = VECTOR3_CONST(0.5f, 0.0f, 0.5f); - Vector3 minRaw = Vector3_RotateY3(leftX - 0.5f, bottomY, 0, 45.0f * MATH_DEG2RAD); - Vector3 maxRaw = Vector3_RotateY3(rightX - 0.5f, topY, 0, 45.0f * MATH_DEG2RAD); + Vector3 minRaw = Vector3_RotateY3(minX - 0.5f, minY, 0.0f, 45.0f * MATH_DEG2RAD); + Vector3 maxRaw = Vector3_RotateY3(maxX - 0.5f, maxY, 0.0f, 45.0f * MATH_DEG2RAD); Vector3_Add(&Block_MinBB[block], &minRaw, ¢re); Vector3_Add(&Block_MaxBB[block], &maxRaw, ¢re); diff --git a/src/Client/Options.c b/src/Client/Options.c index c9a18660d..b7a6437b2 100644 --- a/src/Client/Options.c +++ b/src/Client/Options.c @@ -165,7 +165,7 @@ void Options_Load(void) { /* TODO: Should we just log failure to open? */ ErrorHandler_CheckOrFail(result, "Options - Loading"); - UInt8 lineBuffer[String_BufferSize(2048)]; + UInt8 lineBuffer[String_BufferSize(768)]; String line = String_InitAndClearArray(lineBuffer); Stream stream; Stream_FromFile(&stream, file, &path); @@ -209,7 +209,7 @@ void Options_Save(void) { /* TODO: Should we just log failure to save? */ ErrorHandler_CheckOrFail(result, "Options - Saving"); - UInt8 lineBuffer[String_BufferSize(2048)]; + UInt8 lineBuffer[String_BufferSize(1024)]; String line = String_InitAndClearArray(lineBuffer); Stream stream; Stream_FromFile(&stream, file, &path); UInt32 i; diff --git a/src/Client/TerrainAtlas.c b/src/Client/TerrainAtlas.c index 897be9948..f98aee318 100644 --- a/src/Client/TerrainAtlas.c +++ b/src/Client/TerrainAtlas.c @@ -14,7 +14,7 @@ void Atlas2D_UpdateState(Bitmap* bmp) { static GfxResourceID Atlas2D_LoadTextureElement_Raw(TextureLoc texLoc, Bitmap* element) { Int32 size = Atlas2D_TileSize; - Int32 x = texLoc % ATLAS2D_TILES_PER_ROW, y = texLoc / ATLAS2D_TILES_PER_ROW; + Int32 x = Atlas2D_TileX(texLoc), y = Atlas2D_TileY(texLoc); Bitmap_CopyBlock(x * size, y * size, 0, 0, &Atlas2D_Bitmap, element, size); return Gfx_CreateTexture(element, false, Gfx_Mipmaps); diff --git a/src/Client/TerrainAtlas.h b/src/Client/TerrainAtlas.h index 15282c98b..feb86c40c 100644 --- a/src/Client/TerrainAtlas.h +++ b/src/Client/TerrainAtlas.h @@ -15,6 +15,8 @@ void Atlas2D_UpdateState(Bitmap* bmp); /* Creates a native texture that contains the tile at the specified index. */ GfxResourceID Atlas2D_LoadTile(TextureLoc texLoc); void Atlas2D_Free(void); +#define Atlas2D_TileX(texLoc) ((texLoc) % ATLAS2D_TILES_PER_ROW) +#define Atlas2D_TileY(texLoc) ((texLoc) / ATLAS2D_TILES_PER_ROW) /* The theoretical largest number of 1D atlases that a 2D atlas can be broken down into. */ #define ATLAS1D_MAX_ATLASES (ATLAS2D_TILES_PER_ROW * ATLAS2D_ROWS_COUNT) diff --git a/src/Client/WinPlatform.c b/src/Client/WinPlatform.c index 2c32b1eb9..07aada4bc 100644 --- a/src/Client/WinPlatform.c +++ b/src/Client/WinPlatform.c @@ -160,11 +160,11 @@ void Platform_Log4(const UInt8* format, const void* a1, const void* a2, const vo void Platform_FromSysTime(DateTime* time, SYSTEMTIME* sysTime) { time->Year = sysTime->wYear; - time->Month = (UInt8)sysTime->wMonth; - time->Day = (UInt8)sysTime->wDay; - time->Hour = (UInt8)sysTime->wHour; - time->Minute = (UInt8)sysTime->wMinute; - time->Second = (UInt8)sysTime->wSecond; + time->Month = sysTime->wMonth; + time->Day = sysTime->wDay; + time->Hour = sysTime->wHour; + time->Minute = sysTime->wMinute; + time->Second = sysTime->wSecond; time->Milli = sysTime->wMilliseconds; }