fix animations for inf tex

This commit is contained in:
UnknownShadow200 2018-06-02 13:30:04 +10:00
parent cd285365c2
commit 76d93b1718
4 changed files with 48 additions and 43 deletions

View File

@ -92,7 +92,7 @@ namespace ClassicalSharp.Textures {
byte tileX, tileY; byte tileX, tileY;
if (!Byte.TryParse(parts[0], out tileX) || !Byte.TryParse(parts[1], out tileY) if (!Byte.TryParse(parts[0], out tileX) || !Byte.TryParse(parts[1], out tileY)
|| tileX >= 16 || tileY >= 16) { || tileX >= Atlas2D.TilesPerRow || tileY >= Atlas2D.MaxRowsCount) {
game.Chat.Add("&cInvalid animation tile coords: " + line); continue; game.Chat.Add("&cInvalid animation tile coords: " + line); continue;
} }
@ -116,7 +116,7 @@ namespace ClassicalSharp.Textures {
/// that are applied to the terrain atlas. </summary> /// that are applied to the terrain atlas. </summary>
void DefineAnimation(int tileX, int tileY, int frameX, int frameY, int frameSize, int statesNum, int tickDelay) { void DefineAnimation(int tileX, int tileY, int frameX, int frameY, int frameSize, int statesNum, int tickDelay) {
AnimationData data = new AnimationData(); AnimationData data = new AnimationData();
data.TileX = tileX; data.TileY = tileY; data.TexLoc = tileY * Atlas2D.TilesPerRow + tileX;
data.FrameX = frameX; data.FrameY = frameY; data.FrameX = frameX; data.FrameY = frameY;
data.FrameSize = frameSize; data.StatesCount = statesNum; data.FrameSize = frameSize; data.StatesCount = statesNum;
@ -134,34 +134,34 @@ namespace ClassicalSharp.Textures {
data.State %= data.StatesCount; data.State %= data.StatesCount;
data.Tick = data.TickDelay; data.Tick = data.TickDelay;
int texId = (data.TileY << 4) | data.TileX; int texLoc = data.TexLoc;
if (texId == 30 && useLavaAnim) return; if (texLoc == 30 && useLavaAnim) return;
if (texId == 14 && useWaterAnim) return; if (texLoc == 14 && useWaterAnim) return;
DrawAnimation(data, texId, data.FrameSize); DrawAnimation(data, texLoc, data.FrameSize);
} }
unsafe void DrawAnimation(AnimationData data, int texId, int size) { unsafe void DrawAnimation(AnimationData data, int texLoc, int size) {
if (size <= 128) { if (size <= 128) {
byte* temp = stackalloc byte[size * size * 4]; byte* temp = stackalloc byte[size * size * 4];
DrawAnimationCore(data, texId, size, temp); DrawAnimationCore(data, texLoc, size, temp);
} else { } else {
// cannot allocate memory on the stack for very big animation.png frames // cannot allocate memory on the stack for very big animation.png frames
byte[] temp = new byte[size * size * 4]; byte[] temp = new byte[size * size * 4];
fixed (byte* ptr = temp) { fixed (byte* ptr = temp) {
DrawAnimationCore(data, texId, size, ptr); DrawAnimationCore(data, texLoc, size, ptr);
} }
} }
} }
unsafe void DrawAnimationCore(AnimationData data, int texId, int size, byte* temp) { unsafe void DrawAnimationCore(AnimationData data, int texLoc, int size, byte* temp) {
int index = Atlas1D.Get1DIndex(texId); int index_1D = Atlas1D.Get1DIndex(texLoc);
int rowNum = Atlas1D.Get1DRowId(texId); int rowId_1D = Atlas1D.Get1DRowId(texLoc);
animPart.SetData(size, size, size * 4, (IntPtr)temp, false); animPart.SetData(size, size, size * 4, (IntPtr)temp, false);
if (data == null) { if (data == null) {
if (texId == 30) { if (texLoc == 30) {
lavaAnim.Tick((int*)temp, size); lavaAnim.Tick((int*)temp, size);
} else if (texId == 14) { } else if (texLoc == 14) {
waterAnim.Tick((int*)temp, size); waterAnim.Tick((int*)temp, size);
} }
} else { } else {
@ -169,8 +169,8 @@ namespace ClassicalSharp.Textures {
data.FrameY, 0, 0, animsBuffer, animPart, size); data.FrameY, 0, 0, animsBuffer, animPart, size);
} }
int y = rowNum * Atlas2D.TileSize; int dstY = rowId_1D * Atlas2D.TileSize;
game.Graphics.UpdateTexturePart(Atlas1D.TexIds[index], 0, y, animPart, game.Graphics.Mipmaps); game.Graphics.UpdateTexturePart(Atlas1D.TexIds[index_1D], 0, dstY, animPart, game.Graphics.Mipmaps);
} }
bool IsDefaultZip() { bool IsDefaultZip() {
@ -197,7 +197,7 @@ namespace ClassicalSharp.Textures {
} }
class AnimationData { class AnimationData {
public int TileX, TileY; // Tile (not pixel) coordinates in terrain.png public int TexLoc; // Tile (not pixel) coordinates in terrain.png
public int FrameX, FrameY; // Top left pixel coordinates of start frame in animatons.png public int FrameX, FrameY; // Top left pixel coordinates of start frame in animatons.png
public int FrameSize; // Size of each frame in pixel coordinates public int FrameSize; // Size of each frame in pixel coordinates
public int State; // Current animation frame index public int State; // Current animation frame index
@ -209,11 +209,12 @@ namespace ClassicalSharp.Textures {
const string terrainFormat = "&cAnimation frames for tile ({0}, {1}) are bigger than the size of a tile in terrain.png"; const string terrainFormat = "&cAnimation frames for tile ({0}, {1}) are bigger than the size of a tile in terrain.png";
void ValidateAnimations() { void ValidateAnimations() {
validated = true; validated = true;
int elemSize = Atlas2D.TileSize;
for (int i = animations.Count - 1; i >= 0; i--) { for (int i = animations.Count - 1; i >= 0; i--) {
AnimationData a = animations[i]; AnimationData a = animations[i];
if (a.FrameSize > elemSize) { int tileX = a.TexLoc % Atlas2D.TilesPerRow, tileY = a.TexLoc / Atlas2D.TilesPerRow;
game.Chat.Add(String.Format(terrainFormat, a.TileX, a.TileY));
if (a.FrameSize > Atlas2D.TileSize || tileY >= Atlas2D.RowsCount) {
game.Chat.Add(String.Format(terrainFormat, tileX, tileY));
animations.RemoveAt(i); animations.RemoveAt(i);
continue; continue;
} }
@ -222,7 +223,7 @@ namespace ClassicalSharp.Textures {
int maxX = a.FrameX + a.FrameSize * a.StatesCount; int maxX = a.FrameX + a.FrameSize * a.StatesCount;
if (maxX <= animsBuffer.Width && maxY <= animsBuffer.Height) continue; if (maxX <= animsBuffer.Width && maxY <= animsBuffer.Height) continue;
game.Chat.Add(String.Format(format, a.TileX, a.TileY)); game.Chat.Add(String.Format(format, tileX, tileY));
animations.RemoveAt(i); animations.RemoveAt(i);
} }
} }

View File

@ -126,11 +126,11 @@ static void WaterAnimation_Tick(UInt32* ptr, Int32 size) {
typedef struct AnimationData_ { typedef struct AnimationData_ {
TextureLoc TileX, TileY; /* Tile (not pixel) coordinates in terrain.png */ TextureLoc TexLoc; /* Tile (not pixel) coordinates in terrain.png */
UInt16 FrameX, FrameY; /* Top left pixel coordinates of start frame in animatons.png */ UInt16 FrameX, FrameY; /* Top left pixel coordinates of start frame in animatons.png */
UInt16 FrameSize; /* Size of each frame in pixel coordinates */ UInt16 FrameSize; /* Size of each frame in pixel coordinates */
UInt16 State; /* Current animation frame index */ UInt16 State; /* Current animation frame index */
UInt16 StatesCount; /* Total number of animation frames */ UInt16 StatesCount; /* Total number of animation frames */
Int16 Tick, TickDelay; Int16 Tick, TickDelay;
} AnimationData; } AnimationData;
@ -158,16 +158,18 @@ static void Animations_ReadDescription(Stream* stream) {
while (Stream_ReadLine(&buffered, &line)) { while (Stream_ReadLine(&buffered, &line)) {
if (line.length == 0 || line.buffer[0] == '#') continue; if (line.length == 0 || line.buffer[0] == '#') continue;
AnimationData data = { 0 }; AnimationData data = { 0 };
UInt8 tileX, tileY;
UInt32 partsCount = Array_Elems(parts); UInt32 partsCount = Array_Elems(parts);
String_UNSAFE_Split(&line, ' ', parts, &partsCount); String_UNSAFE_Split(&line, ' ', parts, &partsCount);
if (partsCount < 7) { if (partsCount < 7) {
Animations_LogFail(&line, "Not enough arguments for anim"); continue; Animations_LogFail(&line, "Not enough arguments for anim"); continue;
} }
if (!Convert_TryParseUInt8(&parts[0], &data.TileX) || data.TileX >= 16) { if (!Convert_TryParseUInt8(&parts[0], &tileX) || tileX >= ATLAS2D_TILES_PER_ROW) {
Animations_LogFail(&line, "Invalid anim tile X coord"); continue; Animations_LogFail(&line, "Invalid anim tile X coord"); continue;
} }
if (!Convert_TryParseUInt8(&parts[1], &data.TileY) || data.TileY >= 16) { if (!Convert_TryParseUInt8(&parts[1], &tileY) || tileY >= ATLAS2D_ROWS_COUNT) {
Animations_LogFail(&line, "Invalid anim tile Y coord"); continue; Animations_LogFail(&line, "Invalid anim tile Y coord"); continue;
} }
if (!Convert_TryParseUInt16(&parts[2], &data.FrameX)) { if (!Convert_TryParseUInt16(&parts[2], &data.FrameX)) {
@ -189,13 +191,14 @@ static void Animations_ReadDescription(Stream* stream) {
if (anims_count == Array_Elems(anims_list)) { if (anims_count == Array_Elems(anims_list)) {
ErrorHandler_Fail("Too many animations in animations.txt"); ErrorHandler_Fail("Too many animations in animations.txt");
} }
data.TexLoc = tileX + (tileY * ATLAS2D_TILES_PER_ROW);
anims_list[anims_count++] = data; anims_list[anims_count++] = data;
} }
} }
/* TODO: should we use 128 size here? */ /* TODO: should we use 128 size here? */
#define ANIMS_FAST_SIZE 64 #define ANIMS_FAST_SIZE 64
static void Animations_Draw(AnimationData* data, Int32 texId, Int32 size) { static void Animations_Draw(AnimationData* data, TextureLoc texLoc, Int32 size) {
UInt8 buffer[Bitmap_DataSize(ANIMS_FAST_SIZE, ANIMS_FAST_SIZE)]; UInt8 buffer[Bitmap_DataSize(ANIMS_FAST_SIZE, ANIMS_FAST_SIZE)];
UInt8* ptr = buffer; UInt8* ptr = buffer;
if (size > ANIMS_FAST_SIZE) { if (size > ANIMS_FAST_SIZE) {
@ -204,14 +207,14 @@ static void Animations_Draw(AnimationData* data, Int32 texId, Int32 size) {
if (ptr == NULL) ErrorHandler_Fail("Failed to allocate memory for anim frame"); if (ptr == NULL) ErrorHandler_Fail("Failed to allocate memory for anim frame");
} }
Int32 index = Atlas1D_Index(texId); Int32 index_1D = Atlas1D_Index(texLoc);
Int32 rowNum = Atlas1D_RowId(texId); Int32 rowId_1D = Atlas1D_RowId(texLoc);
Bitmap animPart; Bitmap_Create(&animPart, size, size, buffer); Bitmap animPart; Bitmap_Create(&animPart, size, size, buffer);
if (data == NULL) { if (data == NULL) {
if (texId == 30) { if (texLoc == 30) {
LavaAnimation_Tick((UInt32*)animPart.Scan0, size); LavaAnimation_Tick((UInt32*)animPart.Scan0, size);
} else if (texId == 14) { } else if (texLoc == 14) {
WaterAnimation_Tick((UInt32*)animPart.Scan0, size); WaterAnimation_Tick((UInt32*)animPart.Scan0, size);
} }
} else { } else {
@ -219,8 +222,8 @@ static void Animations_Draw(AnimationData* data, Int32 texId, Int32 size) {
Bitmap_CopyBlock(x, data->FrameY, 0, 0, &anims_bmp, &animPart, size); Bitmap_CopyBlock(x, data->FrameY, 0, 0, &anims_bmp, &animPart, size);
} }
Int32 y = rowNum * Atlas2D_TileSize; Int32 dstY = rowId_1D * Atlas2D_TileSize;
Gfx_UpdateTexturePart(Atlas1D_TexIds[index], 0, y, &animPart, Gfx_Mipmaps); Gfx_UpdateTexturePart(Atlas1D_TexIds[index_1D], 0, dstY, &animPart, Gfx_Mipmaps);
if (size > ANIMS_FAST_SIZE) Platform_MemFree(&ptr); if (size > ANIMS_FAST_SIZE) Platform_MemFree(&ptr);
} }
@ -231,10 +234,10 @@ static void Animations_Apply(AnimationData* data) {
data->State %= data->StatesCount; data->State %= data->StatesCount;
data->Tick = data->TickDelay; data->Tick = data->TickDelay;
Int32 texId = (data->TileY << 4) | data->TileX; TextureLoc texLoc = data->TexLoc;
if (texId == 30 && anims_useLavaAnim) return; if (texLoc == 30 && anims_useLavaAnim) return;
if (texId == 14 && anims_useWaterAnim) return; if (texLoc == 14 && anims_useWaterAnim) return;
Animations_Draw(data, texId, data->FrameSize); Animations_Draw(data, texLoc, data->FrameSize);
} }
static bool Animations_IsDefaultZip(void) { static bool Animations_IsDefaultZip(void) {
@ -264,10 +267,11 @@ static void Animations_Validate(void) {
Int32 maxX = data.FrameX + data.FrameSize * data.StatesCount; Int32 maxX = data.FrameX + data.FrameSize * data.StatesCount;
String_Clear(&msg); String_Clear(&msg);
Int32 tileX = data.TexLoc % ATLAS2D_TILES_PER_ROW, tileY = data.TexLoc / ATLAS2D_TILES_PER_ROW;
if (data.FrameSize > Atlas2D_TileSize) { if (data.FrameSize > Atlas2D_TileSize) {
String_Format2(&msg, "&cAnimation frames for tile (%b, %b) are bigger than the size of a tile in terrain.png", &data.TileX, &data.TileY); 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) { } else if (maxX > anims_bmp.Width || maxY > anims_bmp.Height) {
String_Format2(&msg, "&cSome of the animation frames for tile (%b, %b) are at coordinates outside animations.png", &data.TileX, &data.TileY); String_Format2(&msg, "&cSome of the animation frames for tile (%i, %i) are at coordinates outside animations.png", &tileX, &tileY);
} else { } else {
continue; continue;
} }

View File

@ -57,7 +57,7 @@ typedef struct FontDesc_ { void* Handle; UInt16 Size, Style; } FontDesc;
#define Int32_MaxValue ((Int32)2147483647L) #define Int32_MaxValue ((Int32)2147483647L)
#define UInt32_MaxValue ((UInt32)4294967295UL) #define UInt32_MaxValue ((UInt32)4294967295UL)
#define CC_BUILD_GL11 true #define CC_BUILD_GL11 false
#define CC_BUILD_D3D9 false #define CC_BUILD_D3D9 false
#if CC_BUILD_D3D9 #if CC_BUILD_D3D9