*Fixed crash with loading .iso files

*Fixed freeze in theme menu when its empty
*Optimized the game list loading on fat/ntfs/ext. This should speed up the loading process.
*Added cache of game titles. This will speed up the startup after the cache file is written (in other words on second start of this rev). A TitlesCache.bin will be created in the same path as the wiitdb.xml for this. This should especial speed up the startup of fat/ntfs/ext partitions by a lot if no sub folders with the game titles are used, like GAMEID.wbfs only. That must have been painfully slow before on a lot of games. Should be at about the same speed as with sub folders now. I would still recommend to use sub folders.
*Removed wiilight (disc slot) blinking when switching USB port on Hermes cIOSes (thanks rodries)
*Added the ehcmodule sources from rodries to the branches
*Updated language files
This commit is contained in:
dimok321 2011-02-11 17:41:52 +00:00
parent 7f2778e17f
commit 037edbe7ea
19 changed files with 1178 additions and 1157 deletions

View File

@ -2,8 +2,8 @@
<app version="1">
<name> USB Loader GX</name>
<coder>USB Loader GX Team</coder>
<version>2.0 r1068</version>
<release_date>201102060936</release_date>
<version>2.0 r1069</version>
<release_date>201102061836</release_date>
<no_ios_reload/>
<short_description>Loads games from USB-devices</short_description>
<long_description>USB Loader GX is a libwiigui based USB iso loader with a wii-like GUI. You can install games to your HDDs and boot them with shorter loading times.

View File

@ -145,7 +145,7 @@ msgid "App Language"
msgstr "Programsprog"
msgid "Apply"
msgstr ""
msgstr "Indlæs"
msgid "Apr"
msgstr ""
@ -163,13 +163,13 @@ msgid "Aug"
msgstr ""
msgid "Author(s):"
msgstr ""
msgstr "Forfatter"
msgid "AutoInit Network"
msgstr "AutoInit netværk"
msgid "Automatic port switching is done on the fly. You need to change all custom paths to SD-Card first for this option or else it could damage a filesystem."
msgstr ""
msgstr "Automatisk skift af port er gjort on the fly. For denne mulighed skal du skifte alle brugerdefinerede stier til SD kortet først, for ellers kan det skade dit fil system."
msgid "BCA Codes Path"
msgstr "Sti til BCA koder"
@ -247,7 +247,7 @@ msgid "Both"
msgstr "Begge"
msgid "Both Ports"
msgstr ""
msgstr "Begge porte"
msgid "Can't be formatted"
msgstr "Kan ikke formateres"
@ -445,7 +445,7 @@ msgid "Do you want to apply it now?"
msgstr "Skal det aktiveres nu?"
msgid "Do you want to apply this theme?"
msgstr ""
msgstr "Vil du inlæse dette tema?"
msgid "Do you want to change language?"
msgstr "Skal sproget ændres?"
@ -949,7 +949,7 @@ msgid "No themes found on the site."
msgstr "Der blev ikke fundet nogle temaer på denne side."
msgid "No themes found."
msgstr ""
msgstr "Ingen temaer fundet."
msgid "None"
msgstr "Ingen"
@ -1289,7 +1289,7 @@ msgid "Theme Downloader"
msgstr "Tema-downloader"
msgid "Theme Menu"
msgstr ""
msgstr "Tema menu"
msgid "Theme Path"
msgstr "Sti til temaer"
@ -1331,7 +1331,7 @@ msgid "USB Port"
msgstr ""
msgid "USB Port changing is only supported on Hermes cIOS."
msgstr ""
msgstr "Skift af USB port er kun muligt med Hermess cIOS."
msgid "Uninstall"
msgstr "Afinstallér"

View File

@ -1,12 +1,12 @@
# USB Loader GX language source file.
# dutch.lang - r1061
# dutch.lang - r1068
# don't delete/change this line (é).
msgid ""
msgstr ""
"Project-Id-Version: USB Loader GX\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-02-06 19:36+0100\n"
"PO-Revision-Date: 2011-02-04 13:06+0100\n"
"PO-Revision-Date: 2011-02-07 08:11+0100\n"
"Last-Translator: glowy\n"
"Language-Team: tj_cool, glowy\n"
"MIME-Version: 1.0\n"
@ -145,7 +145,7 @@ msgid "App Language"
msgstr "Applicatie Taal"
msgid "Apply"
msgstr ""
msgstr "Toepassen"
msgid "Apr"
msgstr ""
@ -163,13 +163,13 @@ msgid "Aug"
msgstr ""
msgid "Author(s):"
msgstr ""
msgstr "Auteur(s):"
msgid "AutoInit Network"
msgstr "Netwerk Auto init."
msgid "Automatic port switching is done on the fly. You need to change all custom paths to SD-Card first for this option or else it could damage a filesystem."
msgstr ""
msgstr "Automatisch poort wisselen word zonder onderbreking gedaan. Je moet eerst alle aangepaste paden veranderen naar SD-kaart voor deze optie anders kan het je bestandssysteem beschadigen."
msgid "BCA Codes Path"
msgstr "Locatie BCA codes"
@ -247,7 +247,7 @@ msgid "Both"
msgstr "Beide"
msgid "Both Ports"
msgstr ""
msgstr "Beide poorten"
msgid "Can't be formatted"
msgstr "Kan niet geformatteerd worden"
@ -445,7 +445,7 @@ msgid "Do you want to apply it now?"
msgstr "Wil je dit nu toepassen?"
msgid "Do you want to apply this theme?"
msgstr ""
msgstr "Wil je dit thema toepassen?"
msgid "Do you want to change language?"
msgstr "Wil je de taal wijzigen?"
@ -949,7 +949,7 @@ msgid "No themes found on the site."
msgstr "Geen thema's gevonden op de site."
msgid "No themes found."
msgstr ""
msgstr "Geen thema's gevonden."
msgid "None"
msgstr "Geen"
@ -1289,7 +1289,7 @@ msgid "Theme Downloader"
msgstr "Thema downloader"
msgid "Theme Menu"
msgstr ""
msgstr "Thema Menu"
msgid "Theme Path"
msgstr "Locatie thema"
@ -1328,10 +1328,10 @@ msgid "USB Loader GX is protected"
msgstr "USB Loader GX is vergrendeld"
msgid "USB Port"
msgstr ""
msgstr "USB Poort"
msgid "USB Port changing is only supported on Hermes cIOS."
msgstr ""
msgstr "USB Poort wisselen word alleen door Hermes cIOS ondersteund."
msgid "Uninstall"
msgstr "Verwijderen"
@ -1394,7 +1394,7 @@ msgid "VIDTV Patch"
msgstr "VIDTV patchen"
msgid "Version:"
msgstr ""
msgstr "Versie:"
#, c-format
msgid "Version: %s"

View File

@ -1,11 +1,11 @@
# USB Loader GX
# german language source file - r1061
# german language source file - r1068
# don't delete/change this line (é).
msgid ""
msgstr ""
"Project-Id-Version: USB Loader GX\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-02-06 19:36+0100\n"
"POT-Creation-Date: 2011-02-06 22:00+0100\n"
"PO-Revision-Date: 2010-07-03 17:35-0800\n"
"Last-Translator: TheRealVisitor\n"
"Language-Team: Bertilax, Snoozer, wishmasterf, ZEN.13, TheRealVisitor\n"
@ -145,7 +145,7 @@ msgid "App Language"
msgstr "Sprache"
msgid "Apply"
msgstr ""
msgstr "Anwenden"
msgid "Apr"
msgstr "April"
@ -163,13 +163,13 @@ msgid "Aug"
msgstr "August"
msgid "Author(s):"
msgstr ""
msgstr "Autor(en)"
msgid "AutoInit Network"
msgstr "Autoinit. Netzwerk"
msgid "Automatic port switching is done on the fly. You need to change all custom paths to SD-Card first for this option or else it could damage a filesystem."
msgstr ""
msgstr "Automatische Portumschaltung wird jetzt direkt zur Programmlaufzeit durchgeführt. Für diese Option müssen zuerst alle eigenen Pfade auf die SD Karte verweisen, da ansonsten das Dateisystem beschädigt werden könnte."
msgid "BCA Codes Path"
msgstr "BCA Codes"
@ -247,7 +247,7 @@ msgid "Both"
msgstr "ID und Region"
msgid "Both Ports"
msgstr ""
msgstr "Beide Ports"
msgid "Can't be formatted"
msgstr "Kann nicht formatiert werden."
@ -445,7 +445,7 @@ msgid "Do you want to apply it now?"
msgstr "Jetzt übernehmen?"
msgid "Do you want to apply this theme?"
msgstr ""
msgstr "Dieses Theme angewenden?"
msgid "Do you want to change language?"
msgstr "Sprache ändern?"
@ -460,7 +460,7 @@ msgid "Do you want to load the default theme?"
msgstr "Soll das DEFAULT Theme geladen werden?"
msgid "Do you want to sync free space info sector on all FAT32 partitions?"
msgstr ""
msgstr "Soll die freier Speicher Info auf allen Partitionen synchronisiert werden?"
msgid "Do you wish to update/download all language files?"
msgstr "Alle Sprachdateien aktualisieren?"
@ -949,7 +949,7 @@ msgid "No themes found on the site."
msgstr "Keine Themes auf der Seite gefunden."
msgid "No themes found."
msgstr ""
msgstr "Keine Themes gefunden."
msgid "None"
msgstr "Keine"
@ -1289,7 +1289,7 @@ msgid "Theme Downloader"
msgstr "Theme Downloader"
msgid "Theme Menu"
msgstr ""
msgstr "Theme Menü"
msgid "Theme Path"
msgstr "Theme"
@ -1328,10 +1328,10 @@ msgid "USB Loader GX is protected"
msgstr "USB Loader GX ist jetzt geschützt."
msgid "USB Port"
msgstr ""
msgstr "USB Port"
msgid "USB Port changing is only supported on Hermes cIOS."
msgstr ""
msgstr "USB-Portwechsel wird nur vom Hermes cIOS unterstützt."
msgid "Uninstall"
msgstr "Deinstallieren"
@ -1394,7 +1394,7 @@ msgid "VIDTV Patch"
msgstr "VIDTV Patch"
msgid "Version:"
msgstr ""
msgstr "Version:"
#, c-format
msgid "Version: %s"

View File

@ -1,14 +1,14 @@
# USB Loader GX language source file.
# japanese.lang - r1046J
# japanese.lang - r1065J
# don't delete/change this line (e).
msgid ""
msgstr ""
"Project-Id-Version: USB Loader GX\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-02-06 19:36+0100\n"
"POT-Creation-Date: 2011-02-05 17:39+0100\n"
"PO-Revision-Date: 2009-10-01 01:00+0200\n"
"Last-Translator: ichiroling\n"
"Language-Team: hosigumayuugi, papa\n"
"Language-Team: hosigumayuugi, papa, ichiroling\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
@ -145,7 +145,7 @@ msgid "App Language"
msgstr "使用言語"
msgid "Apply"
msgstr ""
msgstr "適用"
msgid "Apr"
msgstr "4月"
@ -163,14 +163,11 @@ msgid "Aug"
msgstr "8月"
msgid "Author(s):"
msgstr ""
msgstr "制作者:"
msgid "AutoInit Network"
msgstr "自動ネット接続"
msgid "Automatic port switching is done on the fly. You need to change all custom paths to SD-Card first for this option or else it could damage a filesystem."
msgstr ""
msgid "BCA Codes Path"
msgstr "BCAコード"
@ -246,9 +243,6 @@ msgstr "起動しますか?"
msgid "Both"
msgstr "IDとリージョンを表示"
msgid "Both Ports"
msgstr ""
msgid "Can't be formatted"
msgstr "初期化できません"
@ -445,7 +439,7 @@ msgid "Do you want to apply it now?"
msgstr "適用しますか?"
msgid "Do you want to apply this theme?"
msgstr ""
msgstr "このテーマを使いますか?"
msgid "Do you want to change language?"
msgstr "言語を変更しますか?"
@ -949,7 +943,7 @@ msgid "No themes found on the site."
msgstr "テーマが見つかりません"
msgid "No themes found."
msgstr ""
msgstr "テーマが見つかりません"
msgid "None"
msgstr "なし"
@ -994,7 +988,7 @@ msgid "OFF"
msgstr "使わない"
msgid "OK"
msgstr ""
msgstr "確定する"
msgid "ON"
msgstr "使う"
@ -1289,7 +1283,7 @@ msgid "Theme Downloader"
msgstr "テーマをダウンロード"
msgid "Theme Menu"
msgstr ""
msgstr "テーマ"
msgid "Theme Path"
msgstr "テーマ"
@ -1327,12 +1321,6 @@ msgstr "USB機器が見つかりません"
msgid "USB Loader GX is protected"
msgstr "GXは保護されています"
msgid "USB Port"
msgstr ""
msgid "USB Port changing is only supported on Hermes cIOS."
msgstr ""
msgid "Uninstall"
msgstr "アンインストール"
@ -1394,7 +1382,7 @@ msgid "VIDTV Patch"
msgstr "映像パッチ"
msgid "Version:"
msgstr ""
msgstr "バージョン:"
#, c-format
msgid "Version: %s"

View File

@ -5,7 +5,7 @@ msgid ""
msgstr ""
"Project-Id-Version: USB Loader GX\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-02-06 19:36+0100\n"
"POT-Creation-Date: 2011-02-11 18:41+0100\n"
"PO-Revision-Date: 2009-10-01 01:00+0200\n"
"Last-Translator: knife.hu kavid emul8ion\n"
"Language-Team: kavid\n"
@ -145,7 +145,7 @@ msgid "App Language"
msgstr "语言设定"
msgid "Apply"
msgstr ""
msgstr "应用"
msgid "Apr"
msgstr "四月"
@ -163,7 +163,7 @@ msgid "Aug"
msgstr "八月"
msgid "Author(s):"
msgstr ""
msgstr "作者:"
msgid "AutoInit Network"
msgstr "自动检测网络"
@ -247,7 +247,7 @@ msgid "Both"
msgstr "全部"
msgid "Both Ports"
msgstr ""
msgstr "两个接口"
msgid "Can't be formatted"
msgstr "无法格式化"
@ -445,7 +445,7 @@ msgid "Do you want to apply it now?"
msgstr "要现在应用吗?"
msgid "Do you want to apply this theme?"
msgstr ""
msgstr "你想应用这个主题吗?"
msgid "Do you want to change language?"
msgstr "要变更语言吗?"
@ -943,13 +943,13 @@ msgid "No file missing!"
msgstr "没有文件缺少!"
msgid "No new updates."
msgstr "没有可用更新"
msgstr "没有可用更新."
msgid "No themes found on the site."
msgstr "网站上没找到主题"
msgstr "网站上没找到主题."
msgid "No themes found."
msgstr ""
msgstr "没有找到主题."
msgid "None"
msgstr "无"
@ -1289,7 +1289,7 @@ msgid "Theme Downloader"
msgstr "主题下载器"
msgid "Theme Menu"
msgstr ""
msgstr "主题菜单"
msgid "Theme Path"
msgstr "主题路径"
@ -1328,10 +1328,10 @@ msgid "USB Loader GX is protected"
msgstr "USB Loader GX 被锁定"
msgid "USB Port"
msgstr ""
msgstr "USB接口"
msgid "USB Port changing is only supported on Hermes cIOS."
msgstr ""
msgstr "仅Hermes CIOS支持USB接口的改变"
msgid "Uninstall"
msgstr "删除"
@ -1394,7 +1394,7 @@ msgid "VIDTV Patch"
msgstr "VIDTV修改"
msgid "Version:"
msgstr ""
msgstr "版本:"
#, c-format
msgid "Version: %s"

View File

@ -27,11 +27,11 @@ msgstr "不在伺服器上"
#, c-format
msgid "%i files not found on the server!"
msgstr ""
msgstr "伺服器上找不到%i個檔"
#, c-format
msgid "%i missing files"
msgstr ""
msgstr "缺少%i個檔案"
msgid "0 (Everyone)"
msgstr "0 (全年齡)"
@ -145,7 +145,7 @@ msgid "App Language"
msgstr "語言設定"
msgid "Apply"
msgstr ""
msgstr "套用"
msgid "Apr"
msgstr "四月"
@ -163,13 +163,13 @@ msgid "Aug"
msgstr "八月"
msgid "Author(s):"
msgstr ""
msgstr "作者(群)"
msgid "AutoInit Network"
msgstr "自動檢查網路"
msgid "Automatic port switching is done on the fly. You need to change all custom paths to SD-Card first for this option or else it could damage a filesystem."
msgstr ""
msgstr "快速執行自動槽位切換。首先你需要在SD卡改變所有自訂路徑這個選項否則可能會損壞檔案系統。"
msgid "BCA Codes Path"
msgstr "BAC代碼路徑"
@ -247,7 +247,7 @@ msgid "Both"
msgstr "全部"
msgid "Both Ports"
msgstr ""
msgstr "兩個插槽"
msgid "Can't be formatted"
msgstr "無法格式化"
@ -364,7 +364,7 @@ msgid "Credits"
msgstr "作者信息"
msgid "Custom Discarts"
msgstr ""
msgstr "自製光碟圖片"
msgid "Custom Paths"
msgstr "自訂路徑"
@ -445,7 +445,7 @@ msgid "Do you want to apply it now?"
msgstr "要套用設定嗎?"
msgid "Do you want to apply this theme?"
msgstr ""
msgstr "要套用這個佈景主題嗎?"
msgid "Do you want to change language?"
msgstr "要變更語言嗎?"
@ -484,10 +484,10 @@ msgid "Downloading Flat Covers"
msgstr "下載一般封面"
msgid "Downloading Full HQ Covers"
msgstr ""
msgstr "下載完整高畫質封面"
msgid "Downloading Full LQ Covers"
msgstr ""
msgstr "下載完整低畫質封面"
msgid "Downloading custom Discarts"
msgstr "下載自製光碟圖片"
@ -622,7 +622,7 @@ msgid "Formatting, please wait..."
msgstr "格式化中, 請稍候..."
msgid "Found missing images."
msgstr ""
msgstr "找到缺少圖片。"
msgid "Free Space"
msgstr "剩餘空間"
@ -631,13 +631,13 @@ msgid "French"
msgstr "法文"
msgid "Full Cover Path"
msgstr ""
msgstr "完整封面路徑"
msgid "Full HQ Covers"
msgstr ""
msgstr "完整高畫質封面"
msgid "Full LQ Covers"
msgstr ""
msgstr "完整低畫質封面"
msgid "Full Menu"
msgstr "完整選單"
@ -694,7 +694,7 @@ msgid "Game is already installed:"
msgstr "已安裝過遊戲:"
msgid "Game/Install Partition"
msgstr ""
msgstr "遊戲/安裝磁區"
msgid "Gamename [GAMEID]"
msgstr "遊戲名稱 [GAMEID]"
@ -892,7 +892,7 @@ msgid "Mount DVD drive"
msgstr "掛載DVD光碟"
msgid "Multiple Partitions"
msgstr ""
msgstr "多重磁區"
msgid "Music Loop Mode"
msgstr "音樂循環模式"
@ -949,7 +949,7 @@ msgid "No themes found on the site."
msgstr "在網站上找不到主題。"
msgid "No themes found."
msgstr ""
msgstr "找不到佈景主題。"
msgid "None"
msgstr "沒有"
@ -1018,7 +1018,7 @@ msgid "Only for Install"
msgstr "安裝遊戲時"
msgid "Original Discarts"
msgstr ""
msgstr "原始光碟圖片"
msgid "Original/Customs"
msgstr "原始/自製"
@ -1153,7 +1153,7 @@ msgid "Save Game List to"
msgstr "儲存遊戲清單至"
msgid "Save List"
msgstr ""
msgstr "儲存清單"
msgid "Saved"
msgstr "已儲存"
@ -1195,7 +1195,7 @@ msgid "Sort alphabetically"
msgstr "以字母順序排序"
msgid "Sort by number of players"
msgstr ""
msgstr "以玩家人數排序"
msgid "Sort by rank"
msgstr "以等級排序"
@ -1289,7 +1289,7 @@ msgid "Theme Downloader"
msgstr "佈景主題下載"
msgid "Theme Menu"
msgstr ""
msgstr "佈景主題選單"
msgid "Theme Path"
msgstr "佈景主題路徑"
@ -1328,10 +1328,10 @@ msgid "USB Loader GX is protected"
msgstr "USB Loader GX 被上鎖保護"
msgid "USB Port"
msgstr ""
msgstr "USB 插槽"
msgid "USB Port changing is only supported on Hermes cIOS."
msgstr ""
msgstr "USB插槽變更僅Hermes cIOS支援。"
msgid "Uninstall"
msgstr "移除"
@ -1394,7 +1394,7 @@ msgid "VIDTV Patch"
msgstr "VIDTV 修改"
msgid "Version:"
msgstr ""
msgstr "版本:"
#, c-format
msgid "Version: %s"
@ -1857,4 +1857,4 @@ msgstr "剩餘秒數"
#~ msgstr "不存在!檔案錯誤"
#~ msgid "file left"
#~ msgstr "剩餘文件"
#~ msgstr "剩餘文件"

View File

@ -289,18 +289,6 @@ u32 wbfs_sector_used(wbfs_t *p, wbfs_disc_info_t *di)
return tot_blk;
}
u32 wbfs_sector_used2(wbfs_t *p, wbfs_disc_info_t *di, u32 *last_blk)
{
u32 tot_blk = 0, j;
for (j = 0; j < p->n_wbfs_sec_per_disc; j++)
if (wbfs_ntohs( di->wlba_table[j] ))
{
if (last_blk) *last_blk = j;
tot_blk++;
}
return tot_blk;
}
u32 wbfs_get_disc_info(wbfs_t*p, u32 index, u8 *header, int header_size, u32 *size)//size in 32 bit
{
u32 i, count = 0;
@ -790,7 +778,7 @@ int wbfs_get_fragments(wbfs_disc_t *d, _frag_append_t append_fragment, void *cal
int wbfs_iso_file_read(wbfs_disc_t*d, u32 offset, u8 *data, u32 len)
{
if (!d || d->p != &wbfs_iso_file) return -1;
int fd = (int) d->header;
int fd = d->i;
off_t off = ((u64) offset) << 2;
off_t ret_off;
int ret;
@ -801,26 +789,18 @@ int wbfs_iso_file_read(wbfs_disc_t*d, u32 offset, u8 *data, u32 len)
return 0;
}
u32 wbfs_disc_sector_used(wbfs_disc_t *d, u32 *num_blk)
u32 wbfs_disc_sector_used(wbfs_disc_t *d)
{
if(!d) return 0;
if (d->p == &wbfs_iso_file)
{
int fd = (int) d->header;
int fd = d->i;
struct stat st;
if (fstat(fd, &st) == -1) return 0;
if (num_blk)
{
*num_blk = (st.st_size >> 9); // in 512 units
}
return st.st_blocks; // in 512 units (can be sparse)
return (st.st_size >> 9);
}
u32 last_blk = 0;
u32 ret;
ret = wbfs_sector_used2(d->p, d->header, &last_blk);
if (num_blk)
{
*num_blk = last_blk + 1;
}
return ret;
return wbfs_sector_used(d->p, d->header);
}

View File

@ -151,7 +151,6 @@ extern "C"
void wbfs_close_disc(wbfs_disc_t*d);
u32 wbfs_sector_used(wbfs_t *p, wbfs_disc_info_t *di);
u32 wbfs_sector_used2(wbfs_t *p, wbfs_disc_info_t *di, u32 *last_blk);
/*! @brief accessor to the wii disc
@param d: a pointer to already open disc
@ -225,7 +224,7 @@ extern "C"
int wbfs_get_fragments(wbfs_disc_t *d, _frag_append_t append_fragment, void *callback_data);
extern wbfs_t wbfs_iso_file;
u32 wbfs_disc_sector_used(wbfs_disc_t *d, u32 *num_blk);
u32 wbfs_disc_sector_used(wbfs_disc_t *d);
int wbfs_iso_file_read(wbfs_disc_t*d, u32 offset, u8 *data, u32 len);
#ifdef __cplusplus

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,3 @@
#define size_ehcmodule_5 25856
#define size_ehcmodule_5 25776
extern unsigned char ehcmodule_5[25856];
extern unsigned char ehcmodule_5[25776];

View File

@ -543,6 +543,7 @@ int WindowPrompt(const char *title, const char *msg, const char *btn1Label, cons
mainWindow->SetState(STATE_DISABLED);
mainWindow->Append(Window);
mainWindow->ChangeFocus(Window);
ResumeGui();
while (choice == -1)
{

View File

@ -23,13 +23,7 @@ void CGameTitles::SetGameTitle(const char * id, const char * title)
GameTitle newTitle;
newTitle.Title = title;
//! Just in case a 0 termination is missing
int n;
for(n = 0; n < 6; ++n)
newTitle.GameID[n] = id[n];
newTitle.GameID[n] = '\0';
snprintf(newTitle.GameID, sizeof(newTitle.GameID), id);
TitleList.push_back(newTitle);
}
@ -98,6 +92,113 @@ void CGameTitles::SetDefault()
std::vector<GameTitle>().swap(TitleList);
}
typedef struct _CacheTitle
{
char GameID[7];
char Title[100];
int ParentalRating;
int PlayersCount;
} ATTRIBUTE_PACKED CacheTitle;
u32 CGameTitles::ReadCachedTitles(const char * path)
{
//! Load cached least so that the titles are preloaded before reading list
FILE * f = fopen(path, "rb");
if(!f) return 0;
char LangCode[11];
memset(LangCode, 0, sizeof(LangCode));
fread(LangCode, 1, 10, f);
//! Check if cache has correct language code
if(strcmp(LangCode, Settings.db_language) != 0)
{
fclose(f);
return 0;
}
u32 count = 0;
fread(&count, 1, 4, f);
std::vector<CacheTitle> CachedList(count);
TitleList.resize(count);
fread(&CachedList[0], 1, count*sizeof(CacheTitle), f);
fclose(f);
for(u32 i = 0; i < count; ++i)
{
strcpy(TitleList[i].GameID, CachedList[i].GameID);
TitleList[i].Title = CachedList[i].Title;
TitleList[i].ParentalRating = CachedList[i].ParentalRating;
TitleList[i].PlayersCount = CachedList[i].PlayersCount;
}
return count;
}
void CGameTitles::WriteCachedTitles(const char * path)
{
FILE *f = fopen(path, "wb");
if(!f)
return;
CacheTitle Cache;
u32 count = TitleList.size();
fwrite(Settings.db_language, 1, 10, f);
fwrite(&count, 1, 4, f);
for(u32 i = 0; i < count; ++i)
{
memset(&Cache, 0, sizeof(CacheTitle));
strcpy(Cache.GameID, TitleList[i].GameID);
snprintf(Cache.Title, sizeof(Cache.Title), TitleList[i].Title.c_str());
Cache.ParentalRating = TitleList[i].ParentalRating;
Cache.PlayersCount = TitleList[i].PlayersCount;
fwrite(&Cache, 1, sizeof(CacheTitle), f);
}
fclose(f);
}
void CGameTitles::RemoveUnusedCache(std::vector<std::string> &MissingTitles)
{
std::vector<bool> UsedCachedList(TitleList.size(), false);
for(int i = 0; i < gameList.GameCount(); ++i)
{
bool isCached = false;
for(u32 n = 0; n < TitleList.size(); ++n)
{
if(strncmp(TitleList[n].GameID, (const char *) gameList[i]->id, 6) == 0)
{
UsedCachedList[n] = true;
isCached = true;
break;
}
}
if(!isCached)
{
char gameID[7];
snprintf(gameID, sizeof(gameID), (const char *) gameList[i]->id);
MissingTitles.push_back(std::string(gameID));
}
}
for(u32 n = 0; n < TitleList.size(); ++n)
{
if(!UsedCachedList[n])
TitleList.erase(TitleList.begin()+n);
}
}
void CGameTitles::LoadTitlesFromWiiTDB(const char * path)
{
this->SetDefault();
@ -105,39 +206,58 @@ void CGameTitles::LoadTitlesFromWiiTDB(const char * path)
if(!path || !Settings.titlesOverride)
return;
gameList.LoadUnfiltered();
std::string Title;
std::string Filepath = path;
if(path[strlen(path)-1] != '/')
Filepath += '/';
std::string Cachepath = Filepath;
Cachepath += "TitlesCache.bin";
Filepath += "wiitdb.xml";
//! Read game titles cache database
ReadCachedTitles(Cachepath.c_str());
//! Read game list
gameList.LoadUnfiltered();
//! Removed unused cache titles and get the still missing ones
std::vector<std::string> MissingTitles;
RemoveUnusedCache(MissingTitles);
if(MissingTitles.size() == 0)
{
WriteCachedTitles(Cachepath.c_str());
return;
}
std::string Title;
WiiTDB XML_DB(Filepath.c_str());
XML_DB.SetLanguageCode(Settings.db_language);
int Rating;
std::string RatValTxt;
for(int i = 0; i < gameList.GameCount(); ++i)
for(u32 i = 0; i < MissingTitles.size(); ++i)
{
if(!XML_DB.GetTitle((const char *) gameList[i]->id, Title))
if(!XML_DB.GetTitle(MissingTitles[i].c_str(), Title))
continue;
this->SetGameTitle(gameList[i]->id, Title.c_str());
this->SetGameTitle(MissingTitles[i].c_str(), Title.c_str());
TitleList[TitleList.size()-1].ParentalRating = -1;
TitleList[TitleList.size()-1].PlayersCount = 1;
Rating = XML_DB.GetRating((const char *) gameList[i]->id);
Rating = XML_DB.GetRating(MissingTitles[i].c_str());
if(Rating < 0)
continue;
if(!XML_DB.GetRatingValue((const char *) gameList[i]->id, RatValTxt))
if(!XML_DB.GetRatingValue(MissingTitles[i].c_str(), RatValTxt))
continue;
TitleList[TitleList.size()-1].ParentalRating = ConvertRating(RatValTxt.c_str(), WiiTDB::RatingToString(Rating), "PEGI");
int ret = XML_DB.GetPlayers((const char *) gameList[i]->id);
int ret = XML_DB.GetPlayers(MissingTitles[i].c_str());
if(ret > 0)
TitleList[TitleList.size()-1].PlayersCount = ret;
}
WriteCachedTitles(Cachepath.c_str());
}

View File

@ -39,6 +39,10 @@ class CGameTitles
//! Set default game titles
void SetDefault();
protected:
u32 ReadCachedTitles(const char * path);
void WriteCachedTitles(const char * path);
void RemoveUnusedCache(std::vector<std::string> &MissingTitles);
std::vector<GameTitle> TitleList;
};

View File

@ -191,7 +191,6 @@ void ThemeMenu::SetupMainButtons()
if (ThemeDir.GetFilecount() == 0)
{
WindowPrompt(tr( "No themes found." ), 0, "OK");
returnMenu = MENU_SETTINGS;
}
for(int i = 0; i < ThemeDir.GetFilecount(); ++i)

View File

@ -129,6 +129,8 @@ int GameList::InternalReadList(int part)
u32 oldSize = FullGameList.size();
std::vector<struct discHdr> PartGameList(cnt);
memcpy(&PartGameList[0], buffer, len);
free(buffer);
for (u32 i = 0; i < PartGameList.size(); i++)
{
for(u32 j = 0; j < FullGameList.size(); j++)
@ -144,8 +146,6 @@ int GameList::InternalReadList(int part)
FullGameList.resize(oldSize+PartGameList.size());
memcpy(&FullGameList[oldSize], &PartGameList[0], PartGameList.size()*sizeof(struct discHdr));
free(buffer);
GamePartitionList.resize(oldSize+PartGameList.size());
for(u32 i = oldSize; i < GamePartitionList.size(); ++i)

View File

@ -79,19 +79,17 @@ s32 Wbfs::CheckGame(u8 *discid)
s32 Wbfs::GameSize(u8 *discid, f32 *size)
{
wbfs_disc_t *disc = NULL;
u32 sectors;
if(!discid) return 0;
/* Open disc */
disc = OpenDisc(discid);
wbfs_disc_t *disc = OpenDisc(discid);
if (!disc) return -2;
/* Get game size in sectors */
sectors = wbfs_sector_used(disc->p, disc->header);
u32 sectors = wbfs_disc_sector_used(disc);
/* Copy value */
*size = (disc->p->wbfs_sec_sz / GB_SIZE) * sectors;
if(size)
*size = (disc->p->wbfs_sec_sz / GB_SIZE) * sectors;
/* Close disc */
CloseDisc(disc);

View File

@ -92,7 +92,14 @@ wbfs_disc_t* Wbfs_Fat::OpenDisc(u8 *discid)
// mark with a special wbfs_part
wbfs_iso_file.wbfs_sec_sz = 512;
iso_file->p = &wbfs_iso_file;
iso_file->header = (wbfs_disc_info_t*) fd;
iso_file->header = (wbfs_disc_info_t*) malloc(sizeof(wbfs_disc_info_t));
if(!iso_file->header)
{
free(iso_file);
return NULL;
}
read(fd, iso_file->header, sizeof(wbfs_disc_info_t));
iso_file->i = fd;
return iso_file;
}
@ -117,7 +124,8 @@ void Wbfs_Fat::CloseDisc(wbfs_disc_t* disc)
// is this really a .iso file?
if (part == &wbfs_iso_file)
{
close((int) disc->header);
close(disc->i);
free(disc->header);
free(disc);
return;
}
@ -129,37 +137,19 @@ void Wbfs_Fat::CloseDisc(wbfs_disc_t* disc)
s32 Wbfs_Fat::GetCount(u32 *count)
{
*count = 0;
GetHeadersCount();
if (fat_hdr_count && fat_hdr_list)
{
// for compacter mem - move up as it will be freed later
int size = fat_hdr_count * sizeof(struct discHdr);
struct discHdr *buf = (struct discHdr *) malloc(size);
if (buf)
{
memcpy(buf, fat_hdr_list, size);
SAFE_FREE( fat_hdr_list );
fat_hdr_list = buf;
}
}
*count = fat_hdr_count;
return 0;
}
s32 Wbfs_Fat::GetHeaders(struct discHdr *outbuf, u32 cnt, u32 len)
{
u32 i;
if (len > sizeof(struct discHdr))
{
len = sizeof(struct discHdr);
}
if(cnt*len > fat_hdr_count*sizeof(struct discHdr))
return -1;
for (i = 0; i < cnt && i < fat_hdr_count; i++)
{
memcpy(&outbuf[i], &fat_hdr_list[i], len);
}
SAFE_FREE( fat_hdr_list );
memcpy(outbuf, fat_hdr_list, cnt*len);
SAFE_FREE(fat_hdr_list);
fat_hdr_count = 0;
return 0;
@ -187,7 +177,6 @@ s32 Wbfs_Fat::AddGame(void)
ClosePart(part);
if (ret < 0) return ret;
mk_title_txt(&header, path);
return 0;
}
@ -368,19 +357,13 @@ s32 Wbfs_Fat::GetHeadersCount()
char fpath[MAX_FAT_PATH];
struct discHdr tmpHdr;
struct stat st;
wbfs_t *part = NULL;
u8 id[8];
int ret;
char *p;
u32 size;
int is_dir;
int len;
char dir_title[65];
char fname_title[TITLE_LEN];
const char *title;
DIR *dir_iter;
struct dirent *dirent;
//dbg_time1();
SAFE_FREE( fat_hdr_list );
fat_hdr_count = 0;
@ -393,119 +376,97 @@ s32 Wbfs_Fat::GetHeadersCount()
while ((dirent = readdir(dir_iter)) != 0)
{
snprintf(fname, sizeof(fname), "%s/%s", path, dirent->d_name);
if(stat(fname, &st) != 0)
continue;
if (dirent->d_name[0] == '.') continue;
snprintf(fname, sizeof(fname), dirent->d_name);
//printf("found: %s\n", fname); Wpad_WaitButtonsCommon();
if ((char) fname[0] == '.') continue;
len = strlen(fname);
if (len < 8) continue; // "GAMEID_x"
memcpy(id, fname, 6);
id[6] = 0;
// reset id and title
memset(id, 0, sizeof(id));
*fname_title = 0;
is_dir = S_ISDIR( st.st_mode );
//printf("mode: %d %d %x\n", is_dir, st.st_mode, st.st_mode);
if (is_dir)
{
int lay_a = 0;
int lay_b = 0;
if (fname[6] == '_' && is_gameid((char*) id))
{
// usb:/wbfs/GAMEID_TITLE/GAMEID.wbfs
lay_a = 1;
}
if (CheckLayoutB(fname, len, NULL, fname_title))
{
// usb:/wbfs/TITLE[GAMEID]/GAMEID.wbfs
lay_b = 1;
}
if (!lay_a && !lay_b) continue;
if (lay_a)
{
strncpy(dir_title, &fname[7], sizeof(dir_title));
}
else
{
try_lay_b: if (!CheckLayoutB(fname, len, id, fname_title)) continue;
}
snprintf(fpath, sizeof(fpath), "%s/%s/%s.wbfs", path, fname, id);
//printf("path2: %s\n", fpath);
// if more than 50 games, skip second stat to improve speed
// but if ambiguous layout check anyway
if (fat_hdr_count < 50 || (lay_a && lay_b))
{
if (stat(fpath, &st) == -1)
{
//printf("missing: %s\n", fpath);
// try .iso
strcpy(strrchr(fpath, '.'), ".iso"); // replace .wbfs with .iso
if (stat(fpath, &st) == -1)
{
//printf("missing: %s\n", fpath);
// try .ciso
strcpy(strrchr(fpath, '.'), ".ciso"); // replace .iso with .ciso
if (stat(fpath, &st) == -1)
{
if (lay_a && lay_b == 1)
{
// mark lay_b so that the stat check is still done,
// but lay_b is not re-tried again
lay_b = 2;
// retry with layout b
goto try_lay_b;
}
continue;
}
}
}
}
else
{
st.st_size = 1024 * 1024;
}
}
else
const char * fileext = strrchr(fname, '.');
if(fileext && (strcasecmp(fileext, ".wbfs") == 0 ||
strcasecmp(fileext, ".iso") == 0 || strcasecmp(fileext, ".ciso") == 0))
{
// usb:/wbfs/GAMEID.wbfs
// or usb:/wbfs/GAMEID.iso
// or usb:/wbfs/GAMEID.ciso
p = strrchr(fname, '.');
if (!p) continue;
if ((strcasecmp(p, ".wbfs") != 0) && (strcasecmp(p, ".iso") != 0) && (strcasecmp(p, ".ciso") != 0)) continue;
int n = p - fname; // length withouth .wbfs
int n = fileext - fname; // length withouth .wbfs
sprintf((char *) id, "%.6s", fname);
if (n != 6)
{
// TITLE [GAMEID].wbfs
if (!CheckLayoutB(fname, n, id, fname_title)) continue;
}
snprintf(fpath, sizeof(fpath), "%s/%s", path, fname);
is_dir = 0;
}
else
{
snprintf(fname, sizeof(fname), "%s/%s", path, dirent->d_name);
if(stat(fname, &st) != 0)
continue;
is_dir = S_ISDIR( st.st_mode );
if(!is_dir) continue;
snprintf(fname, sizeof(fname), dirent->d_name);
len = strlen(fname);
if (len < 8) continue; // "GAMEID_x"
int lay_a = 0;
int lay_b = 0;
if (CheckLayoutB(fname, len, id, fname_title))
{
// usb:/wbfs/TITLE[GAMEID]/GAMEID.wbfs
lay_b = 1;
}
else if (fname[6] == '_' && is_gameid((char*) id))
{
// usb:/wbfs/GAMEID_TITLE/GAMEID.wbfs
lay_a = 1;
memcpy(id, fname, 6);
snprintf(fname_title, sizeof(fname_title), &fname[7]);
}
if (!lay_a && !lay_b) continue;
// check ahead, make sure it succeeds
snprintf(fpath, sizeof(fpath), "%s/%s/%.6s.wbfs", path, fname, (char *) id);
}
//printf("found: %s %d MB\n", fpath, (int)(st.st_size/1024/1024));
// size must be at least 1MB to be considered a valid wbfs file
if (st.st_size < 1024 * 1024) continue;
// if we have titles.txt entry use that
title = GameTitles.GetTitle(id);
// if no titles.txt get title from dir or file name
if (!title && *fname_title)
{
title = fname_title;
}
if (title)
{
memset(&tmpHdr, 0, sizeof(tmpHdr));
memcpy(tmpHdr.id, id, 6);
strncpy(tmpHdr.title, title, sizeof(tmpHdr.title) - 1);
snprintf(tmpHdr.title, sizeof(tmpHdr.title), title);
tmpHdr.magic = 0x5D1C9EA3;
goto add_hdr;
}
if(is_dir)
{
if (stat(fpath, &st) != 0)
{
// look for direct .iso file
sprintf(strrchr(fpath, '.'), ".iso"); // replace .wbfs with .iso
if (stat(fpath, &st) != 0)
{
// look for direct .ciso file
sprintf(strrchr(fpath, '.'), ".ciso"); // replace .iso with .ciso
if (stat(fpath, &st) != 0) continue;
}
}
}
// else read it from file directly
if (strcasecmp(strrchr(fpath, '.'), ".wbfs") == 0)
{
@ -525,18 +486,17 @@ s32 Wbfs_Fat::GetHeadersCount()
// no title found, read it from wbfs file
// but this is a little bit slower
// open 'partition' file
part = OpenPart(fpath);
wbfs_t *part = OpenPart(fpath);
if (!part)
{
continue;
}
u32 size;
// Get header
ret = wbfs_get_disc_info(part, 0, (u8*) &tmpHdr, sizeof(struct discHdr), &size);
int ret = wbfs_get_disc_info(part, 0, (u8*) &tmpHdr, sizeof(struct discHdr), &size);
ClosePart(part);
if (ret == 0)
{
goto add_hdr;
}
}
else if (strcasecmp(strrchr(fpath, '.'), ".iso") == 0)
{
@ -573,19 +533,23 @@ s32 Wbfs_Fat::GetHeadersCount()
// fail:
continue;
// succes: add tmpHdr to list:
add_hdr: memset(&st, 0, sizeof(st));
//printf("added: %.6s %.20s\n", tmpHdr.id, tmpHdr.title); Wpad_WaitButtons();
// success: add tmpHdr to list:
add_hdr:
//! First allocate before reallocating
if(!fat_hdr_list)
fat_hdr_list = (struct discHdr *) malloc(sizeof(struct discHdr));
fat_hdr_count++;
fat_hdr_list = (struct discHdr *) realloc(fat_hdr_list, fat_hdr_count * sizeof(struct discHdr));
struct discHdr *tmpList = (struct discHdr *) realloc(fat_hdr_list, fat_hdr_count * sizeof(struct discHdr));
if(!tmpList)
break; //out of memory, keep the list until now and stop
fat_hdr_list = tmpList;
memcpy(&fat_hdr_list[fat_hdr_count - 1], &tmpHdr, sizeof(struct discHdr));
}
closedir(dir_iter);
//dbg_time2("\nFAT_GetCount"); Wpad_WaitButtonsCommon();
return 0;
}
@ -602,79 +566,71 @@ int Wbfs_Fat::FindFilename(u8 *id, char *fname, int len)
// look for direct .ciso file
strcpy(strrchr(fname, '.'), ".ciso"); // replace .iso with .ciso
if (stat(fname, &st) == 0) return 1;
// direct file not found, check subdirs
*fname = 0;
DIR *dir_iter;
struct dirent *dirent;
char gameID[7];
snprintf(gameID, sizeof(gameID), (char *) id);
char path[MAX_FAT_PATH];
char name[MAX_FAT_PATH];
strcpy(path, wbfs_fs_drive);
strcat(path, wbfs_fat_dir);
dir_iter = opendir(path);
//printf("dir: %s %p\n", path, dir); Wpad_WaitButtons();
if (!dir_iter)
{
return 0;
}
while ((dirent = readdir(dir_iter)) != 0)
{
snprintf(name, sizeof(name), "%s/%s", path, dirent->d_name);
if(strcasestr(dirent->d_name, gameID) == NULL) continue;
if(stat(name, &st) != 0)
continue;
snprintf(name, sizeof(name), dirent->d_name);
//dbg_printf("name:%s\n", name);
if (name[0] == '.') continue;
int n = strlen(name);
if (dirent->d_name[0] == '.') continue;
int n = strlen(dirent->d_name);
if (n < 8) continue;
if (S_ISDIR( st.st_mode ))
{
if (name[6] == '_')
{
// GAMEID_TITLE
if (strncmp(name, (char*) id, 6) != 0) goto try_alter;
}
else
{
try_alter:
// TITLE [GAMEID]
if (name[n - 8] != '[' || name[n - 1] != ']') continue;
if (strncmp(&name[n - 7], (char*) id, 6) != 0) continue;
}
// look for .wbfs file
snprintf(fname, len, "%s/%s/%.6s.wbfs", path, name, id);
if (stat(fname, &st) == 0) break;
// look for .iso file
snprintf(fname, len, "%s/%s/%.6s.iso", path, name, id);
if (stat(fname, &st) == 0) break;
// look for .ciso file
snprintf(fname, len, "%s/%s/%.6s.ciso", path, name, id);
}
else
const char *fileext = strrchr(dirent->d_name, '.');
if(fileext && (strcasecmp(fileext, ".wbfs") == 0 ||
strcasecmp(fileext, ".iso") == 0 || strcasecmp(fileext, ".ciso") == 0))
{
// TITLE [GAMEID].wbfs
char fn_title[TITLE_LEN];
u8 fn_id[8];
char *p = strrchr(name, '.');
if (!p) continue;
if ((strcasecmp(p, ".wbfs") != 0) && (strcasecmp(p, ".iso") != 0) && (strcasecmp(p, ".ciso") != 0)) continue;
int n = p - name; // length withouth .wbfs
if (!CheckLayoutB(name, n, fn_id, fn_title)) continue;
if (strncmp((char*) fn_id, (char*) id, 6) != 0) continue;
snprintf(fname, len, "%s/%s", path, name);
int n = fileext - dirent->d_name; // length withouth .wbfs
if (!CheckLayoutB(dirent->d_name, n, fn_id, fn_title)) continue;
if (strncmp((char*) fn_id, gameID, 6) != 0) continue;
snprintf(fname, len, "%s/%s", path, dirent->d_name);
if (stat(fname, &st) == 0) break;
}
if (stat(fname, &st) == 0) break;
snprintf(fname, sizeof(fname), "%s/%s", path, dirent->d_name);
if(stat(fname, &st) != 0)
{
*fname = 0;
continue;
}
if (S_ISDIR( st.st_mode ))
{
// look for .wbfs file
snprintf(fname, len, "%s/%s/%.6s.wbfs", path, dirent->d_name, gameID);
if (stat(fname, &st) == 0) break;
// look for .iso file
snprintf(fname, len, "%s/%s/%.6s.iso", path, dirent->d_name, gameID);
if (stat(fname, &st) == 0) break;
// look for .ciso file
snprintf(fname, len, "%s/%s/%.6s.ciso", path, dirent->d_name, gameID);
if (stat(fname, &st) == 0) break;
}
*fname = 0;
}
closedir(dir_iter);
if (*fname)
{
// found
//printf("found:%s\n", fname);
return 2;
}
// not found
return 0;
}
@ -777,23 +733,6 @@ wbfs_t* Wbfs_Fat::CreatePart(u8 *id, char *path)
return part;
}
void Wbfs_Fat::mk_title_txt(struct discHdr *header, char *path)
{
char fname[MAX_FAT_PATH];
FILE *f;
strcpy(fname, path);
strcat(fname, "/");
mk_gameid_title(header, fname + strlen(fname), 1, 0);
strcat(fname, ".txt");
f = fopen(fname, "wb");
if (!f) return;
fprintf(f, "%.6s = %.64s\n", header->id, GameTitles.GetTitle(header));
fclose(f);
printf("Info file: %s\n", fname);
}
void Wbfs_Fat::mk_gameid_title(struct discHdr *header, char *name, int re_space, int layout)
{
int i, len;

View File

@ -49,15 +49,11 @@ class Wbfs_Fat: public Wbfs
s32 GetHeadersCount();
void GetDir(struct discHdr *header, char *path);
void mk_title_txt(struct discHdr *header, char *path);
void mk_gameid_title(struct discHdr *header, char *name, int re_space, int layout);
void title_filename(char *title);
bool is_gameid(char *id);
static int nop_rw_sector(void *_fp, u32 lba, u32 count, void* buf)
{
return 0;
}
static int nop_rw_sector(void *_fp, u32 lba, u32 count, void* buf) { return 0; }
};
#endif //_WBFS_FAT_H