1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-06-20 14:15:23 +00:00

Fixed animation frame layer issues. Fix minor map rendering issues.

This commit is contained in:
Tim Sarbin 2018-12-09 00:55:24 -05:00
parent 468ec1ef2a
commit b2177082dc
3 changed files with 79 additions and 57 deletions

View File

@ -42,6 +42,7 @@ namespace OpenDiablo2.Common.Models
public bool FrameIsBottomUp { get; private set; }
public Rectangle Box { get; private set; }
public Cell[] Cells { get; private set; }
public byte[] PixelData { get; internal set; }
public int HorizontalCellCount { get; private set; }
public int VerticalCellCount { get; private set; }
@ -289,48 +290,64 @@ namespace OpenDiablo2.Common.Models
cell.PixelData = new byte[cell.Width * cell.Height];
}
var frameIndex = -1;
var frameIndex = -1;
foreach (var frame in Frames)
{
frameIndex++;
frame.PixelData = new byte[Box.Width * Box.Height];
var c = -1;
foreach (var cell in frame.Cells)
{
c++;
if (cell.PixelData == null)
cell.PixelData = new byte[cell.Width * cell.Height];
var cellX = cell.XOffset / 4;
var cellY = cell.YOffset / 4;
var cellIndex = cellX + (cellY * HorizontalCellCount);
var bufferCell = Cells[cellIndex];
var pbe = PixelBuffer[pbIdx];
if ((pbe.Frame != frameIndex) || (pbe.FrameCellIndex != c))
{
// This buffer cell has an EqualCell bit set to 1, so copy the frame cell or clear it
if ((cell.Width != bufferCell.LastWidth) || (cell.Height != bufferCell.LastHeight))
{
// Different sizes
/// TODO: Clear the pixels of the frame cell
for (var i = 0; i < bufferCell.PixelData.Length; i++)
bufferCell.PixelData[i] = 0x00;
cell.PixelData = new byte[cell.Width * cell.Height];
}
else
{
// Same sizes
// Copy the old frame cell into the new position
// blit(dir->bmp, dir->bmp, buff_cell->last_x0, buff_cell->last_y0, cell->x0, cell->y0, cell->w, cell->h );
for (var i = 0; i < bufferCell.PixelData.Length; i++)
bufferCell.PixelData[i] = cell.PixelData[i];
for (var fy = 0; fy < cell.Height; fy++)
{
for (var fx = 0; fx < cell.Width; fx++)
{
// blit(dir->bmp, dir->bmp, buff_cell->last_x0, buff_cell->last_y0, cell->x0, cell->y0, cell->w, cell->h );
frame.PixelData[fx + cell.XOffset + ((fy + cell.YOffset) * Box.Width)]
= frame.PixelData[fx + bufferCell.LastXOffset + ((fy + bufferCell.LastYOffset) * Box.Width)];
}
}
//// Copy it again into the final frame image
for (var fy = 0; fy < cell.Height; fy++)
{
for (var fx = 0; fx < cell.Width; fx++)
{
// blit(cell->bmp, frm_bmp, 0, 0, cell->x0, cell->y0, cell->w, cell->h );
frame.PixelData[fx + cell.XOffset + ((fy + cell.YOffset) * Box.Width)]
= cell.PixelData[fx + (fy * cell.Width)];
}
}
bufferCell.LastWidth = cell.LastWidth;
bufferCell.LastHeight = cell.LastHeight;
// Copy it again into the final frame image
// blit(cell->bmp, frm_bmp, 0, 0, cell->x0, cell->y0, cell->w, cell->h );
}
}
else
@ -338,12 +355,12 @@ namespace OpenDiablo2.Common.Models
if (pbe.Value[0] == pbe.Value[1])
{
// Clear the frame
cell.PixelData = new byte[cell.Width * cell.Height];
}
else
{
// Fill the frame cell with the pixels
var bitsToRead = (pbe.Value[1] == pbe.Value[2]) ? 1 : 2;
cell.PixelData = new byte[cell.Width * cell.Height];
for (var y = 0; y < cell.Height; y++)
{
@ -356,9 +373,23 @@ namespace OpenDiablo2.Common.Models
}
// Copy the frame cell into the frame
//blit(cell->bmp, frm_bmp, 0, 0, cell->x0, cell->y0, cell->w, cell->h );
for (var fy = 0; fy < cell.Height; fy++)
{
for (var fx = 0; fx < cell.Width; fx++)
{
//blit(cell->bmp, frm_bmp, 0, 0, cell->x0, cell->y0, cell->w, cell->h );
frame.PixelData[fx + cell.XOffset + ((fy + cell.YOffset) * Box.Width)]
= cell.PixelData[fx + (fy * cell.Width)];
}
}
pbIdx++;
}
bufferCell.LastWidth = cell.Width;
bufferCell.LastHeight = cell.Height;
bufferCell.LastXOffset = cell.XOffset;
bufferCell.LastYOffset = cell.YOffset;
}
}
}

View File

@ -106,9 +106,9 @@ namespace OpenDiablo2.Core.Map_Engine
var cx = -(cameraLocation.X - Math.Truncate(cameraLocation.X));
var cy = -(cameraLocation.Y - Math.Truncate(cameraLocation.Y));
for (int ty = -5; ty <= 9; ty++)
for (int ty = -7; ty <= 8; ty++)
{
for (int tx = -5; tx <= 9; tx++)
for (int tx = -7; tx <= 8; tx++)
{
var ax = tx + Math.Truncate(cameraLocation.X);
var ay = ty + Math.Truncate(cameraLocation.Y);
@ -121,27 +121,27 @@ namespace OpenDiablo2.Core.Map_Engine
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.Floor))
renderWindow.DrawMapCell(cellInfo, 320 + px + (int)ox + xOffset, 210 + py + (int)oy);
renderWindow.DrawMapCell(cellInfo, 320 + px + (int)ox + xOffset, 300 + py + (int)oy);
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.WallLower))
renderWindow.DrawMapCell(cellInfo, 320 + px + (int)ox + xOffset, 210 + py + (int)oy + 80);
renderWindow.DrawMapCell(cellInfo, 320 + px + (int)ox + xOffset, 300 + py + (int)oy + 80);
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.WallUpper))
renderWindow.DrawMapCell(cellInfo, 320 + px + (int)ox + xOffset, 210 + py + (int)oy);
renderWindow.DrawMapCell(cellInfo, 320 + px + (int)ox + xOffset, 300 + py + (int)oy);
// TODO: We need to render the characters infront of, or behind the wall properly...
if (ty == 1 && tx == 1)
if (ty == 0 && tx == 0)
{
foreach (var character in characterRenderers/*.Where(x => Math.Truncate(x.LocationDetails.PlayerX) == ax && Math.Truncate(x.LocationDetails.PlayerY) == ay)*/)
{
// TODO: Temporary hack
character.Render(400 + gameState.CameraOffset, 280);
character.Render(400 + gameState.CameraOffset, 300);
}
}
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.Roof))
renderWindow.DrawMapCell(cellInfo, 320 + px + (int)ox + xOffset, 210 + py + (int)oy);
renderWindow.DrawMapCell(cellInfo, 320 + px + (int)ox + xOffset, 300 + py + (int)oy);
}
}

View File

@ -143,7 +143,7 @@ namespace OpenDiablo2.SDL2_
private unsafe void CacheFrames(IEnumerable<MPQDCC> layerData)
{
var cache = new DirectionCacheItem
var directionCache = new DirectionCacheItem
{
MobMode = MobMode,
Direction = directionConversion[LocationDetails.MovementDirection]
@ -152,9 +152,9 @@ namespace OpenDiablo2.SDL2_
var palette = paletteProvider.PaletteTable[Palettes.Units];
var dirAnimation = animationData.Animations[0];
cache.FramesToAnimate = dirAnimation.FramesPerDirection;
cache.AnimationSpeed = dirAnimation.AnimationSpeed;
cache.RenderFrameIndex = 0;
directionCache.FramesToAnimate = dirAnimation.FramesPerDirection;
directionCache.AnimationSpeed = dirAnimation.AnimationSpeed;
directionCache.RenderFrameIndex = 0;
var minX = Int32.MaxValue;
var minY = Int32.MaxValue;
@ -181,13 +181,13 @@ namespace OpenDiablo2.SDL2_
if (layersIgnored > 0)
log.Warn($"{layersIgnored} animation layer(s) were not found!");
var frameW = (maxX - minX) * 2; // Hack
var frameH = (maxY - minY) * 2;
var frameW = (maxX - minX);
var frameH = (maxY - minY);
cache.SpriteTexture = new IntPtr[cache.FramesToAnimate];
cache.SpriteRect = new SDL.SDL_Rect[cache.FramesToAnimate];
directionCache.SpriteTexture = new IntPtr[directionCache.FramesToAnimate];
directionCache.SpriteRect = new SDL.SDL_Rect[directionCache.FramesToAnimate];
for (var frameIndex = 0; frameIndex < cache.FramesToAnimate; frameIndex++)
for (var frameIndex = 0; frameIndex < directionCache.FramesToAnimate; frameIndex++)
{
var texture = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_ARGB8888, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_STREAMING, frameW, frameH);
@ -202,43 +202,34 @@ namespace OpenDiablo2.SDL2_
var direction = layer.Directions[directionConversion[LocationDetails.MovementDirection]];
var frame = direction.Frames[frameIndex];
foreach (var cell in frame.Cells)
for (var y = 0; y < direction.Box.Height; y++)
{
if (cell.PixelData == null)
continue; // TODO: This isn't good
for (int y = 0; y < cell.Height; y++)
for (var x = 0; x < direction.Box.Width; x++)
{
for (int x = 0; x < cell.Width; x++)
{
// Index 0 is always transparent
var paletteIndex = cell.PixelData[x + (y * cell.Width)];
var paletteIndex = frame.PixelData[x + (y * direction.Box.Width)];
if (paletteIndex == 0)
continue;
if (paletteIndex == 0)
continue;
var color = palette.Colors[paletteIndex];
var color = palette.Colors[paletteIndex];
var actualX = x + direction.Box.X - minX;
var actualY = y + direction.Box.Y - minY;
var offsetX = x + cell.XOffset + (frame.Box.X - minX);
var offsetY = y + cell.YOffset + (frame.Box.Y - minY);
if (offsetX < 0 || offsetX > frameW || offsetY < 0 || offsetY > frameH)
throw new OpenDiablo2Exception("There is nothing we can do now.");
data[actualX + (actualY * (pitch / 4))] = color;
data[offsetX + (offsetY * (pitch / 4))] = color;
}
}
}
}
SDL.SDL_UnlockTexture(texture);
SDL.SDL_SetTextureBlendMode(texture, SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
directionCache.SpriteTexture[frameIndex] = texture;
directionCache.SpriteRect[frameIndex] = new SDL.SDL_Rect { x = minX, y = minY, w = frameW, h = frameH };
// TODO: Temporary code!
cache.SpriteTexture[frameIndex] = texture;
cache.SpriteRect[frameIndex] = new SDL.SDL_Rect { x = minX, y = minY, w = frameW, h = frameH };
directionCache.Add(cache);
currentDirectionCache = cache;
this.directionCache.Add(directionCache);
currentDirectionCache = directionCache;
}
}