Guest User

wbfs patch

a guest
Jan 23rd, 2012
2,009
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. diff -rupN dolphin-orig/Source/Core/Core/Src/CoreParameter.cpp dolphin-patch/Source/Core/Core/Src/CoreParameter.cpp
  2. --- dolphin-orig/Source/Core/Core/Src/CoreParameter.cpp 2012-01-23 17:57:16.000000000 -0500
  3. +++ dolphin-patch/Source/Core/Core/Src/CoreParameter.cpp    2012-01-23 18:05:23.000000000 -0500
  4. @@ -126,6 +126,7 @@ bool SCoreStartupParameter::AutoSetup(EB
  5.             std::string Extension;
  6.             SplitPath(m_strFilename, NULL, NULL, &Extension);
  7.             if (!strcasecmp(Extension.c_str(), ".gcm") ||
  8. +               !strcasecmp(Extension.c_str(), ".wbfs") ||
  9.                 !strcasecmp(Extension.c_str(), ".iso") ||
  10.                 !strcasecmp(Extension.c_str(), ".ciso") ||
  11.                 !strcasecmp(Extension.c_str(), ".gcz") ||
  12. diff -rupN dolphin-orig/Source/Core/DiscIO/SConscript dolphin-patch/Source/Core/DiscIO/SConscript
  13. --- dolphin-orig/Source/Core/DiscIO/SConscript  2012-01-23 17:57:17.000000000 -0500
  14. +++ dolphin-patch/Source/Core/DiscIO/SConscript 2012-01-23 18:05:43.000000000 -0500
  15. @@ -24,6 +24,7 @@ files = [
  16.     'Src/VolumeWad.cpp',
  17.     'Src/VolumeWiiCrypted.cpp',
  18.     'Src/WiiWad.cpp',
  19. +   'Src/WbfsBlob.cpp',
  20.     ]
  21.  
  22.  env['LIBS'] += env.StaticLibrary('discio', files)
  23. diff -rupN dolphin-orig/Source/Core/DiscIO/Src/Blob.cpp dolphin-patch/Source/Core/DiscIO/Src/Blob.cpp
  24. --- dolphin-orig/Source/Core/DiscIO/Src/Blob.cpp    2012-01-23 17:57:17.000000000 -0500
  25. +++ dolphin-patch/Source/Core/DiscIO/Src/Blob.cpp   2012-01-23 18:06:05.000000000 -0500
  26. @@ -23,6 +23,7 @@
  27.  #include "FileBlob.h"
  28.  #include "CISOBlob.h"
  29.  #include "DriveBlob.h"
  30. +#include "WbfsBlob.h"
  31.  
  32.  namespace DiscIO
  33.  {
  34. @@ -128,6 +129,9 @@ IBlobReader* CreateBlobReader(const char
  35.     if (!File::Exists(filename))
  36.         return 0;
  37.  
  38. +   if (IsWbfsBlob(filename))
  39. +       return WbfsFileReader::Create(filename);
  40. +
  41.     if (IsCompressedBlob(filename))
  42.         return CompressedBlobReader::Create(filename);
  43.  
  44. diff -rupN dolphin-orig/Source/Core/DiscIO/Src/WbfsBlob.cpp dolphin-patch/Source/Core/DiscIO/Src/WbfsBlob.cpp
  45. --- dolphin-orig/Source/Core/DiscIO/Src/WbfsBlob.cpp    1969-12-31 19:00:00.000000000 -0500
  46. +++ dolphin-patch/Source/Core/DiscIO/Src/WbfsBlob.cpp   2012-01-23 18:10:06.000000000 -0500
  47. @@ -0,0 +1,209 @@
  48. +// Copyright (C) 2003 Dolphin Project.
  49. +
  50. +// This program is free software: you can redistribute it and/or modify
  51. +// it under the terms of the GNU General Public License as published by
  52. +// the Free Software Foundation, version 2.0.
  53. +
  54. +// This program is distributed in the hope that it will be useful,
  55. +// but WITHOUT ANY WARRANTY; without even the implied warranty of
  56. +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  57. +// GNU General Public License 2.0 for more details.
  58. +
  59. +// A copy of the GPL 2.0 should have been included with the program.
  60. +// If not, see http://www.gnu.org/licenses/
  61. +
  62. +// Official SVN repository and contact information can be found at
  63. +// http://code.google.com/p/dolphin-emu/
  64. +
  65. +#include "WbfsBlob.h"
  66. +#include "FileUtil.h"
  67. +
  68. +namespace DiscIO
  69. +{
  70. +const u64 wii_sector_size = 0x8000;
  71. +const u64 wii_sector_count = 143432 * 2;
  72. +const u64 wii_sector_log2 = 15;
  73. +const u64 wii_disc_header_size = 256;
  74. +
  75. +static inline u64 align(u64 value, u64 bounds)
  76. +{
  77. +   return (value + (bounds - 1)) & (~(bounds - 1));
  78. +}
  79. +
  80. +WbfsFileReader::WbfsFileReader(const char* filename)
  81. +   : m_total_files(0), m_size(0), m_wlba_table(0), m_good(true)
  82. +{
  83. +   if(!filename || (strlen(filename) < 4) || !OpenFiles(filename) || !ReadHeader())
  84. +   {
  85. +       m_good = false;
  86. +       return;
  87. +   }
  88. +
  89. +   // Grab disc info (assume slot 0, checked in ReadHeader())
  90. +   m_wlba_table = new u16[m_blocks_per_disc];
  91. +   m_files[0]->file.Seek(hd_sector_size + wii_disc_header_size /*+ i * m_disc_info_size*/, SEEK_SET);
  92. +   m_files[0]->file.ReadBytes(m_wlba_table, m_blocks_per_disc * sizeof(u16));
  93. +}
  94. +
  95. +WbfsFileReader::~WbfsFileReader()
  96. +{
  97. +   for(u32 i = 0; i != m_files.size(); ++ i)
  98. +   {
  99. +       delete m_files[i];
  100. +   }
  101. +
  102. +   delete[] m_wlba_table;
  103. +}
  104. +
  105. +bool WbfsFileReader::OpenFiles(const char* filename)
  106. +{
  107. +   m_total_files = 0;
  108. +
  109. +   while(true)
  110. +   {
  111. +       file_entry* new_entry = new file_entry;
  112. +
  113. +       // Replace last character with index (e.g. wbfs = wbf1)
  114. +       std::string path = filename;
  115. +       if(0 != m_total_files)
  116. +       {
  117. +           path[path.length() - 1] = '0' + m_total_files;
  118. +       }
  119. +
  120. +       if(!new_entry->file.Open(path, "rb"))
  121. +       {
  122. +           delete new_entry;
  123. +           return 0 != m_total_files;
  124. +       }
  125. +      
  126. +       new_entry->base_address = m_size;
  127. +       new_entry->size = new_entry->file.GetSize();
  128. +       m_size += new_entry->size;
  129. +
  130. +       m_total_files ++;
  131. +       m_files.push_back(new_entry);      
  132. +   }
  133. +}
  134. +
  135. +bool WbfsFileReader::ReadHeader()
  136. +{
  137. +   m_files[0]->file.Seek(4, SEEK_SET);
  138. +  
  139. +   // Read hd size info
  140. +   m_files[0]->file.ReadBytes(&hd_sector_count, 4);
  141. +   hd_sector_count = Common::swap32(hd_sector_count);
  142. +  
  143. +   m_files[0]->file.ReadBytes(&hd_sector_shift, 1);
  144. +   hd_sector_size = 1 << hd_sector_shift;
  145. +  
  146. +   if(m_size != hd_sector_count * hd_sector_size)
  147. +   {
  148. +       //printf("File size doesn't match expected size\n");
  149. +       return false;
  150. +   }
  151. +  
  152. +   // Read wbfs cluster info
  153. +   m_files[0]->file.ReadBytes(&wbfs_sector_shift, 1);
  154. +   wbfs_sector_size = 1 << wbfs_sector_shift;
  155. +   wbfs_sector_count = m_size / wbfs_sector_size;
  156. +  
  157. +   if(wbfs_sector_size < wii_sector_size)
  158. +   {
  159. +       //Setting this too low would case a very large memory allocation
  160. +       return false;
  161. +   }
  162. +  
  163. +   m_blocks_per_disc = (wii_sector_count * wii_sector_size) / wbfs_sector_size;
  164. +   m_disc_info_size = align(wii_disc_header_size + m_blocks_per_disc * 2, hd_sector_size);
  165. +  
  166. +   // Read disc table
  167. +   m_files[0]->file.Seek(2, SEEK_CUR);
  168. +   m_files[0]->file.ReadBytes(disc_table, 500);
  169. +
  170. +   if(0 == disc_table[0])
  171. +   {
  172. +       //printf("Game must be in 'slot 0'\n");
  173. +       return false;
  174. +   }
  175. +  
  176. +   return true;
  177. +}
  178. +
  179. +bool WbfsFileReader::Read(u64 offset, u64 nbytes, u8* out_ptr)
  180. +{
  181. +   while(nbytes)
  182. +   {
  183. +       u64 read_size;
  184. +       File::IOFile& data_file = SeekToCluster(offset, &read_size);
  185. +       read_size = (read_size > nbytes) ? nbytes : read_size;
  186. +
  187. +       data_file.ReadBytes(out_ptr, read_size);
  188. +
  189. +       out_ptr += read_size;
  190. +       nbytes -= read_size;
  191. +       offset += read_size;
  192. +   }
  193. +      
  194. +   return true;
  195. +}
  196. +
  197. +File::IOFile& WbfsFileReader::SeekToCluster(u64 offset, u64* available)
  198. +{
  199. +   u64 base_cluster = offset >> wbfs_sector_shift;
  200. +   if(base_cluster < m_blocks_per_disc)
  201. +   {  
  202. +       u64 cluster_address = wbfs_sector_size * Common::swap16(m_wlba_table[base_cluster]);
  203. +       u64 cluster_offset = offset & (wbfs_sector_size - 1);
  204. +       u64 final_address = cluster_address + cluster_offset;
  205. +
  206. +       for(u32 i = 0; i != m_total_files; i ++)
  207. +       {  
  208. +           if(final_address < (m_files[i]->base_address + m_files[i]->size))
  209. +           {
  210. +               m_files[i]->file.Seek(final_address - m_files[i]->base_address, SEEK_SET);
  211. +               if(available)
  212. +               {
  213. +                   u64 till_end_of_file = m_files[i]->size - (final_address - m_files[i]->base_address);
  214. +                   u64 till_end_of_sector = wbfs_sector_size - cluster_offset;
  215. +                   *available = std::min(till_end_of_file, till_end_of_sector);
  216. +               }
  217. +
  218. +               return m_files[i]->file;
  219. +           }
  220. +       }
  221. +   }
  222. +  
  223. +   PanicAlert("Read beyond end of disc");
  224. +   m_files[0]->file.Seek(0, SEEK_SET);
  225. +   return m_files[0]->file;
  226. +}
  227. +
  228. +WbfsFileReader* WbfsFileReader::Create(const char* filename)
  229. +{ 
  230. +   WbfsFileReader* reader = new WbfsFileReader(filename);
  231. +      
  232. +   if(reader->IsGood())
  233. +   {
  234. +       return reader;
  235. +   }
  236. +   else
  237. +   {
  238. +       delete reader;
  239. +       return NULL;
  240. +   }
  241. +}
  242. +
  243. +bool IsWbfsBlob(const char* filename)
  244. +{
  245. +   File::IOFile f(filename, "rb");
  246. +
  247. +   u8 magic[4] = {0, 0, 0, 0};
  248. +   f.ReadBytes(&magic, 4);
  249. +
  250. +   return  (magic[0] == 'W') &&
  251. +           (magic[1] == 'B') &&
  252. +           (magic[2] == 'F') &&
  253. +           (magic[3] == 'S');
  254. +}
  255. +
  256. +}  // namespace
  257. diff -rupN dolphin-orig/Source/Core/DiscIO/Src/WbfsBlob.h dolphin-patch/Source/Core/DiscIO/Src/WbfsBlob.h
  258. --- dolphin-orig/Source/Core/DiscIO/Src/WbfsBlob.h  1969-12-31 19:00:00.000000000 -0500
  259. +++ dolphin-patch/Source/Core/DiscIO/Src/WbfsBlob.h 2012-01-23 18:06:45.000000000 -0500
  260. @@ -0,0 +1,82 @@
  261. +// Copyright (C) 2003 Dolphin Project.
  262. +
  263. +// This program is free software: you can redistribute it and/or modify
  264. +// it under the terms of the GNU General Public License as published by
  265. +// the Free Software Foundation, version 2.0.
  266. +
  267. +// This program is distributed in the hope that it will be useful,
  268. +// but WITHOUT ANY WARRANTY; without even the implied warranty of
  269. +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  270. +// GNU General Public License 2.0 for more details.
  271. +
  272. +// A copy of the GPL 2.0 should have been included with the program.
  273. +// If not, see http://www.gnu.org/licenses/
  274. +
  275. +// Official SVN repository and contact information can be found at
  276. +// http://code.google.com/p/dolphin-emu/
  277. +
  278. +#ifndef _WBFS_BLOB_H
  279. +#define _WBFS_BLOB_H
  280. +
  281. +#include "Blob.h"
  282. +#include "FileUtil.h"
  283. +
  284. +namespace DiscIO
  285. +{
  286. +
  287. +struct wbfs_head_t;
  288. +
  289. +class WbfsFileReader : public IBlobReader
  290. +{
  291. +   WbfsFileReader(const char* filename);
  292. +   ~WbfsFileReader();
  293. +
  294. +   bool OpenFiles(const char* filename);  
  295. +   bool ReadHeader();
  296. +
  297. +   File::IOFile& SeekToCluster(u64 offset, u64* available);
  298. +   bool IsGood() {return m_good;}
  299. +
  300. +
  301. +   struct file_entry
  302. +   {
  303. +       File::IOFile file;
  304. +       u64 base_address;
  305. +       u64 size;
  306. +   };
  307. +
  308. +   std::vector<file_entry*> m_files;
  309. +
  310. +   u32 m_total_files;
  311. +   u64 m_size;
  312. +
  313. +   u64 hd_sector_size;
  314. +   u8 hd_sector_shift;
  315. +   u32 hd_sector_count;
  316. +
  317. +   u64 wbfs_sector_size;
  318. +   u64 wbfs_sector_shift;
  319. +   u64 wbfs_sector_count;
  320. +   u64 m_disc_info_size;
  321. +
  322. +   u8 disc_table[500];
  323. +
  324. +   u16* m_wlba_table;
  325. +   u64 m_blocks_per_disc;
  326. +  
  327. +   bool m_good;
  328. +
  329. +public:
  330. +   static WbfsFileReader* Create(const char* filename);
  331. +
  332. +   u64 GetDataSize() const { return m_size; }
  333. +   u64 GetRawSize() const { return m_size; }
  334. +   bool Read(u64 offset, u64 nbytes, u8* out_ptr);
  335. +};
  336. +
  337. +bool IsWbfsBlob(const char* filename);
  338. +
  339. +
  340. +}  // namespace
  341. +
  342. +#endif  // _FILE_BLOB_H
  343. diff -rupN dolphin-orig/Source/Core/DolphinWX/Src/GameListCtrl.cpp dolphin-patch/Source/Core/DolphinWX/Src/GameListCtrl.cpp
  344. --- dolphin-orig/Source/Core/DolphinWX/Src/GameListCtrl.cpp 2012-01-23 17:57:17.000000000 -0500
  345. +++ dolphin-patch/Source/Core/DolphinWX/Src/GameListCtrl.cpp    2012-01-23 18:06:32.000000000 -0500
  346. @@ -602,6 +602,7 @@ void CGameListCtrl::ScanForISOs()
  347.         Extensions.push_back("*.iso");
  348.         Extensions.push_back("*.ciso");
  349.         Extensions.push_back("*.gcz");
  350. +       Extensions.push_back("*.wbfs");
  351.     }
  352.     if (SConfig::GetInstance().m_ListWad)
  353.         Extensions.push_back("*.wad");
RAW Paste Data