Tom Sampson

General and Tech Stuff! – Please Please leave comments! I will ALWAYS read and reply.

Debugging full screen DirectX Applications August 2, 2008

Filed under: C++, Coding, DirectX, Game Programming — tomtech999 @ 12:17 pm
Tags: , , , , , ,

Today I was trying to step through some code for intialising a vertex buffer, as something was going drastically wrong along the way. However my application needed to be tested in full screen mode which made debugging through VS impossible as the application I was trying to debug takes full control of the screen.

There seem to be two solutions in this scenario;

  1. Modify your code to run in windowed mode (easy enough to do, just change your window class registration and DirectX initialisation routines)
  2. Use multiple monitors –> Goto control panel, choose DirectX, Goto DirectDraw tab, choose Advanced and enable Multiple Monitor Debugging.
 

Listing files in a directory in C++ July 30, 2008

Filed under: C++ — tomtech999 @ 4:13 pm
Tags: , , , , , ,

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.

 

A Window for your game! May 15, 2008

Filed under: C++, Game Programming, General — tomtech999 @ 2:32 pm
Tags: , , , ,

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.

 

ZeroMemory – What and why May 15, 2008

Filed under: C++ — tomtech999 @ 9:56 am
Tags: , , , ,

Zero Memory is a Macro used within c++ programs to “Zero” some memory but what does this mean?!

Basically, here is an example of using ZeroMemory, it takes 2 parameters, a memory location and a length

ZeroMemory( &myVar, sizeof( myVar) );

So we pass in the memory location of a variable (using the & symbol to give the location of the variable and not the variable value itself) and a length (if myVar was a char lets say, then the value here would be 8).

For the example above, when this is run it will point to the location of myVar specified within memory and for the next 8 consecutive memory positions, store the value 0. so at memory position &myVar the contents of memory will now be

“00000000″

Why?

This is mainly used when variables have not been initialised. For example if you declared a string variable in c++ but gave it no initial value, it will have a location in memory, but no value of its own, in some situations it will be pointing to random values held in ram which have not been cleared previously. Then when you try to cout << stringVar it will most likely crash depending on the data held at the position of the uninitialised variable.

 

C++ String to Uppercase March 24, 2008

Filed under: C++, Coding — tomtech999 @ 10:32 pm
Tags: , , , , , , , ,

In my project today I was taking the name of a user and then usig that to generate a data file e.g. “fred.dat”. I decided that I needed to keep the same data file for each user, regardless of how they entered there name .This name was not a username and could be writtin in any mixture of upper / lower case.

To resolve this I decided to make the filenames for each player uppercase when saved and loaded, e.g. FRED.dat but I couldn’t find any easy way to do so. The toupper() function I am familiar with only works on characters so I designed the following simple function to convert a string to uppercase.

NB:- Here I use the string data type, not c string.The resultant string can ofcourse be converted to c string by adding the post function .c_str()

————————–

string toUpperString(string text)
{
string toReturn(text); // duplicate input for manipulation

for(int i=0;i<text.length();++i) // for each character in string
{
toReturn[i]=toupper(text[i]); // convert char to uppercase
}

return toReturn; // return in upper case
}

Please correct me if there is a simpler way to implement this but for now this works a treat.

 

Dynamic Arrays in C++ March 1, 2008

Filed under: C#, C++, Coding, Systems Architecture — tomtech999 @ 3:25 pm
Tags: , , , ,

C++I have only started using C++ properly over the past few months and I’m realising that many of the features and aspects I took for granted in interpreted languages, are implemented in a much more complicated way in c++!

For example if you wanted to create a dynamic array in c# (as below) the .NET framework will do all the memory allocation and management for you and let you initialise an array of your chosen size at run time (when the size of the array cannot be determined at compile time)

int[] temp = new int[varName] //Where varName could be an integer given by the user

Another interesting point at this stage is that after c# initialises the array dynamicaly, for example with a dimension of 3. When you try and access temp[20] for example, the .net framework instantly detects you are breaching the size of the array and throws an “Out of bounds” exception. However in c++ (and this applies to static and dynamic arrays) accesing a position outside the array simply looks up in memory PAST the array and starts reading random data, not even necessarily from your application!

Anyway, to make a dynamic array in c++ we must follow 3 steps

  1. use the new keyword to initialise the array in memory
  2. ensure that the memory allocation for the array was successfull, catching the failure of this event
  3. delete the array from memory after use (as c++ will not dispose of it automatically)

The example below simply gets a number from the user and then initialises an array with the dimension the user has specified.

int mySize( 0);

cin >> mySize;

int myArray[] = new int[mySize];

if(myArray!=0)

{

//catch failure of array initialisation

}

else

{

//Work with array….

delete[] rain;

}

 

Reflective Glass February 28, 2008

Filed under: C#, Coding, XAML — tomtech999 @ 8:08 pm
Tags: , , , , , , , , ,

I am aware that there is most likely to be a much simpler implementation of this as part of WPF (Windows Presentation Foundation) but this article shows you how to make a reflective glass effect (similar to that used throughout itunes) using GDI library only (in c#).

http://www.codeproject.com/KB/GDI-plus/Image-Glass-Reflection.aspx

 

C++ Pound Sign November 28, 2007

Filed under: C++, Coding — tomtech999 @ 11:08 pm
Tags: , , , , ,

Last night I got so fustrated trying to do something really simple in c++. I needed to represent a GBP £ sign in a c++ windows console application. My smug friend using linux terminal and GCC assured me that the pound sign did not keep him up last night, but for me compiling away on MSBUILD it was a nightmare. Something so simple. yet after trying EVERY POSSIBLE mixture of search terms, google provided me with nothing! For once google had failed me! It did however suggest escape character methods and all sorts of other fruitfull options but none that worked. When outputing a £ to the command line I got “u”. Not much use when your trying to represent a price in GBP! It turns out that microsoft, being american, does not naturally support the character and the following is required to achieve such a simple thing.

//show pound sign in c++

char pound=156;

cout << “This will cost ” <<pound << “5.00″ ;

Why am I blogging this?? In the hope that after this blog post gets indexed by google, the many others who appear on forums searching for this solution, and those who will come across it in the future, will find this and get an early night! Unlike myself :P

 

What I’ve learnt today! October 31, 2007

Filed under: CSS, Coding — tomtech999 @ 6:19 pm
Tags: , , , , , ,

They say you should learn something new everyday! Today I got lucky and learnt 3 interesting bits of information!!

CSS

1. The name CSS (Cascading Style heets) has always seemed a bit odd utill today I learnt the meaning of “Cascading” which explains the heirarchical way in which different kinds of styles are used and over-ridden ( inline styling, embedded, external, browser default etc). Cascading refers to how style informations is passed down through the document and how in some areas it is inherited and nothers not. For a full explanation i reccomend some googling or the book “Stylin’ with css”

2. Each browser has its own “off the shelf” stylesheet for rendering html where all the tags are defined! This can be easily viewed and edited (although not recommended), especially in firefox. Locate the file

[INSTALL DIR]\Mozilla Firefox\res\html.css

or view here (sorry its in pdf)

C++

3. C++ Pointers!!!!

These have remained a mystery to me for quite a while and not through lack of research, but sometimes it’s better to sit down and ask a human! I understood HOW to use pointers in C but not WHY on earth I would ever choose to use them. Today I took the opportunity to ask my programming tutor and she gave me the simplest but most useful answer i have ever found. I shall attempt to explain as simply as possible.

Ok basically when you have a function in any modern language such as c# or Java, the parameters you pass in are never duplicated. For exaple if i declare an integer in my main program then pass that integer into my function. The integer is held in memory only once, and referenced to inside the function accepting it as a parameter. However, in c++ this referencing does not take place and as the parameter is passed into the function, 2 copies are held in memory, the integer belonging to the main programm and the integer to be used within the function. This is often not a problem when using a simple 8 or 16 bit integer but imagine passing in a large database object to your function. In c# or Java we wouldnt be concerned about this and it would be considered normal, however do this in c++ and your whole database object gets duplicated in memory, = BAD!!! To get around this, pointors are used as references to large structs of data within memory and avoid duplication. In this situation you would pass a pointer to the database object into the function, rather that passing the object its’self therefore avoiding duplication. Figure out the rest yourself! As I mentioned, learning how to use pointers is easy, just thought I would explain their usage!!