* 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
* by Miigotu
* Copyright (C) 2011 by Miigotu
* (C) 2012 by OverjoY for Wiiflow-mod
*
* Rewritten code from Mighty Channels and Triiforce
*
* This software is provided 'as-is', without any express or implied
@ -38,6 +39,16 @@
#include "gecko.h"
#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[] = {
{ "Disable", 0, 0x00, 0x00 },
{ "SD/SDHC Card", 1, 0xF0, 0xF1 },
@ -123,7 +134,7 @@ s32 Nand::Nand_Disable(void)
s32 fd = IOS_Open("/dev/fs", 0);
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);
IOS_Close(fd);
@ -175,4 +186,254 @@ void Nand::Set_NandPath(string path)
if(path.size() <= 32)
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;
} NandDevice;
typedef struct _config_header
{
u8 magic[4];
u16 ncnt;
u16 noff[];
} config_header;
using namespace std;
class Nand
@ -42,11 +49,14 @@ class Nand
void Set_Partition(u32 partition) { Partition = partition; };
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; };
u32 Get_Partition(void) { return Partition; };
void Set_NandPath(string path);
s32 Do_Region_Change(string id, char *path);
private:
Nand() : MountedDevice(0), EmuDevice(REAL_NAND), Disabled(true), Partition(0), FullMode(0x100), NandPath() {}
@ -57,6 +67,13 @@ class Nand
s32 Nand_Unmount(NandDevice *Device);
s32 Nand_Enable(NandDevice *Device);
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 EmuDevice;
@ -65,6 +82,8 @@ class Nand
u32 Partition ATTRIBUTE_ALIGN(32);
u32 FullMode ATTRIBUTE_ALIGN(32);
char NandPath[32] ATTRIBUTE_ALIGN(32);
char cfgpath[1024] ATTRIBUTE_ALIGN(32);
char settxtpath[1024] ATTRIBUTE_ALIGN(32);
static Nand * instance;
};

View File

@ -974,8 +974,8 @@ private:
static const SOption _GClanguages[8];
static const SOption _NandEmu[3];
static const SOption _SaveEmu[4];
static const SOption _GlobalSaveEmu[3];
static const SOption _SaveEmu[5];
static const SOption _GlobalSaveEmu[4];
static const SOption _AspectRatio[3];
static const SOption _NMM[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_gameSettingsLblHooktype, _t("cfgg18", L"Hook Type"));
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_gameSettingsLblAspectRatio, _t("cfgg27", L"Aspect Ratio"));
m_btnMgr.setText(m_gameSettingsLblNMM, _t("cfgg28", L"NMM"));

View File

@ -144,16 +144,18 @@ const CMenu::SOption CMenu::_NandEmu[3] = {
{ "NANDfull", L"Full" },
};
const CMenu::SOption CMenu::_GlobalSaveEmu[3] = {
const CMenu::SOption CMenu::_GlobalSaveEmu[4] = {
{ "SaveOffG", L"Off" },
{ "SavePartG", L"Partial" },
{ "SavePartG", L"Game save" },
{ "SaveRegG", L"Regionswitch" },
{ "SaveFullG", L"Full" },
};
const CMenu::SOption CMenu::_SaveEmu[4] = {
const CMenu::SOption CMenu::_SaveEmu[5] = {
{ "SaveDef", L"Default" },
{ "SaveOff", L"Off" },
{ "SavePart", L"Partial" },
{ "SavePart", L"Game save" },
{ "SaveReg", L"Regionswitch" },
{ "SaveFull", L"Full" },
};
@ -1006,7 +1008,15 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
{
char basepath[64];
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;
@ -1121,6 +1131,8 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
DeviceHandler::Instance()->UnMount(emuPartition);
if (emuSave == 3)
Nand::Instance()->Set_RCMode(true);
else if (emuSave == 4)
Nand::Instance()->Set_FullMode(true);
else
Nand::Instance()->Set_FullMode(false);

View File

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

View File

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