Category Archives: Games

PhaseShift and Frets On Fire X Song Packs

0
Filed under Arcade, AutoHotKey, Frets On Fire, Games, Guitar, Stepmania

PhaseShift is an excellent freeware (not open source yet, as far as I can tell, but here’s hoping) version of the RockBand genre of games. It’s even more interesting in that it can interoperate with guitar controllers, game drum kits, vocals, keyboards, MIDI, and even step pads (for Dance Dance Revolution style games, all at the same time!).

Very cool stuff.

What’s even better is that it can read both Frets on Fire songs as well as Stepmania format songs.

Mostly.

There are a ton of great song packs available out on the web, and most that I’ve found work seamlessly with PhaseShift. However, I’ve run into a bunch that do not.

The problem appears to be with the NOTES.MID file (the file that contains all the midi notes that is used by the game to show the onscreen “notes”).

After some digging using a hex editor (my favorite right now is Tiny Hexer), I discovered that in all the cases that failed, the NOTES.MID file appears to contain extranous junk. In many cases, it was a string of keyboard key names, in others it was code snippets. I’m guessing that whatever MIDI editor was used to generate those MID files didn’t properly clear garbage out or compact memory.

At any rate, FoFix appears to ignore the extra junk but PhaseShift does not.

Enter EOF

EOF is a song editor for “fretting” songs for use with rhythm games like Frets On Fire and PhaseShift. The latest version even has specific features to take advantage of elements of PhaseShift that don’t exist in Frets On Fire.

I found that simply using FILE – IMPORT MIDI and importing the NOTES.MID file into EOF, then immediately SAVING the file (and clicking YES to the prompt of “The file hasn’t changed, Save Anyway?”), fixed the problem for every single song I tried it on.

It worked so good in fact, that I wrote up a simple script in AutoHotKey to just run through all the files in a directory and perform those magic steps on them

/*
Convert songs via EOF
*/

F12::
Reload
return

F11::
loop, 1 {
    ;match anywhere in title
    SetTitleMatchMode, 2
    IfWinExist \Songs\
    {
        WinActivate
    }
    else
    {
        msgbox No Window
        return
    }

    ;Copy full path name
    sleep 500
    SendPlay ^+C
    sleep 500
    SendPlay ^+C
    ;msgbox %clipboard%

    ;Over to EOF
    IfWinExist EOF -
    {
        WinActivate
    }
    else
    {
        msgbox No EOF
        return
    }

    sleep 500
    SendInput {F6}{F6}
    sleep 500
    SendInput %clipboard%{enter}
    sleep 1000
    Send ^s
    sleep 500
    Send ^s!FS
    sleep 200
    SendInput Y
    sleep 200
    SendInput Y

    ;Back to DirOpus
    IfWinExist \Songs\
    {
        WinActivate
    }
    else
    {
        return
    }

    sleep 500
    SendPlay {down}

}

Change the loop value from 1 to some count if you want to run it through more than one song at a time.

To explain:

The F12 key I’ve mapped to a reload just to make editing this script easier. It’s not necessary for actually running the script.

The F11 key hooks to the secret sauce.

I used the SEARCH feature in Directory Opus to list only the NOTES.MID files from all songs in all subdirectories of a folder I was targeting. If you don’t have DirOpus, you’ll need to recode the script to accommodate some other logic for getting the list of full pathnames to process.

The script starts by activating the DirOpus window and copying the full path to the selected NOTES.MID file.

Then it switches to EOF, (which needs to already be loaded), and performs the FILE – IMPORT function, pasting in the filename of NOTES.MID.

It then immediately does a FILE – SAVE (and supplies a few Y keypresses to answer the “save anyway” prompt.

And finally, it switches back to DirOpen and moves down to the next file.

It’s a hack to be sure. But it worked a treat for me.

Rock on!

Frets On Fire X From Source Code

0
Filed under Games, Python

poseNOTE: In the process of putting together this post, I discovered both the game PhaseShift, and a fantastic theme for it based on RockBand 3. PhaseShift appears to be everything I was looking for in modifying FoFix and a WHOLE LOT MORE. I pressed on with this post for two main reasons:

  1. It might serve to help anyone else who may be interested in continuing on with more development on FoFix
  2. I had a lot of fun getting everything together and just seeing it work from source.

Still, I highly recommend checking out PhaseShift and the themes that are available for it. There seems to be a lot more work going on with it these days than any of the other rhythm games out there.

If you haven’t played it, Frets on Fire is a RockBand clone from back around 2009. You can read more about the genesis of the game here.

It’s written in Python and open source, so there have been a number of mods made to the original game over the years.

By far the best, in my opinion, is the Frets on Fire X mod, usually called FoFix. Tons of great changes and improvements, plus a fantastic looking theme called ‘RockBand’.

The unfortunate part is the FoFix (and Frets on Fire in general) appear to have fallen by the wayside in terms of people working on them. That’s really too bad, as

it’s a fantastic game which works quite seamlessly.

Still, as good it as it, it could always be better, right?

Features

Really, all I set out to do was add code to the song selection list that would show what instruments were available in each song, without having to actually pick the song and then getting a “This song has no drum part” message. Pretty simple stuff. But this is Python, and open source, and while I’ve worked with open source before, Python was a new beast for me to tangle with.

Getting Organized

If you’re like me, you already have a copy of FoFix installed, it’s just that you run the EXE version of the game, and not the source code version.

If you want to make any changes, you’ll need to be running from the source code itself. That’s what all this is about.

First things first though. This all might not be strictly necessary, but I don’t want to wreck my playable install of the game, so…

  1. Copy the entire FoFix installation to somewhere else, I created a folder called FoFix35 (since 3.121 was the current version).  However, If you have a LOT of songs in your \data\songs folder, don’t copy all of them. There’s no need. Just a few will do. So, at this point, you should have 2 root folders somewhere:
    \FoFix (your original Frets On Fire X installation)
    \FoFix35 (the copy, minus most of the songs)
  2. Create a \FoFix35\src folder if it doesn’t already exist (this is where you’ll want the source files)
  3. Create a \FoFix35\installs folder (this is where I downloaded all the necessary files, see the next section)

The Downloads

Download all these files into the installs folder you created above.

First, the code. You’ll likely want the most recent, active version of FoFix, which, as far as I can tell is 3.121

https://codeload.github.com/fofix/fofix/zip/Release_3.121

Python (Duh, right? You’ll need the 2.6 version)

https://www.python.org/ftp/python/2.6.6/python-2.6.6.msi

PIL (Python Imaging Library, you’ll want 1.1.6, not 1.1.7!)

http://effbot.org/media/downloads/PIL-1.1.6.win32-py2.6.exe

PyAudio

http://people.csail.mit.edu/hubert/pyaudio/packages/pyaudio-0.2.4.py26.exe

PyGame (I used the 1.9.2a version, but if that doesn’t work for you, try installing 1.9.1 over it)

http://www.lfd.uci.edu/~gohlke/pythonlibs/zit7bosa/pygame-1.9.2a0.win32-py2.6.exe

http://pygame.org/ftp/pygame-1.9.1.win32-py2.6.msi

PyOpenGL

http://www.lfd.uci.edu/~gohlke/pythonlibs/zit7bosa/PyOpenGL-3.1.0b2.win32-py2.6.exe

PyOpenGL Accelerator

http://www.lfd.uci.edu/~gohlke/pythonlibs/zit7bosa/PyOpenGL-accelerate-3.1.0b2.win32-py2.6.exe

PyWin32

http://softlayer-dal.dl.sourceforge.net/project/pywin32/pywin32/Build216/pywin32-216.win32-py2.6.exe

The Win32 Dependency Pack

https://fofix.googlecode.com/files/fofix-win32-deppack-20130304.zip

And finally, NumPy (Note: you’ll want this version in particular, older versions didn’t work for me)

http://softlayer-dal.dl.sourceforge.net/project/numpy/NumPy/1.8.1/numpy-1.8.1-win32-superpack-python2.6.exe

 

Installing Everything

First, unzip the Source code zip file into the \src folder you created above. When done, you should have

\FoFix35\src\midi

\FoFix35\src\scripts

\FoFix35\src\win32

plus a bunch of *.py files in the \FoFix35\src folder itself

 

Next, dblclick the Python installation exe and work your way down the list above, till you get to the Win32 dependency pack. Just accept the defaults and you should be able to just install each one after the other.

The dependency pack itself is a zip file that needs to be unpacked in a specific spot.

The zip contains a root folder, ‘deps’. This ‘deps’ folder should be unpacked into:

\FoFix35\src\win32

such that when you’re done, you end up with:

\FoFix35\src\win32\deps

and this deps folder contains ‘bin’, ‘include’ and ‘lib’ folders.

Finally, finish up with the numpy package.

Checking it out

If everything has gone well, you should be able to navigate to

\FoFix35\src\scripts

and run

RunFofFromSources.bat

FoFix should compile and open its normal intro window.

If it doesn’t, be sure to check the log file

\FoFix35\src\fofix.log

This should give you a pretty good indication of what’s gone wrong.

Wrapping Up

If things do go wrong, first check the log I mentioned above.

I ran into several issues while working through this process.

  • I got the wrong versions of some libraries, based on outdated information on the web (Yeah, this post might eventually end up in that same boat!).
  • I started with the wrong version of Python (2.4, you need 2.6).
  • NumPy gave me some issues, in that I didn’t have the right version.
  • The Python Imaging Library I had to back out to an older rev to get functioning

I stuck with the 32bit version of everything. It might be possible to get 64 bit working, but I didn’t go that route.

I’ve played FoFix for almost 4 years now, using 2 Ashley Rock Axe wireless controllers, as well as a Red Octane wireless drum controller. Great fun! And now I can experiment with some Python coding to boot!

Calling C Object Methods from VB.Net

0
Filed under .NET, amBX, Games, Hardware, VB Feng Shui

image I’ve been playing recently with the amBX ambient effects library and devices.

Essentially, it’s an effects platform that allows you to easily create light, wind and rumble effects to coordinate with what’s going on on-screen, in a game, in media players, or what-have-you. The lighting effects are nothing short of fantastic. The rumble and fan effects…. meh. They’re interesting, but I’m not sure where that’ll go.

Regardless, the API for amBX is all C style objects, which means essentially an array of function pointers to the methods of the object; not really an API that VB.net likes to consume. Be sure to grab the amBX developer kit here. You’ll also need to core amBX software available from the main website. Finally, play around with the “Virtual amBX Test Tool”. It’ll allow you to experiment with all the amBX features and functions without having to buy anything at all. Of course, eventually you’ll want to get at least the starter kit, with the lights. But it’s not necessary to begin experimenting.

Hats off to Philips for making this possible!

image

Here’s an example of the structure definition from the amBX.h header file that comes with the API (I’ve clipped out comments and other bits):

struct IamBX {
    amBX_RESULT (*release) (struct IamBX * pThis);
    amBX_RESULT (*createLight) (struct IamBX * pThis,
                                amBX_u32 loc,
                                amBX_u32 height,
                                struct IamBX_Light** ppLight);
....

As you can see, each element in the structure is made up of a pointer to a function. The various functions all take, as their first argument, a pointer back to this structure. Under the covers, this is how virtually all object oriented languages function, it’s just the the compiler usually hides all this nasty plumbing so you don’t have to deal with it regularly.

But this presents a problem. VB.net is “managed” code, and as such, it likes things to be wrapped up in nice “managed” bits. There are plenty of good reasons for this, but these function pointers are decidedly not nice and tidy managed bits! So, what to do?

One solution is the approach Robert Grazz took here. It’s a solid solution, no doubt, and I learned a lot from looking at his approach, but, this being VBFengShui, I wanted that same functionality in native VB.net with no additional dll files hanging around!

Delegates to the Rescue!

A delegate in .net is essentially a managed function pointer. In VB.net, they’re most commonly used to handle events, but you wouldn’t really know it, because VB’s compiler does a good job of hiding all that plumbing from you. However, unlike VB6 and earlier, in VB.net, all the plumbing can, if you’re willing, be “brought into the daylight” and used however you want.

There are many, many discussions about delegates for VB.net out on the web. A really good Introduction to the concepts by Malli_S is on codeproject, so I won’t rehash the basics here.

The problem is, delegates in VB.net tend to be generated by using the AddressOf operator, and I already had the function addresses (they’re in that C structure). I just needed to get a delegate that would allow me to call it.

Some Googling turned up several good posts that provided pointers, including this one on StackOverflow. But it wasn’t exactly all the steps necessary.

Getting the C Structure

The first step toward getting something working with amBX is to retrieve the main amBX object. You do this through a standard Windows DLL call.

<DllImport("ambxrt.dll", ExactSpelling:=True, CharSet:=CharSet.Auto)> _
        Public Shared Function amBXCreateInterface(ByRef IamBXPtr As IntPtr, ByVal Major As UInt32, ByVal Minor As UInt32, ByVal AppName As String, ByVal AppVer As String, ByVal Memptr As Integer, ByVal UsingThreads As Boolean) As Integer
        End Function

Assuming you have the ambxrt.dll file somewhere on your path or in the current dir, the call will succeed, but what exactly does that mean?

Here’s an example of a call to it in C:

    if (amBXCreateInterface(
            &pEngineHandle,
            majorVersion, minorVersion,
            (amBX_char*)cAppName.ToPointer(), (amBX_char*)cAppName.ToPointer(),
            nullptr, false)
        != amBX_OK)

Essentially, you pass in the Major and minor version numbers of the Version of amBX you need, and two strings indicating the name of your app and the version of your app. No problems with any of that. But that &EngineHandle is the trick.

It means that this call will return a 4 byte pointer to a block of memory that contains the amBX object structure, which is, itself, an array of 4 byte function pointers to the various methods of the amBX object. Therefore, in VB.net, that argument is declared ByRef IamBXPtr as IntPtr.

Now, we need a place to store that “structure of pointers.” Going through the ambx.h file, I ended up with a structure that looks like this:

        <StructLayout(LayoutKind.Sequential)> _
        Private Structure IamBX
            Public ReleasePtr As IntPtr
            Public CreateLightPtr As IntPtr
            Public CreateFanPtr As IntPtr
            Public CreateRumblePtr As IntPtr
            Public CreateMoviePtr As IntPtr
            Public CreateEventPtr As IntPtr
            Public SetAllEnabledPtr As IntPtr
            Public UpdatePtr As IntPtr
            Public GetVersionInfoPtr As IntPtr
            Public RunThreadPtr As IntPtr
            Public StopThreadPtr As IntPtr
        End Structure

That StructLayout attribute is particularly important. It tells the compiler that the structure should be layed out in memory JUST AS it’s declared in source code. Otherwise, the compiler could possibly rearrange elements on us. With Managed Code, that’d be no problem, but when working with unmanaged C functions, that would not be a good thing!

And finally, we need a way to retrieve that function pointer array and move it into the structure above, so that it’s easier to work with from VB.net. That’s where the System.Runtime.InteropServices.Marshal.PtrToStructure function comes in. This routine will copy a block of unmanaged memory directly into a managed structure.

Private _IamBX As IamBX
Private _IamBXPtr As IntPtr
...

amBXCreateInterface(_IamBXPtr, 1, 0, “MyAppName”, “1.0”, 0, False)

_IamBX = Marshal.PtrToStructure(_IamBXPtr, GetType(IamBX))

And presto, you should now have the _IamBX structure filled in with the function pointers of all the methods of this C “Object”.

Calling the C Function Pointer

At this point, we’ve got everything necessary to call the function pointer. Take the CreateLight function. The C prototype for this function is shown at the top of this page. As arguments, it takes a pointer back to the amBX structure, 2 32bit integers describing the location and height of the light source, and it returns are pointer to another structure, in this case, an amBX_Light structure, which contains another set of function pointers, just like the amBX structure described above.

First, we need to declare a delegate that matches the calling signature of the CreateLight C function we’ll be calling:

<UnmanagedFunctionPointer(CallingConvention.Cdecl)> _
Private Delegate Function CreateLightDelegate(
         ByVal IamBXPtr As IntPtr, _
         ByVal Location As Locations, _
         ByVal Height As Heights, _
         ByRef IamBXLightPtr As IntPtr) As amBX_RESULT

The key points here are:

  1. Make sure you have the CallingConvention attribute set right. Most C libraries will be CDECL, but some libraries are STDCALL.
  2. Make sure your parameter types match, especially in their sizes. Not doing this will lead to corrupted called or system crashes.

Now, create a variable for the delegate and use the Marshal.GetDelegateFromFunctionPointer function to create a new instance of the delegate, based on the applicable function pointer. Since the function pointer for the CreateLight function is stored in the CreateLightPtr field of the _IamBX structure, we pass that in as the pointer argument.

IMPORTANT NOTE: There are 2 overloads for the Marshal.GetDelegateFromFunctionPointer  function. Be sure to use the one what requires a second argument of the TYPE of the delegate to create. Using the other one will fail at runtime because it won’t be able to dynamically determine the type of delegate to create.

Next, call the function via the delegate, just as if it was a function itself.

Finally, use Marshal.PtrToStructure again to copy the array of function pointers returned into another structure, this one formatted to contain the function pointers of the Light object that just got created.

Dim d As CreateLightDelegate = Marshal.GetDelegateForFunctionPointer(_IamBX.CreateLightPtr, GetType(CreateLightDelegate))
Dim r = d(_IamBXPtr, Location, Height, _IamBXLightPtr)
_IamBXLight = Marshal.PtrToStructure(_IamBXLightPtr, GetType(IamBX_Light))

The amBX library is much, much larger than just this little bit I’ve shown here. Once I get the entire thing coded up, I’ll be presenting it here as well.

But in the meantime, if you have a need to interface with C style function pointer objects, don’t let anyone tell you it can’t be done in VB.net

Final Note

As you may or may not have guessed, amBX is a 32bit library and its interfaces, functions and arguments all live in 32bit land. If you’re working with VS2008, BE SURE to set your project to the x86 platform, and NOT “Any CPU” or “x64”! The default, for whatever reason is “Any CPU”, which means things will work properly when run under 32bit windows, but things won’t work well at all if run under a 64bit OS.

Duke Lives

0
Filed under Games

image Sad news from several days ago. Apparently, 3D-Realms, the team behind the original Duke Nukem 3D, has called it quits.

I’d known the follow-up to the original was long overdue, but I guess there were more problems than just getting the code done.

At any rate, in reading about this story, I discovered something very cool. A complete port of the original Duke Nukem 3D, targeted for Windows, called EDuke32, using all modern support code, including updated audio drivers, and support for OpenGL rendering engines.

Not only that, but there’s a whole fan base that have re-rendered all the level textures in full hi res! The difference is absolutely astonishing and really breaths new life into a wonderful old game. I actually found a deathmatch level I’d designed back in the day (sept 22, 1996 to be precise, the file still had the last modified date on it), loaded it up with EDuke32 and, with the textures from the hi-res pack, it looked spectacular. Far better than it ever did originally.

If you were a fan of Duke back in the day, it’s definitely worth the download.

Tiny PC

0
Filed under Arcade, Games, Hardware

image Here’s a slick little gizmo.

The VIA ArtiGo mini pc.

It’s a full PC, with space for a 2.5″ HD, onboard graphics and audio, and up to 1 GB ram. And it fits in a 5.25″ harddrive bay.

I know, I know, there are case modders out there making still smaller PC’s, but this one’s 300$ at Fry’s, no added bother, headaches, or a Dremel necessary.

The specs are decent, but I wouldn’t want to code on it. However, you could probably make a decent Mame cab out of just about anything you have lying around and I’m guessing this would be plenty powerful enough to drive it, not to mention it’d fit just about anywhere without even a second glance.

Grid Wars 2

0
Filed under Arcade, Games, VB Feng Shui

Ok, nothing to do with Visual Basic, but, you gotta come up for air sometimes!

It’s been a while since a video game really wowed me.

I mean, there’s lots of slick 1st person shooters out there now and with some of the heavy iron running around now, the graphics can make “Toy Story” almost look like “Dragon’ Lair.”

Still, nice graphics only go so far. And 1st person shooters are starting to see a little stale.

Then I stumbled into Grid Wars 2. Holy cow. I mean, seriously.

image

World of Stuart summed it up thusly in his review; “THIS is a video game.”

Go there for some wicked screenshots (far better than what I’ve put up here) and a link to download. You can’t get it from Marc Incitti’s site anymore <sigh>. Apparently, it’s a bit too much like “Geometry Wars” for the comfort of its creator. Grab your copy while you can.

I’ve never played it’s progenitor, but Grid Wars 2 definitely brings the frenetic back to video games. Plus, some subtle scoring tricks that WOS discusses in his writeup that make it all the more interesting. And there seems to be no end to the unique powerups that pop (get 150 bad guys, 3 black holes, 4 snakes, with quad cannons, side fire, fast fire and bouncing shots going all at once, and you’ll swear your screen is about to catch fire).

And, come to think of it, there is a little bit of VB goodness here, or rather BASIC goodness. It’s opensource, and written in BlitzMax, a pseudo-basic, game programming platform form Blitz Research. Plus, the install is unbelievably sweet. A zip file. Just unzip somewhere and run the EXE. T’would be a blessed day that Office trod down that path.