diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ec3c33c --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +/fs/build +/installer/bin +/loader/build +/menu/build +/server/logs/*.txt +/build +/*.elf +/fs/*.elf +/loader/*.elf +/sd_loader/build +/sd_loader/*.elf +/udp_debug_reader/obj +/udp_debug_reader/GeckoLog.txt \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..866adf6 --- /dev/null +++ b/Makefile @@ -0,0 +1,215 @@ +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") +endif +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") +endif +export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) +export LIBOGC_INC := $(DEVKITPRO)/libogc/include +export LIBOGC_LIB := $(DEVKITPRO)/libogc/lib/wii +export PORTLIBS := $(DEVKITPRO)/portlibs/ppc + +PREFIX := powerpc-eabi- + +export AS := $(PREFIX)as +export CC := $(PREFIX)gcc +export CXX := $(PREFIX)g++ +export AR := $(PREFIX)ar +export OBJCOPY := $(PREFIX)objcopy + +#--------------------------------------------------------------------------------- +# 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 := ft2sd +BUILD := build +BUILD_DBG := $(TARGET)_dbg +SOURCES := src \ + src/dynamic_libs \ + src/fs \ + src/system \ + src/utils +DATA := + +INCLUDES := src + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +CFLAGS := -std=gnu11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \ + -O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE) +CXXFLAGS := -std=gnu++11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \ + -O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE) +ASFLAGS := -mregnames +LDFLAGS := -nostartfiles -Wl,-Map,$(notdir $@).map,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r,-wrap,valloc,-wrap,_valloc_r,-wrap,_pvalloc_r,--gc-sections + +#--------------------------------------------------------------------------------- +Q := @ +MAKEFLAGS += --no-print-directory +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -lgcc -lgd -lpng -lz -lfreetype -lvorbisidec -liosuhax + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(CURDIR) \ + $(DEVKITPPC)/lib \ + $(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2 + + +#--------------------------------------------------------------------------------- +# 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 PROJECTDIR := $(CURDIR) +export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(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)/*.*))) +TTFFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.ttf))) +PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png))) + +#--------------------------------------------------------------------------------- +# 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) \ + $(PNGFILES:.png=.png.o) $(addsuffix .o,$(BINFILES)) + +#--------------------------------------------------------------------------------- +# 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) \ + -I$(PORTLIBS)/include -I$(PORTLIBS)/include/freetype2 + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + -L$(LIBOGC_LIB) -L$(PORTLIBS)/lib + +export OUTPUT := $(CURDIR)/$(TARGET) +.PHONY: $(BUILD) clean install + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).elf: $(OFILES) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .jpg extension +#--------------------------------------------------------------------------------- +%.elf: link.ld $(OFILES) + @echo "linking ... $(TARGET).elf" + $(Q)$(LD) -n -T $^ $(LDFLAGS) -o ../$(BUILD_DBG).elf $(LIBPATHS) $(LIBS) + $(Q)$(OBJCOPY) -S -R .comment -R .gnu.attributes ../$(BUILD_DBG).elf $@ + +../data/loader.bin: + $(MAKE) -C ../loader clean + $(MAKE) -C ../loader +#--------------------------------------------------------------------------------- +%.a: +#--------------------------------------------------------------------------------- + @echo $(notdir $@) + @rm -f $@ + @$(AR) -rc $@ $^ + +#--------------------------------------------------------------------------------- +%.o: %.cpp + @echo $(notdir $<) + @$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER) + +#--------------------------------------------------------------------------------- +%.o: %.c + @echo $(notdir $<) + @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) -c $< -o $@ $(ERROR_FILTER) + +#--------------------------------------------------------------------------------- +%.o: %.S + @echo $(notdir $<) + @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@ $(ERROR_FILTER) + +#--------------------------------------------------------------------------------- +%.png.o : %.png + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.jpg.o : %.jpg + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.ttf.o : %.ttf + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.bin.o : %.bin + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.wav.o : %.wav + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.mp3.o : %.mp3 + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.ogg.o : %.ogg + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- diff --git a/meta/meta.xml b/meta/meta.xml new file mode 100644 index 0000000..22755c4 --- /dev/null +++ b/meta/meta.xml @@ -0,0 +1,11 @@ + + + FT2SD + Dimok + 0.1 + 20161101200000 + File Tree 2 SD + File tree to SD dumper. + + + diff --git a/src/common/common.h b/src/common/common.h new file mode 100644 index 0000000..538b5ad --- /dev/null +++ b/src/common/common.h @@ -0,0 +1,36 @@ +#ifndef COMMON_H +#define COMMON_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "os_defs.h" + +#define CAFE_OS_SD_PATH "/vol/external01" +#define SD_PATH "sd:" +#define WIIU_PATH "/wiiu" + +#ifndef MEM_BASE +#define MEM_BASE (0x00800000) +#endif + +#define ELF_DATA_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x00)) +#define ELF_DATA_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x04)) +#define MAIN_ENTRY_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x00)) +#define OS_FIRMWARE (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x04)) + +#define OS_SPECIFICS ((OsSpecifics*)(MEM_BASE + 0x1500)) + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#define EXIT_HBL_EXIT 0xFFFFFFFE +#define EXIT_RELAUNCH_ON_LOAD 0xFFFFFFFD + +#ifdef __cplusplus +} +#endif + +#endif /* COMMON_H */ + diff --git a/src/common/fs_defs.h b/src/common/fs_defs.h new file mode 100644 index 0000000..feda725 --- /dev/null +++ b/src/common/fs_defs.h @@ -0,0 +1,62 @@ +#ifndef FS_DEFS_H +#define FS_DEFS_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* FS defines and types */ +#define FS_MAX_LOCALPATH_SIZE 511 +#define FS_MAX_MOUNTPATH_SIZE 128 +#define FS_MAX_FULLPATH_SIZE (FS_MAX_LOCALPATH_SIZE + FS_MAX_MOUNTPATH_SIZE) +#define FS_MAX_ARGPATH_SIZE FS_MAX_FULLPATH_SIZE + +#define FS_STATUS_OK 0 +#define FS_RET_UNSUPPORTED_CMD 0x0400 +#define FS_RET_NO_ERROR 0x0000 +#define FS_RET_ALL_ERROR (unsigned int)(-1) + +#define FS_STAT_FLAG_IS_DIRECTORY 0x80000000 + +/* max length of file/dir name */ +#define FS_MAX_ENTNAME_SIZE 256 + +#define FS_SOURCETYPE_EXTERNAL 0 +#define FS_SOURCETYPE_HFIO 1 +#define FS_SOURCETYPE_HFIO 1 + +#define FS_MOUNT_SOURCE_SIZE 0x300 +#define FS_CLIENT_SIZE 0x1700 +#define FS_CMD_BLOCK_SIZE 0xA80 + +typedef struct +{ + uint32_t flag; + uint32_t permission; + uint32_t owner_id; + uint32_t group_id; + uint32_t size; + uint32_t alloc_size; + uint64_t quota_size; + uint32_t ent_id; + uint64_t ctime; + uint64_t mtime; + uint8_t attributes[48]; +} __attribute__((packed)) FSStat; + +typedef struct +{ + FSStat stat; + char name[FS_MAX_ENTNAME_SIZE]; +} FSDirEntry; + + +#ifdef __cplusplus +} +#endif + +#endif /* FS_DEFS_H */ + diff --git a/src/common/os_defs.h b/src/common/os_defs.h new file mode 100644 index 0000000..48a4c8f --- /dev/null +++ b/src/common/os_defs.h @@ -0,0 +1,25 @@ +#ifndef __OS_DEFS_H_ +#define __OS_DEFS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _OsSpecifics +{ + unsigned int addr_OSDynLoad_Acquire; + unsigned int addr_OSDynLoad_FindExport; + unsigned int addr_OSTitle_main_entry; + + unsigned int addr_KernSyscallTbl1; + unsigned int addr_KernSyscallTbl2; + unsigned int addr_KernSyscallTbl3; + unsigned int addr_KernSyscallTbl4; + unsigned int addr_KernSyscallTbl5; +} OsSpecifics; + +#ifdef __cplusplus +} +#endif + +#endif // __OS_DEFS_H_ diff --git a/src/common/types.h b/src/common/types.h new file mode 100644 index 0000000..3435e56 --- /dev/null +++ b/src/common/types.h @@ -0,0 +1,7 @@ +#ifndef TYPES_H +#define TYPES_H + +#include + +#endif /* TYPES_H */ + diff --git a/src/dynamic_libs/ax_functions.c b/src/dynamic_libs/ax_functions.c new file mode 100644 index 0000000..d84d6f8 --- /dev/null +++ b/src/dynamic_libs/ax_functions.c @@ -0,0 +1,74 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#include "os_functions.h" +#include "ax_functions.h" + +EXPORT_DECL(void, AXInitWithParams, u32 * params); +EXPORT_DECL(void, AXQuit, void); +EXPORT_DECL(u32, AXGetInputSamplesPerSec, void); +EXPORT_DECL(u32, AXGetInputSamplesPerFrame, void); +EXPORT_DECL(s32, AXVoiceBegin, void *v); +EXPORT_DECL(s32, AXVoiceEnd, void *v); +EXPORT_DECL(void, AXSetVoiceType, void *v, u16 type); +EXPORT_DECL(void, AXSetVoiceOffsets, void *v, const void *buf); +EXPORT_DECL(void, AXSetVoiceSrcType, void *v, u32 type); +EXPORT_DECL(void, AXSetVoiceVe, void *v, const void *vol); +EXPORT_DECL(s32, AXSetVoiceDeviceMix, void *v, s32 device, u32 id, void *mix); +EXPORT_DECL(void, AXSetVoiceState, void *v, u16 state); +EXPORT_DECL(void, AXSetVoiceSrc, void *v, const void *src); +EXPORT_DECL(s32, AXSetVoiceSrcRatio, void *v,f32 ratio) +EXPORT_DECL(void *, AXAcquireVoice, u32 prio, void * callback, u32 arg); +EXPORT_DECL(void, AXFreeVoice, void *v); +EXPORT_DECL(void, AXRegisterFrameCallback, void * callback); +EXPORT_DECL(u32, AXGetVoiceLoopCount, void *v); +EXPORT_DECL(void, AXSetVoiceEndOffset, void *v, u32 offset); +EXPORT_DECL(void, AXSetVoiceLoopOffset, void *v, u32 offset); + +void InitAXFunctionPointers(void) +{ + unsigned int *funcPointer = 0; + unsigned int sound_handle; + OSDynLoad_Acquire("sndcore2.rpl", &sound_handle); + + OS_FIND_EXPORT(sound_handle, AXInitWithParams); + OS_FIND_EXPORT(sound_handle, AXQuit); + OS_FIND_EXPORT(sound_handle, AXGetInputSamplesPerSec); + OS_FIND_EXPORT(sound_handle, AXVoiceBegin); + OS_FIND_EXPORT(sound_handle, AXVoiceEnd); + OS_FIND_EXPORT(sound_handle, AXSetVoiceType); + OS_FIND_EXPORT(sound_handle, AXSetVoiceOffsets); + OS_FIND_EXPORT(sound_handle, AXSetVoiceSrcType); + OS_FIND_EXPORT(sound_handle, AXSetVoiceVe); + OS_FIND_EXPORT(sound_handle, AXSetVoiceDeviceMix); + OS_FIND_EXPORT(sound_handle, AXSetVoiceState); + OS_FIND_EXPORT(sound_handle, AXSetVoiceSrc); + OS_FIND_EXPORT(sound_handle, AXSetVoiceSrcRatio); + OS_FIND_EXPORT(sound_handle, AXAcquireVoice); + OS_FIND_EXPORT(sound_handle, AXFreeVoice); + OS_FIND_EXPORT(sound_handle, AXRegisterFrameCallback); + OS_FIND_EXPORT(sound_handle, AXGetVoiceLoopCount); + OS_FIND_EXPORT(sound_handle, AXSetVoiceEndOffset); + OS_FIND_EXPORT(sound_handle, AXSetVoiceLoopOffset); +} + diff --git a/src/dynamic_libs/ax_functions.h b/src/dynamic_libs/ax_functions.h new file mode 100644 index 0000000..df9647c --- /dev/null +++ b/src/dynamic_libs/ax_functions.h @@ -0,0 +1,59 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#ifndef __AX_FUNCTIONS_H_ +#define __AX_FUNCTIONS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void InitAXFunctionPointers(void); + +extern void (* AXInitWithParams)(u32 * params); +extern void (* AXQuit)(void); +extern u32 (* AXGetInputSamplesPerSec)(void); +extern s32 (* AXVoiceBegin)(void *v); +extern s32 (* AXVoiceEnd)(void *v); +extern void (* AXSetVoiceType)(void *v, u16 type); +extern void (* AXSetVoiceOffsets)(void *v, const void *buf); +extern void (* AXSetVoiceSrcType)(void *v, u32 type); +extern void (* AXSetVoiceVe)(void *v, const void *vol); +extern s32 (* AXSetVoiceDeviceMix)(void *v, s32 device, u32 id, void *mix); +extern void (* AXSetVoiceState)(void *v, u16 state); +extern void (* AXSetVoiceSrc)(void *v, const void *src); +extern s32 (* AXSetVoiceSrcRatio)(void *v, f32 ratio); +extern void * (* AXAcquireVoice)(u32 prio, void * callback, u32 arg); +extern void (* AXFreeVoice)(void *v); +extern void (* AXRegisterFrameCallback)(void * callback); +extern u32 (* AXGetVoiceLoopCount)(void * v); +extern void (* AXSetVoiceEndOffset)(void * v, u32 offset); +extern void (* AXSetVoiceLoopOffset)(void * v, u32 offset); + +#ifdef __cplusplus +} +#endif + +#endif // __VPAD_FUNCTIONS_H_ diff --git a/src/dynamic_libs/fs_functions.c b/src/dynamic_libs/fs_functions.c new file mode 100644 index 0000000..cdcc0bf --- /dev/null +++ b/src/dynamic_libs/fs_functions.c @@ -0,0 +1,120 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#include "fs_functions.h" +#include "os_functions.h" +#include "utils/utils.h" + +EXPORT_DECL(int, FSInit, void); +EXPORT_DECL(int, FSShutdown, void); +EXPORT_DECL(int, FSAddClientEx, void *pClient, int unk_zero_param, int errHandling); +EXPORT_DECL(int, FSDelClient, void *pClient); +EXPORT_DECL(void, FSInitCmdBlock, void *pCmd); +EXPORT_DECL(int, FSGetMountSource, void *pClient, void *pCmd, int type, void *source, int errHandling); + +EXPORT_DECL(int, FSMount, void *pClient, void *pCmd, void *source, char *target, uint32_t bytes, int errHandling); +EXPORT_DECL(int, FSUnmount, void *pClient, void *pCmd, const char *target, int errHandling); + +EXPORT_DECL(int, FSGetStat, void *pClient, void *pCmd, const char *path, FSStat *stats, int errHandling); +EXPORT_DECL(int, FSGetStatAsync, void *pClient, void *pCmd, const char *path, void *stats, int error, void *asyncParams); +EXPORT_DECL(int, FSRename, void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error); +EXPORT_DECL(int, FSRenameAsync, void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error, void *asyncParams); +EXPORT_DECL(int, FSRemove, void *pClient, void *pCmd, const char *path, int error); +EXPORT_DECL(int, FSRemoveAsync, void *pClient, void *pCmd, const char *path, int error, void *asyncParams); +EXPORT_DECL(int, FSFlushQuota, void *pClient, void *pCmd, const char* path, int error); +EXPORT_DECL(int, FSFlushQuotaAsync, void *pClient, void *pCmd, const char *path, int error, void *asyncParams); +EXPORT_DECL(int, FSGetFreeSpaceSize, void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int error); +EXPORT_DECL(int, FSGetFreeSpaceSizeAsync, void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int error, void *asyncParams); +EXPORT_DECL(int, FSRollbackQuota, void *pClient, void *pCmd, const char *path, int error); +EXPORT_DECL(int, FSRollbackQuotaAsync, void *pClient, void *pCmd, const char *path, int error, void *asyncParams); + +EXPORT_DECL(int, FSOpenDir, void *pClient, void *pCmd, const char *path, int *dh, int errHandling); +EXPORT_DECL(int, FSOpenDirAsync, void *pClient, void* pCmd, const char *path, int *handle, int error, void *asyncParams); +EXPORT_DECL(int, FSReadDir, void *pClient, void *pCmd, int dh, FSDirEntry *dir_entry, int errHandling); +EXPORT_DECL(int, FSRewindDir, void *pClient, void *pCmd, int dh, int errHandling); +EXPORT_DECL(int, FSCloseDir, void *pClient, void *pCmd, int dh, int errHandling); +EXPORT_DECL(int, FSChangeDir, void *pClient, void *pCmd, const char *path, int errHandling); +EXPORT_DECL(int, FSChangeDirAsync, void *pClient, void *pCmd, const char *path, int error, void *asyncParams); +EXPORT_DECL(int, FSMakeDir, void *pClient, void *pCmd, const char *path, int errHandling); +EXPORT_DECL(int, FSMakeDirAsync, void *pClient, void *pCmd, const char *path, int error, void *asyncParams); + +EXPORT_DECL(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *fd, int errHandling); +EXPORT_DECL(int, FSOpenFileAsync, void *pClient, void *pCmd, const char *path, const char *mode, int *handle, int error, const void *asyncParams); +EXPORT_DECL(int, FSReadFile, void *pClient, void *pCmd, void *buffer, int size, int count, int fd, int flag, int errHandling); +EXPORT_DECL(int, FSCloseFile, void *pClient, void *pCmd, int fd, int errHandling); + +EXPORT_DECL(int, FSFlushFile, void *pClient, void *pCmd, int fd, int error); +EXPORT_DECL(int, FSTruncateFile, void *pClient, void *pCmd, int fd, int error); +EXPORT_DECL(int, FSGetStatFile, void *pClient, void *pCmd, int fd, void *buffer, int error); +EXPORT_DECL(int, FSSetPosFile, void *pClient, void *pCmd, int fd, int pos, int error); +EXPORT_DECL(int, FSWriteFile, void *pClient, void *pCmd, const void *source, int block_size, int block_count, int fd, int flag, int error); + +void InitFSFunctionPointers(void) +{ + unsigned int *funcPointer = 0; + + OS_FIND_EXPORT(coreinit_handle, FSInit); + OS_FIND_EXPORT(coreinit_handle, FSShutdown); + OS_FIND_EXPORT(coreinit_handle, FSAddClientEx); + OS_FIND_EXPORT(coreinit_handle, FSDelClient); + OS_FIND_EXPORT(coreinit_handle, FSInitCmdBlock); + OS_FIND_EXPORT(coreinit_handle, FSGetMountSource); + + OS_FIND_EXPORT(coreinit_handle, FSMount); + OS_FIND_EXPORT(coreinit_handle, FSUnmount); + + OS_FIND_EXPORT(coreinit_handle, FSGetStat); + OS_FIND_EXPORT(coreinit_handle, FSGetStatAsync); + OS_FIND_EXPORT(coreinit_handle, FSRename); + OS_FIND_EXPORT(coreinit_handle, FSRenameAsync); + OS_FIND_EXPORT(coreinit_handle, FSRemove); + OS_FIND_EXPORT(coreinit_handle, FSRemoveAsync); + OS_FIND_EXPORT(coreinit_handle, FSFlushQuota); + OS_FIND_EXPORT(coreinit_handle, FSFlushQuotaAsync); + OS_FIND_EXPORT(coreinit_handle, FSGetFreeSpaceSize); + OS_FIND_EXPORT(coreinit_handle, FSGetFreeSpaceSizeAsync); + OS_FIND_EXPORT(coreinit_handle, FSRollbackQuota); + OS_FIND_EXPORT(coreinit_handle, FSRollbackQuotaAsync); + + OS_FIND_EXPORT(coreinit_handle, FSOpenDir); + OS_FIND_EXPORT(coreinit_handle, FSOpenDirAsync); + OS_FIND_EXPORT(coreinit_handle, FSReadDir); + OS_FIND_EXPORT(coreinit_handle, FSRewindDir); + OS_FIND_EXPORT(coreinit_handle, FSCloseDir); + OS_FIND_EXPORT(coreinit_handle, FSChangeDir); + OS_FIND_EXPORT(coreinit_handle, FSChangeDirAsync); + OS_FIND_EXPORT(coreinit_handle, FSMakeDir); + OS_FIND_EXPORT(coreinit_handle, FSMakeDirAsync); + + + OS_FIND_EXPORT(coreinit_handle, FSOpenFile); + OS_FIND_EXPORT(coreinit_handle, FSOpenFileAsync); + OS_FIND_EXPORT(coreinit_handle, FSReadFile); + OS_FIND_EXPORT(coreinit_handle, FSCloseFile); + + OS_FIND_EXPORT(coreinit_handle, FSFlushFile); + OS_FIND_EXPORT(coreinit_handle, FSTruncateFile); + OS_FIND_EXPORT(coreinit_handle, FSGetStatFile); + OS_FIND_EXPORT(coreinit_handle, FSSetPosFile); + OS_FIND_EXPORT(coreinit_handle, FSWriteFile); +} diff --git a/src/dynamic_libs/fs_functions.h b/src/dynamic_libs/fs_functions.h new file mode 100644 index 0000000..7a185e1 --- /dev/null +++ b/src/dynamic_libs/fs_functions.h @@ -0,0 +1,87 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#ifndef __FS_FUNCTIONS_H_ +#define __FS_FUNCTIONS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "common/fs_defs.h" + +void InitFSFunctionPointers(void); + +extern int (* FSInit)(void); +extern int (* FSShutdown)(void); +extern int (* FSAddClientEx)(void *pClient, int unk_zero_param, int errHandling); +extern int (* FSDelClient)(void *pClient); +extern void (* FSInitCmdBlock)(void *pCmd); +extern int (* FSGetMountSource)(void *pClient, void *pCmd, int type, void *source, int errHandling); + +extern int (* FSMount)(void *pClient, void *pCmd, void *source, char *target, uint32_t bytes, int errHandling); +extern int (* FSUnmount)(void *pClient, void *pCmd, const char *target, int errHandling); +extern int (* FSRename)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error); +extern int (* FSRenameAsync)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error, void *asyncParams); +extern int (* FSRemove)(void *pClient, void *pCmd, const char *path, int error); +extern int (* FSRemoveAsync)(void *pClient, void *pCmd, const char *path, int error, void *asyncParams); + +extern int (* FSGetStat)(void *pClient, void *pCmd, const char *path, FSStat *stats, int errHandling); +extern int (* FSGetStatAsync)(void *pClient, void *pCmd, const char *path, void *stats, int error, void *asyncParams); +extern int (* FSRename)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error); +extern int (* FSRenameAsync)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error, void *asyncParams); +extern int (* FSRemove)(void *pClient, void *pCmd, const char *path, int error); +extern int (* FSRemoveAsync)(void *pClient, void *pCmd, const char *path, int error, void *asyncParams); +extern int (* FSFlushQuota)(void *pClient, void *pCmd, const char* path, int error); +extern int (* FSFlushQuotaAsync)(void *pClient, void *pCmd, const char *path, int error, void *asyncParams); +extern int (* FSGetFreeSpaceSize)(void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int error); +extern int (* FSGetFreeSpaceSizeAsync)(void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int error, void *asyncParams); +extern int (* FSRollbackQuota)(void *pClient, void *pCmd, const char *path, int error); +extern int (* FSRollbackQuotaAsync)(void *pClient, void *pCmd, const char *path, int error, void *asyncParams); + +extern int (* FSOpenDir)(void *pClient, void *pCmd, const char *path, int *dh, int errHandling); +extern int (* FSOpenDirAsync)(void *pClient, void* pCmd, const char *path, int *handle, int error, void *asyncParams); +extern int (* FSReadDir)(void *pClient, void *pCmd, int dh, FSDirEntry *dir_entry, int errHandling); +extern int (* FSRewindDir)(void *pClient, void *pCmd, int dh, int errHandling); +extern int (* FSCloseDir)(void *pClient, void *pCmd, int dh, int errHandling); +extern int (* FSChangeDir)(void *pClient, void *pCmd, const char *path, int errHandling); +extern int (* FSChangeDirAsync)(void *pClient, void *pCmd, const char *path, int error, void *asyncParams); +extern int (* FSMakeDir)(void *pClient, void *pCmd, const char *path, int errHandling); +extern int (* FSMakeDirAsync)(void *pClient, void *pCmd, const char *path, int error, void *asyncParams); + +extern int (* FSOpenFile)(void *pClient, void *pCmd, const char *path, const char *mode, int *fd, int errHandling); +extern int (* FSOpenFileAsync)(void *pClient, void *pCmd, const char *path, const char *mode, int *handle, int error, const void *asyncParams); +extern int (* FSReadFile)(void *pClient, void *pCmd, void *buffer, int size, int count, int fd, int flag, int errHandling); +extern int (* FSCloseFile)(void *pClient, void *pCmd, int fd, int errHandling); + +extern int (* FSFlushFile)(void *pClient, void *pCmd, int fd, int error); +extern int (* FSTruncateFile)(void *pClient, void *pCmd, int fd, int error); +extern int (* FSGetStatFile)(void *pClient, void *pCmd, int fd, void *buffer, int error); +extern int (* FSSetPosFile)(void *pClient, void *pCmd, int fd, int pos, int error); +extern int (* FSWriteFile)(void *pClient, void *pCmd, const void *source, int block_size, int block_count, int fd, int flag, int error); + +#ifdef __cplusplus +} +#endif + +#endif // __FS_FUNCTIONS_H_ diff --git a/src/dynamic_libs/gx2_functions.c b/src/dynamic_libs/gx2_functions.c new file mode 100644 index 0000000..b9bf671 --- /dev/null +++ b/src/dynamic_libs/gx2_functions.c @@ -0,0 +1,162 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#include "os_functions.h" +#include "gx2_types.h" +#include "utils/utils.h" + +EXPORT_DECL(void, GX2Init, u32 * init_attribs); +EXPORT_DECL(void, GX2Shutdown, void); +EXPORT_DECL(void, GX2Flush, void); +EXPORT_DECL(s32, GX2GetMainCoreId, void) ; +EXPORT_DECL(s32, GX2DrawDone, void); +EXPORT_DECL(void, GX2ClearColor, GX2ColorBuffer *colorBuffer, f32 r, f32 g, f32 b, f32 a); +EXPORT_DECL(void, GX2SetViewport, f32 x, f32 y, f32 w, f32 h, f32 nearZ, f32 farZ); +EXPORT_DECL(void, GX2SetScissor, u32 x_orig, u32 y_orig, u32 wd, u32 ht); +EXPORT_DECL(void, GX2SetContextState, const GX2ContextState* state); +EXPORT_DECL(void, GX2DrawEx, s32 primitive_type, u32 count, u32 first_vertex, u32 instances_count); +EXPORT_DECL(void, GX2DrawIndexedEx, s32 primitive_type, u32 count, s32 index_format, const void* idx, u32 first_vertex, u32 instances_count); +EXPORT_DECL(void, GX2ClearDepthStencilEx, GX2DepthBuffer *depthBuffer, f32 depth_value, u8 stencil_value, s32 clear_mode); +EXPORT_DECL(void, GX2CopyColorBufferToScanBuffer, const GX2ColorBuffer *colorBuffer, s32 scan_target); +EXPORT_DECL(void, GX2SwapScanBuffers, void); +EXPORT_DECL(void, GX2SetTVEnable, s32 enable); +EXPORT_DECL(void, GX2SetSwapInterval, u32 swap_interval); +EXPORT_DECL(u32, GX2GetSwapInterval, void); +EXPORT_DECL(void, GX2WaitForVsync, void); +EXPORT_DECL(void, GX2CalcTVSize, s32 tv_render_mode, s32 format, s32 buffering_mode, u32 * size, s32 * scale_needed); +EXPORT_DECL(void, GX2Invalidate, s32 invalidate_type, void * ptr, u32 buffer_size); +EXPORT_DECL(void, GX2SetTVBuffer, void *buffer, u32 buffer_size, s32 tv_render_mode, s32 format, s32 buffering_mode); +EXPORT_DECL(void, GX2CalcSurfaceSizeAndAlignment, GX2Surface *surface); +EXPORT_DECL(void, GX2InitDepthBufferRegs, GX2DepthBuffer *depthBuffer); +EXPORT_DECL(void, GX2InitColorBufferRegs, GX2ColorBuffer *colorBuffer); +EXPORT_DECL(void, GX2CalcColorBufferAuxInfo, GX2ColorBuffer *colorBuffer, u32 *size, u32 *align); +EXPORT_DECL(void, GX2CalcDepthBufferHiZInfo, GX2DepthBuffer *depthBuffer, u32 *size, u32 *align); +EXPORT_DECL(void, GX2InitDepthBufferHiZEnable, GX2DepthBuffer *depthBuffer, s32 hiZ_enable); +EXPORT_DECL(void, GX2SetupContextStateEx, GX2ContextState* state, s32 enable_profiling); +EXPORT_DECL(void, GX2SetColorBuffer, const GX2ColorBuffer *colorBuffer, s32 target); +EXPORT_DECL(void, GX2SetDepthBuffer, const GX2DepthBuffer *depthBuffer); +EXPORT_DECL(void, GX2SetAttribBuffer, u32 attr_index, u32 attr_size, u32 stride, const void* attr); +EXPORT_DECL(void, GX2InitTextureRegs, GX2Texture *texture); +EXPORT_DECL(void, GX2InitSampler, GX2Sampler *sampler, s32 tex_clamp, s32 min_mag_filter); +EXPORT_DECL(u32, GX2CalcFetchShaderSizeEx, u32 num_attrib, s32 fetch_shader_type, s32 tessellation_mode); +EXPORT_DECL(void, GX2InitFetchShaderEx, GX2FetchShader* fs, void* fs_buffer, u32 count, const GX2AttribStream* attribs, s32 fetch_shader_type, s32 tessellation_mode); +EXPORT_DECL(void, GX2SetFetchShader, const GX2FetchShader* fs); +EXPORT_DECL(void, GX2SetVertexUniformReg, u32 offset, u32 count, const void *values); +EXPORT_DECL(void, GX2SetPixelUniformReg, u32 offset, u32 count, const void *values); +EXPORT_DECL(void, GX2SetPixelTexture, const GX2Texture *texture, u32 texture_hw_location); +EXPORT_DECL(void, GX2SetVertexTexture, const GX2Texture *texture, u32 texture_hw_location); +EXPORT_DECL(void, GX2SetPixelSampler, const GX2Sampler *sampler, u32 sampler_hw_location); +EXPORT_DECL(void, GX2SetVertexSampler, const GX2Sampler *sampler, u32 sampler_hw_location); +EXPORT_DECL(void, GX2SetPixelShader, const GX2PixelShader* pixelShader); +EXPORT_DECL(void, GX2SetVertexShader, const GX2VertexShader* vertexShader); +EXPORT_DECL(void, GX2InitSamplerZMFilter, GX2Sampler *sampler, s32 z_filter, s32 mip_filter); +EXPORT_DECL(void, GX2SetColorControl, s32 lop, u8 blend_enable_mask, s32 enable_multi_write, s32 enable_color_buffer); +EXPORT_DECL(void, GX2SetDepthOnlyControl, s32 enable_depth, s32 enable_depth_write, s32 depth_comp_function); +EXPORT_DECL(void, GX2SetBlendControl, s32 target, s32 color_src_blend, s32 color_dst_blend, s32 color_combine, s32 separate_alpha_blend, s32 alpha_src_blend, s32 alpha_dst_blend, s32 alpha_combine); +EXPORT_DECL(void, GX2CalcDRCSize, s32 drc_mode, s32 format, s32 buffering_mode, u32 *size, s32 *scale_needed); +EXPORT_DECL(void, GX2SetDRCBuffer, void *buffer, u32 buffer_size, s32 drc_mode, s32 surface_format, s32 buffering_mode); +EXPORT_DECL(void, GX2SetDRCScale, u32 width, u32 height); +EXPORT_DECL(void, GX2SetDRCEnable, s32 enable); +EXPORT_DECL(void, GX2SetPolygonControl, s32 front_face_mode, s32 cull_front, s32 cull_back, s32 enable_mode, s32 mode_font, s32 mode_back, s32 poly_offset_front, s32 poly_offset_back, s32 point_line_offset); +EXPORT_DECL(void, GX2SetCullOnlyControl, s32 front_face_mode, s32 cull_front, s32 cull_back); +EXPORT_DECL(void, GX2SetDepthStencilControl, s32 enable_depth_test, s32 enable_depth_write, s32 depth_comp_function, s32 stencil_test_enable, s32 back_stencil_enable, + s32 font_stencil_func, s32 front_stencil_z_pass, s32 front_stencil_z_fail, s32 front_stencil_fail, + s32 back_stencil_func, s32 back_stencil_z_pass, s32 back_stencil_z_fail, s32 back_stencil_fail); +EXPORT_DECL(void, GX2SetStencilMask, u8 mask_front, u8 write_mask_front, u8 ref_front, u8 mask_back, u8 write_mask_back, u8 ref_back); +EXPORT_DECL(void, GX2SetLineWidth, f32 width); +EXPORT_DECL(void, GX2SetTVGamma, f32 val); +EXPORT_DECL(void, GX2SetDRCGamma, f32 gam); +EXPORT_DECL(s32, GX2GetSystemTVScanMode, void); +EXPORT_DECL(s32, GX2GetSystemDRCScanMode, void); +EXPORT_DECL(void, GX2RSetAllocator, void * (* allocFunc)(u32, u32, u32), void (* freeFunc)(u32, void*)); + + +void InitGX2FunctionPointers(void) +{ + unsigned int *funcPointer = 0; + unsigned int gx2_handle; + OSDynLoad_Acquire("gx2.rpl", &gx2_handle); + + OS_FIND_EXPORT(gx2_handle, GX2Init); + OS_FIND_EXPORT(gx2_handle, GX2Shutdown); + OS_FIND_EXPORT(gx2_handle, GX2Flush); + OS_FIND_EXPORT(gx2_handle, GX2GetMainCoreId); + OS_FIND_EXPORT(gx2_handle, GX2DrawDone); + OS_FIND_EXPORT(gx2_handle, GX2ClearColor); + OS_FIND_EXPORT(gx2_handle, GX2SetViewport); + OS_FIND_EXPORT(gx2_handle, GX2SetScissor); + OS_FIND_EXPORT(gx2_handle, GX2SetContextState); + OS_FIND_EXPORT(gx2_handle, GX2DrawEx); + OS_FIND_EXPORT(gx2_handle, GX2DrawIndexedEx); + OS_FIND_EXPORT(gx2_handle, GX2ClearDepthStencilEx); + OS_FIND_EXPORT(gx2_handle, GX2CopyColorBufferToScanBuffer); + OS_FIND_EXPORT(gx2_handle, GX2SwapScanBuffers); + OS_FIND_EXPORT(gx2_handle, GX2SetTVEnable); + OS_FIND_EXPORT(gx2_handle, GX2SetSwapInterval); + OS_FIND_EXPORT(gx2_handle, GX2GetSwapInterval); + OS_FIND_EXPORT(gx2_handle, GX2WaitForVsync); + OS_FIND_EXPORT(gx2_handle, GX2CalcTVSize); + OS_FIND_EXPORT(gx2_handle, GX2Invalidate); + OS_FIND_EXPORT(gx2_handle, GX2SetTVBuffer); + OS_FIND_EXPORT(gx2_handle, GX2CalcSurfaceSizeAndAlignment); + OS_FIND_EXPORT(gx2_handle, GX2InitDepthBufferRegs); + OS_FIND_EXPORT(gx2_handle, GX2InitColorBufferRegs); + OS_FIND_EXPORT(gx2_handle, GX2CalcColorBufferAuxInfo); + OS_FIND_EXPORT(gx2_handle, GX2CalcDepthBufferHiZInfo); + OS_FIND_EXPORT(gx2_handle, GX2InitDepthBufferHiZEnable); + OS_FIND_EXPORT(gx2_handle, GX2SetupContextStateEx); + OS_FIND_EXPORT(gx2_handle, GX2SetColorBuffer); + OS_FIND_EXPORT(gx2_handle, GX2SetDepthBuffer); + OS_FIND_EXPORT(gx2_handle, GX2SetAttribBuffer); + OS_FIND_EXPORT(gx2_handle, GX2InitTextureRegs); + OS_FIND_EXPORT(gx2_handle, GX2InitSampler); + OS_FIND_EXPORT(gx2_handle, GX2CalcFetchShaderSizeEx); + OS_FIND_EXPORT(gx2_handle, GX2InitFetchShaderEx); + OS_FIND_EXPORT(gx2_handle, GX2SetFetchShader); + OS_FIND_EXPORT(gx2_handle, GX2SetVertexUniformReg); + OS_FIND_EXPORT(gx2_handle, GX2SetPixelUniformReg); + OS_FIND_EXPORT(gx2_handle, GX2SetPixelTexture); + OS_FIND_EXPORT(gx2_handle, GX2SetVertexTexture); + OS_FIND_EXPORT(gx2_handle, GX2SetPixelSampler); + OS_FIND_EXPORT(gx2_handle, GX2SetVertexSampler); + OS_FIND_EXPORT(gx2_handle, GX2SetPixelShader); + OS_FIND_EXPORT(gx2_handle, GX2SetVertexShader); + OS_FIND_EXPORT(gx2_handle, GX2InitSamplerZMFilter); + OS_FIND_EXPORT(gx2_handle, GX2SetColorControl); + OS_FIND_EXPORT(gx2_handle, GX2SetDepthOnlyControl); + OS_FIND_EXPORT(gx2_handle, GX2SetBlendControl); + OS_FIND_EXPORT(gx2_handle, GX2CalcDRCSize); + OS_FIND_EXPORT(gx2_handle, GX2SetDRCBuffer); + OS_FIND_EXPORT(gx2_handle, GX2SetDRCScale); + OS_FIND_EXPORT(gx2_handle, GX2SetDRCEnable); + OS_FIND_EXPORT(gx2_handle, GX2SetPolygonControl); + OS_FIND_EXPORT(gx2_handle, GX2SetCullOnlyControl); + OS_FIND_EXPORT(gx2_handle, GX2SetDepthStencilControl); + OS_FIND_EXPORT(gx2_handle, GX2SetStencilMask); + OS_FIND_EXPORT(gx2_handle, GX2SetLineWidth); + OS_FIND_EXPORT(gx2_handle, GX2SetDRCGamma); + OS_FIND_EXPORT(gx2_handle, GX2SetTVGamma); + OS_FIND_EXPORT(gx2_handle, GX2GetSystemTVScanMode); + OS_FIND_EXPORT(gx2_handle, GX2GetSystemDRCScanMode); + OS_FIND_EXPORT(gx2_handle, GX2RSetAllocator); +} diff --git a/src/dynamic_libs/gx2_functions.h b/src/dynamic_libs/gx2_functions.h new file mode 100644 index 0000000..1737833 --- /dev/null +++ b/src/dynamic_libs/gx2_functions.h @@ -0,0 +1,205 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#ifndef __GX2_FUNCTIONS_H_ +#define __GX2_FUNCTIONS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "gx2_types.h" + +void InitGX2FunctionPointers(void); + +extern void (* GX2Init)(u32 * init_attribs); +extern void (* GX2Shutdown)(void); +extern void (* GX2Flush)(void); +extern s32 (* GX2GetMainCoreId)(void) ; +extern s32 (* GX2DrawDone)(void); +extern void (* GX2ClearColor)(GX2ColorBuffer *colorBuffer, f32 r, f32 g, f32 b, f32 a); +extern void (* GX2SetViewport)(f32 x, f32 y, f32 w, f32 h, f32 nearZ, f32 farZ); +extern void (* GX2SetScissor)(u32 x_orig, u32 y_orig, u32 wd, u32 ht); +extern void (* GX2SetContextState)(const GX2ContextState* state); +extern void (* GX2DrawEx)(s32 primitive_type, u32 count, u32 first_vertex, u32 instances_count); +extern void (* GX2DrawIndexedEx)(s32 primitive_type, u32 count, s32 index_format, const void* idx, u32 first_vertex, u32 instances_count); +extern void (* GX2ClearDepthStencilEx)(GX2DepthBuffer *depthBuffer, f32 depth_value, u8 stencil_value, s32 clear_mode); +extern void (* GX2CopyColorBufferToScanBuffer)(const GX2ColorBuffer *colorBuffer, s32 scan_target); +extern void (* GX2SwapScanBuffers)(void); +extern void (* GX2SetTVEnable)(s32 enable); +extern void (* GX2SetSwapInterval)(u32 swap_interval); +extern u32 (* GX2GetSwapInterval)(void); +extern void (* GX2WaitForVsync)(void); +extern void (* GX2CalcTVSize)(s32 tv_render_mode, s32 format, s32 buffering_mode, u32 * size, s32 * scale_needed); +extern void (* GX2Invalidate)(s32 invalidate_type, void * ptr, u32 buffer_size); +extern void (* GX2SetTVBuffer)(void *buffer, u32 buffer_size, s32 tv_render_mode, s32 format, s32 buffering_mode); +extern void (* GX2CalcSurfaceSizeAndAlignment)(GX2Surface *surface); +extern void (* GX2InitDepthBufferRegs)(GX2DepthBuffer *depthBuffer); +extern void (* GX2InitColorBufferRegs)(GX2ColorBuffer *colorBuffer); +extern void (* GX2CalcColorBufferAuxInfo)(GX2ColorBuffer *colorBuffer, u32 *size, u32 *align); +extern void (* GX2CalcDepthBufferHiZInfo)(GX2DepthBuffer *depthBuffer, u32 *size, u32 *align); +extern void (* GX2InitDepthBufferHiZEnable)(GX2DepthBuffer *depthBuffer, s32 hiZ_enable); +extern void (* GX2SetupContextStateEx)(GX2ContextState* state, s32 enable_profiling); +extern void (* GX2SetColorBuffer)(const GX2ColorBuffer *colorBuffer, s32 target); +extern void (* GX2SetDepthBuffer)(const GX2DepthBuffer *depthBuffer); +extern void (* GX2SetAttribBuffer)(u32 attr_index, u32 attr_size, u32 stride, const void* attr); +extern void (* GX2InitTextureRegs)(GX2Texture *texture); +extern void (* GX2InitSampler)(GX2Sampler *sampler, s32 tex_clamp, s32 min_mag_filter); +extern u32 (* GX2CalcFetchShaderSizeEx)(u32 num_attrib, s32 fetch_shader_type, s32 tessellation_mode); +extern void (* GX2InitFetchShaderEx)(GX2FetchShader* fs, void* fs_buffer, u32 count, const GX2AttribStream* attribs, s32 fetch_shader_type, s32 tessellation_mode); +extern void (* GX2SetFetchShader)(const GX2FetchShader* fs); +extern void (* GX2SetVertexUniformReg)(u32 offset, u32 count, const void *values); +extern void (* GX2SetPixelUniformReg)(u32 offset, u32 count, const void *values); +extern void (* GX2SetPixelTexture)(const GX2Texture *texture, u32 texture_hw_location); +extern void (* GX2SetVertexTexture)(const GX2Texture *texture, u32 texture_hw_location); +extern void (* GX2SetPixelSampler)(const GX2Sampler *sampler, u32 sampler_hw_location); +extern void (* GX2SetVertexSampler)(const GX2Sampler *sampler, u32 sampler_hw_location); +extern void (* GX2SetPixelShader)(const GX2PixelShader* pixelShader); +extern void (* GX2SetVertexShader)(const GX2VertexShader* vertexShader); +extern void (* GX2InitSamplerZMFilter)(GX2Sampler *sampler, s32 z_filter, s32 mip_filter); +extern void (* GX2SetColorControl)(s32 lop, u8 blend_enable_mask, s32 enable_multi_write, s32 enable_color_buffer); +extern void (* GX2SetDepthOnlyControl)(s32 enable_depth, s32 enable_depth_write, s32 depth_comp_function); +extern void (* GX2SetBlendControl)(s32 target, s32 color_src_blend, s32 color_dst_blend, s32 color_combine, s32 separate_alpha_blend, s32 alpha_src_blend, s32 alpha_dst_blend, s32 alpha_combine); +extern void (* GX2CalcDRCSize)(s32 drc_mode, s32 format, s32 buffering_mode, u32 *size, s32 *scale_needed); +extern void (* GX2SetDRCBuffer)(void *buffer, u32 buffer_size, s32 drc_mode, s32 surface_format, s32 buffering_mode); +extern void (* GX2SetDRCScale)(u32 width, u32 height); +extern void (* GX2SetDRCEnable)(s32 enable); +extern void (* GX2SetPolygonControl)(s32 front_face_mode, s32 cull_front, s32 cull_back, s32 enable_mode, s32 mode_font, s32 mode_back, s32 poly_offset_front, s32 poly_offset_back, s32 point_line_offset); +extern void (* GX2SetCullOnlyControl)(s32 front_face_mode, s32 cull_front, s32 cull_back); +extern void (* GX2SetDepthStencilControl)(s32 enable_depth_test, s32 enable_depth_write, s32 depth_comp_function, s32 stencil_test_enable, s32 back_stencil_enable, + s32 font_stencil_func, s32 front_stencil_z_pass, s32 front_stencil_z_fail, s32 front_stencil_fail, + s32 back_stencil_func, s32 back_stencil_z_pass, s32 back_stencil_z_fail, s32 back_stencil_fail); +extern void (* GX2SetStencilMask)(u8 mask_front, u8 write_mask_front, u8 ref_front, u8 mask_back, u8 write_mask_back, u8 ref_back); +extern void (* GX2SetLineWidth)(f32 width); +extern void (* GX2SetTVGamma)(f32 val); +extern void (* GX2SetDRCGamma)(f32 val); +extern s32 (* GX2GetSystemTVScanMode)(void); +extern s32 (* GX2GetSystemDRCScanMode)(void); +extern void (* GX2RSetAllocator)(void * (*allocFunc)(u32, u32, u32), void (*freeFunc)(u32, void*)); + +static inline void GX2InitDepthBuffer(GX2DepthBuffer *depthBuffer, s32 dimension, u32 width, u32 height, u32 depth, s32 format, s32 aa) +{ + depthBuffer->surface.dimension = dimension; + depthBuffer->surface.width = width; + depthBuffer->surface.height = height; + depthBuffer->surface.depth = depth; + depthBuffer->surface.num_mips = 1; + depthBuffer->surface.format = format; + depthBuffer->surface.aa = aa; + depthBuffer->surface.use = ((format==GX2_SURFACE_FORMAT_D_D24_S8_UNORM) || (format==GX2_SURFACE_FORMAT_D_D24_S8_FLOAT)) ? GX2_SURFACE_USE_DEPTH_BUFFER : GX2_SURFACE_USE_DEPTH_BUFFER_TEXTURE; + depthBuffer->surface.tile = GX2_TILE_MODE_DEFAULT; + depthBuffer->surface.swizzle = 0; + depthBuffer->view_mip = 0; + depthBuffer->view_first_slice = 0; + depthBuffer->view_slices_count = depth; + depthBuffer->clear_depth = 1.0f; + depthBuffer->clear_stencil = 0; + depthBuffer->hiZ_data = NULL; + depthBuffer->hiZ_size = 0; + GX2CalcSurfaceSizeAndAlignment(&depthBuffer->surface); + GX2InitDepthBufferRegs(depthBuffer); +} + +static inline void GX2InitColorBuffer(GX2ColorBuffer *colorBuffer, s32 dimension, u32 width, u32 height, u32 depth, s32 format, s32 aa) +{ + colorBuffer->surface.dimension = dimension; + colorBuffer->surface.width = width; + colorBuffer->surface.height = height; + colorBuffer->surface.depth = depth; + colorBuffer->surface.num_mips = 1; + colorBuffer->surface.format = format; + colorBuffer->surface.aa = aa; + colorBuffer->surface.use = GX2_SURFACE_USE_COLOR_BUFFER_TEXTURE_FTV; + colorBuffer->surface.image_size = 0; + colorBuffer->surface.image_data = NULL; + colorBuffer->surface.mip_size = 0; + colorBuffer->surface.mip_data = NULL; + colorBuffer->surface.tile = GX2_TILE_MODE_DEFAULT; + colorBuffer->surface.swizzle = 0; + colorBuffer->surface.align = 0; + colorBuffer->surface.pitch = 0; + u32 i; + for(i = 0; i < 13; i++) + colorBuffer->surface.mip_offset[i] = 0; + colorBuffer->view_mip = 0; + colorBuffer->view_first_slice = 0; + colorBuffer->view_slices_count = depth; + colorBuffer->aux_data = NULL; + colorBuffer->aux_size = 0; + for(i = 0; i < 5; i++) + colorBuffer->regs[i] = 0; + + GX2CalcSurfaceSizeAndAlignment(&colorBuffer->surface); + GX2InitColorBufferRegs(colorBuffer); +} + +static inline void GX2InitAttribStream(GX2AttribStream* attr, u32 location, u32 buffer, u32 offset, s32 format) +{ + attr->location = location; + attr->buffer = buffer; + attr->offset = offset; + attr->format = format; + attr->index_type = 0; + attr->divisor = 0; + attr->destination_selector = attribute_dest_comp_selector[format & 0xff]; + attr->endian_swap = GX2_ENDIANSWAP_DEFAULT; +} + +static inline void GX2InitTexture(GX2Texture *tex, u32 width, u32 height, u32 depth, u32 num_mips, s32 format, s32 dimension, s32 tile) +{ + tex->surface.dimension = dimension; + tex->surface.width = width; + tex->surface.height = height; + tex->surface.depth = depth; + tex->surface.num_mips = num_mips; + tex->surface.format = format; + tex->surface.aa = GX2_AA_MODE_1X; + tex->surface.use = GX2_SURFACE_USE_TEXTURE; + tex->surface.image_size = 0; + tex->surface.image_data = NULL; + tex->surface.mip_size = 0; + tex->surface.mip_data = NULL; + tex->surface.tile = tile; + tex->surface.swizzle = 0; + tex->surface.align = 0; + tex->surface.pitch = 0; + u32 i; + for(i = 0; i < 13; i++) + tex->surface.mip_offset[i] = 0; + tex->view_first_mip = 0; + tex->view_mips_count = num_mips; + tex->view_first_slice = 0; + tex->view_slices_count = depth; + tex->component_selector = texture_comp_selector[format & 0x3f]; + for(i = 0; i < 5; i++) + tex->regs[i] = 0; + + GX2CalcSurfaceSizeAndAlignment(&tex->surface); + GX2InitTextureRegs(tex); +} + +#ifdef __cplusplus +} +#endif + +#endif // __GX2_FUNCTIONS_H_ diff --git a/src/dynamic_libs/gx2_types.h b/src/dynamic_libs/gx2_types.h new file mode 100644 index 0000000..e292318 --- /dev/null +++ b/src/dynamic_libs/gx2_types.h @@ -0,0 +1,699 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#ifndef _GX2_TYPES_H_ +#define _GX2_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +//!----------------------------------------------------------------------------------------------------------------------- +//! Constants +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_COMMAND_BUFFER_SIZE 0x400000 +#define GX2_SCAN_BUFFER_ALIGNMENT 0x1000 +#define GX2_SHADER_ALIGNMENT 0x100 +#define GX2_CONTEXT_STATE_ALIGNMENT 0x100 +#define GX2_DISPLAY_LIST_ALIGNMENT 0x20 +#define GX2_VERTEX_BUFFER_ALIGNMENT 0x40 +#define GX2_INDEX_BUFFER_ALIGNMENT 0x20 + +#define GX2_CONTEXT_STATE_SIZE 0xA100 + +#define GX2_AUX_BUFFER_CLEAR_VALUE 0xCC + +//!----------------------------------------------------------------------------------------------------------------------- +//! Common +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_FALSE 0 +#define GX2_TRUE 1 +#define GX2_DISABLE 0 +#define GX2_ENABLE 1 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2InitAttrib +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_INIT_ATTRIB_NULL 0 +#define GX2_INIT_ATTRIB_CB_BASE 1 +#define GX2_INIT_ATTRIB_CB_SIZE 2 +#define GX2_INIT_ATTRIB_ARGC 7 +#define GX2_INIT_ATTRIB_ARGV 8 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 compare functions +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_COMPARE_NEVER 0 +#define GX2_COMPARE_LESS 1 +#define GX2_COMPARE_EQUAL 2 +#define GX2_COMPARE_LEQUAL 3 +#define GX2_COMPARE_GREATER 4 +#define GX2_COMPARE_NOTEQUAL 5 +#define GX2_COMPARE_GEQUAL 6 +#define GX2_COMPARE_ALWAYS 7 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 stencil functions +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_STENCIL_KEEP 0 +#define GX2_STENCIL_ZERO 1 +#define GX2_STENCIL_REPLACE 2 +#define GX2_STENCIL_INCR 3 +#define GX2_STENCIL_DECR 4 +#define GX2_STENCIL_INVERT 5 +#define GX2_STENCIL_INCR_WRAP 6 +#define GX2_STENCIL_DECR_WRAP 7 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 logic op functions +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_LOGIC_OP_CLEAR 0x00 +#define GX2_LOGIC_OP_NOR 0x11 +#define GX2_LOGIC_OP_INVAND 0x22 +#define GX2_LOGIC_OP_INVCOPY 0x33 +#define GX2_LOGIC_OP_REVAND 0x44 +#define GX2_LOGIC_OP_INV 0x55 +#define GX2_LOGIC_OP_XOR 0x66 +#define GX2_LOGIC_OP_NAND 0x77 +#define GX2_LOGIC_OP_AND 0x88 +#define GX2_LOGIC_OP_EQUIV 0x99 +#define GX2_LOGIC_OP_NOOP 0xAA +#define GX2_LOGIC_OP_INVOR 0xBB +#define GX2_LOGIC_OP_COPY 0xCC +#define GX2_LOGIC_OP_REVOR 0xDD +#define GX2_LOGIC_OP_OR 0xEE +#define GX2_LOGIC_OP_SET 0xFF + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 blend combination functions +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_BLEND_COMBINE_ADD 0x00 +#define GX2_BLEND_COMBINE_SRC_MINUS_DST 0x01 +#define GX2_BLEND_COMBINE_MIN 0x02 +#define GX2_BLEND_COMBINE_MAX 0x03 +#define GX2_BLEND_COMBINE_DST_MINUS_SRC 0x04 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 blend functions +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_BLEND_ZERO 0x00 +#define GX2_BLEND_ONE 0x01 +#define GX2_BLEND_SRC_ALPHA 0x04 +#define GX2_BLEND_ONE_MINUS_SRC_ALPHA 0x05 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 render targets +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_RENDER_TARGET_0 0 +#define GX2_RENDER_TARGET_1 1 +#define GX2_RENDER_TARGET_2 2 +#define GX2_RENDER_TARGET_3 3 +#define GX2_RENDER_TARGET_4 4 +#define GX2_RENDER_TARGET_5 5 +#define GX2_RENDER_TARGET_6 6 +#define GX2_RENDER_TARGET_7 7 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 cull modes +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_FRONT_FACE_CCW 0 +#define GX2_FRONT_FACE_CW 1 +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 polygon modes +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_POLYGON_MODE_POINT 0 +#define GX2_POLYGON_MODE_LINE 1 +#define GX2_POLYGON_MODE_TRIANGLE 2 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 special states +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_SPECIAL_STATE_CLEAR 0 +#define GX2_SPECIAL_STATE_CLEAR_HIZ 1 +#define GX2_SPECIAL_STATE_COPY 2 +#define GX2_SPECIAL_STATE_EXPAND_COLOR 3 +#define GX2_SPECIAL_STATE_EXPAND_DEPTH 4 +#define GX2_SPECIAL_STATE_CONVERT_DEPTH 5 +#define GX2_SPECIAL_STATE_CONVERT_AADEPTH 6 +#define GX2_SPECIAL_STATE_RESOLVE_COLOR 7 +#define GX2_SPECIAL_STATE_CLEAR_COLOR_AS_DEPTH 8 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 attribute formats +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_ATTRIB_FORMAT_8_UNORM 0x00000000 +#define GX2_ATTRIB_FORMAT_4_4_UNORM 0x00000001 +#define GX2_ATTRIB_FORMAT_16_UNORM 0x00000002 +#define GX2_ATTRIB_FORMAT_8_8_UNORM 0x00000004 +#define GX2_ATTRIB_FORMAT_16_16_UNORM 0x00000007 +#define GX2_ATTRIB_FORMAT_8_8_8_8_UNORM 0x0000000A +#define GX2_ATTRIB_FORMAT_10_10_10_2_UNORM 0x0000000B +#define GX2_ATTRIB_FORMAT_16_16_16_16_UNORM 0x0000000E + +#define GX2_ATTRIB_FORMAT_8_UINT 0x00000100 +#define GX2_ATTRIB_FORMAT_16_UINT 0x00000102 +#define GX2_ATTRIB_FORMAT_8_8_UINT 0x00000104 +#define GX2_ATTRIB_FORMAT_32_UINT 0x00000105 +#define GX2_ATTRIB_FORMAT_16_16_UINT 0x00000107 +#define GX2_ATTRIB_FORMAT_8_8_8_8_UINT 0x0000010A +#define GX2_ATTRIB_FORMAT_10_10_10_2_UINT 0x0000010B +#define GX2_ATTRIB_FORMAT_32_32_UINT 0x0000010C +#define GX2_ATTRIB_FORMAT_16_16_16_16_UINT 0x0000010E +#define GX2_ATTRIB_FORMAT_32_32_32_UINT 0x00000110 +#define GX2_ATTRIB_FORMAT_32_32_32_32_UINT 0x00000112 + +#define GX2_ATTRIB_FORMAT_8_SNORM 0x00000200 +#define GX2_ATTRIB_FORMAT_16_SNORM 0x00000202 +#define GX2_ATTRIB_FORMAT_8_8_SNORM 0x00000204 +#define GX2_ATTRIB_FORMAT_16_16_SNORM 0x00000207 +#define GX2_ATTRIB_FORMAT_8_8_8_8_SNORM 0x0000020A +#define GX2_ATTRIB_FORMAT_10_10_10_2_SNORM 0x0000020B +#define GX2_ATTRIB_FORMAT_16_16_16_16_SNORM 0x0000020E + +#define GX2_ATTRIB_FORMAT_8_SINT 0x00000300 +#define GX2_ATTRIB_FORMAT_16_SINT 0x00000303 +#define GX2_ATTRIB_FORMAT_8_8_SINT 0x00000304 +#define GX2_ATTRIB_FORMAT_32_SINT 0x00000305 +#define GX2_ATTRIB_FORMAT_16_16_SINT 0x00000307 +#define GX2_ATTRIB_FORMAT_8_8_8_8_SINT 0x0000030A +#define GX2_ATTRIB_FORMAT_10_10_10_2_SINT 0x0000030B +#define GX2_ATTRIB_FORMAT_32_32_SINT 0x0000030C +#define GX2_ATTRIB_FORMAT_16_16_16_16_SINT 0x0000030E +#define GX2_ATTRIB_FORMAT_32_32_32_SINT 0x00000310 +#define GX2_ATTRIB_FORMAT_32_32_32_32_SINT 0x00000312 + +#define GX2_ATTRIB_FORMAT_8_UINT_TO_FLOAT 0x00000800 +#define GX2_ATTRIB_FORMAT_16_UINT_TO_FLOAT 0x00000802 +#define GX2_ATTRIB_FORMAT_16_FLOAT 0x00000803 +#define GX2_ATTRIB_FORMAT_8_8_UINT_TO_FLOAT 0x00000804 +#define GX2_ATTRIB_FORMAT_32_FLOAT 0x00000806 +#define GX2_ATTRIB_FORMAT_16_16_UINT_TO_FLOAT 0x00000807 +#define GX2_ATTRIB_FORMAT_16_16_FLOAT 0x00000808 +#define GX2_ATTRIB_FORMAT_10_11_11_FLOAT 0x00000809 +#define GX2_ATTRIB_FORMAT_8_8_8_8_UINT_TO_FLOAT 0x0000080A +#define GX2_ATTRIB_FORMAT_32_32_FLOAT 0x0000080D +#define GX2_ATTRIB_FORMAT_16_16_16_16_UINT_TO_FLOAT 0x0000080E +#define GX2_ATTRIB_FORMAT_16_16_16_16_FLOAT 0x0000080F +#define GX2_ATTRIB_FORMAT_32_32_32_FLOAT 0x00000811 +#define GX2_ATTRIB_FORMAT_32_32_32_32_FLOAT 0x00000813 + +#define GX2_ATTRIB_FORMAT_8_SINT_TO_FLOAT 0x00000A00 +#define GX2_ATTRIB_FORMAT_16_SINT_TO_FLOAT 0x00000A02 +#define GX2_ATTRIB_FORMAT_8_8_SINT_TO_FLOAT 0x00000A04 +#define GX2_ATTRIB_FORMAT_16_16_SINT_TO_FLOAT 0x00000A07 +#define GX2_ATTRIB_FORMAT_8_8_8_8_SINT_TO_FLOAT 0x00000A0A +#define GX2_ATTRIB_FORMAT_16_16_16_16_SINT_TO_FLOAT 0x00000A0E + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 shader modes +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_SHADER_MODE_UNIFORM_REGISTER 0 +#define GX2_SHADER_MODE_UNIFORM_BLOCK 1 +#define GX2_SHADER_MODE_GEOMETRY_SHADER 2 +#define GX2_SHADER_MODE_COMPUTE_SHADER 3 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 shader modes +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_COMP_SEL_NONE 0x04040405 +#define GX2_COMP_SEL_X001 0x00040405 +#define GX2_COMP_SEL_XY01 0x00010405 +#define GX2_COMP_SEL_XYZ1 0x00010205 +#define GX2_COMP_SEL_XYZW 0x00010203 +#define GX2_COMP_SEL_XXXX 0x00000000 +#define GX2_COMP_SEL_YYYY 0x01010101 +#define GX2_COMP_SEL_ZZZZ 0x02020202 +#define GX2_COMP_SEL_WWWW 0x03030303 +#define GX2_COMP_SEL_WZYX 0x03020100 +#define GX2_COMP_SEL_WXYZ 0x03000102 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 variable types +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_VAR_TYPE_VOID 0 +#define GX2_VAR_TYPE_BOOL 1 +#define GX2_VAR_TYPE_INT 2 +#define GX2_VAR_TYPE_UINT 3 +#define GX2_VAR_TYPE_FLOAT 4 +#define GX2_VAR_TYPE_DOUBLE 5 +#define GX2_VAR_TYPE_VEC2 9 +#define GX2_VAR_TYPE_VEC3 10 +#define GX2_VAR_TYPE_VEC4 11 +#define GX2_VAR_TYPE_MAT2 21 +#define GX2_VAR_TYPE_MAT3 25 +#define GX2_VAR_TYPE_MAT4 29 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 sample types +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_SAMPLER_TYPE_2D 1 + + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 index formats +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_INDEX_FORMAT_U16 4 +#define GX2_INDEX_FORMAT_U32 9 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 primitive types +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_PRIMITIVE_POINTS 0x01 +#define GX2_PRIMITIVE_LINES 0x02 +#define GX2_PRIMITIVE_LINE_STRIP 0x03 +#define GX2_PRIMITIVE_TRIANGLES 0x04 +#define GX2_PRIMITIVE_TRIANGLE_FAN 0x05 +#define GX2_PRIMITIVE_TRIANGLE_STRIP 0x06 +#define GX2_PRIMITIVE_RECTS 0x11 +#define GX2_PRIMITIVE_QUADS 0x13 +#define GX2_PRIMITIVE_QUAD_STRIP 0x14 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 clear modes +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_CLEAR_DEPTH 0x01 +#define GX2_CLEAR_STENCIL 0x02 +#define GX2_CLEAR_BOTH (GX2_CLEAR_DEPTH | GX2_CLEAR_STENCIL) + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 surface formats +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_SURFACE_FORMAT_TC_R8_UNORM 0x00000001 +#define GX2_SURFACE_FORMAT_T_R4_G4_UNORM 0x00000002 +#define GX2_SURFACE_FORMAT_TCD_R16_UNORM 0x00000005 +#define GX2_SURFACE_FORMAT_TC_R8_G8_UNORM 0x00000007 +#define GX2_SURFACE_FORMAT_TCS_R5_G6_B5_UNORM 0x00000008 +#define GX2_SURFACE_FORMAT_TC_R5_G5_B5_A1_UNORM 0x0000000a +#define GX2_SURFACE_FORMAT_TC_R4_G4_B4_A4_UNORM 0x0000000b +#define GX2_SURFACE_FORMAT_TC_A1_B5_G5_R5_UNORM 0x0000000c +#define GX2_SURFACE_FORMAT_TC_R16_G16_UNORM 0x0000000f +#define GX2_SURFACE_FORMAT_D_D24_S8_UNORM 0x00000011 +#define GX2_SURFACE_FORMAT_T_R24_UNORM_X8 0x00000011 +#define GX2_SURFACE_FORMAT_TCS_R10_G10_B10_A2_UNORM 0x00000019 +#define GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM 0x0000001a +#define GX2_SURFACE_FORMAT_TCS_A2_B10_G10_R10_UNORM 0x0000001b +#define GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_UNORM 0x0000001f +#define GX2_SURFACE_FORMAT_T_BC1_UNORM 0x00000031 +#define GX2_SURFACE_FORMAT_T_BC2_UNORM 0x00000032 +#define GX2_SURFACE_FORMAT_T_BC3_UNORM 0x00000033 +#define GX2_SURFACE_FORMAT_T_BC4_UNORM 0x00000034 +#define GX2_SURFACE_FORMAT_T_BC5_UNORM 0x00000035 +#define GX2_SURFACE_FORMAT_T_NV12_UNORM 0x00000081 + +#define GX2_SURFACE_FORMAT_TC_R8_UINT 0x00000101 +#define GX2_SURFACE_FORMAT_TC_R16_UINT 0x00000105 +#define GX2_SURFACE_FORMAT_TC_R8_G8_UINT 0x00000107 +#define GX2_SURFACE_FORMAT_TC_R32_UINT 0x0000010d +#define GX2_SURFACE_FORMAT_TC_R16_G16_UINT 0x0000010f +#define GX2_SURFACE_FORMAT_T_X24_G8_UINT 0x00000111 +#define GX2_SURFACE_FORMAT_TC_R10_G10_B10_A2_UINT 0x00000119 +#define GX2_SURFACE_FORMAT_TC_R8_G8_B8_A8_UINT 0x0000011a +#define GX2_SURFACE_FORMAT_TC_A2_B10_G10_R10_UINT 0x0000011b +#define GX2_SURFACE_FORMAT_T_X32_G8_UINT_X24 0x0000011c +#define GX2_SURFACE_FORMAT_TC_R32_G32_UINT 0x0000011d +#define GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_UINT 0x0000011f +#define GX2_SURFACE_FORMAT_TC_R32_G32_B32_A32_UINT 0x00000122 + +#define GX2_SURFACE_FORMAT_TC_R8_SNORM 0x00000201 +#define GX2_SURFACE_FORMAT_TC_R16_SNORM 0x00000205 +#define GX2_SURFACE_FORMAT_TC_R8_G8_SNORM 0x00000207 +#define GX2_SURFACE_FORMAT_TC_R16_G16_SNORM 0x0000020f +#define GX2_SURFACE_FORMAT_T_R10_G10_B10_A2_SNORM 0x00000219 +#define GX2_SURFACE_FORMAT_TC_R10_G10_B10_A2_SNORM 0x00000219 +#define GX2_SURFACE_FORMAT_TC_R8_G8_B8_A8_SNORM 0x0000021a +#define GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_SNORM 0x0000021f +#define GX2_SURFACE_FORMAT_T_BC4_SNORM 0x00000234 +#define GX2_SURFACE_FORMAT_T_BC5_SNORM 0x00000235 + +#define GX2_SURFACE_FORMAT_TC_R8_SINT 0x00000301 +#define GX2_SURFACE_FORMAT_TC_R16_SINT 0x00000305 +#define GX2_SURFACE_FORMAT_TC_R8_G8_SINT 0x00000307 +#define GX2_SURFACE_FORMAT_TC_R32_SINT 0x0000030d +#define GX2_SURFACE_FORMAT_TC_R16_G16_SINT 0x0000030f +#define GX2_SURFACE_FORMAT_TC_R10_G10_B10_A2_SINT 0x00000319 +#define GX2_SURFACE_FORMAT_TC_R8_G8_B8_A8_SINT 0x0000031a +#define GX2_SURFACE_FORMAT_TC_R32_G32_SINT 0x0000031d +#define GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_SINT 0x0000031f +#define GX2_SURFACE_FORMAT_TC_R32_G32_B32_A32_SINT 0x00000322 + +#define GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_SRGB 0x0000041a +#define GX2_SURFACE_FORMAT_T_BC1_SRGB 0x00000431 +#define GX2_SURFACE_FORMAT_T_BC2_SRGB 0x00000432 +#define GX2_SURFACE_FORMAT_T_BC3_SRGB 0x00000433 + +#define GX2_SURFACE_FORMAT_TC_R16_FLOAT 0x00000806 +#define GX2_SURFACE_FORMAT_TCD_R32_FLOAT 0x0000080e +#define GX2_SURFACE_FORMAT_TC_R16_G16_FLOAT 0x00000810 +#define GX2_SURFACE_FORMAT_D_D24_S8_FLOAT 0x00000811 +#define GX2_SURFACE_FORMAT_TC_R11_G11_B10_FLOAT 0x00000816 +#define GX2_SURFACE_FORMAT_D_D32_FLOAT_S8_UINT_X24 0x0000081c +#define GX2_SURFACE_FORMAT_T_R32_FLOAT_X8_X24 0x0000081c +#define GX2_SURFACE_FORMAT_TC_R32_G32_FLOAT 0x0000081e +#define GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_FLOAT 0x00000820 +#define GX2_SURFACE_FORMAT_TC_R32_G32_B32_A32_FLOAT 0x00000823 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 tile modes +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_TILE_MODE_DEFAULT 0x00000000 +#define GX2_TILE_MODE_LINEAR_ALIGNED 0x00000001 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 surface use +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_SURFACE_USE_TEXTURE 0x00000001 +#define GX2_SURFACE_USE_COLOR_BUFFER 0x00000002 +#define GX2_SURFACE_USE_DEPTH_BUFFER 0x00000004 +#define GX2_SURFACE_USE_SCAN_BUFFER 0x00000008 +#define GX2_SURFACE_USE_FTV 0x80000000 +#define GX2_SURFACE_USE_COLOR_BUFFER_TEXTURE (GX2_SURFACE_USE_COLOR_BUFFER | GX2_SURFACE_USE_TEXTURE) +#define GX2_SURFACE_USE_DEPTH_BUFFER_TEXTURE (GX2_SURFACE_USE_DEPTH_BUFFER | GX2_SURFACE_USE_TEXTURE) +#define GX2_SURFACE_USE_COLOR_BUFFER_FTV (GX2_SURFACE_USE_COLOR_BUFFER | GX2_SURFACE_USE_FTV) +#define GX2_SURFACE_USE_COLOR_BUFFER_TEXTURE_FTV (GX2_SURFACE_USE_COLOR_BUFFER_TEXTURE | GX2_SURFACE_USE_FTV) + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 surface dim +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_SURFACE_DIM_1D 0x00000000 +#define GX2_SURFACE_DIM_2D 0x00000001 +#define GX2_SURFACE_DIM_3D 0x00000002 +#define GX2_SURFACE_DIM_CUBE 0x00000003 +#define GX2_SURFACE_DIM_1D_ARRAY 0x00000004 +#define GX2_SURFACE_DIM_2D_ARRAY 0x00000005 +#define GX2_SURFACE_DIM_2D_MSAA 0x00000006 +#define GX2_SURFACE_DIM_2D_MSAA_ARRAY 0x00000007 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 AA modes +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_AA_MODE_1X 0x00000000 +#define GX2_AA_MODE_2X 0x00000001 +#define GX2_AA_MODE_4X 0x00000002 +#define GX2_AA_MODE_8X 0x00000003 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 texture clamp +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_TEX_CLAMP_WRAP 0x00000000 +#define GX2_TEX_CLAMP_MIRROR 0x00000001 +#define GX2_TEX_CLAMP_CLAMP 0x00000002 +#define GX2_TEX_CLAMP_MIRROR_ONCE 0x00000003 +#define GX2_TEX_CLAMP_CLAMP_HALF_BORDER 0x00000004 +#define GX2_TEX_CLAMP_MIRROR_ONCE_HALF_BORDER 0x00000005 +#define GX2_TEX_CLAMP_CLAMP_BORDER 0x00000006 +#define GX2_TEX_CLAMP_MIRROR_ONCE_BORDER 0x00000007 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 texture filter +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_TEX_XY_FILTER_POINT 0x00000000 +#define GX2_TEX_XY_FILTER_BILINEAR 0x00000001 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 TV scan modes +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_TV_SCAN_MODE_NONE 0x00000000 +#define GX2_TV_SCAN_MODE_576I 0x00000001 +#define GX2_TV_SCAN_MODE_480I 0x00000002 +#define GX2_TV_SCAN_MODE_480P 0x00000003 +#define GX2_TV_SCAN_MODE_720P 0x00000004 +#define GX2_TV_SCAN_MODE_1080I 0x00000006 +#define GX2_TV_SCAN_MODE_1080P 0x00000007 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 TV render modes +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_TV_RENDER_480_NARROW 0x00000001 +#define GX2_TV_RENDER_480_WIDE 0x00000002 +#define GX2_TV_RENDER_720 0x00000003 +#define GX2_TV_RENDER_1080 0x00000005 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 DRC render modes +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_DRC_NONE 0x00000000 +#define GX2_DRC_SINGLE 0x00000001 +#define GX2_DRC_DOUBLE 0x00000002 +#define GX2_DRC_SINGLE_30HZ 0x00000004 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 buffering mode +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_BUFFERING_SINGLE 0x00000001 +#define GX2_BUFFERING_DOUBLE 0x00000002 +#define GX2_BUFFERING_TRIPLE 0x00000003 +#define GX2_BUFFERING_QUAD +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 scan targets +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_SCAN_TARGET_TV 0x00000001 +#define GX2_SCAN_TARGET_DRC_FIRST 0x00000004 +#define GX2_SCAN_TARGET_DRC_SECOND 0x00000008 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 invalidate types +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_INVALIDATE_ATTRIB_BUFFER 0x00000001 +#define GX2_INVALIDATE_TEXTURE 0x00000002 +#define GX2_INVALIDATE_UNIFORM_BLOCK 0x00000004 +#define GX2_INVALIDATE_SHADER 0x00000008 +#define GX2_INVALIDATE_COLOR_BUFFER 0x00000010 +#define GX2_INVALIDATE_DEPTH_BUFFER 0x00000020 +#define GX2_INVALIDATE_CPU 0x00000040 +#define GX2_INVALIDATE_CPU_ATTRIB_BUFFER (GX2_INVALIDATE_CPU | GX2_INVALIDATE_ATTRIB_BUFFER) +#define GX2_INVALIDATE_CPU_TEXTURE (GX2_INVALIDATE_CPU | GX2_INVALIDATE_TEXTURE) +#define GX2_INVALIDATE_CPU_UNIFORM_BLOCK (GX2_INVALIDATE_CPU | GX2_INVALIDATE_UNIFORM_BLOCK) +#define GX2_INVALIDATE_CPU_SHADER (GX2_INVALIDATE_CPU | GX2_INVALIDATE_SHADER) + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 swap modes +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_ENDIANSWAP_DEFAULT 0x00000003 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 tessellation modes +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_TESSELLATION_MODE_DISCRETE 0x00000000 +#define GX2_TESSELLATION_MODE_CONTINUOUS 0x00000001 +#define GX2_TESSELLATION_MODE_ADAPTIVE 0x00000002 + +//!----------------------------------------------------------------------------------------------------------------------- +//! GX2 fetch shader types +//!----------------------------------------------------------------------------------------------------------------------- +#define GX2_FETCH_SHADER_TESSELATION_NONE 0x00000000 +#define GX2_FETCH_SHADER_TESSELATION_LINES 0x00000001 +#define GX2_FETCH_SHADER_TESSELATION_TRIANGLES 0x00000002 +#define GX2_FETCH_SHADER_TESSELATION_QUADS 0x00000003 + + +typedef struct _GX2ContextState { + u8 data[GX2_CONTEXT_STATE_SIZE]; +} GX2ContextState; + +typedef struct _GX2Surface { + s32 dimension; + u32 width; + u32 height; + u32 depth; + u32 num_mips; + s32 format; + s32 aa; + s32 use; + u32 image_size; + void *image_data; + u32 mip_size; + void *mip_data; + s32 tile; + u32 swizzle; + u32 align; + u32 pitch; + u32 mip_offset[13]; +} GX2Surface; + +typedef struct _GX2ColorBuffer { + GX2Surface surface; + u32 view_mip; + u32 view_first_slice; + u32 view_slices_count; + void *aux_data; + u32 aux_size; + u32 regs[5]; +} GX2ColorBuffer; + +typedef struct _GX2DepthBuffer { + GX2Surface surface; + u32 view_mip; + u32 view_first_slice; + u32 view_slices_count; + void *hiZ_data; + u32 hiZ_size; + f32 clear_depth; + u32 clear_stencil; + u32 regs[7]; +} GX2DepthBuffer; + + +typedef struct _GX2Texture { + GX2Surface surface; + u32 view_first_mip; + u32 view_mips_count; + u32 view_first_slice; + u32 view_slices_count; + u32 component_selector; + u32 regs[5]; +} GX2Texture; + + +typedef struct _GX2Sampler { + u32 regs[3]; +} GX2Sampler; + +typedef struct _GX2AttribStream { + u32 location; + u32 buffer; + u32 offset; + s32 format; + s32 index_type; + u32 divisor; + u32 destination_selector; + s32 endian_swap; +} GX2AttribStream; + +typedef struct _GX2FetchShader { + s32 type; + u32 reg; + u32 shader_size; + void *shader_program; + u32 attributes_count; + u32 divisor[3]; +} GX2FetchShader; + +typedef struct _GX2AttribVar +{ + const char *name; + s32 var_type; + u32 array_count; + u32 location; +} GX2AttribVar; + + +typedef struct _GX2UniformBlock { + const char *name; + u32 location; + u32 block_size; +} GX2UniformBlock; + +typedef struct _GX2UniformInitialValue { + f32 value[4]; + u32 offset; +} GX2UniformInitialValue; + +typedef struct _GX2SamplerVar +{ + const char *name; + s32 sampler_type; + u32 location; +} GX2SamplerVar; + +typedef struct _GX2UniformVar +{ + const char *name; + s32 var_type; + u32 array_count; + u32 offset; + u32 block_index; +} GX2UniformVar; + +typedef struct _GX2VertexShader { + u32 regs[52]; + u32 shader_size; + void *shader_data; + s32 shader_mode; + u32 uniform_blocks_count; + GX2UniformBlock *uniform_block; + u32 uniform_vars_count; + GX2UniformVar *uniform_var; + u32 initial_values_count; + GX2UniformInitialValue *initial_value; + u32 loops_count; + void *loops_data; + u32 sampler_vars_count; + GX2SamplerVar *sampler_var; + u32 attribute_vars_count; + GX2AttribVar *attribute_var; + u32 data[6]; + u32 shader_program_buffer[16]; +} GX2VertexShader; + +typedef struct _GX2PixelShader { + u32 regs[41]; + u32 shader_size; + void *shader_data; + s32 shader_mode; + u32 uniform_blocks_count; + GX2UniformBlock *uniform_block; + u32 uniform_vars_count; + GX2UniformVar *uniform_var; + u32 initial_values_count; + GX2UniformInitialValue *initial_value; + u32 loops_count; + void *loops_data; + u32 sampler_vars_count; + GX2SamplerVar *sampler_var; + u32 shader_program_buffer[16]; +} GX2PixelShader; + +static const u32 attribute_dest_comp_selector[20] = { + GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_X001, GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_X001, + GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, + GX2_COMP_SEL_XY01, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZ1, + GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW +}; + +static const u32 texture_comp_selector[54] = { + GX2_COMP_SEL_NONE, GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_X001, + GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, + GX2_COMP_SEL_WZYX, GX2_COMP_SEL_X001, GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XY01, GX2_COMP_SEL_NONE, + GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_NONE, + GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_WZYX, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XY01, + GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, + GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_X001, + GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZ1, + GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01 +}; + +typedef struct _GX2Color { + u8 r, g, b, a; +} GX2Color; + +typedef struct _GX2ColorF32 { + f32 r, g, b, a; +} GX2ColorF32; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dynamic_libs/os_functions.c b/src/dynamic_libs/os_functions.c new file mode 100644 index 0000000..143db91 --- /dev/null +++ b/src/dynamic_libs/os_functions.c @@ -0,0 +1,247 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#include "common/common.h" +#include "os_functions.h" + +unsigned int coreinit_handle __attribute__((section(".data"))) = 0; + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Lib handle functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +EXPORT_DECL(int, OSDynLoad_Acquire, const char* rpl, u32 *handle); +EXPORT_DECL(int, OSDynLoad_FindExport, u32 handle, int isdata, const char *symbol, void *address); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Security functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +EXPORT_DECL(int, OSGetSecurityLevel, void); +EXPORT_DECL(int, OSForceFullRelaunch, void); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Thread functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +EXPORT_DECL(int, OSCreateThread, void *thread, s32 (*callback)(s32, void*), s32 argc, void *args, u32 stack, u32 stack_size, s32 priority, u32 attr); +EXPORT_DECL(int, OSResumeThread, void *thread); +EXPORT_DECL(int, OSSuspendThread, void *thread); +EXPORT_DECL(int, OSIsThreadTerminated, void *thread); +EXPORT_DECL(int, OSIsThreadSuspended, void *thread); +EXPORT_DECL(int, OSSetThreadPriority, void * thread, int priority); +EXPORT_DECL(int, OSJoinThread, void * thread, int * ret_val); +EXPORT_DECL(void, OSDetachThread, void * thread); +EXPORT_DECL(void, OSSleepTicks, u64 ticks); +EXPORT_DECL(u64, OSGetTick, void); +EXPORT_DECL(u64, OSGetTime, void); + + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Mutex functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +EXPORT_DECL(void, OSInitMutex, void* mutex); +EXPORT_DECL(void, OSLockMutex, void* mutex); +EXPORT_DECL(void, OSUnlockMutex, void* mutex); +EXPORT_DECL(int, OSTryLockMutex, void* mutex); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! System functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +EXPORT_DECL(u64, OSGetTitleID, void); +EXPORT_DECL(void, OSGetArgcArgv, int* argc, char*** argv); +EXPORT_DECL(void, __Exit, void); +EXPORT_DECL(void, OSFatal, const char* msg); +EXPORT_DECL(void, OSSetExceptionCallback, u8 exceptionType, exception_callback newCallback); +EXPORT_DECL(void, DCFlushRange, const void *addr, u32 length); +EXPORT_DECL(void, ICInvalidateRange, const void *addr, u32 length); +EXPORT_DECL(void*, OSEffectiveToPhysical, const void*); +EXPORT_DECL(int, __os_snprintf, char* s, int n, const char * format, ...); +EXPORT_DECL(int *, __gh_errno_ptr, void); + +EXPORT_DECL(void, OSScreenInit, void); +EXPORT_DECL(unsigned int, OSScreenGetBufferSizeEx, unsigned int bufferNum); +EXPORT_DECL(int, OSScreenSetBufferEx, unsigned int bufferNum, void * addr); +EXPORT_DECL(int, OSScreenClearBufferEx, unsigned int bufferNum, unsigned int temp); +EXPORT_DECL(int, OSScreenFlipBuffersEx, unsigned int bufferNum); +EXPORT_DECL(int, OSScreenPutFontEx, unsigned int bufferNum, unsigned int posX, unsigned int posY, const char * buffer); +EXPORT_DECL(int, OSScreenEnableEx, unsigned int bufferNum, int enable); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Memory functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +EXPORT_VAR(unsigned int *, pMEMAllocFromDefaultHeapEx); +EXPORT_VAR(unsigned int *, pMEMAllocFromDefaultHeap); +EXPORT_VAR(unsigned int *, pMEMFreeToDefaultHeap); + +EXPORT_DECL(int, MEMGetBaseHeapHandle, int mem_arena); +EXPORT_DECL(unsigned int, MEMGetAllocatableSizeForFrmHeapEx, int heap, int align); +EXPORT_DECL(void *, MEMAllocFromFrmHeapEx, int heap, unsigned int size, int align); +EXPORT_DECL(void, MEMFreeToFrmHeap, int heap, int mode); +EXPORT_DECL(void *, MEMAllocFromExpHeapEx, int heap, unsigned int size, int align); +EXPORT_DECL(int , MEMCreateExpHeapEx, void* address, unsigned int size, unsigned short flags); +EXPORT_DECL(void *, MEMDestroyExpHeap, int heap); +EXPORT_DECL(void, MEMFreeToExpHeap, int heap, void* ptr); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! MCP functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +EXPORT_DECL(int, MCP_Open, void); +EXPORT_DECL(int, MCP_Close, int handle); +EXPORT_DECL(int, MCP_GetOwnTitleInfo, int handle, void * data); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Kernel function addresses +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +EXPORT_DECL(void, addr_PrepareTitle_hook, void); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Other function addresses +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +EXPORT_DECL(void, DCInvalidateRange, void *buffer, uint32_t length); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Energy Saver functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//Burn-in Reduction +EXPORT_DECL(int, IMEnableDim,void); +EXPORT_DECL(int, IMDisableDim,void); +EXPORT_DECL(int, IMIsDimEnabled,int * result); +//Auto power down +EXPORT_DECL(int, IMEnableAPD,void); +EXPORT_DECL(int, IMDisableAPD,void); +EXPORT_DECL(int, IMIsAPDEnabled,int * result); +EXPORT_DECL(int, IMIsAPDEnabledBySysSettings,int * result); + + +EXPORT_DECL(int, IOS_Ioctl,int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len); +EXPORT_DECL(int, IOS_Open,char *path, unsigned int mode); +EXPORT_DECL(int, IOS_Close,int fd); +void InitAcquireOS(void) +{ + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! Lib handle functions + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + EXPORT_FUNC_WRITE(OSDynLoad_Acquire, (int (*)(const char*, unsigned *))OS_SPECIFICS->addr_OSDynLoad_Acquire); + EXPORT_FUNC_WRITE(OSDynLoad_FindExport, (int (*)(u32, int, const char *, void *))OS_SPECIFICS->addr_OSDynLoad_FindExport); + + OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); +} + +void InitOSFunctionPointers(void) +{ + unsigned int *funcPointer = 0; + + InitAcquireOS(); + + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! Security functions + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + OS_FIND_EXPORT(coreinit_handle, OSGetSecurityLevel); + OS_FIND_EXPORT(coreinit_handle, OSForceFullRelaunch); + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! System functions + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + OS_FIND_EXPORT(coreinit_handle, OSFatal); + OS_FIND_EXPORT(coreinit_handle, OSGetTitleID); + OS_FIND_EXPORT(coreinit_handle, OSGetArgcArgv); + OS_FIND_EXPORT(coreinit_handle, OSSetExceptionCallback); + OS_FIND_EXPORT(coreinit_handle, DCFlushRange); + OS_FIND_EXPORT(coreinit_handle, ICInvalidateRange); + OS_FIND_EXPORT(coreinit_handle, OSEffectiveToPhysical); + OS_FIND_EXPORT(coreinit_handle, __os_snprintf); + OS_FIND_EXPORT(coreinit_handle, __gh_errno_ptr); + + OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &__Exit); + + OS_FIND_EXPORT(coreinit_handle, OSScreenInit); + OS_FIND_EXPORT(coreinit_handle, OSScreenGetBufferSizeEx); + OS_FIND_EXPORT(coreinit_handle, OSScreenSetBufferEx); + OS_FIND_EXPORT(coreinit_handle, OSScreenClearBufferEx); + OS_FIND_EXPORT(coreinit_handle, OSScreenFlipBuffersEx); + OS_FIND_EXPORT(coreinit_handle, OSScreenPutFontEx); + OS_FIND_EXPORT(coreinit_handle, OSScreenEnableEx); + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! Thread functions + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + OS_FIND_EXPORT(coreinit_handle, OSCreateThread); + OS_FIND_EXPORT(coreinit_handle, OSResumeThread); + OS_FIND_EXPORT(coreinit_handle, OSSuspendThread); + OS_FIND_EXPORT(coreinit_handle, OSIsThreadTerminated); + OS_FIND_EXPORT(coreinit_handle, OSIsThreadSuspended); + OS_FIND_EXPORT(coreinit_handle, OSJoinThread); + OS_FIND_EXPORT(coreinit_handle, OSSetThreadPriority); + OS_FIND_EXPORT(coreinit_handle, OSDetachThread); + OS_FIND_EXPORT(coreinit_handle, OSSleepTicks); + OS_FIND_EXPORT(coreinit_handle, OSGetTick); + OS_FIND_EXPORT(coreinit_handle, OSGetTime); + + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! Mutex functions + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + OS_FIND_EXPORT(coreinit_handle, OSInitMutex); + OS_FIND_EXPORT(coreinit_handle, OSLockMutex); + OS_FIND_EXPORT(coreinit_handle, OSUnlockMutex); + OS_FIND_EXPORT(coreinit_handle, OSTryLockMutex); + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! MCP functions + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + OS_FIND_EXPORT(coreinit_handle, MCP_Open); + OS_FIND_EXPORT(coreinit_handle, MCP_Close); + OS_FIND_EXPORT(coreinit_handle, MCP_GetOwnTitleInfo); + + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! Memory functions + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &pMEMAllocFromDefaultHeapEx); + OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeap", &pMEMAllocFromDefaultHeap); + OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &pMEMFreeToDefaultHeap); + + OS_FIND_EXPORT(coreinit_handle, MEMGetBaseHeapHandle); + OS_FIND_EXPORT(coreinit_handle, MEMGetAllocatableSizeForFrmHeapEx); + OS_FIND_EXPORT(coreinit_handle, MEMAllocFromFrmHeapEx); + OS_FIND_EXPORT(coreinit_handle, MEMFreeToFrmHeap); + OS_FIND_EXPORT(coreinit_handle, MEMAllocFromExpHeapEx); + OS_FIND_EXPORT(coreinit_handle, MEMCreateExpHeapEx); + OS_FIND_EXPORT(coreinit_handle, MEMDestroyExpHeap); + OS_FIND_EXPORT(coreinit_handle, MEMFreeToExpHeap); + + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! Other function addresses + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + OS_FIND_EXPORT(coreinit_handle, DCInvalidateRange); + + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! Energy Saver functions + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //Burn-in Reduction + OS_FIND_EXPORT(coreinit_handle, IMEnableDim); + OS_FIND_EXPORT(coreinit_handle, IMDisableDim); + OS_FIND_EXPORT(coreinit_handle, IMIsDimEnabled); + //Auto power down + OS_FIND_EXPORT(coreinit_handle, IMEnableAPD); + OS_FIND_EXPORT(coreinit_handle, IMDisableAPD); + OS_FIND_EXPORT(coreinit_handle, IMIsAPDEnabled); + OS_FIND_EXPORT(coreinit_handle, IMIsAPDEnabledBySysSettings); + + OS_FIND_EXPORT(coreinit_handle, IOS_Ioctl); + OS_FIND_EXPORT(coreinit_handle, IOS_Open); + OS_FIND_EXPORT(coreinit_handle, IOS_Close); +} diff --git a/src/dynamic_libs/os_functions.h b/src/dynamic_libs/os_functions.h new file mode 100644 index 0000000..02b27cd --- /dev/null +++ b/src/dynamic_libs/os_functions.h @@ -0,0 +1,163 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#ifndef __OS_FUNCTIONS_H_ +#define __OS_FUNCTIONS_H_ + +#include +#include "common/os_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BUS_SPEED 248625000 +#define SECS_TO_TICKS(sec) (((unsigned long long)(sec)) * (BUS_SPEED/4)) +#define MILLISECS_TO_TICKS(msec) (SECS_TO_TICKS(msec) / 1000) +#define MICROSECS_TO_TICKS(usec) (SECS_TO_TICKS(usec) / 1000000) + +#define usleep(usecs) OSSleepTicks(MICROSECS_TO_TICKS(usecs)) +#define sleep(secs) OSSleepTicks(SECS_TO_TICKS(secs)) + +#define FLUSH_DATA_BLOCK(addr) asm volatile("dcbf 0, %0; sync" : : "r"(((addr) & ~31))) +#define INVAL_DATA_BLOCK(addr) asm volatile("dcbi 0, %0; sync" : : "r"(((addr) & ~31))) + +#define EXPORT_DECL(res, func, ...) res (* func)(__VA_ARGS__) __attribute__((section(".data"))) = 0; +#define EXPORT_VAR(type, var) type var __attribute__((section(".data"))); + + +#define EXPORT_FUNC_WRITE(func, val) *(u32*)(((u32)&func) + 0) = (u32)val + +#define OS_FIND_EXPORT(handle, func) funcPointer = 0; \ + OSDynLoad_FindExport(handle, 0, # func, &funcPointer); \ + if(!funcPointer) \ + OSFatal("Function " # func " is NULL"); \ + EXPORT_FUNC_WRITE(func, funcPointer); + +#define OS_FIND_EXPORT_EX(handle, func, func_p) \ + funcPointer = 0; \ + OSDynLoad_FindExport(handle, 0, # func, &funcPointer); \ + if(!funcPointer) \ + OSFatal("Function " # func " is NULL"); \ + EXPORT_FUNC_WRITE(func_p, funcPointer); + +#define OS_MUTEX_SIZE 44 + +/* Handle for coreinit */ +extern unsigned int coreinit_handle; +void InitOSFunctionPointers(void); +void InitAcquireOS(void); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Lib handle functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +extern int (* OSDynLoad_Acquire)(const char* rpl, u32 *handle); +extern int (* OSDynLoad_FindExport)(u32 handle, int isdata, const char *symbol, void *address); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Security functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +extern int (* OSGetSecurityLevel)(void); +extern int (* OSForceFullRelaunch)(void); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Thread functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +extern int (* OSCreateThread)(void *thread, s32 (*callback)(s32, void*), s32 argc, void *args, u32 stack, u32 stack_size, s32 priority, u32 attr); +extern int (* OSResumeThread)(void *thread); +extern int (* OSSuspendThread)(void *thread); +extern int (* OSIsThreadTerminated)(void *thread); +extern int (* OSIsThreadSuspended)(void *thread); +extern int (* OSJoinThread)(void * thread, int * ret_val); +extern int (* OSSetThreadPriority)(void * thread, int priority); +extern void (* OSDetachThread)(void * thread); +extern void (* OSSleepTicks)(u64 ticks); +extern u64 (* OSGetTick)(void); +extern u64 (* OSGetTime)(void); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Mutex functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +extern void (* OSInitMutex)(void* mutex); +extern void (* OSLockMutex)(void* mutex); +extern void (* OSUnlockMutex)(void* mutex); +extern int (* OSTryLockMutex)(void* mutex); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! System functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +extern u64 (* OSGetTitleID)(void); +extern void (* OSGetArgcArgv)(int* argc, char*** argv); +extern void (* __Exit)(void); +extern void (* OSFatal)(const char* msg); +extern void (* DCFlushRange)(const void *addr, u32 length); +extern void (* ICInvalidateRange)(const void *addr, u32 length); +extern void* (* OSEffectiveToPhysical)(const void*); +extern int (* __os_snprintf)(char* s, int n, const char * format, ...); +extern int * (* __gh_errno_ptr)(void); + +extern void (*OSScreenInit)(void); +extern unsigned int (*OSScreenGetBufferSizeEx)(unsigned int bufferNum); +extern int (*OSScreenSetBufferEx)(unsigned int bufferNum, void * addr); +extern int (*OSScreenClearBufferEx)(unsigned int bufferNum, unsigned int temp); +extern int (*OSScreenFlipBuffersEx)(unsigned int bufferNum); +extern int (*OSScreenPutFontEx)(unsigned int bufferNum, unsigned int posX, unsigned int posY, const char * buffer); +extern int (*OSScreenEnableEx)(unsigned int bufferNum, int enable); + +typedef unsigned char (*exception_callback)(void * interruptedContext); +extern void (* OSSetExceptionCallback)(u8 exceptionType, exception_callback newCallback); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! MCP functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +extern int (* MCP_Open)(void); +extern int (* MCP_Close)(int handle); +extern int (* MCP_GetOwnTitleInfo)(int handle, void * data); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Other function addresses +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +extern void (*DCInvalidateRange)(void *buffer, uint32_t length); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Energy Saver functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +////Burn-in Reduction +extern int (*IMEnableDim)(void); +extern int (*IMDisableDim)(void); +extern int (*IMIsDimEnabled)(int * result); +//Auto power down +extern int (*IMEnableAPD)(void); +extern int (*IMDisableAPD)(void); +extern int (*IMIsAPDEnabled)(int * result); +extern int (*IMIsAPDEnabledBySysSettings)(int * result); + +extern int (*IOS_Ioctl)(int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len); +extern int (*IOS_Open)(char *path, unsigned int mode); +extern int (*IOS_Close)(int fd); + +#ifdef __cplusplus +} +#endif + +#endif // __OS_FUNCTIONS_H_ diff --git a/src/dynamic_libs/padscore_functions.c b/src/dynamic_libs/padscore_functions.c new file mode 100644 index 0000000..c51764f --- /dev/null +++ b/src/dynamic_libs/padscore_functions.c @@ -0,0 +1,50 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#include "os_functions.h" +#include "padscore_functions.h" + +EXPORT_DECL(void, KPADInit, void); +EXPORT_DECL(s32, WPADProbe, s32 chan, u32 * pad_type); +EXPORT_DECL(s32, WPADSetDataFormat, s32 chan, s32 format); +EXPORT_DECL(void, WPADEnableURCC, s32 enable); +EXPORT_DECL(void, WPADRead, s32 chan, void * data); +EXPORT_DECL(s32, KPADRead, s32 chan, void * data, u32 size); + +void InitPadScoreFunctionPointers(void) +{ + unsigned int *funcPointer = 0; + unsigned int padscore_handle; + OSDynLoad_Acquire("padscore.rpl", &padscore_handle); + + OS_FIND_EXPORT(padscore_handle, KPADInit); + OS_FIND_EXPORT(padscore_handle, WPADProbe); + OS_FIND_EXPORT(padscore_handle, WPADSetDataFormat); + OS_FIND_EXPORT(padscore_handle, WPADEnableURCC); + OS_FIND_EXPORT(padscore_handle, WPADRead); + OS_FIND_EXPORT(padscore_handle, KPADRead); + + KPADInit(); + WPADEnableURCC(1); +} + diff --git a/src/dynamic_libs/padscore_functions.h b/src/dynamic_libs/padscore_functions.h new file mode 100644 index 0000000..26eda1a --- /dev/null +++ b/src/dynamic_libs/padscore_functions.h @@ -0,0 +1,122 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#ifndef __PAD_SCORE_FUNCTIONS_H_ +#define __PAD_SCORE_FUNCTIONS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define WPAD_BUTTON_LEFT 0x0001 +#define WPAD_BUTTON_RIGHT 0x0002 +#define WPAD_BUTTON_DOWN 0x0004 +#define WPAD_BUTTON_UP 0x0008 +#define WPAD_BUTTON_PLUS 0x0010 +#define WPAD_BUTTON_2 0x0100 +#define WPAD_BUTTON_1 0x0200 +#define WPAD_BUTTON_B 0x0400 +#define WPAD_BUTTON_A 0x0800 +#define WPAD_BUTTON_MINUS 0x1000 +#define WPAD_BUTTON_Z 0x2000 +#define WPAD_BUTTON_C 0x4000 +#define WPAD_BUTTON_HOME 0x8000 + +#define WPAD_CLASSIC_BUTTON_UP 0x0001 +#define WPAD_CLASSIC_BUTTON_LEFT 0x0002 +#define WPAD_CLASSIC_BUTTON_ZR 0x0004 +#define WPAD_CLASSIC_BUTTON_X 0x0008 +#define WPAD_CLASSIC_BUTTON_A 0x0010 +#define WPAD_CLASSIC_BUTTON_Y 0x0020 +#define WPAD_CLASSIC_BUTTON_B 0x0040 +#define WPAD_CLASSIC_BUTTON_ZL 0x0080 +#define WPAD_CLASSIC_BUTTON_R 0x0200 +#define WPAD_CLASSIC_BUTTON_PLUS 0x0400 +#define WPAD_CLASSIC_BUTTON_HOME 0x0800 +#define WPAD_CLASSIC_BUTTON_MINUS 0x1000 +#define WPAD_CLASSIC_BUTTON_L 0x2000 +#define WPAD_CLASSIC_BUTTON_DOWN 0x4000 +#define WPAD_CLASSIC_BUTTON_RIGHT 0x8000 + +void InitPadScoreFunctionPointers(void); + + +typedef struct _KPADData +{ + u32 btns_h; + u32 btns_d; + u32 btns_r; + u32 unused_1[5]; + f32 pos_x; + f32 pos_y; + u32 unused_2[3]; + f32 angle_x; + f32 angle_y; + u32 unused_3[8]; + u8 device_type; + u8 wpad_error; + u8 pos_valid; + u8 unused_4[1]; + + union + { + struct + { + f32 stick_x; + f32 stick_y; + } nunchuck; + + struct + { + u32 btns_h; + u32 btns_d; + u32 btns_r; + f32 lstick_x; + f32 lstick_y; + f32 rstick_x; + f32 rstick_y; + f32 ltrigger; + f32 rtrigger; + } classic; + + u32 unused_6[20]; + }; + u32 unused_7[16]; +} KPADData; + +typedef void (* wpad_connect_callback_t)(s32 chan, s32 status); + +extern void (* KPADInit)(void); +extern s32 (* WPADProbe)(s32 chan, u32 * pad_type); +extern s32 (* WPADSetDataFormat)(s32 chan, s32 format); +extern void (* WPADEnableURCC)(s32 enable); +extern void (* WPADRead)(s32 chan, void * data); +extern s32 (* KPADRead)(s32 chan, void * data, u32 size); + +#ifdef __cplusplus +} +#endif + +#endif // __PAD_SCORE_FUNCTIONS_H_ diff --git a/src/dynamic_libs/socket_functions.c b/src/dynamic_libs/socket_functions.c new file mode 100644 index 0000000..3b8bb77 --- /dev/null +++ b/src/dynamic_libs/socket_functions.c @@ -0,0 +1,84 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#include "os_functions.h" +#include "socket_functions.h" + +u32 hostIpAddress = 0; + +EXPORT_DECL(void, socket_lib_init, void); +EXPORT_DECL(int, socket, int domain, int type, int protocol); +EXPORT_DECL(int, socketclose, int s); +EXPORT_DECL(int, connect, int s, void *addr, int addrlen); +EXPORT_DECL(int, bind, s32 s,struct sockaddr *name,s32 namelen); +EXPORT_DECL(int, listen, s32 s,u32 backlog); +EXPORT_DECL(int, accept, s32 s,struct sockaddr *addr,s32 *addrlen); +EXPORT_DECL(int, send, int s, const void *buffer, int size, int flags); +EXPORT_DECL(int, recv, int s, void *buffer, int size, int flags); +EXPORT_DECL(int, sendto, int s, const void *buffer, int size, int flags, const struct sockaddr *dest, int dest_len); +EXPORT_DECL(int, setsockopt, int s, int level, int optname, void *optval, int optlen); +EXPORT_DECL(char *, inet_ntoa, struct in_addr in); +EXPORT_DECL(int, inet_aton, const char *cp, struct in_addr *inp); +EXPORT_DECL(int, socketlasterr, void); + +void InitSocketFunctionPointers(void) +{ + unsigned int nsysnet_handle; + unsigned int *funcPointer = 0; + OSDynLoad_Acquire("nsysnet.rpl", &nsysnet_handle); + + unsigned int nn_ac_handle; + int(*ACInitialize)(); + int(*ACGetStartupId) (unsigned int *id); + int(*ACConnectWithConfigId) (unsigned int id); + int(*ACGetAssignedAddress) (u32 * ip); + OSDynLoad_Acquire("nn_ac.rpl", &nn_ac_handle); + OSDynLoad_FindExport(nn_ac_handle, 0, "ACInitialize", &ACInitialize); + OSDynLoad_FindExport(nn_ac_handle, 0, "ACGetStartupId", &ACGetStartupId); + OSDynLoad_FindExport(nn_ac_handle, 0, "ACConnectWithConfigId",&ACConnectWithConfigId); + OSDynLoad_FindExport(nn_ac_handle, 0, "ACGetAssignedAddress",&ACGetAssignedAddress); + + OS_FIND_EXPORT(nsysnet_handle, socket_lib_init); + OS_FIND_EXPORT(nsysnet_handle, socket); + OS_FIND_EXPORT(nsysnet_handle, socketclose); + OS_FIND_EXPORT(nsysnet_handle, connect); + OS_FIND_EXPORT(nsysnet_handle, bind); + OS_FIND_EXPORT(nsysnet_handle, listen); + OS_FIND_EXPORT(nsysnet_handle, accept); + OS_FIND_EXPORT(nsysnet_handle, send); + OS_FIND_EXPORT(nsysnet_handle, recv); + OS_FIND_EXPORT(nsysnet_handle, sendto); + OS_FIND_EXPORT(nsysnet_handle, setsockopt); + OS_FIND_EXPORT(nsysnet_handle, inet_ntoa); + OS_FIND_EXPORT(nsysnet_handle, inet_aton); + OS_FIND_EXPORT(nsysnet_handle, socketlasterr); + + unsigned int nn_startupid; + ACInitialize(); + ACGetStartupId(&nn_startupid); + ACConnectWithConfigId(nn_startupid); + ACGetAssignedAddress(&hostIpAddress); + + socket_lib_init(); +} + diff --git a/src/dynamic_libs/socket_functions.h b/src/dynamic_libs/socket_functions.h new file mode 100644 index 0000000..320f83e --- /dev/null +++ b/src/dynamic_libs/socket_functions.h @@ -0,0 +1,108 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#ifndef __SOCKET_FUNCTIONS_H_ +#define __SOCKET_FUNCTIONS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define INADDR_ANY 0 + +#define AF_INET 2 + +#define SOCK_STREAM 1 +#define SOCK_DGRAM 2 + +#define IPPROTO_IP 0 +#define IPPROTO_TCP 6 +#define IPPROTO_UDP 17 + +#define TCP_NODELAY 0x2004 + +#define SOL_SOCKET -1 +#define SO_REUSEADDR 0x0004 +#define SO_NONBLOCK 0x1016 +#define SO_MYADDR 0x1013 + +#define ENODATA 1 +#define EISCONN 3 +#define EWOULDBLOCK 6 +#define EALREADY 10 +#define EAGAIN EWOULDBLOCK +#define EINVAL 11 +#define ENOMEM 18 +#define EINPROGRESS 22 + +#define htonl(x) x +#define htons(x) x +#define ntohl(x) x +#define ntohs(x) x + + +struct in_addr { + unsigned int s_addr; +}; +struct sockaddr_in { + short sin_family; + unsigned short sin_port; + struct in_addr sin_addr; + char sin_zero[8]; +}; + +struct sockaddr +{ + unsigned short sa_family; + char sa_data[14]; +}; + + +void InitSocketFunctionPointers(void); + +extern void (*socket_lib_init)(void); +extern int (*socket)(int domain, int type, int protocol); +extern int (*socketclose)(int s); +extern int (*connect)(int s, void *addr, int addrlen); +extern int (*bind)(s32 s,struct sockaddr *name,s32 namelen); +extern int (*listen)(s32 s,u32 backlog); +extern int (*accept)(s32 s,struct sockaddr *addr,s32 *addrlen); +extern int (*send)(int s, const void *buffer, int size, int flags); +extern int (*recv)(int s, void *buffer, int size, int flags); +extern int (*sendto)(int s, const void *buffer, int size, int flags, const struct sockaddr *dest, int dest_len); +extern int (*setsockopt)(int s, int level, int optname, void *optval, int optlen); + +extern char * (*inet_ntoa)(struct in_addr in); +extern int (*inet_aton)(const char *cp, struct in_addr *inp); + +extern int (*socketlasterr)(void); + +#define geterrno() (socketlasterr()) + +#ifdef __cplusplus +} +#endif + +#endif // __SOCKET_FUNCTIONS_H_ diff --git a/src/dynamic_libs/sys_functions.c b/src/dynamic_libs/sys_functions.c new file mode 100644 index 0000000..ea7649e --- /dev/null +++ b/src/dynamic_libs/sys_functions.c @@ -0,0 +1,40 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#include "os_functions.h" + +EXPORT_DECL(void, _SYSLaunchTitleByPathFromLauncher, const char* path, int len, int zero); +EXPORT_DECL(int, SYSRelaunchTitle, int argc, char* argv); +EXPORT_DECL(int, SYSLaunchMenu, void); + +void InitSysFunctionPointers(void) +{ + unsigned int *funcPointer = 0; + unsigned int sysapp_handle; + OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle); + + OS_FIND_EXPORT(sysapp_handle, _SYSLaunchTitleByPathFromLauncher); + OS_FIND_EXPORT(sysapp_handle, SYSRelaunchTitle); + OS_FIND_EXPORT(sysapp_handle, SYSLaunchMenu); +} + diff --git a/src/dynamic_libs/sys_functions.h b/src/dynamic_libs/sys_functions.h new file mode 100644 index 0000000..18c9065 --- /dev/null +++ b/src/dynamic_libs/sys_functions.h @@ -0,0 +1,42 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#ifndef __SYS_FUNCTIONS_H_ +#define __SYS_FUNCTIONS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void InitSysFunctionPointers(void); + +extern void(*_SYSLaunchTitleByPathFromLauncher)(const char* path, int len, int zero); +extern int (* SYSRelaunchTitle)(int argc, char* argv); +extern int (* SYSLaunchMenu)(void); + + +#ifdef __cplusplus +} +#endif + +#endif // __SYS_FUNCTIONS_H_ diff --git a/src/dynamic_libs/vpad_functions.c b/src/dynamic_libs/vpad_functions.c new file mode 100644 index 0000000..a2d8e3f --- /dev/null +++ b/src/dynamic_libs/vpad_functions.c @@ -0,0 +1,39 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#include "os_functions.h" +#include "vpad_functions.h" + +EXPORT_DECL(void, VPADInit, void); +EXPORT_DECL(void, VPADRead, int chan, VPADData *buffer, u32 buffer_size, s32 *error); + +void InitVPadFunctionPointers(void) +{ + unsigned int *funcPointer = 0; + unsigned int vpad_handle; + OSDynLoad_Acquire("vpad.rpl", &vpad_handle); + + OS_FIND_EXPORT(vpad_handle, VPADInit); + OS_FIND_EXPORT(vpad_handle, VPADRead); +} + diff --git a/src/dynamic_libs/vpad_functions.h b/src/dynamic_libs/vpad_functions.h new file mode 100644 index 0000000..00f7983 --- /dev/null +++ b/src/dynamic_libs/vpad_functions.h @@ -0,0 +1,102 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#ifndef __VPAD_FUNCTIONS_H_ +#define __VPAD_FUNCTIONS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define VPAD_BUTTON_A 0x8000 +#define VPAD_BUTTON_B 0x4000 +#define VPAD_BUTTON_X 0x2000 +#define VPAD_BUTTON_Y 0x1000 +#define VPAD_BUTTON_LEFT 0x0800 +#define VPAD_BUTTON_RIGHT 0x0400 +#define VPAD_BUTTON_UP 0x0200 +#define VPAD_BUTTON_DOWN 0x0100 +#define VPAD_BUTTON_ZL 0x0080 +#define VPAD_BUTTON_ZR 0x0040 +#define VPAD_BUTTON_L 0x0020 +#define VPAD_BUTTON_R 0x0010 +#define VPAD_BUTTON_PLUS 0x0008 +#define VPAD_BUTTON_MINUS 0x0004 +#define VPAD_BUTTON_HOME 0x0002 +#define VPAD_BUTTON_SYNC 0x0001 +#define VPAD_BUTTON_STICK_R 0x00020000 +#define VPAD_BUTTON_STICK_L 0x00040000 +#define VPAD_BUTTON_TV 0x00010000 + +#define VPAD_STICK_R_EMULATION_LEFT 0x04000000 +#define VPAD_STICK_R_EMULATION_RIGHT 0x02000000 +#define VPAD_STICK_R_EMULATION_UP 0x01000000 +#define VPAD_STICK_R_EMULATION_DOWN 0x00800000 + +#define VPAD_STICK_L_EMULATION_LEFT 0x40000000 +#define VPAD_STICK_L_EMULATION_RIGHT 0x20000000 +#define VPAD_STICK_L_EMULATION_UP 0x10000000 +#define VPAD_STICK_L_EMULATION_DOWN 0x08000000 + + +typedef struct +{ + f32 x,y; +} Vec2D; + +typedef struct +{ + u16 x, y; /* Touch coordinates */ + u16 touched; /* 1 = Touched, 0 = Not touched */ + u16 invalid; /* 0 = All valid, 1 = X invalid, 2 = Y invalid, 3 = Both invalid? */ +} VPADTPData; + +typedef struct +{ + u32 btns_h; /* Held buttons */ + u32 btns_d; /* Buttons that are pressed at that instant */ + u32 btns_r; /* Released buttons */ + Vec2D lstick, rstick; /* Each contains 4-byte X and Y components */ + char unknown1c[0x52 - 0x1c]; /* Contains accelerometer and gyroscope data somewhere */ + VPADTPData tpdata; /* Normal touchscreen data */ + VPADTPData tpdata1; /* Modified touchscreen data 1 */ + VPADTPData tpdata2; /* Modified touchscreen data 2 */ + char unknown6a[0xa0 - 0x6a]; + uint8_t volume; + uint8_t battery; /* 0 to 6 */ + uint8_t unk_volume; /* One less than volume */ + char unknowna4[0xac - 0xa4]; +} VPADData; + +void InitVPadFunctionPointers(void); + +extern void (* VPADInit)(void); +extern void (* VPADRead)(int chan, VPADData *buffer, u32 buffer_size, s32 *error); + +#ifdef __cplusplus +} +#endif + +#endif // __VPAD_FUNCTIONS_H_ diff --git a/src/entry.c b/src/entry.c new file mode 100644 index 0000000..759cee0 --- /dev/null +++ b/src/entry.c @@ -0,0 +1,14 @@ +#include +#include "dynamic_libs/os_functions.h" +#include "dynamic_libs/sys_functions.h" +#include "common/common.h" +#include "utils/utils.h" +#include "main.h" + +int __entry_menu(int argc, char **argv) +{ + //! ******************************************************************* + //! * Jump to our application * + //! ******************************************************************* + return Menu_Main(); +} diff --git a/src/fs/fs_utils.c b/src/fs/fs_utils.c new file mode 100644 index 0000000..efa2e55 --- /dev/null +++ b/src/fs/fs_utils.c @@ -0,0 +1,182 @@ +#include +#include +#include +#include +#include +#include "common/fs_defs.h" +#include "dynamic_libs/fs_functions.h" + + +int MountFS(void *pClient, void *pCmd, char **mount_path) +{ + int result = -1; + + void *mountSrc = malloc(FS_MOUNT_SOURCE_SIZE); + if(!mountSrc) + return -3; + + char* mountPath = (char*) malloc(FS_MAX_MOUNTPATH_SIZE); + if(!mountPath) { + free(mountSrc); + return -4; + } + + memset(mountSrc, 0, FS_MOUNT_SOURCE_SIZE); + memset(mountPath, 0, FS_MAX_MOUNTPATH_SIZE); + + // Mount sdcard + if (FSGetMountSource(pClient, pCmd, FS_SOURCETYPE_EXTERNAL, mountSrc, -1) == 0) + { + result = FSMount(pClient, pCmd, mountSrc, mountPath, FS_MAX_MOUNTPATH_SIZE, -1); + if((result == 0) && mount_path) { + *mount_path = (char*)malloc(strlen(mountPath) + 1); + if(*mount_path) + strcpy(*mount_path, mountPath); + } + } + + free(mountPath); + free(mountSrc); + return result; +} + +int UmountFS(void *pClient, void *pCmd, const char *mountPath) +{ + int result = -1; + result = FSUnmount(pClient, pCmd, mountPath, -1); + + return result; +} + +int LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size) +{ + //! always initialze input + *inbuffer = NULL; + if(size) + *size = 0; + + int iFd = open(filepath, O_RDONLY); + if (iFd < 0) + return -1; + + u32 filesize = lseek(iFd, 0, SEEK_END); + lseek(iFd, 0, SEEK_SET); + + u8 *buffer = (u8 *) malloc(filesize); + if (buffer == NULL) + { + close(iFd); + return -2; + } + + u32 blocksize = 0x4000; + u32 done = 0; + int readBytes = 0; + + while(done < filesize) + { + if(done + blocksize > filesize) { + blocksize = filesize - done; + } + readBytes = read(iFd, buffer + done, blocksize); + if(readBytes <= 0) + break; + done += readBytes; + } + + close(iFd); + + if (done != filesize) + { + free(buffer); + return -3; + } + + *inbuffer = buffer; + + //! sign is optional input + if(size) + *size = filesize; + + return filesize; +} + +int CheckFile(const char * filepath) +{ + if(!filepath) + return 0; + + struct stat filestat; + + char dirnoslash[strlen(filepath)+2]; + snprintf(dirnoslash, sizeof(dirnoslash), "%s", filepath); + + while(dirnoslash[strlen(dirnoslash)-1] == '/') + dirnoslash[strlen(dirnoslash)-1] = '\0'; + + char * notRoot = strrchr(dirnoslash, '/'); + if(!notRoot) + { + strcat(dirnoslash, "/"); + } + + if (stat(dirnoslash, &filestat) == 0) + return 1; + + return 0; +} + +int CreateSubfolder(const char * fullpath) +{ + if(!fullpath) + return 0; + + int result = 0; + + char dirnoslash[strlen(fullpath)+1]; + strcpy(dirnoslash, fullpath); + + int pos = strlen(dirnoslash)-1; + while(dirnoslash[pos] == '/') + { + dirnoslash[pos] = '\0'; + pos--; + } + + if(CheckFile(dirnoslash)) + { + return 1; + } + else + { + char parentpath[strlen(dirnoslash)+2]; + strcpy(parentpath, dirnoslash); + char * ptr = strrchr(parentpath, '/'); + + if(!ptr) + { + //!Device root directory (must be with '/') + strcat(parentpath, "/"); + struct stat filestat; + if (stat(parentpath, &filestat) == 0) + return 1; + + return 0; + } + + ptr++; + ptr[0] = '\0'; + + result = CreateSubfolder(parentpath); + } + + if(!result) + return 0; + + if (mkdir(dirnoslash, 0777) == -1) + { + return 0; + } + + return 1; +} diff --git a/src/fs/fs_utils.h b/src/fs/fs_utils.h new file mode 100644 index 0000000..7022695 --- /dev/null +++ b/src/fs/fs_utils.h @@ -0,0 +1,23 @@ +#ifndef __FS_UTILS_H_ +#define __FS_UTILS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +int MountFS(void *pClient, void *pCmd, char **mount_path); +int UmountFS(void *pClient, void *pCmd, const char *mountPath); + +int LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size); + +//! todo: C++ class +int CreateSubfolder(const char * fullpath); +int CheckFile(const char * filepath); + +#ifdef __cplusplus +} +#endif + +#endif // __FS_UTILS_H_ diff --git a/src/fs/sd_fat_devoptab.c b/src/fs/sd_fat_devoptab.c new file mode 100644 index 0000000..f5b278b --- /dev/null +++ b/src/fs/sd_fat_devoptab.c @@ -0,0 +1,1019 @@ +/*************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include "dynamic_libs/fs_functions.h" +#include "dynamic_libs/os_functions.h" +#include "fs_utils.h" + +#define FS_ALIGNMENT 0x40 +#define FS_ALIGN(x) (((x) + FS_ALIGNMENT - 1) & ~(FS_ALIGNMENT - 1)) + +typedef struct _sd_fat_private_t { + char *mount_path; + void *pClient; + void *pCmd; + void *pMutex; +} sd_fat_private_t; + +typedef struct _sd_fat_file_state_t { + sd_fat_private_t *dev; + int fd; /* File descriptor */ + int flags; /* Opening flags */ + bool read; /* True if allowed to read from file */ + bool write; /* True if allowed to write to file */ + bool append; /* True if allowed to append to file */ + u64 pos; /* Current position within the file (in bytes) */ + u64 len; /* Total length of the file (in bytes) */ + struct _sd_fat_file_state_t *prevOpenFile; /* The previous entry in a double-linked FILO list of open files */ + struct _sd_fat_file_state_t *nextOpenFile; /* The next entry in a double-linked FILO list of open files */ +} sd_fat_file_state_t; + +typedef struct _sd_fat_dir_entry_t { + sd_fat_private_t *dev; + int dirHandle; +} sd_fat_dir_entry_t; + +static sd_fat_private_t *sd_fat_get_device_data(const char *path) +{ + const devoptab_t *devoptab = NULL; + char name[128] = {0}; + int i; + + // Get the device name from the path + strncpy(name, path, 127); + strtok(name, ":/"); + + // Search the devoptab table for the specified device name + // NOTE: We do this manually due to a 'bug' in GetDeviceOpTab + // which ignores names with suffixes and causes names + // like "ntfs" and "ntfs1" to be seen as equals + for (i = 3; i < STD_MAX; i++) { + devoptab = devoptab_list[i]; + if (devoptab && devoptab->name) { + if (strcmp(name, devoptab->name) == 0) { + return (sd_fat_private_t *)devoptab->deviceData; + } + } + } + + return NULL; +} + +static char *sd_fat_real_path (const char *path, sd_fat_private_t *dev) +{ + // Sanity check + if (!path) + return NULL; + + // Move the path pointer to the start of the actual path + if (strchr(path, ':') != NULL) { + path = strchr(path, ':') + 1; + } + + int mount_len = strlen(dev->mount_path); + + char *new_name = (char*)malloc(mount_len + strlen(path) + 1); + if(new_name) { + strcpy(new_name, dev->mount_path); + strcpy(new_name + mount_len, path); + return new_name; + } + return new_name; +} + +static int sd_fat_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode) +{ + sd_fat_private_t *dev = sd_fat_get_device_data(path); + if(!dev) { + r->_errno = ENODEV; + return -1; + } + + sd_fat_file_state_t *file = (sd_fat_file_state_t *)fileStruct; + + file->dev = dev; + // Determine which mode the file is opened for + file->flags = flags; + + const char *mode_str; + + if ((flags & 0x03) == O_RDONLY) { + file->read = true; + file->write = false; + file->append = false; + mode_str = "r"; + } else if ((flags & 0x03) == O_WRONLY) { + file->read = false; + file->write = true; + file->append = (flags & O_APPEND); + mode_str = file->append ? "a" : "w"; + } else if ((flags & 0x03) == O_RDWR) { + file->read = true; + file->write = true; + file->append = (flags & O_APPEND); + mode_str = file->append ? "a+" : "r+"; + } else { + r->_errno = EACCES; + return -1; + } + + int fd = -1; + + OSLockMutex(dev->pMutex); + + char *real_path = sd_fat_real_path(path, dev); + if(!path) { + r->_errno = ENOMEM; + OSUnlockMutex(dev->pMutex); + return -1; + } + + int result = FSOpenFile(dev->pClient, dev->pCmd, real_path, mode_str, &fd, -1); + + free(real_path); + + if(result == 0) + { + FSStat stats; + result = FSGetStatFile(dev->pClient, dev->pCmd, fd, &stats, -1); + if(result != 0) { + FSCloseFile(dev->pClient, dev->pCmd, fd, -1); + r->_errno = result; + OSUnlockMutex(dev->pMutex); + return -1; + } + file->fd = fd; + file->pos = 0; + file->len = stats.size; + OSUnlockMutex(dev->pMutex); + return (int)file; + } + + r->_errno = result; + OSUnlockMutex(dev->pMutex); + return -1; +} + + +static int sd_fat_close_r (struct _reent *r, int fd) +{ + sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; + if(!file->dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(file->dev->pMutex); + + int result = FSCloseFile(file->dev->pClient, file->dev->pCmd, file->fd, -1); + + OSUnlockMutex(file->dev->pMutex); + + if(result < 0) + { + r->_errno = result; + return -1; + } + return 0; +} + +static off_t sd_fat_seek_r (struct _reent *r, int fd, off_t pos, int dir) +{ + sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; + if(!file->dev) { + r->_errno = ENODEV; + return 0; + } + + OSLockMutex(file->dev->pMutex); + + switch(dir) + { + case SEEK_SET: + file->pos = pos; + break; + case SEEK_CUR: + file->pos += pos; + break; + case SEEK_END: + file->pos = file->len + pos; + break; + default: + r->_errno = EINVAL; + return -1; + } + + int result = FSSetPosFile(file->dev->pClient, file->dev->pCmd, file->fd, file->pos, -1); + + OSUnlockMutex(file->dev->pMutex); + + if(result == 0) + { + return file->pos; + } + + return result; +} + +static ssize_t sd_fat_write_r (struct _reent *r, int fd, const char *ptr, size_t len) +{ + sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; + if(!file->dev) { + r->_errno = ENODEV; + return 0; + } + + if(!file->write) + { + r->_errno = EACCES; + return 0; + } + + OSLockMutex(file->dev->pMutex); + + size_t len_aligned = FS_ALIGN(len); + if(len_aligned > 0x4000) + len_aligned = 0x4000; + + unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned); + if(!tmpBuf) { + r->_errno = ENOMEM; + OSUnlockMutex(file->dev->pMutex); + return 0; + } + + size_t done = 0; + + while(done < len) + { + size_t write_size = (len_aligned < (len - done)) ? len_aligned : (len - done); + memcpy(tmpBuf, ptr + done, write_size); + + int result = FSWriteFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, write_size, file->fd, 0, -1); + if(result < 0) + { + r->_errno = result; + break; + } + else if(result == 0) + { + if(write_size > 0) + done = 0; + break; + } + else + { + done += result; + file->pos += result; + } + } + + free(tmpBuf); + OSUnlockMutex(file->dev->pMutex); + return done; +} + +static ssize_t sd_fat_read_r (struct _reent *r, int fd, char *ptr, size_t len) +{ + sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; + if(!file->dev) { + r->_errno = ENODEV; + return 0; + } + + if(!file->read) + { + r->_errno = EACCES; + return 0; + } + + OSLockMutex(file->dev->pMutex); + + size_t len_aligned = FS_ALIGN(len); + if(len_aligned > 0x4000) + len_aligned = 0x4000; + + unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned); + if(!tmpBuf) { + r->_errno = ENOMEM; + OSUnlockMutex(file->dev->pMutex); + return 0; + } + + size_t done = 0; + + while(done < len) + { + size_t read_size = (len_aligned < (len - done)) ? len_aligned : (len - done); + + int result = FSReadFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, read_size, file->fd, 0, -1); + if(result < 0) + { + r->_errno = result; + done = 0; + break; + } + else if(result == 0) + { + //! TODO: error on read_size > 0 + break; + } + else + { + memcpy(ptr + done, tmpBuf, read_size); + done += result; + file->pos += result; + } + } + + free(tmpBuf); + OSUnlockMutex(file->dev->pMutex); + return done; +} + + +static int sd_fat_fstat_r (struct _reent *r, int fd, struct stat *st) +{ + sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; + if(!file->dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(file->dev->pMutex); + + // Zero out the stat buffer + memset(st, 0, sizeof(struct stat)); + + FSStat stats; + int result = FSGetStatFile(file->dev->pClient, file->dev->pCmd, file->fd, &stats, -1); + if(result != 0) { + r->_errno = result; + OSUnlockMutex(file->dev->pMutex); + return -1; + } + + st->st_mode = S_IFREG; + st->st_size = stats.size; + st->st_blocks = (stats.size + 511) >> 9; + st->st_nlink = 1; + + // Fill in the generic entry stats + st->st_dev = stats.ent_id; + st->st_uid = stats.owner_id; + st->st_gid = stats.group_id; + st->st_ino = stats.ent_id; + st->st_atime = stats.mtime; + st->st_ctime = stats.ctime; + st->st_mtime = stats.mtime; + OSUnlockMutex(file->dev->pMutex); + return 0; +} + +static int sd_fat_ftruncate_r (struct _reent *r, int fd, off_t len) +{ + sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; + if(!file->dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(file->dev->pMutex); + + int result = FSTruncateFile(file->dev->pClient, file->dev->pCmd, file->fd, -1); + + OSUnlockMutex(file->dev->pMutex); + + if(result < 0) { + r->_errno = result; + return -1; + } + + return 0; +} + +static int sd_fat_fsync_r (struct _reent *r, int fd) +{ + sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; + if(!file->dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(file->dev->pMutex); + + int result = FSFlushFile(file->dev->pClient, file->dev->pCmd, file->fd, -1); + + OSUnlockMutex(file->dev->pMutex); + + if(result < 0) { + r->_errno = result; + return -1; + } + + return 0; +} + +static int sd_fat_stat_r (struct _reent *r, const char *path, struct stat *st) +{ + sd_fat_private_t *dev = sd_fat_get_device_data(path); + if(!dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dev->pMutex); + + // Zero out the stat buffer + memset(st, 0, sizeof(struct stat)); + + char *real_path = sd_fat_real_path(path, dev); + if(!real_path) { + r->_errno = ENOMEM; + OSUnlockMutex(dev->pMutex); + return -1; + } + + FSStat stats; + + int result = FSGetStat(dev->pClient, dev->pCmd, real_path, &stats, -1); + + free(real_path); + + if(result < 0) { + r->_errno = result; + OSUnlockMutex(dev->pMutex); + return -1; + } + + // mark root also as directory + st->st_mode = ((stats.flag & 0x80000000) || (strlen(dev->mount_path) + 1 == strlen(real_path)))? S_IFDIR : S_IFREG; + st->st_nlink = 1; + st->st_size = stats.size; + st->st_blocks = (stats.size + 511) >> 9; + // Fill in the generic entry stats + st->st_dev = stats.ent_id; + st->st_uid = stats.owner_id; + st->st_gid = stats.group_id; + st->st_ino = stats.ent_id; + st->st_atime = stats.mtime; + st->st_ctime = stats.ctime; + st->st_mtime = stats.mtime; + + OSUnlockMutex(dev->pMutex); + + return 0; +} + +static int sd_fat_link_r (struct _reent *r, const char *existing, const char *newLink) +{ + r->_errno = ENOTSUP; + return -1; +} + +static int sd_fat_unlink_r (struct _reent *r, const char *name) +{ + sd_fat_private_t *dev = sd_fat_get_device_data(name); + if(!dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dev->pMutex); + + char *real_path = sd_fat_real_path(name, dev); + if(!real_path) { + r->_errno = ENOMEM; + OSUnlockMutex(dev->pMutex); + return -1; + } + + + int result = FSRemove(dev->pClient, dev->pCmd, real_path, -1); + + free(real_path); + + OSUnlockMutex(dev->pMutex); + + if(result < 0) { + r->_errno = result; + return -1; + } + + return 0; +} + +static int sd_fat_chdir_r (struct _reent *r, const char *name) +{ + sd_fat_private_t *dev = sd_fat_get_device_data(name); + if(!dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dev->pMutex); + + char *real_path = sd_fat_real_path(name, dev); + if(!real_path) { + r->_errno = ENOMEM; + OSUnlockMutex(dev->pMutex); + return -1; + } + + int result = FSChangeDir(dev->pClient, dev->pCmd, real_path, -1); + + free(real_path); + + OSUnlockMutex(dev->pMutex); + + if(result < 0) { + r->_errno = result; + return -1; + } + + return 0; +} + +static int sd_fat_rename_r (struct _reent *r, const char *oldName, const char *newName) +{ + sd_fat_private_t *dev = sd_fat_get_device_data(oldName); + if(!dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dev->pMutex); + + char *real_oldpath = sd_fat_real_path(oldName, dev); + if(!real_oldpath) { + r->_errno = ENOMEM; + OSUnlockMutex(dev->pMutex); + return -1; + } + char *real_newpath = sd_fat_real_path(newName, dev); + if(!real_newpath) { + r->_errno = ENOMEM; + free(real_oldpath); + OSUnlockMutex(dev->pMutex); + return -1; + } + + int result = FSRename(dev->pClient, dev->pCmd, real_oldpath, real_newpath, -1); + + free(real_oldpath); + free(real_newpath); + + OSUnlockMutex(dev->pMutex); + + if(result < 0) { + r->_errno = result; + return -1; + } + + return 0; + +} + +static int sd_fat_mkdir_r (struct _reent *r, const char *path, int mode) +{ + sd_fat_private_t *dev = sd_fat_get_device_data(path); + if(!dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dev->pMutex); + + char *real_path = sd_fat_real_path(path, dev); + if(!real_path) { + r->_errno = ENOMEM; + OSUnlockMutex(dev->pMutex); + return -1; + } + + int result = FSMakeDir(dev->pClient, dev->pCmd, real_path, -1); + + free(real_path); + + OSUnlockMutex(dev->pMutex); + + if(result < 0) { + r->_errno = result; + return -1; + } + + return 0; +} + +static int sd_fat_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf) +{ + sd_fat_private_t *dev = sd_fat_get_device_data(path); + if(!dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dev->pMutex); + + // Zero out the stat buffer + memset(buf, 0, sizeof(struct statvfs)); + + char *real_path = sd_fat_real_path(path, dev); + if(!real_path) { + r->_errno = ENOMEM; + OSUnlockMutex(dev->pMutex); + return -1; + } + + u64 size; + + int result = FSGetFreeSpaceSize(dev->pClient, dev->pCmd, real_path, &size, -1); + + free(real_path); + + if(result < 0) { + r->_errno = result; + OSUnlockMutex(dev->pMutex); + return -1; + } + + // File system block size + buf->f_bsize = 512; + + // Fundamental file system block size + buf->f_frsize = 512; + + // Total number of blocks on file system in units of f_frsize + buf->f_blocks = size >> 9; // this is unknown + + // Free blocks available for all and for non-privileged processes + buf->f_bfree = buf->f_bavail = size >> 9; + + // Number of inodes at this point in time + buf->f_files = 0xffffffff; + + // Free inodes available for all and for non-privileged processes + buf->f_ffree = 0xffffffff; + + // File system id + buf->f_fsid = (int)dev; + + // Bit mask of f_flag values. + buf->f_flag = 0; + + // Maximum length of filenames + buf->f_namemax = 255; + + OSUnlockMutex(dev->pMutex); + + return 0; +} + +static DIR_ITER *sd_fat_diropen_r (struct _reent *r, DIR_ITER *dirState, const char *path) +{ + sd_fat_private_t *dev = sd_fat_get_device_data(path); + if(!dev) { + r->_errno = ENODEV; + return NULL; + } + + sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; + + OSLockMutex(dev->pMutex); + + char *real_path = sd_fat_real_path(path, dev); + if(!real_path) { + r->_errno = ENOMEM; + OSUnlockMutex(dev->pMutex); + return NULL; + } + + int dirHandle; + + int result = FSOpenDir(dev->pClient, dev->pCmd, real_path, &dirHandle, -1); + + free(real_path); + + OSUnlockMutex(dev->pMutex); + + if(result < 0) + { + r->_errno = result; + return NULL; + } + + dirIter->dev = dev; + dirIter->dirHandle = dirHandle; + + return dirState; +} + +static int sd_fat_dirclose_r (struct _reent *r, DIR_ITER *dirState) +{ + sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; + if(!dirIter->dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dirIter->dev->pMutex); + + int result = FSCloseDir(dirIter->dev->pClient, dirIter->dev->pCmd, dirIter->dirHandle, -1); + + OSUnlockMutex(dirIter->dev->pMutex); + + if(result < 0) + { + r->_errno = result; + return -1; + } + return 0; +} + +static int sd_fat_dirreset_r (struct _reent *r, DIR_ITER *dirState) +{ + sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; + if(!dirIter->dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dirIter->dev->pMutex); + + int result = FSRewindDir(dirIter->dev->pClient, dirIter->dev->pCmd, dirIter->dirHandle, -1); + + OSUnlockMutex(dirIter->dev->pMutex); + + if(result < 0) + { + r->_errno = result; + return -1; + } + return 0; +} + +static int sd_fat_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *st) +{ + sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; + if(!dirIter->dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dirIter->dev->pMutex); + + FSDirEntry * dir_entry = malloc(sizeof(FSDirEntry)); + + int result = FSReadDir(dirIter->dev->pClient, dirIter->dev->pCmd, dirIter->dirHandle, dir_entry, -1); + if(result < 0) + { + free(dir_entry); + r->_errno = result; + OSUnlockMutex(dirIter->dev->pMutex); + return -1; + } + + // Fetch the current entry + strcpy(filename, dir_entry->name); + + if(st) + { + memset(st, 0, sizeof(struct stat)); + st->st_mode = (dir_entry->stat.flag & 0x80000000) ? S_IFDIR : S_IFREG; + st->st_nlink = 1; + st->st_size = dir_entry->stat.size; + st->st_blocks = (dir_entry->stat.size + 511) >> 9; + st->st_dev = dir_entry->stat.ent_id; + st->st_uid = dir_entry->stat.owner_id; + st->st_gid = dir_entry->stat.group_id; + st->st_ino = dir_entry->stat.ent_id; + st->st_atime = dir_entry->stat.mtime; + st->st_ctime = dir_entry->stat.ctime; + st->st_mtime = dir_entry->stat.mtime; + } + + free(dir_entry); + OSUnlockMutex(dirIter->dev->pMutex); + return 0; +} + +// NTFS device driver devoptab +static const devoptab_t devops_sd_fat = { + NULL, /* Device name */ + sizeof (sd_fat_file_state_t), + sd_fat_open_r, + sd_fat_close_r, + sd_fat_write_r, + sd_fat_read_r, + sd_fat_seek_r, + sd_fat_fstat_r, + sd_fat_stat_r, + sd_fat_link_r, + sd_fat_unlink_r, + sd_fat_chdir_r, + sd_fat_rename_r, + sd_fat_mkdir_r, + sizeof (sd_fat_dir_entry_t), + sd_fat_diropen_r, + sd_fat_dirreset_r, + sd_fat_dirnext_r, + sd_fat_dirclose_r, + sd_fat_statvfs_r, + sd_fat_ftruncate_r, + sd_fat_fsync_r, + NULL, /* sd_fat_chmod_r */ + NULL, /* sd_fat_fchmod_r */ + NULL /* Device data */ +}; + +static int sd_fat_add_device (const char *name, const char *mount_path, void *pClient, void *pCmd) +{ + devoptab_t *dev = NULL; + char *devname = NULL; + char *devpath = NULL; + int i; + + // Sanity check + if (!name) { + errno = EINVAL; + return -1; + } + + // Allocate a devoptab for this device + dev = (devoptab_t *) malloc(sizeof(devoptab_t) + strlen(name) + 1); + if (!dev) { + errno = ENOMEM; + return -1; + } + + // Use the space allocated at the end of the devoptab for storing the device name + devname = (char*)(dev + 1); + strcpy(devname, name); + + // create private data + sd_fat_private_t *priv = (sd_fat_private_t *)malloc(sizeof(sd_fat_private_t) + strlen(mount_path) + 1); + if(!priv) { + free(dev); + errno = ENOMEM; + return -1; + } + + devpath = (char*)(priv+1); + strcpy(devpath, mount_path); + + // setup private data + priv->mount_path = devpath; + priv->pClient = pClient; + priv->pCmd = pCmd; + priv->pMutex = malloc(OS_MUTEX_SIZE); + + if(!priv->pMutex) { + free(dev); + free(priv); + errno = ENOMEM; + return -1; + } + + OSInitMutex(priv->pMutex); + + // Setup the devoptab + memcpy(dev, &devops_sd_fat, sizeof(devoptab_t)); + dev->name = devname; + dev->deviceData = priv; + + // Add the device to the devoptab table (if there is a free slot) + for (i = 3; i < STD_MAX; i++) { + if (devoptab_list[i] == devoptab_list[0]) { + devoptab_list[i] = dev; + return 0; + } + } + + // failure, free all memory + free(priv); + free(dev); + + // If we reach here then there are no free slots in the devoptab table for this device + errno = EADDRNOTAVAIL; + return -1; +} + +static int sd_fat_remove_device (const char *path, void **pClient, void **pCmd, char **mountPath) +{ + const devoptab_t *devoptab = NULL; + char name[128] = {0}; + int i; + + // Get the device name from the path + strncpy(name, path, 127); + strtok(name, ":/"); + + // Find and remove the specified device from the devoptab table + // NOTE: We do this manually due to a 'bug' in RemoveDevice + // which ignores names with suffixes and causes names + // like "ntfs" and "ntfs1" to be seen as equals + for (i = 3; i < STD_MAX; i++) { + devoptab = devoptab_list[i]; + if (devoptab && devoptab->name) { + if (strcmp(name, devoptab->name) == 0) { + devoptab_list[i] = devoptab_list[0]; + + if(devoptab->deviceData) + { + sd_fat_private_t *priv = (sd_fat_private_t *)devoptab->deviceData; + *pClient = priv->pClient; + *pCmd = priv->pCmd; + *mountPath = (char*) malloc(strlen(priv->mount_path)+1); + if(*mountPath) + strcpy(*mountPath, priv->mount_path); + if(priv->pMutex) + free(priv->pMutex); + free(devoptab->deviceData); + } + + free((devoptab_t*)devoptab); + return 0; + } + } + } + + return -1; +} + +int mount_sd_fat(const char *path) +{ + int result = -1; + + // get command and client + void* pClient = malloc(FS_CLIENT_SIZE); + void* pCmd = malloc(FS_CMD_BLOCK_SIZE); + + if(!pClient || !pCmd) { + // just in case free if not 0 + if(pClient) + free(pClient); + if(pCmd) + free(pCmd); + return -2; + } + + FSInit(); + FSInitCmdBlock(pCmd); + FSAddClientEx(pClient, 0, -1); + + char *mountPath = NULL; + + if(MountFS(pClient, pCmd, &mountPath) == 0) { + result = sd_fat_add_device(path, mountPath, pClient, pCmd); + free(mountPath); + } + + return result; +} + +int unmount_sd_fat(const char *path) +{ + void *pClient = 0; + void *pCmd = 0; + char *mountPath = 0; + + int result = sd_fat_remove_device(path, &pClient, &pCmd, &mountPath); + if(result == 0) + { + UmountFS(pClient, pCmd, mountPath); + FSDelClient(pClient); + free(pClient); + free(pCmd); + free(mountPath); + //FSShutdown(); + } + return result; +} diff --git a/src/fs/sd_fat_devoptab.h b/src/fs/sd_fat_devoptab.h new file mode 100644 index 0000000..8df487a --- /dev/null +++ b/src/fs/sd_fat_devoptab.h @@ -0,0 +1,38 @@ +/*************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * 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. + ***************************************************************************/ +#ifndef __SD_FAT_DEVOPTAB_H_ +#define __SD_FAT_DEVOPTAB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +int mount_sd_fat(const char *path); +int unmount_sd_fat(const char *path); + +#ifdef __cplusplus +} +#endif + +#endif // __SD_FAT_DEVOPTAB_H_ diff --git a/src/link.ld b/src/link.ld new file mode 100644 index 0000000..fc569d1 --- /dev/null +++ b/src/link.ld @@ -0,0 +1,40 @@ +OUTPUT(ftpiiu.elf); + +/* Tell linker where our application entry is so the garbage collect can work correct */ +ENTRY(__entry_menu); + +SECTIONS { + . = 0x00802000; + .text : { + *(.text*); + } + .rodata : { + *(.rodata*); + } + .data : { + *(.data*); + + __sdata_start = .; + *(.sdata*); + __sdata_end = .; + + __sdata2_start = .; + *(.sdata2*); + __sdata2_end = .; + } + .bss : { + __bss_start = .; + *(.bss*); + *(.sbss*); + *(COMMON); + __bss_end = .; + } + __CODE_END = .; + + /DISCARD/ : { + *(*); + } +} + +/******************************************************** FS ********************************************************/ +/* coreinit.rpl difference in addresses 0xFE3C00 */ diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..a98e97c --- /dev/null +++ b/src/main.c @@ -0,0 +1,367 @@ +#include +#include +#include +#include +#include +#include "dynamic_libs/os_functions.h" +#include "dynamic_libs/fs_functions.h" +#include "dynamic_libs/gx2_functions.h" +#include "dynamic_libs/sys_functions.h" +#include "dynamic_libs/vpad_functions.h" +#include "dynamic_libs/padscore_functions.h" +#include "dynamic_libs/socket_functions.h" +#include "dynamic_libs/ax_functions.h" +#include "fs/fs_utils.h" +#include "fs/sd_fat_devoptab.h" +#include +#include +#include "system/memory.h" +#include "utils/logger.h" +#include "utils/utils.h" +#include "common/common.h" +#include "sd_dumper.h" + +#define MAX_CONSOLE_LINES_TV 27 +#define MAX_CONSOLE_LINES_DRC 18 + +static char * consoleArrayTv[MAX_CONSOLE_LINES_TV]; +static char * consoleArrayDrc[MAX_CONSOLE_LINES_DRC]; + +static void console_print_pos(int x, int y, const char *format, ...) +{ + char * tmp = NULL; + + va_list va; + va_start(va, format); + if((vasprintf(&tmp, format, va) >= 0) && tmp) + { + if(strlen(tmp) > 79) + tmp[79] = 0; + + OSScreenPutFontEx(0, x, y, tmp); + OSScreenPutFontEx(1, x, y, tmp); + + } + va_end(va); + + if(tmp) + free(tmp); +} + +void console_printf(int newline, const char *format, ...) +{ + char * tmp = NULL; + + va_list va; + va_start(va, format); + if((vasprintf(&tmp, format, va) >= 0) && tmp) + { + if(newline) + { + if(consoleArrayTv[0]) + free(consoleArrayTv[0]); + if(consoleArrayDrc[0]) + free(consoleArrayDrc[0]); + + for(int i = 1; i < MAX_CONSOLE_LINES_TV; i++) + consoleArrayTv[i-1] = consoleArrayTv[i]; + + for(int i = 1; i < MAX_CONSOLE_LINES_DRC; i++) + consoleArrayDrc[i-1] = consoleArrayDrc[i]; + } + else + { + if(consoleArrayTv[MAX_CONSOLE_LINES_TV-1]) + free(consoleArrayTv[MAX_CONSOLE_LINES_TV-1]); + if(consoleArrayDrc[MAX_CONSOLE_LINES_DRC-1]) + free(consoleArrayDrc[MAX_CONSOLE_LINES_DRC-1]); + + consoleArrayTv[MAX_CONSOLE_LINES_TV-1] = NULL; + consoleArrayDrc[MAX_CONSOLE_LINES_DRC-1] = NULL; + } + + if(strlen(tmp) > 79) + tmp[79] = 0; + + consoleArrayTv[MAX_CONSOLE_LINES_TV-1] = (char*)malloc(strlen(tmp) + 1); + if(consoleArrayTv[MAX_CONSOLE_LINES_TV-1]) + strcpy(consoleArrayTv[MAX_CONSOLE_LINES_TV-1], tmp); + + consoleArrayDrc[MAX_CONSOLE_LINES_DRC-1] = (tmp); + } + va_end(va); + + // Clear screens + OSScreenClearBufferEx(0, 0); + OSScreenClearBufferEx(1, 0); + + + for(int i = 0; i < MAX_CONSOLE_LINES_TV; i++) + { + if(consoleArrayTv[i]) + OSScreenPutFontEx(0, 0, i, consoleArrayTv[i]); + } + + for(int i = 0; i < MAX_CONSOLE_LINES_DRC; i++) + { + if(consoleArrayDrc[i]) + OSScreenPutFontEx(1, 0, i, consoleArrayDrc[i]); + } + + OSScreenFlipBuffersEx(0); + OSScreenFlipBuffersEx(1); +} + +int CheckCancel(void) +{ + int vpadError = -1; + VPADData vpad; + + //! update only at 50 Hz, thats more than enough + VPADRead(0, &vpad, 1, &vpadError); + + if(vpadError == 0 && ((vpad.btns_d | vpad.btns_h) & VPAD_BUTTON_B)) + { + return 1; + } + return 0; +} + +/* Entry point */ +int Menu_Main(void) +{ + //!******************************************************************* + //! Initialize function pointers * + //!******************************************************************* + //! do OS (for acquire) and sockets first so we got logging + InitOSFunctionPointers(); + InitSocketFunctionPointers(); + + log_init("192.168.178.3"); + log_print("Starting launcher\n"); + + InitFSFunctionPointers(); + InitVPadFunctionPointers(); + + log_print("Function exports loaded\n"); + + //!******************************************************************* + //! Initialize heap memory * + //!******************************************************************* + log_print("Initialize memory management\n"); + //! We don't need bucket and MEM1 memory so no need to initialize + //memoryInitialize(); + + //!******************************************************************* + //! Initialize FS * + //!******************************************************************* + log_printf("Mount SD partition\n"); + mount_sd_fat("sd"); + + for(int i = 0; i < MAX_CONSOLE_LINES_TV; i++) + consoleArrayTv[i] = NULL; + + for(int i = 0; i < MAX_CONSOLE_LINES_DRC; i++) + consoleArrayDrc[i] = NULL; + + VPADInit(); + + // Prepare screen + int screen_buf0_size = 0; + + // Init screen and screen buffers + OSScreenInit(); + screen_buf0_size = OSScreenGetBufferSizeEx(0); + OSScreenSetBufferEx(0, (void *)0xF4000000); + OSScreenSetBufferEx(1, (void *)(0xF4000000 + screen_buf0_size)); + + OSScreenEnableEx(0, 1); + OSScreenEnableEx(1, 1); + + // Clear screens + OSScreenClearBufferEx(0, 0); + OSScreenClearBufferEx(1, 0); + + // Flip buffers + OSScreenFlipBuffersEx(0); + OSScreenFlipBuffersEx(1); + + int res = IOSUHAX_Open(); + if(res < 0) + { + console_printf(1, "IOSUHAX_open failed\n"); + sleep(2); + return 0; + } + + int fsaFd = IOSUHAX_FSA_Open(); + if(fsaFd < 0) + { + console_printf(1, "IOSUHAX_FSA_Open failed\n"); + sleep(2); + return 0; + } + + int vpadError = -1; + VPADData vpad; + + int initScreen = 1; + + static const char* selection_paths[] = + { + "/dev/odd01", + "/dev/odd02", + "/dev/odd03", + "/dev/odd04", + "/dev/slccmpt01", + "/vol/system", + "/vol/storage_mlc01", + "/vol/storage_usb01", + }; + + static const char* selection_paths_description[] = + { + "(disc tickets)", + "(disc update)", + "(disc content)", + "(disc content)", + "(vWii slc content)", + "(slc content)", + "(mlc content)", + "(usb01 content)", + }; + + int selectedItem = 0; + + while(1) + { + //! update only at 50 Hz, thats more than enough + VPADRead(0, &vpad, 1, &vpadError); + + if(initScreen) + { + initScreen = 0; + + //! free memory + for(int i = 0; i < MAX_CONSOLE_LINES_TV; i++) + { + if(consoleArrayTv[i]) + free(consoleArrayTv[i]); + consoleArrayTv[i] = 0; + } + + for(int i = 0; i < MAX_CONSOLE_LINES_DRC; i++) + { + if(consoleArrayDrc[i]) + free(consoleArrayDrc[i]); + consoleArrayDrc[i] = 0; + } + + // Clear screens + OSScreenClearBufferEx(0, 0); + OSScreenClearBufferEx(1, 0); + + + console_print_pos(0, 1, "-- File Tree 2 SD v0.1 by Dimok --"); + + console_print_pos(0, 3, "Select what to dump to sd:/ft2sd and press A to start dump."); + console_print_pos(0, 4, "Hold B to cancel dump."); + + u32 i; + for(i = 0; i < (sizeof(selection_paths) / 4); i++) + { + if(selectedItem == (int)i) + { + console_print_pos(0, 6 + i, "--> %s %s", selection_paths[i], selection_paths_description[i]); + } + else + { + console_print_pos(0, 6 + i, " %s %s", selection_paths[i], selection_paths_description[i]); + } + } + // Flip buffers + OSScreenFlipBuffersEx(0); + OSScreenFlipBuffersEx(1); + } + + if(vpadError == 0 && ((vpad.btns_d | vpad.btns_h) & VPAD_BUTTON_DOWN)) + { + selectedItem = (selectedItem + 1) % (sizeof(selection_paths) / 4); + initScreen = 1; + usleep(100000); + } + + if(vpadError == 0 && ((vpad.btns_d | vpad.btns_h) & VPAD_BUTTON_UP)) + { + selectedItem--; + if(selectedItem < 0) + selectedItem = (sizeof(selection_paths) / 4) - 1; + initScreen = 1; + usleep(100000); + } + + if(vpadError == 0 && ((vpad.btns_d | vpad.btns_h) & VPAD_BUTTON_A)) + { + const char *dev_path = (selectedItem < 5) ? selection_paths[selectedItem] : NULL; + const char *mount_path = (selectedItem >= 5) ? selection_paths[selectedItem] : "/vol/storage_ft_content"; + + int res = mount_fs("dev", fsaFd, dev_path, mount_path); + if(res < 0) + { + console_printf(1, "Mount of %s to %s failed", dev_path, mount_path); + } + else + { + char *targetPath = (char*)malloc(FS_MAX_FULLPATH_SIZE); + if(targetPath) + { + strcpy(targetPath, "dev:/"); + DumpDir(targetPath, "sd:/ft2sd"); + + free(targetPath); + } + unmount_fs("dev"); + console_printf(1, "Dump complete"); + } + sleep(3); + initScreen = 1; + } + + if(vpadError == 0 && ((vpad.btns_d | vpad.btns_h) & VPAD_BUTTON_HOME)) + { + break; + } + + usleep(50000); + } + + //! free memory + for(int i = 0; i < MAX_CONSOLE_LINES_TV; i++) + { + if(consoleArrayTv[i]) + free(consoleArrayTv[i]); + } + + for(int i = 0; i < MAX_CONSOLE_LINES_DRC; i++) + { + if(consoleArrayDrc[i]) + free(consoleArrayDrc[i]); + } + + //!******************************************************************* + //! Enter main application * + //!******************************************************************* + + log_printf("Unmount SD\n"); + unmount_sd_fat("sd"); + + IOSUHAX_FSA_Close(fsaFd); + IOSUHAX_Close(); + + log_printf("Release memory\n"); + //memoryRelease(); + log_deinit(); + + return EXIT_SUCCESS; +} + diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..e8deb2b --- /dev/null +++ b/src/main.h @@ -0,0 +1,20 @@ +#ifndef _MAIN_H_ +#define _MAIN_H_ + +#include "common/types.h" +#include "dynamic_libs/os_functions.h" + +/* Main */ +#ifdef __cplusplus +extern "C" { +#endif + +int Menu_Main(void); +int CheckCancel(void); +void console_printf(int newline, const char *format, ...); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sd_dumper.c b/src/sd_dumper.c new file mode 100644 index 0000000..bba414a --- /dev/null +++ b/src/sd_dumper.c @@ -0,0 +1,141 @@ +#include +#include +#include +#include +#include +#include +#include "dynamic_libs/os_functions.h" +#include "dynamic_libs/fs_functions.h" +#include "fs/fs_utils.h" +#include "main.h" + +#define BUFFER_SIZE 0x80000 + +void console_printf(int newline, const char *format, ...); +int checkCancel(void); + +static int DumpFile(char *pPath, const char * output_path) +{ + char *pSlash = strchr(pPath, '/'); + if(pSlash && pSlash[1] == '/') + pSlash++; + + char *pFilename = strrchr(pPath, '/'); + if(!pFilename) + pFilename = pPath; + else + pFilename++; + + console_printf(1, "0x%X - %s", 0, pSlash); + + unsigned char* dataBuf = (unsigned char*)memalign(0x40, BUFFER_SIZE); + if(!dataBuf) { + return -1; + } + + FILE *pReadFile = fopen(pPath, "rb"); + if(!pReadFile) + { + console_printf(1, "Can't open file %s\n", pPath); + return -2; + } + + FILE *pWriteFile = fopen(output_path, "wb"); + if(!pWriteFile) + { + console_printf(1, "Can't open write file %s\n", output_path); + fclose(pReadFile); + return -3; + } + + unsigned int size = 0; + unsigned int ret; + u32 passedMs = 1; + u64 startTime = OSGetTime(); + + // Copy rpl in memory + while ((ret = fread(dataBuf, 0x1, BUFFER_SIZE, pReadFile)) > 0) + { + passedMs = (OSGetTime() - startTime) * 4000ULL / BUS_SPEED; + if(passedMs == 0) + passedMs = 1; // avoid 0 div + + fwrite(dataBuf, 0x01, ret, pWriteFile); + size += ret; + console_printf(0, " %s - 0x%X (%i kB/s) (%s)\r", pFilename, size, (u32)(((u64)size * 1000) / ((u64)1024 * passedMs)), pSlash); + } + + fclose(pWriteFile); + fclose(pReadFile); + free(dataBuf); + return 0; +} + +int DumpDir(char *pPath, const char * target_path) +{ + struct dirent *dirent = NULL; + DIR *dir = NULL; + + dir = opendir(pPath); + if (dir == NULL) + { + console_printf(1, "Can't open %s\n", pPath); + return -1; + } + + { + char *targetPath = (char*)malloc(FS_MAX_FULLPATH_SIZE); + if(!targetPath) + { + console_printf(1, "no memory\n"); + closedir(dir); + return -1; + } + + char *pSlash = strchr(pPath, '/'); + snprintf(targetPath, FS_MAX_FULLPATH_SIZE, "%s%s", target_path, pSlash); + CreateSubfolder(targetPath); + free(targetPath); + } + + while ((dirent = readdir(dir)) != 0) + { + if(strcmp(dirent->d_name, "..") == 0 || strcmp(dirent->d_name, ".") == 0) + continue; + + if(CheckCancel()) + break; + + int len = strlen(pPath); + snprintf(pPath + len, FS_MAX_FULLPATH_SIZE - len, "/%s", dirent->d_name); + + char *pSlash = strchr(pPath, '/'); + + if(!pSlash) + { + console_printf(1, "Error on %s\n", pPath); + continue; + } + if(pSlash[1] == '/') + pSlash++; + + if(dirent->d_type & DT_DIR) + { + console_printf(1, "%s (%s)\n", dirent->d_name, pSlash); + + DumpDir(pPath, target_path); + } + else + { + char *targetPath = (char*)malloc(FS_MAX_FULLPATH_SIZE); + snprintf(targetPath, FS_MAX_FULLPATH_SIZE, "%s%s", target_path, pSlash); + + DumpFile(pPath, targetPath); + free(targetPath); + } + pPath[len] = 0; + } + + closedir(dir); + return 0; +} diff --git a/src/sd_dumper.h b/src/sd_dumper.h new file mode 100644 index 0000000..3171b82 --- /dev/null +++ b/src/sd_dumper.h @@ -0,0 +1,15 @@ +#ifndef _SD_DUMPER_H_ +#define _SD_DUMPER_H_ + +/* Main */ +#ifdef __cplusplus +extern "C" { +#endif + +int DumpDir(char *pPath, const char * target_path); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/system/memory.c b/src/system/memory.c new file mode 100644 index 0000000..91f5392 --- /dev/null +++ b/src/system/memory.c @@ -0,0 +1,198 @@ +/**************************************************************************** + * Copyright (C) 2015 Dimok + * + * 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 "dynamic_libs/os_functions.h" +#include "common/common.h" +#include "memory.h" + +#define MEMORY_ARENA_1 0 +#define MEMORY_ARENA_2 1 +#define MEMORY_ARENA_3 2 +#define MEMORY_ARENA_4 3 +#define MEMORY_ARENA_5 4 +#define MEMORY_ARENA_6 5 +#define MEMORY_ARENA_7 6 +#define MEMORY_ARENA_8 7 +#define MEMORY_ARENA_FG_BUCKET 8 + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Memory functions +//! This is the only place where those are needed so lets keep them more or less private +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +extern unsigned int * pMEMAllocFromDefaultHeapEx; +extern unsigned int * pMEMAllocFromDefaultHeap; +extern unsigned int * pMEMFreeToDefaultHeap; + +extern int (* MEMGetBaseHeapHandle)(int mem_arena); +extern unsigned int (* MEMGetAllocatableSizeForFrmHeapEx)(int heap, int align); +extern void *(* MEMAllocFromFrmHeapEx)(int heap, unsigned int size, int align); +extern void (* MEMFreeToFrmHeap)(int heap, int mode); +extern void *(* MEMAllocFromExpHeapEx)(int heap, unsigned int size, int align); +extern int (* MEMCreateExpHeapEx)(void* address, unsigned int size, unsigned short flags); +extern void *(* MEMDestroyExpHeap)(int heap); +extern void (* MEMFreeToExpHeap)(int heap, void* ptr); + +static int mem1_heap = -1; +static int bucket_heap = -1; + +void memoryInitialize(void) +{ + int mem1_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_1); + unsigned int mem1_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(mem1_heap_handle, 4); + void *mem1_memory = MEMAllocFromFrmHeapEx(mem1_heap_handle, mem1_allocatable_size, 4); + if(mem1_memory) + mem1_heap = MEMCreateExpHeapEx(mem1_memory, mem1_allocatable_size, 0); + + int bucket_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET); + unsigned int bucket_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(bucket_heap_handle, 4); + void *bucket_memory = MEMAllocFromFrmHeapEx(bucket_heap_handle, bucket_allocatable_size, 4); + if(bucket_memory) + bucket_heap = MEMCreateExpHeapEx(bucket_memory, bucket_allocatable_size, 0); +} + +void memoryRelease(void) +{ + MEMDestroyExpHeap(mem1_heap); + MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_1), 3); + mem1_heap = -1; + + MEMDestroyExpHeap(bucket_heap); + MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET), 3); + bucket_heap = -1; +} + +//!------------------------------------------------------------------------------------------- +//! wraps +//!------------------------------------------------------------------------------------------- +void *__wrap_malloc(size_t size) +{ + // pointer to a function resolve + return ((void * (*)(size_t))(*pMEMAllocFromDefaultHeap))(size); +} + +void *__wrap_memalign(size_t align, size_t size) +{ + if (align < 4) + align = 4; + + // pointer to a function resolve + return ((void * (*)(size_t, size_t))(*pMEMAllocFromDefaultHeapEx))(size, align); +} + +void __wrap_free(void *p) +{ + // pointer to a function resolve + if(p != 0) + ((void (*)(void *))(*pMEMFreeToDefaultHeap))(p); +} + +void *__wrap_calloc(size_t n, size_t size) +{ + void *p = __wrap_malloc(n * size); + if (p != 0) { + memset(p, 0, n * size); + } + return p; +} + +size_t __wrap_malloc_usable_size(void *p) +{ + //! TODO: this is totally wrong and needs to be addressed + return 0x7FFFFFFF; +} + +void *__wrap_realloc(void *p, size_t size) +{ + void *new_ptr = __wrap_malloc(size); + if (new_ptr != 0) + { + memcpy(new_ptr, p, __wrap_malloc_usable_size(p) < size ? __wrap_malloc_usable_size(p) : size); + __wrap_free(p); + } + return new_ptr; +} + +//!------------------------------------------------------------------------------------------- +//! reent versions +//!------------------------------------------------------------------------------------------- +void *__wrap__malloc_r(struct _reent *r, size_t size) +{ + return __wrap_malloc(size); +} + +void *__wrap__calloc_r(struct _reent *r, size_t n, size_t size) +{ + return __wrap_calloc(n, size); +} + +void *__wrap__memalign_r(struct _reent *r, size_t align, size_t size) +{ + return __wrap_memalign(align, size); +} + +void __wrap__free_r(struct _reent *r, void *p) +{ + __wrap_free(p); +} + +size_t __wrap__malloc_usable_size_r(struct _reent *r, void *p) +{ + return __wrap_malloc_usable_size(p); +} + +void *__wrap__realloc_r(struct _reent *r, void *p, size_t size) +{ + return __wrap_realloc(p, size); +} + +//!------------------------------------------------------------------------------------------- +//! some wrappers +//!------------------------------------------------------------------------------------------- +void * MEM2_alloc(unsigned int size, unsigned int align) +{ + return __wrap_memalign(align, size); +} + +void MEM2_free(void *ptr) +{ + __wrap_free(ptr); +} + +void * MEM1_alloc(unsigned int size, unsigned int align) +{ + if (align < 4) + align = 4; + return MEMAllocFromExpHeapEx(mem1_heap, size, align); +} + +void MEM1_free(void *ptr) +{ + MEMFreeToExpHeap(mem1_heap, ptr); +} + +void * MEMBucket_alloc(unsigned int size, unsigned int align) +{ + if (align < 4) + align = 4; + return MEMAllocFromExpHeapEx(bucket_heap, size, align); +} + +void MEMBucket_free(void *ptr) +{ + MEMFreeToExpHeap(bucket_heap, ptr); +} diff --git a/src/system/memory.h b/src/system/memory.h new file mode 100644 index 0000000..59764d0 --- /dev/null +++ b/src/system/memory.h @@ -0,0 +1,42 @@ +/**************************************************************************** + * Copyright (C) 2015 Dimok + * + * 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 . + ****************************************************************************/ +#ifndef __MEMORY_H_ +#define __MEMORY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void memoryInitialize(void); +void memoryRelease(void); + +void * MEM2_alloc(unsigned int size, unsigned int align); +void MEM2_free(void *ptr); + +void * MEM1_alloc(unsigned int size, unsigned int align); +void MEM1_free(void *ptr); + +void * MEMBucket_alloc(unsigned int size, unsigned int align); +void MEMBucket_free(void *ptr); + +#ifdef __cplusplus +} +#endif + +#endif // __MEMORY_H_ diff --git a/src/utils/logger.c b/src/utils/logger.c new file mode 100644 index 0000000..86dd652 --- /dev/null +++ b/src/utils/logger.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include "common/common.h" +#include "dynamic_libs/os_functions.h" +#include "dynamic_libs/socket_functions.h" +#include "logger.h" + +#ifdef DEBUG_LOGGER +static int log_socket = -1; +static volatile int log_lock = 0; + + +void log_init(const char * ipString) +{ + log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (log_socket < 0) + return; + + struct sockaddr_in connect_addr; + memset(&connect_addr, 0, sizeof(connect_addr)); + connect_addr.sin_family = AF_INET; + connect_addr.sin_port = 4405; + inet_aton(ipString, &connect_addr.sin_addr); + + if(connect(log_socket, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0) + { + socketclose(log_socket); + log_socket = -1; + } +} + +void log_deinit(void) +{ + if(log_socket >= 0) + { + socketclose(log_socket); + log_socket = -1; + } +} + +void log_print(const char *str) +{ + // socket is always 0 initially as it is in the BSS + if(log_socket < 0) { + return; + } + + while(log_lock) + usleep(1000); + log_lock = 1; + + int len = strlen(str); + int ret; + while (len > 0) { + int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet + ret = send(log_socket, str, block, 0); + if(ret < 0) + break; + + len -= ret; + str += ret; + } + + log_lock = 0; +} + +void log_printf(const char *format, ...) +{ + if(log_socket < 0) { + return; + } + + char * tmp = NULL; + + va_list va; + va_start(va, format); + if((vasprintf(&tmp, format, va) >= 0) && tmp) + { + log_print(tmp); + } + va_end(va); + + if(tmp) + free(tmp); +} +#endif diff --git a/src/utils/logger.h b/src/utils/logger.h new file mode 100644 index 0000000..0e19ad3 --- /dev/null +++ b/src/utils/logger.h @@ -0,0 +1,26 @@ +#ifndef __LOGGER_H_ +#define __LOGGER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +//#define DEBUG_LOGGER 1 + +#ifdef DEBUG_LOGGER +void log_init(const char * ip); +void log_deinit(void); +void log_print(const char *str); +void log_printf(const char *format, ...); +#else +#define log_init(x) +#define log_deinit() +#define log_print(x) +#define log_printf(x, ...) +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utils/utils.h b/src/utils/utils.h new file mode 100644 index 0000000..c460fa2 --- /dev/null +++ b/src/utils/utils.h @@ -0,0 +1,47 @@ +#ifndef __UTILS_H_ +#define __UTILS_H_ + +#include +#include "../common/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define FlushBlock(addr) asm volatile("dcbf %0, %1\n" \ + "icbi %0, %1\n" \ + "sync\n" \ + "eieio\n" \ + "isync\n" \ + : \ + :"r"(0), "r"(((addr) & ~31)) \ + :"memory", "ctr", "lr", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" \ + ); + +#define LIMIT(x, min, max) \ + ({ \ + typeof( x ) _x = x; \ + typeof( min ) _min = min; \ + typeof( max ) _max = max; \ + ( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \ + }) + +#define DegToRad(a) ( (a) * 0.01745329252f ) +#define RadToDeg(a) ( (a) * 57.29577951f ) + +#define ALIGN4(x) (((x) + 3) & ~3) +#define ALIGN32(x) (((x) + 31) & ~31) + +// those work only in powers of 2 +#define ROUNDDOWN(val, align) ((val) & ~(align-1)) +#define ROUNDUP(val, align) ROUNDDOWN(((val) + (align-1)), align) + +#define le16(i) ((((u16) ((i) & 0xFF)) << 8) | ((u16) (((i) & 0xFF00) >> 8))) +#define le32(i) ((((u32)le16((i) & 0xFFFF)) << 16) | ((u32)le16(((i) & 0xFFFF0000) >> 16))) +#define le64(i) ((((u64)le32((i) & 0xFFFFFFFFLL)) << 32) | ((u64)le32(((i) & 0xFFFFFFFF00000000LL) >> 32))) + +#ifdef __cplusplus +} +#endif + +#endif // __UTILS_H_