Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

some fixes: avoid black banners / minimize one usb related dsi exceptions / get custom banners / install shared content #2

Open
wants to merge 12 commits into
base: enhanced
Choose a base branch
from
Open
13 changes: 11 additions & 2 deletions source/Channels/channels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -707,13 +707,22 @@ u8 *Channels::GetOpeningBnr(const u64 &title, u32 *outsize, const char *pathPref
u32 high = TITLE_UPPER(title);
u32 low = TITLE_LOWER(title);


// avoid black banners - add path prefix length to ISFS_MAXPATH when loading from emuNAND
int customMaxPath;
if (pathPrefix && *pathPrefix != 0)
customMaxPath = ISFS_MAXPATH + strlen(pathPrefix);
else
customMaxPath = ISFS_MAXPATH;

// avoid black banners - we don't change filepath definition, it was already of this size for both cases...
char *filepath = (char *)memalign(32, ISFS_MAXPATH + strlen(pathPrefix));
if (!filepath)
return NULL;

do
{
snprintf(filepath, ISFS_MAXPATH, "%s/title/%08x/%08x/content/title.tmd", pathPrefix, (unsigned int)high, (unsigned int)low);
snprintf(filepath, customMaxPath, "%s/title/%08x/%08x/content/title.tmd", pathPrefix, (unsigned int)high, (unsigned int)low);

u8 *buffer = NULL;
u32 filesize = 0;
Expand Down Expand Up @@ -748,7 +757,7 @@ u8 *Channels::GetOpeningBnr(const u64 &title, u32 *outsize, const char *pathPref
if (!found)
break;

snprintf(filepath, ISFS_MAXPATH, "%s/title/%08x/%08x/content/%08x.app", pathPrefix, (unsigned int)high, (unsigned int)low, (unsigned int)bootcontent);
snprintf(filepath, customMaxPath, "%s/title/%08x/%08x/content/%08x.app", pathPrefix, (unsigned int)high, (unsigned int)low, (unsigned int)bootcontent);

if (pathPrefix && *pathPrefix != 0)
ret = LoadFileToMem(filepath, &buffer, &filesize);
Expand Down
16 changes: 12 additions & 4 deletions source/menu/GameBrowseMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "sys.h"

struct discHdr *dvdheader = NULL;
bool allowUsedSpaceTxtUpdate;

GameBrowseMenu::GameBrowseMenu()
: GuiWindow(screenwidth, screenheight)
Expand Down Expand Up @@ -525,6 +526,7 @@ int GameBrowseMenu::Execute()
GameBrowseMenu * Menu = new GameBrowseMenu();
mainWindow->Append(Menu);

allowUsedSpaceTxtUpdate = true;
if(Settings.ShowFreeSpace)
{
ThreadedTask::Instance()->AddCallback(&Menu->HDDSizeCallback);
Expand All @@ -543,6 +545,8 @@ int GameBrowseMenu::Execute()
retMenu = Menu->MainLoop();
}

// to avoid that the async thread updates usedSpaceText after menu deletion
allowUsedSpaceTxtUpdate = false;
delete Menu;

return retMenu;
Expand Down Expand Up @@ -1689,18 +1693,22 @@ void GameBrowseMenu::UpdateCallback(void * e)

void GameBrowseMenu::SetFreeSpace(float freespace, float used)
{
if (strcmp(Settings.db_language, "JA") == 0)
usedSpaceTxt->SetText(fmt("%.2fGB %s %.2fGB %s", freespace + used, tr( "of" ), freespace, tr( "free" )));
if (strcmp(Settings.db_language, "JA") == 0) {
if ( allowUsedSpaceTxtUpdate == true )
usedSpaceTxt->SetText(fmt("%.2fGB %s %.2fGB %s", freespace + used, tr( "of" ), freespace, tr( "free" )));
}
else
usedSpaceTxt->SetText(fmt("%.2fGB %s %.2fGB %s", freespace, tr( "of" ), freespace + used, tr( "free" )));
if ( allowUsedSpaceTxtUpdate == true )
usedSpaceTxt->SetText(fmt("%.2fGB %s %.2fGB %s", freespace, tr( "of" ), freespace + used, tr( "free" )));
Jacoby6000 marked this conversation as resolved.
Show resolved Hide resolved
}

void GameBrowseMenu::UpdateFreeSpace(void * arg)
{
if (Settings.ShowFreeSpace)
{
float freespace = 0.0, used = 0.0;
usedSpaceTxt->SetVisible(true);
if ( allowUsedSpaceTxtUpdate == true )
usedSpaceTxt->SetVisible(true);
int ret = WBFS_DiskSpace(&used, &freespace);
if (ret >= 0)
SetFreeSpace(freespace, used);
Expand Down
2 changes: 1 addition & 1 deletion source/settings/CSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void CSettings::SetDefault()
strlcpy(GameCubePath, "usb1:/games/", sizeof(GameCubePath));
strlcpy(GameCubeSDPath, "sd:/games/", sizeof(GameCubeSDPath));
strlcpy(CustomAddress, "wiimmfi.de", sizeof(CustomAddress));
strlcpy(URL_Banners, "https://banner.rc24.xyz/", sizeof(URL_Banners));
strlcpy(URL_Banners, "http://banner.rc24.xyz/", sizeof(URL_Banners));
strlcpy(URL_Covers2D, "https://art.gametdb.com/wii/cover/", sizeof(URL_Covers2D));
strlcpy(URL_Covers3D, "https://art.gametdb.com/wii/cover3D/", sizeof(URL_Covers3D));
strlcpy(URL_CoversFull, "https://art.gametdb.com/wii/coverfull/", sizeof(URL_CoversFull));
Expand Down
27 changes: 23 additions & 4 deletions source/wad/wad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,13 +322,14 @@ bool Wad::InstallContents(const char *installpath)
// Install content
if(content->type == 0x8001) {
// shared content
int result = CheckContentMap(installpath, content, filepath);
int result = CheckContentMap(installpath, content, filepath);
if(result == 1) // exists already, skip file
continue;

else if(result < 0) // failure
return false;
// else it does not exist...install it
snprintf(filepath, sizeof(filepath), "%s/shared1/%08x.app", installpath, (unsigned int)content_map_size);
}
else {
// private content
Expand Down Expand Up @@ -419,6 +420,16 @@ bool Wad::InstallContents(const char *installpath)
ShowError(tr("File read/write error."));
return false;
}

if(content->type == 0x8001) {
// shared content installed ok. It's time to update content.map
int result = UpdateContentMap(installpath, content, filepath);
if(result == 1) // exists already, skip file
continue;

else if(result < 0) // failure
return false;
}
}

return true;
Expand Down Expand Up @@ -448,6 +459,16 @@ int Wad::CheckContentMap(const char *installpath, tmd_content *content, char *fi
return 1; // content exists already
}

// Content does not exists
return 0;
}

int Wad::UpdateContentMap(const char *installpath, tmd_content *content, char *filepath)
{
int result = CheckContentMap(installpath,content,filepath);
if ( result != 0 )
return result; // content already exists or error

Comment on lines +462 to +471
Copy link
Owner

@Jacoby6000 Jacoby6000 Jul 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is breaking up the Wad::CheckContentMap function in to two separate functions (which is probably a good thing), I think you will need to update all existing invocations of CheckContentMap to use UpdateContentMap, since those old calls expect CheckContentMap to do both pieces.

Not 💯 on this yet, but I'm pretty sure. Still learning my way around here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Jacoby6000!

No, in fact the original problem was that despite its name, checkContenMap checked and always updated the content.map file without installing the shared content. The updateContentMap process should only be called once, after the shared content has been succesfully installed. The other invocations of checkContentMap only need the check stuff. The flow is explained here with a little more of detail.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahhh I see. I didn't fully understand what was going on. This makes sense! I'll test it this week and get it merged

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have any examples of wads with shared content so that I can validate this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think any title will do.

If you want to see the bug in action, you can prepare the following lab.

Take a working emunand and delete all but one shared content:

cd ${NAND_ROOT}
mv shared1 _shared1
mkdir shared1
cp _shared1/00000000.app shared1
dd if=_shared1/content.map of=shared1/content.map bs=28 count=1
-rw-r--r-- 1  wii  wii      28 Aug  1 11:18 content.map

Install any title with the old build. Check the shared1 folder. You will find no new file. But notice that the content.map file has increased in size::

-rw-r--r-- 1  wii  wii     112 Aug  1  2024 content.map

USBGLX have added the hash of the shared contents included in the wad to the content.map file. The title won't load for sure. And from now on, this emunand is doomed. Any tool that checks content.map will assume that the shared content is already installed and will skip its installation.

Recreate the minimal content.map again:

dd if=_shared1/content.map of=shared1/content.map bs=28 count=1

and install the same content with the new build. content.map will have the same size (and content) than with the old build, but now shared1 folder will contain some 0000000x.app files. If you try, the installed title will (probably) load (if not, well ... we have deleted ~ 70 files or so, some unexpected behavior can happens...).

If you have access to a (physical) Wii , the real case scenario is to create a minimal emunand using modMii and then install any title with USBGLX. You will will succeed only with the new build (with the old build, installation apparently works, but the title won't load).
Or in a wii/vWii, only if you have never installed any title in the real NAND: if you export it to create and emunand, title installation will only succeed with the new build.

It's a subtle bug, which is why it has gone unnoticed for years. And I think mainly affects to new modders.

By the way, when testing this with the previous version, the DSI exception error hit me twice :D

// Content does not exists, append it.
u32 next_entry = content_map_size;
u8 *tmp = (u8 *) realloc(content_map, (next_entry + 1) * sizeof(map_entry_t));
Expand All @@ -461,7 +482,7 @@ int Wad::CheckContentMap(const char *installpath, tmd_content *content, char *fi
content_map = tmp;
content_map_size++;

map = (map_entry_t *) content_map;
map_entry_t *map = (map_entry_t *) content_map;
char name[9];
sprintf(name, "%08x", (unsigned int)next_entry);
memcpy(map[next_entry].name, name, 8);
Expand All @@ -472,8 +493,6 @@ int Wad::CheckContentMap(const char *installpath, tmd_content *content, char *fi
if(!WriteFile(filepath, content_map, content_map_size * sizeof(map_entry_t)))
return -1;

snprintf(filepath, 1024, "%s/shared1/%08x.app", installpath, (unsigned int)next_entry);

return 0;
}

Expand Down
1 change: 1 addition & 0 deletions source/wad/wad.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class Wad
private:
bool InstallContents(const char *installpath);
int CheckContentMap(const char *installpath, tmd_content *content, char *filepath);
int UpdateContentMap(const char *installpath, tmd_content *content, char *filepath);
bool WriteFile(const char *filepath, u8 *buffer, u32 len);
bool SetTitleUID(const char *intallpath, const u64 &tid);

Expand Down