Archive for November 2010

Vanity: Halo Reach Player Armor Image Generator

Recently, I’ve had my hands in a project called Vanity, which is a great little application geared towards helping Halo Reach players pick out their ideal armor configuration before they start buying things in-game. Once finished, it displays the rank and credits required by the game in order to obtain the selected armor configuration, and also allows you the option to save the generated image onto your computer.

All of the content and UI was created by my buddy Nate (a more detailed and interesting description of his portion of the work can be found here at his website), and I tied everything together in code. After I initially spent a few days or so messing around with a windows forms version of the application, we decided to scrap that and use WPF instead for its more advanced presentation features. Vanity is written in C#.NET and boasts custom imaging code (see below) and a caching system created from scratch. The entire application ended up weighing in at around 130 megabytes due to the sheer amount of images (currently 3,117 to be specific) required in order to display all armor piece and color combinations.

Upon release, Louis Wu over at hbo.bungie.org mentioned Vanity in their news section and was kind enough to offer us a secondary hosting source for the application which we greatly appreciate. Bungie also recognized the utility that Vanity offered and posted about it in their blog as well. Due to the large amount of publicity following its initial release, the hbo servers experienced over one terabyte of bandwidth the day after, and another terabyte throughout the next couple of weeks. So far, there have been over 22k unique visitors and 2TB of bandwidth consumed.

If you’re interested in trying out Vanity for yourself, you can find the download link here. In order to extract the Vanity.rar archive you will need to download WinRar, and in order for Vanity to run properly, you will also need to have the .NET Framework 3.5 installed on your computer. Make sure to not change the directory structure when running the application, as it must be run in the same directory as Guardian.dll and the content directory. As usual, any comments or suggestions that you may have are always welcome.

Also, in the spirit of open source and the nature of this blog in general, I’ve included a snippet of code below containing my custom DrawImage method which has been heavily optimized for use in Vanity due to the large amount of drawing performed within. This method clocks in around twice as fast as it’s GDI equivalent Graphics.DrawImage method on my machine, and also does proper alpha blending which Graphics.DrawImage seems to fall short on. The alpha blending formula I’ve came up with performs a simple linear interpolation starting from the base alpha, but the color blending formulas were a bit more involved. I know it may be hard to read due to the heavy use of pointers and integer shifts in place of floating point math, but understand that this was a necessary evil in order to squeeze the absolute most performance possible out of it.

In order to use, you will need to pass it a canvas image, the image you wish to draw on top of that, and the area that you will be drawing in. I’ve made some pretty big assumptions on these arguments for the pixel format and dimensions in particular, so it may require some minor tweaking depending on your specific needs, but it should be a good starting point if you need something similar in one of your projects.

private static void DrawImage(Bitmap canvas, Bitmap render, Rectangle area)
{
    if (canvas != null && render != null && area != null)
    {
        int canvasWidth = render.Width;
        int canvasHeight = render.Height;
        int xMin = area.X;
        int xMax = xMin + area.Width;
        int yMin = area.Y;
        int yMax = yMin + area.Height;
        BitmapData renderBits = render.LockBits(new Rectangle(0, 0, canvasWidth, canvasHeight), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
        BitmapData canvasBits = canvas.LockBits(new Rectangle(0, 0, canvasWidth, canvasHeight), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

        unsafe
        {
            for (int y = yMin; y < yMax; y++)
            {
                byte* ptrRender = (byte*)renderBits.Scan0 + y * renderBits.Stride;
                byte* ptrCanvas = (byte*)canvasBits.Scan0 + y * canvasBits.Stride;
                for (int x = xMin; x < xMax; x++)
                {
                    byte alpha = ptrRender[(x << 2) + 3];
                    if (alpha > 0)
                    {
                        // colorResult = newAlpha * newColor + (1 - newAlpha) * canvasColor
                        ptrCanvas[(x << 2)] = (byte)((alpha * (ptrRender[(x << 2)]) + (256 - alpha) * (ptrCanvas[(x << 2)])) >> 8);
                        ptrCanvas[(x << 2) + 1] = (byte)((alpha * (ptrRender[(x << 2) + 1]) + (256 - alpha) * (ptrCanvas[(x << 2) + 1])) >> 8);
                        ptrCanvas[(x << 2) + 2] = (byte)((alpha * (ptrRender[(x << 2) + 2]) + (256 - alpha) * (ptrCanvas[(x << 2) + 2])) >> 8);

                        // alphaResult = oldAlpha + (1 - oldAlpha) * newAlpha
                        ptrCanvas[(x << 2) + 3] = (byte)(((ptrCanvas[(x << 2) + 3] << 8) + (256 - ptrCanvas[(x << 2) + 3]) * alpha) >> 8);
                    }
                }
            }
        }
        render.UnlockBits(renderBits);
        canvas.UnlockBits(canvasBits);
    }
}

Forza Studio: Forza 3 .Carbin Resource Extraction Tool

The history behind this utility started when a good friend of mine requested that I attempt to extract some of the Forza 3 car model resources (.carbin) from the game so that he could use them in some of his renders. While searching the interwebs for any information related to the subject, I came across the XeNTaX community, and started this thread in hopes that others would join in on my efforts. Their members were quite helpful (ajmiles in particular for his initial help with vertex decoding) at reducing my time spent during the research process. Soon enough I had created a nice little utility for extracting the contents of the Forza 3 .carbin model resources from the game.

Forza studio provides you with the ability to open up entire Forza 3 car or track zip files, as well as the individual .carbin or track .bin files if you manually extract them from the archive.  It also allows for selective piece extraction and exports the selected items into the Wavefront OBJ model format for easy importation into almost all model editing applications.  Use the WASDQE keys to move the camera and the arrow keys to change the look direction.  Right click the viewport to bring up a context menu where you can change other rendering options.

I’ve kept this Visual Studios 2008 C#.NET project open source throughout it’s entire development so that anyone can do what they will with it and pick up wherever I leave off. Since I was researching and developing at the same time, I apologize for the source being a bit messy in parts, but it is what it is. I’ve attached the two most recent builds below with source included as usual. The first one is probably the most stable build for car extraction, and the second one I started refactoring and added partial support for track extraction (and probably broke a few things in the process). In order to run this application on your computer you will need to have the Microsoft .NET 3.5 and Microsoft XNA 3.1 frameworks installed. If you have any questions or problems getting this to run on your machine, give me a shout, and I’ll see what I can do to help you out.

Downloads
Forza Studio (5.29.10) (4736)
Forza Studio (7.9.10) (5719)

Yelo: Halo 2 Xbox Trainer


Here’s the first of a few older projects I’ll end up posting and open sourcing on this site just for historical purposes. The Halo games and Xbox console in general are what originally got me involved in software development, so I figure I’ll post what started it all first.

It began in December of 2004 with me installing a mod-chip on my Xbox which basically turns it into a media center and also allows for the execution of homebrew software among other things. During that process, I stumbled across the Halo 2 map editor Ch2r, which provided the basic ability to open Halo 2 .map files and modify the resources within. Halo maps use a tag-based system for storing information related to everything from vehicle and weapon settings to particle effects or raw resources such as models, images, and sounds. Ch2r had an xml plugin system that was used to identify offsets and data types of the information stored in each of those tags. Since most plugins were still in their infancy, I decided to teach my self how to read the tags extracted by Ch2r in a hex editor and identify some of the tag values for the rest of the Halo modding community to use in their mods.

Eventually, I became interested in the Halo 2 game engine itself, and started learning x86 assembly so I could make a simple third person camera hack similar to the one bitterbanana made for the original Halo on PC. With the help of Acidflash, EvoxT, and a few others in the scene, I started picking up the knowledge needed to create and inject assembly code into Xbox games. On and off over the course of a few years, I spent lots of time researching the Halo 2 game engine by locating things in memory, stepping through the code in a debugger, studying its disassembly, and documenting all of my findings. The features in Yelo are only a small collection of the things I’ve found researching throughout the years, but it still provides users with plenty of options and a good overall summary of some of the useful things that can be done in the game. Bungie must have also recognized the large amount of replay value these kinds of features offer, since they’ve included something similar to Yelo in all of their new titles following Halo 2, allowing you to fly around in the levels and take screen shots. I only wish other game developers in the industry would catch on and do the same, as exploring some of these virtual worlds can be very fun and interesting.

If you don’t know how to use trainers (hell, I barely remember anymore :P), I suggest you check out Xbox-Scene or MaxConsole for further information. Along with the trainer, you must also transfer over the “config_v1.5.inc” file to “E:/TDATA/4D530064/”. If you fail to do so the trainer will not function properly and immediately go into wireframe at the press of a button. Every combo and a few other options can be edited via the trainer config file. Note that some of the cinematic and lighting options are experimental so if you don’t like them, don’t use them :P

This trainer will only work with the Xored ETM Launcher v2.2 (due to memory allocation issues) so be sure to download that before use. Please use Aequitas’ UberScreenshotTool below for screenshot recovery. Use the supplied config editor below if you wish to change things. For those of you that have been complaining about the 1.1 update and wish to still use the new maps, download and apply Snave’s mainmenu patch below.

Configuration:
============
dpad-up = increase cam speed*
dpad-down = decrease cam speed*
dpad-left = decrease look speed*
dpad-right = increase look speed*
lthumb+rthumb = toggle timefreeze
lthumb+dpad-up = increase vertical look shift
lthumb+dpad-down = decrease vertical look shift
lthumb+dpad-left = increase horizontal look shift
lthumb+dpad-right = decrease horizontal look shift
lthumb+black = disable cinematic mode
lthumb+white = enable cinematic mode
lthumb+back = stillcam
rthumb+dpad-up = decrease camera depth
rthumb+dpad-down = increase camera depth
rthumb+dpad-left = increase fov
rthumb+dpad-right = decrease fov
rthumb+A = save camera state (shifts, fov, and depth)
rthumb+B = load camera state (shifts, fov, and depth)
rthumb+X = save gamestate
rthumb+Y = load gamestate
rthumb+back = cutscene camera
back+dpad-up = first person perspective
back+dpad-down = third person perspective
back+dpad-left = chasecam perspective
back+dpad-right = devcam perspective
black+dpad-up = increase z cam shift
black+dpad-down = decrease z cam shift
black+dpad-left = decrease y cam shift
black+dpad-right = increase y cam shift
white+dpad-down = auto hires grabber*
white+dpad-left = vidcap (10fps)
white+dpad-right = 360 degree shot*
white+back = screenshot
rtrigger = move up along z axis*
ltrigger = move down along z axis*
A+dpad-up = letterbox toggle
A+dpad-down = wireframe
A+dpad-left = hud toggle
A+dpad-right = ai toggle
A+black = decrease ambient light brightness
A+white = increase ambient light brightness
B+dpad-up = teleport to current camera coordinates
B+dpad-left = decrease gamespeed
B+dpad-right = increase gamespeed
X+dpad-up = secondary light vertical increase
X+dpad-down = secondary light vertical decrease
X+dpad-left = secondary light horizontal decrease
X+dpad-right = secondary light horizontal increase
X+black = decrease secondary light brightness
X+white = increase secondary light brightness
Y+dpad-up = primary light vertical increase
Y+dpad-down = primary light vertical decrease
Y+dpad-left = primary light horizontal decrease
Y+dpad-right = primary light horizontal increase
Y+black = decrease primary light brightness
Y+white = increase primary light brightness

* while in devcam

Checklist:
=========
-Have you read this entire post?
-Are you using the Xored v2.2 launcher with correct config settings?
-Did you transfer over the “config_v1.5.inc” to “E:/TDATA/4D530064/”?
-Did you disable the Autoupdate in your trainer options menu?
-Do you only have one controller plugged in, and is it in the first controller port?
-Do you have a semi-functional brain that posesses the knowledge required to run such a fine piece of software?

Downloads
Yelo: Halo 2 Xbox Trainer (1472)
Yelo Config Editor (1298)
Snave's Main Menu Patch (1230)
UberScreenshotTool (1114)