Gigi Labs

Please follow Gigi Labs for the latest articles.

Sunday, March 16, 2014

C: Rock, Scissors, Paper (using random numbers)

Hello everyone, and welcome back to the Ranch! :)

In my last C article, "C: Calculating the Average of Several Numbers", we learned how to work with numbers in C. This included using integer variables, input/output of integers, and arithmetic operations.

Today, we're going to take this further and learn how to generate random numbers in C. We'll use this to write a little Rock, Scissors, Paper game.

Pseudo-random numbers in C


So let's start off with a pretty empty program:

#include <stdio.h>

int main(int argc, char ** argv)
{
    return 0;
}

We can generate a random integer using the rand() function, which is defined in stdlib.h. This gives us a random number between 0 and a constant integer called RAND_MAX. We can output the value of RAND_MAX as we would any other integer, although its value is not guaranteed to be the same across different computers:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char ** argv)
{
    int a = rand();
    int b = rand();
    int c = rand();

    printf("RAND_MAX is: %d\n", RAND_MAX);
    printf("a is: %d\n", a);
    printf("b is: %d\n", b);
    printf("c is: %d\n", c);

    return 0;
}

Let us now run this program a few times and see what happens:


On my computer, RAND_MAX is defined as 2147483647, so each time I call rand(), it will give me a random number between 0 and 2147483647.

Another thing you'll see from the output is that each time I run the program, I get the same values for a, b and c. That isn't quite random, is it?

The reason why this is happening is that these random numbers aren't really random.  They are actually generated from a mathematical sequence, that takes a very, very long time to begin repeating itself, but which isn't truly random. These are called pseudo-random numbers. Imagine this sequence:

4, 29, 55, 12, 4, 7, 3, 97, 84, ...

This sequence seems pretty random; there isn't any pattern in it. So each time we get a random number with rand(), we'll get a different number: first 4, then 29, then 55, etc.

Our problem is that each time we run the program, we're starting from the beginning of the sequence, and this gives us the same values. So what we want to do is start from a different position each time.

We do this by seeding the pseudo-random number generator using the srand() function. Let's just add this line at the beginning of main():

    srand(100);

Let's run the program again:


You'll notice the numbers have changed, since we're using a different seed. However, each time we run the program, the same numbers are repeated. In fact we are still making the same mistake as before: we are using the same seed, and starting the pseudo-random number sequence from the same point each time.

In order to use a different seed each time we run the program, we can use the current time as the seed. We can use the time() function, defined in time.h, to give us the current time. So let's include that header file at the top...

#include <time.h>

...and replace our call to srand() with this:

srand(time(NULL));

When we run the program, things work as we expect, and we get different pseudorandom numbers each time we run:


Scaling random numbers


Great. Now, the numbers we are generating are a little bit big. For example, for Rock, Scissors, Paper, we don't need a number between 0 and 2147483647; all we need is a number between 1 and 3 (both inclusive), to represent either rock, scissors, or paper. We can limit the range of a pseudorandom number by dividing it by the maximum we want, and extracting the remainder. This is done using the modulus (%) operator, which gives us the remainder of a division:

    int a = rand() % 10;
    int b = rand() % 10;
    int c = rand() % 10;

Let's say rand() gives us 55. If we divide 55 by 10, then the remainder can be at most 9. So what we're doing above is limiting each random number to the range 0 to 9 (both inclusive). We'll need to add 1 to the number by which we're dividing, in order to make it inclusive (i.e. between 0 and 10 in this case).

What if we need a minimum value that is not zero? In short, we declare a general-purpose function that returns random integers between two integers (both inclusive) like this:

// returns a random number between min and max, both inclusive)
int randomInt(int min, int max)
{
    return min + (rand() % (max - min + 1));
}

We can then use this function from within our main() like this, to give us random numbers between 1 and 10:

    int a = randomInt(1, 10);
    int b = randomInt(1, 10);
    int c = randomInt(1, 10);

And voilĂ :


Rock, Scissors, Paper in C


OK, so now that we know how to generate pseudorandom numbers, we can write out game of Rock, Scissors, Paper. In this game, two people independently choose one of rock, scissors or paper, and state their choice at the same time. The outcome is then as follows:

  • Rock beats scissors (breaks it).
  • Scissors beats paper (cuts it).
  • Paper beats rock (wraps it).

To start off, let's throw away all our code in main(), but keep our randomInt() function:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// returns a random number between min and max, both inclusive)
int randomInt(int min, int max)
{
    return min + (rand() % (max - min + 1));
}

int main(int argc, char ** argv)
{
    // code goes here

    return 0;
}

First, we add code to accept user input:

    int input = -1;

    while (input != 0)
    {
        printf("Choose...\n");
        printf("   1 for rock\n");
        printf("   2 for scissors\n");
        printf("   3 for paper\n");
        printf("or 0 to exit\n");

        scanf("%d", &input);
    }

The user will choose a number between 1 and 3 to represent rock, scissors, or paper respectively. A while loop repeats the game until the user enters 0 to exit the game. We have already used for loops in C: Calculating the Average of Several Numbers, but a while loop will simply keep executing the code within curly brackets as long as the condition within round brackets is true, in this case as long as input is not zero:


Once the human player has chosen, the computer player makes his choice at random:

       int computerChoice = randomInt(1, 3);

We can then display the computer's choice:

       switch(computerChoice)
       {
           case 1: printf("Computer chooses rock\n"); break;
           case 2: printf("Computer chooses scissors\n"); break;
           case 3: printf("Computer chooses paper\n"); break;
       }

A switch statement allows us to specify separate code to be executed depending on the value of a variable. In this case, if computerChoice is 1, we write that the computer has chosen rock, and similarly for the other choices. Note that each case in a switch statement should always end in a break statement; otherwise unexpected things may happen. :)

Finally, we can add the game logic to check who won:

       if (input == computerChoice)
       {
           printf("Game ends in a draw.\n");
       }
       else if (input == 1 && computerChoice == 2)
       {
          printf("Rock beats scissors! You win!\n");
       }
       else if (input == 2 && computerChoice == 3)
       {
          printf("Scissors beats paper! You win!\n");
       }
       else if (input == 3 && computerChoice == 1)
       {
          printf("Paper beats rock! You win!\n");
       }
       else if (computerChoice == 1 && input == 2)
       {
          printf("Rock beats scissors! Computer wins!\n");
       }
       else if (computerChoice == 2 && input == 3)
       {
          printf("Scissors beats paper! Computer wins!\n");
       }
       else if (computerChoice == 3 && input == 1)
       {
          printf("Paper beats rock! Computer wins!\n");
       }

Using a cascade of if statements, we compare the user input with the computer's random choice and see who won. The == operator allows us to compare two integers and determine whether they are equal. The && operator, on the other hand, is a boolean AND operator. If both conditions around the && operator are true, then the printf() statement within the curly brackets of that if statement is executed.

We can now actually play our game:


Summary


Great! :) We have a fully working Rock, Scissors, Paper game here. And in creating it, we learned about pseudo-random numbers, while loops, if statements, switch statements, and also a few operators including == (is equal to), != (is not equal to) and && (boolean AND). Below is the full code.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// returns a random number between min and max, both inclusive)
int randomInt(int min, int max)
{
    return min + (rand() % (max - min + 1));
}

int main(int argc, char ** argv)
{
    int input = -1;

    while (input != 0)
    {
        printf("Choose...\n");
        printf("   1 for rock\n");
        printf("   2 for scissors\n");
        printf("   3 for paper\n");
        printf("or 0 to exit\n");

        scanf("%d", &input);

       int computerChoice = randomInt(1, 3);

       switch(computerChoice)
       {
           case 1: printf("Computer chooses rock\n"); break;
           case 2: printf("Computer chooses scissors\n"); break;
           case 3: printf("Computer chooses paper\n"); break;
       }

       if (input == computerChoice)
       {
           printf("Game ends in a draw.\n");
       }
       else if (input == 1 && computerChoice == 2)
       {
          printf("Rock beats scissors! You win!\n");
       }
       else if (input == 2 && computerChoice == 3)
       {
          printf("Scissors beats paper! You win!\n");
       }
       else if (input == 3 && computerChoice == 1)
       {
          printf("Paper beats rock! You win!\n");
       }
       else if (computerChoice == 1 && input == 2)
       {
          printf("Rock beats scissors! Computer wins!\n");
       }
       else if (computerChoice == 2 && input == 3)
       {
          printf("Scissors beats paper! Computer wins!\n");
       }
       else if (computerChoice == 3 && input == 1)
       {
          printf("Paper beats rock! Computer wins!\n");
       }
    }

    return 0;
}

Friday, March 14, 2014

C#: Authenticating with Active Directory

Hi! :)

If you work in a corporate environment, chances are that your Windows machine is connected to a domain based on Active Directory. In today's article, we're going to write a very simple program that allows us to verify a user's credentials for the domain using Active Directory.

In order to try this out, you're going to need an Active Directory domain. In my case, I installed Windows Server 2008 R2 and followed these instructions to set up a domain, which I called "ranch.local". You may also be able to connect to your domain at work to save yourself the trouble of setting this up.

Let us now create a new Console Application using either SharpDevelop or Visual Studio. After adding a reference to System.DirectoryServices.AccountManagement, add the following statement near the top of your Program.cs file:

using System.DirectoryServices.AccountManagement;

Next, remove any code in Main() and add a simple prompt for the username and password to authenticate against Active Directory:

            // prompt for username

            Console.Write("Username: ");
            string username = Console.ReadLine();

            // prompt for password

            Console.Write("Password: ");
            string password = Console.ReadLine();

For the authentication part, we can use a simple method described here. After obtaining a reference to the domain using the PrincipalContext class (specifying the domain as a parameter), we simply use the ValidateCredentials() method to perform the authentication. This gives us a boolean value indicating whether the authentication was successful or not.

            // authenticate

            using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "RANCH"))
            {
                bool authenticated = pc.ValidateCredentials(username, password);

                if (authenticated)
                    Console.WriteLine("Authenticated");
                else
                    Console.WriteLine("Get lost.");
            }

At this point, we need only add a simple statement to wait for user input before letting the application terminate:

            Console.ReadLine();

Now, we can build our application and test it on the server (or on any machine that is part of the domain). First, let's try a valid login:


Very good! And now, a user that doesn't even exist:


Excellent! As you can see, it only takes a couple of lines of code to perform authentication against Active Directory. I hope you found this useful. Follow the Ranch to read more articles like this! :)

Saturday, February 22, 2014

SDL2: Converting an Image to Grayscale

Hello folks! :)

[Update 2015-11-14: This article is out of date. Check out the latest version at Gigi Labs.]

In the previous article, "SDL2: Pixel Drawing", we saw how to draw pixels onto a blank texture that we created in code. Today, on the other hand, we'll see how we can manipulate pixels on an existing image, such as a photo we loaded from disk. We'll also learn how to manipulate individual bits in an integer using what are called bitwise operators, and ultimately we'll convert an image to grayscale.

We first need to set up an SDL2 project. After following the steps in "SDL2: Setting up SDL2 in Visual Studio (2013 or any other)", you will also need to add SDL2_image.lib to your Linker Input (so that it reads "SDL2.lib; SDL2main.lib; SDL2_image.lib", and place the Visual C++ development libraries obtained from the SDL_image 2.0 homepage into the appropriate folders of your SDL2 directory. After you build your project the first time, make sure you also place all the necessary DLLs (including SDL2.dll, SDL2_image.dll and all the rest) into the same folder as your executable - see "SDL2: Loading Images with SDL_image" in case you need a refresher.

And in fact we're going to start with the code from "SDL2: Loading Images with SDL_image", which is the following (adapted a little bit):

#include <SDL.h>
#include <SDL_image.h>

int main(int argc, char ** argv)
{
    bool quit = false;
    SDL_Event event;

    SDL_Init(SDL_INIT_VIDEO);
    IMG_Init(IMG_INIT_JPG);

    SDL_Window * window = SDL_CreateWindow("SDL2 Grayscale",
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
    SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
    SDL_Surface * image = IMG_Load("PICT3159.JPG");
    SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer,
        image);

    while (!quit)
    {
        SDL_WaitEvent(&event);

        switch (event.type)
        {
        case SDL_QUIT:
            quit = true;
            break;
        }

        SDL_RenderCopy(renderer, texture, NULL, NULL);
        SDL_RenderPresent(renderer);
    }

    SDL_DestroyTexture(texture);
    SDL_FreeSurface(image);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    IMG_Quit();
    SDL_Quit();

    return 0;
}

We can also use the same sample image as in that project, so make sure it's in the appropriate folders where Visual Studio can find it.

Now, let's get down to business.

You see, the problem here is that we can't quite touch the texture pixels directly. So instead, we need to work a little bit similarly to "SDL2: Pixel Drawing": we create our own texture, and then copy the surface pixels over to it. So we throw out the line calling SDL_CreateTextureFromSurface(), and replace it with the following:

    SDL_Texture * texture = SDL_CreateTexture(renderer,
        SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC,
        image->w, image->h);

Then, at the beginning of the while loop, add this:

        SDL_UpdateTexture(texture, NULL, image->pixels,
            image->w * sizeof(Uint32));

If you try and run program now, it will pretty much explode. That's because our code is assuming that our image uses 4 bytes per pixel (ARGB - see "SDL2: Pixel Drawing"). That's something that depends on the image, and this particular JPG image is most likely 3 bytes per pixel. I don't know much about the JPG format, but I'm certain that it doesn't support transparency, so the alpha channel is out.

The good news is that it's possible to convert the surface into one that has a familiar pixel format. To do this, we use SDL_ConvertSurfaceFormat(). Add the following before the while loop:

    image = SDL_ConvertSurfaceFormat(image, SDL_PIXELFORMAT_ARGB8888, 0);

What this does is take our surface (in this case the one that image points to) and return an equivalent surface with the pixel format we specify. Now that the new image has the familiar ARGB format, we can easily access and manipulate the pixels. Add the following after the line you just added (before the while loop) to typecast the surface pixels from void * to Uint32 * which we can work with:

    Uint32 * pixels = (Uint32 *)image->pixels;

So far so good:


Now, let's add some code do our grayscale conversion. We're going to convert the image to grayscale when the user presses the 'G' key, so let us first add some code within the switch statement to handle that:

        case SDL_KEYDOWN:
            switch (event.key.keysym.sym)
            {
            case SDLK_g:
                for (int y = 0; y < image->h; y++)
                {
                    for (int x = 0; x < image->w; x++)
                    {
                        Uint32 pixel = pixels[y * image->w + x];
                        // TODO convert pixel to grayscale here
                    }
                }
                break;
            }
            break;

This is where bit manipulation comes in. You see, each pixel is a 32-bit integer which in concept looks something like this (actual values are invented, just for illustration):

Alpha Red Green Blue
11111111 10110101 10101000 01101111

So let's say we want to extract the Red component. Its value is 10110101 in binary, or 181 in decimal. But since it's in the third byte from right, its value is much greater than that. So we first shift the bits to the right by 16 spaces to move it to the first byte from right:



Alpha Red
00000000 00000000 11111111 10110101

...but we still can't interpret the integer as just red, since the alpha value is still there. We want to extract just that last byte. To do that, we perform a bitwise AND operation:

Pixel 11111111 10110101
Mask 00000000 11111111
Red AND Mask 00000000 10110101

We do an AND operation between our pixel value and a value where only the last byte worth of bits are set to 1. That allows us to extract our red value.

In code, this is how it works:

                        Uint8 r = pixel >> 16 & 0xFF;
                        Uint8 g = pixel >> 8 & 0xFF;
                        Uint8 b = pixel & 0xFF;

The >> operator shifts bits to the right, and the & is a bitwise AND operator. Each colour byte is shifted to the last byte and then ANDed with the value 0xFF, which is hexadecimal notation for what would be 255 in decimal, or 11111111 in binary. That way, we can extract all three colours individually.

We can finally perform the actual grayscaling operation. A simple way to do this might be to average the three colours and set each component to that average:

                        Uint8 v = (r + g + b) / 3;

Then, we pack the individual colour bytes back into a 32-bit integer. We follow the opposite method that we used to extract them in the first place: they are each already at the last byte, so all we need to do is left-shift them into position. Once that is done, we replace the actual pixel in the surface with the grayscaled one:

                        pixel = (0xFF << 24) | (v << 16) | (v << 8) | v;
                        pixels[y * image->w + x] = pixel;

If we now run the program and press the 'G' key, this is what we get:


It looks right, doesn't it? Well, it's not. There's an actual formula for calculating the correct grayscale value (v in our code), which according to Real-Time Rendering is:

Y = 0.212671R + 0.715160G + 0.072169B

The origin of this formula is beyond the scope of this article, but it's due to the fact that humans are sensitive to different colours in different ways - in fact there is a particular affinity to green, hence why it is allocated the greatest portion of the pixel colour. So now all we have to do is replace the declaration of v with the following:

                        Uint8 v = 0.212671f * r
                            + 0.715160f * g
                            + 0.072169f * b;

And with this, the image appears somewhat different:


This approach gives us a more even distribution of grey shades - in particular certain areas such as the trees are much lighter and we can make out the details more easily.

That's all, folks! :) In this article, we learned how to convert an image to grayscale by working on each individual pixel. To do this, we had to resort to converting an image surface to a pixel format we could work with, and then copy the pixels over to a texture for display in the window. To actually perform the grayscale conversion, we learned about bitwise operators which assisted us in dealing with the individual colours. Finally, although averaging the colour channels gives us something in terms of shades of grey, there is a formula that is used for proper grayscale conversion.

Thanks for reading. Come back for the next article! :)

Thursday, February 13, 2014

SDL2: Pixel Drawing

Greetings! :)

[Update 2015-11-14: This article is out of date. Check out the latest version at Gigi Labs.]

In yesterday's article, "SDL2: Keyboard and Mouse Movement (Events)", we saw how we could handle keyboard and mouse events to allow the user to interact with whatever we are displaying on the screen. In today's article, we'll learn how to draw individual pixels onto our window, and we'll use mouse events to create a drawing program similar to a limited version of Microsoft Paint.

You'll first want to create a project in Visual Studio and set it up for SDL2 (see "SDL2: Setting up SDL2 in Visual Studio (2013 or any other)"). We'll then need a bit of code to start off with, so let's take the code from "SDL2: Empty Window" and adapt it a little bit:

#include <SDL.h>

int main(int argc, char ** argv)
{
    bool quit = false;
    SDL_Event event;

    SDL_Init(SDL_INIT_VIDEO);

    SDL_Window * window = SDL_CreateWindow("SDL2 Pixel Drawing",
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);

    while (!quit)
    {
        SDL_WaitEvent(&event);

        switch (event.type)
        {
        case SDL_QUIT:
            quit = true;
            break;
        }
    }

    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

As always, don't forget to put SDL2.dll in the same folder as your executable before running the program.

Since we're going to draw pixels directly rather load an image, our course of action in this article is going to be a little different from past articles. First, we need a renderer, so we use SDL_CreateRenderer() as we have been doing all along:

    SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);

But then, rather than creating a texture from a surface, we're now going to create one from scratch using SDL_CreateTexture():

    SDL_Texture * texture = SDL_CreateTexture(renderer,
        SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, 640, 480);

We pass in several parameters. The first one is the renderer, and the last two are the width and height of the texture.

The second parameter, which we have set to SDL_PIXELFORMAT_ARGB8888, is the pixel format. There are many possible formats (see SDL_CreateTexture() documentation), but in this case we're saying that each pixel a 32-bit value, where there are 8 bits for alpha (opacity/transparency), 8 bits for red, 8 bits for green and 8 bits for blue. These four items are collectively known as channels (e.g. the alpha channel), so each channel consists of one byte and it can range between 0 and 255. The arrangement below thus represents a single pixel:

Alpha Red Green Blue
8 bits 8 bits 8 bits 8 bits

The SDL_TEXTUREACCESS_STATIC defines a method of accessing the texture. Since we're storing our pixels in CPU memory and then copying them over to the GPU, static access is suitable. On the other hand, streaming access is used to allocate pixels in a back buffer in video memory, and that's suitable for more complex scenarios.

Finally, we initialise a set of pixels that we'll be copying onto the window. When we draw stuff, we'll modify these pixels, and then they'll be copied onto the window to reflect the update.

    Uint32 * pixels = new Uint32[640 * 480];

We'll need to clean up all the stuff we just allocated, so add the following just before the other cleanup calls at the end of the code:

    delete[] pixels;
    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(renderer);

At the beginning of the while loop, we may now add the following call:

        SDL_UpdateTexture(texture, NULL, pixels, 640 * sizeof(Uint32));

In this code, we are using SDL_UpdateTexture() to copy our pixels onto the window. We pass it our texture, a region of the texture to update (in our case NULL means to update the entire texture), our array of pixels, and the size in bytes of a single row of pixels (called the pitch). In our case, our window has a width of 640 pixels. Therefore a single row consists of 640 4-byte pixels, hence the multiplication.

At the end of our while loop, we may now render our texture as we have done in previous articles:

        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, texture, NULL, NULL);
        SDL_RenderPresent(renderer);

Great. So far, we have... uh... this:


Let's clear the background to white, so that we can draw black pixels over it. We could do that using SDL_SetRenderDrawColor() as we did in yesterday's article, "SDL2: Keyboard and Mouse Movement (Events)". But since we can now manipulate pixels directly, let's try something. First, add this at the top:

#include <iostream>

Now, we can use the standard function memset() to overwrite our pixels. Add this right after the declaration of pixels:

memset(pixels, 255, 640 * 480 * sizeof(Uint32));

Good, it's white now:


Now, let's add some code to draw black pixels when the mouse is clicked. First, add the following flag at the beginning of main():

    bool leftMouseButtonDown = false;

Then, add this inside the switch statement:

        case SDL_MOUSEBUTTONUP:
            if (event.button.button == SDL_BUTTON_LEFT)
                leftMouseButtonDown = false;
            break;
        case SDL_MOUSEBUTTONDOWN:
            if (event.button.button == SDL_BUTTON_LEFT)
                leftMouseButtonDown = true;
        case SDL_MOUSEMOTION:
            if (leftMouseButtonDown)
            {
                int mouseX = event.motion.x;
                int mouseY = event.motion.y;
                pixels[mouseY * 640 + mouseX] = 0;
            }
            break;

Right, so we're keeping track of whether the left mouse button is pressed. When it's pressed (SDL_MOUSEBUTTONDOWN), leftMouseButtonDown is set to true, and when it's released (SDL_MOUSEBUTTONUP), leftMouseButtonDown is set to false.

If the mouse is moving (SDL_MOUSEMOTION) and the left mouse button is currently down, then the pixel at its location is set to black (or zero, which is the same thing). Note that I intentionally left out a break statement at the end of the SDL_MOUSEBUTTONDOWN case, so that the drawing code in SDL_MOUSEMOTION is executed along with its own.

So now we can draw our hearts out:


Sweet! That was all we needed in order to draw pixels directly onto our window. Before I wrap up, here's the full code I'm using:

#include <iostream>
#include <SDL.h>

int main(int argc, char ** argv)
{
    bool leftMouseButtonDown = false;
    bool quit = false;
    SDL_Event event;

    SDL_Init(SDL_INIT_VIDEO);

    SDL_Window * window = SDL_CreateWindow("SDL2 Pixel Drawing",
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);

    SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
    SDL_Texture * texture = SDL_CreateTexture(renderer,
        SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, 640, 480);
    Uint32 * pixels = new Uint32[640 * 480];
    memset(pixels, 255, 640 * 480 * sizeof(Uint32));

    while (!quit)
    {
        SDL_UpdateTexture(texture, NULL, pixels, 640 * sizeof(Uint32));
        SDL_WaitEvent(&event);

        switch (event.type)
        {
        case SDL_MOUSEBUTTONUP:
            if (event.button.button == SDL_BUTTON_LEFT)
                leftMouseButtonDown = false;
            break;
        case SDL_MOUSEBUTTONDOWN:
            if (event.button.button == SDL_BUTTON_LEFT)
                leftMouseButtonDown = true;
        case SDL_MOUSEMOTION:
            if (leftMouseButtonDown)
            {
                int mouseX = event.motion.x;
                int mouseY = event.motion.y;
                pixels[mouseY * 640 + mouseX] = 0;
            }
            break;
        case SDL_QUIT:
            quit = true;
            break;
        }

        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, texture, NULL, NULL);
        SDL_RenderPresent(renderer);
    }

    delete[] pixels;
    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

Fantastic! In this article, we learned how to draw pixels directly using SDL2. This involved first creating an SDL2 texture with a specified pixel format, then allocating an array to store those pixels, and finally copying the pixels from the array to the texture. We also used a variety of mouse events to allow the user to actually draw pixels onto the window with the mouse, which is like a simplified version of Microsoft Paint.

I hope you find this useful. Check back for more SDL2 and programming goodness! :)

Wednesday, February 12, 2014

SDL2: Keyboard and Mouse Movement (Events)

Hi there! :)

[Update 2015-11-14: This article is out of date. Check out the latest version at Gigi Labs.]

In this article, we'll learn how to handle keyboard and mouse events, and we'll use them to move an object around the window. Hooray! :)

We'll start with an image. I made this 64x64 bitmap:


As you can see, I can't draw to save my life. But since this is a bitmap, we don't need the SDL_image extension.

Once you have an image, you'll want to create a new Visual Studio project, wire it up to work with SDL2, and then add some code to display a window and the spaceship in it. If you don't remember how, these past articles should help:

  1. "SDL2: Setting up SDL2 in Visual Studio (2013 or any other)"
  2. "SDL2: Empty Window"
  3. "SDL2: Displaying an Image in the Window"
You should end up with code that looks something like this:

#include <SDL.h>

int main(int argc, char ** argv)
{
    // variables

    bool quit = false;
    SDL_Event event;
    int x = 288;
    int y = 208;

    // init SDL

    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window * window = SDL_CreateWindow("SDL2 Keyboard/Mouse events",
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
    SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);

    SDL_Surface * image = SDL_LoadBMP("spaceship.bmp");
    SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer,
        image);
    SDL_FreeSurface(image);

    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);

    // handle events

    while (!quit)
    {
        SDL_WaitEvent(&event);

        switch (event.type)
        {
        case SDL_QUIT:
            quit = true;
            break;
        }

        SDL_Rect dstrect = { x, y, 64, 64 };

        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, texture, NULL, &dstrect);
        SDL_RenderPresent(renderer);
    }

    // cleanup SDL

    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}
You'll also want to place spaceship.bmp into the same folder as where your main.cpp, for when you run by pressing F5 (or in the same folder as your executable if you're running it directly from there).

Once you actually run the program, you should see this:


I set the window's background to white to match the spaceship's white background by setting the clear colour using SDL_SetRenderDrawColor(), and then calling SDL_RenderClear() to clear the window to that colour.

In order to handle keyboard and mouse events, we need an SDL_Event. Well, what do you know: we have been using one all along, in order to take action when the window is closed. What we need now is to handle a different type of event type. So let's add a new case statement after the one that handles SDL_QUIT:

        case SDL_KEYDOWN:

            break;

Within this case statement, let us now determine which key was actually pressed, and move the spaceship accordingly:

        case SDL_KEYDOWN:
            switch (event.key.keysym.sym)
            {
            case SDLK_LEFT:  x--; break;
            case SDLK_RIGHT: x++; break;
            case SDLK_UP:    y--; break;
            case SDLK_DOWN:  y++; break;
            }
            break;
        }

If you now run the program, you'll find that you can move the spaceship using the arrow keys:


You'll notice that it seems to move pretty slowly, and you have to keep pressing for quite a while to make any significant movement. Now, in your code, replace SDL_WaitEvent with SDL_PollEvent:

        SDL_WaitEvent(&event);

Now, try running it again:


Swoosh! In less than half a second, the spaceship hits the edge of the window. It's actually too fast. To get this down to something manageable, add a small delay at the beginning of your while loop:

        SDL_Delay(20);

SDL_PollEvent() is better than SDL_WaitEvent() when you want to continuously check (i.e. poll) for events, but it consumes more CPU power (you can see this if you open Task Manager). SDL_WaitEvent() is okay when your window is mostly sitting idle so you don't need to check for events that often.

Handling mouse events is also very easy. All you need to do is handle the appropriate event. Let's see how to handle a mouse click:

        case SDL_MOUSEBUTTONDOWN:
            switch (event.button.button)
            {
            case SDL_BUTTON_LEFT:
                SDL_ShowSimpleMessageBox(0, "Mouse", "Left button was pressed!", window);
                break;
            case SDL_BUTTON_RIGHT:
                SDL_ShowSimpleMessageBox(0, "Mouse", "Right button was pressed!", window);
                break;
            default:
                SDL_ShowSimpleMessageBox(0, "Mouse", "Some other button was pressed!", window);
                break;
            }

And this is what happens when you run it, and click somewhere in the window:


You can also track mouse motion and obtain the current coordinates of the mouse pointer. This is useful when moving things with the mouse (e.g. moving an object by mouse-dragging it). The following code obtains the mouse coordinates and displays then in the window title:

        case SDL_MOUSEMOTION:
            int mouseX = event.motion.x;
            int mouseY = event.motion.y;

            std::stringstream ss;
            ss << "X: " << mouseX << " Y: " << mouseY;

            SDL_SetWindowTitle(window, ss.str().c_str());
            break;

Note that you'll need to add the following at the top of your main.cpp to make the above code work:

#include <sstream>

You will now notice the mouse coordinates in the window title:


Wonderful! You should now have an idea of how to capture and handle keyboard and mouse events in SDL2. We will see more of these in an upcoming article dealing with drawing pixels in the window, so stay tuned to learn more! :)

Monday, February 10, 2014

SDL2: Setting up SDL2 in Visual Studio (2013 or any other)

Hi ladies and gents! :)

[Update 2015-11-14: This article is out of date. Check out the latest version at Gigi Labs.]

A few months ago, in my article "SDL2: Setting up SDL2 in Visual Studio 2010", I wrote how you can get SDL2 working with Visual Studio by copying the headers and libraries into the folders where Visual Studio expects to find them by default.

The problem with this approach is that it might work for one version of Visual Studio, but you'll have to repeat a similar setup when you upgrade to a different version of Visual Studio. In fact, in this article we're going to use Microsoft Visual Studio Express 2013 for Windows Desktop (VS2013 for short). The steps are very similar TwinklebearDev's "Setting up SDL in Visual Studio".

First, head to the SDL2 downloads page and download the Development Libraries for Visual C++. At the time of writing this article, it's listed as SDL2-devel-2.0.1-VC.zip. Extract the contents of this file to a convenient location - for this tutorial it's going to be in C:\sdl2. This folder should directly contain the include and lib folders, so leave out any intermediate folders (at the time of writing this article, there is an SDL2-2.0.1 folder containing them in the package, so just leave that out).

Now you can fire up VS Express 2013 for Desktop (that's how VS2013 is listed if you search for it in the Windows 7 Start menu) and hit the "New Project..." link. Under "Visual C++", select "Empty Project":


In Solution Explorer, right click on the project and select "Properties". Under C/C++, then General, set the "Additional Include Directories" to "C:\sdl2\include" (or wherever you placed your SDL2 include folder):


Under Linker, then General, set the "Additional Library Directories" to "C:\sdl2\lib\x86" (adapt this path depending on where you extracted your SDL2 files):


Still under Linker, but this time going into Input, replace the value of "Additional Dependencies" with "SDL2.lib; SDL2main.lib":


And still under Linker, but now selecting System under it, set "SubSystem" to "Windows (/SUBSYSTEM:Windows)":


That's more or less the configuration we need. This is to compile an SDL2 game as an x86 executable, which should be fine if you're just starting out (since it will work on both 32-bit and 64-bit platforms). If you want to compile as x64 instead, the steps above are the same, except that you'll need to use the x64 libraries instead.

Now that the configuration is done, let's add some code and see that it works correctly. In Solution Explorer, right click on the "Source Files" filter, and then select "Add" -> "New Item...":


At this point, add a C++ file, and name it main.cpp:


Type in some code. The intellisense in VS2013 works nicely:


This code should get you going just fine:

#include <SDL.h>

int main(int argc, char ** argv)
{
 SDL_Init(SDL_INIT_VIDEO);

 // game code eventually goes here

 SDL_Quit();

 return 0;
}

If you press Ctrl+Shift+B to compile the project, it compiles just fine. But if you press F5 to run it, the following error appears:


Don't panic! We've been through this before. All you need to do is retrieve your SDL2.dll file from C:\sdl2\lib\x86 (adapt according to where you placed your SDL2 files) and copy it into your project's Debug folder, where the executable is being generated.

If you run the program now, nothing happens, and that means it worked fine. You can proceed to build your game from here! :)

In this article, we have revisited the configuration necessary to set up an SDL2 project, this time with VS2013 and by configuring settings in Visual Studio as opposed to throwing files into the Windows SDK directories. Here's a summary of the things you have to configure:

  1. C/C++ -> General: Set "Additional Include Directories" to the SDL2 include folder.
  2. Linker -> General: Set "Additional Library Directories" to the SDL2 libraries folder depending on the platform you are targeting.
  3. Linker -> Input: Set "Additional Dependencies" to "SDL2.lib; SDL2main.lib".
  4. Linker -> System: Set "SubSystem" to "Windows (/SUBSYSTEM:Windows)".
  5. Remember to put SDL2.dll in the same directory as the executable!

Enjoy your SDL2 coding! :)

Sunday, January 5, 2014

C# Security: Bypassing a Login Form using SQL Injection

Greetings! :)

I hope you've had a fantastic holiday season. The Ranch had a bit of a break of its own, and is now back to bring you more goodness that you can hopefully learn something from.

In this article, we're going to learn about SQL injection. We'll use it to bypass a login form on a website, and you'll see just how easy it is. Despite its simplicity, this article is going to be a little bit long - because we'll need to set up a simple login form with a database that we can then use to try out the SQL injection. Naturally, you should never try out these types of attacks on someone else's website; so when you want to learn something in practice, set up a vulnerable system of your own.

To demonstrate SQL injection, we're going to be using ASP .NET (for the web form) and SQL Server 2012 Express (for the database). However, SQL injection is not tied to any technology in particular, so you could, for example, use PHP and MySQL instead. You are expected to know a little something about databases (SQL) and websites, although rest assured that there's nothing complicated in this article.

Prerequisites


For the database, we're going to use Microsoft SQL Server 2012 Express, which is freely available from Microsoft. When you download it, you will be given the option to download several different files. What you need is SQLEXPRWT_x64_ENU.exe (for 64-bit systems) or SQLEXPRWT_x86_ENU.exe (for 32-bit systems). This particular file includes tools such as SQL Server Management Studio, which you need to actually create and work with your database. You should see it included in the installer:


In order to create our ASP .NET login form, we'll use Visual Studio. If you have a paid edition of VS, then you can use that. Otherwise, you can get Visual Studio Express for Web (at the time of writing, the 2013 edition is the latest) for free:


Setting up the database



In order to create and set up our database, we'll need to use SQL Server Management Studio. Launch it, and from the Object Explorer on the left, right click on the Databases node, and click on "New Database...". Enter a name for your database (I'm using "sqlinjection") and click OK.


You should now be able to right click on the newly created database and select "New Query". This brings up a text editor where you can enter and run queries against the database. Enter the following script into this editor:

create table users(
    id int not null primary key identity(1,1),
username varchar(50) not null,
password varchar(50) not null
);

...and press F5 to execute it:


You should now have your users table with an id field as well as the username and password. Now, replace the script with the following:

insert into users(username, password)
values('hankmarvin', 'theshadows');

Press F5 to insert a new row where the username is "hankmarvin" and the password is "theshadows". The id column should be filled automatically since we are using an IDENTITY on that column. Note that in this case we're storing a password as cleartext for simplicity, but this is almost never a good idea - see my article "C# Security: Securing Passwords by Salting and Hashing" if you don't know why.

Creating the login form

In Visual Studio, go on File -> New Website... and create a new project of type ASP .NET Empty Web Site:


Next, right click on the project in Solution Explorer, and select Add -> Add New Item..., and then pick Web Form from the list of templates. Leave the name as Default.aspx.

Set up the markup in Default.aspx so that it looks like this:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            Username: <asp:TextBox ID="usernameField" runat="server" />
        </div>
        <div>
            Password: <asp:TextBox ID="passwordField" runat="server" />
        </div>
        <div>
            <asp:Button ID="loginButton" runat="server" Text="Login" OnClick="loginButton_Click" />
        </div>
        <div>
            <asp:Label ID="resultField" runat="server" />
        </div>
    </form>
</body>
</html>

It's not wonderful HTML, and not exactly pretty, but it's the simple login form that we need. You can see the result by pressing F5 to launch the project in your web browser:


Next, go into your webpage's codebehind file (that would be Default.aspx.cs. Add the following statement near the top:

using System.Data.SqlClient;

Add the following event handler that actually takes care of the logic for logging in (your actual connection string may vary depending on how you installed SQL Server - see this if you run into issues):

    protected void loginButton_Click(object sender, EventArgs e)
    {
        String connStr = @"Data Source=localhost\SqlExpress;Initial Catalog=sqlinjection;Integrated Security=True;";
        String username = this.usernameField.Text;
        String password = this.passwordField.Text;
        String query = "select count(*) from users where username = '" + username
            + "' and password = '" + password + "'";

        try
        {
            using (SqlConnection conn = new SqlConnection(connStr))
            {
                conn.Open();

                using (SqlCommand command = new SqlCommand(query, conn))
                {
                    int result = (int)command.ExecuteScalar();
                    if (result > 0)
                        resultField.Text = "Login successful.";
                    else
                        resultField.Text = "Login failed! Go away!";
                }
            }
        }
        catch(Exception ex)
        {
            resultField.Text = ex.Message;
        }
    }

SQL Injection

You can now press F5 and test out the login form. If you enter the correct credentials, which are "hankmarvin" for username and "theshadows" as the password, then you should see the message "Login successful." just below the form. For any other input, the login will fail.

It should be pretty evident that the code in loginButton_Click is constructing dynamic SQL based on the credentials provided. So for the correct credentials, this would build the SQL string:

select count(*) from users where username = 'hankmarvin' and password = 'theshadows'

The weakness in this is that we can write whatever we want into the username and password fields, and they'll be included in the SQL query. Let's see what happens when we use the following input in the password field:

' OR 1=1 --

Using this, we are logged in just fine:


Oops! What just happened here? If we take a look at the dynamic SQL that is being constructed, it becomes clear:

select count(*) from users where username = '' and password = '' OR 1=1 --'

The stuff we entered in the password field is closing off the SQL string (with the apostrophe at the beginning) and is adding a condition that will always be true (1=1). A comment (--) at the end gets rid of the remaining SQL, in this case a closing apostrophe. The query's WHERE clause can now be read as follows:

((username = '') AND (password = '')) OR 1=1

Well, it turns out that 1=1 is always true, so the query ends up returning every row in the database. The count is greater than zero, and so the login is successful, even though we didn't actually provide valid credentials.

Prepared Statements

The correct way to fight SQL injection is to use prepared statements. This means that the event handler changes as follows:

    protected void loginButton_Click(object sender, EventArgs e)
    {
        String connStr = @"Data Source=localhost\SqlExpress;Initial Catalog=sqlinjection;Integrated Security=True;";
        String username = this.usernameField.Text;
        String password = this.passwordField.Text;
        String query = "select count(*) from users where username = @username and password = @password";

        try
        {
            using (SqlConnection conn = new SqlConnection(connStr))
            {
                conn.Open();

                using (SqlCommand command = new SqlCommand(query, conn))
                {
                    command.Parameters.Add(new SqlParameter("@username", username));
                    command.Parameters.Add(new SqlParameter("@password", password));
                    int result = (int)command.ExecuteScalar();
                    if (result > 0)
                        resultField.Text = "Login successful.";
                    else
                        resultField.Text = "Login failed! Go away!";
                }
            }
        }
        catch(Exception ex)
        {
            resultField.Text = ex.Message;
        }
    }

Instead of building dynamic SQL, we insert named placeholders, such as @username, to stand in for parameters in the query. We then provide these values via the SqlCommand's Parameters property, where the values are paired up with the corresponding parameter names. Since these parameters are strongly typed, things like escaping apostrophes in strings are handled automatically, and so users can't inject SQL via input fields.

In fact, if you try the same SQL injection attack as above, you'll see that it doesn't work any more:


Summary

As we have seen in this article, SQL injection is a really simple technique that can be used to breach security in vulnerable websites and applications. Bypassing login forms is only one of many things you can do with SQL injection, which is so dangerous that it has topped the OWASP Top 10 Risks for years.

To protect against SQL injection, use prepared statements to provide strongly-typed parameters in your SQL queries, and avoid dynamic SQL built directly by concatenating strings.