Fix crashing with sprite textures above 255

This commit is contained in:
UnknownShadow200 2018-06-10 15:24:05 +10:00
parent 76f8726951
commit ea712c67a3
7 changed files with 59 additions and 54 deletions

View File

@ -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;
}
}
}

View File

@ -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) {

View File

@ -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, &centre);
Vector3_Add(&Block_MaxBB[block], &maxRaw, &centre);

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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;
}