mirror of
https://gitlab.com/Nanolx/homebrewfilter.git
synced 2024-11-24 10:09:21 +01:00
add Waninkoko nand-loader source
This commit is contained in:
parent
f66ea08af1
commit
c2319b529d
136
nand-loader/Makefile
Normal file
136
nand-loader/Makefile
Normal file
@ -0,0 +1,136 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
# Clear the implicit built in rules
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
|
||||
DEVKITPRO = /opt/devkitPPC
|
||||
DEVKITPPC = /opt/devkitPPC
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(DEVKITPPC)),)
|
||||
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC)
|
||||
endif
|
||||
|
||||
include $(DEVKITPPC)/wii_rules
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# INCLUDES is a list of directories containing extra header files
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
BUILD := build
|
||||
SOURCES := source source/libpng/pngu
|
||||
DATA := data
|
||||
INCLUDES :=
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
CFLAGS = -O2 -mrvl -Wall $(MACHDEP) $(INCLUDE)
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
|
||||
LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# any extra libraries we wish to link with the project
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBS := -lpng -lmodplay -lasnd -lwiiuse -lbte -logc -lm -lz
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# 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 TOPDIR := $(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
|
||||
#---------------------------------------------------------------------------------
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
export LD := $(CC)
|
||||
else
|
||||
export LD := $(CXX)
|
||||
endif
|
||||
|
||||
export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
|
||||
$(sFILES:.s=.o) $(SFILES:.S=.o)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# build a list of include paths
|
||||
#---------------------------------------------------------------------------------
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES), -iquote $(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD) \
|
||||
-I$(LIBOGC_INC)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# build a list of library paths
|
||||
#---------------------------------------------------------------------------------
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
|
||||
-L$(LIBOGC_LIB)
|
||||
|
||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||
.PHONY: $(BUILD) clean
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
$(OUTPUT).bin: $(OUTPUT).elf
|
||||
$(OUTPUT).elf: $(OFILES)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin:
|
||||
$(OBJCOPY) -O binary $^ $@
|
||||
|
||||
%.elf:
|
||||
@echo linking ... $(notdir $@)
|
||||
$(LD) -T ../rvl.ld $^ $(LDFLAGS) $(LIBPATHS) $(LIBS) -o $@
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
29
nand-loader/README.txt
Executable file
29
nand-loader/README.txt
Executable file
@ -0,0 +1,29 @@
|
||||
+---------------------------------+
|
||||
| [+] Custom NAND Loader v1.0 |
|
||||
| developed by Waninkoko |
|
||||
+---------------------------------+
|
||||
| wwww.teknoconsolas.es |
|
||||
+---------------------------------+
|
||||
|
||||
|
||||
[ DESCRIPTION ]:
|
||||
|
||||
- This is a custom NAND Loader for Wii channels. It is 100% legal and works
|
||||
with homebrew and commercial channels.
|
||||
|
||||
Also, it allows to configure the loading options for each channel.
|
||||
|
||||
|
||||
[ NOTES ];
|
||||
|
||||
- If RESET button is held while booting the channel it will access
|
||||
the configuration menu.
|
||||
|
||||
|
||||
[ KUDOS ]:
|
||||
|
||||
- Team Twiizers and devkitPRO devs.
|
||||
- crediar.
|
||||
- WiiGator.
|
||||
- kwiirk.
|
||||
- All the betatesters.
|
BIN
nand-loader/data/background
Normal file
BIN
nand-loader/data/background
Normal file
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
BIN
nand-loader/data/error
Normal file
BIN
nand-loader/data/error
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
BIN
nand-loader/data/loading
Normal file
BIN
nand-loader/data/loading
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
BIN
nand-loader/lib/libpng.a
Normal file
BIN
nand-loader/lib/libpng.a
Normal file
Binary file not shown.
345
nand-loader/rvl.ld
Normal file
345
nand-loader/rvl.ld
Normal file
@ -0,0 +1,345 @@
|
||||
/*
|
||||
* Linkscript for Wii
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc");
|
||||
OUTPUT_ARCH(powerpc:common);
|
||||
EXTERN(_stub_start);
|
||||
ENTRY(_stub_start);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* DOL header (from TITANIK's GC docs) */
|
||||
/* default base address */
|
||||
off = 0;
|
||||
|
||||
.header : AT(off)
|
||||
{
|
||||
/* 0000-001B Text[0..6] sections File Positions */
|
||||
LONG(stub_file_start);
|
||||
LONG(text_file_start);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
|
||||
/* 001C-0047 Data[0..10] sections File Positions */
|
||||
LONG(data_file_start);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
|
||||
/* 0048-0063 Text[0..6] sections Mem Address */
|
||||
LONG(stub_mem_start);
|
||||
LONG(text_mem_start);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
|
||||
/* 0064-008F Data[0..10] sections Mem Address */
|
||||
LONG(data_mem_start);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
|
||||
/* 0090-00AB Text[0..6] sections Sizes */
|
||||
LONG(stub_mem_size);
|
||||
LONG(text_mem_size);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
|
||||
/* 00AC-00D7 Data[0..10] sections Sizes */
|
||||
LONG(data_mem_size);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
|
||||
/* 00D8 BSS Mem address
|
||||
00DC BSS Size */
|
||||
LONG(bss_mem_start);
|
||||
LONG(bss_mem_size);
|
||||
|
||||
/* 00E0 Entry Point */
|
||||
LONG(ABSOLUTE(_stub_start));
|
||||
}
|
||||
|
||||
. = 0x00003400;
|
||||
off += 0x100;
|
||||
|
||||
stub_mem_start = .;
|
||||
stub_file_start = off;
|
||||
|
||||
.stub : AT(off)
|
||||
{
|
||||
KEEP (*(.stub))
|
||||
. = 0x400;
|
||||
} = 0
|
||||
|
||||
stub_mem_size = . - stub_mem_start;
|
||||
off += stub_mem_size;
|
||||
|
||||
. = 0x81330000;
|
||||
|
||||
text_mem_start = .;
|
||||
text_file_start = off;
|
||||
|
||||
.init : AT(off)
|
||||
{
|
||||
KEEP (*crt0.o(*.init))
|
||||
KEEP (*(.init))
|
||||
}
|
||||
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
*(.gnu.linkonce.t.*)
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
}
|
||||
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(.fini))
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
}
|
||||
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
|
||||
text_mem_size = . - text_mem_start;
|
||||
off += text_mem_size;
|
||||
|
||||
data_mem_start = .;
|
||||
data_file_start = off;
|
||||
|
||||
.data : AT(off)
|
||||
{
|
||||
*(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
*(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*)
|
||||
*(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*)
|
||||
PROVIDE (__preinit_array_start = .);
|
||||
*(.preinit_array)
|
||||
PROVIDE (__preinit_array_end = .);
|
||||
PROVIDE (__init_array_start = .);
|
||||
*(.init_array)
|
||||
PROVIDE (__init_array_end = .);
|
||||
PROVIDE (__fini_array_start = .);
|
||||
*(.fini_array)
|
||||
PROVIDE (__fini_array_end = .);
|
||||
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
}
|
||||
|
||||
.data1 : { *(.data1) }
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.gcc_except_table : { *(.gcc_except_table) }
|
||||
.fixup : { *(.fixup) }
|
||||
.got1 : { *(.got1) }
|
||||
.got2 : { *(.got2) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
|
||||
/* We don't want to include the .ctor section from
|
||||
from the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
}
|
||||
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
}
|
||||
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.got : { *(.got.plt) *(.got) }
|
||||
|
||||
|
||||
/* We want the small data sections together, so single-instruction offsets
|
||||
can access them all, and initialized data all before uninitialized, so
|
||||
we can shorten the on-disk segment size. */
|
||||
|
||||
.sdata :
|
||||
{
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
}
|
||||
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
|
||||
data_mem_size = . - data_mem_start;
|
||||
off += data_mem_size;
|
||||
|
||||
bss_mem_start = .;
|
||||
bss_file_start = off;
|
||||
|
||||
.sbss : AT(off)
|
||||
{
|
||||
__sbss_start = .;
|
||||
PROVIDE (__sbss_start = .);
|
||||
PROVIDE (___sbss_start = .);
|
||||
*(.dynsbss)
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
*(.scommon)
|
||||
PROVIDE (__sbss_end = .);
|
||||
PROVIDE (___sbss_end = .);
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
__sbss_end = .;
|
||||
}
|
||||
|
||||
.bss :
|
||||
{
|
||||
__bss_start = .;
|
||||
PROVIDE (__bss_start = .);
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
/* Align here to ensure that the .bss section occupies space up to
|
||||
_end. Align after .bss to ensure correct alignment even if the
|
||||
.bss section disappears because there are no input sections. */
|
||||
|
||||
. = ALIGN(32);
|
||||
|
||||
PROVIDE (__bss_end = .);
|
||||
__bss_end = .;
|
||||
}
|
||||
|
||||
bss_mem_size = . - bss_mem_start;
|
||||
|
||||
_end = .;
|
||||
PROVIDE(end = .);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* These must appear regardless of . */
|
||||
}
|
||||
|
||||
__isIPL = 0;
|
||||
__stack_addr = (__bss_start + SIZEOF(.bss) + 0x20000 + 7) & (-8);
|
||||
__stack_end = (__bss_start + SIZEOF(.bss));
|
||||
__intrstack_addr = (__stack_addr + 0x4000);
|
||||
__intrstack_end = (__stack_addr);
|
||||
__Arena1Lo = (__intrstack_addr + 31) & (-32);
|
||||
__Arena1Hi = (0x816ffff0);
|
||||
__Arena2Lo = (0x90002000);
|
||||
__Arena2Hi = (0x933E0000);
|
||||
|
||||
__gxregs = (__Arena1Hi + 31) & (-32);
|
||||
__ipcbufferLo = (0x933e0000);
|
||||
__ipcbufferHi = (0x93400000);
|
||||
|
||||
/* for backward compatibility with old crt0 */
|
||||
PROVIDE (__stack = (0x816ffff0));
|
||||
|
||||
PROVIDE(__isIPL = __isIPL);
|
||||
PROVIDE(__text_start = text_mem_start);
|
||||
PROVIDE(__text_fstart = text_file_start);
|
||||
PROVIDE(__data_start = data_mem_start);
|
||||
PROVIDE(__data_fstart = data_file_start);
|
||||
PROVIDE(__bss_start = bss_mem_start);
|
||||
PROVIDE(__bss_fstart = bss_file_start);
|
||||
PROVIDE(__stack_addr = __stack_addr);
|
||||
PROVIDE(__stack_end = __stack_end);
|
||||
PROVIDE(__intrstack_addr = __intrstack_addr);
|
||||
PROVIDE(__intrstack_end = __intrstack_end);
|
||||
PROVIDE(__Arena1Lo = __Arena1Lo);
|
||||
PROVIDE(__Arena1Hi = __Arena1Hi);
|
||||
PROVIDE(__Arena2Lo = __Arena2Lo);
|
||||
PROVIDE(__Arena2Hi = __Arena2Hi);
|
||||
PROVIDE(__ipcbufferLo = __ipcbufferLo);
|
||||
PROVIDE(__ipcbufferHi = __ipcbufferHi);
|
||||
PROVIDE(__gxregs = __gxregs);
|
93
nand-loader/source/asm.h
Normal file
93
nand-loader/source/asm.h
Normal file
@ -0,0 +1,93 @@
|
||||
#ifndef _ASM_H_
|
||||
#define _ASM_H_
|
||||
|
||||
/* Registers */
|
||||
#define r0 0
|
||||
#define r1 1
|
||||
#define r2 2
|
||||
#define r3 3
|
||||
#define r4 4
|
||||
#define r5 5
|
||||
#define r6 6
|
||||
#define r7 7
|
||||
#define r8 8
|
||||
#define r9 9
|
||||
#define r10 10
|
||||
#define r11 11
|
||||
#define r12 12
|
||||
#define r13 13
|
||||
#define r14 14
|
||||
#define r15 15
|
||||
#define r16 16
|
||||
#define r17 17
|
||||
#define r18 18
|
||||
#define r19 19
|
||||
#define r20 20
|
||||
#define r21 21
|
||||
#define r22 22
|
||||
#define r23 23
|
||||
#define r24 24
|
||||
#define r25 25
|
||||
#define r26 26
|
||||
#define r27 27
|
||||
#define r28 28
|
||||
#define r29 29
|
||||
#define r30 30
|
||||
#define r31 31
|
||||
|
||||
|
||||
/* BATs */
|
||||
#define IBAT0U 528
|
||||
#define IBAT0L 529
|
||||
#define IBAT1U 530
|
||||
#define IBAT1L 531
|
||||
#define IBAT2U 532
|
||||
#define IBAT2L 533
|
||||
#define IBAT3U 534
|
||||
#define IBAT3L 535
|
||||
#define IBAT4U 560
|
||||
#define IBAT4L 561
|
||||
#define IBAT5U 562
|
||||
#define IBAT5L 563
|
||||
#define IBAT6U 564
|
||||
#define IBAT6L 565
|
||||
#define IBAT7U 566
|
||||
#define IBAT7L 567
|
||||
|
||||
#define DBAT0U 536
|
||||
#define DBAT0L 537
|
||||
#define DBAT1U 538
|
||||
#define DBAT1L 539
|
||||
#define DBAT2U 540
|
||||
#define DBAT2L 541
|
||||
#define DBAT3U 542
|
||||
#define DBAT3L 543
|
||||
#define DBAT4U 568
|
||||
#define DBAT4L 569
|
||||
#define DBAT5U 570
|
||||
#define DBAT5L 571
|
||||
#define DBAT6U 572
|
||||
#define DBAT6L 573
|
||||
#define DBAT7U 574
|
||||
#define DBAT7L 575
|
||||
|
||||
|
||||
/* HIDs */
|
||||
#define HID0 1008
|
||||
#define HID1 1009
|
||||
#define HID2 920
|
||||
#define HID4 1011
|
||||
|
||||
|
||||
/* MSRs */
|
||||
#define MSR_RI 0x00000002
|
||||
#define MSR_DR 0x00000010
|
||||
#define MSR_IR 0x00000020
|
||||
#define MSR_IP 0x00000040
|
||||
#define MSR_SE 0x00000400
|
||||
#define MSR_ME 0x00001000
|
||||
#define MSR_FP 0x00002000
|
||||
#define MSR_POW 0x00004000
|
||||
#define MSR_EE 0x00008000
|
||||
|
||||
#endif
|
219
nand-loader/source/config.c
Normal file
219
nand-loader/source/config.c
Normal file
@ -0,0 +1,219 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ogcsys.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "title.h"
|
||||
#include "video.h"
|
||||
#include "wpad.h"
|
||||
|
||||
/* 'Menu' structure */
|
||||
struct menu {
|
||||
/* Entry name */
|
||||
char *name;
|
||||
|
||||
/* Entry value */
|
||||
bool *value;
|
||||
};
|
||||
|
||||
|
||||
/* NANDLoader configuration */
|
||||
struct config loaderCfg ATTRIBUTE_ALIGN(32) = { 0 };
|
||||
|
||||
/* Config entries */
|
||||
struct menu entryList[] = {
|
||||
{ "Force PAL50", &loaderCfg.forcePal50 },
|
||||
{ "Force PAL60", &loaderCfg.forcePal60 },
|
||||
{ "Force NTSC", &loaderCfg.forceNtsc },
|
||||
{ "Force HDTV", &loaderCfg.forceHdtv },
|
||||
{ "Patch Video Mode", &loaderCfg.patchVmode },
|
||||
};
|
||||
|
||||
/* Macros */
|
||||
#define NB_ENTRIES (sizeof(entryList) / sizeof(struct menu))
|
||||
|
||||
|
||||
void __Config_Credits(void)
|
||||
{
|
||||
/* Clear console */
|
||||
Con_Clear();
|
||||
|
||||
/* Write credits */
|
||||
printf("[+] Custom NAND Loader for Wii\n\n");
|
||||
|
||||
printf(" developed by Waninkoko\n");
|
||||
printf(" www.teknoconsolas.es\n\n\n");
|
||||
|
||||
printf("[+] Thanks to all my betatesters:\n");
|
||||
printf(" - linkinworm\n");
|
||||
printf(" - hectorscasa\n");
|
||||
printf(" - SoraK05\n");
|
||||
printf(" - And the rest... ;-)\n\n");
|
||||
|
||||
printf("[+] Also kudos to:\n\n");
|
||||
printf(" - Team Twiizers\n");
|
||||
printf(" - SoftMii Team\n");
|
||||
printf(" - crediar\n");
|
||||
printf(" - WiiGator and kwiirk\n");
|
||||
printf(" - Teknoconsolas.es community\n\n");
|
||||
|
||||
printf("\n");
|
||||
printf("[+] Press any button to continue...\n");
|
||||
|
||||
/* Wait for any button */
|
||||
Wpad_WaitButtons();
|
||||
}
|
||||
|
||||
s32 __Config_GetFilePath(char *outbuf)
|
||||
{
|
||||
static char nandpath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
|
||||
|
||||
u64 tid;
|
||||
s32 ret;
|
||||
|
||||
/* Get title ID */
|
||||
ret = ES_GetTitleID(&tid);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Get data directory */
|
||||
ret = ES_GetDataDir(tid, nandpath);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Generate filepath */
|
||||
sprintf(outbuf, "%s/nand.cfg", nandpath);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
s32 Config_Read(void)
|
||||
{
|
||||
char filepath[ISFS_MAXPATH];
|
||||
s32 fd, ret;
|
||||
|
||||
/* Get config filepath */
|
||||
ret = __Config_GetFilePath(filepath);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Open config file */
|
||||
fd = IOS_Open(filepath, ISFS_OPEN_READ);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
/* Read config */
|
||||
ret = IOS_Read(fd, &loaderCfg, sizeof(loaderCfg));
|
||||
|
||||
/* Close config file */
|
||||
IOS_Close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 Config_Write(void)
|
||||
{
|
||||
char filepath[ISFS_MAXPATH];
|
||||
s32 fd, ret;
|
||||
|
||||
/* Get config filepath */
|
||||
ret = __Config_GetFilePath(filepath);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Create config file */
|
||||
ISFS_CreateFile(filepath, 0, ISFS_OPEN_RW, ISFS_OPEN_READ, ISFS_OPEN_READ);
|
||||
|
||||
/* Open config file */
|
||||
fd = IOS_Open(filepath, ISFS_OPEN_WRITE);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
/* Write config */
|
||||
ret = IOS_Write(fd, &loaderCfg, sizeof(loaderCfg));
|
||||
|
||||
/* Close config file */
|
||||
IOS_Close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Config_Menu(void)
|
||||
{
|
||||
u32 var = 0;
|
||||
s32 selected = 0;
|
||||
|
||||
for (;;) {
|
||||
u32 cnt;
|
||||
|
||||
/* Clear console */
|
||||
Con_Clear();
|
||||
|
||||
for (cnt = 0; cnt < NB_ENTRIES; cnt++) {
|
||||
struct menu *entry = &entryList[cnt];
|
||||
|
||||
/* Print entry */
|
||||
printf("\t%2s %-16s : %s\n", (selected == cnt) ? ">>" : " ", entry->name, (*entry->value) ? "Yes" : "No");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
printf("[+] Press UP/DOWN to move cursor.\n");
|
||||
printf(" Press LEFT/RIGHT to toggle option.\n\n");
|
||||
|
||||
printf(" Press A button to save and continue...\n");
|
||||
|
||||
u32 buttons = Wpad_WaitButtons();
|
||||
|
||||
/* UP/DOWN buttons */
|
||||
if (buttons & WPAD_BUTTON_UP) {
|
||||
if ((--selected) <= -1)
|
||||
selected = (NB_ENTRIES - 1);
|
||||
}
|
||||
if (buttons & WPAD_BUTTON_DOWN) {
|
||||
if ((++selected) >= NB_ENTRIES)
|
||||
selected = 0;
|
||||
}
|
||||
|
||||
/* LEFT/RIGHT buttons */
|
||||
if (buttons & (WPAD_BUTTON_LEFT | WPAD_BUTTON_RIGHT))
|
||||
*entryList[selected].value ^= 1;
|
||||
|
||||
/* A button */
|
||||
if (buttons & WPAD_BUTTON_A)
|
||||
break;
|
||||
|
||||
|
||||
/* Easter Egg */
|
||||
if (buttons & WPAD_BUTTON_1) {
|
||||
switch (var) {
|
||||
case 0:
|
||||
var++;
|
||||
break;
|
||||
case 3:
|
||||
/* Show credits screen */
|
||||
__Config_Credits();
|
||||
|
||||
var = 0;
|
||||
break;
|
||||
default:
|
||||
var = 0;
|
||||
}
|
||||
}
|
||||
if (buttons & WPAD_BUTTON_2) {
|
||||
switch (var) {
|
||||
case 1:
|
||||
case 2:
|
||||
var++;
|
||||
break;
|
||||
default:
|
||||
var = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Write configuration */
|
||||
Config_Write();
|
||||
}
|
25
nand-loader/source/config.h
Normal file
25
nand-loader/source/config.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef _CONFIG_H_
|
||||
#define _CONFIG_H_
|
||||
|
||||
/* 'Config' structure */
|
||||
struct config {
|
||||
/* Video modes */
|
||||
bool forcePal50;
|
||||
bool forcePal60;
|
||||
bool forceNtsc;
|
||||
bool forceHdtv;
|
||||
|
||||
/* Video mode patching */
|
||||
bool patchVmode;
|
||||
};
|
||||
|
||||
/* NANDLoader configuration */
|
||||
extern struct config loaderCfg;
|
||||
|
||||
/* Prototypes */
|
||||
s32 Config_Read(void);
|
||||
s32 Config_Write(void);
|
||||
void Config_Menu(void);
|
||||
|
||||
#endif
|
||||
|
87
nand-loader/source/gui.c
Normal file
87
nand-loader/source/gui.c
Normal file
@ -0,0 +1,87 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ogcsys.h>
|
||||
|
||||
#include "video.h"
|
||||
|
||||
/* Constants */
|
||||
#define CONSOLE_XCOORD 20
|
||||
#define CONSOLE_YCOORD 100
|
||||
#define CONSOLE_WIDTH 350
|
||||
#define CONSOLE_HEIGHT 300
|
||||
|
||||
#define MSG_XCOORD 180
|
||||
#define MSG_YCOORD 190
|
||||
|
||||
|
||||
s32 __Gui_DrawPng(void *img, u32 x, u32 y)
|
||||
{
|
||||
IMGCTX ctx = NULL;
|
||||
PNGUPROP imgProp;
|
||||
|
||||
s32 ret;
|
||||
|
||||
/* Select PNG data */
|
||||
ctx = PNGU_SelectImageFromBuffer(img);
|
||||
if (!ctx) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Get image properties */
|
||||
ret = PNGU_GetImageProperties(ctx, &imgProp);
|
||||
if (ret != PNGU_OK) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Draw image */
|
||||
Video_DrawPng(ctx, imgProp, x, y);
|
||||
|
||||
/* Success */
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
/* Free memory */
|
||||
if (ctx)
|
||||
PNGU_ReleaseImageContext(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void Gui_InitConsole(void)
|
||||
{
|
||||
/* Initialize console */
|
||||
Con_Init(CONSOLE_XCOORD, CONSOLE_YCOORD, CONSOLE_WIDTH, CONSOLE_HEIGHT);
|
||||
}
|
||||
|
||||
void Gui_DrawBackground(void)
|
||||
{
|
||||
extern char bgData[];
|
||||
|
||||
/* Draw background */
|
||||
__Gui_DrawPng(bgData, 0, 0);
|
||||
}
|
||||
|
||||
void Gui_DrawLoading(void)
|
||||
{
|
||||
extern char loadingImg[];
|
||||
|
||||
/* Clear screen */
|
||||
Video_Clear(COLOR_BLACK);
|
||||
|
||||
/* Draw loading image */
|
||||
__Gui_DrawPng(loadingImg, MSG_XCOORD, MSG_YCOORD);
|
||||
}
|
||||
|
||||
void Gui_DrawError(void)
|
||||
{
|
||||
extern char errorImg[];
|
||||
|
||||
/* Clear screen */
|
||||
Video_Clear(COLOR_BLACK);
|
||||
|
||||
/* Draw error image */
|
||||
__Gui_DrawPng(errorImg, MSG_XCOORD, MSG_YCOORD);
|
||||
}
|
10
nand-loader/source/gui.h
Normal file
10
nand-loader/source/gui.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef _GUI_H_
|
||||
#define _GUI_H_
|
||||
|
||||
/* Prototypes */
|
||||
void Gui_InitConsole(void);
|
||||
void Gui_DrawBackground(void);
|
||||
void Gui_DrawLoading(void);
|
||||
void Gui_DrawError(void);
|
||||
|
||||
#endif
|
3569
nand-loader/source/libpng/png.h
Normal file
3569
nand-loader/source/libpng/png.h
Normal file
File diff suppressed because it is too large
Load Diff
1481
nand-loader/source/libpng/pngconf.h
Normal file
1481
nand-loader/source/libpng/pngconf.h
Normal file
File diff suppressed because it is too large
Load Diff
1132
nand-loader/source/libpng/pngu/pngu.c
Normal file
1132
nand-loader/source/libpng/pngu/pngu.c
Normal file
File diff suppressed because it is too large
Load Diff
171
nand-loader/source/libpng/pngu/pngu.h
Normal file
171
nand-loader/source/libpng/pngu/pngu.h
Normal file
@ -0,0 +1,171 @@
|
||||
/********************************************************************************************
|
||||
|
||||
PNGU Version : 0.2a
|
||||
|
||||
Coder : frontier
|
||||
|
||||
More info : http://frontier-dev.net
|
||||
|
||||
********************************************************************************************/
|
||||
#ifndef __PNGU__
|
||||
#define __PNGU__
|
||||
|
||||
// Return codes
|
||||
#define PNGU_OK 0
|
||||
#define PNGU_ODD_WIDTH 1
|
||||
#define PNGU_ODD_STRIDE 2
|
||||
#define PNGU_INVALID_WIDTH_OR_HEIGHT 3
|
||||
#define PNGU_FILE_IS_NOT_PNG 4
|
||||
#define PNGU_UNSUPPORTED_COLOR_TYPE 5
|
||||
#define PNGU_NO_FILE_SELECTED 6
|
||||
#define PNGU_CANT_OPEN_FILE 7
|
||||
#define PNGU_CANT_READ_FILE 8
|
||||
#define PNGU_LIB_ERROR 9
|
||||
|
||||
// Color types
|
||||
#define PNGU_COLOR_TYPE_GRAY 1
|
||||
#define PNGU_COLOR_TYPE_GRAY_ALPHA 2
|
||||
#define PNGU_COLOR_TYPE_PALETTE 3
|
||||
#define PNGU_COLOR_TYPE_RGB 4
|
||||
#define PNGU_COLOR_TYPE_RGB_ALPHA 5
|
||||
#define PNGU_COLOR_TYPE_UNKNOWN 6
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Types
|
||||
typedef unsigned char PNGU_u8;
|
||||
typedef unsigned short PNGU_u16;
|
||||
typedef unsigned int PNGU_u32;
|
||||
typedef unsigned long long PNGU_u64;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PNGU_u8 r;
|
||||
PNGU_u8 g;
|
||||
PNGU_u8 b;
|
||||
} PNGUCOLOR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PNGU_u32 imgWidth; // In pixels
|
||||
PNGU_u32 imgHeight; // In pixels
|
||||
PNGU_u32 imgBitDepth; // In bitx
|
||||
PNGU_u32 imgColorType; // PNGU_COLOR_TYPE_*
|
||||
PNGU_u32 validBckgrnd; // Non zero if there is a background color
|
||||
PNGUCOLOR bckgrnd; // Backgroun color
|
||||
PNGU_u32 numTrans; // Number of transparent colors
|
||||
PNGUCOLOR *trans; // Transparent colors
|
||||
} PNGUPROP;
|
||||
|
||||
// Image context, always initialize with SelectImageFrom* and free with ReleaseImageContext
|
||||
struct _IMGCTX;
|
||||
typedef struct _IMGCTX *IMGCTX;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Pixel conversion *
|
||||
****************************************************************************/
|
||||
|
||||
// Macro to convert RGB8 values to RGB565
|
||||
#define PNGU_RGB8_TO_RGB565(r,g,b) ( ((((PNGU_u16) r) & 0xF8U) << 8) | ((((PNGU_u16) g) & 0xFCU) << 3) | (((PNGU_u16) b) >> 3) )
|
||||
|
||||
// Macro to convert RGBA8 values to RGB5A3
|
||||
#define PNGU_RGB8_TO_RGB5A3(r,g,b,a) (PNGU_u16) (((a & 0xE0U) == 0xE0U) ? \
|
||||
(0x8000U | ((((PNGU_u16) r) & 0xF8U) << 7) | ((((PNGU_u16) g) & 0xF8U) << 2) | (((PNGU_u16) b) >> 3)) : \
|
||||
(((((PNGU_u16) a) & 0xE0U) << 7) | ((((PNGU_u16) r) & 0xF0U) << 4) | (((PNGU_u16) g) & 0xF0U) | ((((PNGU_u16) b) & 0xF0U) >> 4)))
|
||||
|
||||
// Function to convert two RGB8 values to YCbYCr
|
||||
PNGU_u32 PNGU_RGB8_TO_YCbYCr (PNGU_u8 r1, PNGU_u8 g1, PNGU_u8 b1, PNGU_u8 r2, PNGU_u8 g2, PNGU_u8 b2);
|
||||
|
||||
// Function to convert an YCbYCr to two RGB8 values.
|
||||
void PNGU_YCbYCr_TO_RGB8 (PNGU_u32 ycbycr, PNGU_u8 *r1, PNGU_u8 *g1, PNGU_u8 *b1, PNGU_u8 *r2, PNGU_u8 *g2, PNGU_u8 *b2);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Image context handling *
|
||||
****************************************************************************/
|
||||
|
||||
// Selects a PNG file, previosly loaded into a buffer, and creates an image context for subsequent procesing.
|
||||
IMGCTX PNGU_SelectImageFromBuffer (const void *buffer);
|
||||
|
||||
// Selects a PNG file, from any devoptab device, and creates an image context for subsequent procesing.
|
||||
IMGCTX PNGU_SelectImageFromDevice (const char *filename);
|
||||
|
||||
// Frees resources associated with an image context. Always call this function when you no longer need the IMGCTX.
|
||||
void PNGU_ReleaseImageContext (IMGCTX ctx);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Miscelaneous *
|
||||
****************************************************************************/
|
||||
|
||||
// Retrieves info from selected PNG file, including image dimensions, color format, background and transparency colors.
|
||||
int PNGU_GetImageProperties (IMGCTX ctx, PNGUPROP *fileproperties);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Image conversion *
|
||||
****************************************************************************/
|
||||
|
||||
// Expands selected image into an YCbYCr buffer. You need to specify context, image dimensions,
|
||||
// destination address and stride in pixels (stride = buffer width - image width).
|
||||
int PNGU_DecodeToYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride);
|
||||
|
||||
// Macro for decoding an image inside a buffer at given coordinates.
|
||||
#define PNGU_DECODE_TO_COORDS_YCbYCr(ctx,coordX,coordY,imgWidth,imgHeight,bufferWidth,bufferHeight,buffer) \
|
||||
\
|
||||
PNGU_DecodeToYCbYCr (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \
|
||||
(coordX) * 2, (bufferWidth) - (imgWidth))
|
||||
|
||||
// Expands selected image into a linear RGB565 buffer. You need to specify context, image dimensions,
|
||||
// destination address and stride in pixels (stride = buffer width - image width).
|
||||
int PNGU_DecodeToRGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride);
|
||||
|
||||
// Macro for decoding an image inside a buffer at given coordinates.
|
||||
#define PNGU_DECODE_TO_COORDS_RGB565(ctx,coordX,coordY,imgWidth,imgHeight,bufferWidth,bufferHeight,buffer) \
|
||||
\
|
||||
PNGU_DecodeToRGB565 (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \
|
||||
(coordX) * 2, (bufferWidth) - (imgWidth))
|
||||
|
||||
// Expands selected image into a linear RGBA8 buffer. You need to specify context, image dimensions,
|
||||
// destination address, stride in pixels and default alpha value, which is used if the source image
|
||||
// doesn't have an alpha channel.
|
||||
int PNGU_DecodeToRGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride, PNGU_u8 default_alpha);
|
||||
|
||||
// Macro for decoding an image inside a buffer at given coordinates.
|
||||
#define PNGU_DECODE_TO_COORDS_RGBA8(ctx,coordX,coordY,imgWidth,imgHeight,default_alpha,bufferWidth,bufferHeight,buffer) \
|
||||
\
|
||||
PNGU_DecodeToRGBA8 (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \
|
||||
(coordX) * 2, (bufferWidth) - (imgWidth), default_alpha)
|
||||
|
||||
// Expands selected image into a 4x4 tiled RGB565 buffer. You need to specify context, image dimensions
|
||||
// and destination address.
|
||||
int PNGU_DecodeTo4x4RGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer);
|
||||
|
||||
// Expands selected image into a 4x4 tiled RGB5A3 buffer. You need to specify context, image dimensions,
|
||||
// destination address and default alpha value, which is used if the source image doesn't have an alpha channel.
|
||||
int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u8 default_alpha);
|
||||
|
||||
// Expands selected image into a 4x4 tiled RGBA8 buffer. You need to specify context, image dimensions,
|
||||
// destination address and default alpha value, which is used if the source image doesn't have an alpha channel.
|
||||
int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u8 default_alpha);
|
||||
|
||||
// Encodes an YCbYCr image in PNG format and stores it in the selected device or memory buffer. You need to
|
||||
// specify context, image dimensions, destination address and stride in pixels (stride = buffer width - image width).
|
||||
int PNGU_EncodeFromYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride);
|
||||
|
||||
// Macro for encoding an image stored into an YCbYCr buffer at given coordinates.
|
||||
#define PNGU_ENCODE_TO_COORDS_YCbYCr(ctx,coordX,coordY,imgWidth,imgHeight,bufferWidth,bufferHeight,buffer) \
|
||||
\
|
||||
PNGU_EncodeFromYCbYCr (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \
|
||||
(coordX) * 2, (bufferWidth) - (imgWidth))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
246
nand-loader/source/loader.c
Normal file
246
nand-loader/source/loader.c
Normal file
@ -0,0 +1,246 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ogcsys.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "patches.h"
|
||||
#include "video.h"
|
||||
#include "wpad.h"
|
||||
|
||||
/* DOL header structure */
|
||||
typedef struct {
|
||||
u32 textoff[7];
|
||||
u32 dataoff[11];
|
||||
|
||||
u8 *textmem[7];
|
||||
u8 *datamem[11];
|
||||
|
||||
u32 textsize[7];
|
||||
u32 datasize[11];
|
||||
|
||||
u8 *bssmem;
|
||||
u32 bsssize;
|
||||
|
||||
u32 entry;
|
||||
|
||||
u32 unused[7];
|
||||
} dolheader;
|
||||
|
||||
/* Entry pointer */
|
||||
typedef void (*dolentry)(void);
|
||||
|
||||
/* Constants */
|
||||
#define DOL_INDEX 1
|
||||
|
||||
|
||||
void __Loader_SetLowMem(void)
|
||||
{
|
||||
/* Setup low memory */
|
||||
*(vu32*)0x800000F8 = 0x0E7BE2C0;
|
||||
*(vu32*)0x800000FC = 0x2B73A840;
|
||||
|
||||
/* Flush cache */
|
||||
DCFlushRange((void *)(0x80000000), 0x3F00);
|
||||
}
|
||||
|
||||
void __Loader_SetVMode(u64 tid)
|
||||
{
|
||||
GXRModeObj *vmode_ptr = NULL;
|
||||
u32 vmode_reg;
|
||||
|
||||
u32 progressive, tvmode;
|
||||
|
||||
/* Get video mode configuration */
|
||||
progressive = (CONF_GetProgressiveScan() > 0) && VIDEO_HaveComponentCable();
|
||||
tvmode = CONF_GetVideo();
|
||||
|
||||
/* Select video mode */
|
||||
switch(tid & 0xFF) {
|
||||
/* PAL */
|
||||
case 'P':
|
||||
vmode_reg = (CONF_GetEuRGB60() > 0) ? 5 : 1;
|
||||
|
||||
if (tvmode != CONF_VIDEO_PAL) {
|
||||
vmode_reg = 5;
|
||||
vmode_ptr = &TVNtsc480IntDf;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
/* NTSC or unknown */
|
||||
case 'E':
|
||||
case 'J':
|
||||
vmode_reg = 0;
|
||||
|
||||
if (tvmode != CONF_VIDEO_NTSC)
|
||||
vmode_ptr = &TVEurgb60Hz480IntDf;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
vmode_reg = 0;
|
||||
}
|
||||
|
||||
/* Override video mode */
|
||||
if (loaderCfg.forcePal50) {
|
||||
vmode_reg = 1;
|
||||
vmode_ptr = &TVPal528IntDf;
|
||||
}
|
||||
|
||||
if (loaderCfg.forcePal60) {
|
||||
vmode_reg = 5;
|
||||
vmode_ptr = &TVEurgb60Hz480IntDf;
|
||||
}
|
||||
|
||||
if (loaderCfg.forceNtsc) {
|
||||
vmode_reg = 0;
|
||||
vmode_ptr = &TVNtsc480IntDf;
|
||||
}
|
||||
|
||||
if (loaderCfg.forceHdtv) {
|
||||
vmode_reg = 0;
|
||||
vmode_ptr = &TVNtsc480Prog;
|
||||
}
|
||||
|
||||
|
||||
/* Set video mode register */
|
||||
*(vu32 *)0x800000CC = vmode_reg;
|
||||
|
||||
/* Set video mode */
|
||||
if (vmode_ptr) {
|
||||
/* If progressive available, use it */
|
||||
if (progressive)
|
||||
vmode_ptr = &TVNtsc480Prog;
|
||||
|
||||
Video_Configure(vmode_ptr);
|
||||
Video_Clear(COLOR_BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void __Loader_PatchDol(u8 *buffer, u32 len)
|
||||
{
|
||||
struct config *cfg = &loaderCfg;
|
||||
|
||||
/* Video mode patching */
|
||||
if (cfg->patchVmode)
|
||||
Patch_VideoMode(buffer, len);
|
||||
}
|
||||
|
||||
s32 __Loader_ReadDol(dolentry *p_entry)
|
||||
{
|
||||
static dolheader dol ATTRIBUTE_ALIGN(32);
|
||||
|
||||
u32 cnt;
|
||||
s32 cfd = -1, ret;
|
||||
|
||||
/* Open DOL file */
|
||||
cfd = ES_OpenContent(DOL_INDEX);
|
||||
if (cfd < 0)
|
||||
return cfd;
|
||||
|
||||
/* Read DOL header */
|
||||
ret = ES_ReadContent(cfd, (u8 *)&dol, sizeof(dol));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* Clear BSS */
|
||||
memset(dol.bssmem, 0, dol.bsssize);
|
||||
|
||||
/* Read TEXT section */
|
||||
for (cnt = 0; cnt < 7; cnt++) {
|
||||
u32 offset = dol.textoff[cnt];
|
||||
|
||||
if (offset >= sizeof(dol)) {
|
||||
u8 *buffer = (u8 *)dol.textmem[cnt];
|
||||
u32 len = dol.textsize[cnt];
|
||||
|
||||
/* Seek */
|
||||
ES_SeekContent(cfd, offset, 0);
|
||||
|
||||
/* Read */
|
||||
ret = ES_ReadContent(cfd, buffer, len);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* Patch */
|
||||
__Loader_PatchDol(buffer, len);
|
||||
}
|
||||
}
|
||||
|
||||
/* Read DATA section */
|
||||
for (cnt = 0; cnt < 11; cnt++) {
|
||||
u32 offset = dol.dataoff[cnt];
|
||||
|
||||
if (offset >= sizeof(dol)) {
|
||||
u8 *buffer = (u8 *)dol.datamem[cnt];
|
||||
u32 len = dol.datasize[cnt];
|
||||
|
||||
/* Seek */
|
||||
ES_SeekContent(cfd, offset, 0);
|
||||
|
||||
/* Read */
|
||||
ret = ES_ReadContent(cfd, buffer, len);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* Patch */
|
||||
__Loader_PatchDol(buffer, len);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set entry point */
|
||||
*p_entry = (dolentry)dol.entry;
|
||||
|
||||
out:
|
||||
/* Close DOL file */
|
||||
if (cfd >= 0)
|
||||
ES_CloseContent(cfd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __Loader_Shutdown(void)
|
||||
{
|
||||
/* Deinitialize ISFS */
|
||||
ISFS_Deinitialize();
|
||||
|
||||
/* Shutdown IOS subsystems */
|
||||
SYS_ResetSystem(SYS_SHUTDOWN, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
s32 Loader_Execute(void)
|
||||
{
|
||||
dolentry p_entry = NULL;
|
||||
|
||||
u64 tid;
|
||||
s32 ret;
|
||||
|
||||
/* Get title ID */
|
||||
ret = ES_GetTitleID(&tid);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Load DOL */
|
||||
ret = __Loader_ReadDol(&p_entry);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Set low memory */
|
||||
__Loader_SetLowMem();
|
||||
|
||||
/* Set video mode */
|
||||
__Loader_SetVMode(tid);
|
||||
|
||||
/* Shutdown subsystems */
|
||||
__Loader_Shutdown();
|
||||
|
||||
/* Clear screen */
|
||||
Video_Clear(COLOR_BLACK);
|
||||
|
||||
/* Jump to the entry point */
|
||||
p_entry();
|
||||
|
||||
return 0;
|
||||
}
|
8
nand-loader/source/loader.h
Normal file
8
nand-loader/source/loader.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef _LOADER_H_
|
||||
#define _LOADER_H_
|
||||
|
||||
/* Prototypes */
|
||||
s32 Loader_Execute(void);
|
||||
|
||||
#endif
|
||||
|
78
nand-loader/source/nandloader.c
Normal file
78
nand-loader/source/nandloader.c
Normal file
@ -0,0 +1,78 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <ogcsys.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "gui.h"
|
||||
#include "loader.h"
|
||||
#include "sys.h"
|
||||
#include "video.h"
|
||||
#include "wpad.h"
|
||||
|
||||
/* Constans */
|
||||
#define RESTART_SECONDS 4
|
||||
|
||||
|
||||
/* Override IOS_LoadStartupIOS */
|
||||
s32 __IOS_LoadStartupIOS() { return 0; }
|
||||
|
||||
|
||||
void Menu(void)
|
||||
{
|
||||
/* Initialize Wiimote */
|
||||
Wpad_Init();
|
||||
|
||||
/* Draw background */
|
||||
Gui_DrawBackground();
|
||||
|
||||
/* Initialize console */
|
||||
Gui_InitConsole();
|
||||
|
||||
/* Configuration menu */
|
||||
Config_Menu();
|
||||
|
||||
/* Destroy console */
|
||||
Con_Destroy();
|
||||
|
||||
/* Disconnect Wiimote */
|
||||
Wpad_Disconnect();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
s32 ret;
|
||||
|
||||
/* Initialize subsystems */
|
||||
Sys_Init();
|
||||
|
||||
/* Set video mode */
|
||||
Video_SetMode();
|
||||
|
||||
/* Initialize ISFS */
|
||||
ISFS_Initialize();
|
||||
|
||||
/* Read config */
|
||||
Config_Read();
|
||||
|
||||
/* Config menu */
|
||||
ret = SYS_ResetButtonDown();
|
||||
if (ret)
|
||||
Menu();
|
||||
|
||||
/* Draw loading image */
|
||||
Gui_DrawLoading();
|
||||
|
||||
/* Execute application */
|
||||
Loader_Execute();
|
||||
|
||||
/* Draw error image */
|
||||
Gui_DrawError();
|
||||
|
||||
/* Sleep */
|
||||
sleep(RESTART_SECONDS);
|
||||
|
||||
/* Load System Menu */
|
||||
Sys_LoadMenu();
|
||||
|
||||
return 0;
|
||||
}
|
126
nand-loader/source/patches.c
Normal file
126
nand-loader/source/patches.c
Normal file
@ -0,0 +1,126 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ogcsys.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
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,
|
||||
NULL, NULL
|
||||
};
|
||||
|
||||
GXRModeObj *NTSC2PAL[] = {
|
||||
&TVNtsc240Ds, &TVPal264Ds,
|
||||
&TVNtsc240DsAa, &TVPal264DsAa,
|
||||
&TVNtsc240Int, &TVPal264Int,
|
||||
&TVNtsc240IntAa, &TVPal264IntAa,
|
||||
&TVNtsc480IntDf, &TVPal528IntDf,
|
||||
&TVNtsc480IntAa, &TVPal524IntAa,
|
||||
&TVNtsc480Prog, &TVPal528IntDf,
|
||||
NULL, NULL
|
||||
};
|
||||
|
||||
GXRModeObj *NTSC2PAL60[]={
|
||||
&TVNtsc240Ds, &TVEurgb60Hz240Ds,
|
||||
&TVNtsc240DsAa, &TVEurgb60Hz240DsAa,
|
||||
&TVNtsc240Int, &TVEurgb60Hz240Int,
|
||||
&TVNtsc240IntAa, &TVEurgb60Hz240IntAa,
|
||||
&TVNtsc480IntDf, &TVEurgb60Hz480IntDf,
|
||||
&TVNtsc480IntAa, &TVEurgb60Hz480IntAa,
|
||||
&TVNtsc480Prog, &TVEurgb60Hz480Prog,
|
||||
NULL, NULL
|
||||
};
|
||||
|
||||
|
||||
void Patch_VideoMode(u8 *buffer, u32 len)
|
||||
{
|
||||
GXRModeObj **table = NULL;
|
||||
|
||||
u32 cnt, idx;
|
||||
|
||||
/* Select conversion table */
|
||||
if (loaderCfg.forcePal50)
|
||||
table = NTSC2PAL;
|
||||
if (loaderCfg.forcePal60)
|
||||
table = NTSC2PAL60;
|
||||
if (loaderCfg.forceNtsc)
|
||||
table = PAL2NTSC;
|
||||
|
||||
/* No table selected */
|
||||
if (!table)
|
||||
return;
|
||||
|
||||
for (cnt = 0; cnt < len; cnt += 4) {
|
||||
u8 *ptr = buffer + cnt;
|
||||
|
||||
/* Search for video modes */
|
||||
for (idx = 0; table[idx]; idx += 2) {
|
||||
/* Patch video mode */
|
||||
if (!memcmp(ptr, table[idx], sizeof(GXRModeObj)))
|
||||
memcpy(ptr, table[idx+1], sizeof(GXRModeObj));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// void __Patch_VideoMode(u8 *buffer, u32 len)
|
||||
// {
|
||||
// const u8 pattern[] = { 0x54, 0x00, 0xFF, 0xFE };
|
||||
//
|
||||
// u64 tid;
|
||||
// u32 cnt;
|
||||
//
|
||||
// /* Get title ID */
|
||||
// ES_GetTitleID(&tid);
|
||||
//
|
||||
// for (cnt = 0; cnt < len; cnt += 4) {
|
||||
// u32 *ptr = (u32 *)(buffer + cnt);
|
||||
//
|
||||
// /* Pattern found */
|
||||
// if (!memcmp(ptr, pattern, sizeof(pattern))) {
|
||||
// u8 region = tid & 0xFF;
|
||||
//
|
||||
// /* USA region */
|
||||
// if (region == 'E')
|
||||
// *ptr = 0x38000001;
|
||||
// /* JAP region */
|
||||
// if (region == 'J')
|
||||
// *ptr = 0x38000000;
|
||||
//
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// void Patch_VideoMode(u8 *buffer, u32 len)
|
||||
// {
|
||||
// const u8 pattern[] = { 0x41, 0x82, 0x00, 0x0C, 0x41, 0x80, 0x00, 0x1C, 0x48, 0x00, 0x00, 0x18 };
|
||||
//
|
||||
// u32 cnt;
|
||||
//
|
||||
// for (cnt = 0; cnt < len; cnt += 4) {
|
||||
// u8 *ptr = buffer + cnt;
|
||||
//
|
||||
// /* Pattern found */
|
||||
// if (!memcmp(ptr, pattern, sizeof(pattern)))
|
||||
// __Patch_VideoMode(ptr, len - cnt);
|
||||
// }
|
||||
// }
|
7
nand-loader/source/patches.h
Normal file
7
nand-loader/source/patches.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef _PATCHES_H_
|
||||
#define _PATCHES_H_
|
||||
|
||||
/* Prototypes */
|
||||
void Patch_VideoMode(u8 *, u32);
|
||||
|
||||
#endif
|
118
nand-loader/source/stub.S
Normal file
118
nand-loader/source/stub.S
Normal file
@ -0,0 +1,118 @@
|
||||
.rodata
|
||||
|
||||
.globl bgData
|
||||
bgData:
|
||||
.incbin "../data/background"
|
||||
|
||||
.globl loadingImg
|
||||
loadingImg:
|
||||
.incbin "../data/loading"
|
||||
|
||||
.globl errorImg
|
||||
errorImg:
|
||||
.incbin "../data/error"
|
||||
|
||||
|
||||
|
||||
#include "asm.h"
|
||||
|
||||
.text
|
||||
.section .stub
|
||||
|
||||
.extern _start
|
||||
.globl _stub_start
|
||||
_stub_start:
|
||||
lis r3, 0x0011
|
||||
ori r3, r3, 0x0C64
|
||||
mtspr HID0, r3
|
||||
isync
|
||||
|
||||
li r4, 0x2000
|
||||
mtmsr r4
|
||||
|
||||
ori r3, r3, 0xC000
|
||||
mtspr HID0, r3
|
||||
isync
|
||||
|
||||
li r0, 0
|
||||
mtspr IBAT0U, r0
|
||||
mtspr IBAT1U, r0
|
||||
mtspr IBAT2U, r0
|
||||
mtspr IBAT3U, r0
|
||||
mtspr IBAT4U, r0
|
||||
mtspr IBAT5U, r0
|
||||
mtspr DBAT0U, r0
|
||||
mtspr DBAT1U, r0
|
||||
mtspr DBAT2U, r0
|
||||
mtspr DBAT3U, r0
|
||||
mtspr DBAT4U, r0
|
||||
mtspr DBAT5U, r0
|
||||
isync
|
||||
|
||||
lis r0, 0x8000
|
||||
mtsr 0, r0
|
||||
mtsr 1, r0
|
||||
mtsr 2, r0
|
||||
mtsr 3, r0
|
||||
mtsr 4, r0
|
||||
mtsr 5, r0
|
||||
mtsr 6, r0
|
||||
mtsr 7, r0
|
||||
mtsr 8, r0
|
||||
mtsr 9, r0
|
||||
mtsr 10, r0
|
||||
mtsr 11, r0
|
||||
mtsr 12, r0
|
||||
mtsr 13, r0
|
||||
mtsr 14, r0
|
||||
mtsr 15, r0
|
||||
isync
|
||||
|
||||
li r3, 2
|
||||
lis r4, 0x8000
|
||||
ori r4, r4, 0x1FFF
|
||||
mtspr DBAT0L, r3
|
||||
mtspr DBAT0U, r4
|
||||
isync
|
||||
mtspr IBAT0L, r3
|
||||
mtspr IBAT0U, r4
|
||||
isync
|
||||
|
||||
addis r3, r3, 0x1000
|
||||
addis r4, r4, 0x1000
|
||||
mtspr DBAT4L, r3
|
||||
mtspr DBAT4U, r4
|
||||
isync
|
||||
mtspr IBAT4L, r3
|
||||
mtspr IBAT4U, r4
|
||||
isync
|
||||
|
||||
li r3, 0x2A
|
||||
lis r4, 0xC000
|
||||
ori r4, r4, 0x1FFF
|
||||
mtspr DBAT1L, r3
|
||||
mtspr DBAT1U, r4
|
||||
isync
|
||||
mtspr IBAT1L, r3
|
||||
mtspr IBAT1U, r4
|
||||
isync
|
||||
|
||||
addis r3, r3, 0x1000
|
||||
addis r4, r4, 0x1000
|
||||
mtspr DBAT2L, r3
|
||||
mtspr DBAT2U, r4
|
||||
isync
|
||||
mtspr IBAT2L, r3
|
||||
mtspr IBAT2U, r4
|
||||
isync
|
||||
|
||||
li r3, 0
|
||||
mfmsr r3
|
||||
ori r3, r3, MSR_DR|MSR_IR
|
||||
mtsrr1 r3
|
||||
|
||||
lis r3, _start@h
|
||||
ori r3, r3, _start@l
|
||||
mtsrr0 r3
|
||||
|
||||
rfi
|
48
nand-loader/source/sys.c
Normal file
48
nand-loader/source/sys.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ogcsys.h>
|
||||
|
||||
/* Constants */
|
||||
#define CERTS_LEN 0x280
|
||||
|
||||
/* Variables */
|
||||
static const char certs_fs[] ATTRIBUTE_ALIGN(32) = "/sys/cert.sys";
|
||||
|
||||
|
||||
void Sys_Init(void)
|
||||
{
|
||||
/* Initialize video subsytem */
|
||||
VIDEO_Init();
|
||||
}
|
||||
|
||||
void Sys_LoadMenu(void)
|
||||
{
|
||||
/* Return to the Wii system menu */
|
||||
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
|
||||
}
|
||||
|
||||
s32 Sys_GetCerts(signed_blob **certs, u32 *len)
|
||||
{
|
||||
static signed_blob certificates[CERTS_LEN] ATTRIBUTE_ALIGN(32);
|
||||
|
||||
s32 fd, ret;
|
||||
|
||||
/* Open certificates file */
|
||||
fd = IOS_Open(certs_fs, 1);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
/* Read certificates */
|
||||
ret = IOS_Read(fd, certificates, sizeof(certificates));
|
||||
|
||||
/* Close file */
|
||||
IOS_Close(fd);
|
||||
|
||||
/* Set values */
|
||||
if (ret > 0) {
|
||||
*certs = certificates;
|
||||
*len = sizeof(certificates);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
9
nand-loader/source/sys.h
Normal file
9
nand-loader/source/sys.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef _SYS_H_
|
||||
#define _SYS_H_
|
||||
|
||||
/* Prototypes */
|
||||
void Sys_Init(void);
|
||||
void Sys_LoadMenu(void);
|
||||
s32 Sys_GetCerts(signed_blob **, u32 *);
|
||||
|
||||
#endif
|
256
nand-loader/source/title.c
Executable file
256
nand-loader/source/title.c
Executable file
@ -0,0 +1,256 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <ogcsys.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
s32 Title_GetList(u64 **outbuf, u32 *outlen)
|
||||
{
|
||||
u64 *titles = NULL;
|
||||
|
||||
u32 len, nb_titles;
|
||||
s32 ret;
|
||||
|
||||
/* Get number of titles */
|
||||
ret = ES_GetNumTitles(&nb_titles);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Calculate buffer lenght */
|
||||
len = round_up(sizeof(u64) * nb_titles, 32);
|
||||
|
||||
/* Allocate memory */
|
||||
titles = memalign(32, len);
|
||||
if (!titles)
|
||||
return -1;
|
||||
|
||||
/* Get titles */
|
||||
ret = ES_GetTitles(titles, nb_titles);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Set values */
|
||||
*outbuf = titles;
|
||||
*outlen = nb_titles;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
/* Free memory */
|
||||
if (titles)
|
||||
free(titles);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 Title_GetTicketViews(u64 tid, tikview **outbuf, u32 *outlen)
|
||||
{
|
||||
tikview *views = NULL;
|
||||
|
||||
u32 nb_views;
|
||||
s32 ret;
|
||||
|
||||
/* Get number of ticket views */
|
||||
ret = ES_GetNumTicketViews(tid, &nb_views);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Allocate memory */
|
||||
views = (tikview *)memalign(32, sizeof(tikview) * nb_views);
|
||||
if (!views)
|
||||
return -1;
|
||||
|
||||
/* Get ticket views */
|
||||
ret = ES_GetTicketViews(tid, views, nb_views);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Set values */
|
||||
*outbuf = views;
|
||||
*outlen = nb_views;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
/* Free memory */
|
||||
if (views)
|
||||
free(views);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 Title_GetTMD(u64 tid, signed_blob **outbuf, u32 *outlen)
|
||||
{
|
||||
void *p_tmd = NULL;
|
||||
|
||||
u32 len;
|
||||
s32 ret;
|
||||
|
||||
/* Get TMD size */
|
||||
ret = ES_GetStoredTMDSize(tid, &len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Allocate memory */
|
||||
p_tmd = memalign(32, round_up(len, 32));
|
||||
if (!p_tmd)
|
||||
return -1;
|
||||
|
||||
/* Read TMD */
|
||||
ret = ES_GetStoredTMD(tid, p_tmd, len);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Set values */
|
||||
*outbuf = p_tmd;
|
||||
*outlen = len;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
/* Free memory */
|
||||
if (p_tmd)
|
||||
free(p_tmd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 Title_GetVersion(u64 tid, u16 *outbuf)
|
||||
{
|
||||
signed_blob *p_tmd = NULL;
|
||||
tmd *tmd_data = NULL;
|
||||
|
||||
u32 len;
|
||||
s32 ret;
|
||||
|
||||
/* Get title TMD */
|
||||
ret = Title_GetTMD(tid, &p_tmd, &len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Retrieve TMD info */
|
||||
tmd_data = (tmd *)SIGNATURE_PAYLOAD(p_tmd);
|
||||
|
||||
/* Set values */
|
||||
*outbuf = tmd_data->title_version;
|
||||
|
||||
/* Free memory */
|
||||
free(p_tmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 Title_GetSysVersion(u64 tid, u64 *outbuf)
|
||||
{
|
||||
signed_blob *p_tmd = NULL;
|
||||
tmd *tmd_data = NULL;
|
||||
|
||||
u32 len;
|
||||
s32 ret;
|
||||
|
||||
/* Get title TMD */
|
||||
ret = Title_GetTMD(tid, &p_tmd, &len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Retrieve TMD info */
|
||||
tmd_data = (tmd *)SIGNATURE_PAYLOAD(p_tmd);
|
||||
|
||||
/* Set values */
|
||||
*outbuf = tmd_data->sys_version;
|
||||
|
||||
/* Free memory */
|
||||
free(p_tmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 Title_GetSize(u64 tid, u32 *outbuf)
|
||||
{
|
||||
signed_blob *p_tmd = NULL;
|
||||
tmd *tmd_data = NULL;
|
||||
|
||||
u32 cnt, len, size = 0;
|
||||
s32 ret;
|
||||
|
||||
/* Get title TMD */
|
||||
ret = Title_GetTMD(tid, &p_tmd, &len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Retrieve TMD info */
|
||||
tmd_data = (tmd *)SIGNATURE_PAYLOAD(p_tmd);
|
||||
|
||||
/* Calculate title size */
|
||||
for (cnt = 0; cnt < tmd_data->num_contents; cnt++) {
|
||||
tmd_content *content = &tmd_data->contents[cnt];
|
||||
|
||||
/* Add content size */
|
||||
size += content->size;
|
||||
}
|
||||
|
||||
/* Set values */
|
||||
*outbuf = size;
|
||||
|
||||
/* Free memory */
|
||||
free(p_tmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 Title_GetIOSVersions(u8 **outbuf, u32 *outlen)
|
||||
{
|
||||
u8 *buffer = NULL;
|
||||
u64 *list = NULL;
|
||||
|
||||
u32 count, cnt, idx;
|
||||
s32 ret;
|
||||
|
||||
/* Get title list */
|
||||
ret = Title_GetList(&list, &count);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Count IOS */
|
||||
for (cnt = idx = 0; idx < count; idx++) {
|
||||
u32 tidh = (list[idx] >> 32);
|
||||
u32 tidl = (list[idx] & 0xFFFFFFFF);
|
||||
|
||||
/* Title is IOS */
|
||||
if ((tidh == 0x1) && (tidl >= 3) && (tidl <= 255))
|
||||
cnt++;
|
||||
}
|
||||
|
||||
/* Allocate memory */
|
||||
buffer = (u8 *)memalign(32, cnt);
|
||||
if (!buffer) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Copy IOS */
|
||||
for (cnt = idx = 0; idx < count; idx++) {
|
||||
u32 tidh = (list[idx] >> 32);
|
||||
u32 tidl = (list[idx] & 0xFFFFFFFF);
|
||||
|
||||
/* Title is IOS */
|
||||
if ((tidh == 0x1) && (tidl >= 3) && (tidl <= 255))
|
||||
buffer[cnt++] = (u8)(tidl & 0xFF);
|
||||
}
|
||||
|
||||
/* Set values */
|
||||
*outbuf = buffer;
|
||||
*outlen = cnt;
|
||||
|
||||
goto out;
|
||||
|
||||
out:
|
||||
/* Free memory */
|
||||
if (list)
|
||||
free(list);
|
||||
|
||||
return ret;
|
||||
}
|
16
nand-loader/source/title.h
Executable file
16
nand-loader/source/title.h
Executable file
@ -0,0 +1,16 @@
|
||||
#ifndef _TITLE_H_
|
||||
#define _TITLE_H_
|
||||
|
||||
/* Constants */
|
||||
#define BLOCK_SIZE 1024
|
||||
|
||||
/* Prototypes */
|
||||
s32 Title_GetList(u64 **, u32 *);
|
||||
s32 Title_GetTicketViews(u64, tikview **, u32 *);
|
||||
s32 Title_GetTMD(u64, signed_blob **, u32 *);
|
||||
s32 Title_GetVersion(u64, u16 *);
|
||||
s32 Title_GetSysVersion(u64, u64 *);
|
||||
s32 Title_GetSize(u64, u32 *);
|
||||
s32 Title_GetIOSVersions(u8 **, u32 *);
|
||||
|
||||
#endif
|
15
nand-loader/source/utils.h
Normal file
15
nand-loader/source/utils.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef _UTILS_H_
|
||||
#define _UTILS_H_
|
||||
|
||||
/* Constants */
|
||||
#define KB_SIZE 1024.0
|
||||
#define MB_SIZE 1048576.0
|
||||
#define GB_SIZE 1073741824.0
|
||||
|
||||
/* Macros */
|
||||
#define round_up(x,n) (-(-(x) & -(n)))
|
||||
|
||||
/* Prototypes */
|
||||
u32 swap32(u32);
|
||||
|
||||
#endif
|
147
nand-loader/source/video.c
Normal file
147
nand-loader/source/video.c
Normal file
@ -0,0 +1,147 @@
|
||||
#include <stdio.h>
|
||||
#include <ogcsys.h>
|
||||
|
||||
#include "sys.h"
|
||||
#include "video.h"
|
||||
|
||||
/* Video variables */
|
||||
static void *framebuffer = NULL;
|
||||
static GXRModeObj *vmode = NULL;
|
||||
|
||||
|
||||
void Con_Init(u32 x, u32 y, u32 w, u32 h)
|
||||
{
|
||||
/* Create console in the framebuffer */
|
||||
CON_InitEx(vmode, x, y, w, h);
|
||||
}
|
||||
|
||||
void Con_Destroy(void)
|
||||
{
|
||||
/* Destroy console */
|
||||
VIDEO_SetPostRetraceCallback(NULL);
|
||||
}
|
||||
|
||||
void Con_Clear(void)
|
||||
{
|
||||
/* Clear console */
|
||||
printf("\x1b[2J");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void Con_ClearLine(void)
|
||||
{
|
||||
s32 cols, rows;
|
||||
u32 cnt;
|
||||
|
||||
printf("\r");
|
||||
fflush(stdout);
|
||||
|
||||
/* Get console metrics */
|
||||
CON_GetMetrics(&cols, &rows);
|
||||
|
||||
/* Erase line */
|
||||
for (cnt = 1; cnt < cols; cnt++) {
|
||||
printf(" ");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
printf("\r");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void Con_FgColor(u32 color, u8 bold)
|
||||
{
|
||||
/* Set foreground color */
|
||||
printf("\x1b[%u;%um", color + 30, bold);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void Con_BgColor(u32 color, u8 bold)
|
||||
{
|
||||
/* Set background color */
|
||||
printf("\x1b[%u;%um", color + 40, bold);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void Con_FillRow(u32 row, u32 color, u8 bold)
|
||||
{
|
||||
s32 cols, rows;
|
||||
u32 cnt;
|
||||
|
||||
/* Set color */
|
||||
printf("\x1b[%u;%um", color + 40, bold);
|
||||
fflush(stdout);
|
||||
|
||||
/* Get console metrics */
|
||||
CON_GetMetrics(&cols, &rows);
|
||||
|
||||
/* Save current row and col */
|
||||
printf("\x1b[s");
|
||||
fflush(stdout);
|
||||
|
||||
/* Move to specified row */
|
||||
printf("\x1b[%u;0H", row);
|
||||
fflush(stdout);
|
||||
|
||||
/* Fill row */
|
||||
for (cnt = 0; cnt < cols; cnt++) {
|
||||
printf(" ");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/* Load saved row and col */
|
||||
printf("\x1b[u");
|
||||
fflush(stdout);
|
||||
|
||||
/* Set default color */
|
||||
Con_BgColor(0, 0);
|
||||
Con_FgColor(7, 1);
|
||||
}
|
||||
|
||||
void Video_Configure(GXRModeObj *rmode)
|
||||
{
|
||||
/* Configure the video subsystem */
|
||||
VIDEO_Configure(rmode);
|
||||
|
||||
/* Setup video */
|
||||
VIDEO_SetBlack(FALSE);
|
||||
VIDEO_Flush();
|
||||
VIDEO_WaitVSync();
|
||||
|
||||
if (rmode->viTVMode & VI_NON_INTERLACE)
|
||||
VIDEO_WaitVSync();
|
||||
}
|
||||
|
||||
void Video_SetMode(void)
|
||||
{
|
||||
/* Select preferred video mode */
|
||||
vmode = VIDEO_GetPreferredMode(NULL);
|
||||
|
||||
/* Allocate memory for the framebuffer */
|
||||
framebuffer = MEM_K0_TO_K1(SYS_AllocateFramebuffer(vmode));
|
||||
|
||||
/* Configure the video subsystem */
|
||||
VIDEO_Configure(vmode);
|
||||
|
||||
/* Setup video */
|
||||
VIDEO_SetNextFramebuffer(framebuffer);
|
||||
VIDEO_SetBlack(FALSE);
|
||||
VIDEO_Flush();
|
||||
VIDEO_WaitVSync();
|
||||
|
||||
if (vmode->viTVMode & VI_NON_INTERLACE)
|
||||
VIDEO_WaitVSync();
|
||||
|
||||
/* Clear the screen */
|
||||
Video_Clear(COLOR_BLACK);
|
||||
}
|
||||
|
||||
void Video_Clear(s32 color)
|
||||
{
|
||||
VIDEO_ClearFrameBuffer(vmode, framebuffer, color);
|
||||
}
|
||||
|
||||
void Video_DrawPng(IMGCTX ctx, PNGUPROP imgProp, u16 x, u16 y)
|
||||
{
|
||||
PNGU_DECODE_TO_COORDS_YCbYCr(ctx, x, y, imgProp.imgWidth, imgProp.imgHeight, vmode->fbWidth, vmode->xfbHeight, framebuffer);
|
||||
}
|
20
nand-loader/source/video.h
Normal file
20
nand-loader/source/video.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef _VIDEO_H_
|
||||
#define _VIDEO_H_
|
||||
|
||||
#include "libpng/pngu/pngu.h"
|
||||
|
||||
/* Prototypes */
|
||||
void Con_Init(u32, u32, u32, u32);
|
||||
void Con_Destroy(void);
|
||||
void Con_Clear(void);
|
||||
void Con_ClearLine(void);
|
||||
void Con_FgColor(u32, u8);
|
||||
void Con_BgColor(u32, u8);
|
||||
void Con_FillRow(u32, u32, u8);
|
||||
|
||||
void Video_Configure(GXRModeObj *);
|
||||
void Video_SetMode(void);
|
||||
void Video_Clear(s32);
|
||||
void Video_DrawPng(IMGCTX, PNGUPROP, u16, u16);
|
||||
|
||||
#endif
|
60
nand-loader/source/wpad.c
Normal file
60
nand-loader/source/wpad.c
Normal file
@ -0,0 +1,60 @@
|
||||
#include <stdio.h>
|
||||
#include <ogcsys.h>
|
||||
|
||||
#include "sys.h"
|
||||
#include "wpad.h"
|
||||
|
||||
/* Constants */
|
||||
#define MAX_WIIMOTES 4
|
||||
|
||||
|
||||
s32 Wpad_Init(void)
|
||||
{
|
||||
s32 ret;
|
||||
|
||||
/* Initialize Wiimote subsystem */
|
||||
ret = WPAD_Init();
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Wpad_Disconnect(void)
|
||||
{
|
||||
u32 cnt;
|
||||
|
||||
/* Disconnect Wiimotes */
|
||||
for (cnt = 0; cnt < MAX_WIIMOTES; cnt++)
|
||||
WPAD_Disconnect(cnt);
|
||||
|
||||
/* Shutdown Wiimote subsystem */
|
||||
WPAD_Shutdown();
|
||||
}
|
||||
|
||||
u32 Wpad_GetButtons(void)
|
||||
{
|
||||
u32 buttons = 0, cnt;
|
||||
|
||||
/* Scan pads */
|
||||
WPAD_ScanPads();
|
||||
|
||||
/* Get pressed buttons */
|
||||
for (cnt = 0; cnt < MAX_WIIMOTES; cnt++)
|
||||
buttons |= WPAD_ButtonsDown(cnt);
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
u32 Wpad_WaitButtons(void)
|
||||
{
|
||||
u32 buttons = 0;
|
||||
|
||||
/* Wait for button pressing */
|
||||
while (!buttons) {
|
||||
buttons = Wpad_GetButtons();
|
||||
VIDEO_WaitVSync();
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
12
nand-loader/source/wpad.h
Normal file
12
nand-loader/source/wpad.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _WPAD_H_
|
||||
#define _WPAD_H_
|
||||
|
||||
#include <wiiuse/wpad.h>
|
||||
|
||||
/* Prototypes */
|
||||
s32 Wpad_Init(void);
|
||||
void Wpad_Disconnect(void);
|
||||
u32 Wpad_GetButtons(void);
|
||||
u32 Wpad_WaitButtons(void);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user