fledge68 630594d976 -updated NIN_CFG_VERSION to 7 for Nintendont argsboot and added triforce arcade option to game settings menu. tested and working.
-fixed wii u widescreen option in game config menu. should properly work now. thanks pBullet!
-added a fix for coverflow titles display when coverflow has 3 or more rows. for some reason 3 or more rows caused the title to display improperly.
-removed **disabled** message from source menu. no need for it - was a stupid idea. if you don't want it to display then remove it from your source menu or don't add it. when a view is disabled in wiiflow_lite.ini then only that view icon is disabled from showing on the main menu screen.
-removed titles.ini which wasn't really used except for displaying the return to channel in settings. I googled it and nothing really showed up. it seemed to be the same as custom_titles.ini - it seemed useless.
-removed cacheing sourceflow list. the list is never big enuff to worry about cacheing. plus if you add or remove source btns you won't have to reload cache for the changes to take effect.
-removed max_source_btns from wiiflow_lite.ini - added code to get highest source menu btn so now source menu can have as many buttons as you like.  
-removed Manage Languages Menu - restored option to just change wiiflow language. no need for downloading languages and the google link didn't work anyway. when i make a pack all the languages will be included.
-added flat cover options for sourceflow and homebrew view. can be turned on/off via their config menu's accessed via 'HOME' btn.
-added config menu for homebrew view - press 'HOME' btn while in homebrew view to access it. config menu options are -  switch apps partition, adjust coverflow, smallbox on/off, and flat covers on/off.
-updated config menu for source menu/flow. options include - sourceflow on/off, adjust coverflow, smallbox on/off, flat covers on/off, and for source menu only - multisource on/off.
-added coverflow layouts/versions for individual plugins - which means each plugin can have its own coverflow layout without affecting the others.
-set HQ cover to default to ON
-made it so coverflow doesn't reload every time you access another menu or change favorites or whatever.
-added error messages to game and app launching if any of the bin files needed for launching are missing. previously whenever these errors occurred wiiflow would just exit without the user knowing why. Now the error message should display before exit so the user has an idea what went wrong. had to move cleanup() back some for the errors to show. hopefully that doesn't cause out of mem issues for users with large game collections.
-added error messages to game config menu. now all config options will show but if you can't use it then a error shows telling you. such as 'use neek2o' will be available but if you set it to on and neek2o isn't installed then an error message shows. added error msgs for extracting and flashing saves too.
-added show_mem=yes/no option to wiiflow_lite.ini under [DEBUG]. manually edit wiiflow_lite.ini to turn it on/off. if set to 'yes' wiiflow will show how much free mem is available on screen. no need to compile wiiflow for this option anymore.
-cleaned up some of the boot up code.
-starting a random game - just hold 'B' and press '-'.  no longer press'B' on config or question mark icon and no need to allow it in wiiflow_lite.ini
2016-11-07 15:06:00 +00:00

640 lines
17 KiB
C++

/****************************************************************************
* Copyright (C) 2012 FIX94
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <ogc/machine/processor.h>
#include <ogc/lwp_threads.h>
// for directory parsing and low-level file I/O
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include "menu/menu.hpp"
#include "gc/gc.hpp"
#include "gui/text.hpp"
#include "devicemounter/DeviceHandler.hpp"
#include "gecko/gecko.hpp"
#include "fileOps/fileOps.h"
#include "homebrew/homebrew.h"
#include "loader/utils.h"
#include "loader/disc.h"
#include "loader/sys.h"
#include "memory/memory.h"
#include "memory/mem2.hpp"
// Nintendont
NIN_CFG NinCfg;
u8 NinDevice = 0;
bool NinArgsboot = false;
void Nintendont_SetOptions(const char *game, const char *gameID, char *CheatPath,char *NewCheatPath, const char *partition,
bool cheats, u8 emuMC, u8 videomode, bool widescreen, bool usb_hid, bool native_ctl, bool deflicker,
bool wiiu_widescreen, bool NIN_Debugger, bool tri_arcade)
{
NinDevice = DeviceHandle.PathToDriveType(game);
memset(&NinCfg, 0, sizeof(NIN_CFG));
NinCfg.Magicbytes = 0x01070CF6;
NinCfg.MemCardBlocks = 0x2;//251 blocks
//check version
u32 NIN_cfg_version = NIN_CFG_VERSION;
char NINVersion[7]= "";
u32 NINRev = 0;
for(u8 i = SD; i < MAXDEVICES; ++i)
{
const char *dol_path = fmt(NIN_LOADER_PATH, DeviceName[i]);
if(!fsop_FileExist(dol_path))
continue;
//u8 *buffer = NULL;
u32 filesize = 0;
const char *str = "$$Version:";
u8 *buffer = fsop_ReadFile(dol_path, &filesize);
for(u32 i = 0; i < filesize; i += 32)
{
if(memcmp(buffer+i, str, strlen(str)) == 0)
{
// Write buffer in NINVersion
snprintf(NINVersion, sizeof(NINVersion), "%s", buffer+i+strlen(str));
NINRev = atoi(strchr(NINVersion, '.')+1);
break;
}
}
free(buffer);
break;
/*u32 filesize = 0;
u8 *buffer = fsop_ReadFile(dol_path, &filesize);
char NINversion[21];
for(u32 i = 0; i < filesize-60; ++i)
{
// Nintendont Loader..Built : %s %s..Jan 10 2014.11:21:01
if((*(vu32*)(buffer+i+2)) == 0x6e74656e && (*(vu32*)(buffer+i+6)) == 0x646f6e74
&& (*(vu32*)(buffer+i+11)) == 0x4c6f6164) //'nten' 'dont' 'Load'
{
for(int k= 30; k <50; ++k)
{
if((*(vu32*)(buffer+i+k)) == 0x4A616E20 || (*(vu32*)(buffer+i+k)) == 0x46656220 ||
(*(vu32*)(buffer+i+k)) == 0x4D617220 || (*(vu32*)(buffer+i+k)) == 0x41707220 ||
(*(vu32*)(buffer+i+k)) == 0x4D617920 || (*(vu32*)(buffer+i+k)) == 0x4A756E20 ||
(*(vu32*)(buffer+i+k)) == 0x4A756C20 || (*(vu32*)(buffer+i+k)) == 0x41756720 ||
(*(vu32*)(buffer+i+k)) == 0x53657020 || (*(vu32*)(buffer+i+k)) == 0x4F637420 ||
(*(vu32*)(buffer+i+k)) == 0x4E6F7620 || (*(vu32*)(buffer+i+k)) == 0x44656320 ) // find Month
{
for(int j = 0 ; j < 20 ; j++)
NINversion[j] = *(u8*)(buffer+i+k+j);
NINversion[11] = ' '; // replace \0 between year and time with a space.
NINversion[20] = 0;
struct tm time;
strptime(NINversion, "%b %d %Y %H:%M:%S", &time);
const time_t NINLoaderTime = mktime(&time);
const time_t v135time = 1407167999;// v1.135
if(difftime(NINLoaderTime,v135time) > 0)
NIN_cfg_version = 3;
else
NIN_cfg_version = 2;
break;
}
}
break;
}
}
free(buffer);
break;*/
}
if(NINRev == 0)
return;
if(NINRev >= 135 && NINRev < 354)
NIN_cfg_version = 3;
else if(NINRev >= 354 && NINRev < 358)
NIN_cfg_version = 4;
else if(NINRev >= 358 && NINRev < 368)
NIN_cfg_version = 5;
else if(NINRev >= 368 && NINRev < 424)
NIN_cfg_version = 6;
NinCfg.Version = NIN_cfg_version;
/*if(memcmp("0x474851",gameID,3)==0)
NinCfg.MaxPads = 1;
else*/
NinCfg.MaxPads = 4;
NinCfg.Config |= NIN_CFG_AUTO_BOOT;
if(NinDevice != SD)
NinCfg.Config |= NIN_CFG_USB;
if(IsOnWiiU() == true)
NinCfg.Config |= NIN_CFG_MEMCARDEMU;
NinCfg.VideoMode |= NIN_VID_FORCE;
if((videomode > 3) && (videomode != 6))
NinCfg.Config |= NIN_CFG_FORCE_PROG;
if(usb_hid)
NinCfg.Config |= NIN_CFG_HID;
if(NIN_Debugger)
NinCfg.Config |= NIN_CFG_OSREPORT;
if(native_ctl)
NinCfg.Config |= NIN_CFG_NATIVE_SI;
if(deflicker)
NinCfg.VideoMode |= NIN_VID_FORCE_DF;
if(wiiu_widescreen)
NinCfg.Config |= NIN_CFG_WIIU_WIDE;
if(widescreen)
NinCfg.Config |= NIN_CFG_FORCE_WIDE;
if(tri_arcade)
NinCfg.Config |= NIN_CFG_ARCADE_MODE;
if(emuMC > 0)
NinCfg.Config |= NIN_CFG_MEMCARDEMU;
if(emuMC > 1)
{
NinCfg.Config |= NIN_CFG_MC_MULTI;
NinCfg.MemCardBlocks = 0x4;//1019 blocks (8MB)
}
if(CheatPath != NULL && NewCheatPath != NULL && cheats)
{
const char *ptr = NULL;
if(strncasecmp(CheatPath, partition, strlen(partition)) != 0)
{
fsop_CopyFile(CheatPath, NewCheatPath, NULL, NULL);
ptr = strchr(NewCheatPath, '/');
}
else
ptr = strchr(CheatPath, '/');
snprintf(NinCfg.CheatPath, sizeof(NinCfg.CheatPath), ptr);
NinCfg.Config |= NIN_CFG_CHEAT_PATH;
}
if(cheats)
NinCfg.Config |= NIN_CFG_CHEATS;
strncpy(NinCfg.GamePath, strchr(game, '/'), 254);
if(strstr(NinCfg.GamePath, "boot.bin") != NULL)
{
*strrchr(NinCfg.GamePath, '/') = '\0'; //boot.bin
*(strrchr(NinCfg.GamePath, '/')+1) = '\0'; //sys
}
memcpy(&NinCfg.GameID, gameID, 4);
gprintf("Nintendont Game Path: %s, ID: %08x\n", NinCfg.GamePath, NinCfg.GameID);
}
void Nintendont_BootDisc(u8 emuMC, bool widescreen, bool usb_hid, bool native_ctl, bool deflicker)
{
memset(&NinCfg, 0, sizeof(NIN_CFG));
NinCfg.Magicbytes = 0x01070CF6;
FILE * location = fopen("sd:/nincfg.bin", "r");
if(location == NULL)
{
NinCfg.Config |= NIN_CFG_USB;
fclose(location);
location = NULL;
}
NinCfg.Version = NIN_CFG_VERSION;
NinCfg.Config |= NIN_CFG_AUTO_BOOT;
NinCfg.VideoMode |= NIN_VID_AUTO;
if(usb_hid)
NinCfg.Config |= NIN_CFG_HID;
if(emuMC == 1)
{
NinCfg.Config |= NIN_CFG_MEMCARDEMU;
NinCfg.MemCardBlocks = 0x2;//251 blocks (2MB)
}
else if(emuMC == 2)
{
NinCfg.Config |= NIN_CFG_MEMCARDEMU;
NinCfg.Config |= NIN_CFG_MC_MULTI;
NinCfg.MemCardBlocks = 0x4;//1019 blocks (8MB)
}
if(native_ctl)
NinCfg.Config |= NIN_CFG_NATIVE_SI;
if(deflicker)
NinCfg.VideoMode |= NIN_VID_FORCE_DF;
if(widescreen)
NinCfg.Config |= NIN_CFG_FORCE_WIDE;
snprintf(NinCfg.GamePath,sizeof(NinCfg.GamePath),"di");
}
void Nintendont_WriteOptions()
{
/* Newer Nintendont versions */
if(NinArgsboot == true)
{
gprintf("Writing Arguments\n");
AddBootArgument((char*)&NinCfg, sizeof(NIN_CFG));
return;
}
/* general loader */
if(DeviceHandle.SD_Inserted())
{
gprintf("Writing Nintendont CFG: sd:/%s\n", NIN_CFG_PATH);
fsop_WriteFile(fmt("sd:/%s", NIN_CFG_PATH), &NinCfg, sizeof(NIN_CFG));
}
/* for kernel */
if(NinDevice != SD)
{
gprintf("Writing Nintendont USB Kernel CFG: %s:/%s\n", DeviceName[NinDevice], NIN_CFG_PATH);
fsop_WriteFile(fmt("%s:/%s", DeviceName[NinDevice], NIN_CFG_PATH), &NinCfg, sizeof(NIN_CFG));
}
}
bool Nintendont_Installed()
{
for(u8 i = SD; i < MAXDEVICES; ++i)
{
const char *dol_path = fmt(NIN_LOADER_PATH, DeviceName[i]);
if(fsop_FileExist(dol_path) == true)
{
gprintf("Nintendont found\n");
return true;
}
}
return false;
}
bool Nintendont_GetLoader()
{
bool ret = false;
for(u8 i = SD; i < MAXDEVICES; ++i)
{
const char *dol_path = fmt(NIN_LOADER_PATH, DeviceName[i]);
ret = (LoadHomebrew(dol_path) == 1);
if(ret == true)
{
gprintf("Nintendont loaded: %s\n", dol_path);
AddBootArgument(dol_path);
//search for argsboot
u32 size;
const char *dol_ptr = GetHomebrew(&size);
for(u32 i = 0; i < size; i += 0x10)
{
if(strncmp(dol_ptr + i, "argsboot", 8) == 0)
{
gprintf("Nintendont argsboot found at %08x\n", i);
NinArgsboot = true;
break;
}
}
break;
}
}
return ret;
}
// Devolution
u8 *tmp_buffer = NULL;
u8 *loader_bin = NULL;
u32 loader_size = 0;
extern "C" { extern void __exception_closeall(); }
static gconfig *DEVO_CONFIG = (gconfig*)0x80000020;
#define DEVO_ENTRY ((entry)loader_bin)
bool DEVO_Installed(const char *path)
{
loader_size = 0;
bool devo = false;
fsop_GetFileSizeBytes(fmt(DEVO_LOADER_PATH, path), &loader_size);
if(loader_size > 0x80) //Size should be more than 128b
{
gprintf("Devolution found\n");
devo = true;
}
return devo;
}
void DEVO_GetLoader(const char *path)
{
loader_size = 0;
tmp_buffer = fsop_ReadFile(fmt(DEVO_LOADER_PATH, path), &loader_size);
if(tmp_buffer == NULL)
gprintf("Devolution: Loader not found!\n");
}
void DEVO_SetOptions(const char *isopath, const char *gameID, bool memcard_emu,
bool widescreen, bool activity_led, bool wifi)
{
// re-mount device we need
DeviceHandle.MountDevolution();
//start writing cfg to mem
struct stat st;
int data_fd;
char iso2path[256];
iso2path[255] = '\0';
stat(isopath, &st);
FILE *f = fopen(isopath, "rb");
gprintf("Devolution: ISO Header %s\n", isopath);
fread((u8*)Disc_ID, 1, 32, f);
fclose(f);
f = NULL;
// fill out the Devolution config struct
memset(DEVO_CONFIG, 0, sizeof(gconfig));
DEVO_CONFIG->signature = DEVO_CONFIG_SIG;
DEVO_CONFIG->version = DEVO_CONFIG_VERSION;
DEVO_CONFIG->device_signature = st.st_dev;
DEVO_CONFIG->disc1_cluster = st.st_ino;
// Pergame options
if(wifi)
DEVO_CONFIG->options |= DEVO_CONFIG_WIFILOG;
if(widescreen)
DEVO_CONFIG->options |= DEVO_CONFIG_WIDE;
if(!activity_led)
DEVO_CONFIG->options |= DEVO_CONFIG_NOLED;
// If 2nd iso file tell Devo about it
strncpy(iso2path, isopath, 255);
char *ptz = strstr(iso2path, "game.iso");
if(ptz != NULL)
{
strncpy(ptz, "gam1.iso", 8);
f = fopen(iso2path, "rb");
if(f == NULL)
{
strncpy(ptz, "gam2.iso", 8);
f = fopen(iso2path, "rb");
if(f == NULL)
{
strncpy(ptz, "disc2.iso", 9);
f = fopen(iso2path, "rb");
}
}
if(f != NULL)
{
gprintf("Devolution: 2nd ISO File for Multi DVD Game %s\n", iso2path);
stat(iso2path, &st);
DEVO_CONFIG->disc2_cluster = st.st_ino;
fclose(f);
}
}
// make sure these directories exist, they are required for Devolution to function correctly
fsop_MakeFolder(fmt("%s:/apps", DeviceName[currentPartition]));
fsop_MakeFolder(fmt("%s:/apps/gc_devo", DeviceName[currentPartition]));
if(memcard_emu)
{
const char *memcard_dir = NULL;
// find or create a 16MB memcard file for emulation
// this file can be located anywhere since it's passed by cluster, not name
// it must be at least 512KB (smallest possible memcard = 59 blocks)
if(gameID[3] == 'J') //Japanese Memory Card
memcard_dir = fmt("%s:/apps/gc_devo/memcard_jap.bin", DeviceName[currentPartition]);
else
memcard_dir = fmt("%s:/apps/gc_devo/memcard.bin", DeviceName[currentPartition]);
gprintf("Devolution: Memory Card File %s\n", memcard_dir);
// check if file doesn't exist
if(stat(memcard_dir, &st) == -1 || st.st_size < (1<<19))
{
// need to enlarge or create it
data_fd = open(memcard_dir, O_WRONLY|O_CREAT);
if(data_fd >= 0)
{
// try to make it 16MB (largest possible memcard = 2043 blocks)
gprintf("Devolution: Resizing Memory Card File...\n");
ftruncate(data_fd, 16<<20);
if(fstat(data_fd, &st) == -1 || st.st_size < (1<<19))
{
// it still isn't big enough. Give up.
st.st_ino = 0;
}
close(data_fd);
}
else
{
// couldn't open or create the memory card file
st.st_ino = 0;
}
}
gprintf("Devolution: Memory Card at %08x\n", st.st_ino);
}
else
st.st_ino = 0;
// set FAT cluster for start of memory card file
// if this is zero memory card emulation will not be used
DEVO_CONFIG->memcard_cluster = st.st_ino;
// flush disc ID and Devolution config out to memory
DCFlushRange((void*)Disc_ID, 64);
DeviceHandle.UnMountDevolution();
}
void DEVO_Boot()
{
/* Move our loader into low MEM1 */
loader_bin = (u8*)MEM1_lo_alloc(loader_size);
memcpy(loader_bin, tmp_buffer, loader_size);
DCFlushRange(loader_bin, ALIGN32(loader_size));
MEM2_free(tmp_buffer);
gprintf("%s\n", (loader_bin+4));
/* Boot that binary */
JumpToEntry(DEVO_ENTRY);
}
// General
#define SRAM_ENGLISH 0
#define SRAM_GERMAN 1
#define SRAM_FRENCH 2
#define SRAM_SPANISH 3
#define SRAM_ITALIAN 4
#define SRAM_DUTCH 5
extern "C" {
syssram* __SYS_LockSram();
u32 __SYS_UnlockSram(u32 write);
u32 __SYS_SyncSram(void);
}
void GC_SetVideoMode(u8 videomode, u8 loader)
{
syssram *sram;
sram = __SYS_LockSram();
GXRModeObj *vmode = VIDEO_GetPreferredMode(0);
int vmode_reg = 0;
if((VIDEO_HaveComponentCable() && (CONF_GetProgressiveScan() > 0)) || ((videomode > 3) && (videomode != 6)))
sram->flags |= 0x80; //set progressive flag
else
sram->flags &= 0x7F; //clear progressive flag
if(videomode == 1 || videomode == 3 || videomode == 5 || videomode == 6 || videomode == 7)
{
vmode_reg = 1;
sram->flags |= 0x01; // Set bit 0 to set the video mode to PAL
sram->ntd |= 0x40; //set pal60 flag
}
else
{
sram->flags &= 0xFE; // Clear bit 0 to set the video mode to NTSC
sram->ntd &= 0xBF; //clear pal60 flag
}
if(videomode == 1)
{
if(loader == 1)
NinCfg.VideoMode |= NIN_VID_FORCE_PAL50;
vmode = &TVPal528IntDf;
}
else if(videomode == 2)
{
if(loader == 1)
NinCfg.VideoMode |= NIN_VID_FORCE_NTSC;
vmode = &TVNtsc480IntDf;
}
else if(videomode == 3)
{
if(loader == 1)
NinCfg.VideoMode |= NIN_VID_FORCE_PAL60;
vmode = &TVEurgb60Hz480IntDf;
vmode_reg = 5;
}
else if(videomode == 4)
{
if(loader == 1)
NinCfg.VideoMode |= NIN_VID_FORCE_NTSC;
vmode = &TVNtsc480IntDf;// shouldn't this be vmode = &TVNtsc480Prog
}
else if(videomode == 5)
{
if(loader == 1)
NinCfg.VideoMode |= NIN_VID_FORCE_PAL60;
vmode = &TVEurgb60Hz480IntDf;
vmode_reg = 5;
}
else if(videomode == 6)
{
if(loader == 1)
NinCfg.VideoMode |= NIN_VID_FORCE_MPAL;
vmode = &TVEurgb60Hz480IntDf;
vmode_reg = 5;// not sure about this
}
else if(videomode == 7)
{
if(loader == 1)
NinCfg.VideoMode |= NIN_VID_FORCE_MPAL;
vmode = &TVEurgb60Hz480IntDf;
vmode_reg = 5;
}
__SYS_UnlockSram(1); // 1 -> write changes
while(!__SYS_SyncSram());
/* Set video mode register */
*Video_Mode = vmode_reg;
DCFlushRange((void*)Video_Mode, 4);
/* Set video mode */
if(vmode != 0)
VIDEO_Configure(vmode);
/* Setup video */
VIDEO_SetBlack(FALSE);
VIDEO_Flush();
VIDEO_WaitVSync();
if(vmode->viTVMode & VI_NON_INTERLACE)
VIDEO_WaitVSync();
else while(VIDEO_GetNextField())
VIDEO_WaitVSync();
/* Set black and flush */
VIDEO_SetBlack(TRUE);
VIDEO_Flush();
VIDEO_WaitVSync();
if(vmode->viTVMode & VI_NON_INTERLACE)
VIDEO_WaitVSync();
else while(VIDEO_GetNextField())
VIDEO_WaitVSync();
}
u8 get_wii_language()
{
switch (CONF_GetLanguage())
{
case CONF_LANG_GERMAN:
return SRAM_GERMAN;
case CONF_LANG_FRENCH:
return SRAM_FRENCH;
case CONF_LANG_SPANISH:
return SRAM_SPANISH;
case CONF_LANG_ITALIAN:
return SRAM_ITALIAN;
case CONF_LANG_DUTCH:
return SRAM_DUTCH;
default:
return SRAM_ENGLISH;
}
}
void GC_SetLanguage(u8 lang, u8 loader)
{
if (lang == 0)
lang = get_wii_language();
else
lang--;
syssram *sram;
sram = __SYS_LockSram();
sram->lang = lang;
__SYS_UnlockSram(1); // 1 -> write changes
while(!__SYS_SyncSram());
/* write language for nintendont */
if(loader == 1)
{
switch(lang)
{
case SRAM_GERMAN:
NinCfg.Language = NIN_LAN_GERMAN;
break;
case SRAM_FRENCH:
NinCfg.Language = NIN_LAN_FRENCH;
break;
case SRAM_SPANISH:
NinCfg.Language = NIN_LAN_SPANISH;
break;
case SRAM_ITALIAN:
NinCfg.Language = NIN_LAN_ITALIAN;
break;
case SRAM_DUTCH:
NinCfg.Language = NIN_LAN_DUTCH;
break;
default:
NinCfg.Language = NIN_LAN_ENGLISH;
break;
}
}
}