mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-01 00:55:06 +01:00
-highly beta, unfinished experiments with tinyload as wii game
booter, dont even think about it to report bugs with it
This commit is contained in:
parent
197e5dc1d3
commit
bb1774e2c3
7
Makefile
7
Makefile
@ -5,8 +5,11 @@ all:
|
|||||||
@echo Make WiiFlow Booter
|
@echo Make WiiFlow Booter
|
||||||
@$(MAKE) --no-print-directory -C $(CURDIR_TMP)/resources/wiiflow_game_booter \
|
@$(MAKE) --no-print-directory -C $(CURDIR_TMP)/resources/wiiflow_game_booter \
|
||||||
-f $(CURDIR_TMP)/resources/wiiflow_game_booter/Makefile
|
-f $(CURDIR_TMP)/resources/wiiflow_game_booter/Makefile
|
||||||
@mv -f $(CURDIR_TMP)/resources/wiiflow_game_booter/boot.dol \
|
@$(DEVKITPPC)/bin/raw2c $(CURDIR_TMP)/resources/wiiflow_game_booter/booter
|
||||||
$(CURDIR_TMP)/data/wiiflow_game_booter.dol
|
@mv -u $(CURDIR_TMP)/booter.c \
|
||||||
|
$(CURDIR_TMP)/source/booter/booter.c
|
||||||
|
@mv -u $(CURDIR_TMP)/booter.h \
|
||||||
|
$(CURDIR_TMP)/source/booter/booter.h
|
||||||
@echo Make WiiFlow Main
|
@echo Make WiiFlow Main
|
||||||
@$(MAKE) --no-print-directory -C $(CURDIR_TMP) -f $(CURDIR_TMP)/Makefile.main
|
@$(MAKE) --no-print-directory -C $(CURDIR_TMP) -f $(CURDIR_TMP)/Makefile.main
|
||||||
clean:
|
clean:
|
||||||
|
131
Makefile.main
131
Makefile.main
@ -8,7 +8,6 @@ $(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>dev
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
include $(DEVKITPPC)/wii_rules
|
include $(DEVKITPPC)/wii_rules
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# TARGET is the name of the output
|
# TARGET is the name of the output
|
||||||
# BUILD is the directory where object files & intermediate files will be placed
|
# BUILD is the directory where object files & intermediate files will be placed
|
||||||
@ -18,6 +17,7 @@ include $(DEVKITPPC)/wii_rules
|
|||||||
TARGET := boot
|
TARGET := boot
|
||||||
BUILD := build
|
BUILD := build
|
||||||
SOURCES := source \
|
SOURCES := source \
|
||||||
|
source/booter \
|
||||||
source/banner \
|
source/banner \
|
||||||
source/channel \
|
source/channel \
|
||||||
source/cheats \
|
source/cheats \
|
||||||
@ -43,10 +43,10 @@ SOURCES := source \
|
|||||||
|
|
||||||
DATA := data \
|
DATA := data \
|
||||||
data/images \
|
data/images \
|
||||||
data/sounds \
|
data/help \
|
||||||
data/help
|
data/sounds
|
||||||
|
|
||||||
INCLUDES := source
|
INCLUDES := source
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# Default build shell script options
|
# Default build shell script options
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
@ -54,10 +54,14 @@ ios := 249
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
CFLAGS := -g -O2 -Wall -Wextra $(MACHDEP) $(INCLUDE) -DHAVE_CONFIG_H
|
CFLAGS = -g -ggdb -Os -Wall -Wno-multichar -Wno-unused-parameter -Wextra $(MACHDEP) $(INCLUDE) -DBUILD_IOS=$(IOS)
|
||||||
CXXFLAGS := $(CFLAGS)
|
CXXFLAGS = $(CFLAGS)
|
||||||
|
LDFLAGS = -g -ggdb $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80620000,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size
|
||||||
|
|
||||||
LDFLAGS := -g $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80620000,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size
|
ifeq ($(BUILDMODE),channel)
|
||||||
|
CFLAGS += -DFULLCHANNEL
|
||||||
|
CXXFLAGS += -DFULLCHANNEL
|
||||||
|
endif
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# any extra libraries we wish to link with the project
|
# any extra libraries we wish to link with the project
|
||||||
@ -75,21 +79,30 @@ LIBDIRS := $(CURDIR)/portlibs
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
export PROJECTDIR := $(CURDIR)
|
||||||
|
export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET)
|
||||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||||
|
|
||||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# automatically build a list of object files for our project
|
# automatically build a list of object files for our project
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
SVNREV := $(shell bash ./scripts/svnrev.sh)
|
||||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
IOSTYPE := $(shell bash ./scripts/buildtype.sh $(ios))
|
||||||
|
export CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||||
|
export CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||||
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
|
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
|
||||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
ELFFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.elf)))
|
||||||
|
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.bin)))
|
||||||
|
TTFFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.ttf)))
|
||||||
|
PNGFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.png)))
|
||||||
|
OGGFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.ogg)))
|
||||||
|
WAVFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.wav)))
|
||||||
|
DOLFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.dol)))
|
||||||
|
TXTFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.txt)))
|
||||||
|
JPGFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.jpg)))
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# use CXX for linking C++ projects, CC for standard C
|
# use CXX for linking C++ projects, CC for standard C
|
||||||
@ -102,56 +115,42 @@ endif
|
|||||||
|
|
||||||
export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
|
export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
|
||||||
$(sFILES:.s=.o) $(SFILES:.S=.o) \
|
$(sFILES:.s=.o) $(SFILES:.S=.o) \
|
||||||
$(addsuffix .o,$(BINFILES)) \
|
$(PNGFILES:.png=.png.o) $(JPGFILES:.jpg=.jpg.o) \
|
||||||
|
$(OGGFILES:.ogg=.ogg.o) $(TXTFILES:.txt=.txt.o) \
|
||||||
|
$(WAVFILES:.wav=.wav.o) $(addsuffix .o,$(BINFILES)) \
|
||||||
$(CURDIR)/data/binary/magic_patcher.o
|
$(CURDIR)/data/binary/magic_patcher.o
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# build a list of include paths
|
# build a list of include paths
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
export INCLUDE := $(foreach dir,$(INCLUDES), -I$(CURDIR)/$(dir)) \
|
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||||
-I$(CURDIR)/$(BUILD) \
|
-I$(CURDIR)/$(BUILD) -I$(LIBOGC_INC) \
|
||||||
-I$(LIBOGC_INC)
|
-I$(PORTLIBS)/include
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# build a list of library paths
|
# build a list of library paths
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
|
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) -L$(CURDIR)/source/libs/libfat/ \
|
||||||
-L$(LIBOGC_LIB)
|
-L$(CURDIR)/source/libs/libntfs/ -L$(CURDIR)/source/libs/libext2fs/ \
|
||||||
|
-L$(LIBOGC_LIB) -L$(PORTLIBS)/lib
|
||||||
|
|
||||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||||
|
.PHONY: $(BUILD) all clean
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
.PHONY: $(BUILD) all clean run
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
$(BUILD):
|
$(BUILD):
|
||||||
@echo Building for IOS $(ios).
|
|
||||||
@[ -d $@ ] || mkdir -p $@
|
@[ -d $@ ] || mkdir -p $@
|
||||||
@bash $(CURDIR)/scripts/svnrev.sh
|
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile.main
|
||||||
@bash $(CURDIR)/scripts/buildtype.sh $(ios)
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
all:
|
||||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile.main
|
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile.main
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
clean:
|
clean:
|
||||||
@echo clean ...
|
@echo clean ...
|
||||||
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol $(CURDIR)/data/wiiflow_game_booter.dol \
|
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol
|
||||||
$(CURDIR)/source/loader/alt_ios_gen.c $(CURDIR)/source/svnrev.h
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
run:
|
|
||||||
wiiload $(TARGET).dol
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
gdb:
|
|
||||||
@echo Loading GDB with symbols from boot.elf, type quit to exit.
|
|
||||||
@powerpc-eabi-gdb boot.elf
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
addr:
|
|
||||||
@echo Loading addr2line with symbols from boot.elf..
|
|
||||||
@echo Press ctrl+c to exit.
|
|
||||||
@echo Enter an address from the stack dump:
|
|
||||||
@powerpc-eabi-addr2line -f -e boot.elf
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
else
|
else
|
||||||
@ -162,57 +161,37 @@ DEPENDS := $(OFILES:.o=.d)
|
|||||||
# main targets
|
# main targets
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
$(OUTPUT).dol: $(OUTPUT).elf
|
$(OUTPUT).dol: $(OUTPUT).elf
|
||||||
$(OUTPUT).elf: $(OFILES) alt_ios_gen.o
|
$(OUTPUT).elf: $(OFILES)
|
||||||
$(BUILD)/alt_ios_gen.o: alt_ios_gen.c
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# This rule links in binary data with the .txt extension
|
# This rule links in binary data with .ttf, .png, and .mp3 extensions
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
%.txt.o: %.txt
|
|
||||||
@echo $(notdir $<)
|
|
||||||
@$(bin2o)
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# This rule links in binary data with the .jpg extension
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
%.jpg.o : %.jpg
|
|
||||||
@echo $(notdir $<)
|
|
||||||
@$(bin2o)
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# This rule links in binary data with the .png extension
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
%.png.o : %.png
|
%.png.o : %.png
|
||||||
@echo $(notdir $<)
|
@echo $(notdir $<)
|
||||||
@$(bin2o)
|
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# This rule links in binary data with the .ogg extension
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
%.ogg.o : %.ogg
|
%.ogg.o : %.ogg
|
||||||
@echo $(notdir $<)
|
@echo $(notdir $<)
|
||||||
@$(bin2o)
|
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# This rule links in binary data with the .wav extension
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
%.wav.o : %.wav
|
%.wav.o : %.wav
|
||||||
@echo $(notdir $<)
|
@echo $(notdir $<)
|
||||||
@$(bin2o)
|
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# This rule links in binary data with the .bin extension
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
%.bin.o : %.bin
|
%.bin.o : %.bin
|
||||||
@echo $(notdir $<)
|
@echo $(notdir $<)
|
||||||
@$(bin2o)
|
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
%.txt.o : %.txt
|
||||||
# This rule links in binary data with the .dol extension
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
%.dol.o : %.dol
|
|
||||||
@echo $(notdir $<)
|
@echo $(notdir $<)
|
||||||
@$(bin2o)
|
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||||
|
|
||||||
|
%.jpg.o : %.jpg
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||||
|
|
||||||
|
export PATH := $(PROJECTDIR)/gettext-bin:$(PATH)
|
||||||
|
|
||||||
-include $(DEPENDS)
|
-include $(DEPENDS)
|
||||||
|
|
||||||
|
@ -23,3 +23,17 @@ void *memcpy(void *dst, const void *src, size_t len)
|
|||||||
|
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *memmove(void *dst, const void *src, size_t len)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
unsigned char Current;
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
Current = ((unsigned char *)src)[i];
|
||||||
|
((unsigned char *)src)[i] = 0x00;
|
||||||
|
((unsigned char *)dst)[i] = Current;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
340
resources/wiiflow_game_booter/COPYING
Normal file
340
resources/wiiflow_game_booter/COPYING
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Lesser General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
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.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License.
|
||||||
|
|
@ -14,8 +14,8 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#ifndef _CFG_HPP_
|
#ifndef _CFG_H_
|
||||||
#define _CFG_HPP_
|
#define _CFG_H_
|
||||||
|
|
||||||
#include "cios.h"
|
#include "cios.h"
|
||||||
#include "frag.h"
|
#include "frag.h"
|
||||||
@ -37,8 +37,8 @@ typedef struct _the_CFG {
|
|||||||
u8 patchVidMode;
|
u8 patchVidMode;
|
||||||
u8 configbytes[2];
|
u8 configbytes[2];
|
||||||
u8 debugger;
|
u8 debugger;
|
||||||
bool vipatch;
|
u8 vipatch;
|
||||||
bool countryString;
|
u8 countryString;
|
||||||
int aspectRatio;
|
int aspectRatio;
|
||||||
void *codelist;
|
void *codelist;
|
||||||
u8 *codelistend;
|
u8 *codelistend;
|
@ -1,114 +1,64 @@
|
|||||||
#---------------------------------------------------------------------------------
|
|
||||||
# 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
|
#PREFIX = powerpc-gekko-
|
||||||
|
PREFIX = $(DEVKITPPC)/bin/powerpc-eabi-
|
||||||
|
#PREFIX = /home/megazig/Wii/bootmii-utils/bin/powerpc-elf-
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
AR = $(PREFIX)ar
|
||||||
# TARGET is the name of the output
|
AS = $(PREFIX)as
|
||||||
# BUILD is the directory where object files & intermediate files will be placed
|
CC = $(PREFIX)gcc
|
||||||
# SOURCES is a list of directories containing source code
|
CXX = $(PREFIX)g++
|
||||||
# INCLUDES is a list of directories containing extra header files
|
LD = $(PREFIX)ld
|
||||||
#---------------------------------------------------------------------------------
|
OBJCOPY = $(PREFIX)objcopy
|
||||||
TARGET := boot
|
RANLIB = $(PREFIX)ranlib
|
||||||
BUILD := build
|
STRIP = $(PREFIX)strip
|
||||||
SOURCES := source
|
|
||||||
DATA := data
|
|
||||||
INCLUDES := source
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# options for code generation
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
CFLAGS = -g -O1 -Wall -Wextra -Wno-multichar $(MACHDEP) $(INCLUDE) -DHAVE_CONFIG_H
|
|
||||||
CXXFLAGS = $(CFLAGS)
|
|
||||||
|
|
||||||
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80A00000
|
MACHDEP = -mcpu=750 -mno-eabi -mhard-float -DTINY -DDEBUG
|
||||||
|
#CFLAGS = $(MACHDEP) -Os -Wall -pipe -ffunction-sections -finline-functions-called-once -mno-sdata --combine -fwhole-program -ffreestanding
|
||||||
|
CFLAGS = $(MACHDEP) -O1 -Wall -pipe -ffunction-sections -finline-functions-called-once -mno-sdata
|
||||||
|
LDFLAGS = $(MACHDEP) -n -nostartfiles -nostdlib -Wl,-T,link.ld -L.
|
||||||
|
ASFLAGS = -D_LANGUAGE_ASSEMBLY -DHW_RVL -DTINY
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
TARGET_LINKED = boot.elf
|
||||||
# any extra libraries we wish to link with the project
|
TARGET = booter.bin
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
LIBS := -logc
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
CFILES = apploader.c cios.c cache.c debug.c di.c disc.c ios.c patchcode.c usb.c utils.c main.c
|
||||||
# list of directories containing libraries, this must be the top level containing
|
#OBJS = crt0.o _all.o
|
||||||
# include and lib
|
OBJS = crt0.o apploader.o cios.o cache.o debug.o di.o disc.o ios.o patchcode.o patchhook.o usb.o utils.o main.o
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
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)) \
|
DEPDIR = .deps
|
||||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
|
||||||
|
|
||||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
LIBS =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
all: $(TARGET)
|
||||||
# automatically build a list of object files for our project
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
export CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
|
||||||
export CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
|
||||||
|
|
||||||
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
%.o: %.s
|
||||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
|
@echo " ASSEMBLE $<"
|
||||||
#---------------------------------------------------------------------------------
|
@$(CC) $(CFLAGS) $(DEFINES) $(ASFLAGS) -c $< -o $@
|
||||||
# use CXX for linking C++ projects, CC for standard C
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
ifeq ($(strip $(CPPFILES)),)
|
|
||||||
export LD := $(CC)
|
|
||||||
else
|
|
||||||
export LD := $(CXX)
|
|
||||||
endif
|
|
||||||
|
|
||||||
export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(sFILES:.s=.o) $(SFILES:.S=.o)
|
%.o: %.S
|
||||||
#---------------------------------------------------------------------------------
|
@echo " ASSEMBLE $<"
|
||||||
# build a list of include paths
|
@$(CC) $(CFLAGS) $(DEFINES) $(ASFLAGS) -c $< -o $@
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
export INCLUDE := $(foreach dir,$(INCLUDES), -I$(CURDIR)/$(dir)) \
|
|
||||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
|
||||||
-I$(CURDIR)/$(BUILD) \
|
|
||||||
-I$(LIBOGC_INC)
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
%.o: %.c
|
||||||
# build a list of library paths
|
@echo " COMPILE $<"
|
||||||
#---------------------------------------------------------------------------------
|
@$(CC) $(CFLAGS) $(DEFINES) -c $< -o $@
|
||||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
|
|
||||||
-L$(LIBOGC_LIB)
|
|
||||||
|
|
||||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
%.o: %.cpp
|
||||||
|
@echo " COMPILE $<"
|
||||||
|
@$(CXX) $(CFLAGS) $(DEFINES) -c $< -o $@
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#_all.o: $(CFILES)
|
||||||
.PHONY: $(BUILD) all clean
|
# @echo " COMPILE ALL "
|
||||||
#---------------------------------------------------------------------------------
|
# @mkdir -p $(DEPDIR)
|
||||||
$(BUILD):
|
# @$(CC) $(CFLAGS) $(DEFINES) -Wp,-MMD,$(DEPDIR)/$(*F).d,-MQ,"$@",-MP -c $(CFILES) -o $@
|
||||||
@[ -d $@ ] || mkdir -p $@
|
|
||||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
$(TARGET_LINKED): $(OBJS)
|
||||||
|
@echo " LINK $@"
|
||||||
|
@$(CC) -g -o $@ $(LDFLAGS) $(OBJS) $(LIBS)
|
||||||
|
|
||||||
|
$(TARGET): $(TARGET_LINKED)
|
||||||
|
@echo " OBJCOPY $@"
|
||||||
|
@$(OBJCOPY) -O binary $< $@
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
clean:
|
clean:
|
||||||
@echo clean ...
|
rm -rf $(TARGET_LINKED) $(TARGET) $(OBJS) $(DEPDIR)
|
||||||
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
else
|
|
||||||
|
|
||||||
DEPENDS := $(OFILES:.o=.d)
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# main targets
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
$(OUTPUT).dol: $(OUTPUT).elf
|
|
||||||
$(OUTPUT).elf: $(OFILES)
|
|
||||||
-include $(DEPENDS)
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
endif
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
|
131
resources/wiiflow_game_booter/README
Normal file
131
resources/wiiflow_game_booter/README
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
TinyLoad v0.2
|
||||||
|
A Wii disc game loader in 4096 bytes
|
||||||
|
====================================
|
||||||
|
|
||||||
|
What?
|
||||||
|
=====
|
||||||
|
|
||||||
|
TinyLoad is a simple original Wii game launcher. You run it, it launches
|
||||||
|
whatever's inserted into the drive. Simple. It ignores game regions, so it's
|
||||||
|
region-free. It won't install updates. It won't load burned copies. There are no
|
||||||
|
controls or settings.
|
||||||
|
|
||||||
|
The user interface shows two things: progress, and error status. A white bar
|
||||||
|
across the bottom of the screen shows the current (rough) progress. If an error
|
||||||
|
is detected, a portion of the top of the screen will turn red. It will then
|
||||||
|
attempt to launch The Homebrew Channel (only applies to recent versions with the
|
||||||
|
JODI Title ID). If this fails then it will simply hang.
|
||||||
|
|
||||||
|
If the launcher freezes with the progress bar visible and no red error box, then
|
||||||
|
you've probably hit a bug. Try the debug version if you have a USB Gecko.
|
||||||
|
|
||||||
|
If it freezes with a black screen after the progress bar has reached its
|
||||||
|
endpoint and disappeared, then the game itself is freezing.
|
||||||
|
|
||||||
|
I obviously have only tested this with a few games. Chances are it doesn't work
|
||||||
|
with every Wii game out there.
|
||||||
|
|
||||||
|
The debug version requires a USB Gecko and shows debug messages over it.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- TinyLoad sets the PPC timebase correctly according to your Wii's RTC. This
|
||||||
|
fixes date/time issues in games.
|
||||||
|
- The video code makes lots of assumptions. It will only work if VI was left
|
||||||
|
configured in a "standard" mode, with a 640x480-640x574 framebuffer. VI should
|
||||||
|
be blanked; if it isn't, then TinyLoad will not blank it before launching
|
||||||
|
the game so your screen will blink green for a split second as the game
|
||||||
|
initializes VI. It has been tested to work correctly when launched by the
|
||||||
|
Homebrew Channel in at least NTSC 480p and PAL interlaced modes. If these
|
||||||
|
assumptions don't hold then the progress bar display will not work properly,
|
||||||
|
but the rest of the loader should work fine.
|
||||||
|
- TinyLoad does not perform _any_ patching of games. The lowmem video mode
|
||||||
|
setting follows whatever video mode was left set by the application used to
|
||||||
|
launch TinyLoad, except that PAL games are forced to PAL if NTSC is detected.
|
||||||
|
This does not patch the game, it's merely the informative value in low memory;
|
||||||
|
games are free to read SYSCONF/setting.txt and ignore it. I don't really care
|
||||||
|
because I use 480p mode anyway. If you need more advanced options, just use
|
||||||
|
Gecko OS.
|
||||||
|
- Normally, game audio will not work correctly if launched via a loader that
|
||||||
|
was initially launched via BootMii-boot2. This is a bug in libogc (it doesn't
|
||||||
|
know how to initialize the DSP for the first time and leaves it in a broken
|
||||||
|
state), and it affects anything running after the Wii was booted first into
|
||||||
|
a libogc application, including the System Menu's loader. In other words,
|
||||||
|
BootMii-boot2 -> HBC -> System Menu (or Gecko OS) -> Game may cause distorted
|
||||||
|
audio. TinyLoad _does_ work, by resetting the audio hardware to let the game
|
||||||
|
reinitialize it properly. So, BootMii-boot2 -> HBC -> TinyLoad -> Game will
|
||||||
|
work fine. This ought to be worked around in a future release of HBC, at
|
||||||
|
least. I'd suggest fixing libogc, but I know shagkur is just going to rip the
|
||||||
|
proper code from the SDK again. Anyway, launching using TinyLoad will work
|
||||||
|
fine as it contains the workaround.
|
||||||
|
- TinyLoad will load the correct IOS as specified in the partition TMD. It does
|
||||||
|
not support loading any other IOS.
|
||||||
|
- TinyLoad will not install updates. Not having the right IOS for the game will
|
||||||
|
probably result in a red error and reset about halfway through.
|
||||||
|
|
||||||
|
Broken stuff:
|
||||||
|
- I don't think online games work. Not sure why (I do copy the TitleID to the
|
||||||
|
proper spot, I think). If it works for you, let me know. Likewise, if you know
|
||||||
|
what the problem is or you can fix it, please let me know.
|
||||||
|
|
||||||
|
Who?
|
||||||
|
====
|
||||||
|
|
||||||
|
Program:
|
||||||
|
Copyright 2008-2009 Hector Martin (marcan) <marcan@marcansoft.com>
|
||||||
|
|
||||||
|
Supporting code:
|
||||||
|
Copyright 2008-2009 Segher Boessenkool <segher@kernel.crashing.org>
|
||||||
|
Copyright 2008-2009 Andre Heider (dhewg) <dhewg@wiibrew.org>
|
||||||
|
Copyright 2008 Nuke <wiinuke@gmail.com>
|
||||||
|
|
||||||
|
Awesome icon:
|
||||||
|
Copyright 2009 Freddy Leitner (drmr)
|
||||||
|
|
||||||
|
This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||||
|
see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||||
|
|
||||||
|
The icon is licensed under CC-BY-NC-SA 3.0:
|
||||||
|
http://creativecommons.org/licenses/by-nc-sa/3.0/
|
||||||
|
|
||||||
|
Why?
|
||||||
|
====
|
||||||
|
|
||||||
|
Because:
|
||||||
|
- System Menu 4.2 forever broke region free via modchips
|
||||||
|
- I have a USA Wii which I regularly use with EUR games
|
||||||
|
- Gecko OS is somewhat annoying and recent versions are unstable (for me anyway)
|
||||||
|
- I refuse to perform retarded firmware mods.
|
||||||
|
- I autoboot HBC via BootMii-boot2 and using the System Menu takes longer
|
||||||
|
anyway.
|
||||||
|
|
||||||
|
I also think that low-level apps that tightly hug the hardware are very
|
||||||
|
educational, so why not. And hey, the code is pretty short, so you ought to be
|
||||||
|
able to read it completely and learn how all this crazy Wii stuff *actually*
|
||||||
|
works :-)
|
||||||
|
|
||||||
|
How?
|
||||||
|
====
|
||||||
|
|
||||||
|
TinyLoad is not compressed. The 4 kilobytes are raw code and data, plus the ELF
|
||||||
|
header. The original loader was fit in 4 kilobytes by avoiding bloated libraries
|
||||||
|
like libogc and instead using a small codebase pieced together from bits of the
|
||||||
|
Twilight Hack and of HBC's reload stub. Extra features (SYSCONF reading, RTC
|
||||||
|
reading, proper lowmem settings, VI stuff, progress bar, etc) were added by
|
||||||
|
making space via a combination of increasingly complex compiler options, manual
|
||||||
|
tweaks, and micro-optimization.
|
||||||
|
|
||||||
|
Nonetheless, there is almost no assembly code and the C code, though compact and
|
||||||
|
odd at times, should be moderately readable. Just keep in mind that I
|
||||||
|
deliberately leave old values floating around and/or use odd initializations in
|
||||||
|
order to simplify the code. Also, I haven't commented most of it. If you're
|
||||||
|
really interested, give me a shout and I'll see what I can do to make it more
|
||||||
|
acceptable.
|
||||||
|
|
||||||
|
If you want some *real* fun, load the ELF in IDA. The function inlining and tail
|
||||||
|
call goodness ought to provide tons of entertainment.
|
||||||
|
|
||||||
|
Where?
|
||||||
|
======
|
||||||
|
|
||||||
|
http://wiibrew.org/TinyLoad
|
||||||
|
http://marcansoft.com/blog/
|
@ -1,16 +1,14 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ogcsys.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include "apploader.h"
|
#include "apploader.h"
|
||||||
#include "wdvd.h"
|
|
||||||
#include "patchcode.h"
|
#include "patchcode.h"
|
||||||
#include "videopatch.h"
|
|
||||||
#include "cios.h"
|
#include "cios.h"
|
||||||
#include "fst.h"
|
#include "fst.h"
|
||||||
#include "wip.h"
|
#include "wip.h"
|
||||||
#include "gecko.h"
|
#include "debug.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "di.h"
|
||||||
|
#include "cache.h"
|
||||||
|
#include "config.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);
|
||||||
@ -21,47 +19,49 @@ typedef void (*app_entry)(void (**init)(void (*report)(const char *fmt, ...)),
|
|||||||
/* Apploader pointers */
|
/* Apploader pointers */
|
||||||
static u8 *appldr = (u8 *)0x81200000;
|
static u8 *appldr = (u8 *)0x81200000;
|
||||||
|
|
||||||
/* Constants */
|
|
||||||
#define APPLDR_OFFSET 0x2440
|
|
||||||
|
|
||||||
/* Variables */
|
/* Variables */
|
||||||
static u32 buffer[0x20] ATTRIBUTE_ALIGN(32);
|
static u32 buffer[0x20] __attribute__((aligned(32)));
|
||||||
|
|
||||||
void maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo);
|
void maindolpatches(void *dst, int len, u8 vidMode, u8 vipatch, u8 countryString, u8 patchVidModes, int aspectRatio, u32 returnTo);
|
||||||
static void patch_NoDiscinDrive(void *buffer, u32 len);
|
static void patch_NoDiscinDrive(void *buffer, u32 len);
|
||||||
static void Anti_002_fix(void *Address, int Size);
|
static void Anti_002_fix(void *Address, int Size);
|
||||||
static bool Remove_001_Protection(void *Address, int Size);
|
static u8 Remove_001_Protection(void *Address, int Size);
|
||||||
static bool PrinceOfPersiaPatch();
|
//static u8 PrinceOfPersiaPatch();
|
||||||
static bool NewSuperMarioBrosPatch();
|
//static u8 NewSuperMarioBrosPatch();
|
||||||
bool hookpatched = false;
|
u8 hookpatched = 0;
|
||||||
|
|
||||||
s32 Apploader_Run(entry_point *entry, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo)
|
static void simple_report(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
debug_string(fmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 Apploader_Run(u8 vidMode, u8 vipatch, u8 countryString, u8 patchVidModes, int aspectRatio, u32 returnTo)
|
||||||
{
|
{
|
||||||
void *dst = NULL;
|
void *dst = NULL;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
u32 appldr_len;
|
u32 appldr_len;
|
||||||
s32 ret;
|
s32 ret;
|
||||||
|
u32 Entry = 0;
|
||||||
app_init appldr_init;
|
app_init appldr_init;
|
||||||
app_main appldr_main;
|
app_main appldr_main;
|
||||||
app_final appldr_final;
|
app_final appldr_final;
|
||||||
|
|
||||||
/* Read apploader header */
|
/* Read apploader header */
|
||||||
ret = WDVD_Read(buffer, 0x20, APPLDR_OFFSET);
|
ret = di_read(buffer, 0x20, 0x910);
|
||||||
if(ret < 0)
|
if(ret < 0)
|
||||||
return ret;
|
return Entry;
|
||||||
|
|
||||||
/* Calculate apploader length */
|
/* Calculate apploader length */
|
||||||
appldr_len = buffer[5] + buffer[6];
|
appldr_len = buffer[5] + buffer[6];
|
||||||
|
|
||||||
/* Read apploader code */
|
/* Read apploader code */
|
||||||
ret = WDVD_Read(appldr, appldr_len, APPLDR_OFFSET + 0x20);
|
ret = di_read(appldr, appldr_len, 0x918);
|
||||||
if(ret < 0)
|
if(ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Flush into memory */
|
/* Flush into memory */
|
||||||
DCFlushRange(appldr, appldr_len);
|
sync_after_write(appldr, appldr_len);
|
||||||
ICInvalidateRange(appldr, appldr_len);
|
|
||||||
|
|
||||||
/* Set apploader entry function */
|
/* Set apploader entry function */
|
||||||
app_entry appldr_entry = (app_entry)buffer[4];
|
app_entry appldr_entry = (app_entry)buffer[4];
|
||||||
@ -70,58 +70,51 @@ 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(simple_report);
|
||||||
|
|
||||||
while(appldr_main(&dst, &len, &offset))
|
while(appldr_main(&dst, &len, &offset))
|
||||||
{
|
{
|
||||||
/* Read data from DVD */
|
/* Read data from DVD */
|
||||||
WDVD_Read(dst, len, (u64)(offset << 2));
|
di_read(dst, len, offset);
|
||||||
maindolpatches(dst, len, vidMode, vmode, vipatch, countryString, patchVidModes, aspectRatio, returnTo);
|
maindolpatches(dst, len, vidMode, vipatch, countryString, patchVidModes, aspectRatio, returnTo);
|
||||||
|
sync_after_write(dst, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
free_wip();
|
/*free_wip();
|
||||||
if(hooktype != 0 && hookpatched)
|
if(hooktype != 0 && hookpatched)
|
||||||
ocarina_do_code(0);
|
ocarina_do_code(0);*/
|
||||||
|
|
||||||
/* Set entry point from apploader */
|
/* Set entry point from apploader */
|
||||||
*entry = appldr_final();
|
//*entry = appldr_final();
|
||||||
|
Entry = (u32)appldr_final();
|
||||||
|
|
||||||
/* ERROR 002 fix (WiiPower) */
|
return Entry;
|
||||||
*(u32 *)0x80003140 = *(u32 *)0x80003188;
|
|
||||||
DCFlushRange((void*)0x80000000, 0x3f00);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo)
|
void maindolpatches(void *dst, int len, u8 vidMode, u8 vipatch, u8 countryString, u8 patchVidModes, int aspectRatio, u32 returnTo)
|
||||||
{
|
{
|
||||||
PrinceOfPersiaPatch();
|
//PrinceOfPersiaPatch();
|
||||||
NewSuperMarioBrosPatch();
|
//NewSuperMarioBrosPatch();
|
||||||
// Patch NoDiscInDrive only for IOS 249 < rev13 or IOS 222/223/224
|
// Patch NoDiscInDrive only for IOS 249 < rev13 or IOS 222/223/224
|
||||||
if((CurrentIOS.Type == IOS_TYPE_WANIN && CurrentIOS.Revision < 13) || CurrentIOS.Type == IOS_TYPE_HERMES)
|
if((CurrentIOS.Type == IOS_TYPE_WANIN && CurrentIOS.Revision < 13) || CurrentIOS.Type == IOS_TYPE_HERMES)
|
||||||
patch_NoDiscinDrive(dst, len);
|
patch_NoDiscinDrive(dst, len);
|
||||||
patchVideoModes(dst, len, vidMode, vmode, patchVidModes);
|
//patchVideoModes(dst, len, vidMode, vmode, patchVidModes);
|
||||||
if(hooktype != 0 && dogamehooks(dst, len, false))
|
//if(conf->hooktype != 0 && dogamehooks(dst, len, 0))
|
||||||
hookpatched = true;
|
// hookpatched = 1;
|
||||||
if(vipatch)
|
if(vipatch)
|
||||||
vidolpatcher(dst, len);
|
vidolpatcher(dst, len);
|
||||||
if(configbytes[0] != 0xCD)
|
if(configbytes[0] != 0xCD)
|
||||||
langpatcher(dst, len);
|
langpatcher(dst, len);
|
||||||
if(CurrentIOS.Type == IOS_TYPE_WANIN && CurrentIOS.Revision < 13)
|
if(CurrentIOS.Type == IOS_TYPE_WANIN && CurrentIOS.Revision < 13)
|
||||||
Anti_002_fix(dst, len);
|
Anti_002_fix(dst, len);
|
||||||
if(countryString)
|
//if(conf->countryString)
|
||||||
PatchCountryStrings(dst, len); // Country Patch by WiiPower
|
// PatchCountryStrings(dst, len); // Country Patch by WiiPower
|
||||||
if(aspectRatio != -1)
|
if(aspectRatio != -1)
|
||||||
PatchAspectRatio(dst, len, aspectRatio);
|
PatchAspectRatio(dst, len, aspectRatio);
|
||||||
if(returnTo)
|
if(returnTo > 0)
|
||||||
PatchReturnTo(dst, len, returnTo);
|
PatchReturnTo(dst, len, returnTo);
|
||||||
|
|
||||||
Remove_001_Protection(dst, len);
|
Remove_001_Protection(dst, len);
|
||||||
|
//do_wip_code((u8 *)dst, len);
|
||||||
do_wip_code((u8 *)dst, len);
|
|
||||||
|
|
||||||
DCFlushRange(dst, len);
|
|
||||||
ICInvalidateRange(dst, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void patch_NoDiscinDrive(void *buffer, u32 len)
|
static void patch_NoDiscinDrive(void *buffer, u32 len)
|
||||||
@ -152,13 +145,13 @@ static void Anti_002_fix(void *Address, int Size)
|
|||||||
Addr += 4;
|
Addr += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
static bool PrinceOfPersiaPatch()
|
static u8 PrinceOfPersiaPatch()
|
||||||
{
|
{
|
||||||
if (memcmp("SPX", (char *) 0x80000000, 3) != 0 && memcmp("RPW", (char *) 0x80000000, 3) != 0)
|
if (memcmp("SPX", (char *) 0x80000000, 3) != 0 && memcmp("RPW", (char *) 0x80000000, 3) != 0)
|
||||||
return false;
|
return 0;
|
||||||
|
|
||||||
WIP_Code * CodeList = malloc(5 * sizeof(WIP_Code));
|
WIP_Code CodeList[5*sizeof(WIP_Code)];
|
||||||
CodeList[0].offset = 0x007AAC6A;
|
CodeList[0].offset = 0x007AAC6A;
|
||||||
CodeList[0].srcaddress = 0x7A6B6F6A;
|
CodeList[0].srcaddress = 0x7A6B6F6A;
|
||||||
CodeList[0].dstaddress = 0x6F6A7A6B;
|
CodeList[0].dstaddress = 0x6F6A7A6B;
|
||||||
@ -175,25 +168,18 @@ static bool PrinceOfPersiaPatch()
|
|||||||
CodeList[4].srcaddress = 0x82806F3F;
|
CodeList[4].srcaddress = 0x82806F3F;
|
||||||
CodeList[4].dstaddress = 0x6F3F8280;
|
CodeList[4].dstaddress = 0x6F3F8280;
|
||||||
|
|
||||||
if (set_wip_list(CodeList, 5) == false)
|
if (set_wip_list(CodeList, 5) == 0)
|
||||||
{
|
return 0;
|
||||||
free(CodeList);
|
|
||||||
CodeList = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool NewSuperMarioBrosPatch()
|
static u8 NewSuperMarioBrosPatch()
|
||||||
{
|
{
|
||||||
WIP_Code * CodeList = NULL;
|
WIP_Code CodeList[3 * sizeof(WIP_Code)];
|
||||||
|
|
||||||
if (memcmp("SMNE01", (char *) 0x80000000, 6) == 0)
|
if (memcmp("SMNE01", (char *) 0x80000000, 6) == 0)
|
||||||
{
|
{
|
||||||
CodeList = malloc(3 * sizeof(WIP_Code));
|
|
||||||
if(!CodeList)
|
|
||||||
return false;
|
|
||||||
CodeList[0].offset = 0x001AB610;
|
CodeList[0].offset = 0x001AB610;
|
||||||
CodeList[0].srcaddress = 0x9421FFD0;
|
CodeList[0].srcaddress = 0x9421FFD0;
|
||||||
CodeList[0].dstaddress = 0x4E800020;
|
CodeList[0].dstaddress = 0x4E800020;
|
||||||
@ -206,9 +192,6 @@ static bool NewSuperMarioBrosPatch()
|
|||||||
}
|
}
|
||||||
else if (memcmp("SMNP01", (char *) 0x80000000, 6) == 0)
|
else if (memcmp("SMNP01", (char *) 0x80000000, 6) == 0)
|
||||||
{
|
{
|
||||||
CodeList = malloc(3 * sizeof(WIP_Code));
|
|
||||||
if(!CodeList)
|
|
||||||
return false;
|
|
||||||
CodeList[0].offset = 0x001AB750;
|
CodeList[0].offset = 0x001AB750;
|
||||||
CodeList[0].srcaddress = 0x9421FFD0;
|
CodeList[0].srcaddress = 0x9421FFD0;
|
||||||
CodeList[0].dstaddress = 0x4E800020;
|
CodeList[0].dstaddress = 0x4E800020;
|
||||||
@ -221,9 +204,6 @@ static bool NewSuperMarioBrosPatch()
|
|||||||
}
|
}
|
||||||
else if (memcmp("SMNJ01", (char *) 0x80000000, 6) == 0)
|
else if (memcmp("SMNJ01", (char *) 0x80000000, 6) == 0)
|
||||||
{
|
{
|
||||||
CodeList = malloc(3 * sizeof(WIP_Code));
|
|
||||||
if(!CodeList)
|
|
||||||
return false;
|
|
||||||
CodeList[0].offset = 0x001AB420;
|
CodeList[0].offset = 0x001AB420;
|
||||||
CodeList[0].srcaddress = 0x9421FFD0;
|
CodeList[0].srcaddress = 0x9421FFD0;
|
||||||
CodeList[0].dstaddress = 0x4E800020;
|
CodeList[0].dstaddress = 0x4E800020;
|
||||||
@ -234,16 +214,12 @@ static bool NewSuperMarioBrosPatch()
|
|||||||
CodeList[2].srcaddress = 0xDA000000;
|
CodeList[2].srcaddress = 0xDA000000;
|
||||||
CodeList[2].dstaddress = 0x71000000;
|
CodeList[2].dstaddress = 0x71000000;
|
||||||
}
|
}
|
||||||
if (CodeList && set_wip_list(CodeList, 3) == false)
|
if(set_wip_list(CodeList, 3) == 0)
|
||||||
{
|
return 0;
|
||||||
free(CodeList);
|
return 1;
|
||||||
CodeList = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return CodeList != NULL;
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
static bool Remove_001_Protection(void *Address, int Size)
|
static u8 Remove_001_Protection(void *Address, int Size)
|
||||||
{
|
{
|
||||||
static const u8 SearchPattern[] = {0x40, 0x82, 0x00, 0x0C, 0x38, 0x60, 0x00, 0x01, 0x48, 0x00, 0x02, 0x44, 0x38, 0x61, 0x00, 0x18};
|
static const u8 SearchPattern[] = {0x40, 0x82, 0x00, 0x0C, 0x38, 0x60, 0x00, 0x01, 0x48, 0x00, 0x02, 0x44, 0x38, 0x61, 0x00, 0x18};
|
||||||
static const u8 PatchData[] = {0x40, 0x82, 0x00, 0x04, 0x38, 0x60, 0x00, 0x01, 0x48, 0x00, 0x02, 0x44, 0x38, 0x61, 0x00, 0x18};
|
static const u8 PatchData[] = {0x40, 0x82, 0x00, 0x04, 0x38, 0x60, 0x00, 0x01, 0x48, 0x00, 0x02, 0x44, 0x38, 0x61, 0x00, 0x18};
|
||||||
@ -255,8 +231,8 @@ static bool Remove_001_Protection(void *Address, int Size)
|
|||||||
if (memcmp(Addr, SearchPattern, sizeof SearchPattern) == 0)
|
if (memcmp(Addr, SearchPattern, sizeof SearchPattern) == 0)
|
||||||
{
|
{
|
||||||
memcpy(Addr, PatchData, sizeof PatchData);
|
memcpy(Addr, PatchData, sizeof PatchData);
|
||||||
return true;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
15
resources/wiiflow_game_booter/apploader.h
Normal file
15
resources/wiiflow_game_booter/apploader.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef _APPLOADER_H_
|
||||||
|
#define _APPLOADER_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
#include "types.h"
|
||||||
|
/* Prototypes */
|
||||||
|
u32 Apploader_Run(u8 vidMode, u8 vipatch, u8 countryString, u8 patchVidModes, int aspectRatio, u32 returnTo);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif
|
59
resources/wiiflow_game_booter/cache.c
Normal file
59
resources/wiiflow_game_booter/cache.c
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
TinyLoad - a simple region free (original) game launcher in 4k
|
||||||
|
|
||||||
|
# This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||||
|
# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This code comes from the Twilight Hack */
|
||||||
|
// Copyright 2008-2009 Segher Boessenkool <segher@kernel.crashing.org>
|
||||||
|
// Copyright 2008-2009 Hector Martin <marcan@marcansoft.com>
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
// this saves 12 bytes
|
||||||
|
static void syncret(void) __attribute__((noinline));
|
||||||
|
static void syncret(void)
|
||||||
|
{
|
||||||
|
asm("sync ; isync");
|
||||||
|
}
|
||||||
|
|
||||||
|
void sync_before_read(void *p, u32 len)
|
||||||
|
{
|
||||||
|
u32 a, b;
|
||||||
|
|
||||||
|
a = (u32)p & ~0x1f;
|
||||||
|
b = ((u32)p + len + 0x1f) & ~0x1f;
|
||||||
|
|
||||||
|
for ( ; a < b; a += 32)
|
||||||
|
asm("dcbi 0,%0" : : "b"(a) : "memory");
|
||||||
|
|
||||||
|
syncret();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sync_after_write(const void *p, u32 len)
|
||||||
|
{
|
||||||
|
u32 a, b;
|
||||||
|
|
||||||
|
a = (u32)p & ~0x1f;
|
||||||
|
b = ((u32)p + len + 0x1f) & ~0x1f;
|
||||||
|
|
||||||
|
for ( ; a < b; a += 32)
|
||||||
|
asm("dcbf 0,%0" : : "b"(a));
|
||||||
|
|
||||||
|
syncret();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sync_before_exec(const void *p, u32 len)
|
||||||
|
{
|
||||||
|
u32 a, b;
|
||||||
|
|
||||||
|
a = (u32)p & ~0x1f;
|
||||||
|
b = ((u32)p + len + 0x1f) & ~0x1f;
|
||||||
|
|
||||||
|
for ( ; a < b; a += 32)
|
||||||
|
asm("dcbst 0,%0 ; sync ; icbi 0,%0" : : "b"(a));
|
||||||
|
|
||||||
|
syncret();
|
||||||
|
}
|
21
resources/wiiflow_game_booter/cache.h
Normal file
21
resources/wiiflow_game_booter/cache.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
TinyLoad - a simple region free (original) game launcher in 4k
|
||||||
|
|
||||||
|
# This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||||
|
# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This code comes from the Twilight Hack */
|
||||||
|
// Copyright 2008-2009 Segher Boessenkool <segher@kernel.crashing.org>
|
||||||
|
// Copyright 2008-2009 Hector Martin <marcan@marcansoft.com>
|
||||||
|
|
||||||
|
#ifndef __CACHE_H__
|
||||||
|
#define __CACHE_H__
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
void sync_before_read(void *p, u32 len);
|
||||||
|
void sync_after_write(const void *p, u32 len);
|
||||||
|
void sync_before_exec(const void *p, u32 len);
|
||||||
|
|
||||||
|
#endif
|
@ -24,27 +24,24 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include <gctypes.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "cios.h"
|
#include "cios.h"
|
||||||
#include "gecko.h"
|
#include "debug.h"
|
||||||
|
#include "ios.h"
|
||||||
|
|
||||||
bool Hermes_shadow_mload(int mload_rev)
|
u8 Hermes_shadow_mload(int mload_rev)
|
||||||
{
|
{
|
||||||
int v51 = (5 << 4) & 1;
|
int v51 = (5 << 4) & 1;
|
||||||
if(mload_rev >= v51)
|
if(mload_rev >= v51)
|
||||||
{
|
{
|
||||||
IOS_Open("/dev/mload/OFF",0); // shadow /dev/mload supported in hermes cios v5.1
|
ios_open("/dev/mload/OFF",0); // shadow /dev/mload supported in hermes cios v5.1
|
||||||
gprintf("Shadow mload\n");
|
debug_string("Shadow mload\n");
|
||||||
return true;
|
return 1;
|
||||||
}
|
}
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hermes_Disable_EHC()
|
void Hermes_Disable_EHC()
|
||||||
{
|
{
|
||||||
IOS_Open("/dev/usb123/OFF", 0);// this disables ehc completely
|
ios_open("/dev/usb123/OFF", 0);// this disables ehc completely
|
||||||
gprintf("Hermes EHC Disabled\n");
|
debug_string("Hermes EHC Disabled\n");
|
||||||
}
|
}
|
@ -2,7 +2,6 @@
|
|||||||
#ifndef _CIOSINFO_H_
|
#ifndef _CIOSINFO_H_
|
||||||
#define _CIOSINFO_H_
|
#define _CIOSINFO_H_
|
||||||
|
|
||||||
#include <gccore.h>
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -24,14 +23,8 @@ typedef struct _IOS_Info {
|
|||||||
u8 Type;
|
u8 Type;
|
||||||
u8 Base;
|
u8 Base;
|
||||||
} IOS_Info;
|
} IOS_Info;
|
||||||
|
|
||||||
extern IOS_Info CurrentIOS;
|
extern IOS_Info CurrentIOS;
|
||||||
void IOS_GetCurrentIOSInfo();
|
u8 Hermes_shadow_mload(int mload_rev);
|
||||||
|
|
||||||
bool IOS_D2X(u8 ios, u8 *base);
|
|
||||||
u8 IOS_GetType(u8 slot);
|
|
||||||
|
|
||||||
bool Hermes_shadow_mload(int mload_rev);
|
|
||||||
void Hermes_Disable_EHC();
|
void Hermes_Disable_EHC();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
39
resources/wiiflow_game_booter/crt0.S
Normal file
39
resources/wiiflow_game_booter/crt0.S
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
TinyLoad - a simple region free (original) game launcher in 4k
|
||||||
|
|
||||||
|
# This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||||
|
# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This code comes from the Twilight Hack */
|
||||||
|
// Copyright 2008-2009 Segher Boessenkool <segher@kernel.crashing.org>
|
||||||
|
|
||||||
|
.globl _start
|
||||||
|
_start:
|
||||||
|
|
||||||
|
# Disable interrupts
|
||||||
|
mfmsr 3 ; rlwinm 3,3,0,17,15 ; mtmsr 3 ; isync
|
||||||
|
|
||||||
|
# Setup stack.
|
||||||
|
lis 1,_stack_top@ha ; addi 1,1,_stack_top@l ; li 0,0 ; stwu 0,-64(1)
|
||||||
|
|
||||||
|
#if !defined(TINY) || defined(DEBUG)
|
||||||
|
# Clear BSS.
|
||||||
|
lis 3,__bss_start@ha ; addi 3,3,__bss_start@l
|
||||||
|
#if defined(TINY)
|
||||||
|
lis 4,0xDEAD
|
||||||
|
ori 4,4,0xBEEF
|
||||||
|
#else
|
||||||
|
li 4,0
|
||||||
|
#endif
|
||||||
|
lis 5,__bss_end@ha ; addi 5,5,__bss_end@l ; sub 5,5,3
|
||||||
|
bl memset32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
# Go!
|
||||||
|
bl _main
|
||||||
|
|
||||||
|
#ifndef TINY
|
||||||
|
# If it returns, hang. Shouldn't happen.
|
||||||
|
b .
|
||||||
|
#endif
|
38
resources/wiiflow_game_booter/debug.c
Normal file
38
resources/wiiflow_game_booter/debug.c
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
TinyLoad - a simple region free (original) game launcher in 4k
|
||||||
|
|
||||||
|
# This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||||
|
# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This code comes from HBC's stub which was based on dhewg's geckoloader stub */
|
||||||
|
// Copyright 2008-2009 Andre Heider <dhewg@wiibrew.org>
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
#include "usb.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
static char int2hex[] = "0123456789abcdef";
|
||||||
|
|
||||||
|
void debug_uint (u32 i) {
|
||||||
|
int j;
|
||||||
|
|
||||||
|
usb_sendbuffersafe ("0x", 2);
|
||||||
|
for (j = 0; j < 8; ++j) {
|
||||||
|
usb_sendbuffersafe (&int2hex[(i >> 28) & 0xf], 1);
|
||||||
|
i <<= 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void debug_string (const char *s) {
|
||||||
|
u32 i = 0;
|
||||||
|
|
||||||
|
while (s[i])
|
||||||
|
i++;
|
||||||
|
|
||||||
|
usb_sendbuffersafe (s, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
29
resources/wiiflow_game_booter/debug.h
Normal file
29
resources/wiiflow_game_booter/debug.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
TinyLoad - a simple region free (original) game launcher in 4k
|
||||||
|
|
||||||
|
# This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||||
|
# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This code comes from HBC's stub which was based on dhewg's geckoloader stub */
|
||||||
|
// Copyright 2008-2009 Andre Heider <dhewg@wiibrew.org>
|
||||||
|
|
||||||
|
#ifndef _STUB_DEBUG_H_
|
||||||
|
#define _STUB_DEBUG_H_
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
void debug_uint (u32 i);
|
||||||
|
void debug_string (const char *s);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define debug_uint(x)
|
||||||
|
#define debug_string(x)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
216
resources/wiiflow_game_booter/di.c
Normal file
216
resources/wiiflow_game_booter/di.c
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
/*
|
||||||
|
TinyLoad - a simple region free (original) game launcher in 4k
|
||||||
|
|
||||||
|
# This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||||
|
# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Copyright 2008-2009 Hector Martin <marcan@marcansoft.com>
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "ios.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "di.h"
|
||||||
|
|
||||||
|
int di_fd=0;
|
||||||
|
|
||||||
|
u32 inbuf[16] ALIGNED(64);
|
||||||
|
u32 outbuf[16] ALIGNED(64);
|
||||||
|
|
||||||
|
extern u32 __bss_start[];
|
||||||
|
extern u32 __bss_end[];
|
||||||
|
|
||||||
|
int di_init(void)
|
||||||
|
{
|
||||||
|
debug_string("Opening /dev/di: ");
|
||||||
|
di_fd = ios_open("/dev/di",0);
|
||||||
|
debug_uint(di_fd);
|
||||||
|
debug_string("\n");
|
||||||
|
//memset(inbuf, 0, 0x20 );
|
||||||
|
return di_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int di_shutdown(void)
|
||||||
|
{
|
||||||
|
return ios_close(di_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _di_ioctl_std(int num) __attribute__((noinline));
|
||||||
|
static int _di_ioctl_std(int num)
|
||||||
|
{
|
||||||
|
inbuf[0x00] = num << 24;
|
||||||
|
return ios_ioctl( di_fd, num, inbuf, 0x20, outbuf, 0x20);
|
||||||
|
}
|
||||||
|
|
||||||
|
int di_getcoverstatus(void)
|
||||||
|
{
|
||||||
|
//memset(inbuf, 0, 0x20 );
|
||||||
|
//memset(outbuf, 0, 0x20 );
|
||||||
|
|
||||||
|
//inbuf[0x00] = 0x88000000;
|
||||||
|
|
||||||
|
int ret = _di_ioctl_std(0x88);
|
||||||
|
if( ret != 1 )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return outbuf[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int di_identify(void)
|
||||||
|
{
|
||||||
|
//memset(inbuf, 0, 0x20 );
|
||||||
|
//memset(outbuf, 0, 0x20 );
|
||||||
|
|
||||||
|
//inbuf[0x00] = 0x12000000;
|
||||||
|
|
||||||
|
return _di_ioctl_std(0x12);
|
||||||
|
}
|
||||||
|
#ifndef TINY
|
||||||
|
int di_waitforcoverclose(void)
|
||||||
|
{
|
||||||
|
//memset(inbuf, 0, 0x20 );
|
||||||
|
//memset(outbuf, 0, 0x20 );
|
||||||
|
|
||||||
|
//inbuf[0x00] = 0x79000000;
|
||||||
|
|
||||||
|
int ret = _di_ioctl_std(0x79);
|
||||||
|
if( ret < 0 )
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return outbuf[0];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifndef TINY
|
||||||
|
int di_requesterror(void)
|
||||||
|
{
|
||||||
|
//memset(inbuf, 0, 0x20 );
|
||||||
|
//memset(outbuf, 0, 0x20 );
|
||||||
|
|
||||||
|
//inbuf[0x00] = 0xE0000000;
|
||||||
|
|
||||||
|
int ret = _di_ioctl_std(0xE0);
|
||||||
|
if( ret < 0 )
|
||||||
|
return ret;
|
||||||
|
return outbuf[0];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int di_read(void *dst, u32 size, u32 offset)
|
||||||
|
{
|
||||||
|
//memset(inbuf, 0, 0x20 );
|
||||||
|
|
||||||
|
inbuf[0x00] = 0x71000000;
|
||||||
|
inbuf[0x01] = size;
|
||||||
|
inbuf[0x02] = offset;
|
||||||
|
|
||||||
|
return ios_ioctl( di_fd, 0x71, inbuf, 0x20, dst, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int di_unencryptedread(void *dst, u32 size, u32 offset)
|
||||||
|
{
|
||||||
|
//memset(inbuf, 0, 0x20 );
|
||||||
|
|
||||||
|
inbuf[0x00] = 0x8D000000;
|
||||||
|
inbuf[0x01] = size;
|
||||||
|
inbuf[0x02] = offset;
|
||||||
|
|
||||||
|
return ios_ioctl( di_fd, 0x8D, inbuf, 0x20, dst, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int di_reset(void)
|
||||||
|
{
|
||||||
|
//memset(inbuf, 0, 0x20 );
|
||||||
|
|
||||||
|
//inbuf[0x00] = 0x8A000000;
|
||||||
|
inbuf[0x01] = 1;
|
||||||
|
|
||||||
|
return _di_ioctl_std(0x8A);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef TINY
|
||||||
|
int di_stopmotor(void)
|
||||||
|
{
|
||||||
|
//memset(inbuf, 0, 0x20 );
|
||||||
|
//inbuf[0x00] = 0xE3000000;
|
||||||
|
inbuf[0x01] = 0;
|
||||||
|
inbuf[0x02] = 0;
|
||||||
|
|
||||||
|
return _di_ioctl_std(0xE3);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int di_openpartition(u32 offset, u8 *tmd)
|
||||||
|
{
|
||||||
|
static struct ioctlv vectors[16] ALIGNED(64);
|
||||||
|
|
||||||
|
//memset(inbuf, 0, 0x20 );
|
||||||
|
inbuf[0x00] = 0x8B000000;
|
||||||
|
inbuf[0x01] = offset;
|
||||||
|
|
||||||
|
vectors[0].data = inbuf;
|
||||||
|
vectors[0].len = 0x20;
|
||||||
|
vectors[1].data = NULL;
|
||||||
|
vectors[1].len = 0x2a4;
|
||||||
|
vectors[2].data = NULL;
|
||||||
|
vectors[2].len = 0;
|
||||||
|
|
||||||
|
vectors[3].data = tmd;
|
||||||
|
vectors[3].len = 0x49e4;
|
||||||
|
vectors[4].data = outbuf;
|
||||||
|
vectors[4].len = 0x20;
|
||||||
|
|
||||||
|
return ios_ioctlv(di_fd, 0x8B, 3, 2, vectors);
|
||||||
|
}
|
||||||
|
#ifndef TINY
|
||||||
|
int di_closepartition(void)
|
||||||
|
{
|
||||||
|
//memset(inbuf, 0, 0x20 );
|
||||||
|
//inbuf[0x00] = 0x8C000000;
|
||||||
|
return _di_ioctl_std(0x8C);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
int di_readdiscid(void *dst)
|
||||||
|
{
|
||||||
|
//memset(inbuf, 0, 0x20 );
|
||||||
|
//memset(dst, 0, 0x20 );
|
||||||
|
|
||||||
|
inbuf[0x00] = 0x70000000;
|
||||||
|
|
||||||
|
return ios_ioctl( di_fd, 0x70, inbuf, 0x20, dst, 0x20);
|
||||||
|
}
|
||||||
|
|
||||||
|
int WDVD_SetFragList(int device, void *fraglist, int size)
|
||||||
|
{
|
||||||
|
debug_string("WDVD_SetFragList\n");
|
||||||
|
debug_uint(device);
|
||||||
|
debug_uint((u32)fraglist);
|
||||||
|
debug_uint(size);
|
||||||
|
/* Set FRAG mode */
|
||||||
|
inbuf[0] = 0xF9000000;
|
||||||
|
inbuf[1] = device;
|
||||||
|
inbuf[2] = (u32)fraglist;
|
||||||
|
inbuf[3] = size;
|
||||||
|
|
||||||
|
return ios_ioctl(di_fd, 0xF9, inbuf, 0x20, outbuf, 0x20);
|
||||||
|
}
|
||||||
|
|
||||||
|
int WDVD_SetUSBMode(u32 mode, const u8 *id, s32 partition)
|
||||||
|
{
|
||||||
|
debug_string("WDVD_SetUSBMode\n");
|
||||||
|
memset(inbuf, 0, 0x20);
|
||||||
|
|
||||||
|
/* Set USB mode */
|
||||||
|
inbuf[0] = 0xF4000000;
|
||||||
|
inbuf[1] = mode;
|
||||||
|
|
||||||
|
/* Copy ID */
|
||||||
|
if(id)
|
||||||
|
{
|
||||||
|
memcpy(&inbuf[2], id, 6);
|
||||||
|
if(partition >= 0)
|
||||||
|
inbuf[5] = partition;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ios_ioctl(di_fd, 0xF4, inbuf, 0x20, outbuf, 0x20);
|
||||||
|
}
|
29
resources/wiiflow_game_booter/di.h
Normal file
29
resources/wiiflow_game_booter/di.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
TinyLoad - a simple region free (original) game launcher in 4k
|
||||||
|
|
||||||
|
# This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||||
|
# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Copyright 2008-2009 Hector Martin <marcan@marcansoft.com>
|
||||||
|
|
||||||
|
#ifndef __DI_H__
|
||||||
|
#define __DI_H__
|
||||||
|
|
||||||
|
int di_init(void);
|
||||||
|
int di_getcoverstatus(void);
|
||||||
|
int di_requesterror(void);
|
||||||
|
int di_read(void *dst, u32 size, u32 offset);
|
||||||
|
int di_unencryptedread(void *dst, u32 size, u32 offset);
|
||||||
|
int di_identify(void);
|
||||||
|
int di_reset(void);
|
||||||
|
int di_stopmotor(void);
|
||||||
|
int di_openpartition(u32 offset, u8 *tmd);
|
||||||
|
int di_closepartition(void);
|
||||||
|
int di_readdiscid(void *dst);
|
||||||
|
int di_shutdown(void);
|
||||||
|
|
||||||
|
int WDVD_SetFragList(int device, void *fraglist, int size);
|
||||||
|
int WDVD_SetUSBMode(u32 mode, const u8 *id, s32 partition);
|
||||||
|
|
||||||
|
#endif
|
59
resources/wiiflow_game_booter/disc.c
Normal file
59
resources/wiiflow_game_booter/disc.c
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#include "types.h"
|
||||||
|
#include "memory.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "frag.h"
|
||||||
|
#include "cache.h"
|
||||||
|
#include "di.h"
|
||||||
|
#include "cios.h"
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* ERROR 002 fix (WiiPower) */
|
||||||
|
*(u32 *)0x80003140 = *(u32 *)0x80003188;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 wbfsDev = 0;
|
||||||
|
u32 wbfs_part_idx = 0;
|
||||||
|
FragList *frag_list = NULL;
|
||||||
|
static int set_frag_list()
|
||||||
|
{
|
||||||
|
// (+1 for header which is same size as fragment)
|
||||||
|
int size = sizeof(Fragment) * (frag_list->num + 1);
|
||||||
|
return WDVD_SetFragList(wbfsDev, frag_list, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 Disc_SetUSB(const u8 *id, u8 frag)
|
||||||
|
{
|
||||||
|
//ENABLE USB in cIOS
|
||||||
|
if(id)
|
||||||
|
{
|
||||||
|
if(frag)
|
||||||
|
return set_frag_list();
|
||||||
|
s32 part = -1;
|
||||||
|
if(CurrentIOS.Type == IOS_TYPE_HERMES)
|
||||||
|
part = wbfs_part_idx ? wbfs_part_idx - 1 : 0;
|
||||||
|
return WDVD_SetUSBMode(wbfsDev, (u8*)id, part);
|
||||||
|
}
|
||||||
|
//DISABLE USB in cIOS
|
||||||
|
return WDVD_SetUSBMode(0, NULL, -1);
|
||||||
|
}
|
@ -6,15 +6,14 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
s32 Disc_Open();
|
/*s32 Disc_Open();
|
||||||
s32 Disc_FindPartition(u64 *outbuf);
|
s32 Disc_FindPartition(u64 *outbuf);*/
|
||||||
s32 Disc_SetUSB(const u8 *id, bool frag);
|
s32 Disc_SetUSB(const u8 *id, u8 frag);
|
||||||
void Disc_SetLowMem();
|
void Disc_SetLowMem();
|
||||||
void Disc_SetTime();
|
/*
|
||||||
|
|
||||||
GXRModeObj *Disc_SelectVMode(u8 videoselected, u32 *rmode_reg);
|
GXRModeObj *Disc_SelectVMode(u8 videoselected, u32 *rmode_reg);
|
||||||
void Disc_SetVMode(GXRModeObj *rmode, u32 rmode_reg);
|
void Disc_SetVMode(GXRModeObj *rmode, u32 rmode_reg);
|
||||||
|
*/
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
@ -9,7 +9,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "gctypes.h"
|
#include "types.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
352
resources/wiiflow_game_booter/ios.c
Normal file
352
resources/wiiflow_game_booter/ios.c
Normal file
@ -0,0 +1,352 @@
|
|||||||
|
/*
|
||||||
|
TinyLoad - a simple region free (original) game launcher in 4k
|
||||||
|
|
||||||
|
# This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||||
|
# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This code comes from HBC's stub which was based on the Twilight Hack code */
|
||||||
|
// Copyright 2008-2009 Segher Boessenkool <segher@kernel.crashing.org>
|
||||||
|
// Copyright 2008-2009 Andre Heider <dhewg@wiibrew.org>
|
||||||
|
// Copyright 2008-2009 Hector Martin <marcan@marcansoft.com>
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
#include "ios.h"
|
||||||
|
#include "cache.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#define virt_to_phys(x) ((u32*)(((u32)(x))&0x3FFFFFFF))
|
||||||
|
#define phys_to_virt(x) ((u32*)(((u32)(x))|0x80000000))
|
||||||
|
|
||||||
|
// Low-level IPC access.
|
||||||
|
|
||||||
|
static inline u32 iread32(u32 addr)
|
||||||
|
{
|
||||||
|
u32 x;
|
||||||
|
|
||||||
|
asm volatile("lwz %0,0(%1) ; sync ; isync" : "=r"(x) : "b"(0xc0000000 | addr));
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void iwrite32(u32 addr, u32 x)
|
||||||
|
{
|
||||||
|
asm volatile("stw %0,0(%1) ; eieio" : : "r"(x), "b"(0xc0000000 | addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TINY
|
||||||
|
static u32 _ipc_read(u32 reg) __attribute__((noinline));
|
||||||
|
static void _ipc_write(u32 reg, u32 value) __attribute__((noinline));
|
||||||
|
static void ipc_bell(u32 w) __attribute__((noinline));
|
||||||
|
|
||||||
|
// inline the 4*, don't inline the 0x0d0 stuff. yes, this saves a few bytes.
|
||||||
|
static u32 _ipc_read(u32 reg) {
|
||||||
|
return iread32(0x0d000000 + reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _ipc_write(u32 reg, u32 value) {
|
||||||
|
iwrite32(0x0d000000 + reg, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 ipc_read(u32 reg) {
|
||||||
|
return _ipc_read(4*reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ipc_write(u32 reg, u32 value) {
|
||||||
|
_ipc_write(4*reg, value);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static u32 ipc_read(u32 reg) {
|
||||||
|
return iread32(0x0d000000 + 4*reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ipc_write(u32 reg, u32 value) {
|
||||||
|
iwrite32(0x0d000000 + 4*reg, value);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void ipc_bell(u32 w)
|
||||||
|
{
|
||||||
|
ipc_write(1, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ios_delay(void) __attribute__((noinline));
|
||||||
|
static void ios_delay(void)
|
||||||
|
{
|
||||||
|
udelay(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ipc_wait_ack(void)
|
||||||
|
{
|
||||||
|
while (!(ipc_read(1) & 0x2)) {
|
||||||
|
//debug_string("no ack\n");
|
||||||
|
//udelay(10000);
|
||||||
|
}
|
||||||
|
ios_delay();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ipc_wait_reply(void)
|
||||||
|
{
|
||||||
|
while (!(ipc_read(1) & 0x4)) {
|
||||||
|
//debug_string("no reply\n");
|
||||||
|
//udelay(10000);
|
||||||
|
}
|
||||||
|
ios_delay();
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 ipc_wait(void)
|
||||||
|
{
|
||||||
|
u32 ret;
|
||||||
|
while (!((ret = ipc_read(1)) & 0x6)) {
|
||||||
|
//debug_string("no nothing\n");
|
||||||
|
//udelay(10000);
|
||||||
|
}
|
||||||
|
ios_delay();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mid-level IPC access.
|
||||||
|
|
||||||
|
struct ipc {
|
||||||
|
u32 cmd;
|
||||||
|
int result;
|
||||||
|
int fd;
|
||||||
|
u32 arg[5];
|
||||||
|
|
||||||
|
u32 user[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ipc ipc ALIGNED(64);
|
||||||
|
|
||||||
|
void ipc_init(void)
|
||||||
|
{
|
||||||
|
ipc_write(1, 0x06);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ipc_send_request(void)
|
||||||
|
{
|
||||||
|
sync_after_write(&ipc, 0x40);
|
||||||
|
|
||||||
|
ipc_write(0, (u32)virt_to_phys(&ipc));
|
||||||
|
ipc_bell(1);
|
||||||
|
|
||||||
|
ipc_wait_ack();
|
||||||
|
|
||||||
|
//udelay(1000);
|
||||||
|
ipc_bell(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ipc_send_twoack(void)
|
||||||
|
{
|
||||||
|
sync_after_write(&ipc, 0x40);
|
||||||
|
ios_delay();
|
||||||
|
|
||||||
|
ipc_write(0, (u32)virt_to_phys(&ipc));
|
||||||
|
ipc_bell(1);
|
||||||
|
|
||||||
|
if(ipc_wait() & 4) {
|
||||||
|
debug_string("got reply instead, bad\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ipc_bell(2);
|
||||||
|
|
||||||
|
if(ipc_wait() & 4) {
|
||||||
|
debug_string("got reply instead, bad\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ipc_bell(2);
|
||||||
|
ipc_bell(8);
|
||||||
|
debug_string("\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ipc_recv_reply(void)
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
u32 reply;
|
||||||
|
|
||||||
|
ipc_wait_reply();
|
||||||
|
|
||||||
|
reply = ipc_read(2);
|
||||||
|
ipc_bell(4);
|
||||||
|
|
||||||
|
ipc_bell(8);
|
||||||
|
|
||||||
|
if (((u32*)reply) == virt_to_phys(&ipc))
|
||||||
|
break;
|
||||||
|
|
||||||
|
debug_string("Ignoring unexpected IPC reply @");
|
||||||
|
debug_uint((u32)reply);
|
||||||
|
debug_string("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
sync_before_read(&ipc, 0x40);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// High-level IPC access.
|
||||||
|
|
||||||
|
void ios_cleanup()
|
||||||
|
{
|
||||||
|
int loops = 0xA;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if((ipc_read(1) & 0x22) == 0x22)
|
||||||
|
ipc_write(1, (ipc_read(1)&~0x30) | 2);
|
||||||
|
if((ipc_read(1) & 0x14) == 0x14)
|
||||||
|
{
|
||||||
|
ipc_read(2);
|
||||||
|
ipc_write(1, (ipc_read(1)&~0x30) | 4);
|
||||||
|
ipc_write(12, 0x4000);
|
||||||
|
ipc_write(1, (ipc_read(1)&~0x30) | 8);
|
||||||
|
}
|
||||||
|
ipc_write(12, 0x4000);
|
||||||
|
udelay(1000);
|
||||||
|
loops--;
|
||||||
|
} while(loops != 0);
|
||||||
|
|
||||||
|
int fd;
|
||||||
|
for(fd = 0; fd != 31; fd++)
|
||||||
|
ios_close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ios_open(const char *filename, u32 mode)
|
||||||
|
{
|
||||||
|
#ifdef TINY
|
||||||
|
sync_after_write((void*)filename, 0x20);
|
||||||
|
#else
|
||||||
|
sync_after_write((void*)filename, strlen(filename) + 1);
|
||||||
|
#endif
|
||||||
|
#ifndef TINY
|
||||||
|
memset(&ipc, 0, sizeof ipc);
|
||||||
|
#endif
|
||||||
|
ipc.cmd = 1;
|
||||||
|
ipc.fd = 0;
|
||||||
|
ipc.arg[0] = (u32)virt_to_phys(filename);
|
||||||
|
ipc.arg[1] = mode;
|
||||||
|
|
||||||
|
//debug_string("Sending openreq\n");
|
||||||
|
ipc_send_request();
|
||||||
|
//debug_string("AAA\n");
|
||||||
|
ipc_recv_reply();
|
||||||
|
//debug_string("BBB\n");
|
||||||
|
|
||||||
|
return ipc.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ios_std(int fd, int cmd)
|
||||||
|
{
|
||||||
|
ipc.cmd = cmd;
|
||||||
|
ipc.fd = fd;
|
||||||
|
|
||||||
|
ipc_send_request();
|
||||||
|
ipc_recv_reply();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ios_close(int fd)
|
||||||
|
{
|
||||||
|
#ifndef TINY
|
||||||
|
memset(&ipc, 0, sizeof ipc);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ios_std(fd, 2);
|
||||||
|
|
||||||
|
return ipc.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ios_read(int fd, void *buf, u32 size)
|
||||||
|
{
|
||||||
|
#ifndef TINY
|
||||||
|
memset(&ipc, 0, sizeof ipc);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ipc.arg[0] = (u32)virt_to_phys(buf);
|
||||||
|
ipc.arg[1] = size;
|
||||||
|
|
||||||
|
ios_std(fd, 3);
|
||||||
|
|
||||||
|
sync_before_read(buf, size);
|
||||||
|
|
||||||
|
return ipc.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ios_ioctl(int fd, u32 n, void *in, u32 in_size, void *out, u32 out_size)
|
||||||
|
{
|
||||||
|
#ifndef TINY
|
||||||
|
memset(&ipc, 0, sizeof ipc);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(in)
|
||||||
|
sync_after_write(in, in_size);
|
||||||
|
if(out)
|
||||||
|
sync_after_write(out, out_size);
|
||||||
|
|
||||||
|
ipc.arg[0] = n;
|
||||||
|
ipc.arg[1] = (u32)virt_to_phys(in);
|
||||||
|
ipc.arg[2] = in_size;
|
||||||
|
ipc.arg[3] = (u32)virt_to_phys(out);
|
||||||
|
ipc.arg[4] = out_size;
|
||||||
|
|
||||||
|
ios_std(fd, 6);
|
||||||
|
|
||||||
|
if(out)
|
||||||
|
sync_before_read(out, out_size);
|
||||||
|
|
||||||
|
return ipc.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _ios_ioctlv(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec, int reboot)
|
||||||
|
{
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
#ifndef TINY
|
||||||
|
memset(&ipc, 0, sizeof ipc);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (i = 0; i < in_count + out_count; i++) {
|
||||||
|
if (vec[i].data) {
|
||||||
|
sync_after_write(vec[i].data, vec[i].len);
|
||||||
|
vec[i].data = (void *)virt_to_phys(vec[i].data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sync_after_write(vec, (in_count + out_count) * sizeof *vec);
|
||||||
|
|
||||||
|
ipc.cmd = 7;
|
||||||
|
ipc.fd = fd;
|
||||||
|
ipc.arg[0] = n;
|
||||||
|
ipc.arg[1] = in_count;
|
||||||
|
ipc.arg[2] = out_count;
|
||||||
|
ipc.arg[3] = (u32)virt_to_phys(vec);
|
||||||
|
|
||||||
|
if(reboot) {
|
||||||
|
//debug_string("Sending twoack\n");
|
||||||
|
if(ipc_send_twoack())
|
||||||
|
return 0;
|
||||||
|
debug_string("Reboot returned a reply instead of an ACK");
|
||||||
|
} else {
|
||||||
|
//debug_string("Sending request\n");
|
||||||
|
ipc_send_request();
|
||||||
|
//debug_string("K\n");
|
||||||
|
}
|
||||||
|
ipc_recv_reply();
|
||||||
|
//debug_string("Got reply\n");
|
||||||
|
|
||||||
|
for (i = in_count; i < in_count + out_count; i++) {
|
||||||
|
if (vec[i].data) {
|
||||||
|
vec[i].data = phys_to_virt((u32)vec[i].data);
|
||||||
|
sync_before_read(vec[i].data, vec[i].len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(reboot && (ipc.result >= 0))
|
||||||
|
return -100;
|
||||||
|
return ipc.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ios_ioctlv(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec) {
|
||||||
|
return _ios_ioctlv(fd, n, in_count, out_count, vec, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ios_ioctlvreboot(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec) {
|
||||||
|
return _ios_ioctlv(fd, n, in_count, out_count, vec, 1);
|
||||||
|
}
|
27
resources/wiiflow_game_booter/ios.h
Normal file
27
resources/wiiflow_game_booter/ios.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
TinyLoad - a simple region free (original) game launcher in 4k
|
||||||
|
|
||||||
|
# This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||||
|
# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __IOS_H__
|
||||||
|
#define __IOS_H__
|
||||||
|
|
||||||
|
// Copyright 2008-2009 Hector Martin <marcan@marcansoft.com>
|
||||||
|
|
||||||
|
struct ioctlv {
|
||||||
|
void *data;
|
||||||
|
u32 len;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ipc_init(void);
|
||||||
|
int ios_open(const char *filename, u32 mode);
|
||||||
|
int ios_close(int fd);
|
||||||
|
int ios_ioctl(int fd, u32 n, void *in, u32 in_size, void *out, u32 out_size);
|
||||||
|
int ios_ioctlv(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec);
|
||||||
|
int ios_ioctlvreboot(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec);
|
||||||
|
int ios_read(int fd, void *buf, u32 size);
|
||||||
|
void ios_cleanup(void);
|
||||||
|
|
||||||
|
#endif
|
36
resources/wiiflow_game_booter/link.ld
Normal file
36
resources/wiiflow_game_booter/link.ld
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
TinyLoad - a simple region free (original) game launcher in 4k
|
||||||
|
|
||||||
|
# This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||||
|
# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
OUTPUT_FORMAT("elf32-powerpc")
|
||||||
|
OUTPUT_ARCH(powerpc:common)
|
||||||
|
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
PHDRS {
|
||||||
|
app PT_LOAD FLAGS(7);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
. = 0x80F00000;
|
||||||
|
|
||||||
|
.text : { *(.text) *(.text.*) } :app
|
||||||
|
|
||||||
|
.data : { *(.data) *(.data.*) }
|
||||||
|
.rodata : { *(.rodata) *(.rodata.*) }
|
||||||
|
//.sdata : { *(.sdata) *(.sdata.*) }
|
||||||
|
__bss_start = .;
|
||||||
|
//.sbss : { *(.sbss) *(.sbss.*) }
|
||||||
|
.bss : { *(.bss) *(.bss.*) }
|
||||||
|
__bss_end = .;
|
||||||
|
|
||||||
|
. = ALIGN(0x40);
|
||||||
|
.stack : {
|
||||||
|
. = . + 0x48000;
|
||||||
|
_stack_top = .;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
661
resources/wiiflow_game_booter/main.c
Normal file
661
resources/wiiflow_game_booter/main.c
Normal file
@ -0,0 +1,661 @@
|
|||||||
|
/*
|
||||||
|
TinyLoad - a simple region free (original) game launcher in 4k
|
||||||
|
|
||||||
|
# This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||||
|
# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This code comes from HBC's stub which was based on dhewg's geckoloader stub */
|
||||||
|
// Copyright 2008-2009 Andre Heider <dhewg@wiibrew.org>
|
||||||
|
// Copyright 2008-2009 Hector Martin <marcan@marcansoft.com>
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "usb.h"
|
||||||
|
#include "ios.h"
|
||||||
|
#include "cache.h"
|
||||||
|
#include "di.h"
|
||||||
|
#include "disc.h"
|
||||||
|
#include "apploader.h"
|
||||||
|
#include "patchcode.h"
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
#define COLOR_BLACK 0x00800080
|
||||||
|
#define COLOR_GRAY 0x80808080
|
||||||
|
#define COLOR_WHITE 0xFF80FF80
|
||||||
|
#define COLOR_RED 0x4C544CFF
|
||||||
|
#define COLOR_GREEN 0x4B554B4A
|
||||||
|
#define COLOR_BLUE 0x1DFF1D6B
|
||||||
|
#define COLOR_YELLOW 0xE100E194
|
||||||
|
|
||||||
|
#define IOCTL_ES_LAUNCH 0x08
|
||||||
|
#define IOCTL_ES_GETVIEWCNT 0x12
|
||||||
|
#define IOCTL_ES_GETVIEWS 0x13
|
||||||
|
|
||||||
|
IOS_Info CurrentIOS;
|
||||||
|
static the_CFG *conf = (the_CFG*)0x93100000;
|
||||||
|
|
||||||
|
static struct ioctlv vecs[16] ALIGNED(64);
|
||||||
|
static u32 disc_id[0x40] ALIGNED(32);
|
||||||
|
static u32 AppEntrypoint = 0;
|
||||||
|
static u8 tmd[0x5000] ALIGNED(64);
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
u32 count;
|
||||||
|
u32 offset;
|
||||||
|
u32 pad[6];
|
||||||
|
} part_table_info ALIGNED(32);
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
u32 offset;
|
||||||
|
u32 type;
|
||||||
|
} partition_table[32] ALIGNED(32);
|
||||||
|
/*
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
char revision[16];
|
||||||
|
void *entry;
|
||||||
|
s32 size;
|
||||||
|
s32 trailersize;
|
||||||
|
s32 padding;
|
||||||
|
} apploader_hdr ALIGNED(32);
|
||||||
|
*/
|
||||||
|
static int es_fd;
|
||||||
|
|
||||||
|
void fail(void) __attribute__((noreturn));
|
||||||
|
void prog10(void) __attribute__((noinline));
|
||||||
|
|
||||||
|
static int es_launchtitle(u64 titleID)
|
||||||
|
{
|
||||||
|
static u64 xtitleID __attribute__((aligned(32)));
|
||||||
|
static u32 cntviews __attribute__((aligned(32)));
|
||||||
|
static u8 tikviews[0xd8*4] __attribute__((aligned(32)));
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
debug_string("es_fd:");
|
||||||
|
debug_uint(es_fd);
|
||||||
|
debug_string("\n");
|
||||||
|
|
||||||
|
debug_string("LaunchTitle: ");
|
||||||
|
debug_uint(titleID>>32);
|
||||||
|
debug_string("-");
|
||||||
|
debug_uint(titleID&0xFFFFFFFF);
|
||||||
|
|
||||||
|
xtitleID = titleID;
|
||||||
|
|
||||||
|
debug_string("\nGetTicketViewCount: ");
|
||||||
|
|
||||||
|
vecs[0].data = &xtitleID;
|
||||||
|
vecs[0].len = 8;
|
||||||
|
vecs[1].data = &cntviews;
|
||||||
|
vecs[1].len = 4;
|
||||||
|
ret = ios_ioctlv(es_fd, IOCTL_ES_GETVIEWCNT, 1, 1, vecs);
|
||||||
|
debug_uint(ret);
|
||||||
|
debug_string(", views: ");
|
||||||
|
debug_uint(cntviews);
|
||||||
|
debug_string("\n");
|
||||||
|
if(ret<0) return ret;
|
||||||
|
if(cntviews>4) return -1;
|
||||||
|
|
||||||
|
debug_string("GetTicketViews: ");
|
||||||
|
//vecs[0].data = &xtitleID;
|
||||||
|
//vecs[0].len = 8;
|
||||||
|
//vecs[1].data = &cntviews;
|
||||||
|
//vecs[1].len = 4;
|
||||||
|
vecs[2].data = tikviews;
|
||||||
|
vecs[2].len = 0xd8*cntviews;
|
||||||
|
ret = ios_ioctlv(es_fd, IOCTL_ES_GETVIEWS, 2, 1, vecs);
|
||||||
|
debug_uint(ret);
|
||||||
|
debug_string("\n");
|
||||||
|
if(ret<0) return ret;
|
||||||
|
debug_string("Attempting to launch...\n");
|
||||||
|
//vecs[0].data = &xtitleID;
|
||||||
|
//vecs[0].len = 8;
|
||||||
|
vecs[1].data = tikviews;
|
||||||
|
vecs[1].len = 0xd8;
|
||||||
|
ret = ios_ioctlvreboot(es_fd, IOCTL_ES_LAUNCH, 2, 0, vecs);
|
||||||
|
if(ret < 0) {
|
||||||
|
debug_string("Launch failed: ");
|
||||||
|
debug_uint(ret);
|
||||||
|
debug_string("\r\n");
|
||||||
|
}
|
||||||
|
udelay(100000);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static s32 ios_getversion() __attribute__((unused));
|
||||||
|
static s32 ios_getversion()
|
||||||
|
{
|
||||||
|
u32 vercode;
|
||||||
|
u16 version;
|
||||||
|
sync_before_read((void*)0x80003140,8);
|
||||||
|
vercode = *((u32*)0x80003140);
|
||||||
|
version = vercode >> 16;
|
||||||
|
if(version == 0) return -1;
|
||||||
|
if(version > 0xff) return -1;
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printversion(void)
|
||||||
|
{
|
||||||
|
debug_string("IOS version: ");
|
||||||
|
debug_uint(ios_getversion());
|
||||||
|
debug_string("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int es_init(void)
|
||||||
|
{
|
||||||
|
debug_string("Opening /dev/es: ");
|
||||||
|
es_fd = ios_open("/dev/es", 0);
|
||||||
|
debug_uint(es_fd);
|
||||||
|
debug_string("\n");
|
||||||
|
return es_fd;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
static void simple_report(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
debug_string(fmt);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
static u8 conf_buffer[0x4000] ALIGNED(32);
|
||||||
|
|
||||||
|
static u32 get_counter_bias(void)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
u32 bias = 0;
|
||||||
|
|
||||||
|
fd = ios_open("/shared2/sys/SYSCONF", 1);
|
||||||
|
if(ios_read(fd, conf_buffer, 0x4000) != 0x4000) {
|
||||||
|
debug_string("Failed to get conf buffer\n");
|
||||||
|
fail();
|
||||||
|
//goto finish;
|
||||||
|
}
|
||||||
|
debug_string("Read SYSCONF\n");
|
||||||
|
|
||||||
|
u16 count = *((u16*)(&conf_buffer[4]));
|
||||||
|
u16 *offset = (u16*)&conf_buffer[6];
|
||||||
|
|
||||||
|
while(count--) {
|
||||||
|
if(/*(6 == ((conf_buffer[*offset]&0x0F)+1)) &&*/ !memcmp("IPL.CB", &conf_buffer[*offset+1], 6))
|
||||||
|
break;
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
if(count == -1) {
|
||||||
|
debug_string("Failed to find IPL.CB setting\n");
|
||||||
|
fail();
|
||||||
|
//goto finish;
|
||||||
|
}
|
||||||
|
u8 *b = &conf_buffer[*offset];
|
||||||
|
//memcpy(&bias, &conf_buffer[*offset+7], 4);
|
||||||
|
bias = (b[7]<<24) | (b[8]<<16) | (b[9]<<8) | b[10];
|
||||||
|
debug_string("Counter bias: ");
|
||||||
|
debug_uint(bias);
|
||||||
|
debug_string("\n");
|
||||||
|
|
||||||
|
//finish:
|
||||||
|
ios_close(fd);
|
||||||
|
return bias;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 read_rtc(void)
|
||||||
|
{
|
||||||
|
u32 rtc;
|
||||||
|
exi_chan0sr = 0x00000130;
|
||||||
|
exi_chan0data = 0x20000000;
|
||||||
|
exi_chan0cr = 0x39;
|
||||||
|
while((exi_chan0cr)&1);
|
||||||
|
exi_chan0cr = 0x39;
|
||||||
|
while((exi_chan0cr)&1);
|
||||||
|
rtc = exi_chan0data;
|
||||||
|
debug_string("RTC: ");
|
||||||
|
debug_uint(rtc);
|
||||||
|
debug_string("\n");
|
||||||
|
exi_chan0sr = 0x00000030;
|
||||||
|
//udelay(100);
|
||||||
|
return rtc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void write32(u32 w, u32 addr)
|
||||||
|
{
|
||||||
|
*((u32 *)(addr + 0x80000000)) = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void write16(u16 w, u16 addr)
|
||||||
|
{
|
||||||
|
*((u16 *)(addr + 0x80000000)) = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define framebuffer ((u32*)(0x81600000))
|
||||||
|
|
||||||
|
void memset32(u32 *addr, u32 data, u32 count) __attribute__ ((externally_visible));
|
||||||
|
|
||||||
|
void memset32(u32 *addr, u32 data, u32 count)
|
||||||
|
{
|
||||||
|
int sc = count;
|
||||||
|
void *sa = addr;
|
||||||
|
while(count--)
|
||||||
|
*addr++ = data;
|
||||||
|
sync_after_write(sa, 4*sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drawbar(int pix)
|
||||||
|
{
|
||||||
|
int i = 16;
|
||||||
|
u32* p = framebuffer + 320 * 400;
|
||||||
|
while(i--) {
|
||||||
|
memset32(p, COLOR_WHITE, pix);
|
||||||
|
p += 320;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
u32 vir(u32 addr) __attribute__((noinline));
|
||||||
|
u32 vir(u32 addr)
|
||||||
|
{
|
||||||
|
return *(vu32*)(addr+0xCC002000);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
inline void viw(u32 addr, u32 data)
|
||||||
|
{
|
||||||
|
*(vu32*)(addr+0xCC002000) = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fail(void)
|
||||||
|
{
|
||||||
|
memset32(framebuffer, COLOR_RED, 320*100);
|
||||||
|
debug_string("\nFAILURE\n");
|
||||||
|
es_launchtitle(0x100014a4f4449LL);
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define FAILNOTONE(val,msg) do { int __v = (val); if(__v != 1) { debug_string(msg "Value: "); debug_uint(__v); debug_string("\n"); fail(); } } while(0)
|
||||||
|
#else
|
||||||
|
#define FAILNOTONE(val,msg) failnotone((val))
|
||||||
|
|
||||||
|
static void failnotone(int v) __attribute__((noinline));
|
||||||
|
static void failnotone(int v) {
|
||||||
|
if(v != 1)
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int progress = 20;
|
||||||
|
|
||||||
|
static void prog(int p) __attribute__((noinline));
|
||||||
|
static void prog(int p) {
|
||||||
|
progress += p;
|
||||||
|
drawbar(progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
void prog10(void) {
|
||||||
|
prog(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
//#define prog10() do{}while(0)
|
||||||
|
//#define prog(x) do{}while(0)
|
||||||
|
|
||||||
|
extern s32 wbfsDev;
|
||||||
|
extern u32 wbfs_part_idx;
|
||||||
|
extern FragList *frag_list;
|
||||||
|
|
||||||
|
void _main (void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
//u64 disc_ios;
|
||||||
|
u32 bias;
|
||||||
|
u32 rtc = 0;
|
||||||
|
u32 rtc2 = 1;
|
||||||
|
u64 tbtime;
|
||||||
|
u32 tmp;
|
||||||
|
u32 vtrdcr;
|
||||||
|
u32 oldvtrdcr;
|
||||||
|
u32 vimode;
|
||||||
|
u32 vto,vte;
|
||||||
|
u64 oldvtovte;
|
||||||
|
/*
|
||||||
|
void (*app_init)(void (*report)(const char *fmt, ...));
|
||||||
|
int (*app_main)(void **dst, int *size, int *offset);
|
||||||
|
void *(*app_final)(void);
|
||||||
|
void (*app_entry)(void(**init)(void (*report)(const char *fmt, ...)), int (**main)(), void *(**final)());
|
||||||
|
*/
|
||||||
|
debug_string("WiiFlow External Booter by FIX94 - based on TinyLoad v0.2\n");
|
||||||
|
|
||||||
|
memset32(framebuffer, COLOR_BLACK, 320*574);
|
||||||
|
memset32(framebuffer + 320 * 398, COLOR_WHITE, 320*2);
|
||||||
|
memset32(framebuffer + 320 * 416, COLOR_WHITE, 320*2);
|
||||||
|
|
||||||
|
vtrdcr = oldvtrdcr = *(vu32*)(0xCC002000);
|
||||||
|
oldvtovte = *(vu64*)0xCC00200c;
|
||||||
|
vtrdcr &= 0xFFFFF;
|
||||||
|
vtrdcr |= 0x0F000000;
|
||||||
|
vimode = (vtrdcr>>8)&3;
|
||||||
|
|
||||||
|
vto = 0x30018;
|
||||||
|
vte = 0x20019;
|
||||||
|
|
||||||
|
if(vtrdcr & 4) { // progressive
|
||||||
|
vto = vte = 0x60030;
|
||||||
|
vtrdcr += 0x0F000000;
|
||||||
|
} else if(vimode == 1) {
|
||||||
|
vto = 0x10023;
|
||||||
|
vte = 0x24;
|
||||||
|
vtrdcr += 0x02F00000;
|
||||||
|
}
|
||||||
|
viw(0x0, vtrdcr);
|
||||||
|
viw(0xc, vto);
|
||||||
|
viw(0x10, vte);
|
||||||
|
|
||||||
|
viw(0x1c, (((u32)framebuffer) >> 5) | 0x10000000);
|
||||||
|
viw(0x24, (((u32)framebuffer) >> 5) | 0x10000000);
|
||||||
|
|
||||||
|
prog(0);
|
||||||
|
|
||||||
|
ipc_init();
|
||||||
|
ios_cleanup();
|
||||||
|
//reset_ios();
|
||||||
|
printversion();
|
||||||
|
|
||||||
|
bias = get_counter_bias();
|
||||||
|
while(rtc != rtc2) {
|
||||||
|
rtc2 = rtc;
|
||||||
|
rtc = read_rtc();
|
||||||
|
}
|
||||||
|
|
||||||
|
tbtime = ((u64)((u32)(rtc+bias)))*(243000000u/4);
|
||||||
|
asm volatile(
|
||||||
|
"li %0,0\n\
|
||||||
|
mttbl %0\n\
|
||||||
|
mttbu %1\n\
|
||||||
|
mttbl %2\n"
|
||||||
|
: "=&r" (tmp)
|
||||||
|
: "b" ((u32)(tbtime >> 32)), "b" ((u32)(tbtime & 0xFFFFFFFF))
|
||||||
|
);
|
||||||
|
|
||||||
|
if(es_init() < 0) {
|
||||||
|
debug_string("es_init() failed\n");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
debug_string("Initializing DI\n");
|
||||||
|
if(di_init() < 0) {
|
||||||
|
debug_string("di_init() failed\n");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
frag_list = conf->fragments;
|
||||||
|
wbfsDev = conf->wbfsDevice;
|
||||||
|
wbfs_part_idx = conf->wbfsPart;
|
||||||
|
configbytes[0] = conf->configbytes[0];
|
||||||
|
configbytes[1] = conf->configbytes[1];
|
||||||
|
if(conf->GameBootType == TYPE_WII_DISC)
|
||||||
|
{
|
||||||
|
Disc_SetUSB(NULL, 0);
|
||||||
|
if(CurrentIOS.Type == IOS_TYPE_HERMES)
|
||||||
|
Hermes_Disable_EHC();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Disc_SetUSB((u8*)conf->gameID, conf->GameBootType == TYPE_WII_WBFS_EXT);
|
||||||
|
if(CurrentIOS.Type == IOS_TYPE_HERMES)
|
||||||
|
Hermes_shadow_mload(conf->mload_rev);
|
||||||
|
}
|
||||||
|
|
||||||
|
prog10();
|
||||||
|
//di_closepartition();
|
||||||
|
if((ret = di_getcoverstatus()) != 2) {
|
||||||
|
debug_string("di_getcoverstatus() failed\n");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
debug_string("Resetting drive\n");
|
||||||
|
FAILNOTONE(di_reset(), "di_reset() failed\n");
|
||||||
|
prog10();
|
||||||
|
debug_string("Identifying disc\n");
|
||||||
|
FAILNOTONE(di_identify(), "di_identify() failed\n");
|
||||||
|
prog(40);
|
||||||
|
debug_string("Reading Disc ID\n");
|
||||||
|
FAILNOTONE(di_readdiscid(disc_id), "di_readdiscid() failed\n");
|
||||||
|
prog10();
|
||||||
|
//*(vu32*)0xcd8000c0 |= 0x100;
|
||||||
|
debug_string("Gamecode: ");
|
||||||
|
debug_uint(disc_id[0]);
|
||||||
|
debug_string("\n");
|
||||||
|
if(disc_id[6] != 0x5d1c9ea3) {
|
||||||
|
debug_string("Not a valid Wii disc!\n");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
debug_string("Reading partition table info\n");
|
||||||
|
FAILNOTONE(di_unencryptedread(&part_table_info, sizeof(part_table_info), 0x10000), "Read failed\n");
|
||||||
|
prog10();
|
||||||
|
debug_string("Reading partition table\n");
|
||||||
|
FAILNOTONE(di_unencryptedread(partition_table, sizeof(partition_table), part_table_info.offset), "Read failed\n");
|
||||||
|
prog10();
|
||||||
|
|
||||||
|
for(i=0; i<part_table_info.count; i++) {
|
||||||
|
if(partition_table[i].type == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(i >= part_table_info.count) {
|
||||||
|
debug_string("Could not find valid partition table\n");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
debug_string("Opening partition at ");
|
||||||
|
debug_uint(partition_table[i].offset);
|
||||||
|
debug_string("\n");
|
||||||
|
FAILNOTONE(di_openpartition(partition_table[i].offset, tmd), "Failed to open partition");
|
||||||
|
prog10();
|
||||||
|
|
||||||
|
debug_string("Reloading IOS...\n");
|
||||||
|
if(es_launchtitle(0x0000000100000000 | ios_getversion()) < 0) {
|
||||||
|
debug_string("Failed to launch disc IOS\n");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
debug_string("IOS reloaded!\n");
|
||||||
|
ipc_init();
|
||||||
|
debug_string("IPC reinited.\n");
|
||||||
|
printversion();
|
||||||
|
if(es_init() < 0) {
|
||||||
|
debug_string("es_init() failed\n");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
debug_string("Initializing DI\n");
|
||||||
|
if(di_init() < 0) {
|
||||||
|
debug_string("di_init() failed\n");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(conf->GameBootType == TYPE_WII_DISC)
|
||||||
|
{
|
||||||
|
Disc_SetUSB(NULL, 0);
|
||||||
|
if(CurrentIOS.Type == IOS_TYPE_HERMES)
|
||||||
|
Hermes_Disable_EHC();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Disc_SetUSB((u8*)conf->gameID, conf->GameBootType == TYPE_WII_WBFS_EXT);
|
||||||
|
if(CurrentIOS.Type == IOS_TYPE_HERMES)
|
||||||
|
Hermes_shadow_mload(conf->mload_rev);
|
||||||
|
}
|
||||||
|
prog(20);
|
||||||
|
debug_string("Reading Disc ID\n");
|
||||||
|
FAILNOTONE(di_readdiscid(disc_id), "di_readdiscid() failed\n");
|
||||||
|
prog10();
|
||||||
|
debug_string("Opening partition again\n");
|
||||||
|
FAILNOTONE(di_openpartition(partition_table[i].offset, tmd), "Failed to open partition the second time");
|
||||||
|
prog10();
|
||||||
|
debug_string("Reading partition header\n");
|
||||||
|
FAILNOTONE(di_read((void*)0x80000000, 0x20, 0), "Failed to read partition header");
|
||||||
|
prog10();
|
||||||
|
|
||||||
|
CurrentIOS = conf->IOS;
|
||||||
|
if(CurrentIOS.Type == IOS_TYPE_D2X)
|
||||||
|
{
|
||||||
|
/* IOS Reload Block */
|
||||||
|
static struct ioctlv block_vector[2] ALIGNED(32);
|
||||||
|
static u32 mode ALIGNED(64);
|
||||||
|
static u32 ios ALIGNED(64);
|
||||||
|
mode = 2;
|
||||||
|
block_vector[0].data = &mode;
|
||||||
|
block_vector[0].len = sizeof(u32);
|
||||||
|
ios = ios_getversion();
|
||||||
|
block_vector[1].data = &ios;
|
||||||
|
block_vector[1].len = sizeof(u32);
|
||||||
|
ios_ioctlv(es_fd, 0xA0, 2, 0, block_vector);
|
||||||
|
/* Return to */
|
||||||
|
if(conf->returnTo > 0)
|
||||||
|
{
|
||||||
|
debug_string("Return to d2x way, ID:"); debug_uint(conf->returnTo); debug_string("\n");
|
||||||
|
static u64 sm_title_id[1] ALIGNED(64);
|
||||||
|
static struct ioctlv rtn_vector[1] ALIGNED(64);
|
||||||
|
sm_title_id[0] = (((u64)(0x00010001) << 32) | (conf->returnTo & 0xFFFFFFFF));
|
||||||
|
rtn_vector[0].data = sm_title_id;
|
||||||
|
rtn_vector[0].len = sizeof(u64);
|
||||||
|
ios_ioctlv(es_fd, 0xA1, 1, 0, rtn_vector);
|
||||||
|
memset(&conf->returnTo, 0, sizeof(u32));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AppEntrypoint = Apploader_Run(conf->vidMode, conf->vipatch, conf->countryString,
|
||||||
|
conf->patchVidMode, conf->aspectRatio, conf->returnTo);
|
||||||
|
/*debug_string("Reading apploader header\n");
|
||||||
|
FAILNOTONE(di_read(&apploader_hdr, 0x20, 0x910), "Failed to read apploader header");
|
||||||
|
prog10();
|
||||||
|
debug_string("Reading apploader\n");
|
||||||
|
FAILNOTONE(di_read((void*)0x81200000, apploader_hdr.size+apploader_hdr.trailersize, 0x918),"Failed to read apploader ");
|
||||||
|
sync_before_exec((void*)0x81200000, apploader_hdr.size+apploader_hdr.trailersize);
|
||||||
|
prog10();
|
||||||
|
|
||||||
|
app_entry = apploader_hdr.entry;
|
||||||
|
app_entry(&app_init, &app_main, &app_final);
|
||||||
|
app_init(simple_report);
|
||||||
|
prog10();
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
void *dst;
|
||||||
|
int size;
|
||||||
|
int offset;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = app_main(&dst, &size, &offset);
|
||||||
|
if(res != 1)
|
||||||
|
break;
|
||||||
|
debug_string("Req: ");
|
||||||
|
debug_uint((u32)dst);debug_string(" ");
|
||||||
|
debug_uint((u32)size);debug_string(" ");
|
||||||
|
debug_uint((u32)offset);debug_string("\n");
|
||||||
|
if(di_read(dst, size, offset) != 1) {
|
||||||
|
debug_string("Warning: failed to read apploader request\n");
|
||||||
|
}
|
||||||
|
prog10();
|
||||||
|
}*/
|
||||||
|
debug_string("Apploader complete\n");
|
||||||
|
di_shutdown();
|
||||||
|
ios_close(es_fd);
|
||||||
|
ios_cleanup();
|
||||||
|
prog10();
|
||||||
|
|
||||||
|
//write16(0x0006, 0x0000); // DVDInit
|
||||||
|
|
||||||
|
if(((u8*)disc_id)[3] == 'P' && vimode == 0)
|
||||||
|
vimode = 1;
|
||||||
|
|
||||||
|
debug_string("VI mode: ");
|
||||||
|
debug_uint(vimode);
|
||||||
|
debug_string("\n");
|
||||||
|
|
||||||
|
*(u32*)0x800000cc = vimode;
|
||||||
|
Disc_SetLowMem();
|
||||||
|
|
||||||
|
//*(vu32*)0xCD00643C = 0x00000000; // 32Mhz on Bus
|
||||||
|
*(vu32*)0xCD006C00 = 0x00000000; // deinit audio due to libogc fail
|
||||||
|
|
||||||
|
*(u32*)0x80003180 = *(u32*)0x80000000;
|
||||||
|
|
||||||
|
sync_after_write((void*)0x80000000, 0x3f00);
|
||||||
|
|
||||||
|
progress = 310;
|
||||||
|
prog10();
|
||||||
|
udelay(60000);
|
||||||
|
|
||||||
|
u8 hooktype = 0;
|
||||||
|
//AppEntrypoint = (u32)app_final();
|
||||||
|
debug_string("Game entry: ");
|
||||||
|
debug_uint(AppEntrypoint);
|
||||||
|
debug_string("\n");
|
||||||
|
|
||||||
|
debug_string("ok, taking the plunge\n");
|
||||||
|
|
||||||
|
/* this sets VI to black, but I can't fit it in yet... */
|
||||||
|
viw(0x0, oldvtrdcr);
|
||||||
|
*(vu64*)(0xCC00200c) = oldvtovte;
|
||||||
|
|
||||||
|
/* 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"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,14 +18,11 @@
|
|||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include "utils.h"
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <gccore.h>
|
|
||||||
#include <sys/unistd.h>
|
|
||||||
|
|
||||||
#include "apploader.h"
|
#include "apploader.h"
|
||||||
#include "patchcode.h"
|
#include "patchcode.h"
|
||||||
|
#include "cache.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
u32 hooktype;
|
u32 hooktype;
|
||||||
u8 configbytes[2];
|
u8 configbytes[2];
|
||||||
@ -100,7 +97,7 @@ const u32 langpatch[3] = {0x7C600775, 0x40820010, 0x38000000};
|
|||||||
static const u32 oldpatch002[3] = {0x2C000000, 0x40820214, 0x3C608000};
|
static const u32 oldpatch002[3] = {0x2C000000, 0x40820214, 0x3C608000};
|
||||||
static const u32 newpatch002[3] = {0x2C000000, 0x48000214, 0x3C608000};
|
static const u32 newpatch002[3] = {0x2C000000, 0x48000214, 0x3C608000};
|
||||||
|
|
||||||
bool dogamehooks(void *addr, u32 len, bool channel)
|
u8 dogamehooks(void *addr, u32 len, u8 channel)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
0 No Hook
|
0 No Hook
|
||||||
@ -115,21 +112,21 @@ bool dogamehooks(void *addr, u32 len, bool channel)
|
|||||||
|
|
||||||
void *addr_start = addr;
|
void *addr_start = addr;
|
||||||
void *addr_end = addr+len;
|
void *addr_end = addr+len;
|
||||||
bool hookpatched = false;
|
u8 hookpatched = 0;
|
||||||
|
|
||||||
while(addr_start < addr_end)
|
while(addr_start < addr_end)
|
||||||
{
|
{
|
||||||
switch(hooktype)
|
switch(hooktype)
|
||||||
{
|
{
|
||||||
case 0x00:
|
case 0x00:
|
||||||
hookpatched = true;
|
hookpatched = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x01:
|
case 0x01:
|
||||||
if(memcmp(addr_start, viwiihooks, sizeof(viwiihooks))==0)
|
if(memcmp(addr_start, viwiihooks, sizeof(viwiihooks))==0)
|
||||||
{
|
{
|
||||||
patchhook((u32)addr_start, len);
|
patchhook((u32)addr_start, len);
|
||||||
hookpatched = true;
|
hookpatched = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -137,13 +134,13 @@ bool dogamehooks(void *addr, u32 len, bool channel)
|
|||||||
if(memcmp(addr_start, kpadhooks, sizeof(kpadhooks))==0)
|
if(memcmp(addr_start, kpadhooks, sizeof(kpadhooks))==0)
|
||||||
{
|
{
|
||||||
patchhook((u32)addr_start, len);
|
patchhook((u32)addr_start, len);
|
||||||
hookpatched = true;
|
hookpatched = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(memcmp(addr_start, kpadoldhooks, sizeof(kpadoldhooks))==0)
|
if(memcmp(addr_start, kpadoldhooks, sizeof(kpadoldhooks))==0)
|
||||||
{
|
{
|
||||||
patchhook((u32)addr_start, len);
|
patchhook((u32)addr_start, len);
|
||||||
hookpatched = true;
|
hookpatched = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -151,7 +148,7 @@ bool dogamehooks(void *addr, u32 len, bool channel)
|
|||||||
if(memcmp(addr_start, joypadhooks, sizeof(joypadhooks))==0)
|
if(memcmp(addr_start, joypadhooks, sizeof(joypadhooks))==0)
|
||||||
{
|
{
|
||||||
patchhook((u32)addr_start, len);
|
patchhook((u32)addr_start, len);
|
||||||
hookpatched = true;
|
hookpatched = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -159,7 +156,7 @@ bool dogamehooks(void *addr, u32 len, bool channel)
|
|||||||
if(memcmp(addr_start, gxdrawhooks, sizeof(gxdrawhooks))==0)
|
if(memcmp(addr_start, gxdrawhooks, sizeof(gxdrawhooks))==0)
|
||||||
{
|
{
|
||||||
patchhook((u32)addr_start, len);
|
patchhook((u32)addr_start, len);
|
||||||
hookpatched = true;
|
hookpatched = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -167,7 +164,7 @@ bool dogamehooks(void *addr, u32 len, bool channel)
|
|||||||
if(memcmp(addr_start, gxflushhooks, sizeof(gxflushhooks))==0)
|
if(memcmp(addr_start, gxflushhooks, sizeof(gxflushhooks))==0)
|
||||||
{
|
{
|
||||||
patchhook((u32)addr_start, len);
|
patchhook((u32)addr_start, len);
|
||||||
hookpatched = true;
|
hookpatched = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -175,7 +172,7 @@ bool dogamehooks(void *addr, u32 len, bool channel)
|
|||||||
if(memcmp(addr_start, ossleepthreadhooks, sizeof(ossleepthreadhooks))==0)
|
if(memcmp(addr_start, ossleepthreadhooks, sizeof(ossleepthreadhooks))==0)
|
||||||
{
|
{
|
||||||
patchhook((u32)addr_start, len);
|
patchhook((u32)addr_start, len);
|
||||||
hookpatched = true;
|
hookpatched = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -183,7 +180,7 @@ bool dogamehooks(void *addr, u32 len, bool channel)
|
|||||||
if(memcmp(addr_start, axnextframehooks, sizeof(axnextframehooks))==0)
|
if(memcmp(addr_start, axnextframehooks, sizeof(axnextframehooks))==0)
|
||||||
{
|
{
|
||||||
patchhook((u32)addr_start, len);
|
patchhook((u32)addr_start, len);
|
||||||
hookpatched = true;
|
hookpatched = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -191,7 +188,7 @@ bool dogamehooks(void *addr, u32 len, bool channel)
|
|||||||
/* if(memcmp(addr_start, customhook, customhooksize)==0)
|
/* if(memcmp(addr_start, customhook, customhooksize)==0)
|
||||||
{
|
{
|
||||||
patchhook((u32)addr_start, len);
|
patchhook((u32)addr_start, len);
|
||||||
hookpatched = true;
|
hookpatched = 1;
|
||||||
} */
|
} */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -200,15 +197,15 @@ bool dogamehooks(void *addr, u32 len, bool channel)
|
|||||||
if(channel && memcmp(addr_start, multidolchanhooks, sizeof(multidolchanhooks))==0)
|
if(channel && memcmp(addr_start, multidolchanhooks, sizeof(multidolchanhooks))==0)
|
||||||
{
|
{
|
||||||
*(((u32*)addr_start)+1) = 0x7FE802A6;
|
*(((u32*)addr_start)+1) = 0x7FE802A6;
|
||||||
DCFlushRange(((u32*)addr_start)+1, 4);
|
sync_after_write(((u32*)addr_start)+1, 4);
|
||||||
|
|
||||||
multidolhook((u32)addr_start+sizeof(multidolchanhooks)-4);
|
multidolhook((u32)addr_start+sizeof(multidolchanhooks)-4);
|
||||||
hookpatched = true;
|
hookpatched = 1;
|
||||||
}
|
}
|
||||||
else if(!channel && memcmp(addr_start, multidolhooks, sizeof(multidolhooks))==0)
|
else if(!channel && memcmp(addr_start, multidolhooks, sizeof(multidolhooks))==0)
|
||||||
{
|
{
|
||||||
multidolhook((u32)addr_start+sizeof(multidolhooks)-4);
|
multidolhook((u32)addr_start+sizeof(multidolhooks)-4);
|
||||||
hookpatched = true;
|
hookpatched = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addr_start += 4;
|
addr_start += 4;
|
||||||
@ -254,11 +251,12 @@ static u32 ad[ 4 ] = { 0, 0, 0, 0 };//these variables are global on the off chan
|
|||||||
static u8 found = 0; //to find in the dol are found in different sections of the dol
|
static u8 found = 0; //to find in the dol are found in different sections of the dol
|
||||||
static u8 returnToPatched = 0;
|
static u8 returnToPatched = 0;
|
||||||
|
|
||||||
bool PatchReturnTo( void *Address, int Size, u32 id )
|
u8 PatchReturnTo( void *Address, int Size, u32 id )
|
||||||
{
|
{
|
||||||
if( !id || returnToPatched )
|
if(returnToPatched == 1)
|
||||||
return 0;
|
return 0;
|
||||||
//gprintf("PatchReturnTo( %p, %08x, %08x )\n", Address, Size, id );
|
//gprintf("PatchReturnTo( %p, %08x, %08x )\n", Address, Size, id );
|
||||||
|
//debug_string("PatchReturnTo ID:"); debug_uint(id); debug_string("\n");
|
||||||
|
|
||||||
//new __OSLoadMenu() (SM2.0 and higher)
|
//new __OSLoadMenu() (SM2.0 and higher)
|
||||||
u8 SearchPattern[ 12 ] = { 0x38, 0x80, 0x00, 0x02, 0x38, 0x60, 0x00, 0x01, 0x38, 0xa0, 0x00, 0x00 }; //li r4,2
|
u8 SearchPattern[ 12 ] = { 0x38, 0x80, 0x00, 0x02, 0x38, 0x60, 0x00, 0x01, 0x38, 0xa0, 0x00, 0x00 }; //li r4,2
|
||||||
@ -358,6 +356,7 @@ bool PatchReturnTo( void *Address, int Size, u32 id )
|
|||||||
addr = (u32*)ad[ 0 ];
|
addr = (u32*)ad[ 0 ];
|
||||||
memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ]
|
memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ]
|
||||||
memcpy( addr + 4, &nop, sizeof( u32 ) ); //nop
|
memcpy( addr + 4, &nop, sizeof( u32 ) ); //nop
|
||||||
|
debug_uint((u32)addr); debug_string(" -> "); debug_uint(newval); debug_string("\n");
|
||||||
//gprintf("\t%08x -> %08x\n", addr, newval );
|
//gprintf("\t%08x -> %08x\n", addr, newval );
|
||||||
|
|
||||||
//ES_GetTicketViews() again
|
//ES_GetTicketViews() again
|
||||||
@ -367,6 +366,7 @@ bool PatchReturnTo( void *Address, int Size, u32 id )
|
|||||||
addr = (u32*)ad[ 1 ];
|
addr = (u32*)ad[ 1 ];
|
||||||
memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ]
|
memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ]
|
||||||
memcpy( addr + 4, &nop, sizeof( u32 ) ); //nop
|
memcpy( addr + 4, &nop, sizeof( u32 ) ); //nop
|
||||||
|
debug_uint((u32)addr); debug_string(" -> "); debug_uint(newval); debug_string("\n");
|
||||||
//gprintf("\t%08x -> %08x\n", addr, newval );
|
//gprintf("\t%08x -> %08x\n", addr, newval );
|
||||||
|
|
||||||
//ES_LaunchTitle()
|
//ES_LaunchTitle()
|
||||||
@ -376,6 +376,7 @@ bool PatchReturnTo( void *Address, int Size, u32 id )
|
|||||||
addr = (u32*)ad[ 2 ];
|
addr = (u32*)ad[ 2 ];
|
||||||
memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ]
|
memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ]
|
||||||
memcpy( addr + 4, &nop, sizeof( u32 ) ); //nop
|
memcpy( addr + 4, &nop, sizeof( u32 ) ); //nop
|
||||||
|
debug_uint((u32)addr); debug_string(" -> "); debug_uint(newval); debug_string("\n");
|
||||||
//gprintf("\t%08x -> %08x\n", addr, newval );
|
//gprintf("\t%08x -> %08x\n", addr, newval );
|
||||||
|
|
||||||
returnToPatched = 1;
|
returnToPatched = 1;
|
||||||
@ -413,7 +414,7 @@ void PatchAspectRatio(void *addr, u32 len, u8 aspect)
|
|||||||
addr_start += 4;
|
addr_start += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
void PatchCountryStrings(void *Address, int Size)
|
void PatchCountryStrings(void *Address, int Size)
|
||||||
{
|
{
|
||||||
u8 SearchPattern[4] = {0x00, 0x00, 0x00, 0x00};
|
u8 SearchPattern[4] = {0x00, 0x00, 0x00, 0x00};
|
||||||
@ -490,3 +491,4 @@ void PatchCountryStrings(void *Address, int Size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
@ -30,12 +30,12 @@ extern u32 hooktype;
|
|||||||
extern u8 configbytes[2];
|
extern u8 configbytes[2];
|
||||||
|
|
||||||
// Function prototypes
|
// Function prototypes
|
||||||
bool dogamehooks(void *addr, u32 len, bool channel);
|
u8 dogamehooks(void *addr, u32 len, u8 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);
|
||||||
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);
|
u8 PatchReturnTo(void *Address, int Size, u32 id);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
@ -1,170 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2010
|
|
||||||
* by dude
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
*
|
|
||||||
* Channel Launcher Class
|
|
||||||
*
|
|
||||||
* for WiiXplorer 2010
|
|
||||||
***************************************************************************/
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ogcsys.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
|
|
||||||
#include "ChannelHandler.hpp"
|
|
||||||
#include "patchcode.h"
|
|
||||||
#include "cios.h"
|
|
||||||
#include "fs.h"
|
|
||||||
#include "fst.h"
|
|
||||||
#include "lz77.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include "videopatch.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
void *dolchunkoffset[18];
|
|
||||||
u32 dolchunksize[18];
|
|
||||||
u32 dolchunkcount;
|
|
||||||
u32 bootcontent;
|
|
||||||
|
|
||||||
char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
|
|
||||||
|
|
||||||
static u8 *GetDol(u32 bootcontent, u64 title)
|
|
||||||
{
|
|
||||||
memset(filepath, 0, ISFS_MAXPATH);
|
|
||||||
sprintf(filepath, "/title/%08x/%08x/content/%08x.app", TITLE_UPPER(title), TITLE_LOWER(title), bootcontent);
|
|
||||||
|
|
||||||
u32 contentSize = 0;
|
|
||||||
|
|
||||||
u8 *data = ISFS_GetFile((u8 *) &filepath, &contentSize, -1);
|
|
||||||
if(data != NULL && contentSize != 0)
|
|
||||||
{
|
|
||||||
if(isLZ77compressed(data))
|
|
||||||
{
|
|
||||||
u8 *decompressed;
|
|
||||||
u32 size = 0;
|
|
||||||
if(decompressLZ77content(data, contentSize, &decompressed, &size) < 0)
|
|
||||||
{
|
|
||||||
free(data);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
free(data);
|
|
||||||
data = decompressed;
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool GetAppNameFromTmd(bool dol, u32 *bootcontent, u64 title)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
memset(filepath, 0, ISFS_MAXPATH);
|
|
||||||
sprintf(filepath, "/title/%08x/%08x/content/title.tmd", TITLE_UPPER(title), TITLE_LOWER(title));
|
|
||||||
|
|
||||||
u32 size;
|
|
||||||
u8 *data = ISFS_GetFile((u8 *) &filepath, &size, -1);
|
|
||||||
if(data == NULL || size < 0x208)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
_tmd *tmd_file = (_tmd *)SIGNATURE_PAYLOAD((u32 *)data);
|
|
||||||
for(u16 i = 0; i < tmd_file->num_contents; ++i)
|
|
||||||
{
|
|
||||||
if(tmd_file->contents[i].index == (dol ? tmd_file->boot_index : 0))
|
|
||||||
{
|
|
||||||
*bootcontent = tmd_file->contents[i].cid;
|
|
||||||
ret = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(data);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 MoveDol(u8 *buffer)
|
|
||||||
{
|
|
||||||
dolchunkcount = 0;
|
|
||||||
dolheader *dolfile = (dolheader *)buffer;
|
|
||||||
|
|
||||||
if(dolfile->bss_start)
|
|
||||||
{
|
|
||||||
if(!(dolfile->bss_start & 0x80000000))
|
|
||||||
dolfile->bss_start |= 0x80000000;
|
|
||||||
|
|
||||||
memset((void *)dolfile->bss_start, 0, dolfile->bss_size);
|
|
||||||
DCFlushRange((void *)dolfile->bss_start, dolfile->bss_size);
|
|
||||||
ICInvalidateRange((void *)dolfile->bss_start, dolfile->bss_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(u8 i = 0; i < 18; i++)
|
|
||||||
{
|
|
||||||
if(!dolfile->section_size[i])
|
|
||||||
continue;
|
|
||||||
if(dolfile->section_pos[i] < sizeof(dolheader))
|
|
||||||
continue;
|
|
||||||
if(!(dolfile->section_start[i] & 0x80000000))
|
|
||||||
dolfile->section_start[i] |= 0x80000000;
|
|
||||||
|
|
||||||
dolchunkoffset[dolchunkcount] = (void *)dolfile->section_start[i];
|
|
||||||
dolchunksize[dolchunkcount] = dolfile->section_size[i];
|
|
||||||
|
|
||||||
memmove(dolchunkoffset[dolchunkcount], buffer + dolfile->section_pos[i], dolchunksize[dolchunkcount]);
|
|
||||||
dolchunkcount++;
|
|
||||||
}
|
|
||||||
return dolfile->entry_point;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 LoadChannel(u64 title)
|
|
||||||
{
|
|
||||||
u32 entry = 0;
|
|
||||||
|
|
||||||
GetAppNameFromTmd(true, &bootcontent, title);
|
|
||||||
u8 *data = GetDol(bootcontent, title);
|
|
||||||
entry = MoveDol(data);
|
|
||||||
free(data);
|
|
||||||
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u64 title)
|
|
||||||
{
|
|
||||||
bool hook = false;
|
|
||||||
for(u8 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 && dogamehooks(dolchunkoffset[i], dolchunksize[i], true))
|
|
||||||
hook = true;
|
|
||||||
DCFlushRange(dolchunkoffset[i], dolchunksize[i]);
|
|
||||||
ICInvalidateRange(dolchunkoffset[i], dolchunksize[i]);
|
|
||||||
}
|
|
||||||
if(hook)
|
|
||||||
ocarina_do_code(title);
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
|
|
||||||
#ifndef __CHANHANDLE_HPP_
|
|
||||||
#define __CHANHANDLE_HPP_
|
|
||||||
|
|
||||||
typedef struct _dolheader
|
|
||||||
{
|
|
||||||
u32 section_pos[18];
|
|
||||||
u32 section_start[18];
|
|
||||||
u32 section_size[18];
|
|
||||||
u32 bss_start;
|
|
||||||
u32 bss_size;
|
|
||||||
u32 entry_point;
|
|
||||||
u32 padding[7];
|
|
||||||
} __attribute__((packed)) dolheader;
|
|
||||||
|
|
||||||
void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString,
|
|
||||||
u8 patchVidModes, int aspectRatio, u64 title);
|
|
||||||
u32 LoadChannel(u64 title);
|
|
||||||
|
|
||||||
#endif /* __CHANHANDLE_HPP_ */
|
|
@ -1,18 +0,0 @@
|
|||||||
#ifndef _APPLOADER_H_
|
|
||||||
#define _APPLOADER_H_
|
|
||||||
|
|
||||||
/* Entry point */
|
|
||||||
typedef void (*entry_point)(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
/* Prototypes */
|
|
||||||
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
|
|
@ -1,265 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ogcsys.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <ogc/lwp_watchdog.h>
|
|
||||||
|
|
||||||
#include "frag.h"
|
|
||||||
#include "memory.h"
|
|
||||||
#include "cios.h"
|
|
||||||
#include "types.h"
|
|
||||||
#include "wdvd.h"
|
|
||||||
|
|
||||||
/* Constants */
|
|
||||||
#define PTABLE_OFFSET 0x40000
|
|
||||||
|
|
||||||
static u8 *diskid = (u8*)0x80000000;
|
|
||||||
|
|
||||||
s32 Disc_Open()
|
|
||||||
{
|
|
||||||
/* Reset drive */
|
|
||||||
s32 ret = WDVD_Reset();
|
|
||||||
if (ret < 0) return ret;
|
|
||||||
|
|
||||||
memset(diskid, 0, 32);
|
|
||||||
|
|
||||||
/* Read disc ID */
|
|
||||||
ret = WDVD_ReadDiskId(diskid);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 wbfsDev = 0;
|
|
||||||
u32 wbfs_part_idx = 0;
|
|
||||||
FragList *frag_list = NULL;
|
|
||||||
static int set_frag_list()
|
|
||||||
{
|
|
||||||
// (+1 for header which is same size as fragment)
|
|
||||||
int size = sizeof(Fragment) * (frag_list->num + 1);
|
|
||||||
DCFlushRange(frag_list, size);
|
|
||||||
return WDVD_SetFragList(wbfsDev, frag_list, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 Disc_SetUSB(const u8 *id, bool frag)
|
|
||||||
{
|
|
||||||
/* ENABLE USB in cIOS */
|
|
||||||
if(id)
|
|
||||||
{
|
|
||||||
if(frag)
|
|
||||||
return set_frag_list();
|
|
||||||
s32 part = -1;
|
|
||||||
if(CurrentIOS.Type == IOS_TYPE_HERMES)
|
|
||||||
part = wbfs_part_idx ? wbfs_part_idx - 1 : 0;
|
|
||||||
return WDVD_SetUSBMode(wbfsDev, (u8*)id, part);
|
|
||||||
}
|
|
||||||
/* DISABLE USB in cIOS */
|
|
||||||
return WDVD_SetUSBMode(0, NULL, -1);
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
|
|
||||||
#include <ogcsys.h>
|
|
||||||
#include <locale.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <ogc/isfs.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "fs.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
static fstats stats ATTRIBUTE_ALIGN(32);
|
|
||||||
|
|
||||||
u8 *ISFS_GetFile(u8 *path, u32 *size, s32 length)
|
|
||||||
{
|
|
||||||
*size = 0;
|
|
||||||
|
|
||||||
s32 fd = ISFS_Open((const char *)path, ISFS_OPEN_READ);
|
|
||||||
u8 *buf = NULL;
|
|
||||||
|
|
||||||
if(fd >= 0)
|
|
||||||
{
|
|
||||||
memset(&stats, 0, sizeof(fstats));
|
|
||||||
if(ISFS_GetFileStats(fd, &stats) >= 0)
|
|
||||||
{
|
|
||||||
if(length <= 0)
|
|
||||||
length = stats.file_length;
|
|
||||||
if(length > 0)
|
|
||||||
buf = (u8 *)memalign(32, ALIGN32(length));
|
|
||||||
if(buf)
|
|
||||||
{
|
|
||||||
*size = stats.file_length;
|
|
||||||
if(ISFS_Read(fd, (char*)buf, length) != length)
|
|
||||||
{
|
|
||||||
*size = 0;
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ISFS_Close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(*size > 0)
|
|
||||||
{
|
|
||||||
DCFlushRange(buf, *size);
|
|
||||||
ICInvalidateRange(buf, *size);
|
|
||||||
}
|
|
||||||
return buf;
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
#ifndef _FS_H_
|
|
||||||
#define _FS_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
u8 *ISFS_GetFile(u8 *path, u32 *size, s32 length);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
|||||||
#include <gccore.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/iosupport.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include "gecko.h"
|
|
||||||
|
|
||||||
/* init-globals */
|
|
||||||
bool geckoinit = false;
|
|
||||||
static ssize_t __out_write(struct _reent *r __attribute__((unused)), int fd __attribute__((unused)), const char *ptr, size_t len)
|
|
||||||
{
|
|
||||||
if(geckoinit && ptr)
|
|
||||||
{
|
|
||||||
u32 level;
|
|
||||||
level = IRQ_Disable();
|
|
||||||
usb_sendbuffer_safe(1, ptr, len);
|
|
||||||
IRQ_Restore(level);
|
|
||||||
}
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
char gprintfBuffer[256];
|
|
||||||
void gprintf(const char *format, ...)
|
|
||||||
{
|
|
||||||
va_list va;
|
|
||||||
va_start(va, format);
|
|
||||||
int len = vsnprintf(gprintfBuffer, 255, format, va);
|
|
||||||
__out_write(NULL, 0, gprintfBuffer, len);
|
|
||||||
va_end(va);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InitGecko()
|
|
||||||
{
|
|
||||||
if(geckoinit)
|
|
||||||
return geckoinit;
|
|
||||||
|
|
||||||
u32 geckoattached = usb_isgeckoalive(EXI_CHANNEL_1);
|
|
||||||
if(geckoattached)
|
|
||||||
{
|
|
||||||
geckoinit = true;
|
|
||||||
usb_flush(EXI_CHANNEL_1);
|
|
||||||
}
|
|
||||||
return geckoinit;
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
|
|
||||||
#ifndef _GECKO_H_
|
|
||||||
#define _GECKO_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <gccore.h>
|
|
||||||
|
|
||||||
extern bool bufferMessages;
|
|
||||||
extern bool WriteToSD;
|
|
||||||
|
|
||||||
//use this just like printf();
|
|
||||||
void gprintf(const char *format, ...);
|
|
||||||
void ghexdump(void *d, int len);
|
|
||||||
bool InitGecko();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,215 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* lz77.c
|
|
||||||
*
|
|
||||||
* Copyright (c) 2009 The Lemon Man
|
|
||||||
* Copyright (c) 2009 Nicksasa
|
|
||||||
* Copyright (c) 2009 WiiPower
|
|
||||||
*
|
|
||||||
* Distributed under the terms of the GNU General Public License (v2)
|
|
||||||
* See http://www.gnu.org/licenses/gpl-2.0.txt for more info.
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* -----------
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
#include <gccore.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
|
|
||||||
#include "lz77.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
u32 packBytes(int a, int b, int c, int d)
|
|
||||||
{
|
|
||||||
return (d << 24) | (c << 16) | (b << 8) | (a);
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 __decompressLZ77_11(u8 *in, u32 inputLen, u8 **output, u32 *outputLen)
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
u8 *out = NULL;
|
|
||||||
|
|
||||||
u32 compressedPos = 0x4;
|
|
||||||
u32 decompressedPos = 0x0;
|
|
||||||
u32 decompressedSize = 0;
|
|
||||||
|
|
||||||
decompressedSize = packBytes(in[0], in[1], in[2], in[3]) >> 8;
|
|
||||||
|
|
||||||
if (!decompressedSize)
|
|
||||||
{
|
|
||||||
decompressedSize = packBytes(in[4], in[5], in[6], in[7]);
|
|
||||||
compressedPos += 0x4;
|
|
||||||
}
|
|
||||||
|
|
||||||
//printf("Decompressed size : %i\n", decompressedSize);
|
|
||||||
|
|
||||||
out = malloc(ALIGN32(decompressedSize));
|
|
||||||
if (out == NULL)
|
|
||||||
{
|
|
||||||
printf("Out of memory\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (compressedPos < inputLen && decompressedPos < decompressedSize)
|
|
||||||
{
|
|
||||||
u8 byteFlag = in[compressedPos];
|
|
||||||
compressedPos++;
|
|
||||||
|
|
||||||
for (x = 7; x >= 0; x--)
|
|
||||||
{
|
|
||||||
if ((byteFlag & (1 << x)) > 0)
|
|
||||||
{
|
|
||||||
u8 first = in[compressedPos];
|
|
||||||
u8 second = in[compressedPos + 1];
|
|
||||||
|
|
||||||
u32 pos, copyLen;
|
|
||||||
|
|
||||||
if (first < 0x20)
|
|
||||||
{
|
|
||||||
u8 third = in[compressedPos + 2];
|
|
||||||
|
|
||||||
if (first >= 0x10)
|
|
||||||
{
|
|
||||||
u32 fourth = in[compressedPos + 3];
|
|
||||||
|
|
||||||
pos = (u32)(((third & 0xF) << 8) | fourth) + 1;
|
|
||||||
copyLen = (u32)((second << 4) | ((first & 0xF) << 12) | (third >> 4)) + 273;
|
|
||||||
|
|
||||||
compressedPos += 4;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
pos = (u32)(((second & 0xF) << 8) | third) + 1;
|
|
||||||
copyLen = (u32)(((first & 0xF) << 4) | (second >> 4)) + 17;
|
|
||||||
|
|
||||||
compressedPos += 3;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
pos = (u32)(((first & 0xF) << 8) | second) + 1;
|
|
||||||
copyLen = (u32)(first >> 4) + 1;
|
|
||||||
|
|
||||||
compressedPos += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (y = 0; y < (int)copyLen; y++)
|
|
||||||
{
|
|
||||||
out[decompressedPos + y] = out[decompressedPos - pos + y];
|
|
||||||
}
|
|
||||||
|
|
||||||
decompressedPos += copyLen;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
out[decompressedPos] = in[compressedPos];
|
|
||||||
|
|
||||||
decompressedPos++;
|
|
||||||
compressedPos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (compressedPos >= inputLen || decompressedPos >= decompressedSize)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*output = out;
|
|
||||||
*outputLen = decompressedSize;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 __decompressLZ77_10(u8 *in, u8 **output, u32 *outputLen)
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
u8 *out = NULL;
|
|
||||||
|
|
||||||
u32 compressedPos = 0;
|
|
||||||
u32 decompressedSize = 0x4;
|
|
||||||
u32 decompressedPos = 0;
|
|
||||||
|
|
||||||
decompressedSize = packBytes(in[0], in[1], in[2], in[3]) >> 8;
|
|
||||||
|
|
||||||
//int compressionType = (packBytes(in[0], in[1], in[2], in[3]) >> 4) & 0xF;
|
|
||||||
|
|
||||||
//printf("Decompressed size : %i\n", decompressedSize);
|
|
||||||
|
|
||||||
out = malloc(ALIGN32(decompressedSize));
|
|
||||||
if (out == NULL)
|
|
||||||
{
|
|
||||||
printf("Out of memory\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
compressedPos += 0x4;
|
|
||||||
|
|
||||||
while (decompressedPos < decompressedSize)
|
|
||||||
{
|
|
||||||
u8 flag = *(u8*)(in + compressedPos);
|
|
||||||
compressedPos += 1;
|
|
||||||
|
|
||||||
for (x = 0; x < 8; x++)
|
|
||||||
{
|
|
||||||
if (flag & 0x80)
|
|
||||||
{
|
|
||||||
u8 first = in[compressedPos];
|
|
||||||
u8 second = in[compressedPos + 1];
|
|
||||||
|
|
||||||
u16 pos = (u16)((((first << 8) + second) & 0xFFF) + 1);
|
|
||||||
u8 copyLen = (u8)(3 + ((first >> 4) & 0xF));
|
|
||||||
|
|
||||||
for (y = 0; y < copyLen; y++)
|
|
||||||
{
|
|
||||||
out[decompressedPos + y] = out[decompressedPos - pos + (y % pos)];
|
|
||||||
}
|
|
||||||
|
|
||||||
compressedPos += 2;
|
|
||||||
decompressedPos += copyLen;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
out[decompressedPos] = in[compressedPos];
|
|
||||||
compressedPos += 1;
|
|
||||||
decompressedPos += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
flag <<= 1;
|
|
||||||
|
|
||||||
if (decompressedPos >= decompressedSize)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*output = out;
|
|
||||||
*outputLen = decompressedSize;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int isLZ77compressed(u8 *buffer)
|
|
||||||
{
|
|
||||||
if ((buffer[0] == LZ77_0x10_FLAG) || (buffer[0] == LZ77_0x11_FLAG))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int decompressLZ77content(u8 *buffer, u32 length, u8 **output, u32 *outputLen)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
switch (buffer[0])
|
|
||||||
{
|
|
||||||
case LZ77_0x10_FLAG:
|
|
||||||
//printf("LZ77 variant 0x10 compressed content...unpacking may take a while...\n");
|
|
||||||
ret = __decompressLZ77_10(buffer, output, outputLen);
|
|
||||||
break;
|
|
||||||
case LZ77_0x11_FLAG:
|
|
||||||
//printf("LZ77 variant 0x11 compressed content...unpacking may take a while...\n");
|
|
||||||
ret = __decompressLZ77_11(buffer, length, output, outputLen);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
//printf("Not compressed ...\n");
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* lz77.h
|
|
||||||
*
|
|
||||||
* Copyright (c) 2009 The Lemon Man
|
|
||||||
* Copyright (c) 2009 Nicksasa
|
|
||||||
* Copyright (c) 2009 WiiPower
|
|
||||||
*
|
|
||||||
* Distributed under the terms of the GNU General Public License (v2)
|
|
||||||
* See http://www.gnu.org/licenses/gpl-2.0.txt for more info.
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* -----------
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _LZ77_MODULE
|
|
||||||
#define _LZ77_MODULE
|
|
||||||
|
|
||||||
#define LZ77_0x10_FLAG 0x10
|
|
||||||
#define LZ77_0x11_FLAG 0x11
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
int isLZ77compressed(u8 *buffer);
|
|
||||||
int decompressLZ77content(u8 *buffer, u32 length, u8 **output, u32 *outputLen);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,194 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 "Config.hpp"
|
|
||||||
#include "ChannelHandler.hpp"
|
|
||||||
|
|
||||||
#include "apploader.h"
|
|
||||||
#include "patchcode.h"
|
|
||||||
#include "disc.h"
|
|
||||||
#include "fst.h"
|
|
||||||
#include "wdvd.h"
|
|
||||||
#include "gecko.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
IOS_Info CurrentIOS;
|
|
||||||
|
|
||||||
/* Boot Variables */
|
|
||||||
u32 vmode_reg = 0;
|
|
||||||
entry_point p_entry;
|
|
||||||
GXRModeObj *vmode = NULL;
|
|
||||||
|
|
||||||
u32 AppEntrypoint;
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
extern void __exception_closeall();
|
|
||||||
extern s32 wbfsDev;
|
|
||||||
extern u32 wbfs_part_idx;
|
|
||||||
extern FragList *frag_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
the_CFG normalCFG;
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
if(!argc)
|
|
||||||
return 0;
|
|
||||||
memcpy(&normalCFG, (void*)strtoul(argv[0], NULL, 16), sizeof(the_CFG));
|
|
||||||
|
|
||||||
VIDEO_Init();
|
|
||||||
InitGecko();
|
|
||||||
gprintf("WiiFlow External Booter by FIX94\n");
|
|
||||||
|
|
||||||
configbytes[0] = normalCFG.configbytes[0];
|
|
||||||
configbytes[1] = normalCFG.configbytes[1];
|
|
||||||
hooktype = normalCFG.hooktype;
|
|
||||||
debuggerselect = normalCFG.debugger;
|
|
||||||
CurrentIOS = normalCFG.IOS;
|
|
||||||
app_gameconfig_set(normalCFG.gameconf, normalCFG.gameconfsize);
|
|
||||||
ocarina_set_codes(normalCFG.codelist, normalCFG.codelistend, normalCFG.cheats, normalCFG.cheatSize);
|
|
||||||
frag_list = normalCFG.fragments;
|
|
||||||
wbfsDev = normalCFG.wbfsDevice;
|
|
||||||
wbfs_part_idx = normalCFG.wbfsPart;
|
|
||||||
|
|
||||||
if(normalCFG.BootType == TYPE_WII_GAME)
|
|
||||||
{
|
|
||||||
WDVD_Init();
|
|
||||||
if(normalCFG.GameBootType == TYPE_WII_DISC)
|
|
||||||
{
|
|
||||||
Disc_SetUSB(NULL, false);
|
|
||||||
if(CurrentIOS.Type == IOS_TYPE_HERMES)
|
|
||||||
Hermes_Disable_EHC();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Disc_SetUSB((u8*)normalCFG.gameID, normalCFG.GameBootType == TYPE_WII_WBFS_EXT);
|
|
||||||
if(CurrentIOS.Type == IOS_TYPE_HERMES)
|
|
||||||
Hermes_shadow_mload(normalCFG.mload_rev);
|
|
||||||
}
|
|
||||||
Disc_Open();
|
|
||||||
Disc_SetLowMem();
|
|
||||||
u64 offset = 0;
|
|
||||||
Disc_FindPartition(&offset);
|
|
||||||
WDVD_OpenPartition(offset);
|
|
||||||
vmode = Disc_SelectVMode(normalCFG.vidMode, &vmode_reg);
|
|
||||||
Apploader_Run(&p_entry, normalCFG.vidMode, vmode, normalCFG.vipatch, normalCFG.countryString, normalCFG.patchVidMode,
|
|
||||||
normalCFG.aspectRatio, normalCFG.returnTo);
|
|
||||||
AppEntrypoint = (u32)p_entry;
|
|
||||||
WDVD_Close();
|
|
||||||
}
|
|
||||||
else if(normalCFG.BootType == TYPE_CHANNEL)
|
|
||||||
{
|
|
||||||
ISFS_Initialize();
|
|
||||||
Disc_SetLowMem();
|
|
||||||
AppEntrypoint = LoadChannel(normalCFG.title);
|
|
||||||
vmode = Disc_SelectVMode(normalCFG.vidMode, &vmode_reg);
|
|
||||||
PatchChannel(normalCFG.vidMode, vmode, normalCFG.vipatch, normalCFG.countryString,
|
|
||||||
normalCFG.patchVidMode, normalCFG.aspectRatio, normalCFG.title);
|
|
||||||
ISFS_Deinitialize();
|
|
||||||
}
|
|
||||||
gprintf("Entrypoint: %08x\n", AppEntrypoint);
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
|
|
||||||
#ifndef _TYPES_H_
|
|
||||||
#define _TYPES_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
TYPE_WII_DISC = 0,
|
|
||||||
TYPE_WII_WBFS,
|
|
||||||
TYPE_WII_WBFS_EXT,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
TYPE_WII_GAME = 0,
|
|
||||||
TYPE_GC_GAME,
|
|
||||||
TYPE_CHANNEL,
|
|
||||||
TYPE_PLUGIN,
|
|
||||||
TYPE_HOMEBREW,
|
|
||||||
TYPE_END
|
|
||||||
};
|
|
||||||
#define NoGameID(x) (x == TYPE_PLUGIN || x == TYPE_HOMEBREW)
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
IOS_TYPE_D2X = 0,
|
|
||||||
IOS_TYPE_WANIN,
|
|
||||||
IOS_TYPE_HERMES,
|
|
||||||
IOS_TYPE_KWIIRK,
|
|
||||||
IOS_TYPE_NEEK2O,
|
|
||||||
IOS_TYPE_NORMAL_IOS,
|
|
||||||
IOS_TYPE_STUB,
|
|
||||||
};
|
|
||||||
#define CustomIOS(x) (x != IOS_TYPE_NORMAL_IOS && x != IOS_TYPE_STUB)
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,26 +0,0 @@
|
|||||||
|
|
||||||
#ifndef _UTILS_H_
|
|
||||||
#define _UTILS_H_
|
|
||||||
|
|
||||||
#include <gctypes.h>
|
|
||||||
|
|
||||||
#define KB_SIZE 1024.0
|
|
||||||
#define MB_SIZE 1048576.0
|
|
||||||
#define GB_SIZE 1073741824.0
|
|
||||||
|
|
||||||
#define MAX_FAT_PATH 1024
|
|
||||||
|
|
||||||
#define round_up(x,n) (-(-(x) & -(n)))
|
|
||||||
|
|
||||||
#define ALIGN(n, x) (((x) + (n - 1)) & ~(n - 1))
|
|
||||||
#define ALIGN32(x) (((x) + 31) & ~31)
|
|
||||||
|
|
||||||
#define TITLE_ID(x,y) (((u64)(x) << 32) | (y))
|
|
||||||
#define TITLE_UPPER(x) ((u32)((x) >> 32))
|
|
||||||
#define TITLE_LOWER(x) ((u32)(x) & 0xFFFFFFFF)
|
|
||||||
|
|
||||||
#define Write8(addr, val) *(u8 *)addr = val; DCFlushRange((void *)addr, sizeof(u8));
|
|
||||||
#define Write16(addr, val) *(u16 *)addr = val; DCFlushRange((void *)addr, sizeof(u16));
|
|
||||||
#define Write32(addr, val) *(u32 *)addr = val; DCFlushRange((void *)addr, sizeof(u32));
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,317 +0,0 @@
|
|||||||
// Inspired by WiiPower's "video toy", but simpler
|
|
||||||
|
|
||||||
#include "videopatch.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define ARRAY_SIZE(a) (sizeof a / sizeof a[0])
|
|
||||||
|
|
||||||
extern GXRModeObj TVNtsc480Int;
|
|
||||||
|
|
||||||
GXRModeObj TVPal528Prog =
|
|
||||||
{
|
|
||||||
6, // viDisplayMode
|
|
||||||
640, // fbWidth
|
|
||||||
528, // efbHeight
|
|
||||||
528, // xfbHeight
|
|
||||||
(VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin
|
|
||||||
(VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin
|
|
||||||
640, // viWidth
|
|
||||||
528, // viHeight
|
|
||||||
VI_XFBMODE_SF, // 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
|
|
||||||
{
|
|
||||||
0, // line n-1
|
|
||||||
0, // line n-1
|
|
||||||
21, // line n
|
|
||||||
22, // line n
|
|
||||||
21, // line n
|
|
||||||
0, // line n+1
|
|
||||||
0 // line n+1
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
GXRModeObj TVPal528ProgSoft =
|
|
||||||
{
|
|
||||||
6, // viDisplayMode
|
|
||||||
640, // fbWidth
|
|
||||||
528, // efbHeight
|
|
||||||
528, // xfbHeight
|
|
||||||
(VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin
|
|
||||||
(VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin
|
|
||||||
640, // viWidth
|
|
||||||
528, // viHeight
|
|
||||||
VI_XFBMODE_SF, // 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
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
GXRModeObj TVPal528ProgUnknown =
|
|
||||||
{
|
|
||||||
6, // viDisplayMode
|
|
||||||
640, // fbWidth
|
|
||||||
264, // efbHeight
|
|
||||||
524, // xfbHeight
|
|
||||||
(VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin
|
|
||||||
(VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin
|
|
||||||
640, // viWidth
|
|
||||||
524, // viHeight
|
|
||||||
VI_XFBMODE_SF, // xFBmode
|
|
||||||
GX_FALSE, // field_rendering
|
|
||||||
GX_TRUE, // aa
|
|
||||||
|
|
||||||
// sample points arranged in increasing Y order
|
|
||||||
{
|
|
||||||
{3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
|
|
||||||
{3,2},{9,6},{3,10}, // pix 1
|
|
||||||
{9,2},{3,6},{9,10}, // pix 2
|
|
||||||
{9,2},{3,6},{9,10} // pix 3
|
|
||||||
},
|
|
||||||
|
|
||||||
// vertical filter[7], 1/64 units, 6 bits each
|
|
||||||
{
|
|
||||||
4, // line n-1
|
|
||||||
8, // line n-1
|
|
||||||
12, // line n
|
|
||||||
16, // line n
|
|
||||||
12, // line n
|
|
||||||
8, // line n+1
|
|
||||||
4 // line n+1
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
GXRModeObj TVMpal480Prog =
|
|
||||||
{
|
|
||||||
10, // viDisplayMode
|
|
||||||
640, // fbWidth
|
|
||||||
480, // efbHeight
|
|
||||||
480, // xfbHeight
|
|
||||||
(VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin
|
|
||||||
(VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin
|
|
||||||
640, // viWidth
|
|
||||||
480, // viHeight
|
|
||||||
VI_XFBMODE_SF, // 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
|
|
||||||
{
|
|
||||||
0, // line n-1
|
|
||||||
0, // line n-1
|
|
||||||
21, // line n
|
|
||||||
22, // line n
|
|
||||||
21, // line n
|
|
||||||
0, // line n+1
|
|
||||||
0 // line n+1
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const GXRModeObj *g_vidmodes[] = {
|
|
||||||
&TVNtsc480Int,
|
|
||||||
&TVNtsc480IntDf,
|
|
||||||
&TVNtsc480Prog,
|
|
||||||
|
|
||||||
&TVPal528Int,
|
|
||||||
&TVPal528IntDf,
|
|
||||||
&TVPal528Prog,
|
|
||||||
&TVPal528ProgSoft,
|
|
||||||
&TVPal528ProgUnknown,
|
|
||||||
|
|
||||||
&TVMpal480IntDf,
|
|
||||||
&TVMpal480Prog,
|
|
||||||
|
|
||||||
&TVEurgb60Hz480Int,
|
|
||||||
&TVEurgb60Hz480IntDf,
|
|
||||||
&TVEurgb60Hz480Prog
|
|
||||||
};
|
|
||||||
|
|
||||||
// Level :
|
|
||||||
// 0 : If same number of lines and same mode type (interlaced, progressive)
|
|
||||||
// 1 : If same mode type
|
|
||||||
// 2 : Always
|
|
||||||
static void applyVideoPatch(void *dst, u32 len, GXRModeObj *rmode, int level)
|
|
||||||
{
|
|
||||||
u32 i;
|
|
||||||
u32 *bufEnd = (u32 *)((u8 *)dst + (len - sizeof *rmode));
|
|
||||||
u32 *p = (u32 *)dst;
|
|
||||||
while (p <= bufEnd)
|
|
||||||
{
|
|
||||||
for (i = 0; i < ARRAY_SIZE(g_vidmodes); ++i)
|
|
||||||
if (memcmp(p, g_vidmodes[i], sizeof *rmode) == 0)
|
|
||||||
{
|
|
||||||
// Video mode description found, replace it
|
|
||||||
GXRModeObj *m = (GXRModeObj *)p;
|
|
||||||
if (level == 2
|
|
||||||
|| (((m->viTVMode & 3) == VI_PROGRESSIVE) == ((rmode->viTVMode & 3) == VI_PROGRESSIVE)
|
|
||||||
&& (level == 1 || m->viHeight == rmode->viHeight)))
|
|
||||||
memcpy(p, rmode, sizeof *rmode);
|
|
||||||
p = (u32 *)(m + 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (i == ARRAY_SIZE(g_vidmodes))
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool compare_videomodes(GXRModeObj* mode1, GXRModeObj* mode2)
|
|
||||||
{
|
|
||||||
return memcmp(mode1, mode2, sizeof *mode1) == 0; // padding seems to always be 0
|
|
||||||
}
|
|
||||||
|
|
||||||
static void patch_videomode(GXRModeObj* mode1, GXRModeObj* mode2)
|
|
||||||
{
|
|
||||||
memcpy(mode1, mode2, sizeof *mode1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GXRModeObj* PAL2NTSC[]={
|
|
||||||
&TVMpal480IntDf, &TVNtsc480IntDf,
|
|
||||||
&TVPal264Ds, &TVNtsc240Ds,
|
|
||||||
&TVPal264DsAa, &TVNtsc240DsAa,
|
|
||||||
&TVPal264Int, &TVNtsc240Int,
|
|
||||||
&TVPal264IntAa, &TVNtsc240IntAa,
|
|
||||||
&TVPal524IntAa, &TVNtsc480IntAa,
|
|
||||||
&TVPal528Int, &TVNtsc480IntAa,
|
|
||||||
&TVPal528IntDf, &TVNtsc480IntDf,
|
|
||||||
&TVPal574IntDfScale, &TVNtsc480IntDf,
|
|
||||||
&TVEurgb60Hz240Ds, &TVNtsc240Ds,
|
|
||||||
&TVEurgb60Hz240DsAa, &TVNtsc240DsAa,
|
|
||||||
&TVEurgb60Hz240Int, &TVNtsc240Int,
|
|
||||||
&TVEurgb60Hz240IntAa, &TVNtsc240IntAa,
|
|
||||||
&TVEurgb60Hz480Int, &TVNtsc480IntAa,
|
|
||||||
&TVEurgb60Hz480IntDf, &TVNtsc480IntDf,
|
|
||||||
&TVEurgb60Hz480IntAa, &TVNtsc480IntAa,
|
|
||||||
&TVEurgb60Hz480Prog, &TVNtsc480Prog,
|
|
||||||
&TVEurgb60Hz480ProgSoft,&TVNtsc480Prog,
|
|
||||||
&TVEurgb60Hz480ProgAa, &TVNtsc480Prog,
|
|
||||||
0,0
|
|
||||||
};
|
|
||||||
|
|
||||||
static GXRModeObj* NTSC2PAL[]={
|
|
||||||
&TVNtsc240Ds, &TVPal264Ds,
|
|
||||||
&TVNtsc240DsAa, &TVPal264DsAa,
|
|
||||||
&TVNtsc240Int, &TVPal264Int,
|
|
||||||
&TVNtsc240IntAa, &TVPal264IntAa,
|
|
||||||
&TVNtsc480IntDf, &TVPal528IntDf,
|
|
||||||
&TVNtsc480IntAa, &TVPal524IntAa,
|
|
||||||
&TVNtsc480Prog, &TVPal528IntDf,
|
|
||||||
0,0
|
|
||||||
};
|
|
||||||
|
|
||||||
static GXRModeObj* NTSC2PAL60[]={
|
|
||||||
&TVNtsc240Ds, &TVEurgb60Hz240Ds,
|
|
||||||
&TVNtsc240DsAa, &TVEurgb60Hz240DsAa,
|
|
||||||
&TVNtsc240Int, &TVEurgb60Hz240Int,
|
|
||||||
&TVNtsc240IntAa, &TVEurgb60Hz240IntAa,
|
|
||||||
&TVNtsc480IntDf, &TVEurgb60Hz480IntDf,
|
|
||||||
&TVNtsc480IntAa, &TVEurgb60Hz480IntAa,
|
|
||||||
&TVNtsc480Prog, &TVEurgb60Hz480Prog,
|
|
||||||
0,0
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool Search_and_patch_Video_Modes(void *Address, u32 Size, GXRModeObj* Table[])
|
|
||||||
{
|
|
||||||
u8 *Addr = (u8 *)Address;
|
|
||||||
bool found = 0;
|
|
||||||
u32 i;
|
|
||||||
|
|
||||||
while(Size >= sizeof(GXRModeObj))
|
|
||||||
{
|
|
||||||
for(i = 0; Table[i]; i+=2)
|
|
||||||
{
|
|
||||||
if(compare_videomodes(Table[i], (GXRModeObj*)Addr))
|
|
||||||
{
|
|
||||||
found = 1;
|
|
||||||
patch_videomode((GXRModeObj*)Addr, Table[i+1]);
|
|
||||||
Addr += (sizeof(GXRModeObj)-4);
|
|
||||||
Size -= (sizeof(GXRModeObj)-4);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Addr += 4;
|
|
||||||
Size -= 4;
|
|
||||||
}
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
void patchVideoModes(void *dst, u32 len, int vidMode, GXRModeObj *vmode, int patchVidModes)
|
|
||||||
{
|
|
||||||
GXRModeObj **table = 0;
|
|
||||||
|
|
||||||
if(patchVidModes && vmode != 0)
|
|
||||||
applyVideoPatch(dst, len, vmode, patchVidModes - 1);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch(vidMode)
|
|
||||||
{
|
|
||||||
case 0: // default / disc / game
|
|
||||||
break;
|
|
||||||
case 1: // SYSTEM
|
|
||||||
switch(CONF_GetVideo())
|
|
||||||
{
|
|
||||||
case CONF_VIDEO_PAL:
|
|
||||||
table = CONF_GetEuRGB60() > 0 ? NTSC2PAL60 : NTSC2PAL;
|
|
||||||
break;
|
|
||||||
case CONF_VIDEO_MPAL:
|
|
||||||
table = NTSC2PAL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
table = PAL2NTSC;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Search_and_patch_Video_Modes(dst, len, table);
|
|
||||||
break;
|
|
||||||
case 2: // PAL50
|
|
||||||
Search_and_patch_Video_Modes(dst, len, NTSC2PAL);
|
|
||||||
break;
|
|
||||||
case 3: // PAL60
|
|
||||||
Search_and_patch_Video_Modes(dst, len, NTSC2PAL60);
|
|
||||||
break;
|
|
||||||
case 4: // NTSC
|
|
||||||
Search_and_patch_Video_Modes(dst, len, PAL2NTSC);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
#ifndef _VIDEOPATCH_H_
|
|
||||||
#define _VIDEOPATCH_H_
|
|
||||||
|
|
||||||
#include <gccore.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void patchVideoModes(void *dst, u32 len, int vidMode, GXRModeObj *vmode, int patchVidModes);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // !defined(_VIDEOPATCH_H_)
|
|
@ -1,410 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <ogcsys.h>
|
|
||||||
#include "gecko.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)
|
|
||||||
{
|
|
||||||
gprintf("WDVD_SetUSBMode, Mode: %i, ID: %s, Partition: %i\n", mode, id, 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)
|
|
||||||
{
|
|
||||||
gprintf("WDVD_SetFragList, Device: %i, Size: %i\n", device, 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;
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
#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
|
|
||||||
|
|
71
resources/wiiflow_game_booter/types.h
Normal file
71
resources/wiiflow_game_booter/types.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
TinyLoad - a simple region free (original) game launcher in 4k
|
||||||
|
|
||||||
|
# This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||||
|
# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Copyright 2008-2009 Hector Martin <marcan@marcansoft.com>
|
||||||
|
|
||||||
|
#ifndef __TYPES_H__
|
||||||
|
#define __TYPES_H__
|
||||||
|
|
||||||
|
typedef unsigned char u8;
|
||||||
|
typedef unsigned short u16;
|
||||||
|
typedef unsigned int u32;
|
||||||
|
typedef unsigned long long u64;
|
||||||
|
|
||||||
|
typedef signed char s8;
|
||||||
|
typedef signed short s16;
|
||||||
|
typedef signed int s32;
|
||||||
|
typedef signed long long s64;
|
||||||
|
|
||||||
|
typedef volatile unsigned char vu8;
|
||||||
|
typedef volatile unsigned short vu16;
|
||||||
|
typedef volatile unsigned int vu32;
|
||||||
|
typedef volatile unsigned long long vu64;
|
||||||
|
|
||||||
|
typedef volatile signed char vs8;
|
||||||
|
typedef volatile signed short vs16;
|
||||||
|
typedef volatile signed int vs32;
|
||||||
|
typedef volatile signed long long vs64;
|
||||||
|
|
||||||
|
typedef unsigned int size_t;
|
||||||
|
typedef signed int ssize_t;
|
||||||
|
|
||||||
|
#define NULL ((void *)0)
|
||||||
|
|
||||||
|
#define ALIGNED(n) __attribute__((aligned(n)))
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TYPE_WII_DISC = 0,
|
||||||
|
TYPE_WII_WBFS,
|
||||||
|
TYPE_WII_WBFS_EXT,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TYPE_WII_GAME = 0,
|
||||||
|
TYPE_GC_GAME,
|
||||||
|
TYPE_CHANNEL,
|
||||||
|
TYPE_PLUGIN,
|
||||||
|
TYPE_HOMEBREW,
|
||||||
|
TYPE_END
|
||||||
|
};
|
||||||
|
#define NoGameID(x) (x == TYPE_PLUGIN || x == TYPE_HOMEBREW)
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
IOS_TYPE_D2X = 0,
|
||||||
|
IOS_TYPE_WANIN,
|
||||||
|
IOS_TYPE_HERMES,
|
||||||
|
IOS_TYPE_KWIIRK,
|
||||||
|
IOS_TYPE_NEEK2O,
|
||||||
|
IOS_TYPE_NORMAL_IOS,
|
||||||
|
IOS_TYPE_STUB,
|
||||||
|
};
|
||||||
|
#define CustomIOS(x) (x != IOS_TYPE_NORMAL_IOS && x != IOS_TYPE_STUB)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
221
resources/wiiflow_game_booter/usb.c
Normal file
221
resources/wiiflow_game_booter/usb.c
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* USB Gecko Development Kit - http://www.usbgecko.com
|
||||||
|
* --------------------------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* usb.c - V1.2 functions for the USB Gecko adapter (www.usbgecko.com).
|
||||||
|
* Now works for Wii Mode - use WIIMODE define in usb.h to set
|
||||||
|
* Copyright (c) 2008 - Nuke - <wiinuke@gmail.com>
|
||||||
|
*
|
||||||
|
*---------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "usb.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------*
|
||||||
|
Name: usb_sendbyte
|
||||||
|
Description: Send byte to Gamecube/Wii over EXI memory card port
|
||||||
|
*----------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static int __usb_sendbyte (char sendbyte)
|
||||||
|
{
|
||||||
|
s32 i;
|
||||||
|
|
||||||
|
exi_chan1sr = 0x000000D0;
|
||||||
|
exi_chan1data = 0xB0000000 | (sendbyte<<20);
|
||||||
|
exi_chan1cr = 0x19;
|
||||||
|
while((exi_chan1cr)&1);
|
||||||
|
i = exi_chan1data;
|
||||||
|
exi_chan1sr = 0;
|
||||||
|
if (i&0x04000000){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------*
|
||||||
|
Name: usb_receivebyte
|
||||||
|
Description: Receive byte from Gamecube/Wii over EXI memory card port
|
||||||
|
*----------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static int __usb_receivebyte (char *receivebyte)
|
||||||
|
{
|
||||||
|
s32 i = 0;
|
||||||
|
|
||||||
|
exi_chan1sr = 0x000000D0;
|
||||||
|
exi_chan1data = 0xA0000000;
|
||||||
|
exi_chan1cr = 0x19;
|
||||||
|
while((exi_chan1cr)&1);
|
||||||
|
i = exi_chan1data;
|
||||||
|
exi_chan1sr = 0;
|
||||||
|
if (i&0x08000000){
|
||||||
|
*receivebyte=(i>>16)&0xff;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------*
|
||||||
|
Name: usb_checksendstatus
|
||||||
|
Description: Chesk the FIFO is ready to send
|
||||||
|
*----------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static int __usb_checksendstatus()
|
||||||
|
{
|
||||||
|
s32 i = 0;
|
||||||
|
|
||||||
|
exi_chan1sr = 0x000000D0;
|
||||||
|
exi_chan1data = 0xC0000000;
|
||||||
|
exi_chan1cr = 0x19;
|
||||||
|
while((exi_chan1cr)&1);
|
||||||
|
i = exi_chan1data;
|
||||||
|
exi_chan1sr = 0x0;
|
||||||
|
if (i&0x04000000){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------*
|
||||||
|
Name: usb_checkreceivestatus
|
||||||
|
Description: Check the FIFO is ready to receive
|
||||||
|
*----------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static int __usb_checkreceivestatus()
|
||||||
|
{
|
||||||
|
s32 i = 0;
|
||||||
|
exi_chan1sr = 0x000000D0;
|
||||||
|
exi_chan1data = 0xD0000000;
|
||||||
|
exi_chan1cr = 0x19;
|
||||||
|
while((exi_chan1cr)&1);
|
||||||
|
i = exi_chan1data;
|
||||||
|
exi_chan1sr = 0x0;
|
||||||
|
if (i&0x04000000){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------*
|
||||||
|
Name: usb_sendbuffer
|
||||||
|
Description: Simple buffer send routine
|
||||||
|
*----------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void usb_sendbuffer (const void *buffer, int size)
|
||||||
|
{
|
||||||
|
char *sendbyte = (char*) buffer;
|
||||||
|
s32 bytesleft = size;
|
||||||
|
s32 returnvalue;
|
||||||
|
|
||||||
|
while (bytesleft > 0)
|
||||||
|
{
|
||||||
|
returnvalue = __usb_sendbyte(*sendbyte);
|
||||||
|
if(returnvalue) {
|
||||||
|
sendbyte++;
|
||||||
|
bytesleft--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------*
|
||||||
|
Name: usb_receivebuffer
|
||||||
|
Description: Simple buffer receive routine
|
||||||
|
*----------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void usb_receivebuffer (void *buffer, int size)
|
||||||
|
{
|
||||||
|
char *receivebyte = (char*)buffer;
|
||||||
|
s32 bytesleft = size;
|
||||||
|
s32 returnvalue;
|
||||||
|
|
||||||
|
while (bytesleft > 0)
|
||||||
|
{
|
||||||
|
returnvalue = __usb_receivebyte(receivebyte);
|
||||||
|
if(returnvalue) {
|
||||||
|
receivebyte++;
|
||||||
|
bytesleft--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------*
|
||||||
|
Name: usb_sendbuffersafe
|
||||||
|
Description: Simple buffer send routine with fifo check (use for large transfers)
|
||||||
|
*----------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void usb_sendbuffersafe (const void *buffer, int size)
|
||||||
|
{
|
||||||
|
char *sendbyte = (char*) buffer;
|
||||||
|
s32 bytesleft = size;
|
||||||
|
s32 returnvalue;
|
||||||
|
|
||||||
|
while (bytesleft > 0)
|
||||||
|
{
|
||||||
|
if(__usb_checksendstatus()){
|
||||||
|
returnvalue = __usb_sendbyte(*sendbyte);
|
||||||
|
if(returnvalue) {
|
||||||
|
sendbyte++;
|
||||||
|
bytesleft--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------*
|
||||||
|
Name: usb_receivebuffersafe
|
||||||
|
Description: Simple buffer receive routine with fifo check (use for large transfers)
|
||||||
|
*----------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void usb_receivebuffersafe (void *buffer, int size)
|
||||||
|
{
|
||||||
|
char *receivebyte = (char*)buffer;
|
||||||
|
s32 bytesleft = size;
|
||||||
|
s32 returnvalue;
|
||||||
|
|
||||||
|
while (bytesleft > 0)
|
||||||
|
{
|
||||||
|
if(__usb_checkreceivestatus()){
|
||||||
|
returnvalue = __usb_receivebyte(receivebyte);
|
||||||
|
if(returnvalue) {
|
||||||
|
receivebyte++;
|
||||||
|
bytesleft--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------*
|
||||||
|
Name: usb_checkgecko
|
||||||
|
Description: Chesk the Gecko is connected
|
||||||
|
*----------------------------------------------------------------------------------------------*/
|
||||||
|
int usb_checkgecko()
|
||||||
|
{
|
||||||
|
s32 i = 0;
|
||||||
|
|
||||||
|
exi_chan1sr = 0x000000D0;
|
||||||
|
exi_chan1data = 0x90000000;
|
||||||
|
exi_chan1cr = 0x19;
|
||||||
|
while((exi_chan1cr)&1);
|
||||||
|
i = exi_chan1data;
|
||||||
|
exi_chan1sr = 0x0;
|
||||||
|
if (i==0x04700000){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------*
|
||||||
|
Name: usb_flush
|
||||||
|
Description: Flushes the FIFO, Use at the start of your program to avoid trash
|
||||||
|
*----------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void usb_flush()
|
||||||
|
{
|
||||||
|
char tempbyte;
|
||||||
|
|
||||||
|
while (__usb_receivebyte(&tempbyte));
|
||||||
|
}
|
||||||
|
#endif
|
41
resources/wiiflow_game_booter/usb.h
Normal file
41
resources/wiiflow_game_booter/usb.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* USB Gecko Development Kit - http://www.usbgecko.com
|
||||||
|
* --------------------------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* usb.h - functions for the USB Gecko adapter (www.usbgecko.com).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008 - Nuke - <wiinuke@gmail.com>
|
||||||
|
*
|
||||||
|
*---------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __USB_H__
|
||||||
|
#define __USB_H__
|
||||||
|
|
||||||
|
#define exi_chan0sr *(volatile unsigned int*) 0xCD006800 // Channel 0 Status Register
|
||||||
|
#define exi_chan1sr *(volatile unsigned int*) 0xCD006814 // Channel 1 Status Register
|
||||||
|
#define exi_chan2sr *(volatile unsigned int*) 0xCD006828 // Channel 2 Status Register
|
||||||
|
#define exi_chan0cr *(volatile unsigned int*) 0xCD00680c // Channel 0 Control Register
|
||||||
|
#define exi_chan1cr *(volatile unsigned int*) 0xCD006820 // Channel 1 Control Register
|
||||||
|
#define exi_chan2cr *(volatile unsigned int*) 0xCD006834 // Channel 2 Control Register
|
||||||
|
#define exi_chan0data *(volatile unsigned int*) 0xCD006810 // Channel 0 Immediate Data
|
||||||
|
#define exi_chan1data *(volatile unsigned int*) 0xCD006824 // Channel 1 Immediate Data
|
||||||
|
#define exi_chan2data *(volatile unsigned int*) 0xCD006838 // Channel 2 Immediate Data
|
||||||
|
#define exi_chan0dmasta *(volatile unsigned int*) 0xCD006804 // Channel 0 DMA Start address
|
||||||
|
#define exi_chan1dmasta *(volatile unsigned int*) 0xCD006818 // Channel 1 DMA Start address
|
||||||
|
#define exi_chan2dmasta *(volatile unsigned int*) 0xCD00682c // Channel 2 DMA Start address
|
||||||
|
#define exi_chan0dmalen *(volatile unsigned int*) 0xCD006808 // Channel 0 DMA Length
|
||||||
|
#define exi_chan1dmalen *(volatile unsigned int*) 0xCD00681c // Channel 1 DMA Length
|
||||||
|
#define exi_chan2dmalen *(volatile unsigned int*) 0xCD006830 // Channel 2 DMA Length
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
// Function prototypes
|
||||||
|
void usb_flush();
|
||||||
|
int usb_checkgecko();
|
||||||
|
void usb_sendbuffer (const void *buffer, int size);
|
||||||
|
void usb_receivebuffer (void *buffer, int size);
|
||||||
|
void usb_sendbuffersafe (const void *buffer, int size);
|
||||||
|
void usb_receivebuffersafe (void *buffer, int size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __USB_H__
|
80
resources/wiiflow_game_booter/utils.c
Normal file
80
resources/wiiflow_game_booter/utils.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
TinyLoad - a simple region free (original) game launcher in 4k
|
||||||
|
|
||||||
|
# This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||||
|
# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This code comes from HBC's stub which was based on geckoloader and the Twilight Hack code */
|
||||||
|
/* Some of these routines are from public domain sources */
|
||||||
|
// Copyright 2008-2009 Segher Boessenkool <segher@kernel.crashing.org>
|
||||||
|
// Copyright 2008-2009 Andre Heider <dhewg@wiibrew.org>
|
||||||
|
// Copyright 2008-2009 Hector Martin <marcan@marcansoft.com>
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#ifndef TINY
|
||||||
|
void *memset(void *ptr, int c, int size) {
|
||||||
|
char* ptr2 = ptr;
|
||||||
|
while(size--) *ptr2++ = (char)c;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *memcpy(void *ptr, const void *src, int size) {
|
||||||
|
char* ptr2 = ptr;
|
||||||
|
const char* src2 = src;
|
||||||
|
while(size--) *ptr2++ = *src2++;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int strlen(const char *ptr) {
|
||||||
|
int i=0;
|
||||||
|
while(*ptr++) i++;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int memcmp(const void *s1, const void *s2, size_t n)
|
||||||
|
{
|
||||||
|
const unsigned char *us1 = (const unsigned char *) s1;
|
||||||
|
const unsigned char *us2 = (const unsigned char *) s2;
|
||||||
|
while (n-- != 0) {
|
||||||
|
if (*us1 != *us2)
|
||||||
|
#ifdef TINY
|
||||||
|
return 1;
|
||||||
|
#else
|
||||||
|
return (*us1 < *us2) ? -1 : +1;
|
||||||
|
#endif
|
||||||
|
us1++;
|
||||||
|
us2++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Timebase frequency is core frequency / 8. Ignore roundoff, this
|
||||||
|
// doesn't have to be very accurate.
|
||||||
|
#define TICKS_PER_USEC (729/8)
|
||||||
|
|
||||||
|
static u32 mftb(void)
|
||||||
|
{
|
||||||
|
u32 x;
|
||||||
|
|
||||||
|
asm volatile("mftb %0" : "=r"(x));
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __delay(u32 ticks)
|
||||||
|
{
|
||||||
|
u32 start = mftb();
|
||||||
|
|
||||||
|
while (mftb() - start < ticks)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void udelay(u32 us)
|
||||||
|
{
|
||||||
|
__delay(TICKS_PER_USEC * us);
|
||||||
|
}
|
21
resources/wiiflow_game_booter/utils.h
Normal file
21
resources/wiiflow_game_booter/utils.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
TinyLoad - a simple region free (original) game launcher in 4k
|
||||||
|
|
||||||
|
# This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||||
|
# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Copyright 2008-2009 Hector Martin <marcan@marcansoft.com>
|
||||||
|
|
||||||
|
#ifndef __UTILS_H__
|
||||||
|
#define __UTILS_H__
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
void *memset(void *,int,int);
|
||||||
|
void *memcpy(void *ptr, const void *src, int size);
|
||||||
|
int memcmp(const void *s1, const void *s2, size_t n);
|
||||||
|
int strlen(const char *ptr);
|
||||||
|
void udelay(u32 us);
|
||||||
|
|
||||||
|
#endif
|
@ -12,7 +12,7 @@ typedef struct
|
|||||||
u32 dstaddress;
|
u32 dstaddress;
|
||||||
} WIP_Code;
|
} WIP_Code;
|
||||||
|
|
||||||
bool set_wip_list(WIP_Code *list, int size);
|
u8 set_wip_list(WIP_Code *list, int size);
|
||||||
void wip_reset_counter();
|
void wip_reset_counter();
|
||||||
void free_wip();
|
void free_wip();
|
||||||
void do_wip_code(u8 *dst, u32 len);
|
void do_wip_code(u8 *dst, u32 len);
|
@ -1,6 +1,8 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
echo buildtype.sh
|
||||||
|
|
||||||
FILENAME=source/loader/alt_ios_gen.c
|
FILENAME=source/loader/alt_ios_gen.h
|
||||||
GENERATE=0
|
GENERATE=0
|
||||||
VERSION=249
|
VERSION=249
|
||||||
|
|
||||||
@ -13,7 +15,7 @@ if [ ! -f $FILENAME ];
|
|||||||
then
|
then
|
||||||
GENERATE=1
|
GENERATE=1
|
||||||
else
|
else
|
||||||
CURRENT_VERSION=`grep mainIOS\ = $FILENAME | awk '{printf "%d", $4}'`
|
CURRENT_VERSION=`grep DOL_MAIN_IOS $FILENAME | awk '{printf "%d", $4}'`
|
||||||
if [ $CURRENT_VERSION -ne $VERSION ];
|
if [ $CURRENT_VERSION -ne $VERSION ];
|
||||||
then
|
then
|
||||||
GENERATE=1
|
GENERATE=1
|
||||||
@ -24,6 +26,6 @@ if [ $GENERATE -eq 1 ];
|
|||||||
then
|
then
|
||||||
|
|
||||||
cat <<EOF > $FILENAME
|
cat <<EOF > $FILENAME
|
||||||
int mainIOS = $VERSION;
|
#define DOL_MAIN_IOS $VERSION;
|
||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
@ -1,5 +1,7 @@
|
|||||||
#! /bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
|
echo svnrev.sh
|
||||||
|
|
||||||
rev_new_raw=$(svnversion -n . 2>/dev/null | tr '\n' ' ' | tr -d '\r')
|
rev_new_raw=$(svnversion -n . 2>/dev/null | tr '\n' ' ' | tr -d '\r')
|
||||||
[ -n "$rev_new_raw" ] || rev_new_raw=$(SubWCRev . 2>/dev/null | tr '\n' ' ' | tr -d '\r')
|
[ -n "$rev_new_raw" ] || rev_new_raw=$(SubWCRev . 2>/dev/null | tr '\n' ' ' | tr -d '\r')
|
||||||
|
|
||||||
|
@ -14,11 +14,11 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#ifndef _CFG_HPP_
|
#ifndef _CFG_H_
|
||||||
#define _CFG_HPP_
|
#define _CFG_H_
|
||||||
|
|
||||||
#include "cios.h"
|
#include "loader/cios.h"
|
||||||
#include "frag.h"
|
#include "loader/frag.h"
|
||||||
|
|
||||||
typedef struct _the_CFG {
|
typedef struct _the_CFG {
|
||||||
/* needed for wii games */
|
/* needed for wii games */
|
||||||
@ -37,8 +37,8 @@ typedef struct _the_CFG {
|
|||||||
u8 patchVidMode;
|
u8 patchVidMode;
|
||||||
u8 configbytes[2];
|
u8 configbytes[2];
|
||||||
u8 debugger;
|
u8 debugger;
|
||||||
bool vipatch;
|
u8 vipatch;
|
||||||
bool countryString;
|
u8 countryString;
|
||||||
int aspectRatio;
|
int aspectRatio;
|
||||||
void *codelist;
|
void *codelist;
|
||||||
u8 *codelistend;
|
u8 *codelistend;
|
@ -16,22 +16,28 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include <gccore.h>
|
#include <gccore.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <ogc/machine/processor.h>
|
||||||
|
|
||||||
#include "external_booter.hpp"
|
#include "external_booter.hpp"
|
||||||
#include "Config.hpp"
|
#include "booter.h"
|
||||||
#include "fst.h"
|
#include "Config.h"
|
||||||
#include "mload.h"
|
|
||||||
#include "wdvd.h"
|
|
||||||
#include "channel/nand.hpp"
|
#include "channel/nand.hpp"
|
||||||
#include "devicemounter/DeviceHandler.hpp"
|
#include "devicemounter/DeviceHandler.hpp"
|
||||||
#include "gui/text.hpp"
|
#include "gui/text.hpp"
|
||||||
|
#include "loader/fst.h"
|
||||||
|
#include "loader/mload.h"
|
||||||
|
#include "loader/wdvd.h"
|
||||||
#include "homebrew/homebrew.h"
|
#include "homebrew/homebrew.h"
|
||||||
#include "memory/mem2.hpp"
|
#include "memory/mem2.hpp"
|
||||||
|
#include "plugin/crc32.h"
|
||||||
|
|
||||||
|
typedef void (*entrypoint) (void);
|
||||||
|
extern "C" { void __exception_closeall(); }
|
||||||
|
|
||||||
/* External WiiFlow Game Booter */
|
/* External WiiFlow Game Booter */
|
||||||
#define EXECUTE_ADDR ((u8 *)0x92000000)
|
#define BOOTER_ADDR ((u8 *)0x80F00000)
|
||||||
|
static the_CFG *BooterConfig = (the_CFG*)0x93100000;
|
||||||
extern const u8 wiiflow_game_booter_dol[];
|
static entrypoint exeEntryPoint = (entrypoint)BOOTER_ADDR;
|
||||||
extern const u32 wiiflow_game_booter_dol_size;
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
u8 configbytes[2];
|
u8 configbytes[2];
|
||||||
@ -45,6 +51,8 @@ extern u8 *codelistend;
|
|||||||
extern u32 gameconfsize;
|
extern u32 gameconfsize;
|
||||||
extern u32 *gameconf;
|
extern u32 *gameconf;
|
||||||
|
|
||||||
|
u32 cookie;
|
||||||
|
__argv args;
|
||||||
the_CFG normalCFG;
|
the_CFG normalCFG;
|
||||||
void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio, u32 returnTo, u8 BootType)
|
void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio, u32 returnTo, u8 BootType)
|
||||||
{
|
{
|
||||||
@ -69,14 +77,17 @@ void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 pat
|
|||||||
|
|
||||||
ShutdownBeforeExit(true);
|
ShutdownBeforeExit(true);
|
||||||
/* Copy CFG into new memory region */
|
/* Copy CFG into new memory region */
|
||||||
void *GameCFG = MEM1_lo_alloc(sizeof(the_CFG));
|
memcpy(BooterConfig, &normalCFG, sizeof(the_CFG));
|
||||||
memcpy(GameCFG, &normalCFG, sizeof(the_CFG));
|
DCFlushRange(BooterConfig, sizeof(the_CFG));
|
||||||
DCFlushRange(GameCFG, sizeof(the_CFG));
|
/* Copy in booter */
|
||||||
AddBootArgument(fmt("%08x", GameCFG));
|
memcpy(BOOTER_ADDR, booter, booter_size);
|
||||||
/* Copy booter into apploader region */
|
DCFlushRange(BOOTER_ADDR, booter_size);
|
||||||
memcpy(EXECUTE_ADDR, wiiflow_game_booter_dol, wiiflow_game_booter_dol_size);
|
/* Boot it */
|
||||||
DCFlushRange(EXECUTE_ADDR, wiiflow_game_booter_dol_size);
|
//SYS_ResetSystem(SYS_SHUTDOWN, 0, 0);
|
||||||
BootHomebrew();
|
_CPU_ISR_Disable(cookie);
|
||||||
|
__exception_closeall();
|
||||||
|
exeEntryPoint();
|
||||||
|
_CPU_ISR_Restore(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern FragList *frag_list;
|
extern FragList *frag_list;
|
@ -5,9 +5,9 @@
|
|||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
#include "channel_launcher.h"
|
#include "channel_launcher.h"
|
||||||
|
#include "booter/external_booter.hpp"
|
||||||
#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/utils.h"
|
#include "loader/utils.h"
|
||||||
|
@ -66,7 +66,7 @@ int LoadHomebrew(const char *filepath)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SetupARGV(struct __argv * args)
|
int SetupARGV(struct __argv * args)
|
||||||
{
|
{
|
||||||
if(!args)
|
if(!args)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define _BOOTHOMEBREW_H_
|
#define _BOOTHOMEBREW_H_
|
||||||
|
|
||||||
int BootHomebrew();
|
int BootHomebrew();
|
||||||
|
int SetupARGV(struct __argv * args);
|
||||||
void AddBootArgument(const char * arg);
|
void AddBootArgument(const char * arg);
|
||||||
int LoadHomebrew(const char * filepath);
|
int LoadHomebrew(const char * filepath);
|
||||||
void writeStub();
|
void writeStub();
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
#include "wbfs.h"
|
#include "wbfs.h"
|
||||||
#include "wdvd.h"
|
#include "wdvd.h"
|
||||||
#include "external_booter.hpp"
|
#include "booter/external_booter.hpp"
|
||||||
#include "channel/nand.hpp"
|
#include "channel/nand.hpp"
|
||||||
#include "devicemounter/DeviceHandler.hpp"
|
#include "devicemounter/DeviceHandler.hpp"
|
||||||
#include "devicemounter/sdhc.h"
|
#include "devicemounter/sdhc.h"
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "gecko/gecko.h"
|
#include "gecko/gecko.h"
|
||||||
#include "memory/mem2.hpp"
|
#include "memory/mem2.hpp"
|
||||||
|
|
||||||
|
int mainIOS = 0;
|
||||||
IOS_Info CurrentIOS;
|
IOS_Info CurrentIOS;
|
||||||
signed_blob *GetTMD(u8 ios, u32 *TMD_Length)
|
signed_blob *GetTMD(u8 ios, u32 *TMD_Length)
|
||||||
{
|
{
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "svnrev.h"
|
#include "svnrev.h"
|
||||||
|
|
||||||
|
#include "booter/external_booter.hpp"
|
||||||
#include "channel/nand.hpp"
|
#include "channel/nand.hpp"
|
||||||
#include "devicemounter/DeviceHandler.hpp"
|
#include "devicemounter/DeviceHandler.hpp"
|
||||||
#include "gecko/gecko.h"
|
#include "gecko/gecko.h"
|
||||||
@ -12,7 +13,7 @@
|
|||||||
#include "gui/video.hpp"
|
#include "gui/video.hpp"
|
||||||
#include "gui/text.hpp"
|
#include "gui/text.hpp"
|
||||||
#include "homebrew/homebrew.h"
|
#include "homebrew/homebrew.h"
|
||||||
#include "loader/external_booter.hpp"
|
#include "loader/alt_ios_gen.h"
|
||||||
#include "loader/wdvd.h"
|
#include "loader/wdvd.h"
|
||||||
#include "loader/alt_ios.h"
|
#include "loader/alt_ios.h"
|
||||||
#include "loader/sys.h"
|
#include "loader/sys.h"
|
||||||
@ -24,9 +25,9 @@
|
|||||||
|
|
||||||
CMenu *mainMenu;
|
CMenu *mainMenu;
|
||||||
bool useMainIOS = false;
|
bool useMainIOS = false;
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
mainIOS = DOL_MAIN_IOS;
|
||||||
__exception_setreload(5);
|
__exception_setreload(5);
|
||||||
InitGecko();
|
InitGecko();
|
||||||
|
|
||||||
|
@ -917,7 +917,7 @@ void CMenu::_buildMenus(void)
|
|||||||
theme.btnTexRSH = _texture(theme.texSet, "GENERAL", "button_texture_hlright_selected", theme.btnTexRSH);
|
theme.btnTexRSH = _texture(theme.texSet, "GENERAL", "button_texture_hlright_selected", theme.btnTexRSH);
|
||||||
theme.btnTexCSH.fromPNG(buthscenter_png);
|
theme.btnTexCSH.fromPNG(buthscenter_png);
|
||||||
theme.btnTexCSH = _texture(theme.texSet, "GENERAL", "button_texture_hlcenter_selected", theme.btnTexCSH);
|
theme.btnTexCSH = _texture(theme.texSet, "GENERAL", "button_texture_hlcenter_selected", theme.btnTexCSH);
|
||||||
|
/*
|
||||||
theme.btnAUOn.fromPNG(butauon_png);
|
theme.btnAUOn.fromPNG(butauon_png);
|
||||||
theme.btnAUOn = _texture(theme.texSet, "GENERAL", "button_au_on", theme.btnAUOn);
|
theme.btnAUOn = _texture(theme.texSet, "GENERAL", "button_au_on", theme.btnAUOn);
|
||||||
theme.btnAUOns.fromPNG(butauons_png);
|
theme.btnAUOns.fromPNG(butauons_png);
|
||||||
@ -1025,7 +1025,7 @@ void CMenu::_buildMenus(void)
|
|||||||
theme.btnZHCNOff = _texture(theme.texSet, "GENERAL", "button_zhcn_off", theme.btnZHCNOff);
|
theme.btnZHCNOff = _texture(theme.texSet, "GENERAL", "button_zhcn_off", theme.btnZHCNOff);
|
||||||
theme.btnZHCNOffs.fromPNG(butzhcnoffs_png);
|
theme.btnZHCNOffs.fromPNG(butzhcnoffs_png);
|
||||||
theme.btnZHCNOffs = _texture(theme.texSet, "GENERAL", "button_zhcn_off_selected", theme.btnZHCNOffs);
|
theme.btnZHCNOffs = _texture(theme.texSet, "GENERAL", "button_zhcn_off_selected", theme.btnZHCNOffs);
|
||||||
|
*/
|
||||||
theme.checkboxoff.fromPNG(checkbox_png);
|
theme.checkboxoff.fromPNG(checkbox_png);
|
||||||
theme.checkboxoff = _texture(theme.texSet, "GENERAL", "checkbox_off", theme.checkboxoff);
|
theme.checkboxoff = _texture(theme.texSet, "GENERAL", "checkbox_off", theme.checkboxoff);
|
||||||
theme.checkboxoffs.fromPNG(checkbox_png);
|
theme.checkboxoffs.fromPNG(checkbox_png);
|
||||||
@ -1520,9 +1520,7 @@ void CMenu::_initCF(void)
|
|||||||
m_cf.clear();
|
m_cf.clear();
|
||||||
m_cf.reserve(m_gameList.size());
|
m_cf.reserve(m_gameList.size());
|
||||||
|
|
||||||
const vector<bool> *EnabledPlugins;
|
const vector<bool> &EnabledPlugins = m_plugin.GetEnabledPlugins(m_cfg);
|
||||||
if(m_current_view == COVERFLOW_PLUGIN)
|
|
||||||
EnabledPlugins = m_plugin.GetEnabledPlugins(m_cfg);
|
|
||||||
|
|
||||||
bool dumpGameLst = m_cfg.getBool(domain, "dump_list", true);
|
bool dumpGameLst = m_cfg.getBool(domain, "dump_list", true);
|
||||||
if(dumpGameLst) dump.load(fmt("%s/" TITLES_DUMP_FILENAME, m_settingsDir.c_str()));
|
if(dumpGameLst) dump.load(fmt("%s/" TITLES_DUMP_FILENAME, m_settingsDir.c_str()));
|
||||||
@ -1546,10 +1544,10 @@ void CMenu::_initCF(void)
|
|||||||
// check for single plugin selected
|
// check for single plugin selected
|
||||||
u8 pos = 0;
|
u8 pos = 0;
|
||||||
u8 enabledPluginsCount = 0;
|
u8 enabledPluginsCount = 0;
|
||||||
if(m_current_view == COVERFLOW_PLUGIN && EnabledPlugins->size() != 0)
|
if(m_current_view == COVERFLOW_PLUGIN && EnabledPlugins.size() != 0)
|
||||||
{
|
{
|
||||||
char PluginMagicWord[9];
|
char PluginMagicWord[9];
|
||||||
for(u8 i = 0; i < EnabledPlugins->size(); i++)
|
for(u8 i = 0; i < EnabledPlugins.size(); i++)
|
||||||
{
|
{
|
||||||
snprintf(PluginMagicWord, sizeof(PluginMagicWord), "%08x", m_plugin.getPluginMagic(i));
|
snprintf(PluginMagicWord, sizeof(PluginMagicWord), "%08x", m_plugin.getPluginMagic(i));
|
||||||
if(m_cfg.getBool("PLUGIN", PluginMagicWord, true))
|
if(m_cfg.getBool("PLUGIN", PluginMagicWord, true))
|
||||||
@ -1785,7 +1783,7 @@ void CMenu::_initCF(void)
|
|||||||
if(tempname.find_last_of("/") != string::npos)
|
if(tempname.find_last_of("/") != string::npos)
|
||||||
tempname.assign(&tempname[tempname.find_last_of("/") + 1]);
|
tempname.assign(&tempname[tempname.find_last_of("/") + 1]);
|
||||||
string coverFolder(m_plugin.GetCoverFolderName(m_gameList[i].settings[0]));
|
string coverFolder(m_plugin.GetCoverFolderName(m_gameList[i].settings[0]));
|
||||||
if(EnabledPlugins->size() == 0) //all plugins
|
if(EnabledPlugins.size() == 0) //all plugins
|
||||||
{
|
{
|
||||||
if(coverFolder.size() > 0)
|
if(coverFolder.size() > 0)
|
||||||
m_cf.addItem(&m_gameList[i], fmt("%s/%s/%s.png", m_picDir.c_str(), coverFolder.c_str(), tempname.c_str()), fmt("%s/%s/%s.png", m_boxPicDir.c_str(), coverFolder.c_str(), tempname.c_str()), playcount, lastPlayed);
|
m_cf.addItem(&m_gameList[i], fmt("%s/%s/%s.png", m_picDir.c_str(), coverFolder.c_str(), tempname.c_str()), fmt("%s/%s/%s.png", m_boxPicDir.c_str(), coverFolder.c_str(), tempname.c_str()), playcount, lastPlayed);
|
||||||
@ -1794,9 +1792,9 @@ void CMenu::_initCF(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(u8 j = 0; j < EnabledPlugins->size(); j++)
|
for(u8 j = 0; j < EnabledPlugins.size(); j++)
|
||||||
{
|
{
|
||||||
if(EnabledPlugins->at(j) == true && m_gameList[i].settings[0] == m_plugin.getPluginMagic(j))
|
if(EnabledPlugins.at(j) == true && m_gameList[i].settings[0] == m_plugin.getPluginMagic(j))
|
||||||
{
|
{
|
||||||
if(coverFolder.size() > 0)
|
if(coverFolder.size() > 0)
|
||||||
m_cf.addItem(&m_gameList[i], fmt("%s/%s/%s.png", m_picDir.c_str(), coverFolder.c_str(), tempname.c_str()), fmt("%s/%s/%s.png", m_boxPicDir.c_str(), coverFolder.c_str(), tempname.c_str()), playcount, lastPlayed);
|
m_cf.addItem(&m_gameList[i], fmt("%s/%s/%s.png", m_picDir.c_str(), coverFolder.c_str(), tempname.c_str()), fmt("%s/%s/%s.png", m_boxPicDir.c_str(), coverFolder.c_str(), tempname.c_str()), playcount, lastPlayed);
|
||||||
@ -2294,13 +2292,14 @@ bool CMenu::_loadEmuList()
|
|||||||
if(m_plugin_cfg.loaded())
|
if(m_plugin_cfg.loaded())
|
||||||
{
|
{
|
||||||
m_plugin.AddPlugin(m_plugin_cfg);
|
m_plugin.AddPlugin(m_plugin_cfg);
|
||||||
|
u32 MagicWord = strtoul(m_plugin_cfg.getString(PLUGIN_DOMAIN,"magic").c_str(), NULL, 16);
|
||||||
if(m_plugin_cfg.getString(PLUGIN_DOMAIN,"romDir").find("scummvm.ini") == string::npos)
|
if(m_plugin_cfg.getString(PLUGIN_DOMAIN,"romDir").find("scummvm.ini") == string::npos)
|
||||||
{
|
{
|
||||||
string gameDir(fmt("%s:/%s", DeviceName[currentPartition], m_plugin_cfg.getString(PLUGIN_DOMAIN,"romDir").c_str()));
|
string gameDir(fmt("%s:/%s", DeviceName[currentPartition], m_plugin_cfg.getString(PLUGIN_DOMAIN,"romDir").c_str()));
|
||||||
string cacheDir(fmt("%s/%s_%s.db", m_listCacheDir.c_str(), DeviceName[currentPartition], m_plugin_cfg.getString(PLUGIN_DOMAIN,"magic").c_str()));
|
string cacheDir(fmt("%s/%s_%s.db", m_listCacheDir.c_str(), DeviceName[currentPartition], m_plugin_cfg.getString(PLUGIN_DOMAIN,"magic").c_str()));
|
||||||
vector<string> FileTypes = stringToVector(m_plugin_cfg.getString(PLUGIN_DOMAIN,"fileTypes"), '|');
|
vector<string> FileTypes = stringToVector(m_plugin_cfg.getString(PLUGIN_DOMAIN,"fileTypes"), '|');
|
||||||
m_gameList.Color = strtoul(m_plugin_cfg.getString(PLUGIN_DOMAIN,"coverColor").c_str(), NULL, 16);
|
m_gameList.Color = strtoul(m_plugin_cfg.getString(PLUGIN_DOMAIN,"coverColor").c_str(), NULL, 16);
|
||||||
m_gameList.Magic = strtoul(m_plugin_cfg.getString(PLUGIN_DOMAIN,"magic").c_str(), NULL, 16);
|
m_gameList.Magic = MagicWord;
|
||||||
m_gameList.CreateList(m_current_view, currentPartition, gameDir, FileTypes, cacheDir, updateCache);
|
m_gameList.CreateList(m_current_view, currentPartition, gameDir, FileTypes, cacheDir, updateCache);
|
||||||
for(vector<dir_discHdr>::iterator tmp_itr = m_gameList.begin(); tmp_itr != m_gameList.end(); tmp_itr++)
|
for(vector<dir_discHdr>::iterator tmp_itr = m_gameList.begin(); tmp_itr != m_gameList.end(); tmp_itr++)
|
||||||
emuList.push_back(*tmp_itr);
|
emuList.push_back(*tmp_itr);
|
||||||
@ -2310,7 +2309,7 @@ bool CMenu::_loadEmuList()
|
|||||||
Config scummvm;
|
Config scummvm;
|
||||||
vector<dir_discHdr> scummvmList;
|
vector<dir_discHdr> scummvmList;
|
||||||
scummvm.load(fmt("%s/%s", m_pluginsDir.c_str(), "scummvm.ini"));
|
scummvm.load(fmt("%s/%s", m_pluginsDir.c_str(), "scummvm.ini"));
|
||||||
scummvmList = m_plugin.ParseScummvmINI(scummvm, DeviceName[currentPartition]);
|
scummvmList = m_plugin.ParseScummvmINI(scummvm, DeviceName[currentPartition], MagicWord);
|
||||||
for(vector<dir_discHdr>::iterator tmp_itr = scummvmList.begin(); tmp_itr != scummvmList.end(); tmp_itr++)
|
for(vector<dir_discHdr>::iterator tmp_itr = scummvmList.begin(); tmp_itr != scummvmList.end(); tmp_itr++)
|
||||||
emuList.push_back(*tmp_itr);
|
emuList.push_back(*tmp_itr);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "gui/fanart.hpp"
|
#include "gui/fanart.hpp"
|
||||||
#include "gui/gui.hpp"
|
#include "gui/gui.hpp"
|
||||||
#include "list/ListGenerator.hpp"
|
#include "list/ListGenerator.hpp"
|
||||||
|
#include "loader/alt_ios_gen.h"
|
||||||
#include "loader/disc.h"
|
#include "loader/disc.h"
|
||||||
#include "loader/gc_disc_dump.hpp"
|
#include "loader/gc_disc_dump.hpp"
|
||||||
#include "loader/wbfs.h"
|
#include "loader/wbfs.h"
|
||||||
|
@ -151,12 +151,12 @@ void CMenu::_CategorySettings(bool fromGameSet)
|
|||||||
u8 pos = 0;
|
u8 pos = 0;
|
||||||
if(m_current_view == COVERFLOW_PLUGIN)
|
if(m_current_view == COVERFLOW_PLUGIN)
|
||||||
{
|
{
|
||||||
const vector<bool> *EnabledPlugins = m_plugin.GetEnabledPlugins(m_cfg);
|
const vector<bool> &EnabledPlugins = m_plugin.GetEnabledPlugins(m_cfg);
|
||||||
if(EnabledPlugins->size() != 0)
|
if(EnabledPlugins.size() != 0)
|
||||||
{
|
{
|
||||||
char PluginMagicWord[9];
|
char PluginMagicWord[9];
|
||||||
u8 enabledPluginsCount = 0;
|
u8 enabledPluginsCount = 0;
|
||||||
for(u8 i = 0; i < EnabledPlugins->size(); i++)
|
for(u8 i = 0; i < EnabledPlugins.size(); i++)
|
||||||
{
|
{
|
||||||
snprintf(PluginMagicWord, sizeof(PluginMagicWord), "%08x", m_plugin.getPluginMagic(i));
|
snprintf(PluginMagicWord, sizeof(PluginMagicWord), "%08x", m_plugin.getPluginMagic(i));
|
||||||
if(m_cfg.getBool("PLUGIN", PluginMagicWord, true))
|
if(m_cfg.getBool("PLUGIN", PluginMagicWord, true))
|
||||||
|
@ -162,7 +162,7 @@ int CMenu::_config1(void)
|
|||||||
|
|
||||||
s32 bCurrentPartition = currentPartition;
|
s32 bCurrentPartition = currentPartition;
|
||||||
|
|
||||||
gprintf("Current Partition: %d\n", currentPartition);
|
//gprintf("Current Partition: %d\n", currentPartition);
|
||||||
|
|
||||||
_showConfig();
|
_showConfig();
|
||||||
_textConfig();
|
_textConfig();
|
||||||
@ -222,7 +222,7 @@ int CMenu::_config1(void)
|
|||||||
for(u8 i = 0; strncmp((const char *)&newpartition[i], "\0", 1) != 0; i++)
|
for(u8 i = 0; strncmp((const char *)&newpartition[i], "\0", 1) != 0; i++)
|
||||||
newpartition[i] = toupper(newpartition[i]);
|
newpartition[i] = toupper(newpartition[i]);
|
||||||
|
|
||||||
gprintf("Switching partition to %s\n", newpartition);
|
//gprintf("Switching partition to %s\n", newpartition);
|
||||||
_showWaitMessage();
|
_showWaitMessage();
|
||||||
_loadList();
|
_loadList();
|
||||||
_hideWaitMessage();
|
_hideWaitMessage();
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "menu.hpp"
|
#include "menu.hpp"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "banner/BannerWindow.hpp"
|
#include "banner/BannerWindow.hpp"
|
||||||
|
#include "booter/external_booter.hpp"
|
||||||
#include "channel/channel_launcher.h"
|
#include "channel/channel_launcher.h"
|
||||||
#include "channel/channels.h"
|
#include "channel/channels.h"
|
||||||
#include "channel/nand.hpp"
|
#include "channel/nand.hpp"
|
||||||
@ -24,7 +25,6 @@
|
|||||||
#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/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"
|
||||||
@ -1330,7 +1330,7 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
|
|||||||
if(rtrn != NULL && strlen(rtrn) == 4)
|
if(rtrn != NULL && strlen(rtrn) == 4)
|
||||||
returnTo = rtrn[0] << 24 | rtrn[1] << 16 | rtrn[2] << 8 | rtrn[3];
|
returnTo = rtrn[0] << 24 | rtrn[1] << 16 | rtrn[2] << 8 | rtrn[3];
|
||||||
int userIOS = m_gcfg2.getInt(id, "ios", 0);
|
int userIOS = m_gcfg2.getInt(id, "ios", 0);
|
||||||
int gameIOS = GetRequestedGameIOS(hdr);
|
int gameIOS = dvd ? userIOS : GetRequestedGameIOS(hdr);
|
||||||
|
|
||||||
m_gcfg1.save(true);
|
m_gcfg1.save(true);
|
||||||
m_gcfg2.save(true);
|
m_gcfg2.save(true);
|
||||||
@ -1343,34 +1343,6 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
|
|||||||
if(_loadIOS(gameIOS, userIOS, id) == LOAD_IOS_FAILED)
|
if(_loadIOS(gameIOS, userIOS, id) == LOAD_IOS_FAILED)
|
||||||
Sys_Exit();
|
Sys_Exit();
|
||||||
}
|
}
|
||||||
if(CurrentIOS.Type == IOS_TYPE_D2X)
|
|
||||||
{
|
|
||||||
/* Open ES Module */
|
|
||||||
s32 ESHandle = IOS_Open("/dev/es", 0);
|
|
||||||
/* IOS Reload Block */
|
|
||||||
static ioctlv block_vector[2] ATTRIBUTE_ALIGN(32);
|
|
||||||
static u32 mode ATTRIBUTE_ALIGN(32);
|
|
||||||
static u32 ios ATTRIBUTE_ALIGN(32);
|
|
||||||
mode = 2;
|
|
||||||
block_vector[0].data = &mode;
|
|
||||||
block_vector[0].len = sizeof(u32);
|
|
||||||
ios = IOS_GetVersion();
|
|
||||||
block_vector[1].data = &ios;
|
|
||||||
block_vector[1].len = sizeof(u32);
|
|
||||||
gprintf("Block IOS Reload for %i %s\n", ios, IOS_Ioctlv(ESHandle, 0xA0, 2, 0, block_vector) < 0 ? "failed!" : "succeeded");
|
|
||||||
/* Return to */
|
|
||||||
if(!m_directLaunch && returnTo)
|
|
||||||
{
|
|
||||||
static ioctlv rtn_vector[1] ATTRIBUTE_ALIGN(32);
|
|
||||||
sm_title_id[0] = (((u64)(0x00010001) << 32) | (returnTo & 0xFFFFFFFF));
|
|
||||||
rtn_vector[0].data = sm_title_id;
|
|
||||||
rtn_vector[0].len = sizeof(u64);
|
|
||||||
gprintf("Return to channel %s %s. Using new d2x way\n", rtrn, IOS_Ioctlv(ESHandle, 0xA1, 1, 0, rtn_vector) != -101 ? "succeeded" : "failed!");
|
|
||||||
returnTo = 0;
|
|
||||||
}
|
|
||||||
/* Close ES Module */
|
|
||||||
IOS_Close(ESHandle);
|
|
||||||
}
|
|
||||||
if(emulate_mode && !neek2o() && CurrentIOS.Type == IOS_TYPE_D2X)
|
if(emulate_mode && !neek2o() && CurrentIOS.Type == IOS_TYPE_D2X)
|
||||||
{
|
{
|
||||||
Nand::Instance()->Init(emuPath.c_str(), emuPartition, false);
|
Nand::Instance()->Init(emuPath.c_str(), emuPartition, false);
|
||||||
@ -1411,6 +1383,8 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
|
|||||||
ocarina_load_code(cheatFile.get(), cheatSize);
|
ocarina_load_code(cheatFile.get(), cheatSize);
|
||||||
cheatFile.release();
|
cheatFile.release();
|
||||||
}
|
}
|
||||||
|
//loadIOS(250, false);
|
||||||
|
usleep(10000);
|
||||||
ExternalBooter_WiiGameSetup(wbfs_partition, dvd, id.c_str());
|
ExternalBooter_WiiGameSetup(wbfs_partition, dvd, id.c_str());
|
||||||
WiiFlow_ExternalBooter(videoMode, vipatch, countryPatch, patchVidMode, aspectRatio, returnTo, TYPE_WII_GAME);
|
WiiFlow_ExternalBooter(videoMode, vipatch, countryPatch, patchVidMode, aspectRatio, returnTo, TYPE_WII_GAME);
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <gccore.h>
|
#include <gccore.h>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
u8 Plugin_curPage;
|
u8 m_max_plugins = 0;
|
||||||
u8 Plugin_Pages;
|
u8 Plugin_curPage = 1;
|
||||||
u8 Plugin_lastBtn;
|
u8 Plugin_Pages = 1;
|
||||||
|
|
||||||
// Plugin menu
|
// Plugin menu
|
||||||
s16 m_pluginLblPage;
|
s16 m_pluginLblPage;
|
||||||
@ -18,7 +19,6 @@ s16 m_pluginBtn[11];
|
|||||||
s16 m_pluginBtnCat[11];
|
s16 m_pluginBtnCat[11];
|
||||||
s16 m_pluginBtnCats[11];
|
s16 m_pluginBtnCats[11];
|
||||||
s16 m_pluginLblUser[4];
|
s16 m_pluginLblUser[4];
|
||||||
u8 m_max_plugins;
|
|
||||||
STexture m_pluginBg;
|
STexture m_pluginBg;
|
||||||
|
|
||||||
void CMenu::_hidePluginSettings(bool instant)
|
void CMenu::_hidePluginSettings(bool instant)
|
||||||
@ -74,9 +74,9 @@ void CMenu::_updatePluginCheckboxes(void)
|
|||||||
m_btnMgr.hide(m_pluginBtn[i]);
|
m_btnMgr.hide(m_pluginBtn[i]);
|
||||||
m_btnMgr.hide(m_pluginLblCat[i]);
|
m_btnMgr.hide(m_pluginLblCat[i]);
|
||||||
}
|
}
|
||||||
const vector<bool> *EnabledPlugins = m_plugin.GetEnabledPlugins(m_cfg);
|
const vector<bool> &EnabledPlugins = m_plugin.GetEnabledPlugins(m_cfg);
|
||||||
/* ALL Button */
|
/* ALL Button */
|
||||||
if(EnabledPlugins->size() == 0)
|
if(EnabledPlugins.size() == 0)
|
||||||
m_pluginBtn[0] = m_pluginBtnCats[0];
|
m_pluginBtn[0] = m_pluginBtnCats[0];
|
||||||
else
|
else
|
||||||
m_pluginBtn[0] = m_pluginBtnCat[0];
|
m_pluginBtn[0] = m_pluginBtnCat[0];
|
||||||
@ -86,7 +86,7 @@ void CMenu::_updatePluginCheckboxes(void)
|
|||||||
u32 IteratorHelp = (Plugin_curPage - 1) * 10;
|
u32 IteratorHelp = (Plugin_curPage - 1) * 10;
|
||||||
for(u8 i = 1; i < min(IteratorHelp+10, (u32)m_max_plugins)-IteratorHelp+1; ++i)
|
for(u8 i = 1; i < min(IteratorHelp+10, (u32)m_max_plugins)-IteratorHelp+1; ++i)
|
||||||
{
|
{
|
||||||
if(EnabledPlugins->size() == 0 || EnabledPlugins->at(i+IteratorHelp-1) == true)
|
if(EnabledPlugins.size() == 0 || EnabledPlugins.at(i+IteratorHelp-1) == true)
|
||||||
m_pluginBtn[i] = m_pluginBtnCats[i];
|
m_pluginBtn[i] = m_pluginBtnCats[i];
|
||||||
else
|
else
|
||||||
m_pluginBtn[i] = m_pluginBtnCat[i];
|
m_pluginBtn[i] = m_pluginBtnCat[i];
|
||||||
@ -97,17 +97,21 @@ void CMenu::_updatePluginCheckboxes(void)
|
|||||||
|
|
||||||
void CMenu::_PluginSettings()
|
void CMenu::_PluginSettings()
|
||||||
{
|
{
|
||||||
|
u8 i = 0;
|
||||||
|
while(m_plugin.PluginExist(i)) i++;
|
||||||
|
Plugin_Pages = static_cast<int>(ceil(static_cast<float>(i)/static_cast<float>(10)));
|
||||||
|
m_max_plugins = i;
|
||||||
|
//gprintf("Plugins found: %i, Pages: %i\n", m_max_plugins, Plugin_Pages);
|
||||||
|
if(Plugin_Pages == 0)
|
||||||
|
return;
|
||||||
|
/* Only use Plugin Settings if Plugins are found */
|
||||||
SetupInput();
|
SetupInput();
|
||||||
Plugin_Pages = 1;
|
|
||||||
Plugin_curPage = 1;
|
Plugin_curPage = 1;
|
||||||
_textPluginSettings();
|
|
||||||
_showPluginSettings();
|
_showPluginSettings();
|
||||||
_updatePluginText();
|
_updatePluginText();
|
||||||
while(!m_exit)
|
while(!m_exit)
|
||||||
{
|
{
|
||||||
_mainLoopCommon();
|
_mainLoopCommon();
|
||||||
if(!m_btnMgr.selected(Plugin_lastBtn))
|
|
||||||
m_btnMgr.noHover(false);
|
|
||||||
if(BTN_HOME_PRESSED || BTN_B_PRESSED)
|
if(BTN_HOME_PRESSED || BTN_B_PRESSED)
|
||||||
{
|
{
|
||||||
m_cfg.save();
|
m_cfg.save();
|
||||||
@ -119,8 +123,6 @@ void CMenu::_PluginSettings()
|
|||||||
m_btnMgr.down();
|
m_btnMgr.down();
|
||||||
if((BTN_MINUS_PRESSED || BTN_LEFT_PRESSED) || (BTN_A_PRESSED && m_btnMgr.selected(m_pluginBtnPageM)))
|
if((BTN_MINUS_PRESSED || BTN_LEFT_PRESSED) || (BTN_A_PRESSED && m_btnMgr.selected(m_pluginBtnPageM)))
|
||||||
{
|
{
|
||||||
Plugin_lastBtn = m_pluginBtnPageM;
|
|
||||||
m_btnMgr.noHover(true);
|
|
||||||
Plugin_curPage--;
|
Plugin_curPage--;
|
||||||
if(Plugin_curPage == 0) Plugin_curPage = Plugin_Pages;
|
if(Plugin_curPage == 0) Plugin_curPage = Plugin_Pages;
|
||||||
if(BTN_LEFT_PRESSED || BTN_MINUS_PRESSED)
|
if(BTN_LEFT_PRESSED || BTN_MINUS_PRESSED)
|
||||||
@ -130,8 +132,6 @@ void CMenu::_PluginSettings()
|
|||||||
}
|
}
|
||||||
else if(((BTN_PLUS_PRESSED || BTN_RIGHT_PRESSED)) || (BTN_A_PRESSED && m_btnMgr.selected(m_pluginBtnPageP)))
|
else if(((BTN_PLUS_PRESSED || BTN_RIGHT_PRESSED)) || (BTN_A_PRESSED && m_btnMgr.selected(m_pluginBtnPageP)))
|
||||||
{
|
{
|
||||||
Plugin_lastBtn = m_pluginBtnPageP;
|
|
||||||
m_btnMgr.noHover(true);
|
|
||||||
Plugin_curPage++;
|
Plugin_curPage++;
|
||||||
if(Plugin_curPage > Plugin_Pages) Plugin_curPage = 1;
|
if(Plugin_curPage > Plugin_Pages) Plugin_curPage = 1;
|
||||||
if(BTN_RIGHT_PRESSED || BTN_PLUS_PRESSED)
|
if(BTN_RIGHT_PRESSED || BTN_PLUS_PRESSED)
|
||||||
@ -151,11 +151,9 @@ void CMenu::_PluginSettings()
|
|||||||
{
|
{
|
||||||
if(m_btnMgr.selected(m_pluginBtn[i]))
|
if(m_btnMgr.selected(m_pluginBtn[i]))
|
||||||
{
|
{
|
||||||
Plugin_lastBtn = m_pluginBtn[i];
|
|
||||||
m_btnMgr.noHover(true);
|
|
||||||
if(i == 0)
|
if(i == 0)
|
||||||
{
|
{
|
||||||
bool EnableAll = m_plugin.GetEnabledPlugins(m_cfg)->size();
|
bool EnableAll = m_plugin.GetEnabledPlugins(m_cfg).size();
|
||||||
for(u8 j = 0; m_plugin.PluginExist(j); j++)
|
for(u8 j = 0; m_plugin.PluginExist(j); j++)
|
||||||
m_plugin.SetEnablePlugin(m_cfg, j, EnableAll ? 2 : 1);
|
m_plugin.SetEnablePlugin(m_cfg, j, EnableAll ? 2 : 1);
|
||||||
}
|
}
|
||||||
@ -204,9 +202,6 @@ void CMenu::_initPluginSettingsMenu(CMenu::SThemeData &theme)
|
|||||||
_setHideAnim(m_pluginLblCat[i], fmt("PLUGIN/PLUGIN_%i", i), 0, 0, 1.f, 0.f);
|
_setHideAnim(m_pluginLblCat[i], fmt("PLUGIN/PLUGIN_%i", i), 0, 0, 1.f, 0.f);
|
||||||
m_pluginBtn[i] = m_pluginBtnCat[i];
|
m_pluginBtn[i] = m_pluginBtnCat[i];
|
||||||
}
|
}
|
||||||
Plugin_curPage = 1;
|
|
||||||
Plugin_Pages = 1;
|
|
||||||
m_max_plugins = 0;
|
|
||||||
_hidePluginSettings(true);
|
_hidePluginSettings(true);
|
||||||
_textPluginSettings();
|
_textPluginSettings();
|
||||||
}
|
}
|
||||||
@ -215,20 +210,5 @@ void CMenu::_textPluginSettings(void)
|
|||||||
{
|
{
|
||||||
m_btnMgr.setText(m_pluginLblTitle, _t("cfgpl1", L"Select Plugins"));
|
m_btnMgr.setText(m_pluginLblTitle, _t("cfgpl1", L"Select Plugins"));
|
||||||
m_btnMgr.setText(m_pluginBtnBack, _t("cd1", L"Back"));
|
m_btnMgr.setText(m_pluginBtnBack, _t("cd1", L"Back"));
|
||||||
u8 i = 0;
|
m_btnMgr.setText(m_pluginLblCat[0], _t("dl25", L"All"));
|
||||||
while(!m_exit)
|
|
||||||
{
|
|
||||||
if(i == 0)
|
|
||||||
m_btnMgr.setText(m_pluginLblCat[i], _t("dl25", L"All"));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!m_plugin.PluginExist(i - 1))
|
|
||||||
{
|
|
||||||
Plugin_Pages = (i-1)/10;
|
|
||||||
m_max_plugins = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ void Plugin::SetEnablePlugin(Config &cfg, u8 pos, u8 ForceMode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const vector<bool> *Plugin::GetEnabledPlugins(Config &cfg)
|
const vector<bool> &Plugin::GetEnabledPlugins(Config &cfg)
|
||||||
{
|
{
|
||||||
enabledPlugins.clear();
|
enabledPlugins.clear();
|
||||||
char PluginMagicWord[9];
|
char PluginMagicWord[9];
|
||||||
@ -181,7 +181,7 @@ const vector<bool> *Plugin::GetEnabledPlugins(Config &cfg)
|
|||||||
}
|
}
|
||||||
if(enabledPluginsNumber == Plugins.size())
|
if(enabledPluginsNumber == Plugins.size())
|
||||||
enabledPlugins.clear();
|
enabledPlugins.clear();
|
||||||
return &enabledPlugins;
|
return enabledPlugins;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Plugin::getPluginMagic(u8 pos)
|
u32 Plugin::getPluginMagic(u8 pos)
|
||||||
@ -189,7 +189,7 @@ u32 Plugin::getPluginMagic(u8 pos)
|
|||||||
return Plugins[pos].magicWord;
|
return Plugins[pos].magicWord;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<dir_discHdr> Plugin::ParseScummvmINI(Config &ini, const char *Device)
|
vector<dir_discHdr> Plugin::ParseScummvmINI(Config &ini, const char *Device, u32 MagicWord)
|
||||||
{
|
{
|
||||||
gprintf("Parsing scummvm.ini\n");
|
gprintf("Parsing scummvm.ini\n");
|
||||||
vector<dir_discHdr> gameHeader;
|
vector<dir_discHdr> gameHeader;
|
||||||
@ -203,7 +203,7 @@ vector<dir_discHdr> Plugin::ParseScummvmINI(Config &ini, const char *Device)
|
|||||||
if(GameDomain->size() < 2)
|
if(GameDomain->size() < 2)
|
||||||
break;
|
break;
|
||||||
const string &GameName = ini.getString(*GameDomain, "description");
|
const string &GameName = ini.getString(*GameDomain, "description");
|
||||||
if(GameName.size() < 2 || ini.getString(*GameDomain, "path").find(Device) == string::npos)
|
if(GameName.size() < 2 || strncasecmp(Device, ini.getString(*GameDomain, "path").c_str(), 2) != 0)
|
||||||
{
|
{
|
||||||
GameDomain = &ini.nextDomain();
|
GameDomain = &ini.nextDomain();
|
||||||
continue;
|
continue;
|
||||||
@ -214,7 +214,7 @@ vector<dir_discHdr> Plugin::ParseScummvmINI(Config &ini, const char *Device)
|
|||||||
mbstowcs(ListElement.title, GameName.c_str(), 63);
|
mbstowcs(ListElement.title, GameName.c_str(), 63);
|
||||||
strncpy(ListElement.path, GameDomain->c_str(), sizeof(ListElement.path));
|
strncpy(ListElement.path, GameDomain->c_str(), sizeof(ListElement.path));
|
||||||
gprintf("Found: %s\n", GameDomain->c_str());
|
gprintf("Found: %s\n", GameDomain->c_str());
|
||||||
ListElement.settings[0] = Plugins.back().magicWord;
|
ListElement.settings[0] = MagicWord;
|
||||||
ListElement.type = TYPE_PLUGIN;
|
ListElement.type = TYPE_PLUGIN;
|
||||||
gameHeader.push_back(ListElement);
|
gameHeader.push_back(ListElement);
|
||||||
GameDomain = &ini.nextDomain();
|
GameDomain = &ini.nextDomain();
|
||||||
|
@ -63,13 +63,13 @@ public:
|
|||||||
u32 getPluginMagic(u8 pos);
|
u32 getPluginMagic(u8 pos);
|
||||||
bool PluginExist(u8 pos);
|
bool PluginExist(u8 pos);
|
||||||
void SetEnablePlugin(Config &cfg, u8 pos, u8 ForceMode = 0);
|
void SetEnablePlugin(Config &cfg, u8 pos, u8 ForceMode = 0);
|
||||||
const vector<bool> *GetEnabledPlugins(Config &cfg);
|
const vector<bool> &GetEnabledPlugins(Config &cfg);
|
||||||
vector<string> CreateArgs(const string& device, const string& path,
|
vector<string> CreateArgs(const string& device, const string& path,
|
||||||
const string& title, const string& loader, u32 magic);
|
const string& title, const string& loader, u32 magic);
|
||||||
void init(const string& m_pluginsDir);
|
void init(const string& m_pluginsDir);
|
||||||
void Cleanup();
|
void Cleanup();
|
||||||
void EndAdd();
|
void EndAdd();
|
||||||
vector<dir_discHdr> ParseScummvmINI(Config &ini, const char *Device);
|
vector<dir_discHdr> ParseScummvmINI(Config &ini, const char *Device, u32 MagicWord);
|
||||||
private:
|
private:
|
||||||
s8 GetPluginPosition(u32 magic);
|
s8 GetPluginPosition(u32 magic);
|
||||||
vector<PluginOptions> Plugins;
|
vector<PluginOptions> Plugins;
|
||||||
|
Loading…
Reference in New Issue
Block a user