Skip to content

Instantly share code, notes, and snippets.

@luser
Created November 8, 2012 19:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save luser/4041149 to your computer and use it in GitHub Desktop.
Save luser/4041149 to your computer and use it in GitHub Desktop.
Unpacking Wind Waker strings
First, acquire a Wind Waker ISO somehow.
Next you need some tools. You'll need the Wiimms ISO Tools:
http://wit.wiimm.de/ , you can fetch the source from:
svn co http://opensvn.wiimm.de/wii/trunk/wiimms-iso-tools/
Running "make" in that directory will build them.
You'll also need the Wiimms SZS Tools:
http://szs.wiimm.de/ , source is at:
svn co http://opensvn.wiimm.de/wii/trunk/wiimms-szs-tools/
You'll need to apply the patch in this gist to properly unpack the strings, then just "make" in that directory.
To extract the files from the ISO, run wit from the wiimms-iso-tools directory (don't mkdir /tmp/windwaker first or wit will error):
./wit extract "/path/to/Windwaker.iso" /tmp/windwaker/
Next, extract the RARC archive using the wszst tool from the wiimms-szs-tools directory:
./wszst extract /tmp/windwaker/P-GZLE/files/res/Msg/bmgres.arc
Finally, decode the strings from the BMG using the wbmgt tool from the wiimms-szs-tools directory:
./wbmgt decode /tmp/windwaker/P-GZLE/files/res/Msg/bmgres.d/zel_00.bmg
This should produce a /tmp/windwaker/P-GZLE/files/res/Msg/bmgres.d/zel_00.txt file containing all the strings.
Index: src/lib-bmg.c
===================================================================
--- src/lib-bmg.c (revision 4155)
+++ src/lib-bmg.c (working copy)
@@ -387,26 +387,27 @@
bmg->dat = pdat;
bmg->mid = pmid;
- if ( !pinf || !pdat || !pmid )
+ if ( !pinf || !pdat /*|| !pmid */)
return ERROR0(ERR_INVALID_DATA,"Corrupted BMG file: %s\n",bmg->fname);
const uint max_text_index = ( ntohl(pdat->size) - sizeof(*pdat) )
/ sizeof(*pdat->text_pool);
u8 *text_end = pdat->text_pool + max_text_index;
- uint max_item = ( ntohl(pmid->size) - sizeof(*pmid) ) / sizeof(*pmid->mid);
- if ( max_item > ntohs(pmid->n_msg) )
- max_item = ntohs(pmid->n_msg);
+ uint max_item = ( ntohl(pinf->size) - sizeof(*pinf) ) / sizeof(*pinf->list);
+ if ( max_item > ntohs(pinf->n_msg) )
+ max_item = ntohs(pinf->n_msg);
uint idx;
for ( idx = 0; idx < max_item; idx++ )
{
- u32 mid = ntohl(pmid->mid[idx]);
+ u32 mid = ntohl(pinf->list[idx].mid);
if (!mid)
continue;
- u32 flags = ntohl(pinf->list[idx].flags);
+ u32 flags = 0; //ntohl(pinf->list[idx].flags);
const u32 text_index = ntohl(pinf->list[idx].text_index);
+ //TODO: store the unknown data!
if ( text_index >= max_text_index )
return ERROR0(ERR_INVALID_DATA,"Corrupted BMG file: %s\n",bmg->fname);
@@ -419,7 +420,10 @@
continue;
}
- u8 *ptr, *start = pdat->text_pool + text_index;
+ //LOL WindWaker doesn't use UTF-16
+ u8 *text = pdat->text_pool + text_index;
+ AssignItemTextBMG(bi, text, -1);
+ /*
for ( ptr = start; ptr < text_end; ptr += 2 )
{
if (!ptr[0])
@@ -437,8 +441,9 @@
}
u16 * text = (u16*)( pdat->text_pool + text_index );
- const int text_len = ( ptr - start )/2;
+ const int text_len = ( ptr - start );
AssignItemText16BMG( bi, text, text_len );
+ */
}
return ERR_OK;
@@ -785,7 +790,8 @@
continue;
*mid_ptr++ = htonl(bi->mid);
- inf_list->flags = htonl(bi->flags);
+ //TODO: restore unknown data
+ //inf_list->flags = htonl(bi->flags);
if ( bi->text != bmg_null_entry )
{
inf_list->text_index = htonl(text_index);
Index: src/lib-bmg.h
===================================================================
--- src/lib-bmg.h (revision 4155)
+++ src/lib-bmg.h (working copy)
@@ -95,7 +95,8 @@
typedef struct bmg_inf_list_t
{
u32 text_index; // offset into text pool
- u32 flags; // unknown flags
+ u16 mid; // message id
+ u8 unknown[18]; // unknown
}
__attribute__ ((packed)) bmg_inf_list_t;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment