private static Map LoadMap(Stream stream) { stream.Seek(0, SeekOrigin.Begin); BinaryReader reader = new BinaryReader(stream); int tileCount = (int)(reader.BaseStream.Length / 6); Map map = new Map(); map._tiles = new MapTile[tileCount]; for (int i = 0; i < tileCount; i++) { ushort floor = reader.ReadUInt16(); ushort leftWall = reader.ReadUInt16(); ushort rightWall = reader.ReadUInt16(); map._tiles[i] = new MapTile(floor, leftWall, rightWall); } reader.Close(); return map; }
public Bitmap RenderMap(Map map, Tileset tiles, PaletteTable tileTable, PaletteTable wallTable, Archive wallSource) { int sxs = selectionXStart; int sys = selectionYStart; int sxe = selectionXEnd; int sye = selectionYEnd; int xMin = sxs < sxe ? sxs : sxe; int yMin = sys < sye ? sys : sye; int xMax = sxs > sxe ? sxs : sxe; int yMax = sys > sye ? sys : sye; Bitmap mapImage = new Bitmap(displaywidth, displayheight); if (map == null) return mapImage; Graphics g = Graphics.FromImage(mapImage); int xOrigin = ((mapImage.Width / 2) - 1) - Tileset.TileWidth / 2 + 1 - hscroll; int yOrigin = -vscroll; bool[,] collision = null; if (tabMap) { collision = new bool[map.Width, map.Height]; } int xMul = Tileset.TileWidth / 2; int yxMultiplier = (Tileset.TileHeight + 1) / 2; if (bgShow) { for (int y = 0; y < map.Height; y++) { for (int x = 0; x < map.Width; x++) { int xd = xOrigin + x * xMul; int yd = yOrigin + x * yxMultiplier; if (xd >= -Tileset.TileWidth && yd >= -Tileset.TileHeight && xd < displaywidth && yd < displayheight) { int floor = map[x, y].FloorTile; bool showSelection = false; if (editMode == 0 || editMode == 3) { if (clickmode == 0 && selection != null && MouseHoverX != -1) { int selectionHeight = selection.Length / selectionWidth; if (x >= MouseHoverX && x < MouseHoverX + selectionWidth && y >= MouseHoverY && y < MouseHoverY + selectionHeight) { int _x = x - MouseHoverX; int _y = y - MouseHoverY; floor = selection[_x + _y * selectionWidth].FloorTile; showSelection = true; } } } if (floor > 0) floor -= 1; if (!cachedFloor.ContainsKey(floor)) { if (floor >= 0 && floor < tiles.TileCount) { Bitmap floorTile = RenderTile(tiles[floor], tileTable[floor + 2]); cachedFloor.Add(floor, floorTile); } } Bitmap thisTile = cachedFloor[floor]; if (editMode == 0 || editMode == 3) { if (showSelection || (selectionXStart != -1 && x >= xMin && x <= xMax && y >= yMin && y <= yMax)) { if (!cachedFloorLight.ContainsKey(floor)) { if (floor >= 0 && floor < tiles.TileCount) { thisTile = RenderTile(tiles[floor], tileTable[floor + 2]); for (int yy = 0; yy < thisTile.Height; yy++) { for (int xx = 0; xx < thisTile.Width; xx++) { Color c = thisTile.GetPixel(xx, yy); int colorR = c.R + 25; if (colorR > 255) colorR = 255; int colorG = c.G + 25; if (colorG > 255) colorG = 255; int colorB = c.B + 50; if (colorB > 255) colorB = 255; if (c.R != 0 || c.G != 0 || c.B != 0) thisTile.SetPixel(xx, yy, Color.FromArgb(colorR, colorG, colorB)); } } cachedFloorLight.Add(floor, thisTile); } } else { thisTile = cachedFloorLight[floor]; } } } g.DrawImageUnscaled(thisTile, xd, yd); } } xOrigin -= xMul; yOrigin += yxMultiplier; } } xOrigin = ((mapImage.Width / 2) - 1) - Tileset.TileWidth / 2 + 1 - hscroll; yOrigin = -vscroll; int yAdd = -150 + (Tileset.TileHeight + 1) / 2; for (int y = 0; y < map.Height; y++) { for (int x = 0; x < map.Width; x++) { int xd = xOrigin + x * xMul; int yd = yOrigin + (x + 1) * yxMultiplier + yAdd; if (xd >= -Tileset.TileWidth && yd >= -200 && xd < displaywidth && yd < displayheight + 200) { int leftWall = map[x, y].LeftWall; if (fg1Show) { bool showSelection = false; if (editMode == 1 || editMode == 3 || editMode == 4) { if (clickmode == 0 && selection != null && MouseHoverX != -1) { int selectionHeight = selection.Length / selectionWidth; if (x >= MouseHoverX && x < MouseHoverX + selectionWidth && y >= MouseHoverY && y < MouseHoverY + selectionHeight) { int _x = x - MouseHoverX; int _y = y - MouseHoverY; int _leftWall = selection[_x + _y * selectionWidth].LeftWall; if (_leftWall > 0 || drawEmptyWalls) { leftWall = _leftWall; showSelection = true; } } } } if (leftWall >= 13) { if (!cachedWalls.ContainsKey(leftWall)) { HPF hpf = HPF.FromArchive("stc" + leftWall.ToString().PadLeft(5, '0') + ".hpf", true, wallSource); Bitmap wall = RenderImage(hpf, wallTable[leftWall + 1]); cachedWalls.Add(leftWall, wall); } Bitmap thisTile = cachedWalls[leftWall]; if (editMode == 1 || editMode == 3 || editMode == 4) { if (showSelection || (selectionXStart != -1 && x >= xMin && x <= xMax && y >= yMin && y <= yMax)) { if (!cachedWallsLight.ContainsKey(leftWall)) { HPF hpf = HPF.FromArchive("stc" + leftWall.ToString().PadLeft(5, '0') + ".hpf", true, wallSource); thisTile = RenderImage(hpf, wallTable[leftWall + 1]); for (int yy = 0; yy < thisTile.Height; yy++) { for (int xx = 0; xx < thisTile.Width; xx++) { Color c = thisTile.GetPixel(xx, yy); int colorR = c.R + 25; if (colorR > 255) colorR = 255; int colorG = c.G + 25; if (colorG > 255) colorG = 255; int colorB = c.B + 50; if (colorB > 255) colorB = 255; if (c.R != 0 || c.G != 0 || c.B != 0) thisTile.SetPixel(xx, yy, Color.FromArgb(colorR, colorG, colorB)); } } cachedWallsLight.Add(leftWall, thisTile); } else { thisTile = cachedWallsLight[leftWall]; } } } if ((leftWall % 10000) > 1) { int xleft = xOrigin + x * xMul; int yleft = yOrigin + (x + 1) * yxMultiplier - thisTile.Height + (Tileset.TileHeight + 1) / 2; if (transparency && leftWall > 0 && leftWall - 1 < sotp.Length && (sotp[leftWall - 1] & 0x80) == 0x80) { for (int yy = 0; yy < thisTile.Height; yy++) { for (int xx = 0; xx < thisTile.Width; xx++) { int origX = xleft + xx; int origY = yleft + yy; if (origX >= 0 && origX < mapImage.Width && origY >= 0 && origY < mapImage.Height) { Color newC = thisTile.GetPixel(xx, yy); if (newC.R != 0 || newC.G != 0 || newC.B != 0) { Color origC = mapImage.GetPixel(origX, origY); int _r = origC.R + newC.R; if (_r > 255) _r = 255; int _g = origC.G + newC.G; if (_g > 255) _g = 255; int _b = origC.B + newC.B; if (_b > 255) _b = 255; Color combined = Color.FromArgb(_r, _g, _b); mapImage.SetPixel(xleft + xx, yleft + yy, combined); } } } } } else { g.DrawImageUnscaled(thisTile, xleft, yleft); } } } } if (tabMap && leftWall > 0 && leftWall - 1 < sotp.Length && sotp[leftWall - 1] == 0x0F) { collision[x, y] = true; } int rightWall = map[x, y].RightWall; if (fg2Show) { bool showSelection = false; if (editMode == 2 || editMode == 3 || editMode == 4) { if (clickmode == 0 && selection != null && MouseHoverX != -1) { int selectionHeight = selection.Length / selectionWidth; if (x >= MouseHoverX && x < MouseHoverX + selectionWidth && y >= MouseHoverY && y < MouseHoverY + selectionHeight) { int _x = x - MouseHoverX; int _y = y - MouseHoverY; int _rightWall = selection[_x + _y * selectionWidth].RightWall; if (_rightWall > 0 || drawEmptyWalls) { rightWall = _rightWall; showSelection = true; } } } } if (rightWall >= 13) { if (!cachedWalls.ContainsKey(rightWall)) { HPF hpf = HPF.FromArchive("stc" + rightWall.ToString().PadLeft(5, '0') + ".hpf", true, wallSource); Bitmap wall = RenderImage(hpf, wallTable[rightWall + 1]); cachedWalls.Add(rightWall, wall); } Bitmap thisTile = cachedWalls[rightWall]; if (editMode == 2 || editMode == 3 || editMode == 4) { if (showSelection || (selectionXStart != -1 && x >= xMin && x <= xMax && y >= yMin && y <= yMax)) { if (!cachedWallsLight.ContainsKey(rightWall)) { HPF hpf = HPF.FromArchive("stc" + rightWall.ToString().PadLeft(5, '0') + ".hpf", true, wallSource); thisTile = RenderImage(hpf, wallTable[rightWall + 1]); for (int yy = 0; yy < thisTile.Height; yy++) { for (int xx = 0; xx < thisTile.Width; xx++) { Color c = thisTile.GetPixel(xx, yy); int colorR = c.R + 25; if (colorR > 255) colorR = 255; int colorG = c.G + 25; if (colorG > 255) colorG = 255; int colorB = c.B + 50; if (colorB > 255) colorB = 255; if (c.R != 0 || c.G != 0 || c.B != 0) thisTile.SetPixel(xx, yy, Color.FromArgb(colorR, colorG, colorB)); } } cachedWallsLight.Add(rightWall, thisTile); } else { thisTile = cachedWallsLight[rightWall]; } } } if ((rightWall % 10000) > 1) { int xright = xOrigin + (x + 1) * xMul; int yright = yOrigin + (x + 1) * yxMultiplier - thisTile.Height + (Tileset.TileHeight + 1) / 2; if (transparency && rightWall > 0 && rightWall - 1 < sotp.Length && (sotp[rightWall - 1] & 0x80) == 0x80) { for (int yy = 0; yy < thisTile.Height; yy++) { for (int xx = 0; xx < thisTile.Width; xx++) { int origX = xright + xx; int origY = yright + yy; if (origX >= 0 && origX < mapImage.Width && origY >= 0 && origY < mapImage.Height) { Color origC = mapImage.GetPixel(origX, origY); Color newC = thisTile.GetPixel(xx, yy); int _r = origC.R + newC.R; if (_r > 255) _r = 255; int _g = origC.G + newC.G; if (_g > 255) _g = 255; int _b = origC.B + newC.B; if (_b > 255) _b = 255; Color combined = Color.FromArgb(_r, _g, _b); mapImage.SetPixel(xright + xx, yright + yy, combined); } } } } else { g.DrawImageUnscaled(thisTile, xright, yright); } } } } if (tabMap && rightWall > 0 && rightWall - 1 < sotp.Length && sotp[rightWall - 1] == 0x0F) { collision[x, y] = true; } } } xOrigin -= xMul; yOrigin += yxMultiplier; } if (tabMap) { xOrigin = ((mapImage.Width / 2) - 1) - Tileset.TileWidth / 2 + 1 - hscroll; yOrigin = -vscroll; for (int y = 0; y < map.Height; y++) { for (int x = 0; x < map.Width; x++) { if (tabMap && collision[x, y]) { int xDraw = xOrigin + x * Tileset.TileWidth / 2 + Tileset.TileWidth / 2; int yDraw = yOrigin + x * (Tileset.TileHeight + 1) / 2; PointF[] ps = new PointF[4]; ps[0] = new PointF(xDraw, yDraw); ps[1] = new PointF(xDraw + Tileset.TileWidth / 2, yDraw + Tileset.TileHeight / 2); ps[2] = new PointF(xDraw, yDraw + Tileset.TileHeight); ps[3] = new PointF(xDraw - Tileset.TileWidth / 2, yDraw + Tileset.TileHeight / 2); g.FillPolygon((new SolidBrush(Color.FromArgb(128, 255, 255, 255))), ps); } } xOrigin -= Tileset.TileWidth / 2; yOrigin += (Tileset.TileHeight + 1) / 2; } } if (drawGridLines) { xOrigin = ((mapImage.Width / 2) - 1) - hscroll; yOrigin = -vscroll; for (int y = 0; y < map.Height; y++) { int xPos = xOrigin - y * (Tileset.TileWidth) / 2; int yPos = (int)(yOrigin + y * ((Tileset.TileHeight + 1) / 2)) - 1; int xEnd = xPos + (map.Width - 1) * (Tileset.TileWidth + 1) / 2; int yEnd = (int)(yPos + (map.Height - 1) * (Tileset.TileHeight + 1.5) / 2); g.DrawLine(new Pen(new SolidBrush(Color.Green)), xPos, yPos, xEnd, yEnd); } for (int x = 0; x < map.Width; x++) { int xPos = xOrigin + x * (Tileset.TileWidth) / 2; int yPos = (int)(yOrigin + x * ((Tileset.TileHeight + 1) / 2)) - 1; int xEnd = xPos - (map.Width - 1) * (Tileset.TileWidth + 1) / 2; int yEnd = (int)(yPos + (map.Height - 1) * (Tileset.TileHeight + 1.5) / 2); g.DrawLine(new Pen(new SolidBrush(Color.Green)), xPos, yPos, xEnd, yEnd); } } g.Dispose(); GC.Collect(); return mapImage; }