Beispiel #1
0
		/// <param name="opacity">how much to retain of the first palette (range 0-1)</param>
		public static Palette Merge(Palette A, Palette B, double opacity) {
			// make sure recalculate has been called on A and B,
			// and be sure not to call recalculate on this
			var p = new Palette();
			for (int i = 0; i < 256; i++)
				p.Colors[i] = Color.FromArgb(
					(int)(A.Colors[i].R * opacity + B.Colors[i].R * (1.0 - opacity)),
					(int)(A.Colors[i].G * opacity + B.Colors[i].G * (1.0 - opacity)),
					(int)(A.Colors[i].B * opacity + B.Colors[i].B * (1.0 - opacity)));
			return p;
		}
Beispiel #2
0
        public unsafe void Draw(ShpFile shp, GameObject obj, Drawable dr, DrawProperties props, DrawingSurface ds, int transLucency = 0)
        {
            shp.Initialize();
            Palette p          = props.PaletteOverride ?? obj.Palette;
            int     frameIndex = props.FrameDecider(obj);

            if (obj.Drawable.IsActualWall)
            {
                frameIndex = ((StructureObject)obj).WallBuildingFrame;
            }
            frameIndex = DecideFrameIndex(frameIndex, shp.NumImages);
            if (frameIndex >= shp.Images.Count)
            {
                return;
            }

            var img     = shp.GetImage(frameIndex);
            var imgData = img.GetImageData();

            if (imgData == null || img.Width * img.Height != imgData.Length)
            {
                return;
            }

            Point offset = props.GetOffset(obj);

            offset.X += obj.Tile.Dx * _config.TileWidth / 2 - shp.Width / 2 + img.X;
            offset.Y += (obj.Tile.Dy - obj.Tile.Z) * _config.TileHeight / 2 - shp.Height / 2 + img.Y;
            Logger.Trace("Drawing SHP file {0} (Frame {1}) at ({2},{3})", shp.FileName, frameIndex, offset.X, offset.Y);

            int stride       = ds.BitmapData.Stride;
            var heightBuffer = ds.GetHeightBuffer();
            var zBuffer      = ds.GetZBuffer();

            var   w_low  = (byte *)ds.BitmapData.Scan0;
            byte *w_high = (byte *)ds.BitmapData.Scan0 + stride * ds.BitmapData.Height;
            byte *w      = (byte *)ds.BitmapData.Scan0 + offset.X * 3 + stride * offset.Y;

            // clip to 25-50-75-100
            transLucency = (transLucency / 25) * 25;
            float a = transLucency / 100f;
            float b = 1 - a;

            int   rIdx    = 0;                              // image pixel index
            int   zIdx    = offset.X + offset.Y * ds.Width; // z-buffer pixel index
            short hBufVal = (short)(obj.Tile.Z * _config.TileHeight / 2);
            short zOffset = (short)((obj.BottomTile.Rx + obj.BottomTile.Ry) * _config.TileHeight / 2 + props.ZAdjust);

            if (!dr.Flat)
            {
                hBufVal += shp.Height;
            }

            for (int y = 0; y < img.Height; y++)
            {
                if (offset.Y + y < 0)
                {
                    w    += stride;
                    rIdx += img.Width;
                    zIdx += ds.Width;
                    continue;                     // out of bounds
                }

                for (int x = 0; x < img.Width; x++)
                {
                    byte paletteValue = imgData[rIdx];

                    short zshapeOffset = obj is StructureObject ? (GetBuildingZ(x, y, shp, img, obj)) : (short)0;

                    if (paletteValue != 0)
                    {
                        short zBufVal = zOffset;
                        if (dr.Flat)
                        {
                            zBufVal += (short)(y - img.Height);
                        }
                        else if (dr.IsBuildingPart)
                        {
                            // nonflat building
                            zBufVal += zshapeOffset;
                        }
                        else
                        {
                            zBufVal += img.Height;
                        }

                        if (w_low <= w && w < w_high /*&& zBufVal >= zBuffer[zIdx]*/)
                        {
                            if (transLucency != 0)
                            {
                                *(w + 0) = (byte)(a * *(w + 0) + b * p.Colors[paletteValue].B);
                                *(w + 1) = (byte)(a * *(w + 1) + b * p.Colors[paletteValue].G);
                                *(w + 2) = (byte)(a * *(w + 2) + b * p.Colors[paletteValue].R);
                            }
                            else
                            {
                                *(w + 0) = p.Colors[paletteValue].B;
                                *(w + 1) = p.Colors[paletteValue].G;
                                *(w + 2) = p.Colors[paletteValue].R;

                                //var pal = Theater.Active.GetPalettes().UnitPalette.Colors;
                                //*(w + 0) = pal[zshapeOffset].R;
                                //*(w + 1) = pal[zshapeOffset].G;
                                //*(w + 2) = pal[zshapeOffset].B;
                            }
                            zBuffer[zIdx]      = zBufVal;
                            heightBuffer[zIdx] = hBufVal;
                        }
                    }
                    //else {
                    //	*(w + 0) = 0;
                    //	*(w + 1) = 0;
                    //	*(w + 2) = 255;
                    //}

                    // Up to the next pixel
                    rIdx++;
                    zIdx++;
                    w += 3;
                }
                w    += stride - 3 * img.Width;
                zIdx += ds.Width - img.Width;
            }
        }
Beispiel #3
0
		public static Palette MakePalette(Color c) {
			// be sure not to call recalculate on this
			var p = new Palette();
			for (int i = 0; i < 256; i++)
				p.Colors[i] = c;
			p._originalColorsLoaded = true;
			return p;
		}
Beispiel #4
0
        unsafe public static void Draw(MapTile tile, TmpFile tmp, DrawingSurface ds)
        {
            tmp.Initialize();

            if (tile.SubTile >= tmp.Images.Count)
            {
                return;
            }
            TmpFile.TmpImage img = tmp.Images[tile.SubTile];
            var     zBuffer      = ds.GetZBuffer();
            var     heightBuffer = ds.GetHeightBuffer();
            Palette p            = tile.Palette;

            // calculate tile index -> pixel index
            Point offset = new Point(tile.Dx * tmp.BlockWidth / 2, (tile.Dy - tile.Z) * tmp.BlockHeight / 2);

            // make touched tiles (used for determining image cutoff)
            Point center         = offset + new Size(tmp.BlockWidth / 2, tmp.BlockHeight / 2);
            var   centerGridTile = tile.Layer.GetTileScreen(center, true, true);

            if (centerGridTile != null)
            {
                tile.Layer.GridTouched[centerGridTile.Dx, centerGridTile.Dy / 2]  |= TileLayer.TouchType.ByNormalData;
                tile.Layer.GridTouchedBy[centerGridTile.Dx, centerGridTile.Dy / 2] = tile;
            }

            Logger.Trace("Drawing TMP file {0} (subtile {1}) at ({2},{3})", tmp.FileName, tile.SubTile, offset.X, offset.Y);

            int stride = ds.BitmapData.Stride;

            int halfCx = tmp.BlockWidth / 2,
                halfCy = tmp.BlockHeight / 2;

            // writing bounds
            var   w_low  = (byte *)ds.BitmapData.Scan0;
            byte *w_high = (byte *)ds.BitmapData.Scan0 + stride * ds.BitmapData.Height;
            byte *w      = (byte *)ds.BitmapData.Scan0 + stride * offset.Y + (offset.X + halfCx - 2) * 3;

            int rIdx = 0, x, y = 0;
            int zIdx = offset.Y * ds.Width + offset.X + halfCx - 2;
            int cx   = 0;           // Amount of pixel to copy

            for (; y < halfCy; y++)
            {
                cx += 4;
                for (ushort c = 0; c < cx; c++)
                {
                    byte paletteValue = img.TileData[rIdx];

                    short zBufVal = (short)((tile.Rx + tile.Ry) * tmp.BlockHeight / 2 - (img.ZData != null ? img.ZData[rIdx] : 0));
                    if (paletteValue != 0 && w_low <= w && w < w_high && zBufVal >= zBuffer[zIdx])
                    {
                        *(w + 0)           = p.Colors[paletteValue].B;
                        *(w + 1)           = p.Colors[paletteValue].G;
                        *(w + 2)           = p.Colors[paletteValue].R;
                        zBuffer[zIdx]      = zBufVal;
                        heightBuffer[zIdx] = (short)(tile.Z * Drawable.TileHeight / 2);
                    }
                    w += 3;
                    zIdx++;
                    rIdx++;
                }
                w    += stride - 3 * (cx + 2);
                zIdx += ds.Width - (cx + 2);
            }

            w    += 12;
            zIdx += 4;
            for (; y < tmp.BlockHeight; y++)
            {
                cx -= 4;
                for (ushort c = 0; c < cx; c++)
                {
                    byte paletteValue = img.TileData[rIdx];

                    short zBufVal = (short)((tile.Rx + tile.Ry) * tmp.BlockHeight / 2 - (img.ZData != null ? img.ZData[rIdx] : 0));
                    if (paletteValue != 0 && w_low <= w && w < w_high && zBufVal >= zBuffer[zIdx])
                    {
                        *(w + 0)           = p.Colors[paletteValue].B;
                        *(w + 1)           = p.Colors[paletteValue].G;
                        *(w + 2)           = p.Colors[paletteValue].R;
                        zBuffer[zIdx]      = zBufVal;
                        heightBuffer[zIdx] = (short)(tile.Z * Drawable.TileHeight / 2);
                    }
                    w += 3;
                    zIdx++;
                    rIdx++;
                }
                w    += stride - 3 * (cx - 2);
                zIdx += ds.Width - (cx - 2);
            }

            if (!img.HasExtraData)
            {
                return;                                // we're done now
            }
            offset.X += img.ExtraX - img.X;
            offset.Y += img.ExtraY - img.Y;
            w         = w_low + stride * offset.Y + 3 * offset.X;
            zIdx      = offset.X + offset.Y * ds.Width;
            rIdx      = 0;

            // identify extra-data affected tiles for cutoff
            var extraScreenBounds = Rectangle.FromLTRB(
                Math.Max(0, offset.X), Math.Max(0, offset.Y),
                Math.Min(offset.X + img.ExtraWidth, ds.Width), Math.Min(offset.Y + img.ExtraHeight, ds.Height));

            for (int by = extraScreenBounds.Top; by < extraScreenBounds.Bottom; by += tmp.BlockHeight / 2)
            {
                for (int bx = extraScreenBounds.Left; bx < extraScreenBounds.Right; bx += tmp.BlockWidth / 2)
                {
                    var gridTileNoZ = tile.Layer.GetTileScreen(new Point(bx, by), true, true);
                    if (gridTileNoZ != null)
                    {
                        Logger.Trace("Tile at ({0},{1}) has extradata affecting ({2},{3})", tile.Dx, tile.Dy, gridTileNoZ.Dx,
                                     gridTileNoZ.Dy);
                        tile.Layer.GridTouched[gridTileNoZ.Dx, gridTileNoZ.Dy / 2]  |= TileLayer.TouchType.ByExtraData;
                        tile.Layer.GridTouchedBy[gridTileNoZ.Dx, gridTileNoZ.Dy / 2] = tile;
                    }
                }
            }

            // Extra graphics are just a square
            for (y = 0; y < img.ExtraHeight; y++)
            {
                for (x = 0; x < img.ExtraWidth; x++)
                {
                    // Checking per line is required because v needs to be checked every time
                    byte  paletteValue = img.ExtraData[rIdx];
                    short zBufVal      = (short)((tile.Rx + tile.Ry) * tmp.BlockHeight / 2 + (img.ExtraZData != null ? img.ExtraZData[rIdx] : 0));

                    if (paletteValue != 0 && w_low <= w && w < w_high && zBufVal >= zBuffer[zIdx])
                    {
                        *w++ = p.Colors[paletteValue].B;
                        *w++ = p.Colors[paletteValue].G;
                        *w++ = p.Colors[paletteValue].R;
                        zBuffer[zIdx]      = zBufVal;
                        heightBuffer[zIdx] = (short)(img.ExtraHeight - y + tile.Z * Drawable.TileHeight / 2);
                    }
                    else
                    {
                        w += 3;
                    }
                    zIdx++;
                    rIdx++;
                }
                w    += stride - img.ExtraWidth * 3;
                zIdx += ds.Width - img.ExtraWidth;
            }
        }