1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-09-28 22:26:30 -04: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 bool FrameIsBottomUp { get; private set; }
public Rectangle Box { get; private set; } public Rectangle Box { get; private set; }
public Cell[] Cells { get; private set; } public Cell[] Cells { get; private set; }
public byte[] PixelData { get; internal set; }
public int HorizontalCellCount { get; private set; } public int HorizontalCellCount { get; private set; }
public int VerticalCellCount { get; private set; } public int VerticalCellCount { get; private set; }
@ -295,42 +296,58 @@ namespace OpenDiablo2.Common.Models
foreach (var frame in Frames) foreach (var frame in Frames)
{ {
frameIndex++; frameIndex++;
frame.PixelData = new byte[Box.Width * Box.Height];
var c = -1; var c = -1;
foreach (var cell in frame.Cells) foreach (var cell in frame.Cells)
{ {
c++; c++;
if (cell.PixelData == null)
cell.PixelData = new byte[cell.Width * cell.Height];
var cellX = cell.XOffset / 4; var cellX = cell.XOffset / 4;
var cellY = cell.YOffset / 4; var cellY = cell.YOffset / 4;
var cellIndex = cellX + (cellY * HorizontalCellCount); var cellIndex = cellX + (cellY * HorizontalCellCount);
var bufferCell = Cells[cellIndex]; var bufferCell = Cells[cellIndex];
var pbe = PixelBuffer[pbIdx]; var pbe = PixelBuffer[pbIdx];
if ((pbe.Frame != frameIndex) || (pbe.FrameCellIndex != c)) 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 // 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)) if ((cell.Width != bufferCell.LastWidth) || (cell.Height != bufferCell.LastHeight))
{ {
// Different sizes // Different sizes
/// TODO: Clear the pixels of the frame cell /// TODO: Clear the pixels of the frame cell
for (var i = 0; i < bufferCell.PixelData.Length; i++) cell.PixelData = new byte[cell.Width * cell.Height];
bufferCell.PixelData[i] = 0x00;
} }
else else
{ {
// Same sizes // Same sizes
// Copy the old frame cell into the new position // Copy the old frame cell into the new position
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 ); // 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++) frame.PixelData[fx + cell.XOffset + ((fy + cell.YOffset) * Box.Width)]
bufferCell.PixelData[i] = cell.PixelData[i]; = frame.PixelData[fx + bufferCell.LastXOffset + ((fy + bufferCell.LastYOffset) * Box.Width)];
}
}
bufferCell.LastWidth = cell.LastWidth; //// Copy it again into the final frame image
bufferCell.LastHeight = cell.LastHeight; for (var fy = 0; fy < cell.Height; fy++)
// Copy it again into the final frame image {
for (var fx = 0; fx < cell.Width; fx++)
{
// blit(cell->bmp, frm_bmp, 0, 0, cell->x0, cell->y0, cell->w, cell->h ); // 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)];
}
}
} }
} }
else else
@ -338,12 +355,12 @@ namespace OpenDiablo2.Common.Models
if (pbe.Value[0] == pbe.Value[1]) if (pbe.Value[0] == pbe.Value[1])
{ {
// Clear the frame // Clear the frame
cell.PixelData = new byte[cell.Width * cell.Height];
} }
else else
{ {
// Fill the frame cell with the pixels // Fill the frame cell with the pixels
var bitsToRead = (pbe.Value[1] == pbe.Value[2]) ? 1 : 2; 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++) for (var y = 0; y < cell.Height; y++)
{ {
@ -356,9 +373,23 @@ namespace OpenDiablo2.Common.Models
} }
// Copy the frame cell into the frame // Copy the frame cell into the frame
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 ); //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++; 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 cx = -(cameraLocation.X - Math.Truncate(cameraLocation.X));
var cy = -(cameraLocation.Y - Math.Truncate(cameraLocation.Y)); 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 ax = tx + Math.Truncate(cameraLocation.X);
var ay = ty + Math.Truncate(cameraLocation.Y); 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)) 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)) 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)) 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... // 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)*/) foreach (var character in characterRenderers/*.Where(x => Math.Truncate(x.LocationDetails.PlayerX) == ax && Math.Truncate(x.LocationDetails.PlayerY) == ay)*/)
{ {
// TODO: Temporary hack // 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)) 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) private unsafe void CacheFrames(IEnumerable<MPQDCC> layerData)
{ {
var cache = new DirectionCacheItem var directionCache = new DirectionCacheItem
{ {
MobMode = MobMode, MobMode = MobMode,
Direction = directionConversion[LocationDetails.MovementDirection] Direction = directionConversion[LocationDetails.MovementDirection]
@ -152,9 +152,9 @@ namespace OpenDiablo2.SDL2_
var palette = paletteProvider.PaletteTable[Palettes.Units]; var palette = paletteProvider.PaletteTable[Palettes.Units];
var dirAnimation = animationData.Animations[0]; var dirAnimation = animationData.Animations[0];
cache.FramesToAnimate = dirAnimation.FramesPerDirection; directionCache.FramesToAnimate = dirAnimation.FramesPerDirection;
cache.AnimationSpeed = dirAnimation.AnimationSpeed; directionCache.AnimationSpeed = dirAnimation.AnimationSpeed;
cache.RenderFrameIndex = 0; directionCache.RenderFrameIndex = 0;
var minX = Int32.MaxValue; var minX = Int32.MaxValue;
var minY = Int32.MaxValue; var minY = Int32.MaxValue;
@ -181,13 +181,13 @@ namespace OpenDiablo2.SDL2_
if (layersIgnored > 0) if (layersIgnored > 0)
log.Warn($"{layersIgnored} animation layer(s) were not found!"); log.Warn($"{layersIgnored} animation layer(s) were not found!");
var frameW = (maxX - minX) * 2; // Hack var frameW = (maxX - minX);
var frameH = (maxY - minY) * 2; var frameH = (maxY - minY);
cache.SpriteTexture = new IntPtr[cache.FramesToAnimate]; directionCache.SpriteTexture = new IntPtr[directionCache.FramesToAnimate];
cache.SpriteRect = new SDL.SDL_Rect[cache.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); 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 direction = layer.Directions[directionConversion[LocationDetails.MovementDirection]];
var frame = direction.Frames[frameIndex]; var frame = direction.Frames[frameIndex];
foreach (var cell in frame.Cells) for (var y = 0; y < direction.Box.Height; y++)
{ {
if (cell.PixelData == null) for (var x = 0; x < direction.Box.Width; x++)
continue; // TODO: This isn't good
for (int y = 0; y < cell.Height; y++)
{ {
for (int x = 0; x < cell.Width; x++) var paletteIndex = frame.PixelData[x + (y * direction.Box.Width)];
{
// Index 0 is always transparent
var paletteIndex = cell.PixelData[x + (y * cell.Width)];
if (paletteIndex == 0) if (paletteIndex == 0)
continue; 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); data[actualX + (actualY * (pitch / 4))] = color;
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[offsetX + (offsetY * (pitch / 4))] = color;
}
} }
} }
} }
SDL.SDL_UnlockTexture(texture); SDL.SDL_UnlockTexture(texture);
SDL.SDL_SetTextureBlendMode(texture, SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND); SDL.SDL_SetTextureBlendMode(texture, SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
// TODO: Temporary code! directionCache.SpriteTexture[frameIndex] = texture;
cache.SpriteTexture[frameIndex] = texture; directionCache.SpriteRect[frameIndex] = new SDL.SDL_Rect { x = minX, y = minY, w = frameW, h = frameH };
cache.SpriteRect[frameIndex] = new SDL.SDL_Rect { x = minX, y = minY, w = frameW, h = frameH };
directionCache.Add(cache); this.directionCache.Add(directionCache);
currentDirectionCache = cache; currentDirectionCache = directionCache;
} }
} }