Windows 7 Volume Mixer, Ventrilo and you.

Posted in Gaming on April 26th, 2012 by Mirzero

Recently, I have been playing Super Monday Night Combat by Uber Entertainment (which is totally awesome, and also free! Check it out!), and I kept running into this really strange and really annoying problem.

I play with a group of friends and we use Ventrilo (also totally awesome and free) to talk to each other while we play. Unfortunately, for a reason that eluded me until now, the volume of Ventrilo would seemingly randomly drop to about 20% of full volume, making it extremely hard to hear anyone. Restarting Ventrilo fixed the problem, but that’s a little difficult in the middle of a match!

It turns out that Windows 7 has this setting where when it detects what it thinks is voice communications, it reduces the volume of certain things by 80%. Presumably it was detecting the in-game voice chat, or something, and reducing the volume of Ventrilo accordingly. Except it left the volume low.

Easy fix! Go into Control Panel, into Sounds, click on the Communications tab, and set it to Do Nothing. Viola! Problem solved!

Tags: , , , , ,

Avoiding hard-coded strings in your code.

Posted in Game Development, Software Development on August 14th, 2011 by Mirzero

I’ve been experimenting with XNA recently, attempting to develop my own game. One of the tools that XNA offers is the concept of a Game Content Project, which allows you to shove all of your content (art and audio resources, etc) into a single project which gets compiled to some form of resource file for you. I don’t know all the details of how it works under the hood, but it seems to make life a lot simpler.

I ran into a major complaint while getting started with Game Content Projects, however; in the simplest use case it requires the use of hard coded strings to point to the various resources. For example, imagine that my Game Content project has a Textures folder in it, and inside that folder is defaultTexture32.png.

Game Content Project file structure

An example of the Game Content Project's file structure.

Now, let’s imagine that I want to render this texture to the screen in my game. To do this, I’ll need to create a Texture2D and load an image resource into it, and then draw it.
The naive approach I’m complaining about ends up looking like this:

_backgroundTexture = Content.Load("Textures\defaultTexture32");

You’ll notice I had to hard code the relative path and file name of the resource as an embedded string. I hate embedding strings… so I set about trying to find a solution:

Enumeration.
I started with the idea of creating a static class that was basically just a bunch of strings named the same as their content. Virtually an enum, but with a little bit different structure. It was an improvement over hard coding but it didn’t allow for things like backslashes, and it didn’t allow me to maintain the directory hierarchy.

Nested Namespaces.
To fix the hierarchy problem, I considered the idea of creating a set of nested namespaces for each directory, and putting classes inside them to represent each file. This maintained the hierarchy properly, but it still wasn’t perfect. This method would have meant that every time I added, renamed, or deleted a resource I would have had to go and add, edit, or remove some namespaces and classes. Maintenance nightmare. There’s an even deeper problem with this solution, which is that if I ever forgot to update the objects to reflect changes to obscure resources, I could eventually end up crashing the application with missing file exceptions… this could easily go unnoticed for a long time depending on where I made the mistake. Terrible!

Enter T4.
T4, which stands for Text Template Transformation Toolkit is a Code Generation tool.  In my professional life, I’ve worked with T4MVC, which is a T4 template that helps generate an object structure for MVC views, controllers, view models, actions, etc. for ASP.Net MVC applications. It works really well, but it doesn’t project a file structure into a set of objects; it projects other classes and stuff. It seemed like T4 still might save me. For all my experience with T4MVC however, I had only ever used templates, not actually written them.
I hacked about with T4 for a while, but I ran into some more issues. The biggest one was that I didn’t really want to troll the entire file structure… I really only wanted to work with the files that were currently part of the Visual Studio solution.

Enter DTE.
DTE, which stands for something I don’t remember, is a tool for automating certain Visual Studio tasks related to projects and solutions. I don’t really know the depth of it’s uses, but I quickly discovered it could help me traverse the solution and projects instead of dealing with the file system directly. A short while later, I had a solution that, for the most part, did what I wanted.

The solution.
Ultimately I ended up with a T4 template that uses DTE to traverse the project items, and generates the code for a set of namespaces and classes automatically. This means that any time I change the Content project, I just have to re-run the T4 template, and it will regenerate all of my namespaces and classes for me. Nice and easy! This solution also has the benefit of catching virtually any resource file related screwups at compile time instead of runtime, which is a really big deal.

The code.
I’m going to provide the T4 template below. You’re welcome to use it for whatever you want to free of charge, and without limitations. Some recognition is always nice, but it’s not required. At the very top of the file you will notice a “Global Variables (Config)” section with a pair of variables in it. The first one defines the name of the content project you want to scan (mine is GameContent) and it defines the list of file extensions that you want to include in the generated object structure. Currently I’m really only working with PNGs.

Before you use this code, please remember that I’ve never written T4 templates before, or worked with DTE. I’m certain there are at least a few bugs hanging out in my code, though none that I’ve noticed yet, and I’m aware of a couple places for drastic improvement, but I haven’t gotten around to fixing it all yet. Basically, use at your own risk. I make no promises about it’s usefulness or safety, even though it seems to work for me.

If you find any bugs, want to propose bugfixes, or want to propose enhancements, please let me know in the comments or by email. I intend to maintain this as a side project as I continue with my game development work, and I might eventually shove it up on CodePlex or something similar.

The code for real.

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="EnvDTE" #>
<#@ import namespace="EnvDTE"#>
<#@ import namespace="System"#>
<#@ import namespace="System.IO"#>
<#@ import namespace="System.Collections.Generic"#>
<#
	// Global Variables (Config)
	var ContentProjectName = "GameContent";
	List<string> AcceptableFileExtensions = new List<string>(){".png"};

	// Program
	IServiceProvider serviceProvider = (IServiceProvider)this.Host;
	DTE dte = (DTE) serviceProvider.GetService(typeof(DTE));

    Project activeProject = null;

	foreach(Project p in dte.Solution.Projects)
	{
		if(p.Name == ContentProjectName)
		{
			activeProject = p;
			break;
		}
	}

	emitProject(activeProject, AcceptableFileExtensions);

#>

<#+
private void emitProject(Project p, List<string> acceptableFileExtensions)
{
	this.Write("namespace GameContent\r\n{\r\n");
	foreach(ProjectItem i in p.ProjectItems)
	{
		emitProjectItem(i, 1, acceptableFileExtensions);
	}
	this.Write("}\r\n");
}

private void emitProjectItem(ProjectItem p, int indentDepth, List<string> acceptableFileExtensions)
{
	if(String.IsNullOrEmpty(Path.GetExtension(p.Name)))
	{
		emitDirectory(p, indentDepth, acceptableFileExtensions);
	}
	else if(acceptableFileExtensions.Contains(Path.GetExtension(p.Name)))
	{
		emitFile(p, indentDepth);
	}
}

private void emitDirectory(ProjectItem p, int indentDepth, List<string> acceptableFileExtensions)
{
	emitIndent(indentDepth);
	this.Write("/// Directory: " + Path.GetFullPath(p.Name) + "\r\n");
	emitIndent(indentDepth);
	this.Write("namespace " + Path.GetFileNameWithoutExtension(p.Name) + "\r\n");
	emitIndent(indentDepth);
	this.Write("{" + "\r\n");

	foreach(ProjectItem i in p.ProjectItems)
	{
		emitProjectItem(i, indentDepth + 1, acceptableFileExtensions);
	}

	emitIndent(indentDepth);
	this.Write("}" + "\r\n" + "\r\n");
}

private void emitFile(ProjectItem p, int indentDepth)
{
	emitIndent(indentDepth);
	this.Write("/// File: " + Path.GetFullPath(p.Name) + "\r\n");
	emitIndent(indentDepth);
	this.Write("public static class " + Path.GetFileNameWithoutExtension(p.Name) + "\r\n");
	emitIndent(indentDepth);
	this.Write("{" + "\r\n");

	emitIndent(indentDepth + 1);
	this.Write("public static readonly string Path      = @\"" + Path.GetDirectoryName(Path.GetFullPath(p.Name)) + "\";" + "\r\n");
	emitIndent(indentDepth + 1);
	this.Write("public static readonly string Extension = @\"" + Path.GetExtension(p.Name) + "\";" + "\r\n");
	emitIndent(indentDepth + 1);
	this.Write("public static readonly string Name      = @\"" + Path.GetFileNameWithoutExtension(p.Name) + "\";" + "\r\n");

	emitIndent(indentDepth);
	this.Write("}" + "\r\n" + "\r\n");
}

private void emitIndent(int depth)
{
	for(int i = 0; i < depth; i++)
	{
		this.Write("\t");
	}
}
#>

 

Welcome to my blog!

Posted in Uncategorized on May 31st, 2011 by Mirzero

This blog will serve as a repository of links, thoughts, rants and things learned.