Go for it, Tony!
I got it!
I haven't worked out all the fields of the header in the first sector of hda3, but I found the fields I care about for my purposes. Here's what I've got (duplicating your previous information just for clarity)
0x0010: playlist size (PS)
0x0018: running order size (ROS)
0x0200: beginning of FIDs in the playlist, 8 bytes each
0x0200 + 8 * (PS): beginning of the running order indexes, 4 bytes each
.
The ROS is only different than the PS if you've shuffled (due to duplicate removal.)
So with the above information, given an index into the current running order, I can find the FID number associated with that index. That's not very interesting for the currently playing FID, because we can get that from many areas, including the flash savearea and /proc/empeg_notify. BUT.. Cobbling this information together allows me to get the NEXT fid that will play in the current running order. If I'm at index N of the running order, I just need to go to index N+1, follow that as an index into the FIDs area at 0x200, and there we have it. I wrote a tiny C program to convert a running order index into a FID and it is working flawlessly. Righteous!
Now all I need is a way to get where we're at within the current running order from the userland... It's in the flash savearea, but there's no ioctl() for that. If there was, well, my master plan is going to start coming together very nicely.
Sweet, now I can finally go back to working on my school projects...