* Added new nand emulation feature:

With this feature it's possible to temp change the region of your Wii console. This makes it possible to play those one region only games that wouldn't play on other region consoles. 

Some games that work now are for example:

The Amazing Race (didn't play on PAL consoles)
Hollywood Squares (didn't play on PAL consoles)
Arthur and the Revenge of Maltazard (didn't play on NTSC consoles)

The feature is now working for Wii games if FULL nand emulation is enabled. The Regionswitch only emulation mode is written for and will only work with a yet unreleased feature of davebaol's d2x cIOS

* Updated english.ini
* Updated dutch.ini

Other languages have to change also again :P
This commit is contained in:
overjoy.psm 2012-03-12 23:57:59 +00:00
parent f70808739b
commit 99f3e035c4
7 changed files with 314 additions and 18 deletions

View File

@ -1,6 +1,7 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2011 * Copyright (C) 2011 by Miigotu
* by Miigotu * (C) 2012 by OverjoY for Wiiflow-mod
*
* Rewritten code from Mighty Channels and Triiforce * Rewritten code from Mighty Channels and Triiforce
* *
* This software is provided 'as-is', without any express or implied * This software is provided 'as-is', without any express or implied
@ -38,6 +39,16 @@
#include "gecko.h" #include "gecko.h"
#include "mem2.hpp" #include "mem2.hpp"
u8 *confbuffer;
u8 CCode[0x1008];
char SCode[4];
char *txtbuffer;
config_header *cfg_hdr;
bool tbdec = false;
bool configloaded = false;
static NandDevice NandDeviceList[] = { static NandDevice NandDeviceList[] = {
{ "Disable", 0, 0x00, 0x00 }, { "Disable", 0, 0x00, 0x00 },
{ "SD/SDHC Card", 1, 0xF0, 0xF1 }, { "SD/SDHC Card", 1, 0xF0, 0xF1 },
@ -123,7 +134,7 @@ s32 Nand::Nand_Disable(void)
s32 fd = IOS_Open("/dev/fs", 0); s32 fd = IOS_Open("/dev/fs", 0);
if (fd < 0) return fd; if (fd < 0) return fd;
static u32 inbuf ATTRIBUTE_ALIGN(32) = 0; u32 inbuf ATTRIBUTE_ALIGN(32) = 0;
s32 ret = IOS_Ioctl(fd, 100, &inbuf, sizeof(inbuf), NULL, 0); s32 ret = IOS_Ioctl(fd, 100, &inbuf, sizeof(inbuf), NULL, 0);
IOS_Close(fd); IOS_Close(fd);
@ -176,3 +187,253 @@ void Nand::Set_NandPath(string path)
if(path.size() <= 32) if(path.size() <= 32)
memcpy(NandPath, path.c_str(), path.size()); memcpy(NandPath, path.c_str(), path.size());
} }
void Nand::__Dec_Enc_TB(void)
{
u32 key = 0x73B5DBFA;
int i;
for( i=0; i < 0x100; ++i )
{
txtbuffer[i] ^= key&0xFF;
key = (key<<1) | (key>>31);
}
tbdec = tbdec ? false : true;
}
void Nand::__configshifttxt(char *str)
{
const char *ptr = str;
char *ctr = str;
int i;
int j = strlen(str);
for( i=0; i<j; ++i )
{
if( strncmp( str+(i-3), "PALC", 4 ) == 0 )
*ctr = 0x0d;
else if( strncmp( str+(i-2), "LUH", 3 ) == 0 )
*ctr = 0x0d;
else if( strncmp( str+(i-2), "LUM", 3 ) == 0 )
*ctr = 0x0d;
else
*ctr = str[i];
ctr++;
}
*ctr = *ptr;
*ctr = '\0';
}
s32 Nand::__configread(void)
{
confbuffer = (u8 *)MEM2_alloc(0x4000);
txtbuffer = (char *)MEM2_alloc(0x100);
cfg_hdr = (config_header *)NULL;
FILE *f = fopen(cfgpath, "rb");
if(f)
{
fread(confbuffer, 1, 0x4000, f);
gprintf("SYSCONF readed from: %s \n", cfgpath);
fclose(f);
}
f = fopen(settxtpath, "rb");
if(f)
{
fread(txtbuffer, 1, 0x100, f);
gprintf("setting.txt readed from: %s \n", settxtpath);
fclose(f);
}
cfg_hdr = (config_header *)confbuffer;
__Dec_Enc_TB();
configloaded = configloaded ? false : true;
if(tbdec && configloaded)
return 1;
return 0;
}
s32 Nand::__configwrite(void)
{
if(configloaded)
{
__Dec_Enc_TB();
if(!tbdec)
{
FILE *f = fopen(cfgpath, "wb");
if(f)
{
fwrite(confbuffer, 1, 0x4000, f);
gprintf("SYSCONF written to: %s \n", cfgpath);
fclose(f);
}
f = fopen(settxtpath, "wb");
if(f)
{
fwrite(txtbuffer, 1, 0x100, f);
gprintf("setting.txt written to: %s \n", settxtpath);
fclose(f);
}
configloaded = configloaded ? false : true;
if(!tbdec && !configloaded)
return 1;
}
}
MEM2_free(confbuffer);
MEM2_free(txtbuffer);
return 0;
}
u32 Nand::__configsetbyte(const char *item, u8 val)
{
u32 i;
for(i=0; i<cfg_hdr->ncnt; ++i)
{
if(memcmp(confbuffer+(cfg_hdr->noff[i] + 1), item, strlen(item)) == 0)
{
*(u8*)(confbuffer+cfg_hdr->noff[i] + 1 + strlen(item)) = val;
break;
}
}
return 0;
}
u32 Nand::__configsetbigarray(const char *item, void *val, u32 size)
{
u32 i;
for(i=0; i<cfg_hdr->ncnt; ++i)
{
if(memcmp(confbuffer+(cfg_hdr->noff[i] + 1), item, strlen(item)) == 0)
{
memcpy(confbuffer+cfg_hdr->noff[i] + 3 + strlen(item), val, size);
break;
}
}
return 0;
}
u32 Nand::__configsetsetting(const char *item, const char *val)
{
char *curitem = strstr(txtbuffer, item);
char *curstrt, *curend;
if(curitem == NULL)
return 0;
curstrt = strchr(curitem, '=');
curend = strchr(curitem, 0x0d);
if( curstrt && curend )
{
curstrt += 1;
u32 len = curend - curstrt;
if( strlen( val ) > len )
{
static char buffer[0x100];
u32 nlen;
nlen = txtbuffer-(curstrt+strlen(val));
strcpy( buffer, txtbuffer+nlen );
strncpy( curstrt, val, strlen(val));
curstrt += strlen(val);
strncpy(curstrt, buffer, strlen(buffer));
}
else
{
strncpy(curstrt, val, strlen(val));
}
__configshifttxt(txtbuffer);
return 1;
}
return 0;
}
s32 Nand::Do_Region_Change(string id, char *path)
{
bzero(cfgpath, MAX_FAT_PATH);
bzero(settxtpath, MAX_FAT_PATH);
snprintf(cfgpath, sizeof(cfgpath), "%s/shared2/sys/SYSCONF", path);
snprintf(settxtpath, sizeof(settxtpath), "%s/title/00000001/00000002/data/setting.txt", path);
if(__configread())
{
switch(id[3])
{
case 'J':
{
gprintf("Switching region to NTSC-j \n");
CCode[0] = 1;
__configsetbyte( "IPL.LNG", 0 );
__configsetbigarray( "SADR.LNG", CCode, 0x1007 );
__configsetsetting( "AREA", "JPN" );
__configsetsetting( "MODEL", "RVL-001(JPN)" );
__configsetsetting( "CODE", "LJM" );
__configsetsetting( "VIDEO", "NTSC" );
__configsetsetting( "GAME", "JP" );
} break;
case 'E':
{
gprintf("Switching region to NTSC-u \n");
CCode[0] = 31;
__configsetbyte( "IPL.LNG", 1 );
__configsetbigarray( "IPL.SADR", CCode, 0x1007 );
__configsetsetting( "AREA", "USA" );
__configsetsetting( "MODEL", "RVL-001(USA)" );
__configsetsetting( "CODE", "LU" );
__configsetsetting( "VIDEO", "NTSC" );
__configsetsetting( "GAME", "US" );
} break;
case 'D':
case 'F':
case 'I':
case 'M':
case 'P':
case 'S':
case 'U':
{
gprintf("Switching region to PAL \n");
CCode[0] = 110;
__configsetbyte( "IPL.LNG", 6 );
__configsetbigarray( "IPL.SADR", CCode, 0x1007 );
__configsetsetting( "AREA", "EUR" );
__configsetsetting( "MODEL", "RVL-001(EUR)" );
__configsetsetting( "CODE", "LEH" );
__configsetsetting( "VIDEO", "PAL" );
__configsetsetting( "GAME", "EU" );
} break;
case 'K':
{
gprintf("Switching region to NTSC-k \n");
CCode[0] = 137;
__configsetbyte( "IPL.LNG", 9 );
__configsetbigarray( "IPL.SADR", CCode, 0x1007 );
__configsetsetting( "AREA", "KOR" );
__configsetsetting( "MODEL", "RVL-001(KOR)" );
__configsetsetting( "CODE", "LKM" );
__configsetsetting( "VIDEO", "NTSC" );
__configsetsetting( "GAME", "KR" );
} break;
}
}
__configwrite();
return 1;
}

View File

@ -27,6 +27,13 @@ typedef struct nandDevice
u32 Unmount; u32 Unmount;
} NandDevice; } NandDevice;
typedef struct _config_header
{
u8 magic[4];
u16 ncnt;
u16 noff[];
} config_header;
using namespace std; using namespace std;
class Nand class Nand
@ -42,12 +49,15 @@ class Nand
void Set_Partition(u32 partition) { Partition = partition; }; void Set_Partition(u32 partition) { Partition = partition; };
void Set_FullMode(bool fullmode) { FullMode = fullmode ? 0x100 : 0; }; void Set_FullMode(bool fullmode) { FullMode = fullmode ? 0x100 : 0; };
void Set_RCMode(bool rcmode) { FullMode = rcmode ? 0x40 : 0; };
const char * Get_NandPath(void) { return NandPath; }; const char * Get_NandPath(void) { return NandPath; };
u32 Get_Partition(void) { return Partition; }; u32 Get_Partition(void) { return Partition; };
void Set_NandPath(string path); void Set_NandPath(string path);
s32 Do_Region_Change(string id, char *path);
private: private:
Nand() : MountedDevice(0), EmuDevice(REAL_NAND), Disabled(true), Partition(0), FullMode(0x100), NandPath() {} Nand() : MountedDevice(0), EmuDevice(REAL_NAND), Disabled(true), Partition(0), FullMode(0x100), NandPath() {}
~Nand(void){} ~Nand(void){}
@ -57,6 +67,13 @@ class Nand
s32 Nand_Unmount(NandDevice *Device); s32 Nand_Unmount(NandDevice *Device);
s32 Nand_Enable(NandDevice *Device); s32 Nand_Enable(NandDevice *Device);
s32 Nand_Disable(void); s32 Nand_Disable(void);
void __Dec_Enc_TB(void);
void __configshifttxt(char *str);
s32 __configread(void);
s32 __configwrite(void);
u32 __configsetbyte(const char *item, u8 val);
u32 __configsetbigarray(const char *item, void *val, u32 size);
u32 __configsetsetting(const char *item, const char *val);
u32 MountedDevice; u32 MountedDevice;
u32 EmuDevice; u32 EmuDevice;
@ -65,6 +82,8 @@ class Nand
u32 Partition ATTRIBUTE_ALIGN(32); u32 Partition ATTRIBUTE_ALIGN(32);
u32 FullMode ATTRIBUTE_ALIGN(32); u32 FullMode ATTRIBUTE_ALIGN(32);
char NandPath[32] ATTRIBUTE_ALIGN(32); char NandPath[32] ATTRIBUTE_ALIGN(32);
char cfgpath[1024] ATTRIBUTE_ALIGN(32);
char settxtpath[1024] ATTRIBUTE_ALIGN(32);
static Nand * instance; static Nand * instance;
}; };

View File

@ -974,8 +974,8 @@ private:
static const SOption _GClanguages[8]; static const SOption _GClanguages[8];
static const SOption _NandEmu[3]; static const SOption _NandEmu[3];
static const SOption _SaveEmu[4]; static const SOption _SaveEmu[5];
static const SOption _GlobalSaveEmu[3]; static const SOption _GlobalSaveEmu[4];
static const SOption _AspectRatio[3]; static const SOption _AspectRatio[3];
static const SOption _NMM[4]; static const SOption _NMM[4];
static const SOption _vidModePatch[4]; static const SOption _vidModePatch[4];

View File

@ -901,7 +901,7 @@ void CMenu::_textGameSettings(void)
m_btnMgr.setText(m_gameSettingsBtnCategoryMain, _t("cfgg16", L"Select")); m_btnMgr.setText(m_gameSettingsBtnCategoryMain, _t("cfgg16", L"Select"));
m_btnMgr.setText(m_gameSettingsLblHooktype, _t("cfgg18", L"Hook Type")); m_btnMgr.setText(m_gameSettingsLblHooktype, _t("cfgg18", L"Hook Type"));
m_btnMgr.setText(m_gameSettingsLblDebugger, _t("cfgg22", L"Debugger")); m_btnMgr.setText(m_gameSettingsLblDebugger, _t("cfgg22", L"Debugger"));
m_btnMgr.setText(m_gameSettingsLblEmulation, _t("cfgg24", L"Savegame Emulation")); m_btnMgr.setText(m_gameSettingsLblEmulation, _t("cfgg24", L"Nand emulation"));
m_btnMgr.setText(m_gameSettingsLblIOSreloadBlock, _t("cfgg26", L"Disable IOS Reload block")); m_btnMgr.setText(m_gameSettingsLblIOSreloadBlock, _t("cfgg26", L"Disable IOS Reload block"));
m_btnMgr.setText(m_gameSettingsLblAspectRatio, _t("cfgg27", L"Aspect Ratio")); m_btnMgr.setText(m_gameSettingsLblAspectRatio, _t("cfgg27", L"Aspect Ratio"));
m_btnMgr.setText(m_gameSettingsLblNMM, _t("cfgg28", L"NMM")); m_btnMgr.setText(m_gameSettingsLblNMM, _t("cfgg28", L"NMM"));

View File

@ -144,16 +144,18 @@ const CMenu::SOption CMenu::_NandEmu[3] = {
{ "NANDfull", L"Full" }, { "NANDfull", L"Full" },
}; };
const CMenu::SOption CMenu::_GlobalSaveEmu[3] = { const CMenu::SOption CMenu::_GlobalSaveEmu[4] = {
{ "SaveOffG", L"Off" }, { "SaveOffG", L"Off" },
{ "SavePartG", L"Partial" }, { "SavePartG", L"Game save" },
{ "SaveRegG", L"Regionswitch" },
{ "SaveFullG", L"Full" }, { "SaveFullG", L"Full" },
}; };
const CMenu::SOption CMenu::_SaveEmu[4] = { const CMenu::SOption CMenu::_SaveEmu[5] = {
{ "SaveDef", L"Default" }, { "SaveDef", L"Default" },
{ "SaveOff", L"Off" }, { "SaveOff", L"Off" },
{ "SavePart", L"Partial" }, { "SavePart", L"Game save" },
{ "SaveReg", L"Regionswitch" },
{ "SaveFull", L"Full" }, { "SaveFull", L"Full" },
}; };
@ -1006,7 +1008,15 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
{ {
char basepath[64]; char basepath[64];
snprintf(basepath, 64, "%s:%s", DeviceName[emuPartition], emuPath.c_str()); snprintf(basepath, 64, "%s:%s", DeviceName[emuPartition], emuPath.c_str());
CreateSavePath(basepath, hdr); if(emuSave == 2 || emuSave > 3)
{
CreateSavePath(basepath, hdr);
}
if(emuSave > 2)
{
//Nand::Instance()->CreateConfig(basepath); // TODO: Write config files if they don't excist
Nand::Instance()->Do_Region_Change(id, basepath);
}
} }
int gameIOS = 0; int gameIOS = 0;
@ -1121,6 +1131,8 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
DeviceHandler::Instance()->UnMount(emuPartition); DeviceHandler::Instance()->UnMount(emuPartition);
if (emuSave == 3) if (emuSave == 3)
Nand::Instance()->Set_RCMode(true);
else if (emuSave == 4)
Nand::Instance()->Set_FullMode(true); Nand::Instance()->Set_FullMode(true);
else else
Nand::Instance()->Set_FullMode(false); Nand::Instance()->Set_FullMode(false);

View File

@ -62,7 +62,7 @@ cfgg2=Video modus
cfgg21=Terugkeren naar kanaal cfgg21=Terugkeren naar kanaal
cfgg22=Foutopsporing cfgg22=Foutopsporing
cfgg23=Cheat bestand aan het downloaden.... cfgg23=Cheat bestand aan het downloaden....
cfgg24=Spelopslag Emulatie cfgg24=Nand emulatie
cfgg25=Wachtwoord incorrect cfgg25=Wachtwoord incorrect
cfgg26=IOS Reload block Uitschakelen cfgg26=IOS Reload block Uitschakelen
cfgg27=Beeldverhouding cfgg27=Beeldverhouding
@ -187,8 +187,10 @@ SaveFull=Volledig
SaveFullG=Volledig SaveFullG=Volledig
SaveOff=Uit SaveOff=Uit
SaveOffG=Uit SaveOffG=Uit
SavePart=Gedeeltelijk SavePart=Spelopslag
SavePartG=Gedeeltelijk SavePartG=Spelopslag
SaveReg=Regioswitch
SaveRegG=Regioswitch
snes=Super Nintendo snes=Super Nintendo
sys1=Systeem sys1=Systeem
sys2=WiiFlow Versie: sys2=WiiFlow Versie:

View File

@ -62,7 +62,7 @@ cfgg2=Video mode
cfgg21=Return To Channel cfgg21=Return To Channel
cfgg22=Debugger cfgg22=Debugger
cfgg23=Downloading cheat file.... cfgg23=Downloading cheat file....
cfgg24=Savegame Emulation cfgg24=Nand emulation
cfgg25=Password incorrect cfgg25=Password incorrect
cfgg26=Disable IOS Reload block cfgg26=Disable IOS Reload block
cfgg27=Aspect Ratio cfgg27=Aspect Ratio
@ -192,8 +192,10 @@ SaveFull=Full
SaveFullG=Full SaveFullG=Full
SaveOff=Off SaveOff=Off
SaveOffG=Off SaveOffG=Off
SavePart=Partial SavePart=Game save
SavePartG=Partial SavePartG=Game save
SaveReg=Regionswitch
SaveRegG=Regionswitch
snes=Super Nintendo snes=Super Nintendo
sys1=Update WiiFlow sys1=Update WiiFlow
sys2=WiiFlow Version: sys2=WiiFlow Version: