Example #1
0
        protected override unsafe void DrawSubOverlay(SubOverlay.RenderInfo RenderInfo)
        {
            // todo: negative positions not supported by method below
            if (RenderInfo.Origin.X < 0.0f ||
                RenderInfo.Origin.Y < 0.0f)
            {
                return;
            }

            RenderInfo.Bgf.FillPixelDataAsA8R8G8B8TransparencyBlackScaled(
                (uint *)pixelData.Scan0.ToPointer(),
                (uint)Image.Width, (uint)Image.Height,
                Convert.ToUInt32(RenderInfo.Origin.X),
                Convert.ToUInt32(RenderInfo.Origin.Y),
                Convert.ToUInt32(RenderInfo.Size.X),
                Convert.ToUInt32(RenderInfo.Size.Y),
                RenderInfo.SubOverlay.ColorTranslation);
        }
Example #2
0
        protected override void DrawSubOverlay(SubOverlay.RenderInfo RenderInfo)
        {
            // copy from this rectangle in source
            Rectangle fromRectangle = new Rectangle(0, 0, (int)RenderInfo.Bgf.Width, (int)RenderInfo.Bgf.Height);

            // copy to this rectangle in destination
            Rectangle toRectangle = new Rectangle(
                Convert.ToInt32(RenderInfo.Origin.X),
                Convert.ToInt32(RenderInfo.Origin.Y),
                Convert.ToInt32(RenderInfo.Size.X),
                Convert.ToInt32(RenderInfo.Size.Y));

            // get subimage to draw
            Bitmap bmp = RenderInfo.Bgf.GetBitmap(RenderInfo.SubOverlay.ColorTranslation);

            // draw
            drawTo.DrawImage(bmp, toRectangle, fromRectangle, GraphicsUnit.Pixel);

            // dispose subimage
            bmp.Dispose();
        }
 /// <summary>
 /// Override with code drawing suboverlays
 /// </summary>
 /// <param name="RenderInfo"></param>
 protected abstract void DrawSubOverlay(SubOverlay.RenderInfo RenderInfo);
        protected void Calculate(
            ObjectBase Data,
            BgfBitmap MainFrame,
            bool UseViewerFrame   = true,
            bool ApplyYOffset     = true,
            byte RootHotspotIndex = 0,
            Real Quality          = DEFAULTQUALITY,
            bool ScalePow2        = false,
            uint Width            = 0,
            uint Height           = 0,
            bool CenterVertical   = false,
            bool CenterHorizontal = false,
            bool IsCustomShrink   = false,
            Real CustomShrink     = 1.0f)
        {
            BgfBitmap        mainFrame    = MainFrame;
            BgfFile          mainResource = Data.Resource;
            byte             mainColor    = Data.ColorTranslation;
            BgfBitmap        subOvFrame;
            BgfBitmapHotspot subOvHotspot;
            SubOverlay       subOvParent;
            BgfBitmap        subOvParentFrame;
            BgfBitmapHotspot subOvParentHotspot;
            bool             rootSpotFound = false;

            // use custom compose root (suboverlay=mainoverlay)
            // if it's not found, fallback to full compose
            if (RootHotspotIndex > 0)
            {
                SubOverlay subOv = Data.GetSubOverlayByHotspot(RootHotspotIndex);

                if (subOv != null)
                {
                    rootSpotFound = true;

                    if (UseViewerFrame)
                    {
                        mainFrame = subOv.ViewerFrame;
                    }
                    else
                    {
                        mainFrame = subOv.FrontFrame;
                    }

                    mainResource = subOv.Resource;
                    mainColor    = subOv.ColorTranslation;
                }
            }

            if (mainFrame != null && mainResource != null)
            {
                Bgf       = mainFrame;
                BgfColor  = mainColor;
                size.X    = (Real)mainFrame.Width / (Real)mainResource.ShrinkFactor;
                size.Y    = (Real)mainFrame.Height / (Real)mainResource.ShrinkFactor;
                origin.X  = (Real)mainFrame.XOffset / (Real)mainResource.ShrinkFactor;
                origin.Y  = (Real)mainFrame.YOffset / (Real)mainResource.ShrinkFactor;
                MaxShrink = mainResource.ShrinkFactor;

                // used to calculate the boundingbox
                V2 min = new V2(Origin.X, Origin.Y);
                V2 max = new V2(Size.X, Size.Y);
                if (ApplyYOffset)
                {
                    if (origin.X > 0.0f)
                    {
                        max.X += origin.X;
                    }
                    if (origin.Y > 0.0f)
                    {
                        max.Y += origin.Y;
                    }
                }
                else
                {
                    max += origin;
                }

                Real x, y;

                // walk suboverlay structure
                foreach (SubOverlay subOv in Data.CurrentSubOverlays)
                {
                    if (UseViewerFrame)
                    {
                        subOvFrame   = subOv.ViewerFrame;
                        subOvHotspot = subOv.ViewerHotspot;
                        subOvParent  = subOv.ViewerParent;
                    }
                    else
                    {
                        subOvFrame   = subOv.FrontFrame;
                        subOvHotspot = subOv.FrontHotspot;
                        subOvParent  = subOv.FrontParent;
                    }

                    bool isSubRoot = (subOvParent != null && subOvParent.HotSpot == RootHotspotIndex);

                    if (subOv.Resource != null &&
                        subOvFrame != null &&
                        subOvHotspot != null &&
                        (RootHotspotIndex <= 0 || !rootSpotFound || isSubRoot))
                    {
                        SubOverlay.RenderInfo subOvInfo = new SubOverlay.RenderInfo();

                        // save subov & bitmap
                        subOvInfo.SubOverlay = subOv;
                        subOvInfo.Bgf        = subOvFrame;

                        // calculate the size of this suboverlay
                        subOvInfo.Size.X = (Real)subOvFrame.Width / (Real)subOv.Resource.ShrinkFactor;
                        subOvInfo.Size.Y = (Real)subOvFrame.Height / (Real)subOv.Resource.ShrinkFactor;

                        // update maxshrink if greater
                        if (subOv.Resource.ShrinkFactor > MaxShrink)
                        {
                            MaxShrink = subOv.Resource.ShrinkFactor;
                        }

                        // CASE 1: SubOverlay on mainoverlay
                        if (subOvParent == null || isSubRoot)
                        {
                            // calculate the origin of this suboverlay on the mainoverlay
                            subOvInfo.Origin.X = mainFrame.XOffset
                                                 + ((Real)subOvHotspot.X)
                                                 + ((Real)subOvFrame.XOffset);

                            subOvInfo.Origin.Y = mainFrame.YOffset
                                                 + ((Real)subOvHotspot.Y)
                                                 + ((Real)subOvFrame.YOffset);

                            subOvInfo.Origin.X /= mainResource.ShrinkFactor;
                            subOvInfo.Origin.Y /= mainResource.ShrinkFactor;

                            // determine type of hotspot
                            if (subOvHotspot.Index < 0)
                            {
                                subOvInfo.HotspotType = HotSpotType.HOTSPOT_UNDER;
                            }
                            else
                            {
                                subOvInfo.HotspotType = HotSpotType.HOTSPOT_OVER;
                            }
                        }

                        // CASE 2: SubOverlay on SubOverlay on MainOverlay
                        else
                        {
                            if (UseViewerFrame)
                            {
                                subOvParentFrame   = subOvParent.ViewerFrame;
                                subOvParentHotspot = subOvParent.ViewerHotspot;
                            }
                            else
                            {
                                subOvParentFrame   = subOvParent.FrontFrame;
                                subOvParentHotspot = subOvParent.FrontHotspot;
                            }

                            if (subOvParentHotspot != null &&
                                subOvParentFrame != null &&
                                subOvParent.Resource != null)
                            {
                                // calculate the origin of this suboverlay on the suboverlay on the mainoverlay
                                subOvInfo.Origin.X =
                                    (mainFrame.XOffset +
                                     (Real)subOvParentHotspot.X +
                                     (Real)subOvParentFrame.XOffset) / (Real)mainResource.ShrinkFactor;

                                subOvInfo.Origin.X +=
                                    ((Real)subOvHotspot.X +
                                     (Real)subOvFrame.XOffset) / (Real)subOvParent.Resource.ShrinkFactor;

                                subOvInfo.Origin.Y =
                                    (mainFrame.YOffset +
                                     (Real)subOvParentHotspot.Y +
                                     (Real)subOvParentFrame.YOffset) / (Real)mainResource.ShrinkFactor;

                                subOvInfo.Origin.Y +=
                                    ((Real)subOvHotspot.Y +
                                     (Real)subOvFrame.YOffset) / (Real)subOvParent.Resource.ShrinkFactor;

                                // determine type of nested hotspot
                                if (subOvParentHotspot.Index > 0 && subOvHotspot.Index > 0)
                                {
                                    subOvInfo.HotspotType = HotSpotType.HOTSPOT_OVEROVER;
                                }

                                else if (subOvParentHotspot.Index > 0 && subOvHotspot.Index < 0)
                                {
                                    subOvInfo.HotspotType = HotSpotType.HOTSPOT_OVERUNDER;
                                }

                                else if (subOvParentHotspot.Index < 0 && subOvHotspot.Index > 0)
                                {
                                    subOvInfo.HotspotType = HotSpotType.HOTSPOT_UNDEROVER;
                                }

                                else if (subOvParentHotspot.Index < 0 && subOvHotspot.Index < 0)
                                {
                                    subOvInfo.HotspotType = HotSpotType.HOTSPOT_UNDERUNDER;
                                }
                            }
                        }

                        // update max boundingbox
                        if (subOvInfo.Origin.X < min.X)
                        {
                            min.X = subOvInfo.Origin.X;
                        }

                        if (subOvInfo.Origin.Y < min.Y)
                        {
                            min.Y = subOvInfo.Origin.Y;
                        }

                        x = subOvInfo.Origin.X + subOvInfo.Size.X;
                        y = subOvInfo.Origin.Y + subOvInfo.Size.Y;

                        if (x > max.X)
                        {
                            max.X = x;
                        }

                        if (y > max.Y)
                        {
                            max.Y = y;
                        }

                        // save info for this suboverlay
                        SubBgf.Add(subOvInfo);
                    }
                }

                // get dimension from boundingbox
                dimension.X = Math.Abs(max.X - min.X);
                dimension.Y = Math.Abs(max.Y - min.Y);

                // move all origins so minimum hits 0/0
                // preparation for drawing (pixel origin is 0/0)
                Translate(-min);

                // get the center of the dimension box
                // this is also the center of our image after the translate above
                V2 bbCenter = dimension * 0.5f;

                // get the center of the main overlay
                V2 mainOriginCenter = Origin + (Size * 0.5f);

                // move the x center of the main overlay to the x center of dimensionbox
                V2 centerMove = new V2(bbCenter.X - mainOriginCenter.X, 0.0f);
                Translate(centerMove);

                // since this moves a part outside the dimension box
                // we need to add this size of the move to the dimension,
                // to the right AND left side, so our centering above stays centered
                // then we remove to the center.
                V2 center = new V2(Math.Abs(centerMove.X), 0.0f);
                dimension.X += center.X * 2.0f;
                Translate(center);

                // scale so highest resolution resource has 1:1 ratio (no downscale)
                // or to user provided shrink value
                Scale(IsCustomShrink ? CustomShrink : (Real)MaxShrink);

                // user defined sizes
                if (Width > 0 && Height > 0)
                {
                    // use user given size
                    V2 userSize = new V2(Width, Height);

                    // scale so we use at least all pixels either from upscaled width or height
                    ScaleToBox(userSize, CenterHorizontal, CenterVertical, !IsCustomShrink);
                }
                else
                {
                    Real maxQuality = Quality * QUALITYBASE;
                    Real ratioX     = maxQuality / dimension.X;
                    Real ratioY     = maxQuality / dimension.Y;

                    if (ratioX <= ratioY && ratioX < 1.0f)
                    {
                        Scale(ratioX);
                    }
                    else if (ratioX > ratioY && ratioY < 1.0f)
                    {
                        Scale(ratioY);
                    }

                    // scale up to pow2 if set
                    if (ScalePow2)
                    {
                        // get next power of 2 size
                        V2 pow2Size = new V2(
                            MathUtil.NextPowerOf2((uint)System.Math.Ceiling(dimension.X)),
                            MathUtil.NextPowerOf2((uint)System.Math.Ceiling(dimension.Y)));

                        // scale so we use at least all pixels either from upscaled width or height
                        ScaleToBox(pow2Size, CenterHorizontal, CenterVertical, !IsCustomShrink);
                    }
                }

                // calculate the world-size (shrink=1) of the composed object from dimension, uv-coordinates and scaling
                worldsize.X = (uvend.X * dimension.X) / Scaling;
                worldsize.Y = (uvend.Y * dimension.Y) / Scaling;
            }
        }