public static async Task<PixelColor[,]> GetPixels(RenderTargetBitmap source) { int width = source.PixelWidth; int height = source.PixelHeight; var result = new PixelColor[width, height]; var buffer = await source.GetPixelsAsync(); var bytes = buffer.ToArray(); for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { var k = (y * width + x) * 4; result[x, y] = new PixelColor { Blue = bytes[k], Green = bytes[k + 1], Red = bytes[k + 2] }; } } return result; }
public Block Parse(int x, int y, PixelColor[,] pixels) { if (isUnknown(pixels)) return new Block(x, y, BlockState.Unknown); if (isZero(pixels)) return new Block(x, y, 0); if (compareImages(pixels, imgOne)) return new Block(x, y, 1); if (compareImages(pixels, imgTwo)) return new Block(x, y, 2); if (compareImages(pixels, imgThree)) return new Block(x, y, 3); if (compareImages(pixels, imgFour)) return new Block(x, y, 4); if (compareImages(pixels, imgFive)) return new Block(x, y, 5); if (compareImages(pixels, imgSix)) return new Block(x, y, 6); if (compareImages(pixels, imgSeven)) return new Block(x, y, 7); if (isFlag(pixels)) return new Block(x, y, BlockState.Flag); if (compareImages(pixels, imgGuess)) return new Block(x, y, BlockState.Unknown, true); return new Block(x, y, BlockState.ParseFailed); }
public static bool CompareImages(PixelColor[,] p1, PixelColor[,] p2) { if (p1.GetLength(0) != p2.GetLength(0)) return false; long red = 0, green = 0, blue = 0; for (int i = 1; i < p1.GetLength(0) - 1; i++) { for (int j = 1; j < p1.GetLength(1) - 1; j++) { PixelColor color = p1[i, j]; PixelColor average = getAverageColor(p2, i, j); PixelColor diff = color - average; red += diff.Red; green += diff.Green; blue += diff.Blue; } } red = (int)((float)red / p1.Length); green = (int)((float)green / p1.Length); blue = (int)((float)blue / p1.Length); float total = (float)(red + green + blue) / 3f; return total < 6; }
public static unsafe void CopyPixels(this BitmapSource source, PixelColor[,] pixels, int stride, int offset) { fixed(PixelColor* buffer = &pixels[0, 0]) source.CopyPixels( new Int32Rect(0, 0, source.PixelWidth, source.PixelHeight), (IntPtr)(buffer + offset), pixels.GetLength(0) * pixels.GetLength(1) * sizeof(PixelColor), stride); }
public Pixel(int x, int y, int width, int height, PixelColor color) { this.X = x; this.Y = y; this.Width = width; this.Height = height; this.Color = color; if (color == PixelColor.Black) this.Value = 1; else this.Value = 0; }
public PixelColor[,] GetPixels(BitmapSource source) { var height = source.PixelHeight; var width = source.PixelWidth; var pixelBytes = new byte[height * width * 4]; var pixels = new PixelColor[height, width]; source.CopyPixels(pixelBytes, ((source as BitmapImage).PixelWidth * (source as BitmapImage).Format.BitsPerPixel + 7) / 8, 0); for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) pixels[y, x] = new PixelColor { Blue = pixelBytes[(y * width + x) * 4 + 0], Green = pixelBytes[(y * width + x) * 4 + 1], Red = pixelBytes[(y * width + x) * 4 + 2], Alpha = pixelBytes[(y * width + x) * 4 + 3], }; return pixels; }
//mxd public bool Setup(SectorLevel level, Effect3DFloor extrafloor, bool innerside) { Sector s = level.sector; Vector2D texscale; this.innerside = innerside; //mxd base.Setup(level, extrafloor); // Fetch ZDoom fields float rotate = Angle2D.DegToRad(s.Fields.GetValue("rotationceiling", 0.0f)); Vector2D offset = new Vector2D(s.Fields.GetValue("xpanningceiling", 0.0f), s.Fields.GetValue("ypanningceiling", 0.0f)); Vector2D scale = new Vector2D(s.Fields.GetValue("xscaleceiling", 1.0f), s.Fields.GetValue("yscaleceiling", 1.0f)); //Load ceiling texture if (s.LongCeilTexture != MapSet.EmptyLongName) { base.Texture = General.Map.Data.GetFlatImage(s.LongCeilTexture); if (base.Texture == null || base.Texture is UnknownImage) { base.Texture = General.Map.Data.UnknownTexture3D; setuponloadedtexture = s.LongCeilTexture; } else if (!base.Texture.IsImageLoaded) { setuponloadedtexture = s.LongCeilTexture; } } else { // Use missing texture base.Texture = General.Map.Data.MissingTexture3D; setuponloadedtexture = 0; } // Determine texture scale if (base.Texture.IsImageLoaded) { texscale = new Vector2D(1.0f / base.Texture.ScaledWidth, 1.0f / base.Texture.ScaledHeight); } else { texscale = new Vector2D(1.0f / 64.0f, 1.0f / 64.0f); } // Determine brightness byte alpha = (byte)General.Clamp(level.alpha, 0, 255); int color = PixelColor.FromInt(level.color).WithAlpha(alpha).ToInt(); int targetbrightness; if (extrafloor != null && !extrafloor.VavoomType && !level.disablelighting) { //mxd. Top extrafloor level should calculate fogdensity from the brightness of the level above it if (!innerside) { targetbrightness = 0; SectorData sd = mode.GetSectorData(this.Sector.Sector); for (int i = 0; i < sd.LightLevels.Count - 1; i++) { if (sd.LightLevels[i] == level) { targetbrightness = sd.LightLevels[i + 1].brightnessbelow; break; } } } //mxd. Inner extrafloor ceilings must be colored using control sector's color and brightness else { targetbrightness = level.brightnessbelow; SectorData sd = mode.GetSectorData(this.Sector.Sector); for (int i = 0; i < sd.LightLevels.Count; i++) { if (sd.LightLevels[i] == level) { if (i > 0) { color = PixelColor.FromInt(sd.LightLevels[i - 1].color).WithAlpha(alpha).ToInt(); } break; } } } } else { targetbrightness = level.brightnessbelow; } //mxd. Determine fog density fogfactor = CalculateFogFactor(targetbrightness); // Make vertices ReadOnlyCollection <Vector2D> triverts = Sector.Sector.Triangles.Vertices; WorldVertex[] verts = new WorldVertex[triverts.Count]; for (int i = 0; i < triverts.Count; i++) { // Color shading verts[i].c = color; //mxd // Vertex coordinates verts[i].x = triverts[i].x; verts[i].y = triverts[i].y; verts[i].z = level.plane.GetZ(triverts[i]); // Texture coordinates Vector2D pos = triverts[i]; pos = pos.GetRotated(rotate); pos.y = -pos.y; pos = (pos + offset) * scale * texscale; verts[i].u = pos.x; verts[i].v = pos.y; } // The sector triangulation created clockwise triangles that // are right up for the floor. For the ceiling we must flip // the triangles upside down. if (extrafloor == null || extrafloor.VavoomType || innerside) { SwapTriangleVertices(verts); } // Determine render pass if (extrafloor != null) { if (extrafloor.Sloped3dFloor) //mxd { this.RenderPass = RenderPass.Mask; } else if (extrafloor.RenderAdditive) //mxd { this.RenderPass = RenderPass.Additive; } else if (level.alpha < 255) { this.RenderPass = RenderPass.Alpha; } else { this.RenderPass = RenderPass.Mask; } } else { this.RenderPass = RenderPass.Solid; } //mxd. Update sky render flag UpdateSkyRenderFlag(); // Apply vertices base.SetVertices(verts); return(verts.Length > 0); }
/// <summary> /// Embeds the text using three bits. /// </summary> /// <param name="sourcePixels">The source pixels.</param> /// <param name="decoderPixelWidth">Width of the decoder pixel.</param> /// <param name="decoderPixelHeight">Height of the decoder pixel.</param> /// <param name="text">The text.</param> public void EmbedTextUsingThreeBits(byte[] sourcePixels, uint decoderPixelWidth, uint decoderPixelHeight, string text) { long pixelElementIndex = 0; int charIndex = 0; string wholebyte = ""; int bitsThatAreSet = 0; for (var i = 0; i < decoderPixelHeight; i++) { if (bitsThatAreSet % 9 == 0) { } for (var j = 0; j < decoderPixelWidth; j++) { var pixelColor = PixelColor.GetPixelBgra8(sourcePixels, i, j, decoderPixelWidth, decoderPixelHeight); int r = pixelColor.R; int g = pixelColor.G; int b = pixelColor.B; r &= ~(1 << 0); r &= ~(1 << 1); g &= ~(1 << 0); g &= ~(1 << 1); b &= ~(1 << 0); b &= ~(1 << 1); if (j == 0 && i == 0) { pixelColor.R = 119; pixelColor.B = 119; pixelColor.G = 119; PixelColor.SetPixelBgra8(sourcePixels, i, j, pixelColor, decoderPixelWidth, decoderPixelHeight); } else if (j == 1 && i == 0) { pixelColor.R |= 1; pixelColor.G = (byte)g; pixelColor.G |= 1 << 1; PixelColor.SetPixelBgra8(sourcePixels, i, j, pixelColor, decoderPixelWidth, decoderPixelHeight); } else { for (int n = 0; n < 3; n++) { if (pixelElementIndex % 4 == 0) { if (charIndex >= text.Length) { PixelColor.SetPixelBgra8(sourcePixels, i, j, pixelColor, decoderPixelWidth, decoderPixelHeight); } else { int charValue = text[charIndex++]; wholebyte = Convert.ToString(charValue, 2).PadLeft(8, '0'); } } switch (pixelElementIndex % 3) { case 0: { if (charIndex < text.Length) { if (wholebyte.Length != 0 && Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 0) { r |= 0 << 0; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } else if (wholebyte.Length != 0 && Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 1) { r |= 1 << 0; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } if (wholebyte.Length != 0 && Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 0) { r |= 0 << 1; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } else if (wholebyte.Length != 0 && Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 1) { r |= 1 << 1; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } if (wholebyte.Length != 0 && Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 0) { r |= 0 << 1; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } else if (wholebyte.Length != 0 && Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 1) { r |= 1 << 1; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } } pixelColor.R = (byte)r; } break; case 1: { if (charIndex < text.Length) { if (wholebyte.Length != 0 && Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 0) { g |= 0 << 0; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } else if (wholebyte.Length != 0 && Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 1) { g |= 1 << 0; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } if (wholebyte.Length != 0 && Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 0) { g |= 0 << 1; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } else if (wholebyte.Length != 0 && Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 1) { g |= 1 << 1; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } if (wholebyte.Length != 0 && Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 0) { g |= 0 << 1; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } else if (wholebyte.Length != 0 && Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 1) { g |= 1 << 1; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } } pixelColor.G = (byte)g; } break; case 2: { if (charIndex < text.Length) { if (wholebyte.Length != 0 && Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 0) { b |= 0 << 0; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } else if (wholebyte.Length != 0 && Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 1) { b |= 1 << 0; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } if (wholebyte.Length != 0 && Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 0) { b |= 0 << 1; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } else if (wholebyte.Length != 0 && Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 1) { b |= 1 << 1; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } if (wholebyte.Length != 0 && Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 0) { b |= 0 << 1; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } else if (wholebyte.Length != 0 && Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 1) { b |= 1 << 1; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } } pixelColor.B = (byte)b; PixelColor.SetPixelBgra8(sourcePixels, i, j, pixelColor, decoderPixelWidth, decoderPixelHeight); } break; } pixelElementIndex++; } } } } }
/// <summary> /// Embeds the text using two bits. /// </summary> /// <param name="sourcePixels">The source pixels.</param> /// <param name="decoderPixelWidth">Width of the decoder pixel.</param> /// <param name="decoderPixelHeight">Height of the decoder pixel.</param> /// <param name="text">The text.</param> /// <param name="isEncrypted">if set to <c>true</c> [is encrypted].</param> /// <param name="rotated">The rotated.</param> public void EmbedTextUsingTwoBits(byte[] sourcePixels, uint decoderPixelWidth, uint decoderPixelHeight, string text, bool isEncrypted, int rotated) { if (isEncrypted) { text = text.ForwardRot(rotated); } text += "!EOM!"; long pixelElementIndex = 0; int charIndex = 0; bool notDone = true; string wholebyte = ""; for (var i = 0; i < decoderPixelHeight; i++) { for (var j = 0; j < decoderPixelWidth; j++) { var pixelColor = PixelColor.GetPixelBgra8(sourcePixels, i, j, decoderPixelWidth, decoderPixelHeight); int r = pixelColor.R; int g = pixelColor.G; int b = pixelColor.B; r &= ~(1 << 0); r &= ~(1 << 1); g &= ~(1 << 0); g &= ~(1 << 1); b &= ~(1 << 0); b &= ~(1 << 1); if (j == 0 && i == 0) { pixelColor.R = 119; pixelColor.B = 119; pixelColor.G = 119; PixelColor.SetPixelBgra8(sourcePixels, i, j, pixelColor, decoderPixelWidth, decoderPixelHeight); } else if (j == 1 && i == 0) { pixelColor.R |= 1; pixelColor.G = (byte)g; pixelColor.G |= 1 << 1; b &= ~(1 << 7); if (isEncrypted) { b |= 1 << 7; b = this.changeFiveLSB(b); b += rotated; pixelColor.B = (byte)b; } PixelColor.SetPixelBgra8(sourcePixels, i, j, pixelColor, decoderPixelWidth, decoderPixelHeight); } else { for (int n = 0; n < 3; n++) { if (pixelElementIndex % 4 == 0) { if (charIndex >= text.Length) { notDone = false; } else { int charValue = text[charIndex++]; wholebyte = Convert.ToString(charValue, 2).PadLeft(8, '0'); } } switch (pixelElementIndex % 3) { case 0: { if (notDone) { if (Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 0) { r |= 0 << 0; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } else { r |= 1 << 0; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } if (Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 0) { r |= 0 << 1; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } else { r |= 1 << 1; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } } pixelColor.R = (byte)r; } break; case 1: { if (notDone) { if (Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 0) { g |= 0 << 0; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } else { g |= 1 << 0; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } if (Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 0) { g |= 0 << 1; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } else { g |= 1 << 1; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } } pixelColor.G = (byte)g; } break; case 2: { if (notDone) { if (Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 0) { b |= 0 << 0; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } else { b |= 1 << 0; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } if (Convert.ToInt32(wholebyte.Substring(wholebyte.Length - 1)) == 0) { b |= 0 << 1; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } else { b |= 1 << 1; wholebyte = wholebyte.Remove(wholebyte.Length - 1); } } pixelColor.B = (byte)b; PixelColor.SetPixelBgra8(sourcePixels, i, j, pixelColor, decoderPixelWidth, decoderPixelHeight); } break; } pixelElementIndex++; } } } } }
// This updates the overlay private void UpdateOverlay() { float size = 9 / renderer.Scale; SetupLabels(); if (renderer.StartOverlay(true)) { if (overlaygeometry != null) { renderer.RenderHighlight(overlaygeometry, General.Colors.ModelWireframe.WithAlpha(64).ToInt()); } if (overlaytaggedgeometry != null) { renderer.RenderHighlight(overlaytaggedgeometry, General.Colors.Vertices.WithAlpha(64).ToInt()); } if (selectedsectorgeometry != null) { renderer.RenderHighlight(selectedsectorgeometry, General.Colors.Selection.WithAlpha(64).ToInt()); } if (BuilderPlug.Me.UseHighlight && highlightedsector != null) { renderer.RenderHighlight(highlightedsector.FlatVertices, General.Colors.Highlight.WithAlpha(64).ToInt()); } List <SlopeVertex> vertices = new List <SlopeVertex>(); // Store all slope vertices and draw the lines between them foreach (SlopeVertexGroup svg in BuilderPlug.Me.SlopeVertexGroups) { for (int i = 0; i < svg.Vertices.Count; i++) { vertices.Add(svg.Vertices[i]); if (i < svg.Vertices.Count - 1) { renderer.RenderLine(svg.Vertices[0].Pos, svg.Vertices[i + 1].Pos, 1, new PixelColor(255, 255, 255, 255), true); } } } // Sort the slope vertex list and draw them. The sorting ensures that selected vertices are always drawn on top foreach (SlopeVertex sv in vertices.OrderBy(o => o.Selected)) { PixelColor c = General.Colors.Indication; Vector3D v = sv.Pos; if (sv.Selected) { c = General.Colors.Selection; } renderer.RenderRectangleFilled(new RectangleF(v.x - size / 2, v.y - size / 2, size, size), General.Colors.Background, true); renderer.RenderRectangle(new RectangleF(v.x - size / 2, v.y - size / 2, size, size), 2, c, true); } // Draw highlighted slope vertex if (highlightedslope != null) { renderer.RenderRectangleFilled(new RectangleF(highlightedslope.Pos.x - size / 2, highlightedslope.Pos.y - size / 2, size, size), General.Colors.Background, true); renderer.RenderRectangle(new RectangleF(highlightedslope.Pos.x - size / 2, highlightedslope.Pos.y - size / 2, size, size), 2, General.Colors.Highlight, true); } foreach (TextLabel l in labels) { renderer.RenderText(l); } if (selecting) { RenderMultiSelection(); } renderer.Finish(); } }
public static List <Line3D> GetAmbientSoundShapes(IEnumerable <Thing> things, bool highlight) { List <Line3D> circles = new List <Line3D>(); const int linealpha = 128; foreach (Thing t in things) { ThingTypeInfo info = General.Map.Data.GetThingInfoEx(t.Type); if (info == null) { continue; } float minradius, maxradius; if (info.AmbientSound != null) { minradius = info.AmbientSound.MinimumRadius; maxradius = info.AmbientSound.MaximumRadius; } else if (!General.Map.DOOM && (info.ClassName == "AmbientSound" || info.ClassName == "AmbientSoundNoGravity")) { //arg0: ambient slot //arg1: (optional) sound volume, in percent. 1 is nearly silent, 100 and above are full volume. If left to zero, full volume is also used. //arg2: (optional) minimum distance, in map units, at which volume attenuation begins. Note that arg3 must also be set. If both are left to zero, normal rolloff is used instead. //arg3: (optional) maximum distance, in map units, at which the sound can be heard. If left to zero or lower than arg2, normal rolloff is used instead. //arg4: (optional) scalar by which to multiply the values of arg2 and arg3. If left to zero, no multiplication takes place. if (t.Args[0] == 0 || !General.Map.Data.AmbientSounds.ContainsKey(t.Args[0])) { continue; } // Use custom radii? if (t.Args[2] > 0 && t.Args[3] > 0 && t.Args[3] > t.Args[2]) { minradius = t.Args[2] * (t.Args[4] != 0 ? t.Args[4] : 1.0f); maxradius = t.Args[3] * (t.Args[4] != 0 ? t.Args[4] : 1.0f); } else { minradius = General.Map.Data.AmbientSounds[t.Args[0]].MinimumRadius; maxradius = General.Map.Data.AmbientSounds[t.Args[0]].MaximumRadius; } } else { continue; } // Determine color PixelColor color = (highlight ? General.Colors.Highlight.WithAlpha(linealpha) : t.Color.WithAlpha(linealpha)); // Add lines if visible if (minradius > 0) { circles.AddRange(MakeCircleLines(t.Position, color, minradius, CIRCLE_SIDES)); } if (maxradius > 0) { circles.AddRange(MakeCircleLines(t.Position, color, maxradius, CIRCLE_SIDES)); } } return(circles); }
private static PixelColor[,] GetPixels(BitmapSource source) { if (source.Format != PixelFormats.Bgra32) { source = new FormatConvertedBitmap(source, PixelFormats.Bgra32, null, 0); } int width = source.PixelWidth; int height = source.PixelHeight; var result = new PixelColor[width, height]; CopyPixels(source, result, width * 4, 0); return result; }
private void setOffset(DataStream gs) { PixelColor[,] test = BitmapSourceHelper.GetPixels(new BitmapImage(new Uri(@"pack://application:,,,/MinesweeperSolver;component/Images/test.png"))); int testWidth = 5; int testHeight = 5; byte[] buffer = new byte[testWidth * 4 * testHeight]; PixelColor[,] pixels = new PixelColor[testWidth, testHeight]; for (int x = 0; x < screenWidth-5; x+=5) { for (int y = 0; y < screenHeight-5; y+=5) { for (int line = 0; line < testHeight; line++) { gs.Position = (line + y) * screenWidth * 4 + x * 4; gs.Read(buffer, testWidth * 4 * line, testWidth * 4); } for (int a = 0; a < testWidth; a++) { for (int b = 0; b < testHeight; b++) { int offset = b * testWidth * 4 + (a * 4); pixels[b, a].Red = buffer[offset + 2]; pixels[b, a].Green = buffer[offset + 1]; pixels[b, a].Blue = buffer[offset + 0]; } } if (BlockParser.CompareImages(pixels, test)) { int finalX; int finalY; byte[] pixel = new byte[4]; for (finalX = x; finalX > 0; finalX--) { gs.Position = y * screenWidth * 4 + finalX * 4; gs.Read(pixel, 0, 4); if (compareInt(pixel[0], 58, 9) && compareInt(pixel[1], 52, 9) && compareInt(pixel[2], 47, 9)) break; } for (finalY = y; finalY > 0; finalY--) { gs.Position = finalY * screenWidth * 4 + x * 4; gs.Read(pixel, 0, 4); if (compareInt(pixel[0], 58, 9) && compareInt(pixel[1], 52, 9) && compareInt(pixel[2], 47, 9)) break; } xoffset = finalX-3; yoffset = finalY-1; return; } } } }
// This updates the dragging private void Update() { PixelColor stitchcolor = General.Colors.Highlight; PixelColor losecolor = General.Colors.Selection; PixelColor color; snaptogrid = General.Interface.ShiftState ^ General.Interface.SnapToGrid; snaptonearest = General.Interface.CtrlState ^ General.Interface.AutoMerge; DrawnVertex lastp = new DrawnVertex(); DrawnVertex curp = GetCurrentPosition(); float vsize = ((float)renderer.VertexSize + 1.0f) / renderer.Scale; float vsizeborder = ((float)renderer.VertexSize + 3.0f) / renderer.Scale; SetupLabels(); // Render drawing lines if (renderer.StartOverlay(true)) { float size = 9 / renderer.Scale; if (BuilderPlug.Me.UseHighlight) { renderer.RenderHighlight(overlayGeometry, General.Colors.Selection.WithAlpha(64).ToInt()); } List <SlopeVertex> vertices = new List <SlopeVertex>(); // Store all slope vertices and draw the lines between them foreach (SlopeVertexGroup svg in BuilderPlug.Me.SlopeVertexGroups) { for (int i = 0; i < svg.Vertices.Count; i++) { vertices.Add(svg.Vertices[i]); if (i < svg.Vertices.Count - 1) { renderer.RenderLine(svg.Vertices[0].Pos, svg.Vertices[i + 1].Pos, 1, new PixelColor(255, 255, 255, 255), true); } } } // Sort the slope vertex list and draw them. The sorting ensures that selected vertices are always drawn on top foreach (SlopeVertex sv in vertices.OrderBy(o => o.Selected)) { PixelColor c = General.Colors.Indication; Vector3D v = sv.Pos; renderer.RenderRectangleFilled(new RectangleF((float)(v.x - size / 2), (float)(v.y - size / 2), size, size), General.Colors.Background, true); renderer.RenderRectangle(new RectangleF((float)(v.x - size / 2), (float)(v.y - size / 2), size, size), 2, c, true); } // Go for all points to draw lines if (points.Count > 0) { // Render lines lastp = points[0]; for (int i = 1; i < points.Count; i++) { // Determine line color if (lastp.stitchline && points[i].stitchline) { color = stitchcolor; } else { color = losecolor; } // Render line renderer.RenderLine(points[0].pos, points[i].pos, LINE_THICKNESS, color, true); lastp = points[i]; } // Determine line color if (lastp.stitchline && snaptonearest) { color = stitchcolor; } else { color = losecolor; } // Render line to cursor renderer.RenderLine(points[0].pos, curp.pos, LINE_THICKNESS, color, true); // Render vertices for (int i = 0; i < points.Count; i++) { // Determine vertex color if (points[i].stitch) { color = stitchcolor; } else { color = losecolor; } // Render vertex //renderer.RenderRectangleFilled(new RectangleF(points[i].pos.x - vsize, points[i].pos.y - vsize, vsize * 2.0f, vsize * 2.0f), color, true); renderer.RenderRectangleFilled(new RectangleF((float)(points[i].pos.x - size / 2), (float)(points[i].pos.y - size / 2), size, size), General.Colors.Background, true); renderer.RenderRectangle(new RectangleF((float)(points[i].pos.x - size / 2), (float)(points[i].pos.y - size / 2), size, size), 2, General.Colors.Indication, true); } } foreach (TextLabel l in labels) { renderer.RenderText(l); } // Determine point color if (snaptonearest) { color = stitchcolor; } else { color = losecolor; } // Render vertex at cursor //renderer.RenderRectangleFilled(new RectangleF(curp.pos.x - vsize, curp.pos.y - vsize, vsize * 2.0f, vsize * 2.0f), color, true); renderer.RenderRectangleFilled(new RectangleF((float)(curp.pos.x - size / 2), (float)(curp.pos.y - size / 2), size, size), General.Colors.Background, true); renderer.RenderRectangle(new RectangleF((float)(curp.pos.x - size / 2), (float)(curp.pos.y - size / 2), size, size), 2, General.Colors.Indication, true); // Done renderer.Finish(); } // Done renderer.Present(); }
public void LogPixel(string msg, MessageGroup group, int x, int y, PixelColor color) { string text = $"{msg.PadRight(22)} {color.ToString().PadRight(13)} at ({x.ToString().PadLeft(6)};{y.ToString().PadLeft(6)})"; LogLine(text, group); }
public bool Setup(Effect3DFloor extrafloor) { Sidedef sourceside = extrafloor.Linedef.Front; this.extrafloor = extrafloor; //mxd. Extrafloor may've become invalid during undo/redo... if (sourceside == null) { base.SetVertices(null); return(false); } Vector2D vl, vr; //mxd. lightfog flag support int lightvalue; bool lightabsolute; GetLightValue(out lightvalue, out lightabsolute); Vector2D tscale = new Vector2D(sourceside.Fields.GetValue("scalex_mid", 1.0), sourceside.Fields.GetValue("scaley_mid", 1.0)); Vector2D tscaleAbs = new Vector2D(Math.Abs(tscale.x), Math.Abs(tscale.y)); Vector2D toffset1 = new Vector2D(Sidedef.Fields.GetValue("offsetx_mid", 0.0), Sidedef.Fields.GetValue("offsety_mid", 0.0)); Vector2D toffset2 = new Vector2D(sourceside.Fields.GetValue("offsetx_mid", 0.0), sourceside.Fields.GetValue("offsety_mid", 0.0)); // Left and right vertices for this sidedef if (Sidedef.IsFront) { vl = new Vector2D(Sidedef.Line.Start.Position.x, Sidedef.Line.Start.Position.y); vr = new Vector2D(Sidedef.Line.End.Position.x, Sidedef.Line.End.Position.y); } else { vl = new Vector2D(Sidedef.Line.End.Position.x, Sidedef.Line.End.Position.y); vr = new Vector2D(Sidedef.Line.Start.Position.x, Sidedef.Line.Start.Position.y); } // Load sector data SectorData sd = mode.GetSectorData(Sidedef.Sector); //mxd. which texture we must use? long texturelong = 0; if ((sourceside.Line.Args[2] & (int)Effect3DFloor.Flags.UseUpperTexture) != 0) { if (Sidedef.LongHighTexture != MapSet.EmptyLongName) { texturelong = Sidedef.LongHighTexture; } } else if ((sourceside.Line.Args[2] & (int)Effect3DFloor.Flags.UseLowerTexture) != 0) { if (Sidedef.LongLowTexture != MapSet.EmptyLongName) { texturelong = Sidedef.LongLowTexture; } } else if (sourceside.LongMiddleTexture != MapSet.EmptyLongName) { texturelong = sourceside.LongMiddleTexture; } // Texture given? if (texturelong != 0) { // Load texture base.Texture = General.Map.Data.GetTextureImage(texturelong); if (base.Texture == null || base.Texture is UnknownImage) { base.Texture = General.Map.Data.UnknownTexture3D; setuponloadedtexture = texturelong; } else if (!base.Texture.IsImageLoaded) { setuponloadedtexture = texturelong; } } else { // Use missing texture base.Texture = General.Map.Data.MissingTexture3D; setuponloadedtexture = 0; } // Get texture scaled size. Round up, because that's apparently what GZDoom does Vector2D tsz = new Vector2D(Math.Ceiling(base.Texture.ScaledWidth / tscale.x), Math.Ceiling(base.Texture.ScaledHeight / tscale.y)); // Get texture offsets Vector2D tof = new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY) + new Vector2D(sourceside.OffsetX, sourceside.OffsetY); tof = tof + toffset1 + toffset2; // biwa. Also take the ForceWorldPanning MAPINFO entry into account if (General.Map.Config.ScaledTextureOffsets && (!base.Texture.WorldPanning && !General.Map.Data.MapInfo.ForceWorldPanning)) { tof = tof / tscaleAbs; tof = tof * base.Texture.Scale; // If the texture gets replaced with a "hires" texture it adds more fuckery if (base.Texture is HiResImage) { tof *= tscaleAbs; } // Round up, since that's apparently what GZDoom does. Not sure if this is the right place or if it also has to be done earlier tof = new Vector2D(Math.Ceiling(tof.x), Math.Ceiling(tof.y)); } // For Vavoom type 3D floors the ceiling is lower than floor and they are reversed. // We choose here. double sourcetopheight = extrafloor.VavoomType ? sourceside.Sector.FloorHeight : sourceside.Sector.CeilHeight; double sourcebottomheight = extrafloor.VavoomType ? sourceside.Sector.CeilHeight : sourceside.Sector.FloorHeight; // Determine texture coordinates plane as they would be in normal circumstances. // We can then use this plane to find any texture coordinate we need. // The logic here is the same as in the original VisualMiddleSingle (except that // the values are stored in a TexturePlane) // NOTE: I use a small bias for the floor height, because if the difference in // height is 0 then the TexturePlane doesn't work! TexturePlane tp = new TexturePlane(); double floorbias = (sourcetopheight == sourcebottomheight) ? 1.0f : 0.0f; tp.trb.x = tp.tlt.x + Math.Round(Sidedef.Line.Length); //mxd. (G)ZDoom snaps texture coordinates to integral linedef length tp.trb.y = tp.tlt.y + (sourcetopheight - sourcebottomheight) + floorbias; // Apply texture offset tp.tlt += tof; tp.trb += tof; // Transform pixel coordinates to texture coordinates tp.tlt /= tsz; tp.trb /= tsz; // Left top and right bottom of the geometry that tp.vlt = new Vector3D(vl.x, vl.y, sourcetopheight); tp.vrb = new Vector3D(vr.x, vr.y, sourcebottomheight + floorbias); // Make the right-top coordinates tp.trt = new Vector2D(tp.trb.x, tp.tlt.y); tp.vrt = new Vector3D(tp.vrb.x, tp.vrb.y, tp.vlt.z); //mxd. Get ceiling and floor heights. Use our and neighbour sector's data SectorData sdo = mode.GetSectorData(Sidedef.Other.Sector); double flo = sdo.Floor.plane.GetZ(vl); double fro = sdo.Floor.plane.GetZ(vr); double clo = sdo.Ceiling.plane.GetZ(vl); double cro = sdo.Ceiling.plane.GetZ(vr); double fle = sd.Floor.plane.GetZ(vl); double fre = sd.Floor.plane.GetZ(vr); double cle = sd.Ceiling.plane.GetZ(vl); double cre = sd.Ceiling.plane.GetZ(vr); double fl = flo > fle ? flo : fle; double fr = fro > fre ? fro : fre; double cl = clo < cle ? clo : cle; double cr = cro < cre ? cro : cre; // Anything to see? if (((cl - fl) > 0.01f) || ((cr - fr) > 0.01f)) { // Keep top and bottom planes for intersection testing top = extrafloor.Floor.plane; bottom = extrafloor.Ceiling.plane; // Create initial polygon, which is just a quad between floor and ceiling WallPolygon poly = new WallPolygon(); poly.Add(new Vector3D(vl.x, vl.y, fl)); poly.Add(new Vector3D(vl.x, vl.y, cl)); poly.Add(new Vector3D(vr.x, vr.y, cr)); poly.Add(new Vector3D(vr.x, vr.y, fr)); // Determine initial color int lightlevel = lightabsolute ? lightvalue : sd.Ceiling.brightnessbelow + lightvalue; //mxd. This calculates light with doom-style wall shading PixelColor wallbrightness = PixelColor.FromInt(mode.CalculateBrightness(lightlevel, Sidedef)); PixelColor wallcolor = PixelColor.Modulate(sd.Ceiling.colorbelow, wallbrightness); fogfactor = CalculateFogFactor(lightlevel); poly.color = wallcolor.WithAlpha(255).ToInt(); // Cut off the part above the 3D floor and below the 3D ceiling CropPoly(ref poly, extrafloor.Floor.plane, false); CropPoly(ref poly, extrafloor.Ceiling.plane, false); // Cut out pieces that overlap 3D floors in this sector List <WallPolygon> polygons = new List <WallPolygon> { poly }; bool translucent = (extrafloor.RenderAdditive || extrafloor.Alpha < 255); foreach (Effect3DFloor ef in sd.ExtraFloors) { //mxd. Our poly should be clipped when our ond other extrafloors are both solid or both translucent, // or when only our extrafloor is translucent. // Our poly should not be clipped when our extrafloor is translucent and the other one isn't and both have renderinside setting. bool othertranslucent = (ef.RenderAdditive || ef.Alpha < 255); if (translucent && !othertranslucent && !ef.ClipSidedefs) { continue; } if (ef.ClipSidedefs == extrafloor.ClipSidedefs || ef.ClipSidedefs) { //TODO: find out why ef can be not updated at this point //TODO: [this crashed on me once when performing auto-align on myriad of textures on BoA C1M0] if (ef.Floor == null || ef.Ceiling == null) { ef.Update(); } int num = polygons.Count; for (int pi = 0; pi < num; pi++) { // Split by floor plane of 3D floor WallPolygon p = polygons[pi]; WallPolygon np = SplitPoly(ref p, ef.Ceiling.plane, true); if (np.Count > 0) { // Split part below floor by the ceiling plane of 3D floor // and keep only the part below the ceiling (front) SplitPoly(ref np, ef.Floor.plane, true); if (p.Count == 0) { polygons[pi] = np; } else { polygons[pi] = p; polygons.Add(np); } } else { polygons[pi] = p; } } } } // Process the polygon and create vertices if (polygons.Count > 0) { List <WorldVertex> verts = CreatePolygonVertices(polygons, tp, sd, lightvalue, lightabsolute); if (verts.Count > 2) { if (extrafloor.Sloped3dFloor) { this.RenderPass = RenderPass.Mask; //mxd } else if (extrafloor.RenderAdditive) { this.RenderPass = RenderPass.Additive; //mxd } else if ((extrafloor.Alpha < 255) || Texture.IsTranslucent) { this.RenderPass = RenderPass.Alpha; // [ZZ] translucent texture should trigger Alpha pass } else { this.RenderPass = RenderPass.Mask; } if (extrafloor.Alpha < 255) { // Apply alpha to vertices byte alpha = (byte)General.Clamp(extrafloor.Alpha, 0, 255); if (alpha < 255) { for (int i = 0; i < verts.Count; i++) { WorldVertex v = verts[i]; v.c = PixelColor.FromInt(v.c).WithAlpha(alpha).ToInt(); verts[i] = v; } } } base.SetVertices(verts); return(true); } } } base.SetVertices(null); //mxd return(false); }
/// <summary> /// Sets the color of the cage around the thing geometry. /// </summary> public void SetCageColor(PixelColor color) { cagecolor = color.ToInt(); }
public bool ParseScreen(Board board, out List<Block> nonZeroValues) { Surface surface = dx.CaptureScreen(); DataRectangle dr = surface.LockRectangle(LockFlags.None); DataStream gs = dr.Data; nonZeroValues = new List<Block>(); bool initialBoard = true; if (xoffset == 0 || yoffset == 0) setOffset(gs); byte[] buffer = new byte[blockWidth * 4 * blockHeight]; PixelColor[,] pixels = new PixelColor[blockWidth, blockHeight]; for (int i = 0; i < board.Width; i++) { for (int j = 0; j < board.Height; j++) { for (int k = 0; k < blockHeight; k++) { gs.Position = (k + GetYCoord(j)) * screenWidth * 4 + GetXCoord(i) * 4; gs.Read(buffer, blockWidth * 4 * k, blockWidth * 4); } for (int a = 0; a < blockWidth; a++) { for (int b = 0; b < blockHeight; b++) { int offset = b * blockWidth * 4 + (a * 4); pixels[b, a].Red = buffer[offset + 2]; pixels[b, a].Green = buffer[offset + 1]; pixels[b, a].Blue = buffer[offset + 0]; } } board.Grid[i, j] = blockParser.Parse(i, j, pixels); if (board.Grid[i, j].State == BlockState.ParseFailed) { throw new ParserException("Point [" + i + ", " + j + "] failed! Pixel [" + GetXCoord(i) + "," + GetYCoord(j) + "]"); } if (board.Grid[i, j].Value > 0) nonZeroValues.Add(board.Grid[i, j]); if (board.Grid[i, j].State != BlockState.Unknown) initialBoard = false; } } gs.Close(); surface.UnlockRectangle(); surface.Dispose(); return initialBoard; }
void DrawText(ByteBuffer input, int x, int y, String str, bool center, PixelColor fore, PixelColor back) { if (str == null || str.Length == 0) { return; } char[] charray = str.ToCharArray(); foreach (char ch in charray) { x += DrawChar(input, ch, x, y, fore, back); } }
// This builds the thing geometry. Returns false when nothing was created. public bool Setup() { // Find the sector in which the thing resides Thing.DetermineSector(mode.BlockMap); //mxd. If the thing is inside a sector, apply DECORATE/UDMF alpha/renderstyle overrides byte alpha = 255; if (Thing.Sector != null) { string renderstyle = info.RenderStyle.ToLowerInvariant(); alpha = info.AlphaByte; if (General.Map.UDMF) { if (Thing.IsFlagSet("translucent")) { renderstyle = "translucent"; alpha = 64; } else if (Thing.IsFlagSet("invisible")) { renderstyle = "none"; alpha = 0; } else if (Thing.Fields.ContainsKey("renderstyle")) { renderstyle = Thing.Fields.GetValue("renderstyle", renderstyle).ToLowerInvariant(); } if ((renderstyle == "add" || renderstyle == "translucent" || renderstyle == "subtract" || renderstyle == "translucentstencil") && Thing.Fields.ContainsKey("alpha")) { alpha = (byte)(General.Clamp(Thing.Fields.GetValue("alpha", info.Alpha), 0.0, 1.0) * 255.0); } else if (renderstyle == "soultrans") { // Lost Soul trasparency is controlled by a CVAR (see https://zdoom.org/wiki/CVARs:Display#transsouls), let's use the default 0.75 here alpha = 192; } else if (renderstyle == "shadow") { alpha = 76; // about 0.3 stencilColor = PixelColor.FromInt(PixelColor.INT_BLACK); } if (renderstyle.EndsWith("stencil")) { stencilColor = PixelColor.FromInt(UniFields.GetInteger(Thing.Fields, "fillcolor", 0)); stencilColor.a = 255; // 0xFF alpha means nothing was read. 0x00 alpha means there was a valid fillcolor. } else if (renderstyle != "shadow") { stencilColor.a = 0; } } else if (General.Map.HEXEN) { if (Thing.IsFlagSet("2048")) { renderstyle = "translucent"; alpha = 64; } else if (Thing.IsFlagSet("4096")) { renderstyle = "none"; alpha = 0; } } // Set appropriate RenderPass switch (renderstyle) { case "translucent": case "subtract": case "soultrans": case "translucentstencil": case "shadow": RenderPass = RenderPass.Alpha; break; case "add": case "addstencil": RenderPass = RenderPass.Additive; break; case "none": RenderPass = RenderPass.Mask; alpha = 0; break; // Many render styles are not supported yet... default: RenderPass = RenderPass.Mask; alpha = 255; break; } } int sectorcolor = new PixelColor(alpha, 255, 255, 255).ToInt(); fogfactor = 0f; //mxd //mxd. Check thing size float thingradius = Thing.Size; // Thing.Size has ThingRadius arg override applied thingheight = Thing.Height; // Thing.Height has ThingHeight arg override applied if (thingradius < 0.1f || thingheight < 0.1f) { thingradius = FIXED_RADIUS; thingheight = FIXED_RADIUS; sizeless = true; } else { sizeless = false; } if (Thing.Sector != null) { SectorData sd = mode.GetSectorData(Thing.Sector); Plane floor = sd.Floor.plane; //mxd if (!info.Bright) { Vector3D thingpos = new Vector3D(Thing.Position.x, Thing.Position.y, Thing.Position.z + sd.Floor.plane.GetZ(Thing.Position)); SectorLevel level = sd.GetLevelAboveOrAt(thingpos); //mxd. Let's use point on floor plane instead of Thing.Sector.FloorHeight; if (nointeraction && level == null && sd.LightLevels.Count > 0) { level = sd.LightLevels[sd.LightLevels.Count - 1]; } //mxd. Use the light level of the highest surface when a thing is above highest sector level. if (level != null) { // TECH: In GZDoom, ceiling glow doesn't affect thing brightness // Use sector brightness for color shading int brightness = level.brightnessbelow; //mxd. Apply lightfloor value // According to Graf, this is incorrect behaviour... // TECH: In (G)ZDoom, this is ignored when ceiling texture is sky or a thing is below a 3D floor // It's probably more involved than this, but for now let's do it only when there are no 3d floors in Thing.Sector... /*if(General.Map.UDMF && sd.LightLevels.Count == 2 && Thing.Sector.CeilTexture != General.Map.Config.SkyFlatName) * { * if(sd.Sector.Fields.GetValue("lightfloorabsolute", false)) * brightness = UniFields.GetInteger(sd.Sector.Fields, "lightfloor"); * else * brightness += UniFields.GetInteger(sd.Sector.Fields, "lightfloor"); * }*/ // Level is glowing if (level.affectedbyglow && level.type == SectorLevelType.Floor) { // Extrafloor glow doesn't affect thing brightness if (level.sector == Thing.Sector) { double planez = level.plane.GetZ(thingpos); // Get glow brightness int glowbrightness = sd.FloorGlow.Brightness / 2; SectorLevel nexthigher = sd.GetLevelAbove(new Vector3D(thingpos, planez)); // Interpolate thing brightness between glow and regular ones if (nexthigher != null) { double higherz = nexthigher.plane.GetZ(thingpos); double delta = General.Clamp(1.0f - (thingpos.z - planez) / (higherz - planez), 0f, 1f); brightness = (int)((glowbrightness + level.sector.Brightness / 2) * delta + nexthigher.sector.Brightness * (1.0f - delta)); } } } // Level below this one is glowing. Only possible for floor glow(?) else if (level.type == SectorLevelType.Glow) { // Interpolate thing brightness between glow and regular ones if (sd.Floor != null && sd.FloorGlow != null) { // Get glow brightness double glowz = level.plane.GetZ(thingpos); double floorz = floor.GetZ(thingpos); double delta = General.Clamp((thingpos.z - floorz) / (glowz - floorz), 0f, 1f); brightness = (int)((sd.FloorGlow.Brightness / 2 + sd.Floor.sector.Brightness / 2) * (1.0f - delta) + sd.Floor.sector.Brightness * delta); } } PixelColor areabrightness = PixelColor.FromInt(mode.CalculateBrightness(brightness)); PixelColor areacolor = PixelColor.Modulate(level.colorbelow, areabrightness); // [ZZ] if sector is using Doom64 lighting, apply thing color here. sectorcolor = PixelColor.Modulate(sd.ColorSprites, areacolor).WithAlpha(alpha).ToInt(); //mxd. Calculate fogfactor fogfactor = VisualGeometry.CalculateFogFactor(level.sector, brightness); } } //TECH: even Bright Thing frames are affected by custom fade... else { Vector3D thingpos = new Vector3D(Thing.Position.x, Thing.Position.y, Thing.Position.z + sd.Floor.plane.GetZ(Thing.Position)); SectorLevel level = sd.GetLevelAboveOrAt(thingpos); if (level != null && level.sector.FogMode > SectorFogMode.CLASSIC) { //mxd. Calculate fogfactor fogfactor = VisualGeometry.CalculateFogFactor(level.sector, level.brightnessbelow); } } } //mxd. Create verts for all sprite angles WorldVertex[][] allverts = new WorldVertex[info.SpriteFrame.Length][]; Vector2D[] alloffsets = new Vector2D[info.SpriteFrame.Length]; base.textures = new ImageData[info.SpriteFrame.Length]; isloaded = true; for (int i = 0; i < sprites.Length; i++) { Vector2D offsets = new Vector2D(); // Check if the texture is loaded ImageData sprite = sprites[i]; if (!sprite.IsImageLoaded && !sprite.LoadFailed) { sprite.LoadImageNow(); } if (sprite.IsImageLoaded) { base.textures[i] = sprite; // Determine sprite size and offset float radius = sprite.ScaledWidth * 0.5f; float height = sprite.ScaledHeight; ISpriteImage spriteimg = sprite as ISpriteImage; if (spriteimg != null) { offsets.x = radius - spriteimg.OffsetX; offsets.y = spriteimg.OffsetY - height; } // Scale by thing type/actor scale // We do this after the offset x/y determination above, because that is entirely in sprite pixels space radius *= info.SpriteScale.Width; height *= info.SpriteScale.Height; offsets.x *= info.SpriteScale.Width; offsets.y *= info.SpriteScale.Height; // Make vertices WorldVertex[] verts = new WorldVertex[6]; //mxd. Sprite mirroring float ul = (info.SpriteFrame[i].Mirror ? 1f : 0f); float ur = (info.SpriteFrame[i].Mirror ? 0f : 1f); if (sizeless) //mxd { float hh = height / 2; verts[0] = new WorldVertex((float)(-radius + offsets.x), 0.0f, (float)(offsets.y - hh), sectorcolor, ul, 1.0f); verts[1] = new WorldVertex((float)(-radius + offsets.x), 0.0f, (float)(hh + offsets.y), sectorcolor, ul, 0.0f); verts[2] = new WorldVertex((float)(+radius + offsets.x), 0.0f, (float)(hh + offsets.y), sectorcolor, ur, 0.0f); verts[3] = verts[0]; verts[4] = verts[2]; verts[5] = new WorldVertex((float)(+radius + offsets.x), 0.0f, (float)(offsets.y - hh), sectorcolor, ur, 1.0f); } else { verts[0] = new WorldVertex((float)(-radius + offsets.x), 0.0f, (float)offsets.y, sectorcolor, ul, 1.0f); verts[1] = new WorldVertex((float)(-radius + offsets.x), 0.0f, (float)(height + offsets.y), sectorcolor, ul, 0.0f); verts[2] = new WorldVertex((float)(+radius + offsets.x), 0.0f, (float)(height + offsets.y), sectorcolor, ur, 0.0f); verts[3] = verts[0]; verts[4] = verts[2]; verts[5] = new WorldVertex((float)(+radius + offsets.x), 0.0f, (float)offsets.y, sectorcolor, ur, 1.0f); } allverts[i] = verts; } else { isloaded = false; base.textures[i] = sprite; // Determine sprite size float radius = Math.Min(thingradius, thingheight / 2f); float height = Math.Min(thingradius * 2f, thingheight); //mxd. Determine sprite offsets offsets.x = radius; offsets.y = height / 2; // Make vertices WorldVertex[] verts = new WorldVertex[6]; verts[0] = new WorldVertex(-radius, 0.0f, 0.0f, sectorcolor, 0.0f, 1.0f); verts[1] = new WorldVertex(-radius, 0.0f, height, sectorcolor, 0.0f, 0.0f); verts[2] = new WorldVertex(+radius, 0.0f, height, sectorcolor, 1.0f, 0.0f); verts[3] = verts[0]; verts[4] = verts[2]; verts[5] = new WorldVertex(+radius, 0.0f, 0.0f, sectorcolor, 1.0f, 1.0f); allverts[i] = verts; } //mxd. Store offsets alloffsets[i] = offsets; } //mxd SetVertices(allverts, alloffsets /*, floor, ceiling*/); // Determine position Vector3D pos = Thing.Position; if (Thing.Type == 9501) { if (Thing.Sector != null) //mxd { // This is a special thing that needs special positioning SectorData sd = mode.GetSectorData(Thing.Sector); pos.z = sd.Ceiling.sector.CeilHeight + Thing.Position.z; } } else if (Thing.Type == 9500) { if (Thing.Sector != null) //mxd { // This is a special thing that needs special positioning SectorData sd = mode.GetSectorData(Thing.Sector); pos.z = sd.Floor.sector.FloorHeight + Thing.Position.z; } } else if (info.AbsoluteZ) { // Absolute Z position pos.z = Thing.Position.z; } else if (info.Hangs) { // Hang from ceiling if (Thing.Sector != null) { SectorData sd = mode.GetSectorData(Thing.Sector); double maxz = sd.Ceiling.plane.GetZ(Thing.Position) - info.Height; pos.z = maxz; if (Thing.Position.z > 0 || nointeraction) { pos.z -= Thing.Position.z; } // Check if below floor if (!nointeraction) { double minz = sd.Floor.plane.GetZ(Thing.Position); if (pos.z < minz) { pos.z = Math.Min(minz, maxz); } } } } else { // Stand on floor if (Thing.Sector != null) { SectorData sd = mode.GetSectorData(Thing.Sector); double minz = sd.Floor.plane.GetZ(Thing.Position); pos.z = minz; if (Thing.Position.z > 0 || nointeraction) { pos.z += Thing.Position.z; } // Check if above ceiling if (!nointeraction) { double maxz = sd.Ceiling.plane.GetZ(Thing.Position) - info.Height; if (pos.z > maxz) { pos.z = Math.Max(minz, maxz); } } } } // Apply settings SetPosition(pos); SetCageColor(Thing.Color); // Keep info for object picking cageradius2 = thingradius * Angle2D.SQRT2; cageradius2 = cageradius2 * cageradius2; pos2d = pos; if (sizeless) //mxd { boxp1 = new Vector3D(pos.x - thingradius, pos.y - thingradius, pos.z - thingradius / 2); boxp2 = new Vector3D(pos.x + thingradius, pos.y + thingradius, pos.z + thingradius / 2); } else { boxp1 = new Vector3D(pos.x - thingradius, pos.y - thingradius, pos.z); boxp2 = new Vector3D(pos.x + thingradius, pos.y + thingradius, pos.z + thingheight); } // Done changed = false; return(true); }
public Pixel(int num, PixelColor color) { this.color = color; this.num = num; }
// font public Font GetFont(String File, PixelColor ForeColor) { return(GetFont(File, ForeColor, PixelColor.Black)); }
public Font GetFont(String File, PixelColor ForeColor, PixelColor BackColor) { ResourceInfoFont info; info.Name = File; if (BackColor != PixelColor.Black) { info.Fore = ForeColor; info.Back = BackColor; } else { info.Fore = PixelColor.White; info.Back = PixelColor.Black; } Font font = new Font(engine); font.Info = new FontInfo(); font.Info.Font = File.ToLower(); font.Info.ForeColor = ForeColor; font.Info.BackColor = BackColor; font.Info.UseBackColor = !(BackColor.a == 255 && BackColor.r == 0 && BackColor.g == 0 && BackColor.b == 0); if (fonts.ContainsKey(info)) { font.charInfo = fonts[info].charInfo; font.sprite = fonts[info].sprite; font.offset = fonts[info].offset; font.height = fonts[info].height; return(font); } FilePath path = File; if (!fontProcessors.ContainsKey(path.Extension)) { return(null); } engine.IncreaseLoadingCount(); IFontProcessor processor = (IFontProcessor)Activator.CreateInstance(fontProcessors[path.Extension].GetType()); processor.Process((string)path); Log.Debug("load \"" + path.FullPath + "\""); SlimDX.Direct3D9.Texture tex = engine.Device.CreateTexture(MakePowerOfTwo(processor.Size.x), MakePowerOfTwo(processor.Size.y)); SlimDX.Direct3D9.SurfaceDescription desc = tex.GetLevelDescription(0); MemoryUsage += desc.Width * desc.Height * 4; SlimDX.DataRectangle data = tex.LockRectangle(0, SlimDX.Direct3D9.LockFlags.Discard); System.IO.MemoryStream systemCopy = new System.IO.MemoryStream(); processor.Render(systemCopy, data.Pitch, ForeColor, BackColor); processor.Render(data.Data, data.Pitch, ForeColor, BackColor); tex.UnlockRectangle(0); //// debug output //System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(processor.Size.x, processor.Size.y, System.Drawing.Imaging.PixelFormat.Format32bppArgb); //System.Drawing.Imaging.BitmapData bmpdata = bmp.LockBits(new System.Drawing.Rectangle(0, 0, processor.Size.x, processor.Size.y), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); //byte[] bytes = new byte[processor.Size.y * bmpdata.Stride]; //systemCopy.Seek(0, System.IO.SeekOrigin.Begin); //for (int y = 0; y < processor.Size.y; y++) //{ // systemCopy.Read(bytes, y * bmpdata.Stride, processor.Size.x * 4); //} //System.Runtime.InteropServices.Marshal.Copy(bytes, 0, bmpdata.Scan0, bytes.Length); //bmp.UnlockBits(bmpdata); //bmp.Save("c:\\font.png"); //bmp.Dispose(); SpriteFrame frame = new SpriteFrame(this, tex, processor.Size, systemCopy.ToArray()); font.sprite = new Sprite(this, "", frame); font.sprite.Resolution = processor.Factor; font.charInfo = processor.CharInfo; font.offset = processor.Offset; font.height = processor.Size.y; engine.DecreaseLoadingCount(); fonts.Add(info, font); return(font); }
public static List <Line3D> GetSpotLightShape(Thing t, bool highlight, GZGeneral.LightData ld, int linealpha) { PixelColor color; if (t.Fields.ContainsKey("arg0str")) { ZDoom.ZDTextParser.GetColorFromString(t.Fields["arg0str"].Value.ToString(), out color); color.a = (byte)linealpha; } else { color = new PixelColor((byte)linealpha, (byte)((t.Args[0] & 0xFF0000) >> 16), (byte)((t.Args[0] & 0x00FF00) >> 8), (byte)((t.Args[0] & 0x0000FF))); } if (highlight) { color = General.Colors.Highlight.WithAlpha((byte)linealpha); } PixelColor color_secondary = color; color_secondary.a /= 2; List <Line3D> shapes = new List <Line3D>(); float _lAngle1 = Angle2D.DegToRad(t.Args[1]); float _lAngle2 = Angle2D.DegToRad(t.Args[2]); float lAngle1 = _lAngle1; float lAngle2 = _lAngle2; float lRadius = t.Args[3] * 2; float lDirY1 = (float)Math.Sin(-lAngle1) * lRadius; float lDirX1 = (float)Math.Cos(-lAngle1) * lRadius; float lDirY2 = (float)Math.Sin(-lAngle2) * lRadius; float lDirX2 = (float)Math.Cos(-lAngle2) * lRadius; IEnumerable <Line3D> circleLines = MakeCircleLines(new Vector3D(0, 0, 0), color, (float)Math.Abs(lDirY1), CIRCLE_SIDES); foreach (Line3D l3d in circleLines) { shapes.Add(new Line3D(new Vector3D(lDirX1, l3d.Start.x, l3d.Start.y), new Vector3D(lDirX1, l3d.End.x, l3d.End.y), color, false)); } if (lAngle2 != lAngle1) { circleLines = MakeCircleLines(new Vector3D(0, 0, 0), color_secondary, (float)Math.Abs(lDirY2), CIRCLE_SIDES); foreach (Line3D l3d in circleLines) { shapes.Add(new Line3D(new Vector3D(lDirX2, l3d.Start.x, l3d.Start.y), new Vector3D(lDirX2, l3d.End.x, l3d.End.y), color_secondary, false)); } } // draw another circle to show the front cone shape int numsides = CIRCLE_SIDES * 2; float anglestep = Angle2D.PI2 / numsides; for (int j = -1; j <= 1; j++) { if (j == 0) { continue; } List <Line3D> tmplines = new List <Line3D>(); PixelColor ccol = color; for (int i = 1; i < numsides + 1; i++) { float angc = j * i * anglestep; float angp = j * (i - 1) * anglestep; if (i * anglestep > lAngle1 && ccol.a == color.a) { shapes.Add(new Line3D(new Vector3D((float)Math.Cos(angp) * lRadius, (float)Math.Sin(angp) * lRadius, 0), new Vector3D((float)Math.Cos(j * lAngle1) * lRadius, (float)Math.Sin(j * lAngle1) * lRadius, 0), ccol, false)); bool dobreak = false; if (i * anglestep > lAngle2) { angc = j * lAngle2; dobreak = true; } shapes.Add(new Line3D(new Vector3D((float)Math.Cos(j * lAngle1) * lRadius, (float)Math.Sin(j * lAngle1) * lRadius, 0), new Vector3D((float)Math.Cos(angc) * lRadius, (float)Math.Sin(angc) * lRadius, 0), color_secondary, false)); ccol = color_secondary; if (dobreak) { break; } } else if (i * anglestep > lAngle2) { angc = j * lAngle2; shapes.Add(new Line3D(new Vector3D((float)Math.Cos(angp) * lRadius, (float)Math.Sin(angp) * lRadius, 0), new Vector3D((float)Math.Cos(angc) * lRadius, (float)Math.Sin(angc) * lRadius, 0), ccol, false)); break; } else { shapes.Add(new Line3D(new Vector3D((float)Math.Cos(angp) * lRadius, (float)Math.Sin(angp) * lRadius, 0), new Vector3D((float)Math.Cos(angc) * lRadius, (float)Math.Sin(angc) * lRadius, 0), ccol, false)); } } } shapes.Add(new Line3D(new Vector3D(0, 0, 0), new Vector3D(lDirX1, lDirY1, 0), color, false)); shapes.Add(new Line3D(new Vector3D(0, 0, 0), new Vector3D(lDirX1, -lDirY1, 0), color, false)); if (lAngle2 != lAngle1) { shapes.Add(new Line3D(new Vector3D(0, 0, 0), new Vector3D(lDirX2, lDirY2, 0), color_secondary, false)); shapes.Add(new Line3D(new Vector3D(0, 0, 0), new Vector3D(lDirX2, -lDirY2, 0), color_secondary, false)); } // do translation and rotation foreach (Line3D l3d in shapes) { // rotate l3d.Start = GetRotatedVertex(l3d.Start, t.Angle - 1.5708f, Angle2D.DegToRad(t.Pitch)); l3d.End = GetRotatedVertex(l3d.End, t.Angle - 1.5708f, Angle2D.DegToRad(t.Pitch)); // translate l3d.Start += t.Position; l3d.End += t.Position; } return(shapes); }
// This updates the dragging private void Update() { PixelColor stitchcolor = General.Colors.Highlight; PixelColor losecolor = General.Colors.Selection; PixelColor color; snaptogrid = General.Interface.ShiftState ^ General.Interface.SnapToGrid; snaptonearest = General.Interface.CtrlState ^ General.Interface.AutoMerge; bPenMode = General.Interface.AltState; DrawnVertex lastp = new DrawnVertex(); DrawnVertex curp = GetCurrentPosition(); float vsize = ((float)renderer.VertexSize + 1.0f) / renderer.Scale; float vsizeborder = ((float)renderer.VertexSize + 3.0f) / renderer.Scale; // The last label's end must go to the mouse cursor if (labels.Count > 0) { labels[labels.Count - 1].End = curp.pos; } // Render drawing lines if (renderer.StartOverlay(true)) { // Go for all points to draw lines if (points.Count > 0) { // Render lines lastp = points[0]; for (int i = 1; i < points.Count; i++) { // Determine line color if (lastp.stitchline && points[i].stitchline) { color = stitchcolor; } else { color = losecolor; } // Render line renderer.RenderLine(lastp.pos, points[i].pos, LINE_THICKNESS, color, true); lastp = points[i]; } // Determine line color if (lastp.stitchline && snaptonearest) { color = stitchcolor; } else { color = losecolor; } // Render line to cursor renderer.RenderLine(lastp.pos, curp.pos, LINE_THICKNESS, color, true); // Render vertices for (int i = 0; i < points.Count; i++) { // Determine vertex color if (points[i].stitch) { color = stitchcolor; } else { color = losecolor; } // Render vertex renderer.RenderRectangleFilled(new RectangleF(points[i].pos.x - vsize, points[i].pos.y - vsize, vsize * 2.0f, vsize * 2.0f), color, true); } } // Determine point color if (snaptonearest) { color = stitchcolor; } else { color = losecolor; } // Render vertex at cursor renderer.RenderRectangleFilled(new RectangleF(curp.pos.x - vsize, curp.pos.y - vsize, vsize * 2.0f, vsize * 2.0f), color, true); // Go for all labels foreach (LineLengthLabel l in labels) { renderer.RenderText(l.TextLabel); } // Done renderer.Finish(); } // Done renderer.Present(); if (bPenMode && !(lastp.pos.x == curp.pos.x && lastp.pos.y == curp.pos.y)) { if (!(curp.pos.x == prevcurp.pos.x && curp.pos.y == prevcurp.pos.y) && !(lastp.pos.x == prevcurp.pos.x && lastp.pos.y == prevcurp.pos.y)) { float curangle = Vector2D.GetAngle(prevcurp.pos, curp.pos); float oldangle = Vector2D.GetAngle(lastp.pos, prevcurp.pos); //float oldangle = Vector2D.GetAngle(points[points.Count - 2].pos, lastp.pos); if (Math.Abs(curangle - oldangle) > 0.001f) { /* * General.Interface.DisplayStatus(StatusType.Info, * "(" + lastp.pos.x + "," + lastp.pos.y + "); " + * "(" + prevcurp.pos.x + "," + prevcurp.pos.y + "); " + * "(" + curp.pos.x + "," + curp.pos.y + "); " * ); */ if (!DrawPointAt(prevcurp)) { General.Interface.DisplayStatus(StatusType.Warning, "Failed to draw point: outside of map boundaries."); } //DrawPoint(); } } else if (points.Count >= 2 && points[0].pos.x == curp.pos.x && points[0].pos.y == curp.pos.y) { DrawPoint(); } } prevcurp = curp; }
private void SetupLabels() { Dictionary <Sector, List <TextLabel> > sectorlabels = new Dictionary <Sector, List <TextLabel> >(); PixelColor white = new PixelColor(255, 255, 255, 255); Dictionary <Sector, Dictionary <PlaneType, SlopeVertexGroup> > requiredlabels = new Dictionary <Sector, Dictionary <PlaneType, SlopeVertexGroup> >(); if (labels != null) { // Dispose old labels foreach (TextLabel l in labels) { l.Dispose(); } } labels = new List <TextLabel>(); // Go through all sectors that belong to a SVG and set which SVG their floor and // ceiling belongs to foreach (SlopeVertexGroup svg in BuilderPlug.Me.SlopeVertexGroups) { foreach (Sector s in svg.Sectors) { if (!requiredlabels.ContainsKey(s)) { requiredlabels.Add(s, new Dictionary <PlaneType, SlopeVertexGroup>()); requiredlabels[s][PlaneType.Floor] = null; requiredlabels[s][PlaneType.Ceiling] = null; } if ((svg.SectorPlanes[s] & PlaneType.Floor) == PlaneType.Floor) { requiredlabels[s][PlaneType.Floor] = svg; } if ((svg.SectorPlanes[s] & PlaneType.Ceiling) == PlaneType.Ceiling) { requiredlabels[s][PlaneType.Ceiling] = svg; } } } foreach (KeyValuePair <Sector, Dictionary <PlaneType, SlopeVertexGroup> > element in requiredlabels) { int numlabels = 0; int counter = 0; Sector sector = element.Key; Dictionary <PlaneType, SlopeVertexGroup> dict = element.Value; // How many planes of this sector have a SVG? if (dict[PlaneType.Floor] != null) { numlabels++; } if (dict[PlaneType.Ceiling] != null) { numlabels++; } TextLabel[] labelarray = new TextLabel[sector.Labels.Count * numlabels]; foreach (PlaneType pt in Enum.GetValues(typeof(PlaneType))) { if (dict[pt] == null) { continue; } // If we're in the second iteration of the loop both the ceiling and // floor of the sector have a SVG, so change to alignment of the // existing labels from center to left if (counter == 1) { for (int i = 0; i < sector.Labels.Count; i++) { labelarray[i].AlignX = TextAlignmentX.Left; } } for (int i = 0; i < sector.Labels.Count; i++) { int apos = sector.Labels.Count * counter + i; Vector2D v = sector.Labels[i].position; labelarray[apos] = new TextLabel(); labelarray[apos].TransformCoords = true; labelarray[apos].AlignY = TextAlignmentY.Middle; labelarray[apos].BackColor = General.Colors.Background.WithAlpha(255); labelarray[apos].Location = sector.Labels[i].position; if (dict[pt].Vertices.Contains(highlightedslope)) { labelarray[apos].Color = General.Colors.Highlight.WithAlpha(255); } else { labelarray[apos].Color = white; } if (pt == PlaneType.Floor) { labelarray[apos].Text = "F"; } else { labelarray[apos].Text = "C"; } // First iteration of loop -> may be the only label needed, so // set it to be in the center if (counter == 0) { labelarray[apos].AlignX = TextAlignmentX.Center; } // Second iteration of the loop so set it to be aligned at the right else if (counter == 1) { labelarray[apos].AlignX = TextAlignmentX.Right; } } counter++; } labels.AddRange(labelarray); } foreach (SlopeVertexGroup svg in BuilderPlug.Me.SlopeVertexGroups) { for (int i = 0; i < svg.Vertices.Count; i++) { SlopeVertex sv = svg.Vertices[i]; float x = sv.Pos.x; float y = sv.Pos.y - 14 * (1 / renderer.Scale); TextLabel label = new TextLabel(); label.TransformCoords = true; label.Location = new Vector2D(x, y); label.AlignX = TextAlignmentX.Center; label.AlignY = TextAlignmentY.Middle; label.BackColor = General.Colors.Background.WithAlpha(255); label.Text = ""; // Rearrange labels if they'd be (exactly) on each other // TODO: do something like that also for overlapping labels foreach (TextLabel l in labels) { if (l.Location.x == label.Location.x && l.Location.y == label.Location.y) { label.Location = new Vector2D(x, l.Location.y - l.TextSize.Height * (1 / renderer.Scale)); } } if (svg.Vertices.Contains(highlightedslope)) { label.Color = General.Colors.Highlight.WithAlpha(255); } else if (sv.Selected) { label.Color = General.Colors.Selection.WithAlpha(255); } else { label.Color = white; } label.Text += String.Format("Z: {0}", sv.Z); labels.Add(label); } } }
// Constructor internal ConfigurationInfo(Configuration cfg, string filename) { // Initialize this.filename = filename; this.config = cfg; //mxd this.settingskey = Path.GetFileNameWithoutExtension(filename).ToLower(); // Load settings from game configuration this.name = config.ReadSetting("game", "<unnamed game>"); this.defaultlumpname = config.ReadSetting("defaultlumpname", ""); // Load settings from program configuration this.nodebuildersave = General.Settings.ReadSetting("configurations." + settingskey + ".nodebuildersave", MISSING_NODEBUILDER); this.nodebuildertest = General.Settings.ReadSetting("configurations." + settingskey + ".nodebuildertest", MISSING_NODEBUILDER); this.formatinterface = config.ReadSetting("formatinterface", "").ToLowerInvariant(); //mxd this.defaultscriptcompiler = cfg.ReadSetting("defaultscriptcompiler", ""); //mxd this.resources = new DataLocationList(General.Settings.Config, "configurations." + settingskey + ".resources"); this.startmode = General.Settings.ReadSetting("configurations." + settingskey + ".startmode", "VerticesMode"); this.enabled = General.Settings.ReadSetting("configurations." + settingskey + ".enabled", config.ReadSetting("enabledbydefault", false)); //mxd //mxd. Read test engines testEngines = new List <EngineInfo>(); IDictionary list = General.Settings.ReadSetting("configurations." + settingskey + ".engines", new ListDictionary()); currentEngineIndex = Math.Max(0, General.Settings.ReadSetting("configurations." + settingskey + ".currentengineindex", 0)); // No engine list found? Use old engine properties if (list.Count == 0) { EngineInfo info = new EngineInfo(); info.TestProgram = General.Settings.ReadSetting("configurations." + settingskey + ".testprogram", ""); info.TestProgramName = General.Settings.ReadSetting("configurations." + settingskey + ".testprogramname", EngineInfo.DEFAULT_ENGINE_NAME); info.TestParameters = General.Settings.ReadSetting("configurations." + settingskey + ".testparameters", ""); info.TestShortPaths = General.Settings.ReadSetting("configurations." + settingskey + ".testshortpaths", false); info.CustomParameters = General.Settings.ReadSetting("configurations." + settingskey + ".customparameters", false); info.TestSkill = General.Settings.ReadSetting("configurations." + settingskey + ".testskill", 3); testEngines.Add(info); currentEngineIndex = 0; } else { //read engines settings from config foreach (DictionaryEntry de in list) { string path = "configurations." + settingskey + ".engines." + de.Key; EngineInfo info = new EngineInfo(); info.TestProgram = General.Settings.ReadSetting(path + ".testprogram", ""); info.TestProgramName = General.Settings.ReadSetting(path + ".testprogramname", EngineInfo.DEFAULT_ENGINE_NAME); info.TestParameters = General.Settings.ReadSetting(path + ".testparameters", ""); info.TestShortPaths = General.Settings.ReadSetting(path + ".testshortpaths", false); info.CustomParameters = General.Settings.ReadSetting(path + ".customparameters", false); info.TestSkill = General.Settings.ReadSetting(path + ".testskill", 3); testEngines.Add(info); } if (currentEngineIndex >= testEngines.Count) { currentEngineIndex = 0; } } //mxd. read custom linedef colors List <LinedefColorPreset> colorPresets = new List <LinedefColorPreset>(); list = General.Settings.ReadSetting("configurations." + settingskey + ".linedefcolorpresets", new ListDictionary()); //no presets? add "classic" ones then. if (list.Count == 0) { colorPresets.Add(new LinedefColorPreset("Any action", PixelColor.FromColor(System.Drawing.Color.PaleGreen), -1, 0, new List <string>(), new List <string>(), true)); } else { //read custom linedef colors from config foreach (DictionaryEntry de in list) { string path = "configurations." + settingskey + ".linedefcolorpresets." + de.Key; string presetname = General.Settings.ReadSetting(path + ".name", "Unnamed"); bool presetenabled = General.Settings.ReadSetting(path + ".enabled", true); PixelColor color = PixelColor.FromInt(General.Settings.ReadSetting(path + ".color", -1)); int action = General.Settings.ReadSetting(path + ".action", 0); int activation = General.Settings.ReadSetting(path + ".activation", 0); List <string> flags = new List <string>(); flags.AddRange(General.Settings.ReadSetting(path + ".flags", "").Split(LINEDEF_COLOR_PRESET_FLAGS_SEPARATOR, StringSplitOptions.RemoveEmptyEntries)); List <string> restrictedFlags = new List <string>(); restrictedFlags.AddRange(General.Settings.ReadSetting(path + ".restrictedflags", "").Split(LINEDEF_COLOR_PRESET_FLAGS_SEPARATOR, StringSplitOptions.RemoveEmptyEntries)); LinedefColorPreset preset = new LinedefColorPreset(presetname, color, action, activation, flags, restrictedFlags, presetenabled); colorPresets.Add(preset); } } linedefColorPresets = colorPresets.ToArray(); // Make list of things filters thingsfilters = new List <ThingsFilter>(); IDictionary cfgfilters = General.Settings.ReadSetting("configurations." + settingskey + ".thingsfilters", new Hashtable()); foreach (DictionaryEntry de in cfgfilters) { thingsfilters.Add(new ThingsFilter(General.Settings.Config, "configurations." + settingskey + ".thingsfilters." + de.Key)); } // Make list of texture sets texturesets = new List <DefinedTextureSet>(); IDictionary sets = General.Settings.ReadSetting("configurations." + settingskey + ".texturesets", new Hashtable()); foreach (DictionaryEntry de in sets) { texturesets.Add(new DefinedTextureSet(General.Settings.Config, "configurations." + settingskey + ".texturesets." + de.Key)); } // Make list of edit modes this.editmodes = new Dictionary <string, bool>(StringComparer.Ordinal); IDictionary modes = General.Settings.ReadSetting("configurations." + settingskey + ".editmodes", new Hashtable()); foreach (DictionaryEntry de in modes) { if (de.Key.ToString().StartsWith(MODE_ENABLED_KEY)) { editmodes.Add(de.Value.ToString(), true); } else if (de.Key.ToString().StartsWith(MODE_DISABLED_KEY)) { editmodes.Add(de.Value.ToString(), false); } } }
override protected void Update() { if (blockupdate) { return; } PixelColor stitchcolor = General.Colors.Highlight; PixelColor losecolor = General.Colors.Selection; snaptocardinaldirection = General.Interface.ShiftState && General.Interface.AltState; //mxd snaptogrid = (snaptocardinaldirection || General.Interface.ShiftState ^ General.Interface.SnapToGrid); snaptonearest = General.Interface.CtrlState ^ General.Interface.AutoMerge; DrawnVertex curp = GetCurrentPosition(); Vector2D curvertexpos = curp.pos; float vsize = (renderer.VertexSize + 1.0f) / renderer.Scale; curp.pos = curp.pos.GetRotated(-General.Map.Grid.GridRotate); // Render drawing lines if (renderer.StartOverlay(true)) { PixelColor color = snaptonearest ? stitchcolor : losecolor; if (points.Count == 1) { UpdateReferencePoints(points[0], curp); Vector2D[] shape = GetShape(start, end); Vector2D startrotated = start.GetRotated(General.Map.Grid.GridRotate); Vector2D endrotated = end.GetRotated(General.Map.Grid.GridRotate); // Rotate the shape to fit the grid rotation for (int i = 0; i < shape.Length; i++) { shape[i] = shape[i].GetRotated(General.Map.Grid.GridRotate); } // Render guidelines if (showguidelines) { RenderGuidelines(startrotated, endrotated, General.Colors.Guideline.WithAlpha(80), -General.Map.Grid.GridRotate); } //render shape for (int i = 1; i < shape.Length; i++) { renderer.RenderLine(shape[i - 1], shape[i], LINE_THICKNESS, color, true); } //vertices for (int i = 0; i < shape.Length; i++) { renderer.RenderRectangleFilled(new RectangleF((float)(shape[i].x - vsize), (float)(shape[i].y - vsize), vsize * 2.0f, vsize * 2.0f), color, true); } //and labels if (shape.Length == 2) { // Render label for line labels[0].Move(startrotated, endrotated); renderer.RenderText(labels[0].TextLabel); } else if (shape.Length > 3) { // Render labels for rectangle Vector2D[] labelCoords = { startrotated, new Vector2D(end.x, start.y).GetRotated(General.Map.Grid.GridRotate), endrotated, new Vector2D(start.x, end.y).GetRotated(General.Map.Grid.GridRotate), startrotated }; for (int i = 1; i < 5; i++) { labels[i - 1].Move(labelCoords[i], labelCoords[i - 1]); renderer.RenderText(labels[i - 1].TextLabel); } //got beveled corners? if (alwaysrendershapehints || shape.Length > minpointscount + 1) { //render hint if (width > 64 * vsize && height > 16 * vsize) { hintlabel.Move(startrotated, endrotated); hintlabel.Text = GetHintText(); renderer.RenderText(hintlabel.TextLabel); } //and shape corners for (int i = 0; i < 4; i++) { renderer.RenderRectangleFilled(new RectangleF((float)(labelCoords[i].x - vsize), (float)(labelCoords[i].y - vsize), vsize * 2.0f, vsize * 2.0f), General.Colors.InfoLine, true); } } } else { // Render vertex at points[0] renderer.RenderRectangleFilled(new RectangleF((float)(start.x - vsize), (float)(start.y - vsize), vsize * 2.0f, vsize * 2.0f), General.Colors.InfoLine, true); } } else { // Render vertex at cursor renderer.RenderRectangleFilled(new RectangleF((float)(curvertexpos.x - vsize), (float)(curvertexpos.y - vsize), vsize * 2.0f, vsize * 2.0f), color, true); } // Done renderer.Finish(); } // Done renderer.Present(); }
// This event is called when the plugin is initialized public override void OnInitialize() { base.OnInitialize(); highlightcolor = PixelColor.FromInt(General.Settings.ReadPluginSetting("highlightcolor", new PixelColor(255, 0, 192, 0).ToInt())); level1color = PixelColor.FromInt(General.Settings.ReadPluginSetting("level1color", new PixelColor(255, 0, 255, 0).ToInt())); level2color = PixelColor.FromInt(General.Settings.ReadPluginSetting("level2color", new PixelColor(255, 255, 255, 0).ToInt())); nosoundcolor = PixelColor.FromInt(General.Settings.ReadPluginSetting("nosoundcolor", new PixelColor(255, 160, 160, 160).ToInt())); blocksoundcolor = PixelColor.FromInt(General.Settings.ReadPluginSetting("blocksoundcolor", new PixelColor(255, 255, 0, 0).ToInt())); distinctcolors = new List <PixelColor> { PixelColor.FromInt(0x84d5a4), PixelColor.FromInt(0xc059cb), PixelColor.FromInt(0xd0533d), PixelColor.FromInt(0x415354), PixelColor.FromInt(0xcea953), PixelColor.FromInt(0x91d44b), PixelColor.FromInt(0xcd5b89), PixelColor.FromInt(0xa8b6c0), PixelColor.FromInt(0x797ecb), PixelColor.FromInt(0x567539), PixelColor.FromInt(0x72422f), PixelColor.FromInt(0x5d3762), PixelColor.FromInt(0xffed6f), PixelColor.FromInt(0xccebc5), PixelColor.FromInt(0xbc80bd), PixelColor.FromInt(0xd9d9d9), PixelColor.FromInt(0xfccde5), PixelColor.FromInt(0x80b1d3), PixelColor.FromInt(0xfdb462), PixelColor.FromInt(0xb3de69), PixelColor.FromInt(0xfb8072), PixelColor.FromInt(0xbebada), PixelColor.FromInt(0xffffb3), PixelColor.FromInt(0x8dd3c7), }; //mxd. Create coloured icons distincticons = new List <Bitmap>(distinctcolors.Count); foreach (PixelColor color in distinctcolors) { distincticons.Add(MakeTintedImage(Properties.Resources.Status0, color)); } soundenvironments = new List <SoundEnvironment>(); blockinglinedefs = new List <Linedef>(); soundenvironmentisupdated = false; dataisdirty = true; // This binds the methods in this class that have the BeginAction // and EndAction attributes with their actions. Without this, the // attributes are useless. Note that in classes derived from EditMode // this is not needed, because they are bound automatically when the // editing mode is engaged. General.Actions.BindMethods(this); menusform = new MenusForm(); // TODO: Add DB2 version check so that old DB2 versions won't crash // General.ErrorLogger.Add(ErrorType.Error, "zomg!"); // Keep a static reference me = this; }
/// <summary> /// Embeds the text using one bit. /// </summary> /// <param name="sourcePixels">The source pixels.</param> /// <param name="decoderPixelWidth">Width of the decoder pixel.</param> /// <param name="decoderPixelHeight">Height of the decoder pixel.</param> /// <param name="text">The text.</param> /// <param name="isEncrypted">if set to <c>true</c> [is encrypted].</param> /// <param name="rotated">The rotated.</param> public void EmbedTextUsingOneBit(byte[] sourcePixels, uint decoderPixelWidth, uint decoderPixelHeight, string text, bool isEncrypted, int rotated) { if (isEncrypted) { text = text.ForwardRot(rotated); } text += "!EOM!"; long pixelElementIndex = 0; int charIndex = 0; int charValue = 0; bool notDone = true; for (var i = 0; i < decoderPixelHeight; i++) { for (var j = 0; j < decoderPixelWidth; j++) { var pixelColor = PixelColor.GetPixelBgra8(sourcePixels, i, j, decoderPixelWidth, decoderPixelHeight); var r = pixelColor.R - pixelColor.R % 2; var g = pixelColor.G - pixelColor.G % 2; var b = pixelColor.B - pixelColor.B % 2; if (j == 0 && i == 0) { pixelColor.R = 119; pixelColor.B = 119; pixelColor.G = 119; PixelColor.SetPixelBgra8(sourcePixels, i, j, pixelColor, decoderPixelWidth, decoderPixelHeight); } else if (j == 1 && i == 0) { pixelColor.R |= 1; g &= ~(1 << 0); g &= ~(1 << 1); pixelColor.G = (byte)g; pixelColor.G |= 1 << 0; b &= ~(1 << 7); if (isEncrypted) { b |= 1 << 7; b = this.changeFiveLSB(b); b += rotated; pixelColor.B = (byte)b; } PixelColor.SetPixelBgra8(sourcePixels, i, j, pixelColor, decoderPixelWidth, decoderPixelHeight); } else { for (int n = 0; n < 3; n++) { if (pixelElementIndex % 8 == 0) { if (charIndex >= text.Length) { notDone = false; } else { charValue = text[charIndex++]; } } switch (pixelElementIndex % 3) { case 0: { if (notDone) { r += charValue % 2; charValue /= 2; } pixelColor.R = (byte)r; } break; case 1: { if (notDone) { g += charValue % 2; charValue /= 2; } pixelColor.G = (byte)g; } break; case 2: { if (notDone) { b += charValue % 2; charValue /= 2; } pixelColor.B = (byte)b; PixelColor.SetPixelBgra8(sourcePixels, i, j, pixelColor, decoderPixelWidth, decoderPixelHeight); } break; } pixelElementIndex++; } } } } }
// This creates pixel color data from the given data // Returns null on failure private PixelColor[] ReadAsPixelData(Stream stream, out int width, out int height, out int offsetx, out int offsety) { BinaryReader reader = new BinaryReader(stream); // Initialize width = 0; height = 0; offsetx = 0; offsety = 0; int dataoffset = (int)stream.Position; // Need at least 4 bytes if ((stream.Length - stream.Position) < 4) { return(null); } #if !DEBUG try { #endif // Read size and offset width = reader.ReadInt16(); height = reader.ReadInt16(); offsetx = reader.ReadInt16(); offsety = reader.ReadInt16(); // Valid width and height? if ((width <= 0) || (height <= 0)) { return(null); } // Read the column addresses int[] columns = new int[width]; for (int x = 0; x < width; x++) { columns[x] = reader.ReadInt32(); } // Allocate memory PixelColor[] pixeldata = new PixelColor[width * height]; // Go for all columns for (int x = 0; x < width; x++) { // Seek to column start stream.Seek(dataoffset + columns[x], SeekOrigin.Begin); // Read first post start int y = reader.ReadByte(); int read_y = y; // Continue while not end of column reached while (read_y < 255) { // Read number of pixels in post int count = reader.ReadByte(); // Skip unused pixel stream.Seek(1, SeekOrigin.Current); // Draw post for (int yo = 0; yo < count; yo++) { // Read pixel color index int p = reader.ReadByte(); //mxd. Sanity check required... int offset = (y + yo) * width + x; if (offset > pixeldata.Length - 1) { return(null); } // Draw pixel pixeldata[offset] = palette[p]; } // Skip unused pixel stream.Seek(1, SeekOrigin.Current); // Read next post start read_y = reader.ReadByte(); if (read_y < y || (height > 256 && read_y == y)) { y += read_y; } else { y = read_y; //mxd. Fix for tall patches higher than 508 pixels } } } // Return pointer return(pixeldata); #if !DEBUG } catch (Exception) { // Return nothing return(null); } #endif }
// This builds the geometry. Returns false when no geometry created. public override bool Setup() { Vector2D vl, vr; // Left and right vertices for this sidedef if (Sidedef.IsFront) { vl = new Vector2D(Sidedef.Line.Start.Position.x, Sidedef.Line.Start.Position.y); vr = new Vector2D(Sidedef.Line.End.Position.x, Sidedef.Line.End.Position.y); } else { vl = new Vector2D(Sidedef.Line.End.Position.x, Sidedef.Line.End.Position.y); vr = new Vector2D(Sidedef.Line.Start.Position.x, Sidedef.Line.Start.Position.y); } // Load sector data SectorData sd = Sector.GetSectorData(); SectorData osd = mode.GetSectorData(Sidedef.Other.Sector); if (!osd.Updated) { osd.Update(); } //mxd double vlzc = sd.Ceiling.plane.GetZ(vl); double vrzc = sd.Ceiling.plane.GetZ(vr); //mxd. Side is visible when our sector's ceiling is higher than the other's at any vertex if (!(vlzc > osd.Ceiling.plane.GetZ(vl) || vrzc > osd.Ceiling.plane.GetZ(vr))) { base.SetVertices(null); return(false); } //mxd. Apply sky hack? UpdateSkyRenderFlag(); //mxd. lightfog flag support int lightvalue; bool lightabsolute; GetLightValue(out lightvalue, out lightabsolute); Vector2D tscale = new Vector2D(Sidedef.Fields.GetValue("scalex_top", 1.0), Sidedef.Fields.GetValue("scaley_top", 1.0)); Vector2D tscaleAbs = new Vector2D(Math.Abs(tscale.x), Math.Abs(tscale.y)); Vector2D toffset = new Vector2D(Sidedef.Fields.GetValue("offsetx_top", 0.0), Sidedef.Fields.GetValue("offsety_top", 0.0)); // Texture given? if ((Sidedef.LongHighTexture != MapSet.EmptyLongName)) { // Load texture base.Texture = General.Map.Data.GetTextureImage(Sidedef.LongHighTexture); if (base.Texture == null || base.Texture is UnknownImage) { base.Texture = General.Map.Data.UnknownTexture3D; setuponloadedtexture = Sidedef.LongHighTexture; } else if (!base.Texture.IsImageLoaded) { setuponloadedtexture = Sidedef.LongHighTexture; } } else { // Use missing texture base.Texture = General.Map.Data.MissingTexture3D; setuponloadedtexture = 0; } // Get texture scaled size. Round up, because that's apparently what GZDoom does Vector2D tsz = new Vector2D(Math.Ceiling(base.Texture.ScaledWidth / tscale.x), Math.Ceiling(base.Texture.ScaledHeight / tscale.y)); // Get texture offsets Vector2D tof = new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY); tof = tof + toffset; // biwa. Also take the ForceWorldPanning MAPINFO entry into account if (General.Map.Config.ScaledTextureOffsets && (!base.Texture.WorldPanning && !General.Map.Data.MapInfo.ForceWorldPanning)) { tof = tof / tscaleAbs; tof = tof * base.Texture.Scale; // If the texture gets replaced with a "hires" texture it adds more fuckery if (base.Texture is HiResImage) { tof *= tscaleAbs; } // Round up, since that's apparently what GZDoom does. Not sure if this is the right place or if it also has to be done earlier tof = new Vector2D(Math.Ceiling(tof.x), Math.Ceiling(tof.y)); } // Determine texture coordinates plane as they would be in normal circumstances. // We can then use this plane to find any texture coordinate we need. // The logic here is the same as in the original VisualMiddleSingle (except that // the values are stored in a TexturePlane) // NOTE: I use a small bias for the floor height, because if the difference in // height is 0 then the TexturePlane doesn't work! TexturePlane tp = new TexturePlane(); double ceilbias = (Sidedef.Other.Sector.CeilHeight == Sidedef.Sector.CeilHeight) ? 1.0 : 0.0; if (!Sidedef.Line.IsFlagSet(General.Map.Config.UpperUnpeggedFlag)) { // When lower unpegged is set, the lower texture is bound to the bottom tp.tlt.y = tsz.y - (Sidedef.Sector.CeilHeight - Sidedef.Other.Sector.CeilHeight); } tp.trb.x = tp.tlt.x + Math.Round(Sidedef.Line.Length); //mxd. (G)ZDoom snaps texture coordinates to integral linedef length tp.trb.y = tp.tlt.y + (Sidedef.Sector.CeilHeight - (Sidedef.Other.Sector.CeilHeight + ceilbias)); // Apply texture offset tp.tlt += tof; tp.trb += tof; // Transform pixel coordinates to texture coordinates tp.tlt /= tsz; tp.trb /= tsz; // Left top and right bottom of the geometry that tp.vlt = new Vector3D(vl.x, vl.y, Sidedef.Sector.CeilHeight); tp.vrb = new Vector3D(vr.x, vr.y, Sidedef.Other.Sector.CeilHeight + ceilbias); // Make the right-top coordinates tp.trt = new Vector2D(tp.trb.x, tp.tlt.y); tp.vrt = new Vector3D(tp.vrb.x, tp.vrb.y, tp.vlt.z); // Create initial polygon, which is just a quad between floor and ceiling WallPolygon poly = new WallPolygon(); poly.Add(new Vector3D(vl.x, vl.y, sd.Floor.plane.GetZ(vl))); poly.Add(new Vector3D(vl.x, vl.y, vlzc)); poly.Add(new Vector3D(vr.x, vr.y, vrzc)); poly.Add(new Vector3D(vr.x, vr.y, sd.Floor.plane.GetZ(vr))); // Determine initial color int lightlevel = lightabsolute ? lightvalue : sd.Ceiling.brightnessbelow + lightvalue; //mxd. This calculates light with doom-style wall shading PixelColor wallbrightness = PixelColor.FromInt(mode.CalculateBrightness(lightlevel, Sidedef)); PixelColor wallcolor = PixelColor.Modulate(sd.Ceiling.colorbelow, wallbrightness); fogfactor = CalculateFogFactor(lightlevel); poly.color = wallcolor.WithAlpha(255).ToInt(); // Cut off the part below the other ceiling CropPoly(ref poly, osd.Ceiling.plane, false); // Cut out pieces that overlap 3D floors in this sector List <WallPolygon> polygons = new List <WallPolygon> { poly }; ClipExtraFloors(polygons, sd.ExtraFloors, false); //mxd if (polygons.Count > 0) { // Keep top and bottom planes for intersection testing Vector2D linecenter = Sidedef.Line.GetCenterPoint(); //mxd. Our sector's floor can be higher than the other sector's ceiling! top = sd.Ceiling.plane; bottom = (osd.Ceiling.plane.GetZ(linecenter) > sd.Floor.plane.GetZ(linecenter) ? osd.Ceiling.plane : sd.Floor.plane); // Process the polygon and create vertices List <WorldVertex> verts = CreatePolygonVertices(polygons, tp, sd, lightvalue, lightabsolute); if (verts.Count > 2) { base.SetVertices(verts); return(true); } } base.SetVertices(null); //mxd return(false); }
public PixelColor[,] GetPixels(BitmapSource source) { if (source.Format != PixelFormats.Bgra32) source = new FormatConvertedBitmap(source, PixelFormats.Bgra32, null, 0); int width = source.PixelWidth; int height = source.PixelHeight; PixelColor[,] result = new PixelColor[width, height]; source.CopyPixels(result, width * 4, 0); return result; }
// This loads the image protected unsafe override void LocalLoadImage() { // Leave when already loaded if (this.IsImageLoaded) { return; } lock (this) { // Get the lump data stream string voxellocation = string.Empty; //mxd Stream lumpdata = General.Map.Data.GetVoxelData(voxelname, ref voxellocation); if (lumpdata != null) { // Copy lump data to memory lumpdata.Seek(0, SeekOrigin.Begin); byte[] membytes = new byte[(int)lumpdata.Length]; lumpdata.Read(membytes, 0, (int)lumpdata.Length); using (MemoryStream mem = new MemoryStream(membytes)) { mem.Seek(0, SeekOrigin.Begin); PixelColor[] palette = new PixelColor[256]; // Create front projection image from the KVX using (BinaryReader reader = new BinaryReader(mem, Encoding.ASCII)) { reader.ReadInt32(); //numbytes, we don't use that int xsize = reader.ReadInt32(); int ysize = reader.ReadInt32(); int zsize = reader.ReadInt32(); // Sanity check if (xsize == 0 || ysize == 0 || zsize == 0) { General.ErrorLogger.Add(ErrorType.Error, "Cannot create sprite image for voxel \"" + Path.Combine(voxellocation, voxelname) + "\" for voxel drawing: voxel has invalid size (width: " + xsize + ", height: " + zsize + ", depth: " + ysize); loadfailed = true; return; } int pivotx = (int)Math.Round(reader.ReadInt32() / 256f); int pivoty = (int)Math.Round(reader.ReadInt32() / 256f); int pivotz = (int)Math.Round(reader.ReadInt32() / 256f); // Read offsets int[] xoffset = new int[xsize + 1]; // why is it xsize + 1, not xsize?.. short[,] xyoffset = new short[xsize, ysize + 1]; // why is it ysize + 1, not ysize?.. for (int i = 0; i < xoffset.Length; i++) { xoffset[i] = reader.ReadInt32(); } for (int x = 0; x < xsize; x++) { for (int y = 0; y < ysize + 1; y++) { xyoffset[x, y] = reader.ReadInt16(); } } // Read slabs List <int> offsets = new List <int>(xsize * ysize); for (int x = 0; x < xsize; x++) { for (int y = 0; y < ysize; y++) { offsets.Add(xoffset[x] + xyoffset[x, y] + 28); // for some reason offsets are counted from start of xoffset[]... } } int counter = 0; int slabsend = (int)(reader.BaseStream.Length - 768); // Read palette if (!overridepalette) { reader.BaseStream.Position = slabsend; for (int i = 0; i < 256; i++) { byte r = (byte)(reader.ReadByte() * 4); byte g = (byte)(reader.ReadByte() * 4); byte b = (byte)(reader.ReadByte() * 4); palette[i] = new PixelColor(255, r, g, b); } } else { for (int i = 0; i < 256; i++) { palette[i] = General.Map.Data.Palette[i]; } } // Populate projection pixels array int imgwidth, imgheight, imgoffsetx; bool checkalpha = false; // Convert angleoffsets to the nearest cardinal direction... angleoffset = General.ClampAngle((angleoffset + 45) / 90 * 90); switch (angleoffset) { case 0: imgwidth = xsize; imgheight = zsize; imgoffsetx = pivotx; break; case 90: imgwidth = ysize; imgheight = zsize; imgoffsetx = imgwidth - pivoty; checkalpha = true; break; case 180: imgwidth = xsize; imgheight = zsize; imgoffsetx = imgwidth - pivotx; checkalpha = true; break; case 270: imgwidth = ysize; imgheight = zsize; imgoffsetx = pivoty; break; default: throw new InvalidDataException("Invalid AngleOffset"); } int numpixels = imgwidth * imgheight; PixelColor[] pixelsarr = new PixelColor[numpixels]; // Read pixel colors for (int x = 0; x < xsize; x++) { for (int y = 0; y < ysize; y++) { reader.BaseStream.Position = offsets[counter]; int next = (counter < offsets.Count - 1 ? offsets[counter + 1] : slabsend); // Read first color from the slab while (reader.BaseStream.Position < next) { int ztop = reader.ReadByte(); int zleng = reader.ReadByte(); if (ztop + zleng > zsize) { break; } byte flags = reader.ReadByte(); if (zleng > 0) { // Skip slab if no flags are given (otherwise some garbage pixels may be drawn) if (flags == 0) { reader.BaseStream.Position += zleng; continue; } List <int> colorindices = new List <int>(zleng); for (int i = 0; i < zleng; i++) { colorindices.Add(reader.ReadByte()); } int z = ztop; int cstart = 0; while (z < ztop + zleng) { // Get pixel position int pixelpos; switch (angleoffset) { case 0: pixelpos = x + z * xsize; break; case 90: pixelpos = y + z * ysize; break; case 180: pixelpos = xsize - x - 1 + z * xsize; break; case 270: pixelpos = ysize - y - 1 + z * ysize; break; default: throw new InvalidDataException("Invalid AngleOffset"); } // Add to projection pixels array if ((checkalpha && pixelsarr[pixelpos].a == 0) || !checkalpha) { pixelsarr[pixelpos] = palette[colorindices[cstart]]; } // Increment counters cstart++; z++; } } } counter++; } } // Draw to bitmap if (bitmap != null) { bitmap.Dispose(); } bitmap = new Bitmap(imgwidth, imgheight, PixelFormat.Format32bppArgb); BitmapData bmpdata = null; try { bmpdata = bitmap.LockBits(new Rectangle(0, 0, imgwidth, imgheight), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); } catch (Exception e) { General.ErrorLogger.Add(ErrorType.Error, "Cannot lock image for drawing voxel \"" + Path.Combine(voxellocation, voxelname) + "\". " + e.GetType().Name + ": " + e.Message); bitmap = null; } if (bmpdata != null) { // Apply pixels to image PixelColor *pixels = (PixelColor *)bmpdata.Scan0.ToPointer(); int i = 0; for (PixelColor *cp = pixels; cp < pixels + numpixels; cp++, i++) { if (pixelsarr[i].a == 255) { cp->r = pixelsarr[i].r; cp->g = pixelsarr[i].g; cp->b = pixelsarr[i].b; cp->a = 255; } } bitmap.UnlockBits(bmpdata); } if (bitmap != null) { // Get width and height from image width = bitmap.Size.Width; height = bitmap.Size.Height; scale.x = 1.0f; scale.y = 1.0f; offsetx = imgoffsetx; offsety = pivotz; } else { loadfailed = true; } } } lumpdata.Dispose(); } else { // Missing voxel lump! General.ErrorLogger.Add(ErrorType.Error, "Missing voxel lump \"" + voxelname + "\". Forgot to include required resources?"); } // Pass on to base base.LocalLoadImage(); } }
private bool isFlag(PixelColor[,] pixels) { for (int i = 5; i < 10; i++) for (int j = 10; j < 20; j++) if (!compareColor(pixels[i, j], new PixelColor(229, 194, 79), colorDelta)) return false; return compareColor(pixels[20, 20], new PixelColor(199, 0, 0), colorDelta); }
int DrawChar(ByteBuffer input, char ch, int offsetx, int offsety, PixelColor fore, PixelColor back) { CharInfo info = chars[translateChar(ch)]; reader.Seek(info.pos, Burntime.Platform.IO.SeekPosition.Begin); int w = 1; int h = 8; int round = 0; int pos = 0; int unknown1 = reader.ReadUShort(); int unknown2 = reader.ReadUShort(); w = 4 * (unknown1 + 1); h = unknown2; while (!reader.IsEOF && round != 4) { int data = reader.ReadByte(); PixelColor c; if (back != PixelColor.Black) { c = (data == 0x01) ? back : fore; } else { c = (data == 0x01) ? PixelColor.Black : PixelColor.White; } int x = pos % w; int y = (pos - x) / w; if (data != 0) { input.DrawPixel(x + offsetx, y + offsety, c.r, c.g, c.b); } pos += 4; if (pos >= w * h) { pos -= w * h; pos++; round++; } } return(info.width); }
private bool isZero(PixelColor[,] pixels) { for (int i = 15; i < 30; i++) for (int j = 15; j < 30; j++) if (!compareColor(pixels[i, j], new PixelColor(255, 255, 255), colorDelta)) return false; return true; }
private void bReset_Click(object sender, EventArgs e) { cpColor.Focus(); // Otherwise the focus will go to cpColor's textbox, which is not what we want cpColor.Color = PixelColor.FromInt(defaultvalue).WithAlpha(255); cpColor_ColorChanged(this, EventArgs.Empty); }
private PixelColor[,] CopyPixels(BitmapSource source) { int height = source.PixelHeight; int width = source.PixelWidth; int stride = width * 4; PixelColor[,] pixels = new PixelColor[width, height]; var pixelBytes = new byte[height * width * 4]; source.CopyPixels(pixelBytes, stride, 0); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { pixels[x, y] = new PixelColor { Blue = pixelBytes[(y * width + x) * 4 + 0], Green = pixelBytes[(y * width + x) * 4 + 1], Red = pixelBytes[(y * width + x) * 4 + 2], Alpha = pixelBytes[(y * width + x) * 4 + 3], }; } } return pixels; }
private bool compareColor(PixelColor c1, PixelColor c2, int delta) { return Math.Abs(c1.Blue - c2.Blue) < delta && Math.Abs(c1.Red - c2.Red) < delta && Math.Abs(c1.Green - c2.Green) < delta; }
// This builds the geometry. Returns false when no geometry created. public override bool Setup() { Vector2D vl, vr; //mxd. lightfog flag support int lightvalue; bool lightabsolute; GetLightValue(out lightvalue, out lightabsolute); Vector2D tscale = new Vector2D(Sidedef.Fields.GetValue("scalex_mid", 1.0f), Sidedef.Fields.GetValue("scaley_mid", 1.0f)); Vector2D toffset = new Vector2D(Sidedef.Fields.GetValue("offsetx_mid", 0.0f), Sidedef.Fields.GetValue("offsety_mid", 0.0f)); // Left and right vertices for this sidedef if (Sidedef.IsFront) { vl = new Vector2D(Sidedef.Line.Start.Position.x, Sidedef.Line.Start.Position.y); vr = new Vector2D(Sidedef.Line.End.Position.x, Sidedef.Line.End.Position.y); } else { vl = new Vector2D(Sidedef.Line.End.Position.x, Sidedef.Line.End.Position.y); vr = new Vector2D(Sidedef.Line.Start.Position.x, Sidedef.Line.Start.Position.y); } // Load sector data SectorData sd = mode.GetSectorData(Sidedef.Sector); // Texture given? if (Sidedef.LongMiddleTexture != MapSet.EmptyLongName) { // Load texture base.Texture = General.Map.Data.GetTextureImage(Sidedef.LongMiddleTexture); if (base.Texture == null || base.Texture is UnknownImage) { base.Texture = General.Map.Data.UnknownTexture3D; setuponloadedtexture = Sidedef.LongMiddleTexture; } else { if (!base.Texture.IsImageLoaded) { setuponloadedtexture = Sidedef.LongMiddleTexture; } } } else { // Use missing texture base.Texture = General.Map.Data.MissingTexture3D; setuponloadedtexture = 0; } // Get texture scaled size Vector2D tsz = new Vector2D(base.Texture.ScaledWidth, base.Texture.ScaledHeight); tsz = tsz / tscale; // Get texture offsets Vector2D tof = new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY); tof = tof + toffset; tof = tof / tscale; if (General.Map.Config.ScaledTextureOffsets && !base.Texture.WorldPanning) { tof = tof * base.Texture.Scale; } // Determine texture coordinates plane as they would be in normal circumstances. // We can then use this plane to find any texture coordinate we need. // The logic here is the same as in the original VisualMiddleSingle (except that // the values are stored in a TexturePlane) // NOTE: I use a small bias for the floor height, because if the difference in // height is 0 then the TexturePlane doesn't work! TexturePlane tp = new TexturePlane(); float floorbias = (Sidedef.Sector.CeilHeight == Sidedef.Sector.FloorHeight) ? 1.0f : 0.0f; if (Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag)) { // When lower unpegged is set, the middle texture is bound to the bottom tp.tlt.y = tsz.y - (Sidedef.Sector.CeilHeight - Sidedef.Sector.FloorHeight); } tp.trb.x = tp.tlt.x + (float)Math.Round(Sidedef.Line.Length); //mxd. (G)ZDoom snaps texture coordinates to integral linedef length tp.trb.y = tp.tlt.y + (Sidedef.Sector.CeilHeight - (Sidedef.Sector.FloorHeight + floorbias)); // Apply texture offset tp.tlt += tof; tp.trb += tof; // Transform pixel coordinates to texture coordinates tp.tlt /= tsz; tp.trb /= tsz; // Left top and right bottom of the geometry that tp.vlt = new Vector3D(vl.x, vl.y, Sidedef.Sector.CeilHeight); tp.vrb = new Vector3D(vr.x, vr.y, Sidedef.Sector.FloorHeight + floorbias); // Make the right-top coordinates tp.trt = new Vector2D(tp.trb.x, tp.tlt.y); tp.vrt = new Vector3D(tp.vrb.x, tp.vrb.y, tp.vlt.z); // Get ceiling and floor heights float fl = sd.Floor.plane.GetZ(vl); float fr = sd.Floor.plane.GetZ(vr); float cl = sd.Ceiling.plane.GetZ(vl); float cr = sd.Ceiling.plane.GetZ(vr); // Anything to see? if (((cl - fl) > 0.01f) || ((cr - fr) > 0.01f)) { // Keep top and bottom planes for intersection testing top = sd.Ceiling.plane; bottom = sd.Floor.plane; // Create initial polygon, which is just a quad between floor and ceiling WallPolygon poly = new WallPolygon(); poly.Add(new Vector3D(vl.x, vl.y, fl)); poly.Add(new Vector3D(vl.x, vl.y, cl)); poly.Add(new Vector3D(vr.x, vr.y, cr)); poly.Add(new Vector3D(vr.x, vr.y, fr)); // Determine initial color int lightlevel = lightabsolute ? lightvalue : sd.Ceiling.brightnessbelow + lightvalue; //mxd. This calculates light with doom-style wall shading PixelColor wallbrightness = PixelColor.FromInt(mode.CalculateBrightness(lightlevel, Sidedef)); PixelColor wallcolor = PixelColor.Modulate(sd.Ceiling.colorbelow, wallbrightness); fogfactor = CalculateFogFactor(lightlevel); poly.color = wallcolor.WithAlpha(255).ToInt(); // Cut out pieces that overlap 3D floors in this sector List <WallPolygon> polygons = new List <WallPolygon> { poly }; ClipExtraFloors(polygons, sd.ExtraFloors, false); //mxd if (polygons.Count > 0) { // Process the polygon and create vertices List <WorldVertex> verts = CreatePolygonVertices(polygons, tp, sd, lightvalue, lightabsolute); if (verts.Count > 2) { base.SetVertices(verts); return(true); } } } base.SetVertices(null); //mxd return(false); }
private bool isUnknown(PixelColor[,] pixels) { if (compareColor(pixels[10, 10], new PixelColor(99, 176, 255), colorDelta)) return true; return false; }
private static int[] GetHSV(PixelColor color) { int[] hsv = new int[3]; byte r = color.r; byte g = color.g; byte b = color.b; int min = r; int max = r; float delta = 0.0f; float j = 0.0f; float x = 0.0f; float xr = 0.0f; float xg = 0.0f; float xb = 0.0f; float sum = 0.0f; if (g < min) { min = g; } if (b < min) { min = b; } if (g > max) { max = g; } if (b > max) { max = b; } delta = ((float)max / 255.0f); if (PreciseCmp(delta, 0.0f)) { delta = 0; } else { j = ((delta - ((float)min / 255.0f)) / delta); } if (!PreciseCmp(j, 0.0f)) { xr = ((float)r / 255.0f); if (!PreciseCmp(xr, delta)) { xg = ((float)g / 255.0f); if (!PreciseCmp(xg, delta)) { xb = ((float)b / 255.0f); if (PreciseCmp(xb, delta)) { sum = ((((delta - xg) / (delta - (min / 255.0f))) + 4.0f) - ((delta - xr) / (delta - (min / 255.0f)))); } } else { sum = ((((delta - xr) / (delta - (min / 255.0f))) + 2.0f) - ((delta - (b / 255.0f)) / (delta - (min / 255.0f)))); } } else { sum = (((delta - (b / 255.0f))) / (delta - (min / 255.0f))) - ((delta - (g / 255.0f)) / (delta - (min / 255.0f))); } x = (sum * 60.0f); if (x < 0) { x += 360.0f; } } else { j = 0.0f; } hsv[0] = (int)((x / 360.0f) * 255.0f); hsv[1] = (int)(j * 255.0f); hsv[2] = (int)(delta * 255.0f); return(hsv); }
private static PixelColor GetRGB(int[] hsv) { float x = 0.0f; float j = 0.0f; float i = 0.0f; int table = 0; float xr = 0.0f; float xg = 0.0f; float xb = 0.0f; int h = hsv[0]; int s = hsv[1]; int v = hsv[2]; PixelColor color = new PixelColor(); j = (h / 255.0f) * 360.0f; if (360.0f <= j) { j -= 360.0f; } x = (s / 255.0f); i = (v / 255.0f); if (!PreciseCmp(x, 0.0f)) { table = (int)(j / 60.0f); if (table < 6) { float t = (j / 60.0f); switch (table) { case 0: xr = i; xg = ((1.0f - ((1.0f - (t - (float)table)) * x)) * i); xb = ((1.0f - x) * i); break; case 1: xr = ((1.0f - (x * (t - (float)table))) * i); xg = i; xb = ((1.0f - x) * i); break; case 2: xr = ((1.0f - x) * i); xg = i; xb = ((1.0f - ((1.0f - (t - (float)table)) * x)) * i); break; case 3: xr = ((1.0f - x) * i); xg = ((1.0f - (x * (t - (float)table))) * i); xb = i; break; case 4: xr = ((1.0f - ((1.0f - (t - (float)table)) * x)) * i); xg = ((1.0f - x) * i); xb = i; break; case 5: xr = i; xg = ((1.0f - x) * i); xb = ((1.0f - (x * (t - (float)table))) * i); break; } } } else { xr = xg = xb = i; } color.r = (byte)(xr * 255.0f); color.g = (byte)(xg * 255.0f); color.b = (byte)(xb * 255.0f); color.a = 255; return(color); }
public static List <Line3D> GetPointLightShape(Thing t, bool highlight, GZGeneral.LightData ld, int linealpha) { // TODO: this basically duplicates VisualThing.UpdateLight()... // Determine light radiii int primaryradius; int secondaryradius = 0; if (ld.LightDef != GZGeneral.LightDef.VAVOOM_GENERIC && ld.LightDef != GZGeneral.LightDef.VAVOOM_COLORED) //if it's gzdoom light { if (ld.LightModifier == GZGeneral.LightModifier.SECTOR) { if (t.Sector == null) { t.DetermineSector(); } int scaler = (t.Sector != null ? t.Sector.Brightness / 4 : 2); primaryradius = t.Args[3] * scaler; } else { primaryradius = t.Args[3] * 2; //works... that.. way in GZDoom if (ld.LightAnimated) { secondaryradius = t.Args[4] * 2; } } } else //it's one of vavoom lights { primaryradius = t.Args[0] * 8; } // Check radii... if (primaryradius < 1 && secondaryradius < 1) { return(null); } // Determine light color PixelColor color; if (highlight) { color = General.Colors.Highlight.WithAlpha((byte)linealpha); } else { switch (t.DynamicLightType.LightDef) { case GZGeneral.LightDef.VAVOOM_GENERIC: // Vavoom light color = new PixelColor((byte)linealpha, 255, 255, 255); break; case GZGeneral.LightDef.VAVOOM_COLORED: // Vavoom colored light color = new PixelColor((byte)linealpha, (byte)t.Args[1], (byte)t.Args[2], (byte)t.Args[3]); break; default: color = new PixelColor((byte)linealpha, (byte)t.Args[0], (byte)t.Args[1], (byte)t.Args[2]); break; } } // Add lines if visible List <Line3D> circles = new List <Line3D>(); if (primaryradius > 0) { circles.AddRange(MakeCircleLines(t.Position, color, primaryradius, CIRCLE_SIDES)); } if (secondaryradius > 0) { circles.AddRange(MakeCircleLines(t.Position, color, secondaryradius, CIRCLE_SIDES)); } return(circles); }
private static PixelColor getAverageColor(PixelColor[,] pixels, int x, int y) { int Blue = 0; Blue += pixels[x - 1, y - 1].Blue; Blue += pixels[x - 1, y].Blue; Blue += pixels[x - 1, y + 1].Blue; Blue += pixels[x, y - 1].Blue; Blue += pixels[x, y].Blue; Blue += pixels[x, y + 1].Blue; Blue += pixels[x + 1, y - 1].Blue; Blue += pixels[x + 1, y].Blue; Blue += pixels[x + 1, y + 1].Blue; int Red = 0; Red += pixels[x - 1, y - 1].Red; Red += pixels[x - 1, y].Red; Red += pixels[x - 1, y + 1].Red; Red += pixels[x, y - 1].Red; Red += pixels[x, y].Red; Red += pixels[x, y + 1].Red; Red += pixels[x + 1, y - 1].Red; Red += pixels[x + 1, y].Red; Red += pixels[x + 1, y + 1].Red; int Green = 0; Green += pixels[x - 1, y - 1].Green; Green += pixels[x - 1, y].Green; Green += pixels[x - 1, y + 1].Green; Green += pixels[x, y - 1].Green; Green += pixels[x, y].Green; Green += pixels[x, y + 1].Green; Green += pixels[x + 1, y - 1].Green; Green += pixels[x + 1, y].Green; Green += pixels[x + 1, y + 1].Green; Red = (int)((float)Red / 9); Green = (int)((float)Green / 9); Blue = (int)((float)Blue / 9); return new PixelColor((byte)Red, (byte)Green, (byte)Blue); }
private void SortPixel(byte v, PixelColor color) { int value = (int)v; if (shiftBytes != 0) { value = value >> shiftBytes; } switch (color) { case PixelColor.Red: red[value]++; break; case PixelColor.Blue: blue[value]++; break; case PixelColor.Green: green[value]++; break; } }