Hacking Possible to Disable the Wii's (De)Flicker Filter?

NoobletCheese

Well-Known Member
Member
Joined
Aug 12, 2018
Messages
533
Trophies
0
Age
25
XP
1,083
Country
United States
The Mario Galaxys seem to be using a vertical filter of 20002000000000.

A useful patching strategy for most/all games might be simply patching 00001516150000 into the 7 bytes following every occurrence of 060606060606060606060606060606060606060606060606 or 03020906030A03020906030A09020306090A09020306090A, since I've not yet seen any games that don't use either of those 2 sampling patterns, and they are unique enough to be confident we're in a video mode section.

edit: nope, turns out that isn't safe as I've noticed Donkey Kong Country Returns contains such string of 06's which is not in a video mode section, so that logic would have corrupted the file :)

Another option might be to identify video mode section by pattern:

02 80 ** ** 01 E0 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06

Where ** = any value.

edit2: I can confirm the filter removal is working for Mario Galaxy 1 and 2.
Only thing is, I notice some weird load times when running the patched dol from SD card, so it looks like running them from USB drive is the way to go.
 
Last edited by NoobletCheese,

NoobletCheese

Well-Known Member
Member
Joined
Aug 12, 2018
Messages
533
Trophies
0
Age
25
XP
1,083
Country
United States
I will try it as soon as I can!
How did you find them?

Just search for every occurance of 060606060606060606060606060606060606060606060606 and 03020906030A03020906030A09020306090A09020306090A in main.dol, and look at the following 7 bytes which is the vertical filter setting, according to GXRModeObj definition in https://github.com/devkitPro/libogc/blob/master/libogc/video.c

00001516150000 = no filter
08080A0C0A0808 = Ntsc480ProgSoft
04080C100C0804 = Ntsc480ProgAa
07070C0C0C0707 = Mario Kart Wii
05050F0E0F0505 = Mario Kart Wii
20002000000000 = Mario Galaxy 1&2

The number says how much to blend the source pixel with the above/below pixel.

I'm not sure why there are 3 values for the source pixel (is it the mix of RGB?) and 2 values each for above/below pixel (luma/chroma?).

In any case, we can see the leading and trailing 0's in [0000][151615][0000] means don't blend any above/below pixels, and the middle 3 numbers sum to 64 (0x40) which is the largest 6-bit value*, so the source pixel gets passed through unmolested.

* actually 63 (0x3F) if we start from 0, so I'm not sure why the middle number is 16 instead of 15.



I have been trying to patch Donkey Kong Country without success.

I found the block which the game uses at offset 57F306, as I can modify some of the parameters there and change display mode to interlace or split the frame in 2 like in Superrsonic's image.

By default its filter is already set to 00001516150000 (disabled) but visually it still appears a bit softened and the system menu overlays are showing that too, just like Mario Kart Wii and Mario Galaxy.

No matter what values I put in there, there is no change to the image. Also tried putting values in every other video mode block to no effect. The game appears to be completely ignoring the filter setting.

I speculate the game may be calling some other API function which sets the filter manually without referencing a GXRModeObj, so changing the GXRModeObj won't work.

I think we need to use a break point with Dolphin find the address of that function so we can patch it, but I lack the knowledge to do this. Someone like @SuperrSonic or @Extrems might know...
 
Last edited by NoobletCheese,

totakeke95

Well-Known Member
Member
Joined
Dec 25, 2020
Messages
146
Trophies
0
XP
869
Country
Spain
I thought the filter was only enabled when the console was set to interlaced mode (480i) and progressive mode would disable that filter.

The PAL version of Zelda Twilight Princess when you play in progressive mode the image looks more blurry because the filter is still enabled and many thought it was a programming failure by Nintendo.
 

NoobletCheese

Well-Known Member
Member
Joined
Aug 12, 2018
Messages
533
Trophies
0
Age
25
XP
1,083
Country
United States
I would be interested in making a simple GUI tool to automate the patching. i.e take an iso/wbfs as an input file, and spit out a patched [GameID].dol onto SD/USB for use by ULGX.

This may not be feasible as I was going to use Wiimms ISO tools to extract main.dol, but it's a Linux command line tool that only runs under Cygwin on Windows, so I can't call it directly from my own tool, or the user would have to install Cygwin which is not a simple process iirc.

It seems ULGX can extract and patch main.dol from the iso/wbfs, so probably better to do it there instead. Plus it's way more convenient for the user.

I thought the filter was only enabled when the console was set to interlaced mode (480i) and progressive mode would disable that filter.
The PAL version of Zelda Twilight Princess when you play in progressive mode the image looks more blurry because the filter is still enabled and many thought it was a programming failure by Nintendo.

It appears to be up to the game dev what video mode they want to set.
 
Last edited by NoobletCheese,

Maeson

Well-Known Member
Member
Joined
Apr 3, 2013
Messages
1,180
Trophies
1
XP
3,385
Country
Spain
I've been messing around with this, and I can say many games do use "08080A0C0A0808" or Progressive Soft as it seems to be named.

Beat the Beat: Rhythm Paradise uses the same as Mario Kart, "07 07 0C 0C 0C 07 07", but I see no differences. Wario Land: The Shake Dimension / Shake It doesn't seem to gain anything from it either, both being 2D games. Donkey Kong Country Returns also does not show any difference, I hope we can find something to make it work though.

On the other hand, It's pretty easy to see the difference with others. Besides the Mario games you mention I also tried with Fishing Resort, and it's quite a bit cleaner, for example.

I'll have to mess with this more when I come back home.

You can extract main.dol with USB Loader GX? How? That would save a lot of time...
I wonder if this can work somehow with Wiiware games. Some like Art Style: Cubello use a very, very aggressive filter.
 
  • Like
Reactions: NoobletCheese

totakeke95

Well-Known Member
Member
Joined
Dec 25, 2020
Messages
146
Trophies
0
XP
869
Country
Spain
The main dol of the WiiWare and VC games are in 01.app, just rename extension to dol. I was testing some games like Bomberman Blast and it worked. There are games that the main dol is compressed and need some tools for it.
 

Maeson

Well-Known Member
Member
Joined
Apr 3, 2013
Messages
1,180
Trophies
1
XP
3,385
Country
Spain
I forgot you had to unpack 01.app and I wasn't finding anything. I managed to edit Cubello and it indeed looks quite better, I'm very happy about it. It still uses a filter (it seems like it used a filter OVER a filter and that's why it looked so bad) but by editing it the more annoying filter it had is gone and the 3D elements look a lot better now. I tried with Mega Man 9, and I managed to remove the blurriness, which is phenomenal, but I cannot edit it so it plays in progressive scan. I tried years ago but I never managed to do that. Oh well...

I also went and edited the main.dol of a good chunk of the retail games I have. I don't have time to check every single one right now, but games such as Mario Sports Mix or Pandora's Tower have the same positive gains than the games mentioned above. I'd say pixels are as clear as when forcing video modes on GC to remove the deflicker, so that's great for me.

About the loading times, I think it's not something to blame the SD Card about (I mean, if you have a slow one absolutely but...), I saw the same performance with the main.dol from the USB. So I think for best results, once you see the changes work, would be to simply reinsert the file to the WBFS or iso, which is going to be kinda annoying in the case of WBFS...

...I'll try later to see if I can simply hex edit the WBFS file itself now that I know exactly what to change. That said it only seems to affect the first load when you boot the game from USB Loader GX so... might not even be worth it?
 

NoobletCheese

Well-Known Member
Member
Joined
Aug 12, 2018
Messages
533
Trophies
0
Age
25
XP
1,083
Country
United States
I tried with Mega Man 9, and I managed to remove the blurriness, which is phenomenal, but I cannot edit it so it plays in progressive scan. I tried years ago but I never managed to do that. Oh well...


Did you try changing the first byte

Code:
02       // viDisplayMode (00=480i, 02=480p)
02 80   // fbWidth
01 E0   // efbHeight
01 E0   // xfbHeight
00 28   // viXOrigin
00 00   // viYOrigin
02 80   // viWidth
01 E0   // viHeight
00 00 00 00   // xFBmode (00000000=single field, 00000001=double field)
00 00       // field_rendering (0000=off, 0001=on)
00 00       // anti aliasing (0000=off, 0001=on)
06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 // sample pattern for anti aliasing
00 00 15 16 15 00 00 // vertical filter (off)


You might also need to set field_rendering to off.
 
Last edited by NoobletCheese,
  • Like
Reactions: mive and Maeson

Maeson

Well-Known Member
Member
Joined
Apr 3, 2013
Messages
1,180
Trophies
1
XP
3,385
Country
Spain
Thanks, I tried again changing viDisplayMode to 02 and removing the field rendering and aa besides the vertical filter, but I only get black screens.
 

NoobletCheese

Well-Known Member
Member
Joined
Aug 12, 2018
Messages
533
Trophies
0
Age
25
XP
1,083
Country
United States
I have been trying to patch Donkey Kong Country without success...I speculate the game may be calling some other API function which sets the filter manually without referencing a GXRModeObj, so changing the GXRModeObj won't work.

I think we need to use a break point with Dolphin find the address of that function so we can patch it, but I lack the knowledge to do this. Someone like @SuperrSonic or @Extrems might know...


It may be this one:

Code:
u32 GXSetCopyFilter(
    GXBool aa,
    u8 sample_pattern[12][2],
    GXBool vf,
    u8 vfilter[7] );


Does anyone know the hex value for this function inside main.dol, or how to discover it?

edit: I tried searching for a pattern like:
00 00
XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
00 01

To match:
GX Bool aa
u8 sample_pattern[12][2]
GXBool vf

Where XX = any number.
But there are over 700 occurences of that pattern :O
 
Last edited by NoobletCheese,

NoobletCheese

Well-Known Member
Member
Joined
Aug 12, 2018
Messages
533
Trophies
0
Age
25
XP
1,083
Country
United States
We may also need to patch
Code:
void GXSetDither( GXBool dither );

In relation to
I have played a couple of hours of RE4 now, and am really enjoying the sharper picture (and great motion controls!). But the game uses lots of dithering, which doesn't look that good. I am guessing the (de)flicker filter hides it normally, but without it, the dithering is too much.
Would it be possible to do a similar hex edit to remove the dithering? With Swiss it is possible to remove alpha dithering, so I was thinking this might also be possible?
 
Last edited by NoobletCheese,
  • Like
Reactions: Draxikor

NoobletCheese

Well-Known Member
Member
Joined
Aug 12, 2018
Messages
533
Trophies
0
Age
25
XP
1,083
Country
United States
GXSetCopyFilter, GXSetDither
Does anyone know the hex value for this function inside main.dol, or how to discover it?

Would this work:
1. Compile a one line hello world .dol in RVL_SDK
2. Add one extra line of code, calling the function we want to patch, and compile it to a second .dol.
3. Diff the 2 files in a hex editor
 

NoobletCheese

Well-Known Member
Member
Joined
Aug 12, 2018
Messages
533
Trophies
0
Age
25
XP
1,083
Country
United States
Does it work only with some games ? I tried it with Sonic Colours, I extracted the wbfs, replaced all the values and repacked the wbfs and loaded it, but it looks exactly the same
The american version at least dont use deflicker filter, it woudnt affect it.


Sonic Colours appears filtered to my eyes, in both viewing frustum and sysmenu overlays.

I also observe no effect after patching all GXRModeObj vfilters to 00001516150000.

I would imagine the game is setting the filter by calling GXSetCopyFilter without the GXRModeObj as an argument.

i.e in cases where patching GXRModeObj works, the game might be going:

Code:
GXSetCopyFilter(GX_TRUE, OurPatchedGXRModeObj->sample_pattern,
               GX_TRUE, OurPatchedGXRModeObj->vfilter )

And in cases where patching GXRModeObj doesn't work, the game might be going:

Code:
GXSetCopyFilter(GX_TRUE, some_sample_pattern,
               GX_TRUE, some_vfilter )

This is consistent with the fact that according to the SDK, VIConfigure (the main function which sets the render mode) doesn't initialise GXRModeObj's vfilter, only viTVMode, viXOrigin, viYOrigin, viWidth, xFBmode, xfbHeight and fbWidth.

If this is true, then we must figure out how to patch calls to GXSetCopyFilter.

I tried debugmode in Dolphin (launch with /d argument) but it seems all we could discover is the memory address of the function, which doesn't seem relevant to patching main.dol. But I'm not a computer science expert so I don't really understand how all this low level stuff works :blush:



This post from the Beyond3D Forums explains it:-
For interlaced displays, you call GXNtsc480IntDf().
For progressive scan displays, you call GXNtsc480ProgSoft().


I couldn't find any such functions in SDK 3.3.2, so I reckon that poster may have been referring to some custom setter function their devteam wrote to initialise GXNtsc480ProgSoft's vfilter via GXSetCopyFilter. Or maybe an older SDK had such a function which did that.
 
Last edited by NoobletCheese,

NoobletCheese

Well-Known Member
Member
Joined
Aug 12, 2018
Messages
533
Trophies
0
Age
25
XP
1,083
Country
United States
I've got a feeling it's going to be very difficult to reliably patch GXSetCopyFilter in main.dol.

It seems that patching a compiled function is very different to patching a data structure like GXRModeObj.

In the case of integers, it appears the compiler just inserts them as plaintext in main.dol, so they're easy to find and patch.

Whereas a function's argument (which we want to patch) could be a pointer, which I don't know the length of, and even if I did, I don't think we can just replace a pointer with an array of ints containing our desired vfilter setting. We also don't know if the game dev passed a pointer or an array of ints.

I suppose we could try both in a hello world .dol to see what happens in either scenario, but I'm struggling to understand how to set up the RVL_SDK toolchain for compiling a .dol.
 
Last edited by NoobletCheese,
  • Like
Reactions: Draxikor

contra1980

Member
Newcomer
Joined
Apr 10, 2021
Messages
5
Trophies
0
Age
34
XP
250
Country
Russia
Good to everyone! Help with The Legend of Zelda - Twilight Princess EUR! I really need to edit the DOL file. But I myself do not understand anything at all in HEX editors. Thanks in advance!
 

NoobletCheese

Well-Known Member
Member
Joined
Aug 12, 2018
Messages
533
Trophies
0
Age
25
XP
1,083
Country
United States
Good to everyone! Help with The Legend of Zelda - Twilight Princess EUR! I really need to edit the DOL file. But I myself do not understand anything at all in HEX editors. Thanks in advance!


To patch main.dol, open it in a hex editor such as HxD Hex Editor portable version.

In HxD:

1. Search > Replace > Hex values tab > Search For: 08080A0C0A0808; Replace With: 00001516150000; Search direction All; Replace all.

2. Search > Replace > Hex values tab > Search For: 04080C100C0804; Replace With: 00001516150000; Search direction All; Replace all.

3. File > Save As > GameID.dol

The GameID can be found at https://www.gametdb.com/Wii/Search
In this case it's https://www.gametdb.com/Wii/RZDP01
So save as RZDP01.dol

4. Copy RZDP01.dol to eg. SD:\PatchedDOLs\RZDP01.dol or USB:\PatchedDOLs\RZDP01.dol

I'd recommend copying to USB as I've noticed slow and inconsistent load times on SD (Sandisk SDHC Ultra 32GB).

5. USB Loader GX Settings > Custom Paths > DOL Path > SD:\PatchedDOLs or USB:\PatchedDOLs

6. USB Loader GX Game Setting > Game Load > Alternate DOL > Load from SD/USB



If the filter is still present in-game, it means either:

(a) The game uses a different filter than 08080A0C0A0808 or 04080C100C0804 (the ones we patched in steps 1 and 2) or:

(b) The game uses a different filter than 08080A0C0A0808 or 04080C100C0804, and doesn't set it using the data structure we're modifying (a solution to this has not yet been found).

In the case of (a) we'll have to manually find the filter the game uses.

I'm still trying to find a hex editor that supports regex type expressions to do this automatically, but for now we'll have to do it manually in HxD like so:

1. Search > Find > Hex values tab > Search For: 060606060606060606060606060606060606060606060606; Search direction All; Search all.

2. In the bottom window, go through each result and determine if it looks like a GXRModeObj.

IL1Sc1.png


In the above results you can see the first result is not a GXRModeObj because the numbers leading up to the 06's don't look like one.

Double click to scroll to its location, and notice the numbers after the 06's also don't look like a GXRModeObj:

ILRsb2.png


So this one is not a GXRModeObj and we'll leave it alone, otherwise we'd corrupt the file.

3. Once you found one that looks like a GXRModeObj, double click it in the bottom window to jump to that location, and replace the 7 numbers after the 06's with 00 00 15 16 15 00 00:

ILTiw9.png


4. Repeat the process but instead of searching for 060606060606060606060606060606060606060606060606, search for 03020906030A03020906030A09020306090A09020306090A.



On my PC I'm noticing some bugs with HxD. Sometimes after I search, I get an infinite number of error popups saying "table index out of range" or something, after which it no longer finds results when searching. I'm not sure if this is my PC's fault, but thought I should mention it as it could corrupt DOLs. I am working around it by restarting HxD after every time I do a search or replace.

edit: Appears to be a benign bug -- see follow up here .



Main.dol can be extracted from the game ISO using Wii Scrubber. If the game is a WBFS file you'll need to convert it to ISO; I used Wii Backup Manager.
 
Last edited by NoobletCheese,

Maeson

Well-Known Member
Member
Joined
Apr 3, 2013
Messages
1,180
Trophies
1
XP
3,385
Country
Spain
I have been extracting main.dols from WBFS files with Wii Baclup Fusion. The process is to extract the entire WBFS but because the main.dol is one of the first files to get dumped (besides the Update folder) you only nees to wait for a moment, no more than 300 mb extracted at most.

Good tutorial by the way.
 
  • Like
Reactions: NoobletCheese

NoobletCheese

Well-Known Member
Member
Joined
Aug 12, 2018
Messages
533
Trophies
0
Age
25
XP
1,083
Country
United States
I notice the vfilters tend to have a symmetry to them which might be searchable with a regex to find vfilters in games which don't set them by GXRModeObj.

eg. 04 08 0C 10 0C 08 04 has a pattern like: AA BB XX YY XX BB AA

This pattern would also match
08 08 0A 0C 0A 08 08
07 07 0C 0C 0C 07 07
05 05 0F 0E 0F 05 05

But not
20 00 20 00 00 00 00

Anyone who knows regex please help.

edit: perhaps a simpler way of expressing it is that the last 3 bytes should be a reversed copy of the first 3 bytes, and the middle byte can be anything (wildcard).
 
Last edited by NoobletCheese,

contra1980

Member
Newcomer
Joined
Apr 10, 2021
Messages
5
Trophies
0
Age
34
XP
250
Country
Russia
Thank you very much for the instruction! The archive was deleted, although the disc with the game was bought a long time ago. I thought I had the right))) I'll try it myself!
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    The Real Jdbye @ The Real Jdbye: sure, it can be hands free