Jun
12
2012

How to Delete Directories Recursively with Win32

Well, while I’m at it, here’s the counterpart to the recursive directory creation function from my last post, a function that recursively deletes a directory and all its contents.

Ordinarily, you could just use the shell API to achieve this on classic Win32:

/// <summary>Deletes a directory and everything in it</summary>
/// <param name="path">Path of the directory that will be deleted</param>
void deleteDirectory(const std::wstring &path) {
  SHFILEOPSTRUCTW fileOperation;
  fileOperation.wFunc = FO_DELETE;
  fileOperation.pFrom = path.c_str();
  fileOperation.fFlags = FOF_NO_UI | FOF_NOCONFIRMATION;

  int result = ::SHFileOperationW(&fileOperation);
  if(result != 0) {
    throw std::runtime_error("Could not delete directory");
  }
}

But WinRT/Metro applications cannot use the shell API and have to do it manually. So here’s a piece of code that takes care of directory deletion using nothing but Win32 API calls that are also available to WinRT/Metro applications:

/// <summary>Automatically closes a search handle upon destruction</summary>
class SearchHandleScope {

  /// <summary>Initializes a new search handle closer</summary>
  /// <param name="searchHandle">Search handle that will be closed on destruction</param>
  public: SearchHandleScope(HANDLE searchHandle) :
    searchHandle(searchHandle) {}

  /// <summary>Closes the search handle</summary>
  public: ~SearchHandleScope() {
    ::FindClose(this->searchHandle);
  }

  /// <summary>Search handle that will be closed when the instance is destroyed</summary>
  private: HANDLE searchHandle;

};

/// <summary>Recursively deletes the specified directory and all its contents</summary>
/// <param name="path">Absolute path of the directory that will be deleted</param>
/// <remarks>
///   The path must not be terminated with a path separator.
/// </remarks>
void recursiveDeleteDirectory(const std::wstring &path) {
  static const std::wstring allFilesMask(L"\\*");

  WIN32_FIND_DATAW findData;

  // First, delete the contents of the directory, recursively for subdirectories
  std::wstring searchMask = path + allFilesMask;
  HANDLE searchHandle = ::FindFirstFileExW(
    searchMask.c_str(), FindExInfoBasic, &findData, FindExSearchNameMatch, nullptr, 0
  );
  if(searchHandle == INVALID_HANDLE_VALUE) {
    DWORD lastError = ::GetLastError();
    if(lastError != ERROR_FILE_NOT_FOUND) { // or ERROR_NO_MORE_FILES, ERROR_NOT_FOUND?
      throw std::runtime_error("Could not start directory enumeration");
    }
  }

  // Did this directory have any contents? If so, delete them first
  if(searchHandle != INVALID_HANDLE_VALUE) {
    SearchHandleScope scope(searchHandle);
    for(;;) {

      // Do not process the obligatory '.' and '..' directories
      if(findData.cFileName[0] != '.') {
        bool isDirectory = 
          ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) ||
          ((findData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0);

        // Subdirectories need to be handled by deleting their contents first
        std::wstring filePath = path + L'\\' + findData.cFileName;
        if(isDirectory) {
          recursiveDeleteDirectory(filePath);
        } else {
          BOOL result = ::DeleteFileW(filePath.c_str());
          if(result == FALSE) {
            throw std::runtime_error("Could not delete file");
          }
        }
      }

      // Advance to the next file in the directory
      BOOL result = ::FindNextFileW(searchHandle, &findData);
      if(result == FALSE) {
        DWORD lastError = ::GetLastError();
        if(lastError != ERROR_NO_MORE_FILES) {
          throw std::runtime_error("Error enumerating directory");
        }
        break; // All directory contents enumerated and deleted
      }

    } // for
  }

  // The directory is empty, we can now safely remove it
  BOOL result = ::RemoveDirectory(path.c_str());
  if(result == FALSE) {
    throw std::runtime_error("Could not remove directory");
  }
}

This code is free for the taking and you can use it however you want.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Jun
12
2012

How to Create Directories Recursively with Win32

As I just found out, the CreateDirectory function on Win32 can only create one directory at a time. If one, for example, specifies C:\Users\All Users\FirstNew\SecondNew as the directory to create, and both FirstNew and SecondNew do not exist, then CreateDirectory() fails.

That’s less than ideal for some cases. Recently, for example, I wanted my game to create the C:\Users\<Whoever>\Documents\My Games\<GameName> directory, where both My Games and <GameName> may not yet exist. Here’s a workaround:

/// <summary>Creates all directories down to the specified path</summary>
/// <param name="directory">Directory that will be created recursively</param>
/// <remarks>
///   The provided directory must not be terminated with a path separator.
/// </remarks>
void createDirectoryRecursively(const std::wstring &directory) {
  static const std::wstring separators(L"\\/");

  // If the specified directory name doesn't exist, do our thing
  DWORD fileAttributes = ::GetFileAttributesW(directory.c_str());
  if(fileAttributes == INVALID_FILE_ATTRIBUTES) {

    // Recursively do it all again for the parent directory, if any
    std::size_t slashIndex = directory.find_last_of(separators);
    if(slashIndex != std::wstring::npos) {
      createDirectoryRecursively(directory.substr(0, slashIndex));
    }

    // Create the last directory on the path (the recursive calls will have taken
    // care of the parent directories by now)
    BOOL result = ::CreateDirectoryW(directory.c_str(), nullptr);
    if(result == FALSE) {
      throw std::runtime_error("Could not create directory");
    }

  } else { // Specified directory name already exists as a file or directory

    bool isDirectoryOrJunction =
      ((fileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) ||
      ((fileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0);

    if(!isDirectoryOrJunction) {
      throw std::runtime_error(
        "Could not create directory because a file with the same name exists"
      );
    }

  }
}

This code is free for the taking and you can use it however you want.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Jun
04
2012

Visual Studio 2012 Express – Metro Only?

This post’s title says it all. I’ve just installed the Windows 8 Release Preview with Visual Studio 2012 RC. Just like in the previous release, Visual Studio 11 Beta, the Express edition does not contain any plain Win32 project templates, only ones for Microsoft’s new Metro UI.

This is a pretty scary situation for me: recently, the C++11 Standard was completed which finally makes threading in C++ bearable (when writing libraries, you no longer have to force a decision between Boost, TBB or POCO on your users). But C++11 threading was only added to Microsoft’s C++ compiler & standard library in Visual Studio 2012.

So unless Microsoft reverts the decision to no longer offer a free C++ compiler for Windows desktop applications, these are my options:

  • Buy Visual Studio 2012 Professional and exclude anybody out there who doesn’t want to shell out $500 from using my libraries. Make it harder to build any kind of team because there’s now a significant hurdle to entry. Probably be forced to modify 3rd party libraries in the future because Open Source projects will no longer test compilation of their code with Visual Studio.
  • Keep Visual C++ 2010 Express and either write my own threading wrapper (increasing dependencies of my libraries from 0 to 1) or just go with Boost and forget the rest.
  • Switch to Eclipse CDT + MingW and build my Windows desktop applications this way. That would give me C++11 threading (at least I suppose so – I couldn’t get it to work, see screenshot) but I’d have to always port anything I write to GCC (of which MingW is a port). Could be a good thing, since it lowers the barrier to port my stuff to Linux and Android.

Update: if you want to weigh in, I’ve been so bold and filed a bug report on Microsoft Connect: Support C++ Desktop Applications in Visual Studio 2012 Express.

Update2: the disaster is averted! Today, the Visual Studio blog announced that Microsoft has given in and will be offering two Express editions: The already known Visual Studio 2012 Express and, Visual Studio 2012 Express for Windows Desktop. That means it’s safe to use C++11 across the board now. GCC 4.6 has it, the modded Android NDK has it, and Visual C++ 2012 has it!

Read the rest of this entry »

Apr
07
2012

Perfectly Accurate Game Timing

These days, I designed a timing system for my game. Doesn’t really sound impressive, eh?

The problem with accurate timing, apart from hardware faults making timers change speed or jump back, is to resample a high-frequency clock running at 3+ MHz to the update rate your game is running with.

The naive approach would be to just cast the clock to a double and divide it by one 60th (if you want 60 Hz updates) of the clock’s frequency. But that’s not really such a good idea. Let me illustrate:

int main() {
  float a = 20000000;
  ++a;
  // a is still 20,000,000. The accuracy of the float has diminished so
  // much that you not only have zero decimal places, it cannot even assume
  // the value 20,000,001 -- only 20,000,002!
  
  double b = 10000000000000000;
  ++b;
  // b is still 10,000,000,000,000,000. Same reason.
}
Read the rest of this entry »

Mar
29
2012

Ogre 1.8.0 RC1 for WinRT/Metro

Ogre 3D Logo

Here’s an interesting hypothesis: when Apple started its App Store, it was the El Dorado of software developers. Now Microsoft is adding an App Store to Windows 8. The Windows user base is huge, much larger than even the number of people running around with iPhones in their pockets (some estimates I came across average to around 75 million iPhone users [1] [2] versus around 600 million Windows users [3] [4]). Even if Windows 8 adoption rates are as bad as Vista’s you could turn a mighty profit!

What better way could there be to achieve that than to publish a 3D game on the Windows App Store when most of the world’s developers are still trying to get a grasp of WinRT? :)

Of course I wanted to use an existing 3D engine, so I reviewed my options:

EngineStatus
Ogre 3D A user named Eugene on the Ogre forums already did all the work required fixing invalid API calls so Ogre compiles and validates on WinRT. This is what this post is about!
C4 Engine No word on WinRT/Metro support. C4 is based on OpenGL, but Windows App Store only allows Direct3D 11 to be used. I’ve seen someone on C4’s forums working on a Direct3D 11 renderer, so if its source is released, C4 users might get lucky.
Unity I believe Unity is well positioned for Metro support (they have an experimental Direct3D 11 renderer, I wouldn’t rule out porting Mono to WinRT either). No official statement yet and I’ll not risk betting on some kind of surprise. You can vote for Unity WinRT/Metro support here.
Axiom 3D Axiom 3D is a .NET rewrite of Ogre. Work on a SharpDX renderer is on its way, and SharpDX will support WinRT/Metro. Sadly, Axiom 3D is severely understaffed, thus, despite fantastic people like Borrillis, the massive size of the code base means it’s moving slowly.

Read the rest of this entry »

Mar
20
2012

How to Consume DLLs in a WinRT/Metro Project

Yesterday, I published a small guide on how to consume DLLs in Visual C++ that explained how to best integrate a third-party library into a Visual C++ project. This is a follow-up article for Visual Studio 11 Beta users that contains the additional steps required to consume a normal (non WinRT Component) DLL in a WinRT/Metro project.

Assuming you have the DLL integrated into a WinRT application project as explained in my previous blog post, you will notice that when you try to run the application, there will be an error message stating that the Windows Metro style application could not be activated and the output window will report a missing dependency:

Screenshot of Visual Studio 11 reporting an activation error on a WinRT/Metro application

Read the rest of this entry »

Mar
19
2012

How to Consume DLLs in Visual C++

For the C++ game programmer, there’s a huge collection of Open Source and commercial libraries available doing all kinds of things from simulating physics, reading common image formats or storing your data to rendering cutting-edge 3D graphics. But consuming those libraries in you own applications is often accompanied with a bit of hazzle since you need to point your linker to the right import libraries, copy the right DLLs into your project’s output directory and add the directory containing the matching headers to your compiler’s "include" directories.

It will get a little harder even when you target the Windows 8 App Store, where you need to provide binaries compiled for 3 platforms: x86, x64 and arm. I’ve been using C++ for over 10 years now and over time, I have come up with a method for organizing and consuming libraries that has served me very well.

Read the rest of this entry »

Mar
16
2012

IslandWar: Animating Turrets

Given that a lot of my game involves turrets attacking and defending, after setting up my water plane and a small height-mapped island in it, the next thing I attempted was to import an animated turret in a way that lets me control its orientation and elevation from code.

To start with, I already used a consistent naming scheme for the bones in all my turrets:

Screenshot of Blender showing my bone naming scheme

In short, all turrets have a bone to change their yaw that is called "Rotor". The pitch of the gun barrels is changed by "Elevators" (there can be more than one in case the turret has multiple weapon arms). Finally, each gun barrel has a bone whose name contains the word "Barrel", i.e. "UpperLeftBarrel" or "Barrel1" and an associated muzzle bone exists named identically but with "Muzzle" instead of "Barrel":

Read the rest of this entry »

Mar
13
2012

IslandWar in Unity

I decided to give an old project of mine another try. Back in 2007, after I finished my freeware game Ball Race, I ventured forth to create my first indie title, IslandWar. This is what gave rise to a lot of the classes that can now be found in my Nuclex Framework, including the GUI system that I originally wanted to avoid because I knew it would sidetrack me.

Well, combine some procrastination with a beginning burnout (at the end of 2009 I was certain that I never wanted to work with computers again) and the game was left on hold indefinitely. In the meantime, someone else even published an iPhone game by that title with a very similar concept, so that means I’ll have to find a new title if I ever publish this game.

Unity 3D Logo

Since I originally started working on IslandWar in XNA 1.0 Refresh, several XNA versions have come and gone and Unity, which I already reviewed favorably in 2007 has now gained Windows authoring support (it originally was MacOS-only) and sports a free basic edition. So given the choice between updating all of the game’s code to XNA 4.0 and SunBurn or porting it to Unity, I decided to give Unity a try.

So these are my first steps in Unity. Try not to laugh too hard :)

Read the rest of this entry »

Feb
29
2012

Windows 8 Consumer Preview

The Windows 8 Consumer Preview just went live. According to Microsoft, this is a stable public preview, not a beta.

Windows 8 Logo

I’m still in the process of downloading it, but in a presentation, Microsoft claimed a large number of changes since the Windows 8 Developer Preview last years.

Oh, and all apps in the Windows Store will be free until Windows 8 is officially released in October.

Download Links

Windows 8 Consumer Preview

Visual Studio 11 Beta for Windows 8 Consumer Preview

Read the rest of this entry »

Older posts «

» Newer posts

Social Widgets powered by AB-WebLog.com.