The Cardinal Codez

Sunday, June 10, 2007

Paradigms of code #1


Paradigms of good and efficient code design:

Only write error-checking when the compiler ain't doing it for you:


        /// <summary>
        /// Cuts out a selected portion of Frames and returns them.
        /// </summary>
        /// <param name="start">The zero-based index of the Frames to remove.</param>
        /// <param name="count">The number of Frames to remove.</param>
        /// <returns>The cut-out portion of Frames.</returns>
        public Frame[] Splice(int start, int count)
        {
            Frame[] ret = new Frame[count];
            for(int i=0; i<count; i++)
                ret[i] = frames[i];
            frames.RemoveRange(start, count);
            return ret;
        }



Obviously, an Exception [aka Error] could occur, namely an Out-Of-Bounds Exception, since I didn't check to make sure there actually was that many amount of frames after the starting index.. But there's no need to implement your own Exception handling here, since the compiler's error checking does the job; implementing your own Exception handling just slows down your code unneccessarily, it's like redundancy checking.

Unlike the code below. Alpha values should be positive, and between 0 to 255. Setting any different will corrupt your image data, or just result in glitches that runs just fine, except that, well, it isn't a game anymore. Like seeing your character walk through walls or something. [ wait, that's an exploit/hack then. =P ]



        /// <summary>Opacity of the Scene.</summary>
        public int Alpha
        {
            get
            {
                return alpha;
            }
            set
            {
                if(value<0)
                    throw new ArgumentException("Alpha cannot be less than zero!");
                value %= 255; //not the best option here, but ....
                if(this.alpha != value)
                {
                    this.alpha = value;
                    for(int i=0; i<frames.Count; i++)
                        frames[i].Alpha = value;
                }
            }
        }




If you're wondered why I didn't check for positive values, it's here, further further down the procedural chain. That all [150 lines of code] just for changing opacity. XD



        /// <summary>
        /// Creates a new Bitmap with a new opacity value, whilst preserving transparency. A pretty
        /// laggy function.
        /// </summary>
        /// <param name="bmp">A Bitmap.</param>
        /// <param name="alphaPercent">The alpha percentage, from 0-100.</param>
        /// <param name="alphaChannel">A Bitmap, of the same dimensions as <paramref name="text"/> to use
        /// as the alpha channel. <paramref name="alphaPercent" /> will be calculated based on this new
        /// alpha channel.</param>
        /// <returns>The new Bitmap.</returns>
        /// <remarks>If you want to preserve transparency, keep the original Bitmap and use it as the
        /// <paramref name="alphaChannel" /> next time you need to change the opacity
        /// of the image again.</remarks>
        public static Bitmap ChangeAlpha(Bitmap bmp, int alphaPercent, Bitmap alphaChannel)
        {
            Argument0to100(alphaPercent);
            if(!alphaChannel.Size.Equals(alphaChannel.Size))
                throw new ArgumentException("The dimensions of alpha channel does not match the input bitmap.");
            
            Bitmap newBmp = new Bitmap(bmp);
            int w = bmp.Width;
            int h = bmp.Height;
            WinColor[,] channelColor = IrrBitmap.Retrieve(alphaChannel);
            byte _temp;
            
            BitmapData bmpData = newBmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            int stride = bmpData.Stride;
            System.IntPtr Scan0 = bmpData.Scan0;
            unsafe
            {
                byte* p = (byte*)(void*)Scan0;
                int offset = stride - w * 4;
                for (int y = 0; y < h; ++y)
                {
                    for (int x = 0; x < w; ++x)
                    {
                        _temp = channelColor[x,y].A;
                        p[3] = (byte)(_temp*alphaPercent/100);
                        
                        p += 4;
                    }
                    p += offset;
                }
            }
            newBmp.UnlockBits(bmpData);
            return newBmp;
        }





Gash is on crack.
Konjiki no Gash Bell rocks!! Don't say it ain't.


1. Konjiki no Gash Bell OP3 [Mienai Tsubasa] - Tanimoto Takayashi
2. Bad Day - David Powter
3. Bleach OP6 [Alones] - Aqua Timerz

No comments: