-fixed banners random crashes and codedumps

-WIP commit for wii game/channel booting, now uses a internal
extra dol file to boot wii games and channels, that should be a
better way to fix game and channel booting
This commit is contained in:
fix94.1 2012-08-12 21:26:24 +00:00
parent 7e9fd00e83
commit 0e5a5b4abd
39 changed files with 1890 additions and 823 deletions

View File

@ -58,7 +58,7 @@ ios := 249
CFLAGS = -g -O2 -Wall -Wextra -Wno-multichar $(MACHDEP) $(INCLUDE) -DHAVE_CONFIG_H CFLAGS = -g -O2 -Wall -Wextra -Wno-multichar $(MACHDEP) $(INCLUDE) -DHAVE_CONFIG_H
CXXFLAGS = $(CFLAGS) CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80A00000,-wrap,malloc,-wrap,_malloc_r,-wrap,free,-wrap,_free_r,-wrap,memalign,-wrap,_memalign_r,-wrap,calloc,-wrap,_calloc_r,-wrap,realloc,-wrap,_realloc_r,-wrap,malloc_usable_size,-wrap,_malloc_usable_size_r LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80A00000,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project # any extra libraries we wish to link with the project

BIN
data/wii_game_booter.dol Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

@ -0,0 +1,127 @@
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
endif
include $(DEVKITPPC)/wii_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET := boot
BUILD := build
SOURCES := source
INCLUDES := source
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS = -g -Os -Wall -Wextra $(MACHDEP) $(INCLUDE)
CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80A00000
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -logc
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(CURDIR)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
export DEPSDIR := $(CURDIR)/$(BUILD)
#---------------------------------------------------------------------------------
# automatically build a list of object files for our project
#---------------------------------------------------------------------------------
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
export LD := $(CC)
else
export LD := $(CXX)
endif
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
$(sFILES:.s=.o) $(SFILES:.S=.o) \
#---------------------------------------------------------------------------------
# build a list of include paths
#---------------------------------------------------------------------------------
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD) \
-I$(LIBOGC_INC)
#---------------------------------------------------------------------------------
# build a list of library paths
#---------------------------------------------------------------------------------
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
-L$(LIBOGC_LIB)
export OUTPUT := $(CURDIR)/$(TARGET)
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).dol: $(OUTPUT).elf
$(OUTPUT).elf: $(OFILES)
#---------------------------------------------------------------------------------
# This rule links in binary data with the .jpg extension
#---------------------------------------------------------------------------------
%.png.o : %.png
#---------------------------------------------------------------------------------
@echo $(notdir $<)
$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

View File

@ -2,20 +2,14 @@
#include <stdio.h> #include <stdio.h>
#include <ogcsys.h> #include <ogcsys.h>
#include <string.h> #include <string.h>
#include <malloc.h>
#include "mload_modules.h"
#include "apploader.h" #include "apploader.h"
#include "wdvd.h" #include "wdvd.h"
#include "patchcode.h" #include "patchcode.h"
#include "disc.h"
#include "videopatch.h" #include "videopatch.h"
#include "wip.h"
#include "wbfs.h"
#include "sys.h"
#include "fst.h"
#include "cios.h" #include "cios.h"
#include "types.h" #include "fst.h"
#include "gecko/gecko.h" #include "wip.h"
/* Apploader function pointers */ /* Apploader function pointers */
typedef int (*app_main)(void **dst, int *size, int *offset); typedef int (*app_main)(void **dst, int *size, int *offset);
@ -40,6 +34,8 @@ static bool PrinceOfPersiaPatch();
static bool NewSuperMarioBrosPatch(); static bool NewSuperMarioBrosPatch();
bool hookpatched = false; bool hookpatched = false;
static void no_print(const char*a __attribute__((unused)),...){}
s32 Apploader_Run(entry_point *entry, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo) s32 Apploader_Run(entry_point *entry, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo)
{ {
void *dst = NULL; void *dst = NULL;
@ -75,7 +71,7 @@ s32 Apploader_Run(entry_point *entry, u8 vidMode, GXRModeObj *vmode, bool vipatc
appldr_entry(&appldr_init, &appldr_main, &appldr_final); appldr_entry(&appldr_init, &appldr_main, &appldr_final);
/* Initialize apploader */ /* Initialize apploader */
appldr_init(gprintf); appldr_init(no_print);
while(appldr_main(&dst, &len, &offset)) while(appldr_main(&dst, &len, &offset))
{ {
@ -85,13 +81,8 @@ s32 Apploader_Run(entry_point *entry, u8 vidMode, GXRModeObj *vmode, bool vipatc
} }
free_wip(); free_wip();
if(hooktype != 0) if(hooktype != 0 && hookpatched)
{
if(hookpatched)
ocarina_do_code(); ocarina_do_code();
else
gprintf("Error: Could not patch the hook, Ocarina and debugger won't work\n");
}
/* Set entry point from apploader */ /* Set entry point from apploader */
*entry = appldr_final(); *entry = appldr_final();

View File

@ -4,7 +4,15 @@
/* Entry point */ /* Entry point */
typedef void (*entry_point)(void); typedef void (*entry_point)(void);
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Prototypes */ /* Prototypes */
s32 Apploader_Run(entry_point *entry,u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo); s32 Apploader_Run(entry_point *entry,u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif #endif

View File

@ -0,0 +1,41 @@
#ifndef _CIOSINFO_H_
#define _CIOSINFO_H_
#include <gccore.h>
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct _iosinfo_t {
u32 magicword; //0x1ee7c105
u32 magicversion; // 1
u32 version; // Example: 5
u32 baseios; // Example: 56
char name[0x10]; // Example: d2x
char versionstring[0x10]; // Example: beta2
} iosinfo_t;
typedef struct _IOS_Info {
u32 Revision;
u8 Version;
u8 Type;
u8 Base;
} IOS_Info;
extern IOS_Info CurrentIOS;
void IOS_GetCurrentIOSInfo();
bool IOS_D2X(u8 ios, u8 *base);
u8 IOS_GetType(u8 slot);
bool Hermes_shadow_mload();
void Hermes_Disable_EHC();
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

View File

@ -0,0 +1,223 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ogcsys.h>
#include <unistd.h>
#include <malloc.h>
#include <ogc/lwp_watchdog.h>
#include "memory.h"
#include "cios.h"
#include "types.h"
#include "wdvd.h"
/* Constants */
#define PTABLE_OFFSET 0x40000
static u8 *diskid = (u8*)0x80000000;
void Disc_SetLowMem()
{
/* Setup low memory */
*Sys_Magic = 0x0D15EA5E; // Standard Boot Code
*Sys_Version = 0x00000001; // Version
*Arena_L = 0x00000000; // Arena Low
*BI2 = 0x817E5480; // BI2
*Bus_Speed = 0x0E7BE2C0; // Console Bus Speed
*CPU_Speed = 0x2B73A840; // Console CPU Speed
*Assembler = 0x38A00040; // Assembler
*(vu32*)0x800000E4 = 0x80431A80;
*Dev_Debugger = 0x81800000; // Dev Debugger Monitor Address
*Simulated_Mem = 0x01800000; // Simulated Memory Size
*(vu32*)0xCD00643C = 0x00000000; // 32Mhz on Bus
/* Fix for Sam & Max (WiiPower) */
if(CurrentIOS.Type != IOS_TYPE_HERMES)
*GameID_Address = 0x80000000;
/* Copy disc ID */
memcpy((void *)Online_Check, (void *)Disc_ID, 4);
}
s32 Disc_FindPartition(u64 *outbuf)
{
u8 TMP_Buffer_size = 0x20;
u64 offset = 0;
u32 cnt;
u32 *TMP_Buffer = (u32*)memalign(32, TMP_Buffer_size);
if(!TMP_Buffer)
return -1;
/* Read partition info */
s32 ret = WDVD_UnencryptedRead(TMP_Buffer, TMP_Buffer_size, PTABLE_OFFSET);
if(ret < 0)
{
free(TMP_Buffer);
return ret;
}
/* Get data */
u32 nb_partitions = TMP_Buffer[0];
u64 table_offset = TMP_Buffer[1] << 2;
if(nb_partitions > 8)
{
free(TMP_Buffer);
return -1;
}
memset(TMP_Buffer, 0, TMP_Buffer_size);
/* Read partition table */
ret = WDVD_UnencryptedRead(TMP_Buffer, TMP_Buffer_size, table_offset);
if (ret < 0)
{
free(TMP_Buffer);
return ret;
}
/* Find game partition */
for(cnt = 0; cnt < nb_partitions; cnt++)
{
u32 type = TMP_Buffer[cnt * 2 + 1];
/* Game partition */
if(!type)
offset = TMP_Buffer[cnt * 2] << 2;
}
free(TMP_Buffer);
/* No game partition found */
if (!offset)
return -1;
/* Set output buffer */
*outbuf = offset;
WDVD_Seek(offset);
return 0;
}
void Disc_SetTime()
{
/* Set proper time */
settime(secs_to_ticks(time(NULL) - 946684800));
}
GXRModeObj *Disc_SelectVMode(u8 videoselected, u32 *rmode_reg)
{
GXRModeObj *rmode = VIDEO_GetPreferredMode(0);
/* Get video mode configuration */
bool progressive = (CONF_GetProgressiveScan() > 0) && VIDEO_HaveComponentCable();
/* Select video mode register */
switch (CONF_GetVideo())
{
case CONF_VIDEO_PAL:
if (CONF_GetEuRGB60() > 0)
{
*rmode_reg = VI_EURGB60;
rmode = progressive ? &TVNtsc480Prog : &TVEurgb60Hz480IntDf;
}
else
*rmode_reg = VI_PAL;
break;
case CONF_VIDEO_MPAL:
*rmode_reg = VI_MPAL;
break;
case CONF_VIDEO_NTSC:
*rmode_reg = VI_NTSC;
break;
}
char Region = diskid[3];
switch(videoselected)
{
case 0: // DEFAULT (DISC/GAME)
/* Select video mode */
switch(Region)
{
case 'W':
break; // Don't overwrite wiiware video modes.
// PAL
case 'D':
case 'F':
case 'P':
case 'X':
case 'Y':
if(CONF_GetVideo() != CONF_VIDEO_PAL)
{
*rmode_reg = VI_PAL;
rmode = progressive ? &TVNtsc480Prog : &TVNtsc480IntDf;
}
break;
// NTSC
case 'E':
case 'J':
default:
if(CONF_GetVideo() != CONF_VIDEO_NTSC)
{
*rmode_reg = VI_NTSC;
rmode = progressive ? &TVNtsc480Prog : &TVEurgb60Hz480IntDf;
}
break;
}
break;
case 1: // SYSTEM
break;
case 2: // PAL50
rmode = &TVPal528IntDf;
*rmode_reg = rmode->viTVMode >> 2;
break;
case 3: // PAL60
rmode = progressive ? &TVNtsc480Prog : &TVEurgb60Hz480IntDf;
*rmode_reg = progressive ? TVEurgb60Hz480Prog.viTVMode >> 2 : rmode->viTVMode >> 2;
break;
case 4: // NTSC
rmode = progressive ? &TVNtsc480Prog : &TVNtsc480IntDf;
*rmode_reg = rmode->viTVMode >> 2;
break;
case 5: // PROGRESSIVE 480P
rmode = &TVNtsc480Prog;
*rmode_reg = Region == 'P' ? TVEurgb60Hz480Prog.viTVMode >> 2 : rmode->viTVMode >> 2;
break;
default:
break;
}
return rmode;
}
void Disc_SetVMode(GXRModeObj *rmode, u32 rmode_reg)
{
/* Set video mode register */
*Video_Mode = rmode_reg;
DCFlushRange((void*)Video_Mode, 4);
/* Set video mode */
if(rmode != 0)
VIDEO_Configure(rmode);
/* Setup video */
VIDEO_SetBlack(FALSE);
VIDEO_Flush();
VIDEO_WaitVSync();
if(rmode->viTVMode & VI_NON_INTERLACE)
VIDEO_WaitVSync();
else while(VIDEO_GetNextField())
VIDEO_WaitVSync();
/* Set black and flush */
VIDEO_SetBlack(TRUE);
VIDEO_Flush();
VIDEO_WaitVSync();
if(rmode->viTVMode & VI_NON_INTERLACE)
VIDEO_WaitVSync();
else while(VIDEO_GetNextField())
VIDEO_WaitVSync();
}

View File

@ -0,0 +1,20 @@
#ifndef _DISC_H_
#define _DISC_H_
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
s32 Disc_FindPartition(u64 *outbuf);
void Disc_SetLowMem();
void Disc_SetTime();
GXRModeObj *Disc_SelectVMode(u8 videoselected, u32 *rmode_reg);
void Disc_SetVMode(GXRModeObj *rmode, u32 rmode_reg);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

View File

@ -0,0 +1,265 @@
/*
* Copyright (C) 2008 Nuke (wiinuke@gmail.com)
*
* this file is part of GeckoOS for USB Gecko
* http://www.usbgecko.com
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gccore.h>
#include <sys/unistd.h>
#include <ogc/ipc.h>
#include "fst.h"
#include "patchcode.h"
#include "codehandler.h"
#include "codehandleronly.h"
#include "multidol.h"
#define FSTDIRTYPE 1
#define FSTFILETYPE 0
#define ENTRYSIZE 0xC
#define MAX_FILENAME_LEN 128
u8 *codelistend;
void *codelist;
u32 gameconfsize = 0;
u32 *gameconf = NULL;
u8 debuggerselect = 0;
extern const u32 viwiihooks[4];
extern const u32 kpadhooks[4];
extern const u32 joypadhooks[4];
extern const u32 gxdrawhooks[4];
extern const u32 gxflushhooks[4];
extern const u32 ossleepthreadhooks[4];
extern const u32 axnextframehooks[4];
extern const u32 wpadbuttonsdownhooks[4];
extern const u32 wpadbuttonsdown2hooks[4];
void app_gameconfig_set(u32 *gameconfig, u32 tempgameconfsize)
{
gameconfsize = tempgameconfsize;
gameconf = gameconfig;
}
u8 *code_buf = NULL;
u32 code_size = 0;
void ocarina_set_codes(void *list, u8 *listend, u8 *cheats, u32 cheatSize)
{
codelist = list;
codelistend = listend;
code_buf = cheats;
code_size = cheatSize;
if(code_size <= 0)
{
//printf("Ocarina: No codes found\n");
code_buf = NULL;
code_size = 0;
return;
}
if (code_size > (u32)codelistend - (u32)codelist)
{
//printf("Ocarina: Too many codes found\n");
code_buf = NULL;
code_size = 0;
return;
}
//printf("Ocarina: Codes found.\n");
}
void app_pokevalues()
{
u32 i, *codeaddr, *codeaddr2, *addrfound = NULL;
if (gameconfsize != 0)
{
for (i = 0; i < gameconfsize/4; i++)
{
if (*(gameconf + i) == 0)
{
if (((u32 *) (*(gameconf + i + 1))) == NULL ||
*((u32 *) (*(gameconf + i + 1))) == *(gameconf + i + 2))
{
*((u32 *) (*(gameconf + i + 3))) = *(gameconf + i + 4);
DCFlushRange((void *) *(gameconf + i + 3), 4);
}
i += 4;
}
else
{
codeaddr = (u32 *)*(gameconf + i + *(gameconf + i) + 1);
codeaddr2 = (u32 *)*(gameconf + i + *(gameconf + i) + 2);
if (codeaddr == 0 && addrfound != NULL)
codeaddr = addrfound;
else if (codeaddr == 0 && codeaddr2 != 0)
codeaddr = (u32 *) ((((u32) codeaddr2) >> 28) << 28);
else if (codeaddr == 0 && codeaddr2 == 0)
{
i += *(gameconf + i) + 4;
continue;
}
if (codeaddr2 == 0)
codeaddr2 = codeaddr + *(gameconf + i);
addrfound = NULL;
while (codeaddr <= (codeaddr2 - *(gameconf + i)))
{
if (memcmp(codeaddr, gameconf + i + 1, (*(gameconf + i)) * 4) == 0)
{
*(codeaddr + ((*(gameconf + i + *(gameconf + i) + 3)) / 4)) = *(gameconf + i + *(gameconf + i) + 4);
if (addrfound == NULL) addrfound = codeaddr;
}
codeaddr++;
}
i += *(gameconf + i) + 4;
}
}
}
}
void load_handler()
{
if (hooktype != 0x00)
{
if (debuggerselect == 0x01)
{
//printf("Debbugger selected is gecko\n");
memset((void*)0x80001800,0,codehandler_size);
memcpy((void*)0x80001800,codehandler,codehandler_size);
//if (pausedstartoption == 0x01)
// *(u32*)0x80002798 = 1;
memcpy((void*)0x80001CDE, &codelist, 2);
memcpy((void*)0x80001CE2, ((u8*) &codelist) + 2, 2);
memcpy((void*)0x80001F5A, &codelist, 2);
memcpy((void*)0x80001F5E, ((u8*) &codelist) + 2, 2);
DCFlushRange((void*)0x80001800,codehandler_size);
}
else
{
//printf("Debbugger selected is not gecko\n");
memset((void*)0x80001800,0,codehandleronly_size);
memcpy((void*)0x80001800,codehandleronly,codehandleronly_size);
memcpy((void*)0x80001906, &codelist, 2);
memcpy((void*)0x8000190A, ((u8*) &codelist) + 2, 2);
DCFlushRange((void*)0x80001800,codehandleronly_size);
}
// Load multidol handler
memset((void*)0x80001000,0,multidol_size);
memcpy((void*)0x80001000,multidol,multidol_size);
DCFlushRange((void*)0x80001000,multidol_size);
switch(hooktype)
{
case 0x01:
memcpy((void*)0x8000119C,viwiihooks,12);
memcpy((void*)0x80001198,viwiihooks+3,4);
break;
case 0x02:
memcpy((void*)0x8000119C,kpadhooks,12);
memcpy((void*)0x80001198,kpadhooks+3,4);
break;
case 0x03:
memcpy((void*)0x8000119C,joypadhooks,12);
memcpy((void*)0x80001198,joypadhooks+3,4);
break;
case 0x04:
memcpy((void*)0x8000119C,gxdrawhooks,12);
memcpy((void*)0x80001198,gxdrawhooks+3,4);
break;
case 0x05:
memcpy((void*)0x8000119C,gxflushhooks,12);
memcpy((void*)0x80001198,gxflushhooks+3,4);
break;
case 0x06:
memcpy((void*)0x8000119C,ossleepthreadhooks,12);
memcpy((void*)0x80001198,ossleepthreadhooks+3,4);
break;
case 0x07:
memcpy((void*)0x8000119C,axnextframehooks,12);
memcpy((void*)0x80001198,axnextframehooks+3,4);
break;
case 0x08:
//if (customhooksize == 16)
//{
// memcpy((void*)0x8000119C,customhook,12);
// memcpy((void*)0x80001198,customhook+3,4);
//}
break;
case 0x09:
//memcpy((void*)0x8000119C,wpadbuttonsdownhooks,12);
//memcpy((void*)0x80001198,wpadbuttonsdownhooks+3,4);
break;
case 0x0A:
//memcpy((void*)0x8000119C,wpadbuttonsdown2hooks,12);
//memcpy((void*)0x80001198,wpadbuttonsdown2hooks+3,4);
break;
}
DCFlushRange((void*)0x80001198,16);
}
memcpy((void *)0x80001800, (void*)0x80000000, 6);
}
int ocarina_do_code(u64 chantitle)
{
//if (!code_buf) return 0; // Need the handler loaded for hooking other than cheats!
memset((void *)0x80001800, 0, 0x1800);
char gameidbuffer[8];
if(chantitle != 0)
{
memset(gameidbuffer, 0, 8);
gameidbuffer[0] = (chantitle & 0xff000000) >> 24;
gameidbuffer[1] = (chantitle & 0x00ff0000) >> 16;
gameidbuffer[2] = (chantitle & 0x0000ff00) >> 8;
gameidbuffer[3] = chantitle & 0x000000ff;
}
load_handler();
if(chantitle != 0)
{
memcpy((void *)0x80001800, gameidbuffer, 8);
DCFlushRange((void *)0x80001800, 8);
}
if(codelist)
memset(codelist, 0, (u32)codelistend - (u32)codelist);
//Copy the codes
if(code_size > 0 && code_buf)
{
memcpy(codelist, code_buf, code_size);
DCFlushRange(codelist, (u32)codelistend - (u32)codelist);
}
// TODO What's this???
// enable flag
//*(vu8*)0x80001807 = 0x01;
//This needs to be done after loading the .dol into memory
app_pokevalues();
return 1;
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2008 Nuke (wiinuke@gmail.com)
*
* this file is part of GeckoOS for USB Gecko
* http://www.usbgecko.com
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __FST_H__
#define __FST_H__
#ifdef __cplusplus
extern "C" {
#endif
extern u8 debuggerselect;
#define MAX_GCT_SIZE 2056
void app_gameconfig_set(u32 *gameconfig, u32 tempgameconfsize);
void ocarina_set_codes(void *list, u8 *listend, u8 *cheats, u32 cheatSize);
int ocarina_do_code();
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,212 @@
/****************************************************************************
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ogcsys.h>
#include <unistd.h>
#include <malloc.h>
#include "apploader.h"
#include "wdvd.h"
#include "patchcode.h"
#include "cios.h"
#include "disc.h"
#include "fst.h"
#include "videopatch.h"
using namespace std;
IOS_Info CurrentIOS;
typedef struct _the_CFG {
u8 vidMode;
bool vipatch;
bool countryString;
u8 patchVidMode;
int aspectRatio;
u32 returnTo;
u8 configbytes[2];
IOS_Info IOS;
void *codelist;
u8 *codelistend;
u8 *cheats;
u32 cheatSize;
u32 hooktype;
u8 debugger;
u32 *gameconf;
u32 gameconfsize;
u8 BootType;
/* needed for channels */
void *dolchunkoffset[18];
u32 dolchunksize[18];
u32 dolchunkcount;
u32 startPoint;
} the_CFG;
static the_CFG *conf = (the_CFG*)0x90000000;
/* Boot Variables */
u32 vmode_reg = 0;
entry_point p_entry;
GXRModeObj *vmode = NULL;
u32 AppEntrypoint;
extern "C" { extern void __exception_closeall(); }
void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio)
{
for(u32 i = 0; i < conf->dolchunkcount; i++)
{
patchVideoModes(conf->dolchunkoffset[i], conf->dolchunksize[i], vidMode, vmode, patchVidModes);
if(vipatch) vidolpatcher(conf->dolchunkoffset[i], conf->dolchunksize[i]);
if(configbytes[0] != 0xCD) langpatcher(conf->dolchunkoffset[i], conf->dolchunksize[i]);
if(countryString) PatchCountryStrings(conf->dolchunkoffset[i], conf->dolchunksize[i]);
if(aspectRatio != -1) PatchAspectRatio(conf->dolchunkoffset[i], conf->dolchunksize[i], aspectRatio);
if(hooktype != 0)
dogamehooks(conf->dolchunkoffset[i], conf->dolchunksize[i], true);
}
}
int main()
{
VIDEO_Init();
configbytes[0] = conf->configbytes[0];
configbytes[1] = conf->configbytes[1];
hooktype = conf->hooktype;
debuggerselect = conf->debugger;
CurrentIOS = conf->IOS;
app_gameconfig_set(conf->gameconf, conf->gameconfsize);
ocarina_set_codes(conf->codelist, conf->codelistend, conf->cheats, conf->cheatSize);
/* Set low memory */
Disc_SetLowMem();
/* Select an appropriate video mode */
vmode = Disc_SelectVMode(conf->vidMode, &vmode_reg);
if(conf->BootType == TYPE_WII_GAME)
{
WDVD_Init();
/* Find Partition */
u64 offset = 0;
Disc_FindPartition(&offset);
/* Open Partition */
WDVD_OpenPartition(offset);
/* Run apploader */
Apploader_Run(&p_entry, conf->vidMode, vmode, conf->vipatch, conf->countryString, conf->patchVidMode,
conf->aspectRatio, conf->returnTo);
AppEntrypoint = (u32)p_entry;
}
else if(conf->BootType == TYPE_CHANNEL)
{
if(hooktype != 0)
ocarina_do_code();
PatchChannel(conf->vidMode, vmode, conf->vipatch, conf->countryString,
conf->patchVidMode, conf->aspectRatio);
AppEntrypoint = conf->startPoint;
}
/* Set time */
Disc_SetTime();
/* Set an appropriate video mode */
Disc_SetVMode(vmode, vmode_reg);
/* Shutdown IOS subsystems */
u32 level = IRQ_Disable();
__IOS_ShutdownSubsystems();
__exception_closeall();
/* Originally from tueidj - taken from NeoGamma (thx) */
*(vu32*)0xCC003024 = 1;
if(AppEntrypoint == 0x3400)
{
if(hooktype)
{
asm volatile (
"lis %r3, returnpoint@h\n"
"ori %r3, %r3, returnpoint@l\n"
"mtlr %r3\n"
"lis %r3, 0x8000\n"
"ori %r3, %r3, 0x18A8\n"
"nop\n"
"mtctr %r3\n"
"bctr\n"
"returnpoint:\n"
"bl DCDisable\n"
"bl ICDisable\n"
"li %r3, 0\n"
"mtsrr1 %r3\n"
"lis %r4, AppEntrypoint@h\n"
"ori %r4,%r4,AppEntrypoint@l\n"
"lwz %r4, 0(%r4)\n"
"mtsrr0 %r4\n"
"rfi\n"
);
}
else
{
asm volatile (
"isync\n"
"lis %r3, AppEntrypoint@h\n"
"ori %r3, %r3, AppEntrypoint@l\n"
"lwz %r3, 0(%r3)\n"
"mtsrr0 %r3\n"
"mfmsr %r3\n"
"li %r4, 0x30\n"
"andc %r3, %r3, %r4\n"
"mtsrr1 %r3\n"
"rfi\n"
);
}
}
else if (hooktype)
{
asm volatile (
"lis %r3, AppEntrypoint@h\n"
"ori %r3, %r3, AppEntrypoint@l\n"
"lwz %r3, 0(%r3)\n"
"mtlr %r3\n"
"lis %r3, 0x8000\n"
"ori %r3, %r3, 0x18A8\n"
"nop\n"
"mtctr %r3\n"
"bctr\n"
);
}
else
{
asm volatile (
"lis %r3, AppEntrypoint@h\n"
"ori %r3, %r3, AppEntrypoint@l\n"
"lwz %r3, 0(%r3)\n"
"mtlr %r3\n"
"blr\n"
);
}
IRQ_Restore(level);
return 0;
}

View File

@ -0,0 +1,37 @@
#ifndef __MEMORY_H_
#define __MEMORY_H_
#ifdef __cplusplus
extern "C"
{
#endif
#define Disc_ID ((vu32*)0x80000000)
#define Disc_Region ((vu32*)0x80000003)
#define Disc_Magic ((vu32*)0x80000018)
#define Sys_Magic ((vu32*)0x80000020)
#define Sys_Version ((vu32*)0x80000024)
#define Mem_Size ((vu32*)0x80000028)
#define Board_Model ((vu32*)0x8000002C)
#define Arena_L ((vu32*)0x80000030)
#define Arena_H ((vu32*)0x80000034)
#define FST ((vu32*)0x80000038)
#define Max_FST ((vu32*)0x8000003C)
#define Assembler ((vu32*)0x80000060)
#define Video_Mode ((vu32*)0x800000CC)
#define Dev_Debugger ((vu32*)0x800000EC)
#define Simulated_Mem ((vu32*)0x800000F0)
#define BI2 ((vu32*)0x800000F4)
#define Bus_Speed ((vu32*)0x800000F8)
#define CPU_Speed ((vu32*)0x800000FC)
#define Online_Check ((vu32*)0x80003180)
#define GameID_Address ((vu32*)0x80003184)
#define Priiloader_CFG1 ((vu32*)0x8132FFFB)
#define Priiloader_CFG2 ((vu32*)0x817FEFF0)
#ifdef __cplusplus
}
#endif
#endif

View File

@ -26,7 +26,6 @@
#include "apploader.h" #include "apploader.h"
#include "patchcode.h" #include "patchcode.h"
#include "gecko/gecko.h"
extern void patchhook(u32 address, u32 len); extern void patchhook(u32 address, u32 len);
extern void patchhook2(u32 address, u32 len); extern void patchhook2(u32 address, u32 len);
@ -379,9 +378,6 @@ bool PatchReturnTo( void *Address, int Size, u32 id )
returnToPatched = 1; returnToPatched = 1;
} }
if(returnToPatched)
gprintf("Return to %08X patched with old method.\n", id);
return returnToPatched; return returnToPatched;
} }
@ -390,10 +386,7 @@ s32 IOSReloadBlock(u8 reqios, bool enable)
s32 ESHandle = IOS_Open("/dev/es", 0); s32 ESHandle = IOS_Open("/dev/es", 0);
if (ESHandle < 0) if (ESHandle < 0)
{
gprintf("Reload IOS Block failed, cannot open /dev/es\n");
return ESHandle; return ESHandle;
}
static ioctlv vector[2] ATTRIBUTE_ALIGN(32); static ioctlv vector[2] ATTRIBUTE_ALIGN(32);
static u32 mode ATTRIBUTE_ALIGN(32); static u32 mode ATTRIBUTE_ALIGN(32);
@ -410,8 +403,6 @@ s32 IOSReloadBlock(u8 reqios, bool enable)
} }
s32 r = IOS_Ioctlv(ESHandle, 0xA0, 2, 0, vector); s32 r = IOS_Ioctlv(ESHandle, 0xA0, 2, 0, vector);
gprintf("%s Block IOS Reload for cIOS%uv%u %s\n", (enable ? "Enable" : "Disable"), IOS_GetVersion(), IOS_GetRevision() % 100, r < 0 ? "FAILED!" : "SUCCEEDED!");
IOS_Close(ESHandle); IOS_Close(ESHandle);
return r; return r;
@ -441,7 +432,6 @@ void PatchAspectRatio(void *addr, u32 len, u8 aspect)
&& (memcmp(addr_start + 4 + sizeof(aspect_searchpattern1), aspect_searchpattern2, sizeof(aspect_searchpattern2)) == 0)) && (memcmp(addr_start + 4 + sizeof(aspect_searchpattern1), aspect_searchpattern2, sizeof(aspect_searchpattern2)) == 0))
{ {
*((u32 *)(addr_start+0x44)) = (0x38600000 | aspect); *((u32 *)(addr_start+0x44)) = (0x38600000 | aspect);
gprintf("Aspect ratio patched to: %s\n", aspect ? "16:9" : "4:3");
break; break;
} }
addr_start += 4; addr_start += 4;

View File

@ -33,7 +33,6 @@ u8 configbytes[2];
bool dogamehooks(void *addr, u32 len, bool channel); bool dogamehooks(void *addr, u32 len, bool channel);
void langpatcher(void *addr, u32 len); void langpatcher(void *addr, u32 len);
void vidolpatcher(void *addr, u32 len); void vidolpatcher(void *addr, u32 len);
s32 IOSReloadBlock(u8 reqios, bool enable);
void PatchCountryStrings(void *Address, int Size); void PatchCountryStrings(void *Address, int Size);
void PatchAspectRatio(void *addr, u32 len, u8 aspect); void PatchAspectRatio(void *addr, u32 len, u8 aspect);
bool PatchReturnTo(void *Address, int Size, u32 id); bool PatchReturnTo(void *Address, int Size, u32 id);

View File

@ -0,0 +1,34 @@
#ifndef _TYPES_H_
#define _TYPES_H_
#ifdef __cplusplus
extern "C" {
#endif
enum
{
TYPE_WII_GAME = 0,
TYPE_GC_GAME,
TYPE_CHANNEL,
TYPE_PLUGIN,
TYPE_HOMEBREW,
TYPE_END
};
enum
{
IOS_TYPE_D2X = 0,
IOS_TYPE_WANIN,
IOS_TYPE_HERMES,
IOS_TYPE_KWIIRK,
IOS_TYPE_NO_CIOS,
};
#define NoGameID(x) (x == TYPE_PLUGIN || x == TYPE_HOMEBREW)
#ifdef __cplusplus
}
#endif
#endif

View File

@ -147,39 +147,6 @@ GXRModeObj TVMpal480Prog =
} }
}; };
GXRModeObj TVPal576IntDfScale =
{
VI_TVMODE_PAL_INT, // viDisplayMode
640, // fbWidth
480, // efbHeight
576, // xfbHeight
40, // viXOrigin
0, // viYOrigin
640, // viWidth
576, // viHeight
VI_XFBMODE_DF, // xFBmode
GX_FALSE, // field_rendering
GX_FALSE, // aa
// sample points arranged in increasing Y order
{
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
{6,6},{6,6},{6,6}, // pix 1
{6,6},{6,6},{6,6}, // pix 2
{6,6},{6,6},{6,6} // pix 3
},
// vertical filter[7], 1/64 units, 6 bits each
{
8, // line n-1
8, // line n-1
10, // line n
12, // line n
10, // line n
8, // line n+1
8 // line n+1
}
};
static const GXRModeObj *g_vidmodes[] = { static const GXRModeObj *g_vidmodes[] = {
&TVNtsc480Int, &TVNtsc480Int,
&TVNtsc480IntDf, &TVNtsc480IntDf,
@ -247,7 +214,6 @@ static GXRModeObj* PAL2NTSC[]={
&TVPal528Int, &TVNtsc480IntAa, &TVPal528Int, &TVNtsc480IntAa,
&TVPal528IntDf, &TVNtsc480IntDf, &TVPal528IntDf, &TVNtsc480IntDf,
&TVPal574IntDfScale, &TVNtsc480IntDf, &TVPal574IntDfScale, &TVNtsc480IntDf,
&TVPal576IntDfScale, &TVNtsc480IntDf,
&TVEurgb60Hz240Ds, &TVNtsc240Ds, &TVEurgb60Hz240Ds, &TVNtsc240Ds,
&TVEurgb60Hz240DsAa, &TVNtsc240DsAa, &TVEurgb60Hz240DsAa, &TVNtsc240DsAa,
&TVEurgb60Hz240Int, &TVNtsc240Int, &TVEurgb60Hz240Int, &TVNtsc240Int,

View File

@ -3,7 +3,14 @@
#include <gccore.h> #include <gccore.h>
#ifdef __cplusplus
extern "C" {
#endif
void patchVideoModes(void *dst, u32 len, int vidMode, GXRModeObj *vmode, int patchVidModes); void patchVideoModes(void *dst, u32 len, int vidMode, GXRModeObj *vmode, int patchVidModes);
#ifdef __cplusplus
}
#endif
#endif // !defined(_VIDEOPATCH_H_) #endif // !defined(_VIDEOPATCH_H_)

View File

@ -0,0 +1,407 @@
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <ogcsys.h>
/* Constants */
#define IOCTL_DI_READID 0x70
#define IOCTL_DI_READ 0x71
#define IOCTL_DI_WAITCVRCLOSE 0x79
#define IOCTL_DI_GETCOVER 0x88
#define IOCTL_DI_RESET 0x8A
#define IOCTL_DI_OPENPART 0x8B
#define IOCTL_DI_CLOSEPART 0x8C
#define IOCTL_DI_UNENCREAD 0x8D
#define IOCTL_DI_SEEK 0xAB
#define IOCTL_DI_STOPLASER 0xD2
#define IOCTL_DI_OFFSET 0xD9
#define IOCTL_DI_DISC_BCA 0xDA
#define IOCTL_DI_REQUESTERROR 0xE0
#define IOCTL_DI_STOPMOTOR 0xE3
#define IOCTL_DI_DVDAUDIOBUFFERCFG 0xE4
#define IOCTL_DI_SETWBFSMODE 0xF4
#define IOCTL_DI_SETFRAG 0xF9
#define IOCTL_DI_GETMODE 0xFA
#define IOCTL_DI_HELLO 0xFB
/* Variables */
static u32 inbuf[8] ATTRIBUTE_ALIGN(32);
static u32 outbuf[8] ATTRIBUTE_ALIGN(32);
static const char di_fs[] ATTRIBUTE_ALIGN(32) = "/dev/di";
static s32 di_fd = -1;
s32 WDVD_Init(void)
{
/* Open "/dev/di" */
if (di_fd < 0) {
di_fd = IOS_Open(di_fs, 0);
if (di_fd < 0)
return di_fd;
}
return 0;
}
s32 WDVD_Close(void)
{
/* Close "/dev/di" */
if (di_fd >= 0) {
IOS_Close(di_fd);
di_fd = -1;
}
return 0;
}
s32 WDVD_GetHandle(void)
{
/* Return di handle */
return di_fd;
}
s32 WDVD_Reset(void)
{
memset(inbuf, 0, sizeof(inbuf));
/* Reset drive */
inbuf[0] = IOCTL_DI_RESET << 24;
inbuf[1] = 1;
s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_RESET, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf));
if (ret < 0) return ret;
return (ret == 1) ? 0 : -ret;
}
s32 WDVD_ReadDiskId(void *id)
{
memset(inbuf, 0, sizeof(inbuf));
/* Read disc ID */
inbuf[0] = IOCTL_DI_READID << 24;
s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_READID, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf));
if (ret < 0) return ret;
if (ret == 1)
{
memcpy(id, outbuf, sizeof(dvddiskid));
return 0;
}
return -ret;
}
s32 WDVD_Seek(u64 offset)
{
memset(inbuf, 0, sizeof(inbuf));
/* Drive seek */
inbuf[0] = IOCTL_DI_SEEK << 24;
inbuf[1] = (u32)(offset >> 2);
s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_SEEK, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf));
if (ret < 0) return ret;
return (ret == 1) ? 0 : -ret;
}
s32 WDVD_Offset(u64 offset)
{
//u32 *off = (u32 *)((void *)&offset);
union { u64 off64; u32 off32[2]; } off;
off.off64 = offset;
memset(inbuf, 0, sizeof(inbuf));
/* Set offset */
inbuf[0] = IOCTL_DI_OFFSET << 24;
inbuf[1] = (off.off32[0]) ? 1: 0;
inbuf[2] = (off.off32[1] >> 2);
s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_OFFSET, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf));
if (ret < 0) return ret;
return (ret == 1) ? 0 : -ret;
}
s32 WDVD_StopLaser(void)
{
memset(inbuf, 0, sizeof(inbuf));
/* Stop laser */
inbuf[0] = IOCTL_DI_STOPLASER << 24;
s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_STOPLASER, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf));
if (ret < 0) return ret;
return (ret == 1) ? 0 : -ret;
}
s32 WDVD_StopMotor(void)
{
memset(inbuf, 0, sizeof(inbuf));
/* Stop motor */
inbuf[0] = IOCTL_DI_STOPMOTOR << 24;
s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_STOPMOTOR, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf));
if (ret < 0) return ret;
return (ret == 1) ? 0 : -ret;
}
s32 WDVD_Eject(void)
{
memset(inbuf, 0, sizeof(inbuf));
/* Stop motor */
inbuf[0] = IOCTL_DI_STOPMOTOR << 24;
/* Eject DVD */
inbuf[1] = 1;
s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_STOPMOTOR, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf));
if (ret < 0) return ret;
return (ret == 1) ? 0 : -ret;
}
s32 WDVD_OpenPartition(u64 offset)
{
if (di_fd < 0)
return di_fd;
static u8 Tmd_Buffer[0x4A00] ATTRIBUTE_ALIGN(32);
static ioctlv Vectors[5] ATTRIBUTE_ALIGN(32);
s32 ret;
memset(inbuf, 0, sizeof inbuf);
memset(outbuf, 0, sizeof outbuf);
inbuf[0] = IOCTL_DI_OPENPART << 24;
inbuf[1] = offset >> 2;
Vectors[0].data = inbuf;
Vectors[0].len = 0x20;
Vectors[1].data = 0;
Vectors[1].len = 0;
Vectors[2].data = 0;
Vectors[2].len = 0;
Vectors[3].data = Tmd_Buffer;
Vectors[3].len = 0x49e4;
Vectors[4].data = outbuf;
Vectors[4].len = 0x20;
ret = IOS_Ioctlv(di_fd, IOCTL_DI_OPENPART, 3, 2, (ioctlv *)Vectors);
if (ret < 0)
return ret;
return (ret == 1) ? 0 : -ret;
}
s32 WDVD_ClosePartition(void)
{
memset(inbuf, 0, sizeof(inbuf));
/* Close partition */
inbuf[0] = IOCTL_DI_CLOSEPART << 24;
s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_CLOSEPART, inbuf, sizeof(inbuf), NULL, 0);
if (ret < 0) return ret;
return (ret == 1) ? 0 : -ret;
}
s32 WDVD_UnencryptedRead(void *buf, u32 len, u64 offset)
{
memset(inbuf, 0, sizeof(inbuf));
/* Unencrypted read */
inbuf[0] = IOCTL_DI_UNENCREAD << 24;
inbuf[1] = len;
inbuf[2] = (u32)(offset >> 2);
s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_UNENCREAD, inbuf, sizeof(inbuf), buf, len);
if (ret < 0) return ret;
return (ret == 1) ? 0 : -ret;
}
s32 WDVD_Read(void *buf, u32 len, u64 offset)
{
memset(inbuf, 0, sizeof(inbuf));
/* Disc read */
inbuf[0] = IOCTL_DI_READ << 24;
inbuf[1] = len;
inbuf[2] = (u32)(offset >> 2);
s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_READ, inbuf, sizeof(inbuf), buf, len);
if (ret < 0) return ret;
return (ret == 1) ? 0 : -ret;
}
s32 WDVD_LowRequestError(u32 *error)
{
memset(inbuf, 0, sizeof(inbuf));
inbuf[0] = IOCTL_DI_REQUESTERROR << 24;
s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_REQUESTERROR, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf));
if (ret < 0) return ret;
if (ret == 1)
memcpy(error, outbuf, sizeof(u32));
return (ret == 1) ? 0 : -ret;
}
s32 WDVD_WaitForDisc(void)
{
memset(inbuf, 0, sizeof(inbuf));
/* Wait for disc */
inbuf[0] = IOCTL_DI_WAITCVRCLOSE << 24;
s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_WAITCVRCLOSE, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf));
if (ret < 0) return ret;
return (ret == 1) ? 0 : -ret;
}
s32 WDVD_GetCoverStatus(u32 *status)
{
memset(inbuf, 0, sizeof(inbuf));
/* Get cover status */
inbuf[0] = IOCTL_DI_GETCOVER << 24;
s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_GETCOVER, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf));
if (ret < 0) return ret;
if (ret == 1) {
/* Copy cover status */
memcpy(status, outbuf, sizeof(u32));
return 0;
}
return -ret;
}
s32 WDVD_SetUSBMode(u32 mode, const u8 *id, s32 partition)
{
memset(inbuf, 0, sizeof(inbuf));
/* Set USB mode */
inbuf[0] = IOCTL_DI_SETWBFSMODE << 24;
inbuf[1] = mode;
/* Copy ID */
if(id)
{
memcpy(&inbuf[2], id, 6);
if(partition >= 0)
inbuf[5] = partition;
}
s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_SETWBFSMODE, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf));
if(ret < 0)
return ret;
return(ret == 1) ? 0 : -ret;
}
s32 WDVD_Read_Disc_BCA(void *buf)
{
memset(inbuf, 0, sizeof(inbuf));
/* Disc read */
inbuf[0] = IOCTL_DI_DISC_BCA << 24;
//inbuf[1] = 64;
s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_DISC_BCA, inbuf, sizeof(inbuf), buf, 64);
if (ret < 0) return ret;
return (ret == 1) ? 0 : -ret;
}
// frag
s32 WDVD_SetFragList(int device, void *fraglist, int size)
{
memset(inbuf, 0, sizeof(inbuf));
memset(outbuf, 0, sizeof(outbuf));
/* Set FRAG mode */
inbuf[0] = IOCTL_DI_SETFRAG << 24;
inbuf[1] = device;
inbuf[2] = (u32)fraglist;
inbuf[3] = size;
DCFlushRange(fraglist, size);
s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_SETFRAG, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf));
if (ret < 0) return ret;
return (ret == 1) ? 0 : -ret;
}
s32 WDVD_hello(u32 *status)
{
memset(inbuf, 0, sizeof(inbuf));
inbuf[0] = IOCTL_DI_HELLO << 24;
s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_HELLO, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf));
if (ret < 0) return ret;
if (ret == 1)
{
if (status) memcpy(status, outbuf, sizeof(u32));
return 0;
}
return -ret;
}
s32 WDVD_SetStreaming(void)
{
memset(inbuf, 0, sizeof(inbuf));
inbuf[0] = IOCTL_DI_DVDAUDIOBUFFERCFG << 24;
if ((*(u32*)0x80000008)>>24)
{
inbuf[1] = 1;
if(((*(u32*)0x80000008)>>16) & 0xFF)
inbuf[2] = 10;
else
inbuf[2] = 0;
}
else
{
inbuf[1] = 0;
inbuf[2] = 0;
}
s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_DVDAUDIOBUFFERCFG, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf));
if (ret < 0) return ret;
return (ret == 1) ? 0 : -ret;
}
s32 WDVD_NEEK_LoadDisc(u32 id, u32 magic)
{
u32 *vec = (u32*)memalign(32, sizeof(u32) * 2);
vec[0] = id;
vec[1] = magic;
s32 ret = IOS_Ioctl(di_fd, 0x25, vec, sizeof(u32) * 2, NULL, 0);
free(vec);
return ret;
}

View File

@ -0,0 +1,37 @@
#ifndef _WDVD_H_
#define _WDVD_H_
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Prototypes */
s32 WDVD_Init(void);
s32 WDVD_Close(void);
s32 WDVD_GetHandle(void);
s32 WDVD_Reset(void);
s32 WDVD_ReadDiskId(void *);
s32 WDVD_Seek(u64);
s32 WDVD_Offset(u64);
s32 WDVD_StopLaser(void);
s32 WDVD_StopMotor(void);
s32 WDVD_OpenPartition(u64 offset);
s32 WDVD_ClosePartition(void);
s32 WDVD_UnencryptedRead(void *, u32, u64);
s32 WDVD_Read(void *, u32, u64);
s32 WDVD_LowRequestError(u32 *error);
s32 WDVD_WaitForDisc(void);
s32 WDVD_GetCoverStatus(u32 *);
s32 WDVD_SetUSBMode(u32, const u8 *, s32);
s32 WDVD_Eject(void);
s32 WDVD_Read_Disc_BCA(void *);
s32 WDVD_SetFragList(int device, void *fraglist, int size);
s32 WDVD_SetStreaming(void);
s32 WDVD_NEEK_LoadDisc(u32 id, u32 magic);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

View File

@ -0,0 +1,140 @@
#include <gccore.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include "wip.h"
static WIP_Code * CodeList = NULL;
static u32 CodesCount = 0;
static u32 ProcessedLength = 0;
static u32 Counter = 0;
void do_wip_code(u8 * dst, u32 len)
{
if(!CodeList)
return;
if(Counter < 3)
{
Counter++;
return;
}
u32 i = 0;
s32 n = 0;
s32 offset = 0;
for(i = 0; i < CodesCount; i++)
{
for(n = 0; n < 4; n++)
{
offset = CodeList[i].offset+n-ProcessedLength;
if(offset < 0 || (u32)offset >= len)
continue;
if(dst[offset] == ((u8 *)&CodeList[i].srcaddress)[n])
{
dst[offset] = ((u8 *)&CodeList[i].dstaddress)[n];
//printf("WIP: %08X Address Patched.\n", CodeList[i].offset + n);
}
else
{
//printf("WIP: %08X Address does not match with WIP entry.\n", CodeList[i].offset+n);
//printf("Destination: %02X | Should be: %02X.\n", dst[offset], ((u8 *)&CodeList[i].srcaddress)[n]);
}
}
}
ProcessedLength += len;
Counter++;
}
//! for internal patches only
//! .wip files override internal patches
//! the codelist has to be freed if the set fails
//! if set was successful the codelist will be freed when it's done
bool set_wip_list(WIP_Code * list, int size)
{
if(!CodeList && size > 0)
{
CodeList = list;
CodesCount = size;
return true;
}
return false;
}
void wip_reset_counter()
{
ProcessedLength = 0;
//alternative dols don't need a skip. only main.dol.
Counter = 3;
}
void free_wip()
{
if(CodeList)
free(CodeList);
CodesCount = 0;
ProcessedLength = 0;
}
int load_wip_patches(u8 *dir, u8 *gameid)
{
char filepath[150];
char GameID[8];
memset(GameID, 0, sizeof(GameID));
memcpy(GameID, gameid, 6);
snprintf(filepath, sizeof(filepath), "%s/%s.wip", dir, GameID);
FILE *fp = fopen(filepath, "rb");
if(!fp)
{
memset(GameID, 0, sizeof(GameID));
memcpy(GameID, gameid, 3);
snprintf(filepath, sizeof(filepath), "%s/%s.wip", dir, GameID);
fp = fopen(filepath, "rb");
}
if(!fp)
return -1;
char line[255];
//printf("\nLoading WIP code from %s.\n", filepath);
while(fgets(line, sizeof(line), fp))
{
if(line[0] == '#' || strlen(line) < 26)
continue;
u32 offset = (u32) strtoul(line, NULL, 16);
u32 srcaddress = (u32) strtoul(line+9, NULL, 16);
u32 dstaddress = (u32) strtoul(line+18, NULL, 16);
if(!CodeList)
CodeList = malloc(sizeof(WIP_Code));
WIP_Code *tmp = realloc(CodeList, (CodesCount+1)*sizeof(WIP_Code));
if(!tmp)
{
free(CodeList);
fclose(fp);
return -1;
}
CodeList = tmp;
CodeList[CodesCount].offset = offset;
CodeList[CodesCount].srcaddress = srcaddress;
CodeList[CodesCount].dstaddress = dstaddress;
CodesCount++;
}
fclose(fp);
//printf("\n");
return 0;
}

View File

@ -0,0 +1,25 @@
#ifndef __WIP_H__
#define __WIP_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct
{
u32 offset;
u32 srcaddress;
u32 dstaddress;
} WIP_Code;
bool set_wip_list(WIP_Code *list, int size);
void wip_reset_counter();
void free_wip();
void do_wip_code(u8 *dst, u32 len);
int load_wip_patches(u8 *dir, u8 *gameid);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif //__WIP_H__

View File

@ -7,18 +7,12 @@
#include "channel_launcher.h" #include "channel_launcher.h"
#include "gecko/gecko.h" #include "gecko/gecko.h"
#include "loader/disc.h" #include "loader/disc.h"
#include "loader/external_booter.hpp"
#include "loader/fs.h" #include "loader/fs.h"
#include "loader/fst.h" #include "loader/fst.h"
#include "loader/patchcode.h"
#include "loader/utils.h" #include "loader/utils.h"
#include "loader/videopatch.h"
#include "unzip/lz77.h" #include "unzip/lz77.h"
#include "types.h"
void __Disc_SetLowMem(void);
void __Disc_SetTime(void);
void _unstub_start();
extern void __exception_closeall();
typedef void (*entrypoint) (void); typedef void (*entrypoint) (void);
@ -33,33 +27,12 @@ typedef struct _dolheader
u32 padding[7]; u32 padding[7];
} __attribute__((packed)) dolheader; } __attribute__((packed)) dolheader;
u32 entryPoint; void *dolchunkoffset[18];
u32 dolchunksize[18];
u32 dolchunkcount;
s32 BootChannel(u32 entry, u64 chantitle, u32 ios, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio) s32 BootChannel(u32 entry, u64 chantitle, u32 ios, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio)
{ {
gprintf("Loading Channel...\n");
entryPoint = entry;
/* Select an appropriate video mode */
u32 vmode_reg = 0;
GXRModeObj *vmode = Disc_SelectVMode(vidMode, chantitle, &vmode_reg);
/* Set time */
__Disc_SetTime();
/* Set low memory */
__Disc_SetLowMem();
if (hooktype != 0)
ocarina_do_code();
PatchChannel(vidMode, vmode, vipatch, countryString, patchVidMode, aspectRatio);
entrypoint appJump = (entrypoint)entryPoint;
/* Set an appropriate video mode */
Disc_SetVMode(vmode, vmode_reg);
// IOS Version Check // IOS Version Check
*(vu32*)0x80003140 = ((ios << 16)) | 0xFFFF; *(vu32*)0x80003140 = ((ios << 16)) | 0xFFFF;
*(vu32*)0x80003188 = ((ios << 16)) | 0xFFFF; *(vu32*)0x80003188 = ((ios << 16)) | 0xFFFF;
@ -71,70 +44,11 @@ s32 BootChannel(u32 entry, u64 chantitle, u32 ios, u8 vidMode, bool vipatch, boo
*(vu32 *)0x80000000 = TITLE_LOWER(chantitle); *(vu32 *)0x80000000 = TITLE_LOWER(chantitle);
DCFlushRange((void *)0x80000000, 4); DCFlushRange((void *)0x80000000, 4);
gprintf("Jumping to entrypoint %08x\n", entryPoint); ExternalBooter_ChannelSetup(dolchunkoffset, dolchunksize, dolchunkcount, entry);
WiiFlow_ExternalBooter(vidMode, vipatch, countryString, patchVidMode, aspectRatio, 0, TYPE_CHANNEL);
/* Shutdown IOS subsystems */
u32 level = IRQ_Disable();
__IOS_ShutdownSubsystems();
__exception_closeall();
/* Originally from tueidj - taken from NeoGamma (thx) */
*(vu32*)0xCC003024 = 1;
if (entryPoint != 0x3400)
{
if(hooktype != 0)
{
asm volatile (
"lis %r3, entryPoint@h\n"
"ori %r3, %r3, entryPoint@l\n"
"lwz %r3, 0(%r3)\n"
"mtlr %r3\n"
"lis %r3, 0x8000\n"
"ori %r3, %r3, 0x18A8\n"
"nop\n"
"mtctr %r3\n"
"bctr\n"
);
}
else
appJump();
}
else if(hooktype != 0)
{
asm volatile (
"lis %r3, returnpoint@h\n"
"ori %r3, %r3, returnpoint@l\n"
"mtlr %r3\n"
"lis %r3, 0x8000\n"
"ori %r3, %r3, 0x18A8\n"
"nop\n"
"mtctr %r3\n"
"bctr\n"
"returnpoint:\n"
"bl DCDisable\n"
"bl ICDisable\n"
"li %r3, 0\n"
"mtsrr1 %r3\n"
"lis %r4, entryPoint@h\n"
"ori %r4,%r4,entryPoint@l\n"
"lwz %r4, 0(%r4)\n"
"mtsrr0 %r4\n"
"rfi\n"
);
}
else
_unstub_start();
IRQ_Restore(level);
return 0; return 0;
} }
void *dolchunkoffset[18];
u32 dolchunksize[18];
u32 dolchunkcount;
u32 LoadChannel(u8 *buffer) u32 LoadChannel(u8 *buffer)
{ {
dolchunkcount = 0; dolchunkcount = 0;
@ -163,7 +77,7 @@ u32 LoadChannel(u8 *buffer)
dolchunkoffset[dolchunkcount] = (void *)dolfile->section_start[i]; dolchunkoffset[dolchunkcount] = (void *)dolfile->section_start[i];
dolchunksize[dolchunkcount] = dolfile->section_size[i]; dolchunksize[dolchunkcount] = dolfile->section_size[i];
gprintf("Moving section %u from offset %08x to %08x-%08x...\n", i, dolfile->section_pos[i], dolchunkoffset[dolchunkcount], dolchunkoffset[dolchunkcount]+dolchunksize[dolchunkcount]); gprintf("Moving section %u from offset %08x to %08x-%08x...\n", i, dolfile->section_pos[i], dolchunkoffset[dolchunkcount], (u32)dolchunkoffset[dolchunkcount]+dolchunksize[dolchunkcount]);
memmove(dolchunkoffset[dolchunkcount], buffer + dolfile->section_pos[i], dolchunksize[dolchunkcount]); memmove(dolchunkoffset[dolchunkcount], buffer + dolfile->section_pos[i], dolchunksize[dolchunkcount]);
DCFlushRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]); DCFlushRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]);
ICInvalidateRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]); ICInvalidateRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]);
@ -173,30 +87,6 @@ u32 LoadChannel(u8 *buffer)
return dolfile->entry_point; return dolfile->entry_point;
} }
void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio)
{
bool hookpatched = false;
u32 i;
for (i=0; i < dolchunkcount; i++)
{
patchVideoModes(dolchunkoffset[i], dolchunksize[i], vidMode, vmode, patchVidModes);
if (vipatch) vidolpatcher(dolchunkoffset[i], dolchunksize[i]);
if (configbytes[0] != 0xCD) langpatcher(dolchunkoffset[i], dolchunksize[i]);
if (countryString) PatchCountryStrings(dolchunkoffset[i], dolchunksize[i]);
if (aspectRatio != -1) PatchAspectRatio(dolchunkoffset[i], dolchunksize[i], aspectRatio);
if (hooktype != 0)
if (dogamehooks(dolchunkoffset[i], dolchunksize[i], true))
hookpatched = true;
}
if (hooktype != 0 && !hookpatched)
{
gprintf("Error: Could not patch the hook\n");
gprintf("Ocarina and debugger won't work\n");
}
}
bool Identify_GenerateTik(signed_blob **outbuf, u32 *outlen) bool Identify_GenerateTik(signed_blob **outbuf, u32 *outlen)
{ {
signed_blob *buffer = (signed_blob *)memalign(32, ALIGN32(STD_SIGNED_TIK_SIZE)); signed_blob *buffer = (signed_blob *)memalign(32, ALIGN32(STD_SIGNED_TIK_SIZE));

View File

@ -1,10 +1,6 @@
#ifndef _CHAN_LAUNCHER #ifndef _CHAN_LAUNCHER
#define _CHAN_LAUNCHER #define _CHAN_LAUNCHER
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <gctypes.h> #include <gctypes.h>
#include <gccore.h> #include <gccore.h>
@ -18,8 +14,4 @@ u8 *GetDol(u64 title, u32 bootcontent);
bool Identify(u64 titleid); bool Identify(u64 titleid);
bool Identify_GenerateTik(signed_blob **outbuf, u32 *outlen); bool Identify_GenerateTik(signed_blob **outbuf, u32 *outlen);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _CHAN_LAUNCHER */ #endif /* _CHAN_LAUNCHER */

View File

@ -1,18 +0,0 @@
#define STUB 0x3400
.text
.section .text
.globl _unstub_start
_unstub_start:
isync
// set MSR[DR:IR] = 00, jump to STUB
lis 3,STUB@h
ori 3,3,STUB@l
mtsrr0 3
mfmsr 3
li 4,0x30
andc 3,3,4
mtsrr1 3
rfi

View File

@ -32,6 +32,7 @@
#include "fileOps/fileOps.h" #include "fileOps/fileOps.h"
#include "loader/utils.h" #include "loader/utils.h"
#include "loader/disc.h" #include "loader/disc.h"
#include "memory/memory.h"
// DIOS-MIOS // DIOS-MIOS
DML_CFG *DMLCfg = NULL; DML_CFG *DMLCfg = NULL;
@ -384,8 +385,31 @@ void GC_SetVideoMode(u8 videomode, u8 videoSetting)
__SYS_UnlockSram(1); // 1 -> write changes __SYS_UnlockSram(1); // 1 -> write changes
while(!__SYS_SyncSram()); while(!__SYS_SyncSram());
/* Set an appropriate video mode */ /* Set video mode register */
Disc_SetVMode(vmode, vmode_reg); *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() u8 get_wii_language()

View File

@ -7,15 +7,12 @@
#include <ogc/lwp_watchdog.h> #include <ogc/lwp_watchdog.h>
#include <ogc/machine/processor.h> #include <ogc/machine/processor.h>
#include "apploader.h"
#include "disc.h" #include "disc.h"
#include "wdvd.h" #include "wdvd.h"
#include "sys.h" #include "sys.h"
#include "fst.h" #include "fst.h"
#include "videopatch.h"
#include "wbfs.h" #include "wbfs.h"
#include "patchcode.h"
#include "frag.h" #include "frag.h"
#include "wip.h" #include "wip.h"
@ -36,224 +33,6 @@ u32 appentrypoint;
static u32 *buffer = (u32 *)0x93000000; static u32 *buffer = (u32 *)0x93000000;
static u8 *diskid = (u8 *)0x80000000; static u8 *diskid = (u8 *)0x80000000;
GXRModeObj *vmode = NULL;
u32 vmode_reg = 0;
extern void __exception_closeall();
entry_point p_entry;
void __Disc_SetLowMem()
{
/* Setup low memory */
*Sys_Magic = 0x0D15EA5E; // Standard Boot Code
*Sys_Version = 0x00000001; // Version
*Arena_L = 0x00000000; // Arena Low
*BI2 = 0x817E5480; // BI2
*Bus_Speed = 0x0E7BE2C0; // Console Bus Speed
*CPU_Speed = 0x2B73A840; // Console CPU Speed
*Assembler = 0x38A00040; // Assembler
*(vu32*)0x800000E4 = 0x80431A80;
*Dev_Debugger = 0x81800000; // Dev Debugger Monitor Address
*Simulated_Mem = 0x01800000; // Simulated Memory Size
*(vu32*)0xCD00643C = 0x00000000; // 32Mhz on Bus
/* Fix for Sam & Max (WiiPower) */
if(CurrentIOS.Type != IOS_TYPE_HERMES)
*GameID_Address = 0x80000000;
/* Copy disc ID */
memcpy((void *)Online_Check, (void *)Disc_ID, 4);
}
GXRModeObj *Disc_SelectVMode(u8 videoselected, u64 chantitle, u32 *rmode_reg)
{
GXRModeObj *rmode = VIDEO_GetPreferredMode(0);
/* Get video mode configuration */
bool progressive = (CONF_GetProgressiveScan() > 0) && VIDEO_HaveComponentCable();
/* Select video mode register */
switch (CONF_GetVideo())
{
case CONF_VIDEO_PAL:
if (CONF_GetEuRGB60() > 0)
{
*rmode_reg = VI_EURGB60;
rmode = progressive ? &TVNtsc480Prog : &TVEurgb60Hz480IntDf;
}
else
*rmode_reg = VI_PAL;
break;
case CONF_VIDEO_MPAL:
*rmode_reg = VI_MPAL;
break;
case CONF_VIDEO_NTSC:
*rmode_reg = VI_NTSC;
break;
}
char Region;
if(chantitle)
Region = ((u32)(chantitle) & 0xFFFFFFFF) % 256;
else
Region = diskid[3];
switch(videoselected)
{
case 0: // DEFAULT (DISC/GAME)
/* Select video mode */
switch(Region)
{
case 'W':
break; // Don't overwrite wiiware video modes.
// PAL
case 'D':
case 'F':
case 'P':
case 'X':
case 'Y':
if(CONF_GetVideo() != CONF_VIDEO_PAL)
{
*rmode_reg = VI_PAL;
rmode = progressive ? &TVNtsc480Prog : &TVNtsc480IntDf;
}
break;
// NTSC
case 'E':
case 'J':
default:
if(CONF_GetVideo() != CONF_VIDEO_NTSC)
{
*rmode_reg = VI_NTSC;
rmode = progressive ? &TVNtsc480Prog : &TVEurgb60Hz480IntDf;
}
break;
}
break;
case 1: // SYSTEM
break;
case 2: // PAL50
rmode = &TVPal528IntDf;
*rmode_reg = rmode->viTVMode >> 2;
break;
case 3: // PAL60
rmode = progressive ? &TVNtsc480Prog : &TVEurgb60Hz480IntDf;
*rmode_reg = progressive ? TVEurgb60Hz480Prog.viTVMode >> 2 : rmode->viTVMode >> 2;
break;
case 4: // NTSC
rmode = progressive ? &TVNtsc480Prog : &TVNtsc480IntDf;
*rmode_reg = rmode->viTVMode >> 2;
break;
case 5: // PROGRESSIVE 480P
rmode = &TVNtsc480Prog;
*rmode_reg = Region == 'P' ? TVEurgb60Hz480Prog.viTVMode >> 2 : rmode->viTVMode >> 2;
break;
default:
break;
}
return rmode;
}
void Disc_SetVMode(GXRModeObj *rmode, u32 rmode_reg)
{
/* Set video mode register */
*Video_Mode = rmode_reg;
DCFlushRange((void*)Video_Mode, 4);
/* Set video mode */
if(rmode != 0)
VIDEO_Configure(rmode);
/* Setup video */
VIDEO_SetBlack(FALSE);
VIDEO_Flush();
VIDEO_WaitVSync();
if(rmode->viTVMode & VI_NON_INTERLACE)
VIDEO_WaitVSync();
else while(VIDEO_GetNextField())
VIDEO_WaitVSync();
/* Set black and flush */
VIDEO_SetBlack(TRUE);
VIDEO_Flush();
VIDEO_WaitVSync();
if(rmode->viTVMode & VI_NON_INTERLACE)
VIDEO_WaitVSync();
else while(VIDEO_GetNextField())
VIDEO_WaitVSync();
}
void __Disc_SetTime(void)
{
/* Set proper time */
settime(secs_to_ticks(time(NULL) - 946684800));
}
s32 Disc_FindPartition(u64 *outbuf)
{
u8 TMP_Buffer_size = 0x20;
u64 offset = 0;
u32 cnt;
u32 *TMP_Buffer = (u32*)memalign(32, TMP_Buffer_size);
if(!TMP_Buffer)
return -1;
/* Read partition info */
s32 ret = WDVD_UnencryptedRead(TMP_Buffer, TMP_Buffer_size, PTABLE_OFFSET);
if(ret < 0)
{
free(TMP_Buffer);
return ret;
}
/* Get data */
u32 nb_partitions = TMP_Buffer[0];
u64 table_offset = TMP_Buffer[1] << 2;
if(nb_partitions > 8)
{
free(TMP_Buffer);
return -1;
}
memset(TMP_Buffer, 0, TMP_Buffer_size);
/* Read partition table */
ret = WDVD_UnencryptedRead(TMP_Buffer, TMP_Buffer_size, table_offset);
if (ret < 0)
{
free(TMP_Buffer);
return ret;
}
/* Find game partition */
for(cnt = 0; cnt < nb_partitions; cnt++)
{
u32 type = TMP_Buffer[cnt * 2 + 1];
/* Game partition */
if(!type)
offset = TMP_Buffer[cnt * 2] << 2;
}
free(TMP_Buffer);
/* No game partition found */
if (!offset)
return -1;
/* Set output buffer */
*outbuf = offset;
WDVD_Seek(offset);
return 0;
}
s32 Disc_Init(void) s32 Disc_Init(void)
{ {
/* Init DVD subsystem */ /* Init DVD subsystem */
@ -371,69 +150,3 @@ s32 Disc_IsGC(void)
{ {
return Disc_Type(1); return Disc_Type(1);
} }
s32 Disc_BootPartition()
{
/* Set time */
__Disc_SetTime();
/* Set an appropriate video mode */
Disc_SetVMode(vmode, vmode_reg);
/* Shutdown IOS subsystems */
u32 level = IRQ_Disable();
__IOS_ShutdownSubsystems();
__exception_closeall();
/* Originally from tueidj - taken from NeoGamma (thx) */
*(vu32*)0xCC003024 = 1;
if(hooktype != 0)
{
asm volatile (
"lis %r3, appentrypoint@h\n"
"ori %r3, %r3, appentrypoint@l\n"
"lwz %r3, 0(%r3)\n"
"mtlr %r3\n"
"lis %r3, 0x8000\n"
"ori %r3, %r3, 0x18A8\n"
"nop\n"
"mtctr %r3\n"
"bctr\n"
);
}
else
{
asm volatile (
"lis %r3, appentrypoint@h\n"
"ori %r3, %r3, appentrypoint@l\n"
"lwz %r3, 0(%r3)\n"
"mtlr %r3\n"
"blr\n"
);
}
IRQ_Restore(level);
return 0;
}
void Disc_BootWiiGame(u64 offset, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio, u32 returnTo)
{
/* Open Partition */
WDVD_OpenPartition(offset);
/* Setup low memory */
__Disc_SetLowMem();
/* Select an appropriate video mode */
vmode = Disc_SelectVMode(vidMode, 0, &vmode_reg);
/* Run apploader */
Apploader_Run(&p_entry, vidMode, vmode, vipatch, countryString, patchVidMode, aspectRatio, returnTo);
appentrypoint = (u32)p_entry;
/* Boot Game */
gprintf("Entry Point: 0x%08x\n", appentrypoint);
Disc_BootPartition();
}

View File

@ -103,14 +103,6 @@ s32 Disc_ReadGCHeader(void *);
s32 Disc_Type(bool); s32 Disc_Type(bool);
s32 Disc_IsWii(void); s32 Disc_IsWii(void);
s32 Disc_IsGC(void); s32 Disc_IsGC(void);
s32 Disc_BootPartition();
s32 Disc_FindPartition(u64 *outbuf);
GXRModeObj *Disc_SelectVMode(u8 videoselected, u64 chantitle, u32 *rmode_reg);
void Disc_SetVMode(GXRModeObj *rmode, u32 rmode_reg);
void Disc_BootWiiGame(u64 offset, u8 vidMode, bool vipatch, bool countryString,
u8 patchVidMode, int aspectRatio, u32 returnTo);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -0,0 +1,106 @@
/****************************************************************************
* 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 <string.h>
#include "external_booter.hpp"
#include "cios.h"
#include "fst.h"
#include "homebrew/homebrew.h"
/* External WiiFlow Game Booter */
#define EXECUTE_ADDR ((u8 *)0x92000000)
extern const u8 wii_game_booter_dol[];
extern const u32 wii_game_booter_dol_size;
extern "C" {
u8 configbytes[2];
u32 hooktype;
};
typedef struct _the_CFG {
u8 vidMode;
bool vipatch;
bool countryString;
u8 patchVidMode;
int aspectRatio;
u32 returnTo;
u8 configbytes[2];
IOS_Info IOS;
void *codelist;
u8 *codelistend;
u8 *cheats;
u32 cheatSize;
u32 hooktype;
u8 debugger;
u32 *gameconf;
u32 gameconfsize;
u8 BootType;
/* needed for channels */
void *dolchunkoffset[18];
u32 dolchunksize[18];
u32 dolchunkcount;
u32 startPoint;
} the_CFG;
the_CFG normalCFG;
extern u8 *code_buf;
extern u32 code_size;
extern void *codelist;
extern u8 *codelistend;
extern u32 gameconfsize;
extern u32 *gameconf;
void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio, u32 returnTo, u8 BootType)
{
normalCFG.vidMode = vidMode;
normalCFG.vipatch = vipatch;
normalCFG.countryString = countryString;
normalCFG.patchVidMode = patchVidMode;
normalCFG.aspectRatio = aspectRatio;
normalCFG.returnTo = returnTo;
normalCFG.configbytes[0] = configbytes[0];
normalCFG.configbytes[1] = configbytes[1];
normalCFG.IOS = CurrentIOS;
normalCFG.codelist = codelist;
normalCFG.codelistend = codelistend;
normalCFG.cheats = code_buf;
normalCFG.cheatSize = code_size;
normalCFG.hooktype = hooktype;
normalCFG.debugger = debuggerselect;
normalCFG.gameconf = gameconf;
normalCFG.gameconfsize = gameconfsize;
normalCFG.BootType = BootType;
memcpy((void *)0x90000000, &normalCFG, sizeof(the_CFG));
DCFlushRange((void *)(0x90000000), sizeof(the_CFG));
memcpy(EXECUTE_ADDR, wii_game_booter_dol, wii_game_booter_dol_size);
DCFlushRange(EXECUTE_ADDR, wii_game_booter_dol_size);
BootHomebrew();
}
void ExternalBooter_ChannelSetup(void *dolchunkoffset[18], u32 dolchunksize[18], u32 dolchunkcount, u32 StartPoint)
{
for(u8 i = 0; i < 18; i++)
{
normalCFG.dolchunkoffset[i] = dolchunkoffset[i];
normalCFG.dolchunksize[i] = dolchunksize[i];
}
normalCFG.dolchunkcount = dolchunkcount;
normalCFG.startPoint = StartPoint;
}

View File

@ -0,0 +1,35 @@
/****************************************************************************
* 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/>.
****************************************************************************/
#ifndef EXTERNAL_BOOTER_HPP
#define EXTERNAL_BOOTER_HPP
#ifdef __cplusplus
extern "C" {
#endif
extern u8 configbytes[2];
extern u32 hooktype;
#ifdef __cplusplus
}
#endif
void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode,
int aspectRatio, u32 returnTo, u8 BootType);
void ExternalBooter_ChannelSetup(void *dolchunkoffset[18], u32 dolchunksize[18], u32 dolchunkcount, u32 StartPoint);
#endif

View File

@ -28,11 +28,6 @@
#include "fst.h" #include "fst.h"
#include "sys.h" #include "sys.h"
#include "patchcode.h"
#include "codehandler.h"
#include "codehandleronly.h"
#include "multidol.h"
#include "gecko/gecko.h" #include "gecko/gecko.h"
#include "memory/mem2.hpp" #include "memory/mem2.hpp"
@ -42,7 +37,7 @@
#define MAX_FILENAME_LEN 128 #define MAX_FILENAME_LEN 128
static u8 *codelistend; u8 *codelistend;
void *codelist; void *codelist;
u32 gameconfsize = 0; u32 gameconfsize = 0;
@ -240,7 +235,7 @@ int app_gameconfig_load(u8 *discid, const u8 *gameconfig, u32 tempgameconfsize)
if (i != tempgameconfsize) while ((tempgameconf[i] != 10 && tempgameconf[i] != 13) && (i != 0)) i--; if (i != tempgameconfsize) while ((tempgameconf[i] != 10 && tempgameconf[i] != 13) && (i != 0)) i--;
} }
} }
free(gameconf); free(tempgameconf);
return 0; return 0;
} }
@ -275,181 +270,6 @@ int ocarina_load_code(const u8 *cheat, u32 cheatSize)
} }
gprintf("Ocarina: Codes found.\n"); gprintf("Ocarina: Codes found.\n");
DCFlushRange(code_buf, code_size);
return code_size; return code_size;
} }
void app_pokevalues()
{
u32 i, *codeaddr, *codeaddr2, *addrfound = NULL;
if (gameconfsize != 0)
{
for (i = 0; i < gameconfsize/4; i++)
{
if (*(gameconf + i) == 0)
{
if (((u32 *) (*(gameconf + i + 1))) == NULL ||
*((u32 *) (*(gameconf + i + 1))) == *(gameconf + i + 2))
{
*((u32 *) (*(gameconf + i + 3))) = *(gameconf + i + 4);
DCFlushRange((void *) *(gameconf + i + 3), 4);
}
i += 4;
}
else
{
codeaddr = (u32 *)*(gameconf + i + *(gameconf + i) + 1);
codeaddr2 = (u32 *)*(gameconf + i + *(gameconf + i) + 2);
if (codeaddr == 0 && addrfound != NULL)
codeaddr = addrfound;
else if (codeaddr == 0 && codeaddr2 != 0)
codeaddr = (u32 *) ((((u32) codeaddr2) >> 28) << 28);
else if (codeaddr == 0 && codeaddr2 == 0)
{
i += *(gameconf + i) + 4;
continue;
}
if (codeaddr2 == 0)
codeaddr2 = codeaddr + *(gameconf + i);
addrfound = NULL;
while (codeaddr <= (codeaddr2 - *(gameconf + i)))
{
if (memcmp(codeaddr, gameconf + i + 1, (*(gameconf + i)) * 4) == 0)
{
*(codeaddr + ((*(gameconf + i + *(gameconf + i) + 3)) / 4)) = *(gameconf + i + *(gameconf + i) + 4);
if (addrfound == NULL) addrfound = codeaddr;
}
codeaddr++;
}
i += *(gameconf + i) + 4;
}
}
}
}
void load_handler()
{
if (hooktype != 0x00)
{
if (debuggerselect == 0x01)
{
//gprintf("Debbugger selected is gecko\n");
memset((void*)0x80001800,0,codehandler_size);
memcpy((void*)0x80001800,codehandler,codehandler_size);
//if (pausedstartoption == 0x01)
// *(u32*)0x80002798 = 1;
memcpy((void*)0x80001CDE, &codelist, 2);
memcpy((void*)0x80001CE2, ((u8*) &codelist) + 2, 2);
memcpy((void*)0x80001F5A, &codelist, 2);
memcpy((void*)0x80001F5E, ((u8*) &codelist) + 2, 2);
DCFlushRange((void*)0x80001800,codehandler_size);
}
else
{
//gprintf("Debbugger selected is not gecko\n");
memset((void*)0x80001800,0,codehandleronly_size);
memcpy((void*)0x80001800,codehandleronly,codehandleronly_size);
memcpy((void*)0x80001906, &codelist, 2);
memcpy((void*)0x8000190A, ((u8*) &codelist) + 2, 2);
DCFlushRange((void*)0x80001800,codehandleronly_size);
}
// Load multidol handler
memset((void*)0x80001000,0,multidol_size);
memcpy((void*)0x80001000,multidol,multidol_size);
DCFlushRange((void*)0x80001000,multidol_size);
switch(hooktype)
{
case 0x01:
memcpy((void*)0x8000119C,viwiihooks,12);
memcpy((void*)0x80001198,viwiihooks+3,4);
break;
case 0x02:
memcpy((void*)0x8000119C,kpadhooks,12);
memcpy((void*)0x80001198,kpadhooks+3,4);
break;
case 0x03:
memcpy((void*)0x8000119C,joypadhooks,12);
memcpy((void*)0x80001198,joypadhooks+3,4);
break;
case 0x04:
memcpy((void*)0x8000119C,gxdrawhooks,12);
memcpy((void*)0x80001198,gxdrawhooks+3,4);
break;
case 0x05:
memcpy((void*)0x8000119C,gxflushhooks,12);
memcpy((void*)0x80001198,gxflushhooks+3,4);
break;
case 0x06:
memcpy((void*)0x8000119C,ossleepthreadhooks,12);
memcpy((void*)0x80001198,ossleepthreadhooks+3,4);
break;
case 0x07:
memcpy((void*)0x8000119C,axnextframehooks,12);
memcpy((void*)0x80001198,axnextframehooks+3,4);
break;
case 0x08:
//if (customhooksize == 16)
//{
// memcpy((void*)0x8000119C,customhook,12);
// memcpy((void*)0x80001198,customhook+3,4);
//}
break;
case 0x09:
//memcpy((void*)0x8000119C,wpadbuttonsdownhooks,12);
//memcpy((void*)0x80001198,wpadbuttonsdownhooks+3,4);
break;
case 0x0A:
//memcpy((void*)0x8000119C,wpadbuttonsdown2hooks,12);
//memcpy((void*)0x80001198,wpadbuttonsdown2hooks+3,4);
break;
}
DCFlushRange((void*)0x80001198,16);
}
memcpy((void *)0x80001800, (void*)0x80000000, 6);
}
int ocarina_do_code(u64 chantitle)
{
//if (!code_buf) return 0; // Need the handler loaded for hooking other than cheats!
memset((void *)0x80001800, 0, 0x1800);
char gameidbuffer[8];
if(chantitle != 0)
{
memset(gameidbuffer, 0, 8);
gameidbuffer[0] = (chantitle & 0xff000000) >> 24;
gameidbuffer[1] = (chantitle & 0x00ff0000) >> 16;
gameidbuffer[2] = (chantitle & 0x0000ff00) >> 8;
gameidbuffer[3] = chantitle & 0x000000ff;
}
load_handler();
if(chantitle != 0)
{
memcpy((void *)0x80001800, gameidbuffer, 8);
DCFlushRange((void *)0x80001800, 8);
}
if(codelist)
memset(codelist, 0, (u32)codelistend - (u32)codelist);
//Copy the codes
if (code_size > 0 && code_buf)
{
memcpy(codelist, code_buf, code_size);
DCFlushRange(codelist, (u32)codelistend - (u32)codelist);
free(code_buf);
}
// TODO What's this???
// enable flag
//*(vu8*)0x80001807 = 0x01;
//This needs to be done after loading the .dol into memory
app_pokevalues();
return 1;
}

View File

@ -23,20 +23,6 @@ extern __typeof(memalign) __real_memalign;
extern __typeof(free) __real_free; extern __typeof(free) __real_free;
extern __typeof(malloc_usable_size) __real_malloc_usable_size; extern __typeof(malloc_usable_size) __real_malloc_usable_size;
extern __typeof(_malloc_r) __real__malloc_r;
extern __typeof(_calloc_r) __real__calloc_r;
extern __typeof(_realloc_r) __real__realloc_r;
extern __typeof(_memalign_r) __real__memalign_r;
extern __typeof(_free_r) __real__free_r;
extern __typeof(_malloc_usable_size_r) __real__malloc_usable_size_r;
bool first_mem = true;
void DisableMEM1allocR()
{
first_mem = false;
}
void *MEM1_alloc(unsigned int s) void *MEM1_alloc(unsigned int s)
{ {
return __real_malloc(s); return __real_malloc(s);
@ -125,14 +111,6 @@ void *__wrap_malloc(size_t size)
return g_mem2gp.allocate(size); return g_mem2gp.allocate(size);
} }
void *__wrap__malloc_r(struct _reent *r, size_t size)
{
if(first_mem)
return __real__malloc_r(r, size);
return MEM2_alloc(size);
}
void *__wrap_calloc(size_t n, size_t size) void *__wrap_calloc(size_t n, size_t size)
{ {
void *p; void *p;
@ -156,17 +134,6 @@ void *__wrap_calloc(size_t n, size_t size)
return p; return p;
} }
void *__wrap__calloc_r(struct _reent *r, size_t n, size_t size)
{
if(first_mem)
return __real__calloc_r(r, n, size);
void *p = MEM2_alloc(n*size);
if(p)
memset(p, 0, n*size);
return p;
}
void *__wrap_memalign(size_t a, size_t size) void *__wrap_memalign(size_t a, size_t size)
{ {
void *p; void *p;
@ -187,14 +154,6 @@ void *__wrap_memalign(size_t a, size_t size)
return g_mem2gp.allocate(size); return g_mem2gp.allocate(size);
} }
void *__wrap__memalign_r(struct _reent *r, size_t a, size_t size)
{
if(first_mem)
return __real__memalign_r(r, a, size);
return MEM2_alloc(size);
}
void __wrap_free(void *p) void __wrap_free(void *p)
{ {
if(!p) if(!p)
@ -206,14 +165,6 @@ void __wrap_free(void *p)
__real_free(p); __real_free(p);
} }
void __wrap__free_r(struct _reent *r, void *p)
{
if(first_mem)
__real__free_r(r, p);
else
MEM2_free(p);
}
void *__wrap_realloc(void *p, size_t size) void *__wrap_realloc(void *p, size_t size)
{ {
void *n; void *n;
@ -248,14 +199,6 @@ void *__wrap_realloc(void *p, size_t size)
return n; return n;
} }
void *__wrap__realloc_r(struct _reent *r, void *p, size_t size)
{
if(first_mem)
return __real__realloc_r(r, p, size);
return MEM2_realloc(p, size);
}
size_t __wrap_malloc_usable_size(void *p) size_t __wrap_malloc_usable_size(void *p)
{ {
if(((u32)p & 0x10000000) != 0) if(((u32)p & 0x10000000) != 0)
@ -263,12 +206,4 @@ size_t __wrap_malloc_usable_size(void *p)
return __real_malloc_usable_size(p); return __real_malloc_usable_size(p);
} }
size_t __wrap__malloc_usable_size_r(struct _reent *r, void *p)
{
if(first_mem)
return __real__malloc_usable_size_r(r, p);
return CMEM2Alloc::usableSize(p);
}
} ///extern "C" } ///extern "C"

View File

@ -26,7 +26,6 @@ void *MEM2_memalign(unsigned int /* alignment */, unsigned int s);
void *MEM2_realloc(void *p, unsigned int s); void *MEM2_realloc(void *p, unsigned int s);
unsigned int MEM2_usableSize(void *p); unsigned int MEM2_usableSize(void *p);
unsigned int MEM2_freesize(); unsigned int MEM2_freesize();
void DisableMEM1allocR();
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -23,7 +23,7 @@
#include "gui/Gekko.h" #include "gui/Gekko.h"
#include "homebrew/homebrew.h" #include "homebrew/homebrew.h"
#include "loader/alt_ios.h" #include "loader/alt_ios.h"
#include "loader/patchcode.h" #include "loader/external_booter.hpp"
#include "loader/sys.h" #include "loader/sys.h"
#include "loader/wdvd.h" #include "loader/wdvd.h"
#include "loader/alt_ios.h" #include "loader/alt_ios.h"
@ -983,6 +983,33 @@ int CMenu::_loadIOS(u8 gameIOS, int userIOS, string id, bool emu_channel)
return LOAD_IOS_NOT_NEEDED; return LOAD_IOS_NOT_NEEDED;
} }
s32 IOSReloadBlock(u8 reqios, bool enable)
{
s32 ESHandle = IOS_Open("/dev/es", 0);
if (ESHandle < 0)
return ESHandle;
static ioctlv vector[2] ATTRIBUTE_ALIGN(32);
static u32 mode ATTRIBUTE_ALIGN(32);
static u32 ios ATTRIBUTE_ALIGN(32);
mode = enable ? 2 : 0;
vector[0].data = &mode;
vector[0].len = sizeof(u32);
if (enable) {
ios = reqios;
vector[1].data = &ios;
vector[1].len = sizeof(u32);
}
s32 r = IOS_Ioctlv(ESHandle, 0xA0, 2, 0, vector);
IOS_Close(ESHandle);
return r;
}
static const char systems[11] = { 'C', 'E', 'F', 'J', 'L', 'M', 'N', 'P', 'Q', 'W', 'H' }; static const char systems[11] = { 'C', 'E', 'F', 'J', 'L', 'M', 'N', 'P', 'Q', 'W', 'H' };
void CMenu::_launchChannel(dir_discHdr *hdr) void CMenu::_launchChannel(dir_discHdr *hdr)
@ -1111,7 +1138,13 @@ void CMenu::_launchChannel(dir_discHdr *hdr)
return; return;
} }
} }
if(!forwarder) if(forwarder)
{
WII_Initialize();
if(WII_LaunchTitle(gameTitle) < 0)
Sys_LoadMenu();
}
else
{ {
entry = channel.Load(gameTitle); entry = channel.Load(gameTitle);
setLanguage(language); setLanguage(language);
@ -1120,15 +1153,8 @@ void CMenu::_launchChannel(dir_discHdr *hdr)
if(cheat) if(cheat)
_loadFile(cheatFile, cheatSize, m_cheatDir.c_str(), fmt("%s.gct", id.c_str())); _loadFile(cheatFile, cheatSize, m_cheatDir.c_str(), fmt("%s.gct", id.c_str()));
ocarina_load_code(cheatFile.get(), cheatSize); ocarina_load_code(cheatFile.get(), cheatSize);
BootChannel(entry, gameTitle, gameIOS, videoMode, vipatch, countryPatch, patchVidMode, aspectRatio);
} }
if(forwarder)
{
WII_Initialize();
if(WII_LaunchTitle(gameTitle) < 0)
Sys_LoadMenu();
}
else if(!BootChannel(entry, gameTitle, gameIOS, videoMode, vipatch, countryPatch, patchVidMode, aspectRatio))
Sys_LoadMenu();
} }
void CMenu::_launchGame(dir_discHdr *hdr, bool dvd) void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
@ -1399,16 +1425,11 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
return; return;
} }
} }
/* Find game partition offset */
u64 offset;
s32 ret = Disc_FindPartition(&offset);
if(ret < 0)
return;
#ifndef DOLPHIN #ifndef DOLPHIN
USBStorage2_Deinit(); USBStorage2_Deinit();
USB_Deinitialize(); USB_Deinitialize();
#endif
if(CurrentIOS.Type == IOS_TYPE_HERMES) if(CurrentIOS.Type == IOS_TYPE_HERMES)
{ {
if(dvd) if(dvd)
@ -1416,20 +1437,7 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
else else
Hermes_shadow_mload(); Hermes_shadow_mload();
} }
#endif WiiFlow_ExternalBooter(videoMode, vipatch, countryPatch, patchVidMode, aspectRatio, returnTo, TYPE_WII_GAME);
/* Last check if the Disc ID is correct */
void *ReadBuffer = MEM2_memalign(32, 32);
WDVD_UnencryptedRead(ReadBuffer, 32, 0);
string ReadedID((char*)ReadBuffer, 6);
MEM2_free(ReadBuffer);
gprintf("WDVD_UnencryptedRead ID: %s (expected: %s)\n", ReadedID.c_str(), id.c_str());
if(strncasecmp(id.c_str(), ReadedID.c_str(), 6) != 0)
return;
DisableMEM1allocR();
Disc_BootWiiGame(offset, videoMode, vipatch, countryPatch, patchVidMode, aspectRatio, returnTo);
} }
void CMenu::_initGameMenu(CMenu::SThemeData &theme) void CMenu::_initGameMenu(CMenu::SThemeData &theme)

View File

@ -65,6 +65,7 @@ void SoundDecoder::Init()
SoundBlocks = 8; //Settings.SoundblockCount; SoundBlocks = 8; //Settings.SoundblockCount;
SoundBlockSize = 8092; //Settings.SoundblockSize; SoundBlockSize = 8092; //Settings.SoundblockSize;
CurPos = 0; CurPos = 0;
LoopStart = 0;
Loop = false; Loop = false;
EndOfFile = false; EndOfFile = false;
Decoding = false; Decoding = false;