undo the code formatting. somehow it got screwed up

This commit is contained in:
giantpune 2010-02-09 10:59:55 +00:00
parent f988afc60d
commit bf03e49dc6
401 changed files with 61944 additions and 59427 deletions

View File

@ -2,8 +2,8 @@
<app version="1"> <app version="1">
<name> USB Loader GX</name> <name> USB Loader GX</name>
<coder>USB Loader GX Team</coder> <coder>USB Loader GX Team</coder>
<version>1.0 r908</version> <version>1.0 r909</version>
<release_date>201002090353</release_date> <release_date>201002091053</release_date>
<short_description>Loads games from USB-devices</short_description> <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. <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.
The interactive GUI is completely controllable with WiiMote, Classic Controller or GC Controller. The interactive GUI is completely controllable with WiiMote, Classic Controller or GC Controller.

View File

@ -65,9 +65,10 @@ typedef struct ftgxDataOffset_ {
* @param vertexIndex Optional vertex format index (GX_VTXFMT*) of the glyph textures as defined by the libogc gx.h header file. If not specified default value is GX_VTXFMT1. * @param vertexIndex Optional vertex format index (GX_VTXFMT*) of the glyph textures as defined by the libogc gx.h header file. If not specified default value is GX_VTXFMT1.
*/ */
FreeTypeGX::FreeTypeGX(uint8_t textureFormat, uint8_t vertexIndex, uint32_t compatibilityMode) FreeTypeGX::FreeTypeGX(uint8_t textureFormat, uint8_t vertexIndex, uint32_t compatibilityMode)
: :
ftFace(NULL), ftFace(NULL),
ftFace_fromFile(NULL) { ftFace_fromFile(NULL)
{
FT_Init_FreeType(&this->ftLibrary); FT_Init_FreeType(&this->ftLibrary);
this->textureFormat = textureFormat; this->textureFormat = textureFormat;
@ -94,8 +95,8 @@ FreeTypeGX::~FreeTypeGX() {
*/ */
wchar_t* FreeTypeGX::charToWideChar(const char* strChar) { wchar_t* FreeTypeGX::charToWideChar(const char* strChar) {
wchar_t *strWChar; wchar_t *strWChar;
strWChar = new(std::nothrow) wchar_t[strlen(strChar) + 1]; strWChar = new(std::nothrow) wchar_t[strlen(strChar) + 1];
if (!strWChar) return NULL; if(!strWChar) return NULL;
// UTF-8 // UTF-8
int bt; int bt;
bt = mbstowcs(strWChar, strChar, strlen(strChar)); bt = mbstowcs(strWChar, strChar, strlen(strChar));
@ -260,29 +261,32 @@ void FreeTypeGX::clearGlyphData() {
GX_DrawDone(); GX_DrawDone();
GX_Flush(); GX_Flush();
for ( std::map<uint16_t, FTGX_Cache>::iterator i = this->fontDatas.begin(); i != this->fontDatas.end(); i++) { for ( std::map<uint16_t, FTGX_Cache>::iterator i = this->fontDatas.begin(); i != this->fontDatas.end(); i++)
for ( FTGX_Cache::iterator j = i->second.begin(); j != i->second.end(); j++) { {
free(j->second.glyphDataTexture); for ( FTGX_Cache::iterator j = i->second.begin(); j != i->second.end(); j++)
} {
i->second.clear(); free(j->second.glyphDataTexture);
}
i->second.clear();
} }
/* for ( std::map<wchar_t, ftgxCharData>::iterator i = this->fontData.begin(); i != this->fontData.end(); i++) { /* for ( std::map<wchar_t, ftgxCharData>::iterator i = this->fontData.begin(); i != this->fontData.end(); i++) {
free(i->second.glyphDataTexture); free(i->second.glyphDataTexture);
} }
*/ */
this->fontDatas.clear(); this->fontDatas.clear();
} }
void FreeTypeGX::changeSize(FT_UInt vPointSize, FT_UInt hPointSize/*=0*/) { void FreeTypeGX::changeSize(FT_UInt vPointSize, FT_UInt hPointSize/*=0*/) {
if (hPointSize == 0) hPointSize = vPointSize; if(hPointSize == 0) hPointSize = vPointSize;
if (vPointSize > 255) vPointSize = 255;// limit to 255 if(vPointSize > 255) vPointSize = 255;// limit to 255
if (hPointSize > 255) hPointSize = 255; if(hPointSize > 255) hPointSize = 255;
if (this->ftPointSize_v != vPointSize || this->ftPointSize_h != hPointSize) { if(this->ftPointSize_v != vPointSize || this->ftPointSize_h != hPointSize)
{
// this->clearGlyphData(); // this->clearGlyphData();
this->ftPointSize_v = vPointSize; this->ftPointSize_v = vPointSize;
this->ftPointSize_h = hPointSize; this->ftPointSize_h = hPointSize;
FT_Set_Pixel_Sizes(this->ftFace, this->ftPointSize_h, this->ftPointSize_v); FT_Set_Pixel_Sizes(this->ftFace, this->ftPointSize_h, this->ftPointSize_v);
} }
} }
/** /**
@ -356,42 +360,44 @@ uint16_t FreeTypeGX::adjustTextureHeight(uint16_t textureHeight, uint8_t texture
* @param charCode The requested glyph's character code. * @param charCode The requested glyph's character code.
* @return A pointer to the allocated font structure. * @return A pointer to the allocated font structure.
*/ */
ftgxCharData *FreeTypeGX::cacheGlyphData(wchar_t charCode) { ftgxCharData *FreeTypeGX::cacheGlyphData(wchar_t charCode)
FTGX_Cache &fontData = this->fontDatas[ftPointSize_v | ftPointSize_h << 8]; {
return cacheGlyphData(charCode, fontData); FTGX_Cache &fontData = this->fontDatas[ftPointSize_v | ftPointSize_h << 8];
return cacheGlyphData(charCode, fontData);
} }
ftgxCharData *FreeTypeGX::cacheGlyphData(wchar_t charCode, FTGX_Cache &fontData) { ftgxCharData *FreeTypeGX::cacheGlyphData(wchar_t charCode, FTGX_Cache &fontData)
FT_UInt gIndex; {
uint16_t textureWidth = 0, textureHeight = 0; FT_UInt gIndex;
uint16_t textureWidth = 0, textureHeight = 0;
gIndex = FT_Get_Char_Index( this->ftFace, charCode ); gIndex = FT_Get_Char_Index( this->ftFace, charCode );
if (!FT_Load_Glyph(this->ftFace, gIndex, FT_LOAD_DEFAULT )) { if (!FT_Load_Glyph(this->ftFace, gIndex, FT_LOAD_DEFAULT )) {
FT_Render_Glyph( this->ftSlot, FT_RENDER_MODE_NORMAL ); FT_Render_Glyph( this->ftSlot, FT_RENDER_MODE_NORMAL );
if (this->ftSlot->format == FT_GLYPH_FORMAT_BITMAP) { if (this->ftSlot->format == FT_GLYPH_FORMAT_BITMAP) {
FT_Bitmap *glyphBitmap = &this->ftSlot->bitmap; FT_Bitmap *glyphBitmap = &this->ftSlot->bitmap;
textureWidth = adjustTextureWidth(glyphBitmap->width, this->textureFormat); textureWidth = adjustTextureWidth(glyphBitmap->width, this->textureFormat);
textureHeight = adjustTextureHeight(glyphBitmap->rows, this->textureFormat); textureHeight = adjustTextureHeight(glyphBitmap->rows, this->textureFormat);
fontData[charCode] = (ftgxCharData) { fontData[charCode] = (ftgxCharData) {
this->ftSlot->bitmap_left, this->ftSlot->bitmap_left,
this->ftSlot->advance.x >> 6, this->ftSlot->advance.x >> 6,
gIndex, gIndex,
textureWidth, textureWidth,
textureHeight, textureHeight,
this->ftSlot->bitmap_top, this->ftSlot->bitmap_top,
this->ftSlot->bitmap_top, this->ftSlot->bitmap_top,
glyphBitmap->rows - this->ftSlot->bitmap_top, glyphBitmap->rows - this->ftSlot->bitmap_top,
NULL NULL
}; };
this->loadGlyphData(glyphBitmap, &fontData[charCode]); this->loadGlyphData(glyphBitmap, &fontData[charCode]);
return &fontData[charCode]; return &fontData[charCode];
} }
} }
return NULL; return NULL;
} }
/** /**
@ -546,7 +552,7 @@ uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, const wchar_t *text, GXColor
GXTexObj glyphTexture; GXTexObj glyphTexture;
FT_Vector pairDelta; FT_Vector pairDelta;
ftgxDataOffset offset; ftgxDataOffset offset;
FTGX_Cache &fontData = this->fontDatas[ftPointSize_v | ftPointSize_h << 8]; FTGX_Cache &fontData = this->fontDatas[ftPointSize_v | ftPointSize_h << 8];
if (textStyle & FTGX_JUSTIFY_MASK) { if (textStyle & FTGX_JUSTIFY_MASK) {
x_offset = this->getStyleOffsetWidth(this->getWidth(text), textStyle); x_offset = this->getStyleOffsetWidth(this->getWidth(text), textStyle);
@ -643,7 +649,7 @@ uint16_t FreeTypeGX::getWidth(const wchar_t *text) {
uint16_t strLength = wcslen(text); uint16_t strLength = wcslen(text);
uint16_t strWidth = 0; uint16_t strWidth = 0;
FT_Vector pairDelta; FT_Vector pairDelta;
FTGX_Cache &fontData = this->fontDatas[ftPointSize_v | ftPointSize_h << 8]; FTGX_Cache &fontData = this->fontDatas[ftPointSize_v | ftPointSize_h << 8];
for (uint16_t i = 0; i < strLength; i++) { for (uint16_t i = 0; i < strLength; i++) {
@ -697,7 +703,7 @@ uint16_t FreeTypeGX::getHeight(const wchar_t *text) {
ftgxDataOffset* FreeTypeGX::getOffset(const wchar_t *text, ftgxDataOffset* offset) { ftgxDataOffset* FreeTypeGX::getOffset(const wchar_t *text, ftgxDataOffset* offset) {
uint16_t strLength = wcslen(text); uint16_t strLength = wcslen(text);
int16_t strMax = 0, strMin = 9999; int16_t strMax = 0, strMin = 9999;
FTGX_Cache &fontData = this->fontDatas[ftPointSize_v | ftPointSize_h << 8]; FTGX_Cache &fontData = this->fontDatas[ftPointSize_v | ftPointSize_h << 8];
for (uint16_t i = 0; i < strLength; i++) { for (uint16_t i = 0; i < strLength; i++) {

View File

@ -203,7 +203,9 @@ typedef struct ftgxDataOffset_ ftgxDataOffset;
#define FTGX_COMPATIBILITY_GRRLIB FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_PASSCLR | FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_NONE #define FTGX_COMPATIBILITY_GRRLIB FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_PASSCLR | FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_NONE
#define FTGX_COMPATIBILITY_LIBWIISPRITE FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_MODULATE | FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_DIRECT #define FTGX_COMPATIBILITY_LIBWIISPRITE FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_MODULATE | FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_DIRECT
const GXColor ftgxWhite = (GXColor) {0xff, 0xff, 0xff, 0xff} const GXColor ftgxWhite = (GXColor) {
0xff, 0xff, 0xff, 0xff
}
; /**< Constant color value used only to sanitize Doxygen documentation. */ ; /**< Constant color value used only to sanitize Doxygen documentation. */
/*! \class FreeTypeGX /*! \class FreeTypeGX
@ -231,7 +233,7 @@ private:
uint8_t vertexIndex; /**< Vertex format descriptor index. */ uint8_t vertexIndex; /**< Vertex format descriptor index. */
uint32_t compatibilityMode; /**< Compatibility mode for default tev operations and vertex descriptors. */ uint32_t compatibilityMode; /**< Compatibility mode for default tev operations and vertex descriptors. */
// FTGX_Cache fontData; /**< Map which holds the glyph data structures for the corresponding characters. */ // FTGX_Cache fontData; /**< Map which holds the glyph data structures for the corresponding characters. */
std::map<uint16_t, FTGX_Cache> fontDatas; std::map<uint16_t, FTGX_Cache> fontDatas;
static uint16_t adjustTextureWidth(uint16_t textureWidth, uint8_t textureFormat); static uint16_t adjustTextureWidth(uint16_t textureWidth, uint8_t textureFormat);
static uint16_t adjustTextureHeight(uint16_t textureHeight, uint8_t textureFormat); static uint16_t adjustTextureHeight(uint16_t textureHeight, uint8_t textureFormat);
@ -242,7 +244,7 @@ private:
void unloadFont(); void unloadFont();
void clearGlyphData(); void clearGlyphData();
ftgxCharData *cacheGlyphData(wchar_t charCode); ftgxCharData *cacheGlyphData(wchar_t charCode);
ftgxCharData *cacheGlyphData(wchar_t charCode, FTGX_Cache &fontData); ftgxCharData *cacheGlyphData(wchar_t charCode, FTGX_Cache &fontData);
uint16_t cacheGlyphDataComplete(); uint16_t cacheGlyphDataComplete();
void loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData); void loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData);

View File

@ -39,22 +39,26 @@
#include "ZipFile.h" #include "ZipFile.h"
#include "language/gettext.h" #include "language/gettext.h"
ZipFile::ZipFile(const char *filepath) { ZipFile::ZipFile(const char *filepath)
{
File = unzOpen(filepath); File = unzOpen(filepath);
if (File) if(File)
this->LoadList(); this->LoadList();
} }
ZipFile::~ZipFile() { ZipFile::~ZipFile()
{
unzClose(File); unzClose(File);
} }
bool ZipFile::LoadList() { bool ZipFile::LoadList()
{
return true; return true;
} }
bool ZipFile::ExtractAll(const char *dest) { bool ZipFile::ExtractAll(const char *dest)
if (!File) {
if(!File)
return false; return false;
bool Stop = false; bool Stop = false;
@ -62,7 +66,7 @@ bool ZipFile::ExtractAll(const char *dest) {
u32 blocksize = 1024*50; u32 blocksize = 1024*50;
u8 *buffer = new u8[blocksize]; u8 *buffer = new u8[blocksize];
if (!buffer) if(!buffer)
return false; return false;
char writepath[MAXPATHLEN]; char writepath[MAXPATHLEN];
@ -70,14 +74,16 @@ bool ZipFile::ExtractAll(const char *dest) {
memset(filename, 0, sizeof(filename)); memset(filename, 0, sizeof(filename));
int ret = unzGoToFirstFile(File); int ret = unzGoToFirstFile(File);
if (ret != UNZ_OK) if(ret != UNZ_OK)
Stop = true; Stop = true;
while (!Stop) { while(!Stop)
if (unzGetCurrentFileInfo(File, &cur_file_info, filename, sizeof(filename), NULL, NULL, NULL, NULL) != UNZ_OK) {
if(unzGetCurrentFileInfo(File, &cur_file_info, filename, sizeof(filename), NULL, NULL, NULL, NULL) != UNZ_OK)
Stop = true; Stop = true;
if (!Stop && filename[strlen(filename)-1] != '/') { if(!Stop && filename[strlen(filename)-1] != '/')
{
u32 uncompressed_size = cur_file_info.uncompressed_size; u32 uncompressed_size = cur_file_info.uncompressed_size;
u32 done = 0; u32 done = 0;
@ -95,31 +101,33 @@ bool ZipFile::ExtractAll(const char *dest) {
subfoldercreate(temppath); subfoldercreate(temppath);
if (ret == UNZ_OK) { if(ret == UNZ_OK)
{
FILE *pfile = fopen(writepath, "wb"); FILE *pfile = fopen(writepath, "wb");
do { do
{
ShowProgress(tr("Extracting files..."), 0, pointer+1, done, uncompressed_size); ShowProgress(tr("Extracting files..."), 0, pointer+1, done, uncompressed_size);
if (uncompressed_size - done < blocksize) if(uncompressed_size - done < blocksize)
blocksize = uncompressed_size - done; blocksize = uncompressed_size - done;
ret = unzReadCurrentFile(File, buffer, blocksize); ret = unzReadCurrentFile(File, buffer, blocksize);
if (ret == 0) if(ret == 0)
break; break;
fwrite(buffer, 1, blocksize, pfile); fwrite(buffer, 1, blocksize, pfile);
done += ret; done += ret;
} while (done < uncompressed_size); } while(done < uncompressed_size);
fclose(pfile); fclose(pfile);
unzCloseCurrentFile(File); unzCloseCurrentFile(File);
} }
} }
if (unzGoToNextFile(File) != UNZ_OK) if(unzGoToNextFile(File) != UNZ_OK)
Stop = true; Stop = true;
} }

View File

@ -30,27 +30,29 @@
#include "unzip/unzip.h" #include "unzip/unzip.h"
typedef struct { typedef struct
u64 offset; // ZipFile offset {
u64 length; // uncompressed file length in 64 bytes for sizes higher than 4GB u64 offset; // ZipFile offset
bool isdir; // 0 - file, 1 - directory u64 length; // uncompressed file length in 64 bytes for sizes higher than 4GB
char filename[256]; // full filename bool isdir; // 0 - file, 1 - directory
char filename[256]; // full filename
} FileStructure; } FileStructure;
class ZipFile { class ZipFile
public: {
//!Constructor public:
ZipFile(const char *filepath); //!Constructor
//!Destructor ZipFile(const char *filepath);
~ZipFile(); //!Destructor
//!Extract all files from a zip file to a directory ~ZipFile();
//!\param dest Destination path to where to extract //!Extract all files from a zip file to a directory
bool ExtractAll(const char *dest); //!\param dest Destination path to where to extract
protected: bool ExtractAll(const char *dest);
bool LoadList(); protected:
unzFile File; bool LoadList();
unz_file_info cur_file_info; unzFile File;
FileStructure *FileList; unz_file_info cur_file_info;
FileStructure *FileList;
}; };
#endif #endif

View File

@ -110,26 +110,29 @@
* array. They're divided up into four groups of 16. * array. They're divided up into four groups of 16.
*/ */
static const uint8_t K[3][16] = { static const uint8_t K[3][16] =
{
/* Round 1: skipped (since it is simply sequential). */ /* Round 1: skipped (since it is simply sequential). */
{ 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12 }, /* R2 */ { 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12 }, /* R2 */
{ 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2 }, /* R3 */ { 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2 }, /* R3 */
{ 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 } /* R4 */ { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 } /* R4 */
}; };
static const uint8_t S[4][4] = { static const uint8_t S[4][4] =
{
{ 7, 12, 17, 22 }, /* Round 1 */ { 7, 12, 17, 22 }, /* Round 1 */
{ 5, 9, 14, 20 }, /* Round 2 */ { 5, 9, 14, 20 }, /* Round 2 */
{ 4, 11, 16, 23 }, /* Round 3 */ { 4, 11, 16, 23 }, /* Round 3 */
{ 6, 10, 15, 21 } /* Round 4 */ { 6, 10, 15, 21 } /* Round 4 */
}; };
static const uint32_t T[4][16] = { static const uint32_t T[4][16] =
{
{ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, /* Round 1 */ { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, /* Round 1 */
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 }, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 },
{ 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, /* Round 2 */ { 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, /* Round 2 */
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
@ -145,7 +148,7 @@ static const uint32_t T[4][16] = {
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 }, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 },
}; };
/* -------------------------------------------------------------------------- ** /* -------------------------------------------------------------------------- **
@ -175,118 +178,122 @@ static const uint32_t T[4][16] = {
*/ */
static void Permute( uint32_t ABCD[4], const unsigned char block[64] ) static void Permute( uint32_t ABCD[4], const unsigned char block[64] )
/* ------------------------------------------------------------------------ ** /* ------------------------------------------------------------------------ **
* Permute the ABCD "registers" using the 64-byte <block> as a driver. * Permute the ABCD "registers" using the 64-byte <block> as a driver.
* *
* Input: ABCD - Pointer to an array of four unsigned longwords. * Input: ABCD - Pointer to an array of four unsigned longwords.
* block - An array of bytes, 64 bytes in size. * block - An array of bytes, 64 bytes in size.
* *
* Output: none. * Output: none.
* *
* Notes: The MD5 algorithm operates on a set of four longwords stored * Notes: The MD5 algorithm operates on a set of four longwords stored
* (conceptually) in four "registers". It is easy to imagine a * (conceptually) in four "registers". It is easy to imagine a
* simple MD4/5 chip that would operate this way. In any case, * simple MD4/5 chip that would operate this way. In any case,
* the mangling of the contents of those registers is driven by * the mangling of the contents of those registers is driven by
* the input message. The message is chopped and finally padded * the input message. The message is chopped and finally padded
* into 64-byte chunks and each chunk is used to manipulate the * into 64-byte chunks and each chunk is used to manipulate the
* contents of the registers. * contents of the registers.
* *
* The MD5 Algorithm calls for padding the input to ensure that * The MD5 Algorithm calls for padding the input to ensure that
* it is a multiple of 64 bytes in length. The last 16 bytes * it is a multiple of 64 bytes in length. The last 16 bytes
* of the padding space are used to store the message length * of the padding space are used to store the message length
* (the length of the original message, before padding, expressed * (the length of the original message, before padding, expressed
* in terms of bits). If there is not enough room for 16 bytes * in terms of bits). If there is not enough room for 16 bytes
* worth of bitcount (eg., if the original message was 122 bytes * worth of bitcount (eg., if the original message was 122 bytes
* long) then the block is padded to the end with zeros and * long) then the block is padded to the end with zeros and
* passed to this function. Then *another* block is filled with * passed to this function. Then *another* block is filled with
* zeros except for the last 16 bytes which contain the length. * zeros except for the last 16 bytes which contain the length.
* *
* Oh... and the algorithm requires that there be at least one * Oh... and the algorithm requires that there be at least one
* padding byte. The first padding byte has a value of 0x80, * padding byte. The first padding byte has a value of 0x80,
* and any others are 0x00. * and any others are 0x00.
* *
* ------------------------------------------------------------------------ ** * ------------------------------------------------------------------------ **
*/ */
{ {
int round; int round;
int i, j; int i, j;
uint8_t s; uint8_t s;
uint32_t a, b, c, d; uint32_t a, b, c, d;
uint32_t KeepABCD[4]; uint32_t KeepABCD[4];
uint32_t X[16]; uint32_t X[16];
/* Store the current ABCD values for later re-use. /* Store the current ABCD values for later re-use.
*/ */
for ( i = 0; i < 4; i++ ) for( i = 0; i < 4; i++ )
KeepABCD[i] = ABCD[i]; KeepABCD[i] = ABCD[i];
/* Convert the input block into an array of unsigned longs, taking care /* Convert the input block into an array of unsigned longs, taking care
* to read the block in Little Endian order (the algorithm assumes this). * to read the block in Little Endian order (the algorithm assumes this).
* The uint32_t values are then handled in host order. * The uint32_t values are then handled in host order.
*/ */
for ( i = 0, j = 0; i < 16; i++ ) { for( i = 0, j = 0; i < 16; i++ )
X[i] = (uint32_t)block[j++]; {
X[i] |= ((uint32_t)block[j++] << 8); X[i] = (uint32_t)block[j++];
X[i] |= ((uint32_t)block[j++] << 16); X[i] |= ((uint32_t)block[j++] << 8);
X[i] |= ((uint32_t)block[j++] << 24); X[i] |= ((uint32_t)block[j++] << 16);
X[i] |= ((uint32_t)block[j++] << 24);
} }
/* This loop performs the four rounds of permutations. /* This loop performs the four rounds of permutations.
* The rounds are each very similar. The differences are in three areas: * The rounds are each very similar. The differences are in three areas:
* - The function (F, G, H, or I) used to perform bitwise permutations * - The function (F, G, H, or I) used to perform bitwise permutations
* on the registers, * on the registers,
* - The order in which values from X[] are chosen. * - The order in which values from X[] are chosen.
* - Changes to the number of bits by which the registers are rotated. * - Changes to the number of bits by which the registers are rotated.
* This implementation uses a switch statement to deal with some of the * This implementation uses a switch statement to deal with some of the
* differences between rounds. Other differences are handled by storing * differences between rounds. Other differences are handled by storing
* values in arrays and using the round number to select the correct set * values in arrays and using the round number to select the correct set
* of values. * of values.
* *
* (My implementation appears to be a poor compromise between speed, size, * (My implementation appears to be a poor compromise between speed, size,
* and clarity. Ugh. [crh]) * and clarity. Ugh. [crh])
*/ */
for ( round = 0; round < 4; round++ ) { for( round = 0; round < 4; round++ )
for ( i = 0; i < 16; i++ ) { {
j = (4 - (i % 4)) & 0x3; /* <j> handles the rotation of ABCD. */ for( i = 0; i < 16; i++ )
s = S[round][i%4]; /* <s> is the bit shift for this iteration. */ {
j = (4 - (i % 4)) & 0x3; /* <j> handles the rotation of ABCD. */
s = S[round][i%4]; /* <s> is the bit shift for this iteration. */
b = ABCD[(j+1) & 0x3]; /* Copy the b,c,d values per ABCD rotation. */ b = ABCD[(j+1) & 0x3]; /* Copy the b,c,d values per ABCD rotation. */
c = ABCD[(j+2) & 0x3]; /* This isn't really necessary, it just looks */ c = ABCD[(j+2) & 0x3]; /* This isn't really necessary, it just looks */
d = ABCD[(j+3) & 0x3]; /* clean & will hopefully be optimized away. */ d = ABCD[(j+3) & 0x3]; /* clean & will hopefully be optimized away. */
/* The actual perumation function. /* The actual perumation function.
* This is broken out to minimize the code within the switch(). * This is broken out to minimize the code within the switch().
*/ */
switch ( round ) { switch( round )
case 0: {
/* round 1 */ case 0:
a = md5F( b, c, d ) + X[i]; /* round 1 */
break; a = md5F( b, c, d ) + X[i];
case 1: break;
/* round 2 */ case 1:
a = md5G( b, c, d ) + X[ K[0][i] ]; /* round 2 */
break; a = md5G( b, c, d ) + X[ K[0][i] ];
case 2: break;
/* round 3 */ case 2:
a = md5H( b, c, d ) + X[ K[1][i] ]; /* round 3 */
break; a = md5H( b, c, d ) + X[ K[1][i] ];
default: break;
/* round 4 */ default:
a = md5I( b, c, d ) + X[ K[2][i] ]; /* round 4 */
break; a = md5I( b, c, d ) + X[ K[2][i] ];
} break;
a = 0xFFFFFFFF & ( ABCD[j] + a + T[round][i] );
ABCD[j] = b + (0xFFFFFFFF & (( a << s ) | ( a >> (32 - s) )));
} }
a = 0xFFFFFFFF & ( ABCD[j] + a + T[round][i] );
ABCD[j] = b + (0xFFFFFFFF & (( a << s ) | ( a >> (32 - s) )));
}
} }
/* Use the stored original A, B, C, D values to perform /* Use the stored original A, B, C, D values to perform
* one last convolution. * one last convolution.
*/ */
for ( i = 0; i < 4; i++ ) for( i = 0; i < 4; i++ )
ABCD[i] = 0xFFFFFFFF & ( ABCD[i] + KeepABCD[i] ); ABCD[i] = 0xFFFFFFFF & ( ABCD[i] + KeepABCD[i] );
} /* Permute */ } /* Permute */
/* -------------------------------------------------------------------------- ** /* -------------------------------------------------------------------------- **
@ -294,246 +301,250 @@ static void Permute( uint32_t ABCD[4], const unsigned char block[64] )
*/ */
auth_md5Ctx *auth_md5InitCtx( auth_md5Ctx *ctx ) auth_md5Ctx *auth_md5InitCtx( auth_md5Ctx *ctx )
/* ------------------------------------------------------------------------ ** /* ------------------------------------------------------------------------ **
* Initialize an MD5 context. * Initialize an MD5 context.
* *
* Input: ctx - A pointer to the MD5 context structure to be initialized. * Input: ctx - A pointer to the MD5 context structure to be initialized.
* Contexts are typically created thusly: * Contexts are typically created thusly:
* ctx = (auth_md5Ctx *)malloc( sizeof(auth_md5Ctx) ); * ctx = (auth_md5Ctx *)malloc( sizeof(auth_md5Ctx) );
* *
* Output: A pointer to the initialized context (same as <ctx>). * Output: A pointer to the initialized context (same as <ctx>).
* *
* Notes: The purpose of the context is to make it possible to generate * Notes: The purpose of the context is to make it possible to generate
* an MD5 Message Digest in stages, rather than having to pass a * an MD5 Message Digest in stages, rather than having to pass a
* single large block to a single MD5 function. The context * single large block to a single MD5 function. The context
* structure keeps track of various bits of state information. * structure keeps track of various bits of state information.
* *
* Once the context is initialized, the blocks of message data * Once the context is initialized, the blocks of message data
* are passed to the <auth_md5SumCtx()> function. Once the * are passed to the <auth_md5SumCtx()> function. Once the
* final bit of data has been handed to <auth_md5SumCtx()> the * final bit of data has been handed to <auth_md5SumCtx()> the
* context can be closed out by calling <auth_md5CloseCtx()>, * context can be closed out by calling <auth_md5CloseCtx()>,
* which also calculates the final MD5 result. * which also calculates the final MD5 result.
* *
* Don't forget to free an allocated context structure when * Don't forget to free an allocated context structure when
* you've finished using it. * you've finished using it.
* *
* See Also: <auth_md5SumCtx()>, <auth_md5CloseCtx()> * See Also: <auth_md5SumCtx()>, <auth_md5CloseCtx()>
* *
* ------------------------------------------------------------------------ ** * ------------------------------------------------------------------------ **
*/ */
{ {
ctx->len = 0; ctx->len = 0;
ctx->b_used = 0; ctx->b_used = 0;
ctx->ABCD[0] = 0x67452301; /* The array ABCD[] contains the four 4-byte */ ctx->ABCD[0] = 0x67452301; /* The array ABCD[] contains the four 4-byte */
ctx->ABCD[1] = 0xefcdab89; /* "registers" that are manipulated to */ ctx->ABCD[1] = 0xefcdab89; /* "registers" that are manipulated to */
ctx->ABCD[2] = 0x98badcfe; /* produce the MD5 digest. The input acts */ ctx->ABCD[2] = 0x98badcfe; /* produce the MD5 digest. The input acts */
ctx->ABCD[3] = 0x10325476; /* upon the registers, not the other way */ ctx->ABCD[3] = 0x10325476; /* upon the registers, not the other way */
/* 'round. The initial values are those */ /* 'round. The initial values are those */
/* given in RFC 1321 (pg. 4). Note, however, that RFC 1321 */ /* given in RFC 1321 (pg. 4). Note, however, that RFC 1321 */
/* provides these values as bytes, not as longwords, and the */ /* provides these values as bytes, not as longwords, and the */
/* bytes are arranged in little-endian order as if they were */ /* bytes are arranged in little-endian order as if they were */
/* the bytes of (little endian) 32-bit ints. That's */ /* the bytes of (little endian) 32-bit ints. That's */
/* confusing as all getout (to me, anyway). The values given */ /* confusing as all getout (to me, anyway). The values given */
/* here are provided as 32-bit values in C language format, */ /* here are provided as 32-bit values in C language format, */
/* so they are endian-agnostic. */ /* so they are endian-agnostic. */
return( ctx ); return( ctx );
} /* auth_md5InitCtx */ } /* auth_md5InitCtx */
auth_md5Ctx *auth_md5SumCtx( auth_md5Ctx *ctx, auth_md5Ctx *auth_md5SumCtx( auth_md5Ctx *ctx,
const unsigned char *src, const unsigned char *src,
const int len ) const int len )
/* ------------------------------------------------------------------------ ** /* ------------------------------------------------------------------------ **
* Build an MD5 Message Digest within the given context. * Build an MD5 Message Digest within the given context.
* *
* Input: ctx - Pointer to the context in which the MD5 sum is being * Input: ctx - Pointer to the context in which the MD5 sum is being
* built. * built.
* src - A chunk of source data. This will be used to drive * src - A chunk of source data. This will be used to drive
* the MD5 algorithm. * the MD5 algorithm.
* len - The number of bytes in <src>. * len - The number of bytes in <src>.
* *
* Output: A pointer to the updated context (same as <ctx>). * Output: A pointer to the updated context (same as <ctx>).
* *
* See Also: <auth_md5InitCtx()>, <auth_md5CloseCtx()>, <auth_md5Sum()> * See Also: <auth_md5InitCtx()>, <auth_md5CloseCtx()>, <auth_md5Sum()>
* *
* ------------------------------------------------------------------------ ** * ------------------------------------------------------------------------ **
*/ */
{ {
int i; int i;
/* Add the new block's length to the total length. /* Add the new block's length to the total length.
*/ */
ctx->len += (uint32_t)len; ctx->len += (uint32_t)len;
/* Copy the new block's data into the context block. /* Copy the new block's data into the context block.
* Call the Permute() function whenever the context block is full. * Call the Permute() function whenever the context block is full.
*/ */
for ( i = 0; i < len; i++ ) { for( i = 0; i < len; i++ )
ctx->block[ ctx->b_used ] = src[i]; {
(ctx->b_used)++; ctx->block[ ctx->b_used ] = src[i];
if ( 64 == ctx->b_used ) { (ctx->b_used)++;
Permute( ctx->ABCD, ctx->block ); if( 64 == ctx->b_used )
ctx->b_used = 0; {
} Permute( ctx->ABCD, ctx->block );
ctx->b_used = 0;
}
} }
/* Return the updated context. /* Return the updated context.
*/ */
return( ctx ); return( ctx );
} /* auth_md5SumCtx */ } /* auth_md5SumCtx */
auth_md5Ctx *auth_md5CloseCtx( auth_md5Ctx *ctx, unsigned char *dst ) auth_md5Ctx *auth_md5CloseCtx( auth_md5Ctx *ctx, unsigned char *dst )
/* ------------------------------------------------------------------------ ** /* ------------------------------------------------------------------------ **
* Close an MD5 Message Digest context and generate the final MD5 sum. * Close an MD5 Message Digest context and generate the final MD5 sum.
* *
* Input: ctx - Pointer to the context in which the MD5 sum is being * Input: ctx - Pointer to the context in which the MD5 sum is being
* built. * built.
* dst - A pointer to at least 16 bytes of memory, which will * dst - A pointer to at least 16 bytes of memory, which will
* receive the finished MD5 sum. * receive the finished MD5 sum.
* *
* Output: A pointer to the closed context (same as <ctx>). * Output: A pointer to the closed context (same as <ctx>).
* You might use this to free a malloc'd context structure. :) * You might use this to free a malloc'd context structure. :)
* *
* Notes: The context (<ctx>) is returned in an undefined state. * Notes: The context (<ctx>) is returned in an undefined state.
* It must be re-initialized before re-use. * It must be re-initialized before re-use.
* *
* See Also: <auth_md5InitCtx()>, <auth_md5SumCtx()> * See Also: <auth_md5InitCtx()>, <auth_md5SumCtx()>
* *
* ------------------------------------------------------------------------ ** * ------------------------------------------------------------------------ **
*/ */
{ {
int i; int i;
uint32_t l; uint32_t l;
/* Add the required 0x80 padding initiator byte. /* Add the required 0x80 padding initiator byte.
* The auth_md5SumCtx() function always permutes and resets the context * The auth_md5SumCtx() function always permutes and resets the context
* block when it gets full, so we know that there must be at least one * block when it gets full, so we know that there must be at least one
* free byte in the context block. * free byte in the context block.
*/ */
ctx->block[ctx->b_used] = 0x80; ctx->block[ctx->b_used] = 0x80;
(ctx->b_used)++; (ctx->b_used)++;
/* Zero out any remaining free bytes in the context block. /* Zero out any remaining free bytes in the context block.
*/ */
for ( i = ctx->b_used; i < 64; i++ ) for( i = ctx->b_used; i < 64; i++ )
ctx->block[i] = 0; ctx->block[i] = 0;
/* We need 8 bytes to store the length field. /* We need 8 bytes to store the length field.
* If we don't have 8, call Permute() and reset the context block. * If we don't have 8, call Permute() and reset the context block.
*/ */
if ( 56 < ctx->b_used ) { if( 56 < ctx->b_used )
Permute( ctx->ABCD, ctx->block ); {
for ( i = 0; i < 64; i++ )
ctx->block[i] = 0;
}
/* Add the total length and perform the final perumation.
* Note: The 60'th byte is read from the *original* <ctx->len> value
* and shifted to the correct position. This neatly avoids
* any MAXINT numeric overflow issues.
*/
l = ctx->len << 3;
for ( i = 0; i < 4; i++ )
ctx->block[56+i] |= GetLongByte( l, i );
ctx->block[60] = ((GetLongByte( ctx->len, 3 ) & 0xE0) >> 5); /* See Above! */
Permute( ctx->ABCD, ctx->block ); Permute( ctx->ABCD, ctx->block );
for( i = 0; i < 64; i++ )
/* Now copy the result into the output buffer and we're done. ctx->block[i] = 0;
*/
for ( i = 0; i < 4; i++ ) {
dst[ 0+i] = GetLongByte( ctx->ABCD[0], i );
dst[ 4+i] = GetLongByte( ctx->ABCD[1], i );
dst[ 8+i] = GetLongByte( ctx->ABCD[2], i );
dst[12+i] = GetLongByte( ctx->ABCD[3], i );
} }
/* Return the context. /* Add the total length and perform the final perumation.
* This is done for compatibility with the other auth_md5*Ctx() functions. * Note: The 60'th byte is read from the *original* <ctx->len> value
*/ * and shifted to the correct position. This neatly avoids
return( ctx ); * any MAXINT numeric overflow issues.
} /* auth_md5CloseCtx */ */
l = ctx->len << 3;
for( i = 0; i < 4; i++ )
ctx->block[56+i] |= GetLongByte( l, i );
ctx->block[60] = ((GetLongByte( ctx->len, 3 ) & 0xE0) >> 5); /* See Above! */
Permute( ctx->ABCD, ctx->block );
/* Now copy the result into the output buffer and we're done.
*/
for( i = 0; i < 4; i++ )
{
dst[ 0+i] = GetLongByte( ctx->ABCD[0], i );
dst[ 4+i] = GetLongByte( ctx->ABCD[1], i );
dst[ 8+i] = GetLongByte( ctx->ABCD[2], i );
dst[12+i] = GetLongByte( ctx->ABCD[3], i );
}
/* Return the context.
* This is done for compatibility with the other auth_md5*Ctx() functions.
*/
return( ctx );
} /* auth_md5CloseCtx */
unsigned char * MD5(unsigned char *dst, const unsigned char *src, const int len ) unsigned char * MD5(unsigned char *dst, const unsigned char *src, const int len )
/* ------------------------------------------------------------------------ ** /* ------------------------------------------------------------------------ **
* Compute an MD5 message digest. * Compute an MD5 message digest.
* *
* Input: dst - Destination buffer into which the result will be written. * Input: dst - Destination buffer into which the result will be written.
* Must be 16 bytes, minimum. * Must be 16 bytes, minimum.
* src - Source data block to be MD5'd. * src - Source data block to be MD5'd.
* len - The length, in bytes, of the source block. * len - The length, in bytes, of the source block.
* (Note that the length is given in bytes, not bits.) * (Note that the length is given in bytes, not bits.)
* *
* Output: A pointer to <dst>, which will contain the calculated 16-byte * Output: A pointer to <dst>, which will contain the calculated 16-byte
* MD5 message digest. * MD5 message digest.
* *
* Notes: This function is a shortcut. It takes a single input block. * Notes: This function is a shortcut. It takes a single input block.
* For more drawn-out operations, see <auth_md5InitCtx()>. * For more drawn-out operations, see <auth_md5InitCtx()>.
* *
* This function is interface-compatible with the * This function is interface-compatible with the
* <auth_md4Sum()> function in the MD4 module. * <auth_md4Sum()> function in the MD4 module.
* *
* The MD5 algorithm is designed to work on data with an * The MD5 algorithm is designed to work on data with an
* arbitrary *bit* length. Most implementations, this one * arbitrary *bit* length. Most implementations, this one
* included, handle the input data in byte-sized chunks. * included, handle the input data in byte-sized chunks.
* *
* The MD5 algorithm does much of its work using four-byte * The MD5 algorithm does much of its work using four-byte
* words, and so can be tuned for speed based on the endian-ness * words, and so can be tuned for speed based on the endian-ness
* of the host. This implementation is intended to be * of the host. This implementation is intended to be
* endian-neutral, which may make it a teeny bit slower than * endian-neutral, which may make it a teeny bit slower than
* others. ...maybe. * others. ...maybe.
* *
* See Also: <auth_md5InitCtx()> * See Also: <auth_md5InitCtx()>
* *
* ------------------------------------------------------------------------ ** * ------------------------------------------------------------------------ **
*/ */
{ {
auth_md5Ctx ctx[1]; auth_md5Ctx ctx[1];
(void)auth_md5InitCtx( ctx ); /* Open a context. */ (void)auth_md5InitCtx( ctx ); /* Open a context. */
(void)auth_md5SumCtx( ctx, src, len ); /* Pass only one block. */ (void)auth_md5SumCtx( ctx, src, len ); /* Pass only one block. */
(void)auth_md5CloseCtx( ctx, dst ); /* Close the context. */ (void)auth_md5CloseCtx( ctx, dst ); /* Close the context. */
return( dst ); /* Makes life easy. */ return( dst ); /* Makes life easy. */
} /* auth_md5Sum */ } /* auth_md5Sum */
unsigned char * MD5fromFile(unsigned char *dst, const char *src) unsigned char * MD5fromFile(unsigned char *dst, const char *src)
/* ------------------------------------------------------------------------ ** /* ------------------------------------------------------------------------ **
* Compute an MD5 message digest. * Compute an MD5 message digest.
* *
* Input: dst - Destination buffer into which the result will be written. * Input: dst - Destination buffer into which the result will be written.
* Must be 16 bytes, minimum. * Must be 16 bytes, minimum.
* src - filepath of the file to be checked * src - filepath of the file to be checked
* *
* Output: A pointer to <dst>, which will contain the calculated 16-byte * Output: A pointer to <dst>, which will contain the calculated 16-byte
* MD5 message digest. * MD5 message digest.
* *
* Notes: This function is a shortcut. It takes a single input block. * Notes: This function is a shortcut. It takes a single input block.
* For more drawn-out operations, see <auth_md5InitCtx()>. * For more drawn-out operations, see <auth_md5InitCtx()>.
* *
* This function is interface-compatible with the * This function is interface-compatible with the
* <auth_md4Sum()> function in the MD4 module. * <auth_md4Sum()> function in the MD4 module.
* *
* The MD5 algorithm is designed to work on data with an * The MD5 algorithm is designed to work on data with an
* arbitrary *bit* length. Most implementations, this one * arbitrary *bit* length. Most implementations, this one
* included, handle the input data in byte-sized chunks. * included, handle the input data in byte-sized chunks.
* *
* The MD5 algorithm does much of its work using four-byte * The MD5 algorithm does much of its work using four-byte
* words, and so can be tuned for speed based on the endian-ness * words, and so can be tuned for speed based on the endian-ness
* of the host. This implementation is intended to be * of the host. This implementation is intended to be
* endian-neutral, which may make it a teeny bit slower than * endian-neutral, which may make it a teeny bit slower than
* others. ...maybe. * others. ...maybe.
* *
* See Also: <auth_md5InitCtx()> * See Also: <auth_md5InitCtx()>
* *
* ------------------------------------------------------------------------ ** * ------------------------------------------------------------------------ **
*/ */
{ {
auth_md5Ctx ctx[1]; auth_md5Ctx ctx[1];
FILE * file; FILE * file;
unsigned int blksize = 0; unsigned int blksize = 0;
@ -541,7 +552,7 @@ unsigned char * MD5fromFile(unsigned char *dst, const char *src)
file = fopen(src, "rb"); file = fopen(src, "rb");
if (file==NULL) { if (file==NULL){
return NULL; return NULL;
} }
@ -551,24 +562,25 @@ unsigned char * MD5fromFile(unsigned char *dst, const char *src)
unsigned long long filesize = ftell(file); unsigned long long filesize = ftell(file);
rewind (file); rewind (file);
if (filesize < 1048576) //1MB cache for files bigger than 1 MB if(filesize < 1048576) //1MB cache for files bigger than 1 MB
blksize = filesize; blksize = filesize;
else else
blksize = 1048576; blksize = 1048576;
unsigned char * buffer = malloc(blksize); unsigned char * buffer = malloc(blksize);
if (buffer == NULL) { if(buffer == NULL){
//no memory //no memory
fclose(file); fclose(file);
return NULL; return NULL;
} }
do { do
read = fread(buffer, 1, blksize, file); {
read = fread(buffer, 1, blksize, file);
(void)auth_md5SumCtx( ctx, buffer, read ); /* Pass only one block. */ (void)auth_md5SumCtx( ctx, buffer, read ); /* Pass only one block. */
} while (read > 0); } while(read > 0);
fclose(file); fclose(file);
free(buffer); free(buffer);
@ -576,14 +588,16 @@ unsigned char * MD5fromFile(unsigned char *dst, const char *src)
(void)auth_md5CloseCtx( ctx, dst ); /* Close the context. */ (void)auth_md5CloseCtx( ctx, dst ); /* Close the context. */
return( dst ); /* Makes life easy. */ return( dst ); /* Makes life easy. */
} /* auth_md5Sum */ } /* auth_md5Sum */
const char * MD5ToString(const unsigned char * hash, char * dst) { const char * MD5ToString(const unsigned char * hash, char * dst)
{
char hexchar[3]; char hexchar[3];
short i = 0, n = 0; short i = 0, n = 0;
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++)
{
sprintf(hexchar, "%02X", hash[i]); sprintf(hexchar, "%02X", hash[i]);
dst[n++] = hexchar[0]; dst[n++] = hexchar[0];
@ -595,11 +609,13 @@ const char * MD5ToString(const unsigned char * hash, char * dst) {
return dst; return dst;
} }
unsigned char * StringToMD5(const char * hash, unsigned char * dst) { unsigned char * StringToMD5(const char * hash, unsigned char * dst)
{
char hexchar[2]; char hexchar[2];
short i = 0, n = 0; short i = 0, n = 0;
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++)
{
hexchar[0] = hash[n++]; hexchar[0] = hash[n++];
hexchar[1] = hash[n++]; hexchar[1] = hash[n++];

View File

@ -2,241 +2,243 @@
#define MD5_H #define MD5_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
/* ========================================================================== ** /* ========================================================================== **
* *
* MD5.h * MD5.h
* *
* Copyright: * Copyright:
* Copyright (C) 2003-2005 by Christopher R. Hertel * Copyright (C) 2003-2005 by Christopher R. Hertel
* *
* Email: crh@ubiqx.mn.org * Email: crh@ubiqx.mn.org
* *
* $Id: MD5.h,v 0.6 2005/06/08 18:35:59 crh Exp $ * $Id: MD5.h,v 0.6 2005/06/08 18:35:59 crh Exp $
* *
* Modifications and additions by dimok * Modifications and additions by dimok
* *
* -------------------------------------------------------------------------- ** * -------------------------------------------------------------------------- **
* *
* Description: * Description:
* Implements the MD5 hash algorithm, as described in RFC 1321. * Implements the MD5 hash algorithm, as described in RFC 1321.
* *
* -------------------------------------------------------------------------- ** * -------------------------------------------------------------------------- **
* *
* License: * License:
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. * version 2.1 of the License, or (at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* -------------------------------------------------------------------------- ** * -------------------------------------------------------------------------- **
* *
* Notes: * Notes:
* *
* None of this will make any sense unless you're studying RFC 1321 as you * None of this will make any sense unless you're studying RFC 1321 as you
* read the code. * read the code.
* *
* MD5 is described in RFC 1321. * MD5 is described in RFC 1321.
* The MD*4* algorithm is described in RFC 1320 (that's 1321 - 1). * The MD*4* algorithm is described in RFC 1320 (that's 1321 - 1).
* MD5 is very similar to MD4, but not quite similar enough to justify * MD5 is very similar to MD4, but not quite similar enough to justify
* putting the two into a single module. Besides, I wanted to add a few * putting the two into a single module. Besides, I wanted to add a few
* extra functions to this one to expand its usability. * extra functions to this one to expand its usability.
* *
* There are three primary motivations for this particular implementation. * There are three primary motivations for this particular implementation.
* 1) Programmer's pride. I wanted to be able to say I'd done it, and I * 1) Programmer's pride. I wanted to be able to say I'd done it, and I
* wanted to learn from the experience. * wanted to learn from the experience.
* 2) Portability. I wanted an implementation that I knew to be portable * 2) Portability. I wanted an implementation that I knew to be portable
* to a reasonable number of platforms. In particular, the algorithm is * to a reasonable number of platforms. In particular, the algorithm is
* designed with little-endian platforms in mind, but I wanted an * designed with little-endian platforms in mind, but I wanted an
* endian-agnostic implementation. * endian-agnostic implementation.
* 3) Compactness. While not an overriding goal, I thought it worth-while * 3) Compactness. While not an overriding goal, I thought it worth-while
* to see if I could reduce the overall size of the result. This is in * to see if I could reduce the overall size of the result. This is in
* keeping with my hopes that this library will be suitable for use in * keeping with my hopes that this library will be suitable for use in
* some embedded environments. * some embedded environments.
* Beyond that, cleanliness and clarity are always worth pursuing. * Beyond that, cleanliness and clarity are always worth pursuing.
* *
* As mentioned above, the code really only makes sense if you are familiar * As mentioned above, the code really only makes sense if you are familiar
* with the MD5 algorithm or are using RFC 1321 as a guide. This code is * with the MD5 algorithm or are using RFC 1321 as a guide. This code is
* quirky, however, so you'll want to be reading carefully. * quirky, however, so you'll want to be reading carefully.
* *
* Yeah...most of the comments are cut-and-paste from my MD4 implementation. * Yeah...most of the comments are cut-and-paste from my MD4 implementation.
* *
* -------------------------------------------------------------------------- ** * -------------------------------------------------------------------------- **
* *
* References: * References:
* IETF RFC 1321: The MD5 Message-Digest Algorithm * IETF RFC 1321: The MD5 Message-Digest Algorithm
* Ron Rivest. IETF, April, 1992 * Ron Rivest. IETF, April, 1992
* *
* ========================================================================== ** * ========================================================================== **
*/ */
/* -------------------------------------------------------------------------- ** /* -------------------------------------------------------------------------- **
* Typedefs: * Typedefs:
*/ */
typedef struct { typedef struct
unsigned int len; {
unsigned int ABCD[4]; unsigned int len;
int b_used; unsigned int ABCD[4];
unsigned char block[64]; int b_used;
} auth_md5Ctx; unsigned char block[64];
} auth_md5Ctx;
/* -------------------------------------------------------------------------- ** /* -------------------------------------------------------------------------- **
* Functions: * Functions:
*/ */
auth_md5Ctx *auth_md5InitCtx( auth_md5Ctx *ctx ); auth_md5Ctx *auth_md5InitCtx( auth_md5Ctx *ctx );
/* ------------------------------------------------------------------------ ** /* ------------------------------------------------------------------------ **
* Initialize an MD5 context. * Initialize an MD5 context.
* *
* Input: ctx - A pointer to the MD5 context structure to be initialized. * Input: ctx - A pointer to the MD5 context structure to be initialized.
* Contexts are typically created thusly: * Contexts are typically created thusly:
* ctx = (auth_md5Ctx *)malloc( sizeof(auth_md5Ctx) ); * ctx = (auth_md5Ctx *)malloc( sizeof(auth_md5Ctx) );
* *
* Output: A pointer to the initialized context (same as <ctx>). * Output: A pointer to the initialized context (same as <ctx>).
* *
* Notes: The purpose of the context is to make it possible to generate * Notes: The purpose of the context is to make it possible to generate
* an MD5 Message Digest in stages, rather than having to pass a * an MD5 Message Digest in stages, rather than having to pass a
* single large block to a single MD5 function. The context * single large block to a single MD5 function. The context
* structure keeps track of various bits of state information. * structure keeps track of various bits of state information.
* *
* Once the context is initialized, the blocks of message data * Once the context is initialized, the blocks of message data
* are passed to the <auth_md5SumCtx()> function. Once the * are passed to the <auth_md5SumCtx()> function. Once the
* final bit of data has been handed to <auth_md5SumCtx()> the * final bit of data has been handed to <auth_md5SumCtx()> the
* context can be closed out by calling <auth_md5CloseCtx()>, * context can be closed out by calling <auth_md5CloseCtx()>,
* which also calculates the final MD5 result. * which also calculates the final MD5 result.
* *
* Don't forget to free an allocated context structure when * Don't forget to free an allocated context structure when
* you've finished using it. * you've finished using it.
* *
* See Also: <auth_md5SumCtx()>, <auth_md5CloseCtx()> * See Also: <auth_md5SumCtx()>, <auth_md5CloseCtx()>
* *
* ------------------------------------------------------------------------ ** * ------------------------------------------------------------------------ **
*/ */
auth_md5Ctx *auth_md5SumCtx( auth_md5Ctx *ctx, auth_md5Ctx *auth_md5SumCtx( auth_md5Ctx *ctx,
const unsigned char *src, const unsigned char *src,
const int len ); const int len );
/* ------------------------------------------------------------------------ ** /* ------------------------------------------------------------------------ **
* Build an MD5 Message Digest within the given context. * Build an MD5 Message Digest within the given context.
* *
* Input: ctx - Pointer to the context in which the MD5 sum is being * Input: ctx - Pointer to the context in which the MD5 sum is being
* built. * built.
* src - A chunk of source data. This will be used to drive * src - A chunk of source data. This will be used to drive
* the MD5 algorithm. * the MD5 algorithm.
* len - The number of bytes in <src>. * len - The number of bytes in <src>.
* *
* Output: A pointer to the updated context (same as <ctx>). * Output: A pointer to the updated context (same as <ctx>).
* *
* See Also: <auth_md5InitCtx()>, <auth_md5CloseCtx()>, <auth_md5Sum()> * See Also: <auth_md5InitCtx()>, <auth_md5CloseCtx()>, <auth_md5Sum()>
* *
* ------------------------------------------------------------------------ ** * ------------------------------------------------------------------------ **
*/ */
auth_md5Ctx *auth_md5CloseCtx( auth_md5Ctx *ctx, unsigned char *dst ); auth_md5Ctx *auth_md5CloseCtx( auth_md5Ctx *ctx, unsigned char *dst );
/* ------------------------------------------------------------------------ ** /* ------------------------------------------------------------------------ **
* Close an MD5 Message Digest context and generate the final MD5 sum. * Close an MD5 Message Digest context and generate the final MD5 sum.
* *
* Input: ctx - Pointer to the context in which the MD5 sum is being * Input: ctx - Pointer to the context in which the MD5 sum is being
* built. * built.
* dst - A pointer to at least 16 bytes of memory, which will * dst - A pointer to at least 16 bytes of memory, which will
* receive the finished MD5 sum. * receive the finished MD5 sum.
* *
* Output: A pointer to the closed context (same as <ctx>). * Output: A pointer to the closed context (same as <ctx>).
* You might use this to free a malloc'd context structure. :) * You might use this to free a malloc'd context structure. :)
* *
* Notes: The context (<ctx>) is returned in an undefined state. * Notes: The context (<ctx>) is returned in an undefined state.
* It must be re-initialized before re-use. * It must be re-initialized before re-use.
* *
* See Also: <auth_md5InitCtx()>, <auth_md5SumCtx()> * See Also: <auth_md5InitCtx()>, <auth_md5SumCtx()>
* *
* ------------------------------------------------------------------------ ** * ------------------------------------------------------------------------ **
*/ */
unsigned char * MD5(unsigned char * hash, const unsigned char *src, const int len ); unsigned char * MD5(unsigned char * hash, const unsigned char *src, const int len );
/* ------------------------------------------------------------------------ ** /* ------------------------------------------------------------------------ **
* Compute an MD5 message digest. * Compute an MD5 message digest.
* *
* Input: dst - Destination buffer into which the result will be written. * Input: dst - Destination buffer into which the result will be written.
* Must be 16 bytes, minimum. * Must be 16 bytes, minimum.
* src - Source data block to be MD5'd. * src - Source data block to be MD5'd.
* len - The length, in bytes, of the source block. * len - The length, in bytes, of the source block.
* (Note that the length is given in bytes, not bits.) * (Note that the length is given in bytes, not bits.)
* *
* Output: A pointer to <dst>, which will contain the calculated 16-byte * Output: A pointer to <dst>, which will contain the calculated 16-byte
* MD5 message digest. * MD5 message digest.
* *
* Notes: This function is a shortcut. It takes a single input block. * Notes: This function is a shortcut. It takes a single input block.
* For more drawn-out operations, see <auth_md5InitCtx()>. * For more drawn-out operations, see <auth_md5InitCtx()>.
* *
* This function is interface-compatible with the * This function is interface-compatible with the
* <auth_md4Sum()> function in the MD4 module. * <auth_md4Sum()> function in the MD4 module.
* *
* The MD5 algorithm is designed to work on data with an * The MD5 algorithm is designed to work on data with an
* arbitrary *bit* length. Most implementations, this one * arbitrary *bit* length. Most implementations, this one
* included, handle the input data in byte-sized chunks. * included, handle the input data in byte-sized chunks.
* *
* The MD5 algorithm does much of its work using four-byte * The MD5 algorithm does much of its work using four-byte
* words, and so can be tuned for speed based on the endian-ness * words, and so can be tuned for speed based on the endian-ness
* of the host. This implementation is intended to be * of the host. This implementation is intended to be
* endian-neutral, which may make it a teeny bit slower than * endian-neutral, which may make it a teeny bit slower than
* others. ...maybe. * others. ...maybe.
* *
* See Also: <auth_md5InitCtx()> * See Also: <auth_md5InitCtx()>
* *
* ------------------------------------------------------------------------ ** * ------------------------------------------------------------------------ **
*/ */
unsigned char * MD5fromFile(unsigned char *dst, const char *src); unsigned char * MD5fromFile(unsigned char *dst, const char *src);
/* ------------------------------------------------------------------------ ** /* ------------------------------------------------------------------------ **
* Compute an MD5 message digest. * Compute an MD5 message digest.
* *
* Input: dst - Destination buffer into which the result will be written. * Input: dst - Destination buffer into which the result will be written.
* Must be 16 bytes, minimum. * Must be 16 bytes, minimum.
* src - filepath to the file to be MD5'd. * src - filepath to the file to be MD5'd.
* *
* Output: A pointer to <dst>, which will contain the calculated 16-byte * Output: A pointer to <dst>, which will contain the calculated 16-byte
* MD5 message digest. * MD5 message digest.
* *
* Notes: This function is a shortcut. It takes a single input block. * Notes: This function is a shortcut. It takes a single input block.
* For more drawn-out operations, see <auth_md5InitCtx()>. * For more drawn-out operations, see <auth_md5InitCtx()>.
* *
* This function is interface-compatible with the * This function is interface-compatible with the
* <auth_md4Sum()> function in the MD4 module. * <auth_md4Sum()> function in the MD4 module.
* *
* The MD5 algorithm is designed to work on data with an * The MD5 algorithm is designed to work on data with an
* arbitrary *bit* length. Most implementations, this one * arbitrary *bit* length. Most implementations, this one
* included, handle the input data in byte-sized chunks. * included, handle the input data in byte-sized chunks.
* *
* The MD5 algorithm does much of its work using four-byte * The MD5 algorithm does much of its work using four-byte
* words, and so can be tuned for speed based on the endian-ness * words, and so can be tuned for speed based on the endian-ness
* of the host. This implementation is intended to be * of the host. This implementation is intended to be
* endian-neutral, which may make it a teeny bit slower than * endian-neutral, which may make it a teeny bit slower than
* others. ...maybe. * others. ...maybe.
* *
* See Also: <auth_md5InitCtx()> * See Also: <auth_md5InitCtx()>
* *
* ------------------------------------------------------------------------ ** * ------------------------------------------------------------------------ **
*/ */
const char * MD5ToString(const unsigned char *hash, char *dst); const char * MD5ToString(const unsigned char *hash, char *dst);
unsigned char * StringToMD5(const char * hash, unsigned char * dst); unsigned char * StringToMD5(const char * hash, unsigned char * dst);
/* ========================================================================== */ /* ========================================================================== */
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -22,98 +22,106 @@
#include "patches/fst.h" #include "patches/fst.h"
#include "usbloader/fstfile.h" #include "usbloader/fstfile.h"
s32 dump_banner(const u8* discid,const char * dest) { s32 dump_banner(const u8* discid,const char * dest)
// Mount the disc {
//Disc_SetWBFS(1, (u8*)discid); // Mount the disc
Disc_SetUSB(discid); //Disc_SetWBFS(1, (u8*)discid);
Disc_SetUSB(discid);
Disc_Open(); Disc_Open();
u64 offset; u64 offset;
s32 ret; s32 ret;
ret = __Disc_FindPartition(&offset); ret = __Disc_FindPartition(&offset);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = WDVD_OpenPartition(offset); ret = WDVD_OpenPartition(offset);
if (ret < 0) { if (ret < 0) {
//printf("ERROR: OpenPartition(0x%llx) %d\n", offset, ret); //printf("ERROR: OpenPartition(0x%llx) %d\n", offset, ret);
return ret; return ret;
} }
// Read where to find the fst.bin // Read where to find the fst.bin
u32 *buffer = memalign(32, 0x20); u32 *buffer = memalign(32, 0x20);
if (buffer == NULL) { if (buffer == NULL)
//Out of memory {
return -1; //Out of memory
} return -1;
}
ret = WDVD_Read(buffer, 0x20, 0x420); ret = WDVD_Read(buffer, 0x20, 0x420);
if (ret < 0) if (ret < 0)
return ret; return ret;
// Read fst.bin // Read fst.bin
void *fstbuffer = memalign(32, buffer[2]*4); void *fstbuffer = memalign(32, buffer[2]*4);
FST_ENTRY *fst = (FST_ENTRY *)fstbuffer; FST_ENTRY *fst = (FST_ENTRY *)fstbuffer;
if (fst == NULL) { if (fst == NULL)
//Out of memory {
free(buffer); //Out of memory
return -1; free(buffer);
} return -1;
}
ret = WDVD_Read(fstbuffer, buffer[2]*4, buffer[1]*4); ret = WDVD_Read(fstbuffer, buffer[2]*4, buffer[1]*4);
if (ret < 0) if (ret < 0)
return ret; return ret;
free(buffer); free(buffer);
// Search the fst.bin // Search the fst.bin
u32 count = fst[0].filelen; u32 count = fst[0].filelen;
int i; int i;
u32 index = 0; u32 index = 0;
for (i=1;i<count;i++) { for (i=1;i<count;i++)
if (strstr(fstfiles(fst, i), "opening.bnr") != NULL) { {
index = i; if (strstr(fstfiles(fst, i), "opening.bnr") != NULL)
} {
} index = i;
}
}
if (index == 0) { if (index == 0)
//opening.bnr not found {
free(fstbuffer); //opening.bnr not found
return -1; free(fstbuffer);
} return -1;
}
// Load the .bnr // Load the .bnr
u8 *banner = memalign(32, fst[index].filelen); u8 *banner = memalign(32, fst[index].filelen);
if (banner == NULL) { if (banner == NULL)
//Out of memory {
free(fstbuffer); //Out of memory
return -1; free(fstbuffer);
} return -1;
}
ret = WDVD_Read((void *)banner, fst[index].filelen, fst[index].fileoffset * 4); ret = WDVD_Read((void *)banner, fst[index].filelen, fst[index].fileoffset * 4);
if (ret < 0) if (ret < 0)
return ret; return ret;
WDVD_Reset(); WDVD_Reset();
WDVD_ClosePartition(); WDVD_ClosePartition();
//fatInitDefault(); //fatInitDefault();
//SDCard_Init(); //SDCard_Init();
WDVD_SetUSBMode(NULL, 0); WDVD_SetUSBMode(NULL, 0);
FILE *fp = fopen(dest, "wb"); FILE *fp = fopen(dest, "wb");
if (fp) { if(fp)
fwrite(banner, 1, fst[index].filelen, fp); {
fclose(fp); fwrite(banner, 1, fst[index].filelen, fp);
} fclose(fp);
free(fstbuffer); }
free(banner); free(fstbuffer);
free(banner);
return 1; return 1;
} }

View File

@ -9,10 +9,11 @@
#define BANNER_H #define BANNER_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
s32 dump_banner(const u8 *discid,const char * dest); s32 dump_banner(const u8 *discid,const char * dest);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -6,63 +6,65 @@
***************************************************************************/ ***************************************************************************/
#include "gui_banner.h" #include "gui_banner.h"
GuiBanner::GuiBanner(const char *tplfilepath) { GuiBanner::GuiBanner(const char *tplfilepath)
{
memory = NULL; memory = NULL;
tplfilesize = 0; tplfilesize = 0;
width = 0; width = 0;
height = 0; height = 0;
FILE *tplfp = fopen(tplfilepath,"rb"); FILE *tplfp = fopen(tplfilepath,"rb");
if (tplfp !=NULL) { if(tplfp !=NULL) {
unsigned short heighttemp = 0; unsigned short heighttemp = 0;
unsigned short widthtemp = 0; unsigned short widthtemp = 0;
fseek(tplfp , 0x14, SEEK_SET); fseek(tplfp , 0x14, SEEK_SET);
fread((void*)&heighttemp,1,2,tplfp); fread((void*)&heighttemp,1,2,tplfp);
fread((void*)&widthtemp,1,2,tplfp); fread((void*)&widthtemp,1,2,tplfp);
fseek (tplfp , 0 , SEEK_END); fseek (tplfp , 0 , SEEK_END);
tplfilesize = ftell (tplfp); tplfilesize = ftell (tplfp);
rewind (tplfp); rewind (tplfp);
memory = memalign(32, tplfilesize); memory = memalign(32, tplfilesize);
if (!memory) { if(!memory) {
fclose(tplfp); fclose(tplfp);
return; return;
} }
fread(memory, 1, tplfilesize, tplfp); fread(memory, 1, tplfilesize, tplfp);
fclose(tplfp); fclose(tplfp);
TPLFile tplfile; TPLFile tplfile;
int ret; int ret;
ret = TPL_OpenTPLFromMemory(&tplfile, memory, tplfilesize); ret = TPL_OpenTPLFromMemory(&tplfile, memory, tplfilesize);
if (ret < 0) { if(ret < 0) {
free(memory); free(memory);
memory = NULL; memory = NULL;
return; return;
} }
ret = TPL_GetTexture(&tplfile,0,&texObj); ret = TPL_GetTexture(&tplfile,0,&texObj);
if (ret < 0) { if(ret < 0) {
free(memory); free(memory);
memory = NULL; memory = NULL;
return; return;
} }
TPL_CloseTPLFile(&tplfile); TPL_CloseTPLFile(&tplfile);
width = widthtemp; width = widthtemp;
height = heighttemp; height = heighttemp;
widescreen = 0; widescreen = 0;
filecheck = true; filecheck = true;
} else { } else {
filecheck = false; filecheck = false;
fclose(tplfp); fclose(tplfp);
} }
} }
GuiBanner::GuiBanner(void *mem, u32 len, int w, int h) { GuiBanner::GuiBanner(void *mem, u32 len, int w, int h)
if (!mem || !len) {
if(!mem || !len)
return; return;
memory = mem; memory = mem;
tplfilesize = len; tplfilesize = len;
@ -74,13 +76,13 @@ GuiBanner::GuiBanner(void *mem, u32 len, int w, int h) {
int ret; int ret;
ret = TPL_OpenTPLFromMemory(&tplfile, memory, tplfilesize); ret = TPL_OpenTPLFromMemory(&tplfile, memory, tplfilesize);
if (ret < 0) { if(ret < 0) {
free(memory); free(memory);
memory = NULL; memory = NULL;
return; return;
} }
ret = TPL_GetTexture(&tplfile,0,&texObj); ret = TPL_GetTexture(&tplfile,0,&texObj);
if (ret < 0) { if(ret < 0) {
free(memory); free(memory);
memory = NULL; memory = NULL;
return; return;
@ -90,21 +92,23 @@ GuiBanner::GuiBanner(void *mem, u32 len, int w, int h) {
filecheck = true; filecheck = true;
} }
GuiBanner::~GuiBanner() { GuiBanner::~GuiBanner()
if (memory != NULL) { {
if(memory != NULL) {
free(memory); free(memory);
memory = NULL; memory = NULL;
} }
} }
void GuiBanner::Draw() { void GuiBanner::Draw()
LOCK(this); {
if (!filecheck ||!this->IsVisible()) LOCK(this);
return; if(!filecheck ||!this->IsVisible())
return;
float currScale = this->GetScale(); float currScale = this->GetScale();
Menu_DrawTPLImg(this->GetLeft(), this->GetTop(), 0, width, height, &texObj, imageangle, widescreen ? currScale*0.80 : currScale, currScale, this->GetAlpha(), xx1,yy1,xx2,yy2,xx3,yy3,xx4,yy4); Menu_DrawTPLImg(this->GetLeft(), this->GetTop(), 0, width, height, &texObj, imageangle, widescreen ? currScale*0.80 : currScale, currScale, this->GetAlpha(), xx1,yy1,xx2,yy2,xx3,yy3,xx4,yy4);
this->UpdateEffects(); this->UpdateEffects();
} }

View File

@ -10,24 +10,25 @@
#include "libwiigui/gui.h" #include "libwiigui/gui.h"
class GuiBanner : public GuiImage { class GuiBanner : public GuiImage
{
public: public:
//!Constructor //!Constructor
//!\param tplfilepath Path of the tpl file //!\param tplfilepath Path of the tpl file
GuiBanner(const char *tplfilepath); GuiBanner(const char *tplfilepath);
//!Constructor //!Constructor
//!\param mem Memory of the loaded tpl //!\param mem Memory of the loaded tpl
//!\param len Filesize of the tpl //!\param len Filesize of the tpl
//!\param w Width of the tpl //!\param w Width of the tpl
//!\param h Height of the tpl //!\param h Height of the tpl
GuiBanner(void *mem, u32 len, int w, int h); GuiBanner(void *mem, u32 len, int w, int h);
//!Destructor //!Destructor
~GuiBanner(); ~GuiBanner();
void Draw(); void Draw();
protected: protected:
void * memory; void * memory;
bool filecheck; bool filecheck;
u32 tplfilesize; u32 tplfilesize;
GXTexObj texObj; GXTexObj texObj;
}; };

View File

@ -28,39 +28,47 @@
#include "../ramdisk/ramdisk.h" #include "../ramdisk/ramdisk.h"
#include "../listfiles.h" #include "../listfiles.h"
u16 be16(const u8 *p) { u16 be16(const u8 *p)
return (p[0] << 8) | p[1]; {
return (p[0] << 8) | p[1];
} }
u32 be32(const u8 *p) { u32 be32(const u8 *p)
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; {
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
} }
u64 be64(const u8 *p) { u64 be64(const u8 *p)
return ((u64)be32(p) << 32) | be32(p + 4); {
return ((u64)be32(p) << 32) | be32(p + 4);
} }
u64 be34(const u8 *p) { u64 be34(const u8 *p)
return 4 * (u64)be32(p); {
return 4 * (u64)be32(p);
} }
void wbe16(u8 *p, u16 x) { void wbe16(u8 *p, u16 x)
p[0] = x >> 8; {
p[1] = x; p[0] = x >> 8;
p[1] = x;
} }
void wbe32(u8 *p, u32 x) { void wbe32(u8 *p, u32 x)
wbe16(p, x >> 16); {
wbe16(p + 2, x); wbe16(p, x >> 16);
wbe16(p + 2, x);
} }
void wbe64(u8 *p, u64 x) { void wbe64(u8 *p, u64 x)
wbe32(p, x >> 32); {
wbe32(p + 4, x); wbe32(p, x >> 32);
wbe32(p + 4, x);
} }
void md5(u8 *data, u32 len, u8 *hash) { void md5(u8 *data, u32 len, u8 *hash)
MD5(hash, data, len); {
MD5(hash, data, len);
} }
@ -82,416 +90,440 @@ typedef struct {
} imet_data_t; } imet_data_t;
typedef struct { typedef struct {
u32 imd5_tag; // 0x494D4435 "IMD5"; u32 imd5_tag; // 0x494D4435 "IMD5";
u32 size; // size of the rest of part B, starting from next field. u32 size; // size of the rest of part B, starting from next field.
u8 zeroes[8]; u8 zeroes[8];
u8 md5[16]; u8 md5[16];
u32 payload_tag; // 0x4C5A3737 "LZ77" if this is lz77 u32 payload_tag; // 0x4C5A3737 "LZ77" if this is lz77
u32 payload_data; u32 payload_data;
} imd5_header_t; } imd5_header_t;
typedef struct { typedef struct
u16 type; {
u16 name_offset; u16 type;
u32 data_offset; // == absolut offset från U.8- headerns början u16 name_offset;
u32 size; // last included file num for directories u32 data_offset; // == absolut offset från U.8- headerns början
u32 size; // last included file num for directories
} U8_node; } U8_node;
typedef struct { typedef struct
u32 tag; // 0x55AA382D "U.8-" {
u32 rootnode_offset; // offset to root_node, always 0x20. u32 tag; // 0x55AA382D "U.8-"
u32 header_size; // size of header from root_node to end of string table. u32 rootnode_offset; // offset to root_node, always 0x20.
u32 data_offset; // offset to data -- this is rootnode_offset + header_size, aligned to 0x40. u32 header_size; // size of header from root_node to end of string table.
u8 zeroes[16]; u32 data_offset; // offset to data -- this is rootnode_offset + header_size, aligned to 0x40.
u8 zeroes[16];
} U8_archive_header; } U8_archive_header;
static int write_file(void* data, size_t size, char* name) { static int write_file(void* data, size_t size, char* name)
size_t written=0; {
FILE *out; size_t written=0;
out = fopen(name, "wb"); FILE *out;
if (out) { out = fopen(name, "wb");
written = fwrite(data, 1, size, out); if(out)
fclose(out); {
} written = fwrite(data, 1, size, out);
return (written == size) ? 1 : -1; fclose(out);
}
return (written == size) ? 1 : -1;
} }
u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size) { u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size)
u8 *data_end; {
u8 *decompressed_data; u8 *data_end;
size_t unpacked_size; u8 *decompressed_data;
u8 *in_ptr; size_t unpacked_size;
u8 *out_ptr; u8 *in_ptr;
u8 *out_end; u8 *out_ptr;
u8 *out_end;
in_ptr = data; in_ptr = data;
data_end = data + data_size; data_end = data + data_size;
// Assume this for now and grow when needed // Assume this for now and grow when needed
unpacked_size = data_size; unpacked_size = data_size;
decompressed_data = malloc(unpacked_size); decompressed_data = malloc(unpacked_size);
out_end = decompressed_data + unpacked_size; out_end = decompressed_data + unpacked_size;
out_ptr = decompressed_data; out_ptr = decompressed_data;
while (in_ptr < data_end) { while (in_ptr < data_end) {
int bit; int bit;
u8 bitmask = *in_ptr; u8 bitmask = *in_ptr;
in_ptr++; in_ptr++;
for (bit = 0x80; bit != 0; bit >>= 1) { for (bit = 0x80; bit != 0; bit >>= 1) {
if (bitmask & bit) { if (bitmask & bit) {
// Next section is compressed // Next section is compressed
u8 rep_length; u8 rep_length;
u16 rep_offset; u16 rep_offset;
rep_length = (*in_ptr >> 4) + 3; rep_length = (*in_ptr >> 4) + 3;
rep_offset = *in_ptr & 0x0f; rep_offset = *in_ptr & 0x0f;
in_ptr++; in_ptr++;
rep_offset = *in_ptr | (rep_offset << 8); rep_offset = *in_ptr | (rep_offset << 8);
in_ptr++; in_ptr++;
if (out_ptr-decompressed_data < rep_offset) { if (out_ptr-decompressed_data < rep_offset) {
return NULL; return NULL;
} }
for ( ; rep_length > 0; rep_length--) { for ( ; rep_length > 0; rep_length--) {
*out_ptr = out_ptr[-rep_offset-1]; *out_ptr = out_ptr[-rep_offset-1];
out_ptr++; out_ptr++;
if (out_ptr >= out_end) { if (out_ptr >= out_end) {
// Need to grow buffer // Need to grow buffer
decompressed_data = realloc(decompressed_data, unpacked_size*2); decompressed_data = realloc(decompressed_data, unpacked_size*2);
out_ptr = decompressed_data + unpacked_size; out_ptr = decompressed_data + unpacked_size;
unpacked_size *= 2; unpacked_size *= 2;
out_end = decompressed_data + unpacked_size; out_end = decompressed_data + unpacked_size;
} }
}
} else {
// Just copy byte
*out_ptr = *in_ptr;
out_ptr++;
if (out_ptr >= out_end) {
// Need to grow buffer
decompressed_data = realloc(decompressed_data, unpacked_size*2);
out_ptr = decompressed_data + unpacked_size;
unpacked_size *= 2;
out_end = decompressed_data + unpacked_size;
}
in_ptr++;
}
} }
} } else {
// Just copy byte
*out_ptr = *in_ptr;
out_ptr++;
if (out_ptr >= out_end) {
// Need to grow buffer
decompressed_data = realloc(decompressed_data, unpacked_size*2);
out_ptr = decompressed_data + unpacked_size;
unpacked_size *= 2;
out_end = decompressed_data + unpacked_size;
}
in_ptr++;
}
}
}
*decompressed_size = (out_ptr - decompressed_data); *decompressed_size = (out_ptr - decompressed_data);
return decompressed_data; return decompressed_data;
} }
static int write_imd5_lz77(u8* data, size_t size, char* outname) { static int write_imd5_lz77(u8* data, size_t size, char* outname)
imd5_header_t* header = (imd5_header_t*) data; {
u32 tag; imd5_header_t* header = (imd5_header_t*) data;
u32 size_in_imd5; u32 tag;
u32 size_in_imd5;
u8 md5_calc[16]; u8 md5_calc[16];
u8 *decompressed_data; u8 *decompressed_data;
size_t decompressed_size; size_t decompressed_size;
tag = be32((u8*) &header->imd5_tag); tag = be32((u8*) &header->imd5_tag);
if (tag != 0x494D4435) { if (tag != 0x494D4435) {
return -4; return -4;
} }
md5(data+32, size-32, md5_calc); md5(data+32, size-32, md5_calc);
if (memcmp(&header->md5, md5_calc, 0x10)) { if (memcmp(&header->md5, md5_calc, 0x10)) {
return -5; return -5;
} }
size_in_imd5 = be32((u8*) &header->size); size_in_imd5 = be32((u8*) &header->size);
if (size_in_imd5 != size - 32) { if (size_in_imd5 != size - 32) {
return -6; return -6;
} }
tag = be32((u8*) &header->payload_tag); tag = be32((u8*) &header->payload_tag);
if (tag == 0x4C5A3737) { if (tag == 0x4C5A3737) {
// "LZ77" - uncompress // "LZ77" - uncompress
decompressed_data = decompress_lz77(data + sizeof(imd5_header_t), size - sizeof(imd5_header_t), &decompressed_size); decompressed_data = decompress_lz77(data + sizeof(imd5_header_t), size - sizeof(imd5_header_t), &decompressed_size);
if (decompressed_data == NULL) if(decompressed_data == NULL)
return -7; return -7;
write_file(decompressed_data, decompressed_size, outname); write_file(decompressed_data, decompressed_size, outname);
//printf(", uncompressed %d bytes, md5 ok", decompressed_size); //printf(", uncompressed %d bytes, md5 ok", decompressed_size);
free(decompressed_data); free(decompressed_data);
} else { } else {
write_file(&header->payload_tag, size-32, outname); write_file(&header->payload_tag, size-32, outname);
//printf(", md5 ok"); //printf(", md5 ok");
} }
return 0; return 0;
} }
static int do_U8_archive(FILE *fp) { static int do_U8_archive(FILE *fp)
U8_archive_header header; {
U8_node root_node; U8_archive_header header;
u32 tag; U8_node root_node;
u32 num_nodes; u32 tag;
U8_node* nodes; u32 num_nodes;
u8* string_table; U8_node* nodes;
size_t rest_size; u8* string_table;
unsigned int i; size_t rest_size;
u32 data_offset; unsigned int i;
u32 current_offset; u32 data_offset;
u16 dir_stack[16]; u32 current_offset;
int dir_index = 0; u16 dir_stack[16];
int dir_index = 0;
fread(&header, 1, sizeof header, fp); fread(&header, 1, sizeof header, fp);
tag = be32((u8*) &header.tag); tag = be32((u8*) &header.tag);
if (tag != 0x55AA382D) { if (tag != 0x55AA382D) {
return -1; return -1;
} }
fread(&root_node, 1, sizeof(root_node), fp); fread(&root_node, 1, sizeof(root_node), fp);
num_nodes = be32((u8*) &root_node.size) - 1; num_nodes = be32((u8*) &root_node.size) - 1;
//printf("Number of files: %d\n", num_nodes); //printf("Number of files: %d\n", num_nodes);
nodes = malloc(sizeof(U8_node) * (num_nodes)); nodes = malloc(sizeof(U8_node) * (num_nodes));
fread(nodes, 1, num_nodes * sizeof(U8_node), fp); fread(nodes, 1, num_nodes * sizeof(U8_node), fp);
data_offset = be32((u8*) &header.data_offset); data_offset = be32((u8*) &header.data_offset);
rest_size = data_offset - sizeof(header) - (num_nodes+1)*sizeof(U8_node); rest_size = data_offset - sizeof(header) - (num_nodes+1)*sizeof(U8_node);
string_table = malloc(rest_size); string_table = malloc(rest_size);
fread(string_table, 1, rest_size, fp); fread(string_table, 1, rest_size, fp);
current_offset = data_offset; current_offset = data_offset;
for (i = 0; i < num_nodes; i++) { for (i = 0; i < num_nodes; i++) {
U8_node* node = &nodes[i]; U8_node* node = &nodes[i];
u16 type = be16((u8*)&node->type); u16 type = be16((u8*)&node->type);
u16 name_offset = be16((u8*)&node->name_offset); u16 name_offset = be16((u8*)&node->name_offset);
u32 my_data_offset = be32((u8*)&node->data_offset); u32 my_data_offset = be32((u8*)&node->data_offset);
u32 size = be32((u8*)&node->size); u32 size = be32((u8*)&node->size);
char* name = (char*) &string_table[name_offset]; char* name = (char*) &string_table[name_offset];
u8* file_data; u8* file_data;
if (type == 0x0100) { if (type == 0x0100) {
// Directory // Directory
mkdir(name, 0777); mkdir(name, 0777);
chdir(name); chdir(name);
dir_stack[++dir_index] = size; dir_stack[++dir_index] = size;
//printf("%*s%s/\n", dir_index, "", name); //printf("%*s%s/\n", dir_index, "", name);
} else { } else {
// Normal file // Normal file
u8 padding[32]; u8 padding[32];
if (type != 0x0000) { if (type != 0x0000) {
free(string_table); free(string_table);
return -2; return -2;
} }
if (current_offset < my_data_offset) { if (current_offset < my_data_offset) {
int diff = my_data_offset - current_offset; int diff = my_data_offset - current_offset;
if (diff > 32) { if (diff > 32) {
free(string_table); free(string_table);
return -3; return -3;
}
fread(padding, 1, diff, fp);
current_offset += diff;
}
file_data = malloc(size);
fread(file_data, 1, size, fp);
//printf("%*s %s (%d bytes", dir_index, "", name, size);
int result;
result = write_imd5_lz77(file_data, size, name);
if (result < 0) {
free(string_table);
return result;
}
//printf(")\n");
current_offset += size;
} }
fread(padding, 1, diff, fp);
current_offset += diff;
}
while (dir_stack[dir_index] == i+2 && dir_index > 0) { file_data = malloc(size);
chdir(".."); fread(file_data, 1, size, fp);
dir_index--; //printf("%*s %s (%d bytes", dir_index, "", name, size);
} int result;
} result = write_imd5_lz77(file_data, size, name);
free(string_table); if(result < 0)
return 0; {free(string_table);
} return result;
}
static void do_imet_header(FILE *fp) { //printf(")\n");
imet_data_t header; current_offset += size;
fread(&header, 1, sizeof header, fp);
write_file(&header, sizeof(header), "header.imet");
}
void do_U8_archivebanner(FILE *fp) {
U8_archive_header header;
U8_node root_node;
u32 tag;
u32 num_nodes;
U8_node* nodes;
u8* string_table;
size_t rest_size;
unsigned int i;
u32 data_offset;
u16 dir_stack[16];
int dir_index = 0;
fread(&header, 1, sizeof header, fp);
tag = be32((u8*) &header.tag);
if (tag != 0x55AA382D) {
//printf("No U8 tag");
exit(0);
} }
fread(&root_node, 1, sizeof(root_node), fp); while (dir_stack[dir_index] == i+2 && dir_index > 0) {
num_nodes = be32((u8*) &root_node.size) - 1; chdir("..");
printf("Number of files: %d\n", num_nodes); dir_index--;
nodes = malloc(sizeof(U8_node) * (num_nodes));
fread(nodes, 1, num_nodes * sizeof(U8_node), fp);
data_offset = be32((u8*) &header.data_offset);
rest_size = data_offset - sizeof(header) - (num_nodes+1)*sizeof(U8_node);
string_table = malloc(rest_size);
fread(string_table, 1, rest_size, fp);
for (i = 0; i < num_nodes; i++) {
U8_node* node = &nodes[i];
u16 type = be16((u8*)&node->type);
u16 name_offset = be16((u8*)&node->name_offset);
u32 my_data_offset = be32((u8*)&node->data_offset);
u32 size = be32((u8*)&node->size);
char* name = (char*) &string_table[name_offset];
u8* file_data;
if (type == 0x0100) {
// Directory
mkdir(name, 0777);
chdir(name);
dir_stack[++dir_index] = size;
//printf("%*s%s/\n", dir_index, "", name);
} else {
// Normal file
if (type != 0x0000) {
printf("Unknown type");
exit(0);
}
fseek(fp, my_data_offset, SEEK_SET);
file_data = malloc(size);
fread(file_data, 1, size, fp);
write_file(file_data, size, name);
free(file_data);
//printf("%*s %s (%d bytes)\n", dir_index, "", name, size);
}
while (dir_stack[dir_index] == i+2 && dir_index > 0) {
chdir("..");
dir_index--;
}
} }
free(string_table); }
free(string_table);
return 0;
} }
int extractbnrfile(const char * filepath, const char * destpath) { static void do_imet_header(FILE *fp)
{
imet_data_t header;
fread(&header, 1, sizeof header, fp);
write_file(&header, sizeof(header), "header.imet");
}
void do_U8_archivebanner(FILE *fp)
{
U8_archive_header header;
U8_node root_node;
u32 tag;
u32 num_nodes;
U8_node* nodes;
u8* string_table;
size_t rest_size;
unsigned int i;
u32 data_offset;
u16 dir_stack[16];
int dir_index = 0;
fread(&header, 1, sizeof header, fp);
tag = be32((u8*) &header.tag);
if (tag != 0x55AA382D) {
//printf("No U8 tag");
exit(0);
}
fread(&root_node, 1, sizeof(root_node), fp);
num_nodes = be32((u8*) &root_node.size) - 1;
printf("Number of files: %d\n", num_nodes);
nodes = malloc(sizeof(U8_node) * (num_nodes));
fread(nodes, 1, num_nodes * sizeof(U8_node), fp);
data_offset = be32((u8*) &header.data_offset);
rest_size = data_offset - sizeof(header) - (num_nodes+1)*sizeof(U8_node);
string_table = malloc(rest_size);
fread(string_table, 1, rest_size, fp);
for (i = 0; i < num_nodes; i++) {
U8_node* node = &nodes[i];
u16 type = be16((u8*)&node->type);
u16 name_offset = be16((u8*)&node->name_offset);
u32 my_data_offset = be32((u8*)&node->data_offset);
u32 size = be32((u8*)&node->size);
char* name = (char*) &string_table[name_offset];
u8* file_data;
if (type == 0x0100) {
// Directory
mkdir(name, 0777);
chdir(name);
dir_stack[++dir_index] = size;
//printf("%*s%s/\n", dir_index, "", name);
} else {
// Normal file
if (type != 0x0000) {
printf("Unknown type");
exit(0);
}
fseek(fp, my_data_offset, SEEK_SET);
file_data = malloc(size);
fread(file_data, 1, size, fp);
write_file(file_data, size, name);
free(file_data);
//printf("%*s %s (%d bytes)\n", dir_index, "", name, size);
}
while (dir_stack[dir_index] == i+2 && dir_index > 0) {
chdir("..");
dir_index--;
}
}
free(string_table);
}
int extractbnrfile(const char * filepath, const char * destpath)
{
int ret = -1; int ret = -1;
FILE *fp = fopen(filepath, "rb"); FILE *fp = fopen(filepath, "rb");
if (fp) { if(fp)
subfoldercreate(destpath); {
chdir(destpath); subfoldercreate(destpath);
chdir(destpath);
do_imet_header(fp); do_imet_header(fp);
ret = do_U8_archive(fp); ret = do_U8_archive(fp);
fclose(fp); fclose(fp);
} }
return ret; return ret;
} }
int unpackBin(const char * filename,const char * outdir) { int unpackBin(const char * filename,const char * outdir)
FILE *fp = fopen(filename,"rb");; {
if (fp) { FILE *fp = fopen(filename,"rb");;
subfoldercreate(outdir); if(fp)
chdir(outdir); {
subfoldercreate(outdir);
chdir(outdir);
do_U8_archivebanner(fp); do_U8_archivebanner(fp);
fclose(fp); fclose(fp);
return 1; return 1;
} }
return 0; return 0;
} }
#define TMP_PATH(s) "BANNER:/dump"s #define TMP_PATH(s) "BANNER:/dump"s
//#define TMP_PATH(s) "SD:/dump"s //#define TMP_PATH(s) "SD:/dump"s
int unpackBanner(const u8 *gameid, int what, const char *outdir) { int unpackBanner(const u8 *gameid, int what, const char *outdir)
{
char path[256]; char path[256];
if (!ramdiskMount("BANNER", NULL)) return -1; if(!ramdiskMount("BANNER", NULL)) return -1;
subfoldercreate(TMP_PATH("/")); subfoldercreate(TMP_PATH("/"));
s32 ret = dump_banner(gameid, TMP_PATH("/opening.bnr")); s32 ret = dump_banner(gameid, TMP_PATH("/opening.bnr"));
if (ret != 1) { if (ret != 1)
ret = -1; {
goto error2; ret = -1;
} goto error2;
}
ret = extractbnrfile(TMP_PATH("/opening.bnr"), TMP_PATH("/")); ret = extractbnrfile(TMP_PATH("/opening.bnr"), TMP_PATH("/"));
if (ret != 0) { if (ret != 0)
ret = -1; {
goto error2; ret = -1;
} goto error2;
}
if (what & UNPACK_BANNER_BIN) { if(what & UNPACK_BANNER_BIN)
snprintf(path, sizeof(path),"%sbanner/", outdir); {
ret = unpackBin(TMP_PATH("/meta/banner.bin"), path); snprintf(path, sizeof(path),"%sbanner/", outdir);
if (ret != 1) { ret = unpackBin(TMP_PATH("/meta/banner.bin"), path);
ret = -1; if (ret != 1)
goto error2; {
} ret = -1;
} goto error2;
if (what & UNPACK_ICON_BIN) { }
snprintf(path, sizeof(path),"%sicon/", outdir); }
ret = unpackBin(TMP_PATH("/meta/icon.bin"), path); if(what & UNPACK_ICON_BIN)
if (ret != 1) { {
ret = -1; snprintf(path, sizeof(path),"%sicon/", outdir);
goto error2; ret = unpackBin(TMP_PATH("/meta/icon.bin"), path);
} if (ret != 1)
} {
if (what & UNPACK_SOUND_BIN) { ret = -1;
snprintf(path, sizeof(path),"%ssound.bin", outdir); goto error2;
FILE *fp = fopen(TMP_PATH("/meta/sound.bin"), "rb"); }
if (fp) { }
size_t size; if(what & UNPACK_SOUND_BIN)
u8 *data; {
fseek(fp, 0, SEEK_END); snprintf(path, sizeof(path),"%ssound.bin", outdir);
size = ftell(fp); FILE *fp = fopen(TMP_PATH("/meta/sound.bin"), "rb");
if (!size) { if(fp)
ret = -1; {
goto error; size_t size;
} u8 *data;
fseek(fp, 0, SEEK_SET); fseek(fp, 0, SEEK_END);
data = (u8 *)malloc(size); size = ftell(fp);
if (!data) { if(!size)
ret = -1; {
goto error; ret = -1;
} goto error;
if (fread(data, 1, size, fp) != size) { }
ret = -1; fseek(fp, 0, SEEK_SET);
goto error; data = (u8 *)malloc(size);
} if(!data)
ret = write_file(data, size, path); {
} ret = -1;
error: goto error;
fclose(fp); }
} if(fread(data, 1, size, fp) != size)
ramdiskUnmount("BANNER"); {
ret = -1;
goto error;
}
ret = write_file(data, size, path);
}
error: fclose(fp);
}
ramdiskUnmount("BANNER");
error2: error2:
if (ret < 0) if(ret < 0)
return ret; return ret;
return 1; return 1;
} }

View File

@ -9,35 +9,36 @@
#define _OPENINGBNR_H_ #define _OPENINGBNR_H_
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
/*********************************************************** /***********************************************************
* Error description: * Error description:
* 0 Successfully extracted * 0 Successfully extracted
* -1 No U8 tag * -1 No U8 tag
* -2 Unknown type * -2 Unknown type
* -3 Archive inconsistency, too much padding * -3 Archive inconsistency, too much padding
* -4 No IMD5 tag * -4 No IMD5 tag
* -5 MD5 mismatch * -5 MD5 mismatch
* -6 Size mismatch * -6 Size mismatch
* -7 Inconsistency in LZ77 encoding * -7 Inconsistency in LZ77 encoding
************************************************************/ ************************************************************/
//! Extract opening.bnr from filepath to destpath //! Extract opening.bnr from filepath to destpath
//! Files extracted: banner.bin icon.bin and sound.bin //! Files extracted: banner.bin icon.bin and sound.bin
int extractbnrfile(const char * filepath, const char * destpath); int extractbnrfile(const char * filepath, const char * destpath);
int unpackBin(const char * filename,const char * outdir); int unpackBin(const char * filename,const char * outdir);
#define UNPACK_BANNER_BIN 1 /* extract banner.bin to outdir/banner/ */ #define UNPACK_BANNER_BIN 1 /* extract banner.bin to outdir/banner/ */
#define UNPACK_ICON_BIN 2 /* extract icon.bin to outdir/icon/ */ #define UNPACK_ICON_BIN 2 /* extract icon.bin to outdir/icon/ */
#define UNPACK_SOUND_BIN 4 /* copies sound.bin to outdir/sound.bin */ #define UNPACK_SOUND_BIN 4 /* copies sound.bin to outdir/sound.bin */
#define UNPACK_ALL (UNPACK_SOUND_BIN | UNPACK_ICON_BIN | UNPACK_BANNER_BIN) #define UNPACK_ALL (UNPACK_SOUND_BIN | UNPACK_ICON_BIN | UNPACK_BANNER_BIN)
int unpackBanner(const u8 * gameid, int what, const char *outdir); int unpackBanner(const u8 * gameid, int what, const char *outdir);
//! Extract the lz77 compressed banner, icon and sound .bin //! Extract the lz77 compressed banner, icon and sound .bin
u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size); u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size);
u16 be16(const u8 *p); u16 be16(const u8 *p);
u32 be32(const u8 *p); u32 be32(const u8 *p);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -11,177 +11,199 @@
#include "bannersound.h" #include "bannersound.h"
struct IMD5Header { struct IMD5Header
u32 fcc; {
u32 filesize; u32 fcc;
u8 zeroes[8]; u32 filesize;
u8 crypto[16]; u8 zeroes[8];
u8 crypto[16];
} __attribute__((packed)); } __attribute__((packed));
struct IMETHeader { struct IMETHeader
u8 zeroes[64]; {
u32 fcc; u8 zeroes[64];
u8 unk[8]; u32 fcc;
u32 iconSize; u8 unk[8];
u32 bannerSize; u32 iconSize;
u32 soundSize; u32 bannerSize;
u32 flag1; u32 soundSize;
u8 names[7][84]; u32 flag1;
u8 zeroes_2[0x348]; u8 names[7][84];
u8 crypto[16]; u8 zeroes_2[0x348];
u8 crypto[16];
} __attribute__((packed)); } __attribute__((packed));
struct U8Header { struct U8Header
u32 fcc; {
u32 rootNodeOffset; u32 fcc;
u32 headerSize; u32 rootNodeOffset;
u32 dataOffset; u32 headerSize;
u8 zeroes[16]; u32 dataOffset;
u8 zeroes[16];
} __attribute__((packed)); } __attribute__((packed));
struct U8Entry { struct U8Entry
struct { {
u32 fileType : struct
8; {
u32 nameOffset : u32 fileType : 8;
24; u32 nameOffset : 24;
}; };
u32 fileOffset; u32 fileOffset;
union { union
u32 fileLength; {
u32 numEntries; u32 fileLength;
}; u32 numEntries;
};
} __attribute__((packed)); } __attribute__((packed));
struct LZ77Info { struct LZ77Info
u16 length : {
4; u16 length : 4;
u16 offset : u16 offset : 12;
12;
} __attribute__((packed)); } __attribute__((packed));
static char *u8Filename(const U8Entry *fst, int i) { static char *u8Filename(const U8Entry *fst, int i)
return (char *)(fst + fst[0].numEntries) + fst[i].nameOffset; {
return (char *)(fst + fst[0].numEntries) + fst[i].nameOffset;
} }
inline u32 le32(u32 i) { inline u32 le32(u32 i)
return ((i & 0xFF) << 24) | ((i & 0xFF00) << 8) | ((i & 0xFF0000) >> 8) | ((i & 0xFF000000) >> 24); {
return ((i & 0xFF) << 24) | ((i & 0xFF00) << 8) | ((i & 0xFF0000) >> 8) | ((i & 0xFF000000) >> 24);
} }
inline u16 le16(u16 i) { inline u16 le16(u16 i)
return ((i & 0xFF) << 8) | ((i & 0xFF00) >> 8); {
return ((i & 0xFF) << 8) | ((i & 0xFF00) >> 8);
} }
static u8 *uncompressLZ77(const u8 *inBuf, u32 inLength, u32 &size) { static u8 *uncompressLZ77(const u8 *inBuf, u32 inLength, u32 &size)
u8 *buffer = NULL; {
if (inLength <= 0x8 || *((const u32 *)inBuf) != 0x4C5A3737 /*"LZ77"*/ || inBuf[4] != 0x10) u8 *buffer = NULL;
return NULL; if (inLength <= 0x8 || *((const u32 *)inBuf) != 0x4C5A3737 /*"LZ77"*/ || inBuf[4] != 0x10)
u32 uncSize = le32(((const u32 *)inBuf)[1] << 8); return NULL;
u32 uncSize = le32(((const u32 *)inBuf)[1] << 8);
const u8 *inBufEnd = inBuf + inLength; const u8 *inBufEnd = inBuf + inLength;
inBuf += 8; inBuf += 8;
buffer = new(std::nothrow) u8[uncSize]; buffer = new(std::nothrow) u8[uncSize];
if (!buffer) if (!buffer)
return buffer; return buffer;
u8 *bufCur = buffer; u8 *bufCur = buffer;
u8 *bufEnd = buffer + uncSize; u8 *bufEnd = buffer + uncSize;
while (bufCur < bufEnd && inBuf < inBufEnd) { while (bufCur < bufEnd && inBuf < inBufEnd)
u8 flags = *inBuf; {
++inBuf; u8 flags = *inBuf;
for (int i = 0; i < 8 && bufCur < bufEnd && inBuf < inBufEnd; ++i) { ++inBuf;
if ((flags & 0x80) != 0) { for (int i = 0; i < 8 && bufCur < bufEnd && inBuf < inBufEnd; ++i)
const LZ77Info &info = *(const LZ77Info *)inBuf; {
inBuf += sizeof (LZ77Info); if ((flags & 0x80) != 0)
int length = info.length + 3; {
if (bufCur - info.offset - 1 < buffer || bufCur + length > bufEnd) const LZ77Info &info = *(const LZ77Info *)inBuf;
return buffer; inBuf += sizeof (LZ77Info);
memcpy(bufCur, bufCur - info.offset - 1, length); int length = info.length + 3;
bufCur += length; if (bufCur - info.offset - 1 < buffer || bufCur + length > bufEnd)
} else { return buffer;
*bufCur = *inBuf; memcpy(bufCur, bufCur - info.offset - 1, length);
++inBuf; bufCur += length;
++bufCur; }
} else
flags <<= 1; {
} *bufCur = *inBuf;
} ++inBuf;
size = uncSize; ++bufCur;
return buffer; }
flags <<= 1;
}
}
size = uncSize;
return buffer;
} }
const u8 *LoadBannerSound(const u8 *discid, u32 *size) { const u8 *LoadBannerSound(const u8 *discid, u32 *size)
if (!discid) {
if(!discid)
return NULL; return NULL;
Disc_SetUSB(NULL); Disc_SetUSB(NULL);
wbfs_disc_t *disc = WBFS_OpenDisc((u8 *) discid); wbfs_disc_t *disc = WBFS_OpenDisc((u8 *) discid);
if (!disc) { if(!disc)
// WindowPrompt(tr("Can't find disc"), 0, tr("OK")); {
// WindowPrompt(tr("Can't find disc"), 0, tr("OK"));
return NULL; return NULL;
} }
wiidisc_t *wdisc = wd_open_disc((int (*)(void *, u32, u32, void *))wbfs_disc_read, disc); wiidisc_t *wdisc = wd_open_disc((int (*)(void *, u32, u32, void *))wbfs_disc_read, disc);
if (!wdisc) { if(!wdisc)
//WindowPrompt(tr("Could not open Disc"), 0, tr("OK")); {
//WindowPrompt(tr("Could not open Disc"), 0, tr("OK"));
return NULL; return NULL;
} }
u8 * opening_bnr = wd_extract_file(wdisc, ALL_PARTITIONS, (char *) "opening.bnr"); u8 * opening_bnr = wd_extract_file(wdisc, ALL_PARTITIONS, (char *) "opening.bnr");
if (!opening_bnr) { if(!opening_bnr)
//WindowPrompt(tr("ERROR"), tr("Failed to extract opening.bnr"), tr("OK")); {
//WindowPrompt(tr("ERROR"), tr("Failed to extract opening.bnr"), tr("OK"));
return NULL; return NULL;
} }
wd_close_disc(wdisc); wd_close_disc(wdisc);
WBFS_CloseDisc(disc); WBFS_CloseDisc(disc);
const U8Entry *fst; const U8Entry *fst;
const IMETHeader *imetHdr = (IMETHeader *)opening_bnr; const IMETHeader *imetHdr = (IMETHeader *)opening_bnr;
if ( imetHdr->fcc != 0x494D4554 /*"IMET"*/ ) { if ( imetHdr->fcc != 0x494D4554 /*"IMET"*/ )
// WindowPrompt(tr("IMET Header wrong."), 0, tr("OK")); {
free(opening_bnr); // WindowPrompt(tr("IMET Header wrong."), 0, tr("OK"));
free(opening_bnr);
return NULL; return NULL;
} }
const U8Header *bnrArcHdr = (U8Header *)(imetHdr + 1); const U8Header *bnrArcHdr = (U8Header *)(imetHdr + 1);
fst = (const U8Entry *)( ((const u8 *)bnrArcHdr) + bnrArcHdr->rootNodeOffset); fst = (const U8Entry *)( ((const u8 *)bnrArcHdr) + bnrArcHdr->rootNodeOffset);
u32 i; u32 i;
for (i = 1; i < fst[0].numEntries; ++i) for (i = 1; i < fst[0].numEntries; ++i)
if (fst[i].fileType == 0 && strcasecmp(u8Filename(fst, i), "sound.bin") == 0) if (fst[i].fileType == 0 && strcasecmp(u8Filename(fst, i), "sound.bin") == 0)
break; break;
if (i >= fst[0].numEntries) { if (i >= fst[0].numEntries)
/* Not all games have a sound.bin and this message is annoying **/ {
//WindowPrompt(tr("sound.bin not found."), 0, tr("OK")); /* Not all games have a sound.bin and this message is annoying **/
free(opening_bnr); //WindowPrompt(tr("sound.bin not found."), 0, tr("OK"));
free(opening_bnr);
return NULL; return NULL;
} }
const u8 *sound_bin = ((const u8 *)bnrArcHdr) + fst[i].fileOffset; const u8 *sound_bin = ((const u8 *)bnrArcHdr) + fst[i].fileOffset;
if ( ((IMD5Header *)sound_bin)->fcc != 0x494D4435 /*"IMD5"*/ ) { if ( ((IMD5Header *)sound_bin)->fcc != 0x494D4435 /*"IMD5"*/ )
// WindowPrompt(tr("IMD5 Header not right."), 0, tr("OK")); {
free(opening_bnr); // WindowPrompt(tr("IMD5 Header not right."), 0, tr("OK"));
free(opening_bnr);
return NULL; return NULL;
} }
const u8 *soundChunk = sound_bin + sizeof (IMD5Header);; const u8 *soundChunk = sound_bin + sizeof (IMD5Header);;
u32 soundChunkSize = fst[i].fileLength - sizeof (IMD5Header); u32 soundChunkSize = fst[i].fileLength - sizeof (IMD5Header);
if ( *((u32*)soundChunk) == 0x4C5A3737 /*"LZ77"*/ ) { if ( *((u32*)soundChunk) == 0x4C5A3737 /*"LZ77"*/ )
u32 uncSize = NULL; {
u8 * uncompressed_data = uncompressLZ77(soundChunk, soundChunkSize, uncSize); u32 uncSize = NULL;
if (!uncompressed_data) { u8 * uncompressed_data = uncompressLZ77(soundChunk, soundChunkSize, uncSize);
// WindowPrompt(tr("Can't decompress LZ77"), 0, tr("OK")); if (!uncompressed_data)
free(opening_bnr); {
return NULL; // WindowPrompt(tr("Can't decompress LZ77"), 0, tr("OK"));
} free(opening_bnr);
if (size) *size=uncSize; return NULL;
free(opening_bnr); }
return uncompressed_data; if(size) *size=uncSize;
} free(opening_bnr);
u8 *out = new(std::nothrow) u8[soundChunkSize]; return uncompressed_data;
if (out) { }
memcpy(out, soundChunk, soundChunkSize); u8 *out = new(std::nothrow) u8[soundChunkSize];
if (size) *size=soundChunkSize; if(out)
} {
free(opening_bnr); memcpy(out, soundChunk, soundChunkSize);
return out; if(size) *size=soundChunkSize;
}
free(opening_bnr);
return out;
} }

View File

@ -24,140 +24,142 @@ extern GuiWindow * mainWindow;
* CheatMenu * CheatMenu
***************************************************************************/ ***************************************************************************/
int CheatMenu(const char * gameID) { int CheatMenu(const char * gameID) {
int choice = 0; int choice = 0;
bool exit = false; bool exit = false;
int ret = 1; int ret = 1;
// because destroy GuiSound must wait while sound playing is finished, we use a global sound // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if (!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); // GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
GuiImageData btnOutline(imgPath, button_dialogue_box_png); GuiImageData btnOutline(imgPath, button_dialogue_box_png);
snprintf(imgPath, sizeof(imgPath), "%ssettings_background.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%ssettings_background.png", CFG.theme_path);
GuiImageData settingsbg(imgPath, settings_background_png); GuiImageData settingsbg(imgPath, settings_background_png);
GuiImage settingsbackground(&settingsbg); GuiImage settingsbackground(&settingsbg);
GuiTrigger trigA; GuiTrigger trigA;
trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
GuiTrigger trigB; GuiTrigger trigB;
trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B); trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B);
GuiText backBtnTxt(tr("Back") , 22, THEME.prompttext); GuiText backBtnTxt(tr("Back") , 22, THEME.prompttext);
backBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30); backBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30);
GuiImage backBtnImg(&btnOutline); GuiImage backBtnImg(&btnOutline);
GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -140, 400, &trigA, NULL, btnClick2,1); GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -140, 400, &trigA, NULL, btnClick2,1);
backBtn.SetLabel(&backBtnTxt); backBtn.SetLabel(&backBtnTxt);
backBtn.SetTrigger(&trigB); backBtn.SetTrigger(&trigB);
GuiText createBtnTxt(tr("Create") , 22, THEME.prompttext); GuiText createBtnTxt(tr("Create") , 22, THEME.prompttext);
createBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30); createBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30);
GuiImage createBtnImg(&btnOutline); GuiImage createBtnImg(&btnOutline);
GuiButton createBtn(&createBtnImg,&createBtnImg, 2, 3, 160, 400, &trigA, NULL, btnClick2,1); GuiButton createBtn(&createBtnImg,&createBtnImg, 2, 3, 160, 400, &trigA, NULL, btnClick2,1);
createBtn.SetLabel(&createBtnTxt); createBtn.SetLabel(&createBtnTxt);
char txtfilename[55]; char txtfilename[55];
snprintf(txtfilename,sizeof(txtfilename),"%s%s.txt",Settings.TxtCheatcodespath,gameID); snprintf(txtfilename,sizeof(txtfilename),"%s%s.txt",Settings.TxtCheatcodespath,gameID);
GCTCheats c; GCTCheats c;
int check = c.openTxtfile(txtfilename); int check = c.openTxtfile(txtfilename);
int download =0; int download =0;
switch (check) { switch (check) {
case -1: case -1:
WindowPrompt(tr("Error"),tr("Cheatfile is blank"),tr("OK")); WindowPrompt(tr("Error"),tr("Cheatfile is blank"),tr("OK"));
break; break;
case 0: case 0:
download = WindowPrompt(tr("Error"),tr("No Cheatfile found"),tr("Download Now"),tr("Cancel")); download = WindowPrompt(tr("Error"),tr("No Cheatfile found"),tr("Download Now"),tr("Cancel"));
if (download==1) { if (download==1)
download = CodeDownload(gameID); {
if (download < 0 || c.openTxtfile(txtfilename) != 1) download = CodeDownload(gameID);
break; if(download < 0 || c.openTxtfile(txtfilename) != 1)
} else break;
break; }
case 1: else
int cntcheats = c.getCnt(); break;
customOptionList cheatslst(cntcheats); case 1:
GuiCustomOptionBrowser chtBrowser(400, 280, &cheatslst, CFG.theme_path, "bg_options_settings.png", bg_options_settings_png, 1, 90); int cntcheats = c.getCnt();
chtBrowser.SetPosition(0, 90); customOptionList cheatslst(cntcheats);
chtBrowser.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); GuiCustomOptionBrowser chtBrowser(400, 280, &cheatslst, CFG.theme_path, "bg_options_settings.png", bg_options_settings_png, 1, 90);
chtBrowser.SetClickable(true); chtBrowser.SetPosition(0, 90);
chtBrowser.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
chtBrowser.SetClickable(true);
GuiText titleTxt(c.getGameName().c_str(), 28, (GXColor) {0, 0, 0, 255}); GuiText titleTxt(c.getGameName().c_str(), 28, (GXColor) {0, 0, 0, 255});
titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
titleTxt.SetMaxWidth(350, GuiText::SCROLL); titleTxt.SetMaxWidth(350, GuiText::SCROLL);
titleTxt.SetPosition(12,40); titleTxt.SetPosition(12,40);
for (int i = 0; i <= cntcheats; i++) { for (int i = 0; i <= cntcheats; i++) {
cheatslst.SetValue(i, "%s",c.getCheatName(i).c_str()); cheatslst.SetValue(i, "%s",c.getCheatName(i).c_str());
cheatslst.SetName(i, "OFF"); cheatslst.SetName(i, "OFF");
} }
HaltGui(); HaltGui();
GuiWindow w(screenwidth, screenheight); GuiWindow w(screenwidth, screenheight);
w.Append(&settingsbackground); w.Append(&settingsbackground);
w.Append(&titleTxt); w.Append(&titleTxt);
w.Append(&backBtn); w.Append(&backBtn);
w.Append(&createBtn); w.Append(&createBtn);
w.Append(&chtBrowser); w.Append(&chtBrowser);
mainWindow->SetState(STATE_DISABLED); mainWindow->SetState(STATE_DISABLED);
mainWindow->ChangeFocus(&w); mainWindow->ChangeFocus(&w);
mainWindow->Append(&w); mainWindow->Append(&w);
ResumeGui(); ResumeGui();
while (!exit) { while (!exit) {
VIDEO_WaitVSync (); VIDEO_WaitVSync ();
ret = chtBrowser.GetClickedOption(); ret = chtBrowser.GetClickedOption();
if (ret != -1) { if (ret != -1) {
const char *strCheck = cheatslst.GetName(ret); const char *strCheck = cheatslst.GetName(ret);
if (strncmp(strCheck,"ON",2) == 0) { if (strncmp(strCheck,"ON",2) == 0) {
cheatslst.SetName(ret,"%s","OFF"); cheatslst.SetName(ret,"%s","OFF");
} else if (strncmp(strCheck,"OFF",3) == 0) { } else if (strncmp(strCheck,"OFF",3) == 0) {
cheatslst.SetName(ret,"%s","ON"); cheatslst.SetName(ret,"%s","ON");
} }
} }
if (createBtn.GetState() == STATE_CLICKED) { if (createBtn.GetState() == STATE_CLICKED) {
createBtn.ResetState(); createBtn.ResetState();
if (cntcheats > 0) { if (cntcheats > 0) {
int selectednrs[30]; int selectednrs[30];
int x = 0; int x = 0;
for (int i = 0; i <= cntcheats; i++) { for (int i = 0; i <= cntcheats; i++) {
const char *strCheck = cheatslst.GetName(i); const char *strCheck = cheatslst.GetName(i);
if (strncmp(strCheck,"ON",2) == 0) { if (strncmp(strCheck,"ON",2) == 0) {
selectednrs[x] = i; selectednrs[x] = i;
x++; x++;
} }
} }
if (x == 0) { if (x == 0) {
WindowPrompt(tr("Error"),tr("No cheats were selected"),tr("OK")); WindowPrompt(tr("Error"),tr("No cheats were selected"),tr("OK"));
} else { } else {
subfoldercreate(Settings.Cheatcodespath); subfoldercreate(Settings.Cheatcodespath);
string chtpath = Settings.Cheatcodespath; string chtpath = Settings.Cheatcodespath;
string gctfname = chtpath + c.getGameID() + ".gct"; string gctfname = chtpath + c.getGameID() + ".gct";
c.createGCT(selectednrs,x,gctfname.c_str()); c.createGCT(selectednrs,x,gctfname.c_str());
WindowPrompt(tr("GCT File created"),NULL,tr("OK")); WindowPrompt(tr("GCT File created"),NULL,tr("OK"));
exit = true; exit = true;
break; break;
} }
} else WindowPrompt(tr("Error"),tr("Could not create GCT file"),tr("OK")); } else WindowPrompt(tr("Error"),tr("Could not create GCT file"),tr("OK"));
} }
if (backBtn.GetState() == STATE_CLICKED) { if (backBtn.GetState() == STATE_CLICKED) {
backBtn.ResetState(); backBtn.ResetState();
exit = true; exit = true;
break; break;
} }
} }
HaltGui(); HaltGui();
mainWindow->SetState(STATE_DEFAULT); mainWindow->SetState(STATE_DEFAULT);
mainWindow->Remove(&w); mainWindow->Remove(&w);
ResumeGui(); ResumeGui();
break; break;
} }
return choice; return choice;
} }

View File

@ -63,8 +63,8 @@ string GCTCheats::getCheatComment(int nr) {
int GCTCheats::createGCT(int nr,const char * filename) { int GCTCheats::createGCT(int nr,const char * filename) {
if (nr == 0) if (nr == 0)
return 0; return 0;
ofstream filestr; ofstream filestr;
filestr.open(filename); filestr.open(filename);
@ -132,8 +132,8 @@ int GCTCheats::createGCT(const char * chtbuffer,const char * filename) {
int GCTCheats::createGCT(int nr[],int cnt,const char * filename) { int GCTCheats::createGCT(int nr[],int cnt,const char * filename) {
if (cnt == 0) if (cnt == 0)
return 0; return 0;
ofstream filestr; ofstream filestr;
filestr.open(filename); filestr.open(filename);
@ -185,29 +185,29 @@ int GCTCheats::openTxtfile(const char * filename) {
filestr.seekg(0,ios_base::beg); filestr.seekg(0,ios_base::beg);
getline(filestr,sGameID); getline(filestr,sGameID);
if (sGameID[sGameID.length() - 1] == '\r') if (sGameID[sGameID.length() - 1] == '\r')
sGameID.erase(sGameID.length() - 1); sGameID.erase(sGameID.length() - 1);
getline(filestr,sGameTitle); getline(filestr,sGameTitle);
if (sGameTitle[sGameTitle.length() - 1] == '\r') if (sGameTitle[sGameTitle.length() - 1] == '\r')
sGameTitle.erase(sGameTitle.length() - 1); sGameTitle.erase(sGameTitle.length() - 1);
getline(filestr,sCheatName[i]); // skip first line if file uses CRLF getline(filestr,sCheatName[i]); // skip first line if file uses CRLF
if (!sGameTitle[sGameTitle.length() - 1] == '\r') if (!sGameTitle[sGameTitle.length() - 1] == '\r')
filestr.seekg(0,ios_base::beg); filestr.seekg(0,ios_base::beg);
while (!filestr.eof()) { while (!filestr.eof()) {
getline(filestr,sCheatName[i]); // '\n' delimiter by default getline(filestr,sCheatName[i]); // '\n' delimiter by default
if (sCheatName[i][sCheatName[i].length() - 1] == '\r') if (sCheatName[i][sCheatName[i].length() - 1] == '\r')
sCheatName[i].erase(sCheatName[i].length() - 1); sCheatName[i].erase(sCheatName[i].length() - 1);
string cheatdata; string cheatdata;
bool emptyline = false; bool emptyline = false;
do { do {
getline(filestr,str); getline(filestr,str);
if (str[str.length() - 1] == '\r') if (str[str.length() - 1] == '\r')
str.erase(str.length() - 1); str.erase(str.length() - 1);
if (str == "" || str[0] == '\r' || str[0] == '\n') { if (str == "" || str[0] == '\r' || str[0] == '\n') {
emptyline = true; emptyline = true;
@ -215,24 +215,24 @@ int GCTCheats::openTxtfile(const char * filename) {
} }
if (IsCode(str)) { if (IsCode(str)) {
// remove any garbage (comment) after code // remove any garbage (comment) after code
while (str.size() > 17) { while (str.size() > 17) {
str.erase(str.length() - 1); str.erase(str.length() - 1);
} }
cheatdata.append(str); cheatdata.append(str);
size_t found=cheatdata.find(' '); size_t found=cheatdata.find(' ');
cheatdata.replace(found,1,""); cheatdata.replace(found,1,"");
} else { } else {
//printf("%i",str.size()); //printf("%i",str.size());
sCheatComment[i] = str; sCheatComment[i] = str;
} }
if (filestr.eof()) break; if (filestr.eof()) break;
} while (!emptyline); } while (!emptyline);
sCheats[i] = cheatdata; sCheats[i] = cheatdata;
i++; i++;
if (i == MAXCHEATS) break; if (i == MAXCHEATS) break;
} }
iCntCheats = i; iCntCheats = i;
filestr.close(); filestr.close();
@ -240,15 +240,15 @@ int GCTCheats::openTxtfile(const char * filename) {
} }
bool GCTCheats::IsCode(const std::string& str) { bool GCTCheats::IsCode(const std::string& str) {
if (str[8] == ' ' && str.size() >= 17) { if (str[8] == ' ' && str.size() >= 17) {
// accept strings longer than 17 in case there is a comment on the same line as the code // accept strings longer than 17 in case there is a comment on the same line as the code
char part1[9]; char part1[9];
char part2[9]; char part2[9];
snprintf(part1,sizeof(part1),"%c%c%c%c%c%c%c%c",str[0],str[1],str[2],str[3],str[4],str[5],str[6],str[7]); snprintf(part1,sizeof(part1),"%c%c%c%c%c%c%c%c",str[0],str[1],str[2],str[3],str[4],str[5],str[6],str[7]);
snprintf(part1,sizeof(part2),"%c%c%c%c%c%c%c%c",str[9],str[10],str[11],str[12],str[13],str[14],str[15],str[16]); snprintf(part1,sizeof(part2),"%c%c%c%c%c%c%c%c",str[9],str[10],str[11],str[12],str[13],str[14],str[15],str[16]);
if ((strtok(part1,"0123456789ABCDEFabcdef") == NULL) && (strtok(part2,"0123456789ABCDEFabcdef") == NULL)) { if ((strtok(part1,"0123456789ABCDEFabcdef") == NULL) && (strtok(part2,"0123456789ABCDEFabcdef") == NULL)) {
return true; return true;
} }
} }
return false; return false;
} }

View File

@ -66,9 +66,9 @@ public:
//!Gets Cheat Comment //!Gets Cheat Comment
//!\return Cheat Comment //!\return Cheat Comment
string getCheatComment(int nr); string getCheatComment(int nr);
//!Check if string is a code //!Check if string is a code
//!\return true/false //!\return true/false
bool IsCode(const std::string& s); bool IsCode(const std::string& s);
}; };
#endif /* _GCT_H */ #endif /* _GCT_H */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -43,34 +43,34 @@ int fs_ntfs_mount = 0;
sec_t fs_ntfs_sec = 0; sec_t fs_ntfs_sec = 0;
int USBDevice_Init() { int USBDevice_Init() {
gprintf("\nUSBDevice_Init()"); gprintf("\nUSBDevice_Init()");
//closing all open Files write back the cache and then shutdown em! //closing all open Files write back the cache and then shutdown em!
fatUnmount("USB:/"); fatUnmount("USB:/");
//right now mounts first FAT-partition //right now mounts first FAT-partition
//try first mount with cIOS //try first mount with cIOS
if (!fatMount("USB", &__io_wiiums, 0, CACHE, SECTORS)) { if (!fatMount("USB", &__io_wiiums, 0, CACHE, SECTORS)) {
//try now mount with libogc //try now mount with libogc
if (!fatMount("USB", &__io_usbstorage, 0, CACHE, SECTORS)) { if (!fatMount("USB", &__io_usbstorage, 0, CACHE, SECTORS)) {
gprintf(":-1"); gprintf(":-1");
return -1; return -1;
} }
} }
fat_usb_mount = 1; fat_usb_mount = 1;
fat_usb_sec = _FAT_startSector; fat_usb_sec = _FAT_startSector;
gprintf(":0"); gprintf(":0");
return 0; return 0;
} }
void USBDevice_deInit() { void USBDevice_deInit() {
gprintf("\nUSBDevice_deInit()"); gprintf("\nUSBDevice_deInit()");
//closing all open Files write back the cache and then shutdown em! //closing all open Files write back the cache and then shutdown em!
fatUnmount("USB:/"); fatUnmount("USB:/");
fat_usb_mount = 0; fat_usb_mount = 0;
fat_usb_sec = 0; fat_usb_sec = 0;
} }
int WBFSDevice_Init(u32 sector) { int WBFSDevice_Init(u32 sector) {
@ -78,29 +78,29 @@ int WBFSDevice_Init(u32 sector) {
fatUnmount("WBFS:/"); fatUnmount("WBFS:/");
//right now mounts first FAT-partition //right now mounts first FAT-partition
//try first mount with cIOS //try first mount with cIOS
if (!fatMount("WBFS", &__io_wiiums, 0, CACHE, SECTORS)) { if (!fatMount("WBFS", &__io_wiiums, 0, CACHE, SECTORS)) {
//try now mount with libogc //try now mount with libogc
if (!fatMount("WBFS", &__io_usbstorage, 0, CACHE, SECTORS)) { if (!fatMount("WBFS", &__io_usbstorage, 0, CACHE, SECTORS)) {
return -1; return -1;
} }
} }
fat_wbfs_mount = 1; fat_wbfs_mount = 1;
fat_wbfs_sec = _FAT_startSector; fat_wbfs_sec = _FAT_startSector;
if (sector && fat_wbfs_sec != sector) { if (sector && fat_wbfs_sec != sector) {
// This is an error situation...actually, but is ignored in Config loader also // This is an error situation...actually, but is ignored in Config loader also
// Should ask Oggzee about it... // Should ask Oggzee about it...
} }
return 0; return 0;
} }
void WBFSDevice_deInit() { void WBFSDevice_deInit() {
//closing all open Files write back the cache and then shutdown em! //closing all open Files write back the cache and then shutdown em!
fatUnmount("WBFS:/"); fatUnmount("WBFS:/");
fat_wbfs_mount = 0; fat_wbfs_mount = 0;
fat_wbfs_sec = 0; fat_wbfs_sec = 0;
} }
int isInserted(const char *path) { int isInserted(const char *path) {
@ -111,118 +111,128 @@ int isInserted(const char *path) {
} }
int SDCard_Init() { int SDCard_Init() {
gprintf("\nSDCard_Init()"); gprintf("\nSDCard_Init()");
//closing all open Files write back the cache and then shutdown em! //closing all open Files write back the cache and then shutdown em!
fatUnmount("SD:/"); fatUnmount("SD:/");
//right now mounts first FAT-partition //right now mounts first FAT-partition
if (fatMount("SD", &__io_wiisd, 0, CACHE, SECTORS)) { if (fatMount("SD", &__io_wiisd, 0, CACHE, SECTORS)) {
fat_sd_mount = MOUNT_SD; fat_sd_mount = MOUNT_SD;
fat_sd_sec = _FAT_startSector; fat_sd_sec = _FAT_startSector;
gprintf(":1"); gprintf(":1");
return 1; return 1;
} else if (fatMount("SD", &__io_sdhc, 0, CACHE, SDHC_SECTOR_SIZE)) { }
fat_sd_mount = MOUNT_SDHC; else if (fatMount("SD", &__io_sdhc, 0, CACHE, SDHC_SECTOR_SIZE)) {
fat_sd_sec = _FAT_startSector; fat_sd_mount = MOUNT_SDHC;
gprintf(":1"); fat_sd_sec = _FAT_startSector;
return 1; gprintf(":1");
} return 1;
gprintf(":-1"); }
gprintf(":-1");
return -1; return -1;
} }
void SDCard_deInit() { void SDCard_deInit() {
gprintf("\nSDCard_deInit()"); gprintf("\nSDCard_deInit()");
//closing all open Files write back the cache and then shutdown em! //closing all open Files write back the cache and then shutdown em!
fatUnmount("SD:/"); fatUnmount("SD:/");
fat_sd_mount = MOUNT_NONE; fat_sd_mount = MOUNT_NONE;
fat_sd_sec = 0; fat_sd_sec = 0;
} }
void ntfsInit(); void ntfsInit();
s32 MountNTFS(u32 sector) { s32 MountNTFS(u32 sector)
s32 ret; {
s32 ret;
if (fs_ntfs_mount) return 0; if (fs_ntfs_mount) return 0;
//printf("mounting NTFS\n"); //printf("mounting NTFS\n");
//Wpad_WaitButtons(); //Wpad_WaitButtons();
_FAT_mem_init(); _FAT_mem_init();
ntfsInit(); // Call ntfs init here, to prevent locale resets ntfsInit(); // Call ntfs init here, to prevent locale resets
// ntfsInit resets locale settings // ntfsInit resets locale settings
// which breaks unicode in console // which breaks unicode in console
// so we change it back to C-UTF-8 // so we change it back to C-UTF-8
setlocale(LC_CTYPE, "C-UTF-8"); setlocale(LC_CTYPE, "C-UTF-8");
setlocale(LC_MESSAGES, "C-UTF-8"); setlocale(LC_MESSAGES, "C-UTF-8");
if (wbfsDev == WBFS_DEVICE_USB) { if (wbfsDev == WBFS_DEVICE_USB) {
/* Initialize WBFS interface */ /* Initialize WBFS interface */
if (!__io_wiiums.startup()) { if (!__io_wiiums.startup()) {
ret = __io_usbstorage.startup(); ret = __io_usbstorage.startup();
if (!ret) { if (!ret) {
return -1; return -1;
} }
} }
/* Mount device */ /* Mount device */
if (!ntfsMount("NTFS", &__io_wiiums, sector, CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER)) { if (!ntfsMount("NTFS", &__io_wiiums, sector, CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER)) {
ret = ntfsMount("NTFS", &__io_usbstorage, sector, CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER); ret = ntfsMount("NTFS", &__io_usbstorage, sector, CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER);
if (!ret) { if (!ret) {
return -2; return -2;
} }
} }
} else if (wbfsDev == WBFS_DEVICE_SDHC) { } else if (wbfsDev == WBFS_DEVICE_SDHC) {
if (sdhc_mode_sd == 0) { if (sdhc_mode_sd == 0) {
ret = ntfsMount("NTFS", &__io_sdhc, 0, CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER); ret = ntfsMount("NTFS", &__io_sdhc, 0, CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER);
} else { } else {
ret = ntfsMount("NTFS", &__io_sdhc, 0, CACHE, SECTORS_SD, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER); ret = ntfsMount("NTFS", &__io_sdhc, 0, CACHE, SECTORS_SD, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER);
} }
if (!ret) { if (!ret) {
return -5; return -5;
} }
} }
fs_ntfs_mount = 1; fs_ntfs_mount = 1;
fs_ntfs_sec = sector; //_FAT_startSector; fs_ntfs_sec = sector; //_FAT_startSector;
return 0; return 0;
} }
s32 UnmountNTFS(void) { s32 UnmountNTFS(void)
/* Unmount device */ {
ntfsUnmount("NTFS:/", true); /* Unmount device */
ntfsUnmount("NTFS:/", true);
fs_ntfs_mount = 0; fs_ntfs_mount = 0;
fs_ntfs_sec = 0; fs_ntfs_sec = 0;
return 0; return 0;
} }
void _FAT_mem_init() { void _FAT_mem_init()
{
} }
void* _FAT_mem_allocate(size_t size) { void* _FAT_mem_allocate(size_t size)
return malloc(size); {
return malloc(size);
} }
void* _FAT_mem_align(size_t size) { void* _FAT_mem_align(size_t size)
return memalign(32, size); {
return memalign(32, size);
} }
void _FAT_mem_free(void *mem) { void _FAT_mem_free(void *mem)
free(mem); {
free(mem);
} }
void* ntfs_alloc (size_t size) { void* ntfs_alloc (size_t size)
return _FAT_mem_allocate(size); {
return _FAT_mem_allocate(size);
} }
void* ntfs_align (size_t size) { void* ntfs_align (size_t size)
return _FAT_mem_align(size); {
return _FAT_mem_align(size);
} }
void ntfs_free (void* mem) { void ntfs_free (void* mem)
_FAT_mem_free(mem); {
_FAT_mem_free(mem);
} }

View File

@ -5,12 +5,12 @@
extern "C" { extern "C" {
#endif #endif
extern int fat_sd_mount; extern int fat_sd_mount;
extern sec_t fat_sd_sec; extern sec_t fat_sd_sec;
extern int fat_usb_mount; extern int fat_usb_mount;
extern sec_t fat_usb_sec; extern sec_t fat_usb_sec;
extern int fat_wbfs_mount; extern int fat_wbfs_mount;
extern sec_t fat_wbfs_sec; extern sec_t fat_wbfs_sec;
int USBDevice_Init(); int USBDevice_Init();
void USBDevice_deInit(); void USBDevice_deInit();
@ -20,15 +20,15 @@ extern "C" {
int SDCard_Init(); int SDCard_Init();
void SDCard_deInit(); void SDCard_deInit();
s32 MountNTFS(u32 sector); s32 MountNTFS(u32 sector);
s32 UnmountNTFS(void); s32 UnmountNTFS(void);
extern int fat_usb_mount; extern int fat_usb_mount;
extern sec_t fat_usb_sec; extern sec_t fat_usb_sec;
extern int fat_wbfs_mount; extern int fat_wbfs_mount;
extern sec_t fat_wbfs_sec; extern sec_t fat_wbfs_sec;
extern int fs_ntfs_mount; extern int fs_ntfs_mount;
extern sec_t fs_ntfs_sec; extern sec_t fs_ntfs_sec;
#ifdef __cplusplus #ifdef __cplusplus
} }

Binary file not shown.

Binary file not shown.

View File

@ -10,27 +10,31 @@ bool textVideoInit = false;
#include <stdarg.h> #include <stdarg.h>
//using the gprintf from crediar because it is smaller than mine //using the gprintf from crediar because it is smaller than mine
void gprintf( const char *str, ... ) { void gprintf( const char *str, ... )
if (!(geckoinit))return; {
if (!(geckoinit))return;
char astr[4096]; char astr[4096];
va_list ap; va_list ap;
va_start(ap,str); va_start(ap,str);
vsprintf( astr, str, ap ); vsprintf( astr, str, ap );
va_end(ap); va_end(ap);
usb_sendbuffer_safe( 1, astr, strlen(astr) ); usb_sendbuffer_safe( 1, astr, strlen(astr) );
} }
bool InitGecko() { bool InitGecko()
u32 geckoattached = usb_isgeckoalive(EXI_CHANNEL_1); {
if (geckoattached) { u32 geckoattached = usb_isgeckoalive(EXI_CHANNEL_1);
usb_flush(EXI_CHANNEL_1); if (geckoattached)
return true; {
} else return false; usb_flush(EXI_CHANNEL_1);
return true;
}
else return false;
} }

View File

@ -8,12 +8,12 @@ extern "C" {
#endif #endif
#ifndef NO_DEBUG #ifndef NO_DEBUG
//use this just like printf(); //use this just like printf();
void gprintf(const char *str, ...); void gprintf(const char *str, ...);
bool InitGecko(); bool InitGecko();
#else #else
#define gprintf(...) #define gprintf(...)
#define InitGecko() false #define InitGecko() false
#endif /* NO_DEBUG */ #endif /* NO_DEBUG */

View File

@ -37,9 +37,9 @@ void CopyHomebrewMemory(u32 read, u8 *temp, u32 len) {
} }
int BootHomebrew(char * path) { int BootHomebrew(char * path) {
loadStub(); loadStub();
if (Set_Stub_Split(0x00010001,"UNEO")<0) if (Set_Stub_Split(0x00010001,"UNEO")<0)
Set_Stub_Split(0x00010001,"ULNR"); Set_Stub_Split(0x00010001,"ULNR");
void *buffer = NULL; void *buffer = NULL;
u32 filesize = 0; u32 filesize = 0;
entrypoint entry; entrypoint entry;
@ -106,9 +106,9 @@ int BootHomebrew(char * path) {
} }
int BootHomebrewFromMem() { int BootHomebrewFromMem() {
loadStub(); loadStub();
if (Set_Stub_Split(0x00010001,"UNEO")<0) if (Set_Stub_Split(0x00010001,"UNEO")<0)
Set_Stub_Split(0x00010001,"ULNR"); Set_Stub_Split(0x00010001,"ULNR");
entrypoint entry; entrypoint entry;
u32 cpu_isr; u32 cpu_isr;

View File

@ -86,9 +86,9 @@ int MenuHomebrewBrowse() {
/*** Sound Variables ***/ /*** Sound Variables ***/
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
// because destroy GuiSound must wait while sound playing is finished, we use a global sound // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if (!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); // GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
GuiSound btnClick1(button_click_pcm, button_click_pcm_size, Settings.sfxvolume); GuiSound btnClick1(button_click_pcm, button_click_pcm_size, Settings.sfxvolume);
/*** Image Variables ***/ /*** Image Variables ***/
@ -219,11 +219,11 @@ int MenuHomebrewBrowse() {
GuiImage MainButton2Img(&MainButtonImgData); GuiImage MainButton2Img(&MainButtonImgData);
GuiImage MainButton2ImgOver(&MainButtonImgOverData); GuiImage MainButton2ImgOver(&MainButtonImgOverData);
GuiText MainButton2Txt(MainButtonText, 18, (GXColor) {0, 0, 0, 255}); GuiText MainButton2Txt(MainButtonText, 18, (GXColor) {0, 0, 0, 255 });
MainButton2Txt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); MainButton2Txt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton2Txt.SetPosition(148, -12); MainButton2Txt.SetPosition(148, -12);
MainButton2Txt.SetMaxWidth(MainButton2Img.GetWidth()-150, GuiText::DOTTED); MainButton2Txt.SetMaxWidth(MainButton2Img.GetWidth()-150, GuiText::DOTTED);
GuiText MainButton2DescTxt(MainButtonText, 18, (GXColor) {0, 0, 0, 255}); GuiText MainButton2DescTxt(MainButtonText, 18, (GXColor) { 0, 0, 0, 255});
MainButton2DescTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); MainButton2DescTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton2DescTxt.SetPosition(148, 15); MainButton2DescTxt.SetPosition(148, 15);
MainButton2DescTxt.SetMaxWidth(MainButton2Img.GetWidth()-150, GuiText::DOTTED); MainButton2DescTxt.SetMaxWidth(MainButton2Img.GetWidth()-150, GuiText::DOTTED);
@ -250,11 +250,11 @@ int MenuHomebrewBrowse() {
MainButton3Txt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); MainButton3Txt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton3Txt.SetPosition(148, -12); MainButton3Txt.SetPosition(148, -12);
MainButton3Txt.SetMaxWidth(MainButton3Img.GetWidth()-150, GuiText::DOTTED); MainButton3Txt.SetMaxWidth(MainButton3Img.GetWidth()-150, GuiText::DOTTED);
GuiText MainButton3DescTxt(MainButtonText, 18, (GXColor) {0, 0, 0, 255}); GuiText MainButton3DescTxt(MainButtonText, 18, (GXColor) { 0, 0, 0, 255});
MainButton3DescTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); MainButton3DescTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton3DescTxt.SetPosition(148, 15); MainButton3DescTxt.SetPosition(148, 15);
MainButton3DescTxt.SetMaxWidth(MainButton3Img.GetWidth()-150, GuiText::DOTTED); MainButton3DescTxt.SetMaxWidth(MainButton3Img.GetWidth()-150, GuiText::DOTTED);
GuiText MainButton3DescOverTxt(MainButtonText, 18, (GXColor) {0, 0, 0, 255}); GuiText MainButton3DescOverTxt(MainButtonText, 18, (GXColor) {0, 0, 0, 255 });
MainButton3DescOverTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); MainButton3DescOverTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton3DescOverTxt.SetPosition(148, 15); MainButton3DescOverTxt.SetPosition(148, 15);
MainButton3DescOverTxt.SetMaxWidth(MainButton3Img.GetWidth()-150, GuiText::SCROLL); MainButton3DescOverTxt.SetMaxWidth(MainButton3Img.GetWidth()-150, GuiText::SCROLL);
@ -273,7 +273,7 @@ int MenuHomebrewBrowse() {
GuiImage MainButton4Img(&MainButtonImgData); GuiImage MainButton4Img(&MainButtonImgData);
GuiImage MainButton4ImgOver(&MainButtonImgOverData); GuiImage MainButton4ImgOver(&MainButtonImgOverData);
GuiText MainButton4Txt(MainButtonText, 18, (GXColor) {0, 0, 0, 255}); GuiText MainButton4Txt(MainButtonText, 18, (GXColor) {0, 0, 0, 255} );
MainButton4Txt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); MainButton4Txt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton4Txt.SetPosition(148, -12); MainButton4Txt.SetPosition(148, -12);
MainButton4Txt.SetMaxWidth(MainButton4Img.GetWidth()-150, GuiText::DOTTED); MainButton4Txt.SetMaxWidth(MainButton4Img.GetWidth()-150, GuiText::DOTTED);
@ -281,7 +281,7 @@ int MenuHomebrewBrowse() {
MainButton4DescTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); MainButton4DescTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton4DescTxt.SetPosition(148, 15); MainButton4DescTxt.SetPosition(148, 15);
MainButton4DescTxt.SetMaxWidth(MainButton4Img.GetWidth()-150, GuiText::DOTTED); MainButton4DescTxt.SetMaxWidth(MainButton4Img.GetWidth()-150, GuiText::DOTTED);
GuiText MainButton4DescOverTxt(MainButtonText, 18, (GXColor) {0, 0, 0, 255}); GuiText MainButton4DescOverTxt(MainButtonText, 18, (GXColor) { 0, 0, 0, 255});
MainButton4DescOverTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); MainButton4DescOverTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton4DescOverTxt.SetPosition(148, 15); MainButton4DescOverTxt.SetPosition(148, 15);
MainButton4DescOverTxt.SetMaxWidth(MainButton4Img.GetWidth()-150, GuiText::SCROLL); MainButton4DescOverTxt.SetMaxWidth(MainButton4Img.GetWidth()-150, GuiText::SCROLL);
@ -808,8 +808,8 @@ int MenuHomebrewBrowse() {
int len = NETWORKBLOCKSIZE; int len = NETWORKBLOCKSIZE;
temp = (u8 *) malloc(infilesize); temp = (u8 *) malloc(infilesize);
bool error = false; bool error = false;
u8 *ptr = temp; u8 *ptr = temp;
while (read < infilesize) { while (read < infilesize) {
ShowProgress(tr("Receiving file from:"), GetIncommingIP(), NULL, read, infilesize, true); ShowProgress(tr("Receiving file from:"), GetIncommingIP(), NULL, read, infilesize, true);
@ -823,72 +823,73 @@ int MenuHomebrewBrowse() {
if (result < 0) { if (result < 0) {
WindowPrompt(tr("Error while transfering data."), 0, tr("OK")); WindowPrompt(tr("Error while transfering data."), 0, tr("OK"));
error = true; error = true;
break; break;
} }
if (!result) { if (!result) {
break; break;
} }
ptr += result; ptr += result;
read += result; read += result;
} }
char filename[101]; char filename[101];
if (!error) { if (!error) {
network_read((u8*) &filename, 100); network_read((u8*) &filename, 100);
// Do we need to unzip this thing? // Do we need to unzip this thing?
if (wiiloadVersion[0] > 0 || wiiloadVersion[1] > 4) { if (wiiloadVersion[0] > 0 || wiiloadVersion[1] > 4) {
// We need to unzip... // We need to unzip...
if (temp[0] == 'P' && temp[1] == 'K' && temp[2] == 0x03 && temp[3] == 0x04) { if (temp[0] == 'P' && temp[1] == 'K' && temp[2] == 0x03 && temp[3] == 0x04) {
// It's a zip file, unzip to the apps directory // It's a zip file, unzip to the apps directory
// Zip archive, ask for permission to install the zip // Zip archive, ask for permission to install the zip
char zippath[255]; char zippath[255];
sprintf((char *) &zippath, "%s%s", Settings.homebrewapps_path, filename); sprintf((char *) &zippath, "%s%s", Settings.homebrewapps_path, filename);
FILE *fp = fopen(zippath, "wb"); FILE *fp = fopen(zippath, "wb");
if (fp != NULL) { if (fp != NULL)
fwrite(temp, 1, infilesize, fp); {
fclose(fp); fwrite(temp, 1, infilesize, fp);
fclose(fp);
// Now unzip the zip file... // Now unzip the zip file...
unzFile uf = unzOpen(zippath); unzFile uf = unzOpen(zippath);
if (uf==NULL) { if (uf==NULL) {
error = true; error = true;
} else { } else {
extractZip(uf,0,1,0, Settings.homebrewapps_path); extractZip(uf,0,1,0, Settings.homebrewapps_path);
unzCloseCurrentFile(uf); unzCloseCurrentFile(uf);
remove(zippath); remove(zippath);
// Reload this menu here... // Reload this menu here...
menu = MENU_HOMEBREWBROWSE; menu = MENU_HOMEBREWBROWSE;
break; break;
} }
} else { } else {
error = true; error = true;
} }
} else if (uncfilesize != 0) { // if uncfilesize == 0, it's not compressed } else if (uncfilesize != 0) { // if uncfilesize == 0, it's not compressed
// It's compressed, uncompress // It's compressed, uncompress
u8 *unc = (u8 *) malloc(uncfilesize); u8 *unc = (u8 *) malloc(uncfilesize);
uLongf f = uncfilesize; uLongf f = uncfilesize;
error = uncompress(unc, &f, temp, infilesize) != Z_OK; error = uncompress(unc, &f, temp, infilesize) != Z_OK;
uncfilesize = f; uncfilesize = f;
free(temp); free(temp);
temp = unc; temp = unc;
} }
} }
if (!error && strstr(filename,".zip") == NULL) { if (!error && strstr(filename,".zip") == NULL) {
innetbuffer = temp; innetbuffer = temp;
} }
} }
ProgressStop(); ProgressStop();
@ -897,18 +898,18 @@ int MenuHomebrewBrowse() {
FreeHomebrewBuffer(); FreeHomebrewBuffer();
} else { } else {
if (strstr(filename,".dol") || strstr(filename,".DOL") if (strstr(filename,".dol") || strstr(filename,".DOL")
|| strstr(filename,".elf") || strstr(filename,".ELF")) { || strstr(filename,".elf") || strstr(filename,".ELF")) {
boothomebrew = 2; boothomebrew = 2;
menu = MENU_EXIT; menu = MENU_EXIT;
CloseConnection(); CloseConnection();
break; break;
} else if (strstr(filename,".zip")) { } else if (strstr(filename,".zip")) {
WindowPrompt(tr("Success:"), tr("Uploaded ZIP file installed to homebrew directory."), tr("OK")); WindowPrompt(tr("Success:"), tr("Uploaded ZIP file installed to homebrew directory."), tr("OK"));
CloseConnection(); CloseConnection();
} else { } else {
FreeHomebrewBuffer(); FreeHomebrewBuffer();
WindowPrompt(tr("ERROR:"), tr("Not a DOL/ELF file."), tr("OK")); WindowPrompt(tr("ERROR:"), tr("Not a DOL/ELF file."), tr("OK"));
} }
} }
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 891 B

After

Width:  |  Height:  |  Size: 856 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 957 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 937 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 B

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 267 B

After

Width:  |  Height:  |  Size: 225 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 B

After

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 B

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 B

After

Width:  |  Height:  |  Size: 86 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Some files were not shown because too many files have changed in this diff Show More