mirror of
https://gitlab.com/Nanolx/homebrewfilter.git
synced 2024-11-01 07:05:10 +01:00
merge changes dones by obcd
This commit is contained in:
parent
6e11c98ff2
commit
ac051ca05b
Binary file not shown.
@ -14,6 +14,10 @@
|
||||
#include "DiskOperations/di2.h"
|
||||
#include "Tools/load_channel.h"
|
||||
#include "Tools/parser.h"
|
||||
#include "Tools/SelectIos.h"
|
||||
#include "uneek_fs.h"
|
||||
#include "gecko.h"
|
||||
#include "ahbfix.h"
|
||||
|
||||
#define BLOCKSIZE 70*1024 //70KB
|
||||
#define MAX_CMDLINE 4096
|
||||
@ -30,6 +34,8 @@ char *a_argv[MAX_ARGV];
|
||||
char *meta_buf = NULL;
|
||||
static u8 *homebrewbuffer = (u8 *) 0x92000000;
|
||||
static u32 homebrewsize = 0;
|
||||
static int wiiload_args = 0;
|
||||
static char temp_arg[1024];
|
||||
std::string filepath;
|
||||
|
||||
void arg_init()
|
||||
@ -157,6 +163,13 @@ int CopyHomebrewMemory(u8 *temp, u32 pos, u32 len)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CopyArgs(u8* temp, u32 len)
|
||||
{
|
||||
memcpy(temp_arg,temp,len);
|
||||
wiiload_args = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LoadHomebrew(const char * path)
|
||||
{
|
||||
filepath = path;
|
||||
@ -177,6 +190,10 @@ int LoadHomebrew(const char * path)
|
||||
|
||||
int BootHomebrew()
|
||||
{
|
||||
|
||||
char* abuf;
|
||||
size_t asize;
|
||||
|
||||
if(homebrewsize == 0)
|
||||
return -1;
|
||||
|
||||
@ -184,11 +201,28 @@ int BootHomebrew()
|
||||
u32 cpu_isr;
|
||||
|
||||
arg_init();
|
||||
arg_add(filepath.c_str()); // argv[0] = filepath
|
||||
while(parser(Settings.forwarder_arg, "<arg>", "</arg>") != "")
|
||||
|
||||
if (wiiload_args)
|
||||
{
|
||||
arg_add(parser(Settings.forwarder_arg, "<arg>", "</arg>").c_str());
|
||||
Settings.forwarder_arg.erase(0, Settings.forwarder_arg.find("</arg>") +1);
|
||||
abuf = temp_arg;
|
||||
asize = strlen(abuf);
|
||||
while (asize != 0)
|
||||
{
|
||||
gprintf("argument = %s\n",abuf);
|
||||
arg_add(abuf);
|
||||
abuf+=asize;
|
||||
abuf+=1;
|
||||
asize = strlen(abuf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
arg_add(filepath.c_str()); // argv[0] = filepath
|
||||
while(parser(Settings.forwarder_arg, "<arg>", "</arg>") != "")
|
||||
{
|
||||
arg_add(parser(Settings.forwarder_arg, "<arg>", "</arg>").c_str());
|
||||
Settings.forwarder_arg.erase(0, Settings.forwarder_arg.find("</arg>") +1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( valid_elf_image(homebrewbuffer) == 1 )
|
||||
@ -199,6 +233,23 @@ int BootHomebrew()
|
||||
if (!entry)
|
||||
return -1;
|
||||
|
||||
/* ExitApp();
|
||||
|
||||
this will also be called when wiiloading an application
|
||||
will need to check if it's expected behavour? */
|
||||
|
||||
if(!wiiload_args)
|
||||
{
|
||||
if(SelectedIOS() != IOS_GetVersion())
|
||||
{
|
||||
//keep ahbprot rights in new ios
|
||||
Patch_ahbprot();
|
||||
IOS_ReloadIOS(SelectedIOS());
|
||||
}
|
||||
}
|
||||
|
||||
wiiload_args = 0;
|
||||
|
||||
SYS_ResetSystem(SYS_SHUTDOWN, 0, 0);
|
||||
_CPU_ISR_Disable (cpu_isr);
|
||||
__exception_closeall();
|
||||
@ -220,14 +271,15 @@ int BootGameCubeHomebrew()
|
||||
DI2_ReadDiscID((u64 *) 0x80000000);
|
||||
DI2_Mount();
|
||||
|
||||
strcpy(GC_MAGIC_BUF, GC_DOL_MAGIC);
|
||||
DCFlushRange(GC_MAGIC_BUF, 32);
|
||||
strcpy(GC_MAGIC_BUF, GC_DOL_MAGIC);
|
||||
DCFlushRange(GC_MAGIC_BUF, 32);
|
||||
memcpy(GC_DOL_BUF, homebrewbuffer, homebrewsize);
|
||||
DCFlushRange(GC_DOL_BUF, homebrewsize);
|
||||
*(vu32 *) 0xCC003024 |= 0x07;
|
||||
DCFlushRange(GC_DOL_BUF, homebrewsize);
|
||||
*(vu32 *) 0xCC003024 |= 0x07;
|
||||
|
||||
ES_GetTicketViews(BC, &view, 1);
|
||||
ES_GetTicketViews(BC, &view, 1);
|
||||
int ret = ES_LaunchTitle(BC, &view);
|
||||
exit_uneek_fs();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
int BootHomebrew();
|
||||
int BootGameCubeHomebrew();
|
||||
int CopyHomebrewMemory(u8 *temp, u32 pos, u32 len);
|
||||
int CopyArgs(u8* temp, u32 len);
|
||||
void AddBootArgument(const char * arg);
|
||||
int LoadHomebrew(const char * filepath);
|
||||
|
||||
|
@ -16,6 +16,7 @@ extern GuiWindow * mainWindow;
|
||||
extern void ResumeGui();
|
||||
extern void HaltGui();
|
||||
|
||||
extern bool runaway;
|
||||
|
||||
/****************************************************************************
|
||||
* MenuSettings
|
||||
@ -38,13 +39,13 @@ int MenuSettingsChildlock()
|
||||
GuiImage btn1Img(&btn);
|
||||
GuiImage btn2Img(&btn);
|
||||
GuiImage backBtnImg(&btn);
|
||||
|
||||
|
||||
// normale Buttons over
|
||||
GuiImageData btn_over(Theme.button_focus);
|
||||
GuiImage btn1ImgOver(&btn_over);
|
||||
GuiImage btn2ImgOver(&btn_over);
|
||||
GuiImage backBtnImgOver(&btn_over);
|
||||
|
||||
|
||||
GuiText btn1Txt(tr("Activate"), 22, (GXColor){Theme.button_small_text_1, Theme.button_small_text_2, Theme.button_small_text_3, 255});
|
||||
GuiButton btn1(btn.GetWidth(), btn.GetHeight());
|
||||
btn1.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
|
||||
@ -106,7 +107,7 @@ int MenuSettingsChildlock()
|
||||
{
|
||||
for(int i = 0; i < (signed)strlen(buffer); i++)
|
||||
buffer[i] = '\0';
|
||||
|
||||
|
||||
OnScreenCodeboard(buffer, 4);
|
||||
// wenn eingabe richtig
|
||||
if(strcasecmp(buffer, Options.temp_code) == 0 )
|
||||
@ -130,7 +131,7 @@ int MenuSettingsChildlock()
|
||||
if(strcasecmp(buffer,"NULL") != 0 )
|
||||
sprintf (Options.temp_code, buffer);
|
||||
}
|
||||
|
||||
|
||||
menu = MENU_SETTINGS_CHILDLOCK;
|
||||
}
|
||||
else if(btn2.GetState() == STATE_CLICKED)
|
||||
@ -141,7 +142,7 @@ int MenuSettingsChildlock()
|
||||
{
|
||||
for(int i = 0; i < (signed)strlen(buffer); i++)
|
||||
buffer[i] = '\0';
|
||||
|
||||
|
||||
// alten code eingeben
|
||||
WindowPrompt(tr("Info"), tr("Old Code"), tr("Back"));
|
||||
OnScreenCodeboard(buffer, 4);
|
||||
@ -175,6 +176,12 @@ int MenuSettingsChildlock()
|
||||
Options.temp_last_setting = 1;
|
||||
menu = MENU_SETTINGS_FILE;
|
||||
}
|
||||
|
||||
if(runaway == true)
|
||||
{
|
||||
Options.temp_last_setting = 1;
|
||||
menu = MENU_SETTINGS_FILE;
|
||||
}
|
||||
}
|
||||
|
||||
HaltGui();
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
|
||||
@ -629,30 +628,34 @@ int MenuMain()
|
||||
menu = MENU_MAIN;
|
||||
}
|
||||
|
||||
// Netzwerksymbol anzeigen
|
||||
if(IsNetworkInit())
|
||||
if (!IsNetworkError())
|
||||
{
|
||||
network_Btn.SetImage(&network_BtnImgOver);
|
||||
ResumeTcpThread();
|
||||
if(boot_buffer)
|
||||
menu = MENU_EXIT;
|
||||
if((IsNetworkInit())&&(!IsNetworkHalted()))
|
||||
{
|
||||
network_Btn.SetImage(&network_BtnImgOver);
|
||||
ResumeTcpThread();
|
||||
if(boot_buffer)
|
||||
menu = MENU_EXIT;
|
||||
}
|
||||
else
|
||||
network_Btn.SetImage(&network_BtnImg);
|
||||
}
|
||||
else if(!IsNetworkInit() || IsNetworkError())
|
||||
network_Btn.SetImage(&network_BtnImg);
|
||||
else
|
||||
{
|
||||
networtwaittime++;
|
||||
if(networkswitch && networtwaittime == 10000)
|
||||
if (networtwaittime == 10000)
|
||||
{
|
||||
networtwaittime = 0;
|
||||
networkswitch = false;
|
||||
network_Btn.SetImage(&network_BtnImgOver);
|
||||
}
|
||||
else if(!networkswitch && networtwaittime == 10000)
|
||||
{
|
||||
networtwaittime = 0;
|
||||
networkswitch = true;
|
||||
network_Btn.SetImage(&network_BtnImg);
|
||||
if (networkswitch)
|
||||
{
|
||||
networkswitch = false;
|
||||
network_Btn.SetImage(&network_BtnImgOver);
|
||||
}
|
||||
else
|
||||
{
|
||||
networkswitch = true;
|
||||
network_Btn.SetImage(&network_BtnImg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ extern bool boot_buffer;
|
||||
extern void ResumeGui();
|
||||
extern void HaltGui();
|
||||
|
||||
extern bool runaway;
|
||||
|
||||
/****************************************************************************
|
||||
* MenuSettings
|
||||
@ -42,7 +43,7 @@ int MenuSettings()
|
||||
GuiImage optionsBtnImg(&btn);
|
||||
GuiImage updateBtnImg(&btn);
|
||||
GuiImage backBtnImg(&btn);
|
||||
|
||||
|
||||
// normale Buttons over
|
||||
GuiImageData btn_over(Theme.button_focus);
|
||||
GuiImage categoryCreateBtnImgOver(&btn_over);
|
||||
@ -51,7 +52,7 @@ int MenuSettings()
|
||||
GuiImage optionsBtnImgOver(&btn_over);
|
||||
GuiImage updateBtnImgOver(&btn_over);
|
||||
GuiImage backBtnImgOver(&btn_over);
|
||||
|
||||
|
||||
GuiText categoryCreateBtnTxt(tr("Create Category"), 22, (GXColor){Theme.button_small_text_1, Theme.button_small_text_2, Theme.button_small_text_3, 255});
|
||||
GuiButton categoryCreateBtn(btn.GetWidth(), btn.GetHeight());
|
||||
categoryCreateBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
|
||||
@ -96,7 +97,7 @@ int MenuSettings()
|
||||
updateBtn.SetImage(&updateBtnImg);
|
||||
updateBtn.SetImageOver(&updateBtnImgOver);
|
||||
updateBtn.SetTrigger(&trigA);
|
||||
|
||||
|
||||
GuiText backBtnTxt(tr("Back"), 22, (GXColor){Theme.button_small_text_1, Theme.button_small_text_2, Theme.button_small_text_3, 255});
|
||||
GuiButton backBtn(btn.GetWidth(), btn.GetHeight());
|
||||
backBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
|
||||
@ -139,15 +140,15 @@ int MenuSettings()
|
||||
categoryEraseBtn.SetClickable(false);
|
||||
updateBtn.SetClickable(false);
|
||||
}
|
||||
|
||||
|
||||
if(categoryCreateBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
categoryCreateBtn.ResetState();
|
||||
|
||||
|
||||
char new_category_name[256];
|
||||
sprintf (new_category_name, tr(Settings.new_category_name));
|
||||
OnScreenKeyboard(new_category_name, 256, false);
|
||||
|
||||
|
||||
if(strcasecmp(new_category_name,"NULL") != 0 )
|
||||
KategorieEinfuegen(new_category_name);
|
||||
}
|
||||
@ -157,7 +158,7 @@ int MenuSettings()
|
||||
if(AvailableCategory.categories.size() > 1)
|
||||
{
|
||||
string entferne_kategorie = eraseCategory();
|
||||
|
||||
|
||||
if( entferne_kategorie != "NULL" )
|
||||
{
|
||||
int choice = WindowPrompt(entferne_kategorie.c_str(), tr("Really remove?"), tr("Yes"), tr("No"));
|
||||
@ -178,7 +179,7 @@ int MenuSettings()
|
||||
{
|
||||
for(int i = 0; i < (signed)strlen(buffer); i++)
|
||||
buffer[i] = '\0';
|
||||
|
||||
|
||||
OnScreenCodeboard(buffer, 4);
|
||||
// wenn eingabe richtig
|
||||
if(strcasecmp(buffer, Settings.code) == 0 )
|
||||
@ -205,21 +206,21 @@ int MenuSettings()
|
||||
else if(updateBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
updateBtn.ResetState();
|
||||
|
||||
|
||||
string revnumber = checkUpdatePrompt();
|
||||
|
||||
|
||||
if(revnumber != "NULL")
|
||||
{
|
||||
char title[100];
|
||||
if(revnumber == "Beta")
|
||||
sprintf(title, "%s ( rev.%i %s Beta )", tr("Update"), SvnRev(), "»");
|
||||
sprintf(title, "%s ( rev.%i %s Beta )", tr("Update"), SvnRev(), "»");
|
||||
else
|
||||
sprintf(title, "%s ( rev.%i %s rev.%s )", tr("Update"), SvnRev(), "»", revnumber.c_str());
|
||||
|
||||
sprintf(title, "%s ( rev.%i %s rev.%s )", tr("Update"), SvnRev(), "»", revnumber.c_str());
|
||||
|
||||
// auflisten
|
||||
string version_text = NewVersionsText();
|
||||
vector <string> versions_text;
|
||||
|
||||
|
||||
int strpos = version_text.find("//rev");
|
||||
while(strpos != -1)
|
||||
{
|
||||
@ -232,18 +233,18 @@ int MenuSettings()
|
||||
}
|
||||
else
|
||||
versions_text.push_back(version_text.substr(0, version_text.find("end") -2));
|
||||
|
||||
|
||||
strpos = version_text.find("//rev");
|
||||
}
|
||||
|
||||
|
||||
char revinfo[10];
|
||||
if(revnumber == "Beta")
|
||||
sprintf(revinfo, "rev_Beta");
|
||||
else
|
||||
sprintf(revinfo, "rev%i", atoi(revnumber.c_str()));
|
||||
|
||||
|
||||
string text;
|
||||
|
||||
|
||||
for(int i=0; i < (signed)versions_text.size(); i++)
|
||||
{
|
||||
if(strcasecmp(versions_text[i].substr(0, versions_text[i].find(":")).c_str(), revinfo) == 0)
|
||||
@ -252,9 +253,9 @@ int MenuSettings()
|
||||
text = versions_text[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
revtext(text.c_str());
|
||||
|
||||
|
||||
// anzeigen
|
||||
int choice = WindowPrompt(title, tr("Do you want to update now ?"), tr("Yes"), tr("No"));
|
||||
if(choice == 1)
|
||||
@ -267,6 +268,9 @@ int MenuSettings()
|
||||
}
|
||||
else if(backBtn.GetState() == STATE_CLICKED)
|
||||
menu = MENU_MAIN;
|
||||
|
||||
if(runaway == true)
|
||||
menu = MENU_MAIN;
|
||||
}
|
||||
|
||||
HaltGui();
|
||||
|
@ -14,13 +14,15 @@ extern GuiWindow * mainWindow;
|
||||
extern void ResumeGui();
|
||||
extern void HaltGui();
|
||||
|
||||
extern bool runaway;
|
||||
|
||||
/****************************************************************************
|
||||
* MenuSettings
|
||||
***************************************************************************/
|
||||
int MenuSettingsDisplay()
|
||||
{
|
||||
int menu = MENU_NONE;
|
||||
|
||||
|
||||
int top = Settings.top;
|
||||
int bottom = Settings.bottom;
|
||||
int left = Settings.left;
|
||||
@ -37,21 +39,21 @@ int MenuSettingsDisplay()
|
||||
|
||||
// Buttons Data
|
||||
GuiImageData textBtn(keyboard_textbox_png);
|
||||
|
||||
|
||||
GuiImageData btn(Theme.button_small);
|
||||
GuiImageData btn_over(Theme.button_small_focus);
|
||||
|
||||
|
||||
GuiImageData plusBtnData(Theme.scrollbar_arrowup);
|
||||
GuiImageData plusBtnOverData(Theme.scrollbar_arrowup_over);
|
||||
GuiImageData minusBtnData(Theme.scrollbar_arrowdown);
|
||||
GuiImageData minusBtnOverData(Theme.scrollbar_arrowdown_over);
|
||||
|
||||
// Buttons
|
||||
|
||||
// Buttons
|
||||
GuiImage backBtnImg(&btn);
|
||||
GuiImage backBtnImgOver(&btn_over);
|
||||
GuiImage saveBtnImg(&btn);
|
||||
GuiImage saveBtnImgOver(&btn_over);
|
||||
|
||||
|
||||
GuiImage plusTopBtnImg(&plusBtnData);
|
||||
GuiImage plusTopBtnImgOver(&plusBtnOverData);
|
||||
GuiImage minusTopBtnImg(&minusBtnData);
|
||||
@ -68,11 +70,11 @@ int MenuSettingsDisplay()
|
||||
GuiImage plusRightBtnImgOver(&plusBtnOverData);
|
||||
GuiImage minusRightBtnImg(&minusBtnData);
|
||||
GuiImage minusRightBtnImgOver(&minusBtnOverData);
|
||||
|
||||
|
||||
|
||||
|
||||
char number[4];
|
||||
int y = 130;
|
||||
|
||||
|
||||
// oben
|
||||
GuiImage textTopBtnImg(&textBtn);
|
||||
textTopBtnImg.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
|
||||
@ -89,7 +91,7 @@ int MenuSettingsDisplay()
|
||||
plusTopBtn.SetImage(&plusTopBtnImg);
|
||||
plusTopBtn.SetImageOver(&plusTopBtnImgOver);
|
||||
plusTopBtn.SetTrigger(&trigA);
|
||||
|
||||
|
||||
sprintf(number, "%i", top);
|
||||
GuiText topNr(number, 30, (GXColor){0, 0, 0, 255});
|
||||
topNr.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
|
||||
@ -101,9 +103,9 @@ int MenuSettingsDisplay()
|
||||
minusTopBtn.SetImage(&minusTopBtnImg);
|
||||
minusTopBtn.SetImageOver(&minusTopBtnImgOver);
|
||||
minusTopBtn.SetTrigger(&trigA);
|
||||
|
||||
|
||||
y += 50;
|
||||
|
||||
|
||||
// unten
|
||||
GuiImage textBottomBtnImg(&textBtn);
|
||||
textBottomBtnImg.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
|
||||
@ -120,7 +122,7 @@ int MenuSettingsDisplay()
|
||||
plusBottomBtn.SetImage(&plusBottomBtnImg);
|
||||
plusBottomBtn.SetImageOver(&plusBottomBtnImgOver);
|
||||
plusBottomBtn.SetTrigger(&trigA);
|
||||
|
||||
|
||||
sprintf(number, "%i", bottom);
|
||||
GuiText bottomNr(number, 30, (GXColor){0, 0, 0, 255});
|
||||
bottomNr.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
|
||||
@ -132,7 +134,7 @@ int MenuSettingsDisplay()
|
||||
minusBottomBtn.SetImage(&minusBottomBtnImg);
|
||||
minusBottomBtn.SetImageOver(&minusBottomBtnImgOver);
|
||||
minusBottomBtn.SetTrigger(&trigA);
|
||||
|
||||
|
||||
y += 50;
|
||||
|
||||
// links
|
||||
@ -151,7 +153,7 @@ int MenuSettingsDisplay()
|
||||
plusLeftBtn.SetImage(&plusLeftBtnImg);
|
||||
plusLeftBtn.SetImageOver(&plusLeftBtnImgOver);
|
||||
plusLeftBtn.SetTrigger(&trigA);
|
||||
|
||||
|
||||
sprintf(number, "%i", left);
|
||||
GuiText leftNr(number, 30, (GXColor){0, 0, 0, 255});
|
||||
leftNr.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
|
||||
@ -163,9 +165,9 @@ int MenuSettingsDisplay()
|
||||
minusLeftBtn.SetImage(&minusLeftBtnImg);
|
||||
minusLeftBtn.SetImageOver(&minusLeftBtnImgOver);
|
||||
minusLeftBtn.SetTrigger(&trigA);
|
||||
|
||||
|
||||
y += 50;
|
||||
|
||||
|
||||
// rechts
|
||||
GuiImage textRightBtnImg(&textBtn);
|
||||
textRightBtnImg.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
|
||||
@ -182,7 +184,7 @@ int MenuSettingsDisplay()
|
||||
plusRightBtn.SetImage(&plusRightBtnImg);
|
||||
plusRightBtn.SetImageOver(&plusRightBtnImgOver);
|
||||
plusRightBtn.SetTrigger(&trigA);
|
||||
|
||||
|
||||
sprintf(number, "%i", right);
|
||||
GuiText rightNr(number, 30, (GXColor){0, 0, 0, 255});
|
||||
rightNr.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
|
||||
@ -194,7 +196,7 @@ int MenuSettingsDisplay()
|
||||
minusRightBtn.SetImage(&minusRightBtnImg);
|
||||
minusRightBtn.SetImageOver(&minusRightBtnImgOver);
|
||||
minusRightBtn.SetTrigger(&trigA);
|
||||
|
||||
|
||||
GuiText backBtnTxt(tr("Stop"), 22, (GXColor){Theme.button_small_text_1, Theme.button_small_text_2, Theme.button_small_text_3, 255});
|
||||
GuiButton backBtn(btn.GetWidth(), btn.GetHeight());
|
||||
backBtn.SetAlignment(ALIGN_RIGHT, ALIGN_BOTTOM);
|
||||
@ -219,25 +221,25 @@ int MenuSettingsDisplay()
|
||||
HaltGui();
|
||||
GuiWindow w(screenwidth, screenheight);
|
||||
w.Append(&titleTxt);
|
||||
|
||||
|
||||
w.Append(&textTopBtnImg);
|
||||
w.Append(&topTxt);
|
||||
w.Append(&plusTopBtn);
|
||||
w.Append(&topNr);
|
||||
w.Append(&minusTopBtn);
|
||||
|
||||
|
||||
w.Append(&textBottomBtnImg);
|
||||
w.Append(&bottomTxt);
|
||||
w.Append(&plusBottomBtn);
|
||||
w.Append(&bottomNr);
|
||||
w.Append(&minusBottomBtn);
|
||||
|
||||
|
||||
w.Append(&textLeftBtnImg);
|
||||
w.Append(&lefttTxt);
|
||||
w.Append(&plusLeftBtn);
|
||||
w.Append(&leftNr);
|
||||
w.Append(&minusLeftBtn);
|
||||
|
||||
|
||||
w.Append(&textRightBtnImg);
|
||||
w.Append(&rightTxt);
|
||||
w.Append(&plusRightBtn);
|
||||
@ -254,11 +256,11 @@ int MenuSettingsDisplay()
|
||||
int display = DISPLAY_NONE;
|
||||
bool add = -1;
|
||||
int temp_number = 0;
|
||||
|
||||
|
||||
while(menu == MENU_NONE)
|
||||
{
|
||||
usleep(100);
|
||||
|
||||
|
||||
// oben
|
||||
if(plusTopBtn.GetState() == STATE_CLICKED || minusTopBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
@ -266,13 +268,13 @@ int MenuSettingsDisplay()
|
||||
add = true;
|
||||
else
|
||||
add = false;
|
||||
|
||||
|
||||
plusTopBtn.ResetState();
|
||||
minusTopBtn.ResetState();
|
||||
display = DISPLAY_TOP;
|
||||
temp_number = top;
|
||||
}
|
||||
|
||||
|
||||
// unten
|
||||
if(plusBottomBtn.GetState() == STATE_CLICKED || minusBottomBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
@ -280,13 +282,13 @@ int MenuSettingsDisplay()
|
||||
add = true;
|
||||
else
|
||||
add = false;
|
||||
|
||||
|
||||
plusBottomBtn.ResetState();
|
||||
minusBottomBtn.ResetState();
|
||||
display = DISPLAY_BOTTOM;
|
||||
temp_number = bottom;
|
||||
}
|
||||
|
||||
|
||||
// links
|
||||
if(plusLeftBtn.GetState() == STATE_CLICKED || minusLeftBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
@ -294,13 +296,13 @@ int MenuSettingsDisplay()
|
||||
add = true;
|
||||
else
|
||||
add = false;
|
||||
|
||||
|
||||
plusLeftBtn.ResetState();
|
||||
minusLeftBtn.ResetState();
|
||||
display = DISPLAY_LEFT;
|
||||
temp_number = left;
|
||||
}
|
||||
|
||||
|
||||
// rechts
|
||||
if(plusRightBtn.GetState() == STATE_CLICKED || minusRightBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
@ -308,13 +310,13 @@ int MenuSettingsDisplay()
|
||||
add = true;
|
||||
else
|
||||
add = false;
|
||||
|
||||
|
||||
plusRightBtn.ResetState();
|
||||
minusRightBtn.ResetState();
|
||||
display = DISPLAY_RIGHT;
|
||||
temp_number = right;
|
||||
}
|
||||
|
||||
|
||||
if(display != DISPLAY_NONE)
|
||||
{
|
||||
while(WPAD_ButtonsHeld(0) & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A) || PAD_ButtonsHeld(0) & PAD_BUTTON_A)
|
||||
@ -323,40 +325,40 @@ int MenuSettingsDisplay()
|
||||
temp_number++;
|
||||
else
|
||||
temp_number--;
|
||||
|
||||
|
||||
sprintf(number, "%i", temp_number);
|
||||
|
||||
|
||||
switch (display)
|
||||
{
|
||||
case DISPLAY_TOP:
|
||||
top = temp_number;
|
||||
topNr.SetText(number);
|
||||
break;
|
||||
|
||||
|
||||
case DISPLAY_BOTTOM:
|
||||
bottom = temp_number;
|
||||
bottomNr.SetText(number);
|
||||
break;
|
||||
|
||||
|
||||
case DISPLAY_LEFT:
|
||||
left = temp_number;
|
||||
leftNr.SetText(number);
|
||||
break;
|
||||
|
||||
|
||||
case DISPLAY_RIGHT:
|
||||
right = temp_number;
|
||||
rightNr.SetText(number);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
stretch(top, bottom, left, right);
|
||||
|
||||
|
||||
if(temp_number == 0)
|
||||
usleep(500000);
|
||||
else
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
|
||||
if(add && display == DISPLAY_TOP)
|
||||
plusTopBtn.SetState(STATE_SELECTED);
|
||||
else if(!add && display == DISPLAY_TOP)
|
||||
@ -373,10 +375,10 @@ int MenuSettingsDisplay()
|
||||
plusRightBtn.SetState(STATE_SELECTED);
|
||||
else if(!add && display == DISPLAY_RIGHT)
|
||||
minusRightBtn.SetState(STATE_SELECTED);
|
||||
|
||||
|
||||
display = DISPLAY_NONE;
|
||||
}
|
||||
|
||||
|
||||
if(backBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
Options.temp_last_setting = 1;
|
||||
@ -390,7 +392,14 @@ int MenuSettingsDisplay()
|
||||
Settings.bottom = bottom;
|
||||
Settings.left = left;
|
||||
Settings.right = right;
|
||||
|
||||
|
||||
menu = MENU_SETTINGS_FILE;
|
||||
}
|
||||
|
||||
if(runaway == true)
|
||||
{
|
||||
Options.temp_last_setting = 1;
|
||||
stretch(Settings.top, Settings.bottom, Settings.left, Settings.right);
|
||||
menu = MENU_SETTINGS_FILE;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "libwiigui/gui.h"
|
||||
@ -19,6 +18,7 @@ extern void ResumeGui();
|
||||
extern void HaltGui();
|
||||
extern void HaltResumeGui();
|
||||
|
||||
extern bool runaway;
|
||||
int temp_last_category;
|
||||
int temp_slide_effect;
|
||||
int temp_apps;
|
||||
@ -480,7 +480,17 @@ int MenuSettingsFile()
|
||||
}
|
||||
|
||||
menu = MENU_SETTINGS;
|
||||
|
||||
}
|
||||
|
||||
if(runaway == true)
|
||||
{
|
||||
strcpy (Options.temp_code, Settings.code);
|
||||
Options.temp_network = Options.network;
|
||||
Options.temp_newrevtext = Options.newrevtext;
|
||||
menu = MENU_SETTINGS;
|
||||
}
|
||||
|
||||
}
|
||||
HaltGui();
|
||||
Options.temp_last_setting = 0;
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
|
||||
@ -6,6 +5,7 @@
|
||||
#include "main.h"
|
||||
#include "menu.h"
|
||||
#include "Prompts/prompts.h"
|
||||
#include "Network/network.h"
|
||||
|
||||
/*** Extern variables ***/
|
||||
extern GuiWindow * mainWindow;
|
||||
@ -15,22 +15,24 @@ extern void ResumeGui();
|
||||
extern void HaltGui();
|
||||
extern void HaltResumeGui();
|
||||
|
||||
extern bool runaway;
|
||||
|
||||
/****************************************************************************
|
||||
* MenuSettings
|
||||
***************************************************************************/
|
||||
int MenuSettingsNetwork()
|
||||
{
|
||||
int menu = MENU_NONE;
|
||||
|
||||
|
||||
int ret = -1;
|
||||
int i = 0;
|
||||
int focus = 0;
|
||||
|
||||
|
||||
int network = Options.temp_network;
|
||||
int newrevtext = Options.temp_newrevtext;
|
||||
|
||||
OptionList options;
|
||||
|
||||
|
||||
sprintf(options.name[i++], tr("Auto Connect"));
|
||||
sprintf(options.name[i++], tr("Update Info"));
|
||||
options.length = i;
|
||||
@ -85,7 +87,7 @@ int MenuSettingsNetwork()
|
||||
w.Append(&backBtn);
|
||||
mainWindow->Append(&w);
|
||||
mainWindow->Append(&optionBrowser);
|
||||
|
||||
|
||||
mainWindow->ChangeFocus(&optionBrowser);
|
||||
ResumeGui();
|
||||
|
||||
@ -93,9 +95,9 @@ int MenuSettingsNetwork()
|
||||
while(menu == MENU_NONE)
|
||||
{
|
||||
usleep(100);
|
||||
|
||||
|
||||
ret = optionBrowser.GetChangedOption();
|
||||
|
||||
|
||||
if(WPAD_ButtonsDown(0) & (WPAD_BUTTON_RIGHT | WPAD_CLASSIC_BUTTON_RIGHT) || PAD_ButtonsDown(0) & PAD_BUTTON_RIGHT)
|
||||
{
|
||||
change = 0;
|
||||
@ -108,7 +110,7 @@ int MenuSettingsNetwork()
|
||||
change = 1;
|
||||
network = change;
|
||||
break;
|
||||
|
||||
|
||||
case 1:
|
||||
change = newrevtext;
|
||||
change++;
|
||||
@ -119,7 +121,7 @@ int MenuSettingsNetwork()
|
||||
}
|
||||
HaltResumeGui();
|
||||
}
|
||||
|
||||
|
||||
if(WPAD_ButtonsDown(0) & (WPAD_BUTTON_LEFT | WPAD_CLASSIC_BUTTON_LEFT) || PAD_ButtonsDown(0) & PAD_BUTTON_LEFT)
|
||||
{
|
||||
change = 0;
|
||||
@ -132,7 +134,7 @@ int MenuSettingsNetwork()
|
||||
change = 0;
|
||||
network = change;
|
||||
break;
|
||||
|
||||
|
||||
case 1:
|
||||
change = newrevtext;
|
||||
change--;
|
||||
@ -143,27 +145,27 @@ int MenuSettingsNetwork()
|
||||
}
|
||||
HaltResumeGui();
|
||||
}
|
||||
|
||||
|
||||
if(change != -1)
|
||||
{
|
||||
change = -1;
|
||||
|
||||
|
||||
if(network == 0)
|
||||
sprintf (options.value[0], tr("No"));
|
||||
else
|
||||
sprintf (options.value[0], tr("Yes"));
|
||||
|
||||
|
||||
if(newrevtext == 0)
|
||||
sprintf (options.value[1], tr("No"));
|
||||
else
|
||||
sprintf (options.value[1], tr("Yes"));
|
||||
|
||||
|
||||
optionBrowser.TriggerUpdate();
|
||||
}
|
||||
|
||||
|
||||
if(optionBrowser.GetClickedOption() != -1)
|
||||
optionBrowser.TriggerUpdate();
|
||||
|
||||
|
||||
if(WPAD_ButtonsDown(0) & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B) || PAD_ButtonsDown(0) & PAD_BUTTON_B)
|
||||
{
|
||||
if(focus == 0)
|
||||
@ -178,20 +180,37 @@ int MenuSettingsNetwork()
|
||||
}
|
||||
HaltResumeGui();
|
||||
}
|
||||
|
||||
|
||||
if(okBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
Options.temp_last_setting = 1;
|
||||
if (Options.temp_network != network)
|
||||
{
|
||||
if(network == 1)
|
||||
{
|
||||
ResumeNetworkThread();
|
||||
}
|
||||
else
|
||||
{
|
||||
HaltNetworkThread();
|
||||
}
|
||||
}
|
||||
Options.temp_network = network;
|
||||
Options.temp_newrevtext = newrevtext;
|
||||
menu = MENU_SETTINGS_FILE;
|
||||
}
|
||||
|
||||
|
||||
if(backBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
Options.temp_last_setting = 1;
|
||||
menu = MENU_SETTINGS_FILE;
|
||||
}
|
||||
|
||||
if(runaway == true)
|
||||
{
|
||||
Options.temp_last_setting = 1;
|
||||
menu = MENU_SETTINGS_FILE;
|
||||
}
|
||||
}
|
||||
HaltGui();
|
||||
mainWindow->Remove(&optionBrowser);
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
|
||||
@ -16,6 +15,7 @@ extern void ResumeGui();
|
||||
extern void HaltGui();
|
||||
extern void HaltResumeGui();
|
||||
|
||||
extern bool runaway;
|
||||
bool theme_dl = false;
|
||||
|
||||
/****************************************************************************
|
||||
@ -25,14 +25,14 @@ bool theme_dl = false;
|
||||
int MenuSettingsTheme()
|
||||
{
|
||||
int menu = MENU_NONE;
|
||||
|
||||
|
||||
int ret = -1;
|
||||
int activated = -1;
|
||||
int i = 0;
|
||||
int focus = 0;
|
||||
|
||||
|
||||
OptionList options;
|
||||
|
||||
|
||||
sprintf(options.name[i], tr("STANDARD"));
|
||||
if(stricmp(Options.temp_theme.c_str(), tr("STANDARD")) == 0)
|
||||
{
|
||||
@ -53,7 +53,7 @@ int MenuSettingsTheme()
|
||||
if(stricmp(dirEntry->d_name, ".") != 0 && stricmp(dirEntry->d_name, "..") != 0)
|
||||
{
|
||||
sprintf(options.name[i], dirEntry->d_name);
|
||||
|
||||
|
||||
if(stricmp(Options.temp_theme.c_str(), dirEntry->d_name) == 0)
|
||||
{
|
||||
sprintf (options.value[i], tr("activated"));
|
||||
@ -61,7 +61,7 @@ int MenuSettingsTheme()
|
||||
}
|
||||
else
|
||||
sprintf (options.value[i], " ");
|
||||
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@ -134,7 +134,7 @@ int MenuSettingsTheme()
|
||||
w.Append(&backBtn);
|
||||
mainWindow->Append(&w);
|
||||
mainWindow->Append(&optionBrowser);
|
||||
|
||||
|
||||
mainWindow->ChangeFocus(&optionBrowser);
|
||||
ResumeGui();
|
||||
|
||||
@ -175,7 +175,7 @@ int MenuSettingsTheme()
|
||||
}
|
||||
HaltResumeGui();
|
||||
}
|
||||
|
||||
|
||||
if(downloadBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
downloadBtn.ResetState();
|
||||
@ -191,19 +191,25 @@ int MenuSettingsTheme()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(okBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
Options.temp_last_setting = 1;
|
||||
Options.temp_theme = options.name[activated];
|
||||
menu = MENU_SETTINGS_FILE;
|
||||
}
|
||||
|
||||
|
||||
if(backBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
Options.temp_last_setting = 1;
|
||||
menu = MENU_SETTINGS_FILE;
|
||||
}
|
||||
|
||||
if(runaway == true)
|
||||
{
|
||||
Options.temp_last_setting = 1;
|
||||
menu = MENU_SETTINGS_FILE;
|
||||
}
|
||||
}
|
||||
HaltGui();
|
||||
mainWindow->Remove(&optionBrowser);
|
||||
|
@ -59,10 +59,10 @@ void CheckVersion(void)
|
||||
{
|
||||
revs = (char*)file.data;
|
||||
free(file.data);
|
||||
|
||||
|
||||
if((signed)revs.find("\n") != -1)
|
||||
revs.erase(revs.find("\n"));
|
||||
|
||||
|
||||
Settings.checkrev = atoi(revs.c_str());
|
||||
}
|
||||
}
|
||||
@ -114,6 +114,14 @@ bool IsNetworkError(void)
|
||||
return networkerror;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Check that network thread is halted
|
||||
***************************************************************************/
|
||||
bool IsNetworkHalted(void)
|
||||
{
|
||||
return networkHalt;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Get network IP
|
||||
***************************************************************************/
|
||||
@ -170,10 +178,9 @@ static void * networkinitcallback(void *arg)
|
||||
{
|
||||
LWP_SetThreadPriority(networkthread, 0);
|
||||
firstRun = true;
|
||||
CheckVersion();
|
||||
}
|
||||
|
||||
CheckVersion();
|
||||
|
||||
usleep(200000);
|
||||
}
|
||||
return NULL;
|
||||
|
@ -30,6 +30,7 @@ void Initialize_Network(void);
|
||||
void DeInit_Network(void);
|
||||
bool IsNetworkInit(void);
|
||||
bool IsNetworkError(void);
|
||||
bool IsNetworkHalted(void);
|
||||
char * GetNetworkIP(void);
|
||||
void HaltNetworkThread();
|
||||
void ResumeNetworkThread();
|
||||
|
@ -1,15 +1,17 @@
|
||||
|
||||
#include <network.h>
|
||||
#include <ogcsys.h>
|
||||
#include <unistd.h>
|
||||
#include <zlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <ogc/lwp_watchdog.h>
|
||||
|
||||
#include "libwiigui/gui.h"
|
||||
#include "main.h"
|
||||
#include "BootHomebrew/BootHomebrew.h"
|
||||
#include "Prompts/prompts.h"
|
||||
#include "gecko.h"
|
||||
|
||||
#define READ_SIZE (1 << 10)
|
||||
#define READ_SIZE (1 << 10)
|
||||
|
||||
u8 *data = (u8 *)0x92000000;
|
||||
|
||||
@ -24,40 +26,93 @@ extern void HaltGui();
|
||||
|
||||
static lwp_t tcpthread = LWP_THREAD_NULL;
|
||||
static bool tcpHalt = true;
|
||||
char Argtemp[1024];
|
||||
|
||||
//read with timeout. Comes from postloader
|
||||
static int NetRead(int connection, u8 *buf, u32 len, u32 tout) // timeout in msec
|
||||
{
|
||||
u32 read = 0;
|
||||
s32 ret = 0;
|
||||
u32 t;
|
||||
|
||||
t = ticks_to_millisecs(gettime()) + tout;
|
||||
|
||||
while (read < len)
|
||||
{
|
||||
ret = net_read(connection, buf + read, len - read);
|
||||
|
||||
if (ret <= 0)
|
||||
usleep (10 * 1000);
|
||||
else
|
||||
read += ret;
|
||||
|
||||
if (ticks_to_millisecs(gettime()) > t)
|
||||
break;
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
// code to oport a socket; originally from bzs@bu-cs.bu.edu
|
||||
int oport(unsigned short portnum)
|
||||
{
|
||||
int s;
|
||||
struct sockaddr_in sa;
|
||||
int err;
|
||||
|
||||
net_init();
|
||||
memset(&sa, 0, sizeof(struct sockaddr_in)); /* clear our address */
|
||||
sa.sin_family= AF_INET; /* this is our host address */
|
||||
sa.sin_port= htons(portnum); /* this is our port number */
|
||||
sa.sin_addr.s_addr = net_gethostip();
|
||||
sa.sin_len = 8;
|
||||
if ((s= net_socket(AF_INET, SOCK_STREAM, 0)) < 0) /* create socket */
|
||||
return(-1);
|
||||
{
|
||||
gprintf("net_socket failed\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
int one = 1;
|
||||
err = net_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&one, sizeof(one));
|
||||
if (err < 0)
|
||||
{
|
||||
gprintf("net_setsockopt SO_REUSEADDR error");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
//this makes the read timeout if no data available
|
||||
/*
|
||||
int flags = net_fcntl(s, F_GETFL, 0);
|
||||
flags = net_fcntl(s, F_SETFL, flags|4); // Set non blocking
|
||||
*/
|
||||
|
||||
if (net_bind(s,(struct sockaddr *)&sa,8) < 0)
|
||||
{
|
||||
net_close(s);
|
||||
return(-1); /* bind address to socket */
|
||||
}
|
||||
|
||||
net_listen(s, 3); /* max # of queued connects */
|
||||
|
||||
/*
|
||||
u32 buflen = 8;
|
||||
int t = net_accept(s,(struct sockaddr *)&sa, &buflen);
|
||||
gprintf("Dummy net_accept returned %d\n",t);
|
||||
*/
|
||||
|
||||
return(s);
|
||||
}
|
||||
|
||||
// wait for a connection to occur on a socket created with oport()
|
||||
int get_connection(int s, struct sockaddr_in *sa)
|
||||
{
|
||||
{
|
||||
int t; /* socket of connection */
|
||||
// struct sockaddr_in sa;
|
||||
sa->sin_len = 8;
|
||||
sa->sin_family = AF_INET;
|
||||
u32 buflen = 8;
|
||||
t = net_accept(s,(struct sockaddr *)sa, &buflen);
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
debug("Incoming connection");
|
||||
printf("Incoming connection from %d.%d.%d.%d\n",
|
||||
(sa->sin_addr.s_addr >> 24) & 0xFF,
|
||||
@ -86,7 +141,10 @@ int read_data(int s, /* connected socket */
|
||||
buf += br; /* move buffer ptr for next read */
|
||||
}
|
||||
else if (br < 0) /* signal an error to the caller */
|
||||
{
|
||||
gprintf("NetRead failure\n");
|
||||
return br;
|
||||
}
|
||||
}
|
||||
return bcount;
|
||||
}
|
||||
@ -118,14 +176,14 @@ static void * tcp_callback(void *arg)
|
||||
u8 *bfr[READ_SIZE];
|
||||
bool compress = false;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
redo:
|
||||
|
||||
redo:
|
||||
s32 listen = oport(4299);
|
||||
while(1)
|
||||
while(1)
|
||||
{
|
||||
if(tcpHalt)
|
||||
{
|
||||
LWP_SuspendThread(tcpthread);
|
||||
LWP_SuspendThread(tcpthread);
|
||||
usleep(100);
|
||||
continue;
|
||||
}
|
||||
@ -134,13 +192,14 @@ static void * tcp_callback(void *arg)
|
||||
// Waiting for connection
|
||||
client = get_connection(listen, &addr);
|
||||
|
||||
gprintf("After get_connection\n");
|
||||
if(client > 0)
|
||||
{
|
||||
// client connected
|
||||
|
||||
|
||||
GuiImage * progressImg = new GuiImage(new GuiImageData(Theme.progress));
|
||||
progressImg->SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
|
||||
|
||||
|
||||
GXColor ImgColor[4];
|
||||
|
||||
ImgColor[0] = (GXColor){Theme.progressbar_color1_1, Theme.progressbar_color1_2, Theme.progressbar_color1_3, 200}; // oben links
|
||||
@ -148,21 +207,25 @@ static void * tcp_callback(void *arg)
|
||||
ImgColor[2] = (GXColor){Theme.progressbar_color2_1, Theme.progressbar_color2_2, Theme.progressbar_color2_3, 200}; // unten rechts
|
||||
ImgColor[3] = ImgColor[2]; // unten links
|
||||
|
||||
|
||||
|
||||
GuiImage * progressbarImg = new GuiImage(0, 38, (GXColor *) &ImgColor);
|
||||
progressbarImg->SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
|
||||
progressbarImg->SetPosition((screenwidth - progressImg->GetWidth()) /2 +36, 2);
|
||||
|
||||
|
||||
GuiText * PercentTxt = new GuiText("0%", 20, (GXColor){Theme.text_1, Theme.text_2, Theme.text_3, 255});
|
||||
PercentTxt->SetAlignment(ALIGN_RIGHT, ALIGN_MIDDLE);
|
||||
PercentTxt->SetPosition(-((screenwidth - progressImg->GetWidth()) /2 +36), 38);
|
||||
|
||||
|
||||
|
||||
float Percent = 0.0f;
|
||||
|
||||
//wait 2 milliseconds hopefully fixes the error we see
|
||||
//usleep (100000);
|
||||
gprintf("reading protocol id\n");
|
||||
int temp = read_data(client, (char *)&read, 4);
|
||||
if(temp < 0)
|
||||
{
|
||||
// printf("read_data() error while reading check\n");
|
||||
//printf("read_data() error while reading protocol id\n");
|
||||
net_close(client);
|
||||
net_close(listen);
|
||||
goto redo;
|
||||
@ -176,59 +239,74 @@ static void * tcp_callback(void *arg)
|
||||
mainWindow->Append(PercentTxt);
|
||||
ResumeGui();
|
||||
}
|
||||
|
||||
|
||||
if(read == 1212242008) // 1212242008 -> 48415858 -> HAXX -> wiiload
|
||||
{
|
||||
compress = true;
|
||||
// printf("HAXX\n");
|
||||
|
||||
//printf("HAXX\n");
|
||||
|
||||
gprintf("reading version\n");
|
||||
read_data(client, (char *)&read, 4);
|
||||
// int WIILOAD_VERSION_MAYOR = (u8)(((u16)(read >> 16)) >> 8);
|
||||
// int WIILOAD_VERSION_MINOR = (u8)(((u16)(read >> 16)) & 0xFF);
|
||||
// int a = (u8)(((u16)(read & 0xFFFF)) >> 8);
|
||||
// int b = (u8)(((u16)(read & 0xFFFF)) & 0xFF);
|
||||
|
||||
// printf("wiiload v%x.%x\n", WIILOAD_VERSION_MAYOR, WIILOAD_VERSION_MINOR);
|
||||
// printf("args %x08\n", read);
|
||||
// printf("args a=%x b=%x\n", a, b);
|
||||
|
||||
/*int WIILOAD_VERSION_MAYOR = (u8)(((u16)(read >> 16)) >> 8);
|
||||
int WIILOAD_VERSION_MINOR = (u8)(((u16)(read >> 16)) & 0xFF);
|
||||
int a = (u8)(((u16)(read & 0xFFFF)) >> 8);
|
||||
int b = (u8)(((u16)(read & 0xFFFF)) & 0xFF);
|
||||
|
||||
printf("wiiload v%x.%x\n", WIILOAD_VERSION_MAYOR, WIILOAD_VERSION_MINOR);
|
||||
printf("args %x08\n", read);
|
||||
printf("args a=%x b=%x\n", a, b);*/
|
||||
|
||||
gprintf("reading size\n");
|
||||
read_data(client, (char *)&size, 4);
|
||||
|
||||
gprintf("reading uncompressed size\n");
|
||||
read_data(client, (char *)&uncfilesize, 4);
|
||||
}
|
||||
else
|
||||
size = read;
|
||||
|
||||
|
||||
offset = 0;
|
||||
while(offset < size && (read = read_data(client, (char *)bfr, (size - offset) > READ_SIZE ? READ_SIZE : (size - offset))) > 0)
|
||||
{
|
||||
gprintf("finished reading block at offset %x\n",offset);
|
||||
memcpy(data + offset, bfr, READ_SIZE);
|
||||
offset += read;
|
||||
|
||||
|
||||
Percent = 100.0f * offset/size;
|
||||
progressbarImg->SetSize(Percent*3.27f, 38);
|
||||
|
||||
|
||||
char buffer[6];
|
||||
sprintf(buffer, "%i %%", (int)Percent);
|
||||
PercentTxt->SetText(buffer);
|
||||
}
|
||||
|
||||
// These are the arguments....
|
||||
int ret = NetRead(client, (u8 *) Argtemp, 1023, 250);
|
||||
Argtemp[ret] = 0;
|
||||
//gprintf("all arguments = %s\n",Argtemp);
|
||||
if (ret > 2 && Argtemp[ret - 1] == '\0' && Argtemp[ret - 2] == '\0') // Check if it is really an arg
|
||||
{
|
||||
CopyArgs((u8*)(Argtemp),ret);
|
||||
}
|
||||
|
||||
usleep(100000);
|
||||
net_close(client);
|
||||
net_close(listen);
|
||||
|
||||
|
||||
if(compress)
|
||||
{
|
||||
u8 *zdata = (u8 *) malloc(uncfilesize);
|
||||
if(!zdata)
|
||||
return NULL;
|
||||
|
||||
|
||||
uLongf zdatalen = uncfilesize;
|
||||
|
||||
|
||||
int res = uncompress (zdata, &zdatalen, data, (uLongf)size);
|
||||
|
||||
if (res != Z_OK)
|
||||
{
|
||||
free(zdata);
|
||||
// fprintf (stderr, "error decompressing data: %d\n", res);
|
||||
//fprintf (stderr, "error decompressing data: %d\n", res);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
@ -238,13 +316,13 @@ static void * tcp_callback(void *arg)
|
||||
// free(zdata);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CopyHomebrewMemory(data, 0, size);
|
||||
if(data)
|
||||
free(data);
|
||||
// if(zdata)
|
||||
// free(zdata);
|
||||
|
||||
//if(zdata)
|
||||
// free(zdata);
|
||||
|
||||
mainWindow->Remove(PercentTxt);
|
||||
mainWindow->Remove(progressbarImg);
|
||||
mainWindow->Remove(progressImg);
|
||||
@ -255,6 +333,10 @@ static void * tcp_callback(void *arg)
|
||||
wiiload = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
usleep(250 * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
280
source/Network/wiiload_gecko.cpp
Normal file
280
source/Network/wiiload_gecko.cpp
Normal file
@ -0,0 +1,280 @@
|
||||
|
||||
#include <network.h>
|
||||
#include <ogcsys.h>
|
||||
#include <unistd.h>
|
||||
#include <zlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <ogc/lwp_watchdog.h>
|
||||
|
||||
#include "libwiigui/gui.h"
|
||||
#include "main.h"
|
||||
#include "BootHomebrew/BootHomebrew.h"
|
||||
#include "Prompts/prompts.h"
|
||||
#include "gecko.h"
|
||||
|
||||
#define READ_SIZE (1 << 10)
|
||||
|
||||
u8 *gdata = (u8 *)0x92000000;
|
||||
|
||||
/*** Extern variables ***/
|
||||
extern GuiWindow * mainWindow;
|
||||
extern bool boot_buffer;
|
||||
extern bool wiiload;
|
||||
|
||||
/*** Extern functions ***/
|
||||
extern void ResumeGui();
|
||||
extern void HaltGui();
|
||||
|
||||
static lwp_t geckothread = LWP_THREAD_NULL;
|
||||
static bool geckoHalt = true;
|
||||
char GArgtemp[1024];
|
||||
|
||||
|
||||
int read_gecko_data(int s, /* connected socket */
|
||||
char *buf, /* pointer to the buffer */
|
||||
int n, /* number of characters (bytes) we want */
|
||||
u32 timeout /* maximum time of no reception */
|
||||
)
|
||||
{
|
||||
int bcount; /* counts bytes read */
|
||||
int br; /* bytes read this pass */
|
||||
u32 t;
|
||||
|
||||
t = ticks_to_millisecs(gettime()) + timeout;
|
||||
|
||||
bcount= 0;
|
||||
br= 0;
|
||||
while (bcount < n)
|
||||
{ /* loop until full buffer */
|
||||
if ((br= usb_recvbuffer_safe_ex(s,buf,n-bcount,100)) > 0)
|
||||
{
|
||||
bcount += br; /* increment byte counter */
|
||||
buf += br; /* move buffer ptr for next read */
|
||||
|
||||
}
|
||||
else if (br < 0) /* signal an error to the caller */
|
||||
{
|
||||
gprintf("GeckoRead failure\n");
|
||||
return br;
|
||||
}
|
||||
if (ticks_to_millisecs(gettime()) > t)
|
||||
return 0;
|
||||
|
||||
}
|
||||
return bcount;
|
||||
}
|
||||
|
||||
void ResumeGeckoThread()
|
||||
{
|
||||
if(geckoHalt)
|
||||
{
|
||||
geckoHalt = false;
|
||||
LWP_ResumeThread(geckothread);
|
||||
}
|
||||
}
|
||||
|
||||
void HaltGeckoThread()
|
||||
{
|
||||
if(!geckoHalt)
|
||||
{
|
||||
geckoHalt = true;
|
||||
|
||||
// wait for thread to finish
|
||||
while(!LWP_ThreadIsSuspended(geckothread))
|
||||
usleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
static void * gecko_l_callback(void *arg)
|
||||
{
|
||||
u32 offset, read, size, channel, uncfilesize;
|
||||
u8 *bfr[READ_SIZE];
|
||||
u32 tms;
|
||||
bool compress = false;
|
||||
|
||||
channel = EXI_CHANNEL_1;
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(geckoHalt)
|
||||
{
|
||||
LWP_SuspendThread(geckothread);
|
||||
usleep(100);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
//gprintf("wiiload_gecko thread running\n");
|
||||
int temp = usb_recvbuffer_safe_ex(channel,(char *)&read,4,100);
|
||||
if(temp == 4)
|
||||
{
|
||||
|
||||
gprintf("4 bytes received from usb buffer\n");
|
||||
GuiImage * progressImg = new GuiImage(new GuiImageData(Theme.progress));
|
||||
progressImg->SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
|
||||
|
||||
GXColor ImgColor[4];
|
||||
|
||||
ImgColor[0] = (GXColor){Theme.progressbar_color1_1, Theme.progressbar_color1_2, Theme.progressbar_color1_3, 200}; // oben links
|
||||
ImgColor[1] = ImgColor[0]; // oben rechts
|
||||
ImgColor[2] = (GXColor){Theme.progressbar_color2_1, Theme.progressbar_color2_2, Theme.progressbar_color2_3, 200}; // unten rechts
|
||||
ImgColor[3] = ImgColor[2]; // unten links
|
||||
|
||||
|
||||
GuiImage * progressbarImg = new GuiImage(0, 38, (GXColor *) &ImgColor);
|
||||
progressbarImg->SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
|
||||
progressbarImg->SetPosition((screenwidth - progressImg->GetWidth()) /2 +36, 2);
|
||||
|
||||
GuiText * PercentTxt = new GuiText("0%", 20, (GXColor){Theme.text_1, Theme.text_2, Theme.text_3, 255});
|
||||
PercentTxt->SetAlignment(ALIGN_RIGHT, ALIGN_MIDDLE);
|
||||
PercentTxt->SetPosition(-((screenwidth - progressImg->GetWidth()) /2 +36), 38);
|
||||
|
||||
|
||||
float Percent = 0.0f;
|
||||
|
||||
HaltGui();
|
||||
mainWindow->SetState(STATE_DISABLED);
|
||||
mainWindow->Append(progressImg);
|
||||
mainWindow->Append(progressbarImg);
|
||||
mainWindow->Append(PercentTxt);
|
||||
ResumeGui();
|
||||
|
||||
if(read == 1212242008) // 1212242008 -> 48415858 -> HAXX -> wiiload
|
||||
{
|
||||
compress = true;
|
||||
// printf("HAXX\n");
|
||||
|
||||
gprintf("reading version\n");
|
||||
|
||||
read_gecko_data(channel, (char *)&read, 4,1000);
|
||||
// int WIILOAD_VERSION_MAYOR = (u8)(((u16)(read >> 16)) >> 8);
|
||||
// int WIILOAD_VERSION_MINOR = (u8)(((u16)(read >> 16)) & 0xFF);
|
||||
// int a = (u8)(((u16)(read & 0xFFFF)) >> 8);
|
||||
// int b = (u8)(((u16)(read & 0xFFFF)) & 0xFF);
|
||||
|
||||
// printf("wiiload v%x.%x\n", WIILOAD_VERSION_MAYOR, WIILOAD_VERSION_MINOR);
|
||||
// printf("args %x08\n", read);
|
||||
// printf("args a=%x b=%x\n", a, b);
|
||||
|
||||
gprintf("reading size\n");
|
||||
|
||||
read_gecko_data(channel, (char *)&size, 4, 1000);
|
||||
|
||||
gprintf("reading uncompressed size\n");
|
||||
|
||||
read_gecko_data(channel, (char *)&uncfilesize, 4, 1000);
|
||||
}
|
||||
else
|
||||
size = read;
|
||||
|
||||
offset = 0;
|
||||
while(offset < size && (read = read_gecko_data(channel, (char *)bfr, (size - offset) > READ_SIZE ? READ_SIZE : (size - offset), 2000)) > 0)
|
||||
{
|
||||
gprintf("finished reading block at offset %x\n",offset);
|
||||
memcpy(gdata + offset, bfr, READ_SIZE);
|
||||
offset += read;
|
||||
|
||||
Percent = 100.0f * offset/size;
|
||||
progressbarImg->SetSize(Percent*3.27f, 38);
|
||||
|
||||
char buffer[6];
|
||||
sprintf(buffer, "%i %%", (int)Percent);
|
||||
PercentTxt->SetText(buffer);
|
||||
}
|
||||
if (offset >= size)
|
||||
{
|
||||
//again, free gift from postloader
|
||||
|
||||
// These are the arguments....
|
||||
tms = ticks_to_millisecs(gettime());
|
||||
gprintf("timer1 = %d\n",tms);
|
||||
int ret = read_gecko_data(channel, (char *) (GArgtemp), 1023, 1000);
|
||||
tms = ticks_to_millisecs(gettime());
|
||||
gprintf("timer2 = %d\n",tms);
|
||||
GArgtemp[ret] = 0;
|
||||
//gprintf("all arguments = %s\n",GArgtemp);
|
||||
if (ret > 2 && GArgtemp[ret - 1] == '\0' && GArgtemp[ret - 2] == '\0') // Check if it is really an arg
|
||||
{
|
||||
CopyArgs((u8*)(GArgtemp),ret);
|
||||
}
|
||||
usleep(100000);
|
||||
if(compress)
|
||||
{
|
||||
u8 *zdata = (u8 *) malloc(uncfilesize);
|
||||
if(!zdata)
|
||||
return NULL;
|
||||
|
||||
uLongf zdatalen = uncfilesize;
|
||||
|
||||
int res = uncompress (zdata, &zdatalen, gdata, (uLongf)size);
|
||||
|
||||
if (res != Z_OK)
|
||||
{
|
||||
free(zdata);
|
||||
// fprintf (stderr, "error decompressing data: %d\n", res);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
gdata = zdata;
|
||||
size = zdatalen;
|
||||
// free(zdata);
|
||||
}
|
||||
}
|
||||
|
||||
CopyHomebrewMemory(gdata, 0, size);
|
||||
if(gdata)
|
||||
free(gdata);
|
||||
// if(zdata)
|
||||
// free(zdata);
|
||||
|
||||
mainWindow->Remove(PercentTxt);
|
||||
mainWindow->Remove(progressbarImg);
|
||||
mainWindow->Remove(progressImg);
|
||||
mainWindow->SetState(STATE_DEFAULT);
|
||||
ResumeGui();
|
||||
|
||||
boot_buffer = true;
|
||||
wiiload = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
//receive timeout
|
||||
//we shouldn't hang, but resume
|
||||
//hanging is unprofessional
|
||||
mainWindow->Remove(PercentTxt);
|
||||
mainWindow->Remove(progressbarImg);
|
||||
mainWindow->Remove(progressImg);
|
||||
mainWindow->SetState(STATE_DEFAULT);
|
||||
ResumeGui();
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
usleep(250 * 1000);
|
||||
//gprintf(".");
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void InitGeckoThread()
|
||||
{
|
||||
LWP_CreateThread (&geckothread, gecko_l_callback, NULL, NULL, 32768, 60);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* ShutdownThread
|
||||
***************************************************************************/
|
||||
void ShutdownGeckoThread()
|
||||
{
|
||||
if(geckothread != LWP_THREAD_NULL)
|
||||
{
|
||||
ResumeGeckoThread();
|
||||
LWP_JoinThread (geckothread, NULL);
|
||||
geckothread = LWP_THREAD_NULL;
|
||||
}
|
||||
}
|
5
source/Network/wiiload_gecko.h
Normal file
5
source/Network/wiiload_gecko.h
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
void HaltGeckoThread();
|
||||
void ResumeGeckoThread();
|
||||
void InitGeckoThread();
|
||||
void ShutdownGeckoThread();
|
@ -3,6 +3,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "gecko.h"
|
||||
|
||||
#include "RuntimeIOSPatch.h"
|
||||
|
||||
@ -30,7 +31,7 @@ const u8 addticket_patch[] = { 0xE0 };
|
||||
|
||||
u32 apply_patch(const char *name, const u8 *old, u32 old_size, const u8 *patch, u32 patch_size, u32 patch_offset)
|
||||
{
|
||||
// printf("Applying patch %s.....", name);
|
||||
gprintf("Applying patch %s.....", name);
|
||||
u8 *ptr = (u8 *) 0x93400000;
|
||||
u32 i, found = 0;
|
||||
u8 *start;
|
||||
@ -48,11 +49,12 @@ u32 apply_patch(const char *name, const u8 *old, u32 old_size, const u8 *patch,
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
/* if(found)
|
||||
printf("Patched\n");
|
||||
|
||||
if(found)
|
||||
gprintf("Patched\n");
|
||||
else
|
||||
printf("\n");
|
||||
*/
|
||||
gprintf("\n");
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
#include "main.h"
|
||||
#include <dirent.h>
|
||||
#include <sstream>
|
||||
#include "gecko.h"
|
||||
|
||||
extern const u8 banner_bin[];
|
||||
extern const u32 banner_bin_size;
|
||||
@ -9,12 +9,12 @@ extern const u32 banner_bin_size;
|
||||
bool folder_exists()
|
||||
{
|
||||
bool create = false;
|
||||
|
||||
|
||||
if(Settings.device_dat == "sd1" && SDCard_Inserted())
|
||||
create = true;
|
||||
else if(Settings.device_dat == "usb1" && USBDevice_Inserted())
|
||||
create = true;
|
||||
|
||||
|
||||
if(create)
|
||||
{
|
||||
// speicher ordner erstellen
|
||||
@ -33,7 +33,7 @@ bool folder_exists()
|
||||
else
|
||||
{
|
||||
if (mkdir((Settings.device_dat + ":/config/HBF").c_str(), 0777) != -1)
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -55,30 +55,30 @@ void save()
|
||||
|
||||
// create save banner
|
||||
string save_banner_path = "/title/00010001/54484246/data/banner.bin";
|
||||
|
||||
|
||||
file = ISFS_Open(save_banner_path.c_str(), ISFS_OPEN_READ);
|
||||
if (file <= 0)
|
||||
{
|
||||
ISFS_CreateFile(save_banner_path.c_str(), 0, 3, 3, 3);
|
||||
|
||||
|
||||
file = ISFS_Open(save_banner_path.c_str(), ISFS_OPEN_RW);
|
||||
if (file > 0)
|
||||
ISFS_Write(file, banner_bin, banner_bin_size);
|
||||
|
||||
|
||||
ISFS_Close(file);
|
||||
}
|
||||
ISFS_Close(file);
|
||||
|
||||
// save settings
|
||||
ISFS_Delete(Settings.settings_dat.c_str());
|
||||
|
||||
|
||||
ISFS_CreateFile(Settings.settings_dat.c_str(), 0, 3, 3, 3);
|
||||
file = ISFS_Open(Settings.settings_dat.c_str(), ISFS_OPEN_RW);
|
||||
if (file > 0)
|
||||
{
|
||||
int last_category;
|
||||
string last_category_name;
|
||||
|
||||
|
||||
if(Options.last_category > 0)
|
||||
{
|
||||
last_category = 1;
|
||||
@ -114,24 +114,29 @@ void save()
|
||||
save_settings << "bottom = \"" << Settings.bottom << "\"" << endl;
|
||||
save_settings << "left = \"" << Settings.left << "\"" << endl;
|
||||
save_settings << "right = \"" << Settings.right << "\"" << endl;
|
||||
|
||||
|
||||
char *pbuf = NULL;
|
||||
unsigned int psize = save_settings.str().size();
|
||||
|
||||
pbuf = (char*)memalign( 32, sizeof(char) *psize );
|
||||
memset( pbuf, 0, sizeof(char) *psize );
|
||||
|
||||
|
||||
char text[psize];
|
||||
sprintf(text, "%s", save_settings.str().c_str());
|
||||
strcpy(pbuf, text);
|
||||
|
||||
|
||||
ISFS_Write(file, pbuf, sizeof(char) *psize);
|
||||
}
|
||||
else
|
||||
{
|
||||
gprintf("ERROR: ISFS: opening %s failed\n", Settings.settings_dat.c_str());
|
||||
}
|
||||
|
||||
ISFS_Close(file);
|
||||
|
||||
|
||||
// save appios
|
||||
ISFS_Delete(Settings.ios_dat.c_str());
|
||||
|
||||
|
||||
ISFS_CreateFile(Settings.ios_dat.c_str(), 0, 3, 3, 3);
|
||||
file = ISFS_Open(Settings.ios_dat.c_str(), ISFS_OPEN_RW);
|
||||
if (file > 0)
|
||||
@ -145,15 +150,15 @@ void save()
|
||||
|
||||
pbuf = (char*)memalign( 32, sizeof(char) *psize );
|
||||
memset( pbuf, 0, sizeof(char) *psize );
|
||||
|
||||
|
||||
char text[psize];
|
||||
sprintf(text, "%s", save_appios.str().c_str());
|
||||
strcpy(pbuf, text);
|
||||
|
||||
|
||||
ISFS_Write(file, pbuf, sizeof(char) *psize);
|
||||
}
|
||||
ISFS_Close(file);
|
||||
|
||||
|
||||
// save category
|
||||
AvailableCategorySave(Settings.dir_dat);
|
||||
}
|
||||
|
85
source/ahbfix.cpp
Normal file
85
source/ahbfix.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
/*--------------------------------------------------------------
|
||||
Copyright (C) 2011 Tueidj
|
||||
|
||||
This software falls under the GPL license
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
-------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gccore.h>
|
||||
#include <ogc/machine/processor.h>
|
||||
#include "gecko.h"
|
||||
|
||||
|
||||
#define CHECK_AHB 0x0D800064
|
||||
#define MEM2_PROT 0x0D8B420A
|
||||
#define ES_MODULE_START (u16*)0x939F0000
|
||||
|
||||
static const u16 ticket_check[] = {
|
||||
0x685B, // ldr r3,[r3,#4] ; get TMD pointer
|
||||
0x22EC, 0x0052, // movls r2, 0x1D8
|
||||
0x189B, // adds r3, r3, r2 ; add offset of access rights field in TMD
|
||||
0x681B, // ldr r3, [r3] ; load access rights (haxxme!)
|
||||
0x4698, // mov r8, r3 ; store it for the DVD video bitcheck later
|
||||
0x07DB // lsls r3, r3, #31; check AHBPROT bit
|
||||
};
|
||||
|
||||
s32 Patch_ahbprot(void)
|
||||
{
|
||||
// patch HID4 write in HBC stub - this should be done when the extra HID4 bits are turned on
|
||||
*(u32*)0x80002174 = 0x60000000;
|
||||
|
||||
if (read32(CHECK_AHB) != -1)
|
||||
{
|
||||
gprintf("AHBPROT doesn't seem to be disabled.\n");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
u16 *patchme;
|
||||
write16(MEM2_PROT, 2);
|
||||
for (patchme=ES_MODULE_START; patchme < ES_MODULE_START+0x4000; patchme++)
|
||||
{
|
||||
if (!memcmp(patchme, ticket_check, sizeof(ticket_check)))
|
||||
{
|
||||
gprintf("Found TMD Access rights check at %p\n", patchme);
|
||||
// write16/uncached poke doesn't work for this. Go figure.
|
||||
patchme[4] = 0x23FF; // li r3, 0xFF
|
||||
DCFlushRange(patchme+4, 2);
|
||||
return true;
|
||||
//break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
IOS_ReloadIOS(58); // MEM2 protection re-enabled here
|
||||
dprintf("Loaded a new IOS.\n");
|
||||
if (read32(CHECK_AHB) != -1)
|
||||
dprintf("AHBPROT doesn't seem to be disabled.\n");
|
||||
else
|
||||
dprintf("AHBPROT is disabled (TADA!).\n");
|
||||
*/
|
1
source/ahbfix.h
Normal file
1
source/ahbfix.h
Normal file
@ -0,0 +1 @@
|
||||
s32 Patch_ahbprot(void);
|
119
source/gecko.c
Normal file
119
source/gecko.c
Normal file
@ -0,0 +1,119 @@
|
||||
#include <gccore.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <sys/iosupport.h>
|
||||
|
||||
/* init-globals */
|
||||
static bool geckoinit = false;
|
||||
|
||||
#ifndef NO_DEBUG
|
||||
#include <stdarg.h>
|
||||
|
||||
void gprintf(const char *format, ...)
|
||||
{
|
||||
if (!geckoinit)
|
||||
return;
|
||||
|
||||
char * tmp = NULL;
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
if((vasprintf(&tmp, format, va) >= 0) && tmp)
|
||||
{
|
||||
usb_sendbuffer(1, tmp, strlen(tmp));
|
||||
}
|
||||
va_end(va);
|
||||
|
||||
if(tmp)
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
bool InitGecko()
|
||||
{
|
||||
u32 geckoattached = usb_isgeckoalive(EXI_CHANNEL_1);
|
||||
if (geckoattached)
|
||||
{
|
||||
usb_flush(EXI_CHANNEL_1);
|
||||
geckoinit = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
char ascii(char s)
|
||||
{
|
||||
if (s < 0x20) return '.';
|
||||
if (s > 0x7E) return '.';
|
||||
return s;
|
||||
}
|
||||
|
||||
void hexdump(void *d, int len)
|
||||
{
|
||||
u8 *data;
|
||||
int i, off;
|
||||
data = (u8*) d;
|
||||
|
||||
gprintf("\n 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF");
|
||||
gprintf("\n==== =============================================== ================\n");
|
||||
|
||||
for (off = 0; off < len; off += 16)
|
||||
{
|
||||
gprintf("%04x ", off);
|
||||
for (i = 0; i < 16; i++)
|
||||
if ((i + off) >= len)
|
||||
gprintf(" ");
|
||||
else gprintf("%02x ", data[off + i]);
|
||||
|
||||
gprintf(" ");
|
||||
for (i = 0; i < 16; i++)
|
||||
if ((i + off) >= len)
|
||||
gprintf(" ");
|
||||
else gprintf("%c", ascii(data[off + i]));
|
||||
gprintf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t __out_write(struct _reent *r, int fd, const char *ptr, size_t len)
|
||||
{
|
||||
if(geckoinit && ptr)
|
||||
usb_sendbuffer(1, ptr, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static const devoptab_t gecko_out = {
|
||||
"stdout", // device name
|
||||
0, // size of file structure
|
||||
NULL, // device open
|
||||
NULL, // device close
|
||||
__out_write,// device write
|
||||
NULL, // device read
|
||||
NULL, // device seek
|
||||
NULL, // device fstat
|
||||
NULL, // device stat
|
||||
NULL, // device link
|
||||
NULL, // device unlink
|
||||
NULL, // device chdir
|
||||
NULL, // device rename
|
||||
NULL, // device mkdir
|
||||
0, // dirStateSize
|
||||
NULL, // device diropen_r
|
||||
NULL, // device dirreset_r
|
||||
NULL, // device dirnext_r
|
||||
NULL, // device dirclose_r
|
||||
NULL, // device statvfs_r
|
||||
NULL, // device ftruncate_r
|
||||
NULL, // device fsync_r
|
||||
NULL, // device deviceData
|
||||
NULL, // device chmod_r
|
||||
NULL, // device fchmod_r
|
||||
};
|
||||
|
||||
void USBGeckoOutput()
|
||||
{
|
||||
devoptab_list[STD_OUT] = &gecko_out;
|
||||
devoptab_list[STD_ERR] = &gecko_out;
|
||||
}
|
||||
|
||||
#endif /* NO_DEBUG */
|
29
source/gecko.h
Normal file
29
source/gecko.h
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
#ifndef _GECKO_H_
|
||||
#define _GECKO_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
char ascii(char s);
|
||||
|
||||
#ifndef NO_DEBUG
|
||||
//use this just like printf();
|
||||
void gprintf(const char *str, ...);
|
||||
bool InitGecko();
|
||||
void hexdump(void *d, int len);
|
||||
void USBGeckoOutput();
|
||||
#else
|
||||
#define gprintf(...)
|
||||
#define InitGecko() false
|
||||
#define hexdump( x, y )
|
||||
#endif /* NO_DEBUG */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include <wiiuse/wpad.h>
|
||||
#include <dirent.h>
|
||||
|
||||
//#include "audio.h"
|
||||
#include "filelist.h"
|
||||
#include "FreeTypeGX.h"
|
||||
#include "input.h"
|
||||
@ -36,6 +35,9 @@
|
||||
#include "BootHomebrew/BootHomebrew.h"
|
||||
#include "BootHomebrew/dolloader.h"
|
||||
#include "DiskOperations/di2.h"
|
||||
#include "gecko.h"
|
||||
#include "Network/wiiload_gecko.h"
|
||||
#include "uneek_fs.h"
|
||||
|
||||
#define HAVE_AHBPROT ((*(vu32*)0xcd800064 == 0xFFFFFFFF) ? 1 : 0)
|
||||
|
||||
@ -59,6 +61,8 @@ s8 PowerOff = -1;
|
||||
bool boothomebrew = false;
|
||||
bool boot_buffer = false;
|
||||
bool wiiload = false;
|
||||
bool runaway = false;
|
||||
bool gecko_connected;
|
||||
|
||||
// kopiere ios für app in einen vector
|
||||
void addAppIos(string foldername, int ios)
|
||||
@ -86,21 +90,26 @@ void addAppIos(string foldername, int ios)
|
||||
|
||||
void ExitApp()
|
||||
{
|
||||
gprintf("Running ExitApp()\n");
|
||||
ShutdownPads();
|
||||
StopGX();
|
||||
//if(strcasecmp(Settings.code,"NULL") == 0)
|
||||
save();
|
||||
UnmountAllDevices();
|
||||
save();
|
||||
UnmountAllDevices();
|
||||
exit_uneek_fs();
|
||||
ISFS_Deinitialize();
|
||||
}
|
||||
|
||||
static void WiiResetPressed()
|
||||
{
|
||||
gprintf("Reset button pressed \n");
|
||||
runaway = true;
|
||||
PowerOff = SYS_RETURNTOMENU;
|
||||
}
|
||||
|
||||
static void WiiPowerPressed()
|
||||
{
|
||||
gprintf("Power button pressed \n");
|
||||
runaway = true;
|
||||
PowerOff = SYS_POWEROFF_STANDBY;
|
||||
}
|
||||
|
||||
@ -123,15 +132,6 @@ DefaultSettings()
|
||||
Settings.checkrev = -1;
|
||||
sprintf (Settings.code, "NULL");
|
||||
|
||||
// in kleinbuchstaben umwandeln
|
||||
/* transform(Settings.MyDir.begin(),Settings.MyDir.end(),Settings.MyDir.begin(),::tolower);
|
||||
if(Settings.MyDir.substr(0, Settings.MyDir.find(":/")) == "sd")
|
||||
Settings.MyPath = "sd1" + Settings.MyDir.substr(Settings.MyDir.find(":/"), Settings.MyDir.rfind("/") - Settings.MyDir.find(":/") +1);
|
||||
else if(Settings.MyDir.substr(0, Settings.MyDir.find(":/")) == "usb")
|
||||
Settings.MyPath = "usb1" + Settings.MyDir.substr(Settings.MyDir.find(":/"), Settings.MyDir.rfind("/") - Settings.MyDir.find(":/") +1);
|
||||
else
|
||||
Settings.MyPath = Settings.MyDir.substr(0, Settings.MyDir.rfind("/") +1);
|
||||
*/
|
||||
Settings.Apps_from = EFFECT_SLIDE_TOP; // Apps kommen von "EFFECT_SLIDE_TOP", "EFFECT_SLIDE_BOTTOM", "EFFECT_SLIDE_RIGHT", "EFFECT_SLIDE_LEFT"
|
||||
Settings.Apps_to = 0; // Apps geht nach "EFFECT_SLIDE_TOP", "EFFECT_SLIDE_BOTTOM", "EFFECT_SLIDE_RIGHT", "EFFECT_SLIDE_LEFT"
|
||||
Settings.grid = false;
|
||||
@ -162,16 +162,21 @@ int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
SYS_SetResetCallback(WiiResetPressed);
|
||||
SYS_SetPowerCallback(WiiPowerPressed);
|
||||
WPAD_SetPowerButtonCallback(WiimotePowerPressed);
|
||||
gecko_connected = InitGecko();
|
||||
|
||||
InitVideo(); // Initialize video
|
||||
SetupPads(); // Initialize input
|
||||
InitGUIThreads(); // Initialize GUI
|
||||
|
||||
init_uneek_fs(ISFS_OPEN_READ|ISFS_OPEN_WRITE);
|
||||
|
||||
MountAllDevices();
|
||||
InitNetworkThread(); // Initialize Network
|
||||
InitTcpThread();
|
||||
|
||||
if (gecko_connected)
|
||||
InitGeckoThread();
|
||||
|
||||
InitThrobberThread(); // Initialize Throbber
|
||||
ISFS_Initialize(); // Initialize Nand
|
||||
|
||||
@ -182,11 +187,18 @@ main(int argc, char *argv[])
|
||||
DefaultTheme();
|
||||
|
||||
load();
|
||||
|
||||
if(Options.network)
|
||||
ResumeNetworkThread();
|
||||
if (gecko_connected)
|
||||
ResumeGeckoThread();
|
||||
|
||||
SetFont();
|
||||
|
||||
SYS_SetResetCallback(WiiResetPressed);
|
||||
SYS_SetPowerCallback(WiiPowerPressed);
|
||||
WPAD_SetPowerButtonCallback(WiimotePowerPressed);
|
||||
|
||||
#ifdef HW_RVL
|
||||
pointer = new GuiImageData(Theme.player_point);
|
||||
#endif
|
||||
@ -199,8 +211,14 @@ main(int argc, char *argv[])
|
||||
ResumeGui();
|
||||
stretch(Settings.top, Settings.bottom, Settings.left, Settings.right);
|
||||
|
||||
if(HAVE_AHBPROT)
|
||||
if(HAVE_AHBPROT)
|
||||
{
|
||||
runtimePatchApply();
|
||||
}
|
||||
else
|
||||
{
|
||||
gprintf("ERROR no AHBPROT\n");
|
||||
}
|
||||
|
||||
DI2_Init(); // Init DVD
|
||||
|
||||
@ -214,8 +232,8 @@ main(int argc, char *argv[])
|
||||
|
||||
if(boothomebrew)
|
||||
{
|
||||
if(SelectedIOS() != IOS_GetVersion())
|
||||
IOS_ReloadIOS(SelectedIOS());
|
||||
/*if(SelectedIOS() != IOS_GetVersion())
|
||||
IOS_ReloadIOS(SelectedIOS());*/
|
||||
|
||||
if(strstr(Settings.forwarder_path.c_str(), ":/apps/") != 0)
|
||||
BootHomebrew();
|
||||
@ -227,7 +245,18 @@ main(int argc, char *argv[])
|
||||
BootHomebrew();
|
||||
|
||||
if(get_bootmii() == 2)
|
||||
IOS_ReloadIOS(254);
|
||||
{
|
||||
if(!check_uneek_fs())
|
||||
{
|
||||
IOS_ReloadIOS(254);
|
||||
}
|
||||
else
|
||||
{
|
||||
//we can't launch bootmii from within neek2o I assume
|
||||
//so we should do something else
|
||||
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if(get_nandemu() == 2)
|
||||
{
|
||||
@ -247,6 +276,7 @@ main(int argc, char *argv[])
|
||||
{
|
||||
*(vu32*)0x8132FFFB = 0x4461636f;
|
||||
DCFlushRange((void*)0x8132FFFB, 4);
|
||||
//ExitApp();
|
||||
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
|
||||
}
|
||||
|
||||
@ -254,9 +284,11 @@ main(int argc, char *argv[])
|
||||
{
|
||||
*(vu32*)0x8132FFFB = 0x50756E65;
|
||||
DCFlushRange((void*)0x8132FFFB, 4);
|
||||
//ExitApp();
|
||||
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
|
||||
}
|
||||
else if(PowerOff != -1)
|
||||
//ExitApp();
|
||||
SYS_ResetSystem(PowerOff, 0, 0);
|
||||
|
||||
return 0;
|
||||
|
652
source/uneek_fs.c
Normal file
652
source/uneek_fs.c
Normal file
@ -0,0 +1,652 @@
|
||||
/*-------------------------------------------------------------
|
||||
|
||||
uneek_fs.c -- USB mass storage support, using a modified uneek fs-usb
|
||||
|
||||
rev. 1.00 first draft
|
||||
|
||||
rev. 1.01 second draft
|
||||
added detection and support for SDHC access in SNEEK
|
||||
added check_uneek_fs_type function to see if it's sneek or uneek
|
||||
|
||||
rev. 1.02 third draft
|
||||
added the UNEEK_FS_BOTH option to the init_uneek_fs function.
|
||||
when the parameter is set, both sd and usb access are rerouted to the sd card.
|
||||
it can only be used with sneek and could serve programs like Joyflow on a sd only
|
||||
setup.
|
||||
the exit_uneek_fs function needs to be called when that setup is used.
|
||||
since I can't disable usb, not knowing if sd access is still needed, and
|
||||
I can't disable sd if usb access if sd is still needed.
|
||||
It's probably exceptional that one will be shutdown and the other still used,
|
||||
but it's better to stay on the safe area.
|
||||
|
||||
rev. 1.04 fourth draft.
|
||||
shutdown function is now a stub as some programs call it before they end to force a remount
|
||||
exit_uneek_fs added to properly shutdown the uneek_usb_fs file system.
|
||||
max_write_sectors increased to speedup things. Transfer speed from wiixplorer gone up
|
||||
from 20KB/s to 265KB/s.
|
||||
|
||||
rev. 1.05 fifth draft
|
||||
added "is_uneek" function
|
||||
|
||||
rev. 1.06 sixth draft
|
||||
added "is_neek2" and "is_neek3" functions
|
||||
Crediar changed the boot2 version back from 5 to 4.
|
||||
The is_uneek function will not detect those neek versions anymore.
|
||||
Stfour created the is_neek2 method to detect if neek is running.
|
||||
JoostinOnline and GiantPune created the is_neek3 which is a little less code.
|
||||
So, you should use either is_neek2 or is_neek3
|
||||
|
||||
rev. 1.07 seventh draft
|
||||
added "is_neek4" function
|
||||
Dj_Skual created the is_neek4 method to detect if neek is running.
|
||||
|
||||
added WII_launch_Channel. It's not really uneek_fs related, but it could be handy
|
||||
|
||||
|
||||
Copyright (C) 2011 Obcd
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
-------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ogcsys.h>
|
||||
#include <locale.h>
|
||||
#include <malloc.h>
|
||||
#include <ogc/isfs.h>
|
||||
//#include <sdcard/wiisd_io.h>
|
||||
//#include <gctypes.h>
|
||||
//#include <ogc/disc_io.h>
|
||||
|
||||
|
||||
//#define SHOW_GECKO_DEBUG 1
|
||||
|
||||
#ifdef SHOW_GECKO_DEBUG
|
||||
#include "gecko.h"
|
||||
#endif
|
||||
|
||||
#define MAX_READ_SECTORS 16 //yet to be determined how much is allowed?
|
||||
#define MAX_WRITE_SECTORS 16 //yet to be determined how much is allowed?
|
||||
#define CACHE_SECTOR_LOCATION 1 //not sure if it will improve speed much...
|
||||
|
||||
#define UNEEK_FS_NONE 0
|
||||
#define UNEEK_FS_USB 1
|
||||
#define UNEEK_FS_SD 2
|
||||
#define UNEEK_FS_BOTH 4
|
||||
|
||||
#define ISFS_OPEN_ALL 64
|
||||
|
||||
#define DEVICE_TYPE_WII_SD (('W'<<24)|('I'<<16)|('S'<<8)|'D')
|
||||
|
||||
|
||||
//Not yet implemented as most disk io buffers don't seem have proper alignment
|
||||
//It would require a more serious modification in the code (aligning those buffers)
|
||||
//#define USE_ORIGINAL_ALIGNED_BUF 0 //if the buffer is aligned already...why not?
|
||||
|
||||
|
||||
|
||||
//This one triggers the unique functions in the uneek fs
|
||||
//Don't try to change it.
|
||||
//If you really need to access that file with ISFS, access it in read/write mode
|
||||
//As only read mode will trigger uneek fs
|
||||
|
||||
static char _dev_obcd[] ATTRIBUTE_ALIGN(32) = "/sneek/obcd.txt";
|
||||
|
||||
static s32 fu = -1;
|
||||
// static bool uneek_fs_ok = false;
|
||||
static s32 uneek_fs_type = UNEEK_FS_NONE;
|
||||
|
||||
s32 confirm_neek1 = 5;
|
||||
s32 confirm_neek2 = 5;
|
||||
s32 confirm_neek3 = 5;
|
||||
s32 confirm_neek4 = 5;
|
||||
|
||||
|
||||
#ifdef CACHE_SECTOR_LOCATION
|
||||
static u32 seek_cache;
|
||||
#endif
|
||||
|
||||
// DISC_INTERFACE __io_usbstorage;
|
||||
DISC_INTERFACE __io_wiisd;
|
||||
extern DISC_INTERFACE __io_usbstorage;
|
||||
//extern DISC_INTERFACE __io_usb2storage;
|
||||
|
||||
// DISC_INTERFACE methods
|
||||
|
||||
static bool __io_uns_IsInserted(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __io_uns_Startup(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int usb_verbose = 0;
|
||||
|
||||
bool __io_uns_ReadSectors(u32 sector, u32 count, void *buffer)
|
||||
{
|
||||
|
||||
u8* buf;
|
||||
s32 whence;
|
||||
u32 done;
|
||||
u32 sec;
|
||||
u32 amount;
|
||||
u8* resultbuf;
|
||||
|
||||
done = 0;
|
||||
sec = sector;
|
||||
if (count <= MAX_READ_SECTORS)
|
||||
{
|
||||
amount = count;
|
||||
}
|
||||
else
|
||||
{
|
||||
amount = MAX_READ_SECTORS;
|
||||
}
|
||||
// buf = (u8 *)memalign(32, 512 * amount);
|
||||
// sdhc aligns it's buffers on 64 byte boundaries
|
||||
buf = (u8 *)memalign(64, 512 * amount);
|
||||
|
||||
while(done < count)
|
||||
{
|
||||
whence = 0;
|
||||
if ((sec & 0x80000000)!= 0)
|
||||
{
|
||||
sec &= 0x7fffffff;
|
||||
whence = 1;
|
||||
}
|
||||
#ifdef CACHE_SECTOR_LOCATION
|
||||
if ((sector + done) != seek_cache)
|
||||
{
|
||||
#endif
|
||||
ISFS_Seek(fu,sec,whence);
|
||||
#ifdef CACHE_SECTOR_LOCATION
|
||||
seek_cache = sector + done;
|
||||
}
|
||||
#endif
|
||||
s32 ret = ISFS_Read(fu,buf,512*amount);
|
||||
if (ret == (s32)(512*amount))
|
||||
{
|
||||
resultbuf = (u8*)buffer + (done * 512);
|
||||
memcpy(resultbuf,buf,512*amount);
|
||||
done+=amount;
|
||||
sec = sector + done;
|
||||
#ifdef CACHE_SECTOR_LOCATION
|
||||
seek_cache = sector + done;
|
||||
#endif
|
||||
if((count-done)<=MAX_READ_SECTORS)
|
||||
{
|
||||
amount = count - done;
|
||||
}
|
||||
else
|
||||
{
|
||||
amount = MAX_READ_SECTORS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef CACHE_SECTOR_LOCATION
|
||||
seek_cache = 0xfffffff8;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
if (usb_verbose) {
|
||||
printf("usb-r: %x [%d]\n", sector, count);
|
||||
//sleep(1);
|
||||
}
|
||||
//printf("ret = %x\n",ret);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool __io_uns_WriteSectors(u32 sector, u32 count, void *buffer)
|
||||
{
|
||||
|
||||
u8* buf;
|
||||
s32 whence;
|
||||
u32 done;
|
||||
u32 sec;
|
||||
u32 amount;
|
||||
u8* resultbuf;
|
||||
|
||||
done = 0;
|
||||
sec = sector;
|
||||
if (count <= MAX_WRITE_SECTORS)
|
||||
{
|
||||
amount = count;
|
||||
}
|
||||
else
|
||||
{
|
||||
amount = MAX_WRITE_SECTORS;
|
||||
}
|
||||
// buf = (u8 *)memalign(32, 512 * amount);
|
||||
// sdhc aligns it's buffers on 64 byte boundaries
|
||||
buf = (u8 *)memalign(64, 512 * amount);
|
||||
|
||||
while(done < count)
|
||||
{
|
||||
whence = 0;
|
||||
if ((sec & 0x80000000)!= 0)
|
||||
{
|
||||
sec &= 0x7fffffff;
|
||||
whence = 1;
|
||||
}
|
||||
#ifdef CACHE_SECTOR_LOCATION
|
||||
if ((sector + done) != seek_cache)
|
||||
{
|
||||
#endif
|
||||
ISFS_Seek(fu,sec,whence);
|
||||
#ifdef CACHE_SECTOR_LOCATION
|
||||
seek_cache = sector + done;
|
||||
}
|
||||
#endif
|
||||
resultbuf = (u8*)buffer + (done * 512);
|
||||
memcpy(buf,resultbuf,512*amount);
|
||||
s32 ret = ISFS_Write(fu,buf,512*amount);
|
||||
if (ret == (s32)(512*amount))
|
||||
{
|
||||
done+=amount;
|
||||
sec = sector + done;
|
||||
#ifdef CACHE_SECTOR_LOCATION
|
||||
seek_cache = sector + done;
|
||||
#endif
|
||||
if((count-done)<=MAX_WRITE_SECTORS)
|
||||
{
|
||||
amount = count - done;
|
||||
}
|
||||
else
|
||||
{
|
||||
amount = MAX_WRITE_SECTORS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef CACHE_SECTOR_LOCATION
|
||||
seek_cache = 0xfffffff8;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
free(buf);
|
||||
if (usb_verbose) {
|
||||
printf("usb-r: %x [%d]\n", sector, count);
|
||||
//sleep(1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __io_uns_ClearStatus(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __io_uns_Shutdown(void)
|
||||
{
|
||||
|
||||
return true;
|
||||
/*
|
||||
if ((uneek_fs_type != UNEEK_FS_NONE)&&(uneek_fs_type != UNEEK_FS_BOTH))
|
||||
{
|
||||
ISFS_Close(fu);
|
||||
ISFS_Deinitialize();
|
||||
uneek_fs_type = UNEEK_FS_NONE;
|
||||
}
|
||||
// do nothing
|
||||
return true;
|
||||
*/
|
||||
}
|
||||
|
||||
static bool __io_uns_NOP(void)
|
||||
{
|
||||
// do nothing
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool init_uneek_fs(u32 mode)
|
||||
{
|
||||
|
||||
u8* buf = NULL;
|
||||
struct _fstats* pstat = NULL;
|
||||
//struct _fstats stat;
|
||||
|
||||
if (uneek_fs_type == UNEEK_FS_NONE){
|
||||
ISFS_Initialize();
|
||||
fu = ISFS_Open(_dev_obcd, ISFS_OPEN_READ);
|
||||
buf = (u8*)memalign(32, sizeof(struct _fstats));
|
||||
pstat = (struct _fstats*)buf;
|
||||
pstat->file_length = 0;
|
||||
pstat->file_pos = 0;
|
||||
if(fu >= 0)
|
||||
{
|
||||
ISFS_GetFileStats(fu,pstat);
|
||||
//printf("Filestat length returned %x\n",pstat->file_length);
|
||||
//printf("Filestat pos returned %x\n",pstat->file_pos);
|
||||
}
|
||||
if ((pstat->file_length == 0xfffffff0)&&(pstat->file_pos == 0xfffffff8)&&(fu>=0))
|
||||
{
|
||||
#ifdef CACHE_SECTOR_LOCATION
|
||||
seek_cache = 0xfffffff8;
|
||||
#endif
|
||||
if (mode & ISFS_OPEN_WRITE)
|
||||
{
|
||||
__io_usbstorage.ioType = DEVICE_TYPE_WII_USB;
|
||||
__io_usbstorage.features = FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB;
|
||||
__io_usbstorage.startup = (FN_MEDIUM_STARTUP)&__io_uns_Startup;
|
||||
__io_usbstorage.isInserted = (FN_MEDIUM_ISINSERTED)&__io_uns_IsInserted;
|
||||
__io_usbstorage.readSectors = (FN_MEDIUM_READSECTORS)&__io_uns_ReadSectors;
|
||||
__io_usbstorage.writeSectors = (FN_MEDIUM_WRITESECTORS)&__io_uns_WriteSectors;
|
||||
__io_usbstorage.clearStatus = (FN_MEDIUM_CLEARSTATUS)&__io_uns_ClearStatus;
|
||||
__io_usbstorage.shutdown = (FN_MEDIUM_SHUTDOWN)&__io_uns_Shutdown;
|
||||
}
|
||||
else
|
||||
{
|
||||
__io_usbstorage.ioType = DEVICE_TYPE_WII_USB;
|
||||
__io_usbstorage.features = FEATURE_MEDIUM_CANREAD | FEATURE_WII_USB;
|
||||
__io_usbstorage.startup = (FN_MEDIUM_STARTUP)&__io_uns_Startup;
|
||||
__io_usbstorage.isInserted = (FN_MEDIUM_ISINSERTED)&__io_uns_IsInserted;
|
||||
__io_usbstorage.readSectors = (FN_MEDIUM_READSECTORS)&__io_uns_ReadSectors;
|
||||
__io_usbstorage.writeSectors = (FN_MEDIUM_WRITESECTORS)&__io_uns_NOP; //&__io_uns_WriteSectors
|
||||
__io_usbstorage.clearStatus = (FN_MEDIUM_CLEARSTATUS)&__io_uns_ClearStatus;
|
||||
__io_usbstorage.shutdown = (FN_MEDIUM_SHUTDOWN)&__io_uns_Shutdown;
|
||||
}
|
||||
|
||||
uneek_fs_type = UNEEK_FS_USB;
|
||||
free (buf);
|
||||
return true;
|
||||
}
|
||||
//sneek
|
||||
else if ((pstat->file_length == 0xfffffff1)&&(pstat->file_pos == 0xfffffff8)&&(fu>=0))
|
||||
{
|
||||
#ifdef CACHE_SECTOR_LOCATION
|
||||
seek_cache = 0xfffffff8;
|
||||
#endif
|
||||
uneek_fs_type = UNEEK_FS_SD;
|
||||
if (mode & ISFS_OPEN_WRITE)
|
||||
{
|
||||
__io_wiisd.ioType = DEVICE_TYPE_WII_SD;
|
||||
__io_wiisd.features = FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_SD;
|
||||
__io_wiisd.startup = (FN_MEDIUM_STARTUP)&__io_uns_Startup;
|
||||
__io_wiisd.isInserted = (FN_MEDIUM_ISINSERTED)&__io_uns_IsInserted;
|
||||
__io_wiisd.readSectors = (FN_MEDIUM_READSECTORS)&__io_uns_ReadSectors;
|
||||
__io_wiisd.writeSectors = (FN_MEDIUM_WRITESECTORS)&__io_uns_WriteSectors;
|
||||
__io_wiisd.clearStatus = (FN_MEDIUM_CLEARSTATUS)&__io_uns_ClearStatus;
|
||||
__io_wiisd.shutdown = (FN_MEDIUM_SHUTDOWN)&__io_uns_Shutdown;
|
||||
|
||||
//usb and sd will be treated equally
|
||||
//needed for joyflow with the sd only setup
|
||||
|
||||
if (mode & ISFS_OPEN_ALL)
|
||||
{
|
||||
__io_usbstorage.ioType = DEVICE_TYPE_WII_USB;
|
||||
__io_usbstorage.features = FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB;
|
||||
__io_usbstorage.startup = (FN_MEDIUM_STARTUP)&__io_uns_Startup;
|
||||
__io_usbstorage.isInserted = (FN_MEDIUM_ISINSERTED)&__io_uns_IsInserted;
|
||||
__io_usbstorage.readSectors = (FN_MEDIUM_READSECTORS)&__io_uns_ReadSectors;
|
||||
__io_usbstorage.writeSectors = (FN_MEDIUM_WRITESECTORS)&__io_uns_WriteSectors;
|
||||
__io_usbstorage.clearStatus = (FN_MEDIUM_CLEARSTATUS)&__io_uns_ClearStatus;
|
||||
__io_usbstorage.shutdown = (FN_MEDIUM_SHUTDOWN)&__io_uns_Shutdown;
|
||||
uneek_fs_type = UNEEK_FS_BOTH;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
__io_wiisd.ioType = DEVICE_TYPE_WII_SD;
|
||||
__io_wiisd.features = FEATURE_MEDIUM_CANREAD | FEATURE_WII_SD;
|
||||
__io_wiisd.startup = (FN_MEDIUM_STARTUP)&__io_uns_Startup;
|
||||
__io_wiisd.isInserted = (FN_MEDIUM_ISINSERTED)&__io_uns_IsInserted;
|
||||
__io_wiisd.readSectors = (FN_MEDIUM_READSECTORS)&__io_uns_ReadSectors;
|
||||
__io_wiisd.writeSectors = (FN_MEDIUM_WRITESECTORS)&__io_uns_NOP; //&__io_uns_WriteSectors
|
||||
__io_wiisd.clearStatus = (FN_MEDIUM_CLEARSTATUS)&__io_uns_ClearStatus;
|
||||
__io_wiisd.shutdown = (FN_MEDIUM_SHUTDOWN)&__io_uns_Shutdown;
|
||||
if(mode & ISFS_OPEN_ALL)
|
||||
{
|
||||
__io_usbstorage.ioType = DEVICE_TYPE_WII_USB;
|
||||
__io_usbstorage.features = FEATURE_MEDIUM_CANREAD | FEATURE_WII_USB;
|
||||
__io_usbstorage.startup = (FN_MEDIUM_STARTUP)&__io_uns_Startup;
|
||||
__io_usbstorage.isInserted = (FN_MEDIUM_ISINSERTED)&__io_uns_IsInserted;
|
||||
__io_usbstorage.readSectors = (FN_MEDIUM_READSECTORS)&__io_uns_ReadSectors;
|
||||
__io_usbstorage.writeSectors = (FN_MEDIUM_WRITESECTORS)&__io_uns_NOP; //&__io_uns_WriteSectors
|
||||
__io_usbstorage.clearStatus = (FN_MEDIUM_CLEARSTATUS)&__io_uns_ClearStatus;
|
||||
__io_usbstorage.shutdown = (FN_MEDIUM_SHUTDOWN)&__io_uns_Shutdown;
|
||||
uneek_fs_type = UNEEK_FS_BOTH;
|
||||
}
|
||||
}
|
||||
free (buf);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* these should be initialised right in the ogc library */
|
||||
/* so we will ignore those for the moment */
|
||||
/*
|
||||
__io_usbstorage.ioType = DEVICE_TYPE_WII_USB;
|
||||
__io_usbstorage.features = FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB;
|
||||
__io_usbstorage.startup = (FN_MEDIUM_STARTUP)&__io_usb_Startup;
|
||||
__io_usbstorage.isInserted = (FN_MEDIUM_ISINSERTED)&__io_usb_IsInserted;
|
||||
__io_usbstorage.readSectors = (FN_MEDIUM_READSECTORS)&__io_usb_ReadSectors;
|
||||
__io_usbstorage.writeSectors = (FN_MEDIUM_WRITESECTORS)&__io_usb_WriteSectors;
|
||||
__io_usbstorage.clearStatus = (FN_MEDIUM_CLEARSTATUS)&__io_usb_ClearStatus;
|
||||
__io_usbstorage.shutdown = (FN_MEDIUM_SHUTDOWN)&__io_usb_Shutdown;
|
||||
*/
|
||||
|
||||
uneek_fs_type = UNEEK_FS_NONE;
|
||||
free(buf);
|
||||
ISFS_Close(fu);
|
||||
ISFS_Deinitialize();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else //was already initialised
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* stay compatible with previous versions */
|
||||
bool check_uneek_fs(void)
|
||||
{
|
||||
if(uneek_fs_type != UNEEK_FS_NONE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
s32 check_uneek_fs_type(void)
|
||||
{
|
||||
return uneek_fs_type;
|
||||
}
|
||||
|
||||
bool exit_uneek_fs(void)
|
||||
{
|
||||
if (uneek_fs_type != UNEEK_FS_NONE)
|
||||
{
|
||||
ISFS_Close(fu);
|
||||
ISFS_Deinitialize();
|
||||
uneek_fs_type = UNEEK_FS_NONE;
|
||||
}
|
||||
// do nothing
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SenseSneek (bool isfsinit)
|
||||
{
|
||||
bool ret = true;
|
||||
char path[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
|
||||
|
||||
strcpy (path, "/SNEEK/kernel.bin");
|
||||
|
||||
if (isfsinit) ISFS_Initialize ();
|
||||
|
||||
s32 fd = ISFS_Open(path, ISFS_OPEN_READ);
|
||||
if (fd < 0)
|
||||
ret = false;
|
||||
else
|
||||
ISFS_Close (fd);
|
||||
|
||||
if (isfsinit) ISFS_Deinitialize();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool is_neek(void)
|
||||
{
|
||||
u32 boot2version;
|
||||
|
||||
if(confirm_neek1 == 5)
|
||||
{
|
||||
ES_GetBoot2Version(&boot2version);
|
||||
if(boot2version < 5)
|
||||
confirm_neek1 = false;
|
||||
else
|
||||
confirm_neek1 = true;
|
||||
}
|
||||
return confirm_neek1;
|
||||
}
|
||||
|
||||
|
||||
bool is_neek2 (bool isfsinit)
|
||||
{
|
||||
|
||||
char path[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
|
||||
|
||||
if(confirm_neek2 == 5)
|
||||
{
|
||||
confirm_neek2 = true;
|
||||
strcpy (path, "/SNEEK/kernel.bin");
|
||||
|
||||
if (isfsinit) ISFS_Initialize ();
|
||||
|
||||
s32 fd = ISFS_Open(path, ISFS_OPEN_READ);
|
||||
if (fd < 0)
|
||||
confirm_neek2 = false;
|
||||
else
|
||||
ISFS_Close (fd);
|
||||
|
||||
if (isfsinit) ISFS_Deinitialize ();
|
||||
}
|
||||
return confirm_neek2;
|
||||
}
|
||||
|
||||
//! New method for determining if this is a real or emu nand.
|
||||
//! Works with new versions of classic Crediar NEEK
|
||||
bool is_neek3(bool isfsinit)
|
||||
{
|
||||
u32 num = 0;
|
||||
|
||||
//! Thanks goes to the almighty giantpune for this
|
||||
if(confirm_neek3 == 5)
|
||||
{
|
||||
if (isfsinit) ISFS_Initialize ();
|
||||
if(ISFS_ReadDir("/Sneek", NULL, &num)==0)
|
||||
confirm_neek3 = true;
|
||||
else
|
||||
confirm_neek3 = false;
|
||||
if (isfsinit) ISFS_Deinitialize ();
|
||||
}
|
||||
return confirm_neek3;
|
||||
}
|
||||
|
||||
bool is_neek4(bool isfsinit)
|
||||
{
|
||||
|
||||
u32 ownerID;
|
||||
u16 groupID;
|
||||
u8 attributes;
|
||||
u8 ownerperm;
|
||||
u8 groupperm;
|
||||
u8 otherperm;
|
||||
|
||||
if(confirm_neek4 == 5)
|
||||
{
|
||||
confirm_neek4 = false;
|
||||
if(isfsinit) ISFS_Initialize();
|
||||
ISFS_GetAttr("/shared1/00000000.app", &ownerID, &groupID, &attributes, &ownerperm, &groupperm, &otherperm);
|
||||
if(otherperm)
|
||||
confirm_neek4 = true;
|
||||
|
||||
if(isfsinit) ISFS_Deinitialize();
|
||||
}
|
||||
return confirm_neek4;
|
||||
}
|
||||
|
||||
bool WII_Launch_Channel(char* which)
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
size_t wlen;
|
||||
u64 title_id;
|
||||
int titlemsb, titlelsb;
|
||||
char stitlexsb[16];
|
||||
union lsbstufftype
|
||||
{
|
||||
char titlename[4];
|
||||
u32 title_lsb;
|
||||
}lsbstuff;
|
||||
|
||||
|
||||
wlen = strlen(which);
|
||||
if ((wlen != 4) && (wlen != 16))
|
||||
{
|
||||
#ifdef SHOW_GECKO_DEBUG
|
||||
gprintf("Title %s has an invalid length\n",which);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
if (wlen == 4)
|
||||
{
|
||||
titlemsb = 0x00010001;
|
||||
strncpy(lsbstuff.titlename,which,4);
|
||||
titlelsb = lsbstuff.title_lsb;
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(stitlexsb,which,8);
|
||||
stitlexsb[8]=0;
|
||||
sscanf(stitlexsb,"%x",&titlemsb);
|
||||
strncpy(stitlexsb,which+8,8);
|
||||
stitlexsb[8]=0;
|
||||
sscanf(stitlexsb,"%x",&titlelsb);
|
||||
}
|
||||
title_id = (u64)(titlemsb) << 32;
|
||||
title_id = title_id + (u64)(titlelsb);
|
||||
#ifdef SHOW_GECKO_DEBUG
|
||||
gprintf( "titleid = %08x %08x\r\n", (u32)((title_id)>>32), (u32)(title_id) );
|
||||
s32 lret = WII_LaunchTitle(title_id);
|
||||
gprintf("WII_LaunchTitle returned %d\r\n",lret);
|
||||
#else
|
||||
WII_LaunchTitle(title_id);
|
||||
#endif
|
||||
// basically, it shouldn't get here I assume
|
||||
#endif //HW_RVL
|
||||
return false;
|
||||
}
|
96
source/uneek_fs.h
Normal file
96
source/uneek_fs.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*-------------------------------------------------------------
|
||||
|
||||
uneek_fs.H -- USB mass storage support, using a modified uneek fs-usb
|
||||
|
||||
rev. 1.00 first draft
|
||||
|
||||
rev. 1.01 second draft
|
||||
added detection and support for SDHC access in SNEEK
|
||||
added check_uneek_fs_type function to see if it's sneek or uneek
|
||||
|
||||
rev. 1.02 third draft
|
||||
added the UNEEK_FS_BOTH option to the init_uneek_fs function.
|
||||
when the parameter is set, both sd and usb access are rerouted to the sd card.
|
||||
it can only be used with sneek.
|
||||
the exit_uneek_fs function needs to be called when that setup is used.
|
||||
since I can't disable usb, not knowing if sd access is still needed, and
|
||||
I can't disable sd if usb access if sd is still needed.
|
||||
It's probably exceptional that one will be shutdown and the other still used,
|
||||
but it's better to stay on the safe area.
|
||||
|
||||
rev. 1.05 fifth draft
|
||||
added "is_uneek" function
|
||||
|
||||
rev. 1.06 sixth draft
|
||||
added "is_neek2" and "is_neek3" functions
|
||||
Crediar changed the boot2 version back from 5 to 4.
|
||||
The is_uneek function will not detect those neek versions anymore.
|
||||
Stfour created the is_neek2 method to detect if neek is running.
|
||||
JoostinOnline and GiantPune created the is_neek3 which is a little less code.
|
||||
So, you should use either is_neek2 or is_neek3
|
||||
|
||||
rev. 1.07 seventh draft
|
||||
added "is_neek4" function
|
||||
Dj_Skual created the is_neek4 method to detect if neek is running.
|
||||
|
||||
added WII_launch_Channel. It's not really uneek_fs related, but it could be handy
|
||||
|
||||
|
||||
Copyright (C) 2011 Obcd
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
-------------------------------------------------------------*/
|
||||
|
||||
#ifndef _UNEEK_FS_H_
|
||||
#define _UNEEK_FS_H_
|
||||
|
||||
#include <ogcsys.h>
|
||||
#include <ogc/isfs.h>
|
||||
|
||||
|
||||
#define UNEEK_FS_NONE 0
|
||||
#define UNEEK_FS_USB 1
|
||||
#define UNEEK_FS_SD 2
|
||||
#define UNEEK_FS_BOTH 4
|
||||
|
||||
#define ISFS_OPEN_ALL 64
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif //__cplusplus
|
||||
bool init_uneek_fs(u32 mode);
|
||||
bool check_uneek_fs(void);
|
||||
s32 check_uneek_fs_type(void);
|
||||
bool exit_uneek_fs(void);
|
||||
bool is_neek(void);
|
||||
bool is_neek2 (bool isfsinit);
|
||||
bool is_neek3 (bool isfsinit);
|
||||
bool is_neek4 (bool isfsinit);
|
||||
bool WII_Launch_Channel(char* which);
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //__cplusplus
|
||||
|
||||
#endif
|
93
source/wpad.c
Normal file
93
source/wpad.c
Normal file
@ -0,0 +1,93 @@
|
||||
#include <stdio.h>
|
||||
#include <ogcsys.h>
|
||||
#include <ogc/pad.h>
|
||||
|
||||
//#include <sys.h>
|
||||
#include "wpad.h"
|
||||
|
||||
/* Constants */
|
||||
#define MAX_WIIMOTES 4
|
||||
|
||||
extern u8 shutdown;
|
||||
|
||||
void __Wpad_PowerCallback(s32 chan)
|
||||
{
|
||||
/* Poweroff console */
|
||||
shutdown = 1;
|
||||
}
|
||||
|
||||
s32 Wpad_Init(void)
|
||||
{
|
||||
s32 ret;
|
||||
|
||||
/* Initialize Wiimote subsystem */
|
||||
ret = WPAD_Init();
|
||||
if (ret < 0) return ret;
|
||||
|
||||
/* Set POWER button callback */
|
||||
// WPAD_SetPowerButtonCallback(__Wpad_PowerCallback);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Wpad_Disconnect(void)
|
||||
{
|
||||
u32 cnt;
|
||||
|
||||
/* Disconnect Wiimotes */
|
||||
for (cnt = 0; cnt < MAX_WIIMOTES; cnt++)
|
||||
WPAD_Disconnect(cnt);
|
||||
|
||||
/* Shutdown Wiimote subsystem */
|
||||
WPAD_Shutdown();
|
||||
}
|
||||
|
||||
bool IsWpadConnected()
|
||||
{
|
||||
int i = 0;
|
||||
u32 test = 0;
|
||||
int notconnected = 0;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (WPAD_Probe(i, &test) == WPAD_ERR_NO_CONTROLLER)
|
||||
{
|
||||
notconnected++;
|
||||
}
|
||||
}
|
||||
if (notconnected < 4)
|
||||
return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
u32 ButtonsHold(void)
|
||||
{
|
||||
|
||||
int i;
|
||||
u32 buttons = 0;
|
||||
|
||||
WPAD_ScanPads();
|
||||
PAD_ScanPads();
|
||||
|
||||
for (i = 3; i >= 0; i--)
|
||||
{
|
||||
buttons |= PAD_ButtonsHeld(i);
|
||||
buttons |= WPAD_ButtonsHeld(i);
|
||||
}
|
||||
return buttons;
|
||||
}
|
||||
|
||||
u32 ButtonsPressed(void)
|
||||
{
|
||||
int i;
|
||||
u32 buttons = 0;
|
||||
|
||||
WPAD_ScanPads();
|
||||
PAD_ScanPads();
|
||||
|
||||
for (i = 3; i >= 0; i--)
|
||||
{
|
||||
buttons |= PAD_ButtonsDown(i);
|
||||
buttons |= WPAD_ButtonsDown(i);
|
||||
}
|
||||
return buttons;
|
||||
}
|
22
source/wpad.h
Normal file
22
source/wpad.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef _WPAD_H_
|
||||
#define _WPAD_H_
|
||||
|
||||
#include <wiiuse/wpad.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Prototypes */
|
||||
s32 Wpad_Init(void);
|
||||
void Wpad_Disconnect(void);
|
||||
u32 ButtonsPressed(void);
|
||||
u32 ButtonsHold(void);
|
||||
bool IsWpadConnected();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
5
updates
5
updates
@ -13,10 +13,15 @@
|
||||
- installer now supports GameCube-Controller
|
||||
- adopt libwiigui changes from ZERO
|
||||
- BUGFIX: loading apps through wiiload works again
|
||||
- support passing arguements using wiiload [obcd]
|
||||
- BUGFIX: when changing network settings, the network thread is
|
||||
halted or started accordingly [obcd]
|
||||
- BUGFIX: only show 'launch priiloader' in external loaders prompt,
|
||||
if priiloader is really installed
|
||||
- changed loading address from 0x81230000 to 0x81330000
|
||||
- removed all sound related code
|
||||
- support for neek2o [obcd]
|
||||
- only check once on startup for a new version [obcd]
|
||||
- updated PNGu
|
||||
|
||||
//rev37:
|
||||
|
Loading…
Reference in New Issue
Block a user