diff --git a/Makefile.main b/Makefile.main index f0d20cee..fe9b1831 100644 --- a/Makefile.main +++ b/Makefile.main @@ -54,7 +54,7 @@ ios := 249 #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -CFLAGS = -g -ggdb -O1 -Wall -Wno-multichar -Wno-unused-parameter -Wextra $(MACHDEP) $(INCLUDE) -DBUILD_IOS=$(IOS) +CFLAGS = -g -ggdb -O1 -Wall -Wextra $(MACHDEP) $(INCLUDE) -DHAVE_CONFIG_H 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 @@ -150,7 +150,8 @@ all: #--------------------------------------------------------------------------------- clean: @echo clean ... - @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol $(CURDIR)/source/svnrev.h $(CURDIR)/source/loader/alt_ios_gen.h + @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol $(CURDIR)/source/svnrev.h $(CURDIR)/source/loader/alt_ios_gen.h \ + $(CURDIR)/source/booter/booter.c $(CURDIR)/source/booter/booter.h #--------------------------------------------------------------------------------- else diff --git a/resources/wiiflow_game_booter/COPYING b/resources/wiiflow_game_booter/COPYING deleted file mode 100644 index 08ddefd0..00000000 --- a/resources/wiiflow_game_booter/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - 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. - - - Copyright (C) - - 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. - - , 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. - diff --git a/resources/wiiflow_game_booter/Makefile b/resources/wiiflow_game_booter/Makefile index 11944889..cb6053be 100644 --- a/resources/wiiflow_game_booter/Makefile +++ b/resources/wiiflow_game_booter/Makefile @@ -1,66 +1,117 @@ - -#PREFIX = powerpc-gekko- -PREFIX = $(DEVKITPPC)/bin/powerpc-eabi- -#PREFIX = /home/megazig/Wii/bootmii-utils/bin/powerpc-elf- - -AR = $(PREFIX)ar -AS = $(PREFIX)as -CC = $(PREFIX)gcc -CXX = $(PREFIX)g++ -LD = $(PREFIX)ld -OBJCOPY = $(PREFIX)objcopy -RANLIB = $(PREFIX)ranlib -STRIP = $(PREFIX)strip - -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 -TARGET = booter.bin - -CFILES = apploader.c cios.c cache.c debug.c di.c disc.c ios.c patchcode.c usb.c utils.c video.c \ -fst.c multidol.c wip.c main.c -#OBJS = crt0.o _all.o -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 video.o \ -fst.o multidol.o wip.o main.o - -DEPDIR = .deps - -LIBS = - -all: $(TARGET) - -%.o: %.s - @echo " ASSEMBLE $<" - @$(CC) $(CFLAGS) $(DEFINES) $(ASFLAGS) -c $< -o $@ - -%.o: %.S - @echo " ASSEMBLE $<" - @$(CC) $(CFLAGS) $(DEFINES) $(ASFLAGS) -c $< -o $@ - -%.o: %.c - @echo " COMPILE $<" - @$(CC) $(CFLAGS) $(DEFINES) -c $< -o $@ - -%.o: %.cpp - @echo " COMPILE $<" - @$(CXX) $(CFLAGS) $(DEFINES) -c $< -o $@ - -#_all.o: $(CFILES) -# @echo " COMPILE ALL " -# @mkdir -p $(DEPDIR) -# @$(CC) $(CFLAGS) $(DEFINES) -Wp,-MMD,$(DEPDIR)/$(*F).d,-MQ,"$@",-MP -c $(CFILES) -o $@ - -$(TARGET_LINKED): $(OBJS) - @echo " LINK $@" - @$(CC) -g -o $@ $(LDFLAGS) $(OBJS) $(LIBS) - -$(TARGET): $(TARGET_LINKED) - @echo " OBJCOPY $@" - @$(OBJCOPY) -O binary $< $@ - -clean: - rm -rf $(TARGET_LINKED) $(TARGET) $(OBJS) $(DEPDIR) +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") +endif + +include $(DEVKITPPC)/wii_rules + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# INCLUDES is a list of directories containing extra header files +#--------------------------------------------------------------------------------- +TARGET := booter +BUILD := build +SOURCES := source +DATA := data +INCLUDES := source +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +CFLAGS = -g -ggdb -O1 -Wall -Wextra $(MACHDEP) $(INCLUDE) -DHAVE_CONFIG_H +CXXFLAGS = $(CFLAGS) +LDFLAGS = -g -ggdb $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80B00000 + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -logc + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(CURDIR) +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- +export OUTPUT := $(CURDIR)/$(TARGET) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# 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))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) + export LD := $(CC) +else + export LD := $(CXX) +endif + +export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(sFILES:.s=.o) $(SFILES:.S=.o) +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +export INCLUDE := $(foreach dir,$(INCLUDES), -I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) \ + -I$(LIBOGC_INC) + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + -L$(LIBOGC_LIB) + +export OUTPUT := $(CURDIR)/$(TARGET) + +#--------------------------------------------------------------------------------- +.PHONY: $(BUILD) all clean +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).bin: $(OUTPUT).elf +$(OUTPUT).elf: $(OFILES) +%.bin: %.elf + @echo output ... $(notdir $(@)) + @$(OBJCOPY) -O binary $< $(@) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- diff --git a/resources/wiiflow_game_booter/README b/resources/wiiflow_game_booter/README deleted file mode 100644 index 734df4b9..00000000 --- a/resources/wiiflow_game_booter/README +++ /dev/null @@ -1,131 +0,0 @@ -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) - -Supporting code: -Copyright 2008-2009 Segher Boessenkool -Copyright 2008-2009 Andre Heider (dhewg) -Copyright 2008 Nuke - -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/ diff --git a/resources/wiiflow_game_booter/apploader.h b/resources/wiiflow_game_booter/apploader.h deleted file mode 100644 index ee01bba4..00000000 --- a/resources/wiiflow_game_booter/apploader.h +++ /dev/null @@ -1,15 +0,0 @@ -#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 diff --git a/resources/wiiflow_game_booter/cache.c b/resources/wiiflow_game_booter/cache.c deleted file mode 100644 index 50f68225..00000000 --- a/resources/wiiflow_game_booter/cache.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - 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 -// Copyright 2008-2009 Hector Martin - -#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(); -} diff --git a/resources/wiiflow_game_booter/cache.h b/resources/wiiflow_game_booter/cache.h deleted file mode 100644 index 24538eee..00000000 --- a/resources/wiiflow_game_booter/cache.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - 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 -// Copyright 2008-2009 Hector Martin - -#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 diff --git a/resources/wiiflow_game_booter/crt0.S b/resources/wiiflow_game_booter/crt0.S deleted file mode 100644 index 219649f4..00000000 --- a/resources/wiiflow_game_booter/crt0.S +++ /dev/null @@ -1,39 +0,0 @@ -/* - 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 - - .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 diff --git a/resources/wiiflow_game_booter/debug.c b/resources/wiiflow_game_booter/debug.c deleted file mode 100644 index 88970522..00000000 --- a/resources/wiiflow_game_booter/debug.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - 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 - -#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 - diff --git a/resources/wiiflow_game_booter/di.c b/resources/wiiflow_game_booter/di.c deleted file mode 100644 index 585cfb28..00000000 --- a/resources/wiiflow_game_booter/di.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - 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 - -#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"); - memset(inbuf, 0, 0x20); - - /* 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); -} diff --git a/resources/wiiflow_game_booter/di.h b/resources/wiiflow_game_booter/di.h deleted file mode 100644 index 5e6e217d..00000000 --- a/resources/wiiflow_game_booter/di.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 - -#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 \ No newline at end of file diff --git a/resources/wiiflow_game_booter/disc.c b/resources/wiiflow_game_booter/disc.c deleted file mode 100644 index c7049a78..00000000 --- a/resources/wiiflow_game_booter/disc.c +++ /dev/null @@ -1,59 +0,0 @@ -#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); -} diff --git a/resources/wiiflow_game_booter/ios.c b/resources/wiiflow_game_booter/ios.c deleted file mode 100644 index 8dcfe063..00000000 --- a/resources/wiiflow_game_booter/ios.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - 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 -// Copyright 2008-2009 Andre Heider -// Copyright 2008-2009 Hector Martin - -#include "debug.h" -#include "ios.h" -#include "cache.h" -#include "utils.h" -#include "di.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); -} diff --git a/resources/wiiflow_game_booter/ios.h b/resources/wiiflow_game_booter/ios.h deleted file mode 100644 index 81ddb4a6..00000000 --- a/resources/wiiflow_game_booter/ios.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - 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 - -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 \ No newline at end of file diff --git a/resources/wiiflow_game_booter/link.ld b/resources/wiiflow_game_booter/link.ld deleted file mode 100644 index 62a85a7f..00000000 --- a/resources/wiiflow_game_booter/link.ld +++ /dev/null @@ -1,36 +0,0 @@ -/* - 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 = .; - } -} - diff --git a/resources/wiiflow_game_booter/main.c b/resources/wiiflow_game_booter/main.c deleted file mode 100644 index f91e15c1..00000000 --- a/resources/wiiflow_game_booter/main.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - 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 -// Copyright 2008-2009 Hector Martin - -#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" -#include "video.h" -#include "fst.h" - -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 int es_fd; - -void fail(void); - -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 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; -} - -void fail(void) -{ - debug_string("\nFAILURE\n"); - void (*entrypoint)(void) = (void(*)(void))0x80001800; - entrypoint(); - 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 - -u32 hooktype; -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; - - debug_string("WiiFlow External Booter by FIX94 - based on TinyLoad v0.2\n"); - video_init(); - ipc_init(); - 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)) - ); - debug_string("Initializing DI\n"); - if(di_init() < 0) { - debug_string("di_init() failed\n"); - fail(); - } - prog10(); - - app_gameconfig_set(conf->gameconf, conf->gameconfsize); - ocarina_set_codes(conf->codelist, conf->codelistend, conf->cheats, conf->cheatSize); - debuggerselect = conf->debugger; - hooktype = conf->hooktype; - 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) { - 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("Reading partition header\n"); - FAILNOTONE(di_read((void*)0x80000000, 0x20, 0), "Failed to read partition header"); - prog10(); - - CurrentIOS = conf->IOS; - AppEntrypoint = Apploader_Run(conf->vidMode, conf->vipatch, conf->countryString, - conf->patchVidMode, conf->aspectRatio, conf->returnTo); - debug_string("Apploader complete\n"); - - prog10(); - - extern u32 vimode; - if(((u8*)disc_id)[3] == 'P' && vimode == 0) - vimode = 1; - debug_string("VI mode: "); - debug_uint(vimode); - debug_string("\n"); - - Disc_SetLowMem(); - *(vu32*)0x800000cc = vimode; - sync_after_write((void*)0x80000000, 0x3f00); - - setprog(320); - udelay(60000); - - debug_string("Game entry: "); - debug_uint(AppEntrypoint); - debug_string("\n"); - - debug_string("ok, taking the plunge\n"); - video_setblack(); - di_shutdown(); - - *(vu32*)0xCD006C00 = 0x00000000; // deinit audio due to libogc fail - - /* 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" - ); - } - fail(); -} - diff --git a/resources/wiiflow_game_booter/source/ChannelHandler.cpp b/resources/wiiflow_game_booter/source/ChannelHandler.cpp new file mode 100644 index 00000000..b596c08d --- /dev/null +++ b/resources/wiiflow_game_booter/source/ChannelHandler.cpp @@ -0,0 +1,173 @@ +/*************************************************************************** + * 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 +#include +#include +#include +#include +#include + +#include "ChannelHandler.hpp" +#include "patchcode.h" +#include "cios.h" +#include "fs.h" +#include "fst.h" +#include "lz77.h" +#include "utils.h" +#include "videopatch.h" +#include "video_tinyload.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++; + prog(5); + } + 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]); + prog(5); + } + if(hook) + ocarina_do_code(title); +} diff --git a/resources/wiiflow_game_booter/source/ChannelHandler.hpp b/resources/wiiflow_game_booter/source/ChannelHandler.hpp new file mode 100644 index 00000000..33649ac8 --- /dev/null +++ b/resources/wiiflow_game_booter/source/ChannelHandler.hpp @@ -0,0 +1,20 @@ + +#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_ */ diff --git a/resources/wiiflow_game_booter/Config.h b/resources/wiiflow_game_booter/source/Config.hpp similarity index 94% rename from resources/wiiflow_game_booter/Config.h rename to resources/wiiflow_game_booter/source/Config.hpp index 9188b683..69d19bcd 100644 --- a/resources/wiiflow_game_booter/Config.h +++ b/resources/wiiflow_game_booter/source/Config.hpp @@ -14,8 +14,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . ****************************************************************************/ -#ifndef _CFG_H_ -#define _CFG_H_ +#ifndef _CFG_HPP_ +#define _CFG_HPP_ #include "cios.h" #include "frag.h" @@ -37,8 +37,8 @@ typedef struct _the_CFG { u8 patchVidMode; u8 configbytes[2]; u8 debugger; - u8 vipatch; - u8 countryString; + bool vipatch; + bool countryString; int aspectRatio; void *codelist; u8 *codelistend; diff --git a/resources/wiiflow_game_booter/apploader.c b/resources/wiiflow_game_booter/source/apploader.c similarity index 62% rename from resources/wiiflow_game_booter/apploader.c rename to resources/wiiflow_game_booter/source/apploader.c index af27eb00..b65cc483 100644 --- a/resources/wiiflow_game_booter/apploader.c +++ b/resources/wiiflow_game_booter/source/apploader.c @@ -1,15 +1,17 @@ +#include +#include +#include +#include #include "apploader.h" +#include "wdvd.h" #include "patchcode.h" +#include "videopatch.h" #include "cios.h" #include "fst.h" #include "wip.h" -#include "debug.h" -#include "utils.h" -#include "di.h" -#include "cache.h" -#include "config.h" -#include "video.h" +#include "gecko.h" +#include "video_tinyload.h" /* Apploader function pointers */ typedef int (*app_main)(void **dst, int *size, int *offset); @@ -20,50 +22,36 @@ typedef void (*app_entry)(void (**init)(void (*report)(const char *fmt, ...)), /* Apploader pointers */ static u8 *appldr = (u8 *)0x81200000; -/* Variables */ -static u32 buffer[0x20] __attribute__((aligned(32))); +/* Constants */ +#define APPLDR_OFFSET 0x2440 -void maindolpatches(void *dst, int len, u8 vidMode, u8 vipatch, u8 countryString, u8 patchVidModes, int aspectRatio, u32 returnTo); +/* Variables */ +static u32 buffer[0x20] ATTRIBUTE_ALIGN(32); + +void maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo); static void patch_NoDiscinDrive(void *buffer, u32 len); static void Anti_002_fix(void *Address, int Size); -static u8 Remove_001_Protection(void *Address, int Size); -static u8 PrinceOfPersiaPatch(); -static u8 NewSuperMarioBrosPatch(); -u8 hookpatched = 0; -u8 wip_needed = 0; +static bool Remove_001_Protection(void *Address, int Size); +static bool PrinceOfPersiaPatch(); +static bool NewSuperMarioBrosPatch(); +bool hookpatched = false; -static void simple_report(const char *fmt, ...) +s32 Apploader_Run(entry_point *entry, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo) { - debug_string(fmt); -} + PrinceOfPersiaPatch(); + NewSuperMarioBrosPatch(); -u32 Apploader_Run(u8 vidMode, u8 vipatch, u8 countryString, u8 patchVidModes, int aspectRatio, u32 returnTo) -{ - /* Check if WIP patches are needed */ - if(PrinceOfPersiaPatch() == 1) - { - debug_string("PoP patch\n"); - wip_needed = 1; - } - else if(NewSuperMarioBrosPatch() == 1) - { - debug_string("NSMBW patch\n"); - wip_needed = 1; - } - else - { - debug_string("No WIP patch\n"); - wip_needed = 0; - } - /* Variables */ - s32 ret; + void *dst = NULL; + int len = 0; + int offset = 0; u32 appldr_len; + s32 ret; app_init appldr_init; app_main appldr_main; app_final appldr_final; /* Read apploader header */ - ret = di_read(buffer, 0x20, 0x910); + ret = WDVD_Read(buffer, 0x20, APPLDR_OFFSET); if(ret < 0) return ret; @@ -71,12 +59,13 @@ u32 Apploader_Run(u8 vidMode, u8 vipatch, u8 countryString, u8 patchVidModes, in appldr_len = buffer[5] + buffer[6]; /* Read apploader code */ - ret = di_read(appldr, appldr_len, 0x918); + ret = WDVD_Read(appldr, appldr_len, APPLDR_OFFSET + 0x20); if(ret < 0) return ret; /* Flush into memory */ - sync_after_write(appldr, appldr_len); + DCFlushRange(appldr, appldr_len); + ICInvalidateRange(appldr, appldr_len); /* Set apploader entry function */ app_entry appldr_entry = (app_entry)buffer[4]; @@ -85,28 +74,33 @@ u32 Apploader_Run(u8 vidMode, u8 vipatch, u8 countryString, u8 patchVidModes, in appldr_entry(&appldr_init, &appldr_main, &appldr_final); /* Initialize apploader */ - appldr_init(simple_report); + appldr_init(gprintf); - void *dst = NULL; - int len = 0; - int offset = 0; while(appldr_main(&dst, &len, &offset)) { /* Read data from DVD */ - di_read(dst, len, offset); - maindolpatches(dst, len, vidMode, vipatch, countryString, patchVidModes, aspectRatio, returnTo); - sync_after_write(dst, len); + WDVD_Read(dst, len, (u64)(offset << 2)); + maindolpatches(dst, len, vidMode, vmode, vipatch, countryString, patchVidModes, aspectRatio, returnTo); + DCFlushRange(dst, len); + ICInvalidateRange(dst, len); prog10(); } - if(wip_needed == 1) - free_wip(); - if(hooktype != 0 && hookpatched == 1) + + free_wip(); + if(hooktype != 0 && hookpatched) ocarina_do_code(0); + /* Set entry point from apploader */ - return (u32)appldr_final(); + *entry = appldr_final(); + + /* ERROR 002 fix (WiiPower) */ + *(u32 *)0x80003140 = *(u32 *)0x80003188; + DCFlushRange((void*)0x80000000, 0x3f00); + + return 0; } -void maindolpatches(void *dst, int len, u8 vidMode, u8 vipatch, u8 countryString, u8 patchVidModes, int aspectRatio, u32 returnTo) +void maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo) { // 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) @@ -114,21 +108,21 @@ void maindolpatches(void *dst, int len, u8 vidMode, u8 vipatch, u8 countryString if(CurrentIOS.Type == IOS_TYPE_WANIN && CurrentIOS.Revision < 13) Anti_002_fix(dst, len); Remove_001_Protection(dst, len); - //patchVideoModes(dst, len, vidMode, vmode, patchVidModes); - if(hooktype != 0 && dogamehooks(dst, len, 0)) - hookpatched = 1; - if(vipatch == 1) + + patchVideoModes(dst, len, vidMode, vmode, patchVidModes); + if(hooktype != 0 && dogamehooks(dst, len, false)) + hookpatched = true; + if(vipatch) vidolpatcher(dst, len); if(configbytes[0] != 0xCD) langpatcher(dst, len); - //if(conf->countryString) - // PatchCountryStrings(dst, len); // Country Patch by WiiPower + if(countryString) + PatchCountryStrings(dst, len); // Country Patch by WiiPower if(aspectRatio != -1) PatchAspectRatio(dst, len, aspectRatio); - if(returnTo > 0) + if(returnTo) PatchReturnTo(dst, len, returnTo); - if(wip_needed == 1) - do_wip_code((u8*)dst, len); + do_wip_code((u8 *)dst, len); } static void patch_NoDiscinDrive(void *buffer, u32 len) @@ -160,12 +154,12 @@ static void Anti_002_fix(void *Address, int Size) } } - -static u8 PrinceOfPersiaPatch() +static bool PrinceOfPersiaPatch() { - if(memcmp("SPX", (char *)0x80000000, 3) != 0 && memcmp("RPW", (char *) 0x80000000, 3) != 0) - return 0; - WIP_Code CodeList[5*sizeof(WIP_Code)]; + if (memcmp("SPX", (char *) 0x80000000, 3) != 0 && memcmp("RPW", (char *) 0x80000000, 3) != 0) + return false; + + WIP_Code * CodeList = malloc(5 * sizeof(WIP_Code)); CodeList[0].offset = 0x007AAC6A; CodeList[0].srcaddress = 0x7A6B6F6A; CodeList[0].dstaddress = 0x6F6A7A6B; @@ -181,16 +175,26 @@ static u8 PrinceOfPersiaPatch() CodeList[4].offset = 0x007AAC9D; CodeList[4].srcaddress = 0x82806F3F; CodeList[4].dstaddress = 0x6F3F8280; - set_wip_list(CodeList, 5); - return 1; + + if (set_wip_list(CodeList, 5) == false) + { + free(CodeList); + CodeList = NULL; + return false; + } + + return true; } -static u8 NewSuperMarioBrosPatch() +static bool NewSuperMarioBrosPatch() { - WIP_Code CodeList[3 * sizeof(WIP_Code)]; + WIP_Code * CodeList = NULL; - 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].srcaddress = 0x9421FFD0; CodeList[0].dstaddress = 0x4E800020; @@ -200,11 +204,12 @@ static u8 NewSuperMarioBrosPatch() CodeList[2].offset = 0x001CED6B; CodeList[2].srcaddress = 0xDA000000; CodeList[2].dstaddress = 0x71000000; - set_wip_list(CodeList, 3); - return 1; } - 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].srcaddress = 0x9421FFD0; CodeList[0].dstaddress = 0x4E800020; @@ -214,11 +219,12 @@ static u8 NewSuperMarioBrosPatch() CodeList[2].offset = 0x001CEEA8; CodeList[2].srcaddress = 0x388000DA; CodeList[2].dstaddress = 0x38800071; - set_wip_list(CodeList, 3); - return 1; } - 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].srcaddress = 0x9421FFD0; CodeList[0].dstaddress = 0x4E800020; @@ -228,13 +234,17 @@ static u8 NewSuperMarioBrosPatch() CodeList[2].offset = 0x001CEB7B; CodeList[2].srcaddress = 0xDA000000; CodeList[2].dstaddress = 0x71000000; - set_wip_list(CodeList, 3); - return 1; } - return 0; + if (CodeList && set_wip_list(CodeList, 3) == false) + { + free(CodeList); + CodeList = NULL; + return false; + } + return CodeList != NULL; } -static u8 Remove_001_Protection(void *Address, int Size) +static bool 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 PatchData[] = {0x40, 0x82, 0x00, 0x04, 0x38, 0x60, 0x00, 0x01, 0x48, 0x00, 0x02, 0x44, 0x38, 0x61, 0x00, 0x18}; @@ -246,8 +256,8 @@ static u8 Remove_001_Protection(void *Address, int Size) if (memcmp(Addr, SearchPattern, sizeof SearchPattern) == 0) { memcpy(Addr, PatchData, sizeof PatchData); - return 1; + return true; } } - return 0; -} + return false; +} \ No newline at end of file diff --git a/resources/wiiflow_game_booter/source/apploader.h b/resources/wiiflow_game_booter/source/apploader.h new file mode 100644 index 00000000..ae80dc60 --- /dev/null +++ b/resources/wiiflow_game_booter/source/apploader.h @@ -0,0 +1,18 @@ +#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 diff --git a/resources/wiiflow_game_booter/cios.c b/resources/wiiflow_game_booter/source/cios.c similarity index 79% rename from resources/wiiflow_game_booter/cios.c rename to resources/wiiflow_game_booter/source/cios.c index d621e44a..6013ca3a 100644 --- a/resources/wiiflow_game_booter/cios.c +++ b/resources/wiiflow_game_booter/source/cios.c @@ -24,24 +24,27 @@ * 3. This notice may not be removed or altered from any source * distribution. ***************************************************************************/ -#include "cios.h" -#include "debug.h" -#include "ios.h" +#include +#include +#include -u8 Hermes_shadow_mload(int mload_rev) +#include "cios.h" +#include "gecko.h" + +bool Hermes_shadow_mload(int mload_rev) { int v51 = (5 << 4) & 1; if(mload_rev >= v51) { - ios_open("/dev/mload/OFF",0); // shadow /dev/mload supported in hermes cios v5.1 - debug_string("Shadow mload\n"); - return 1; + IOS_Open("/dev/mload/OFF",0); // shadow /dev/mload supported in hermes cios v5.1 + gprintf("Shadow mload\n"); + return true; } - return 0; + return false; } void Hermes_Disable_EHC() { - ios_open("/dev/usb123/OFF", 0);// this disables ehc completely - debug_string("Hermes EHC Disabled\n"); + IOS_Open("/dev/usb123/OFF", 0);// this disables ehc completely + gprintf("Hermes EHC Disabled\n"); } diff --git a/resources/wiiflow_game_booter/cios.h b/resources/wiiflow_game_booter/source/cios.h similarity index 79% rename from resources/wiiflow_game_booter/cios.h rename to resources/wiiflow_game_booter/source/cios.h index c1d153b5..4b77a946 100644 --- a/resources/wiiflow_game_booter/cios.h +++ b/resources/wiiflow_game_booter/source/cios.h @@ -2,6 +2,7 @@ #ifndef _CIOSINFO_H_ #define _CIOSINFO_H_ +#include #include "types.h" #ifdef __cplusplus @@ -23,8 +24,14 @@ typedef struct _IOS_Info { u8 Type; u8 Base; } IOS_Info; + extern IOS_Info CurrentIOS; -u8 Hermes_shadow_mload(int mload_rev); +void IOS_GetCurrentIOSInfo(); + +bool IOS_D2X(u8 ios, u8 *base); +u8 IOS_GetType(u8 slot); + +bool Hermes_shadow_mload(int mload_rev); void Hermes_Disable_EHC(); #ifdef __cplusplus diff --git a/resources/wiiflow_game_booter/codehandler.h b/resources/wiiflow_game_booter/source/codehandler.h similarity index 100% rename from resources/wiiflow_game_booter/codehandler.h rename to resources/wiiflow_game_booter/source/codehandler.h diff --git a/resources/wiiflow_game_booter/codehandleronly.h b/resources/wiiflow_game_booter/source/codehandleronly.h similarity index 100% rename from resources/wiiflow_game_booter/codehandleronly.h rename to resources/wiiflow_game_booter/source/codehandleronly.h diff --git a/resources/wiiflow_game_booter/source/disc.c b/resources/wiiflow_game_booter/source/disc.c new file mode 100644 index 00000000..9fb7b35c --- /dev/null +++ b/resources/wiiflow_game_booter/source/disc.c @@ -0,0 +1,265 @@ +#include +#include +#include +#include +#include +#include +#include + +#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); +} diff --git a/resources/wiiflow_game_booter/disc.h b/resources/wiiflow_game_booter/source/disc.h similarity index 70% rename from resources/wiiflow_game_booter/disc.h rename to resources/wiiflow_game_booter/source/disc.h index b3503a85..a959e5b6 100644 --- a/resources/wiiflow_game_booter/disc.h +++ b/resources/wiiflow_game_booter/source/disc.h @@ -6,14 +6,15 @@ extern "C" { #endif /* __cplusplus */ -/*s32 Disc_Open(); -s32 Disc_FindPartition(u64 *outbuf);*/ -s32 Disc_SetUSB(const u8 *id, u8 frag); +s32 Disc_Open(); +s32 Disc_FindPartition(u64 *outbuf); +s32 Disc_SetUSB(const u8 *id, bool frag); void Disc_SetLowMem(); -/* +void Disc_SetTime(); + GXRModeObj *Disc_SelectVMode(u8 videoselected, u32 *rmode_reg); void Disc_SetVMode(GXRModeObj *rmode, u32 rmode_reg); -*/ + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/resources/wiiflow_game_booter/frag.h b/resources/wiiflow_game_booter/source/frag.h similarity index 90% rename from resources/wiiflow_game_booter/frag.h rename to resources/wiiflow_game_booter/source/frag.h index 89d5efed..783a1658 100644 --- a/resources/wiiflow_game_booter/frag.h +++ b/resources/wiiflow_game_booter/source/frag.h @@ -9,7 +9,7 @@ extern "C" { #endif -#include "types.h" +#include "gctypes.h" typedef struct { diff --git a/resources/wiiflow_game_booter/source/fs.c b/resources/wiiflow_game_booter/source/fs.c new file mode 100644 index 00000000..f46eb838 --- /dev/null +++ b/resources/wiiflow_game_booter/source/fs.c @@ -0,0 +1,48 @@ + +#include +#include +#include +#include +#include + +#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; +} diff --git a/resources/wiiflow_game_booter/source/fs.h b/resources/wiiflow_game_booter/source/fs.h new file mode 100644 index 00000000..619057dd --- /dev/null +++ b/resources/wiiflow_game_booter/source/fs.h @@ -0,0 +1,15 @@ +#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 + diff --git a/resources/wiiflow_game_booter/fst.c b/resources/wiiflow_game_booter/source/fst.c similarity index 86% rename from resources/wiiflow_game_booter/fst.c rename to resources/wiiflow_game_booter/source/fst.c index cdcc45a7..cc5a4d50 100644 --- a/resources/wiiflow_game_booter/fst.c +++ b/resources/wiiflow_game_booter/source/fst.c @@ -18,10 +18,16 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "types.h" -#include "utils.h" -#include "cache.h" +#include +#include +#include +#include +#include +#include + #include "fst.h" +#include "gecko.h" +#include "memory.h" #include "patchcode.h" #include "codehandler.h" #include "codehandleronly.h" @@ -68,21 +74,19 @@ void ocarina_set_codes(void *list, u8 *listend, u8 *cheats, u32 cheatSize) code_size = cheatSize; if(code_size <= 0) { - //printf("Ocarina: No codes found\n"); + gprintf("Ocarina: No codes found\n"); code_buf = NULL; code_size = 0; return; } - if (code_size > (u32)codelistend - (u32)codelist) { - //printf("Ocarina: Too many codes found\n"); + gprintf("Ocarina: Too many codes found\n"); code_buf = NULL; code_size = 0; return; } - - //printf("Ocarina: Codes found.\n"); + gprintf("Ocarina: Codes found.\n"); } void app_pokevalues() @@ -99,7 +103,7 @@ void app_pokevalues() *((u32 *) (*(gameconf + i + 1))) == *(gameconf + i + 2)) { *((u32 *) (*(gameconf + i + 3))) = *(gameconf + i + 4); - sync_after_write((void *) *(gameconf + i + 3), 4); + DCFlushRange((void *) *(gameconf + i + 3), 4); } i += 4; } @@ -149,7 +153,7 @@ void load_handler() memcpy((void*)0x80001CE2, ((u8*) &codelist) + 2, 2); memcpy((void*)0x80001F5A, &codelist, 2); memcpy((void*)0x80001F5E, ((u8*) &codelist) + 2, 2); - sync_after_write((void*)0x80001800,codehandler_size); + DCFlushRange((void*)0x80001800,codehandler_size); } else { @@ -158,13 +162,13 @@ void load_handler() memcpy((void*)0x80001800,codehandleronly,codehandleronly_size); memcpy((void*)0x80001906, &codelist, 2); memcpy((void*)0x8000190A, ((u8*) &codelist) + 2, 2); - sync_after_write((void*)0x80001800,codehandleronly_size); + DCFlushRange((void*)0x80001800,codehandleronly_size); } // Load multidol handler memset((void*)0x80001000,0,multidol_size); memcpy((void*)0x80001000,multidol,multidol_size); - sync_after_write((void*)0x80001000,multidol_size); + DCFlushRange((void*)0x80001000,multidol_size); switch(hooktype) { case 0x01: @@ -211,7 +215,7 @@ void load_handler() //memcpy((void*)0x80001198,wpadbuttonsdown2hooks+3,4); break; } - sync_after_write((void*)0x80001198,16); + DCFlushRange((void*)0x80001198,16); } memcpy((void *)0x80001800, (void*)0x80000000, 6); } @@ -223,22 +227,20 @@ int ocarina_do_code(u64 chantitle) memset((void *)0x80001800, 0, 0x1800); char gameidbuffer[8]; + memset(gameidbuffer, 0, 8); if(chantitle != 0) { - memset(gameidbuffer, 0, 8); gameidbuffer[0] = (chantitle & 0xff000000) >> 24; gameidbuffer[1] = (chantitle & 0x00ff0000) >> 16; gameidbuffer[2] = (chantitle & 0x0000ff00) >> 8; gameidbuffer[3] = chantitle & 0x000000ff; } + else + strncpy(gameidbuffer, (char*)Disc_ID, 6); load_handler(); + memcpy((void *)0x80001800, gameidbuffer, 8); + DCFlushRange((void *)0x80001800, 8); - if(chantitle != 0) - { - memcpy((void *)0x80001800, gameidbuffer, 8); - sync_after_write((void *)0x80001800, 8); - } - if(codelist) memset(codelist, 0, (u32)codelistend - (u32)codelist); @@ -246,7 +248,7 @@ int ocarina_do_code(u64 chantitle) if(code_size > 0 && code_buf) { memcpy(codelist, code_buf, code_size); - sync_after_write(codelist, (u32)codelistend - (u32)codelist); + DCFlushRange(codelist, (u32)codelistend - (u32)codelist); } // TODO What's this??? diff --git a/resources/wiiflow_game_booter/fst.h b/resources/wiiflow_game_booter/source/fst.h similarity index 100% rename from resources/wiiflow_game_booter/fst.h rename to resources/wiiflow_game_booter/source/fst.h diff --git a/resources/wiiflow_game_booter/source/gecko.c b/resources/wiiflow_game_booter/source/gecko.c new file mode 100644 index 00000000..f339d2d6 --- /dev/null +++ b/resources/wiiflow_game_booter/source/gecko.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include +#include +#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; +} diff --git a/resources/wiiflow_game_booter/source/gecko.h b/resources/wiiflow_game_booter/source/gecko.h new file mode 100644 index 00000000..d42b973f --- /dev/null +++ b/resources/wiiflow_game_booter/source/gecko.h @@ -0,0 +1,23 @@ + +#ifndef _GECKO_H_ +#define _GECKO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +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 diff --git a/resources/wiiflow_game_booter/source/lz77.c b/resources/wiiflow_game_booter/source/lz77.c new file mode 100644 index 00000000..f44230c3 --- /dev/null +++ b/resources/wiiflow_game_booter/source/lz77.c @@ -0,0 +1,215 @@ +/******************************************************************************* + * 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 +#include +#include +#include +#include + +#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; +} diff --git a/resources/wiiflow_game_booter/source/lz77.h b/resources/wiiflow_game_booter/source/lz77.h new file mode 100644 index 00000000..ebaf0b5e --- /dev/null +++ b/resources/wiiflow_game_booter/source/lz77.h @@ -0,0 +1,34 @@ +/******************************************************************************* + * 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 + diff --git a/resources/wiiflow_game_booter/source/main.cpp b/resources/wiiflow_game_booter/source/main.cpp new file mode 100644 index 00000000..771757f9 --- /dev/null +++ b/resources/wiiflow_game_booter/source/main.cpp @@ -0,0 +1,198 @@ +/**************************************************************************** + * 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 . + ****************************************************************************/ +#include +#include +#include +#include +#include +#include + +#include "Config.hpp" +#include "ChannelHandler.hpp" +#include "video_tinyload.h" +#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() +{ + InitGecko(); + gprintf("WiiFlow External Booter by FIX94\n"); + memcpy(&normalCFG, (void*)0x93100000, sizeof(the_CFG)); + VIDEO_Init(); + video_init(); + prog10(); + + 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); + } + prog10(); + Disc_Open(); + Disc_SetLowMem(); + prog10(); + u64 offset = 0; + Disc_FindPartition(&offset); + WDVD_OpenPartition(offset); + vmode = Disc_SelectVMode(normalCFG.vidMode, &vmode_reg); + prog10(); + 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(); + prog10(); + 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); + setprog(320); + + /* 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; +} diff --git a/resources/wiiflow_game_booter/memory.h b/resources/wiiflow_game_booter/source/memory.h similarity index 100% rename from resources/wiiflow_game_booter/memory.h rename to resources/wiiflow_game_booter/source/memory.h diff --git a/resources/wiiflow_game_booter/multidol.c b/resources/wiiflow_game_booter/source/multidol.c similarity index 100% rename from resources/wiiflow_game_booter/multidol.c rename to resources/wiiflow_game_booter/source/multidol.c diff --git a/resources/wiiflow_game_booter/multidol.h b/resources/wiiflow_game_booter/source/multidol.h similarity index 100% rename from resources/wiiflow_game_booter/multidol.h rename to resources/wiiflow_game_booter/source/multidol.h diff --git a/resources/wiiflow_game_booter/patchcode.c b/resources/wiiflow_game_booter/source/patchcode.c similarity index 90% rename from resources/wiiflow_game_booter/patchcode.c rename to resources/wiiflow_game_booter/source/patchcode.c index 25980d4d..2ab92e3d 100644 --- a/resources/wiiflow_game_booter/patchcode.c +++ b/resources/wiiflow_game_booter/source/patchcode.c @@ -18,11 +18,14 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "utils.h" +#include +#include +#include +#include +#include + #include "apploader.h" #include "patchcode.h" -#include "cache.h" -#include "debug.h" u32 hooktype; u8 configbytes[2]; @@ -97,7 +100,7 @@ const u32 langpatch[3] = {0x7C600775, 0x40820010, 0x38000000}; static const u32 oldpatch002[3] = {0x2C000000, 0x40820214, 0x3C608000}; static const u32 newpatch002[3] = {0x2C000000, 0x48000214, 0x3C608000}; -u8 dogamehooks(void *addr, u32 len, u8 channel) +bool dogamehooks(void *addr, u32 len, bool channel) { /* 0 No Hook @@ -112,21 +115,21 @@ u8 dogamehooks(void *addr, u32 len, u8 channel) void *addr_start = addr; void *addr_end = addr+len; - u8 hookpatched = 0; + bool hookpatched = false; while(addr_start < addr_end) { switch(hooktype) { case 0x00: - hookpatched = 1; + hookpatched = true; break; case 0x01: if(memcmp(addr_start, viwiihooks, sizeof(viwiihooks))==0) { patchhook((u32)addr_start, len); - hookpatched = 1; + hookpatched = true; } break; @@ -134,13 +137,13 @@ u8 dogamehooks(void *addr, u32 len, u8 channel) if(memcmp(addr_start, kpadhooks, sizeof(kpadhooks))==0) { patchhook((u32)addr_start, len); - hookpatched = 1; + hookpatched = true; } if(memcmp(addr_start, kpadoldhooks, sizeof(kpadoldhooks))==0) { patchhook((u32)addr_start, len); - hookpatched = 1; + hookpatched = true; } break; @@ -148,7 +151,7 @@ u8 dogamehooks(void *addr, u32 len, u8 channel) if(memcmp(addr_start, joypadhooks, sizeof(joypadhooks))==0) { patchhook((u32)addr_start, len); - hookpatched = 1; + hookpatched = true; } break; @@ -156,7 +159,7 @@ u8 dogamehooks(void *addr, u32 len, u8 channel) if(memcmp(addr_start, gxdrawhooks, sizeof(gxdrawhooks))==0) { patchhook((u32)addr_start, len); - hookpatched = 1; + hookpatched = true; } break; @@ -164,7 +167,7 @@ u8 dogamehooks(void *addr, u32 len, u8 channel) if(memcmp(addr_start, gxflushhooks, sizeof(gxflushhooks))==0) { patchhook((u32)addr_start, len); - hookpatched = 1; + hookpatched = true; } break; @@ -172,7 +175,7 @@ u8 dogamehooks(void *addr, u32 len, u8 channel) if(memcmp(addr_start, ossleepthreadhooks, sizeof(ossleepthreadhooks))==0) { patchhook((u32)addr_start, len); - hookpatched = 1; + hookpatched = true; } break; @@ -180,7 +183,7 @@ u8 dogamehooks(void *addr, u32 len, u8 channel) if(memcmp(addr_start, axnextframehooks, sizeof(axnextframehooks))==0) { patchhook((u32)addr_start, len); - hookpatched = 1; + hookpatched = true; } break; @@ -188,7 +191,7 @@ u8 dogamehooks(void *addr, u32 len, u8 channel) /* if(memcmp(addr_start, customhook, customhooksize)==0) { patchhook((u32)addr_start, len); - hookpatched = 1; + hookpatched = true; } */ break; } @@ -197,15 +200,15 @@ u8 dogamehooks(void *addr, u32 len, u8 channel) if(channel && memcmp(addr_start, multidolchanhooks, sizeof(multidolchanhooks))==0) { *(((u32*)addr_start)+1) = 0x7FE802A6; - sync_after_write(((u32*)addr_start)+1, 4); + DCFlushRange(((u32*)addr_start)+1, 4); multidolhook((u32)addr_start+sizeof(multidolchanhooks)-4); - hookpatched = 1; + hookpatched = true; } else if(!channel && memcmp(addr_start, multidolhooks, sizeof(multidolhooks))==0) { multidolhook((u32)addr_start+sizeof(multidolhooks)-4); - hookpatched = 1; + hookpatched = true; } } addr_start += 4; @@ -251,12 +254,11 @@ 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 returnToPatched = 0; -u8 PatchReturnTo( void *Address, int Size, u32 id ) +bool PatchReturnTo( void *Address, int Size, u32 id ) { - if(returnToPatched == 1) + if( !id || returnToPatched ) return 0; //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) u8 SearchPattern[ 12 ] = { 0x38, 0x80, 0x00, 0x02, 0x38, 0x60, 0x00, 0x01, 0x38, 0xa0, 0x00, 0x00 }; //li r4,2 @@ -356,7 +358,6 @@ u8 PatchReturnTo( void *Address, int Size, u32 id ) addr = (u32*)ad[ 0 ]; memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ] 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 ); //ES_GetTicketViews() again @@ -366,7 +367,6 @@ u8 PatchReturnTo( void *Address, int Size, u32 id ) addr = (u32*)ad[ 1 ]; memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ] 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 ); //ES_LaunchTitle() @@ -376,7 +376,6 @@ u8 PatchReturnTo( void *Address, int Size, u32 id ) addr = (u32*)ad[ 2 ]; memcpy( addr, &newval, sizeof( u32 ) ); //bl ad[ 3 ] 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 ); returnToPatched = 1; @@ -414,7 +413,7 @@ void PatchAspectRatio(void *addr, u32 len, u8 aspect) addr_start += 4; } } -#if 0 + void PatchCountryStrings(void *Address, int Size) { u8 SearchPattern[4] = {0x00, 0x00, 0x00, 0x00}; @@ -491,4 +490,3 @@ void PatchCountryStrings(void *Address, int Size) } } } -#endif \ No newline at end of file diff --git a/resources/wiiflow_game_booter/patchcode.h b/resources/wiiflow_game_booter/source/patchcode.h similarity index 89% rename from resources/wiiflow_game_booter/patchcode.h rename to resources/wiiflow_game_booter/source/patchcode.h index 3d6797ef..41c13dc1 100644 --- a/resources/wiiflow_game_booter/patchcode.h +++ b/resources/wiiflow_game_booter/source/patchcode.h @@ -30,12 +30,12 @@ extern u32 hooktype; extern u8 configbytes[2]; // Function prototypes -u8 dogamehooks(void *addr, u32 len, u8 channel); +bool dogamehooks(void *addr, u32 len, bool channel); void langpatcher(void *addr, u32 len); void vidolpatcher(void *addr, u32 len); void PatchCountryStrings(void *Address, int Size); void PatchAspectRatio(void *addr, u32 len, u8 aspect); -u8 PatchReturnTo(void *Address, int Size, u32 id); +bool PatchReturnTo(void *Address, int Size, u32 id); #ifdef __cplusplus } diff --git a/resources/wiiflow_game_booter/patchhook.S b/resources/wiiflow_game_booter/source/patchhook.S similarity index 100% rename from resources/wiiflow_game_booter/patchhook.S rename to resources/wiiflow_game_booter/source/patchhook.S diff --git a/resources/wiiflow_game_booter/source/types.h b/resources/wiiflow_game_booter/source/types.h new file mode 100644 index 00000000..a13c89b1 --- /dev/null +++ b/resources/wiiflow_game_booter/source/types.h @@ -0,0 +1,43 @@ + +#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 \ No newline at end of file diff --git a/resources/wiiflow_game_booter/source/utils.h b/resources/wiiflow_game_booter/source/utils.h new file mode 100644 index 00000000..67f2a90f --- /dev/null +++ b/resources/wiiflow_game_booter/source/utils.h @@ -0,0 +1,26 @@ + +#ifndef _UTILS_H_ +#define _UTILS_H_ + +#include + +#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 diff --git a/resources/wiiflow_game_booter/video.c b/resources/wiiflow_game_booter/source/video_tinyload.c similarity index 71% rename from resources/wiiflow_game_booter/video.c rename to resources/wiiflow_game_booter/source/video_tinyload.c index b29062a8..42ce8709 100644 --- a/resources/wiiflow_game_booter/video.c +++ b/resources/wiiflow_game_booter/source/video_tinyload.c @@ -1,3 +1,15 @@ +/* + 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 +// Copyright 2008-2009 Hector Martin +#include +#include #include "utils.h" #define COLOR_BLACK 0x00800080 @@ -17,6 +29,15 @@ u32 vto,vte; u64 oldvtovte; int progress = 20; +void memset32(u32 *addr, u32 data, u32 count) +{ + int sc = count; + void *sa = addr; + while(count--) + *addr++ = data; + DCFlushRange(sa, 4*sc); +} + static void drawbar(int pix) { int i = 16; @@ -79,10 +100,3 @@ void video_init(void) prog(0); } - -void video_setblack(void) -{ - /* this sets VI to black, but I can't fit it in yet... */ - viw(0x0, oldvtrdcr); - *(vu64*)(0xCC00200c) = oldvtovte; -} diff --git a/resources/wiiflow_game_booter/debug.h b/resources/wiiflow_game_booter/source/video_tinyload.h similarity index 55% rename from resources/wiiflow_game_booter/debug.h rename to resources/wiiflow_game_booter/source/video_tinyload.h index a6ae3fe6..788db11e 100644 --- a/resources/wiiflow_game_booter/debug.h +++ b/resources/wiiflow_game_booter/source/video_tinyload.h @@ -7,23 +7,21 @@ /* This code comes from HBC's stub which was based on dhewg's geckoloader stub */ // Copyright 2008-2009 Andre Heider +// Copyright 2008-2009 Hector Martin +#ifndef _VIDEO_TINYLOAD_H_ +#define _VIDEO_TINYLOAD_H_ -#ifndef _STUB_DEBUG_H_ -#define _STUB_DEBUG_H_ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ -#include "types.h" +void video_init(void); +void prog(int p); +void prog10(void); +void setprog(int p); -#ifdef DEBUG - -void debug_uint (u32 i); -void debug_string (const char *s); - -#else - -#define debug_uint(x) -#define debug_string(x) +#ifdef __cplusplus +} +#endif /* __cplusplus */ #endif - -#endif - diff --git a/resources/wiiflow_game_booter/source/videopatch.c b/resources/wiiflow_game_booter/source/videopatch.c new file mode 100644 index 00000000..9b4a2632 --- /dev/null +++ b/resources/wiiflow_game_booter/source/videopatch.c @@ -0,0 +1,317 @@ +// Inspired by WiiPower's "video toy", but simpler + +#include "videopatch.h" + +#include + +#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; + } + } +} diff --git a/resources/wiiflow_game_booter/source/videopatch.h b/resources/wiiflow_game_booter/source/videopatch.h new file mode 100644 index 00000000..7d1bbabf --- /dev/null +++ b/resources/wiiflow_game_booter/source/videopatch.h @@ -0,0 +1,16 @@ +#ifndef _VIDEOPATCH_H_ +#define _VIDEOPATCH_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void patchVideoModes(void *dst, u32 len, int vidMode, GXRModeObj *vmode, int patchVidModes); + +#ifdef __cplusplus +} +#endif + +#endif // !defined(_VIDEOPATCH_H_) diff --git a/resources/wiiflow_game_booter/source/wdvd.c b/resources/wiiflow_game_booter/source/wdvd.c new file mode 100644 index 00000000..e2905524 --- /dev/null +++ b/resources/wiiflow_game_booter/source/wdvd.c @@ -0,0 +1,410 @@ +#include +#include +#include +#include +#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; +} diff --git a/resources/wiiflow_game_booter/source/wdvd.h b/resources/wiiflow_game_booter/source/wdvd.h new file mode 100644 index 00000000..16028882 --- /dev/null +++ b/resources/wiiflow_game_booter/source/wdvd.h @@ -0,0 +1,37 @@ +#ifndef _WDVD_H_ +#define _WDVD_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Prototypes */ +s32 WDVD_Init(void); +s32 WDVD_Close(void); +s32 WDVD_GetHandle(void); +s32 WDVD_Reset(void); +s32 WDVD_ReadDiskId(void *); +s32 WDVD_Seek(u64); +s32 WDVD_Offset(u64); +s32 WDVD_StopLaser(void); +s32 WDVD_StopMotor(void); +s32 WDVD_OpenPartition(u64 offset); +s32 WDVD_ClosePartition(void); +s32 WDVD_UnencryptedRead(void *, u32, u64); +s32 WDVD_Read(void *, u32, u64); +s32 WDVD_LowRequestError(u32 *error); +s32 WDVD_WaitForDisc(void); +s32 WDVD_GetCoverStatus(u32 *); +s32 WDVD_SetUSBMode(u32, const u8 *, s32); +s32 WDVD_Eject(void); +s32 WDVD_Read_Disc_BCA(void *); +s32 WDVD_SetFragList(int device, void *fraglist, int size); +s32 WDVD_SetStreaming(void); +s32 WDVD_NEEK_LoadDisc(u32 id, u32 magic); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/resources/wiiflow_game_booter/source/wip.c b/resources/wiiflow_game_booter/source/wip.c new file mode 100644 index 00000000..1e2cb489 --- /dev/null +++ b/resources/wiiflow_game_booter/source/wip.c @@ -0,0 +1,141 @@ + +#include +#include +#include +#include +#include +#include "wip.h" +#include "gecko.h" + +static WIP_Code * CodeList = NULL; +static u32 CodesCount = 0; +static u32 ProcessedLength = 0; +static u32 Counter = 0; + +void do_wip_code(u8 * dst, u32 len) +{ + if(!CodeList) + return; + + if(Counter < 3) + { + Counter++; + return; + } + + u32 i = 0; + s32 n = 0; + s32 offset = 0; + + for(i = 0; i < CodesCount; i++) + { + for(n = 0; n < 4; n++) + { + offset = CodeList[i].offset+n-ProcessedLength; + + if(offset < 0 || (u32)offset >= len) + continue; + + if(dst[offset] == ((u8 *)&CodeList[i].srcaddress)[n]) + { + dst[offset] = ((u8 *)&CodeList[i].dstaddress)[n]; + gprintf("WIP: %08X Address Patched.\n", CodeList[i].offset + n); + } + else + { + gprintf("WIP: %08X Address does not match with WIP entry.\n", CodeList[i].offset+n); + gprintf("Destination: %02X | Should be: %02X.\n", dst[offset], ((u8 *)&CodeList[i].srcaddress)[n]); + } + } + } + ProcessedLength += len; + Counter++; +} + +//! for internal patches only +//! .wip files override internal patches +//! the codelist has to be freed if the set fails +//! if set was successful the codelist will be freed when it's done +bool set_wip_list(WIP_Code * list, int size) +{ + if(!CodeList && size > 0) + { + CodeList = list; + CodesCount = size; + return true; + } + + return false; +} + +void wip_reset_counter() +{ + ProcessedLength = 0; + //alternative dols don't need a skip. only main.dol. + Counter = 3; +} + +void free_wip() +{ + if(CodeList) + free(CodeList); + + CodesCount = 0; + ProcessedLength = 0; +} + +int load_wip_patches(u8 *dir, u8 *gameid) +{ + char filepath[150]; + char GameID[8]; + memset(GameID, 0, sizeof(GameID)); + memcpy(GameID, gameid, 6); + snprintf(filepath, sizeof(filepath), "%s/%s.wip", dir, GameID); + + FILE *fp = fopen(filepath, "rb"); + if(!fp) + { + memset(GameID, 0, sizeof(GameID)); + memcpy(GameID, gameid, 3); + snprintf(filepath, sizeof(filepath), "%s/%s.wip", dir, GameID); + fp = fopen(filepath, "rb"); + } + + if(!fp) + return -1; + + char line[255]; + //printf("\nLoading WIP code from %s.\n", filepath); + + while(fgets(line, sizeof(line), fp)) + { + if(line[0] == '#' || strlen(line) < 26) + continue; + + u32 offset = (u32) strtoul(line, NULL, 16); + u32 srcaddress = (u32) strtoul(line+9, NULL, 16); + u32 dstaddress = (u32) strtoul(line+18, NULL, 16); + + if(!CodeList) + CodeList = malloc(sizeof(WIP_Code)); + + WIP_Code *tmp = realloc(CodeList, (CodesCount+1)*sizeof(WIP_Code)); + if(!tmp) + { + free(CodeList); + fclose(fp); + return -1; + } + + CodeList = tmp; + + CodeList[CodesCount].offset = offset; + CodeList[CodesCount].srcaddress = srcaddress; + CodeList[CodesCount].dstaddress = dstaddress; + CodesCount++; + } + fclose(fp); + //printf("\n"); + + return 0; +} diff --git a/resources/wiiflow_game_booter/wip.h b/resources/wiiflow_game_booter/source/wip.h similarity index 67% rename from resources/wiiflow_game_booter/wip.h rename to resources/wiiflow_game_booter/source/wip.h index a369f385..bdb6343f 100644 --- a/resources/wiiflow_game_booter/wip.h +++ b/resources/wiiflow_game_booter/source/wip.h @@ -12,9 +12,11 @@ typedef struct u32 dstaddress; } WIP_Code; -u8 set_wip_list(WIP_Code *list, int size); +bool set_wip_list(WIP_Code *list, int size); +void wip_reset_counter(); void free_wip(); void do_wip_code(u8 *dst, u32 len); +int load_wip_patches(u8 *dir, u8 *gameid); #ifdef __cplusplus } diff --git a/resources/wiiflow_game_booter/types.h b/resources/wiiflow_game_booter/types.h deleted file mode 100644 index c6a735e4..00000000 --- a/resources/wiiflow_game_booter/types.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - 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 - -#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 - diff --git a/resources/wiiflow_game_booter/usb.c b/resources/wiiflow_game_booter/usb.c deleted file mode 100644 index 44fe91c5..00000000 --- a/resources/wiiflow_game_booter/usb.c +++ /dev/null @@ -1,221 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * 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 - - * - *---------------------------------------------------------------------------------------------*/ - - -#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 diff --git a/resources/wiiflow_game_booter/usb.h b/resources/wiiflow_game_booter/usb.h deleted file mode 100644 index 4e3c3c74..00000000 --- a/resources/wiiflow_game_booter/usb.h +++ /dev/null @@ -1,41 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * USB Gecko Development Kit - http://www.usbgecko.com - * -------------------------------------------------------------------------------------------- - * - * - * usb.h - functions for the USB Gecko adapter (www.usbgecko.com). - * - * Copyright (c) 2008 - Nuke - - * - *---------------------------------------------------------------------------------------------*/ - -#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__ diff --git a/resources/wiiflow_game_booter/utils.c b/resources/wiiflow_game_booter/utils.c deleted file mode 100644 index 2ed2ad12..00000000 --- a/resources/wiiflow_game_booter/utils.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - 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 -// Copyright 2008-2009 Andre Heider -// Copyright 2008-2009 Hector Martin - -#include "types.h" -#include "utils.h" -#include "cache.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -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; -} - -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) - return (*us1 < *us2) ? -1 : +1; - us1++; - us2++; - } - return 0; -} - -void memset32(u32 *addr, u32 data, u32 count) -{ - int sc = count; - void *sa = addr; - while(count--) - *addr++ = data; - sync_after_write(sa, 4*sc); -} - -#ifdef __cplusplus -} -#endif - -// 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); -} diff --git a/resources/wiiflow_game_booter/utils.h b/resources/wiiflow_game_booter/utils.h deleted file mode 100644 index b1ed3bdb..00000000 --- a/resources/wiiflow_game_booter/utils.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - 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 - -#ifndef __UTILS_H__ -#define __UTILS_H__ - -#include "types.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -void *memset(void *,int,int); -void memset32(u32 *addr, u32 data, u32 count) __attribute__ ((externally_visible)); -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); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/resources/wiiflow_game_booter/video.h b/resources/wiiflow_game_booter/video.h deleted file mode 100644 index 4bc73bd9..00000000 --- a/resources/wiiflow_game_booter/video.h +++ /dev/null @@ -1,12 +0,0 @@ - -#ifndef VIDEO_H_ -#define VIDEO_H_ - -void video_init(void); -void video_setblack(void); - -void prog(int p); -void prog10(void); -void setprog(int p); - -#endif diff --git a/resources/wiiflow_game_booter/wip.c b/resources/wiiflow_game_booter/wip.c deleted file mode 100644 index 4ea9f170..00000000 --- a/resources/wiiflow_game_booter/wip.c +++ /dev/null @@ -1,66 +0,0 @@ - -#include "utils.h" -#include "debug.h" -#include "wip.h" - -WIP_Code *CodeList; -u32 CodesCount; -u32 ProcessedLength; -u32 Counter; - -void do_wip_code(u8 * dst, u32 len) -{ - if(Counter < 3) - { - Counter++; - return; - } - u32 i = 0; - s32 n = 0; - s32 offset = 0; - - for(i = 0; i < CodesCount; i++) - { - for(n = 0; n < 4; n++) - { - offset = CodeList[i].offset+n-ProcessedLength; - - if(offset < 0 || (u32)offset >= len) - continue; - - if(dst[offset] == ((u8 *)&CodeList[i].srcaddress)[n]) - { - dst[offset] = ((u8 *)&CodeList[i].dstaddress)[n]; - debug_string("Address patched:"); debug_uint(CodeList[i].offset+n); debug_string("\n"); - //printf("WIP: %08X Address Patched.\n", CodeList[i].offset + n); - } - else - { - debug_string("Address NOT patched:"); debug_uint(CodeList[i].offset+n); debug_string("\n"); - //printf("WIP: %08X Address does not match with WIP entry.\n", CodeList[i].offset+n); - //printf("Destination: %02X | Should be: %02X.\n", dst[offset], ((u8 *)&CodeList[i].srcaddress)[n]); - } - } - } - ProcessedLength += len; - Counter++; -} - -//! for internal patches only -//! .wip files override internal patches -//! the codelist has to be freed if the set fails -//! if set was successful the codelist will be freed when it's done -u8 set_wip_list(WIP_Code *list, int size) -{ - CodeList = list; - CodesCount = size; - ProcessedLength = 0; - Counter = 0; - return 1; -} - -void free_wip() -{ - CodesCount = 0; - ProcessedLength = 0; -} diff --git a/source/booter/external_booter.cpp b/source/booter/external_booter.cpp index 4529343f..402acfd9 100644 --- a/source/booter/external_booter.cpp +++ b/source/booter/external_booter.cpp @@ -36,7 +36,7 @@ typedef void (*entrypoint) (void); extern "C" { void __exception_closeall(); } /* External WiiFlow Game Booter */ -#define BOOTER_ADDR ((u8 *)0x80F00000) +#define BOOTER_ADDR ((u8 *)0x80B00000) static the_CFG *BooterConfig = (the_CFG*)0x93100000; static entrypoint exeEntryPoint = (entrypoint)BOOTER_ADDR; @@ -76,7 +76,7 @@ void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 pat normalCFG.gameconfsize = gameconfsize; normalCFG.BootType = BootType; - ShutdownBeforeExit(true); + ShutdownBeforeExit(); /* Copy CFG into new memory region */ memcpy(BooterConfig, &normalCFG, sizeof(the_CFG)); DCFlushRange(BooterConfig, sizeof(the_CFG)); @@ -84,14 +84,14 @@ void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 pat memcpy(BOOTER_ADDR, booter, booter_size); DCFlushRange(BOOTER_ADDR, booter_size); /* Shutdown IOS subsystems */ - u32 level = IRQ_Disable(); __IOS_ShutdownSubsystems(); - __lwp_thread_closeall(); - __exception_closeall(); - /* Boot it */ - exeEntryPoint(); - /* Fail */ - IRQ_Restore(level); + u32 level = IRQ_Disable(); + __lwp_thread_closeall(); + __exception_closeall(); + /* Boot it */ + exeEntryPoint(); + /* Fail */ + IRQ_Restore(level); } extern FragList *frag_list; @@ -114,9 +114,9 @@ void ExternalBooter_ChannelSetup(u64 title) memcpy(&normalCFG.title, &title, sizeof(u64)); } -void ShutdownBeforeExit(bool KeepPatches) +void ShutdownBeforeExit() { DeviceHandle.UnMountAll(); - Nand::Instance()->DeInit_ISFS(KeepPatches); + Nand::Instance()->DeInit_ISFS(); WDVD_Close(); } diff --git a/source/booter/external_booter.hpp b/source/booter/external_booter.hpp index 4d7b5294..34604894 100644 --- a/source/booter/external_booter.hpp +++ b/source/booter/external_booter.hpp @@ -32,6 +32,6 @@ void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 pat int aspectRatio, u32 returnTo, u8 BootType); void ExternalBooter_ChannelSetup(u64 title); void ExternalBooter_WiiGameSetup(bool wbfs, bool dvd, const char *ID); -void ShutdownBeforeExit(bool BootGame = false); +void ShutdownBeforeExit(); #endif diff --git a/source/channel/nand.cpp b/source/channel/nand.cpp index 3881dd5e..f69c3587 100644 --- a/source/channel/nand.cpp +++ b/source/channel/nand.cpp @@ -40,6 +40,7 @@ #include "gecko/gecko.h" #include "loader/alt_ios.h" #include "loader/cios.h" +#include "loader/nk.h" #include "loader/sys.h" #include "loader/wbfs.h" #include "memory/memory.h" @@ -1052,10 +1053,8 @@ s32 Nand::Do_Region_Change(string id) extern "C" { extern s32 MagicPatches(s32); } -void Nand::Init_ISFS() +void Nand::Enable_ISFS_Patches(void) { - //gprintf("Init ISFS\n"); - ISFS_Initialize(); if(AHBRPOT_Patched()) { // Disable memory protection @@ -1068,22 +1067,33 @@ void Nand::Init_ISFS() } } -void Nand::DeInit_ISFS(bool KeepPatches) +void Nand::Disable_ISFS_Patches(void) { - //gprintf("Deinit ISFS\n"); if(AHBRPOT_Patched()) { // Disable memory protection write16(MEM_PROT, 0); - if(!KeepPatches) - { - // Do patches - MagicPatches(0); - // Enable memory protection - write16(MEM_PROT, 1); - } + // Do patches + MagicPatches(0); + // Enable memory protection + write16(MEM_PROT, 1); } +} + +void Nand::Init_ISFS() +{ + //gprintf("Init ISFS\n"); + if(IOS_GetVersion() == 58 && !neek2o()) + Enable_ISFS_Patches(); + ISFS_Initialize(); +} + +void Nand::DeInit_ISFS() +{ + //gprintf("Deinit ISFS\n"); ISFS_Deinitialize(); + if(IOS_GetVersion() == 58 && !neek2o()) + Disable_ISFS_Patches(); } /* Thanks to postloader for that patch */ @@ -1112,6 +1122,18 @@ void Nand::PatchAHB() } } +void Nand::Patch_AHB() +{ + if(AHBRPOT_Patched()) + { + // Disable memory protection + write16(MEM_PROT, 0); + // Do patches + PatchAHB(); + // Enable memory protection + write16(MEM_PROT, 1); + } +} /* part of miniunz.c diff --git a/source/channel/nand.hpp b/source/channel/nand.hpp index f31b6295..37e4328a 100644 --- a/source/channel/nand.hpp +++ b/source/channel/nand.hpp @@ -68,8 +68,9 @@ public: void Set_RCMode(bool rcmode) { FullMode = rcmode ? 0x40 : 0; }; void Set_SSMode(bool ssmode) { FullMode = ssmode ? 0x60 : 0; }; + void Patch_AHB(); void Init_ISFS(); - void DeInit_ISFS(bool KeepPatches = false); + void DeInit_ISFS(); const char * Get_NandPath(void) { return NandPath; }; u32 Get_Partition(void) { return Partition; }; @@ -96,7 +97,11 @@ private: s32 Nand_Unmount(NandDevice *Device); s32 Nand_Enable(NandDevice *Device); s32 Nand_Disable(void); + void PatchAHB(void); + void Enable_ISFS_Patches(void); + void Disable_ISFS_Patches(void); + void __Dec_Enc_TB(void); void __configshifttxt(char *str); void __GetNameList(const char *source, namelist **entries, int *count); diff --git a/source/loader/alt_ios.cpp b/source/loader/alt_ios.cpp index c6b57543..ea75cc42 100644 --- a/source/loader/alt_ios.cpp +++ b/source/loader/alt_ios.cpp @@ -83,6 +83,7 @@ bool loadIOS(int ios, bool MountDevices) WDVD_Close(); Close_Inputs(); gprintf("Reloading into IOS %i from %i...\n", ios, CurIOS); + Nand::Instance()->Patch_AHB(); //No AHBPROT for the next IOS ShutdownBeforeExit(); ret = IOS_ReloadIOS(ios) == 0; Nand::Instance()->Init_ISFS(); diff --git a/source/loader/fst.c b/source/loader/fst.c index 9e3a58c3..eceeb90b 100644 --- a/source/loader/fst.c +++ b/source/loader/fst.c @@ -55,28 +55,21 @@ extern const u32 axnextframehooks[4]; extern const u32 wpadbuttonsdownhooks[4]; extern const u32 wpadbuttonsdown2hooks[4]; -int app_gameconfig_load(u8 *discid, const u8 *gameconfig, u32 tempgameconfsize) +int app_gameconfig_load(const char *discid, u8 *tempgameconf, u32 tempgameconfsize) { - gameconfsize = 0; - if (gameconf == NULL) { - gameconf = malloc(65536); + gameconf = (u32*) MEM2_alloc(65536); if (gameconf == NULL) return -1; } - - if (gameconfig == NULL || tempgameconfsize == 0) - return -2; - - u8 *tempgameconf = (u8 *)gameconfig; - u32 ret; s32 gameidmatch, maxgameidmatch = -1, maxgameidmatch2 = -1; u32 i, numnonascii, parsebufpos; u32 codeaddr, codeval, codeaddr2, codeval2, codeoffset; u32 temp, tempoffset = 0; char parsebuffer[18]; + // Remove non-ASCII characters numnonascii = 0; for (i = 0; i < tempgameconfsize; i++) @@ -84,7 +77,7 @@ int app_gameconfig_load(u8 *discid, const u8 *gameconfig, u32 tempgameconfsize) if (tempgameconf[i] < 9 || tempgameconf[i] > 126) numnonascii++; else - tempgameconf[i-numnonascii] = tempgameconf[i]; + tempgameconf[i - numnonascii] = tempgameconf[i]; } tempgameconfsize -= numnonascii; @@ -99,9 +92,11 @@ int app_gameconfig_load(u8 *discid, const u8 *gameconfig, u32 tempgameconfsize) maxgameidmatch2 = -1; while (maxgameidmatch != maxgameidmatch2) { - while (i != tempgameconfsize && tempgameconf[i] != ':') i++; + while (i != tempgameconfsize && tempgameconf[i] != ':') + i++; if (i == tempgameconfsize) break; - while ((tempgameconf[i] != 10 && tempgameconf[i] != 13) && (i != 0)) i--; + while ((tempgameconf[i] != 10 && tempgameconf[i] != 13) && (i != 0)) + i--; if (i != 0) i++; parsebufpos = 0; gameidmatch = 0; @@ -118,8 +113,7 @@ int app_gameconfig_load(u8 *discid, const u8 *gameconfig, u32 tempgameconfsize) parsebuffer[parsebufpos++] = tempgameconf[i++]; else if (tempgameconf[i] == ' ') break; - else - i++; + else i++; if (parsebufpos == 8) break; } parsebuffer[parsebufpos] = 0; @@ -128,114 +122,124 @@ int app_gameconfig_load(u8 *discid, const u8 *gameconfig, u32 tempgameconfsize) gameidmatch = 0; goto idmatch; } - if (strncmp((char *) discid, parsebuffer, strlen(parsebuffer)) == 0) + if (strncasecmp(discid, parsebuffer, strlen(parsebuffer)) == 0) { gameidmatch += strlen(parsebuffer); - idmatch: - if (gameidmatch > maxgameidmatch2) + idmatch: if (gameidmatch > maxgameidmatch2) + { maxgameidmatch2 = gameidmatch; + } } - while ((i != tempgameconfsize) && (tempgameconf[i] != 10 && tempgameconf[i] != 13)) i++; + while ((i != tempgameconfsize) && (tempgameconf[i] != 10 && tempgameconf[i] != 13)) + i++; } while (i != tempgameconfsize && tempgameconf[i] != ':') { parsebufpos = 0; while ((i != tempgameconfsize) && (tempgameconf[i] != 10 && tempgameconf[i] != 13)) { - if (tempgameconf[i] != 0 && tempgameconf[i] != ' ' && tempgameconf[i] != '(' && tempgameconf[i] != ':') + if (tempgameconf[i] != 0 && tempgameconf[i] != ' ' && tempgameconf[i] != '(' && tempgameconf[i] + != ':') parsebuffer[parsebufpos++] = tempgameconf[i++]; else if (tempgameconf[i] == ' ' || tempgameconf[i] == '(' || tempgameconf[i] == ':') break; - else - i++; + else i++; if (parsebufpos == 17) break; } parsebuffer[parsebufpos] = 0; - if (strncasecmp("codeliststart", parsebuffer, strlen(parsebuffer)) == 0 && strlen(parsebuffer) == 13) + //if (!autobootcheck) { - sscanf((char *)(tempgameconf + i), " = %x", (unsigned int *)&codelist); - } - if (strncasecmp("codelistend", parsebuffer, strlen(parsebuffer)) == 0 && strlen(parsebuffer) == 11) - { - sscanf((char *)(tempgameconf + i), " = %x", (unsigned int *)&codelistend); - } - if (strncasecmp("poke", parsebuffer, strlen(parsebuffer)) == 0 && strlen(parsebuffer) == 4) - { - ret = sscanf((char *)tempgameconf + i, "( %x , %x", &codeaddr, &codeval); - if (ret == 2) + if (strncasecmp("codeliststart", parsebuffer, strlen(parsebuffer)) == 0 && strlen(parsebuffer) + == 13) { - *(gameconf + (gameconfsize / 4)) = 0; - gameconfsize += 4; - *(gameconf + (gameconfsize / 4)) = 0; - gameconfsize += 8; - *(gameconf + (gameconfsize / 4)) = codeaddr; - gameconfsize += 4; - *(gameconf + (gameconfsize / 4)) = codeval; - gameconfsize += 4; - DCFlushRange((void *) (gameconf + (gameconfsize / 4) - 5), 20); + sscanf((char *) (tempgameconf + i), " = %x", (unsigned int *) &codelist); } - } - if (strncasecmp("pokeifequal", parsebuffer, strlen(parsebuffer)) == 0 && strlen(parsebuffer) == 11) - { - ret = sscanf((char *)(tempgameconf + i), "( %x , %x , %x , %x", &codeaddr, &codeval, &codeaddr2, &codeval2); - if (ret == 4) + if (strncasecmp("codelistend", parsebuffer, strlen(parsebuffer)) == 0 && strlen(parsebuffer) == 11) { - *(gameconf + (gameconfsize / 4)) = 0; - gameconfsize += 4; - *(gameconf + (gameconfsize / 4)) = codeaddr; - gameconfsize += 4; - *(gameconf + (gameconfsize / 4)) = codeval; - gameconfsize += 4; - *(gameconf + (gameconfsize / 4)) = codeaddr2; - gameconfsize += 4; - *(gameconf + (gameconfsize / 4)) = codeval2; - gameconfsize += 4; - DCFlushRange((void *) (gameconf + (gameconfsize / 4) - 5), 20); + sscanf((char *) (tempgameconf + i), " = %x", (unsigned int *) &codelistend); } - } - if (strncasecmp("searchandpoke", parsebuffer, strlen(parsebuffer)) == 0 && strlen(parsebuffer) == 13) - { - ret = sscanf((char *)(tempgameconf + i), "( %x%n", &codeval, &tempoffset); - if (ret == 1) + if (strncasecmp("poke", parsebuffer, strlen(parsebuffer)) == 0 && strlen(parsebuffer) == 4) { - gameconfsize += 4; - temp = 0; - while (ret == 1) + ret = sscanf((char *) tempgameconf + i, "( %x , %x", &codeaddr, &codeval); + if (ret == 2) { + *(gameconf + (gameconfsize / 4)) = 0; + gameconfsize += 4; + *(gameconf + (gameconfsize / 4)) = 0; + gameconfsize += 8; + *(gameconf + (gameconfsize / 4)) = codeaddr; + gameconfsize += 4; *(gameconf + (gameconfsize / 4)) = codeval; gameconfsize += 4; - temp++; - i += tempoffset; - ret = sscanf((char *)(tempgameconf + i), " %x%n", &codeval, &tempoffset); + DCFlushRange((void *) (gameconf + (gameconfsize / 4) - 5), 20); } - *(gameconf + (gameconfsize / 4) - temp - 1) = temp; - ret = sscanf((char *)(tempgameconf + i), " , %x , %x , %x , %x", &codeaddr, &codeaddr2, &codeoffset, &codeval2); + } + if (strncasecmp("pokeifequal", parsebuffer, strlen(parsebuffer)) == 0 && strlen(parsebuffer) == 11) + { + ret = sscanf((char *) (tempgameconf + i), "( %x , %x , %x , %x", &codeaddr, &codeval, + &codeaddr2, &codeval2); if (ret == 4) { + *(gameconf + (gameconfsize / 4)) = 0; + gameconfsize += 4; *(gameconf + (gameconfsize / 4)) = codeaddr; gameconfsize += 4; + *(gameconf + (gameconfsize / 4)) = codeval; + gameconfsize += 4; *(gameconf + (gameconfsize / 4)) = codeaddr2; gameconfsize += 4; - *(gameconf + (gameconfsize / 4)) = codeoffset; - gameconfsize += 4; *(gameconf + (gameconfsize / 4)) = codeval2; gameconfsize += 4; - DCFlushRange((void *) (gameconf + (gameconfsize / 4) - temp - 5), temp * 4 + 20); + DCFlushRange((void *) (gameconf + (gameconfsize / 4) - 5), 20); } - else - gameconfsize -= temp * 4 + 4; + } + if (strncasecmp("searchandpoke", parsebuffer, strlen(parsebuffer)) == 0 && strlen(parsebuffer) + == 13) + { + ret = sscanf((char *) (tempgameconf + i), "( %x%n", &codeval, &tempoffset); + if (ret == 1) + { + gameconfsize += 4; + temp = 0; + while (ret == 1) + { + *(gameconf + (gameconfsize / 4)) = codeval; + gameconfsize += 4; + temp++; + i += tempoffset; + ret = sscanf((char *) (tempgameconf + i), " %x%n", &codeval, &tempoffset); + } + *(gameconf + (gameconfsize / 4) - temp - 1) = temp; + ret = sscanf((char *) (tempgameconf + i), " , %x , %x , %x , %x", &codeaddr, &codeaddr2, + &codeoffset, &codeval2); + if (ret == 4) + { + *(gameconf + (gameconfsize / 4)) = codeaddr; + gameconfsize += 4; + *(gameconf + (gameconfsize / 4)) = codeaddr2; + gameconfsize += 4; + *(gameconf + (gameconfsize / 4)) = codeoffset; + gameconfsize += 4; + *(gameconf + (gameconfsize / 4)) = codeval2; + gameconfsize += 4; + DCFlushRange((void *) (gameconf + (gameconfsize / 4) - temp - 5), temp * 4 + 20); + } + else gameconfsize -= temp * 4 + 4; + } + } } if (tempgameconf[i] != ':') { - while ((i != tempgameconfsize) && (tempgameconf[i] != 10 && tempgameconf[i] != 13)) i++; + while ((i != tempgameconfsize) && (tempgameconf[i] != 10 && tempgameconf[i] != 13)) + i++; if (i != tempgameconfsize) i++; } } - if (i != tempgameconfsize) while ((tempgameconf[i] != 10 && tempgameconf[i] != 13) && (i != 0)) i--; + if (i != tempgameconfsize) while ((tempgameconf[i] != 10 && tempgameconf[i] != 13) && (i != 0)) + i--; } } - free(tempgameconf); return 0; } @@ -260,15 +264,6 @@ int ocarina_load_code(const u8 *cheat, u32 cheatSize) code_size = 0; return 0; } - - if (code_size > (u32)codelistend - (u32)codelist) - { - gprintf("Ocarina: Too many codes found\n"); - code_buf = NULL; - code_size = 0; - return 0; - } - //gprintf("Ocarina: Codes found.\n"); DCFlushRange(code_buf, code_size); return code_size; diff --git a/source/loader/fst.h b/source/loader/fst.h index c32e1699..eeb6a0d3 100644 --- a/source/loader/fst.h +++ b/source/loader/fst.h @@ -30,7 +30,7 @@ extern u8 debuggerselect; #define MAX_GCT_SIZE 2056 -int app_gameconfig_load(u8 *id, const u8 *gameconfig, u32 gameconfigsize); +int app_gameconfig_load(const char *discid, u8 *tempgameconf, u32 tempgameconfsize); int ocarina_load_code(const u8 *cheat, u32 cheatSize); int ocarina_do_code(); diff --git a/source/menu/menu_game.cpp b/source/menu/menu_game.cpp index e1b3cceb..4da5b0d0 100644 --- a/source/menu/menu_game.cpp +++ b/source/menu/menu_game.cpp @@ -1401,16 +1401,16 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd) Sys_Exit(); WBFS_Close(); } - if(gameconfig.get() != NULL) - { - app_gameconfig_load((u8*)&id, gameconfig.get(), gameconfigSize); - gameconfig.release(); - } if(cheatFile.get() != NULL) { ocarina_load_code(cheatFile.get(), cheatSize); cheatFile.release(); } + if(gameconfig.get() != NULL) + { + app_gameconfig_load(id.c_str(), gameconfig.get(), gameconfigSize); + gameconfig.release(); + } ExternalBooter_WiiGameSetup(wbfs_partition, dvd, id.c_str()); WiiFlow_ExternalBooter(videoMode, vipatch, countryPatch, patchVidMode, aspectRatio, returnTo, TYPE_WII_GAME); }