initial commit

This commit is contained in:
dimok789 2016-02-29 22:36:09 +01:00
commit f458982ab1
45 changed files with 6410 additions and 0 deletions

13
.gitignore vendored Normal file
View File

@ -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

19
LICENSE.txt Normal file
View File

@ -0,0 +1,19 @@
Copyright (C) 2008 Joseph Jordan <joe.ftpii@psychlaw.com.au>
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.

215
Makefile Normal file
View File

@ -0,0 +1,215 @@
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
endif
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>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 := ftpiiu
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
#---------------------------------------------------------------------------------
# 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
#---------------------------------------------------------------------------------

36
src/common/common.h Normal file
View File

@ -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 */

62
src/common/fs_defs.h Normal file
View File

@ -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 */

25
src/common/os_defs.h Normal file
View File

@ -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_

7
src/common/types.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef TYPES_H
#define TYPES_H
#include <gctypes.h>
#endif /* TYPES_H */

View File

@ -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);
}

View File

@ -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 <gctypes.h>
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_

View File

@ -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);
}

View File

@ -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_

View File

@ -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);
}

View File

@ -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_

View File

@ -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 <gctypes.h>
//!-----------------------------------------------------------------------------------------------------------------------
//! 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 0x00000000
#define GX2_TV_RENDER_480_WIDE 0x00000001
#define GX2_TV_RENDER_720 0x00000002
#define GX2_TV_RENDER_1080 0x00000004
//!-----------------------------------------------------------------------------------------------------------------------
//! 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

View File

@ -0,0 +1,166 @@
/****************************************************************************
* 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 = 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);
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! 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);
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! 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, __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(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);
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! Loader functions (not real rpl)
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
EXPORT_DECL(int, LiWaitIopComplete, int unknown_syscall_arg_r3, int * remaining_bytes);
EXPORT_DECL(int, LiWaitIopCompleteWithInterrupts, int unknown_syscall_arg_r3, int * remaining_bytes);
void InitOSFunctionPointers(void)
{
unsigned int *funcPointer = 0;
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! 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);
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! System functions
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
OS_FIND_EXPORT(coreinit_handle, OSFatal);
OS_FIND_EXPORT(coreinit_handle, OSGetTitleID);
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);
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);
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! 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);
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! 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);
}

View File

@ -0,0 +1,128 @@
/****************************************************************************
* 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 <gctypes.h>
#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);
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! 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);
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! 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);
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! 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 (* __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 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);
extern int (* LiWaitIopComplete)(int unknown_syscall_arg_r3, int * remaining_bytes);
extern int (* LiWaitIopCompleteWithInterrupts)(int unknown_syscall_arg_r3, int * remaining_bytes);
#ifdef __cplusplus
}
#endif
#endif // __OS_FUNCTIONS_H_

View File

@ -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);
}

View File

@ -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 <gctypes.h>
#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_

View File

@ -0,0 +1,82 @@
/****************************************************************************
* 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);
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);
unsigned int nn_startupid;
ACInitialize();
ACGetStartupId(&nn_startupid);
ACConnectWithConfigId(nn_startupid);
ACGetAssignedAddress(&hostIpAddress);
socket_lib_init();
}

View File

@ -0,0 +1,95 @@
/****************************************************************************
* 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 <gctypes.h>
#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 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);
#ifdef __cplusplus
}
#endif
#endif // __SOCKET_FUNCTIONS_H_

View File

@ -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);
}

View File

@ -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_

View File

@ -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);
}

View File

@ -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 <gctypes.h>
#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_

14
src/entry.c Normal file
View File

@ -0,0 +1,14 @@
#include <string.h>
#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();
}

182
src/fs/fs_utils.c Normal file
View File

@ -0,0 +1,182 @@
#include <malloc.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#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;
}

23
src/fs/fs_utils.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef __FS_UTILS_H_
#define __FS_UTILS_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <gctypes.h>
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_

1019
src/fs/sd_fat_devoptab.c Normal file

File diff suppressed because it is too large Load Diff

38
src/fs/sd_fat_devoptab.h Normal file
View File

@ -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_

913
src/ftp.c Normal file
View File

@ -0,0 +1,913 @@
/*
ftpii -- an FTP server for the Wii
Copyright (C) 2008 Joseph Jordan <joe.ftpii@psychlaw.com.au>
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 <errno.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <sys/dir.h>
#include <unistd.h>
#include "dynamic_libs/os_functions.h"
#include "dynamic_libs/socket_functions.h"
#undef EAGAIN
#define EAGAIN 1
//! TODO: fix those function
#define gettime() OSGetTick()
#include "ftp.h"
#include "virtualpath.h"
#include "net.h"
#include "vrt.h"
#define UNUSED __attribute__((unused))
#define FTP_BUFFER_SIZE 1024
#define MAX_CLIENTS 5
extern void console_printf(const char *format, ...);
static const u16 SRC_PORT = 20;
static const s32 EQUIT = 696969;
static const char *CRLF = "\r\n";
static const u32 CRLF_LENGTH = 2;
static u8 num_clients = 0;
static u16 passive_port = 1024;
static char *password = NULL;
typedef s32 (*data_connection_callback)(s32 data_socket, void *arg);
struct client_struct {
s32 socket;
char representation_type;
s32 passive_socket;
s32 data_socket;
char cwd[MAXPATHLEN];
char pending_rename[MAXPATHLEN];
off_t restart_marker;
struct sockaddr_in address;
bool authenticated;
char buf[FTP_BUFFER_SIZE];
s32 offset;
bool data_connection_connected;
data_connection_callback data_callback;
void *data_connection_callback_arg;
void (*data_connection_cleanup)(void *arg);
u64 data_connection_timer;
};
typedef struct client_struct client_t;
static client_t *clients[MAX_CLIENTS] = { NULL };
void set_ftp_password(char *new_password) {
if (password) free(password);
if (new_password) {
password = malloc(strlen(new_password) + 1);
if (!password)
return;
strcpy((char *)password, new_password);
} else {
password = NULL;
}
}
static bool compare_ftp_password(char *password_attempt) {
return !password || !strcmp((char *)password, password_attempt);
}
/*
TODO: support multi-line reply
*/
static s32 write_reply(client_t *client, u16 code, char *msg) {
u32 msglen = 4 + strlen(msg) + CRLF_LENGTH;
char * msgbuf = (char *) malloc(msglen + 1);
if (msgbuf == NULL) return -ENOMEM;
sprintf(msgbuf, "%u %s\r\n", code, msg);
console_printf("Wrote reply: %s", msgbuf);
s32 ret = send_exact(client->socket, msgbuf, msglen);
free(msgbuf);
return ret;
}
static void close_passive_socket(client_t *client) {
if (client->passive_socket >= 0) {
network_close_blocking(client->passive_socket);
client->passive_socket = -1;
}
}
/*
result must be able to hold up to maxsplit+1 null-terminated strings of length strlen(s)
returns the number of strings stored in the result array (up to maxsplit+1)
*/
static u32 split(char *s, char sep, u32 maxsplit, char *result[]) {
u32 num_results = 0;
u32 result_pos = 0;
u32 trim_pos = 0;
bool in_word = false;
for (; *s; s++) {
if (*s == sep) {
if (num_results <= maxsplit) {
in_word = false;
continue;
} else if (!trim_pos) {
trim_pos = result_pos;
}
} else if (trim_pos) {
trim_pos = 0;
}
if (!in_word) {
in_word = true;
if (num_results <= maxsplit) {
num_results++;
result_pos = 0;
}
}
result[num_results - 1][result_pos++] = *s;
result[num_results - 1][result_pos] = '\0';
}
if (trim_pos) {
result[num_results - 1][trim_pos] = '\0';
}
u32 i = num_results;
for (i = num_results; i <= maxsplit; i++) {
result[i][0] = '\0';
}
return num_results;
}
static s32 ftp_USER(client_t *client, char *username UNUSED) {
return write_reply(client, 331, "User name okay, need password.");
}
static s32 ftp_PASS(client_t *client, char *password_attempt) {
if (compare_ftp_password(password_attempt)) {
client->authenticated = true;
return write_reply(client, 230, "User logged in, proceed.");
} else {
return write_reply(client, 530, "Login incorrect.");
}
}
static s32 ftp_REIN(client_t *client, char *rest UNUSED) {
close_passive_socket(client);
strcpy(client->cwd, "/");
client->representation_type = 'A';
client->authenticated = false;
return write_reply(client, 220, "Service ready for new user.");
}
static s32 ftp_QUIT(client_t *client, char *rest UNUSED) {
// TODO: dont quit if xfer in progress
s32 result = write_reply(client, 221, "Service closing control connection.");
return result < 0 ? result : -EQUIT;
}
static s32 ftp_SYST(client_t *client, char *rest UNUSED) {
return write_reply(client, 215, "UNIX Type: L8 Version: ftpii");
}
static s32 ftp_TYPE(client_t *client, char *rest) {
char representation_type[FTP_BUFFER_SIZE], param[FTP_BUFFER_SIZE];
char *args[] = { representation_type, param };
u32 num_args = split(rest, ' ', 1, args);
if (num_args == 0) {
return write_reply(client, 501, "Syntax error in parameters.");
} else if ((!strcasecmp("A", representation_type) && (!*param || !strcasecmp("N", param))) ||
(!strcasecmp("I", representation_type) && num_args == 1)) {
client->representation_type = *representation_type;
} else {
return write_reply(client, 501, "Syntax error in parameters.");
}
char msg[15];
sprintf(msg, "Type set to %s.", representation_type);
return write_reply(client, 200, msg);
}
static s32 ftp_MODE(client_t *client, char *rest) {
if (!strcasecmp("S", rest)) {
return write_reply(client, 200, "Mode S ok.");
} else {
return write_reply(client, 501, "Syntax error in parameters.");
}
}
static s32 ftp_PWD(client_t *client, char *rest UNUSED) {
char msg[MAXPATHLEN + 24];
// TODO: escape double-quotes
sprintf(msg, "\"%s\" is current directory.", client->cwd);
return write_reply(client, 257, msg);
}
static s32 ftp_CWD(client_t *client, char *path) {
s32 result;
if (!vrt_chdir(client->cwd, path)) {
result = write_reply(client, 250, "CWD command successful.");
} else {
result = write_reply(client, 550, strerror(errno));
}
return result;
}
static s32 ftp_CDUP(client_t *client, char *rest UNUSED) {
s32 result;
if (!vrt_chdir(client->cwd, "..")) {
result = write_reply(client, 250, "CDUP command successful.");
} else {
result = write_reply(client, 550, strerror(errno));
}
return result;
}
static s32 ftp_DELE(client_t *client, char *path) {
if (!vrt_unlink(client->cwd, path)) {
return write_reply(client, 250, "File or directory removed.");
} else {
return write_reply(client, 550, strerror(errno));
}
}
static s32 ftp_MKD(client_t *client, char *path) {
if (!*path) {
return write_reply(client, 501, "Syntax error in parameters.");
}
if (!vrt_mkdir(client->cwd, path, 0777)) {
char msg[MAXPATHLEN + 21];
char abspath[MAXPATHLEN];
strcpy(abspath, client->cwd);
vrt_chdir(abspath, path); // TODO: error checking
// TODO: escape double-quotes
sprintf(msg, "\"%s\" directory created.", abspath);
return write_reply(client, 257, msg);
} else {
return write_reply(client, 550, strerror(errno));
}
}
static s32 ftp_RNFR(client_t *client, char *path) {
strcpy(client->pending_rename, path);
return write_reply(client, 350, "Ready for RNTO.");
}
static s32 ftp_RNTO(client_t *client, char *path) {
if (!*client->pending_rename) {
return write_reply(client, 503, "RNFR required first.");
}
s32 result;
if (!vrt_rename(client->cwd, client->pending_rename, path)) {
result = write_reply(client, 250, "Rename successful.");
} else {
result = write_reply(client, 550, strerror(errno));
}
*client->pending_rename = '\0';
return result;
}
static s32 ftp_SIZE(client_t *client, char *path) {
struct stat st;
if (!vrt_stat(client->cwd, path, &st)) {
char size_buf[12];
sprintf(size_buf, "%llu", st.st_size);
return write_reply(client, 213, size_buf);
} else {
return write_reply(client, 550, strerror(errno));
}
}
static s32 ftp_PASV(client_t *client, char *rest UNUSED) {
close_passive_socket(client);
client->passive_socket = network_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (client->passive_socket < 0) {
return write_reply(client, 520, "Unable to create listening socket.");
}
set_blocking(client->passive_socket, false);
struct sockaddr_in bindAddress;
memset(&bindAddress, 0, sizeof(bindAddress));
bindAddress.sin_family = AF_INET;
bindAddress.sin_port = htons(passive_port++); // XXX: BUG: This will overflow eventually, with interesting results...
bindAddress.sin_addr.s_addr = htonl(INADDR_ANY);
s32 result;
if ((result = network_bind(client->passive_socket, (struct sockaddr *)&bindAddress, sizeof(bindAddress))) < 0) {
close_passive_socket(client);
return write_reply(client, 520, "Unable to bind listening socket.");
}
if ((result = network_listen(client->passive_socket, 1)) < 0) {
close_passive_socket(client);
return write_reply(client, 520, "Unable to listen on socket.");
}
char reply[49];
u16 port = bindAddress.sin_port;
u32 ip = network_gethostip();
struct in_addr addr;
addr.s_addr = ip;
console_printf("Listening for data connections at %s:%u...\n", inet_ntoa(addr), port);
sprintf(reply, "Entering Passive Mode (%u,%u,%u,%u,%u,%u).", (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff, (port >> 8) & 0xff, port & 0xff);
return write_reply(client, 227, reply);
}
static s32 ftp_PORT(client_t *client, char *portspec) {
u32 h1, h2, h3, h4, p1, p2;
if (sscanf(portspec, "%3u,%3u,%3u,%3u,%3u,%3u", &h1, &h2, &h3, &h4, &p1, &p2) < 6) {
return write_reply(client, 501, "Syntax error in parameters.");
}
char addr_str[44];
sprintf(addr_str, "%u.%u.%u.%u", h1, h2, h3, h4);
struct in_addr sin_addr;
if (!inet_aton(addr_str, &sin_addr)) {
return write_reply(client, 501, "Syntax error in parameters.");
}
close_passive_socket(client);
u16 port = ((p1 &0xff) << 8) | (p2 & 0xff);
client->address.sin_addr = sin_addr;
client->address.sin_port = htons(port);
console_printf("Set client address to %s:%u\n", addr_str, port);
return write_reply(client, 200, "PORT command successful.");
}
typedef s32 (*data_connection_handler)(client_t *client, data_connection_callback callback, void *arg);
static s32 prepare_data_connection_active(client_t *client, data_connection_callback callback UNUSED, void *arg UNUSED) {
s32 data_socket = network_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (data_socket < 0) return data_socket;
set_blocking(data_socket, false);
struct sockaddr_in bindAddress;
memset(&bindAddress, 0, sizeof(bindAddress));
bindAddress.sin_family = AF_INET;
bindAddress.sin_port = htons(SRC_PORT);
bindAddress.sin_addr.s_addr = htonl(INADDR_ANY);
s32 result;
if ((result = network_bind(data_socket, (struct sockaddr *)&bindAddress, sizeof(bindAddress))) < 0) {
network_close(data_socket);
return result;
}
client->data_socket = data_socket;
console_printf("Attempting to connect to client at %s:%u\n", inet_ntoa(client->address.sin_addr), client->address.sin_port);
return 0;
}
static s32 prepare_data_connection_passive(client_t *client, data_connection_callback callback UNUSED, void *arg UNUSED) {
client->data_socket = client->passive_socket;
console_printf("Waiting for data connections...\n");
return 0;
}
static s32 prepare_data_connection(client_t *client, void *callback, void *arg, void *cleanup) {
s32 result = write_reply(client, 150, "Transferring data.");
if (result >= 0) {
data_connection_handler handler = prepare_data_connection_active;
if (client->passive_socket >= 0) handler = prepare_data_connection_passive;
result = handler(client, (data_connection_callback)callback, arg);
if (result < 0) {
result = write_reply(client, 520, "Closing data connection, error occurred during transfer.");
} else {
client->data_connection_connected = false;
client->data_callback = callback;
client->data_connection_callback_arg = arg;
client->data_connection_cleanup = cleanup;
client->data_connection_timer = gettime() + SECS_TO_TICKS(30);
}
}
return result;
}
static s32 send_nlst(s32 data_socket, DIR_P *iter) {
s32 result = 0;
char filename[MAXPATHLEN];
struct dirent *dirent = NULL;
while ((dirent = vrt_readdir(iter)) != 0) {
size_t end_index = strlen(dirent->d_name);
if(end_index + 2 >= MAXPATHLEN)
continue;
strcpy(filename, dirent->d_name);
filename[end_index] = CRLF[0];
filename[end_index + 1] = CRLF[1];
filename[end_index + 2] = '\0';
if ((result = send_exact(data_socket, filename, strlen(filename))) < 0) {
break;
}
}
return result < 0 ? result : 0;
}
static s32 send_list(s32 data_socket, DIR_P *iter) {
struct stat st;
s32 result = 0;
time_t mtime = 0;
u64 size = 0;
char filename[MAXPATHLEN];
char line[MAXPATHLEN + 56 + CRLF_LENGTH + 1];
struct dirent *dirent = NULL;
while ((dirent = vrt_readdir(iter)) != 0) {
snprintf(filename, sizeof(filename), "%s/%s", iter->path, dirent->d_name);
if(stat(filename, &st) == 0)
{
mtime = st.st_mtime;
size = st.st_size;
}
else
{
mtime = time(0);
size = 0;
}
char timestamp[13];
strftime(timestamp, sizeof(timestamp), "%b %d %Y", localtime(&mtime));
snprintf(line, sizeof(line), "%crwxr-xr-x 1 0 0 %10llu %s %s\r\n", (dirent->d_type & DT_DIR) ? 'd' : '-', size, timestamp, dirent->d_name);
if ((result = send_exact(data_socket, line, strlen(line))) < 0) {
break;
}
}
return result < 0 ? result : 0;
}
static s32 ftp_NLST(client_t *client, char *path) {
if (!*path) {
path = ".";
}
DIR_P *dir = vrt_opendir(client->cwd, path);
if (dir == NULL) {
return write_reply(client, 550, strerror(errno));
}
s32 result = prepare_data_connection(client, send_nlst, dir, vrt_closedir);
if (result < 0) vrt_closedir(dir);
return result;
}
static s32 ftp_LIST(client_t *client, char *path) {
if (*path == '-') {
// handle buggy clients that use "LIST -aL" or similar, at the expense of breaking paths that begin with '-'
char flags[FTP_BUFFER_SIZE];
char rest[FTP_BUFFER_SIZE];
char *args[] = { flags, rest };
split(path, ' ', 1, args);
path = rest;
}
if (!*path) {
path = ".";
}
if(path && client->cwd)
{
if(strcmp(path, ".") == 0 && strcmp(client->cwd, "/") == 0)
{
UnmountVirtualPaths();
MountVirtualDevices();
}
}
DIR_P *dir = vrt_opendir(client->cwd, path);
if (dir == NULL) {
return write_reply(client, 550, strerror(errno));
}
s32 result = prepare_data_connection(client, send_list, dir, vrt_closedir);
if (result < 0) vrt_closedir(dir);
return result;
}
static s32 ftp_RETR(client_t *client, char *path) {
FILE *f = vrt_fopen(client->cwd, path, "rb");
if (!f) {
return write_reply(client, 550, strerror(errno));
}
int fd = fileno(f);
if (client->restart_marker && lseek(fd, client->restart_marker, SEEK_SET) != client->restart_marker) {
s32 lseek_error = errno;
fclose(f);
client->restart_marker = 0;
return write_reply(client, 550, strerror(lseek_error));
}
client->restart_marker = 0;
s32 result = prepare_data_connection(client, send_from_file, f, fclose);
if (result < 0) fclose(f);
return result;
}
static s32 stor_or_append(client_t *client, FILE *f) {
if (!f) {
return write_reply(client, 550, strerror(errno));
}
s32 result = prepare_data_connection(client, recv_to_file, f, fclose);
if (result < 0) fclose(f);
return result;
}
static s32 ftp_STOR(client_t *client, char *path) {
FILE *f = vrt_fopen(client->cwd, path, "wb");
int fd;
if (f) fd = fileno(f);
if (f && client->restart_marker && lseek(fd, client->restart_marker, SEEK_SET) != client->restart_marker) {
s32 lseek_error = errno;
fclose(f);
client->restart_marker = 0;
return write_reply(client, 550, strerror(lseek_error));
}
client->restart_marker = 0;
return stor_or_append(client, f);
}
static s32 ftp_APPE(client_t *client, char *path) {
return stor_or_append(client, vrt_fopen(client->cwd, path, "ab"));
}
static s32 ftp_REST(client_t *client, char *offset_str) {
off_t offset;
if (sscanf(offset_str, "%lli", &offset) < 1 || offset < 0) {
return write_reply(client, 501, "Syntax error in parameters.");
}
client->restart_marker = offset;
char msg[FTP_BUFFER_SIZE];
sprintf(msg, "Restart position accepted (%lli).", offset);
return write_reply(client, 350, msg);
}
static s32 ftp_SITE_LOADER(client_t *client, char *rest UNUSED) {
s32 result = write_reply(client, 200, "Exiting to loader.");
//set_reset_flag();
return result;
}
static s32 ftp_SITE_CLEAR(client_t *client, char *rest UNUSED) {
s32 result = write_reply(client, 200, "Cleared.");
u32 i;
for (i = 0; i < 18; i++) console_printf("\n");
//console_printf("\x1b[2;0H");
return result;
}
/*
This is implemented as a no-op to prevent some FTP clients
from displaying skip/abort/retry type prompts.
*/
static s32 ftp_SITE_CHMOD(client_t *client, char *rest UNUSED) {
return write_reply(client, 250, "SITE CHMOD command ok.");
}
static s32 ftp_SITE_PASSWD(client_t *client, char *new_password) {
set_ftp_password(new_password);
return write_reply(client, 200, "Password changed.");
}
static s32 ftp_SITE_NOPASSWD(client_t *client, char *rest UNUSED) {
set_ftp_password(NULL);
return write_reply(client, 200, "Authentication disabled.");
}
static s32 ftp_SITE_EJECT(client_t *client, char *rest UNUSED) {
//if (dvd_eject()) return write_reply(client, 550, "Unable to eject DVD.");
return write_reply(client, 200, "DVD ejected.");
}
static s32 ftp_SITE_MOUNT(client_t *client, char *path UNUSED) {
//if (!mount_virtual(path)) return write_reply(client, 550, "Unable to mount.");
return write_reply(client, 250, "Mounted.");
}
static s32 ftp_SITE_UNMOUNT(client_t *client, char *path UNUSED) {
//if (!unmount_virtual(path)) return write_reply(client, 550, "Unable to unmount.");
return write_reply(client, 250, "Unmounted.");
}
static s32 ftp_SITE_UNKNOWN(client_t *client, char *rest UNUSED) {
return write_reply(client, 501, "Unknown SITE command.");
}
static s32 ftp_SITE_LOAD(client_t *client, char *path UNUSED) {
// FILE *f = vrt_fopen(client->cwd, path, "rb");
// if (!f) return write_reply(client, 550, strerror(errno));
// char *real_path = to_real_path(client->cwd, path);
// if (!real_path) goto end;
// load_from_file(f, real_path);
// free(real_path);
// end:
// fclose(f);
return write_reply(client, 500, "Unable to load.");
}
typedef s32 (*ftp_command_handler)(client_t *client, char *args);
static s32 dispatch_to_handler(client_t *client, char *cmd_line, const char **commands, const ftp_command_handler *handlers) {
char cmd[FTP_BUFFER_SIZE], rest[FTP_BUFFER_SIZE];
char *args[] = { cmd, rest };
split(cmd_line, ' ', 1, args);
s32 i;
for (i = 0; commands[i]; i++) {
if (!strcasecmp(commands[i], cmd)) break;
}
return handlers[i](client, rest);
}
static const char *site_commands[] = { "LOADER", "CLEAR", "CHMOD", "PASSWD", "NOPASSWD", "EJECT", "MOUNT", "UNMOUNT", "LOAD", NULL };
static const ftp_command_handler site_handlers[] = { ftp_SITE_LOADER, ftp_SITE_CLEAR, ftp_SITE_CHMOD, ftp_SITE_PASSWD, ftp_SITE_NOPASSWD, ftp_SITE_EJECT, ftp_SITE_MOUNT, ftp_SITE_UNMOUNT, ftp_SITE_LOAD, ftp_SITE_UNKNOWN };
static s32 ftp_SITE(client_t *client, char *cmd_line) {
return dispatch_to_handler(client, cmd_line, site_commands, site_handlers);
}
static s32 ftp_NOOP(client_t *client, char *rest UNUSED) {
return write_reply(client, 200, "NOOP command successful.");
}
static s32 ftp_SUPERFLUOUS(client_t *client, char *rest UNUSED) {
return write_reply(client, 202, "Command not implemented, superfluous at this site.");
}
static s32 ftp_NEEDAUTH(client_t *client, char *rest UNUSED) {
return write_reply(client, 530, "Please login with USER and PASS.");
}
static s32 ftp_UNKNOWN(client_t *client, char *rest UNUSED) {
return write_reply(client, 502, "Command not implemented.");
}
static const char *unauthenticated_commands[] = { "USER", "PASS", "QUIT", "REIN", "NOOP", NULL };
static const ftp_command_handler unauthenticated_handlers[] = { ftp_USER, ftp_PASS, ftp_QUIT, ftp_REIN, ftp_NOOP, ftp_NEEDAUTH };
static const char *authenticated_commands[] = {
"USER", "PASS", "LIST", "PWD", "CWD", "CDUP",
"SIZE", "PASV", "PORT", "TYPE", "SYST", "MODE",
"RETR", "STOR", "APPE", "REST", "DELE", "MKD",
"RMD", "RNFR", "RNTO", "NLST", "QUIT", "REIN",
"SITE", "NOOP", "ALLO", NULL
};
static const ftp_command_handler authenticated_handlers[] = {
ftp_USER, ftp_PASS, ftp_LIST, ftp_PWD, ftp_CWD, ftp_CDUP,
ftp_SIZE, ftp_PASV, ftp_PORT, ftp_TYPE, ftp_SYST, ftp_MODE,
ftp_RETR, ftp_STOR, ftp_APPE, ftp_REST, ftp_DELE, ftp_MKD,
ftp_DELE, ftp_RNFR, ftp_RNTO, ftp_NLST, ftp_QUIT, ftp_REIN,
ftp_SITE, ftp_NOOP, ftp_SUPERFLUOUS, ftp_UNKNOWN
};
/*
returns negative to signal an error that requires closing the connection
*/
static s32 process_command(client_t *client, char *cmd_line) {
if (strlen(cmd_line) == 0) {
return 0;
}
console_printf("Got command: %s\n", cmd_line);
const char **commands = unauthenticated_commands;
const ftp_command_handler *handlers = unauthenticated_handlers;
if (client->authenticated) {
commands = authenticated_commands;
handlers = authenticated_handlers;
}
return dispatch_to_handler(client, cmd_line, commands, handlers);
}
static void cleanup_data_resources(client_t *client) {
if (client->data_socket >= 0 && client->data_socket != client->passive_socket) {
network_close_blocking(client->data_socket);
}
client->data_socket = -1;
client->data_connection_connected = false;
client->data_callback = NULL;
if (client->data_connection_cleanup) {
client->data_connection_cleanup(client->data_connection_callback_arg);
}
client->data_connection_callback_arg = NULL;
client->data_connection_cleanup = NULL;
client->data_connection_timer = 0;
}
static void cleanup_client(client_t *client) {
network_close_blocking(client->socket);
cleanup_data_resources(client);
close_passive_socket(client);
int client_index;
for (client_index = 0; client_index < MAX_CLIENTS; client_index++) {
if (clients[client_index] == client) {
clients[client_index] = NULL;
break;
}
}
free(client);
num_clients--;
console_printf("Client disconnected.\n");
}
void cleanup_ftp() {
int client_index;
for (client_index = 0; client_index < MAX_CLIENTS; client_index++) {
client_t *client = clients[client_index];
if (client) {
write_reply(client, 421, "Service not available, closing control connection.");
cleanup_client(client);
}
}
}
static bool process_accept_events(s32 server) {
s32 peer;
struct sockaddr_in client_address;
s32 addrlen = sizeof(client_address);
while ((peer = network_accept(server, (struct sockaddr *)&client_address, &addrlen)) != -EAGAIN) {
if (peer < 0) {
console_printf("Error accepting connection: [%i] %s\n", -peer, strerror(-peer));
return false;
}
console_printf("Accepted connection from %s!\n", inet_ntoa(client_address.sin_addr));
if (num_clients == MAX_CLIENTS) {
console_printf("Maximum of %u clients reached, not accepting client.\n", MAX_CLIENTS);
network_close(peer);
return true;
}
client_t *client = malloc(sizeof(client_t));
if (!client) {
console_printf("Could not allocate memory for client state, not accepting client.\n");
network_close(peer);
return true;
}
client->socket = peer;
client->representation_type = 'A';
client->passive_socket = -1;
client->data_socket = -1;
strcpy(client->cwd, "/");
*client->pending_rename = '\0';
client->restart_marker = 0;
client->authenticated = false;
client->offset = 0;
client->data_connection_connected = false;
client->data_callback = NULL;
client->data_connection_callback_arg = NULL;
client->data_connection_cleanup = NULL;
client->data_connection_timer = 0;
memcpy(&client->address, &client_address, sizeof(client_address));
int client_index;
if (write_reply(client, 220, "ftpii") < 0) {
console_printf("Error writing greeting.\n");
network_close_blocking(peer);
free(client);
} else {
for (client_index = 0; client_index < MAX_CLIENTS; client_index++) {
if (!clients[client_index]) {
clients[client_index] = client;
break;
}
}
num_clients++;
}
}
return true;
}
static void process_data_events(client_t *client) {
s32 result;
if (!client->data_connection_connected) {
if (client->passive_socket >= 0) {
struct sockaddr_in data_peer_address;
s32 addrlen = sizeof(data_peer_address);
result = network_accept(client->passive_socket, (struct sockaddr *)&data_peer_address ,&addrlen);
if (result >= 0) {
client->data_socket = result;
client->data_connection_connected = true;
}
} else {
if ((result = network_connect(client->data_socket, (struct sockaddr *)&client->address, sizeof(client->address))) < 0) {
if (result == -EINPROGRESS || result == -EALREADY) result = -EAGAIN;
if ((result != -EAGAIN) && (result != -EISCONN))
{
console_printf("Unable to connect to client: [%i] %s\n", -result, strerror(-result));
}
}
if (result >= 0 || result == -EISCONN) {
client->data_connection_connected = true;
}
}
if (client->data_connection_connected) {
result = 1;
console_printf("Connected to client! Transferring data...\n");
} else if (gettime() > client->data_connection_timer) {
result = -2;
console_printf("Timed out waiting for data connection.\n");
}
} else {
result = client->data_callback(client->data_socket, client->data_connection_callback_arg);
}
if (result <= 0 && result != -EAGAIN) {
cleanup_data_resources(client);
if (result < 0) {
result = write_reply(client, 520, "Closing data connection, error occurred during transfer.");
} else {
result = write_reply(client, 226, "Closing data connection, transfer successful.");
}
if (result < 0) {
cleanup_client(client);
}
}
}
static void process_control_events(client_t *client) {
s32 bytes_read;
while (client->offset < (FTP_BUFFER_SIZE - 1)) {
if (client->data_callback) {
return;
}
char *offset_buf = client->buf + client->offset;
if ((bytes_read = network_read(client->socket, offset_buf, FTP_BUFFER_SIZE - 1 - client->offset)) < 0) {
if (bytes_read != -EAGAIN) {
console_printf("Read error %i occurred, closing client.\n", bytes_read);
goto recv_loop_end;
}
return;
} else if (bytes_read == 0) {
goto recv_loop_end; // EOF from client
}
client->offset += bytes_read;
client->buf[client->offset] = '\0';
if (strchr(offset_buf, '\0') != (client->buf + client->offset)) {
console_printf("Received a null byte from client, closing connection ;-)\n"); // i have decided this isn't allowed =P
goto recv_loop_end;
}
char *next;
char *end;
for (next = client->buf; (end = strstr(next, CRLF)) && !client->data_callback; next = end + CRLF_LENGTH) {
*end = '\0';
if (strchr(next, '\n')) {
console_printf("Received a line-feed from client without preceding carriage return, closing connection ;-)\n"); // i have decided this isn't allowed =P
goto recv_loop_end;
}
if (*next) {
s32 result;
if ((result = process_command(client, next)) < 0) {
if (result != -EQUIT) {
console_printf("Closing connection due to error while processing command: %s\n", next);
}
goto recv_loop_end;
}
}
}
if (next != client->buf) { // some lines were processed
client->offset = strlen(next);
char tmp_buf[client->offset];
memcpy(tmp_buf, next, client->offset);
memcpy(client->buf, tmp_buf, client->offset);
}
}
console_printf("Received line longer than %u bytes, closing client.\n", FTP_BUFFER_SIZE - 1);
recv_loop_end:
cleanup_client(client);
}
bool process_ftp_events(s32 server) {
bool network_down = !process_accept_events(server);
int client_index;
for (client_index = 0; client_index < MAX_CLIENTS; client_index++) {
client_t *client = clients[client_index];
if (client) {
if (client->data_callback) {
process_data_events(client);
} else {
process_control_events(client);
}
}
}
return network_down;
}

42
src/ftp.h Normal file
View File

@ -0,0 +1,42 @@
/*
ftpii -- an FTP server for the Wii
Copyright (C) 2008 Joseph Jordan <joe.ftpii@psychlaw.com.au>
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 _FTP_H_
#define _FTP_H_
#ifdef __cplusplus
extern "C"{
#endif
void accept_ftp_client(s32 server);
void set_ftp_password(char *new_password);
bool process_ftp_events(s32 server);
void cleanup_ftp();
#ifdef __cplusplus
}
#endif
#endif /* _FTP_H_ */

40
src/link.ld Normal file
View File

@ -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 */

190
src/main.c Normal file
View File

@ -0,0 +1,190 @@
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <malloc.h>
#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 "system/memory.h"
#include "utils/logger.h"
#include "utils/utils.h"
#include "common/common.h"
#include "ftp.h"
#include "virtualpath.h"
#include "net.h"
#define PORT 21
#define MAX_CONSOLE_LINES 18
static char * consoleArray[MAX_CONSOLE_LINES];
void console_printf(const char *format, ...)
{
char * tmp = NULL;
va_list va;
va_start(va, format);
if((vasprintf(&tmp, format, va) >= 0) && tmp)
{
if(consoleArray[0])
free(consoleArray[0]);
for(int i = 1; i < MAX_CONSOLE_LINES; i++)
consoleArray[i-1] = consoleArray[i];
if(strlen(tmp) > 79)
tmp[79] = 0;
consoleArray[MAX_CONSOLE_LINES-1] = (tmp);
}
va_end(va);
// Clear screens
OSScreenClearBufferEx(0, 0);
OSScreenClearBufferEx(1, 0);
for(int i = 0; i < MAX_CONSOLE_LINES; i++)
{
if(consoleArray[i])
{
//! TODO: find out why TV screen is distorted
//OSScreenPutFontEx(0, 0, i, consoleArray[i]);
OSScreenPutFontEx(1, 0, i, consoleArray[i]);
}
}
unsigned int screen_buf0_size = OSScreenGetBufferSizeEx(0);
unsigned int screen_buf1_size = OSScreenGetBufferSizeEx(1);
// Flush the cache
DCFlushRange((void *)0xF4000000, screen_buf0_size);
DCFlushRange((void *)0xF4000000 + screen_buf0_size, screen_buf1_size);
OSScreenFlipBuffersEx(0);
OSScreenFlipBuffersEx(1);
}
/* 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; i++)
{
consoleArray[i] = NULL;
}
VPADInit();
// Prepare screen
int screen_buf0_size = 0;
int screen_buf1_size = 0;
// Init screen and screen buffers
OSScreenInit();
screen_buf0_size = OSScreenGetBufferSizeEx(0);
screen_buf1_size = OSScreenGetBufferSizeEx(1);
OSScreenSetBufferEx(0, (void *)0xF4000000);
OSScreenSetBufferEx(1, (void *)(0xF4000000 + screen_buf0_size));
//! TODO: find out why TV screen is distorted, for now TV is disabled
OSScreenEnableEx(0, 0);
OSScreenEnableEx(1, 1);
// Clear screens
OSScreenClearBufferEx(0, 0);
OSScreenClearBufferEx(1, 0);
// Flush the cache
DCFlushRange((void *)0xF4000000, screen_buf0_size);
DCFlushRange((void *)(0xF4000000 + screen_buf0_size), screen_buf1_size);
// Flip buffers
OSScreenFlipBuffersEx(0);
OSScreenFlipBuffersEx(1);
console_printf("FTPiiU listening on %u.%u.%u.%u:%i", (network_gethostip() >> 24) & 0xFF, (network_gethostip() >> 16) & 0xFF, (network_gethostip() >> 8) & 0xFF, (network_gethostip() >> 0) & 0xFF, PORT);
MountVirtualDevices();
int serverSocket = create_server(PORT);
int network_down = 0;
int vpadError = -1;
VPADData vpad;
int vpadReadCounter = 0;
while(serverSocket >= 0 && !network_down)
{
network_down = process_ftp_events(serverSocket);
if(network_down)
{
break;
}
//! update only at 50 Hz, thats more than enough
if(++vpadReadCounter >= 20)
{
vpadReadCounter = 0;
VPADRead(0, &vpad, 1, &vpadError);
if(vpadError == 0 && ((vpad.btns_d | vpad.btns_h) & VPAD_BUTTON_HOME))
break;
}
usleep(1000);
}
cleanup_ftp();
if(serverSocket >= 0)
network_close(serverSocket);
UnmountVirtualPaths();
//!*******************************************************************
//! Enter main application *
//!*******************************************************************
log_printf("Unmount SD\n");
unmount_sd_fat("sd");
log_printf("Release memory\n");
//memoryRelease();
log_deinit();
return EXIT_SUCCESS;
}

19
src/main.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef _MAIN_H_
#define _MAIN_H_
#include "common/types.h"
#include "dynamic_libs/os_functions.h"
/* Main */
#ifdef __cplusplus
extern "C" {
#endif
//! C wrapper for our C++ functions
int Menu_Main(void);
#ifdef __cplusplus
}
#endif
#endif

263
src/net.c Normal file
View File

@ -0,0 +1,263 @@
/*
Copyright (C) 2008 Joseph Jordan <joe.ftpii@psychlaw.com.au>
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 <errno.h>
#include <gctypes.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <unistd.h>
#include <sys/fcntl.h>
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#include "dynamic_libs/os_functions.h"
#include "dynamic_libs/socket_functions.h"
#include "net.h"
#define MAX_NET_BUFFER_SIZE (60*1024)
#define MIN_NET_BUFFER_SIZE 4096
#define FREAD_BUFFER_SIZE (60*1024)
extern u32 hostIpAddress;
static u32 NET_BUFFER_SIZE = MAX_NET_BUFFER_SIZE;
#if 0
void initialise_network() {
printf("Waiting for network to initialise...\n");
s32 result = -1;
while (!check_reset_synchronous() && result < 0) {
net_deinit();
while (!check_reset_synchronous() && (result = net_init()) == -EAGAIN);
if (result < 0) printf("net_init() failed: [%i] %s, retrying...\n", result, strerror(-result));
}
if (result >= 0) {
u32 ip = 0;
do {
ip = net_gethostip();
if (!ip) printf("net_gethostip() failed, retrying...\n");
} while (!check_reset_synchronous() && !ip);
if (ip) {
struct in_addr addr;
addr.s_addr = ip;
printf("Network initialised. Wii IP address: %s\n", inet_ntoa(addr));
}
}
}
#endif
s32 network_socket(u32 domain,u32 type,u32 protocol)
{
return socket(domain, type, protocol);
}
s32 network_bind(s32 s,struct sockaddr *name,s32 namelen)
{
return bind(s, name, namelen);
}
s32 network_listen(s32 s,u32 backlog)
{
return listen(s, backlog);
}
s32 network_accept(s32 s,struct sockaddr *addr,s32 *addrlen)
{
return accept(s, addr, addrlen);
}
s32 network_connect(s32 s,struct sockaddr *addr, s32 addrlen)
{
return connect(s, addr, addrlen);
}
s32 network_read(s32 s,void *mem,s32 len)
{
return recv(s, mem, len, 0);
}
u32 network_gethostip()
{
return hostIpAddress;
}
s32 network_write(s32 s, const void *mem,s32 len)
{
s32 transfered = 0;
while(len)
{
int ret = send(s, mem, len, 0);
if(ret < 0)
{
transfered = ret;
break;
}
mem += ret;
transfered += ret;
len -= ret;
}
return transfered;
}
s32 network_close(s32 s)
{
if(s < 0)
return -1;
return socketclose(s);
}
s32 set_blocking(s32 s, bool blocking) {
s32 block = !blocking;
setsockopt(s, SOL_SOCKET, SO_NONBLOCK, &block, sizeof(block));
return 0;
}
s32 network_close_blocking(s32 s) {
set_blocking(s, true);
return network_close(s);
}
s32 create_server(u16 port) {
s32 server = network_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (server < 0)
return -1;
set_blocking(server, false);
u32 enable = 1;
setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));
struct sockaddr_in bindAddress;
memset(&bindAddress, 0, sizeof(bindAddress));
bindAddress.sin_family = AF_INET;
bindAddress.sin_port = htons(port);
bindAddress.sin_addr.s_addr = htonl(INADDR_ANY);
s32 ret;
if ((ret = network_bind(server, (struct sockaddr *)&bindAddress, sizeof(bindAddress))) < 0) {
network_close(server);
//gxprintf("Error binding socket: [%i] %s\n", -ret, strerror(-ret));
return ret;
}
if ((ret = network_listen(server, 3)) < 0) {
network_close(server);
//gxprintf("Error listening on socket: [%i] %s\n", -ret, strerror(-ret));
return ret;
}
return server;
}
typedef s32 (*transferrer_type)(s32 s, void *mem, s32 len);
static s32 transfer_exact(s32 s, char *buf, s32 length, transferrer_type transferrer) {
s32 result = 0;
s32 remaining = length;
s32 bytes_transferred;
set_blocking(s, true);
while (remaining) {
try_again_with_smaller_buffer:
bytes_transferred = transferrer(s, buf, MIN(remaining, (int) NET_BUFFER_SIZE));
if (bytes_transferred > 0) {
remaining -= bytes_transferred;
buf += bytes_transferred;
} else if (bytes_transferred < 0) {
if (bytes_transferred == -EINVAL && NET_BUFFER_SIZE == MAX_NET_BUFFER_SIZE) {
NET_BUFFER_SIZE = MIN_NET_BUFFER_SIZE;
usleep(1000);
goto try_again_with_smaller_buffer;
}
result = bytes_transferred;
break;
} else {
result = -ENODATA;
break;
}
}
set_blocking(s, false);
return result;
}
s32 send_exact(s32 s, char *buf, s32 length) {
return transfer_exact(s, buf, length, (transferrer_type)network_write);
}
s32 send_from_file(s32 s, FILE *f) {
char * buf = (char *) malloc(FREAD_BUFFER_SIZE);
if(!buf)
return -1;
s32 bytes_read;
s32 result = 0;
bytes_read = fread(buf, 1, FREAD_BUFFER_SIZE, f);
if (bytes_read > 0) {
result = send_exact(s, buf, bytes_read);
if (result < 0) goto end;
}
if (bytes_read < FREAD_BUFFER_SIZE) {
result = -!feof(f);
goto end;
}
free(buf);
return -EAGAIN;
end:
free(buf);
return result;
}
s32 recv_to_file(s32 s, FILE *f) {
char * buf = (char *) malloc(NET_BUFFER_SIZE);
if(!buf)
return -1;
s32 bytes_read;
while (1) {
try_again_with_smaller_buffer:
bytes_read = network_read(s, buf, NET_BUFFER_SIZE);
if (bytes_read < 0) {
if (bytes_read == -EINVAL && NET_BUFFER_SIZE == MAX_NET_BUFFER_SIZE) {
NET_BUFFER_SIZE = MIN_NET_BUFFER_SIZE;
usleep(1000);
goto try_again_with_smaller_buffer;
}
free(buf);
return bytes_read;
} else if (bytes_read == 0) {
free(buf);
return 0;
}
s32 bytes_written = fwrite(buf, 1, bytes_read, f);
if (bytes_written < bytes_read)
{
free(buf);
return -1;
}
}
return -1;
}

62
src/net.h Normal file
View File

@ -0,0 +1,62 @@
/*
Copyright (C) 2008 Joseph Jordan <joe.ftpii@psychlaw.com.au>
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 _NET_H_
#define _NET_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <stdio.h>
#if 0
void initialise_network();
#endif
s32 network_socket(u32 domain,u32 type,u32 protocol);
s32 network_bind(s32 s,struct sockaddr *name,s32 namelen);
s32 network_listen(s32 s,u32 backlog);
s32 network_accept(s32 s,struct sockaddr *addr,s32 *addrlen);
s32 network_connect(s32 s,struct sockaddr *,s32);
s32 network_read(s32 s,void *mem,s32 len);
s32 network_close(s32 s);
u32 network_gethostip();
s32 set_blocking(s32 s, bool blocking);
s32 network_close_blocking(s32 s);
s32 create_server(u16 port);
s32 send_exact(s32 s, char *buf, s32 length);
s32 send_from_file(s32 s, FILE *f);
s32 recv_to_file(s32 s, FILE *f);
#ifdef __cplusplus
}
#endif
#endif /* _NET_H_ */

198
src/system/memory.c Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
****************************************************************************/
#include <malloc.h>
#include <string.h>
#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);
}

42
src/system/memory.h Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef __MEMORY_H_
#define __MEMORY_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <malloc.h>
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_

89
src/utils/logger.c Normal file
View File

@ -0,0 +1,89 @@
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#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

26
src/utils/logger.h Normal file
View File

@ -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

47
src/utils/utils.h Normal file
View File

@ -0,0 +1,47 @@
#ifndef __UTILS_H_
#define __UTILS_H_
#include <malloc.h>
#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_

116
src/virtualpath.c Normal file
View File

@ -0,0 +1,116 @@
/****************************************************************************
* Copyright (C) 2008
* Joseph Jordan <joe.ftpii@psychlaw.com.au>
*
* Copyright (C) 2010
* 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.
*
* for WiiXplorer 2010
***************************************************************************/
#include <malloc.h>
#include <string.h>
#include "virtualpath.h"
u8 MAX_VIRTUAL_PARTITIONS = 0;
VIRTUAL_PARTITION * VIRTUAL_PARTITIONS = NULL;
void VirtualMountDevice(const char * path)
{
if(!path)
return;
int i = 0;
char name[255];
char alias[255];
char prefix[255];
bool namestop = false;
alias[0] = '/';
do
{
if(path[i] == ':')
namestop = true;
if(!namestop)
{
name[i] = path[i];
name[i+1] = '\0';
alias[i+1] = path[i];
alias[i+2] = '\0';
}
prefix[i] = path[i];
prefix[i+1] = '\0';
i++;
}
while(path[i-1] != '/');
AddVirtualPath(name, alias, prefix);
}
void AddVirtualPath(const char *name, const char *alias, const char *prefix)
{
if(!VIRTUAL_PARTITIONS)
VIRTUAL_PARTITIONS = (VIRTUAL_PARTITION *) malloc(sizeof(VIRTUAL_PARTITION));
VIRTUAL_PARTITION * tmp = realloc(VIRTUAL_PARTITIONS, sizeof(VIRTUAL_PARTITION)*(MAX_VIRTUAL_PARTITIONS+1));
if(!tmp)
{
free(VIRTUAL_PARTITIONS);
MAX_VIRTUAL_PARTITIONS = 0;
return;
}
VIRTUAL_PARTITIONS = tmp;
VIRTUAL_PARTITIONS[MAX_VIRTUAL_PARTITIONS].name = strdup(name);
VIRTUAL_PARTITIONS[MAX_VIRTUAL_PARTITIONS].alias = strdup(alias);
VIRTUAL_PARTITIONS[MAX_VIRTUAL_PARTITIONS].prefix = strdup(prefix);
VIRTUAL_PARTITIONS[MAX_VIRTUAL_PARTITIONS].inserted = true;
MAX_VIRTUAL_PARTITIONS++;
}
void MountVirtualDevices()
{
VirtualMountDevice("sd:/");
}
void UnmountVirtualPaths()
{
u32 i = 0;
for(i = 0; i < MAX_VIRTUAL_PARTITIONS; i++)
{
if(VIRTUAL_PARTITIONS[i].name)
free(VIRTUAL_PARTITIONS[i].name);
if(VIRTUAL_PARTITIONS[i].alias)
free(VIRTUAL_PARTITIONS[i].alias);
if(VIRTUAL_PARTITIONS[i].prefix)
free(VIRTUAL_PARTITIONS[i].prefix);
}
if(VIRTUAL_PARTITIONS)
free(VIRTUAL_PARTITIONS);
VIRTUAL_PARTITIONS = NULL;
MAX_VIRTUAL_PARTITIONS = 0;
}

58
src/virtualpath.h Normal file
View File

@ -0,0 +1,58 @@
/****************************************************************************
* Copyright (C) 2010
* by Dimok
*
* Original VIRTUAL_PART Struct
* Copyright (C) 2008
* Joseph Jordan <joe.ftpii@psychlaw.com.au>
*
* 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.
*
* for WiiXplorer 2010
***************************************************************************/
#ifndef _VIRTUALPATH_H_
#define _VIRTUALPATH_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <gctypes.h>
typedef struct {
char *name;
char *alias;
char *prefix;
bool inserted;
} VIRTUAL_PARTITION;
extern VIRTUAL_PARTITION * VIRTUAL_PARTITIONS;
extern u8 MAX_VIRTUAL_PARTITIONS;
void VirtualMountDevice(const char * devicepath);
void AddVirtualPath(const char *name, const char *alias, const char *prefix);
void MountVirtualDevices();
void UnmountVirtualPaths();
#ifdef __cplusplus
}
#endif
#endif /* _VIRTUALPART_H_ */

322
src/vrt.c Normal file
View File

@ -0,0 +1,322 @@
/*
Copyright (C) 2008 Joseph Jordan <joe.ftpii@psychlaw.com.au>
This work is derived from Daniel Ehlers' <danielehlers@mindeye.net> srg_vrt branch.
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 <errno.h>
#include <malloc.h>
#include <stdarg.h>
#include <string.h>
#include <sys/dirent.h>
#include <unistd.h>
#include <gctypes.h>
#include "virtualpath.h"
#include "vrt.h"
static char *virtual_abspath(char *virtual_cwd, char *virtual_path) {
char *path;
if (virtual_path[0] == '/') {
path = virtual_path;
} else {
size_t path_size = strlen(virtual_cwd) + strlen(virtual_path) + 1;
if (path_size > MAXPATHLEN || !(path = malloc(path_size))) return NULL;
strcpy(path, virtual_cwd);
strcat(path, virtual_path);
}
char *normalised_path = malloc(strlen(path) + 1);
if (!normalised_path) goto end;
*normalised_path = '\0';
char *curr_dir = normalised_path;
u32 state = 0; // 0:start, 1:slash, 2:dot, 3:dotdot
char *token = path;
while (1) {
switch (state) {
case 0:
if (*token == '/') {
state = 1;
curr_dir = normalised_path + strlen(normalised_path);
strncat(normalised_path, token, 1);
}
break;
case 1:
if (*token == '.') state = 2;
else if (*token != '/') state = 0;
break;
case 2:
if (*token == '/' || !*token) {
state = 1;
*(curr_dir + 1) = '\0';
} else if (*token == '.') state = 3;
else state = 0;
break;
case 3:
if (*token == '/' || !*token) {
state = 1;
*curr_dir = '\0';
char *prev_dir = strrchr(normalised_path, '/');
if (prev_dir) curr_dir = prev_dir;
else *curr_dir = '/';
*(curr_dir + 1) = '\0';
} else state = 0;
break;
}
if (!*token) break;
if (state == 0 || *token != '/') strncat(normalised_path, token, 1);
token++;
}
u32 end = strlen(normalised_path);
while (end > 1 && normalised_path[end - 1] == '/') {
normalised_path[--end] = '\x00';
}
end:
if (path != virtual_path) free(path);
return normalised_path;
}
/*
Converts a client-visible path to a real absolute path
E.g. "/sd/foo" -> "sd:/foo"
"/sd" -> "sd:/"
"/sd/../usb" -> "usb:/"
The resulting path will fit in an array of size MAXPATHLEN
Returns NULL to indicate that the client-visible path is invalid
*/
char *to_real_path(char *virtual_cwd, char *virtual_path) {
errno = ENOENT;
if (strchr(virtual_path, ':')) {
return NULL; // colon is not allowed in virtual path, i've decided =P
}
virtual_path = virtual_abspath(virtual_cwd, virtual_path);
if (!virtual_path) return NULL;
char *path = NULL;
char *rest = virtual_path;
if (!strcmp("/", virtual_path)) {
// indicate vfs-root with ""
path = "";
goto end;
}
const char *prefix = NULL;
u32 i;
for (i = 0; i < MAX_VIRTUAL_PARTITIONS; i++) {
VIRTUAL_PARTITION *partition = VIRTUAL_PARTITIONS + i;
const char *alias = partition->alias;
size_t alias_len = strlen(alias);
if (!strcasecmp(alias, virtual_path) || (!strncasecmp(alias, virtual_path, alias_len) && virtual_path[alias_len] == '/')) {
prefix = partition->prefix;
rest += alias_len;
if (*rest == '/') rest++;
break;
}
}
if (!prefix) {
errno = ENODEV;
goto end;
}
size_t real_path_size = strlen(prefix) + strlen(rest) + 1;
if (real_path_size > MAXPATHLEN) goto end;
path = malloc(real_path_size);
if (!path) goto end;
strcpy(path, prefix);
strcat(path, rest);
end:
free(virtual_path);
return path;
}
typedef void * (*path_func)(char *path, ...);
static void *with_virtual_path(void *virtual_cwd, void *void_f, char *virtual_path, s32 failed, ...) {
char *path = to_real_path(virtual_cwd, virtual_path);
if (!path || !*path) return (void *)failed;
path_func f = (path_func)void_f;
va_list ap;
void *args[3];
unsigned int num_args = 0;
va_start(ap, failed);
do {
void *arg = va_arg(ap, void *);
if (!arg) break;
args[num_args++] = arg;
} while (1);
va_end(ap);
void *result;
switch (num_args) {
case 0: result = f(path); break;
case 1: result = f(path, args[0]); break;
case 2: result = f(path, args[0], args[1]); break;
case 3: result = f(path, args[0], args[1], args[2]); break;
default: result = (void *)failed; break;
}
free(path);
return result;
}
FILE *vrt_fopen(char *cwd, char *path, char *mode) {
return with_virtual_path(cwd, fopen, path, 0, mode, NULL);
}
int vrt_stat(char *cwd, char *path, struct stat *st) {
char *real_path = to_real_path(cwd, path);
if (!real_path) return -1;
else if (!*real_path) {
st->st_mode = S_IFDIR;
st->st_size = 31337;
return 0;
}
free(real_path);
return (int)with_virtual_path(cwd, stat, path, -1, st, NULL);
}
int vrt_chdir(char *cwd, char *path) {
struct stat st;
if (vrt_stat(cwd, path, &st)) {
return -1;
} else if (!(st.st_mode & S_IFDIR)) {
errno = ENOTDIR;
return -1;
}
char *abspath = virtual_abspath(cwd, path);
if (!abspath) {
errno = ENOMEM;
return -1;
}
strcpy(cwd, abspath);
if (cwd[1]) strcat(cwd, "/");
free(abspath);
return 0;
}
int vrt_unlink(char *cwd, char *path) {
return (int)with_virtual_path(cwd, unlink, path, -1, NULL);
}
int vrt_mkdir(char *cwd, char *path, mode_t mode) {
return (int)with_virtual_path(cwd, mkdir, path, -1, mode, NULL);
}
int vrt_rename(char *cwd, char *from_path, char *to_path) {
char *real_to_path = to_real_path(cwd, to_path);
if (!real_to_path || !*real_to_path) return -1;
int result = (int)with_virtual_path(cwd, rename, from_path, -1, real_to_path, NULL);
free(real_to_path);
return result;
}
/*
When in vfs-root this creates a fake DIR_ITER.
*/
DIR_P *vrt_opendir(char *cwd, char *path)
{
char *real_path = to_real_path(cwd, path);
if (!real_path) return NULL;
DIR_P *iter = malloc(sizeof(DIR_P));
if (!iter)
{
if (*real_path != 0)
free(real_path);
return NULL;
}
iter->virt_root = 0;
iter->path = real_path;
if (*iter->path == 0) {
iter->dir = malloc(sizeof(DIR));
if(!iter->dir) {
// root path is not allocated
free(iter);
return NULL;
}
memset(iter->dir, 0, sizeof(DIR));
iter->virt_root = 1; // we are at the virtual root
return iter;
}
iter->dir = with_virtual_path(cwd, opendir, path, 0, NULL);
if(!iter->dir)
{
free(iter->path);
free(iter);
return NULL;
}
return iter;
}
/*
Yields virtual aliases when pDir->virt_root
*/
struct dirent *vrt_readdir(DIR_P *pDir) {
if(!pDir || !pDir->dir) return NULL;
DIR *iter = pDir->dir;
if (pDir->virt_root) {
for (; (u32)iter->position < MAX_VIRTUAL_PARTITIONS; iter->position++) {
VIRTUAL_PARTITION *partition = VIRTUAL_PARTITIONS + (int)iter->position;
if (partition->inserted) {
iter->fileData.d_type = DT_DIR;
strcpy(iter->fileData.d_name, partition->alias + 1);
iter->position++;
return &iter->fileData;
}
}
return NULL;
}
return readdir(iter);
}
int vrt_closedir(DIR_P *iter) {
if(!iter) return -1;
if(iter->dir)
{
if (iter->virt_root)
free(iter->dir);
else
closedir(iter->dir);
}
// root path is not allocated
if(iter->path && *iter->path != 0)
free(iter->path);
free(iter);
return 0;
}

58
src/vrt.h Normal file
View File

@ -0,0 +1,58 @@
/*
Copyright (C) 2008 Joseph Jordan <joe.ftpii@psychlaw.com.au>
This work is derived from Daniel Ehlers' <danielehlers@mindeye.net> srg_vrt branch.
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 _VRT_H_
#define _VRT_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <stdio.h>
#include <sys/dirent.h>
typedef struct
{
DIR *dir;
char *path;
u8 virt_root;
} DIR_P;
char *to_real_path(char *virtual_cwd, char *virtual_path);
FILE *vrt_fopen(char *cwd, char *path, char *mode);
int vrt_stat(char *cwd, char *path, struct stat *st);
int vrt_chdir(char *cwd, char *path);
int vrt_unlink(char *cwd, char *path);
int vrt_mkdir(char *cwd, char *path, mode_t mode);
int vrt_rename(char *cwd, char *from_path, char *to_path);
DIR_P *vrt_opendir(char *cwd, char *path);
struct dirent *vrt_readdir(DIR_P *iter);
int vrt_closedir(DIR_P *iter);
#ifdef __cplusplus
}
#endif
#endif /* _VRT_H_ */