mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-01-13 04:46:38 -05:00
Rendering refactor
This commit is contained in:
parent
cb8916c085
commit
ea5c8bd787
@ -10,6 +10,9 @@ namespace OpenDiablo2.Common.Enums
|
||||
{
|
||||
None,
|
||||
Act1_Town = 1,
|
||||
Act2_Town = 40,
|
||||
Act2_Harem = 50,
|
||||
Act3_Town = 75,
|
||||
Act4_Fortress = 103,
|
||||
Act5_Baal_Entrance = 120
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ namespace OpenDiablo2.Common.Interfaces
|
||||
{
|
||||
MPQDS1 MapData { get; }
|
||||
int Act { get; }
|
||||
int Seed { get; }
|
||||
string MapName { get; }
|
||||
Palette CurrentPalette { get; }
|
||||
|
||||
|
@ -29,6 +29,6 @@ namespace OpenDiablo2.Common.Interfaces
|
||||
void Draw(ISprite sprite, int frame);
|
||||
void Draw(ISprite sprite, int xSegments, int ySegments, int offset);
|
||||
void Draw(ILabel label);
|
||||
void DrawMapCell(int xCell, int yCell, int xPixel, int yPixel, MPQDS1 mapData, int main_index, int sub_index, Palette palette);
|
||||
void DrawMapCell(int xCell, int yCell, int xPixel, int yPixel, MPQDS1 mapData, int main_index, int sub_index, Palette palette, MPQDS1WallOrientationTileProps orientation);
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +58,17 @@ namespace OpenDiablo2.Common.Models
|
||||
public Int32 Height { get; internal set; }
|
||||
}
|
||||
|
||||
public struct DS1LookupTable
|
||||
{
|
||||
public int Orientation;
|
||||
public int MainIndex;
|
||||
public int SubIndex;
|
||||
public int Frame;
|
||||
|
||||
public MPQDT1Tile TileRef;
|
||||
|
||||
}
|
||||
|
||||
public sealed class MPQDS1
|
||||
{
|
||||
static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
@ -76,6 +87,7 @@ namespace OpenDiablo2.Common.Models
|
||||
public Int32 NumberOfGroups { get; internal set; }
|
||||
|
||||
public MPQDT1[] DT1s = new MPQDT1[33];
|
||||
public List<DS1LookupTable> LookupTable { get; internal set; }
|
||||
|
||||
public List<string> FileNames { get; internal set; } = new List<string>();
|
||||
public MPQDS1WallLayer[] WallLayers { get; internal set; }
|
||||
@ -230,7 +242,13 @@ namespace OpenDiablo2.Common.Models
|
||||
}
|
||||
else
|
||||
{
|
||||
br.ReadBytes(4);
|
||||
WallLayers[layoutStream[n] - 5].Orientations[x + (y * Width)] = new MPQDS1WallOrientationTileProps
|
||||
{
|
||||
Orientation1 = br.ReadByte(),
|
||||
Orientation2 = br.ReadByte(),
|
||||
Orientation3 = br.ReadByte(),
|
||||
Orientation4 = br.ReadByte(),
|
||||
};
|
||||
}
|
||||
break;
|
||||
|
||||
@ -264,60 +282,6 @@ namespace OpenDiablo2.Common.Models
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
NumberOfObjects = 0;
|
||||
if (Version >= 2)
|
||||
{
|
||||
|
||||
NumberOfObjects = br.ReadInt32();
|
||||
Objects = new MPQDS1Object[NumberOfObjects];
|
||||
|
||||
for (int i = 0; i < NumberOfObjects; i++)
|
||||
{
|
||||
Objects[i] = new MPQDS1Object
|
||||
{
|
||||
Type = br.ReadInt32(),
|
||||
Id = br.ReadInt32(),
|
||||
X = br.ReadInt32(),
|
||||
Y = br.ReadInt32()
|
||||
};
|
||||
|
||||
if (Version > 5)
|
||||
Objects[i].DS1Flags = br.ReadInt32();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (Version >= 12 && TagType == 1 || TagType == 2)
|
||||
{
|
||||
if (Version >= 18)
|
||||
br.ReadBytes(4);
|
||||
|
||||
NumberOfGroups = br.ReadInt32();
|
||||
}
|
||||
else NumberOfGroups = 0;
|
||||
|
||||
|
||||
Groups = new MPQDS1Group[NumberOfGroups];
|
||||
for (var x = 0; x < NumberOfGroups; x++)
|
||||
{
|
||||
Groups[x] = new MPQDS1Group
|
||||
{
|
||||
TileX = br.ReadInt32(),
|
||||
TileY = br.ReadInt32(),
|
||||
Width = br.ReadInt32(),
|
||||
Height = br.ReadInt32(),
|
||||
};
|
||||
if (Version >= 13)
|
||||
br.ReadBytes(4);
|
||||
}
|
||||
|
||||
if (Version >= 14)
|
||||
{
|
||||
|
||||
NumberOfNPCs = br.ReadInt32();
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
@ -335,6 +299,24 @@ namespace OpenDiablo2.Common.Models
|
||||
DT1s[i] = resourceManager.GetMPQDT1("data\\global\\tiles\\" + levelType.File[i].Replace("/", "\\"));
|
||||
|
||||
}
|
||||
|
||||
LookupTable = new List<DS1LookupTable>();
|
||||
foreach(var dt1 in DT1s.Where(x => x != null))
|
||||
{
|
||||
foreach(var tile in dt1.Tiles)
|
||||
{
|
||||
LookupTable.Add(new DS1LookupTable
|
||||
{
|
||||
MainIndex = tile.MainIndex,
|
||||
Orientation = tile.Orientation,
|
||||
SubIndex = tile.SubIndex,
|
||||
Frame = tile.RarityOrFrameIndex,
|
||||
TileRef = tile
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ namespace OpenDiablo2.Core.GameState_
|
||||
public string MapName { get; private set; }
|
||||
public Palette CurrentPalette => paletteProvider.PaletteTable[$"ACT{Act}"];
|
||||
|
||||
public int Seed { get; internal set; }
|
||||
|
||||
public GameState(
|
||||
ISceneManager sceneManager,
|
||||
IResourceManager resourceManager,
|
||||
@ -36,10 +38,15 @@ namespace OpenDiablo2.Core.GameState_
|
||||
this.paletteProvider = paletteProvider;
|
||||
this.getMapEngine = getMapEngine;
|
||||
this.engineDataManager = engineDataManager;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void Initialize(string characterName, eHero hero)
|
||||
{
|
||||
var random = new Random();
|
||||
Seed = random.Next();
|
||||
|
||||
sceneManager.ChangeScene("Game");
|
||||
ChangeMap(eLevelId.Act1_Town);
|
||||
}
|
||||
@ -59,10 +66,10 @@ namespace OpenDiablo2.Core.GameState_
|
||||
if (level.File5 != "0") mapNames.Add(level.File5);
|
||||
if (level.File6 != "0") mapNames.Add(level.File6);
|
||||
|
||||
var random = new Random();
|
||||
var random = new Random(Seed);
|
||||
var mapName = "data\\global\\tiles\\" + mapNames[random.Next(mapNames.Count())].Replace("/", "\\");
|
||||
MapName = level.Name;
|
||||
Act = Convert.ToInt32(mapNames.First().Substring(3, 1));
|
||||
Act = levelType.Act;
|
||||
MapData = resourceManager.GetMPQDS1(mapName, level, levelDetails, levelType);
|
||||
getMapEngine().NotifyMapChanged();
|
||||
}
|
||||
|
@ -57,36 +57,27 @@ namespace OpenDiablo2.Core.Map_Engine
|
||||
{
|
||||
PurgeAllMapData();
|
||||
LoadNewMapData();
|
||||
CameraLocation = new PointF(gameState.MapData.Width / 2, gameState.MapData.Height / 2);
|
||||
//CameraLocation = new PointF(gameState.MapData.Width / 2, gameState.MapData.Height / 2);
|
||||
}
|
||||
|
||||
private void LoadNewMapData()
|
||||
{
|
||||
/*
|
||||
var cellsToLoad = gameState.MapData.Width * gameState.MapData.Height;
|
||||
tempMapCell = new ISprite[cellsToLoad];
|
||||
|
||||
for (var cell = 0; cell < cellsToLoad; cell++)
|
||||
{
|
||||
renderWindow.Clear();
|
||||
loadingSprite.Frame = (int)(loadingSprite.TotalFrames * ((float)cell / (float)cellsToLoad));
|
||||
renderWindow.Draw(loadingSprite);
|
||||
renderWindow.Sync();
|
||||
|
||||
tempMapCell[cell] = renderWindow.GenerateMapCell(
|
||||
gameState.MapData,
|
||||
cell % gameState.MapData.Width,
|
||||
cell / gameState.MapData.Width,
|
||||
Common.Enums.eRenderCellType.Floor,
|
||||
gameState.CurrentPalette
|
||||
);
|
||||
}
|
||||
*/
|
||||
//CameraLocation = new Point(((gameState.MapData.Width * cellSizeX) / 2) - 400, ((gameState.MapData.Height * cellSizeY) / 2) - 300);
|
||||
}
|
||||
|
||||
public void Render()
|
||||
{
|
||||
// Lower Walls, Floors, and Shadows
|
||||
|
||||
// Shadows of objects
|
||||
|
||||
// Objects with OrderFlag = 1
|
||||
|
||||
// Upper Walls and objects with ORderFlag = 0 or 2
|
||||
|
||||
// Roofs
|
||||
|
||||
|
||||
for (int y = 0; y < gameState.MapData.Width; y++)
|
||||
for (int x = 0; x < gameState.MapData.Height; x++)
|
||||
{
|
||||
@ -94,27 +85,63 @@ namespace OpenDiablo2.Core.Map_Engine
|
||||
var visualX = ((x - y) * (cellSizeX / 2)) - cOffX;
|
||||
var visualY = ((x + y) * (cellSizeY / 2)) - cOffY;
|
||||
|
||||
if (visualX < -160 || visualX > 800 || visualY < -80 || visualY > 600)
|
||||
if (visualX < -160 || visualX > 800 || visualY < -120 || visualY > 650)
|
||||
continue;
|
||||
|
||||
var floorLayer = gameState.MapData.FloorLayers[0];
|
||||
var idx = x + (y * gameState.MapData.Width);
|
||||
if (idx >= floorLayer.Props.Length)
|
||||
break;
|
||||
var floor = floorLayer.Props[idx];
|
||||
// Render the floor
|
||||
foreach (var floorLayer in gameState.MapData.FloorLayers)
|
||||
{
|
||||
var idx = x + (y * gameState.MapData.Width);
|
||||
if (idx >= floorLayer.Props.Length)
|
||||
break;
|
||||
var floor = floorLayer.Props[idx];
|
||||
|
||||
if (floor.Prop1 == 0)
|
||||
return;
|
||||
if (floor.Prop1 == 0)
|
||||
continue;
|
||||
|
||||
var sub_index = floor.Prop2;
|
||||
var main_index = (floor.Prop3 >> 4) + ((floor.Prop4 & 0x03) << 4);
|
||||
var sub_index = floor.Prop2;
|
||||
var main_index = (floor.Prop3 >> 4) + ((floor.Prop4 & 0x03) << 4);
|
||||
|
||||
|
||||
if (x < 0 || y < 0 || x >= gameState.MapData.Width || y >= gameState.MapData.Height)
|
||||
continue;
|
||||
renderWindow.DrawMapCell(x, y, ((x - y) * 80) - cOffX, ((x + y) * 40) - cOffY, gameState.MapData, main_index, sub_index, gameState.CurrentPalette, null);
|
||||
}
|
||||
|
||||
renderWindow.DrawMapCell(x, y, ((x - y) * 80) - cOffX, ((x + y) * 40) - cOffY, gameState.MapData, main_index, sub_index, gameState.CurrentPalette);
|
||||
}
|
||||
/*
|
||||
|
||||
// Render the walls
|
||||
foreach (var wallLayer in gameState.MapData.WallLayers)
|
||||
{
|
||||
|
||||
for (int y = 0; y < gameState.MapData.Width; y++)
|
||||
for (int x = 0; x < gameState.MapData.Height; x++)
|
||||
{
|
||||
|
||||
var visualX = ((x - y) * (cellSizeX / 2)) - cOffX;
|
||||
var visualY = ((x + y) * (cellSizeY / 2)) - cOffY;
|
||||
|
||||
if (visualX < -160 || visualX > 800 || visualY < -120 || visualY > 650)
|
||||
continue;
|
||||
|
||||
var idx = x + (y * gameState.MapData.Width);
|
||||
if (idx >= wallLayer.Props.Length)
|
||||
continue;
|
||||
var wall = wallLayer.Props[idx];
|
||||
|
||||
if (wall.Prop1 == 0)
|
||||
continue;
|
||||
|
||||
var sub_index = wall.Prop2;
|
||||
var main_index = (wall.Prop3 >> 4) + ((wall.Prop4 & 0x03) << 4);
|
||||
|
||||
var orientation = wallLayer.Orientations[x + (y * gameState.MapData.Width)];
|
||||
renderWindow.DrawMapCell(x, y, ((x - y) * 80) - cOffX, ((x + y) * 40) - cOffY + 80, gameState.MapData, main_index, sub_index, gameState.CurrentPalette, orientation);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
public void Update(long ms)
|
||||
|
@ -32,18 +32,21 @@ namespace OpenDiablo2.SDL2_
|
||||
private readonly IMPQProvider mpqProvider;
|
||||
private readonly IPaletteProvider paletteProvider;
|
||||
private readonly IResourceManager resourceManager;
|
||||
private readonly IGameState gameState;
|
||||
|
||||
private IntPtr cellTexture;
|
||||
|
||||
public SDL2RenderWindow(
|
||||
IMPQProvider mpqProvider,
|
||||
IPaletteProvider paletteProvider,
|
||||
IResourceManager resourceManager
|
||||
IResourceManager resourceManager,
|
||||
IGameState gameState
|
||||
)
|
||||
{
|
||||
this.mpqProvider = mpqProvider;
|
||||
this.paletteProvider = paletteProvider;
|
||||
this.resourceManager = resourceManager;
|
||||
this.gameState = gameState;
|
||||
|
||||
SDL.SDL_Init(SDL.SDL_INIT_EVERYTHING);
|
||||
if (SDL.SDL_SetHint(SDL.SDL_HINT_RENDER_SCALE_QUALITY, "0") == SDL.SDL_bool.SDL_FALSE)
|
||||
@ -61,7 +64,7 @@ namespace OpenDiablo2.SDL2_
|
||||
SDL.SDL_SetRenderDrawBlendMode(renderer, SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
|
||||
SDL.SDL_ShowCursor(0);
|
||||
|
||||
cellTexture = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_ARGB8888, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_STREAMING, 256, 256);
|
||||
cellTexture = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_ARGB8888, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_STREAMING, 256, 1024);
|
||||
SDL.SDL_SetTextureBlendMode(cellTexture, SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
|
||||
|
||||
|
||||
@ -277,23 +280,34 @@ namespace OpenDiablo2.SDL2_
|
||||
SDL.SDL_RenderCopy(renderer, lbl.texture, IntPtr.Zero, ref destRect);
|
||||
}
|
||||
|
||||
public unsafe void DrawMapCell(int xCell, int yCell, int xPixel, int yPixel, MPQDS1 mapData, int main_index, int sub_index, Palette palette)
|
||||
public unsafe void DrawMapCell(int xCell, int yCell, int xPixel, int yPixel, MPQDS1 mapData, int main_index, int sub_index, Palette palette, MPQDS1WallOrientationTileProps orientation)
|
||||
{
|
||||
|
||||
var tiles = mapData.LookupTable.Where(x =>
|
||||
x.MainIndex == main_index &&
|
||||
x.SubIndex == sub_index &&
|
||||
(orientation == null || x.Orientation == orientation.Orientation1)).Select(x => x.TileRef);
|
||||
|
||||
if (!tiles.Any())
|
||||
return; // TODO: Why does this happen....
|
||||
|
||||
MPQDT1Tile tile = null;
|
||||
for (int i = 0; i < mapData.DT1s.Count(); i++)
|
||||
if (tiles.Count() > 0)
|
||||
{
|
||||
if (mapData.DT1s[i] == null)
|
||||
continue;
|
||||
|
||||
tile = mapData.DT1s[i].Tiles.FirstOrDefault(z => z.MainIndex == main_index && z.SubIndex == sub_index);
|
||||
if (tile != null)
|
||||
break;
|
||||
}
|
||||
|
||||
if (tile == null)
|
||||
throw new ApplicationException("Could not locate tile!");
|
||||
|
||||
var totalRarity = tiles.Sum(q => q.RarityOrFrameIndex);
|
||||
var random = new Random(gameState.Seed + xCell + (mapData.Width * yCell));
|
||||
var x = random.Next(totalRarity);
|
||||
var z = 0;
|
||||
foreach(var t in tiles)
|
||||
{
|
||||
z += t.RarityOrFrameIndex;
|
||||
if (x <= z)
|
||||
{
|
||||
tile = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else tile = tiles.First();
|
||||
|
||||
var frameSize = new Size(tile.Width, Math.Abs(tile.Height));
|
||||
var srcRect = new SDL.SDL_Rect { x = 0, y = 0, w = frameSize.Width, h = frameSize.Height };
|
||||
@ -315,16 +329,20 @@ namespace OpenDiablo2.SDL2_
|
||||
{
|
||||
var index = block.PositionX + ((block.PositionY) * pitchChange);
|
||||
var xx = 0;
|
||||
var yy = 0;
|
||||
foreach (var colorIndex in block.PixelData)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (colorIndex == 0)
|
||||
continue;
|
||||
var color = palette.Colors[colorIndex];
|
||||
|
||||
|
||||
if ((color & 0xFFFFFF) > 0)
|
||||
data[index] = color;
|
||||
|
||||
} finally
|
||||
}
|
||||
finally
|
||||
{
|
||||
index++;
|
||||
xx++;
|
||||
@ -333,6 +351,7 @@ namespace OpenDiablo2.SDL2_
|
||||
index -= 32;
|
||||
index += pitchChange;
|
||||
xx = 0;
|
||||
yy++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -343,8 +362,9 @@ namespace OpenDiablo2.SDL2_
|
||||
SDL.SDL_UnlockTexture(cellTexture);
|
||||
}
|
||||
|
||||
|
||||
var dstRect = new SDL.SDL_Rect { x = xPixel, y = yPixel, w = frameSize.Width, h = frameSize.Height };
|
||||
SDL.SDL_SetRenderDrawBlendMode(renderer, SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
|
||||
SDL.SDL_SetTextureBlendMode(cellTexture, SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
|
||||
var dstRect = new SDL.SDL_Rect { x = xPixel, y = yPixel - tile.RoofHeight, w = frameSize.Width, h = frameSize.Height };
|
||||
SDL.SDL_RenderCopy(renderer, cellTexture, ref srcRect, ref dstRect);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user