Thomas Sampson


6 Comments

Listing files in a directory in C++

First of all I am not sure how you go about doing this in unix or linux! There is no standard, platform specific way to get all the files in a directory, however the following method works on windows making use of calls to winAPI so dont forget to include this!

#include <windows.h>

The following code then loops through a folder (in this case the starting folder of the executable) and puts the filenames into a string array.  The functions FindFirstFile and FindNextFile both work by populating a structure of the type WIN32_FIND_DATA which holds all the properties of the file in question.

UINT counter(0);
bool working(true);
string buffer;
string fileName[1000];

WIN32_FIND_DATA myimage;
HANDLE myHandle=FindFirstFile("*.jpg",&myimage);

if(myHandle!=INVALID_HANDLE_VALUE)
{
       buffer=myimage.cFileName;
       fileName[counter]=buffer;

       while(working)
       {
              FindNextFile(myHandle,&myimage);
              if(myimage.cFileName!=buffer)
              {
                     buffer=myimage.cFileName;
                     ++counter;
                     fileName[counter]=buffer;
              }
              else
              {
                      //end of files reached
                      working=false;
              }

       }
}

When the last file in the folder has been read, the FindNextFile method will keep returning the same filename over and over again in the while loop. To catch this i use a sort of swap buffer to check if the same filename is found twice, and if so exiting the loop. I am sure there is a better way to catch the last file and will look into this soon. If anyone knows a more efficient way to do this please let me know.

NOTE:- “*.jpg” could be replaced with “C:/myfolder” or “*.doc” or a combination of the two depending on how you wish to filter the files that are found.  Using “” would list all the files in the running directory of the executable.

Advertisements


1 Comment

A Window for your game!

WindowBefore touching any graphics API it is important that we think about how the game will run. As mentioned previously I have chosen to use the DirectX graphics library to display and render my whole application. DirectX is used for creating rich 3d visuals for both the PC and xBox. Regardless of this choice, the initial process of getting a game (or any application) to run on the PC requires using the Windows API to set up the application and window in which the game will run, hence this post would apply almost identically if you were planning on using the OpenGL library.

Before starting it is worth mentioning that I have no experience at all of getting home brew code to run on a 360 but I do understand that like the PC, it’s games use the DirectX libraries. Ofcourse, I will be compiling my c++ code for the PC but it is important to remeber that the c++ code for a PC game and a 360 will be very similar. The main difference is the system architecture of the two platforms.

When compiling for the PC we are compiling to an x86 binary file, however the xBox 360 uses the Power PC architecture so a different compiler must be used to generate the appropriate machine code. I am also sure that a number of things must also be done to your c++ code if you were planning to port it to an xBox 360, but I have no understanding of this (and you probably wont need to know this as it is usually handled by a game engine). This does not mean that this isn’t an interesting topic and I may do a post on this area at a later date. If anyone reading does know more about this please leave a comment and I will try and integrate your feedback into this post!

Starting the project

Anyway, I will now try and explain the process of setting up a window in which you will be able to host your game. At this stage no extra libraries need including, we simply make use of the “windows.h” header file. I will show code snippets step by step, the complete source code for this post can be found here.

You first need to set up a new “win32” project in visual studio (as shown below), and make sure you tick the “blank project” check box when required.

Next simply add a source code (cpp) file to your project and call this anything you like, preferably “main” or “winMain”.

Setting Up Your Window

When programming a windows application, if the application has any form of visual representation beyond command line you must register a window class. Once a window class is registered, the windows operating will send any messages necessary to your application. Messages are anything that your application needs to know about, for instance a keypress, minimising your window, or a mouse click. To start off we will include the windows header file and set up global variables to hold our application and window instances.

#include <windows.h>

HINSTANCE hInst;       //global access to application instance
HWND wndHandle;        //global access to the window instance

//function prototypes
bool initWindow( HINSTANCE hInstance);
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM);

Don’t worry too much about the function prototypes as they simply tell the compiler that we plan to use the defined functions later in our code (forward decleration). Next we need to create the program entry point, for console applications this is “int main()” however with a windows application it translates to..

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)

A quick summary of whats going on here. This is the program entry point and you can see there are 4 arguments. hInstance is the handle to your application, hPreviousInstance will always be NULL and historically was a way of identifying a previous instance of your program, lpCmdLine is a pointer to any parameters passed to your application (for instance if someone ran your program as “myApp.exe -h hi”). As far ask I know nShowCmd is the start mode of your application from the operating system (maximized, minimized etc). For now all of this is useless and we will not use any of the parameters, they just need to exist within the code.

The Main Program Code

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
    //Initialize the main window
    if(!initWindow( hInstance))
    {
        return false; //If initialisation fails, exit program
    }

    MSG msg;                             //New message object
    ZeroMemory( &msg, sizeof( msg) );    //Clear memory

    //Main Message Loop
    while( msg.message!=WM_QUIT)
    {
        // Check the message queue
        while( GetMessage(&msg, wndHandle, 0, 0) )
        {
            TranslateMessage( &msg);
            DispatchMessage( &msg);
        }
    }

    return (int) msg.wParam; //Return with exit code
}

This is basically what is going off here…

  1. Attempt to initialise the window (using the yet to be defined “initWIndow” method)
  2. Check the success of the window creation, quitting immediately if anything failed
  3. Create and clear a message object which will be used when processing window messages
  4. While ever the QUIT message (the user clicks close) isn’t on the message queue, check for the next message
  5. Translate and dispatch messages to be interpreted and handled by the (yet to be defined) “wndProc” callback method.

Click here for more information on ZeroMemory() – (popup window)

This should be pretty self explantory although you might wonder how the program knows to use the wndProc callback method? Well this is set up and configured when we set up our window in the initWIndow function to follow.

initiWindow

Here is the code for the initWindow function previously declared

bool initWindow( HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.hInstance=hInstance;                      //link this window with the application instance
    wcex.cbSize= sizeof(WNDCLASSEX);               //size of the structure
    wcex.style= CS_HREDRAW | CS_VREDRAW;           //style
    wcex.lpfnWndProc = (WNDPROC)WndProc;           //the window procedure callback mechanism
    wcex.cbClsExtra = 0;                           //Extra bytpe allocation (not required)
    wcex.cbWndExtra = 0;                           //Extra bytpe allocation (not required)
    wcex.hIcon = 0;                                //icon to use for the window
    wcex.hIconSm = 0;                              //Set small icon
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);    //choose the cursor for the window
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); //Choose background colour
    wcex.lpszMenuName = NULL;                       //Not using
    wcex.lpszClassName = (LPCSTR)"WindowExample";   //Name of the class
    RegisterClassEx(&wcex);                         //Register window class with system

    wndHandle=CreateWindow((LPCSTR)"WindowExample",
                           (LPCSTR)"Title bar text here",
                           WS_OVERLAPPEDWINDOW,
                           CW_USEDEFAULT, CW_USEDEFAULT,
                           640,480,NULL,NULL,hInstance,NULL);

    //Check success of window creation
    if(!wndHandle)
    {
        return false;
    }
    //Show successful window
    ShowWindow(wndHandle,SW_SHOW);
    UpdateWindow(wndHandle);
    return true;
}

Again this should be fairly self explanitory. We make a new instance of a window class and set all its attributes (the long wcex. list! ) Most of these attributes you dont need to know and others are self explantory, however it is important you are specific with your lpszClassName as this exact value is required a little further down as the first parameter of CreateWindow.

Here is a summary of this function…

  1. Make an instance of a WNDCLASSEX object and set all its attribute including its “lpszClassName”, and “lpfnWndProc” to set up the callback method (for handling messages)
  2. Register this class object with the system
  3. Create a window based upon the registered window class, assigning this to out window handle (wndHandle)
  4. Check to ensure the window creation was a success (returning false if it fails)
  5. Show and update the window.

Finally…

All that remains to do now is define our callback mechnism which will handle all the messages that our window recieves while it is open. Remember, this was defined at the very top as “LRESULT CALLBACK WndProc”. Here is the code for this function..

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hWnd,message,wParam,lParam);
}

Pretty simple really..

  1. Check the contents of the message (we are only currently listening out for a quit message)
  2. If a quit message is fired run PostQuitMessage to quit tidily
  3. At this point (the user has quitted) , the while loop condition in the main program is broken, and the code will exit and return the user to the desktop.

All together now!

Here is a link to the complete cpp file

At this stage i would recommend making sure your code works and displays a white blank window, and put it in a safe place. You never really want to write this code again and should just adapt it to any project you start in future.