mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-12-26 12:06:24 -05:00
Added start of cell renderer. Still trying to fix map load issue
This commit is contained in:
parent
6c2847e4b3
commit
ecc6eb2138
14
OpenDiablo2.Common/Enums/eRenderCellType.cs
Normal file
14
OpenDiablo2.Common/Enums/eRenderCellType.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OpenDiablo2.Common.Enums
|
||||
{
|
||||
public enum eRenderCellType
|
||||
{
|
||||
Floor,
|
||||
Wall
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using OpenDiablo2.Common.Models;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
@ -18,6 +19,7 @@ namespace OpenDiablo2.Common.Interfaces
|
||||
void Quit();
|
||||
ISprite LoadSprite(string resourcePath, string palette, Point location);
|
||||
ISprite LoadSprite(string resourcePath, string palette);
|
||||
ISprite GenerateMapCell(MPQDS1 mapData, int x, int y, eRenderCellType cellType, Palette palette);
|
||||
IFont LoadFont(string resourcePath, string palette);
|
||||
ILabel CreateLabel(IFont font);
|
||||
ILabel CreateLabel(IFont font, string text);
|
||||
|
@ -15,7 +15,7 @@ namespace OpenDiablo2.Common.Models
|
||||
public byte GridY { get; internal set; }
|
||||
public UInt16 Format { get; internal set; }
|
||||
public UInt32 Length { get; internal set; }
|
||||
public Int32 FileOffset { get; internal set; }
|
||||
public UInt32 FileOffset { get; internal set; }
|
||||
public Int16[] PixelData { get; internal set; }
|
||||
}
|
||||
|
||||
@ -55,57 +55,53 @@ namespace OpenDiablo2.Common.Models
|
||||
|
||||
for (int tileIndex = 0; tileIndex < NumberOfTiles; tileIndex++)
|
||||
{
|
||||
stream.Seek(tileHeaderOffset + (96 * tileIndex), SeekOrigin.Begin);
|
||||
Tiles[tileIndex] = new MPQDT1Tile();
|
||||
Tiles[tileIndex].Direction = br.ReadUInt32();
|
||||
Tiles[tileIndex].RoofHeight = br.ReadUInt16();
|
||||
Tiles[tileIndex].SoundIndex = br.ReadByte();
|
||||
Tiles[tileIndex].Animated = br.ReadByte() == 1;
|
||||
Tiles[tileIndex].Height = br.ReadInt32();
|
||||
Tiles[tileIndex].Width = br.ReadInt32();
|
||||
var tile = Tiles[tileIndex];
|
||||
|
||||
tile.Direction = br.ReadUInt32();
|
||||
tile.RoofHeight = br.ReadUInt16();
|
||||
tile.SoundIndex = br.ReadByte();
|
||||
tile.Animated = br.ReadByte() == 1;
|
||||
tile.Height = br.ReadInt32();
|
||||
tile.Width = br.ReadInt32();
|
||||
br.ReadBytes(4);
|
||||
Tiles[tileIndex].Orientation = br.ReadUInt32();
|
||||
Tiles[tileIndex].MainIndex = br.ReadUInt32();
|
||||
Tiles[tileIndex].SubIndex = br.ReadUInt32();
|
||||
Tiles[tileIndex].RarityOrFrameIndex = br.ReadUInt32();
|
||||
tile.Orientation = br.ReadUInt32();
|
||||
tile.MainIndex = br.ReadUInt32();
|
||||
tile.SubIndex = br.ReadUInt32();
|
||||
tile.RarityOrFrameIndex = br.ReadUInt32();
|
||||
br.ReadBytes(4);
|
||||
for (int i = 0; i < 25; i++)
|
||||
Tiles[tileIndex].SubTileFlags[i] = br.ReadByte();
|
||||
tile.SubTileFlags[i] = br.ReadByte();
|
||||
br.ReadBytes(7);
|
||||
Tiles[tileIndex].BlockHeadersPointer = br.ReadUInt32();
|
||||
Tiles[tileIndex].BlockDataLength = br.ReadUInt32();
|
||||
Tiles[tileIndex].NumberOfBlocks = br.ReadUInt32();
|
||||
tile.BlockHeadersPointer = br.ReadUInt32();
|
||||
tile.BlockDataLength = br.ReadUInt32();
|
||||
tile.NumberOfBlocks = br.ReadUInt32();
|
||||
br.ReadBytes(12);
|
||||
}
|
||||
|
||||
|
||||
for (int tileIndex = 0; tileIndex < NumberOfTiles; tileIndex++)
|
||||
{
|
||||
var tile = Tiles[tileIndex];
|
||||
if (tile.BlockHeadersPointer == 0)
|
||||
if (tile.BlockHeadersPointer == 0 || tile.Width == 0 || tile.Height == 0)
|
||||
{
|
||||
tile.Blocks = new MPQDT1Block[0];
|
||||
continue;
|
||||
}
|
||||
stream.Seek(tile.BlockHeadersPointer, SeekOrigin.Begin);
|
||||
|
||||
tile.Blocks = new MPQDT1Block[tile.NumberOfBlocks];
|
||||
for (int blockIndex = 0; blockIndex < tile.NumberOfBlocks; blockIndex++)
|
||||
{
|
||||
stream.Seek(tile.BlockHeadersPointer + (20 * blockIndex), SeekOrigin.Begin);
|
||||
tile.Blocks[blockIndex] = new MPQDT1Block();
|
||||
tile.Blocks[blockIndex].PositionX = br.ReadUInt16();
|
||||
tile.Blocks[blockIndex].PositionY = br.ReadUInt16();
|
||||
br.ReadBytes(2);
|
||||
tile.Blocks[blockIndex].GridX = br.ReadByte();
|
||||
tile.Blocks[blockIndex].GridX = br.ReadByte();
|
||||
tile.Blocks[blockIndex].Format = br.ReadUInt16();
|
||||
tile.Blocks[blockIndex].Length = br.ReadUInt32();
|
||||
br.ReadBytes(2);
|
||||
tile.Blocks[blockIndex].FileOffset = br.ReadInt32();
|
||||
}
|
||||
|
||||
for (int blockIndex = 0; blockIndex < tile.NumberOfBlocks; blockIndex++)
|
||||
{
|
||||
var block = tile.Blocks[blockIndex];
|
||||
|
||||
block.PositionX = br.ReadUInt16();
|
||||
block.PositionY = br.ReadUInt16();
|
||||
br.ReadBytes(2);
|
||||
block.GridX = br.ReadByte();
|
||||
block.GridX = br.ReadByte();
|
||||
block.Format = br.ReadUInt16();
|
||||
block.Length = br.ReadUInt32();
|
||||
br.ReadBytes(2);
|
||||
block.FileOffset = br.ReadUInt32();
|
||||
|
||||
stream.Seek(tile.BlockHeadersPointer + block.FileOffset, SeekOrigin.Begin);
|
||||
|
||||
if (block.Format == 1)
|
||||
@ -136,18 +132,18 @@ namespace OpenDiablo2.Common.Models
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
// TODO: This doesn't work.. memory pointer issues?
|
||||
continue;
|
||||
|
||||
// RLE block
|
||||
/* TODO: BROKEN
|
||||
var length = block.Length;
|
||||
byte b1;
|
||||
byte b2;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
block.PixelData = new Int16[32 * 16];
|
||||
int width = (block.Format >> 8);
|
||||
int height = (block.Format & 0xFF);
|
||||
block.PixelData = new Int16[width * height];
|
||||
while (length > 0)
|
||||
{
|
||||
b1 = br.ReadByte();
|
||||
@ -157,7 +153,7 @@ namespace OpenDiablo2.Common.Models
|
||||
{
|
||||
x += b1;
|
||||
length -= b2;
|
||||
while(b2 > 0)
|
||||
while (b2 > 0)
|
||||
{
|
||||
block.PixelData[x + (y * 32)] = br.ReadByte();
|
||||
br.ReadByte();
|
||||
@ -171,6 +167,7 @@ namespace OpenDiablo2.Common.Models
|
||||
y++;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,6 +73,7 @@
|
||||
<Compile Include="Enums\eButtonType.cs" />
|
||||
<Compile Include="Enums\eHero.cs" />
|
||||
<Compile Include="Enums\eMPQFormatVersion.cs" />
|
||||
<Compile Include="Enums\eRenderCellType.cs" />
|
||||
<Compile Include="Interfaces\IEngineDataManager.cs" />
|
||||
<Compile Include="Interfaces\IFont.cs" />
|
||||
<Compile Include="Interfaces\IGameEngine.cs" />
|
||||
|
@ -14,18 +14,33 @@ namespace OpenDiablo2.Core.GameState_
|
||||
{
|
||||
private readonly ISceneManager sceneManager;
|
||||
private readonly IResourceManager resourceManager;
|
||||
MPQDS1 mapData;
|
||||
private readonly IPaletteProvider paletteProvider;
|
||||
|
||||
public GameState(ISceneManager sceneManager, IResourceManager resourceManager)
|
||||
public MPQDS1 MapData { get; set; }
|
||||
public bool MapDirty { get; set; }
|
||||
public int Act { get; private set; }
|
||||
public string MapName { get; set; }
|
||||
public Palette CurrentPalette => paletteProvider.PaletteTable[$"ACT{Act}"];
|
||||
|
||||
public GameState(ISceneManager sceneManager, IResourceManager resourceManager, IPaletteProvider paletteProvider)
|
||||
{
|
||||
this.sceneManager = sceneManager;
|
||||
this.resourceManager = resourceManager;
|
||||
this.paletteProvider = paletteProvider;
|
||||
}
|
||||
|
||||
public void Initialize(string characterName, eHero hero)
|
||||
{
|
||||
sceneManager.ChangeScene("Game");
|
||||
mapData = resourceManager.GetMPQDS1(ResourcePaths.MapAct1TownE1, -1, 1);
|
||||
ChangeMap(ResourcePaths.MapAct1TownE1, 1);
|
||||
}
|
||||
|
||||
public void ChangeMap(string mapName, int act)
|
||||
{
|
||||
MapName = mapName;
|
||||
Act = act;
|
||||
MapDirty = true;
|
||||
MapData = resourceManager.GetMPQDS1(mapName, -1, act);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ using System.Drawing;
|
||||
using OpenDiablo2.Common.Models;
|
||||
using Autofac;
|
||||
using System.Runtime.InteropServices;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
|
||||
namespace OpenDiablo2.SDL2_
|
||||
{
|
||||
@ -266,5 +267,8 @@ namespace OpenDiablo2.SDL2_
|
||||
|
||||
SDL.SDL_RenderCopy(renderer, lbl.texture, IntPtr.Zero, ref destRect);
|
||||
}
|
||||
|
||||
public ISprite GenerateMapCell(MPQDS1 mapData, int x, int y, eRenderCellType cellType, Palette palette)
|
||||
=> new SDL2Sprite(this.renderer, palette, mapData, x, y, cellType);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
using OpenDiablo2.Common.Models;
|
||||
using SDL2;
|
||||
@ -15,10 +16,12 @@ namespace OpenDiablo2.SDL2_
|
||||
internal readonly ImageSet source;
|
||||
private readonly IntPtr renderer;
|
||||
internal IntPtr texture = IntPtr.Zero;
|
||||
private Point globalFrameOffset = new Point(0, 0);
|
||||
|
||||
public Point Location { get; set; } = new Point();
|
||||
public Size FrameSize { get; set; } = new Size();
|
||||
|
||||
|
||||
private bool darken;
|
||||
public bool Darken
|
||||
{
|
||||
@ -80,11 +83,63 @@ namespace OpenDiablo2.SDL2_
|
||||
FrameSize = new Size(Pow2((int)source.Frames.Max(x => x.Width)), Pow2((int)source.Frames.Max(x => x.Height)));
|
||||
}
|
||||
|
||||
public unsafe SDL2Sprite(IntPtr renderer, Palette palette, MPQDS1 mapData, int x, int y, eRenderCellType cellType)
|
||||
{
|
||||
this.renderer = renderer;
|
||||
// TODO: Cell types
|
||||
|
||||
// Floor cell types
|
||||
// Todo: multiple floor layers
|
||||
var floorLayer = mapData.FloorLayers.First();
|
||||
var floor = floorLayer.Props[x + (y * mapData.Width)];
|
||||
|
||||
if (floor.Prop1 == 0)
|
||||
return;
|
||||
|
||||
var sub_index = floor.Prop2;
|
||||
var main_index = (floor.Prop3 / 16) + ((floor.Prop4 & 0x0F) * 16);
|
||||
var tile = mapData.DT1s[main_index].Tiles[sub_index];
|
||||
|
||||
FrameSize = new Size(tile.Width, Math.Abs(tile.Height));
|
||||
TotalFrames = 1;
|
||||
frame = 0;
|
||||
IntPtr pixels;
|
||||
int pitch;
|
||||
|
||||
texture = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_ARGB8888, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_STREAMING, FrameSize.Width, FrameSize.Height);
|
||||
|
||||
if (texture == IntPtr.Zero)
|
||||
throw new ApplicationException($"Unaple to initialize texture: {SDL.SDL_GetError()}");
|
||||
|
||||
SDL.SDL_LockTexture(texture, IntPtr.Zero, out pixels, out pitch);
|
||||
try
|
||||
{
|
||||
UInt32* data = (UInt32*)pixels;
|
||||
for (var i = 0; i < FrameSize.Width * FrameSize.Height; i++)
|
||||
data[i] = 0;
|
||||
|
||||
for (var subtileX = 0; subtileX < 5; subtileX++)
|
||||
{
|
||||
for (var subtileY = 0; subtileY < 5; subtileY++)
|
||||
{
|
||||
var subtileFlags = tile.SubTileFlags[subtileX + (subtileY * 5)];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
SDL.SDL_UnlockTexture(texture);
|
||||
}
|
||||
}
|
||||
|
||||
internal Point GetRenderPoint()
|
||||
=> new Point(
|
||||
Location.X + source.Frames[Frame].OffsetX,
|
||||
(Location.Y - FrameSize.Height) + source.Frames[Frame].OffsetY
|
||||
);
|
||||
{
|
||||
return source == null
|
||||
? globalFrameOffset
|
||||
: new Point(Location.X + source.Frames[Frame].OffsetX, (Location.Y - FrameSize.Height) + source.Frames[Frame].OffsetY);
|
||||
}
|
||||
|
||||
public Size LocalFrameSize => new Size((int)source.Frames[Frame].Width, (int)source.Frames[Frame].Height);
|
||||
|
||||
@ -152,5 +207,6 @@ namespace OpenDiablo2.SDL2_
|
||||
{
|
||||
SDL.SDL_DestroyTexture(texture);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,9 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using OpenDiablo2.Common;
|
||||
using OpenDiablo2.Common.Attributes;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
using OpenDiablo2.Core.GameState_;
|
||||
|
||||
namespace OpenDiablo2.Scenes
|
||||
{
|
||||
@ -15,13 +17,17 @@ namespace OpenDiablo2.Scenes
|
||||
{
|
||||
private readonly IRenderWindow renderWindow;
|
||||
private readonly IResourceManager resourceManager;
|
||||
private GameState gameState;
|
||||
|
||||
private ISprite testSprite;
|
||||
|
||||
private ISprite panelSprite, healthManaSprite, gameGlobeOverlapSprite;
|
||||
|
||||
public Game(IRenderWindow renderWindow, IResourceManager resourceManager)
|
||||
public Game(IRenderWindow renderWindow, IResourceManager resourceManager, GameState gameState)
|
||||
{
|
||||
this.renderWindow = renderWindow;
|
||||
this.resourceManager = resourceManager;
|
||||
this.gameState = gameState;
|
||||
|
||||
panelSprite = renderWindow.LoadSprite(ResourcePaths.GamePanels, Palettes.Act1);
|
||||
healthManaSprite = renderWindow.LoadSprite(ResourcePaths.HealthMana, Palettes.Act1);
|
||||
@ -30,6 +36,10 @@ namespace OpenDiablo2.Scenes
|
||||
|
||||
public void Render()
|
||||
{
|
||||
if (gameState.MapDirty)
|
||||
RedrawMap();
|
||||
|
||||
renderWindow.Draw(testSprite);
|
||||
|
||||
DrawPanel();
|
||||
|
||||
@ -64,5 +74,15 @@ namespace OpenDiablo2.Scenes
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void RedrawMap()
|
||||
{
|
||||
gameState.MapDirty = false;
|
||||
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
testSprite = renderWindow.GenerateMapCell(gameState.MapData, 0, 0, eRenderCellType.Floor, gameState.CurrentPalette);
|
||||
testSprite.Location = new Point(((x * 80) - (y * 80)) + 100, ((x * 40) + (y * 40)) + 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,8 @@ namespace OpenDiablo2.Scenes
|
||||
this.mouseInfoProvider = mouseInfoProvider;
|
||||
this.sceneManager = sceneManager;
|
||||
|
||||
resourceManager.GetMPQDS1(ResourcePaths.MapAct1TownE1, -1, 1);
|
||||
|
||||
backgroundSprite = renderWindow.LoadSprite(ResourcePaths.GameSelectScreen, Palettes.Sky);
|
||||
diabloLogoLeft = renderWindow.LoadSprite(ResourcePaths.Diablo2LogoFireLeft, Palettes.Units, new Point(400, 120));
|
||||
diabloLogoLeft.Blend = true;
|
||||
|
Loading…
Reference in New Issue
Block a user