• Advertisement
Sign in to follow this  
  • entries
  • comments
  • views

Entries in this blog


True, False, FileNotFound

Sigh. From the SDK of a certain big-name console:

enum GraphicsBoolean

Graphics's version of bool-type values.


That makes me sad.

EDIT: Censored the library name

Evil Steve


Preview of the game I'm working on

IGN has released a preview of the game I'm working on: Need For Speed: The Run on 3DS. Obviously I can't say an awful lot about it, but the preview doesn't do it justice IMO - some of the tracks are much prettier than the screenshots there, and it doesn't cover some fun things like heroic stunts (Which you can see mentioned on the bottom screen in the second screenshot).

Anyway. Back to work. I need to tighten up the graphics on level 3.

Evil Steve


I'm not dead!

Last update was in January, whoops.

I've been pretty busy recently, been buying a 3 bedroom flat in Glasgow which is a lot more stressful than I thought it'd be.

I finally moved my stuff in at the start of June, after having fun trying to get a certificate of building works for the work that the previous owner did to the property. He moved the kitchen completely, put in an en-suite, and added an air duct to extract air from the en-suite, kitchen and bathroom and spew it into the stairwell. And there's the problem. The building certificate guy said that it can't vent into the stairwell, since it's a fire escape so it's a fire hazard - despite every other flat in the building doing the exact same thing. I was told that it would need to be re-ducted to an exterior wall, and was then told a week later that it'd been done. All this happened about 2 weeks before I was due to move in, after my offer had been accepted, so there wasn't a lot of time for me to argue it or anything like that.
So I officially moved in on the Friday, and I went to the flat on Saturday to see what had been done with the ducting. And it hadn't exactly been re-ducted, it'd been blocked up. I spoke with my solicitor who said that basically there's nothing we can do about it, because he has a certificate to say that the building works are carried out to code (They're not functional, but they're to code...). I spoke to the previous owner about it and he said that apparently this is just something that everyone does, and he's happy to unblock it if I want, so it'll vent back into the stairwell - which is against the building regulations and will need blocked up again if I sell the place, but at least it'll be functional.
So he came and did that, which took him 5 mins which was good-ish.

Other fun things I noticed after moving in is that the floors are a mess. It's laminate flooring, and it was in a reasonable state when I went to view the place in February, but the owner had tenants in during this time, and I stupidly didn't go to see it after they'd moved out. The floors weren't really that bad, but they were worse than when I saw it previously, with big cracks between the pieces of laminate in the hall, and a big spongy bit just as you enter the lounge. There was also a damp patch that wasn't visible before because it was behind a sofa. It was mentioned in the home report, but I assumed it was just a mark on a different wall (Same wall, but on the other side) that the owner said he was taking care of.

So, the current state of affairs: I got hardwood flooring from Direct Flooring and got it put in throughout, which is still a work in progress as we speak. It looks considerably better than the laminate, and the guys who put the flooring in (Area Joinery) have done a fantastic job. They've not done the flooring around the damp patch, because it'd just need ripped up again, so the plan is that I get the damp fixed, then they come back and do the rest as a separate, smaller job.
I got a quote from one builder for fixing the damp - who quoted GBP640 ex. VAT, so around GBP750 including VAT. The damp patch is pretty small, and is because it's just a plastered-over fireplace which hasn't been properly blocked up, so I think GBP750 is perhaps a bit steep. I also need to get a fireplace trimmed because the large concrete slab base of it is raised up above the floorboards so the flooring guys can't floor over it - thankfully it's the fireplace at the damp patch, so it couldn't be floored over anyway - but I don't think I'll be getting the GBP750 builder to do that somehow...
I was due to have another builder come and give me a quote last night, but he "forgot" apparently, and is supposed to phone me today but hasn't yet. So I might end up needing to find another builder instead...

On top of that I've been extremely busy at work, I can now say that I'm working on Need For Speed: The Run on the 3DS. And speaking of being extremely busy, now this has FINALLY finished compiling, I'm going to get back to it...

Evil Steve


What! I need a title now?

Well, I'm working on the new DirectX and XNA forum FAQ. The Previous FAQ is pretty massive, and out of date - although I suppose it needs to be quite wordy to cover all of the DirectX API...

I'm also beginning to realise how out of date I am, having never used Direct3D 10, 10.1 or 11, or Direct2D or DirectWrite. Which makes the FAQ on those sections a bit lacking...

Despite me saying that I'd try and have the FAQ done by Monday (2 days ago), It'll be done "when it's done" - although unlike my tutorial stuff, I'm actively working on the FAQ, and hope to have a first draft done by this weekend (maybe...).

I'm making my own cider at home. Which should be ready soon (might be ready now in fact). It took a bit longer than it was supposed to, due to me adding honey as well as sugar initially (Since I didn't trust the look or smell of it), and it not being at the correct temperature - I don't have anywhere that's a constant 25'C, the closest to that is next to my radiator, which is far from ideal...
So anyway, I've brewed it and bottled it (I've been collecting bottles for a while, and I got a bottle capper and bottle caps), it now needs to sit somewhere at ~30'C for 3 days to prime (So I'm leaving it next to the radiator for a week), and then it'll be done.

I have a stag doo for one of my friends on Saturday, so that's Saturday gone and Sunday will probably be spent recovering, so I doubt I'll get anything constructive done at the weekend.

Anyway, end of lunch, time for me to get back to work. Joy joy joy...

Evil Steve


If you've got monkeys on the knees, just say Thynn

I'm not dead! Again.

I've not been doing an awful lot of my own stuff recently, I've been particularly busy with work stuff - as usual.

We got one of our projects (On two platforms) canned unfortunately, especially since we'd been working on it for over a year. I can't say much more about it for obvious reasons.

I'm currently dicking around doing some stuff like Microsoft's Detours library, just because I like doing fun low-level stuff like this. I've gone back to my APIHijack app that I wrote a while ago (Might be linked in a previous entry, PM me if it's not and you especially want the source), that lets me redirect calls to any call made from an EXE (or DLL) to another DLL to my own function.
That works by injecting a DLL into a remote process, via the usual CreateRemoteThread method, but the problem is that you can only do any real "work" in DllMain, or when a patched API call is made. Doing stuff in DllMain has several well known problems (The loader lock), and doing stuff in a patched API call might not be practical for various reasons.

So, the obvious solution is to use an initialisation function, which is called after the DLL has been loaded. The problem is calling that function, since it needs to be called from within the target process. That means that you need to do a GetProcAddress() in the remote process to get the address of the initialisation function, which isn't directly possible (It rather involved being on the other side of this airtight hatchway).

So, I've now written a GetRemoteProcAddress function, which uses ReadProcessMemory to parse the PE header and read the exports section (Which is what GetProcAddress does internally anyway).

So, for anyone who cares:

FARPROC GetRemoteProcAddress(HANDLE hProcess, HMODULE hDll, const char* szFunc)
// Read and check the DOS and NT headers
BYTE* pBaseAddress = (BYTE*)hDll;
SIZE_T nBytesToRead = sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS) + 4096;
BYTE* pBuffer = new BYTE[nBytesToRead];
SIZE_T nBytesRead = 0;
if(!ReadProcessMemory(hProcess, pBaseAddress, pBuffer, nBytesToRead, &nBytesRead) ||
nBytesRead != nBytesToRead)
delete[] pBuffer;
return NULL;
if(pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE || pDOSHeader->e_lfanew 0 ||
(DWORD)pDOSHeader->e_lfanew > nBytesToRead-sizeof(IMAGE_NT_HEADERS))
delete[] pBuffer;
return NULL;
IMAGE_NT_HEADERS* pNTHeader = (IMAGE_NT_HEADERS*)(pBuffer + pDOSHeader->e_lfanew);
if(pNTHeader->Signature != IMAGE_NT_SIGNATURE)
delete[] pBuffer;
return NULL;

// Get export data directory
IMAGE_OPTIONAL_HEADER& optionalHeader = pNTHeader->OptionalHeader;
DWORD dwExportRVA = optionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
if(optionalHeader.NumberOfRvaAndSizes 0)
delete[] pBuffer;
return NULL;

// Read export directory header
delete[] pBuffer;
if(!ReadProcessMemory(hProcess, pBaseAddress + dwExportRVA, &exportDirectory,
sizeof(exportDirectory), &nBytesRead) || nBytesRead != sizeof(exportDirectory))
return NULL;

// Find this functions ordinal
WORD wFunctionIndex = 0xffff;
if((DWORD)szFunc {
// Function name passed as an ordinal
wFunctionIndex = (WORD)szFunc - (WORD)exportDirectory.Base;
DWORD dwFunctionOrdinalIndex = exportDirectory.NumberOfFunctions;

// Read export names table
DWORD* pNameRVAs = new DWORD[exportDirectory.NumberOfNames];
if(!ReadProcessMemory(hProcess, pBaseAddress + exportDirectory.AddressOfNames, pNameRVAs,
exportDirectory.NumberOfNames*sizeof(DWORD), &nBytesRead) ||
nBytesRead != exportDirectory.NumberOfNames*sizeof(DWORD))
delete[] pNameRVAs;
return NULL;

// Search the name table for this function
for(DWORD i=0; i {
// Read this export name
char szBuff[128];
if(!ReadProcessMemory(hProcess, pBaseAddress + pNameRVAs, szBuff, sizeof(szBuff),
delete[] pNameRVAs;
return NULL;
if(nBytesRead sizeof(szBuff))
szBuff[nBytesRead] = 0;

// Is this the one we want?
if(strcmp(szBuff, szFunc) == 0)
dwFunctionOrdinalIndex = i;
delete[] pNameRVAs;

// Lookup this function in the ordinal table
if(dwFunctionOrdinalIndex >= exportDirectory.NumberOfFunctions)
return NULL;
pBaseAddress + exportDirectory.AddressOfNameOrdinals + dwFunctionOrdinalIndex*sizeof(WORD),
&wFunctionIndex, sizeof(wFunctionIndex), &nBytesRead) ||
nBytesRead != sizeof(wFunctionIndex))
return NULL;
if(wFunctionIndex >= exportDirectory.NumberOfFunctions)
return NULL;

// Read the export RVA in the export table
DWORD dwFunctionRVA;
pBaseAddress + exportDirectory.AddressOfFunctions + wFunctionIndex*sizeof(DWORD),
&dwFunctionRVA, sizeof(dwFunctionRVA), &nBytesRead) ||
nBytesRead != sizeof(dwFunctionRVA))
return NULL;

// Convert RVA to FARPROC
return (FARPROC)(pBaseAddress + dwFunctionRVA);

Not very well tested, and it could be a bit more optimal, but it does the job - especially if there's only a handful of exports.

Anyway, that's enough of my rambling for now. I'm returning to bed - I have the plague. Or flu. But I'm pretty sure it's the plague.

Evil Steve



so there was this ad on gumtree
for a fireplace
we emailed them and asked for a picture of somebody standing next to the fireplace
and they sent us this kind of miserable looking woman standing next to it looking sad and wistful
so we wrote a song about it and sent it to them
we made up this huge story about the fireplace
how it was his father's life work
but his new wife didn't like it
so she was forcing him to sell it
just checked our inbox on my phone
the reply:

Evil Steve





In the actual example, j was about 10 lines further down than i, so I could only see the j. Hooray for 30 minutes of wasted debugging.

Evil Steve



I got into work this morning to a lovely BIOS message proclaiming "SATA0: NO DISK FOUND. PRESS F1 TO CONTINUE", followed by "No boot disk found". Which is bad, since there most certainly is a disk there. I took the hard drive out and shook it a little, then got "DISK READ ERROR". I took the drive out, blew on it, and put it back and then Windows booted up (Albeit taking about 4 times longer than normal).
So, I now have an hour to kill while XXClone copies my hard drive to a spare hard drive...

Ellipsoid - cuboid collision is hard. I spent 2 days at work getting that working, because we figured it should be pretty easy to do, "after all, you can just transform everything into ellipsoid space and then you're doing cuboid - unit sphere tests". Well, it sounds easy, but it really isn't. You have a skewed cube, which you can't just plane test against the unit sphere because there's cases where that will give a false positive (When a corner of a cuboid is close to the ellipsoid).
Anyway, I got it working at last, with the help of some PDF I found on the Internet. Now I just need to get hemiellipsoid - cuboid collision working...

In other news, there is no other news. Fun.

Evil Steve


More nothing

I think it's high time I start actually making worthwhile journal posts. But this isn't going to be one of them.

My laptop AC adapter has bitten the dust. I don't really use my laptop much any more (It gets used for maybe an hour a month on average at the moment), and a new charger is going to be ?50 for a universal adapter from PC World, or ?70 for an "official" Toshiba one.
So this sounds like a good excuse for me to buy a new laptop really...

I've been busy at work doing some fairly low level engine work and tools stuff, which I find interesting, and passes by quickly, but doesn't actually give me much to show. Our asset builder is now Teh Awesomes++, after I've spent 2 days rewriting large chunks of it and porting over various fixes from various projects.

Some of the Wii audio library is quite cool, some of it is mind-rapingly annoying. I like having direct access to the sound buffer (voice) play cursor, and I don't like the function call to disable interrupts (So the play cursor doesn't get changed by the DSP while you're dicking around with it) doing bugger all when the app is being debugged (That wasted a good hour or two, thanks Nintendo / Freescale).
I like the Wii Audio effects library - it's pretty full-featured and really easy to apply audio effects to sounds. I don't like the Wii "special" ADPCM format, and I don't like having to use a Nintendo-provided DLL in the asset builder to actually generate these files. Especially since the DLL is single threaded and the builder is multithreadtastic.

Guild Wars is down for maintenance while they move servers around somewhere, so no playing today it seems.

Oh well, it's end of lunch now. Back to my audio-induced hilarity...

Evil Steve



I'm not dead! Just being useless at doing... anything.


I've an MVP for another year (DirectX/XNA). Hooray!

I've rebuilt my server with "proper" components in it, so I now have a reasonable second PC. The graphics card is still crap, but I don't use it for gaming, so never mind. I also installed Windows Server 2008 R2 on it, and tried to set up the latest PHP and MySQL, only to find that the latest PHP doesn't work with MySQL if the database is on the localhost (And the PHP people say it's not a bug, or it's a MySQL bug, even though the bug is clearly in PHP...). So, after much dicking around I got PHP working and set up the latest phpbb.
However, in the week or so since I upgraded everything, there's been 2 posts on my forums (Which are really only used by my friends), and since my site really doesn't have anything useful on it, I'm probably going to ditch it and just have a spare PC rather than an always-on server (And I can always buy webspace if I need).

I was looking back at the articles/tutorials I've written, and the last one was written on the 29th April last year. Whoops. I didn't realise it's been so long. I will be writing a 6th one, and I hope soon. I've not been taking my laptop with me on the bus recently, just because I can't be arsed doing programming at that time in the morning or after work.

I finally got around to moving an ISA I have from Cheltenham & Gloucester to Halifax (Since C&G give me 0.5% interest, and Halifax give 2.6% for the first year). I also managed to fail miserably when setting my account up - throughout the whole process, there's helpful "What does this mean?" style links which open in a new window (Well, tab since it's Firefox). I got as far as getting my account number and username, and the page said "We recommend you print this page, click here to print". So, I clicked there to print, it opened a new window (tab), I clicked the "Print" button, and closed the window.
Except it hadn't opened a new window at all, it had opened in the existing window. I went to try and log in, and it said I need a password (Which I don't have). I went to "I forgot my password" and was given the option to use my initial temporary password (Which I didn't have), or to get a new one posted to me. I went to sign up again and was told I wasn't eligible for that account (Because it was already registered). I finally phoned up the helpline and was told that I already had a password on it's way to me, and it seems that that was the last page anyway.
Oh well. Pointless story for anyone still reading.

Guild Wars has had the Dragon Festival on this weekend, so I spent most of the weekend doing the quests on all the characters I could, and spending all my cash on the nine rings game to try and get some lucky points. Currently, they seem to have bugged the game - the nine rings is still accessible, but there's no visual indicator of where they are (I.e. the game assets have changed back over but the scripts and logic haven't). Fun.

Erm, that's about it I think. Nothing exciting to report. Hence the lack of updates :P

Evil Steve



Time for an update...

I got a new phone; the Sony Ericsson Xperia X10. It's quite nice and snazzy, but has lots of annoyances - although that might just be because it's my first phone.
Things that annoy me so far:
There's no manual. It comes with a sheet of folded A3 paper telling you how to switch the phone on and insert the battery, and there's a user guide in the phone itself (A load of HTML files), but this is severely lacking. The Sony Ericsson site is pretty crap for information too.
It took me about 3 hours to change the text message alert. There's plenty of information about how to change the alert to one of the built-in sounds, but no mention of setting a custom MP3 to play. Even searching on the Internet yielded no results save for one guy saying it's impossible. I only found out how to do it by looking through every file on the SD card and finding one audio file called "Facebook_pop", which I recognised as one of the message alerts you can change to. I added an MP3 in the same folder and then the phone detected it and gave me the option to use it as a message alert.
The touchscreen is a bit funny sometimes; it seems like the software has some problems distinguishing between a tap and a swipe - but then I imagine this is a general touchscreen problem rather than specific to my phone.
The music player doesn't remember the track position when you pause the track then exit the player - my previous phone (A Sony Ericsson K850i) managed that just fine. I listen to audiobooks on my commute to/from work, and it's annoying to have to make a note of where in the track I am when I switch it off and then seek there when I next start up.
The music player's seek is awkward to use - it's touch screen too, which makes it very difficult to make little changes. Seek back 10 seconds in a 30 minute MP3? Good luck, the least I managed was about 3 minutes.
No "real" keyboard, just touchscreen. Not such a big deal really, and I'm sure I'll get used to it.
The software that comes with the phone (On the SD card) doesn't install on XP x64. Also not too bad, since hardly anything does really...
Due to the lack of information anywhere about playing audiobook (M4B) files, or more specifically where to put them on the SD card, I ended up having to E-mail Sony support. That was 3 days ago, still no reply...

Overall, I'm sure I'll get used to it, and it's nice to have a smartphone for a change. I hope to look into doing some Android dev at some point in the reasonably near future.

In other news, I bought a new 2TB hard drive since my old 1TB drive was almost full, and I got a 80GB solid state drive too. Since the SSD is 2.5" and my PC case only handles 3.5" drives, I had to get a mounting bracket thing too.
My PC case (An Arctic Cooling Silentium T1) is one of these "Easy install" cases, so you clip a couple of runners onto the drive (into the screw holes) and then the runners slide into the case.
All well and good except the hard drive runners don't fit the mounting bracket; which has the screw holes in a different place. I ended up taking a hacksaw and super glue to two runners to attach them to the bracket, and then putting that in the PC case. Then I realised two things:
1. Those were my last two hard drive runners, and I have 2 more hard drives to put in the PC.
2. The floppy disk drive runners would have fitted the mounting bracket

After getting everything plugged in, I managed to break the power switch on the case by pulling one of the wires out. Then I discovered that neither of the two soldering irons we have in the house worked, so I had to go and buy a new one - which causes the fuses to blow when the iron gets to maximum temperature. Sigh.

So, I've got it all working now (just), but I've ordered a new PC case too, since I'm fed up with mine and I don't care how silent it is or isn't.

I've now got Windows 7 x64 installed, and I've downloaded VC2010 and Office 2010 from my MSDN subscription, so I'll see how they go.

I'd like to say that my SSD is lightning fast and everything is awesome, but I can't really tell. I can get into Windows from the BIOS in about 5-10 seconds, but I don't know if that's because of the SSD, Windows 7, or because it's a clean install...

Evil Steve



Jack (Jollyjeffers) is apparently stepping away for GDNet stuff for a while and has kindly nominated me for DirectX / XNA forum moderator (As supposed to a roaming mod).

So, I will be your friendly local brutal DirectX / XNA dictator for now.

Evil Steve



I'm defragmenting my server's C drive (Since it was 73% fragmented), watching some programme about Chemistry on BBC Four, and doing some work on Tutorial #6.

Oh yeah. That's how I roll.

Evil Steve



1. More TM Wii Screenshots!

2. I discovered that several MP3 search engines have crawled my site and found 5 MP3s that some of my friends had uploaded to my forums (Which I wasn't aware of). The MP3s weren't hotlinked from anywhere I could find, and the only reference to them was in a post in my forum, which can only be accessed by people I know personally (Access is restricted to a particular user group), so I have no idea how they were discovered.
I only noticed this because I ran Webalizer over my Apache logs, and it showed 2.2GB of traffic to one particular MP3 last month. Bastards.
Anyway, I've replaced them all with "HEY EVERYBODY; I'M LOOKING AT GAY PORNO!". Which can be observed Here. Har har har.

3. I've been dicking around a little with programming stuff. I spent a few days writing an API hooking program (Just for fun). So I can now inject a DLL (Via QueueUserAPC() or CreateRemoteThread()) into a new process at startup, or into an already running process.
I haven't quite decided what I'm going to use it for though, but I'm sure it'll come in handy in some cases.

4. Yes, I will still be continuing with my tutorials and the next one will be about creating a scene graph.

That is all for now.

Evil Steve



Hooray; a use for my Microsoft source code access: Link to thread. At the time of writing, it seems that the DX runtimes are ignoring the number of mip levels parameter to CreateVolumeTexture(). I couldn't find the source to any D3D functions in the Windows source code, but there is what seems to be the debug runtimes - which is where the error "Width must be power of two for mip-volumes" seems to be coming from.
So, when I get home tonight (I don't have my smart card+reader with me, and I don't think I'm allowed to just carry it around with me anyway) I'll see what conditions cause that message to be shown, and if the D3DPTEXTURECAPS_NONPOW2CONDITIONAL flag is tested.

Evil Steve



Holy Source Code, Batman!

I finally got around to signing up to Microsoft's Shared Source Licensing program, which is one of my MVP benefits.

Long story short, I'm currently browsing the Direct3D9 source code [cool]

Evil Steve



Time for an update I feel...

I've still not done any more on the next tutorial, I did bring my laptop with me on the bus for a couple of days, but the bus was packed, and I need a free seat next to me to be able to type, so I didn't get anything done :(

I'm not sure if I want to do shadows or stencil buffer stuff in my next tutorial - I've had a couple of E-mails from people asking how to go from drawing a basic shape or two to making a game engine, so I may veer more that way, and show how to do a scene graph and state machine.

In other news, there's a new mind.in.a.box album out next month, which sounds awesome (audio clips in that URL), I'm going to see Rammstein in Manchester on the 2nd Feb, and then Assemblage 23 in Glasgow on the 14th Feb. Hooray!

Well, it's 9am. Time to start work...

Evil Steve



I'm still alive!

I didn't make it into work on the 23rd Dec, along with most of the other people in the studio, due to excessive snow. I had to dodge a car coming downhill sideways towards me, and had to give someone a push because they got stuck in snow trying to avoid someone else driving towards them...

I was in Bournemouth for Christmas, visiting the girlfriend's parents. No snow at all, but loads in Edinburgh. Planes were delayed for around 6 hours on the 23rd, but they were mostly on time on the 24th when I was flying, which was good.

New year was nothing spectacular, went to a friends house to get a view of the fireworks at Edinburgh castle, then went home.

I got a kitten for Christmas, along with some other stuff and a load of Blu-ray. Obligatory picture:

Well, back to work I suppose...

Evil Steve



I've not done anything to my tutorial for a couple of weeks now due to lack of motivation caused by "hilarity" at work. I will get on with it at some point...

I saw Grendel on Wednesday in Glasgow, who were a bit "meh" unfortunately. Their old stuff sounded totally wrong in the vocals department, but was still alright. Their new stuff (All 3 tracks of it :P) was pretty awesome.

And Serotonin Rush by Grendel is win.

Evil Steve

Sign in to follow this  
  • Advertisement