Compatibility List
Current Build: 007 (windows executable)  Source (MSVC++) 

What is FlickerFucker?

FlickerFucker (FF) is a windows based, xbox executable patching utility which changes the behaviour of the default FlickerFilter settings.

The FlickerFilter is a bit of hardware built into the xbox itself, which can be controlled by software.  Due to a television's slight over and underscan when drawing a screen, there is often a bit of jumpiness and flicker on finely drawn details, such as text.  To keep text from being too jumpy, the FlickerFilter allows the image to be blurred slightly, which reduces the amount of jumpiness in trade for image sharpness.

Virtually every single xbox title defaults the FlickerFilter to a value of 5, the maximum amount of blurring available, and offers no means to reduce the amount through in game options.

FF allows you to force the amount of FlickerFilter used in a game.  You can turn it off altogether or select any amount of flicker filtering between 1 (minimum) and 5 (maximum).

Obviously this is only true for Standard Definition Interlaced TV´s (15khz), and the benefit will be proportional to the quality of the cables used for connecting the Xbox to the TV (best results with Scart RGB cables, worst with composite cables)

Usage

FF is a windows application which runs on your PC.  This means that you have to take xbox executables off your xbox and put them on your PC in order to patch them.  
 1.	FTP the game's default.xbe file from your xbox to your PC.
 2.	Make a backup of the default.xbe file, just in case you don't like what FF does to the display.  There is no undo!
 3.	Launch FF, click on the browse button and locate the default.xbe file you transferred over.  Click open.
 4.	Select the desired amount of flicker filter you'd like the game to have.  Off is a good choice for first time usage, as you will then be able to instantly verify that the patch worked properly.  The difference between 1 and 5 is rather subtle.
 5.	Press the "Patch it!" button.
 6.	FF will then load, analyse and display the available patches that can be made (if any) to this xbe file.
Since FF is a generic utility, it may find multiple instances of FlickerFilter code to be patched.  Not all of them will be required to be patched to change the setting in the game, but there is no way to know until you try them.  There should be no harm in patching every instance, but the option is there to skip a patch if it ever causes trouble.
 7.	Select yes or no to the patches listed.  The first time a game is tried, it is suggested to allow FF to patch everything.
 8.	Check the output messages to verify that the file was successfully patched and saved.
 9.	FTP the patched default.xbe back to your xbox and try it. 

Technical Details (warning, geeky stuff ahead)

FF can patch up to 4 different types of calls to the SetFlickerFilter routine.
Since FF is a generic patch utility, and not all executables are compiled the same, FF had to be smart enough to examine different types of calls made to SetFlickerFilter, and be able to modify their behaviour without causing the code to crash.

Currently, there are 4 different types of calls known, which covers all the xbe titles tested.  As more titles are tested, it is quite possible that more will be added in future releases.

Type 1 - the simplest type of patch.  FlickerFilter parameters are simply passed on the stack as static values.
.text:0031DE65                 test    eax, eax
.text:0031DE67                 push    esi
.text:0031DE68                 mov     esi, ds:AvSendTVEncoderOption
.text:0031DE6E                 jz      short loc_31DE79
.text:0031DE70                 cmp     ds:dword_3D9284, 5
.text:0031DE77                 jz      short loc_31DEA1
.text:0031DE79 
.text:0031DE79 loc_31DE79:                             
.text:0031DE79                 mov     eax, ds:dword_3D83C8     ; opcodes:
.text:0031DE7E                 mov     ecx, {eax+1C28h}         ; 8b 88 ...
.text:0031DE84                 push    0                        ; 6a 00
.text:0031DE86                 push    5                        ; 6a 05
.text:0031DE88                 push    0Bh                      ; 6a 0b
.text:0031DE8A                 push    ecx                      ; 51
.text:0031DE8B                 call    esi                      ; ff d6
.text:0031DE8D                 mov     ds:dword_3D928C, 1
.text:0031DE97                 mov     ds:dword_3D9284, 5
All FF does here is change the blue-highlighted 5 into the value the user selects from the dropdown list.
FF also removes the conditional jump statement above the patch to ensure the patch is always executed.

type 2 - register is being used to pass value into FlickerFilter call (see blue line)
D3D:003C82B6                 test    ecx, ecx
D3D:003C82B8                 mov     eax, ds:dword_3D83C8
D3D:003C82BD                 jz      short loc_3C82C7
D3D:003C82BF                 cmp     ds:dword_3D9284, esi
D3D:003C82C5                 jz      short locret_3C82E9        ; 74 22
D3D:003C82C7 
D3D:003C82C7 loc_3C82C7:                             
D3D:003C82C7                 mov     eax, {eax+1C28h}           ; 8b 80 ..
D3D:003C82CD                 push    0                          ; 6a 00
D3D:003C82CF                 push    esi                        ; 56
D3D:003C82D0                 push    0Bh                        ; 6a 0b
D3D:003C82D2                 push    eax                        ; 50
D3D:003C82D3                 call    ds:AvSendTVEncoderOption   ; ff 15
D3D:003C82D9                 mov     ds:dword_3D928C, 1
D3D:003C82E3                 mov     ds:dword_3D9284, esi
FF first removes the conditional jump statements above the patch to ensure the patch is always executed.

In this case, FF must relocate the "push 0" statement to where the 2nd conditional jump was removed.  This frees up the space needed to do a direct passing of the user selected flicker filter parameter in place of that "push esi"

The topmost conditional jump must be removed to ensure the stack is properly set up prior to the call, otherwise the jump could have skipped over the push 0 we just located into the bytes used by the 2nd conditional jump.  naughty.

type 3 - very similar to type 2, except there is no direct "push 0" statement at the top of the call routine.
D3D:003CC02B                 jnz     short loc_3CBFF0
D3D:003CC02D                 mov     esi, {esp+28h+arg_0}
D3D:003CC031                 mov     eax, {esi+1DDCh}
D3D:003CC037                 mov     ebx, ds:AvSendTVEncoderOption
D3D:003CC03D                 xor     ebp, ebp
D3D:003CC03F                 test    eax, 1000000h
D3D:003CC044                 jz      short loc_3CC053           ; 74 0d
D3D:003CC046                 mov     edx, {esi+1C28h}           ; 8b 96 . . .
D3D:003CC04C                 push    ebp                        ; 55
D3D:003CC04D                 push    ebp                        ; 55
D3D:003CC04E                 push    0Bh                        ; 6a 0b
D3D:003CC050                 push    edx                        ; 52
D3D:003CC051                 call    ebx                        ; ff d3
FF first removes the conditional jump, as always, and then relocates the first push statement into the freed bytes.
FF then adds a direct "push {userValue}" to the 2 bytes freed up by relocating the first push.

Type 4 - very similar to type 3, except there's an extra statement before the pushing begins.
D3D:00168F1F                 call    ds:AvSetDisplayMode
D3D:00168F25                 mov     esi, eax
D3D:00168F27                 test    esi, esi
D3D:00168F29                 jnz     short loc_168F08
D3D:00168F2B                 test    dword ptr {edi+1DDCh}, 1000000h
D3D:00168F35                 mov     ebx, ds:AvSendTVEncoderOption
D3D:00168F3B                 jz      short loc_168F4E
D3D:00168F3D                 mov     ecx, {edi+1C28h}
D3D:00168F43                 xor     ebp, ebp
D3D:00168F45                 push    ebp
D3D:00168F46                 push    ebp
D3D:00168F47                 push    0Bh
D3D:00168F49                 push    ecx
D3D:00168F4A                 call    ebx
D3D:00168F4C                 jmp     short loc_168F50
FF must first remove the conditional jump, then deal with the extra opcodes (in this case the "xor ebp, ebp") in order to make room for the push {flickerValue} statement that has to be inserted. "xor exp,ebp" is relocated to the conditional jump bytes, and the pushes slid up to make room for the additional byte required to push a static value.  this is the worst type of patch so far.

Thanks to IDA for the disassembly.

release history: 
007 - fixed bug in patch type 4-the conditional jump removal was a little too aggressive and removed jumps that were actually MOV's ;) 
006 - first public release