mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-30 15:14:18 +01:00
-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:
parent
7e9fd00e83
commit
0e5a5b4abd
2
Makefile
2
Makefile
@ -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
BIN
data/wii_game_booter.dol
Normal file
Binary file not shown.
After Width: | Height: | Size: 61 KiB |
127
resources/wiiflow_game_booter/Makefile
Normal file
127
resources/wiiflow_game_booter/Makefile
Normal 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
|
||||||
|
#---------------------------------------------------------------------------------
|
@ -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();
|
@ -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
|
41
resources/wiiflow_game_booter/source/cios.h
Normal file
41
resources/wiiflow_game_booter/source/cios.h
Normal 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
|
223
resources/wiiflow_game_booter/source/disc.c
Normal file
223
resources/wiiflow_game_booter/source/disc.c
Normal 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();
|
||||||
|
}
|
20
resources/wiiflow_game_booter/source/disc.h
Normal file
20
resources/wiiflow_game_booter/source/disc.h
Normal 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
|
265
resources/wiiflow_game_booter/source/fst.c
Normal file
265
resources/wiiflow_game_booter/source/fst.c
Normal 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;
|
||||||
|
}
|
41
resources/wiiflow_game_booter/source/fst.h
Normal file
41
resources/wiiflow_game_booter/source/fst.h
Normal 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
|
212
resources/wiiflow_game_booter/source/main.cpp
Normal file
212
resources/wiiflow_game_booter/source/main.cpp
Normal 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;
|
||||||
|
}
|
37
resources/wiiflow_game_booter/source/memory.h
Normal file
37
resources/wiiflow_game_booter/source/memory.h
Normal 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
|
@ -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;
|
@ -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);
|
34
resources/wiiflow_game_booter/source/types.h
Normal file
34
resources/wiiflow_game_booter/source/types.h
Normal 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
|
@ -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,
|
@ -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_)
|
407
resources/wiiflow_game_booter/source/wdvd.c
Normal file
407
resources/wiiflow_game_booter/source/wdvd.c
Normal 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;
|
||||||
|
}
|
37
resources/wiiflow_game_booter/source/wdvd.h
Normal file
37
resources/wiiflow_game_booter/source/wdvd.h
Normal 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
|
||||||
|
|
140
resources/wiiflow_game_booter/source/wip.c
Normal file
140
resources/wiiflow_game_booter/source/wip.c
Normal 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;
|
||||||
|
}
|
25
resources/wiiflow_game_booter/source/wip.h
Normal file
25
resources/wiiflow_game_booter/source/wip.h
Normal 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__
|
@ -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));
|
@ -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 */
|
||||||
|
@ -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
|
|
@ -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()
|
||||||
|
@ -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();
|
|
||||||
}
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
106
source/loader/external_booter.cpp
Normal file
106
source/loader/external_booter.cpp
Normal 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;
|
||||||
|
}
|
35
source/loader/external_booter.hpp
Normal file
35
source/loader/external_booter.hpp
Normal 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
|
@ -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;
|
|
||||||
}
|
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user