private AnimDrawable LoadExtraImage(string extraImage, DrawProperties inheritProps) { string animSection = Art.ReadString(extraImage); if (animSection == "") { return(null); } IniFile.IniSection extraRules = OwnerCollection.Rules.GetOrCreateSection(animSection); IniFile.IniSection extraArt = OwnerCollection.Art.GetOrCreateSection(animSection); var anim = new AnimDrawable(extraRules, extraArt); anim.OwnerCollection = OwnerCollection; anim.LoadFromRules(); anim.NewTheater = this.NewTheater; if (extraArt.HasKey("YSortAdjust") || Art.HasKey(extraImage + "YSort") || extraArt.HasKey("ZAdjust") || Art.HasKey(extraImage + "ZAdjust")) { anim.Props.SortIndex = extraArt.ReadInt("YSortAdjust", Art.ReadInt(extraImage + "YSort")) - extraArt.ReadInt("ZAdjust", Art.ReadInt(extraImage + "ZAdjust")); } else { anim.Props.SortIndex = inheritProps.SortIndex; } if (Art.HasKey(extraImage + "X") || Art.HasKey(extraImage + "Y")) { anim.Props.Offset = this.Props.Offset + new Size(Art.ReadInt(extraImage + "X"), Art.ReadInt(extraImage + "Y")); } else { anim.Props.Offset = inheritProps.Offset; } anim.Props.ZAdjust = Art.ReadInt(extraImage + "ZAdjust"); anim.IsBuildingPart = true; anim.Shp = VFS.Open <ShpFile>(anim.GetFilename()); return(anim); }
private void LoadOverlayDrawable(Drawable drawable) { int objIdx = _drawables.Count - 1; var ovl = new OverlayObject((byte)objIdx, 0); var tibType = SpecialOverlays.GetOverlayTibType(ovl, Engine); DrawProperties props = drawable.Props; if (Engine >= EngineType.RedAlert2) { if (tibType != OverlayTibType.NotSpecial) { props.FrameDecider = FrameDeciders.OverlayValueFrameDecider; props.PaletteType = PaletteType.Overlay; props.LightingType = LightingType.None; } else if (SpecialOverlays.IsHighBridge(ovl)) { props.OffsetHack = OffsetHacks.RA2BridgeOffsets; props.ShadowOffsetHack = OffsetHacks.RA2BridgeShadowOffsets; drawable.TileElevation = 4; // for lighting drawable.Foundation = new Size(3, 1); // ensures they're drawn later --> fixes overlap } } else if (Engine <= EngineType.Firestorm) { if (tibType != OverlayTibType.NotSpecial) { props.FrameDecider = FrameDeciders.OverlayValueFrameDecider; props.PaletteType = PaletteType.Unit; props.LightingType = LightingType.None; drawable.IsRemapable = true; } else if (SpecialOverlays.IsHighBridge(ovl) || SpecialOverlays.IsTSHighRailsBridge(ovl)) { props.OffsetHack = OffsetHacks.TSBridgeOffsets; props.ShadowOffsetHack = OffsetHacks.TSBridgeShadowOffsets; drawable.TileElevation = 4; // for lighting //drawable.Foundation = new Size(3, 1); // ensures they're drawn later --> fixes overlap } } }
private unsafe void BlitVoxelToSurface(DrawingSurface ds, DrawingSurface vxl_ds, GameObject obj, DrawProperties props, int transLucency = 0) { Point d = new Point(obj.Tile.Dx * TileWidth / 2, (obj.Tile.Dy - obj.Tile.Z) * TileHeight / 2); d.Offset(props.GetOffset(obj)); d.Offset(-vxl_ds.BitmapData.Width / 2, -vxl_ds.BitmapData.Height / 2); // rows inverted! var w_low = (byte *)ds.BitmapData.Scan0; byte *w_high = w_low + ds.BitmapData.Stride * ds.BitmapData.Height; var zBuffer = ds.GetZBuffer(); var shadowBufVxl = vxl_ds.GetShadows(); var shadowBuf = ds.GetShadows(); // int rowsTouched = 0; // clip to 25-50-75-100 transLucency = transLucency / 25 * 25; float a = transLucency / 100f; float b = 1 - a; // short firstRowTouched = short.MaxValue; for (int y = 0; y < vxl_ds.Height; y++) { byte *src_row = (byte *)vxl_ds.BitmapData.Scan0 + vxl_ds.BitmapData.Stride * (vxl_ds.Height - y - 1); byte *dst_row = ((byte *)ds.BitmapData.Scan0 + (d.Y + y) * ds.BitmapData.Stride + d.X * 3); int zIdx = (d.Y + y) * ds.Width + d.X; if (dst_row < w_low || dst_row >= w_high) { continue; } for (int x = 0; x < vxl_ds.Width; x++) { // only non-transparent pixels if (*(src_row + x * 4 + 3) > 0) { if (transLucency != 0) { *(dst_row + x * 3) = (byte)(a * *(dst_row + x * 3) + b * *(src_row + x * 4)); *(dst_row + x * 3 + 1) = (byte)(a * *(dst_row + x * 3 + 1) + b * *(src_row + x * 4 + 1)); *(dst_row + x * 3 + 2) = (byte)(a * *(dst_row + x * 3 + 2) + b * *(src_row + x * 4 + 2)); } else { *(dst_row + x * 3) = *(src_row + x * 4); *(dst_row + x * 3 + 1) = *(src_row + x * 4 + 1); *(dst_row + x * 3 + 2) = *(src_row + x * 4 + 2); } // if (y < firstRowTouched) // firstRowTouched = (short)y; short zBufVal = (short)((obj.Tile.Rx + obj.Tile.Ry + obj.Tile.Z) * TileHeight / 2); if (zBufVal >= zBuffer[zIdx]) { zBuffer[zIdx] = zBufVal; } } // or shadows else if (shadowBufVxl[x + y * vxl_ds.Height]) { int shadIdx = (d.Y + y) * ds.Width + d.X + x; if (!shadowBuf[shadIdx]) { *(dst_row + x * 3) /= 2; *(dst_row + x * 3 + 1) /= 2; *(dst_row + x * 3 + 2) /= 2; shadowBuf[shadIdx] = true; } } zIdx++; } } }
private unsafe void BlitVoxelToSurface(DrawingSurface ds, DrawingSurface vxl_ds, GameObject obj, DrawProperties props) { Point d = new Point(obj.Tile.Dx * TileWidth / 2, (obj.Tile.Dy - obj.Tile.Z) * TileHeight / 2); d.Offset(props.GetOffset(obj)); d.Offset(-vxl_ds.BitmapData.Width / 2, -vxl_ds.BitmapData.Height / 2); // rows inverted! var w_low = (byte *)ds.BitmapData.Scan0; byte *w_high = w_low + ds.BitmapData.Stride * ds.BitmapData.Height; var zBuffer = ds.GetZBuffer(); // int rowsTouched = 0; // short firstRowTouched = short.MaxValue; for (int y = 0; y < vxl_ds.Height; y++) { byte *src_row = (byte *)vxl_ds.BitmapData.Scan0 + vxl_ds.BitmapData.Stride * (vxl_ds.Height - y - 1); byte *dst_row = ((byte *)ds.BitmapData.Scan0 + (d.Y + y) * ds.BitmapData.Stride + d.X * 3); int zIdx = (d.Y + y) * ds.Width + d.X; if (dst_row < w_low || dst_row >= w_high) { continue; } for (int x = 0; x < vxl_ds.Width; x++) { // only non-transparent pixels if (*(src_row + x * 4 + 3) > 0) { *(dst_row + x * 3) = *(src_row + x * 4); *(dst_row + x * 3 + 1) = *(src_row + x * 4 + 1); *(dst_row + x * 3 + 2) = *(src_row + x * 4 + 2); // if (y < firstRowTouched) // firstRowTouched = (short)y; short zBufVal = (short)((obj.Tile.Rx + obj.Tile.Ry + obj.Tile.Z) * TileHeight / 2); if (zBufVal >= zBuffer[zIdx]) { zBuffer[zIdx] = zBufVal; } } zIdx++; } } }