Brian Clifton . com

Programming Articles: Example code and more.

Previous   1 2 3 4 5 6   Next
Showing articles 1 - 5 (26 posts total)

Taking a screenshot using XNA 4.0 and C#

Posted by Brian Clifton
Written August 8, 2011 at 07:49
I've been working a lot on an old game that a few friends and I made in college. We ported it to C# using the XNA framework and it's working great! You can read more about that project by clicking here.

The old code was C++ with OpenGL. One of the functions I had a hard time porting was taking a screenshot. Older versions of XNA seemed to have a way to do it, but the newest version, 4.0, didn't have an easy way to do it. Here's what I ended up doing:
public void ScreenShot(string prefix) {
    #if WINDOWS
    int w = GraphicsDevice.PresentationParameters.BackBufferWidth;
    int h = GraphicsDevice.PresentationParameters.BackBufferHeight;

    //force a frame to be drawn (otherwise back buffer is empty)
    Draw(new GameTime());

    //pull the picture from the buffer
    int[] backBuffer = new int[w * h];
    GraphicsDevice.GetBackBufferData(backBuffer);

    //copy into a texture
    Texture2D texture = new Texture2D(GraphicsDevice, w, h, false, GraphicsDevice.PresentationParameters.BackBufferFormat);
    texture.SetData(backBuffer);

    //save to disk
    Stream stream = File.OpenWrite(prefix + "_" + Guid.NewGuid().ToString() + ".png");
    texture.SaveAsPng(stream, w, h);
    stream.Close();

    #elif XBOX
    throw new NotSupportedException();
    #endif
}

Here's an article you can check out that explains the new behavior:
http://blogs.msdn.com/b/shawnhar/archive/2010/03/30/resolvebackbuffer-and-resolvetexture2d-in-xna-game-studio-4-0.aspx

Getting the assembly version in ASP.NET

Posted by Brian Clifton
Written February 11, 2011 at 10:43
I typically update the .NET assembly for this website by hand whenever I have a new major release and I'd like to be able to get the version.

Unlike a Windows Forms application, there is no Application.ProductVersion. I Googled for answers and it looked like I needed to do this:using System.Reflection;

string version = Assembly.GetExecutingAssembly().GetName().Version.ToString();

However, that causes a SecurityException to be thrown. I'm running my website at GoDaddy.com in a shared hosting environment and the permissions are limited.

Here's how I solved the problem...using System.Reflection;

Type t = typeof(*pick any class that's in the assembly you want the version of*);
AssemblyName an = new AssemblyName(Assembly.GetAssembly(t).FullName);
string version = an.Version.ToString();

Some examples that I found use Assembly.GetExecutingAssembly(), but I found that this doesn't work. It'll compile, but always returns back 0.0.0.0 as the version. That's why you'll have to use Assembly.GetAssembly() and provide a type as shown above.

Searching the database for text in SQL Server

Posted by Brian Clifton
Written May 9, 2010 at 23:57
In SQL Server, there's a lot of times where you need to find out where a stored procedure, user function, or value is referenced in the database.

For example, let's say we have a stored procedure called "InsertUser". We can search all database text for any references of this:SELECT *
FROM syscomments
WHERE text LIKE '%InsertUser%'

Simple object pool in C++

Posted by Brian Clifton
Written November 26, 2009 at 02:52
This is a simple object pool I use in my C++ code. It provides good performance and avoids memory fragmentation. I based the code on an example from Game Programming Gems 4.
#include <stdlib.h>
#include <list>

using namespace std;

class TestObject{
    public:
        int _TestValue;
        TestObject(void)
        {
            _TestValue = 0;
        }
};

template<class OPDataType> class ObjectPool{
    protected:
        OPDataType* _ObjectData;
        OPDataType** _ObjectFree;
        int _ObjectCount,_Top;

    protected:
        void FreeAll(void)
        {
            int i = (_ObjectCount-1);

            for(_Top=0;_Top<_ObjectCount;_Top++){
                _ObjectFree[_Top] = &_ObjectData[i--];
            }
            return;
        }
    public:
        void FreeInstance(OPDataType* instance)
        {
            if((instance) && (_Top<_ObjectCount) && (instance>=&_ObjectData[0]) && (instance<=&_ObjectData[_ObjectCount-1])){
                _ObjectFree[_Top++] = instance;
            }
            return;
        }

        OPDataType* NewInstance(void)
        {
            if(_Top>0){
                return(_ObjectFree[--_Top]);
            }
            return(0);
        }

        ObjectPool(int count)
        {
            _ObjectData = new OPDataType[count];
            _ObjectFree = new OPDataType*[count];

            _ObjectCount = count;

            FreeAll();
        }

        virtual ~ObjectPool(void)
        {
            delete[] _ObjectData;
            delete[] _ObjectFree;
        }
};

#define TEST_POOL_SIZE 200

int main(int argc,char** argv)
{
    ObjectPool<TestObject> pool(TEST_POOL_SIZE);
    list<TestObject*> objects;

    for(int i=0;i<TEST_POOL_SIZE;i++){
        TestObject* test = pool.NewInstance();
        test->_TestValue = rand();
        objects.push_back(test);
    }

    list<TestObject*>::iterator it = objects.begin();
    while(it != objects.end()){
        pool.FreeInstance( (*it) );
        ++it;
    }

    objects.clear();

    return(0);
}

Handling NIC information on Windows

Posted by Brian Clifton
Written August 6, 2009 at 22:00
If you need to programmatically get info about the NIC, you can find it in the registry:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}

You can enumerate through all of the sub-keys; they're labeled as 0000, 0001, 0002, etc. If you're on Windows Vista / Server 2008, be sure to catch exceptions because there is a sub-key called Properties that you will get an access violation on.

For example, in my Shuttle SG33G5, I have my primary NIC under a sub-key called 0004. I can tell it's my primary NIC because of the DriverDesc value. From this key, you can set duplex, buffer sizes, and other NIC driver settings.

Just as an example, lets say you want to set your NIC to be 100Mbps full duplex. Before you make an automated solution, you can see the values passed to the NIC driver in the sub-key called NDI under the sub-key Params. In my case, I would need to open this key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0004\Ndi\Params\*SpeedDuplex

There is a value here called default and it's set to 0. Looking at the sub-key called enum, there are some values I could use:
0 = Auto Negotiation
1 = 10 Mbps Half Duplex
2 = 10 Mbps Full Duplex
3 = 100 Mbps Half Duplex
4 = 100 Mbps Full Duplex

So when it's time for automating this, my code would:
1) Open this key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}
2) Go through each sub-key (0000,0001,0002...), until it finds a value DriverDesc called "Generic Marvell Yukon Chipset based Ethernet Controller".
3) I know for this card, the value 4 is 100Mbps. So I can set the value data for "*SpeedDuplex" to 4. The full path to this registry value is
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0004\*SpeedDuplex
4) After making the change you can restart your network interface by making a shell execute call to netsh.exe
netsh interface set interface "Local Area Connection" DISABLED
netsh interface set interface "Local Area Connection" ENABLED

This article is basically documentation of some code my friend Daymion wrote. You can probably achieve the same result with WMI, but it's a lot nastier to do that in C or C++.
Previous   1 2 3 4 5 6   Next
Showing articles 1 - 5 (26 posts total)